[hibernate-commits] Hibernate SVN: r15004 - in core/tags: hibernate-3.3.0.CR2 and 104 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Thu Jul 31 16:04:00 EDT 2008


Author: steve.ebersole at jboss.com
Date: 2008-07-31 16:03:48 -0400 (Thu, 31 Jul 2008)
New Revision: 15004

Added:
   core/tags/hibernate-3.3.0.CR2/
   core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml
   core/tags/hibernate-3.3.0.CR2/changelog.txt
   core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml
   core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml
   core/tags/hibernate-3.3.0.CR2/core/pom.xml
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/BasicTransformerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html
   core/tags/hibernate-3.3.0.CR2/distribution/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml
   core/tags/hibernate-3.3.0.CR2/documentation/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml
   core/tags/hibernate-3.3.0.CR2/jmx/pom.xml
   core/tags/hibernate-3.3.0.CR2/parent/pom.xml
   core/tags/hibernate-3.3.0.CR2/pom.xml
   core/tags/hibernate-3.3.0.CR2/testing/pom.xml
   core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml
   core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java
   core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml
   core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml
   core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml
Removed:
   core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml
   core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml
   core/tags/hibernate-3.3.0.CR2/changelog.txt
   core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml
   core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml
   core/tags/hibernate-3.3.0.CR2/core/pom.xml
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java
   core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html
   core/tags/hibernate-3.3.0.CR2/distribution/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml
   core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml
   core/tags/hibernate-3.3.0.CR2/documentation/pom.xml
   core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml
   core/tags/hibernate-3.3.0.CR2/jmx/pom.xml
   core/tags/hibernate-3.3.0.CR2/parent/pom.xml
   core/tags/hibernate-3.3.0.CR2/pom.xml
   core/tags/hibernate-3.3.0.CR2/testing/pom.xml
   core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml
   core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java
   core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml
   core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml
   core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml
Log:
[maven-release-plugin]  copy for tag hibernate-3.3.0.CR2

Copied: core/tags/hibernate-3.3.0.CR2 (from rev 14744, core/trunk)

Deleted: core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml
===================================================================
--- core/trunk/cache-ehcache/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-ehcache</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Ehcache Integration</name>
-    <description>Integration of Hibernate with Ehcache</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>net.sf.ehcache</groupId>
-            <artifactId>ehcache</artifactId>
-            <version>1.2.3</version>
-        </dependency>
-
-        <!-- testing deps -->
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-testing</artifactId>
-            <version>${version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>hsqldb</groupId>
-            <artifactId>hsqldb</artifactId>
-            <version>1.8.0.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl104-over-slf4j</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-            <scope>test</scope>
-        </dependency>
-        <!-- these are optional on core... :( -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib</artifactId>
-            <version>2.1_3</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm-attrs</artifactId>
-            <version>1.5.3</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml (from rev 15003, core/trunk/cache-ehcache/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/cache-ehcache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-ehcache</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Ehcache Integration</name>
+    <description>Integration of Hibernate with Ehcache</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+
+        <!-- testing deps -->
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-testing</artifactId>
+            <version>${version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>1.8.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- these are optional on core... :( -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib</artifactId>
+            <version>2.1_3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-attrs</artifactId>
+            <version>1.5.3</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml
===================================================================
--- core/trunk/cache-jbosscache/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,125 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-jbosscache</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate JBossCache Integration</name>
-    <description>Integration of Hibernate with JBossCache (based on JBossCache1.x APIs)</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>jboss</groupId>
-            <artifactId>jboss-cache</artifactId>
-            <version>1.4.1.GA</version>
-        </dependency>
-        <!-- jboss-cache (the one from the jboss repo, anyway) does not properly define its dependencies -->
-        <dependency>
-            <groupId>jboss</groupId>
-            <artifactId>jboss-system</artifactId>
-            <version>4.0.2</version>
-        </dependency>
-        <dependency>
-            <groupId>jboss</groupId>
-            <artifactId>jboss-common</artifactId>
-            <version>4.0.2</version>
-        </dependency>
-        <dependency>
-            <groupId>jboss</groupId>
-            <artifactId>jboss-minimal</artifactId>
-            <version>4.0.2</version>
-        </dependency>
-        <dependency>
-            <groupId>jboss</groupId>
-            <artifactId>jboss-j2se</artifactId>
-            <version>200504122039</version>
-        </dependency>
-        <dependency>
-            <groupId>concurrent</groupId>
-            <artifactId>concurrent</artifactId>
-            <version>1.3.4</version>
-        </dependency>
-        <dependency>
-            <groupId>jgroups</groupId>
-            <artifactId>jgroups-all</artifactId>
-            <version>2.2.7</version>
-        </dependency>
-
-        <!-- testing deps -->
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-testing</artifactId>
-            <version>${version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>hsqldb</groupId>
-            <artifactId>hsqldb</artifactId>
-            <version>1.8.0.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl104-over-slf4j</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-            <scope>test</scope>
-        </dependency>
-        <!-- these are optional on core... :( -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib</artifactId>
-            <version>2.1_3</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm-attrs</artifactId>
-            <version>1.5.3</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml (from rev 15003, core/trunk/cache-jbosscache/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/cache-jbosscache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,125 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-jbosscache</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate JBossCache Integration</name>
+    <description>Integration of Hibernate with JBossCache (based on JBossCache1.x APIs)</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-cache</artifactId>
+            <version>1.4.1.GA</version>
+        </dependency>
+        <!-- jboss-cache (the one from the jboss repo, anyway) does not properly define its dependencies -->
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-system</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-common</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-minimal</artifactId>
+            <version>4.0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>jboss</groupId>
+            <artifactId>jboss-j2se</artifactId>
+            <version>200504122039</version>
+        </dependency>
+        <dependency>
+            <groupId>concurrent</groupId>
+            <artifactId>concurrent</artifactId>
+            <version>1.3.4</version>
+        </dependency>
+        <dependency>
+            <groupId>jgroups</groupId>
+            <artifactId>jgroups-all</artifactId>
+            <version>2.2.7</version>
+        </dependency>
+
+        <!-- testing deps -->
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-testing</artifactId>
+            <version>${version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>1.8.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- these are optional on core... :( -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib</artifactId>
+            <version>2.1_3</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-attrs</artifactId>
+            <version>1.5.3</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml
===================================================================
--- core/trunk/cache-jbosscache2/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,187 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-jbosscache2</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate JBossCache2.x Integration</name>
-    <description>Integration of Hibernate with JBossCache (based on JBossCache2.x APIs)</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.jboss.cache</groupId>
-            <artifactId>jbosscache-core</artifactId>
-            <version>2.1.1.GA</version> 
-        </dependency>
-        
-        <!-- test dependencies -->
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-testing</artifactId>
-            <version>${version}</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>hsqldb</groupId>
-            <artifactId>hsqldb</artifactId>
-            <version>1.8.0.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl104-over-slf4j</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-            <scope>test</scope>
-        </dependency>
-        <!-- this is optional on core :( and needed for testing -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <testResources>
-            <testResource>
-                <filtering>false</filtering>
-                <directory>src/test/java</directory>
-                <includes>
-                    <include>**/*.xml</include>
-                </includes>
-            </testResource>
-            <testResource>
-                <filtering>true</filtering>
-                <directory>src/test/resources</directory>
-            </testResource>
-        </testResources>
-        
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <excludes>
-                        <!-- Skip a long-running test of a prototype class -->
-                        <exclude>**/ClusteredConcurrentTimestampRegionTestCase.java</exclude>
-                    </excludes>
-                    <systemProperties>
-                        <property>
-                            <name>hibernate.test.validatefailureexpected</name>
-                            <value>true</value>
-                        </property>
-                        <property>
-                            <name>jgroups.bind_addr</name>
-                            <value>${jgroups.bind_addr}</value>
-                        </property>
-                        <!-- There are problems with multicast and IPv6 on some
-                             OS/JDK combos, so we tell Java to use IPv4. If you
-                             have problems with multicast when running the tests
-                             you can try setting this to 'false', although typically
-                             that won't be helpful.
-                        -->
-                        <property>
-                            <name>java.net.preferIPv4Stack</name>
-                            <value>true</value>
-                        </property>
-                        <!-- Tell JGroups to only wait a short time for PING 
-                             responses before determining coordinator. Speeds cluster
-                             formation during integration tests. (This is too
-                             low a value for a real system; only use for tests.)
-                        -->
-                        <property>
-                            <name>jgroups.ping.timeout</name>
-                            <value>500</value>
-                        </property>
-                        <!-- Tell JGroups to only require one PING response
-                             before determining coordinator. Speeds cluster
-                             formation during integration tests. (This is too
-                             low a value for a real system; only use for tests.)
-                        -->
-                        <property>
-                            <name>jgroups.ping.num_initial_members</name>
-                            <value>1</value>
-                        </property>
-                        <!-- Disable the JGroups message bundling feature
-                             to speed tests and avoid FLUSH issue -->
-                        <property>
-                            <name>jgroups.udp.enable_bundling</name>
-                            <value>false</value>
-                        </property>
-                    </systemProperties>
-                    <skipExec>${skipUnitTests}</skipExec>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <properties>
-        <skipUnitTests>true</skipUnitTests>
-        <!-- 
-            Following is the default jgroups mcast address.  If you find the testsuite runs very slowly, there
-            may be problems with multicast on the interface JGroups uses by default on your machine. You can
-            try to resolve setting 'jgroups.bind_addr' as a system-property to the jvm launching maven and
-            setting the value to an interface where you know multicast works
-        -->
-        <jgroups.bind_addr>127.0.0.1</jgroups.bind_addr>
-    </properties>
-
-    <profiles>
-        <profile>
-            <id>test</id>
-            <activation>
-                <activeByDefault>false</activeByDefault>
-            </activation>
-            <properties>
-                <skipUnitTests>false</skipUnitTests>
-            </properties>
-        </profile>
-     </profiles>
-</project>

Copied: core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml (from rev 15003, core/trunk/cache-jbosscache2/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/cache-jbosscache2/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,187 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-jbosscache2</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate JBossCache2.x Integration</name>
+    <description>Integration of Hibernate with JBossCache (based on JBossCache2.x APIs)</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.cache</groupId>
+            <artifactId>jbosscache-core</artifactId>
+            <version>2.1.1.GA</version> 
+        </dependency>
+        
+        <!-- test dependencies -->
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-testing</artifactId>
+            <version>${version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+            <version>1.8.0.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>99.0-does-not-exist</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+            <scope>test</scope>
+        </dependency>
+        <!-- this is optional on core :( and needed for testing -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <testResources>
+            <testResource>
+                <filtering>false</filtering>
+                <directory>src/test/java</directory>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </testResource>
+            <testResource>
+                <filtering>true</filtering>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+        
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <!-- Skip a long-running test of a prototype class -->
+                        <exclude>**/ClusteredConcurrentTimestampRegionTestCase.java</exclude>
+                    </excludes>
+                    <systemProperties>
+                        <property>
+                            <name>hibernate.test.validatefailureexpected</name>
+                            <value>true</value>
+                        </property>
+                        <property>
+                            <name>jgroups.bind_addr</name>
+                            <value>${jgroups.bind_addr}</value>
+                        </property>
+                        <!-- There are problems with multicast and IPv6 on some
+                             OS/JDK combos, so we tell Java to use IPv4. If you
+                             have problems with multicast when running the tests
+                             you can try setting this to 'false', although typically
+                             that won't be helpful.
+                        -->
+                        <property>
+                            <name>java.net.preferIPv4Stack</name>
+                            <value>true</value>
+                        </property>
+                        <!-- Tell JGroups to only wait a short time for PING 
+                             responses before determining coordinator. Speeds cluster
+                             formation during integration tests. (This is too
+                             low a value for a real system; only use for tests.)
+                        -->
+                        <property>
+                            <name>jgroups.ping.timeout</name>
+                            <value>500</value>
+                        </property>
+                        <!-- Tell JGroups to only require one PING response
+                             before determining coordinator. Speeds cluster
+                             formation during integration tests. (This is too
+                             low a value for a real system; only use for tests.)
+                        -->
+                        <property>
+                            <name>jgroups.ping.num_initial_members</name>
+                            <value>1</value>
+                        </property>
+                        <!-- Disable the JGroups message bundling feature
+                             to speed tests and avoid FLUSH issue -->
+                        <property>
+                            <name>jgroups.udp.enable_bundling</name>
+                            <value>false</value>
+                        </property>
+                    </systemProperties>
+                    <skipExec>${skipUnitTests}</skipExec>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <properties>
+        <skipUnitTests>true</skipUnitTests>
+        <!-- 
+            Following is the default jgroups mcast address.  If you find the testsuite runs very slowly, there
+            may be problems with multicast on the interface JGroups uses by default on your machine. You can
+            try to resolve setting 'jgroups.bind_addr' as a system-property to the jvm launching maven and
+            setting the value to an interface where you know multicast works
+        -->
+        <jgroups.bind_addr>127.0.0.1</jgroups.bind_addr>
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>test</id>
+            <activation>
+                <activeByDefault>false</activeByDefault>
+            </activation>
+            <properties>
+                <skipUnitTests>false</skipUnitTests>
+            </properties>
+        </profile>
+     </profiles>
+</project>

Deleted: core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml
===================================================================
--- core/trunk/cache-oscache/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-oscache</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate OSCache Integration</name>
-    <description>Integration of Hibernate with OSCache</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>opensymphony</groupId>
-            <artifactId>oscache</artifactId>
-            <version>2.1</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml (from rev 15003, core/trunk/cache-oscache/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/cache-oscache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-oscache</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate OSCache Integration</name>
+    <description>Integration of Hibernate with OSCache</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>opensymphony</groupId>
+            <artifactId>oscache</artifactId>
+            <version>2.1</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml
===================================================================
--- core/trunk/cache-swarmcache/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-swarmcache</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate SwarmCache Integration</name>
-    <description>Integration of Hibernate with SwarmCache</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>swarmcache</groupId>
-            <artifactId>swarmcache</artifactId>
-            <version>1.0RC2</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml (from rev 15003, core/trunk/cache-swarmcache/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/cache-swarmcache/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-swarmcache</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate SwarmCache Integration</name>
+    <description>Integration of Hibernate with SwarmCache</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>swarmcache</groupId>
+            <artifactId>swarmcache</artifactId>
+            <version>1.0RC2</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/changelog.txt
===================================================================
--- core/trunk/changelog.txt	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/changelog.txt	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,2581 +0,0 @@
-Hibernate Changelog
-===================
-Note: Newer entries are automatically generated and the description might not
-match the actual issue resolution (i.e. a bug might not be a bug). Please
-refer to the particular case on JIRA using the issue tracking number to learn
-more about each case.
-
-
-Changes in version 3.3.0.CR1 (2008.03.18)
--------------------------------------------
-
-** Bug
-    * [HHH-1312] - Unclosed ResultSet when using Identity
-    * [HHH-1396] - Table.validateColumns fails on valid column
-    * [HHH-1569] - Immutable Natural Id check fails with ArrayIndexOutOfBounds in some cases
-    * [HHH-1593] - Infinite loop/StackOverflow when calling configuration.setListener(null)
-    * [HHH-1753] - DB2Dialect.getCurrentTimestampSQLFunctionName() uses Oracle syntax
-    * [HHH-1916] - param values in generator element should be trimmed during HbmBinding
-    * [HHH-1920] - Incorrect documentation regarding XML manipulation in Hibernate reference manual (chapter 18.3).
-    * [HHH-1956] - Interceptor.afterTransactionCompletion not called with JTATransaction (CacheSynchronization.hibernateTransaction not set)
-    * [HHH-2159] - NullPointerException in FromElement#findIntendedAliasedFromElementBasedOnCrazyJPARequirements with 'hibernate.query.jpaql_strict_compliance' enabled
-    * [HHH-2164] - Minor bug in section "20.1.1. Customizing the schema"
-    * [HHH-2200] - Memory leak in AbstractBatcher with Generated Properties
-    * [HHH-2320] - Regression: optional properties under a <join> tag no longer update properly
-    * [HHH-2503] - AbstractEntityPersister swallows JDBCExceptions in processGeneratedProperties
-    * [HHH-2513] - Abusive WARN logged during deserialization of replicated SessionFactory
-    * [HHH-2542] - NullPointerException in TypeFactory.replaceAssociations for ComponentType
-    * [HHH-2553] - New LoadContexts Implementation causing possible performance degradation
-    * [HHH-2593] - Keyword UNION is prefixed with "this_." in filter conditions
-    * [HHH-2616] - No event is fired on Collection recreate/remove/update action
-    * [HHH-2627] - Generated properties leak prepared statements in Hibernate 3.2.3 and higher.
-    * [HHH-2631] - Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts
-    * [HHH-2711] - PropertyAccessException with backref and <composite-map-key/>
-    * [HHH-2726] - spelling o your CLASSPATH
-    * [HHH-2728] - Calling session.clear() while retrieving objects via an iterator will cause a "LazyInitializationException - No Session" by the CGLIBLazyInitializer
-    * [HHH-2788] - Oracl8iDialect No Dialect mapping for JDBC type 91
-    * [HHH-2795] - CollectionLoadContexts for empy collections are not removed until PersistenceContext.clear()
-    * [HHH-2816] - DefaultFlushEntityEventListener.checkNaturalId() causes extra SELECTs on read-only entities
-    * [HHH-2833] - insert-select query fails with NPE when select includes join
-    * [HHH-2857] - schemaSupport for HSQLDialect remote connections doesn't work
-    * [HHH-2861] - cascade="delete-orphan,all" is ignored
-    * [HHH-2863] - testsuite fix-ups for maven and/or directory changes
-    * [HHH-2864] - Merging a detached instance with a new child in a unidirectional one-to-many association fails if the parent was previously loaded as a proxy
-    * [HHH-2892] - skip up-to-date checks of query cache for natural-id only if immutable
-    * [HHH-2928] - optimizers for enhanced id generators should be synchronized against multi-threaded access
-    * [HHH-2948] - QueryStatistics.executionMinTime always = 0
-    * [HHH-3111] - WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getStatus() implemented incorrect
-    * [HHH-3140] - Region prefix ignored for entities and collections
-
-** Deprecation
-    * [HHH-2755] - Wrong "jsdk.jar" referenced in the tutorial
-
-** Improvement
-    * [HHH-1786] - JTASessionContext.CleanupSynch does not remove sessions from currentSessionMap
-    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
-    * [HHH-2156] - Section 19.3, "Managing the caches" doesn't document CacheMode.IGNORE
-    * [HHH-2533] - redesign Cache/CacheProviders
-    * [HHH-2662] - Workaround PostgreSQL issues in testsuite
-    * [HHH-2663] - Map java.sql.Types.REAL to Hibernate FloatType for auto-discovery stuff
-    * [HHH-2665] - Split Oracle9Dialect into Oracle9iDialect and Oracle10gDialect
-    * [HHH-2669] - Unequivocally map MySQL LOB types to the LONG variant
-    * [HHH-2682] - support for auto-discovery of H2 dialect
-    * [HHH-2696] - Consider migrating to slf4j
-    * [HHH-2761] - Handle null and empty string consistently in PropertiesHelper
-    * [HHH-2778] - TransactionManagerLookup implementation for Bitronix Transaction Manager
-    * [HHH-2789] - Section 19.2 of the documentation does not show OSCache as supporting clusters. It does.
-    * [HHH-2822] - timestamp extraction functions for SAPDBDialect
-    * [HHH-2826] - IS [NOT] NULL checks with component values
-    * [HHH-2859] - Introduce a 'Work' API for user to perform JDBC work
-    * [HHH-3131] - Add a method to ActionQueue to tell whether there are currently entries in the executions collection
-
-** New Feature
-    * [HHH-1] - Optimize Hibernate for the bulk insertion of related entities
-    * [HHH-2555] - Create new RegionFactory for JBossCache
-    * [HHH-2884] - Provide a sessionFactory close event or hook for the event listeners
-
-** Patch
-    * [HHH-952] - Patch to allow subqueries with joins using Criteria API and Subqueries with DetachedCriteria
-    * [HHH-2070] - Expand DB2Dialect auto-discovery support (Martin Renner)
-    * [HHH-2519] - Schema dropping not documented with hibernate.hbm2ddl.auto=create
-    * [HHH-2630] - Hibernate Dialect is not auto-detected for Sybase ASE and DB2 (Shelley McGowan)
-    * [HHH-2758] - Patch IngresDialect based on certification
-    * [HHH-2839] - Don't use dummy dual table for hsqldb (David Bala?ic)
-    * [HHH-2849] - Better error logging in IdentifierGeneratorFactory (Antony Stubbs)
-    * [HHH-2957] - ActionQueue Insertion sort performance degrades exponentially (Jay Erb)
-    * [HHH-3084] - DialectFactory detection of Ingres metadata (Michael Leo)
-
-** Task
-    * [HHH-2702] - Officially move to JDK 1.4
-    * [HHH-2704] - Migrate to Maven2 for build
-
-
-Changes in version 3.2.6 (2008.02.07)
--------------------------------------------
-
-** Bug
-    * [HHH-925] - DetachedCriteria.createCriteria not working with alias
-    * [HHH-1312] - Unclosed ResultSet when using Identity
-    * [HHH-1329] - SchemaValidator fail when views are involved
-    * [HHH-1593] - Infinite loop/StackOverflow when calling configuration.setListener(null)
-    * [HHH-1685] - DetachedCriteria doesn't create alias on subcriteria
-    * [HHH-1753] - DB2Dialect.getCurrentTimestampSQLFunctionName() uses Oracle syntax
-    * [HHH-1916] - param values in generator element should be trimmed during HbmBinding
-    * [HHH-1956] - Interceptor.afterTransactionCompletion not called with JTATransaction (CacheSynchronization.hibernateTransaction not set)
-    * [HHH-2016] - Oracle9Dialect registers last_day() function as "lastday"
-    * [HHH-2159] - NullPointerException in FromElement#findIntendedAliasedFromElementBasedOnCrazyJPARequirements with 'hibernate.query.jpaql_strict_compliance' enabled
-    * [HHH-2200] - Memory leak in AbstractBatcher with Generated Properties
-    * [HHH-2261] - Setting hibernate.hbm2ddl.auto=validate causes problems on mySQL with numeric fields
-    * [HHH-2320] - Regression: optional properties under a <join> tag no longer update properly
-    * [HHH-2503] - AbstractEntityPersister swallows JDBCExceptions in processGeneratedProperties
-    * [HHH-2542] - NullPointerException in TypeFactory.replaceAssociations for ComponentType
-    * [HHH-2593] - Keyword UNION is prefixed with "this_." in filter conditions
-    * [HHH-2598] - Mapping a collection of entities from two different classes with the same collection name results in duplicate backref property exception if collection keys are not null
-    * [HHH-2616] - No event is fired on Collection recreate/remove/update action
-    * [HHH-2627] - Generated properties leak prepared statements in Hibernate 3.2.3 and higher.
-    * [HHH-2728] - Calling session.clear() while retrieving objects via an iterator will cause a "LazyInitializationException - No Session" by the CGLIBLazyInitializer
-    * [HHH-2788] - Oracl8iDialect No Dialect mapping for JDBC type 91
-    * [HHH-2795] - CollectionLoadContexts for empy collections are not removed until PersistenceContext.clear()
-    * [HHH-2816] - DefaultFlushEntityEventListener.checkNaturalId() causes extra SELECTs on read-only entities
-    * [HHH-2833] - insert-select query fails with NPE when select includes join
-    * [HHH-2857] - schemaSupport for HSQLDialect remote connections doesn't work
-    * [HHH-2861] - cascade="delete-orphan,all" is ignored
-    * [HHH-2864] - Merging a detached instance with a new child in a unidirectional one-to-many association fails if the parent was previously loaded as a proxy
-    * [HHH-2892] - skip up-to-date checks of query cache for natural-id only if immutable
-    * [HHH-2928] - optimizers for enhanced id generators should be synchronized against multi-threaded access
-    * [HHH-2948] - QueryStatistics.executionMinTime always = 0
-
-** Improvement
-    * [HHH-1630] - duplicate property mapping - more details
-    * [HHH-1696] - Add outer join support for aliases on DetachedCriteria
-    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
-    * [HHH-2682] - support for auto-discovery of H2 dialect
-    * [HHH-2761] - Handle null and empty string consistently in PropertiesHelper
-    * [HHH-2822] - timestamp extraction functions for SAPDBDialect
-    * [HHH-2826] - IS [NOT] NULL checks with component values
-    * [HHH-2852] - Better error messages when schema validation fails
-
-** Patch
-    * [HHH-952] - Patch to allow subqueries with joins using Criteria API and Subqueries with DetachedCriteria
-    * [HHH-2070] - Expand DB2Dialect auto-discovery support (Martin Renner)
-    * [HHH-2839] - Don't use dummy dual table for hsqldb (David Bala?ic)
-    * [HHH-2849] - Better error logging in IdentifierGeneratorFactory (Antony Stubbs)
-    * [HHH-2957] - ActionQueue Insertion sort performance degrades exponentially (Jay Erb)
-    * [HHH-3084] - DialectFactory detection of Ingres metadata (Michael Leo)
-
-** Task
-    * [HHH-2559] - http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd needs to be updated
-    * [HHH-3085] - Remove connector.jar (unnecessary library)
-    * [HHH-3086] - Remove jdbc2_0-stdext.jar (unnecessary library)
-
-
-Changes in version 3.2.5 (2007.07.31)
--------------------------------------------
-
-** Bug
-    * [HHH-1116] - batch-size typo
-    * [HHH-1561] - Missing " in Documentation for H3, Chapter 15.8
-    * [HHH-1569] - Immutable Natural Id check fails with ArrayIndexOutOfBounds in some cases
-    * [HHH-1694] - Documentation Outdated: "10.4.4. Queries in native SQL"
-    * [HHH-2180] - minordocumentation error in hbm xml
-    * [HHH-2201] - session.iterate() does not exist
-    * [HHH-2267] - A copy/paste mistake in the documentation for <schemavalidator> ant task
-    * [HHH-2334] - Documentation error in section 5.1.3
-    * [HHH-2420] - Error in 2.5. Contextual Sessions
-    * [HHH-2502] - The second level caching documentation states that ehcache is not distributed.
-    * [HHH-2631] - Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts
-    * [HHH-2649] - Batcher configuration parameter incorrectly documented
-    * [HHH-2711] - PropertyAccessException with backref and <composite-map-key/>
-    * [HHH-2713] - duplicated phrase in docs "of the of the"
-    * [HHH-2714] - Three typos in code examples
-    * [HHH-2719] - adddress --> address
-    * [HHH-2720] - Monetory --> Monetary
-
-** Improvement
-    * [HHH-1022] - incomplete documentation in _README.txt in the lib directory
-    * [HHH-1682] - Improve the description of differences between save() and persist()
-    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
-    * [HHH-2417] - Update book on Hibernate reference
-    * [HHH-2418] - Refer HSQL DB website in chapter 1.2.3
-    * [HHH-2487] - Typo in "5.1.7. version (optional)"
-    * [HHH-2550] - Update API Class in 10.4.3. Criteria queries
-    * [HHH-2662] - Workaround PostgreSQL issues in testsuite
-    * [HHH-2663] - Map java.sql.Types.REAL to Hibernate FloatType for auto-discovery stuff
-    * [HHH-2665] - Split Oracle9Dialect into Oracle9iDialect and Oracle10gDialect
-
-** Patch
-    * [HHH-2520] - Miscellaneous config doc spelling fixes
-    * [HHH-2630] - Hibernate Dialect is not auto-detected for Sybase ASE and DB2 (Shelley McGowan)
-    * [HHH-2758] - Patch IngresDialect based on certification
-
-** Task
-    * [HHH-2551] - Deprecate org.hibernate.criterion.Expression
-    * [HHH-2566] - Replace usages of FlushMode.NEVER with FlushMode.MANUAL
-    * [HHH-2567] - Update reference to use FlushMode.MANUAL
-    * [HHH-2568] - Hibernate javadoc overview refering wrong classes and packages
-
-
-Changes in version 3.2.4.sp1 (2007.05.18)
--------------------------------------------
-
-** Bug
-    * [HHH-2605] - Since 3.2.4 no value specified for row id
-    * [HHH-2613] - LockMode.FORCE on non versioned entity leads to NPE
-
-
-Changes in version 3.2.4 (2007.05.09)
--------------------------------------------
-
-** Bug
-    * [HHH-511] - reattach object from same session
-    * [HHH-2316] - org.hibernate.cache.CacheKey.equals() can cause PropertyAccessException to be thrown
-    * [HHH-2553] - New LoadContexts Implementation causing possible performance degradation
-    * [HHH-2602] - instrumented many-to-one problem with aggressive release
-
-** Deprecation
-    * [HHH-2603] - Deprecate the Session.connection() method
-
-** Improvement
-    * [HHH-2549] - Warn users explicitly about schemaexport and schemaupdate does not support annotations
-
-** New Feature
-    * [HHH-1] - Optimize Hibernate for the bulk insertion of related entities
-
-** Patch
-    * [HHH-2301] - Identity generator with custom insert SQL broken in 3.2 (Scott Rankin and Gail Badner)
-    * [HHH-2336] - paremeterizable and typedef-able UserCollectionType (Holger Brands)
-    * [HHH-2580] - Performace: Too many lookups of WAS extended transaction support (Jesper Udby)
-
-
-Changes in version 3.2.3 (2007.04.02)
--------------------------------------------
-
-** Bug
-    * [HHH-2376] - Query with fully qualified entity class fails
-    * [HHH-2392] - LockModes referencing non-root joined-subclass class in HQL/Criteria
-    * [HHH-2393] - Generated properties leave open ResultSet on Batcher to be closed on transaction completion
-    * [HHH-2397] - hilo generator can generate negative numbers because of arithmetic overflow
-    * [HHH-2469] - ArrayIndexOutOfBoundsException during update by rowid
-    * [HHH-2476] - PersistentMap.put() incorrect on uninitialized, non-extra-lazy map
-    * [HHH-2481] - Big memory leak in the use of CGLIB
-    * [HHH-2499] - incorrect assertion failure relating to generated property values
-    * [HHH-2513] - Abusive WARN logged during deserialization of replicated SessionFactory
-    * [HHH-2521] - Fix cascading of merge across component properties
-    * [HHH-2532] - update/delete executeUpdate() causes problems with JBossCache (at least in opt-locking setups)
-
-** Improvement
-    * [HHH-2495] - encapsulate the notion of state pertaining to processing a result set
-    * [HHH-2534] - better error message for illegal 'collection dereference' in HQL query
-    * [HHH-2535] - Change Cache' Cache71Dialect so that sequence support returns false
-
-** New Feature
-    * [HHH-2471] - create a set of "enhanced" generators
-    * [HHH-2500] - apply Terradata certification results
-
-** Patch
-    * [HHH-2367] - InformixDialect uses wrong data type
-    * [HHH-2489] - SQL comments for HQL bulk operations
-
-
-Changes in version 3.2.2 (2007.01.24)
--------------------------------------------
-
-** Bug
-    * [HHH-1471] - If the 'generated' attribute is set to 'insert' or 'always' on the property of a component it is ignored and the value is not read from the database.
-    * [HHH-1646] - Bad code in FastClass.equals
-    * [HHH-1889] - LockMode.UPGRADE not applied in all cases for SQL Server / Sybase
-    * [HHH-2112] - ClassCastException in StatefulPersistenceContext.getCachedDatabaseSnapshot(...)
-    * [HHH-2221] - MySQL temp table DDL and isolation
-    * [HHH-2238] - SQLQuery executeUpdate doesn't respect Query.setFlushMode()
-    * [HHH-2251] - Settings build unnecessary in schemaupdate/schemavalidate
-    * [HHH-2257] - Query.iterate() results differ from Query.list() 2
-    * [HHH-2259] - autoflush and autoclose not longer occur in JTA environment with hibernate 3.2
-    * [HHH-2264] - NPE when NamedQuery contains space before variable name
-    * [HHH-2274] - Collection ordering when many to many order by is used is not respected
-    * [HHH-2275] - Mapping a composite element as a map key using formulas can lead to AOOBE
-    * [HHH-2284] - HQL: selecting components inside components doesn't work
-    * [HHH-2291] - collection based on property-ref not handled correctly during reattch
-    * [HHH-2292] - merge detached instance fails to persist collection changes in case of bare collection reference
-    * [HHH-2356] - NullableType.toString(Object) should account for nulls
-    * [HHH-2366] - Changing a component's value does not trigger an update during flush
-    * [HHH-2378] - replicate() of non-versioned entiy can result in wrong value for version in entity cache
-
-** Improvement
-    * [HHH-1851] - relax special handling of 'id' property
-    * [HHH-2130] - SQLQuery does not autoflush all entities used in the query
-    * [HHH-2193] - Introduce a flag to avoid checking NamedQuery at startup
-    * [HHH-2242] - Consider Allowing Optimistic Lock Strategies other than 'Version' with joined-subclass
-    * [HHH-2250] - Create an appropriate error message if Query.setEntity is passed a NULL value
-    * [HHH-2282] - PersistentClass property lookups do not properly account for embedded composite identifiers
-    * [HHH-2286] - dialect informational metadata
-    * [HHH-2372] - Allow tooling to create Settings via SettingsFactory without contacting the db
-
-** New Feature
-    * [HHH-2246] - No way to specify CACHE_PROVIDER_CONFIG in HibernateServiceMBean
-
-** Patch
-    * [HHH-2300] - Updated dialect for H2 database engine
-    * [HHH-2371] - enhancements to C3P0ConnectionProvider
-
-** Task
-    * [HHH-2032] - update c3p0 to 0.9.1
-
-
-
-Changes in version 3.2.1 (2006.11.16)
--------------------------------------------
-
-** Bug
-    * [HHH-939] - 'class' property in HQL results in incorrect SQL for joined-subclass
-    * [HHH-1401] - session.merge() executes unnecessary updates when one-to-many relationship is defined.
-    * [HHH-1460] - Inconsistent behavior when using Session.get() with multiple subclasses
-    * [HHH-1564] - deleting versioned object with collection leads to unecessary update
-    * [HHH-1629] - SchemaUpdate/validator doesn't listen to quoting
-    * [HHH-1631] - Missing table in SQL from clause that is referenced in where clause when using joined subclass
-    * [HHH-1651] - hibernate does not find an existing sequence from an Oracle database
-    * [HHH-1663] - <any/> with collection will produce "AssertionFailure: collection was not processed by flush()"
-    * [HHH-1737] - Add a ConnectionWrapper interface to allow access to the underlying connection from a BorrowedConnectionProxy
-    * [HHH-1756] - Proxy objects are not removed from the BatchFetchQueue during a session evict
-    * [HHH-1774] - Component parameters bound incorrectly
-    * [HHH-1921] - "dirty, but no dirty properties" thrown when Interceptor resets properties.
-    * [HHH-1986] - javassist throws InvocationTargetException instead of original checked Exception
-    * [HHH-2027] - merge listener over-writes Interceptor changes to component state for a transient entity
-    * [HHH-2044] - DefaultMergeEventListener.entityIsDetached call StaleObjectStateException with wrong identifier
-    * [HHH-2082] - UpdateTimestampsCache.isUpToDate returns before checking all spaces
-    * [HHH-2108] - cacheable files broken
-    * [HHH-2138] - merge with bidirectional one-to-one may fail
-    * [HHH-2145] - set.retainAll calling set.addAll
-    * [HHH-2174] - Wrong log message in SessionImpl.afterTransactionCompletion(...)
-    * [HHH-2199] - Unique constraints on nullable columns should not be generated with unique-key is used and supportsNotNullUnique=false
-    * [HHH-2202] - Clearing the connection warnings even when log is > WARN to workaround a Sybase issue
-    * [HHH-2206] - SessionImpl tries to deserialize itself in an incorrect order
-    * [HHH-2207] - Suggested fix for HQL - MySQL setMaxResults issue
-    * [HHH-2226] - org.hibernate.hql.ast.tree.FromElementType contains warning log message that should be debug instead
-    * [HHH-2229] - Performance issue with fix for HHH-1293, CGLIBLazyInitializer may be slower for certain Java classes
-    * [HHH-2236] - Lazy property + setReadOnly + Instrumented classes results in NullPointerException when accessing lazy property
-
-** Improvement
-    * [HHH-2037] - provide Query.setProperties(Map)
-    * [HHH-2042] - Typo in FlushMode.MANUAL Javadoc
-    * [HHH-2057] - Add "remove" cascading style to CascadeStyle for XML mappings
-    * [HHH-2127] - Document <filter-def condition="defaultCondition"> and <filter-def>defaultCondition
-    * [HHH-2135] - Hibernate Deserialization:  In org.hibernate.type.SerializableType the code makes a test for the return of a null object by simply testing the object as to whether or not it is null.
-    * [HHH-2185] - introduce setting to control cglib caching of classes
-    * [HHH-2203] - Make Post*Events extend AbstractEvent
-    * [HHH-2208] - Table schema use in DatabaseMetadata
-    * [HHH-2209] - ehcache.jar is old and does not contain the SingletonCacheProvider which are advised in exception messages
-    * [HHH-2217] - Collection write methods and dirtying the collection
-
-** New Feature
-    * [HHH-2205] - Dialect for Intersystems' Cache SQL 2007.1
-
-** Patch
-    * [HHH-1767] - read-only cache for immutable collection causes unnecessary warning
-
-** Task
-    * [HHH-2219] - Upgrade to Javassist 3.4
-
-
-Changes in version 3.2.0.ga (16.10.2006)
------------------------------------------
-(retag of 3.2.0.cr5 (2006.10.16))
-
-Changes in version 3.2.0.cr5 (04.10.2006)
--------------------------------------------
-
-** Bug
-    * [HHH-1668] - PersistentSet write methods mark collection as dirty even if entry is not written
-    * [HHH-1714] - Session.get() behavior
-    * [HHH-1891] - Since rc3 deprecation Warning: The syntax 'TYPE=storage_engine' is deprecated and will be removed in MySQL 5.2.
-
-** Improvement
-    * [HHH-2093] - PERSIST_ON_FLUSH ineffective for recursive object graphs
-    * [HHH-2103] - Rolling back 'SELECT is mandatory' on JPA strict compliance
-
-** Task
-    * [HHH-1931] - verify that the instrument tasks actually work
-
-
-Changes in version 3.2.0.cr4 (24.08.2006)
--------------------------------------------
-
-** Bug
-    * [HHH-1293] - java.lang.NoSuchMethodError: <persistent class>.getHibernateLazyInitializer()
-    * [HHH-1677] - optimistic-lock="dirty|all" is ignored at delete time
-    * [HHH-1710] - persistent collections with property-ref to secondary tables cannot be joined in HQL
-    * [HHH-1713] - AbstractEntityPersister causes an exception when a row in a joined table is missing with fetch="select"
-    * [HHH-1740] - Build-time instrumentation breaks lazy="proxy"
-    * [HHH-1750] - Exception ORA-01000 too many open cursors by generated="insert"
-    * [HHH-1806] - No Dialect mapping for JDBC type: 3
-    * [HHH-1848] - A session.lock generates a query with a version column in a joined subclass which does not exist
-    * [HHH-1892] - finish HHH-1789 for ordered and sorted collections
-    * [HHH-1898] - With hibernate 3.2.0-cr3 there is an hql parsing error on a one-to-one relation
-    * [HHH-1924] - ForeignKeys: TransientObjectException is thrown without a message because of a wrong bracket in the code
-    * [HHH-1927] - persist() and then merge() not handled correctly for multiple entity instances representing the same logical state
-    * [HHH-1937] - Proxy creation failure leads to NPEs
-    * [HHH-1943] - PersistenceContext not checked to see whether the associated entity is transient or not
-    * [HHH-1944] - generated subqueries and jpaql compliance (derived select clause) check
-    * [HHH-1947] - OF part of MEMBER  OF is optional
-    * [HHH-1948] - Query Idetification variables are case insensitive in JPA
-    * [HHH-1949] - having trim(BOTH from c.name) translated into having ltrim(rtrim(BOTH)) on DB2
-    * [HHH-1954] - Proxies are never unassociated (evicted) from a session
-    * [HHH-1958] - session.lock(LockMode.FORCE) can lead to NPE
-    * [HHH-1963] - meta inheritance broken
-    * [HHH-1992] - Some cascade actions should not trigger a property access on lazy properties
-    * [HHH-2001] - javaassist does not setup the proper protection domain thus does not work with signed/secured deployments such as webstart
-    * [HHH-2015] - where= does not set parenthesis leading to unexpected query when multiclause are used
-    * [HHH-2017] - locate function defined on Oracle9Dialect is incorrect
-    * [HHH-2022] - property names beginning with underscores cause Hibernate to generate invalid aliases
-
-** Improvement
-    * [HHH-1470] - Enhance Hibernate-Mapping DTD Definition of type element
-    * [HHH-1934] - logging NonUniqueObjectException and WrongClassException
-    * [HHH-1941] - Be more specific about x not found and invalid mapping exceptions to allow tools to tell about it
-    * [HHH-1968] - unify bytecode instrumentation
-    * [HHH-1980] - disallow the mapping combination of <version/> and optimistic-lock
-    * [HHH-2005] - more standard build script
-    * [HHH-2023] - performance optimization of JTATransactionFactory.isTransactionInProgress()
-
-** Patch
-    * [HHH-1271] - When using Stored Procedure for update or delete, the check is not done correctly.
-
-** Task
-    * [HHH-1931] - verify that the instrument tasks actually work
-
-
-Chages in version 3.2 cr3 (2006.07.06)
--------------------------------------------
-
-** Bug
-    * [HHH-1452] - Native SQL query is missing join if entity includes many-to-one on secondary table
-    * [HHH-1507] - one-to-one can have formula or meta but not both of them.
-    * [HHH-1552] - Error when using ?1 and parameterList
-    * [HHH-1586] - ClassCastException in CollectionType.toLoggableString if using CustomCollectionType
-    * [HHH-1732] - EhCache.toMap still assumes Serializable objects
-    * [HHH-1734] - Connection leak when using hilo strategy in SE environment
-    * [HHH-1741] - Bug in reference documentation
-    * [HHH-1746] - NullPointerException at IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:195
-    * [HHH-1748] - Setting a comment that contains a single quote on a query results in an unintuitive exception
-    * [HHH-1763] - Bug in InputStream org.hibernate.util.ConfigHelper.getResourceAsStream(String resource)
-    * [HHH-1791] - property update="false" ignored since 3.2.0.cr2
-    * [HHH-1816] - serializing session from a named session factory to a different vm broken
-    * [HHH-1822] - flushing entity linked to transient instance (non cascaded) should always fail
-    * [HHH-1828] - registering a transaction marked for Rollback is illegal
-    * [HHH-1833] - Not Generating HibernateException
-    * [HHH-1838] - Wrong SQL generated for hql query on "any" relation
-    * [HHH-1855] - booleans not properly handled in assignment clause of UPDATE statements
-    * [HHH-1858] - wrong sql generated against many-to-any association table
-    * [HHH-1871] - query type autodiscovery assume wrong column when mixing entities and scalars
-
-** Deprecation
-    * [HHH-1792] - Callable update/insert/delete statements should not force rowcount out parameter
-
-** Improvement
-    * [HHH-1617] - Check the second-level cache before adding a PK to a batch fetch
-    * [HHH-1773] - Typo in ImprovedNamingStrategy
-    * [HHH-1779] - Allow Session.remove() on transient object
-    * [HHH-1789] - improve efficiency of collection initialization from L2 cache hits
-    * [HHH-1795] - default cache provider to NoCacheProvider
-    * [HHH-1796] - TreeCache based providers and Fqn
-    * [HHH-1800] - session.get() / load() should raise exception when the id is of the wrong type
-    * [HHH-1818] - remove() should force subsequent contains() calls to return false
-    * [HHH-1831] - Batch loading the same EntityKey (one side of manytoone ) more than once
-    * [HHH-1861] - More complete component handling in HQL
-    * [HHH-1881] - introduce LoggableUserType interface
-
-** New Feature
-    * [HHH-1709] - Be able to raise ENFE rather than LIE in proxies
-    * [HHH-1727] - Add a SQLFunctionRegistry
-    * [HHH-1817] - Introduce setting for JPA-QL strict compliance
-    * [HHH-1826] - Built-in type for char[] -> VARCHAR Byte[] and Character[]
-
-** Patch
-    * [HHH-1558] - Dialect for new database engine H2
-    * [HHH-1847] - QBE 'like' clause with backslashes don't work with MySQL
-
-** Task
-    * [HHH-1839] - rename FlushMode.NEVER -> FlushMode.MANUAL
-
-
-Changes in version 3.2 cr2 (2006.05.05)
--------------------------------------------
-
-** Bug
-    * [HHH-1114] - The first (HSQL) Hibernate Application doesn't work as expected due to lack of database shutdown
-    * [HHH-1175] - Exception when loading inheritance mapping in single file
-    * [HHH-1560] - PropertiesHelper.resolvePlaceHolders() fails with non-String values in System properties
-    * [HHH-1620] - Errors on max_lo <=1 boundaries
-    * [HHH-1625] - Hibernate.isPropertyInitialized() returns false on instrumented transient object
-    * [HHH-1648] - Exception while resuming a transaction is silently eaten
-    * [HHH-1674] - Configuration serialization error: filterDefinitions map not serializable
-    * [HHH-1695] - subsequent calls to non-existent proxy causes NPE
-
-** Improvement
-    * [HHH-1266] - StatelessSession can implement refresh
-    * [HHH-1414] - many-to-many and metadata order-by based on column from the target table
-    * [HHH-1477] - Improve naming strategy for ANN-195
-    * [HHH-1538] - aggregations functions in EJBQL queries does not return the appropriate types
-    * [HHH-1670] - Update EhCache and EhCache provider to support EhCache 1.2
-    * [HHH-1704] - Deduplicate unique constraints generation sharing the same column(s)
-
-** New Feature
-    * [HHH-870] - support SQL updates in named queries
-    * [HHH-1591] - Replace LazyInitializationException by EntityNotFoundException
-    * [HHH-1719] - Provide a ClassTransformer interface to the BytecodeProvider
-
-
-Changes in version 3.2 cr1 (2006.03.27)
--------------------------------------------
-
-** Bug
-    * [HHH-1453] - Broken exception handling in NullableType
-
-** Improvement
-    * [HHH-227] - remove reflection optimizer
-    * [HHH-587] - Make ResultTransformer available for all query methods
-    * [HHH-1588] - delay inserts for insert-generated-identifiers outside transaction
-    * [HHH-1590] - redesign how PostInsertIdentifierGenerators are handled at insertion
-    * [HHH-1592] - allow SelectGenerator to use a defined natural-id (if one)
-
-** New Feature
-    * [HHH-332] - create ability to add resulttransformer to HQL query
-    * [HHH-1179] - support inline sequence id generation on Oracle using RETURNING clause
-
-
-Changes in version 3.2 alpha2 (2006.03.15)
--------------------------------------------
-
-** Bug
-    * [HHH-535] - properties element causes exception in interface/abstract class
-    * [HHH-1325] - ArrayOutOfBounds expected in DatabaseMetadata.isTable when specifing schema
-    * [HHH-1435] - many-to-one lazy seems to be broken in 3.1.x
-    * [HHH-1531] - NPE with many-to-many and property-ref
-    * [HHH-1546] - generated version properties fail with multiple actions per flush
-
-** Improvement
-    * [HHH-1540] - Better Error Feedback In CollectionEntry.postFlush(PersistentCollection)
-    * [HHH-1555] - ConnectionReleaseMode.AFTER_STATEMENT and flushes
-    * [HHH-1559] - introduce TransactionFactory.isTransactionInProgress to facilitate EJB3 joinTransaction handling
-
-
-Changes in version 3.2 alpha1 (2006.02.28)
--------------------------------------------
-
-** Bug
-    * [HHH-687] - Exception QuerySyntaxError not really serializable
-    * [HHH-1236] - Remove static reference to classloader, to avoid memory leak at webapp reload
-    * [HHH-1287] - Problem with WAS ExtendedJTATransaction not available when using MDB
-    * [HHH-1419] - Update + Exists doesn't seem to work
-    * [HHH-1445] - SchemaUpdate closes shared ConnectionProvider
-    * [HHH-1464] - QueryException from Query.getReturnAliases when query uses "fetch"
-    * [HHH-1486] - Concurrent access issues with both SoftLimitMRUCache and SimpleMRUCache
-    * [HHH-1508] - Session.createQuery() should not flush the session
-
-** Improvement
-    * [HHH-1411] - Collection fetches and DISTINCT
-    * [HHH-1412] - Collection fetches and firstResult/maxRows
-    * [HHH-1416] - LockMode.FORCE to implement EJB3 LockModeType.WRITE
-    * [HHH-1457] - support new optimisitc locking capabilities of JBossCache
-    * [HHH-1466] - better handling of Antlr exceptions
-    * [HHH-1516] - support DataDirect standard jdbc stored procedures
-    * [HHH-1518] - Guarentee LockMode behaviors
-    * [HHH-1520] - with clause with implied joins within an explicit join
-    * [HHH-1526] - Improved DTDEntityResolver
-
-** New Feature
-    * [HHH-1251] - Avoid replicating the clearing of TreeCache on SessionFactory..close()
-    * [HHH-1410] - FlushMode.AUTO -> COMMIT when outside a transaction
-    * [HHH-1447] - pluggable bytecode libraries
-
-
-Changes in version 3.1.2 (01.27.2006)
--------------------------------------------
-
-** Bug
-    * [HHH-73] - Statistics for HQL queries use pre-processed query string
-    * [HHH-1306] - HQL parsing problem with join fetching of arrays/collections of values
-    * [HHH-1370] - Warning in hibernate-mapping-3.0.dtd
-    * [HHH-1371] - MappingException is thrown when the same column is referenced with different case
-    * [HHH-1386] - Numeric (long) literals not properly handled by HQL parser
-    * [HHH-1390] - Session.isOpen() throws exeception when the session is closed with ThreadLocalSessionContext
-    * [HHH-1391] - Invalid parameter index SQLException when using named parameters after positional parameters
-    * [HHH-1392] - Proxies cannot be serialized after session is closed
-    * [HHH-1398] - extends and entity-names broken with mapping-level package attribute
-    * [HHH-1407] - return-join broken for entity collections
-
-** Improvement
-    * [HHH-1364] - Defensive check of isClosed when obtaining a connection from ConnectionManager
-    * [HHH-1367] - warn level log "this operation breaks ==" may be disturbing
-
-** New Feature
-    * [HHH-1372] - Support for MySQL5 new varchar length
-
-** Patch
-    * [HHH-1005] - Criteria LEFT JOIN capability when adding Order to associations
-
-** Task
-    * [HHH-1373] - Document update versioned
-
-
-Changes in version 3.1.1 (01.13.2006)
--------------------------------------------
-
-** Bug
-    * [HHH-853] - DML-style HQL queries and associations
-    * [HHH-1281] - FORWARD_ONLY ScrollableResults#next() throw GenericJDBCException
-    * [HHH-1286] - Set entity in HQL query without prefix -> incorrect SQL
-    * [HHH-1308] - Session.createFilter(...).iterate() results in bogus column names for result set extraction
-    * [HHH-1314] - float/double literals not sent to the database correctly
-    * [HHH-1316] - SchemaUpdate : java.sql.SQLException: You cannot commit during a managed transaction!
-    * [HHH-1328] - org.hibernate.util.SimpleMRUCache keeps a soft reference to the cache key, so cached values get collected prematurely
-    * [HHH-1336] - ForeignGenerator does not handle transient entities with an entity-name properly
-    * [HHH-1337] - Mapped <component> generated column names incorrect with ImprovedNamingStrategy
-    * [HHH-1349] - HQL delete statement problem due to oracle lacking table aliases in delete clause
-    * [HHH-1361] - creating temporary table for bulk delete will commit current transaction in managed environment such as J2EE
-
-** Improvement
-    * [HHH-1019] - Native SQL return-property mapping doesn't support dot-syntax in return-property for components
-    * [HHH-1290] - Defensive checking of session status
-    * [HHH-1302] - query.getReturnTypes inconsistent
-    * [HHH-1304] - better handling of borrowed connections in non-ON_CLOSE release semantics
-    * [HHH-1309] - schemaupdate does not handle TableHiLoGenerator
-    * [HHH-1339] - empty property name in mapping file gives imcomprehensible error message
-    * [HHH-1344] - ANSI-SQL trim function for SQLServer
-    * [HHH-1345] - ANSI-SQL mod function for SQLServer
-    * [HHH-1346] - ANSI-SQL bit_length function for SQLServer
-    * [HHH-1351] - <return-scalar name="blah"/> should be possible
-    * [HHH-1360] - set autodiscovery flag for SQLQueries when resultsetmappings are used
-
-
-Changes in version 3.1  (12.12.2005)
--------------------------------------------
-
-** Bug
-    * [HHH-849] - Cartesian product + implicit joins
-    * [HHH-1065] - user provided connection not usable by default due to agressive release changes
-    * [HHH-1101] - associations join fetched in HQL without owner being selected
-    * [HHH-1133] - Comparators, defined for collections in mapping files, are not set
-    * [HHH-1149] - NPE flushing reattached entity  w/ non-mutable natural-id
-    * [HHH-1170] - HQL 'cast' function doesn't work with MySQL 4 when casting to string
-    * [HHH-1187] - Cannot delete a object having a delete-orphan collection when user_rollback_id is set
-    * [HHH-1191] - HQL fails backward compatibility using classic translator
-    * [HHH-1194] - hql delete statements with joined-subclass hierarchies with a mapped where attribute at the root
-    * [HHH-1206] - Mappings.TableDescription is not serializable
-    * [HHH-1212] - mismatch in entity-modes defined in DTD and EntityMode class
-    * [HHH-1227] - ClassCastException on DOM4J replicate of Calendar property
-    * [HHH-1239] - BinaryArithmeticOperatorNode.getDataType() does not properly handle date/time arithmetic
-    * [HHH-1240] - Track connection leakage in JDBCContext.afterTransactionCompletion()
-    * [HHH-1245] - Calling the Session should register it with the current JTA txn.
-    * [HHH-1254] - Serialization of Sessions using JDBCTransactions with auto-flush/auto-close
-
-** New Feature
-    * [HHH-1222] - Autodiscover scalar types in native-sql
-    * [HHH-1243] - allow placeholders to system properties in config properties
-    * [HHH-1244] - Support for MySQL5 stored procedures
-    * [HHH-1260] - Configuration.mergeProperties()
-
-** Task
-    * [HHH-1066] - Upgrade CGLIB to fix proxy memory leak
-    * [HHH-1242] - upgrade ANTLR to 2.7.6rc1
-
-** Improvement
-    * [HHH-860] - insert ... select ... and version numbers
-    * [HHH-926] - TypeDef should be global
-    * [HHH-1138] - No ConstraintName when using PostgreSQL
-    * [HHH-1144] - Implement naming convention for temporary test failures
-    * [HHH-1153] - PropertiesHelper fails reading primitive values from hibernate-mapping when doc has whitespace
-    * [HHH-1182] - Access to filter metadata
-    * [HHH-1183] - Getting sql "plan" for DML operations
-    * [HHH-1197] - Support for HQL delete on MaxDB
-    * [HHH-1198] - post-insert event pass the entity wo the id field filled when the generator is identity
-    * [HHH-1213] - make JACC event listeners auto configurable (through initialize(Configuration))
-    * [HHH-1215] - Added support for LVARCHAR in InformixDialect
-    * [HHH-1218] - Add concat() function support to SAPDBDialect
-    * [HHH-1255] - ThreadLocalSessionContext and Session serialization
-
-** Patch
-    * [HHH-967] - executeUpdate on StatelessSession
-    * [HHH-1172] - Missing configuration templates for the new MimerSQLDialect
-
-** Deprecation
-    * [HHH-1229] - deprecate ability for entities to not define identifier properties
-
-
-Changes in version 3.1 rc3  (17.11.2005)
--------------------------------------------
-
-** Bug
-    * [HHH-755] - Setter / Getter for property gDate are wrong
-    * [HHH-764] - XML mapping
-    * [HHH-1034] - The connection is closed  *outside* the JTA transaction in TransactionHelper
-    * [HHH-1062] - java:comp/UserTransaction not correct for JBoss
-    * [HHH-1064] - Exception using JTATransaction in WebSphere 6
-    * [HHH-1069] - Unnecessary commas generated in select with left outer joins
-    * [HHH-1075] - New parser  "not exists" command bug
-    * [HHH-1077] - Typo in docs: "equiped"
-    * [HHH-1080] - HQL delete fails on entities with where-fragments using operators other than '='
-    * [HHH-1081] - missing parens in example code for Criteria Associations
-    * [HHH-1084] - incorrect method name "sql" in Restrictions example, should be "sqlRestriction"
-    * [HHH-1091] - Can't write transparent CurrentSessionContext for BMT
-    * [HHH-1098] - Patch for build.sh to be able to build latest version on linux
-    * [HHH-1106] - HQL "not in" generatad wrong SQL
-    * [HHH-1111] - JDBCTransaction.rollback() results in a call to Interceptor.beforeTransactionCompletion()
-    * [HHH-1128] - Column alias clashes under  certain circumstances
-    * [HHH-1146] - latest cvs(11/10/05)  hibernate3 issue with classic query
-    * [HHH-1156] - StatefulPersistenceContext not serializable when property-ref is used
-    * [HHH-1160] - Incorrect use of getGeneratedKey() for Oracle
-
-** New Feature
-    * [HHH-449] - korean hibernate reference manual
-    * [HHH-1129] - use expected-type in 'untyped' Query.setParameter()
-
-** Improvement
-    * [HHH-221] - Proxy for one-to-one with property-ref
-    * [HHH-844] - move parameter "bookkeeping" into QueryTranslator
-    * [HHH-1051] - "Compiled" native SQL queries are not cached
-    * [HHH-1061] - import.sql should allow more human readable and usable files
-    * [HHH-1078] - <dynamic-component> requires type on property
-    * [HHH-1120] - Make NamingStrategy to work nicely with HA and EJB3 naming strategy
-    * [HHH-1142] - added getSelectSequenceNextValString() and getCurrentTimestampSelectString() to TimesTenDialect
-
-** Patch
-    * [HHH-1063] - support for 'locate' function in SQLServer and Sybase dialects
-    * [HHH-1090] - Allow subqueries on criteria to obtain non-string results
-    * [HHH-1095] - Hibernate takes incorrect HasCode when a lot of CompositeKeys and Lazy loading is involved
-    * [HHH-1103] -  finalize method filter for proxies
-    * [HHH-1136] - more meaningful AssertionFailure message in org.hibernate.persister.entity.JoinedSubclassEntityPersister.getTableId(...)
-
-
-Changes in version 3.1 rc2  (17.10.2005)
--------------------------------------------
-** Bug
-    * [HHH-1045] - Example contains inner classes that aren't serializable
-    * [HHH-1055] - optimistic-lock is not inherited from class to subclass et.al.
-
-** Improvement
-    * [HHH-702] - auto detect aliasing for collection properties (coll.key, coll.id etc.)
-    * [HHH-1038] - make 'auto' the default for hibernate.connection.release_mode
-    * [HHH-1042] - determine "expected type" of parameters during HQL parsing
-
-
-Changes in version 3.1 rc1  (07.10.2005)
--------------------------------------------
-** Bug
-    * [HHH-528] - component.manyToOne.id in HQL causes join
-    * [HHH-871] - Configuration.setListener(String type, Object listener) throws ClassCastException
-    * [HHH-873] - referencing raw HQL FromElement alias outide the from clause of update and delete statements generates incorrect sql
-    * [HHH-876] - PreparedStatement being closed before being executed by AbstractBatcher
-    * [HHH-884] - SchemaExport does not propagate parent indexes to <union-subclass> tables
-    * [HHH-887] - Aggressive release and Session.connection()
-    * [HHH-893] - custom tuplizer are not instantiated for components
-    * [HHH-905] - $PlaceHolder$ remains in generated SQL when filter is enabled
-    * [HHH-907] - optimistic-lock="false" for timestamped object results in SQLException: Invalid column index
-    * [HHH-908] - CLONE -NullPointerException when using BigInteger in a query
-    * [HHH-911] - CGLIBLazyInitializer and Exceptions
-    * [HHH-913] - NPE in CMTTransaction since javax.transaction.Transaction is never set
-    * [HHH-918] - impossible to move objects to another session
-    * [HHH-924] - Useless OracleErrorCodeConverter (and possibly others)
-    * [HHH-932] - HQL UPDATE and <union-subclass>
-    * [HHH-946] - QuerySyntaxException might not be serializable
-    * [HHH-964] - ORA-00936 with joined subclass / Oracle
-    * [HHH-986] - Need to check Thread.currentThread().getContextClassLoader() in ConfigHelper
-    * [HHH-991] - Cannot use comparator class
-    * [HHH-1000] - varchar(xxx char) not supported on Oracle8i
-
-** New Feature
-    * [HHH-950] - interface for SessionFactory.getCurrentSession() handling
-
-
-** Improvement
-    * [HHH-608] - update HSQLDialect for HSQL 1.8 sequence support
-    * [HHH-889] - Add read-only cache-mode comment in <query and <sql-query
-    * [HHH-898] - OracleDialect UTF8 varchar2
-    * [HHH-909] - Onquoted primary key in IncrementGenerator
-    * [HHH-988] - generated="never|insert|always"
-    * [HHH-989] - add discussion of implicit and explcit joins
-    * [HHH-1011] - Make disconnect/reconnect of a Session implicit
-
-** Patch
-    * [HHH-994] - Sybase/SQLServer support for temporary tables
-
-
-Changes in version 3.1 beta 3  (13.09.2005)
--------------------------------------------
-** Bug
-    * [HHH-528] - component.manyToOne.id in HQL causes join
-    * [HHH-871] - Configuration.setListener(String type, Object listener) throws ClassCastException
-    * [HHH-873] - referencing raw HQL FromElement alias of update and delete statements
-    * [HHH-876] - PreparedStatement being closed before being executed by AbstractBatcher
-    * [HHH-884] - SchemaExport does not propagate parent indexes to <union-subclass> tables
-    * [HHH-887] - Aggressive release and Session.connection()
-    * [HHH-893] - custom tuplizer are not instantiated for components
-    * [HHH-905] - $PlaceHolder$ remains in generated SQL when filter is enabled
-    * [HHH-907] - optimistic-lock="false" for timestamped object results in SQLException: Invalid column index
-    * [HHH-908] - NullPointerException when using BigInteger in a query
-    * [HHH-911] - CGLIBLazyInitializer and Exceptions
-    * [HHH-913] - NPE in CMTTransaction since javax.transaction.Transaction is never set
-    * [HHH-918] - impossible to move objects to another session 
-    * [HHH-924] - Removed ErrorCodeConverters
-    * [HHH-946] - QuerySyntaxException might not be serializable
-
-** Improvement
-    * [HHH-898] - OracleDialect UTF8 varchar2
-    * [HHH-909] - Unquoted primary key in IncrementGenerator
-
-
-Changes in version 3.1 beta 2 (16.08.2005)
--------------------------------------------
-** Bug
-    * [HHH-477] - Boolean discriminators generate invalid SQL for PostgreSQL dialect
-    * [HHH-480] - SchemaExportTask ignores some properties not defined in hibernate.properties
-    * [HHH-615] - SchemaExport outputFile ignores ant's basedir
-    * [HHH-770] - hql query execution generates invalid SQL
-    * [HHH-779] - Assertion failure occured with Hibernate 3 saving objects
-    * [HHH-781] - SimpleExpression ignorecase regression
-    * [HHH-799] - merge() and embedded composite identifiers
-    * [HHH-801] - subselect fetch and named parameters
-    * [HHH-802] - querying "mapped" composite identifiers
-    * [HHH-803] - no version increment from delayed collection adds
-    * [HHH-805] - Session.getStatistics().getEntityCount() throws UnsupportedOperationException
-    * [HHH-819] - Firebird CONCAT SQL function
-    * [HHH-821] - query by natural-id cache is not update when object is inserted or deleted
-    * [HHH-822] - <key-property> will actually pick up <type> tags if it were allowed by the DTD
-    * [HHH-825] - ReadWrite-Cache issues NullPointerException after modification of an array
-    * [HHH-839] - Session.refresh not working for custom 'Load' SQL
-    * [HHH-849] - Cartesian product + implicit joins
-    * [HHH-854] - Class with mapped composite id can't have subclasses
-    * [HHH-858] - Autocommit status inconsistent in connections created by DriverManagerConnectionProvider
-    * [HHH-863] - Hibernate generates "notExists" instead of "not exists"
-    * [HHH-868] - Missing parens after / or -
-
-** New Feature
-    * [HHH-35] - add attribute haltonerror to schemaexport Ant task
-    * [HHH-182] - Mimer SQL Dialect for Hibernate 3
-    * [HHH-704] - Statistics for optimistic lock failures
-    * [HHH-725] - Allow hooks into all executed sql by a session
-    * [HHH-783] - collection lazy="extra"
-    * [HHH-818] - Optimisitc locking using database current timestamp
-    * [HHH-828] - session.getTransaction()
-    * [HHH-829] - <cache include="all|non-lazy" ... />
-    * [HHH-831] - allow database generated property values
-    * [HHH-832] - allow database generated property values for versioning
-    * [HHH-838] - Transaction.setTimeout()
-    * [HHH-840] - allow definition of "auxiliary" database objects in mapping
-    * [HHH-846] - Add Intializable interface for events
-    * [HHH-848] - Validate mappings against JDBC metadata
-    * [HHH-859] - post-commit events
-
-** Improvement
-    * [HHH-133] - schemaexport task: provide independent drop/create output
-    * [HHH-135] - parameterized types can't be used on key-property or ir (possible others)
-    * [HHH-552] - NoopAccessor for HQL-only properties
-    * [HHH-680] - Easier support for doing UserCollectionType's
-    * [HHH-686] - Final classes and classes with private null ctors cause unhelpful NullPointerException
-    * [HHH-754] - Allow HQL DML for implicit polymorphism
-    * [HHH-782] - Avoid unnecessary updates when component property is update='false' but modified
-    * [HHH-786] - Improve lazy options for <one-to-one>
-    * [HHH-791] - Use cascade styles when fetching entities in refresh() and merge()
-    * [HHH-815] - Confusing use of the term "dereference"
-    * [HHH-830] - Improvements to caching lazy properties
-
-** Patch
-    * [HHH-378] - Better LockMode.UPGRADE for DB2 UDB v8.2
-    * [HHH-430] - Improved SizeExpression with greater, lesser, not equals, etc. capabilities
-    * [HHH-735] - SchemaUpdate reads table metadata from wrong schema
-    * [HHH-780] - org.hibernate.proxy.BasicLazyInitializer reflection hotspot
-    * [HHH-864] - Use QUERY_CACHE for sessions with filters to improve performance
-
-
-Changes in version 3.1 beta 1 (21.07.2005)
--------------------------------------------
-
-** Bug
-   * [HHH-145] - union-subclass and oracle 8i
-   * [HHH-374] - EJB3 example delete query doesn't work in Hibernate.
-   * [HHH-447] - EHCache integration prevents multiple session factories
-   * [HHH-488] - JACCListeners are not working at all
-   * [HHH-564] - missing commas for implicit joins
-   * [HHH-577] - joins within subqueries on dbs supporting ansi-joins result in extraneous commas
-   * [HHH-592] - cast() function doesn't know its returned Hibernate type
-   * [HHH-639] - CGLIB instrumentation of subclasses
-   * [HHH-658] - Bug in Alias Name Generation
-   * [HHH-671] - Firebird support of sequences/generators
-   * [HHH-679] - setLockMode(LockMode.UPGRADE_NOWAIT) does not translate to correct SQL on Oracle
-   * [HHH-688] - Bad implementation in org.hibernate.type.CustomType.stringToObject
-   * [HHH-691] - generated column alias is incorrect if there is a prior relationship and the table column names are similar to the table name
-   * [HHH-694] - NPE when accessing the SLCache stats with TreeCache
-   * [HHH-698] - Exception on EG , trying to change immutable id (natural-id)
-   * [HHH-699] - Incorrect Tablename genetaion when using MySQL Dialect and no Schema definition
-   * [HHH-708] - Restrictions.in could not be used properly on composite-ids
-   * [HHH-709] - ArrayType.replaceElements fails if original.length != target.length
-   * [HHH-718] - HQL "fetch all properties" not working for column level lazy props
-   * [HHH-726] - ConstraintViolationException with primitive collection
-   * [HHH-727] - java.lang.StackOverflowError when cascade="true" on both sides of bidirectional one-to-one association using FK
-   * [HHH-734] - HQL incorrectly parses certain query strings
-   * [HHH-736] - Use of sql functions containing space not supported in filter conditions
-   * [HHH-738] - formula property with select-before-update
-   * [HHH-747] - Order.toSQLString generates incorrect statement
-   * [HHH-748] - component dereferencing in subquery from clauses
-   * [HHH-752] - Typo in 8.5.3 bidirectional one-to-one jjoin table example
-   * [HHH-757] - NullPointerException when using BigInteger in a query
-
-** New Feature
-   * [HHH-595] - HQL insert select
-   * [HHH-597] - Named XML resultsetmappings
-   * [HHH-696] - handle discriminators on HQL insert
-   * [HHH-697] - allow bumping versions in HQL update
-   * [HHH-716] - handle version columns in bulk inserts
-   * [HHH-723] - Need to be able to pass in javax.sql.DataSource in SF creation
-   * [HHH-739] - Order.ignoreCase()
-   * [HHH-741] - select clause subselects
-   * [HHH-742] - Stateless session
-   * [HHH-744] - collection fetching in scroll() via "break processing"
-   * [HHH-768] - <many-to-many property-ref=".."/>
-
-** Improvement
-   * [HHH-14] - Add Session.delete(String entityName, Object entity)
-   * [HHH-295] - cleanup and expose the Tuplizers
-   * [HHH-352] - HQL bulk and cache
-   * [HHH-689] - exclude parens for components outside where-clause
-   * [HHH-743] - {coll.key}, {coll.index}, {coll.element}, etc
-   * [HHH-745] - EJB3 composite PK style
-   * [HHH-749] - Cascade merge() and unidirectional one-to-many
-   * [HHH-750] - use attribute name other than 'type' in dynamic-maps
-   * [HHH-753] - Replace antlr System.exit with QueryException
-   * [HHH-769] - property-ref="foo.bar" to a component property
-   * [HHH-772] - null in maps are handled inconsistently
-   * [TODO-18] - optimistic-lock="all|dirty" with components
-
-
-Changes in version 3.1 alpha 1 (24.06.2005)
-------------------------------------
-** Bug
-    * [HHH-204] - Wrong/uncommon log name in class ...hql ast ErrorCounter
-    * [HHH-241] - HQL lexer doesn't support unicode quoted strings
-    * [HHH-354] - property named "full" breaks HQL queries
-    * [HHH-493] -  WARNING: Keyword 'member' is being intepreted as an ident
-    * [HHH-538] - length() function does not work in SQLServerDialect
-    * [HHH-539] - ClassCastException on mapping a property with a formula in a set of composite elements
-    * [HHH-540] - Mapping a one-to-many collection with a non-null foreign key within a component fails on save
-    * [HHH-547] - Cannot commit using UserCollectionType and debug logging
-    * [HHH-548] - many-to-many faulty delete optimization when filter in use
-    * [HHH-554] - Hibernate 3 HQL to SQL FROM Clause Comma Generation Problem
-    * [HHH-558] - HQL doesn't support multi-byte character in class name and property names
-    * [HHH-559] - quoted multi-byte character in HQL is translated into weird character in SQL.
-    * [HHH-565] - delete-orphan generating AssertionFailure
-    * [HHH-566] - The result is not correct in  'createQuery("select new Foor(x,x) from Foo").scroll()'
-    * [HHH-570] - size operator fails on a many to many in HQL
-    * [HHH-571] - JDK 1.3 Compatibility Issue
-    * [HHH-573] - error when merging entity graph has cascade level>2
-    * [HHH-575] - org.hibernate.cache.FilterKey is not Serializable
-    * [HHH-589] - parameterized expression inside function
-    * [HHH-594] - order-by mapping for collections overrides order by in HQL
-    * [HHH-601] - New temporary table feature assumes all persisters are ready
-    * [HHH-614] - SchemaUpdate broken in DB2/400
-    * [HHH-622] - Spelling mistake 'intepreted' in org.hibernate.hql.PARSER warning
-    * [HHH-642] - criterias with projection
-    * [HHH-650] - FilterImpl is Serializable yet FilterDefinition is not
-    * [HHH-657] - Date parse exception using EntityMode.DOM4J
-    * [HHH-666] - JTAHelper.isInProgress( txn.getStatus()) throws NPE when txn null
-
-** New Feature
-    * [HHH-620] - Extra join conditions in HQL
-    * [HHH-640] - short-circuit dirty checking for instrumented classes
-    * [HHH-643] - support mutable="false" for collections
-    * [HHH-645] - Session.setReadOnly()
-    * [HHH-549] - portable to_char() function
-    * [HHH-576] - Hook to pre-process generated select strings in the Dialect
-    * [HHH-662] - Add support for definition of functional composite key ("properties") in joined subclass
-
-** Improvement
-    * [HHH-46] - Allow access to properties that are not joined
-    * [HHH-261] - Stored procedure support for SQLServer dialects
-    * [HHH-351] - multi-table bulk operations
-    * [HHH-574] - improve in naming named-query
-    * [HHH-596] - Auto-detect {..} in native SQL queries
-    * [HHH-641] - create constraints for many-to-one property-ref
-    * [HHH-501] - warn when a final method is tried to be proxied
-    * [HHH-525] - cglib related startup performance
-    * [HHH-557] - Helpful error message for non Serializable classes with a composite-id
-    * [HHH-586] - check immutable natural-ids
-    * [HHH-609] - Adds substr to PostgreSQL dialect
-    * [HHH-618] - documentation bugs
-
-** Patch
-    * [HHH-224] - JDataStore Dialect and updated Testfiles
-    * [HHH-366] - InformixDialect SQLExceptionConverter
-    * [HHH-536] - ImprovedNamingStrategy modifies capitalized column names inappropriately
-    * [HHH-632] - Informix Dialect missing from automatic dialect discovery
-    * [HHH-4] - CachedFile bugfix + configuration + autodetect resource as file
-
-
-Changes in version 3.0.5 (25.5.2005)
-------------------------------------
-
-** Bug
-    * [HHH-516] - Interceptor.onFlushDirty() sometimes not called
-    * [HHH-517] - getDatabaseMajorVersion() not available in JDK 1.3
-    * [HHH-518] - SQL parser does not recognize all whitespace
-    * [HHH-519] - broken SQL when traversing many-to-many to joined <subselect>
-    * [HHH-529] - Bug in merge()
-
-** New Feature
-    * added <natural-id> mapping
-    * [HHH-533] - allow unique-key on <property> and <many-to-one>
-    * [HHH-534] - efficient cache by natural key
-    * support for <comment> on MySQL
-
-** Improvement
-    * [HHH-526] - log "Aggressively releasing JDBC Connection" as DEBUG instead of INFO
-    * various logging improvements
-
-
-Changes in version 3.0.4 (23.5.2005)
-------------------------------------
-
-** Bug
-    * [HHH-452] - UnsavedValueFactory.instantiate does not wrap the Exception it catches
-    * [HHH-456] - Session still holds references to entities after close()
-    * [HHH-457] - Log info for structured second-level cache entries is incorrect
-    * [HHH-466] - Made default for MS SQL dialect definition more flexible
-    * [HHH-473] - Formula can't contain SQL cast keyword
-    * [HHH-484] - Order-by not applied to collections fetched by OuterJoinLoader
-    * [HHH-487] - Possible empty union in UnionSubclassEntityPersister
-    * [HHH-505] - Possible NullPointerException in BigIntegerType
-    * [HHH-507] - Cached List does not show additions
-    * Fixed bugs in subselect fetching
-
-** New Feature
-    * [HHH-455] - Obtain non-intercepted Session by passing an EmptyInterceptor
-    * [HHH-467] - HQL: support for case when then else end IN select clause
-    * [HHH-485] - Support multiple collection join fetches (attention: Cartesian product) in native SQL queries
-    * Added SessionStatistics metric interface
-    * Added support for table and column level <comment> blocks
-    * Added Simplified Chinese translation of reference documentation (Xiaogang Cao)
-
-** Improvement
-    * Any query may now join fetch >1 collection role (attention: Cartesian product)
-    * [HHH-454] - Add 2292 integrityViolationCode to Oracle9Dialect
-    * [HHH-503] - Implemented ViolatedConstraintNameExtracter for HSQLDialect (Frank Grimes)
-
-
-Changes in version 3.0.3 (8.5.2005)
------------------------------------
-* fixed bug in HQL for composite key classes which have a property named the same as the owning entity's id property
-* replaced 'connection.aggressive_release' with 'hibernate.connection.release_mode'
-* added ConnectionReleaseMode
-* added eager fetch for any associations with fetch=join, even after a HQL query, or cache retrieval (EJB3)
-* added replicate() isUpdate flag to OnReplicateVisitor, useful for native ids
-* fixed ParameterizedTypes order of initialization
-* fixed bug in DB2Dialect
-* fixed EntityMode.DOM4J creation of duplicate <set> output
-* fixed JDBCException error code handling
-* fixed Criteria Restrictions.isEmpty()/isNotEmpty() when collection is mapped to superclass
-* fixed HQL indexed collections access with no alias
-* fixed HQL aggregate functions on components when "id" property is used
-* fixed issue with non-cascading refresh to collections
-* fixed query-timeout not being applied to bulk HQL (Stephan Fudeus)
-* fixed pessimistic locking with Firebird (Yuichi Sugimura)
-* updated Ant 1.6.3
-* improved validation of sql queries, throw QueryException if addEntity() nor addScalar() was called
-* added automatic dialect detection if no dialect is configured
-* added new tutorial (Michael Gloegl, Christian Bauer)
-
-
-Changes in version 3.0.2 (27.4.2005)
-------------------------------------
-* fixed union operations on PostgreSQL
-* fixed HQL concat() function for Oracle dialect
-* fixed auto-close/auto-flush during getCurrentSession() processing
-* fixed ClassCastException with EntityMode.DOM4J
-* fixed HQL dynamic instantiation with iterate()
-* fixed HQL bug with missing parantheses and implicit joins
-* fixed bug were Interceptor.getEntity() wasn't called if in cache
-* fixed bug in merge() of sorted sets
-* fixed bug in EntityMode.DOM4J with non-lazy embedded many-to-ones
-* fixed Criteria/Projection ordering bug
-* fixed HQL referencing component attribute
-* fixed column duplication detection for components
-* fixed eager fetching for many-to-many associations
-* fixed stack overflow with auto_close_session and aggressive_release and unclosed ScrollableResults/HibernateIterator
-* fixed bug in HQL parser regarding naked property refs which reference component properties
-* fixed bug with eager fetched arrays not being loaded
-* fixed bug in filter against joined-subclass
-* improved CacheMode.GET/IGNORE, disabled cache put
-* improved HQL support for standard SQL functions, including coalesce() and nullif()
-* improved filtering of many-to-many associations
-* added HQL support for cast(x as type) if SQL database supports it
-* added increment id generation for union-subclass
-* added ConnectionProvider.supportsAggressiveRelease() for managed environments
-* added support for caching of queries if filter is enabled
-* added PreparedStatement count to Statistics
-* added transactional/nontransactional read()/get() to Cache API
-* added quotation of schema names
-* added Distinct to Projection API
-* added config parameter 'connection.aggressive_release'
-
-Changes in version 3.0.1 (18.4.2005)
-------------------------------------
-* added HQL tuple constructor/comparison feature
-* added HQL "fetch all properties" override if instrumentation is used for lazy loading
-* added HQL projection feature, return Lists instead of arrays for projection
-* added HQL projection feature, return Maps with user-defined HQL SELECT aliases as keys
-* added HQL support for expressions in aggregation functions
-* added new IntegrityViolationException to MySQL dialect
-* added value mapping type 'big_integer'
-* added not-found="ignore|exception" switch for legacy associations (i.e. broken database integrity)
-* added fully automatic Session scoping in JTA environments with sf.getCurrentSession()
-* fixed bug in DTD that wouldn't allow union-subclass in separate file
-* fixed a MS SQL Server case sensitivity issue with native SQL queries
-* fixed a minor bug in subselect fetching
-* fixed case sensitivity in HQL functions
-* fixed a bug with listener assignment for save() operation (Matthew Inger)
-* fixed return-property in named SQL queries to work with all identifier names
-* fixed TransactionManager lookup (again) for WAS 6.0
-* fixed a bug with HQL batch delete and MS SQL Server
-* fixed session not getting closed with auto_close when rollback occured
-* improved concatentation handling in AST parser
-* updated dom4j to avoid memory leak in old version
-* updated C3P0
-
-
-Changes in version 3.0 (31.3.2005)
-----------------------------------
-* added support for autoflush/autoclose to HibernateServiceMBean
-* fixed initialization/session association detection problem of collections
-* fixed creation of FK constraints to union superclass table
-* fixed bug where union-subclass table did not get a PK constraint
-* added a separate log category for HQL parser warnings and errors
-* fixed bulk delete operation on MS SQL Server
-* added support for proxying protected methods (Juozas)
-* added support for unicode quoted strings in new HQL parser
-* fixed implied joins in subselect WHERE clause in new HQL parser
-* added SQLServer7Dialect to handle differences in functions
-* added support for JNDI-bound cache instances, future use for JBoss Cache
-* added scale attribute to column mappings for numeric precision control
-* added fetch=subselect for collections
-* added support for bulk update/delete against discriminator-based inheritence hierarchies
-* added the ability to use naked property refs in HQL (required in update/delete statements)
-* updated CGLIB 2.1.0
-* fixed NPE at BasicEntityPersister.getPropertyIndex (Todd Nine)
-* fixed issue with entity-name and subclasses (Sverker Abrahamsson)
-* fixed issue with correlated subqueries in new HQL parser
-* fixed a problem with native SQL query mapping and embedded composite identifiers
-* improved mapping binding, allowing unordered extends for pure entity-name hiearchies
-* fixed NPE for delete() with deprecated Lifecycle interface
-* fixed a problem with serial joins ending in component value in new HQL parser
-* fixed inner join/subselect precedence problem in new HQL parser
-* fixed indices() function in new HQL parser
-* fixed a bug in InformixDialect, now correct LIMIT clause
-* fixed a bug in idbag.remove() (Sebastien Cesbron)
-* fixed a conflict on OracleDialect between setMaxResult and LockMode.UPGRADE
-* fixed XML configuration file issue with SchemaExport
-* fixed an ArrayIndexOutOfBounds problem
-* renamed executeUpate() to executeUpdate()
-* fixed batch loading for property-ref entities
-* fixed loading from cache of <key property-ref> collection owner
-* fixed minor bug in SQL exception reporting
-* fixed dynamic-component cannot be bound to XML
-* fixed querying component with formula property
-* fixed incorrect table alias for order-by on many-to-many
-* fixed a bug for unidirectional one-to-many with moving child objects
-* fixed a bug with union-subclasses and persister creation
-* fixed a HQL concatenation problem on MySQL
-* fixed a bug where an unnecessary exception was thrown for a property-ref to a superclass property
-* fixed minor dtd bug
-* fixed new bug in Clob/Blob support
-* fixed issue with INDEX_OP and subclass joins on theta-join dialects
-* fixed some minor issues in query cache regions, including HB-1449
-* fixed superflous import and regression bug in verifyparameters
-* fixed two bugs in select id generator (Malcolm Green)
-* fixed increment generator for union-subclass mappings
-* updated JBoss Cache to 1.2.1alpha, fixing locking issues
-* made stat classes serializable
-* fixed merge(), now ignores blob and clob fields
-* added support/dialect for TimesTen
-* improved algorithm for batch fetching, more aggressive
-* improved toStrings()s for Statistics objects (Ryan Lynch)
-* renamed <result-*> to <return-*> for externalized SQL query mapping
-* renamed Session.openSession() for EntityMode to Session.getSession()
-* added support for CASE in HQL
-* fixed bug with filters and polymorphic queries
-* fixed import ordering problem of super/subclass mappings
-* switched to patched ANTLR 2.7.5, now using context classloader before doing class.forname
-* TableHiloGenerator now falls back to TableGenerator properly with max_lo < 2 (Emmanuel Bernard)
-* better transaction handling of TableGenerator in a JTA environment  (Emmanuel Bernard)
-* removed hard coded log4j dependency (Emmanuel Bernard)
-* added support for stored procedure in named queries (Max Andersen)
-* added <property-result> to named SQL queries to allow users to use sql without {}-markup
-* added multi-column property support to native SQL mapping
-
-Changes in version 3.0rc1 (28.2.2005)
-----------------------------------
-* introduced EntityModes, and XML mapping preview
-* several minor dialect improvements
-* fixed a problem where filters were not applied to subclasses
-* fixed a problem where InstrumentTask would fail if applied to already-instrumented classes
-* fixed many problems with new parser and made it the default (thanks again to Joshua for the new parser)
-* implemented bulk update/delete queries for the new parser
-* fixed a minor bug in the classic query parser
-* renamed create() to persist() as per EJB3edr2
-
-Changes in version 3.0 beta 4 (11.2.2005)
------------------------------------------
-* support unidirection one-to-many with a not-null foreign key
-* support formulas for index and element of collections
-* support one-to-ones mapped to formulas
-* fixed a bug in proxying methods that return "this"
-* optimized proxies for embededded composite id classes
-* fixed a bug affecting <key-many-to-one>
-* fixed a bug caching newly inserted objects
-* introduced DetachedCriteria
-* support subselects in Criteria queries
-* miscellaneous Criteria API enhancements
-* fixed a problem where hibernate.max_fetch_depth applied to eager fetching via setFetchMode()
-* use inner joins for join fetching not-null fk associations
-* support unique="true" in <component> and <properties> mappings
-* union-subclass hierarchies may own collections (dtd bug)
-* added guid support for Oracle
-* new mechanism for auto-detecting unsaved-value
-* pass state array in delete events
-* improved implementation of hibernate.auto_close_session and hibernate.close_before_completion
-* fixed a bug where components with only collections would be incorrectly nullified
-* fixed a bug where criteria queries with projection could not be cached
-* fixed a problem where duplicate column name aliases could be generated
-
-Changes in version 3.0 beta 3 (30.1.2005)
-------------------------------------------
-* Major rework of Criteria queries, support for projection, grouping, aggregation, ordering by any attribute
-* various improvements to new HQL parser (Joshua Davis)
-* fixed a bug where <join fetch="select"> was broken for subclasses with duplicated property names
-* fixed problems with long types in Oracle DDL generation
-* added EnhancedUserType, UserCollectionType, UserVersionType
-* added CacheMode
-* fixed minor performance problem where cascade delete could add objects to second-level cache
-* added hibernate.default_batch_fetch_size
-* added hibernate.cache.use_structured_entries
-* different classes and collection roles may now share a cache region
-* don't include discriminators for abstract classes in generated SQL
-* it is no longer truly necessary for composite identifier classes to implement equals()/hashCode() (but still recommended)
-* workaround for bug in MySQL InnoDB with self-referential foreign keys
-* added lazy="true" to many-to-one and one-to-one mappings (requires bytecode instrumentation)
-
-Changes in version 3.0 beta 2 (24.1.2005)
-------------------------------------------
-* added LockAcquisitionErrorCodes to MySQL dialect (Jesse Barnum, Emmanuel Bernard)
-* added MultipleHiLoPerTableGenerator, one hi value per row/per table (compliant with EJB3)
-* added a generator handling multiple hi values per table (Emmanuel Bernard)
-* added events for pre/post SQL operation interception
-* added experimental support for JACC-aware configuration and events
-* added full support for implicit polymorphism in Criteria queries
-* added support annotated classes through XML configuration (Emmanuel Bernard)
-* added support for WebSphere's weird TxManagerLookup
-* added support for filters with dynamic-class mappings
-* added support for lists of parameters in filters
-* added support for scalar queries in createSQLQuery (Michael Gloegl)
-* added support for scalar results in native SQL queries (Michael Gloegl)
-* fixed SchemaExport/SchemaUpdate, now respect default_schema and default_catalog (Michael Gloegl)
-* fixed a bug in one-to-one mapping with property-ref
-* fixed a bug in the query cache lookup routine
-* fixed compilation problems on IBM JDK 1.4. and JDK 1.3.1
-* fixed custom SQL for loading when using composite identifiers
-* fixed exception thrown from optimistic locking failures
-* fixed support for limit queries (select first ?) in Informix
-* improved SchemaExport/Update, now respect default_schema and default_catalog
-* improved dialect handling, throw an exception if no dialect has been set
-* improved loading of mappings, no ordering of super/subclasses required anymore
-* improved statistics for second-level cache
-* improved table generators for hi/lo, can now be used in a JTA environment (Emmanuel Bernard)
-* query engine: added support for 'trim([leading | trailing | both] [expression from] expression)'
-* query engine: added support for DISTINCT and ALL
-* query engine: added support for FETCH
-* query engine: added support for HAVING count()
-* query engine: added support for HQL NOT IN and EJBQL '[NOT] MEMBER OF'
-* query engine: added support for ORDER BY COUNT(*)
-* query engine: added support for collections of scalar values
-* query engine: added support for literals in constructor select expressions.
-* query engine: added support for select elements(..) from Foo f
-* query engine: added support for template functions in the SELECT clause
-* query engine: fixed NOT LIKE
-* query engine: introduced EMPTY and added it to constant (support for IS [NOT] EMPTY)
-* updated dom4j, OSCache, EHCache, JBoss Cache, Xerces, Xalan, and Log4j
-* associated class where filter now applies to <one-to-one property-ref>
-
-Changes in version 3.0 beta 1 (21.12.2004)
-------------------------------------------
-* reimplemented HQL using an ANTLR-based AST parser (Joshua Davis)
-* added class="select" id generator
-* added Query.setReadOnly()
-* added hibernate.order_updates
-* introduced cascade refresh
-* added typed JDBC exceptions (Steve Ebersole)
-* improved lifecycle for CacheProviders (Steve Ebersole)
-* added Expression.isEmpty()
-* fixed some minor mapping DTD bugs (Ben Sommerville)
-* fixed auto-commit mode for SchemaUpdate
-* added default-lazy to <hibernate-mapping>, which defaults to true!
-* added fetch="join|select" and deprecated outer-join attribute
-* fixed a bug where <custom-insert> was not used for entities with "identity" id generation
-* fixed some problems with dynamic-class
-* added property-level optimistic-lock attribute, to allow an unchecked property
-* cascade lock() now cascades with LockMode.NONE
-* fixed some bugs in filter handling (Steve Ebersole)
-* added hibernate.transaction.flush_before_completion and hibernate.transaction.auto_flush_session
-* added JSR-220 compliant create() and merge() operations
-* cascade attribute is now multi-valued, with values save-update,create,merge,delete,delete-orphan,lock,evict,replicate,all-delete-orphan
-* index and unique-key attributes may now be multi-valued
-* introduced unsaved-value="undefined", the default for "assigned" ids and <composite-id>, which forces Hibernate to hit the db
-* primitive typed <id> property mappings now default to unsaved-value="0"
-* added ScrollMode
-* added dialect for Derby (Simon Johnston)
-* added MySQLMyISAMDialect and MySQLInnoDBDialect
-* added precision and scale mapping attributes, for numeric types in DDL
-* fixed a problem with duplicate column mappings on Sybase
-* read-write cache now uses version numbers to ensure consistency with database, if available
-* native SQL queries may now fetch a collection role (Steve Ebersole)
-* added sequential-select, optional and inverse attributes to <join/>
-* added <properties> element, which can be the target of a property-ref
-* fixed a bug relating to composite property-refs
-* Hibernate now much more robust if user does not implement equals()/hashCode() on id and unique key classes
-* enabled batch deletes for versioned data
-* fixed a minor bug in Session.close()
-* removed uuid.string and renamed uuid.hex to plain uuid
-* workaround for a MySQL bug in SchemaUpdate
-* added JDBCException.getSQL() and made various improvements to exception flow
-* createSQLQuery() now fully supports components
-* fixed a bug in SQL generation for <joined-subclass> mappings
-* fixed a bug where filter and query parameters could be bound in the wrong order (Steve Ebersole)
-* fixed a problem where quantifiers could not appear in SQL fragments
-* fixed a bug with dynamic components
-* fixed a bug where Dialect default properties overrode user-specified properties (Ben Sommerville)
-* fixed a bug where duplicate column name in a joined table caused an exception
-* implemented two-phase load for dynamic components
-* fixed a bug where cancelQuery() canceled a re-pooled statement
-* deleted collections are now removed from session-level cache
-* fixed a bug in LocaleType (Steve Ebersole)
-* use "with rr" to obtain UPGRADE locks in DB2
-* package attribute now significant for extends
-* fixed a minor problem with Hibernate Clobs and Blobs
-* extends attribute does no longer require specific ordering of mapping files
-
-Changes in version 3.0 alpha (23.8.2004)
-----------------------------------------
-* package rename net.sf.hibernate -> org.hibernate
-* checked exceptions are now runtime exceptions
-* some session methods deprecated and moved to org.hibernate.classic.Session
-* removed various deprecated functionality
-* added Filter API and mappings, for temporal, regional and permissioned data (Steve Ebersole, Gavin King)
-* support cascade delete via ON DELETE CASCADE constraint
-* added extra attributes to named query definition
-* added hibernate.use_identifier_rollback
-* added subselect mappings
-* added lazy="true" to property mappings
-* added <join/> for multitable mappings
-* added <union-subclass/> for table-per-concrete-class strategy
-* added Statistics API and JMX MBean (Gavin King, Emmanuel Bernard)
-* introduced new event-driven design (Steve Ebersole)
-* support for faster startup with Configuration.addCachableFile() (Joris Verschoor, Max Andersen)
-* mask connection password for log level greater of equals to info (Joris Verschoor, Emmanuel Bernard)
-* add check of named queries when building SessionFactory (Joris Verschoor, Emmanuel Bernard)
-* added custom EntityResolver setting capability (Emmanuel Ligne, Emmanuel Bernard)
-* PropertyValueException for null values in not-null properties of components (Emmanuel Bernard)
-* enhanced support for single- and no-argument sql-functions in HQL select clause (Michael Gloegl)
-* Added catalog element, to enable table names like catalog.schema.table (Michael Gloegl)
-* Added <sql-insert>, <sql-update> and <sql-delete> support (Max Andersen)
-* Support callable statements (stored procedures/functions) via callable="true" on custom sql (Max Andersen)
-* Added support for type parameters and typedefs (Michael Gloegl)
-* Added support for JDBC escape sequences in createSQLQuery (Max Andersen)
-* Added statistics per SessionFactory (Gavin King, Emmanuel Bernard)
-* Added a StatisticsService MBean for JMX publucation (Emmanuel Bernard)
-* support for updates via rownum in Oracle
-* fixed problems with SchemaUpdate
-* support for <column formula="..."/>
-* added hibernate.use_sql_comments
-* added property-ref to collection <key/>
-* fixed performance problems with <one-to-one property-ref=.../>
-* enhanced UserType with new methods assemble()/disassemble()
-* better algorithm for batch fetch batch sizes
-* added <dynamic-class>
-* added entity-name concept, and session methods save(entityName, object), update(entityName, object), etc
-* added framework in proxy package
-* native SQL queries may now fetch a collection role
-* added <loader/> for class and collection mappings
-* added getEntity() and getEntityName() to Interceptor
-* formula-based discriminators and association mappings
-* added "guid" id generation strategy
-* various improvements to dialects
-* <discriminator force="true"/> now acts as a filter on collections
-* where filters now apply in the on clause in an outer join
-* added hibernate.jdbc.factory_class to select a custom batcher
-* session now uses entity name + id to enforce uniqueness, instead of table name + id
-
-Changes in version 2.1.6 (9.8.2004)
-------------------------------------
-* fixed Quickstart/readme.txt instructions
-* fixed DB2/400 identity column support
-* fixed the scroll() query method
-* fixed exotic classloader problems with CGLIB
-* added insert="false" for discriminator columns which are part of a composite identifier
-* added several new configuration settings to JMX HibernateService
-* added new instantiate() method to SessionFactory.getClassMetadata()
-* improved the HSQL DB dialect with features from new version
-* added hibernate.jdbc.batch_versioned_data (Steve Ebersole)
-
-Changes in version 2.1.4 (2.6.2004)
-------------------------------------
-* improved Session serialization support by adding ability to serialize unflushed sessions (Steve Ebersole)
-* fixed Session.clear() functionality to clear the internal nonExists cache (Steve Ebersole)
-* much better implementation of scroll() (Steve Ebersole)
-* support "select new ..." for iterate() and scroll() (Steve Ebersole)
-* added support for multi-parameter SQL functions (Steve Ebersole)
-* fixed hbm2ddl generating infinite indexes on MySQL (Michael Gloegl)
-* fixed alias precedence in HQL queries, function names are second (Steve Ebersole)
-* added "transactional" as allowed cache concurrency strategy in XML configuration file
-* improved System.getProperties() with security exception warning in secure environments
-* improved Proxool integration, better property handling
-* fixed problem with use of getDefinedMethod() in secure environments (Ken Arnold)
-* fixed bug in createSQLQuery() which prohibited multiple aliases for the same entity (Max Andersen)
-* fixed query cache misses when using named bind parameters (Michael Greer)
-* recognize "left" and "right as keywords in SQL fragments
-* recognize SQL quoted identifiers in SQL fragments
-* improved identity handling on SQL Server by using scope_identity() for update counts (Arthur Fitt)
-* added DB2390Dialect for DB2/390 databases (Kristoffer Dyrkorn)
-* fixed a bug in toArray() of identifier bag collections (Khachchou Mohammed)
-* fixed a problem with DDL generation for serial columns in Informix
-* fixed a problem with DDL generation for timestamp columns in Informix (Michael Schmidt)
-* fixed a NPE that occurred calling saveOrUpdateCopy() for components
-* fixed a bug with replicate() and uninitialized collections
-* fixed a bug caching one-to-one associations
-* fixed eviction from named query cache regions
-
-Changes in version 2.1.3 (25.4.2004)
------------------------------------
-* added SELECT-clause SQL function support to main Dialects
-* fixed a problem where some unnecessary selects where issued for optional one-to-one associations
-* fixed a bug in SQL generation for criteria queries with multiple one-to-many joins
-* deprecated everything related to PersistentEnum
-* fixed an NPE that occurred when using <one-to-one property-ref> with composite ids
-* fixed a problem with JCA adaptor on WebLogic (Michael Gloegl)
-* improved behavior when removing elements from <idbag>s
-* fixed a bug in getGeneratedKeys() support (Michael Gloegl, Kevin Day)
-* fixed a bug when using Criteria queries with collections of joined-subclasses
-* fixed an NPE that occurred when calling comparator() on a lazy sorted set (Attila Szegedi)
-* fixed a bug when using setMaxResults() with native SQL queries in some Dialects
-* validate that composite id classes override hashCode() (Adrien)
-* fixed some minor problems with saveOrUpdateCopy()
-* fixed some problems in OSCache provider
-* fixed an NPE that occurred when calling a lazy collection after evicting from session
-* fixed an NPE that occurred when select-before-update is used with unversioned data (Patrick Peralta)
-* fixed a bug where dynamic-components could not be queried (Massimo Ferrari)
-* SQL formula parser now recognizes all Dialect-specific SQL functions (Anthony Patricio)
-* fixed a problem where SQL CASE statements could not appear in SQL formulas
-* fixed a problem where subselects with joins could not appear in SQL formulas
-* C3P0 and Proxool pools now cleaned up after SessionFactory.close()
-* fixed a bug where dirty checking of mutable properties was broken after lock()
-* fixed a minor bug where orphan delete was broken for newly saved instances
-* added Query.setFetchSize() and Criteria.setFetchSize()
-* PreparedStatement pooling in DBCPConnectionProvider can now be disabled (Emmanuel Bernard)
-* Query.setProperties(Object) now detects array and collection valued properties and delegates to Query.setParameterList() (Max Andersen, Nick Heudecker)
-* lengths of positional parameters and types arrays are now validated
-* fixed an obscure problem where a PreparedStatement was not closed
-
-Changes in version 2.1.2 (4.2.2004)
------------------------------------
-* added Session.isDirty()
-* fixed a very obscure concurrency problem with read-write cache for inverse collections
-* deprecated Criteria.returnMaps() / Criteria.returnRootEntities() in favor of new ResultTransformer framework
-* don't cache objects with dynamic-update="true" or <joined-subclass> mappings immediately after insert/update
-* added version checking to saveOrUpdateCopy()
-* fixed constraint violations that occurred when mixing identity columns with other id generation strategies
-* added Sybase 11.9.2 dialect to support older versions of Sybase that do not support ANSI joins (Colm O' Flaherty)
-* added Informix9Dialect (Finn McCann and Max Andersen)
-* added DB2400Dialect (Peter DeGregorio)
-* fixed a problem where mapping validation failure was reported as duplicate import (Michael Gloegl)
-* fixed a problem with Expression.not() in MySQL (Michael Gloegl)
-* added support for ResultSet.getGeneratedKeys() (David Morris, John Kristian)
-* added check attribute to allow check constraints in DDL
-* implicit polymorphism for Criteria queries (Shorn Tolley)
-* use IF EXISTS for dropping hilo tables (Michael Gloegl)
-* better exception report if deleted object is resaved by cascade
-* support nested components in Example queries (Emmanuel Bernard)
-* fixed a minor problem with onDelete() callbacks
-* fixed an obscure problem with select-before-update
-* added SunONETransactionManagerLookup (Robert Davidson)
-* fixed a problem with replicate() and <joined-subclass> mappings
-* made setParameterList() accept empty lists and deny null values (Max Andersen)
-* validation check on query parameters now allows setParameter(x, null) (Max Andersen)
-* added default-access to DTD (Max Andersen)
-* made Query.setParameterList() accept empty lists and deny null values (Max Andersen)
-* allow Query.setParameter(x, null) (Max Andersen)
-* queries with "select new" now cacheable
-* throw meaningful exception when lazy initialization occurs on disconnected session
-* added default-access to <hibernate-mapping> (Max Andersen)
-* added -text support to SchemaUpdate (Max Andersen, Matt Hall)
-* fixed broken implementation of embedded composite keys with createSQLQuery() (Max Andersen)
-* added hibernate.cache.use_minimal_puts config property to reduce unnecessary second-level cache puts
-* optimized performance of orphan delete detection (Bertrand Renuart)
-* fixed problem where unnecessary UPDATE occurred after INSERT for versioned objects with collections
-* WebSphereTransactionManagerLookup for WAS 5.1 (Edina Pimp)
-* Criteria queries now cacheable (Mario Ivankovits)
-* fixed problem with ordered, paginated queries in DB2 (Tim Collins)
-* fixed a bug caching <idbag>s
-* lazy="true" collections are now lazy even when available in cache
-* fixed a problem with version unsaved-value="negative"
-* added hibernate.cache.region_prefix config property (William Drai)
-* fixed problem where configuration input streams were not closed (Rajesh Patel)
-
-Changes in version 2.1.1 (17.12.2003)
--------------------------------------
-* added optional package attribute to <hibernate-mapping>
-* added <meta-value> element to allow simpler <any> mapping
-* native SQL queries are now cacheable - added <synchronize> element to allow correct result set expiry
-* fixed a bug in CGLIB2 integration (Chris Nockleberg)
-* added NamingStrategy
-* don't cache objects with formula properties immediately after insert/update
-* log generated SQL to a special category
-* type of property with access="field" may now be guessed using reflection
-
-Changes in version 2.1 final (12.12.2003)
------------------------------------------
-* fixed a problem with CGLIB2 proxies and method calls inside constructors
-* fixed a bug running SchemaExportTask with mappings in jar files (Tom McCune)
-* allow custom persister declaration for subclasses (Nick Johnson)
-* fixed handling of sequences in SchemaUpdate on Oracle (Andrew Delpha)
-* fixed a bug where Iterator did not handle single null values correctly
-* detect and throw exception in the case of a duplicate property mapping
-* don't auto-create indexes for collection foreign keys (roll back to 2.0.x)
-
-Changes in version 2.1 rc1 (29.11.2003)
----------------------------------------
-* long identifier and discriminator column names are now safely aliased (Max Andersen)
-* cleaned up mapping package to allow applications to manipulate metamodel programmatically
-* fixed a recent bug where collection sort order was lost in second-level cache
-* formula attribute now supported for joined-subclass mappings
-* formula properties may now be used anywhere in queries
-* dialect-specific query pagination for SQL Server
-* fixed a bug where a long path expression ending in collection access by index missed some tables in SQL FROM clause
-* fixed a very ancient performance problem where null one-to-one associations caused n+1 selects
-* added Session.saveOrUpdateCopy()
-* fixed some bugs in Example queries
-* fixed some minor bugs in dialect-specific query pagination
-* immutable entity passed to update() is now lock()ed instead
-* reworked the semantics of nonstrict-read-write
-* JCS cache support now deprecated
-* fixed some obscure bugs in collection handling
-* migrated to CGLIB2 (thanks to Chris Nockleberg)
-* fixed bugs in replicate()
-* fixed a bug affecting joined-subclass mappings with dynamic-update=true
-* performance improvements to boolean type mappings (Bertrand Renuart)
-* integrated JBoss TreeCache clustered cache (thanks to Bela Ban and Ben Wang)
-* fixed a bug in new query parameter validation (Steve Ebersole)
-* fixed a bug where <any> mappings caused unnecessary ObjectDeletedException at flush time
-* fixed a bug where associations with property-ref mappings were not properly cached
-* throw PropertyValueException when not-null properties are null at flush time
-* added unsaved-value attribute to version property mapping (Emmanuel Bernard)
-* tolerate classnames containing $ (Steve Ebersole)
-
-Changes in version 2.1 beta 6 (5.11.2003)
------------------------------------------
-* added Session.cancelQuery()
-* improvements to transaction handling for failed commit (thanks to Juergen Hoeller)
-* added cascade="delete-orphan"
-* fixed an exception that occurred when a property was declared not-null="true" update="false" (thanks to John Kristian)
-* support multiple named query cache regions (Mikheil Kapanadze)
-* some improvements to collection reattachment
-* fixed a bad bug with adds to an uninitialized bag or list
-* removed support for <dynabean/> components
-* added <dynamic-component/> mapping for properties of type Map
-* fixed a bug where schema export generated index names that were too long for DB2
-* allow per-region expiry policies in OSCache (Matthias Bogaert)
-* fixed a stack overflow that could occur while initializing nonlazy collections
-* fixed a bug in case-insensitive like for Example queries
-* fixed a bug in ScrollableResults.setRowNumber() (Martin Priekopa)
-* improvements to the cache concurrency strategies
-
-Changes in version 2.1 beta 5 (30.10.2003)
-------------------------------------------
-* Support for custom CollectionPersister (Nick Johnson, Max Andersen)
-* Support for named SQL queries (Max Andersen)
-* duplicate named queries now throws MappingException instead of just logging warning (Max Andersen)
-* fixed problems with WebSphereTransactionManagerLookup (Ralf Taugerbeck, Daniel Bradby)
-* added support for custom collection persisters (thanks to Max Anderson, Nick Johnson)
-* fixed a performance problem during query compilation (Bulent Erdemir)
-* composite keys now supported in createSQLQuery() (Max Andersen)
-* fixed JCA adaptor to run in WebLogic (Daniel Bradby)
-* integrated SwarmCache (Jason Carreira)
-* integrated OSCache (Matthias Bogaert)
-* fixed an NPE that could occur with lists and orphan delete
-* allow nullable one-to-one with property-ref
-* improved usage of Dialect-specific limit SQL
-* fixed problem where non-lazy collections held by cached objects were not immediately initialized
-* fixed getReturnTypes() for native SQL queries (Max Andersen)
-* fixed problems with Criterions that applied to multi-column properties
-* check of rowcounts when JDBC batch updates enabled
-* added named SQL queries using <sql-query> element (Max Andersen)
-* added some extra validations so Hibernate fails earlier when user makes mistakes
-* allow lazy="true" as an alternative to proxy="ClassName"
-* removed dependency to commons-lang
-* SchemaExport now creates indexes for collection foreign key columns if specified by Dialect
-* fixed a bug parsing named parameters in setParameterList()
-* select new Foo(...) will now tolerate null values if the constructor accepts a wrapper type
-* fixed a problem detecting Proxool
-* added logging of persistent object states during flush()
-* allow "not null" as a discriminator value
-* added "parameters" config param to "sequence" generator (Matthias Bogaert)
-
-Changes in version 2.1 beta 4 (3.10.2003)
------------------------------------------
-* fixed a bug where <any> mappings did not handle proxies correctly
-* implemented new optimistic-lock strategies
-* fixed several bugs in Criteria query API
-* fixed a bug caching property-ref associations
-* improvements to XML Databinder (Ara Abrahamian)
-* added Session.replicate() and ReplicationMode
-* added ScrollableResults.setRowNumber() / ScrollableResults.getRowNumber()
-* added query cache and Query.setCacheable()
-* added Criteria.returnMaps()
-* fixed some problems with CGLIB proxies
-* fixed an NPE that occurred when a joined-subclass of a versioned entity defined only collections
-* added the access attribute, direct field access and the PropertyAccessor extension point
-* added MatchMode for use with Criteria queries (thanks to Michael Gloegl)
-* fixed a bug where some lazy="false" collections were not immediately initialized
-* fixed problem with WebSphere 5 TransactionManager
-* support schema attribute in MySQL, by using an underscore in the table name (Chris Hane)
-* now seperate Dialects for Interbase and Firebird (Reha Cenani, Max Andersen)
-* removed built-in PreparedStatement cache
-* added Session.getSessionFactory()
-* fixed problem with native SQL queries and Query.setProperties() (Max Andersen)
-* Query now fully validates parameters against the query string before passing them to JDBC (Max Andersen)
-* fixed an NPE in SessionFactory.close()
-* fixed an NPE that occurred when using <idbag>s
-* added SQL-level query results paging to DB2Dialect
-* "foreign" id generator now handles detached instances
-
-Changes in version 2.1 beta 3 (7.9.2003)
-----------------------------------------
-* added Example queries
-* fixed an exception that occurred at startup with <key-many-to-one> and <joined-subclass>
-* fixed a bug where composite-elements were not being updated if a property not in the equals() was changed
-* <parent> property of a composite-element may now be used in equals()
-* named parameters may now be used in HQL order by clause
-* null value of version property now indicates unsaved instance
-* added select-before-update attribute
-* two-phase loading now use for components
-* better implementation of equals()/hashCode() for proxies
-* added property-ref attribute to <many-to-one>
-* renamed result() to uniqueResult()
-* added Session.get()
-* added HashtableCacheProvider
-* JTA TransactionManager now used even when not using Hibernate Transaction API
-* always bypass process-level cache for LockMode.READ
-
-Changes in version 2.1 beta 2 (27.8.2003)
------------------------------------------
-* <subclass> and <joined-subclass> may now appear outside of a <class> element, by providing the extends attribute (Max Andersen)
-* fixed an NPE at startup that was introduced in beta 1
-* fixed a bug in Map.putAll()
-* new pluggable cache API
-- deprecated <jcs-cache> in favor of <cache>
-- net.sf.hibernate.cache.CacheProvider settable via hibernate.cache.provider_class
-* more aggressive caching
-* added Hibernate.close(Iterator)
-* Criteria queries may now include joins
-- Criteria.addJoin()
-- Criteria.createCriteria()
-* hibernate.transaction.manager_lookup_class should now ALWAYS be specified in JTA environment when using jcs caching
-* fixed a bug caching <key-many-to-one>
-* fixed bug where cached component did not get <parent> property populated
-* added hibernate.max_fetch_depth property
-* smarter outer-join fetching
-* transient object may now be associated with session using Session.lock()
-* added Query.result(), Criteria.result()
-
-Changes in version 2.1 beta 1 (10.8.2003)
------------------------------------------
-* batch-size attribute for collection and class mappings, to allow batch loading
-* collections of "value types" (including composite-elements) may now appear in HQL from clause
-* more efficient loading of collections, and better handling of non-lazy collections
-* added HQL index() function to allow access to collection element index
-* added Session.createSQLQuery() (Max Andersen)
-* added outer-join attribute to collection mappings
-* Criteria.setFetchMode() now applies to collection-valued path expressions
-* added property-ref attribute to <one-to-one>, enabling unique foreign key associations
-* added hibernate.max_fetch_depth config property
-* added hibernate.hbm2ddl.auto config property
-* fixed a bug with combination of <jcs-cache> and <key-many-to-one>
-* support for Dialect-specific SQL functions in HQL select clause (David Channon)
-* added Session.clear()
-
-Changes in version 2.0.2 (2.8.2003)
------------------------------------
-* subqueries may now use HAVING and GROUP BY clauses
-* fixed a bug with setMaxResults(), setFirstResult() in HSQL (introduced in 2.0.1)
-* fixed a bug in Set.removeAll()
-* fixed a bug in SchemaUpdate (Mathias Bogaert)
-* added weak typing functionality to ScrollableResults
-* fixed a bug with "calendar" versioning in IBM JDK1.3.1 (workaround for JDK bug)
-* fixed a bug in mapping DTD that caused a problem for hbm2java (Max Andersen)
-* fixed a bug querying nested components
-* SQL generation now prefers ANSI-style inner joins to theta inner joins
-* fixed a bug caching collection references loaded using FETCH
-* fixed a bug with composite foreign keys in normalized table mappings (Tom Sedge)
-* limit support for Interbase (Ludovic Orban)
-* added where attribute to <class> mappings
-* added cascade="all-delete-orphan" for collection mappings
-* fixed a bug binding named parameters with setMaxResults()/setFirstResults()
-* fixed some minor bugs in HQL translator
-* fixed a long-standing bug where a <key-many-to-one> could not be dereferenced in HQL
-* SQL UPDATEs now occur in a predictable order (same order as objects were loaded)
-* support for SELECT ... FOR UPDATE in SAPDB
-* fixed bug where Criteria queries against a subclass also returned superclass instances
-* fixed a very rare bug where an update could get lost with normalized mappings
-* fixed a problem with proxied class heirarchies rooted at an interface or abstract class
-* where and order-by attributes now allow SQL function calls and subselects
-* added formula attribute to <property> tag, to allow "computed" properties
-* fixed a bug where PreparedStatements were sometimes not closed when an exception occured
-* workaround for a problem with <joined-subclass> and Interceptor.onFlushDirty()
-
-Changes in version 2.0.1 (17.6.2003)
-------------------------------------
-* fixed some problems with new dialect-specific LIMIT clauses
-* improved parsing of collection where attribute
-* made one-to-many bags more efficient (they are really sets!)
-* allowed type="calendar" for <version> properties
-* fixed a bug with locking a versioned composite-id class
-* refresh() may now take a transient instance
-* added ProxoolConnectionProvider (Martin Crawford)
-* fixed some minor JCA issues (Mike Mosiewicz)
-* fixed a bug with FETCH and sorted associations
-* improved performance of SchemaUpdate tool (Teodor Danciu)
-* fixed a bug in Configuration.addFile(String) (Ken Geis)
-* tidied up and documented hbm2ddl package (esp. Ant tasks)
-* deprecated CounterGenerator in favor of IncrementGenerator
-* improved logging during initialization
-* deprecated "vm" in favor of "increment" id generator
-
-Changes in version 2.0 final (8.6.2003)
----------------------------------------
-* added "fetch" keyword to HQL
-* added evict() methods to SessionFactory for JVM-level cache
-* destroy caches from SessionFactory.close()
-* fixed an NPE in Session.evict() (Simon Spero)
-* added Query.setLockMode()
-* tidied up implementation of Loader
-* release ResultSets more aggressively
-* miscellaneous improvements to some Dialects
-* hbm2java now honors the sort attribute (Max Andersen)
-* added exceptions to Interceptor interface
-* fixed problem with setMaxResults(), setFirstResult() in Oracle (introduced in beta 6)
-* fixed some SQL generation that was a problem for Sybase (Dietmar Posselt)
-* fixed some problems with ODMG API (Oliver Gries)
-* added JOTMTransactionManagerLookup (Low Heng Sin)
-* added JOnASTransactionManagerLookup (?)
-* fixed a bug in WeblogicTransactionManagerLookup (Mathias Bogaert)
-* added Criteria.setFetchMode()
-* added new Expressions
-* much more elegant/robust handling of quoted identifiers
-* renamed Hibernate.association() to Hibernate.entity()
-* added dynamic-update and dynamic-insert mapping attributes
-* fixed a bug with refresh() of objects with collections
-* HQL aliases now optional - "from Cat" now legal
-* platform-independant quoting of identifiers using backticks
-
-Changes in version 2.0 beta 6 (10.5.2003)
------------------------------------------
-* fixed a bug querying one-to-many associations to a <joined-subclass>
-* added support for dialect-specific LIMIT-style clauses (David White)
-* added <idbag>
-* fixed bug in hashCode() of persistent collections
-* <joined-subclass> now supported in HSQL (Wolfgang Jung)
-* fixed problem for XML parsers which ignore default values declared in DTD
-* <meta> tags can now be set to not be inheritable
-* fixed bug in Expression.in()
-* fixed an NPE that could occur from update() in very strange cases (Chris Nockleberg)
-* disabled outer-join back to owner when initializing one-to-many (performance improvement)
-* fixed a bug in Query.setParameterList() (Nick Heudecker)
-* improved JCA support (Igor Fedorenko)
-
-Changes in version 2.0 beta 5 (21.4.2003)
------------------------------------------
-* Informix support (Steve Molitor)
-* fixed a bug parsing "select new ... " queries
-* deprecated "object" type in favor of <any> mappings
-* added Session.contains()
-* added extra DBCP config options (Alex Burgel)
-* SessionFactory.close() now unbinds from JNDI
-* added Session.evict()
-* got rid of an unnecessary SQL DELETE issued when an empty collection was dereferenced
-* where attribute of collection mappings no longer ignored for deletion
-* improved logging
-* support polymorphic associations to "embedded" composite id classes
-* various bugfixes to collection filter parameter binding
-* fixed some problems with proxies introduced in earlier beta versions
-* fixed bug with self-reference in the case of identity column id generation
-* added hibernate.cglib.use_reflection_optimizer property
-* added nonstrict-read-write cache
-* fixed an SQL-generation bug in new Criteria API
-* added CompositeUserType
-* sequence and table id generators now aware of default-schema
-* added update and insert attributes to <component> element
-* fixed a bug with expressions like elements(foo.bar.baz) in where clause
-* more efficient Set initialization (two-phase load)
-* removed support for hibernate.query.imports and added <import> mapping element
-* fixed problem in DBCP connection validation and added new config properties
-* hbm2java can now generate finder methods for persistent objects (experimental) (Matt Hall)
-* hbm2java small fixes/refactorings to support generating more than one file per persistent object (Max Andersen)
-
-Changes in version 2.0 beta 4 (22.3.2003)
------------------------------------------
-* Major HQL improvements
-- from "Foo as foo join foo.bars as bar" instead of "from foo in class Foo, bar in elements(foo.bars)"
-- "select new Foo(bar.name, bar.amount) from ...."
-- outer and full join support
-* Query methods now return this, to allow chaining
-* FrontBase support (Run Lussier)
-* experimental JCA support (Daniel Bradby)
-* hbm2java now can generate Beans style property events (Klaus Zimmermann)
-* support SQL identifiers quoted with []
-* fixed bug with PostgreSQL
-* name attribute now optional in .cfg.xml
-* support for postgres ilike operator (M Lang)
-* squash warnings with GNU JAXP (Chris Nockleberg)
-* fixed a bug in Query.setParameterList()
-* Ingres support (Ian Booth)
-* collections now detect changes not made via wrapper for newly saved objects
-* new (experimental) Criteria + Expression APIs
-* Query.setEntity(), etc, now aware of proxies (also improved hueristics for guessing Type)
-* added Hibernate.isInitialized()
-* detect changes made directly to newly-wrapped collection (ie. not via the wrapper)
-* added Hibernate.refresh(Object, LockMode)
-* update(), saveOrUpdate() no longer initialize a proxy
-* fixed problems with Sybase
-* added force attribute to <discriminator>
-* improved handling of null discriminator-value
-* support SQL-style '' escape for HQL strings
-
-Changes in version 2.0 beta 3 (24.2.2003)
-----------------------------------------
-* collections now represent null elements as a missing row
-* collections now deserialize correctly (fix for bug in beta 2)
-* standardised on dom4j for XML parsing
-* fixed bugs in collection caching (an exception occurred for some sorted collections and some kinds of maps)
-* allowed null discriminators
-* set autocommit to true in SchemaUpdate
-* fixed a stack overflow that could occur in toString() of classes created with hbm2java (Max Andersen)
-* fixed a bug where composite-element <parent> property was not being set after retrieval from cache
-* added where attribute to collection mappings to allow filtering
-* fixed a exception that occurred when wrapping collections with sort="MyComparator" (Jason Horne)
-* objects with mutable="false" are now never updated
-* fixed an exception that occurs with <key-many-to-one> association to a class with a composite id (Stefano Travelli)
-* added SchemaExport Ant task (Rong C Ou)
-* integrated latest CGLIB release (Juozas Baliuka)
-- added support for new CGLIB reflection optimizer (Juozas Baliuka)
-* improved query cache algorithm (Who?)
-* fixed a bug in "object" type
-* Lists and arrays now represent null elements as a missing row
-* fixed a bug in Hibernate PreparedStatement cache where maxRows and fetchSize were not cleared before re-caching
-* fixed a bug in HibernateService that caused a restart to fail
-* added SybaseAnywhereDialect (?)
-* added SessionFactory.close()
-
-Changes in version 2.0 beta 2 (2.2.2003)
-----------------------------------------
-* property column names may now be of any length (Mark Woon)
-* fixed problem where CodeGenerator created private get/set pairs (Max Andersen)
-* fixed all silly bugs in Configuration.configure()
-* efficient collection updates from Session.update()
-* added <jcs-class-cache> and <jcs-collection-cache> elements to hibernate-configuration.dtd
-* support for normalized mappings for databases with DECODE instead of CASE (Simon Harris)
-* added Oracle9Dialect
-* added JRun4TransactionManagerLookup (Joseph Bissen)
-* fixed JDBCException to keep reference to underlying SQLException
-* fixed a bug loading many-to-many associations with a repeated column name
-* fixed a bug in ShortType
-* added IngresDialect (Ian Booth)
-* added --config option to SchemaExport
-
-Changed in version 2.0 beta 1 (28.1.2003)
------------------------------------------
-* renamed packages to net.sf.hibernate.*
-* all API methods now wrap SQLExceptions
-* removed support for toplevel collections / subcollections
-* created hibernate-mapping-2.0.dtd
-- renamed 'readonly' attribute to 'inverse'
-- renamed 'role' attribute to 'name'
-- changed default value for 'unsaved-value' to "null"
-- added mandatory 'name' attribute to <param>
-- added <meta> tag
-* created hibernate-configuration-2.0.dtd
-* brand new Configuration API, including exposed mapping package
-* completely reworked IdentifierGenerator framework
-- built-in generators now auto-detect the type (so integer identity columns are supported, for example)
-- parameters are now named
-- built-in strategies are renamed
-* expanded Interceptor interface
-* removed exceptions that occur if an object is saved or deleted multiple times in a session
-* added <parent> subelement to <composite-element> and <nested-composite-element>
-* collections except for <bag>s now implement by-value equals() and hashCode()
-* removed all deprecated methods
-* added Session.refresh()
-* added dynamic-update functionality
-* added update and insert attributes to <property> and <many-to-one> mappings
-* added elements(), indices(), size(), maxelement(), minelement(), maxindex(), minindex() collection functions to query language
-* huge improvements to CodeGenerator (Max Andersen)
-* enhanced outerjoin fetching support in queries
-* experimental support for DynaBeans as components
-
-Changes in version 1.2.3 (28.1.2003)
-------------------------------------
-* fixed a recently-introduced problem with Timestamp dirty checking
-* added createClob(), createBlob() for streams (Benoit Menendez)
-* SchemaUpdate now configures Dialect correctly (Michael Locher)
-* update() now working for classes with embedded composite ids
-* unsaved-value attribute now recognized for <composite-id>
-* fixed a minor problem where a very specific kind of SQL select did not qualify a column name
-* added Query.getQueryString()
-* fixed an NPE that sometimes occurred when hibernate.connection.username was not specified
-* fixed a bug in SchemaExport where foreign key constraints did not use qualified tablenames
-* added isFirst(), isLast() to ScrollableResults
-* fixed bug finding properties inherited by mapped interfaces
-
-Changes in version 1.2.1b (4.1.2003)
-------------------------------------
-* fixed an NPE that occurred while loading Hibernate classes in IBM JVM
-* arbitrary JNDI InitialContext properties may now be passed as hibernate.jndi.*
-* fixed a problem where index column was not being nullified when an entity was removed from a one-to-many
-
-Changes in version 1.2.1 (31.12.2002)
--------------------------------------
-* Changed the MySQL mapping of Hibernate "timestamp" to MySQL "DATETIME" (Matthias Schwinn)
-* TransactionManagerLookup classes now define defaut UserTransaction JNDI names
-* support for WebSphere 5 (Venkat Srinivasan)
-* fixed a bug with query expressions of the form "foo.bar.id" for normalized mappings
-* experimental Blob/Clob support (thanks to Benoit Menendez and Mark Woon)
-* improvements to SchemaUpdater (Benoit Menendez)
-* deprecated suspendFlushes() / resumeFlushes() in favor of FlushMode
-* deprecated IDGenerationException in favor of IdentifierGenerationException
-* fixed a bug introduced in 1.2 final where cascade save-update was sometimes ignored for readonly="true" bags
-* fixed a bug caching null-valued one-to-one associations
-* CodeGenerator now supports <bag> and <joined-subclass>
-* fixed problem with TimestampType on DB2 (Jonas)
-* fixed a bug in generated SQL for collections with <joined-subclass> mappings (Robson Miranda)
-* fixed a bug caching Maps (Benoit Menendez)
-* SchemaExport now accepts a .jar file as a source of mappings
-* hibernate.dbcp.validationQuery setting (Juozas Baliuka)
-* hibernate.c3p0.validate setting
-* added Query.setTimeout()
-* setMaxResults() now behaves sensibly on SAPDB (Russel Smyth)
-* added Query.setProperties() and Query.getNamedParameters(), fixed a bug in Query.getReturnTypes()
-* CodeGenerator now generates equals() and hashCode() for composite-id classes (and toString() for all classes)
-* CodeGenerator now includes superclass properties in subclass constructors (Max Andersen)
-* added Hibernate.custom()
-
-Changes in version 1.2 final (7.12.2002)
-----------------------------------------
-* fixed a bug where uppercase IS NOT NULL, NOT IN, etc were not parsed correctly
-* addition to readonly="true" bags now no longer requires collection initialization
-* added ResinTransactionManagerLookup (Aapo Laakkonen)
-* improved exception message when setting null to primitive type (Max Andersen)
-* improved exception message for an unserializable identifier
-* support for overloaded setter methods (patch by Alex Staubo)
-* CodeGenerator support for <composite-element> (patch by Wolfgang Jung)
-
-Changes in version 1.2 beta 4 (29.11.2002)
-------------------------------------------
-* fixed bugs in one-to-many associations to a <joined-subclass>
-* LockMode class now properly serializable
-* exceptions thrown by proxied objects are now propagated correctly (rather than being wrapped)
-* made Calendar types compilable in JDK1.2
-* added --format and --delimiter options to SchemaExport (thanks to Richard Mixon)
-* fix for problem with class with no properties + native id generation + MS SQL Server contributed by Max Andersen
-* fixed a BAD bug in Hibernate.configure() (thanks to Rob Stokes)
-* CodeGenerator now recognizes <key-many-to-one> (patch by Wolfgang Jung)
-* CodeGenerator now recognizes <version> and <timestamp> (patch by Max Andersen)
-
-Changes in version 1.2 beta 3 (26.11.2002)
-------------------------------------------
-* fixed bug in UPDATE SQL generation for <joined-subclass> mapping strategy (fix by Robson Miranda)
-* support <composite-id> correctly in CodeGenerator (patch by Tom Cellucci)
-* fixed an exception that occurred with short qualified tablenames
-* added the polymorphism attribute to the <class> element
-* allow "not between", "not in" in query language
-* allow subqueries beginning with a from clause in query language
-* query expressions like "not (foo.bar.baz=1)" now translated to "(bar.baz!=1 and foo.bar=bar.id)"
-* support for PostgreSQL ~ operator (regular expression match)
-* load(id, lockMode) now working for normalized table mappings
-* now compiling properly under JDK1.2, 1.3 (fix by Tom Cellucci)
-* support for subcollections in query language: foo.bars[2]['index'], foo.bars[4].elements, foo.bars[0].size, etc.
-* added calendar and calendar_date types
-* find() queries may now return scalar values
-* component-type properties may appear in a select clause
-* ConnectionProviders now set isolation level before toggle autocommit
-* Iterator.next() now throws NoSuchElementException as per Iterator contract (fix by Alex Staubo)
-* database reverse engineering GUI tool contributed by Tom Cellucci
-* SchemaExport now generates column in mapping file order (rather than alphabetical order)
-* <joined-subclass> mappings working on Oracle (?)
-
-Changes in version 1.2 beta 2 (15.11.2002)
-------------------------------------------
-* support multi-argument SQL functions in queries
-* reintroduced deprecated form of update() with slightly altered semantics
-* fixed BAD problem in the generated SQL for certain queries
-* added OrionTransactionManagerLookup
-
-Changes in version 1.2 beta 1 (11.11.2002)
-------------------------------------------
-* Fixed a bad bug binding to JNDI with servers that use serialization in preference to getReference()
-* support for quoted SQL identifiers (patch by Jean-Francois Nadeau)
-* Hibernate.initialize() allows the user to force initialization of a proxy or persistent collection
-* fix to minor bug in CodeGenerator by Max Andersen
-* fixed a problem with outerjoin fetching of one-to-one associations defined on subclasses
-* fixed a minor problem with proxies of classes that override finalize()
-* finished work on normalized table mappings using <joined-subclass> declaration (only for databases with ANSI OUTER JOIN and CASE)
-* deprecated hibernate-mapping.dtd in favor of hibernate-mapping-1.1.dtd
-* reworked unmapped class / interface / table-per-concrete-class query functionality, fixing several problems
-* removed deprecated methods
-* deprecated findIdentifiers()
-* fixed some problems with embedded composite identifiers
-* fixed a bug cascading deletes to one-to-one associations
-* CodeGenerator now generates isFoo() style getters for boolean properties (patch by Aapo Laakkonen)
-* components may now have a nonpublic constructor (patch by Jon Lipsky)
-* changes / bugfixes to MapGenerator tool
-* experimental SchemaUpdate tool contributed by Christoph Sturm
-
-Changes in version 1.1.8 (30.10.2002)
--------------------------------------
-* full support for composite keys in query language
-* fixed bug where character type could not be null
-* fixed bug parsing collection filters like: "group by this.date"
-* fixed a bad bug where C3P0 properties were not always being used
-* replaced hibernate.use_jdbc_batch with hibernate.jdbc.batch_size
-* renamed some other properties to hibernate.jdbc.*
-* made hibernate.show_sql settable from JMX (patch by Matas Veitas)
-* added SessionFactory.getAllClassMetadata(), getAllCollectionMetadata (patch by Max Andersen)
-* allowed use of concrete-class proxies with inherited classes ie. <subclass name="ConcreteClass" proxy="ConcreteClass">
-* HibernateException extends Apache commons lang NestableException (patch by Max Andersen)
-* <parent> subelement of <component> allows a component to get a reference back to owning entity
-* Query.setParameterList() to bind lists of values to "in (:list)"
-* Java constants may now be used in Queries
-* serialization of an object graph now removes all initialized proxies
-* several other improvements to proxy handling
-* proxies may now be used in JDK 1.2
-
-Changes in version 1.1.7 (25.10.2002)
--------------------------------------
-* added Session.createFilter() 
-* fixed a bug parsing queries with properties of form idXXX (introduced in 1.1.6)
-* fixed a bug parsing queries with the id property named in the select clause (introduced in 1.1.6)
-* fixed a bug dirty checking big_decimal (fix by Andrea Aime)
-
-Changes in version 1.1.6 (24.10.2002)
--------------------------------------
-* classes without subclasses may now declare themselves as their own proxy
-* outer-join attribute now working for component properties and <many-to-many>
-* outer-join="true" will now force outerjoin loading for an association even if associated class has a proxy
-* enabled oracle-style outerjoins for SAP DB
-* version properties may now be long or short (previously always integer)
-* discriminators may now be boolean type
-* fixed the foo.bar.id.baz syntax for queries doing composite-key joins
-* fixed an NPE that occurred when no Dialect was specified
-* CodeGenerator now fully proxy-aware (patch by Max Andersen)
-* removed dependency upon trove4j
-
-Changes in version 1.1.5b (20.10.2002)
---------------------------------------
-* fixed an NPE that occurred on JMX startup
-* smarter fetching for one-to-one associations
-
-Changes in version 1.1.5 (19.10.2002)
--------------------------------------
-* added built-in currency and timezone types
-* hibernate-mapping-1.1.dtd
-- added <index-many-to-many> and <composite-index> subelements of <map>
-- added <key-property> and <key-many-to-one>
-- renamed "save/update" to "save-update"
-- tightened up the dtd (now using enumerated attribute types)
-* enabled multi-column map indexes (ie. key of a Map)
-* composited-id may now include a many-to-one association
-* improvements to Databinder contributed by Brad Clow
-* fixed bugs in minIndex, maxIndex, minElement, maxElement
-* fixed a problem with JTATransaction in a JBoss BMT bean
-* added addMapResource() to the MBean
-* minor improvements to Configuration
-* more accurate cache entry timestamping to increase the likelihood of cache hits
-* JCS cache may now be used with JTATransaction in WebSphere, Weblogic, JBoss (thanks to Matt Baird)
-* improvements to CodeGenerator contributed by Andrea Aime
-* stopped a TransientObjectException that was being thrown when it shouldn't be
-* re-enabled primary key export for tables of sets with not-null elements
-* hibernate.statement.fetch_size configuration contributed by Matas Veitas
-* added Interceptor application callback interface
-* added metadata package to expose persistence metadata to the application
-* changed filter() argument type from Collection to Object to allow filtering of arrays and Maps
-* added <column> index attribute to allow table indexes to be specified in mapping document
-* implemented support for queries against interfaces and abstract superclasses
-
-Changes in version 1.1.4b (4.10.2002)
--------------------------------------
-* fixed problems for JDK1.2 (thanks to Chris Webb)
-
-Changes in version 1.1.4 (4.10.2002)
-------------------------------------
-* New locking API
-* disabled 2-phase load for objects contained in Sets (because they should be initialized before equals() or hashCode() is called)
-* fixed a bug where non-serializable cache entries could not be cached by JCS auxiliary cache
-* fixed a bug in dirty checking PersistentEnums
-* deprecated getID() in favor of getIdentifier() (for mainly cosmetic reasons)
-* HibernateService may now be subclassed to obtain mapping files by some other mechanism (patch by Chris Winters)
-
-Changes in version 1.1.3 (1.10.2002)
-------------------------------------
-* new 2-phase loading process (replaces complicated "deferred" loading process)
-* new ScrollableResults interface for efficiently navigating Query results
-* removed deprecated interfaces
-* created engine package to hold "internal" APIs (ie. the external contract of the impl package)
-* fixed bug where a component defined before all collections in the mapping file caused collections to not be persisted (thanks to Michael Link)
-* fixed a bug where cascaded saveOrUpdate was ignoring the unsaved-value setting
-* faster Timestamp dirty checking
-
-Changes in version 1.1.2 (29.9.2002)
-------------------------------------
-* added persister attibute of class mapping to support custom persistence strategies
-* Support for Oracle outerjoins contributed by Jon Lipsky
-* Reworked versioning, fixing bugs (and tightening tests)
-* Fixed a bug where an ObjectNotFoundException was thrown for null one-to-one associations
-* fixed problems with timestamps introduced in 1.1.1
-* added batch file for running demo
-
-Changes in version 1.1.1 (27.9.2002)
-------------------------------------
-* Major refactoring / abstraction of persistence logic
-* added maxIndex, minIndex, maxElement, minElement properties for collections
-* added support for class names in where clause of queries
-* fixed a bug where an association could become null after caching
-* fixed a bug where an NPE could occur for a null component
-* fixed minor bugs in SortedMap, SortedSet
-* object type is now cacheable
-* added big_integer type
-* improved dirty checking for timestamp type
-
-Changes in version 1.1.0 (22.9.2002)
-------------------------------------
-* implemented collection indexing with [] in query language
-* fixed some minor query-language bugs
-
-Changes in version 1.1 beta 14 (19.9.2002)
-------------------------------------------
-* bags now implement java.util.List
-* delete() may now take a transient object
-* bug where sorted collections were not being sorted fixed by Brad Clow
-* fixed a bug in many-to-many association filtering
-* no longer try to query connection metadata when using user-supplied connections
-* added hibernate.use_scrollable_resultsets for user-supplied connections
-* fixed a problem where sublists were not being proxied
-* fixed a problem where Hibernate could not call methods of package-visibility classes
-* removed obsolete select attribute from MapGenerator
-* multiple occurrences of same path in a query no longer require multiple joins
-* added WrongClassException
-
-Changes in version 1.1 beta 13 (15.9.2002)
-------------------------------------------
-* added constants to Lifecycle interface
-* fix for circular cascade="save/update"
-* fixed a bug in cascaded update introduced in version 1.1 beta 11
-* added object type
-
-Changes in version 1.1 beta 12 (14.9.2002)
-------------------------------------------
-* Session.filter() for applying a filter query to collections
-* experimental ODMG API (OQL features are not yet compliant)
-* new DBCPConnectionProvider for Apache commons-dbcp connection pool
-* Session.lock() now does version number check even on databases with no FOR UPDATE clause
-* introduced new cascade styles: cascade="save/update", cascade="delete"
-* added default-cascade attribute
-* foreign key columns lengths now automatically set to primary key column lengths for SchemaExport
-* added error checking of row update counts when batching disabled
-* major improvements to ProxyGenerator tool
-* CodeGenerator now aware of proxy attribute
-* integrated PointbaseDialect contributed by Ed Mackenzie
-* fix for problem where Proxies were being initialized on identifier access by Christoph Sturm
-
-Changes in version 1.1 beta 11 (7.9.2002)
------------------------------------------
-* deprecated update() in favor of saveOrUpdate() and introduced unsaved-value attribute of <id>
-* children mapped with cascade="all" are now always saved/updated even without a call to update(parent)
-* support for composite-id classes where the composite id consists of properties of the persistent class
-* added constrained attribute to <one-to-one> element
-* added Validatable interface
-* renamed several config properties (Hibernate issues log warnings for obsolete property usage)
-* arbitrary JDBC connection properties may now be passed using hibernate.connection.*
-* fixed a classloading bug in C3P0ConnectionProvider (introduced in 1.1 beta 10)
-* CodeGenerator may now take multiple mapping files on the commandline
-
-Changes in version 1.1 beta 10 (28.8.2002)
-------------------------------------------
-* fixed a bug that occurred when calling Session.update() for an object with no properties
-* changed class loading to use the context classloader first
-* introduced <timestamp> as an alternative to <version>
-* added Query.getReturnTypes()
-* fixed a bug with composite-elements introduced in 1.1 beta 7
-* save() may now be used to persist classes with composite-ids
-* improved handling of nanoseconds values in Timestamps
-* support for composite id properties + objects in select clause of iterate()
-* beefed-up collection tests
-
-Changes in version 1.1 beta 9 (26.8.2002)
------------------------------------------
-* fixed a bug introduced in 1.1 beta 8 that could cause an NPE after deserializing a session with proxies
-* deprecated insert() in favor of more flexible save()
-* deprecated IDGenerator in favor of new IdentifierGenerator interface
-* "assigned" id generator now returns the existing value of the id property instead of throwing an Exception
-* fixed a problem where PreparedStatements were not being recached after retrieving a natively generated id
-
-Changes in version 1.1 beta 8 (25.8.2002)
------------------------------------------
-* fixed a bug introduced in 1.1 beta 6 where an updated element of an indexed one-to-many collection caused an SQLException
-* uninitialized collections passed to update() may now be initialized in the new Session
-* uninitialized proxies passed to update() may now be initialized in the new Session
-
-Changes in version 1.1 beta 7 (23.8.2002)
------------------------------------------
-* fixed a bug where Hibernate was not returning statements to the cache when batch updates were disabled
-* fixed a bad bug parsing mappings with toplevel one-to-many associations
-* fixed a bug with versioning and subcollections
-* reworked Set updates again for much improved efficiency
-* schema export now creates primary keys for indexed collection tables
-* minor refactor to Type hierarchy
-* improved some user-error detection
-* fixed foreign key constraint creation for MySQL with Innodb tables
-
-Changes in version 1.1 beta 6b (20.8.2002)
-------------------------------------------
-* Fixed a problem updating Sets
-* added <bag> mapping for java.util.Collection
-
-Changes in version 1.1 beta 6 (20.8.2002)
------------------------------------------
-* completely reworked fetching code
-- one-to-many associations now always fetched in a single select
-- many-to-many associations fetched in a single select when outerjoin fetching is enabled 
-- this includes nested outerjoin fetching of the associated class!
-- outerjoin fetching for <many-to-one> nested inside <component> or <composite-element>
-- code refactored to be cleaner and faster
-* removed unnecessary order by clause in List and array fetching SQL
-* collections now individually update, insert and delete only rows that changed (thanks to Doug Currie)
-* fixed a problem where exceptions were being wrapped in a LazyInitializationException for non-lazy collections
-* added order-by attribute to <set> and <map> to specify a table column as defining the iteration order (JDK1.4 only)
-* improved error detection in Session.update()
-* further usage of JDBC2 batch updates
-* some fine-tuning of JDBC2 feature usage configuration
-* CodeGenerator will now generate components and arrays
-* fixed problem where CodeGenerator could not generate classes in the default package
-* improved logging of flush() activity
-* renamed property hibernate.use_jdbc2 to hibernate.use_jdbc_batch
-
-Changes in version 1.1 beta 5 (13.8.2002)
------------------------------------------
-* hibernate.query.imports property to allow use of unqualified classnames in queries
-* fixed a bug in collection flushing that was introduced in 1.1 beta 4
-
-Changes in version 1.1 beta 4 (11.8.2002)
------------------------------------------
-* JMX integration (thanks to John Urberg)
-* "having" clause in query language
-
-Changes in version 1.1 beta 3 (10.8.2002)
------------------------------------------
-* removed the select="all" attribute for <class> mappings - "select distinct" now specified in the hibernate query
-* system properties now override hibernate.properties
-* Session now flushes changes even less often (only when actual updates to the queried table(s) are waiting)
-* fixed a *very* rare problem where an unnecessary update could be accidently issued before a delete
-
-Changes in version 1.1 beta 2 (6.8.2002)
-----------------------------------------
-* fixed a bug exporting schemas with identity columns
-* implemented factory-level caching of collections
-* Datastore.storeJar() contributed by Christian Meunier
-* added <mapping jar="jarfile"> to hibernate.cfg.xml
-
-Changes in version 1.1 beta 1 (4.8.2002)
-----------------------------------------
-* new Query API including named parameters, pageable results
-* subqueries in Hibernate queries (only for databases that support subselects)
-* new DocBook documentation (contributed by Christian Bauer)
-* support collections .elements, .indices inside select clause (even in aggregate functions)
-* don't load collections before removal unless absolutely necessary
-* mutable="false" attribute in <class> element to map immutable classes
-* use JDBC batch to insert collection elements if hibernate.use_jdbc2 is set
-* brand new PreparedStatementCache
-* improvements to MYSQL dialect for long datatypes
-* always check isAccessible() before setAccessible(true)
-* removed extra unnecessary table join in queries with one-to-many association
-* removed ugly "WHERE 1=1" from generated SQL
-* fixed exception mapping a class with no properties (fix by Rob Stokes)
-* logging enhancements including SQLException logging
-* reworked factory-level cache and integrated JCS support (thanks to Christian Meunier)
-* fixed a bug with circular references in cached data
-* removed blocking cache support
-* now rendering outerjoins as "LEFT OUTER JOIN" because "LEFT JOIN" caused problems for some Sybase versions
-* added default Hibernate properties to Dialects
-* native id generation now falls back to sequence id generation when identity columns not supported by the dialect
-* fixed some problems with native id generation under HSQL
-* may now use Session.insert() even when using native id generation
-
-Changes in version 1.0.1b (18.7.2002)
--------------------------------------
-* fixed a bad bug in query parser when hibernate.query.substitutions was unset
-* much improved build.xml Ant script
-* latest c3p0.jar
-
-Changes in version 1.0.1 (17.7.2002)
-------------------------------------
-* enabled use of scalar values and aggregate SQL functions in select clause of iterate() queries
-* fixed bug in JNDI lookup for SessionFactory
-* changed ordering of SQL inserts/deletes for child collections of a cascade-enabled association 
-- better behaviour for some not-null constraints
-- performance optimization for bidirectional many-to-one associations
-* added hibernate.query.substitutions property to allow named query constants (eg. translate 'true' to '1')
-* added locale type for java.util.Locale
-* added sequence hi/lo generator (seqhilo.long)
-* fixed bug where load(), onLoad() callbacks were sometimes called at wrong time
-* fixed an exception (fix by Eric Everman) and improved identifier searching in MapGenerator tool 
-* refactored SerializableType
-* extra logging + error handling
-* documentation enhancements
-
-Changes in version 0.9.17 (3.7.2002)
-------------------------------------
-* Added UserType interface
-* documented Lifecycle
-* added some new trace messages to log
-* bugfix to allow SQL functions like upper(), lower(), etc to work on all platforms
-* documented SAP DB support (dialect contributed by Brad Clow)
-* foreign key constraint export for SAP DB
-* map index may be the composite-id of the element class (contributed by Jon Lipsky)
-* fixes to CodeGenerator tool (contributed by Uros Jurglic)
-
-Changes in version 0.9.16 (19.6.2002)
-------------------------------------
-* fixed bug cacheing objects with references to themselves
-* support for composite ids of classes with no id property
-* may now disable outer join (deep) fetching for an association by setting outer-join="false"
-* enabled outer join fetching for one-to-one
-* fixed a bug for mappings that specify class attribute of <one-to-many>
-* fixed a bug where Hashbelt did not expire cached data in a timely fashion
-* fixed a mistake in the mapping DTD
-* new user-error check in update()
-
-Changes in version 0.9.15 (15.6.2002)
-------------------------------------
-* one-to-one associations
-* support for "tricky" mappings in SchemaExport tool (multiple properties to one column, etc)
-* Transaction API contributed by Anton van Straaten
-* SessionFactory may be bound to JNDI name by setting hibernate.session_factory_name
-* Sessions are now Serializable!
-* added Session.findIdentifiers() query methods
-* new Lifecycle interface to replace deprecated PersistentLifecycle
-* fixed problem where session did not autoflush on iterate() queries
-* performance enhancements to collection dirty checking
-* added Hibernate.configure() and configuration file format
-* removed some deprecated methods
-* refactored Type hierarchy
-* query language identifiers now case sensitive (bugfix for case sensitive SQL dialects)
-* username/password now optional for datasource (contributed by Emmanuel Bourg)
-* much improved API documentation
-* binary types now saved using streams if hibernate.use_streams_for_binary=true (contributed by Jon Lipsky)
-* MySQL Strings now mapped to TEXT columns if length > 255 (contributed by Christoph Beck)
-
-Changes in version 0.9.14 (4.6.2002)
--------------------------------------
-* lifecycle objects - properties now have a cascade attribute to cascade save, update, delete
-* composite id properties may now be used in queries eg. foo.id.bar (contributed by Jon Lipsky)
-* slightly changed semantics of update() so it now also save()s new transient instances
-* Session now flushes() itself less often before query execution (performance enhancement)
-* fixed problem where Session.save() returned null instead of the natively generated id
-* fixed bug with object identity for cached classes
-* fixed bug where delete(x) could not be called after update(x)
-* MUCH improved Exception hierarchy
-* deprecated create()
-* added sql-type attribute to <column> tag to allow user to override default type mapping
-* deeper fetching with use_outer_join
-* new ConnectionProvider framework
-* fixed a bug where blocking cache could return stale data
-* now working again in JDK1.2.2
-* fixed problem with not-null associations + native key generation
-* minor changes to PersistentLifecycle interface
-* initial, minimal version of new Transaction mechanism
-* MUCH improved documentation
-
-Changes in version 0.9.13 (25.5.2002)
--------------------------------------
-* Datastore.storeResource() to load mapping files from classpath
-* fixed a problem executing under JDK1.3 when compiled from JDK1.4
-* documentation improvements
-
-Changes in version 0.9.12 (24.5.2002)
-------------------------------------
-* Session.update() methods to update a persistent instance from transient copy (as requested by many users)
-* discriminator column name, type, length, etc now configurable by <discriminator> tag in mapping file
-* discriminator column values configurable by discriminator-value attribute of <class> and <subclass> tags
-* added Session.insert(object, id) for classes with no identifier property
-* fixed another bad bug with connection handling (fix by Anton van Straaten)
-* fixed a problem with deferred loading
-* fixed a problem with sorted collections (fix by Anton van Straaten)
-* nested collections of objects now require 2 SQL SELECTs to load, rather than size+1
-* session is NO LONGER atomic - application should discard session when exception occurs
-* fixed problem where character type was mapped to VARCHAR column
-* arrays of proxies now possible by using new element-class attribute of <array> tag
-* fixed various problems with proxies
-* added proxy generation tool
-* proxy unit tests
-* replaced two RuntimeExceptions with checked exceptions
-* made hibernate.username/hibernate.password optional for DriverManager
-* CodeGenerator now supports all hibernate basic types
-* much improved caching algorithm for compiled queries
-* may now specify properties simply by placing hibernate.properties in classpath
-* documentation improvements + fixes
-* --abstract switch to MapGenerator (contributed by Eric Everman)
-
-Changes in version 0.9.11 (12.5.2002)
-------------------------------------
-* fixed major bug with connection handling (fix by Anton van Straaten)
-
-Changes in version 0.9.10 (11.5.2002)
-------------------------------------
-* set a default schema name using SessionFactory property hibernate.default_schema
-* code generator tool contributed by Brad Clow (www.workingmouse.com)
-* lazy object initialization under JDK 1.3 and above
-* fixed some error messages to go to logging framework, not stdout
-* new system property hibernate.show_sql=true logs all executed SQL to stdout
-* integration of bugfixes in c3p0
-* wrap IllegalArgumentExceptions in HibernateExceptions
-* added ObjectNotFoundException and StaleObjectStateException
-* fixed a bug when using schemas
-* new caching strategy (and documented cache feature)
-
-Changes in version 0.9.9 (25.4.2002)
------------------------------------
-* sorted sets and maps (thanks to Doug Currie)
-* mapping files may now be loaded using getResourceAsStream() (thanks to Markus Meissner)
-* hibernate messages now logged by Apache commons-logging
-* default hi/lo generator table now has column named "next_id", instead of "next"
-* query language may now refer to identifier property name (eg. foo.fooKey as alternative to foo.id)
-* hibernate.jndi_class, hibernate.jndi_url now optional when using datasource
-* hibernate now throws an exception if you try to persist an object with a reference to a transient object
-* improved connection pooling algorithm (hibernate.pool_size limits pooled conections)
-* very experimental integration of c3p0 JDBC connection pool (http://sourceforge.net/projects/c3p0)
-* now compiles under JDK 1.2.2
-* fixed bug persisting null components
-* fixed bug where cached prepared statements were not cleaned up after disconnect() session
-* fixed a null pointer exception in MappingByReflection
-
-Changes in version 0.9.8 (13.3.2002)
------------------------------------
-* supports database native key generation in Sybase, MS SQL, MySQL, DB2, Hypersonic (contributed by Christoph Sturm)
-* supports Mckoi (dialect contributed by Doug Currie)
-* supports Progress (dialect contributed by Phillip Baird)
-* added exceptions to catch Session reentrancy from PersistentLifecycle.load() + store()
-* experimental cross-transaction cache
-* Session.lock() and Session.loadWithLock() for pessimistic locking
-* HiLoGenerators may now use their own DriverManager connection properties + may now use same table across diff mapping files
-* Session.flush(), Session.close() and Session.connection() replace Session.commit(), Session.cancel()
-* Session.disconnect() and Session.reconnect() for long transactions
-* added single JVM id generators vm.long, vm.hex
-* added unique column constraints to mappings
-* extensions to IDGenerator framework
-* support sequence-style ID generation in Oracle, PostgreSQL, DB2, Interbase
-
-* fixed problem where subcollections of a collection that changed roles would be deleted
-* changed class loading strategy to be compatible with JBoss
-* stopped queries retrieving unnecessary columns
-* mutable types (binary + serializable) now always detected as dirty
-
-Changes in version 0.9.7 (26.2.2002)
------------------------------------
-* save() now safe from foreign key violations (so create() is no longer preferred method of adding data)
-* delete() now completely safe from foreign key violations - it no longer matters what order objects are deleted in
-* removed Session.copy()
-* hilo generators now NOT for use with application server datasources
-
-* fixed two intermittent bugs in queries
-* fixed a problem where components not detected as dirty
-* fixed broken hilo generator which was not updating database
-* fixed a minor bug when hibernate.use_outer_join was set
-
-Changes in version 0.9.6 (24.2.2002)
------------------------------------
-* experimental XML generation
-* added support for bi-directional associations (one-to-set, set-to-set) with <set readonly="true"> config
-* reflective generation of mappings tool was contributed by Doug Currie
-* Session operations now atomic, so exceptions are recoverable
-* made ID properties optional in persistent classes
-* support for multiple schemas through schema attribute of <hibernate-mapping>, <class>, <set>, <map>, etc.
-* auto-creation of tables for hilo id generators (restriction: cannot use same table from more than one mapping file)
-* added some more assertions to catch user "mistakes" like deleting transient or saving persistent objects
-
-* major rework of collections and fixed some bad bugs
-* lazy initialization re-enabled for one-to-many associations (thanks to Georg Schneemayer)
-* fixed a problem in the mapping DTD to allow nested components in collections
-* fixed a BAD bug in RelationalDatabaseSession when loading objects with PersistentLifecycle callbacks (thanks to Paul Szego)
-* fixed problems with quoted strings in query language
-* fixed a bug where a stack overflow occurred instead of HibernateException thrown (thanks to Georg Schneemayer)
-* fixed a bug deleting updated versioned data
-* fixed some problems with name generation for indexes + foreign keys
-* fixed problem in Sun JDK 1.4 (only?) where IllegalArgumentException was not handled
-* minor improvements to handling of dates and times
-* HiLoGenerator now safe for all transaction isolation levels + safe when rollback occurs
-* noticed and fixed obscure piece of nonthreadsafe code outside of core persistence engine
-* removed unnecessary drop constraints for some dialects
-
-* MUCH more comprehensive test suite
-
-* changed some terminology used in documentation
-* added javadoc for API classes
-* commented the mapping DTD
-
-Changes in version 0.9.5 (8.2.2002)
------------------------------------
-* supports HypersonicSQL (dialect contributed by Phillip Baird)
-* supports Microsoft SQL server (with third party JDBC driver)
-* proper command-line tool for schema generation and export
-* deprecated the interface cirrus.hibernate.Persistent (due to popular demand)
-* changes to hibernate-mapping DTD (required to support optional Persistent interface):
-- deprecated <property type="package.PersistentClassName"/> in favor of <many-to-one class="package.PersistentClassName"/>
-- deprecated <element type="package.PersistentClassName"/> in favor of <many-to-many class="package.PersistentClassName"/>
-- deprecated <property role="..."/> in favor of <collection role="..."/>
-- deprecated <element role=".."/> in favor of <subcollection role="..."/>
-- deprecated <association> in favor of <one-to-many>
-* class attribute optional in <component> and <composite-id> tags (determined by reflection)
-* querying components of components now supported
-* one-shot table creation (no use of unportable "alter table")
-* time dataype support
-* reflective mappings of java.sql.Time, java.sql.Timestamp, java.sql.Date
-* fixed error msg thrown when class is missing a method but has a superclass
-* property names now conform to JavaBean spec ("foo" instead of "Foo"). Note that "Foo" still works
-* constructors of persistent classes may now be non-public
-* collection indexes now mapped to not-null columns
-* fixed obscure bug with querying collections inside components of components
-* fixed potential bug related to cacheing of compiled queries
-* major rewrite of code relating to O-R mappings
-* Session.copy() and Session.equals() as convenience for users
-* fixed repeated invocations of hasNext() on iterator + iterators now always work with distinct SQL resultsets
-* McKoi dialect was contributed by Gabe Hicks
-
-Changes in version 0.9.4 (29.1.2002)
-------------------------------------
-* fixed BAD bug where XML parsing would not work for parsers other than Xerces - thanks to Christian Winkler
-* added some more assertions to catch user "mistakes" like changing ids or reusing existing ids
-
-Changes in version 0.9.3 (27.1.2002)
-------------------------------------
-* repackaged (corrupted DatasourceConnectionProvider.class)
-* better exception reporting using datasource
-* added Datastore.storeClass() which looks for mapping file in classpath (class foo.Bar -> foo/Bar.hbm.xml)
-* improved documentation
-
-Changes in version 0.9.2 (25.1.2002)
-------------------------------------
-* iterate over query results (lazy instantiation of query results)
-* added "select foo, bar" style queries returning multiple objects per row
-* delete by query
-* composite key support
-* outer joins for faster (?) loading of associated objects ( set "hibernate.use_outer_join" to "true" )
-* connection pooling when using DriverManager
-* foreign key constraint from unkeyed collection table to owner entity table
-* improved drop tables script execution (still not infallible)
-* added <composite-element> tag
-* added not-null properties and elements
-* added an optimisation for dates and components
-* made some XML attributes optional
-* fixed errors in documentation + documented some extra features
-* bugfix: store() not getting called on lifecycle interface
-* bugfix: schema generation for indexed associations
-* added many tests
-
-Changes in version 0.9.1 (20.1.2002)
-------------------------------------
-Too many to list
-
-version 0.8.1
--------------
-Initial alpha version
-

Copied: core/tags/hibernate-3.3.0.CR2/changelog.txt (from rev 15001, core/trunk/changelog.txt)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/changelog.txt	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/changelog.txt	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,2618 @@
+Hibernate Changelog
+===================
+Note: Newer entries are automatically generated and the description might not
+match the actual issue resolution (i.e. a bug might not be a bug). Please
+refer to the particular case on JIRA using the issue tracking number to learn
+more about each case.
+
+
+Changes in version 3.3.0.CR2 (2008.07.31)
+-------------------------------------------
+
+** Bug
+    * [HHH-1697] - OracleDialect fails to recognize sequence accessible through syonyms when validating schema
+    * [HHH-2604] - Isolator.JdbcDelegate masks the exception if it isn't possible to open a connection.
+    * [HHH-2683] - "datediff" is declared as NoArgSQLFunction in H2Dialect, but actually accepts 3 arguments.
+    * [HHH-3006] - ConcurrentModificationException in AbstractBatcher results in infinite loop
+    * [HHH-3229] - Merge can fail when there is a transient entity reachable by multiple paths and at least one path does not cascade on merge
+    * [HHH-3257] - Content images not displayed
+    * [HHH-3260] - Hibernate wraps a listener init or destroy exception into an AssertionFailure
+    * [HHH-3261] - Do not wrap exceptions raised by event listeners (at init or destroy time)
+    * [HHH-3265] - change license url in pom to http://www.gnu.org/licenses/lgpl-2.1.html
+    * [HHH-3266] - distribution bundle missing jta dependency
+    * [HHH-3272] - using of Integer.valueOf(int), which is not available in JDK 1.4
+    * [HHH-3282] - DB2Dialect should report supportsLobValueChangePropogation() == false
+    * [HHH-3309] - Serialize/Deserialize problem in AbstractLazyInitializer with entitymode.MAP.
+    * [HHH-3409] - ResultTransformers need smarter equals() and hashCode() impls
+
+** Improvement
+    * [HHH-1786] - JTASessionContext.CleanupSynch does not remove sessions from currentSessionMap
+    * [HHH-2060] - To be able to use <generator> with <composite-id>
+    * [HHH-2506] - Make javassist the default ByteCodeProvider
+    * [HHH-2875] - repackage cglib/asm under org.hibernate namespace
+    * [HHH-3269] - upgrade to jDocBook plugin version 2.1.1
+    * [HHH-3283] - protect BulkManipulationTest#testInsertWithGeneratedTimestampVersion where Dialect#supportsParametersInInsertSelect == false
+    * [HHH-3358] - Enable JTATransactionFactory and JTATransaction factory to work without JNDI
+    * [HHH-3390] - Use READ_COMMITTED for JBC 2 cache
+
+** Patch
+    * [HHH-3294] - Version incorrectly incremented for unchanged persistent entity that is parent of a one to many relationship
+
+** Task
+    * [HHH-3270] - follow up on documentation license questions
+
+
+
+Changes in version 3.3.0.CR1 (2008.04.28)
+-------------------------------------------
+
+** Bug
+    * [HHH-1312] - Unclosed ResultSet when using Identity
+    * [HHH-1396] - Table.validateColumns fails on valid column
+    * [HHH-1569] - Immutable Natural Id check fails with ArrayIndexOutOfBounds in some cases
+    * [HHH-1593] - Infinite loop/StackOverflow when calling configuration.setListener(null)
+    * [HHH-1753] - DB2Dialect.getCurrentTimestampSQLFunctionName() uses Oracle syntax
+    * [HHH-1916] - param values in generator element should be trimmed during HbmBinding
+    * [HHH-1920] - Incorrect documentation regarding XML manipulation in Hibernate reference manual (chapter 18.3).
+    * [HHH-1956] - Interceptor.afterTransactionCompletion not called with JTATransaction (CacheSynchronization.hibernateTransaction not set)
+    * [HHH-2159] - NullPointerException in FromElement#findIntendedAliasedFromElementBasedOnCrazyJPARequirements with 'hibernate.query.jpaql_strict_compliance' enabled
+    * [HHH-2164] - Minor bug in section "20.1.1. Customizing the schema"
+    * [HHH-2200] - Memory leak in AbstractBatcher with Generated Properties
+    * [HHH-2320] - Regression: optional properties under a <join> tag no longer update properly
+    * [HHH-2503] - AbstractEntityPersister swallows JDBCExceptions in processGeneratedProperties
+    * [HHH-2513] - Abusive WARN logged during deserialization of replicated SessionFactory
+    * [HHH-2542] - NullPointerException in TypeFactory.replaceAssociations for ComponentType
+    * [HHH-2553] - New LoadContexts Implementation causing possible performance degradation
+    * [HHH-2593] - Keyword UNION is prefixed with "this_." in filter conditions
+    * [HHH-2616] - No event is fired on Collection recreate/remove/update action
+    * [HHH-2627] - Generated properties leak prepared statements in Hibernate 3.2.3 and higher.
+    * [HHH-2631] - Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts
+    * [HHH-2711] - PropertyAccessException with backref and <composite-map-key/>
+    * [HHH-2726] - spelling o your CLASSPATH
+    * [HHH-2728] - Calling session.clear() while retrieving objects via an iterator will cause a "LazyInitializationException - No Session" by the CGLIBLazyInitializer
+    * [HHH-2788] - Oracl8iDialect No Dialect mapping for JDBC type 91
+    * [HHH-2795] - CollectionLoadContexts for empy collections are not removed until PersistenceContext.clear()
+    * [HHH-2816] - DefaultFlushEntityEventListener.checkNaturalId() causes extra SELECTs on read-only entities
+    * [HHH-2833] - insert-select query fails with NPE when select includes join
+    * [HHH-2857] - schemaSupport for HSQLDialect remote connections doesn't work
+    * [HHH-2861] - cascade="delete-orphan,all" is ignored
+    * [HHH-2863] - testsuite fix-ups for maven and/or directory changes
+    * [HHH-2864] - Merging a detached instance with a new child in a unidirectional one-to-many association fails if the parent was previously loaded as a proxy
+    * [HHH-2892] - skip up-to-date checks of query cache for natural-id only if immutable
+    * [HHH-2928] - optimizers for enhanced id generators should be synchronized against multi-threaded access
+    * [HHH-2948] - QueryStatistics.executionMinTime always = 0
+    * [HHH-3111] - WebSphereExtendedJTATransactionLookup$TransactionManagerAdapter.getStatus() implemented incorrect
+    * [HHH-3140] - Region prefix ignored for entities and collections
+
+** Deprecation
+    * [HHH-2755] - Wrong "jsdk.jar" referenced in the tutorial
+
+** Improvement
+    * [HHH-1786] - JTASessionContext.CleanupSynch does not remove sessions from currentSessionMap
+    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
+    * [HHH-2156] - Section 19.3, "Managing the caches" doesn't document CacheMode.IGNORE
+    * [HHH-2533] - redesign Cache/CacheProviders
+    * [HHH-2662] - Workaround PostgreSQL issues in testsuite
+    * [HHH-2663] - Map java.sql.Types.REAL to Hibernate FloatType for auto-discovery stuff
+    * [HHH-2665] - Split Oracle9Dialect into Oracle9iDialect and Oracle10gDialect
+    * [HHH-2669] - Unequivocally map MySQL LOB types to the LONG variant
+    * [HHH-2682] - support for auto-discovery of H2 dialect
+    * [HHH-2696] - Consider migrating to slf4j
+    * [HHH-2761] - Handle null and empty string consistently in PropertiesHelper
+    * [HHH-2778] - TransactionManagerLookup implementation for Bitronix Transaction Manager
+    * [HHH-2789] - Section 19.2 of the documentation does not show OSCache as supporting clusters. It does.
+    * [HHH-2822] - timestamp extraction functions for SAPDBDialect
+    * [HHH-2826] - IS [NOT] NULL checks with component values
+    * [HHH-2859] - Introduce a 'Work' API for user to perform JDBC work
+    * [HHH-3131] - Add a method to ActionQueue to tell whether there are currently entries in the executions collection
+
+** New Feature
+    * [HHH-1] - Optimize Hibernate for the bulk insertion of related entities
+    * [HHH-2555] - Create new RegionFactory for JBossCache
+    * [HHH-2884] - Provide a sessionFactory close event or hook for the event listeners
+
+** Patch
+    * [HHH-952] - Patch to allow subqueries with joins using Criteria API and Subqueries with DetachedCriteria
+    * [HHH-2070] - Expand DB2Dialect auto-discovery support (Martin Renner)
+    * [HHH-2519] - Schema dropping not documented with hibernate.hbm2ddl.auto=create
+    * [HHH-2630] - Hibernate Dialect is not auto-detected for Sybase ASE and DB2 (Shelley McGowan)
+    * [HHH-2758] - Patch IngresDialect based on certification
+    * [HHH-2839] - Don't use dummy dual table for hsqldb (David Bala?ic)
+    * [HHH-2849] - Better error logging in IdentifierGeneratorFactory (Antony Stubbs)
+    * [HHH-2957] - ActionQueue Insertion sort performance degrades exponentially (Jay Erb)
+    * [HHH-3084] - DialectFactory detection of Ingres metadata (Michael Leo)
+
+** Task
+    * [HHH-2702] - Officially move to JDK 1.4
+    * [HHH-2704] - Migrate to Maven2 for build
+
+
+Changes in version 3.2.6 (2008.02.07)
+-------------------------------------------
+
+** Bug
+    * [HHH-925] - DetachedCriteria.createCriteria not working with alias
+    * [HHH-1312] - Unclosed ResultSet when using Identity
+    * [HHH-1329] - SchemaValidator fail when views are involved
+    * [HHH-1593] - Infinite loop/StackOverflow when calling configuration.setListener(null)
+    * [HHH-1685] - DetachedCriteria doesn't create alias on subcriteria
+    * [HHH-1753] - DB2Dialect.getCurrentTimestampSQLFunctionName() uses Oracle syntax
+    * [HHH-1916] - param values in generator element should be trimmed during HbmBinding
+    * [HHH-1956] - Interceptor.afterTransactionCompletion not called with JTATransaction (CacheSynchronization.hibernateTransaction not set)
+    * [HHH-2016] - Oracle9Dialect registers last_day() function as "lastday"
+    * [HHH-2159] - NullPointerException in FromElement#findIntendedAliasedFromElementBasedOnCrazyJPARequirements with 'hibernate.query.jpaql_strict_compliance' enabled
+    * [HHH-2200] - Memory leak in AbstractBatcher with Generated Properties
+    * [HHH-2261] - Setting hibernate.hbm2ddl.auto=validate causes problems on mySQL with numeric fields
+    * [HHH-2320] - Regression: optional properties under a <join> tag no longer update properly
+    * [HHH-2503] - AbstractEntityPersister swallows JDBCExceptions in processGeneratedProperties
+    * [HHH-2542] - NullPointerException in TypeFactory.replaceAssociations for ComponentType
+    * [HHH-2593] - Keyword UNION is prefixed with "this_." in filter conditions
+    * [HHH-2598] - Mapping a collection of entities from two different classes with the same collection name results in duplicate backref property exception if collection keys are not null
+    * [HHH-2616] - No event is fired on Collection recreate/remove/update action
+    * [HHH-2627] - Generated properties leak prepared statements in Hibernate 3.2.3 and higher.
+    * [HHH-2728] - Calling session.clear() while retrieving objects via an iterator will cause a "LazyInitializationException - No Session" by the CGLIBLazyInitializer
+    * [HHH-2788] - Oracl8iDialect No Dialect mapping for JDBC type 91
+    * [HHH-2795] - CollectionLoadContexts for empy collections are not removed until PersistenceContext.clear()
+    * [HHH-2816] - DefaultFlushEntityEventListener.checkNaturalId() causes extra SELECTs on read-only entities
+    * [HHH-2833] - insert-select query fails with NPE when select includes join
+    * [HHH-2857] - schemaSupport for HSQLDialect remote connections doesn't work
+    * [HHH-2861] - cascade="delete-orphan,all" is ignored
+    * [HHH-2864] - Merging a detached instance with a new child in a unidirectional one-to-many association fails if the parent was previously loaded as a proxy
+    * [HHH-2892] - skip up-to-date checks of query cache for natural-id only if immutable
+    * [HHH-2928] - optimizers for enhanced id generators should be synchronized against multi-threaded access
+    * [HHH-2948] - QueryStatistics.executionMinTime always = 0
+
+** Improvement
+    * [HHH-1630] - duplicate property mapping - more details
+    * [HHH-1696] - Add outer join support for aliases on DetachedCriteria
+    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
+    * [HHH-2682] - support for auto-discovery of H2 dialect
+    * [HHH-2761] - Handle null and empty string consistently in PropertiesHelper
+    * [HHH-2822] - timestamp extraction functions for SAPDBDialect
+    * [HHH-2826] - IS [NOT] NULL checks with component values
+    * [HHH-2852] - Better error messages when schema validation fails
+
+** Patch
+    * [HHH-952] - Patch to allow subqueries with joins using Criteria API and Subqueries with DetachedCriteria
+    * [HHH-2070] - Expand DB2Dialect auto-discovery support (Martin Renner)
+    * [HHH-2839] - Don't use dummy dual table for hsqldb (David Bala?ic)
+    * [HHH-2849] - Better error logging in IdentifierGeneratorFactory (Antony Stubbs)
+    * [HHH-2957] - ActionQueue Insertion sort performance degrades exponentially (Jay Erb)
+    * [HHH-3084] - DialectFactory detection of Ingres metadata (Michael Leo)
+
+** Task
+    * [HHH-2559] - http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd needs to be updated
+    * [HHH-3085] - Remove connector.jar (unnecessary library)
+    * [HHH-3086] - Remove jdbc2_0-stdext.jar (unnecessary library)
+
+
+Changes in version 3.2.5 (2007.07.31)
+-------------------------------------------
+
+** Bug
+    * [HHH-1116] - batch-size typo
+    * [HHH-1561] - Missing " in Documentation for H3, Chapter 15.8
+    * [HHH-1569] - Immutable Natural Id check fails with ArrayIndexOutOfBounds in some cases
+    * [HHH-1694] - Documentation Outdated: "10.4.4. Queries in native SQL"
+    * [HHH-2180] - minordocumentation error in hbm xml
+    * [HHH-2201] - session.iterate() does not exist
+    * [HHH-2267] - A copy/paste mistake in the documentation for <schemavalidator> ant task
+    * [HHH-2334] - Documentation error in section 5.1.3
+    * [HHH-2420] - Error in 2.5. Contextual Sessions
+    * [HHH-2502] - The second level caching documentation states that ehcache is not distributed.
+    * [HHH-2631] - Leaking PreparedStatement and ResultSet via CollectionLoadContext instances maintained in Map collectionLoadContexts in LoadContexts
+    * [HHH-2649] - Batcher configuration parameter incorrectly documented
+    * [HHH-2711] - PropertyAccessException with backref and <composite-map-key/>
+    * [HHH-2713] - duplicated phrase in docs "of the of the"
+    * [HHH-2714] - Three typos in code examples
+    * [HHH-2719] - adddress --> address
+    * [HHH-2720] - Monetory --> Monetary
+
+** Improvement
+    * [HHH-1022] - incomplete documentation in _README.txt in the lib directory
+    * [HHH-1682] - Improve the description of differences between save() and persist()
+    * [HHH-2048] - Incomplete MappingException at org.hibernate.mapping.SimpleValue
+    * [HHH-2417] - Update book on Hibernate reference
+    * [HHH-2418] - Refer HSQL DB website in chapter 1.2.3
+    * [HHH-2487] - Typo in "5.1.7. version (optional)"
+    * [HHH-2550] - Update API Class in 10.4.3. Criteria queries
+    * [HHH-2662] - Workaround PostgreSQL issues in testsuite
+    * [HHH-2663] - Map java.sql.Types.REAL to Hibernate FloatType for auto-discovery stuff
+    * [HHH-2665] - Split Oracle9Dialect into Oracle9iDialect and Oracle10gDialect
+
+** Patch
+    * [HHH-2520] - Miscellaneous config doc spelling fixes
+    * [HHH-2630] - Hibernate Dialect is not auto-detected for Sybase ASE and DB2 (Shelley McGowan)
+    * [HHH-2758] - Patch IngresDialect based on certification
+
+** Task
+    * [HHH-2551] - Deprecate org.hibernate.criterion.Expression
+    * [HHH-2566] - Replace usages of FlushMode.NEVER with FlushMode.MANUAL
+    * [HHH-2567] - Update reference to use FlushMode.MANUAL
+    * [HHH-2568] - Hibernate javadoc overview refering wrong classes and packages
+
+
+Changes in version 3.2.4.sp1 (2007.05.18)
+-------------------------------------------
+
+** Bug
+    * [HHH-2605] - Since 3.2.4 no value specified for row id
+    * [HHH-2613] - LockMode.FORCE on non versioned entity leads to NPE
+
+
+Changes in version 3.2.4 (2007.05.09)
+-------------------------------------------
+
+** Bug
+    * [HHH-511] - reattach object from same session
+    * [HHH-2316] - org.hibernate.cache.CacheKey.equals() can cause PropertyAccessException to be thrown
+    * [HHH-2553] - New LoadContexts Implementation causing possible performance degradation
+    * [HHH-2602] - instrumented many-to-one problem with aggressive release
+
+** Deprecation
+    * [HHH-2603] - Deprecate the Session.connection() method
+
+** Improvement
+    * [HHH-2549] - Warn users explicitly about schemaexport and schemaupdate does not support annotations
+
+** New Feature
+    * [HHH-1] - Optimize Hibernate for the bulk insertion of related entities
+
+** Patch
+    * [HHH-2301] - Identity generator with custom insert SQL broken in 3.2 (Scott Rankin and Gail Badner)
+    * [HHH-2336] - paremeterizable and typedef-able UserCollectionType (Holger Brands)
+    * [HHH-2580] - Performace: Too many lookups of WAS extended transaction support (Jesper Udby)
+
+
+Changes in version 3.2.3 (2007.04.02)
+-------------------------------------------
+
+** Bug
+    * [HHH-2376] - Query with fully qualified entity class fails
+    * [HHH-2392] - LockModes referencing non-root joined-subclass class in HQL/Criteria
+    * [HHH-2393] - Generated properties leave open ResultSet on Batcher to be closed on transaction completion
+    * [HHH-2397] - hilo generator can generate negative numbers because of arithmetic overflow
+    * [HHH-2469] - ArrayIndexOutOfBoundsException during update by rowid
+    * [HHH-2476] - PersistentMap.put() incorrect on uninitialized, non-extra-lazy map
+    * [HHH-2481] - Big memory leak in the use of CGLIB
+    * [HHH-2499] - incorrect assertion failure relating to generated property values
+    * [HHH-2513] - Abusive WARN logged during deserialization of replicated SessionFactory
+    * [HHH-2521] - Fix cascading of merge across component properties
+    * [HHH-2532] - update/delete executeUpdate() causes problems with JBossCache (at least in opt-locking setups)
+
+** Improvement
+    * [HHH-2495] - encapsulate the notion of state pertaining to processing a result set
+    * [HHH-2534] - better error message for illegal 'collection dereference' in HQL query
+    * [HHH-2535] - Change Cache' Cache71Dialect so that sequence support returns false
+
+** New Feature
+    * [HHH-2471] - create a set of "enhanced" generators
+    * [HHH-2500] - apply Terradata certification results
+
+** Patch
+    * [HHH-2367] - InformixDialect uses wrong data type
+    * [HHH-2489] - SQL comments for HQL bulk operations
+
+
+Changes in version 3.2.2 (2007.01.24)
+-------------------------------------------
+
+** Bug
+    * [HHH-1471] - If the 'generated' attribute is set to 'insert' or 'always' on the property of a component it is ignored and the value is not read from the database.
+    * [HHH-1646] - Bad code in FastClass.equals
+    * [HHH-1889] - LockMode.UPGRADE not applied in all cases for SQL Server / Sybase
+    * [HHH-2112] - ClassCastException in StatefulPersistenceContext.getCachedDatabaseSnapshot(...)
+    * [HHH-2221] - MySQL temp table DDL and isolation
+    * [HHH-2238] - SQLQuery executeUpdate doesn't respect Query.setFlushMode()
+    * [HHH-2251] - Settings build unnecessary in schemaupdate/schemavalidate
+    * [HHH-2257] - Query.iterate() results differ from Query.list() 2
+    * [HHH-2259] - autoflush and autoclose not longer occur in JTA environment with hibernate 3.2
+    * [HHH-2264] - NPE when NamedQuery contains space before variable name
+    * [HHH-2274] - Collection ordering when many to many order by is used is not respected
+    * [HHH-2275] - Mapping a composite element as a map key using formulas can lead to AOOBE
+    * [HHH-2284] - HQL: selecting components inside components doesn't work
+    * [HHH-2291] - collection based on property-ref not handled correctly during reattch
+    * [HHH-2292] - merge detached instance fails to persist collection changes in case of bare collection reference
+    * [HHH-2356] - NullableType.toString(Object) should account for nulls
+    * [HHH-2366] - Changing a component's value does not trigger an update during flush
+    * [HHH-2378] - replicate() of non-versioned entiy can result in wrong value for version in entity cache
+
+** Improvement
+    * [HHH-1851] - relax special handling of 'id' property
+    * [HHH-2130] - SQLQuery does not autoflush all entities used in the query
+    * [HHH-2193] - Introduce a flag to avoid checking NamedQuery at startup
+    * [HHH-2242] - Consider Allowing Optimistic Lock Strategies other than 'Version' with joined-subclass
+    * [HHH-2250] - Create an appropriate error message if Query.setEntity is passed a NULL value
+    * [HHH-2282] - PersistentClass property lookups do not properly account for embedded composite identifiers
+    * [HHH-2286] - dialect informational metadata
+    * [HHH-2372] - Allow tooling to create Settings via SettingsFactory without contacting the db
+
+** New Feature
+    * [HHH-2246] - No way to specify CACHE_PROVIDER_CONFIG in HibernateServiceMBean
+
+** Patch
+    * [HHH-2300] - Updated dialect for H2 database engine
+    * [HHH-2371] - enhancements to C3P0ConnectionProvider
+
+** Task
+    * [HHH-2032] - update c3p0 to 0.9.1
+
+
+
+Changes in version 3.2.1 (2006.11.16)
+-------------------------------------------
+
+** Bug
+    * [HHH-939] - 'class' property in HQL results in incorrect SQL for joined-subclass
+    * [HHH-1401] - session.merge() executes unnecessary updates when one-to-many relationship is defined.
+    * [HHH-1460] - Inconsistent behavior when using Session.get() with multiple subclasses
+    * [HHH-1564] - deleting versioned object with collection leads to unecessary update
+    * [HHH-1629] - SchemaUpdate/validator doesn't listen to quoting
+    * [HHH-1631] - Missing table in SQL from clause that is referenced in where clause when using joined subclass
+    * [HHH-1651] - hibernate does not find an existing sequence from an Oracle database
+    * [HHH-1663] - <any/> with collection will produce "AssertionFailure: collection was not processed by flush()"
+    * [HHH-1737] - Add a ConnectionWrapper interface to allow access to the underlying connection from a BorrowedConnectionProxy
+    * [HHH-1756] - Proxy objects are not removed from the BatchFetchQueue during a session evict
+    * [HHH-1774] - Component parameters bound incorrectly
+    * [HHH-1921] - "dirty, but no dirty properties" thrown when Interceptor resets properties.
+    * [HHH-1986] - javassist throws InvocationTargetException instead of original checked Exception
+    * [HHH-2027] - merge listener over-writes Interceptor changes to component state for a transient entity
+    * [HHH-2044] - DefaultMergeEventListener.entityIsDetached call StaleObjectStateException with wrong identifier
+    * [HHH-2082] - UpdateTimestampsCache.isUpToDate returns before checking all spaces
+    * [HHH-2108] - cacheable files broken
+    * [HHH-2138] - merge with bidirectional one-to-one may fail
+    * [HHH-2145] - set.retainAll calling set.addAll
+    * [HHH-2174] - Wrong log message in SessionImpl.afterTransactionCompletion(...)
+    * [HHH-2199] - Unique constraints on nullable columns should not be generated with unique-key is used and supportsNotNullUnique=false
+    * [HHH-2202] - Clearing the connection warnings even when log is > WARN to workaround a Sybase issue
+    * [HHH-2206] - SessionImpl tries to deserialize itself in an incorrect order
+    * [HHH-2207] - Suggested fix for HQL - MySQL setMaxResults issue
+    * [HHH-2226] - org.hibernate.hql.ast.tree.FromElementType contains warning log message that should be debug instead
+    * [HHH-2229] - Performance issue with fix for HHH-1293, CGLIBLazyInitializer may be slower for certain Java classes
+    * [HHH-2236] - Lazy property + setReadOnly + Instrumented classes results in NullPointerException when accessing lazy property
+
+** Improvement
+    * [HHH-2037] - provide Query.setProperties(Map)
+    * [HHH-2042] - Typo in FlushMode.MANUAL Javadoc
+    * [HHH-2057] - Add "remove" cascading style to CascadeStyle for XML mappings
+    * [HHH-2127] - Document <filter-def condition="defaultCondition"> and <filter-def>defaultCondition
+    * [HHH-2135] - Hibernate Deserialization:  In org.hibernate.type.SerializableType the code makes a test for the return of a null object by simply testing the object as to whether or not it is null.
+    * [HHH-2185] - introduce setting to control cglib caching of classes
+    * [HHH-2203] - Make Post*Events extend AbstractEvent
+    * [HHH-2208] - Table schema use in DatabaseMetadata
+    * [HHH-2209] - ehcache.jar is old and does not contain the SingletonCacheProvider which are advised in exception messages
+    * [HHH-2217] - Collection write methods and dirtying the collection
+
+** New Feature
+    * [HHH-2205] - Dialect for Intersystems' Cache SQL 2007.1
+
+** Patch
+    * [HHH-1767] - read-only cache for immutable collection causes unnecessary warning
+
+** Task
+    * [HHH-2219] - Upgrade to Javassist 3.4
+
+
+Changes in version 3.2.0.ga (16.10.2006)
+-----------------------------------------
+(retag of 3.2.0.cr5 (2006.10.16))
+
+Changes in version 3.2.0.cr5 (04.10.2006)
+-------------------------------------------
+
+** Bug
+    * [HHH-1668] - PersistentSet write methods mark collection as dirty even if entry is not written
+    * [HHH-1714] - Session.get() behavior
+    * [HHH-1891] - Since rc3 deprecation Warning: The syntax 'TYPE=storage_engine' is deprecated and will be removed in MySQL 5.2.
+
+** Improvement
+    * [HHH-2093] - PERSIST_ON_FLUSH ineffective for recursive object graphs
+    * [HHH-2103] - Rolling back 'SELECT is mandatory' on JPA strict compliance
+
+** Task
+    * [HHH-1931] - verify that the instrument tasks actually work
+
+
+Changes in version 3.2.0.cr4 (24.08.2006)
+-------------------------------------------
+
+** Bug
+    * [HHH-1293] - java.lang.NoSuchMethodError: <persistent class>.getHibernateLazyInitializer()
+    * [HHH-1677] - optimistic-lock="dirty|all" is ignored at delete time
+    * [HHH-1710] - persistent collections with property-ref to secondary tables cannot be joined in HQL
+    * [HHH-1713] - AbstractEntityPersister causes an exception when a row in a joined table is missing with fetch="select"
+    * [HHH-1740] - Build-time instrumentation breaks lazy="proxy"
+    * [HHH-1750] - Exception ORA-01000 too many open cursors by generated="insert"
+    * [HHH-1806] - No Dialect mapping for JDBC type: 3
+    * [HHH-1848] - A session.lock generates a query with a version column in a joined subclass which does not exist
+    * [HHH-1892] - finish HHH-1789 for ordered and sorted collections
+    * [HHH-1898] - With hibernate 3.2.0-cr3 there is an hql parsing error on a one-to-one relation
+    * [HHH-1924] - ForeignKeys: TransientObjectException is thrown without a message because of a wrong bracket in the code
+    * [HHH-1927] - persist() and then merge() not handled correctly for multiple entity instances representing the same logical state
+    * [HHH-1937] - Proxy creation failure leads to NPEs
+    * [HHH-1943] - PersistenceContext not checked to see whether the associated entity is transient or not
+    * [HHH-1944] - generated subqueries and jpaql compliance (derived select clause) check
+    * [HHH-1947] - OF part of MEMBER  OF is optional
+    * [HHH-1948] - Query Idetification variables are case insensitive in JPA
+    * [HHH-1949] - having trim(BOTH from c.name) translated into having ltrim(rtrim(BOTH)) on DB2
+    * [HHH-1954] - Proxies are never unassociated (evicted) from a session
+    * [HHH-1958] - session.lock(LockMode.FORCE) can lead to NPE
+    * [HHH-1963] - meta inheritance broken
+    * [HHH-1992] - Some cascade actions should not trigger a property access on lazy properties
+    * [HHH-2001] - javaassist does not setup the proper protection domain thus does not work with signed/secured deployments such as webstart
+    * [HHH-2015] - where= does not set parenthesis leading to unexpected query when multiclause are used
+    * [HHH-2017] - locate function defined on Oracle9Dialect is incorrect
+    * [HHH-2022] - property names beginning with underscores cause Hibernate to generate invalid aliases
+
+** Improvement
+    * [HHH-1470] - Enhance Hibernate-Mapping DTD Definition of type element
+    * [HHH-1934] - logging NonUniqueObjectException and WrongClassException
+    * [HHH-1941] - Be more specific about x not found and invalid mapping exceptions to allow tools to tell about it
+    * [HHH-1968] - unify bytecode instrumentation
+    * [HHH-1980] - disallow the mapping combination of <version/> and optimistic-lock
+    * [HHH-2005] - more standard build script
+    * [HHH-2023] - performance optimization of JTATransactionFactory.isTransactionInProgress()
+
+** Patch
+    * [HHH-1271] - When using Stored Procedure for update or delete, the check is not done correctly.
+
+** Task
+    * [HHH-1931] - verify that the instrument tasks actually work
+
+
+Chages in version 3.2 cr3 (2006.07.06)
+-------------------------------------------
+
+** Bug
+    * [HHH-1452] - Native SQL query is missing join if entity includes many-to-one on secondary table
+    * [HHH-1507] - one-to-one can have formula or meta but not both of them.
+    * [HHH-1552] - Error when using ?1 and parameterList
+    * [HHH-1586] - ClassCastException in CollectionType.toLoggableString if using CustomCollectionType
+    * [HHH-1732] - EhCache.toMap still assumes Serializable objects
+    * [HHH-1734] - Connection leak when using hilo strategy in SE environment
+    * [HHH-1741] - Bug in reference documentation
+    * [HHH-1746] - NullPointerException at IdentNode.resolveAsNakedComponentPropertyRefLHS(IdentNode.java:195
+    * [HHH-1748] - Setting a comment that contains a single quote on a query results in an unintuitive exception
+    * [HHH-1763] - Bug in InputStream org.hibernate.util.ConfigHelper.getResourceAsStream(String resource)
+    * [HHH-1791] - property update="false" ignored since 3.2.0.cr2
+    * [HHH-1816] - serializing session from a named session factory to a different vm broken
+    * [HHH-1822] - flushing entity linked to transient instance (non cascaded) should always fail
+    * [HHH-1828] - registering a transaction marked for Rollback is illegal
+    * [HHH-1833] - Not Generating HibernateException
+    * [HHH-1838] - Wrong SQL generated for hql query on "any" relation
+    * [HHH-1855] - booleans not properly handled in assignment clause of UPDATE statements
+    * [HHH-1858] - wrong sql generated against many-to-any association table
+    * [HHH-1871] - query type autodiscovery assume wrong column when mixing entities and scalars
+
+** Deprecation
+    * [HHH-1792] - Callable update/insert/delete statements should not force rowcount out parameter
+
+** Improvement
+    * [HHH-1617] - Check the second-level cache before adding a PK to a batch fetch
+    * [HHH-1773] - Typo in ImprovedNamingStrategy
+    * [HHH-1779] - Allow Session.remove() on transient object
+    * [HHH-1789] - improve efficiency of collection initialization from L2 cache hits
+    * [HHH-1795] - default cache provider to NoCacheProvider
+    * [HHH-1796] - TreeCache based providers and Fqn
+    * [HHH-1800] - session.get() / load() should raise exception when the id is of the wrong type
+    * [HHH-1818] - remove() should force subsequent contains() calls to return false
+    * [HHH-1831] - Batch loading the same EntityKey (one side of manytoone ) more than once
+    * [HHH-1861] - More complete component handling in HQL
+    * [HHH-1881] - introduce LoggableUserType interface
+
+** New Feature
+    * [HHH-1709] - Be able to raise ENFE rather than LIE in proxies
+    * [HHH-1727] - Add a SQLFunctionRegistry
+    * [HHH-1817] - Introduce setting for JPA-QL strict compliance
+    * [HHH-1826] - Built-in type for char[] -> VARCHAR Byte[] and Character[]
+
+** Patch
+    * [HHH-1558] - Dialect for new database engine H2
+    * [HHH-1847] - QBE 'like' clause with backslashes don't work with MySQL
+
+** Task
+    * [HHH-1839] - rename FlushMode.NEVER -> FlushMode.MANUAL
+
+
+Changes in version 3.2 cr2 (2006.05.05)
+-------------------------------------------
+
+** Bug
+    * [HHH-1114] - The first (HSQL) Hibernate Application doesn't work as expected due to lack of database shutdown
+    * [HHH-1175] - Exception when loading inheritance mapping in single file
+    * [HHH-1560] - PropertiesHelper.resolvePlaceHolders() fails with non-String values in System properties
+    * [HHH-1620] - Errors on max_lo <=1 boundaries
+    * [HHH-1625] - Hibernate.isPropertyInitialized() returns false on instrumented transient object
+    * [HHH-1648] - Exception while resuming a transaction is silently eaten
+    * [HHH-1674] - Configuration serialization error: filterDefinitions map not serializable
+    * [HHH-1695] - subsequent calls to non-existent proxy causes NPE
+
+** Improvement
+    * [HHH-1266] - StatelessSession can implement refresh
+    * [HHH-1414] - many-to-many and metadata order-by based on column from the target table
+    * [HHH-1477] - Improve naming strategy for ANN-195
+    * [HHH-1538] - aggregations functions in EJBQL queries does not return the appropriate types
+    * [HHH-1670] - Update EhCache and EhCache provider to support EhCache 1.2
+    * [HHH-1704] - Deduplicate unique constraints generation sharing the same column(s)
+
+** New Feature
+    * [HHH-870] - support SQL updates in named queries
+    * [HHH-1591] - Replace LazyInitializationException by EntityNotFoundException
+    * [HHH-1719] - Provide a ClassTransformer interface to the BytecodeProvider
+
+
+Changes in version 3.2 cr1 (2006.03.27)
+-------------------------------------------
+
+** Bug
+    * [HHH-1453] - Broken exception handling in NullableType
+
+** Improvement
+    * [HHH-227] - remove reflection optimizer
+    * [HHH-587] - Make ResultTransformer available for all query methods
+    * [HHH-1588] - delay inserts for insert-generated-identifiers outside transaction
+    * [HHH-1590] - redesign how PostInsertIdentifierGenerators are handled at insertion
+    * [HHH-1592] - allow SelectGenerator to use a defined natural-id (if one)
+
+** New Feature
+    * [HHH-332] - create ability to add resulttransformer to HQL query
+    * [HHH-1179] - support inline sequence id generation on Oracle using RETURNING clause
+
+
+Changes in version 3.2 alpha2 (2006.03.15)
+-------------------------------------------
+
+** Bug
+    * [HHH-535] - properties element causes exception in interface/abstract class
+    * [HHH-1325] - ArrayOutOfBounds expected in DatabaseMetadata.isTable when specifing schema
+    * [HHH-1435] - many-to-one lazy seems to be broken in 3.1.x
+    * [HHH-1531] - NPE with many-to-many and property-ref
+    * [HHH-1546] - generated version properties fail with multiple actions per flush
+
+** Improvement
+    * [HHH-1540] - Better Error Feedback In CollectionEntry.postFlush(PersistentCollection)
+    * [HHH-1555] - ConnectionReleaseMode.AFTER_STATEMENT and flushes
+    * [HHH-1559] - introduce TransactionFactory.isTransactionInProgress to facilitate EJB3 joinTransaction handling
+
+
+Changes in version 3.2 alpha1 (2006.02.28)
+-------------------------------------------
+
+** Bug
+    * [HHH-687] - Exception QuerySyntaxError not really serializable
+    * [HHH-1236] - Remove static reference to classloader, to avoid memory leak at webapp reload
+    * [HHH-1287] - Problem with WAS ExtendedJTATransaction not available when using MDB
+    * [HHH-1419] - Update + Exists doesn't seem to work
+    * [HHH-1445] - SchemaUpdate closes shared ConnectionProvider
+    * [HHH-1464] - QueryException from Query.getReturnAliases when query uses "fetch"
+    * [HHH-1486] - Concurrent access issues with both SoftLimitMRUCache and SimpleMRUCache
+    * [HHH-1508] - Session.createQuery() should not flush the session
+
+** Improvement
+    * [HHH-1411] - Collection fetches and DISTINCT
+    * [HHH-1412] - Collection fetches and firstResult/maxRows
+    * [HHH-1416] - LockMode.FORCE to implement EJB3 LockModeType.WRITE
+    * [HHH-1457] - support new optimisitc locking capabilities of JBossCache
+    * [HHH-1466] - better handling of Antlr exceptions
+    * [HHH-1516] - support DataDirect standard jdbc stored procedures
+    * [HHH-1518] - Guarentee LockMode behaviors
+    * [HHH-1520] - with clause with implied joins within an explicit join
+    * [HHH-1526] - Improved DTDEntityResolver
+
+** New Feature
+    * [HHH-1251] - Avoid replicating the clearing of TreeCache on SessionFactory..close()
+    * [HHH-1410] - FlushMode.AUTO -> COMMIT when outside a transaction
+    * [HHH-1447] - pluggable bytecode libraries
+
+
+Changes in version 3.1.2 (01.27.2006)
+-------------------------------------------
+
+** Bug
+    * [HHH-73] - Statistics for HQL queries use pre-processed query string
+    * [HHH-1306] - HQL parsing problem with join fetching of arrays/collections of values
+    * [HHH-1370] - Warning in hibernate-mapping-3.0.dtd
+    * [HHH-1371] - MappingException is thrown when the same column is referenced with different case
+    * [HHH-1386] - Numeric (long) literals not properly handled by HQL parser
+    * [HHH-1390] - Session.isOpen() throws exeception when the session is closed with ThreadLocalSessionContext
+    * [HHH-1391] - Invalid parameter index SQLException when using named parameters after positional parameters
+    * [HHH-1392] - Proxies cannot be serialized after session is closed
+    * [HHH-1398] - extends and entity-names broken with mapping-level package attribute
+    * [HHH-1407] - return-join broken for entity collections
+
+** Improvement
+    * [HHH-1364] - Defensive check of isClosed when obtaining a connection from ConnectionManager
+    * [HHH-1367] - warn level log "this operation breaks ==" may be disturbing
+
+** New Feature
+    * [HHH-1372] - Support for MySQL5 new varchar length
+
+** Patch
+    * [HHH-1005] - Criteria LEFT JOIN capability when adding Order to associations
+
+** Task
+    * [HHH-1373] - Document update versioned
+
+
+Changes in version 3.1.1 (01.13.2006)
+-------------------------------------------
+
+** Bug
+    * [HHH-853] - DML-style HQL queries and associations
+    * [HHH-1281] - FORWARD_ONLY ScrollableResults#next() throw GenericJDBCException
+    * [HHH-1286] - Set entity in HQL query without prefix -> incorrect SQL
+    * [HHH-1308] - Session.createFilter(...).iterate() results in bogus column names for result set extraction
+    * [HHH-1314] - float/double literals not sent to the database correctly
+    * [HHH-1316] - SchemaUpdate : java.sql.SQLException: You cannot commit during a managed transaction!
+    * [HHH-1328] - org.hibernate.util.SimpleMRUCache keeps a soft reference to the cache key, so cached values get collected prematurely
+    * [HHH-1336] - ForeignGenerator does not handle transient entities with an entity-name properly
+    * [HHH-1337] - Mapped <component> generated column names incorrect with ImprovedNamingStrategy
+    * [HHH-1349] - HQL delete statement problem due to oracle lacking table aliases in delete clause
+    * [HHH-1361] - creating temporary table for bulk delete will commit current transaction in managed environment such as J2EE
+
+** Improvement
+    * [HHH-1019] - Native SQL return-property mapping doesn't support dot-syntax in return-property for components
+    * [HHH-1290] - Defensive checking of session status
+    * [HHH-1302] - query.getReturnTypes inconsistent
+    * [HHH-1304] - better handling of borrowed connections in non-ON_CLOSE release semantics
+    * [HHH-1309] - schemaupdate does not handle TableHiLoGenerator
+    * [HHH-1339] - empty property name in mapping file gives imcomprehensible error message
+    * [HHH-1344] - ANSI-SQL trim function for SQLServer
+    * [HHH-1345] - ANSI-SQL mod function for SQLServer
+    * [HHH-1346] - ANSI-SQL bit_length function for SQLServer
+    * [HHH-1351] - <return-scalar name="blah"/> should be possible
+    * [HHH-1360] - set autodiscovery flag for SQLQueries when resultsetmappings are used
+
+
+Changes in version 3.1  (12.12.2005)
+-------------------------------------------
+
+** Bug
+    * [HHH-849] - Cartesian product + implicit joins
+    * [HHH-1065] - user provided connection not usable by default due to agressive release changes
+    * [HHH-1101] - associations join fetched in HQL without owner being selected
+    * [HHH-1133] - Comparators, defined for collections in mapping files, are not set
+    * [HHH-1149] - NPE flushing reattached entity  w/ non-mutable natural-id
+    * [HHH-1170] - HQL 'cast' function doesn't work with MySQL 4 when casting to string
+    * [HHH-1187] - Cannot delete a object having a delete-orphan collection when user_rollback_id is set
+    * [HHH-1191] - HQL fails backward compatibility using classic translator
+    * [HHH-1194] - hql delete statements with joined-subclass hierarchies with a mapped where attribute at the root
+    * [HHH-1206] - Mappings.TableDescription is not serializable
+    * [HHH-1212] - mismatch in entity-modes defined in DTD and EntityMode class
+    * [HHH-1227] - ClassCastException on DOM4J replicate of Calendar property
+    * [HHH-1239] - BinaryArithmeticOperatorNode.getDataType() does not properly handle date/time arithmetic
+    * [HHH-1240] - Track connection leakage in JDBCContext.afterTransactionCompletion()
+    * [HHH-1245] - Calling the Session should register it with the current JTA txn.
+    * [HHH-1254] - Serialization of Sessions using JDBCTransactions with auto-flush/auto-close
+
+** New Feature
+    * [HHH-1222] - Autodiscover scalar types in native-sql
+    * [HHH-1243] - allow placeholders to system properties in config properties
+    * [HHH-1244] - Support for MySQL5 stored procedures
+    * [HHH-1260] - Configuration.mergeProperties()
+
+** Task
+    * [HHH-1066] - Upgrade CGLIB to fix proxy memory leak
+    * [HHH-1242] - upgrade ANTLR to 2.7.6rc1
+
+** Improvement
+    * [HHH-860] - insert ... select ... and version numbers
+    * [HHH-926] - TypeDef should be global
+    * [HHH-1138] - No ConstraintName when using PostgreSQL
+    * [HHH-1144] - Implement naming convention for temporary test failures
+    * [HHH-1153] - PropertiesHelper fails reading primitive values from hibernate-mapping when doc has whitespace
+    * [HHH-1182] - Access to filter metadata
+    * [HHH-1183] - Getting sql "plan" for DML operations
+    * [HHH-1197] - Support for HQL delete on MaxDB
+    * [HHH-1198] - post-insert event pass the entity wo the id field filled when the generator is identity
+    * [HHH-1213] - make JACC event listeners auto configurable (through initialize(Configuration))
+    * [HHH-1215] - Added support for LVARCHAR in InformixDialect
+    * [HHH-1218] - Add concat() function support to SAPDBDialect
+    * [HHH-1255] - ThreadLocalSessionContext and Session serialization
+
+** Patch
+    * [HHH-967] - executeUpdate on StatelessSession
+    * [HHH-1172] - Missing configuration templates for the new MimerSQLDialect
+
+** Deprecation
+    * [HHH-1229] - deprecate ability for entities to not define identifier properties
+
+
+Changes in version 3.1 rc3  (17.11.2005)
+-------------------------------------------
+
+** Bug
+    * [HHH-755] - Setter / Getter for property gDate are wrong
+    * [HHH-764] - XML mapping
+    * [HHH-1034] - The connection is closed  *outside* the JTA transaction in TransactionHelper
+    * [HHH-1062] - java:comp/UserTransaction not correct for JBoss
+    * [HHH-1064] - Exception using JTATransaction in WebSphere 6
+    * [HHH-1069] - Unnecessary commas generated in select with left outer joins
+    * [HHH-1075] - New parser  "not exists" command bug
+    * [HHH-1077] - Typo in docs: "equiped"
+    * [HHH-1080] - HQL delete fails on entities with where-fragments using operators other than '='
+    * [HHH-1081] - missing parens in example code for Criteria Associations
+    * [HHH-1084] - incorrect method name "sql" in Restrictions example, should be "sqlRestriction"
+    * [HHH-1091] - Can't write transparent CurrentSessionContext for BMT
+    * [HHH-1098] - Patch for build.sh to be able to build latest version on linux
+    * [HHH-1106] - HQL "not in" generatad wrong SQL
+    * [HHH-1111] - JDBCTransaction.rollback() results in a call to Interceptor.beforeTransactionCompletion()
+    * [HHH-1128] - Column alias clashes under  certain circumstances
+    * [HHH-1146] - latest cvs(11/10/05)  hibernate3 issue with classic query
+    * [HHH-1156] - StatefulPersistenceContext not serializable when property-ref is used
+    * [HHH-1160] - Incorrect use of getGeneratedKey() for Oracle
+
+** New Feature
+    * [HHH-449] - korean hibernate reference manual
+    * [HHH-1129] - use expected-type in 'untyped' Query.setParameter()
+
+** Improvement
+    * [HHH-221] - Proxy for one-to-one with property-ref
+    * [HHH-844] - move parameter "bookkeeping" into QueryTranslator
+    * [HHH-1051] - "Compiled" native SQL queries are not cached
+    * [HHH-1061] - import.sql should allow more human readable and usable files
+    * [HHH-1078] - <dynamic-component> requires type on property
+    * [HHH-1120] - Make NamingStrategy to work nicely with HA and EJB3 naming strategy
+    * [HHH-1142] - added getSelectSequenceNextValString() and getCurrentTimestampSelectString() to TimesTenDialect
+
+** Patch
+    * [HHH-1063] - support for 'locate' function in SQLServer and Sybase dialects
+    * [HHH-1090] - Allow subqueries on criteria to obtain non-string results
+    * [HHH-1095] - Hibernate takes incorrect HasCode when a lot of CompositeKeys and Lazy loading is involved
+    * [HHH-1103] -  finalize method filter for proxies
+    * [HHH-1136] - more meaningful AssertionFailure message in org.hibernate.persister.entity.JoinedSubclassEntityPersister.getTableId(...)
+
+
+Changes in version 3.1 rc2  (17.10.2005)
+-------------------------------------------
+** Bug
+    * [HHH-1045] - Example contains inner classes that aren't serializable
+    * [HHH-1055] - optimistic-lock is not inherited from class to subclass et.al.
+
+** Improvement
+    * [HHH-702] - auto detect aliasing for collection properties (coll.key, coll.id etc.)
+    * [HHH-1038] - make 'auto' the default for hibernate.connection.release_mode
+    * [HHH-1042] - determine "expected type" of parameters during HQL parsing
+
+
+Changes in version 3.1 rc1  (07.10.2005)
+-------------------------------------------
+** Bug
+    * [HHH-528] - component.manyToOne.id in HQL causes join
+    * [HHH-871] - Configuration.setListener(String type, Object listener) throws ClassCastException
+    * [HHH-873] - referencing raw HQL FromElement alias outide the from clause of update and delete statements generates incorrect sql
+    * [HHH-876] - PreparedStatement being closed before being executed by AbstractBatcher
+    * [HHH-884] - SchemaExport does not propagate parent indexes to <union-subclass> tables
+    * [HHH-887] - Aggressive release and Session.connection()
+    * [HHH-893] - custom tuplizer are not instantiated for components
+    * [HHH-905] - $PlaceHolder$ remains in generated SQL when filter is enabled
+    * [HHH-907] - optimistic-lock="false" for timestamped object results in SQLException: Invalid column index
+    * [HHH-908] - CLONE -NullPointerException when using BigInteger in a query
+    * [HHH-911] - CGLIBLazyInitializer and Exceptions
+    * [HHH-913] - NPE in CMTTransaction since javax.transaction.Transaction is never set
+    * [HHH-918] - impossible to move objects to another session
+    * [HHH-924] - Useless OracleErrorCodeConverter (and possibly others)
+    * [HHH-932] - HQL UPDATE and <union-subclass>
+    * [HHH-946] - QuerySyntaxException might not be serializable
+    * [HHH-964] - ORA-00936 with joined subclass / Oracle
+    * [HHH-986] - Need to check Thread.currentThread().getContextClassLoader() in ConfigHelper
+    * [HHH-991] - Cannot use comparator class
+    * [HHH-1000] - varchar(xxx char) not supported on Oracle8i
+
+** New Feature
+    * [HHH-950] - interface for SessionFactory.getCurrentSession() handling
+
+
+** Improvement
+    * [HHH-608] - update HSQLDialect for HSQL 1.8 sequence support
+    * [HHH-889] - Add read-only cache-mode comment in <query and <sql-query
+    * [HHH-898] - OracleDialect UTF8 varchar2
+    * [HHH-909] - Onquoted primary key in IncrementGenerator
+    * [HHH-988] - generated="never|insert|always"
+    * [HHH-989] - add discussion of implicit and explcit joins
+    * [HHH-1011] - Make disconnect/reconnect of a Session implicit
+
+** Patch
+    * [HHH-994] - Sybase/SQLServer support for temporary tables
+
+
+Changes in version 3.1 beta 3  (13.09.2005)
+-------------------------------------------
+** Bug
+    * [HHH-528] - component.manyToOne.id in HQL causes join
+    * [HHH-871] - Configuration.setListener(String type, Object listener) throws ClassCastException
+    * [HHH-873] - referencing raw HQL FromElement alias of update and delete statements
+    * [HHH-876] - PreparedStatement being closed before being executed by AbstractBatcher
+    * [HHH-884] - SchemaExport does not propagate parent indexes to <union-subclass> tables
+    * [HHH-887] - Aggressive release and Session.connection()
+    * [HHH-893] - custom tuplizer are not instantiated for components
+    * [HHH-905] - $PlaceHolder$ remains in generated SQL when filter is enabled
+    * [HHH-907] - optimistic-lock="false" for timestamped object results in SQLException: Invalid column index
+    * [HHH-908] - NullPointerException when using BigInteger in a query
+    * [HHH-911] - CGLIBLazyInitializer and Exceptions
+    * [HHH-913] - NPE in CMTTransaction since javax.transaction.Transaction is never set
+    * [HHH-918] - impossible to move objects to another session 
+    * [HHH-924] - Removed ErrorCodeConverters
+    * [HHH-946] - QuerySyntaxException might not be serializable
+
+** Improvement
+    * [HHH-898] - OracleDialect UTF8 varchar2
+    * [HHH-909] - Unquoted primary key in IncrementGenerator
+
+
+Changes in version 3.1 beta 2 (16.08.2005)
+-------------------------------------------
+** Bug
+    * [HHH-477] - Boolean discriminators generate invalid SQL for PostgreSQL dialect
+    * [HHH-480] - SchemaExportTask ignores some properties not defined in hibernate.properties
+    * [HHH-615] - SchemaExport outputFile ignores ant's basedir
+    * [HHH-770] - hql query execution generates invalid SQL
+    * [HHH-779] - Assertion failure occured with Hibernate 3 saving objects
+    * [HHH-781] - SimpleExpression ignorecase regression
+    * [HHH-799] - merge() and embedded composite identifiers
+    * [HHH-801] - subselect fetch and named parameters
+    * [HHH-802] - querying "mapped" composite identifiers
+    * [HHH-803] - no version increment from delayed collection adds
+    * [HHH-805] - Session.getStatistics().getEntityCount() throws UnsupportedOperationException
+    * [HHH-819] - Firebird CONCAT SQL function
+    * [HHH-821] - query by natural-id cache is not update when object is inserted or deleted
+    * [HHH-822] - <key-property> will actually pick up <type> tags if it were allowed by the DTD
+    * [HHH-825] - ReadWrite-Cache issues NullPointerException after modification of an array
+    * [HHH-839] - Session.refresh not working for custom 'Load' SQL
+    * [HHH-849] - Cartesian product + implicit joins
+    * [HHH-854] - Class with mapped composite id can't have subclasses
+    * [HHH-858] - Autocommit status inconsistent in connections created by DriverManagerConnectionProvider
+    * [HHH-863] - Hibernate generates "notExists" instead of "not exists"
+    * [HHH-868] - Missing parens after / or -
+
+** New Feature
+    * [HHH-35] - add attribute haltonerror to schemaexport Ant task
+    * [HHH-182] - Mimer SQL Dialect for Hibernate 3
+    * [HHH-704] - Statistics for optimistic lock failures
+    * [HHH-725] - Allow hooks into all executed sql by a session
+    * [HHH-783] - collection lazy="extra"
+    * [HHH-818] - Optimisitc locking using database current timestamp
+    * [HHH-828] - session.getTransaction()
+    * [HHH-829] - <cache include="all|non-lazy" ... />
+    * [HHH-831] - allow database generated property values
+    * [HHH-832] - allow database generated property values for versioning
+    * [HHH-838] - Transaction.setTimeout()
+    * [HHH-840] - allow definition of "auxiliary" database objects in mapping
+    * [HHH-846] - Add Intializable interface for events
+    * [HHH-848] - Validate mappings against JDBC metadata
+    * [HHH-859] - post-commit events
+
+** Improvement
+    * [HHH-133] - schemaexport task: provide independent drop/create output
+    * [HHH-135] - parameterized types can't be used on key-property or ir (possible others)
+    * [HHH-552] - NoopAccessor for HQL-only properties
+    * [HHH-680] - Easier support for doing UserCollectionType's
+    * [HHH-686] - Final classes and classes with private null ctors cause unhelpful NullPointerException
+    * [HHH-754] - Allow HQL DML for implicit polymorphism
+    * [HHH-782] - Avoid unnecessary updates when component property is update='false' but modified
+    * [HHH-786] - Improve lazy options for <one-to-one>
+    * [HHH-791] - Use cascade styles when fetching entities in refresh() and merge()
+    * [HHH-815] - Confusing use of the term "dereference"
+    * [HHH-830] - Improvements to caching lazy properties
+
+** Patch
+    * [HHH-378] - Better LockMode.UPGRADE for DB2 UDB v8.2
+    * [HHH-430] - Improved SizeExpression with greater, lesser, not equals, etc. capabilities
+    * [HHH-735] - SchemaUpdate reads table metadata from wrong schema
+    * [HHH-780] - org.hibernate.proxy.BasicLazyInitializer reflection hotspot
+    * [HHH-864] - Use QUERY_CACHE for sessions with filters to improve performance
+
+
+Changes in version 3.1 beta 1 (21.07.2005)
+-------------------------------------------
+
+** Bug
+   * [HHH-145] - union-subclass and oracle 8i
+   * [HHH-374] - EJB3 example delete query doesn't work in Hibernate.
+   * [HHH-447] - EHCache integration prevents multiple session factories
+   * [HHH-488] - JACCListeners are not working at all
+   * [HHH-564] - missing commas for implicit joins
+   * [HHH-577] - joins within subqueries on dbs supporting ansi-joins result in extraneous commas
+   * [HHH-592] - cast() function doesn't know its returned Hibernate type
+   * [HHH-639] - CGLIB instrumentation of subclasses
+   * [HHH-658] - Bug in Alias Name Generation
+   * [HHH-671] - Firebird support of sequences/generators
+   * [HHH-679] - setLockMode(LockMode.UPGRADE_NOWAIT) does not translate to correct SQL on Oracle
+   * [HHH-688] - Bad implementation in org.hibernate.type.CustomType.stringToObject
+   * [HHH-691] - generated column alias is incorrect if there is a prior relationship and the table column names are similar to the table name
+   * [HHH-694] - NPE when accessing the SLCache stats with TreeCache
+   * [HHH-698] - Exception on EG , trying to change immutable id (natural-id)
+   * [HHH-699] - Incorrect Tablename genetaion when using MySQL Dialect and no Schema definition
+   * [HHH-708] - Restrictions.in could not be used properly on composite-ids
+   * [HHH-709] - ArrayType.replaceElements fails if original.length != target.length
+   * [HHH-718] - HQL "fetch all properties" not working for column level lazy props
+   * [HHH-726] - ConstraintViolationException with primitive collection
+   * [HHH-727] - java.lang.StackOverflowError when cascade="true" on both sides of bidirectional one-to-one association using FK
+   * [HHH-734] - HQL incorrectly parses certain query strings
+   * [HHH-736] - Use of sql functions containing space not supported in filter conditions
+   * [HHH-738] - formula property with select-before-update
+   * [HHH-747] - Order.toSQLString generates incorrect statement
+   * [HHH-748] - component dereferencing in subquery from clauses
+   * [HHH-752] - Typo in 8.5.3 bidirectional one-to-one jjoin table example
+   * [HHH-757] - NullPointerException when using BigInteger in a query
+
+** New Feature
+   * [HHH-595] - HQL insert select
+   * [HHH-597] - Named XML resultsetmappings
+   * [HHH-696] - handle discriminators on HQL insert
+   * [HHH-697] - allow bumping versions in HQL update
+   * [HHH-716] - handle version columns in bulk inserts
+   * [HHH-723] - Need to be able to pass in javax.sql.DataSource in SF creation
+   * [HHH-739] - Order.ignoreCase()
+   * [HHH-741] - select clause subselects
+   * [HHH-742] - Stateless session
+   * [HHH-744] - collection fetching in scroll() via "break processing"
+   * [HHH-768] - <many-to-many property-ref=".."/>
+
+** Improvement
+   * [HHH-14] - Add Session.delete(String entityName, Object entity)
+   * [HHH-295] - cleanup and expose the Tuplizers
+   * [HHH-352] - HQL bulk and cache
+   * [HHH-689] - exclude parens for components outside where-clause
+   * [HHH-743] - {coll.key}, {coll.index}, {coll.element}, etc
+   * [HHH-745] - EJB3 composite PK style
+   * [HHH-749] - Cascade merge() and unidirectional one-to-many
+   * [HHH-750] - use attribute name other than 'type' in dynamic-maps
+   * [HHH-753] - Replace antlr System.exit with QueryException
+   * [HHH-769] - property-ref="foo.bar" to a component property
+   * [HHH-772] - null in maps are handled inconsistently
+   * [TODO-18] - optimistic-lock="all|dirty" with components
+
+
+Changes in version 3.1 alpha 1 (24.06.2005)
+------------------------------------
+** Bug
+    * [HHH-204] - Wrong/uncommon log name in class ...hql ast ErrorCounter
+    * [HHH-241] - HQL lexer doesn't support unicode quoted strings
+    * [HHH-354] - property named "full" breaks HQL queries
+    * [HHH-493] -  WARNING: Keyword 'member' is being intepreted as an ident
+    * [HHH-538] - length() function does not work in SQLServerDialect
+    * [HHH-539] - ClassCastException on mapping a property with a formula in a set of composite elements
+    * [HHH-540] - Mapping a one-to-many collection with a non-null foreign key within a component fails on save
+    * [HHH-547] - Cannot commit using UserCollectionType and debug logging
+    * [HHH-548] - many-to-many faulty delete optimization when filter in use
+    * [HHH-554] - Hibernate 3 HQL to SQL FROM Clause Comma Generation Problem
+    * [HHH-558] - HQL doesn't support multi-byte character in class name and property names
+    * [HHH-559] - quoted multi-byte character in HQL is translated into weird character in SQL.
+    * [HHH-565] - delete-orphan generating AssertionFailure
+    * [HHH-566] - The result is not correct in  'createQuery("select new Foor(x,x) from Foo").scroll()'
+    * [HHH-570] - size operator fails on a many to many in HQL
+    * [HHH-571] - JDK 1.3 Compatibility Issue
+    * [HHH-573] - error when merging entity graph has cascade level>2
+    * [HHH-575] - org.hibernate.cache.FilterKey is not Serializable
+    * [HHH-589] - parameterized expression inside function
+    * [HHH-594] - order-by mapping for collections overrides order by in HQL
+    * [HHH-601] - New temporary table feature assumes all persisters are ready
+    * [HHH-614] - SchemaUpdate broken in DB2/400
+    * [HHH-622] - Spelling mistake 'intepreted' in org.hibernate.hql.PARSER warning
+    * [HHH-642] - criterias with projection
+    * [HHH-650] - FilterImpl is Serializable yet FilterDefinition is not
+    * [HHH-657] - Date parse exception using EntityMode.DOM4J
+    * [HHH-666] - JTAHelper.isInProgress( txn.getStatus()) throws NPE when txn null
+
+** New Feature
+    * [HHH-620] - Extra join conditions in HQL
+    * [HHH-640] - short-circuit dirty checking for instrumented classes
+    * [HHH-643] - support mutable="false" for collections
+    * [HHH-645] - Session.setReadOnly()
+    * [HHH-549] - portable to_char() function
+    * [HHH-576] - Hook to pre-process generated select strings in the Dialect
+    * [HHH-662] - Add support for definition of functional composite key ("properties") in joined subclass
+
+** Improvement
+    * [HHH-46] - Allow access to properties that are not joined
+    * [HHH-261] - Stored procedure support for SQLServer dialects
+    * [HHH-351] - multi-table bulk operations
+    * [HHH-574] - improve in naming named-query
+    * [HHH-596] - Auto-detect {..} in native SQL queries
+    * [HHH-641] - create constraints for many-to-one property-ref
+    * [HHH-501] - warn when a final method is tried to be proxied
+    * [HHH-525] - cglib related startup performance
+    * [HHH-557] - Helpful error message for non Serializable classes with a composite-id
+    * [HHH-586] - check immutable natural-ids
+    * [HHH-609] - Adds substr to PostgreSQL dialect
+    * [HHH-618] - documentation bugs
+
+** Patch
+    * [HHH-224] - JDataStore Dialect and updated Testfiles
+    * [HHH-366] - InformixDialect SQLExceptionConverter
+    * [HHH-536] - ImprovedNamingStrategy modifies capitalized column names inappropriately
+    * [HHH-632] - Informix Dialect missing from automatic dialect discovery
+    * [HHH-4] - CachedFile bugfix + configuration + autodetect resource as file
+
+
+Changes in version 3.0.5 (25.5.2005)
+------------------------------------
+
+** Bug
+    * [HHH-516] - Interceptor.onFlushDirty() sometimes not called
+    * [HHH-517] - getDatabaseMajorVersion() not available in JDK 1.3
+    * [HHH-518] - SQL parser does not recognize all whitespace
+    * [HHH-519] - broken SQL when traversing many-to-many to joined <subselect>
+    * [HHH-529] - Bug in merge()
+
+** New Feature
+    * added <natural-id> mapping
+    * [HHH-533] - allow unique-key on <property> and <many-to-one>
+    * [HHH-534] - efficient cache by natural key
+    * support for <comment> on MySQL
+
+** Improvement
+    * [HHH-526] - log "Aggressively releasing JDBC Connection" as DEBUG instead of INFO
+    * various logging improvements
+
+
+Changes in version 3.0.4 (23.5.2005)
+------------------------------------
+
+** Bug
+    * [HHH-452] - UnsavedValueFactory.instantiate does not wrap the Exception it catches
+    * [HHH-456] - Session still holds references to entities after close()
+    * [HHH-457] - Log info for structured second-level cache entries is incorrect
+    * [HHH-466] - Made default for MS SQL dialect definition more flexible
+    * [HHH-473] - Formula can't contain SQL cast keyword
+    * [HHH-484] - Order-by not applied to collections fetched by OuterJoinLoader
+    * [HHH-487] - Possible empty union in UnionSubclassEntityPersister
+    * [HHH-505] - Possible NullPointerException in BigIntegerType
+    * [HHH-507] - Cached List does not show additions
+    * Fixed bugs in subselect fetching
+
+** New Feature
+    * [HHH-455] - Obtain non-intercepted Session by passing an EmptyInterceptor
+    * [HHH-467] - HQL: support for case when then else end IN select clause
+    * [HHH-485] - Support multiple collection join fetches (attention: Cartesian product) in native SQL queries
+    * Added SessionStatistics metric interface
+    * Added support for table and column level <comment> blocks
+    * Added Simplified Chinese translation of reference documentation (Xiaogang Cao)
+
+** Improvement
+    * Any query may now join fetch >1 collection role (attention: Cartesian product)
+    * [HHH-454] - Add 2292 integrityViolationCode to Oracle9Dialect
+    * [HHH-503] - Implemented ViolatedConstraintNameExtracter for HSQLDialect (Frank Grimes)
+
+
+Changes in version 3.0.3 (8.5.2005)
+-----------------------------------
+* fixed bug in HQL for composite key classes which have a property named the same as the owning entity's id property
+* replaced 'connection.aggressive_release' with 'hibernate.connection.release_mode'
+* added ConnectionReleaseMode
+* added eager fetch for any associations with fetch=join, even after a HQL query, or cache retrieval (EJB3)
+* added replicate() isUpdate flag to OnReplicateVisitor, useful for native ids
+* fixed ParameterizedTypes order of initialization
+* fixed bug in DB2Dialect
+* fixed EntityMode.DOM4J creation of duplicate <set> output
+* fixed JDBCException error code handling
+* fixed Criteria Restrictions.isEmpty()/isNotEmpty() when collection is mapped to superclass
+* fixed HQL indexed collections access with no alias
+* fixed HQL aggregate functions on components when "id" property is used
+* fixed issue with non-cascading refresh to collections
+* fixed query-timeout not being applied to bulk HQL (Stephan Fudeus)
+* fixed pessimistic locking with Firebird (Yuichi Sugimura)
+* updated Ant 1.6.3
+* improved validation of sql queries, throw QueryException if addEntity() nor addScalar() was called
+* added automatic dialect detection if no dialect is configured
+* added new tutorial (Michael Gloegl, Christian Bauer)
+
+
+Changes in version 3.0.2 (27.4.2005)
+------------------------------------
+* fixed union operations on PostgreSQL
+* fixed HQL concat() function for Oracle dialect
+* fixed auto-close/auto-flush during getCurrentSession() processing
+* fixed ClassCastException with EntityMode.DOM4J
+* fixed HQL dynamic instantiation with iterate()
+* fixed HQL bug with missing parantheses and implicit joins
+* fixed bug were Interceptor.getEntity() wasn't called if in cache
+* fixed bug in merge() of sorted sets
+* fixed bug in EntityMode.DOM4J with non-lazy embedded many-to-ones
+* fixed Criteria/Projection ordering bug
+* fixed HQL referencing component attribute
+* fixed column duplication detection for components
+* fixed eager fetching for many-to-many associations
+* fixed stack overflow with auto_close_session and aggressive_release and unclosed ScrollableResults/HibernateIterator
+* fixed bug in HQL parser regarding naked property refs which reference component properties
+* fixed bug with eager fetched arrays not being loaded
+* fixed bug in filter against joined-subclass
+* improved CacheMode.GET/IGNORE, disabled cache put
+* improved HQL support for standard SQL functions, including coalesce() and nullif()
+* improved filtering of many-to-many associations
+* added HQL support for cast(x as type) if SQL database supports it
+* added increment id generation for union-subclass
+* added ConnectionProvider.supportsAggressiveRelease() for managed environments
+* added support for caching of queries if filter is enabled
+* added PreparedStatement count to Statistics
+* added transactional/nontransactional read()/get() to Cache API
+* added quotation of schema names
+* added Distinct to Projection API
+* added config parameter 'connection.aggressive_release'
+
+Changes in version 3.0.1 (18.4.2005)
+------------------------------------
+* added HQL tuple constructor/comparison feature
+* added HQL "fetch all properties" override if instrumentation is used for lazy loading
+* added HQL projection feature, return Lists instead of arrays for projection
+* added HQL projection feature, return Maps with user-defined HQL SELECT aliases as keys
+* added HQL support for expressions in aggregation functions
+* added new IntegrityViolationException to MySQL dialect
+* added value mapping type 'big_integer'
+* added not-found="ignore|exception" switch for legacy associations (i.e. broken database integrity)
+* added fully automatic Session scoping in JTA environments with sf.getCurrentSession()
+* fixed bug in DTD that wouldn't allow union-subclass in separate file
+* fixed a MS SQL Server case sensitivity issue with native SQL queries
+* fixed a minor bug in subselect fetching
+* fixed case sensitivity in HQL functions
+* fixed a bug with listener assignment for save() operation (Matthew Inger)
+* fixed return-property in named SQL queries to work with all identifier names
+* fixed TransactionManager lookup (again) for WAS 6.0
+* fixed a bug with HQL batch delete and MS SQL Server
+* fixed session not getting closed with auto_close when rollback occured
+* improved concatentation handling in AST parser
+* updated dom4j to avoid memory leak in old version
+* updated C3P0
+
+
+Changes in version 3.0 (31.3.2005)
+----------------------------------
+* added support for autoflush/autoclose to HibernateServiceMBean
+* fixed initialization/session association detection problem of collections
+* fixed creation of FK constraints to union superclass table
+* fixed bug where union-subclass table did not get a PK constraint
+* added a separate log category for HQL parser warnings and errors
+* fixed bulk delete operation on MS SQL Server
+* added support for proxying protected methods (Juozas)
+* added support for unicode quoted strings in new HQL parser
+* fixed implied joins in subselect WHERE clause in new HQL parser
+* added SQLServer7Dialect to handle differences in functions
+* added support for JNDI-bound cache instances, future use for JBoss Cache
+* added scale attribute to column mappings for numeric precision control
+* added fetch=subselect for collections
+* added support for bulk update/delete against discriminator-based inheritence hierarchies
+* added the ability to use naked property refs in HQL (required in update/delete statements)
+* updated CGLIB 2.1.0
+* fixed NPE at BasicEntityPersister.getPropertyIndex (Todd Nine)
+* fixed issue with entity-name and subclasses (Sverker Abrahamsson)
+* fixed issue with correlated subqueries in new HQL parser
+* fixed a problem with native SQL query mapping and embedded composite identifiers
+* improved mapping binding, allowing unordered extends for pure entity-name hiearchies
+* fixed NPE for delete() with deprecated Lifecycle interface
+* fixed a problem with serial joins ending in component value in new HQL parser
+* fixed inner join/subselect precedence problem in new HQL parser
+* fixed indices() function in new HQL parser
+* fixed a bug in InformixDialect, now correct LIMIT clause
+* fixed a bug in idbag.remove() (Sebastien Cesbron)
+* fixed a conflict on OracleDialect between setMaxResult and LockMode.UPGRADE
+* fixed XML configuration file issue with SchemaExport
+* fixed an ArrayIndexOutOfBounds problem
+* renamed executeUpate() to executeUpdate()
+* fixed batch loading for property-ref entities
+* fixed loading from cache of <key property-ref> collection owner
+* fixed minor bug in SQL exception reporting
+* fixed dynamic-component cannot be bound to XML
+* fixed querying component with formula property
+* fixed incorrect table alias for order-by on many-to-many
+* fixed a bug for unidirectional one-to-many with moving child objects
+* fixed a bug with union-subclasses and persister creation
+* fixed a HQL concatenation problem on MySQL
+* fixed a bug where an unnecessary exception was thrown for a property-ref to a superclass property
+* fixed minor dtd bug
+* fixed new bug in Clob/Blob support
+* fixed issue with INDEX_OP and subclass joins on theta-join dialects
+* fixed some minor issues in query cache regions, including HB-1449
+* fixed superflous import and regression bug in verifyparameters
+* fixed two bugs in select id generator (Malcolm Green)
+* fixed increment generator for union-subclass mappings
+* updated JBoss Cache to 1.2.1alpha, fixing locking issues
+* made stat classes serializable
+* fixed merge(), now ignores blob and clob fields
+* added support/dialect for TimesTen
+* improved algorithm for batch fetching, more aggressive
+* improved toStrings()s for Statistics objects (Ryan Lynch)
+* renamed <result-*> to <return-*> for externalized SQL query mapping
+* renamed Session.openSession() for EntityMode to Session.getSession()
+* added support for CASE in HQL
+* fixed bug with filters and polymorphic queries
+* fixed import ordering problem of super/subclass mappings
+* switched to patched ANTLR 2.7.5, now using context classloader before doing class.forname
+* TableHiloGenerator now falls back to TableGenerator properly with max_lo < 2 (Emmanuel Bernard)
+* better transaction handling of TableGenerator in a JTA environment  (Emmanuel Bernard)
+* removed hard coded log4j dependency (Emmanuel Bernard)
+* added support for stored procedure in named queries (Max Andersen)
+* added <property-result> to named SQL queries to allow users to use sql without {}-markup
+* added multi-column property support to native SQL mapping
+
+Changes in version 3.0rc1 (28.2.2005)
+----------------------------------
+* introduced EntityModes, and XML mapping preview
+* several minor dialect improvements
+* fixed a problem where filters were not applied to subclasses
+* fixed a problem where InstrumentTask would fail if applied to already-instrumented classes
+* fixed many problems with new parser and made it the default (thanks again to Joshua for the new parser)
+* implemented bulk update/delete queries for the new parser
+* fixed a minor bug in the classic query parser
+* renamed create() to persist() as per EJB3edr2
+
+Changes in version 3.0 beta 4 (11.2.2005)
+-----------------------------------------
+* support unidirection one-to-many with a not-null foreign key
+* support formulas for index and element of collections
+* support one-to-ones mapped to formulas
+* fixed a bug in proxying methods that return "this"
+* optimized proxies for embededded composite id classes
+* fixed a bug affecting <key-many-to-one>
+* fixed a bug caching newly inserted objects
+* introduced DetachedCriteria
+* support subselects in Criteria queries
+* miscellaneous Criteria API enhancements
+* fixed a problem where hibernate.max_fetch_depth applied to eager fetching via setFetchMode()
+* use inner joins for join fetching not-null fk associations
+* support unique="true" in <component> and <properties> mappings
+* union-subclass hierarchies may own collections (dtd bug)
+* added guid support for Oracle
+* new mechanism for auto-detecting unsaved-value
+* pass state array in delete events
+* improved implementation of hibernate.auto_close_session and hibernate.close_before_completion
+* fixed a bug where components with only collections would be incorrectly nullified
+* fixed a bug where criteria queries with projection could not be cached
+* fixed a problem where duplicate column name aliases could be generated
+
+Changes in version 3.0 beta 3 (30.1.2005)
+------------------------------------------
+* Major rework of Criteria queries, support for projection, grouping, aggregation, ordering by any attribute
+* various improvements to new HQL parser (Joshua Davis)
+* fixed a bug where <join fetch="select"> was broken for subclasses with duplicated property names
+* fixed problems with long types in Oracle DDL generation
+* added EnhancedUserType, UserCollectionType, UserVersionType
+* added CacheMode
+* fixed minor performance problem where cascade delete could add objects to second-level cache
+* added hibernate.default_batch_fetch_size
+* added hibernate.cache.use_structured_entries
+* different classes and collection roles may now share a cache region
+* don't include discriminators for abstract classes in generated SQL
+* it is no longer truly necessary for composite identifier classes to implement equals()/hashCode() (but still recommended)
+* workaround for bug in MySQL InnoDB with self-referential foreign keys
+* added lazy="true" to many-to-one and one-to-one mappings (requires bytecode instrumentation)
+
+Changes in version 3.0 beta 2 (24.1.2005)
+------------------------------------------
+* added LockAcquisitionErrorCodes to MySQL dialect (Jesse Barnum, Emmanuel Bernard)
+* added MultipleHiLoPerTableGenerator, one hi value per row/per table (compliant with EJB3)
+* added a generator handling multiple hi values per table (Emmanuel Bernard)
+* added events for pre/post SQL operation interception
+* added experimental support for JACC-aware configuration and events
+* added full support for implicit polymorphism in Criteria queries
+* added support annotated classes through XML configuration (Emmanuel Bernard)
+* added support for WebSphere's weird TxManagerLookup
+* added support for filters with dynamic-class mappings
+* added support for lists of parameters in filters
+* added support for scalar queries in createSQLQuery (Michael Gloegl)
+* added support for scalar results in native SQL queries (Michael Gloegl)
+* fixed SchemaExport/SchemaUpdate, now respect default_schema and default_catalog (Michael Gloegl)
+* fixed a bug in one-to-one mapping with property-ref
+* fixed a bug in the query cache lookup routine
+* fixed compilation problems on IBM JDK 1.4. and JDK 1.3.1
+* fixed custom SQL for loading when using composite identifiers
+* fixed exception thrown from optimistic locking failures
+* fixed support for limit queries (select first ?) in Informix
+* improved SchemaExport/Update, now respect default_schema and default_catalog
+* improved dialect handling, throw an exception if no dialect has been set
+* improved loading of mappings, no ordering of super/subclasses required anymore
+* improved statistics for second-level cache
+* improved table generators for hi/lo, can now be used in a JTA environment (Emmanuel Bernard)
+* query engine: added support for 'trim([leading | trailing | both] [expression from] expression)'
+* query engine: added support for DISTINCT and ALL
+* query engine: added support for FETCH
+* query engine: added support for HAVING count()
+* query engine: added support for HQL NOT IN and EJBQL '[NOT] MEMBER OF'
+* query engine: added support for ORDER BY COUNT(*)
+* query engine: added support for collections of scalar values
+* query engine: added support for literals in constructor select expressions.
+* query engine: added support for select elements(..) from Foo f
+* query engine: added support for template functions in the SELECT clause
+* query engine: fixed NOT LIKE
+* query engine: introduced EMPTY and added it to constant (support for IS [NOT] EMPTY)
+* updated dom4j, OSCache, EHCache, JBoss Cache, Xerces, Xalan, and Log4j
+* associated class where filter now applies to <one-to-one property-ref>
+
+Changes in version 3.0 beta 1 (21.12.2004)
+------------------------------------------
+* reimplemented HQL using an ANTLR-based AST parser (Joshua Davis)
+* added class="select" id generator
+* added Query.setReadOnly()
+* added hibernate.order_updates
+* introduced cascade refresh
+* added typed JDBC exceptions (Steve Ebersole)
+* improved lifecycle for CacheProviders (Steve Ebersole)
+* added Expression.isEmpty()
+* fixed some minor mapping DTD bugs (Ben Sommerville)
+* fixed auto-commit mode for SchemaUpdate
+* added default-lazy to <hibernate-mapping>, which defaults to true!
+* added fetch="join|select" and deprecated outer-join attribute
+* fixed a bug where <custom-insert> was not used for entities with "identity" id generation
+* fixed some problems with dynamic-class
+* added property-level optimistic-lock attribute, to allow an unchecked property
+* cascade lock() now cascades with LockMode.NONE
+* fixed some bugs in filter handling (Steve Ebersole)
+* added hibernate.transaction.flush_before_completion and hibernate.transaction.auto_flush_session
+* added JSR-220 compliant create() and merge() operations
+* cascade attribute is now multi-valued, with values save-update,create,merge,delete,delete-orphan,lock,evict,replicate,all-delete-orphan
+* index and unique-key attributes may now be multi-valued
+* introduced unsaved-value="undefined", the default for "assigned" ids and <composite-id>, which forces Hibernate to hit the db
+* primitive typed <id> property mappings now default to unsaved-value="0"
+* added ScrollMode
+* added dialect for Derby (Simon Johnston)
+* added MySQLMyISAMDialect and MySQLInnoDBDialect
+* added precision and scale mapping attributes, for numeric types in DDL
+* fixed a problem with duplicate column mappings on Sybase
+* read-write cache now uses version numbers to ensure consistency with database, if available
+* native SQL queries may now fetch a collection role (Steve Ebersole)
+* added sequential-select, optional and inverse attributes to <join/>
+* added <properties> element, which can be the target of a property-ref
+* fixed a bug relating to composite property-refs
+* Hibernate now much more robust if user does not implement equals()/hashCode() on id and unique key classes
+* enabled batch deletes for versioned data
+* fixed a minor bug in Session.close()
+* removed uuid.string and renamed uuid.hex to plain uuid
+* workaround for a MySQL bug in SchemaUpdate
+* added JDBCException.getSQL() and made various improvements to exception flow
+* createSQLQuery() now fully supports components
+* fixed a bug in SQL generation for <joined-subclass> mappings
+* fixed a bug where filter and query parameters could be bound in the wrong order (Steve Ebersole)
+* fixed a problem where quantifiers could not appear in SQL fragments
+* fixed a bug with dynamic components
+* fixed a bug where Dialect default properties overrode user-specified properties (Ben Sommerville)
+* fixed a bug where duplicate column name in a joined table caused an exception
+* implemented two-phase load for dynamic components
+* fixed a bug where cancelQuery() canceled a re-pooled statement
+* deleted collections are now removed from session-level cache
+* fixed a bug in LocaleType (Steve Ebersole)
+* use "with rr" to obtain UPGRADE locks in DB2
+* package attribute now significant for extends
+* fixed a minor problem with Hibernate Clobs and Blobs
+* extends attribute does no longer require specific ordering of mapping files
+
+Changes in version 3.0 alpha (23.8.2004)
+----------------------------------------
+* package rename net.sf.hibernate -> org.hibernate
+* checked exceptions are now runtime exceptions
+* some session methods deprecated and moved to org.hibernate.classic.Session
+* removed various deprecated functionality
+* added Filter API and mappings, for temporal, regional and permissioned data (Steve Ebersole, Gavin King)
+* support cascade delete via ON DELETE CASCADE constraint
+* added extra attributes to named query definition
+* added hibernate.use_identifier_rollback
+* added subselect mappings
+* added lazy="true" to property mappings
+* added <join/> for multitable mappings
+* added <union-subclass/> for table-per-concrete-class strategy
+* added Statistics API and JMX MBean (Gavin King, Emmanuel Bernard)
+* introduced new event-driven design (Steve Ebersole)
+* support for faster startup with Configuration.addCachableFile() (Joris Verschoor, Max Andersen)
+* mask connection password for log level greater of equals to info (Joris Verschoor, Emmanuel Bernard)
+* add check of named queries when building SessionFactory (Joris Verschoor, Emmanuel Bernard)
+* added custom EntityResolver setting capability (Emmanuel Ligne, Emmanuel Bernard)
+* PropertyValueException for null values in not-null properties of components (Emmanuel Bernard)
+* enhanced support for single- and no-argument sql-functions in HQL select clause (Michael Gloegl)
+* Added catalog element, to enable table names like catalog.schema.table (Michael Gloegl)
+* Added <sql-insert>, <sql-update> and <sql-delete> support (Max Andersen)
+* Support callable statements (stored procedures/functions) via callable="true" on custom sql (Max Andersen)
+* Added support for type parameters and typedefs (Michael Gloegl)
+* Added support for JDBC escape sequences in createSQLQuery (Max Andersen)
+* Added statistics per SessionFactory (Gavin King, Emmanuel Bernard)
+* Added a StatisticsService MBean for JMX publucation (Emmanuel Bernard)
+* support for updates via rownum in Oracle
+* fixed problems with SchemaUpdate
+* support for <column formula="..."/>
+* added hibernate.use_sql_comments
+* added property-ref to collection <key/>
+* fixed performance problems with <one-to-one property-ref=.../>
+* enhanced UserType with new methods assemble()/disassemble()
+* better algorithm for batch fetch batch sizes
+* added <dynamic-class>
+* added entity-name concept, and session methods save(entityName, object), update(entityName, object), etc
+* added framework in proxy package
+* native SQL queries may now fetch a collection role
+* added <loader/> for class and collection mappings
+* added getEntity() and getEntityName() to Interceptor
+* formula-based discriminators and association mappings
+* added "guid" id generation strategy
+* various improvements to dialects
+* <discriminator force="true"/> now acts as a filter on collections
+* where filters now apply in the on clause in an outer join
+* added hibernate.jdbc.factory_class to select a custom batcher
+* session now uses entity name + id to enforce uniqueness, instead of table name + id
+
+Changes in version 2.1.6 (9.8.2004)
+------------------------------------
+* fixed Quickstart/readme.txt instructions
+* fixed DB2/400 identity column support
+* fixed the scroll() query method
+* fixed exotic classloader problems with CGLIB
+* added insert="false" for discriminator columns which are part of a composite identifier
+* added several new configuration settings to JMX HibernateService
+* added new instantiate() method to SessionFactory.getClassMetadata()
+* improved the HSQL DB dialect with features from new version
+* added hibernate.jdbc.batch_versioned_data (Steve Ebersole)
+
+Changes in version 2.1.4 (2.6.2004)
+------------------------------------
+* improved Session serialization support by adding ability to serialize unflushed sessions (Steve Ebersole)
+* fixed Session.clear() functionality to clear the internal nonExists cache (Steve Ebersole)
+* much better implementation of scroll() (Steve Ebersole)
+* support "select new ..." for iterate() and scroll() (Steve Ebersole)
+* added support for multi-parameter SQL functions (Steve Ebersole)
+* fixed hbm2ddl generating infinite indexes on MySQL (Michael Gloegl)
+* fixed alias precedence in HQL queries, function names are second (Steve Ebersole)
+* added "transactional" as allowed cache concurrency strategy in XML configuration file
+* improved System.getProperties() with security exception warning in secure environments
+* improved Proxool integration, better property handling
+* fixed problem with use of getDefinedMethod() in secure environments (Ken Arnold)
+* fixed bug in createSQLQuery() which prohibited multiple aliases for the same entity (Max Andersen)
+* fixed query cache misses when using named bind parameters (Michael Greer)
+* recognize "left" and "right as keywords in SQL fragments
+* recognize SQL quoted identifiers in SQL fragments
+* improved identity handling on SQL Server by using scope_identity() for update counts (Arthur Fitt)
+* added DB2390Dialect for DB2/390 databases (Kristoffer Dyrkorn)
+* fixed a bug in toArray() of identifier bag collections (Khachchou Mohammed)
+* fixed a problem with DDL generation for serial columns in Informix
+* fixed a problem with DDL generation for timestamp columns in Informix (Michael Schmidt)
+* fixed a NPE that occurred calling saveOrUpdateCopy() for components
+* fixed a bug with replicate() and uninitialized collections
+* fixed a bug caching one-to-one associations
+* fixed eviction from named query cache regions
+
+Changes in version 2.1.3 (25.4.2004)
+-----------------------------------
+* added SELECT-clause SQL function support to main Dialects
+* fixed a problem where some unnecessary selects where issued for optional one-to-one associations
+* fixed a bug in SQL generation for criteria queries with multiple one-to-many joins
+* deprecated everything related to PersistentEnum
+* fixed an NPE that occurred when using <one-to-one property-ref> with composite ids
+* fixed a problem with JCA adaptor on WebLogic (Michael Gloegl)
+* improved behavior when removing elements from <idbag>s
+* fixed a bug in getGeneratedKeys() support (Michael Gloegl, Kevin Day)
+* fixed a bug when using Criteria queries with collections of joined-subclasses
+* fixed an NPE that occurred when calling comparator() on a lazy sorted set (Attila Szegedi)
+* fixed a bug when using setMaxResults() with native SQL queries in some Dialects
+* validate that composite id classes override hashCode() (Adrien)
+* fixed some minor problems with saveOrUpdateCopy()
+* fixed some problems in OSCache provider
+* fixed an NPE that occurred when calling a lazy collection after evicting from session
+* fixed an NPE that occurred when select-before-update is used with unversioned data (Patrick Peralta)
+* fixed a bug where dynamic-components could not be queried (Massimo Ferrari)
+* SQL formula parser now recognizes all Dialect-specific SQL functions (Anthony Patricio)
+* fixed a problem where SQL CASE statements could not appear in SQL formulas
+* fixed a problem where subselects with joins could not appear in SQL formulas
+* C3P0 and Proxool pools now cleaned up after SessionFactory.close()
+* fixed a bug where dirty checking of mutable properties was broken after lock()
+* fixed a minor bug where orphan delete was broken for newly saved instances
+* added Query.setFetchSize() and Criteria.setFetchSize()
+* PreparedStatement pooling in DBCPConnectionProvider can now be disabled (Emmanuel Bernard)
+* Query.setProperties(Object) now detects array and collection valued properties and delegates to Query.setParameterList() (Max Andersen, Nick Heudecker)
+* lengths of positional parameters and types arrays are now validated
+* fixed an obscure problem where a PreparedStatement was not closed
+
+Changes in version 2.1.2 (4.2.2004)
+-----------------------------------
+* added Session.isDirty()
+* fixed a very obscure concurrency problem with read-write cache for inverse collections
+* deprecated Criteria.returnMaps() / Criteria.returnRootEntities() in favor of new ResultTransformer framework
+* don't cache objects with dynamic-update="true" or <joined-subclass> mappings immediately after insert/update
+* added version checking to saveOrUpdateCopy()
+* fixed constraint violations that occurred when mixing identity columns with other id generation strategies
+* added Sybase 11.9.2 dialect to support older versions of Sybase that do not support ANSI joins (Colm O' Flaherty)
+* added Informix9Dialect (Finn McCann and Max Andersen)
+* added DB2400Dialect (Peter DeGregorio)
+* fixed a problem where mapping validation failure was reported as duplicate import (Michael Gloegl)
+* fixed a problem with Expression.not() in MySQL (Michael Gloegl)
+* added support for ResultSet.getGeneratedKeys() (David Morris, John Kristian)
+* added check attribute to allow check constraints in DDL
+* implicit polymorphism for Criteria queries (Shorn Tolley)
+* use IF EXISTS for dropping hilo tables (Michael Gloegl)
+* better exception report if deleted object is resaved by cascade
+* support nested components in Example queries (Emmanuel Bernard)
+* fixed a minor problem with onDelete() callbacks
+* fixed an obscure problem with select-before-update
+* added SunONETransactionManagerLookup (Robert Davidson)
+* fixed a problem with replicate() and <joined-subclass> mappings
+* made setParameterList() accept empty lists and deny null values (Max Andersen)
+* validation check on query parameters now allows setParameter(x, null) (Max Andersen)
+* added default-access to DTD (Max Andersen)
+* made Query.setParameterList() accept empty lists and deny null values (Max Andersen)
+* allow Query.setParameter(x, null) (Max Andersen)
+* queries with "select new" now cacheable
+* throw meaningful exception when lazy initialization occurs on disconnected session
+* added default-access to <hibernate-mapping> (Max Andersen)
+* added -text support to SchemaUpdate (Max Andersen, Matt Hall)
+* fixed broken implementation of embedded composite keys with createSQLQuery() (Max Andersen)
+* added hibernate.cache.use_minimal_puts config property to reduce unnecessary second-level cache puts
+* optimized performance of orphan delete detection (Bertrand Renuart)
+* fixed problem where unnecessary UPDATE occurred after INSERT for versioned objects with collections
+* WebSphereTransactionManagerLookup for WAS 5.1 (Edina Pimp)
+* Criteria queries now cacheable (Mario Ivankovits)
+* fixed problem with ordered, paginated queries in DB2 (Tim Collins)
+* fixed a bug caching <idbag>s
+* lazy="true" collections are now lazy even when available in cache
+* fixed a problem with version unsaved-value="negative"
+* added hibernate.cache.region_prefix config property (William Drai)
+* fixed problem where configuration input streams were not closed (Rajesh Patel)
+
+Changes in version 2.1.1 (17.12.2003)
+-------------------------------------
+* added optional package attribute to <hibernate-mapping>
+* added <meta-value> element to allow simpler <any> mapping
+* native SQL queries are now cacheable - added <synchronize> element to allow correct result set expiry
+* fixed a bug in CGLIB2 integration (Chris Nockleberg)
+* added NamingStrategy
+* don't cache objects with formula properties immediately after insert/update
+* log generated SQL to a special category
+* type of property with access="field" may now be guessed using reflection
+
+Changes in version 2.1 final (12.12.2003)
+-----------------------------------------
+* fixed a problem with CGLIB2 proxies and method calls inside constructors
+* fixed a bug running SchemaExportTask with mappings in jar files (Tom McCune)
+* allow custom persister declaration for subclasses (Nick Johnson)
+* fixed handling of sequences in SchemaUpdate on Oracle (Andrew Delpha)
+* fixed a bug where Iterator did not handle single null values correctly
+* detect and throw exception in the case of a duplicate property mapping
+* don't auto-create indexes for collection foreign keys (roll back to 2.0.x)
+
+Changes in version 2.1 rc1 (29.11.2003)
+---------------------------------------
+* long identifier and discriminator column names are now safely aliased (Max Andersen)
+* cleaned up mapping package to allow applications to manipulate metamodel programmatically
+* fixed a recent bug where collection sort order was lost in second-level cache
+* formula attribute now supported for joined-subclass mappings
+* formula properties may now be used anywhere in queries
+* dialect-specific query pagination for SQL Server
+* fixed a bug where a long path expression ending in collection access by index missed some tables in SQL FROM clause
+* fixed a very ancient performance problem where null one-to-one associations caused n+1 selects
+* added Session.saveOrUpdateCopy()
+* fixed some bugs in Example queries
+* fixed some minor bugs in dialect-specific query pagination
+* immutable entity passed to update() is now lock()ed instead
+* reworked the semantics of nonstrict-read-write
+* JCS cache support now deprecated
+* fixed some obscure bugs in collection handling
+* migrated to CGLIB2 (thanks to Chris Nockleberg)
+* fixed bugs in replicate()
+* fixed a bug affecting joined-subclass mappings with dynamic-update=true
+* performance improvements to boolean type mappings (Bertrand Renuart)
+* integrated JBoss TreeCache clustered cache (thanks to Bela Ban and Ben Wang)
+* fixed a bug in new query parameter validation (Steve Ebersole)
+* fixed a bug where <any> mappings caused unnecessary ObjectDeletedException at flush time
+* fixed a bug where associations with property-ref mappings were not properly cached
+* throw PropertyValueException when not-null properties are null at flush time
+* added unsaved-value attribute to version property mapping (Emmanuel Bernard)
+* tolerate classnames containing $ (Steve Ebersole)
+
+Changes in version 2.1 beta 6 (5.11.2003)
+-----------------------------------------
+* added Session.cancelQuery()
+* improvements to transaction handling for failed commit (thanks to Juergen Hoeller)
+* added cascade="delete-orphan"
+* fixed an exception that occurred when a property was declared not-null="true" update="false" (thanks to John Kristian)
+* support multiple named query cache regions (Mikheil Kapanadze)
+* some improvements to collection reattachment
+* fixed a bad bug with adds to an uninitialized bag or list
+* removed support for <dynabean/> components
+* added <dynamic-component/> mapping for properties of type Map
+* fixed a bug where schema export generated index names that were too long for DB2
+* allow per-region expiry policies in OSCache (Matthias Bogaert)
+* fixed a stack overflow that could occur while initializing nonlazy collections
+* fixed a bug in case-insensitive like for Example queries
+* fixed a bug in ScrollableResults.setRowNumber() (Martin Priekopa)
+* improvements to the cache concurrency strategies
+
+Changes in version 2.1 beta 5 (30.10.2003)
+------------------------------------------
+* Support for custom CollectionPersister (Nick Johnson, Max Andersen)
+* Support for named SQL queries (Max Andersen)
+* duplicate named queries now throws MappingException instead of just logging warning (Max Andersen)
+* fixed problems with WebSphereTransactionManagerLookup (Ralf Taugerbeck, Daniel Bradby)
+* added support for custom collection persisters (thanks to Max Anderson, Nick Johnson)
+* fixed a performance problem during query compilation (Bulent Erdemir)
+* composite keys now supported in createSQLQuery() (Max Andersen)
+* fixed JCA adaptor to run in WebLogic (Daniel Bradby)
+* integrated SwarmCache (Jason Carreira)
+* integrated OSCache (Matthias Bogaert)
+* fixed an NPE that could occur with lists and orphan delete
+* allow nullable one-to-one with property-ref
+* improved usage of Dialect-specific limit SQL
+* fixed problem where non-lazy collections held by cached objects were not immediately initialized
+* fixed getReturnTypes() for native SQL queries (Max Andersen)
+* fixed problems with Criterions that applied to multi-column properties
+* check of rowcounts when JDBC batch updates enabled
+* added named SQL queries using <sql-query> element (Max Andersen)
+* added some extra validations so Hibernate fails earlier when user makes mistakes
+* allow lazy="true" as an alternative to proxy="ClassName"
+* removed dependency to commons-lang
+* SchemaExport now creates indexes for collection foreign key columns if specified by Dialect
+* fixed a bug parsing named parameters in setParameterList()
+* select new Foo(...) will now tolerate null values if the constructor accepts a wrapper type
+* fixed a problem detecting Proxool
+* added logging of persistent object states during flush()
+* allow "not null" as a discriminator value
+* added "parameters" config param to "sequence" generator (Matthias Bogaert)
+
+Changes in version 2.1 beta 4 (3.10.2003)
+-----------------------------------------
+* fixed a bug where <any> mappings did not handle proxies correctly
+* implemented new optimistic-lock strategies
+* fixed several bugs in Criteria query API
+* fixed a bug caching property-ref associations
+* improvements to XML Databinder (Ara Abrahamian)
+* added Session.replicate() and ReplicationMode
+* added ScrollableResults.setRowNumber() / ScrollableResults.getRowNumber()
+* added query cache and Query.setCacheable()
+* added Criteria.returnMaps()
+* fixed some problems with CGLIB proxies
+* fixed an NPE that occurred when a joined-subclass of a versioned entity defined only collections
+* added the access attribute, direct field access and the PropertyAccessor extension point
+* added MatchMode for use with Criteria queries (thanks to Michael Gloegl)
+* fixed a bug where some lazy="false" collections were not immediately initialized
+* fixed problem with WebSphere 5 TransactionManager
+* support schema attribute in MySQL, by using an underscore in the table name (Chris Hane)
+* now seperate Dialects for Interbase and Firebird (Reha Cenani, Max Andersen)
+* removed built-in PreparedStatement cache
+* added Session.getSessionFactory()
+* fixed problem with native SQL queries and Query.setProperties() (Max Andersen)
+* Query now fully validates parameters against the query string before passing them to JDBC (Max Andersen)
+* fixed an NPE in SessionFactory.close()
+* fixed an NPE that occurred when using <idbag>s
+* added SQL-level query results paging to DB2Dialect
+* "foreign" id generator now handles detached instances
+
+Changes in version 2.1 beta 3 (7.9.2003)
+----------------------------------------
+* added Example queries
+* fixed an exception that occurred at startup with <key-many-to-one> and <joined-subclass>
+* fixed a bug where composite-elements were not being updated if a property not in the equals() was changed
+* <parent> property of a composite-element may now be used in equals()
+* named parameters may now be used in HQL order by clause
+* null value of version property now indicates unsaved instance
+* added select-before-update attribute
+* two-phase loading now use for components
+* better implementation of equals()/hashCode() for proxies
+* added property-ref attribute to <many-to-one>
+* renamed result() to uniqueResult()
+* added Session.get()
+* added HashtableCacheProvider
+* JTA TransactionManager now used even when not using Hibernate Transaction API
+* always bypass process-level cache for LockMode.READ
+
+Changes in version 2.1 beta 2 (27.8.2003)
+-----------------------------------------
+* <subclass> and <joined-subclass> may now appear outside of a <class> element, by providing the extends attribute (Max Andersen)
+* fixed an NPE at startup that was introduced in beta 1
+* fixed a bug in Map.putAll()
+* new pluggable cache API
+- deprecated <jcs-cache> in favor of <cache>
+- net.sf.hibernate.cache.CacheProvider settable via hibernate.cache.provider_class
+* more aggressive caching
+* added Hibernate.close(Iterator)
+* Criteria queries may now include joins
+- Criteria.addJoin()
+- Criteria.createCriteria()
+* hibernate.transaction.manager_lookup_class should now ALWAYS be specified in JTA environment when using jcs caching
+* fixed a bug caching <key-many-to-one>
+* fixed bug where cached component did not get <parent> property populated
+* added hibernate.max_fetch_depth property
+* smarter outer-join fetching
+* transient object may now be associated with session using Session.lock()
+* added Query.result(), Criteria.result()
+
+Changes in version 2.1 beta 1 (10.8.2003)
+-----------------------------------------
+* batch-size attribute for collection and class mappings, to allow batch loading
+* collections of "value types" (including composite-elements) may now appear in HQL from clause
+* more efficient loading of collections, and better handling of non-lazy collections
+* added HQL index() function to allow access to collection element index
+* added Session.createSQLQuery() (Max Andersen)
+* added outer-join attribute to collection mappings
+* Criteria.setFetchMode() now applies to collection-valued path expressions
+* added property-ref attribute to <one-to-one>, enabling unique foreign key associations
+* added hibernate.max_fetch_depth config property
+* added hibernate.hbm2ddl.auto config property
+* fixed a bug with combination of <jcs-cache> and <key-many-to-one>
+* support for Dialect-specific SQL functions in HQL select clause (David Channon)
+* added Session.clear()
+
+Changes in version 2.0.2 (2.8.2003)
+-----------------------------------
+* subqueries may now use HAVING and GROUP BY clauses
+* fixed a bug with setMaxResults(), setFirstResult() in HSQL (introduced in 2.0.1)
+* fixed a bug in Set.removeAll()
+* fixed a bug in SchemaUpdate (Mathias Bogaert)
+* added weak typing functionality to ScrollableResults
+* fixed a bug with "calendar" versioning in IBM JDK1.3.1 (workaround for JDK bug)
+* fixed a bug in mapping DTD that caused a problem for hbm2java (Max Andersen)
+* fixed a bug querying nested components
+* SQL generation now prefers ANSI-style inner joins to theta inner joins
+* fixed a bug caching collection references loaded using FETCH
+* fixed a bug with composite foreign keys in normalized table mappings (Tom Sedge)
+* limit support for Interbase (Ludovic Orban)
+* added where attribute to <class> mappings
+* added cascade="all-delete-orphan" for collection mappings
+* fixed a bug binding named parameters with setMaxResults()/setFirstResults()
+* fixed some minor bugs in HQL translator
+* fixed a long-standing bug where a <key-many-to-one> could not be dereferenced in HQL
+* SQL UPDATEs now occur in a predictable order (same order as objects were loaded)
+* support for SELECT ... FOR UPDATE in SAPDB
+* fixed bug where Criteria queries against a subclass also returned superclass instances
+* fixed a very rare bug where an update could get lost with normalized mappings
+* fixed a problem with proxied class heirarchies rooted at an interface or abstract class
+* where and order-by attributes now allow SQL function calls and subselects
+* added formula attribute to <property> tag, to allow "computed" properties
+* fixed a bug where PreparedStatements were sometimes not closed when an exception occured
+* workaround for a problem with <joined-subclass> and Interceptor.onFlushDirty()
+
+Changes in version 2.0.1 (17.6.2003)
+------------------------------------
+* fixed some problems with new dialect-specific LIMIT clauses
+* improved parsing of collection where attribute
+* made one-to-many bags more efficient (they are really sets!)
+* allowed type="calendar" for <version> properties
+* fixed a bug with locking a versioned composite-id class
+* refresh() may now take a transient instance
+* added ProxoolConnectionProvider (Martin Crawford)
+* fixed some minor JCA issues (Mike Mosiewicz)
+* fixed a bug with FETCH and sorted associations
+* improved performance of SchemaUpdate tool (Teodor Danciu)
+* fixed a bug in Configuration.addFile(String) (Ken Geis)
+* tidied up and documented hbm2ddl package (esp. Ant tasks)
+* deprecated CounterGenerator in favor of IncrementGenerator
+* improved logging during initialization
+* deprecated "vm" in favor of "increment" id generator
+
+Changes in version 2.0 final (8.6.2003)
+---------------------------------------
+* added "fetch" keyword to HQL
+* added evict() methods to SessionFactory for JVM-level cache
+* destroy caches from SessionFactory.close()
+* fixed an NPE in Session.evict() (Simon Spero)
+* added Query.setLockMode()
+* tidied up implementation of Loader
+* release ResultSets more aggressively
+* miscellaneous improvements to some Dialects
+* hbm2java now honors the sort attribute (Max Andersen)
+* added exceptions to Interceptor interface
+* fixed problem with setMaxResults(), setFirstResult() in Oracle (introduced in beta 6)
+* fixed some SQL generation that was a problem for Sybase (Dietmar Posselt)
+* fixed some problems with ODMG API (Oliver Gries)
+* added JOTMTransactionManagerLookup (Low Heng Sin)
+* added JOnASTransactionManagerLookup (?)
+* fixed a bug in WeblogicTransactionManagerLookup (Mathias Bogaert)
+* added Criteria.setFetchMode()
+* added new Expressions
+* much more elegant/robust handling of quoted identifiers
+* renamed Hibernate.association() to Hibernate.entity()
+* added dynamic-update and dynamic-insert mapping attributes
+* fixed a bug with refresh() of objects with collections
+* HQL aliases now optional - "from Cat" now legal
+* platform-independant quoting of identifiers using backticks
+
+Changes in version 2.0 beta 6 (10.5.2003)
+-----------------------------------------
+* fixed a bug querying one-to-many associations to a <joined-subclass>
+* added support for dialect-specific LIMIT-style clauses (David White)
+* added <idbag>
+* fixed bug in hashCode() of persistent collections
+* <joined-subclass> now supported in HSQL (Wolfgang Jung)
+* fixed problem for XML parsers which ignore default values declared in DTD
+* <meta> tags can now be set to not be inheritable
+* fixed bug in Expression.in()
+* fixed an NPE that could occur from update() in very strange cases (Chris Nockleberg)
+* disabled outer-join back to owner when initializing one-to-many (performance improvement)
+* fixed a bug in Query.setParameterList() (Nick Heudecker)
+* improved JCA support (Igor Fedorenko)
+
+Changes in version 2.0 beta 5 (21.4.2003)
+-----------------------------------------
+* Informix support (Steve Molitor)
+* fixed a bug parsing "select new ... " queries
+* deprecated "object" type in favor of <any> mappings
+* added Session.contains()
+* added extra DBCP config options (Alex Burgel)
+* SessionFactory.close() now unbinds from JNDI
+* added Session.evict()
+* got rid of an unnecessary SQL DELETE issued when an empty collection was dereferenced
+* where attribute of collection mappings no longer ignored for deletion
+* improved logging
+* support polymorphic associations to "embedded" composite id classes
+* various bugfixes to collection filter parameter binding
+* fixed some problems with proxies introduced in earlier beta versions
+* fixed bug with self-reference in the case of identity column id generation
+* added hibernate.cglib.use_reflection_optimizer property
+* added nonstrict-read-write cache
+* fixed an SQL-generation bug in new Criteria API
+* added CompositeUserType
+* sequence and table id generators now aware of default-schema
+* added update and insert attributes to <component> element
+* fixed a bug with expressions like elements(foo.bar.baz) in where clause
+* more efficient Set initialization (two-phase load)
+* removed support for hibernate.query.imports and added <import> mapping element
+* fixed problem in DBCP connection validation and added new config properties
+* hbm2java can now generate finder methods for persistent objects (experimental) (Matt Hall)
+* hbm2java small fixes/refactorings to support generating more than one file per persistent object (Max Andersen)
+
+Changes in version 2.0 beta 4 (22.3.2003)
+-----------------------------------------
+* Major HQL improvements
+- from "Foo as foo join foo.bars as bar" instead of "from foo in class Foo, bar in elements(foo.bars)"
+- "select new Foo(bar.name, bar.amount) from ...."
+- outer and full join support
+* Query methods now return this, to allow chaining
+* FrontBase support (Run Lussier)
+* experimental JCA support (Daniel Bradby)
+* hbm2java now can generate Beans style property events (Klaus Zimmermann)
+* support SQL identifiers quoted with []
+* fixed bug with PostgreSQL
+* name attribute now optional in .cfg.xml
+* support for postgres ilike operator (M Lang)
+* squash warnings with GNU JAXP (Chris Nockleberg)
+* fixed a bug in Query.setParameterList()
+* Ingres support (Ian Booth)
+* collections now detect changes not made via wrapper for newly saved objects
+* new (experimental) Criteria + Expression APIs
+* Query.setEntity(), etc, now aware of proxies (also improved hueristics for guessing Type)
+* added Hibernate.isInitialized()
+* detect changes made directly to newly-wrapped collection (ie. not via the wrapper)
+* added Hibernate.refresh(Object, LockMode)
+* update(), saveOrUpdate() no longer initialize a proxy
+* fixed problems with Sybase
+* added force attribute to <discriminator>
+* improved handling of null discriminator-value
+* support SQL-style '' escape for HQL strings
+
+Changes in version 2.0 beta 3 (24.2.2003)
+----------------------------------------
+* collections now represent null elements as a missing row
+* collections now deserialize correctly (fix for bug in beta 2)
+* standardised on dom4j for XML parsing
+* fixed bugs in collection caching (an exception occurred for some sorted collections and some kinds of maps)
+* allowed null discriminators
+* set autocommit to true in SchemaUpdate
+* fixed a stack overflow that could occur in toString() of classes created with hbm2java (Max Andersen)
+* fixed a bug where composite-element <parent> property was not being set after retrieval from cache
+* added where attribute to collection mappings to allow filtering
+* fixed a exception that occurred when wrapping collections with sort="MyComparator" (Jason Horne)
+* objects with mutable="false" are now never updated
+* fixed an exception that occurs with <key-many-to-one> association to a class with a composite id (Stefano Travelli)
+* added SchemaExport Ant task (Rong C Ou)
+* integrated latest CGLIB release (Juozas Baliuka)
+- added support for new CGLIB reflection optimizer (Juozas Baliuka)
+* improved query cache algorithm (Who?)
+* fixed a bug in "object" type
+* Lists and arrays now represent null elements as a missing row
+* fixed a bug in Hibernate PreparedStatement cache where maxRows and fetchSize were not cleared before re-caching
+* fixed a bug in HibernateService that caused a restart to fail
+* added SybaseAnywhereDialect (?)
+* added SessionFactory.close()
+
+Changes in version 2.0 beta 2 (2.2.2003)
+----------------------------------------
+* property column names may now be of any length (Mark Woon)
+* fixed problem where CodeGenerator created private get/set pairs (Max Andersen)
+* fixed all silly bugs in Configuration.configure()
+* efficient collection updates from Session.update()
+* added <jcs-class-cache> and <jcs-collection-cache> elements to hibernate-configuration.dtd
+* support for normalized mappings for databases with DECODE instead of CASE (Simon Harris)
+* added Oracle9Dialect
+* added JRun4TransactionManagerLookup (Joseph Bissen)
+* fixed JDBCException to keep reference to underlying SQLException
+* fixed a bug loading many-to-many associations with a repeated column name
+* fixed a bug in ShortType
+* added IngresDialect (Ian Booth)
+* added --config option to SchemaExport
+
+Changed in version 2.0 beta 1 (28.1.2003)
+-----------------------------------------
+* renamed packages to net.sf.hibernate.*
+* all API methods now wrap SQLExceptions
+* removed support for toplevel collections / subcollections
+* created hibernate-mapping-2.0.dtd
+- renamed 'readonly' attribute to 'inverse'
+- renamed 'role' attribute to 'name'
+- changed default value for 'unsaved-value' to "null"
+- added mandatory 'name' attribute to <param>
+- added <meta> tag
+* created hibernate-configuration-2.0.dtd
+* brand new Configuration API, including exposed mapping package
+* completely reworked IdentifierGenerator framework
+- built-in generators now auto-detect the type (so integer identity columns are supported, for example)
+- parameters are now named
+- built-in strategies are renamed
+* expanded Interceptor interface
+* removed exceptions that occur if an object is saved or deleted multiple times in a session
+* added <parent> subelement to <composite-element> and <nested-composite-element>
+* collections except for <bag>s now implement by-value equals() and hashCode()
+* removed all deprecated methods
+* added Session.refresh()
+* added dynamic-update functionality
+* added update and insert attributes to <property> and <many-to-one> mappings
+* added elements(), indices(), size(), maxelement(), minelement(), maxindex(), minindex() collection functions to query language
+* huge improvements to CodeGenerator (Max Andersen)
+* enhanced outerjoin fetching support in queries
+* experimental support for DynaBeans as components
+
+Changes in version 1.2.3 (28.1.2003)
+------------------------------------
+* fixed a recently-introduced problem with Timestamp dirty checking
+* added createClob(), createBlob() for streams (Benoit Menendez)
+* SchemaUpdate now configures Dialect correctly (Michael Locher)
+* update() now working for classes with embedded composite ids
+* unsaved-value attribute now recognized for <composite-id>
+* fixed a minor problem where a very specific kind of SQL select did not qualify a column name
+* added Query.getQueryString()
+* fixed an NPE that sometimes occurred when hibernate.connection.username was not specified
+* fixed a bug in SchemaExport where foreign key constraints did not use qualified tablenames
+* added isFirst(), isLast() to ScrollableResults
+* fixed bug finding properties inherited by mapped interfaces
+
+Changes in version 1.2.1b (4.1.2003)
+------------------------------------
+* fixed an NPE that occurred while loading Hibernate classes in IBM JVM
+* arbitrary JNDI InitialContext properties may now be passed as hibernate.jndi.*
+* fixed a problem where index column was not being nullified when an entity was removed from a one-to-many
+
+Changes in version 1.2.1 (31.12.2002)
+-------------------------------------
+* Changed the MySQL mapping of Hibernate "timestamp" to MySQL "DATETIME" (Matthias Schwinn)
+* TransactionManagerLookup classes now define defaut UserTransaction JNDI names
+* support for WebSphere 5 (Venkat Srinivasan)
+* fixed a bug with query expressions of the form "foo.bar.id" for normalized mappings
+* experimental Blob/Clob support (thanks to Benoit Menendez and Mark Woon)
+* improvements to SchemaUpdater (Benoit Menendez)
+* deprecated suspendFlushes() / resumeFlushes() in favor of FlushMode
+* deprecated IDGenerationException in favor of IdentifierGenerationException
+* fixed a bug introduced in 1.2 final where cascade save-update was sometimes ignored for readonly="true" bags
+* fixed a bug caching null-valued one-to-one associations
+* CodeGenerator now supports <bag> and <joined-subclass>
+* fixed problem with TimestampType on DB2 (Jonas)
+* fixed a bug in generated SQL for collections with <joined-subclass> mappings (Robson Miranda)
+* fixed a bug caching Maps (Benoit Menendez)
+* SchemaExport now accepts a .jar file as a source of mappings
+* hibernate.dbcp.validationQuery setting (Juozas Baliuka)
+* hibernate.c3p0.validate setting
+* added Query.setTimeout()
+* setMaxResults() now behaves sensibly on SAPDB (Russel Smyth)
+* added Query.setProperties() and Query.getNamedParameters(), fixed a bug in Query.getReturnTypes()
+* CodeGenerator now generates equals() and hashCode() for composite-id classes (and toString() for all classes)
+* CodeGenerator now includes superclass properties in subclass constructors (Max Andersen)
+* added Hibernate.custom()
+
+Changes in version 1.2 final (7.12.2002)
+----------------------------------------
+* fixed a bug where uppercase IS NOT NULL, NOT IN, etc were not parsed correctly
+* addition to readonly="true" bags now no longer requires collection initialization
+* added ResinTransactionManagerLookup (Aapo Laakkonen)
+* improved exception message when setting null to primitive type (Max Andersen)
+* improved exception message for an unserializable identifier
+* support for overloaded setter methods (patch by Alex Staubo)
+* CodeGenerator support for <composite-element> (patch by Wolfgang Jung)
+
+Changes in version 1.2 beta 4 (29.11.2002)
+------------------------------------------
+* fixed bugs in one-to-many associations to a <joined-subclass>
+* LockMode class now properly serializable
+* exceptions thrown by proxied objects are now propagated correctly (rather than being wrapped)
+* made Calendar types compilable in JDK1.2
+* added --format and --delimiter options to SchemaExport (thanks to Richard Mixon)
+* fix for problem with class with no properties + native id generation + MS SQL Server contributed by Max Andersen
+* fixed a BAD bug in Hibernate.configure() (thanks to Rob Stokes)
+* CodeGenerator now recognizes <key-many-to-one> (patch by Wolfgang Jung)
+* CodeGenerator now recognizes <version> and <timestamp> (patch by Max Andersen)
+
+Changes in version 1.2 beta 3 (26.11.2002)
+------------------------------------------
+* fixed bug in UPDATE SQL generation for <joined-subclass> mapping strategy (fix by Robson Miranda)
+* support <composite-id> correctly in CodeGenerator (patch by Tom Cellucci)
+* fixed an exception that occurred with short qualified tablenames
+* added the polymorphism attribute to the <class> element
+* allow "not between", "not in" in query language
+* allow subqueries beginning with a from clause in query language
+* query expressions like "not (foo.bar.baz=1)" now translated to "(bar.baz!=1 and foo.bar=bar.id)"
+* support for PostgreSQL ~ operator (regular expression match)
+* load(id, lockMode) now working for normalized table mappings
+* now compiling properly under JDK1.2, 1.3 (fix by Tom Cellucci)
+* support for subcollections in query language: foo.bars[2]['index'], foo.bars[4].elements, foo.bars[0].size, etc.
+* added calendar and calendar_date types
+* find() queries may now return scalar values
+* component-type properties may appear in a select clause
+* ConnectionProviders now set isolation level before toggle autocommit
+* Iterator.next() now throws NoSuchElementException as per Iterator contract (fix by Alex Staubo)
+* database reverse engineering GUI tool contributed by Tom Cellucci
+* SchemaExport now generates column in mapping file order (rather than alphabetical order)
+* <joined-subclass> mappings working on Oracle (?)
+
+Changes in version 1.2 beta 2 (15.11.2002)
+------------------------------------------
+* support multi-argument SQL functions in queries
+* reintroduced deprecated form of update() with slightly altered semantics
+* fixed BAD problem in the generated SQL for certain queries
+* added OrionTransactionManagerLookup
+
+Changes in version 1.2 beta 1 (11.11.2002)
+------------------------------------------
+* Fixed a bad bug binding to JNDI with servers that use serialization in preference to getReference()
+* support for quoted SQL identifiers (patch by Jean-Francois Nadeau)
+* Hibernate.initialize() allows the user to force initialization of a proxy or persistent collection
+* fix to minor bug in CodeGenerator by Max Andersen
+* fixed a problem with outerjoin fetching of one-to-one associations defined on subclasses
+* fixed a minor problem with proxies of classes that override finalize()
+* finished work on normalized table mappings using <joined-subclass> declaration (only for databases with ANSI OUTER JOIN and CASE)
+* deprecated hibernate-mapping.dtd in favor of hibernate-mapping-1.1.dtd
+* reworked unmapped class / interface / table-per-concrete-class query functionality, fixing several problems
+* removed deprecated methods
+* deprecated findIdentifiers()
+* fixed some problems with embedded composite identifiers
+* fixed a bug cascading deletes to one-to-one associations
+* CodeGenerator now generates isFoo() style getters for boolean properties (patch by Aapo Laakkonen)
+* components may now have a nonpublic constructor (patch by Jon Lipsky)
+* changes / bugfixes to MapGenerator tool
+* experimental SchemaUpdate tool contributed by Christoph Sturm
+
+Changes in version 1.1.8 (30.10.2002)
+-------------------------------------
+* full support for composite keys in query language
+* fixed bug where character type could not be null
+* fixed bug parsing collection filters like: "group by this.date"
+* fixed a bad bug where C3P0 properties were not always being used
+* replaced hibernate.use_jdbc_batch with hibernate.jdbc.batch_size
+* renamed some other properties to hibernate.jdbc.*
+* made hibernate.show_sql settable from JMX (patch by Matas Veitas)
+* added SessionFactory.getAllClassMetadata(), getAllCollectionMetadata (patch by Max Andersen)
+* allowed use of concrete-class proxies with inherited classes ie. <subclass name="ConcreteClass" proxy="ConcreteClass">
+* HibernateException extends Apache commons lang NestableException (patch by Max Andersen)
+* <parent> subelement of <component> allows a component to get a reference back to owning entity
+* Query.setParameterList() to bind lists of values to "in (:list)"
+* Java constants may now be used in Queries
+* serialization of an object graph now removes all initialized proxies
+* several other improvements to proxy handling
+* proxies may now be used in JDK 1.2
+
+Changes in version 1.1.7 (25.10.2002)
+-------------------------------------
+* added Session.createFilter() 
+* fixed a bug parsing queries with properties of form idXXX (introduced in 1.1.6)
+* fixed a bug parsing queries with the id property named in the select clause (introduced in 1.1.6)
+* fixed a bug dirty checking big_decimal (fix by Andrea Aime)
+
+Changes in version 1.1.6 (24.10.2002)
+-------------------------------------
+* classes without subclasses may now declare themselves as their own proxy
+* outer-join attribute now working for component properties and <many-to-many>
+* outer-join="true" will now force outerjoin loading for an association even if associated class has a proxy
+* enabled oracle-style outerjoins for SAP DB
+* version properties may now be long or short (previously always integer)
+* discriminators may now be boolean type
+* fixed the foo.bar.id.baz syntax for queries doing composite-key joins
+* fixed an NPE that occurred when no Dialect was specified
+* CodeGenerator now fully proxy-aware (patch by Max Andersen)
+* removed dependency upon trove4j
+
+Changes in version 1.1.5b (20.10.2002)
+--------------------------------------
+* fixed an NPE that occurred on JMX startup
+* smarter fetching for one-to-one associations
+
+Changes in version 1.1.5 (19.10.2002)
+-------------------------------------
+* added built-in currency and timezone types
+* hibernate-mapping-1.1.dtd
+- added <index-many-to-many> and <composite-index> subelements of <map>
+- added <key-property> and <key-many-to-one>
+- renamed "save/update" to "save-update"
+- tightened up the dtd (now using enumerated attribute types)
+* enabled multi-column map indexes (ie. key of a Map)
+* composited-id may now include a many-to-one association
+* improvements to Databinder contributed by Brad Clow
+* fixed bugs in minIndex, maxIndex, minElement, maxElement
+* fixed a problem with JTATransaction in a JBoss BMT bean
+* added addMapResource() to the MBean
+* minor improvements to Configuration
+* more accurate cache entry timestamping to increase the likelihood of cache hits
+* JCS cache may now be used with JTATransaction in WebSphere, Weblogic, JBoss (thanks to Matt Baird)
+* improvements to CodeGenerator contributed by Andrea Aime
+* stopped a TransientObjectException that was being thrown when it shouldn't be
+* re-enabled primary key export for tables of sets with not-null elements
+* hibernate.statement.fetch_size configuration contributed by Matas Veitas
+* added Interceptor application callback interface
+* added metadata package to expose persistence metadata to the application
+* changed filter() argument type from Collection to Object to allow filtering of arrays and Maps
+* added <column> index attribute to allow table indexes to be specified in mapping document
+* implemented support for queries against interfaces and abstract superclasses
+
+Changes in version 1.1.4b (4.10.2002)
+-------------------------------------
+* fixed problems for JDK1.2 (thanks to Chris Webb)
+
+Changes in version 1.1.4 (4.10.2002)
+------------------------------------
+* New locking API
+* disabled 2-phase load for objects contained in Sets (because they should be initialized before equals() or hashCode() is called)
+* fixed a bug where non-serializable cache entries could not be cached by JCS auxiliary cache
+* fixed a bug in dirty checking PersistentEnums
+* deprecated getID() in favor of getIdentifier() (for mainly cosmetic reasons)
+* HibernateService may now be subclassed to obtain mapping files by some other mechanism (patch by Chris Winters)
+
+Changes in version 1.1.3 (1.10.2002)
+------------------------------------
+* new 2-phase loading process (replaces complicated "deferred" loading process)
+* new ScrollableResults interface for efficiently navigating Query results
+* removed deprecated interfaces
+* created engine package to hold "internal" APIs (ie. the external contract of the impl package)
+* fixed bug where a component defined before all collections in the mapping file caused collections to not be persisted (thanks to Michael Link)
+* fixed a bug where cascaded saveOrUpdate was ignoring the unsaved-value setting
+* faster Timestamp dirty checking
+
+Changes in version 1.1.2 (29.9.2002)
+------------------------------------
+* added persister attibute of class mapping to support custom persistence strategies
+* Support for Oracle outerjoins contributed by Jon Lipsky
+* Reworked versioning, fixing bugs (and tightening tests)
+* Fixed a bug where an ObjectNotFoundException was thrown for null one-to-one associations
+* fixed problems with timestamps introduced in 1.1.1
+* added batch file for running demo
+
+Changes in version 1.1.1 (27.9.2002)
+------------------------------------
+* Major refactoring / abstraction of persistence logic
+* added maxIndex, minIndex, maxElement, minElement properties for collections
+* added support for class names in where clause of queries
+* fixed a bug where an association could become null after caching
+* fixed a bug where an NPE could occur for a null component
+* fixed minor bugs in SortedMap, SortedSet
+* object type is now cacheable
+* added big_integer type
+* improved dirty checking for timestamp type
+
+Changes in version 1.1.0 (22.9.2002)
+------------------------------------
+* implemented collection indexing with [] in query language
+* fixed some minor query-language bugs
+
+Changes in version 1.1 beta 14 (19.9.2002)
+------------------------------------------
+* bags now implement java.util.List
+* delete() may now take a transient object
+* bug where sorted collections were not being sorted fixed by Brad Clow
+* fixed a bug in many-to-many association filtering
+* no longer try to query connection metadata when using user-supplied connections
+* added hibernate.use_scrollable_resultsets for user-supplied connections
+* fixed a problem where sublists were not being proxied
+* fixed a problem where Hibernate could not call methods of package-visibility classes
+* removed obsolete select attribute from MapGenerator
+* multiple occurrences of same path in a query no longer require multiple joins
+* added WrongClassException
+
+Changes in version 1.1 beta 13 (15.9.2002)
+------------------------------------------
+* added constants to Lifecycle interface
+* fix for circular cascade="save/update"
+* fixed a bug in cascaded update introduced in version 1.1 beta 11
+* added object type
+
+Changes in version 1.1 beta 12 (14.9.2002)
+------------------------------------------
+* Session.filter() for applying a filter query to collections
+* experimental ODMG API (OQL features are not yet compliant)
+* new DBCPConnectionProvider for Apache commons-dbcp connection pool
+* Session.lock() now does version number check even on databases with no FOR UPDATE clause
+* introduced new cascade styles: cascade="save/update", cascade="delete"
+* added default-cascade attribute
+* foreign key columns lengths now automatically set to primary key column lengths for SchemaExport
+* added error checking of row update counts when batching disabled
+* major improvements to ProxyGenerator tool
+* CodeGenerator now aware of proxy attribute
+* integrated PointbaseDialect contributed by Ed Mackenzie
+* fix for problem where Proxies were being initialized on identifier access by Christoph Sturm
+
+Changes in version 1.1 beta 11 (7.9.2002)
+-----------------------------------------
+* deprecated update() in favor of saveOrUpdate() and introduced unsaved-value attribute of <id>
+* children mapped with cascade="all" are now always saved/updated even without a call to update(parent)
+* support for composite-id classes where the composite id consists of properties of the persistent class
+* added constrained attribute to <one-to-one> element
+* added Validatable interface
+* renamed several config properties (Hibernate issues log warnings for obsolete property usage)
+* arbitrary JDBC connection properties may now be passed using hibernate.connection.*
+* fixed a classloading bug in C3P0ConnectionProvider (introduced in 1.1 beta 10)
+* CodeGenerator may now take multiple mapping files on the commandline
+
+Changes in version 1.1 beta 10 (28.8.2002)
+------------------------------------------
+* fixed a bug that occurred when calling Session.update() for an object with no properties
+* changed class loading to use the context classloader first
+* introduced <timestamp> as an alternative to <version>
+* added Query.getReturnTypes()
+* fixed a bug with composite-elements introduced in 1.1 beta 7
+* save() may now be used to persist classes with composite-ids
+* improved handling of nanoseconds values in Timestamps
+* support for composite id properties + objects in select clause of iterate()
+* beefed-up collection tests
+
+Changes in version 1.1 beta 9 (26.8.2002)
+-----------------------------------------
+* fixed a bug introduced in 1.1 beta 8 that could cause an NPE after deserializing a session with proxies
+* deprecated insert() in favor of more flexible save()
+* deprecated IDGenerator in favor of new IdentifierGenerator interface
+* "assigned" id generator now returns the existing value of the id property instead of throwing an Exception
+* fixed a problem where PreparedStatements were not being recached after retrieving a natively generated id
+
+Changes in version 1.1 beta 8 (25.8.2002)
+-----------------------------------------
+* fixed a bug introduced in 1.1 beta 6 where an updated element of an indexed one-to-many collection caused an SQLException
+* uninitialized collections passed to update() may now be initialized in the new Session
+* uninitialized proxies passed to update() may now be initialized in the new Session
+
+Changes in version 1.1 beta 7 (23.8.2002)
+-----------------------------------------
+* fixed a bug where Hibernate was not returning statements to the cache when batch updates were disabled
+* fixed a bad bug parsing mappings with toplevel one-to-many associations
+* fixed a bug with versioning and subcollections
+* reworked Set updates again for much improved efficiency
+* schema export now creates primary keys for indexed collection tables
+* minor refactor to Type hierarchy
+* improved some user-error detection
+* fixed foreign key constraint creation for MySQL with Innodb tables
+
+Changes in version 1.1 beta 6b (20.8.2002)
+------------------------------------------
+* Fixed a problem updating Sets
+* added <bag> mapping for java.util.Collection
+
+Changes in version 1.1 beta 6 (20.8.2002)
+-----------------------------------------
+* completely reworked fetching code
+- one-to-many associations now always fetched in a single select
+- many-to-many associations fetched in a single select when outerjoin fetching is enabled 
+- this includes nested outerjoin fetching of the associated class!
+- outerjoin fetching for <many-to-one> nested inside <component> or <composite-element>
+- code refactored to be cleaner and faster
+* removed unnecessary order by clause in List and array fetching SQL
+* collections now individually update, insert and delete only rows that changed (thanks to Doug Currie)
+* fixed a problem where exceptions were being wrapped in a LazyInitializationException for non-lazy collections
+* added order-by attribute to <set> and <map> to specify a table column as defining the iteration order (JDK1.4 only)
+* improved error detection in Session.update()
+* further usage of JDBC2 batch updates
+* some fine-tuning of JDBC2 feature usage configuration
+* CodeGenerator will now generate components and arrays
+* fixed problem where CodeGenerator could not generate classes in the default package
+* improved logging of flush() activity
+* renamed property hibernate.use_jdbc2 to hibernate.use_jdbc_batch
+
+Changes in version 1.1 beta 5 (13.8.2002)
+-----------------------------------------
+* hibernate.query.imports property to allow use of unqualified classnames in queries
+* fixed a bug in collection flushing that was introduced in 1.1 beta 4
+
+Changes in version 1.1 beta 4 (11.8.2002)
+-----------------------------------------
+* JMX integration (thanks to John Urberg)
+* "having" clause in query language
+
+Changes in version 1.1 beta 3 (10.8.2002)
+-----------------------------------------
+* removed the select="all" attribute for <class> mappings - "select distinct" now specified in the hibernate query
+* system properties now override hibernate.properties
+* Session now flushes changes even less often (only when actual updates to the queried table(s) are waiting)
+* fixed a *very* rare problem where an unnecessary update could be accidently issued before a delete
+
+Changes in version 1.1 beta 2 (6.8.2002)
+----------------------------------------
+* fixed a bug exporting schemas with identity columns
+* implemented factory-level caching of collections
+* Datastore.storeJar() contributed by Christian Meunier
+* added <mapping jar="jarfile"> to hibernate.cfg.xml
+
+Changes in version 1.1 beta 1 (4.8.2002)
+----------------------------------------
+* new Query API including named parameters, pageable results
+* subqueries in Hibernate queries (only for databases that support subselects)
+* new DocBook documentation (contributed by Christian Bauer)
+* support collections .elements, .indices inside select clause (even in aggregate functions)
+* don't load collections before removal unless absolutely necessary
+* mutable="false" attribute in <class> element to map immutable classes
+* use JDBC batch to insert collection elements if hibernate.use_jdbc2 is set
+* brand new PreparedStatementCache
+* improvements to MYSQL dialect for long datatypes
+* always check isAccessible() before setAccessible(true)
+* removed extra unnecessary table join in queries with one-to-many association
+* removed ugly "WHERE 1=1" from generated SQL
+* fixed exception mapping a class with no properties (fix by Rob Stokes)
+* logging enhancements including SQLException logging
+* reworked factory-level cache and integrated JCS support (thanks to Christian Meunier)
+* fixed a bug with circular references in cached data
+* removed blocking cache support
+* now rendering outerjoins as "LEFT OUTER JOIN" because "LEFT JOIN" caused problems for some Sybase versions
+* added default Hibernate properties to Dialects
+* native id generation now falls back to sequence id generation when identity columns not supported by the dialect
+* fixed some problems with native id generation under HSQL
+* may now use Session.insert() even when using native id generation
+
+Changes in version 1.0.1b (18.7.2002)
+-------------------------------------
+* fixed a bad bug in query parser when hibernate.query.substitutions was unset
+* much improved build.xml Ant script
+* latest c3p0.jar
+
+Changes in version 1.0.1 (17.7.2002)
+------------------------------------
+* enabled use of scalar values and aggregate SQL functions in select clause of iterate() queries
+* fixed bug in JNDI lookup for SessionFactory
+* changed ordering of SQL inserts/deletes for child collections of a cascade-enabled association 
+- better behaviour for some not-null constraints
+- performance optimization for bidirectional many-to-one associations
+* added hibernate.query.substitutions property to allow named query constants (eg. translate 'true' to '1')
+* added locale type for java.util.Locale
+* added sequence hi/lo generator (seqhilo.long)
+* fixed bug where load(), onLoad() callbacks were sometimes called at wrong time
+* fixed an exception (fix by Eric Everman) and improved identifier searching in MapGenerator tool 
+* refactored SerializableType
+* extra logging + error handling
+* documentation enhancements
+
+Changes in version 0.9.17 (3.7.2002)
+------------------------------------
+* Added UserType interface
+* documented Lifecycle
+* added some new trace messages to log
+* bugfix to allow SQL functions like upper(), lower(), etc to work on all platforms
+* documented SAP DB support (dialect contributed by Brad Clow)
+* foreign key constraint export for SAP DB
+* map index may be the composite-id of the element class (contributed by Jon Lipsky)
+* fixes to CodeGenerator tool (contributed by Uros Jurglic)
+
+Changes in version 0.9.16 (19.6.2002)
+------------------------------------
+* fixed bug cacheing objects with references to themselves
+* support for composite ids of classes with no id property
+* may now disable outer join (deep) fetching for an association by setting outer-join="false"
+* enabled outer join fetching for one-to-one
+* fixed a bug for mappings that specify class attribute of <one-to-many>
+* fixed a bug where Hashbelt did not expire cached data in a timely fashion
+* fixed a mistake in the mapping DTD
+* new user-error check in update()
+
+Changes in version 0.9.15 (15.6.2002)
+------------------------------------
+* one-to-one associations
+* support for "tricky" mappings in SchemaExport tool (multiple properties to one column, etc)
+* Transaction API contributed by Anton van Straaten
+* SessionFactory may be bound to JNDI name by setting hibernate.session_factory_name
+* Sessions are now Serializable!
+* added Session.findIdentifiers() query methods
+* new Lifecycle interface to replace deprecated PersistentLifecycle
+* fixed problem where session did not autoflush on iterate() queries
+* performance enhancements to collection dirty checking
+* added Hibernate.configure() and configuration file format
+* removed some deprecated methods
+* refactored Type hierarchy
+* query language identifiers now case sensitive (bugfix for case sensitive SQL dialects)
+* username/password now optional for datasource (contributed by Emmanuel Bourg)
+* much improved API documentation
+* binary types now saved using streams if hibernate.use_streams_for_binary=true (contributed by Jon Lipsky)
+* MySQL Strings now mapped to TEXT columns if length > 255 (contributed by Christoph Beck)
+
+Changes in version 0.9.14 (4.6.2002)
+-------------------------------------
+* lifecycle objects - properties now have a cascade attribute to cascade save, update, delete
+* composite id properties may now be used in queries eg. foo.id.bar (contributed by Jon Lipsky)
+* slightly changed semantics of update() so it now also save()s new transient instances
+* Session now flushes() itself less often before query execution (performance enhancement)
+* fixed problem where Session.save() returned null instead of the natively generated id
+* fixed bug with object identity for cached classes
+* fixed bug where delete(x) could not be called after update(x)
+* MUCH improved Exception hierarchy
+* deprecated create()
+* added sql-type attribute to <column> tag to allow user to override default type mapping
+* deeper fetching with use_outer_join
+* new ConnectionProvider framework
+* fixed a bug where blocking cache could return stale data
+* now working again in JDK1.2.2
+* fixed problem with not-null associations + native key generation
+* minor changes to PersistentLifecycle interface
+* initial, minimal version of new Transaction mechanism
+* MUCH improved documentation
+
+Changes in version 0.9.13 (25.5.2002)
+-------------------------------------
+* Datastore.storeResource() to load mapping files from classpath
+* fixed a problem executing under JDK1.3 when compiled from JDK1.4
+* documentation improvements
+
+Changes in version 0.9.12 (24.5.2002)
+------------------------------------
+* Session.update() methods to update a persistent instance from transient copy (as requested by many users)
+* discriminator column name, type, length, etc now configurable by <discriminator> tag in mapping file
+* discriminator column values configurable by discriminator-value attribute of <class> and <subclass> tags
+* added Session.insert(object, id) for classes with no identifier property
+* fixed another bad bug with connection handling (fix by Anton van Straaten)
+* fixed a problem with deferred loading
+* fixed a problem with sorted collections (fix by Anton van Straaten)
+* nested collections of objects now require 2 SQL SELECTs to load, rather than size+1
+* session is NO LONGER atomic - application should discard session when exception occurs
+* fixed problem where character type was mapped to VARCHAR column
+* arrays of proxies now possible by using new element-class attribute of <array> tag
+* fixed various problems with proxies
+* added proxy generation tool
+* proxy unit tests
+* replaced two RuntimeExceptions with checked exceptions
+* made hibernate.username/hibernate.password optional for DriverManager
+* CodeGenerator now supports all hibernate basic types
+* much improved caching algorithm for compiled queries
+* may now specify properties simply by placing hibernate.properties in classpath
+* documentation improvements + fixes
+* --abstract switch to MapGenerator (contributed by Eric Everman)
+
+Changes in version 0.9.11 (12.5.2002)
+------------------------------------
+* fixed major bug with connection handling (fix by Anton van Straaten)
+
+Changes in version 0.9.10 (11.5.2002)
+------------------------------------
+* set a default schema name using SessionFactory property hibernate.default_schema
+* code generator tool contributed by Brad Clow (www.workingmouse.com)
+* lazy object initialization under JDK 1.3 and above
+* fixed some error messages to go to logging framework, not stdout
+* new system property hibernate.show_sql=true logs all executed SQL to stdout
+* integration of bugfixes in c3p0
+* wrap IllegalArgumentExceptions in HibernateExceptions
+* added ObjectNotFoundException and StaleObjectStateException
+* fixed a bug when using schemas
+* new caching strategy (and documented cache feature)
+
+Changes in version 0.9.9 (25.4.2002)
+-----------------------------------
+* sorted sets and maps (thanks to Doug Currie)
+* mapping files may now be loaded using getResourceAsStream() (thanks to Markus Meissner)
+* hibernate messages now logged by Apache commons-logging
+* default hi/lo generator table now has column named "next_id", instead of "next"
+* query language may now refer to identifier property name (eg. foo.fooKey as alternative to foo.id)
+* hibernate.jndi_class, hibernate.jndi_url now optional when using datasource
+* hibernate now throws an exception if you try to persist an object with a reference to a transient object
+* improved connection pooling algorithm (hibernate.pool_size limits pooled conections)
+* very experimental integration of c3p0 JDBC connection pool (http://sourceforge.net/projects/c3p0)
+* now compiles under JDK 1.2.2
+* fixed bug persisting null components
+* fixed bug where cached prepared statements were not cleaned up after disconnect() session
+* fixed a null pointer exception in MappingByReflection
+
+Changes in version 0.9.8 (13.3.2002)
+-----------------------------------
+* supports database native key generation in Sybase, MS SQL, MySQL, DB2, Hypersonic (contributed by Christoph Sturm)
+* supports Mckoi (dialect contributed by Doug Currie)
+* supports Progress (dialect contributed by Phillip Baird)
+* added exceptions to catch Session reentrancy from PersistentLifecycle.load() + store()
+* experimental cross-transaction cache
+* Session.lock() and Session.loadWithLock() for pessimistic locking
+* HiLoGenerators may now use their own DriverManager connection properties + may now use same table across diff mapping files
+* Session.flush(), Session.close() and Session.connection() replace Session.commit(), Session.cancel()
+* Session.disconnect() and Session.reconnect() for long transactions
+* added single JVM id generators vm.long, vm.hex
+* added unique column constraints to mappings
+* extensions to IDGenerator framework
+* support sequence-style ID generation in Oracle, PostgreSQL, DB2, Interbase
+
+* fixed problem where subcollections of a collection that changed roles would be deleted
+* changed class loading strategy to be compatible with JBoss
+* stopped queries retrieving unnecessary columns
+* mutable types (binary + serializable) now always detected as dirty
+
+Changes in version 0.9.7 (26.2.2002)
+-----------------------------------
+* save() now safe from foreign key violations (so create() is no longer preferred method of adding data)
+* delete() now completely safe from foreign key violations - it no longer matters what order objects are deleted in
+* removed Session.copy()
+* hilo generators now NOT for use with application server datasources
+
+* fixed two intermittent bugs in queries
+* fixed a problem where components not detected as dirty
+* fixed broken hilo generator which was not updating database
+* fixed a minor bug when hibernate.use_outer_join was set
+
+Changes in version 0.9.6 (24.2.2002)
+-----------------------------------
+* experimental XML generation
+* added support for bi-directional associations (one-to-set, set-to-set) with <set readonly="true"> config
+* reflective generation of mappings tool was contributed by Doug Currie
+* Session operations now atomic, so exceptions are recoverable
+* made ID properties optional in persistent classes
+* support for multiple schemas through schema attribute of <hibernate-mapping>, <class>, <set>, <map>, etc.
+* auto-creation of tables for hilo id generators (restriction: cannot use same table from more than one mapping file)
+* added some more assertions to catch user "mistakes" like deleting transient or saving persistent objects
+
+* major rework of collections and fixed some bad bugs
+* lazy initialization re-enabled for one-to-many associations (thanks to Georg Schneemayer)
+* fixed a problem in the mapping DTD to allow nested components in collections
+* fixed a BAD bug in RelationalDatabaseSession when loading objects with PersistentLifecycle callbacks (thanks to Paul Szego)
+* fixed problems with quoted strings in query language
+* fixed a bug where a stack overflow occurred instead of HibernateException thrown (thanks to Georg Schneemayer)
+* fixed a bug deleting updated versioned data
+* fixed some problems with name generation for indexes + foreign keys
+* fixed problem in Sun JDK 1.4 (only?) where IllegalArgumentException was not handled
+* minor improvements to handling of dates and times
+* HiLoGenerator now safe for all transaction isolation levels + safe when rollback occurs
+* noticed and fixed obscure piece of nonthreadsafe code outside of core persistence engine
+* removed unnecessary drop constraints for some dialects
+
+* MUCH more comprehensive test suite
+
+* changed some terminology used in documentation
+* added javadoc for API classes
+* commented the mapping DTD
+
+Changes in version 0.9.5 (8.2.2002)
+-----------------------------------
+* supports HypersonicSQL (dialect contributed by Phillip Baird)
+* supports Microsoft SQL server (with third party JDBC driver)
+* proper command-line tool for schema generation and export
+* deprecated the interface cirrus.hibernate.Persistent (due to popular demand)
+* changes to hibernate-mapping DTD (required to support optional Persistent interface):
+- deprecated <property type="package.PersistentClassName"/> in favor of <many-to-one class="package.PersistentClassName"/>
+- deprecated <element type="package.PersistentClassName"/> in favor of <many-to-many class="package.PersistentClassName"/>
+- deprecated <property role="..."/> in favor of <collection role="..."/>
+- deprecated <element role=".."/> in favor of <subcollection role="..."/>
+- deprecated <association> in favor of <one-to-many>
+* class attribute optional in <component> and <composite-id> tags (determined by reflection)
+* querying components of components now supported
+* one-shot table creation (no use of unportable "alter table")
+* time dataype support
+* reflective mappings of java.sql.Time, java.sql.Timestamp, java.sql.Date
+* fixed error msg thrown when class is missing a method but has a superclass
+* property names now conform to JavaBean spec ("foo" instead of "Foo"). Note that "Foo" still works
+* constructors of persistent classes may now be non-public
+* collection indexes now mapped to not-null columns
+* fixed obscure bug with querying collections inside components of components
+* fixed potential bug related to cacheing of compiled queries
+* major rewrite of code relating to O-R mappings
+* Session.copy() and Session.equals() as convenience for users
+* fixed repeated invocations of hasNext() on iterator + iterators now always work with distinct SQL resultsets
+* McKoi dialect was contributed by Gabe Hicks
+
+Changes in version 0.9.4 (29.1.2002)
+------------------------------------
+* fixed BAD bug where XML parsing would not work for parsers other than Xerces - thanks to Christian Winkler
+* added some more assertions to catch user "mistakes" like changing ids or reusing existing ids
+
+Changes in version 0.9.3 (27.1.2002)
+------------------------------------
+* repackaged (corrupted DatasourceConnectionProvider.class)
+* better exception reporting using datasource
+* added Datastore.storeClass() which looks for mapping file in classpath (class foo.Bar -> foo/Bar.hbm.xml)
+* improved documentation
+
+Changes in version 0.9.2 (25.1.2002)
+------------------------------------
+* iterate over query results (lazy instantiation of query results)
+* added "select foo, bar" style queries returning multiple objects per row
+* delete by query
+* composite key support
+* outer joins for faster (?) loading of associated objects ( set "hibernate.use_outer_join" to "true" )
+* connection pooling when using DriverManager
+* foreign key constraint from unkeyed collection table to owner entity table
+* improved drop tables script execution (still not infallible)
+* added <composite-element> tag
+* added not-null properties and elements
+* added an optimisation for dates and components
+* made some XML attributes optional
+* fixed errors in documentation + documented some extra features
+* bugfix: store() not getting called on lifecycle interface
+* bugfix: schema generation for indexed associations
+* added many tests
+
+Changes in version 0.9.1 (20.1.2002)
+------------------------------------
+Too many to list
+
+version 0.8.1
+-------------
+Initial alpha version
+

Deleted: core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml
===================================================================
--- core/trunk/connection-c3p0/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-c3p0</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate C3P0 ConnectionProvider</name>
-    <description>C3P0-based implementation of the Hibernate ConnectionProvder contract</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>c3p0</groupId>
-            <artifactId>c3p0</artifactId>
-            <version>0.9.1</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml (from rev 15003, core/trunk/connection-c3p0/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/connection-c3p0/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-c3p0</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate C3P0 ConnectionProvider</name>
+    <description>C3P0-based implementation of the Hibernate ConnectionProvder contract</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>c3p0</groupId>
+            <artifactId>c3p0</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml
===================================================================
--- core/trunk/connection-proxool/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-proxool</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Proxool ConnectionProvider</name>
-    <description>Proxool-based implementation of the Hibernate ConnectionProvder contract</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>proxool</groupId>
-            <artifactId>proxool</artifactId>
-            <version>0.8.3</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml (from rev 15003, core/trunk/connection-proxool/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/connection-proxool/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,31 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-proxool</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Proxool ConnectionProvider</name>
+    <description>Proxool-based implementation of the Hibernate ConnectionProvder contract</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>proxool</groupId>
+            <artifactId>proxool</artifactId>
+            <version>0.8.3</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/pom.xml
===================================================================
--- core/trunk/core/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/core/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,138 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-core</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Core</name>
-    <description>The core functionality of Hibernate</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>antlr</groupId>
-            <artifactId>antlr</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>commons-collections</groupId>
-            <artifactId>commons-collections</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>dom4j</groupId>
-            <artifactId>dom4j</artifactId>
-        </dependency>
-
-        <dependency>
-            <!-- YUCK, YUCK, YUCK!!!! -->
-            <groupId>javax.transaction</groupId>
-            <artifactId>jta</artifactId>
-            <version>1.1</version>
-        </dependency>
-        <dependency>
-            <groupId>javax.security</groupId>
-            <artifactId>jaas</artifactId>
-            <version>1.0.01</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>javax.security</groupId>
-            <artifactId>jacc</artifactId>
-            <version>1.0</version>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>ant</groupId>
-            <artifactId>ant</artifactId>
-            <version>1.6.5</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <!-- optional deps for bytecode providers until those are finally properly scoped -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>org.hibernate</groupId>
-            <artifactId>hibernate-cglib-repack</artifactId>
-            <version>2.1_3</version>
-            <optional>true</optional>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>antlr-maven-plugin</artifactId>
-                <version>${antlrPluginVersion}</version>
-                <configuration>
-                    <grammars>hql.g,hql-sql.g,sql-gen.g</grammars>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>generate</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>antlr-maven-plugin</artifactId>
-                <version>${antlrPluginVersion}</version>
-                <configuration>
-                    <!-- eventually should be based on the second phase grammar -->
-                    <grammars>hql.g</grammars>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <configuration>
-                    <!-- 
-                    for the time being, gonna ignore the custom stylesheet (what did it do anyway???) 
-                    <stylesheetfile>xyz</stylesheetfile>
-                    -->
-                    <groups>
-                        <group>
-                            <title>Core API</title>
-                            <packages>org.hibernate:org.hibernate.classic:org.hibernate.criterion:org.hibernate.metadata:org.hibernate.cfg:org.hibernate.usertype</packages>
-                        </group>
-                        <group>
-                            <title>Extension API</title>
-                            <packages>org.hibernate.id:org.hibernate.connection:org.hibernate.transaction:org.hibernate.type:org.hibernate.dialect*:org.hibernate.cache*:org.hibernate.event*:org.hibernate.action:org.hibernate.property:org.hibernate.loader*:org.hibernate.persister*:org.hibernate.proxy:org.hibernate.tuple:org.hibernate.transform:org.hibernate.collection:org.hibernate.jdbc</packages>
-                        </group>
-                        <group>
-                            <title>Miscellaneous API</title>
-                            <packages>org.hibernate.stat:org.hibernate.tool.hbm2ddl:org.hibernate.jmx:org.hibernate.mapping:org.hibernate.tool.instrument</packages>
-                        </group>
-                        <group>
-                            <title>Internal Implementation</title>
-			    <packages>org.hibernate.engine:org.hibernate.impl:org.hibernate.sql:org.hibernate.lob:org.hibernate.util:org.hibernate.exception:org.hibernate.hql:org.hibernate.hql.ast:org.hibernate.hql.antlr:org.hibernate.hql.classic:org.hibernate.intercept:org.hibernate.secure:org.hibernate.pretty</packages>
-                        </group>
-                    </groups>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
-
-    <properties>
-        <antlrPluginVersion>2.1</antlrPluginVersion>
-    </properties>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/pom.xml (from rev 15003, core/trunk/core/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,138 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-core</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Core</name>
+    <description>The core functionality of Hibernate</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>antlr</groupId>
+            <artifactId>antlr</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-collections</groupId>
+            <artifactId>commons-collections</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>dom4j</groupId>
+            <artifactId>dom4j</artifactId>
+        </dependency>
+
+        <dependency>
+            <!-- YUCK, YUCK, YUCK!!!! -->
+            <groupId>javax.transaction</groupId>
+            <artifactId>jta</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.security</groupId>
+            <artifactId>jaas</artifactId>
+            <version>1.0.01</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.security</groupId>
+            <artifactId>jacc</artifactId>
+            <version>1.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>1.6.5</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- optional deps for bytecode providers until those are finally properly scoped -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-cglib-repack</artifactId>
+            <version>2.1_3</version>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>antlr-maven-plugin</artifactId>
+                <version>${antlrPluginVersion}</version>
+                <configuration>
+                    <grammars>hql.g,hql-sql.g,sql-gen.g</grammars>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>antlr-maven-plugin</artifactId>
+                <version>${antlrPluginVersion}</version>
+                <configuration>
+                    <!-- eventually should be based on the second phase grammar -->
+                    <grammars>hql.g</grammars>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <!-- 
+                    for the time being, gonna ignore the custom stylesheet (what did it do anyway???) 
+                    <stylesheetfile>xyz</stylesheetfile>
+                    -->
+                    <groups>
+                        <group>
+                            <title>Core API</title>
+                            <packages>org.hibernate:org.hibernate.classic:org.hibernate.criterion:org.hibernate.metadata:org.hibernate.cfg:org.hibernate.usertype</packages>
+                        </group>
+                        <group>
+                            <title>Extension API</title>
+                            <packages>org.hibernate.id:org.hibernate.connection:org.hibernate.transaction:org.hibernate.type:org.hibernate.dialect*:org.hibernate.cache*:org.hibernate.event*:org.hibernate.action:org.hibernate.property:org.hibernate.loader*:org.hibernate.persister*:org.hibernate.proxy:org.hibernate.tuple:org.hibernate.transform:org.hibernate.collection:org.hibernate.jdbc</packages>
+                        </group>
+                        <group>
+                            <title>Miscellaneous API</title>
+                            <packages>org.hibernate.stat:org.hibernate.tool.hbm2ddl:org.hibernate.jmx:org.hibernate.mapping:org.hibernate.tool.instrument</packages>
+                        </group>
+                        <group>
+                            <title>Internal Implementation</title>
+			    <packages>org.hibernate.engine:org.hibernate.impl:org.hibernate.sql:org.hibernate.lob:org.hibernate.util:org.hibernate.exception:org.hibernate.hql:org.hibernate.hql.ast:org.hibernate.hql.antlr:org.hibernate.hql.classic:org.hibernate.intercept:org.hibernate.secure:org.hibernate.pretty</packages>
+                        </group>
+                    </groups>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <properties>
+        <antlrPluginVersion>2.1</antlrPluginVersion>
+    </properties>
+</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java (from rev 14992, core/trunk/core/src/main/java)

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/AssertionFailure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-//$Id: AssertionFailure.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-import org.hibernate.exception.NestableRuntimeException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Indicates failure of an assertion: a possible bug in Hibernate.
- *
- * @author Gavin King
- */
-
-public class AssertionFailure extends NestableRuntimeException {
-
-	private static final Logger log = LoggerFactory.getLogger(AssertionFailure.class);
-
-	private static final String MESSAGE = "an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)";
-
-	public AssertionFailure(String s) {
-		super(s);
-		log.error(MESSAGE, this);
-	}
-
-	public AssertionFailure(String s, Throwable t) {
-		super(s, t);
-		log.error(MESSAGE, t);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/AssertionFailure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/AssertionFailure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.exception.NestableRuntimeException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Indicates failure of an assertion: a possible bug in Hibernate.
+ *
+ * @author Gavin King
+ */
+public class AssertionFailure extends NestableRuntimeException {
+
+	private static final Logger log = LoggerFactory.getLogger( AssertionFailure.class );
+
+	private static final String MESSAGE = "an assertion failure occured" +
+			" (this may indicate a bug in Hibernate, but is more likely due" +
+			" to unsafe use of the session)";
+
+	public AssertionFailure(String s) {
+		super( s );
+		log.error( MESSAGE, this );
+	}
+
+	public AssertionFailure(String s, Throwable t) {
+		super( s, t );
+		log.error( MESSAGE, t );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/CacheMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: CacheMode.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Controls how the session interacts with the second-level
- * cache and query cache.
- *
- * @see Session#setCacheMode(CacheMode)
- * @author Gavin King
- */
-public final class CacheMode implements Serializable {
-	private final String name;
-	private final boolean isPutEnabled;
-	private final boolean isGetEnabled;
-	private static final Map INSTANCES = new HashMap();
-
-	private CacheMode(String name, boolean isPutEnabled, boolean isGetEnabled) {
-		this.name=name;
-		this.isPutEnabled = isPutEnabled;
-		this.isGetEnabled = isGetEnabled;
-	}
-	public String toString() {
-		return name;
-	}
-	public boolean isPutEnabled() {
-		return isPutEnabled;
-	}
-	public boolean isGetEnabled() {
-		return isGetEnabled;
-	}
-	/**
-	 * The session may read items from the cache, and add items to the cache
-	 */
-	public static final CacheMode NORMAL = new CacheMode("NORMAL", true, true);
-	/**
-	 * The session will never interact with the cache, except to invalidate
-	 * cache items when updates occur
-	 */
-	public static final CacheMode IGNORE = new CacheMode("IGNORE", false, false);
-	/**
-	 * The session may read items from the cache, but will not add items, 
-	 * except to invalidate items when updates occur
-	 */
-	public static final CacheMode GET = new CacheMode("GET", false, true);
-	/**
-	 * The session will never read items from the cache, but will add items
-	 * to the cache as it reads them from the database.
-	 */
-	public static final CacheMode PUT = new CacheMode("PUT", true, false);
-	
-	/**
-	 * The session will never read items from the cache, but will add items
-	 * to the cache as it reads them from the database. In this mode, the
-	 * effect of <tt>hibernate.cache.use_minimal_puts</tt> is bypassed, in
-	 * order to <em>force</em> a cache refresh
-	 */
-	public static final CacheMode REFRESH = new CacheMode("REFRESH", true, false);
-	
-	static {
-		INSTANCES.put( NORMAL.name, NORMAL );
-		INSTANCES.put( IGNORE.name, IGNORE );
-		INSTANCES.put( GET.name, GET );
-		INSTANCES.put( PUT.name, PUT );
-		INSTANCES.put( REFRESH.name, REFRESH );
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get( name );
-	}
-
-	public static CacheMode parse(String name) {
-		return ( CacheMode ) INSTANCES.get( name );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/CacheMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CacheMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Controls how the session interacts with the second-level
+ * cache and query cache.
+ *
+ * @see Session#setCacheMode(CacheMode)
+ * @author Gavin King
+ */
+public final class CacheMode implements Serializable {
+	private final String name;
+	private final boolean isPutEnabled;
+	private final boolean isGetEnabled;
+	private static final Map INSTANCES = new HashMap();
+
+	private CacheMode(String name, boolean isPutEnabled, boolean isGetEnabled) {
+		this.name=name;
+		this.isPutEnabled = isPutEnabled;
+		this.isGetEnabled = isGetEnabled;
+	}
+	public String toString() {
+		return name;
+	}
+	public boolean isPutEnabled() {
+		return isPutEnabled;
+	}
+	public boolean isGetEnabled() {
+		return isGetEnabled;
+	}
+	/**
+	 * The session may read items from the cache, and add items to the cache
+	 */
+	public static final CacheMode NORMAL = new CacheMode("NORMAL", true, true);
+	/**
+	 * The session will never interact with the cache, except to invalidate
+	 * cache items when updates occur
+	 */
+	public static final CacheMode IGNORE = new CacheMode("IGNORE", false, false);
+	/**
+	 * The session may read items from the cache, but will not add items, 
+	 * except to invalidate items when updates occur
+	 */
+	public static final CacheMode GET = new CacheMode("GET", false, true);
+	/**
+	 * The session will never read items from the cache, but will add items
+	 * to the cache as it reads them from the database.
+	 */
+	public static final CacheMode PUT = new CacheMode("PUT", true, false);
+	
+	/**
+	 * The session will never read items from the cache, but will add items
+	 * to the cache as it reads them from the database. In this mode, the
+	 * effect of <tt>hibernate.cache.use_minimal_puts</tt> is bypassed, in
+	 * order to <em>force</em> a cache refresh
+	 */
+	public static final CacheMode REFRESH = new CacheMode("REFRESH", true, false);
+	
+	static {
+		INSTANCES.put( NORMAL.name, NORMAL );
+		INSTANCES.put( IGNORE.name, IGNORE );
+		INSTANCES.put( GET.name, GET );
+		INSTANCES.put( PUT.name, PUT );
+		INSTANCES.put( REFRESH.name, REFRESH );
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get( name );
+	}
+
+	public static CacheMode parse(String name) {
+		return ( CacheMode ) INSTANCES.get( name );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/CallbackException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-//$Id: CallbackException.java 4242 2004-08-11 09:10:45Z oneovthafew $
-package org.hibernate;
-
-
-/**
- * Should be thrown by persistent objects from <tt>Lifecycle</tt>
- * or <tt>Interceptor</tt> callbacks.
- *
- * @see Lifecycle
- * @see Interceptor
- * @author Gavin King
- */
-
-public class CallbackException extends HibernateException {
-
-	public CallbackException(Exception root) {
-		super("An exception occurred in a callback", root);
-	}
-
-	public CallbackException(String message) {
-		super(message);
-	}
-
-	public CallbackException(String message, Exception e) {
-		super(message, e);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/CallbackException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/CallbackException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Should be thrown by persistent objects from <tt>Lifecycle</tt>
+ * or <tt>Interceptor</tt> callbacks.
+ *
+ * @see org.hibernate.classic.Lifecycle
+ * @see Interceptor
+ * @author Gavin King
+ */
+
+public class CallbackException extends HibernateException {
+
+	public CallbackException(Exception root) {
+		super("An exception occurred in a callback", root);
+	}
+
+	public CallbackException(String message) {
+		super(message);
+	}
+
+	public CallbackException(String message, Exception e) {
+		super(message, e);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ConnectionReleaseMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,77 +0,0 @@
-// $Id: ConnectionReleaseMode.java 8409 2005-10-14 20:28:18Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-/**
- * Defines the various policies by which Hibernate might release its underlying
- * JDBC connection.
- *
- * @author Steve Ebersole
- */
-public class ConnectionReleaseMode  implements Serializable {
-
-	/**
-	 * Indicates that JDBC connection should be aggressively released after each 
-	 * SQL statement is executed. In this mode, the application <em>must</em>
-	 * explicitly close all iterators and scrollable results. This mode may
-	 * only be used with a JTA datasource.
-	 */
-	public static final ConnectionReleaseMode AFTER_STATEMENT = new ConnectionReleaseMode( "after_statement" );
-
-	/**
-	 * Indicates that JDBC connections should be released after each transaction 
-	 * ends (works with both JTA-registered synch and HibernateTransaction API).
-	 * This mode may not be used with an application server JTA datasource.
-	 * <p/>
-	 * This is the default mode starting in 3.1; was previously {@link #ON_CLOSE}.
-	 */
-	public static final ConnectionReleaseMode AFTER_TRANSACTION = new ConnectionReleaseMode( "after_transaction" );
-
-	/**
-	 * Indicates that connections should only be released when the Session is explicitly closed 
-	 * or disconnected; this is the legacy (Hibernate2 and pre-3.1) behavior.
-	 */
-	public static final ConnectionReleaseMode ON_CLOSE = new ConnectionReleaseMode( "on_close" );
-
-
-	private String name;
-
-	private ConnectionReleaseMode(String name) {
-		this.name = name;
-	}
-
-	/**
-	 * Override of Object.toString().  Returns the release mode name.
-	 *
-	 * @return The release mode name.
-	 */
-	public String toString() {
-		return name;
-	}
-
-	/**
-	 * Determine the correct ConnectionReleaseMode instance based on the given
-	 * name.
-	 *
-	 * @param modeName The release mode name.
-	 * @return The appropriate ConnectionReleaseMode instance
-	 * @throws HibernateException Indicates the modeName param did not match any known modes.
-	 */
-	public static ConnectionReleaseMode parse(String modeName) throws HibernateException {
-		if ( AFTER_STATEMENT.name.equals( modeName ) ) {
-			return AFTER_STATEMENT;
-		}
-		else if ( AFTER_TRANSACTION.name.equals( modeName ) ) {
-			return AFTER_TRANSACTION;
-		}
-		else if ( ON_CLOSE.name.equals( modeName ) ) {
-			return ON_CLOSE;
-		}
-		throw new HibernateException( "could not determine appropriate connection release mode [" + modeName + "]" );
-	}
-
-	private Object readResolve() {
-		return parse( name );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ConnectionReleaseMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ConnectionReleaseMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * Defines the various policies by which Hibernate might release its underlying
+ * JDBC connection.
+ *
+ * @author Steve Ebersole
+ */
+public class ConnectionReleaseMode  implements Serializable {
+
+	/**
+	 * Indicates that JDBC connection should be aggressively released after each 
+	 * SQL statement is executed. In this mode, the application <em>must</em>
+	 * explicitly close all iterators and scrollable results. This mode may
+	 * only be used with a JTA datasource.
+	 */
+	public static final ConnectionReleaseMode AFTER_STATEMENT = new ConnectionReleaseMode( "after_statement" );
+
+	/**
+	 * Indicates that JDBC connections should be released after each transaction 
+	 * ends (works with both JTA-registered synch and HibernateTransaction API).
+	 * This mode may not be used with an application server JTA datasource.
+	 * <p/>
+	 * This is the default mode starting in 3.1; was previously {@link #ON_CLOSE}.
+	 */
+	public static final ConnectionReleaseMode AFTER_TRANSACTION = new ConnectionReleaseMode( "after_transaction" );
+
+	/**
+	 * Indicates that connections should only be released when the Session is explicitly closed 
+	 * or disconnected; this is the legacy (Hibernate2 and pre-3.1) behavior.
+	 */
+	public static final ConnectionReleaseMode ON_CLOSE = new ConnectionReleaseMode( "on_close" );
+
+
+	private String name;
+
+	private ConnectionReleaseMode(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * Override of Object.toString().  Returns the release mode name.
+	 *
+	 * @return The release mode name.
+	 */
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * Determine the correct ConnectionReleaseMode instance based on the given
+	 * name.
+	 *
+	 * @param modeName The release mode name.
+	 * @return The appropriate ConnectionReleaseMode instance
+	 * @throws HibernateException Indicates the modeName param did not match any known modes.
+	 */
+	public static ConnectionReleaseMode parse(String modeName) throws HibernateException {
+		if ( AFTER_STATEMENT.name.equals( modeName ) ) {
+			return AFTER_STATEMENT;
+		}
+		else if ( AFTER_TRANSACTION.name.equals( modeName ) ) {
+			return AFTER_TRANSACTION;
+		}
+		else if ( ON_CLOSE.name.equals( modeName ) ) {
+			return ON_CLOSE;
+		}
+		throw new HibernateException( "could not determine appropriate connection release mode [" + modeName + "]" );
+	}
+
+	private Object readResolve() {
+		return parse( name );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Criteria.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,338 +0,0 @@
-//$Id: Criteria.java 9116 2006-01-23 21:21:01Z steveebersole $
-package org.hibernate;
-
-import java.util.List;
-
-import org.hibernate.criterion.CriteriaSpecification;
-import org.hibernate.criterion.Criterion;
-import org.hibernate.criterion.Order;
-import org.hibernate.criterion.Projection;
-import org.hibernate.transform.ResultTransformer;
-
-/**
- * <tt>Criteria</tt> is a simplified API for retrieving entities
- * by composing <tt>Criterion</tt> objects. This is a very
- * convenient approach for functionality like "search" screens
- * where there is a variable number of conditions to be placed
- * upon the result set.<br>
- * <br>
- * The <tt>Session</tt> is a factory for <tt>Criteria</tt>.
- * <tt>Criterion</tt> instances are usually obtained via
- * the factory methods on <tt>Restrictions</tt>. eg.
- * <pre>
- * List cats = session.createCriteria(Cat.class)
- *     .add( Restrictions.like("name", "Iz%") )
- *     .add( Restrictions.gt( "weight", new Float(minWeight) ) )
- *     .addOrder( Order.asc("age") )
- *     .list();
- * </pre>
- * You may navigate associations using <tt>createAlias()</tt> or
- * <tt>createCriteria()</tt>.
- * <pre>
- * List cats = session.createCriteria(Cat.class)
- *     .createCriteria("kittens")
- *         .add( Restrictions.like("name", "Iz%") )
- *     .list();
- * </pre>
- * <pre>
- * List cats = session.createCriteria(Cat.class)
- *     .createAlias("kittens", "kit")
- *     .add( Restrictions.like("kit.name", "Iz%") )
- *     .list();
- * </pre>
- * You may specify projection and aggregation using <tt>Projection</tt>
- * instances obtained via the factory methods on <tt>Projections</tt>.
- * <pre>
- * List cats = session.createCriteria(Cat.class)
- *     .setProjection( Projections.projectionList()
- *         .add( Projections.rowCount() )
- *         .add( Projections.avg("weight") )
- *         .add( Projections.max("weight") )
- *         .add( Projections.min("weight") )
- *         .add( Projections.groupProperty("color") )
- *     )
- *     .addOrder( Order.asc("color") )
- *     .list();
- * </pre>
- *
- * @see Session#createCriteria(java.lang.Class)
- * @see org.hibernate.criterion.Restrictions
- * @see org.hibernate.criterion.Projections
- * @see org.hibernate.criterion.Order
- * @see org.hibernate.criterion.Criterion
- * @see org.hibernate.criterion.Projection
- * @see org.hibernate.criterion.DetachedCriteria a disconnected version of this API
- * @author Gavin King
- */
-public interface Criteria extends CriteriaSpecification {
-
-	/**
-	 * Get the alias of the entity encapsulated by this criteria instance.
-	 *
-	 * @return The alias for the encapsulated entity.
-	 */
-	public String getAlias();
-
-	/**
-	 * Used to specify that the query results will be a projection (scalar in
-	 * nature).  Implicitly specifies the {@link #PROJECTION} result transformer.
-	 * <p/>
-	 * The individual components contained within the given
-	 * {@link Projection projection} determines the overall "shape" of the
-	 * query result.
-	 *
-	 * @param projection The projection representing the overall "shape" of the
-	 * query results.
-	 * @return this (for method chaining)
-	 */
-	public Criteria setProjection(Projection projection);
-
-	/**
-	 * Add a {@link Criterion restriction} to constrain the results to be
-	 * retrieved.
-	 *
-	 * @param criterion The {@link Criterion criterion} object representing the
-	 * restriction to be applied.
-	 * @return this (for method chaining)
-	 */
-	public Criteria add(Criterion criterion);
-	
-	/**
-	 * Add an {@link Order ordering} to the result set.
-	 *
-	 * @param order The {@link Order order} object representing an ordering
-	 * to be applied to the results.
-	 * @return this (for method chaining)
-	 */
-	public Criteria addOrder(Order order);
-
-	/**
-	 * Specify an association fetching strategy for an association or a
-	 * collection of values.
-	 *
-	 * @param associationPath a dot seperated property path
-	 * @param mode The fetch mode for the referenced association
-	 * @return this (for method chaining)
-	 */
-	public Criteria setFetchMode(String associationPath, FetchMode mode) throws HibernateException;
-
-	/**
-	 * Set the lock mode of the current entity
-	 *
-	 * @param lockMode The lock mode to be applied
-	 * @return this (for method chaining)
-	 */
-	public Criteria setLockMode(LockMode lockMode);
-
-	/**
-	 * Set the lock mode of the aliased entity
-	 *
-	 * @param alias The previously assigned alias representing the entity to
-	 * which the given lock mode should apply.
-	 * @param lockMode The lock mode to be applied
-	 * @return this (for method chaining)
-	 */
-	public Criteria setLockMode(String alias, LockMode lockMode);
-
-	/**
-	 * Join an association, assigning an alias to the joined association.
-	 * <p/>
-	 * Functionally equivalent to {@link #createAlias(String, String, int)} using
-	 * {@link #INNER_JOIN} for the joinType.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @param alias The alias to assign to the joined association (for later reference).
-	 * @return this (for method chaining)
-	 */
-	public Criteria createAlias(String associationPath, String alias) throws HibernateException;
-
-	/**
-	 * Join an association using the specified join-type, assigning an alias
-	 * to the joined association.
-	 * <p/>
-	 * The joinType is expected to be one of {@link #INNER_JOIN} (the default),
-	 * {@link #FULL_JOIN}, or {@link #LEFT_JOIN}.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @param alias The alias to assign to the joined association (for later reference).
-	 * @param joinType The type of join to use.
-	 * @return this (for method chaining)
-	 */
-	public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException;
-
-	/**
-	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity.
-	 * <p/>
-	 * Functionally equivalent to {@link #createCriteria(String, int)} using
-	 * {@link #INNER_JOIN} for the joinType.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @return the created "sub criteria"
-	 */
-	public Criteria createCriteria(String associationPath) throws HibernateException;
-
-	/**
-	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity, using the
-	 * specified join type.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @param joinType The type of join to use.
-	 * @return the created "sub criteria"
-	 */
-	public Criteria createCriteria(String associationPath, int joinType) throws HibernateException;
-
-	/**
-	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity,
-	 * assigning the given alias.
-	 * <p/>
-	 * Functionally equivalent to {@link #createCriteria(String, String, int)} using
-	 * {@link #INNER_JOIN} for the joinType.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @param alias The alias to assign to the joined association (for later reference).
-	 * @return the created "sub criteria"
-	 */
-	public Criteria createCriteria(String associationPath, String alias) throws HibernateException;
-
-	/**
-	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity,
-	 * assigning the given alias and using the specified join type.
-	 *
-	 * @param associationPath A dot-seperated property path
-	 * @param alias The alias to assign to the joined association (for later reference).
-	 * @param joinType The type of join to use.
-	 * @return the created "sub criteria"
-	 */
-	public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException;
-
-	/**
-	 * Set a strategy for handling the query results. This determines the
-	 * "shape" of the query result.
-	 *
-	 * @param resultTransformer The transformer to apply
-	 * @return this (for method chaining)
-	 *
-	 * @see #ROOT_ENTITY
-	 * @see #DISTINCT_ROOT_ENTITY
-	 * @see #ALIAS_TO_ENTITY_MAP
-	 * @see #PROJECTION
-	 */
-	public Criteria setResultTransformer(ResultTransformer resultTransformer);
-
-	/**
-	 * Set a limit upon the number of objects to be retrieved.
-	 *
-	 * @param maxResults the maximum number of results
-	 * @return this (for method chaining)
-	 */
-	public Criteria setMaxResults(int maxResults);
-	
-	/**
-	 * Set the first result to be retrieved.
-	 *
-	 * @param firstResult the first result to retrieve, numbered from <tt>0</tt>
-	 * @return this (for method chaining)
-	 */
-	public Criteria setFirstResult(int firstResult);
-	
-	/**
-	 * Set a fetch size for the underlying JDBC query.
-	 *
-	 * @param fetchSize the fetch size
-	 * @return this (for method chaining)
-	 *
-	 * @see java.sql.Statement#setFetchSize
-	 */
-	public Criteria setFetchSize(int fetchSize);
-
-	/**
-	 * Set a timeout for the underlying JDBC query.
-	 *
-	 * @param timeout The timeout value to apply.
-	 * @return this (for method chaining)
-	 *
-	 * @see java.sql.Statement#setQueryTimeout
-	 */
-	public Criteria setTimeout(int timeout);
-
-	/**
-	 * Enable caching of this query result, provided query caching is enabled
-	 * for the underlying session factory.
-	 *
-	 * @param cacheable Should the result be considered cacheable; default is
-	 * to not cache (false).
-	 * @return this (for method chaining)
-	 */
-	public Criteria setCacheable(boolean cacheable);
-
-	/**
-	 * Set the name of the cache region to use for query result caching.
-	 *
-	 * @param cacheRegion the name of a query cache region, or <tt>null</tt>
-	 * for the default query cache
-	 * @return this (for method chaining)
-	 *
-	 * @see #setCacheable
-	 */
-	public Criteria setCacheRegion(String cacheRegion);
-
-	/**
-	 * Add a comment to the generated SQL.
-	 *
-	 * @param comment a human-readable string
-	 * @return this (for method chaining)
-	 */
-	public Criteria setComment(String comment);
-
-	/**
-	 * Override the flush mode for this particular query.
-	 *
-	 * @param flushMode The flush mode to use.
-	 * @return this (for method chaining)
-	 */
-	public Criteria setFlushMode(FlushMode flushMode);
-
-	/**
-	 * Override the cache mode for this particular query.
-	 *
-	 * @param cacheMode The cache mode to use.
-	 * @return this (for method chaining)
-	 */
-	public Criteria setCacheMode(CacheMode cacheMode);
-
-	/**
-	 * Get the results.
-	 *
-	 * @return The list of matched query results.
-	 */
-	public List list() throws HibernateException;
-	
-	/**
-	 * Get the results as an instance of {@link ScrollableResults}
-	 *
-	 * @return The {@link ScrollableResults} representing the matched
-	 * query results.
-	 */
-	public ScrollableResults scroll() throws HibernateException;
-
-	/**
-	 * Get the results as an instance of {@link ScrollableResults} based on the
-	 * given scroll mode.
-	 *
-	 * @param scrollMode Indicates the type of underlying database cursor to
-	 * request.
-	 * @return The {@link ScrollableResults} representing the matched
-	 * query results.
-	 */
-	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException;
-
-	/**
-	 * Convenience method to return a single instance that matches
-	 * the query, or null if the query returns no results.
-	 *
-	 * @return the single result or <tt>null</tt>
-	 * @throws HibernateException if there is more than one matching result
-	 */
-	public Object uniqueResult() throws HibernateException;
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Criteria.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Criteria.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,361 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.hibernate.criterion.CriteriaSpecification;
+import org.hibernate.criterion.Criterion;
+import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projection;
+import org.hibernate.transform.ResultTransformer;
+
+/**
+ * <tt>Criteria</tt> is a simplified API for retrieving entities
+ * by composing <tt>Criterion</tt> objects. This is a very
+ * convenient approach for functionality like "search" screens
+ * where there is a variable number of conditions to be placed
+ * upon the result set.<br>
+ * <br>
+ * The <tt>Session</tt> is a factory for <tt>Criteria</tt>.
+ * <tt>Criterion</tt> instances are usually obtained via
+ * the factory methods on <tt>Restrictions</tt>. eg.
+ * <pre>
+ * List cats = session.createCriteria(Cat.class)
+ *     .add( Restrictions.like("name", "Iz%") )
+ *     .add( Restrictions.gt( "weight", new Float(minWeight) ) )
+ *     .addOrder( Order.asc("age") )
+ *     .list();
+ * </pre>
+ * You may navigate associations using <tt>createAlias()</tt> or
+ * <tt>createCriteria()</tt>.
+ * <pre>
+ * List cats = session.createCriteria(Cat.class)
+ *     .createCriteria("kittens")
+ *         .add( Restrictions.like("name", "Iz%") )
+ *     .list();
+ * </pre>
+ * <pre>
+ * List cats = session.createCriteria(Cat.class)
+ *     .createAlias("kittens", "kit")
+ *     .add( Restrictions.like("kit.name", "Iz%") )
+ *     .list();
+ * </pre>
+ * You may specify projection and aggregation using <tt>Projection</tt>
+ * instances obtained via the factory methods on <tt>Projections</tt>.
+ * <pre>
+ * List cats = session.createCriteria(Cat.class)
+ *     .setProjection( Projections.projectionList()
+ *         .add( Projections.rowCount() )
+ *         .add( Projections.avg("weight") )
+ *         .add( Projections.max("weight") )
+ *         .add( Projections.min("weight") )
+ *         .add( Projections.groupProperty("color") )
+ *     )
+ *     .addOrder( Order.asc("color") )
+ *     .list();
+ * </pre>
+ *
+ * @see Session#createCriteria(java.lang.Class)
+ * @see org.hibernate.criterion.Restrictions
+ * @see org.hibernate.criterion.Projections
+ * @see org.hibernate.criterion.Order
+ * @see org.hibernate.criterion.Criterion
+ * @see org.hibernate.criterion.Projection
+ * @see org.hibernate.criterion.DetachedCriteria a disconnected version of this API
+ * @author Gavin King
+ */
+public interface Criteria extends CriteriaSpecification {
+
+	/**
+	 * Get the alias of the entity encapsulated by this criteria instance.
+	 *
+	 * @return The alias for the encapsulated entity.
+	 */
+	public String getAlias();
+
+	/**
+	 * Used to specify that the query results will be a projection (scalar in
+	 * nature).  Implicitly specifies the {@link #PROJECTION} result transformer.
+	 * <p/>
+	 * The individual components contained within the given
+	 * {@link Projection projection} determines the overall "shape" of the
+	 * query result.
+	 *
+	 * @param projection The projection representing the overall "shape" of the
+	 * query results.
+	 * @return this (for method chaining)
+	 */
+	public Criteria setProjection(Projection projection);
+
+	/**
+	 * Add a {@link Criterion restriction} to constrain the results to be
+	 * retrieved.
+	 *
+	 * @param criterion The {@link Criterion criterion} object representing the
+	 * restriction to be applied.
+	 * @return this (for method chaining)
+	 */
+	public Criteria add(Criterion criterion);
+	
+	/**
+	 * Add an {@link Order ordering} to the result set.
+	 *
+	 * @param order The {@link Order order} object representing an ordering
+	 * to be applied to the results.
+	 * @return this (for method chaining)
+	 */
+	public Criteria addOrder(Order order);
+
+	/**
+	 * Specify an association fetching strategy for an association or a
+	 * collection of values.
+	 *
+	 * @param associationPath a dot seperated property path
+	 * @param mode The fetch mode for the referenced association
+	 * @return this (for method chaining)
+	 */
+	public Criteria setFetchMode(String associationPath, FetchMode mode) throws HibernateException;
+
+	/**
+	 * Set the lock mode of the current entity
+	 *
+	 * @param lockMode The lock mode to be applied
+	 * @return this (for method chaining)
+	 */
+	public Criteria setLockMode(LockMode lockMode);
+
+	/**
+	 * Set the lock mode of the aliased entity
+	 *
+	 * @param alias The previously assigned alias representing the entity to
+	 * which the given lock mode should apply.
+	 * @param lockMode The lock mode to be applied
+	 * @return this (for method chaining)
+	 */
+	public Criteria setLockMode(String alias, LockMode lockMode);
+
+	/**
+	 * Join an association, assigning an alias to the joined association.
+	 * <p/>
+	 * Functionally equivalent to {@link #createAlias(String, String, int)} using
+	 * {@link #INNER_JOIN} for the joinType.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @param alias The alias to assign to the joined association (for later reference).
+	 * @return this (for method chaining)
+	 */
+	public Criteria createAlias(String associationPath, String alias) throws HibernateException;
+
+	/**
+	 * Join an association using the specified join-type, assigning an alias
+	 * to the joined association.
+	 * <p/>
+	 * The joinType is expected to be one of {@link #INNER_JOIN} (the default),
+	 * {@link #FULL_JOIN}, or {@link #LEFT_JOIN}.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @param alias The alias to assign to the joined association (for later reference).
+	 * @param joinType The type of join to use.
+	 * @return this (for method chaining)
+	 */
+	public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException;
+
+	/**
+	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity.
+	 * <p/>
+	 * Functionally equivalent to {@link #createCriteria(String, int)} using
+	 * {@link #INNER_JOIN} for the joinType.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @return the created "sub criteria"
+	 */
+	public Criteria createCriteria(String associationPath) throws HibernateException;
+
+	/**
+	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity, using the
+	 * specified join type.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @param joinType The type of join to use.
+	 * @return the created "sub criteria"
+	 */
+	public Criteria createCriteria(String associationPath, int joinType) throws HibernateException;
+
+	/**
+	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity,
+	 * assigning the given alias.
+	 * <p/>
+	 * Functionally equivalent to {@link #createCriteria(String, String, int)} using
+	 * {@link #INNER_JOIN} for the joinType.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @param alias The alias to assign to the joined association (for later reference).
+	 * @return the created "sub criteria"
+	 */
+	public Criteria createCriteria(String associationPath, String alias) throws HibernateException;
+
+	/**
+	 * Create a new <tt>Criteria</tt>, "rooted" at the associated entity,
+	 * assigning the given alias and using the specified join type.
+	 *
+	 * @param associationPath A dot-seperated property path
+	 * @param alias The alias to assign to the joined association (for later reference).
+	 * @param joinType The type of join to use.
+	 * @return the created "sub criteria"
+	 */
+	public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException;
+
+	/**
+	 * Set a strategy for handling the query results. This determines the
+	 * "shape" of the query result.
+	 *
+	 * @param resultTransformer The transformer to apply
+	 * @return this (for method chaining)
+	 *
+	 * @see #ROOT_ENTITY
+	 * @see #DISTINCT_ROOT_ENTITY
+	 * @see #ALIAS_TO_ENTITY_MAP
+	 * @see #PROJECTION
+	 */
+	public Criteria setResultTransformer(ResultTransformer resultTransformer);
+
+	/**
+	 * Set a limit upon the number of objects to be retrieved.
+	 *
+	 * @param maxResults the maximum number of results
+	 * @return this (for method chaining)
+	 */
+	public Criteria setMaxResults(int maxResults);
+	
+	/**
+	 * Set the first result to be retrieved.
+	 *
+	 * @param firstResult the first result to retrieve, numbered from <tt>0</tt>
+	 * @return this (for method chaining)
+	 */
+	public Criteria setFirstResult(int firstResult);
+	
+	/**
+	 * Set a fetch size for the underlying JDBC query.
+	 *
+	 * @param fetchSize the fetch size
+	 * @return this (for method chaining)
+	 *
+	 * @see java.sql.Statement#setFetchSize
+	 */
+	public Criteria setFetchSize(int fetchSize);
+
+	/**
+	 * Set a timeout for the underlying JDBC query.
+	 *
+	 * @param timeout The timeout value to apply.
+	 * @return this (for method chaining)
+	 *
+	 * @see java.sql.Statement#setQueryTimeout
+	 */
+	public Criteria setTimeout(int timeout);
+
+	/**
+	 * Enable caching of this query result, provided query caching is enabled
+	 * for the underlying session factory.
+	 *
+	 * @param cacheable Should the result be considered cacheable; default is
+	 * to not cache (false).
+	 * @return this (for method chaining)
+	 */
+	public Criteria setCacheable(boolean cacheable);
+
+	/**
+	 * Set the name of the cache region to use for query result caching.
+	 *
+	 * @param cacheRegion the name of a query cache region, or <tt>null</tt>
+	 * for the default query cache
+	 * @return this (for method chaining)
+	 *
+	 * @see #setCacheable
+	 */
+	public Criteria setCacheRegion(String cacheRegion);
+
+	/**
+	 * Add a comment to the generated SQL.
+	 *
+	 * @param comment a human-readable string
+	 * @return this (for method chaining)
+	 */
+	public Criteria setComment(String comment);
+
+	/**
+	 * Override the flush mode for this particular query.
+	 *
+	 * @param flushMode The flush mode to use.
+	 * @return this (for method chaining)
+	 */
+	public Criteria setFlushMode(FlushMode flushMode);
+
+	/**
+	 * Override the cache mode for this particular query.
+	 *
+	 * @param cacheMode The cache mode to use.
+	 * @return this (for method chaining)
+	 */
+	public Criteria setCacheMode(CacheMode cacheMode);
+
+	/**
+	 * Get the results.
+	 *
+	 * @return The list of matched query results.
+	 */
+	public List list() throws HibernateException;
+	
+	/**
+	 * Get the results as an instance of {@link ScrollableResults}
+	 *
+	 * @return The {@link ScrollableResults} representing the matched
+	 * query results.
+	 */
+	public ScrollableResults scroll() throws HibernateException;
+
+	/**
+	 * Get the results as an instance of {@link ScrollableResults} based on the
+	 * given scroll mode.
+	 *
+	 * @param scrollMode Indicates the type of underlying database cursor to
+	 * request.
+	 * @return The {@link ScrollableResults} representing the matched
+	 * query results.
+	 */
+	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException;
+
+	/**
+	 * Convenience method to return a single instance that matches
+	 * the query, or null if the query returns no results.
+	 *
+	 * @return the single result or <tt>null</tt>
+	 * @throws HibernateException if there is more than one matching result
+	 */
+	public Object uniqueResult() throws HibernateException;
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/DuplicateMappingException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate;
-
-/**
- * Raised whenever a duplicate for a certain type occurs.
- * Duplicate class, table, property name etc.
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class DuplicateMappingException extends MappingException {
-
-	private final String name;
-	private final String type;
-
-	public DuplicateMappingException(String customMessage, String type, String name) {
-		super(customMessage);
-		this.type=type;
-		this.name=name;
-	}
-	
-	public DuplicateMappingException(String type, String name) {
-		this("Duplicate " + type + " mapping " + name, type, name);
-	}
-
-	public String getType() {
-		return type;
-	}
-	
-	public String getName() {
-		return name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/DuplicateMappingException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/DuplicateMappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Raised whenever a duplicate for a certain type occurs.
+ * Duplicate class, table, property name etc.
+ * 
+ * @author Max Rydahl Andersen
+ *
+ */
+public class DuplicateMappingException extends MappingException {
+
+	private final String name;
+	private final String type;
+
+	public DuplicateMappingException(String customMessage, String type, String name) {
+		super(customMessage);
+		this.type=type;
+		this.name=name;
+	}
+	
+	public DuplicateMappingException(String type, String name) {
+		this("Duplicate " + type + " mapping " + name, type, name);
+	}
+
+	public String getType() {
+		return type;
+	}
+	
+	public String getName() {
+		return name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/EmptyInterceptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,98 +0,0 @@
-//$Id: EmptyInterceptor.java 7859 2005-08-11 21:57:33Z oneovthafew $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.Iterator;
-
-import org.hibernate.type.Type;
-
-/**
- * An interceptor that does nothing. May be used as a base class
- * for application-defined custom interceptors.
- * 
- * @author Gavin King
- */
-public class EmptyInterceptor implements Interceptor, Serializable {
-	
-	public static final Interceptor INSTANCE = new EmptyInterceptor();
-	
-	protected EmptyInterceptor() {}
-
-	public void onDelete(
-			Object entity, 
-			Serializable id, 
-			Object[] state, 
-			String[] propertyNames, 
-			Type[] types) {}
-
-	public boolean onFlushDirty(
-			Object entity, 
-			Serializable id, 
-			Object[] currentState, 
-			Object[] previousState, 
-			String[] propertyNames, 
-			Type[] types) {
-		return false;
-	}
-
-	public boolean onLoad(
-			Object entity, 
-			Serializable id, 
-			Object[] state, 
-			String[] propertyNames, 
-			Type[] types) {
-		return false;
-	}
-
-	public boolean onSave(
-			Object entity, 
-			Serializable id, 
-			Object[] state, 
-			String[] propertyNames, 
-			Type[] types) {
-		return false;
-	}
-
-	public void postFlush(Iterator entities) {}
-	public void preFlush(Iterator entities) {}
-
-	public Boolean isTransient(Object entity) {
-		return null;
-	}
-
-	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
-		return null;
-	}
-
-	public int[] findDirty(Object entity,
-			Serializable id,
-			Object[] currentState,
-			Object[] previousState,
-			String[] propertyNames,
-			Type[] types) {
-		return null;
-	}
-
-	public String getEntityName(Object object) {
-		return null;
-	}
-
-	public Object getEntity(String entityName, Serializable id) {
-		return null;
-	}
-
-	public void afterTransactionBegin(Transaction tx) {}
-	public void afterTransactionCompletion(Transaction tx) {}
-	public void beforeTransactionCompletion(Transaction tx) {}
-
-	public String onPrepareStatement(String sql) {
-		return sql;
-	}
-
-	public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {}
-
-	public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {}
-
-	public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/EmptyInterceptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EmptyInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.hibernate.type.Type;
+
+/**
+ * An interceptor that does nothing. May be used as a base class
+ * for application-defined custom interceptors.
+ * 
+ * @author Gavin King
+ */
+public class EmptyInterceptor implements Interceptor, Serializable {
+	
+	public static final Interceptor INSTANCE = new EmptyInterceptor();
+	
+	protected EmptyInterceptor() {}
+
+	public void onDelete(
+			Object entity, 
+			Serializable id, 
+			Object[] state, 
+			String[] propertyNames, 
+			Type[] types) {}
+
+	public boolean onFlushDirty(
+			Object entity, 
+			Serializable id, 
+			Object[] currentState, 
+			Object[] previousState, 
+			String[] propertyNames, 
+			Type[] types) {
+		return false;
+	}
+
+	public boolean onLoad(
+			Object entity, 
+			Serializable id, 
+			Object[] state, 
+			String[] propertyNames, 
+			Type[] types) {
+		return false;
+	}
+
+	public boolean onSave(
+			Object entity, 
+			Serializable id, 
+			Object[] state, 
+			String[] propertyNames, 
+			Type[] types) {
+		return false;
+	}
+
+	public void postFlush(Iterator entities) {}
+	public void preFlush(Iterator entities) {}
+
+	public Boolean isTransient(Object entity) {
+		return null;
+	}
+
+	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
+		return null;
+	}
+
+	public int[] findDirty(Object entity,
+			Serializable id,
+			Object[] currentState,
+			Object[] previousState,
+			String[] propertyNames,
+			Type[] types) {
+		return null;
+	}
+
+	public String getEntityName(Object object) {
+		return null;
+	}
+
+	public Object getEntity(String entityName, Serializable id) {
+		return null;
+	}
+
+	public void afterTransactionBegin(Transaction tx) {}
+	public void afterTransactionCompletion(Transaction tx) {}
+	public void beforeTransactionCompletion(Transaction tx) {}
+
+	public String onPrepareStatement(String sql) {
+		return sql;
+	}
+
+	public void onCollectionRemove(Object collection, Serializable key) throws CallbackException {}
+
+	public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException {}
+
+	public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException {}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/EntityMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-// $Id: EntityMode.java 8697 2005-11-29 14:29:24Z steveebersole $
-package org.hibernate;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.io.Serializable;
-
-/**
- * Defines the representation modes available for entities.
- *
- * @author Steve Ebersole
- */
-public class EntityMode implements Serializable {
-
-	private static final Map INSTANCES = new HashMap();
-
-	public static final EntityMode POJO = new EntityMode( "pojo" );
-	public static final EntityMode DOM4J = new EntityMode( "dom4j" );
-	public static final EntityMode MAP = new EntityMode( "dynamic-map" );
-
-	static {
-		INSTANCES.put( POJO.name, POJO );
-		INSTANCES.put( DOM4J.name, DOM4J );
-		INSTANCES.put( MAP.name, MAP );
-	}
-
-	private final String name;
-
-	public EntityMode(String name) {
-		this.name = name;
-	}
-
-	public String toString() {
-		return name;
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get( name );
-	}
-
-	public static EntityMode parse(String name) {
-		EntityMode rtn = ( EntityMode ) INSTANCES.get( name );
-		if ( rtn == null ) {
-			// default is POJO
-			rtn = POJO;
-		}
-		return rtn;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/EntityMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/EntityMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+
+/**
+ * Defines the representation modes available for entities.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityMode implements Serializable {
+
+	private static final Map INSTANCES = new HashMap();
+
+	public static final EntityMode POJO = new EntityMode( "pojo" );
+	public static final EntityMode DOM4J = new EntityMode( "dom4j" );
+	public static final EntityMode MAP = new EntityMode( "dynamic-map" );
+
+	static {
+		INSTANCES.put( POJO.name, POJO );
+		INSTANCES.put( DOM4J.name, DOM4J );
+		INSTANCES.put( MAP.name, MAP );
+	}
+
+	private final String name;
+
+	public EntityMode(String name) {
+		this.name = name;
+	}
+
+	public String toString() {
+		return name;
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get( name );
+	}
+
+	public static EntityMode parse(String name) {
+		EntityMode rtn = ( EntityMode ) INSTANCES.get( name );
+		if ( rtn == null ) {
+			// default is POJO
+			rtn = POJO;
+		}
+		return rtn;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/FetchMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,70 +0,0 @@
-//$Id: FetchMode.java 5060 2004-12-24 03:11:05Z oneovthafew $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Represents an association fetching strategy. This is used
- * together with the <tt>Criteria</tt> API to specify runtime
- * fetching strategies.<br>
- * <br>
- * For HQL queries, use the <tt>FETCH</tt> keyword instead.
- *
- * @see Criteria#setFetchMode(java.lang.String, FetchMode)
- * @author Gavin King
- */
-public final class FetchMode implements Serializable {
-	private final String name;
-	private static final Map INSTANCES = new HashMap();
-
-	private FetchMode(String name) {
-		this.name=name;
-	}
-	public String toString() {
-		return name;
-	}
-	/**
-	 * Default to the setting configured in the mapping file.
-	 */
-	public static final FetchMode DEFAULT = new FetchMode("DEFAULT");
-
-	/**
-	 * Fetch using an outer join. Equivalent to <tt>fetch="join"</tt>.
-	 */
-	public static final FetchMode JOIN = new FetchMode("JOIN");
-	/**
-	 * Fetch eagerly, using a separate select. Equivalent to
-	 * <tt>fetch="select"</tt>.
-	 */
-	public static final FetchMode SELECT = new FetchMode("SELECT");
-
-	/**
-	 * Fetch lazily. Equivalent to <tt>outer-join="false"</tt>.
-	 * @deprecated use <tt>FetchMode.SELECT</tt>
-	 */
-	public static final FetchMode LAZY = SELECT;
-	/**
-	 * Fetch eagerly, using an outer join. Equivalent to
-	 * <tt>outer-join="true"</tt>.
-	 * @deprecated use <tt>FetchMode.JOIN</tt>
-	 */
-	public static final FetchMode EAGER = JOIN;
-	
-	static {
-		INSTANCES.put( JOIN.name, JOIN );
-		INSTANCES.put( SELECT.name, SELECT );
-		INSTANCES.put( DEFAULT.name, DEFAULT );
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get(name);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/FetchMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FetchMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents an association fetching strategy. This is used
+ * together with the <tt>Criteria</tt> API to specify runtime
+ * fetching strategies.<br>
+ * <br>
+ * For HQL queries, use the <tt>FETCH</tt> keyword instead.
+ *
+ * @see Criteria#setFetchMode(java.lang.String, FetchMode)
+ * @author Gavin King
+ */
+public final class FetchMode implements Serializable {
+	private final String name;
+	private static final Map INSTANCES = new HashMap();
+
+	private FetchMode(String name) {
+		this.name=name;
+	}
+	public String toString() {
+		return name;
+	}
+	/**
+	 * Default to the setting configured in the mapping file.
+	 */
+	public static final FetchMode DEFAULT = new FetchMode("DEFAULT");
+
+	/**
+	 * Fetch using an outer join. Equivalent to <tt>fetch="join"</tt>.
+	 */
+	public static final FetchMode JOIN = new FetchMode("JOIN");
+	/**
+	 * Fetch eagerly, using a separate select. Equivalent to
+	 * <tt>fetch="select"</tt>.
+	 */
+	public static final FetchMode SELECT = new FetchMode("SELECT");
+
+	/**
+	 * Fetch lazily. Equivalent to <tt>outer-join="false"</tt>.
+	 * @deprecated use <tt>FetchMode.SELECT</tt>
+	 */
+	public static final FetchMode LAZY = SELECT;
+	/**
+	 * Fetch eagerly, using an outer join. Equivalent to
+	 * <tt>outer-join="true"</tt>.
+	 * @deprecated use <tt>FetchMode.JOIN</tt>
+	 */
+	public static final FetchMode EAGER = JOIN;
+	
+	static {
+		INSTANCES.put( JOIN.name, JOIN );
+		INSTANCES.put( SELECT.name, SELECT );
+		INSTANCES.put( DEFAULT.name, DEFAULT );
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get(name);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Filter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-// $Id: Filter.java 8754 2005-12-05 23:36:59Z steveebersole $
-package org.hibernate;
-
-import org.hibernate.engine.FilterDefinition;
-
-import java.util.Collection;
-
-/**
- * Type definition of Filter.  Filter defines the user's view into enabled dynamic filters,
- * allowing them to set filter parameter values.
- *
- * @author Steve Ebersole
- */
-public interface Filter {
-
-	/**
-	 * Get the name of this filter.
-	 *
-	 * @return This filter's name.
-	 */
-	public String getName();
-
-	/**
-	 * Get the filter definition containing additional information about the
-	 * filter (such as default-condition and expected parameter names/types).
-	 *
-	 * @return The filter definition
-	 */
-	public FilterDefinition getFilterDefinition();
-
-
-	/**
-	 * Set the named parameter's value for this filter.
-	 *
-	 * @param name The parameter's name.
-	 * @param value The value to be applied.
-	 * @return This FilterImpl instance (for method chaining).
-	 */
-	public Filter setParameter(String name, Object value);
-
-	/**
-	 * Set the named parameter's value list for this filter.  Used
-	 * in conjunction with IN-style filter criteria.
-	 *
-	 * @param name The parameter's name.
-	 * @param values The values to be expanded into an SQL IN list.
-	 * @return This FilterImpl instance (for method chaining).
-	 */
-	public Filter setParameterList(String name, Collection values);
-
-	/**
-	 * Set the named parameter's value list for this filter.  Used
-	 * in conjunction with IN-style filter criteria.
-	 *
-	 * @param name The parameter's name.
-	 * @param values The values to be expanded into an SQL IN list.
-	 * @return This FilterImpl instance (for method chaining).
-	 */
-	public Filter setParameterList(String name, Object[] values);
-
-	/**
-	 * Perform validation of the filter state.  This is used to verify the
-	 * state of the filter after its enablement and before its use.
-	 *
-	 * @throws HibernateException If the state is not currently valid.
-	 */
-	public void validate() throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Filter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Filter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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;
+
+import org.hibernate.engine.FilterDefinition;
+
+import java.util.Collection;
+
+/**
+ * Type definition of Filter.  Filter defines the user's view into enabled dynamic filters,
+ * allowing them to set filter parameter values.
+ *
+ * @author Steve Ebersole
+ */
+public interface Filter {
+
+	/**
+	 * Get the name of this filter.
+	 *
+	 * @return This filter's name.
+	 */
+	public String getName();
+
+	/**
+	 * Get the filter definition containing additional information about the
+	 * filter (such as default-condition and expected parameter names/types).
+	 *
+	 * @return The filter definition
+	 */
+	public FilterDefinition getFilterDefinition();
+
+
+	/**
+	 * Set the named parameter's value for this filter.
+	 *
+	 * @param name The parameter's name.
+	 * @param value The value to be applied.
+	 * @return This FilterImpl instance (for method chaining).
+	 */
+	public Filter setParameter(String name, Object value);
+
+	/**
+	 * Set the named parameter's value list for this filter.  Used
+	 * in conjunction with IN-style filter criteria.
+	 *
+	 * @param name The parameter's name.
+	 * @param values The values to be expanded into an SQL IN list.
+	 * @return This FilterImpl instance (for method chaining).
+	 */
+	public Filter setParameterList(String name, Collection values);
+
+	/**
+	 * Set the named parameter's value list for this filter.  Used
+	 * in conjunction with IN-style filter criteria.
+	 *
+	 * @param name The parameter's name.
+	 * @param values The values to be expanded into an SQL IN list.
+	 * @return This FilterImpl instance (for method chaining).
+	 */
+	public Filter setParameterList(String name, Object[] values);
+
+	/**
+	 * Perform validation of the filter state.  This is used to verify the
+	 * state of the filter after its enablement and before its use.
+	 *
+	 * @throws HibernateException If the state is not currently valid.
+	 */
+	public void validate() throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/FlushMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,92 +0,0 @@
-//$Id: FlushMode.java 10469 2006-09-08 12:23:18Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Represents a flushing strategy. The flush process synchronizes
- * database state with session state by detecting state changes
- * and executing SQL statements.
- *
- * @see Session#setFlushMode(FlushMode)
- * @see Query#setFlushMode(FlushMode)
- * @see Criteria#setFlushMode(FlushMode)
- *
- * @author Gavin King
- */
-public final class FlushMode implements Serializable {
-	private static final Map INSTANCES = new HashMap();
-
-	private final int level;
-	private final String name;
-
-	private FlushMode(int level, String name) {
-		this.level = level;
-		this.name = name;
-	}
-
-	public String toString() {
-		return name;
-	}
-
-	/**
-	 * The {@link Session} is never flushed unless {@link Session#flush}
-	 * is explicitly called by the application. This mode is very
-	 * efficient for read only transactions.
-	 *
-	 * @deprecated use {@link #MANUAL} instead.
-	 */
-	public static final FlushMode NEVER = new FlushMode( 0, "NEVER" );
-
-	/**
-	 * The {@link Session} is only ever flushed when {@link Session#flush}
-	 * is explicitly called by the application. This mode is very
-	 * efficient for read only transactions.
-	 */
-	public static final FlushMode MANUAL = new FlushMode( 0, "MANUAL" );
-
-	/**
-	 * The {@link Session} is flushed when {@link Transaction#commit}
-	 * is called.
-	 */
-	public static final FlushMode COMMIT = new FlushMode(5, "COMMIT");
-
-	/**
-	 * The {@link Session} is sometimes flushed before query execution
-	 * in order to ensure that queries never return stale state. This
-	 * is the default flush mode.
-	 */
-	public static final FlushMode AUTO = new FlushMode(10, "AUTO");
-
-	/**
-	 * The {@link Session} is flushed before every query. This is
-	 * almost always unnecessary and inefficient.
-	 */
-	public static final FlushMode ALWAYS = new FlushMode(20, "ALWAYS");
-	
-	public boolean lessThan(FlushMode other) {
-		return this.level<other.level;
-	}
-
-	static {
-		INSTANCES.put( NEVER.name, NEVER );
-		INSTANCES.put( MANUAL.name, MANUAL );
-		INSTANCES.put( AUTO.name, AUTO );
-		INSTANCES.put( ALWAYS.name, ALWAYS );
-		INSTANCES.put( COMMIT.name, COMMIT );
-	}
-
-	public static boolean isManualFlushMode(FlushMode mode) {
-		return MANUAL.level == mode.level;
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get( name );
-	}
-
-	public static FlushMode parse(String name) {
-		return ( FlushMode ) INSTANCES.get( name );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/FlushMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/FlushMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents a flushing strategy. The flush process synchronizes
+ * database state with session state by detecting state changes
+ * and executing SQL statements.
+ *
+ * @see Session#setFlushMode(FlushMode)
+ * @see Query#setFlushMode(FlushMode)
+ * @see Criteria#setFlushMode(FlushMode)
+ *
+ * @author Gavin King
+ */
+public final class FlushMode implements Serializable {
+	private static final Map INSTANCES = new HashMap();
+
+	private final int level;
+	private final String name;
+
+	private FlushMode(int level, String name) {
+		this.level = level;
+		this.name = name;
+	}
+
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * The {@link Session} is never flushed unless {@link Session#flush}
+	 * is explicitly called by the application. This mode is very
+	 * efficient for read only transactions.
+	 *
+	 * @deprecated use {@link #MANUAL} instead.
+	 */
+	public static final FlushMode NEVER = new FlushMode( 0, "NEVER" );
+
+	/**
+	 * The {@link Session} is only ever flushed when {@link Session#flush}
+	 * is explicitly called by the application. This mode is very
+	 * efficient for read only transactions.
+	 */
+	public static final FlushMode MANUAL = new FlushMode( 0, "MANUAL" );
+
+	/**
+	 * The {@link Session} is flushed when {@link Transaction#commit}
+	 * is called.
+	 */
+	public static final FlushMode COMMIT = new FlushMode(5, "COMMIT");
+
+	/**
+	 * The {@link Session} is sometimes flushed before query execution
+	 * in order to ensure that queries never return stale state. This
+	 * is the default flush mode.
+	 */
+	public static final FlushMode AUTO = new FlushMode(10, "AUTO");
+
+	/**
+	 * The {@link Session} is flushed before every query. This is
+	 * almost always unnecessary and inefficient.
+	 */
+	public static final FlushMode ALWAYS = new FlushMode(20, "ALWAYS");
+	
+	public boolean lessThan(FlushMode other) {
+		return this.level<other.level;
+	}
+
+	static {
+		INSTANCES.put( NEVER.name, NEVER );
+		INSTANCES.put( MANUAL.name, MANUAL );
+		INSTANCES.put( AUTO.name, AUTO );
+		INSTANCES.put( ALWAYS.name, ALWAYS );
+		INSTANCES.put( COMMIT.name, COMMIT );
+	}
+
+	public static boolean isManualFlushMode(FlushMode mode) {
+		return MANUAL.level == mode.level;
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get( name );
+	}
+
+	public static FlushMode parse(String name) {
+		return ( FlushMode ) INSTANCES.get( name );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Hibernate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,454 +0,0 @@
-//$Id: Hibernate.java 10009 2006-06-10 03:24:05Z epbernard $
-package org.hibernate;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.Serializable;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.util.Iterator;
-import java.util.Properties;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.HibernateIterator;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableBlob;
-import org.hibernate.lob.SerializableClob;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.type.AnyType;
-import org.hibernate.type.BigDecimalType;
-import org.hibernate.type.BigIntegerType;
-import org.hibernate.type.BinaryType;
-import org.hibernate.type.BlobType;
-import org.hibernate.type.BooleanType;
-import org.hibernate.type.ByteType;
-import org.hibernate.type.CalendarDateType;
-import org.hibernate.type.CalendarType;
-import org.hibernate.type.CharacterType;
-import org.hibernate.type.ClassType;
-import org.hibernate.type.ClobType;
-import org.hibernate.type.CompositeCustomType;
-import org.hibernate.type.CurrencyType;
-import org.hibernate.type.CustomType;
-import org.hibernate.type.DateType;
-import org.hibernate.type.DoubleType;
-import org.hibernate.type.FloatType;
-import org.hibernate.type.IntegerType;
-import org.hibernate.type.LocaleType;
-import org.hibernate.type.LongType;
-import org.hibernate.type.ManyToOneType;
-import org.hibernate.type.NullableType;
-import org.hibernate.type.SerializableType;
-import org.hibernate.type.ShortType;
-import org.hibernate.type.StringType;
-import org.hibernate.type.TextType;
-import org.hibernate.type.TimeType;
-import org.hibernate.type.TimeZoneType;
-import org.hibernate.type.TimestampType;
-import org.hibernate.type.TrueFalseType;
-import org.hibernate.type.Type;
-import org.hibernate.type.YesNoType;
-import org.hibernate.type.CharArrayType;
-import org.hibernate.type.WrapperBinaryType;
-import org.hibernate.type.CharacterArrayType;
-import org.hibernate.usertype.CompositeUserType;
-
-/**
- * <ul>
- * <li>Provides access to the full range of Hibernate built-in types. <tt>Type</tt>
- * instances may be used to bind values to query parameters.
- * <li>A factory for new <tt>Blob</tt>s and <tt>Clob</tt>s.
- * <li>Defines static methods for manipulation of proxies.
- * </ul>
- *
- * @author Gavin King
- * @see java.sql.Clob
- * @see java.sql.Blob
- * @see org.hibernate.type.Type
- */
-
-public final class Hibernate {
-
-	/**
-	 * Hibernate <tt>long</tt> type.
-	 */
-	public static final NullableType LONG = new LongType();
-	/**
-	 * Hibernate <tt>short</tt> type.
-	 */
-	public static final NullableType SHORT = new ShortType();
-	/**
-	 * Hibernate <tt>integer</tt> type.
-	 */
-	public static final NullableType INTEGER = new IntegerType();
-	/**
-	 * Hibernate <tt>byte</tt> type.
-	 */
-	public static final NullableType BYTE = new ByteType();
-	/**
-	 * Hibernate <tt>float</tt> type.
-	 */
-	public static final NullableType FLOAT = new FloatType();
-	/**
-	 * Hibernate <tt>double</tt> type.
-	 */
-	public static final NullableType DOUBLE = new DoubleType();
-	/**
-	 * Hibernate <tt>character</tt> type.
-	 */
-	public static final NullableType CHARACTER = new CharacterType();
-	/**
-	 * Hibernate <tt>string</tt> type.
-	 */
-	public static final NullableType STRING = new StringType();
-	/**
-	 * Hibernate <tt>time</tt> type.
-	 */
-	public static final NullableType TIME = new TimeType();
-	/**
-	 * Hibernate <tt>date</tt> type.
-	 */
-	public static final NullableType DATE = new DateType();
-	/**
-	 * Hibernate <tt>timestamp</tt> type.
-	 */
-	public static final NullableType TIMESTAMP = new TimestampType();
-	/**
-	 * Hibernate <tt>boolean</tt> type.
-	 */
-	public static final NullableType BOOLEAN = new BooleanType();
-	/**
-	 * Hibernate <tt>true_false</tt> type.
-	 */
-	public static final NullableType TRUE_FALSE = new TrueFalseType();
-	/**
-	 * Hibernate <tt>yes_no</tt> type.
-	 */
-	public static final NullableType YES_NO = new YesNoType();
-	/**
-	 * Hibernate <tt>big_decimal</tt> type.
-	 */
-	public static final NullableType BIG_DECIMAL = new BigDecimalType();
-	/**
-	 * Hibernate <tt>big_integer</tt> type.
-	 */
-	public static final NullableType BIG_INTEGER = new BigIntegerType();
-	/**
-	 * Hibernate <tt>binary</tt> type.
-	 */
-	public static final NullableType BINARY = new BinaryType();
-	/**
-	 * Hibernate <tt>wrapper-binary</tt> type.
-	 */
-	public static final NullableType WRAPPER_BINARY = new WrapperBinaryType();
-	/**
-	 * Hibernate char[] type.
-	 */
-	public static final NullableType CHAR_ARRAY = new CharArrayType();
-	/**
-	 * Hibernate Character[] type.
-	 */
-	public static final NullableType CHARACTER_ARRAY = new CharacterArrayType();
-	/**
-	 * Hibernate <tt>text</tt> type.
-	 */
-	public static final NullableType TEXT = new TextType();
-	/**
-	 * Hibernate <tt>blob</tt> type.
-	 */
-	public static final Type BLOB = new BlobType();
-	/**
-	 * Hibernate <tt>clob</tt> type.
-	 */
-	public static final Type CLOB = new ClobType();
-	/**
-	 * Hibernate <tt>calendar</tt> type.
-	 */
-	public static final NullableType CALENDAR = new CalendarType();
-	/**
-	 * Hibernate <tt>calendar_date</tt> type.
-	 */
-	public static final NullableType CALENDAR_DATE = new CalendarDateType();
-	/**
-	 * Hibernate <tt>locale</tt> type.
-	 */
-	public static final NullableType LOCALE = new LocaleType();
-	/**
-	 * Hibernate <tt>currency</tt> type.
-	 */
-	public static final NullableType CURRENCY = new CurrencyType();
-	/**
-	 * Hibernate <tt>timezone</tt> type.
-	 */
-	public static final NullableType TIMEZONE = new TimeZoneType();
-	/**
-	 * Hibernate <tt>class</tt> type.
-	 */
-	public static final NullableType CLASS = new ClassType();
-	/**
-	 * Hibernate <tt>serializable</tt> type.
-	 */
-	public static final NullableType SERIALIZABLE = new SerializableType( Serializable.class );
-	/**
-	 * Hibernate <tt>object</tt> type.
-	 */
-	public static final Type OBJECT = new AnyType();
-
-
-	/**
-	 * Cannot be instantiated.
-	 */
-	private Hibernate() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * A Hibernate <tt>serializable</tt> type.
-	 */
-	public static Type serializable(Class serializableClass) {
-		return new SerializableType( serializableClass );
-	}
-
-	/**
-	 * A Hibernate <tt>any</tt> type.
-	 *
-	 * @param metaType       a type mapping <tt>java.lang.Class</tt> to a single column
-	 * @param identifierType the entity identifier type
-	 * @return the Type
-	 */
-	public static Type any(Type metaType, Type identifierType) {
-		return new AnyType( metaType, identifierType );
-	}
-
-	/**
-	 * A Hibernate persistent object (entity) type.
-	 *
-	 * @param persistentClass a mapped entity class
-	 */
-	public static Type entity(Class persistentClass) {
-		// not really a many-to-one association *necessarily*
-		return new ManyToOneType( persistentClass.getName() );
-	}
-
-	/**
-	 * A Hibernate persistent object (entity) type.
-	 *
-	 * @param entityName a mapped entity class
-	 */
-	public static Type entity(String entityName) {
-		// not really a many-to-one association *necessarily*
-		return new ManyToOneType( entityName );
-	}
-
-	/**
-	 * A Hibernate custom type.
-	 *
-	 * @param userTypeClass a class that implements <tt>UserType</tt>
-	 */
-	public static Type custom(Class userTypeClass) throws HibernateException {
-		return custom( userTypeClass, null );
-	}
-
-	/**
-	 * A Hibernate parameterizable custom type.
-	 *
-	 * @param userTypeClass   a class that implements <tt>UserType and ParameterizableType</tt>
-	 * @param parameterNames  the names of the parameters passed to the type
-	 * @param parameterValues the values of the parameters passed to the type. They must match
-	 *                        up with the order and length of the parameterNames array.
-	 */
-	public static Type custom(Class userTypeClass, String[] parameterNames, String[] parameterValues)
-			throws HibernateException {
-		Properties parameters = new Properties();
-		for ( int i = 0; i < parameterNames.length; i++ ) {
-			parameters.setProperty( parameterNames[i], parameterValues[i] );
-		}
-		return custom( userTypeClass, parameters );
-	}
-
-	/**
-	 * A Hibernate parameterizable custom type.
-	 *
-	 * @param userTypeClass a class that implements <tt>UserType and ParameterizableType</tt>
-	 * @param parameters    the parameters as a collection of name/value pairs
-	 */
-	public static Type custom(Class userTypeClass, Properties parameters)
-			throws HibernateException {
-		if ( CompositeUserType.class.isAssignableFrom( userTypeClass ) ) {
-			CompositeCustomType type = new CompositeCustomType( userTypeClass, parameters );
-			return type;
-		}
-		else {
-			CustomType type = new CustomType( userTypeClass, parameters );
-			return type;
-		}
-	}
-
-	/**
-	 * Force initialization of a proxy or persistent collection.
-	 * <p/>
-	 * Note: This only ensures intialization of a proxy object or collection;
-	 * it is not guaranteed that the elements INSIDE the collection will be initialized/materialized.
-	 *
-	 * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt>
-	 * @throws HibernateException if we can't initialize the proxy at this time, eg. the <tt>Session</tt> was closed
-	 */
-	public static void initialize(Object proxy) throws HibernateException {
-		if ( proxy == null ) {
-			return;
-		}
-		else if ( proxy instanceof HibernateProxy ) {
-			( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().initialize();
-		}
-		else if ( proxy instanceof PersistentCollection ) {
-			( ( PersistentCollection ) proxy ).forceInitialization();
-		}
-	}
-
-	/**
-	 * Check if the proxy or persistent collection is initialized.
-	 *
-	 * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt>
-	 * @return true if the argument is already initialized, or is not a proxy or collection
-	 */
-	public static boolean isInitialized(Object proxy) {
-		if ( proxy instanceof HibernateProxy ) {
-			return !( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isUninitialized();
-		}
-		else if ( proxy instanceof PersistentCollection ) {
-			return ( ( PersistentCollection ) proxy ).wasInitialized();
-		}
-		else {
-			return true;
-		}
-	}
-
-	/**
-	 * Get the true, underlying class of a proxied persistent class. This operation
-	 * will initialize a proxy by side-effect.
-	 *
-	 * @param proxy a persistable object or proxy
-	 * @return the true class of the instance
-	 * @throws HibernateException
-	 */
-	public static Class getClass(Object proxy) {
-		if ( proxy instanceof HibernateProxy ) {
-			return ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer()
-					.getImplementation()
-					.getClass();
-		}
-		else {
-			return proxy.getClass();
-		}
-	}
-
-	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
-	 *
-	 * @param bytes a byte array
-	 * @return the Blob
-	 */
-	public static Blob createBlob(byte[] bytes) {
-		return new SerializableBlob( new BlobImpl( bytes ) );
-	}
-
-	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
-	 *
-	 * @param stream a binary stream
-	 * @param length the number of bytes in the stream
-	 * @return the Blob
-	 */
-	public static Blob createBlob(InputStream stream, int length) {
-		return new SerializableBlob( new BlobImpl( stream, length ) );
-	}
-
-	/**
-	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
-	 *
-	 * @param stream a binary stream
-	 * @return the Blob
-	 * @throws IOException
-	 */
-	public static Blob createBlob(InputStream stream) throws IOException {
-		return new SerializableBlob( new BlobImpl( stream, stream.available() ) );
-	}
-
-	/**
-	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
-	 *
-	 * @param string a <tt>String</tt>
-	 */
-	public static Clob createClob(String string) {
-		return new SerializableClob( new ClobImpl( string ) );
-	}
-
-	/**
-	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
-	 *
-	 * @param reader a character stream
-	 * @param length the number of characters in the stream
-	 */
-	public static Clob createClob(Reader reader, int length) {
-		return new SerializableClob( new ClobImpl( reader, length ) );
-	}
-
-	/**
-	 * Close an <tt>Iterator</tt> created by <tt>iterate()</tt> immediately,
-	 * instead of waiting until the session is closed or disconnected.
-	 *
-	 * @param iterator an <tt>Iterator</tt> created by <tt>iterate()</tt>
-	 * @throws HibernateException
-	 * @see org.hibernate.Query#iterate
-	 * @see Query#iterate()
-	 */
-	public static void close(Iterator iterator) throws HibernateException {
-		if ( iterator instanceof HibernateIterator ) {
-			( ( HibernateIterator ) iterator ).close();
-		}
-		else {
-			throw new IllegalArgumentException( "not a Hibernate iterator" );
-		}
-	}
-
-	/**
-	 * Check if the property is initialized. If the named property does not exist
-	 * or is not persistent, this method always returns <tt>true</tt>.
-	 *
-	 * @param proxy The potential proxy
-	 * @param propertyName the name of a persistent attribute of the object
-	 * @return true if the named property of the object is not listed as uninitialized
-	 * @return false if the object is an uninitialized proxy, or the named property is uninitialized
-	 */
-	public static boolean isPropertyInitialized(Object proxy, String propertyName) {
-		
-		Object entity;
-		if ( proxy instanceof HibernateProxy ) {
-			LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
-			if ( li.isUninitialized() ) {
-				return false;
-			}
-			else {
-				entity = li.getImplementation();
-			}
-		}
-		else {
-			entity = proxy;
-		}
-
-		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
-			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
-			return interceptor == null || interceptor.isInitialized( propertyName );
-		}
-		else {
-			return true;
-		}
-		
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Hibernate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Hibernate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,477 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.HibernateIterator;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.lob.BlobImpl;
+import org.hibernate.lob.ClobImpl;
+import org.hibernate.lob.SerializableBlob;
+import org.hibernate.lob.SerializableClob;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.type.AnyType;
+import org.hibernate.type.BigDecimalType;
+import org.hibernate.type.BigIntegerType;
+import org.hibernate.type.BinaryType;
+import org.hibernate.type.BlobType;
+import org.hibernate.type.BooleanType;
+import org.hibernate.type.ByteType;
+import org.hibernate.type.CalendarDateType;
+import org.hibernate.type.CalendarType;
+import org.hibernate.type.CharacterType;
+import org.hibernate.type.ClassType;
+import org.hibernate.type.ClobType;
+import org.hibernate.type.CompositeCustomType;
+import org.hibernate.type.CurrencyType;
+import org.hibernate.type.CustomType;
+import org.hibernate.type.DateType;
+import org.hibernate.type.DoubleType;
+import org.hibernate.type.FloatType;
+import org.hibernate.type.IntegerType;
+import org.hibernate.type.LocaleType;
+import org.hibernate.type.LongType;
+import org.hibernate.type.ManyToOneType;
+import org.hibernate.type.NullableType;
+import org.hibernate.type.SerializableType;
+import org.hibernate.type.ShortType;
+import org.hibernate.type.StringType;
+import org.hibernate.type.TextType;
+import org.hibernate.type.TimeType;
+import org.hibernate.type.TimeZoneType;
+import org.hibernate.type.TimestampType;
+import org.hibernate.type.TrueFalseType;
+import org.hibernate.type.Type;
+import org.hibernate.type.YesNoType;
+import org.hibernate.type.CharArrayType;
+import org.hibernate.type.WrapperBinaryType;
+import org.hibernate.type.CharacterArrayType;
+import org.hibernate.usertype.CompositeUserType;
+
+/**
+ * <ul>
+ * <li>Provides access to the full range of Hibernate built-in types. <tt>Type</tt>
+ * instances may be used to bind values to query parameters.
+ * <li>A factory for new <tt>Blob</tt>s and <tt>Clob</tt>s.
+ * <li>Defines static methods for manipulation of proxies.
+ * </ul>
+ *
+ * @author Gavin King
+ * @see java.sql.Clob
+ * @see java.sql.Blob
+ * @see org.hibernate.type.Type
+ */
+
+public final class Hibernate {
+
+	/**
+	 * Hibernate <tt>long</tt> type.
+	 */
+	public static final NullableType LONG = new LongType();
+	/**
+	 * Hibernate <tt>short</tt> type.
+	 */
+	public static final NullableType SHORT = new ShortType();
+	/**
+	 * Hibernate <tt>integer</tt> type.
+	 */
+	public static final NullableType INTEGER = new IntegerType();
+	/**
+	 * Hibernate <tt>byte</tt> type.
+	 */
+	public static final NullableType BYTE = new ByteType();
+	/**
+	 * Hibernate <tt>float</tt> type.
+	 */
+	public static final NullableType FLOAT = new FloatType();
+	/**
+	 * Hibernate <tt>double</tt> type.
+	 */
+	public static final NullableType DOUBLE = new DoubleType();
+	/**
+	 * Hibernate <tt>character</tt> type.
+	 */
+	public static final NullableType CHARACTER = new CharacterType();
+	/**
+	 * Hibernate <tt>string</tt> type.
+	 */
+	public static final NullableType STRING = new StringType();
+	/**
+	 * Hibernate <tt>time</tt> type.
+	 */
+	public static final NullableType TIME = new TimeType();
+	/**
+	 * Hibernate <tt>date</tt> type.
+	 */
+	public static final NullableType DATE = new DateType();
+	/**
+	 * Hibernate <tt>timestamp</tt> type.
+	 */
+	public static final NullableType TIMESTAMP = new TimestampType();
+	/**
+	 * Hibernate <tt>boolean</tt> type.
+	 */
+	public static final NullableType BOOLEAN = new BooleanType();
+	/**
+	 * Hibernate <tt>true_false</tt> type.
+	 */
+	public static final NullableType TRUE_FALSE = new TrueFalseType();
+	/**
+	 * Hibernate <tt>yes_no</tt> type.
+	 */
+	public static final NullableType YES_NO = new YesNoType();
+	/**
+	 * Hibernate <tt>big_decimal</tt> type.
+	 */
+	public static final NullableType BIG_DECIMAL = new BigDecimalType();
+	/**
+	 * Hibernate <tt>big_integer</tt> type.
+	 */
+	public static final NullableType BIG_INTEGER = new BigIntegerType();
+	/**
+	 * Hibernate <tt>binary</tt> type.
+	 */
+	public static final NullableType BINARY = new BinaryType();
+	/**
+	 * Hibernate <tt>wrapper-binary</tt> type.
+	 */
+	public static final NullableType WRAPPER_BINARY = new WrapperBinaryType();
+	/**
+	 * Hibernate char[] type.
+	 */
+	public static final NullableType CHAR_ARRAY = new CharArrayType();
+	/**
+	 * Hibernate Character[] type.
+	 */
+	public static final NullableType CHARACTER_ARRAY = new CharacterArrayType();
+	/**
+	 * Hibernate <tt>text</tt> type.
+	 */
+	public static final NullableType TEXT = new TextType();
+	/**
+	 * Hibernate <tt>blob</tt> type.
+	 */
+	public static final Type BLOB = new BlobType();
+	/**
+	 * Hibernate <tt>clob</tt> type.
+	 */
+	public static final Type CLOB = new ClobType();
+	/**
+	 * Hibernate <tt>calendar</tt> type.
+	 */
+	public static final NullableType CALENDAR = new CalendarType();
+	/**
+	 * Hibernate <tt>calendar_date</tt> type.
+	 */
+	public static final NullableType CALENDAR_DATE = new CalendarDateType();
+	/**
+	 * Hibernate <tt>locale</tt> type.
+	 */
+	public static final NullableType LOCALE = new LocaleType();
+	/**
+	 * Hibernate <tt>currency</tt> type.
+	 */
+	public static final NullableType CURRENCY = new CurrencyType();
+	/**
+	 * Hibernate <tt>timezone</tt> type.
+	 */
+	public static final NullableType TIMEZONE = new TimeZoneType();
+	/**
+	 * Hibernate <tt>class</tt> type.
+	 */
+	public static final NullableType CLASS = new ClassType();
+	/**
+	 * Hibernate <tt>serializable</tt> type.
+	 */
+	public static final NullableType SERIALIZABLE = new SerializableType( Serializable.class );
+	/**
+	 * Hibernate <tt>object</tt> type.
+	 */
+	public static final Type OBJECT = new AnyType();
+
+
+	/**
+	 * Cannot be instantiated.
+	 */
+	private Hibernate() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * A Hibernate <tt>serializable</tt> type.
+	 */
+	public static Type serializable(Class serializableClass) {
+		return new SerializableType( serializableClass );
+	}
+
+	/**
+	 * A Hibernate <tt>any</tt> type.
+	 *
+	 * @param metaType       a type mapping <tt>java.lang.Class</tt> to a single column
+	 * @param identifierType the entity identifier type
+	 * @return the Type
+	 */
+	public static Type any(Type metaType, Type identifierType) {
+		return new AnyType( metaType, identifierType );
+	}
+
+	/**
+	 * A Hibernate persistent object (entity) type.
+	 *
+	 * @param persistentClass a mapped entity class
+	 */
+	public static Type entity(Class persistentClass) {
+		// not really a many-to-one association *necessarily*
+		return new ManyToOneType( persistentClass.getName() );
+	}
+
+	/**
+	 * A Hibernate persistent object (entity) type.
+	 *
+	 * @param entityName a mapped entity class
+	 */
+	public static Type entity(String entityName) {
+		// not really a many-to-one association *necessarily*
+		return new ManyToOneType( entityName );
+	}
+
+	/**
+	 * A Hibernate custom type.
+	 *
+	 * @param userTypeClass a class that implements <tt>UserType</tt>
+	 */
+	public static Type custom(Class userTypeClass) throws HibernateException {
+		return custom( userTypeClass, null );
+	}
+
+	/**
+	 * A Hibernate parameterizable custom type.
+	 *
+	 * @param userTypeClass   a class that implements <tt>UserType and ParameterizableType</tt>
+	 * @param parameterNames  the names of the parameters passed to the type
+	 * @param parameterValues the values of the parameters passed to the type. They must match
+	 *                        up with the order and length of the parameterNames array.
+	 */
+	public static Type custom(Class userTypeClass, String[] parameterNames, String[] parameterValues)
+			throws HibernateException {
+		Properties parameters = new Properties();
+		for ( int i = 0; i < parameterNames.length; i++ ) {
+			parameters.setProperty( parameterNames[i], parameterValues[i] );
+		}
+		return custom( userTypeClass, parameters );
+	}
+
+	/**
+	 * A Hibernate parameterizable custom type.
+	 *
+	 * @param userTypeClass a class that implements <tt>UserType and ParameterizableType</tt>
+	 * @param parameters    the parameters as a collection of name/value pairs
+	 */
+	public static Type custom(Class userTypeClass, Properties parameters)
+			throws HibernateException {
+		if ( CompositeUserType.class.isAssignableFrom( userTypeClass ) ) {
+			CompositeCustomType type = new CompositeCustomType( userTypeClass, parameters );
+			return type;
+		}
+		else {
+			CustomType type = new CustomType( userTypeClass, parameters );
+			return type;
+		}
+	}
+
+	/**
+	 * Force initialization of a proxy or persistent collection.
+	 * <p/>
+	 * Note: This only ensures intialization of a proxy object or collection;
+	 * it is not guaranteed that the elements INSIDE the collection will be initialized/materialized.
+	 *
+	 * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt>
+	 * @throws HibernateException if we can't initialize the proxy at this time, eg. the <tt>Session</tt> was closed
+	 */
+	public static void initialize(Object proxy) throws HibernateException {
+		if ( proxy == null ) {
+			return;
+		}
+		else if ( proxy instanceof HibernateProxy ) {
+			( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().initialize();
+		}
+		else if ( proxy instanceof PersistentCollection ) {
+			( ( PersistentCollection ) proxy ).forceInitialization();
+		}
+	}
+
+	/**
+	 * Check if the proxy or persistent collection is initialized.
+	 *
+	 * @param proxy a persistable object, proxy, persistent collection or <tt>null</tt>
+	 * @return true if the argument is already initialized, or is not a proxy or collection
+	 */
+	public static boolean isInitialized(Object proxy) {
+		if ( proxy instanceof HibernateProxy ) {
+			return !( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().isUninitialized();
+		}
+		else if ( proxy instanceof PersistentCollection ) {
+			return ( ( PersistentCollection ) proxy ).wasInitialized();
+		}
+		else {
+			return true;
+		}
+	}
+
+	/**
+	 * Get the true, underlying class of a proxied persistent class. This operation
+	 * will initialize a proxy by side-effect.
+	 *
+	 * @param proxy a persistable object or proxy
+	 * @return the true class of the instance
+	 * @throws HibernateException
+	 */
+	public static Class getClass(Object proxy) {
+		if ( proxy instanceof HibernateProxy ) {
+			return ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer()
+					.getImplementation()
+					.getClass();
+		}
+		else {
+			return proxy.getClass();
+		}
+	}
+
+	/**
+	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 *
+	 * @param bytes a byte array
+	 * @return the Blob
+	 */
+	public static Blob createBlob(byte[] bytes) {
+		return new SerializableBlob( new BlobImpl( bytes ) );
+	}
+
+	/**
+	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 *
+	 * @param stream a binary stream
+	 * @param length the number of bytes in the stream
+	 * @return the Blob
+	 */
+	public static Blob createBlob(InputStream stream, int length) {
+		return new SerializableBlob( new BlobImpl( stream, length ) );
+	}
+
+	/**
+	 * Create a new <tt>Blob</tt>. The returned object will be initially immutable.
+	 *
+	 * @param stream a binary stream
+	 * @return the Blob
+	 * @throws IOException
+	 */
+	public static Blob createBlob(InputStream stream) throws IOException {
+		return new SerializableBlob( new BlobImpl( stream, stream.available() ) );
+	}
+
+	/**
+	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+	 *
+	 * @param string a <tt>String</tt>
+	 */
+	public static Clob createClob(String string) {
+		return new SerializableClob( new ClobImpl( string ) );
+	}
+
+	/**
+	 * Create a new <tt>Clob</tt>. The returned object will be initially immutable.
+	 *
+	 * @param reader a character stream
+	 * @param length the number of characters in the stream
+	 */
+	public static Clob createClob(Reader reader, int length) {
+		return new SerializableClob( new ClobImpl( reader, length ) );
+	}
+
+	/**
+	 * Close an <tt>Iterator</tt> created by <tt>iterate()</tt> immediately,
+	 * instead of waiting until the session is closed or disconnected.
+	 *
+	 * @param iterator an <tt>Iterator</tt> created by <tt>iterate()</tt>
+	 * @throws HibernateException
+	 * @see org.hibernate.Query#iterate
+	 * @see Query#iterate()
+	 */
+	public static void close(Iterator iterator) throws HibernateException {
+		if ( iterator instanceof HibernateIterator ) {
+			( ( HibernateIterator ) iterator ).close();
+		}
+		else {
+			throw new IllegalArgumentException( "not a Hibernate iterator" );
+		}
+	}
+
+	/**
+	 * Check if the property is initialized. If the named property does not exist
+	 * or is not persistent, this method always returns <tt>true</tt>.
+	 *
+	 * @param proxy The potential proxy
+	 * @param propertyName the name of a persistent attribute of the object
+	 * @return true if the named property of the object is not listed as uninitialized
+	 * @return false if the object is an uninitialized proxy, or the named property is uninitialized
+	 */
+	public static boolean isPropertyInitialized(Object proxy, String propertyName) {
+		
+		Object entity;
+		if ( proxy instanceof HibernateProxy ) {
+			LazyInitializer li = ( ( HibernateProxy ) proxy ).getHibernateLazyInitializer();
+			if ( li.isUninitialized() ) {
+				return false;
+			}
+			else {
+				entity = li.getImplementation();
+			}
+		}
+		else {
+			entity = proxy;
+		}
+
+		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
+			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
+			return interceptor == null || interceptor.isInitialized( propertyName );
+		}
+		else {
+			return true;
+		}
+		
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/HibernateException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-//$Id: HibernateException.java 5683 2005-02-12 03:09:22Z oneovthafew $
-package org.hibernate;
-
-import org.hibernate.exception.NestableRuntimeException;
-
-/**
- * Any exception that occurs inside the persistence layer
- * or JDBC driver. <tt>SQLException</tt>s are always wrapped
- * by instances of <tt>JDBCException</tt>.
- *
- * @see JDBCException
- * @author Gavin King
- */
-
-public class HibernateException extends NestableRuntimeException {
-
-	public HibernateException(Throwable root) {
-		super(root);
-	}
-
-	public HibernateException(String string, Throwable root) {
-		super(string, root);
-	}
-
-	public HibernateException(String s) {
-		super(s);
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/HibernateException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/HibernateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import org.hibernate.exception.NestableRuntimeException;
+
+/**
+ * Any exception that occurs inside the persistence layer
+ * or JDBC driver. <tt>SQLException</tt>s are always wrapped
+ * by instances of <tt>JDBCException</tt>.
+ *
+ * @see JDBCException
+ * @author Gavin King
+ */
+
+public class HibernateException extends NestableRuntimeException {
+
+	public HibernateException(Throwable root) {
+		super(root);
+	}
+
+	public HibernateException(String string, Throwable root) {
+		super(string, root);
+	}
+
+	public HibernateException(String s) {
+		super(s);
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/InstantiationException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-//$Id: InstantiationException.java 6781 2005-05-14 17:27:57Z oneovthafew $
-package org.hibernate;
-
-/**
- * Thrown if Hibernate can't instantiate an entity or component
- * class at runtime.
- *
- * @author Gavin King
- */
-
-public class InstantiationException extends HibernateException {
-
-	private final Class clazz;
-
-	public InstantiationException(String s, Class clazz, Throwable root) {
-		super(s, root);
-		this.clazz = clazz;
-	}
-
-	public InstantiationException(String s, Class clazz) {
-		super(s);
-		this.clazz = clazz;
-	}
-
-	public InstantiationException(String s, Class clazz, Exception e) {
-		super(s, e);
-		this.clazz = clazz;
-	}
-
-	public Class getPersistentClass() {
-		return clazz;
-	}
-
-	public String getMessage() {
-		return super.getMessage() + clazz.getName();
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/InstantiationException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InstantiationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+/**
+ * Thrown if Hibernate can't instantiate an entity or component
+ * class at runtime.
+ *
+ * @author Gavin King
+ */
+
+public class InstantiationException extends HibernateException {
+
+	private final Class clazz;
+
+	public InstantiationException(String s, Class clazz, Throwable root) {
+		super(s, root);
+		this.clazz = clazz;
+	}
+
+	public InstantiationException(String s, Class clazz) {
+		super(s);
+		this.clazz = clazz;
+	}
+
+	public InstantiationException(String s, Class clazz, Exception e) {
+		super(s, e);
+		this.clazz = clazz;
+	}
+
+	public Class getPersistentClass() {
+		return clazz;
+	}
+
+	public String getMessage() {
+		return super.getMessage() + clazz.getName();
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Interceptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,155 +0,0 @@
-//$Id: Interceptor.java 7883 2005-08-12 20:03:07Z oneovthafew $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.Iterator;
-
-import org.hibernate.type.Type;
-
-/**
- * Allows user code to inspect and/or change property values.
- * <br><br>
- * Inspection occurs before property values are written and after they are read
- * from the database.<br>
- * <br>
- * There might be a single instance of <tt>Interceptor</tt> for a <tt>SessionFactory</tt>, or a new instance
- * might be specified for each <tt>Session</tt>. Whichever approach is used, the interceptor must be
- * serializable if the <tt>Session</tt> is to be serializable. This means that <tt>SessionFactory</tt>-scoped
- * interceptors should implement <tt>readResolve()</tt>.<br>
- * <br>
- * The <tt>Session</tt> may not be invoked from a callback (nor may a callback cause a collection or proxy to
- * be lazily initialized).<br>
- * <br>
- * Instead of implementing this interface directly, it is usually better to extend <tt>EmptyInterceptor</tt>
- * and override only the callback methods of interest.
- *
- * @see SessionFactory#openSession(Interceptor)
- * @see org.hibernate.cfg.Configuration#setInterceptor(Interceptor)
- * @see EmptyInterceptor
- * @author Gavin King
- */
-public interface Interceptor {
-	/**
-	 * Called just before an object is initialized. The interceptor may change the <tt>state</tt>, which will
-	 * be propagated to the persistent object. Note that when this method is called, <tt>entity</tt> will be
-	 * an empty uninitialized instance of the class.
-	 *
-	 * @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
-	 */
-	public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
-	/**
-	 * Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected
-	 * <tt>currentState</tt>, which will be propagated to both the database and the persistent object.
-	 * Note that not all flushes end in actual synchronization with the database, in which case the
-	 * new <tt>currentState</tt> will be propagated to the object, but not necessarily (immediately) to
-	 * the database. It is strongly recommended that the interceptor <b>not</b> modify the <tt>previousState</tt>.
-	 *
-	 * @return <tt>true</tt> if the user modified the <tt>currentState</tt> in any way.
-	 */
-	public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException;
-	/**
-	 * Called before an object is saved. The interceptor may modify the <tt>state</tt>, which will be used for
-	 * the SQL <tt>INSERT</tt> and propagated to the persistent object.
-	 *
-	 * @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
-	 */
-	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
-	/**
-	 *  Called before an object is deleted. It is not recommended that the interceptor modify the <tt>state</tt>.
-	 */
-	public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
-	/**
-	 * Called before a collection is (re)created.
-	 */
-	public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException;
-	/**
-	 * Called before a collection is deleted.
-	 */
-	public void onCollectionRemove(Object collection, Serializable key) throws CallbackException;
-	/**
-	 * Called before a collection is updated.
-	 */
-	public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException;
-	/**
-	 * Called before a flush
-	 */
-	public void preFlush(Iterator entities) throws CallbackException;
-	/**
-	 * Called after a flush that actually ends in execution of the SQL statements required to synchronize
-	 * in-memory state with the database.
-	 */
-	public void postFlush(Iterator entities) throws CallbackException;
-	/**
-	 * Called to distinguish between transient and detached entities. The return value determines the
-	 * state of the entity with respect to the current session.
-	 * <ul>
-	 * <li><tt>Boolean.TRUE</tt> - the entity is transient
-	 * <li><tt>Boolean.FALSE</tt> - the entity is detached
-	 * <li><tt>null</tt> - Hibernate uses the <tt>unsaved-value</tt> mapping and other heuristics to 
-	 * determine if the object is unsaved
-	 * </ul>
-	 * @param entity a transient or detached entity
-	 * @return Boolean or <tt>null</tt> to choose default behaviour
-	 */
-	public Boolean isTransient(Object entity);
-	/**
-	 * Called from <tt>flush()</tt>. The return value determines whether the entity is updated
-	 * <ul>
-	 * <li>an array of property indices - the entity is dirty
-	 * <li>an empty array - the entity is not dirty
-	 * <li><tt>null</tt> - use Hibernate's default dirty-checking algorithm
-	 * </ul>
-	 * @param entity a persistent entity
-	 * @return array of dirty property indices or <tt>null</tt> to choose default behaviour
-	 */
-	public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types);
-	/**
-	 * Instantiate the entity class. Return <tt>null</tt> to indicate that Hibernate should use
-	 * the default constructor of the class. The identifier property of the returned instance
-	 * should be initialized with the given identifier.
-	 *
-	 * @param entityName the name of the entity
-	 * @param entityMode The type of entity instance to be returned.
-	 * @param id the identifier of the new instance
-	 * @return an instance of the class, or <tt>null</tt> to choose default behaviour
-	 */
-	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException;
-
-	/**
-	 * Get the entity name for a persistent or transient instance
-	 * @param object an entity instance
-	 * @return the name of the entity
-	 */
-	public String getEntityName(Object object) throws CallbackException;
-
-	/**
-	 * Get a fully loaded entity instance that is cached externally
-	 * @param entityName the name of the entity
-	 * @param id the instance identifier
-	 * @return a fully initialized entity
-	 * @throws CallbackException
-	 */
-	public Object getEntity(String entityName, Serializable id) throws CallbackException;
-	
-	/**
-	 * Called when a Hibernate transaction is begun via the Hibernate <tt>Transaction</tt> 
-	 * API. Will not be called if transactions are being controlled via some other 
-	 * mechanism (CMT, for example).
-	 */
-	public void afterTransactionBegin(Transaction tx);
-	/**
-	 * Called before a transaction is committed (but not before rollback).
-	 */
-	public void beforeTransactionCompletion(Transaction tx);
-	/**
-	 * Called after a transaction is committed or rolled back.
-	 */
-	public void afterTransactionCompletion(Transaction tx);
-
-	/**
-	 * Called when sql string is being prepared. 
-	 * @param sql sql to be prepared
-	 * @return original or modified sql
-	 */
-	public String onPrepareStatement(String sql);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Interceptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Interceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,178 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.hibernate.type.Type;
+
+/**
+ * Allows user code to inspect and/or change property values.
+ * <br><br>
+ * Inspection occurs before property values are written and after they are read
+ * from the database.<br>
+ * <br>
+ * There might be a single instance of <tt>Interceptor</tt> for a <tt>SessionFactory</tt>, or a new instance
+ * might be specified for each <tt>Session</tt>. Whichever approach is used, the interceptor must be
+ * serializable if the <tt>Session</tt> is to be serializable. This means that <tt>SessionFactory</tt>-scoped
+ * interceptors should implement <tt>readResolve()</tt>.<br>
+ * <br>
+ * The <tt>Session</tt> may not be invoked from a callback (nor may a callback cause a collection or proxy to
+ * be lazily initialized).<br>
+ * <br>
+ * Instead of implementing this interface directly, it is usually better to extend <tt>EmptyInterceptor</tt>
+ * and override only the callback methods of interest.
+ *
+ * @see SessionFactory#openSession(Interceptor)
+ * @see org.hibernate.cfg.Configuration#setInterceptor(Interceptor)
+ * @see EmptyInterceptor
+ * @author Gavin King
+ */
+public interface Interceptor {
+	/**
+	 * Called just before an object is initialized. The interceptor may change the <tt>state</tt>, which will
+	 * be propagated to the persistent object. Note that when this method is called, <tt>entity</tt> will be
+	 * an empty uninitialized instance of the class.
+	 *
+	 * @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
+	 */
+	public boolean onLoad(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
+	/**
+	 * Called when an object is detected to be dirty, during a flush. The interceptor may modify the detected
+	 * <tt>currentState</tt>, which will be propagated to both the database and the persistent object.
+	 * Note that not all flushes end in actual synchronization with the database, in which case the
+	 * new <tt>currentState</tt> will be propagated to the object, but not necessarily (immediately) to
+	 * the database. It is strongly recommended that the interceptor <b>not</b> modify the <tt>previousState</tt>.
+	 *
+	 * @return <tt>true</tt> if the user modified the <tt>currentState</tt> in any way.
+	 */
+	public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types) throws CallbackException;
+	/**
+	 * Called before an object is saved. The interceptor may modify the <tt>state</tt>, which will be used for
+	 * the SQL <tt>INSERT</tt> and propagated to the persistent object.
+	 *
+	 * @return <tt>true</tt> if the user modified the <tt>state</tt> in any way.
+	 */
+	public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
+	/**
+	 *  Called before an object is deleted. It is not recommended that the interceptor modify the <tt>state</tt>.
+	 */
+	public void onDelete(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) throws CallbackException;
+	/**
+	 * Called before a collection is (re)created.
+	 */
+	public void onCollectionRecreate(Object collection, Serializable key) throws CallbackException;
+	/**
+	 * Called before a collection is deleted.
+	 */
+	public void onCollectionRemove(Object collection, Serializable key) throws CallbackException;
+	/**
+	 * Called before a collection is updated.
+	 */
+	public void onCollectionUpdate(Object collection, Serializable key) throws CallbackException;
+	/**
+	 * Called before a flush
+	 */
+	public void preFlush(Iterator entities) throws CallbackException;
+	/**
+	 * Called after a flush that actually ends in execution of the SQL statements required to synchronize
+	 * in-memory state with the database.
+	 */
+	public void postFlush(Iterator entities) throws CallbackException;
+	/**
+	 * Called to distinguish between transient and detached entities. The return value determines the
+	 * state of the entity with respect to the current session.
+	 * <ul>
+	 * <li><tt>Boolean.TRUE</tt> - the entity is transient
+	 * <li><tt>Boolean.FALSE</tt> - the entity is detached
+	 * <li><tt>null</tt> - Hibernate uses the <tt>unsaved-value</tt> mapping and other heuristics to 
+	 * determine if the object is unsaved
+	 * </ul>
+	 * @param entity a transient or detached entity
+	 * @return Boolean or <tt>null</tt> to choose default behaviour
+	 */
+	public Boolean isTransient(Object entity);
+	/**
+	 * Called from <tt>flush()</tt>. The return value determines whether the entity is updated
+	 * <ul>
+	 * <li>an array of property indices - the entity is dirty
+	 * <li>an empty array - the entity is not dirty
+	 * <li><tt>null</tt> - use Hibernate's default dirty-checking algorithm
+	 * </ul>
+	 * @param entity a persistent entity
+	 * @return array of dirty property indices or <tt>null</tt> to choose default behaviour
+	 */
+	public int[] findDirty(Object entity, Serializable id, Object[] currentState, Object[] previousState, String[] propertyNames, Type[] types);
+	/**
+	 * Instantiate the entity class. Return <tt>null</tt> to indicate that Hibernate should use
+	 * the default constructor of the class. The identifier property of the returned instance
+	 * should be initialized with the given identifier.
+	 *
+	 * @param entityName the name of the entity
+	 * @param entityMode The type of entity instance to be returned.
+	 * @param id the identifier of the new instance
+	 * @return an instance of the class, or <tt>null</tt> to choose default behaviour
+	 */
+	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) throws CallbackException;
+
+	/**
+	 * Get the entity name for a persistent or transient instance
+	 * @param object an entity instance
+	 * @return the name of the entity
+	 */
+	public String getEntityName(Object object) throws CallbackException;
+
+	/**
+	 * Get a fully loaded entity instance that is cached externally
+	 * @param entityName the name of the entity
+	 * @param id the instance identifier
+	 * @return a fully initialized entity
+	 * @throws CallbackException
+	 */
+	public Object getEntity(String entityName, Serializable id) throws CallbackException;
+	
+	/**
+	 * Called when a Hibernate transaction is begun via the Hibernate <tt>Transaction</tt> 
+	 * API. Will not be called if transactions are being controlled via some other 
+	 * mechanism (CMT, for example).
+	 */
+	public void afterTransactionBegin(Transaction tx);
+	/**
+	 * Called before a transaction is committed (but not before rollback).
+	 */
+	public void beforeTransactionCompletion(Transaction tx);
+	/**
+	 * Called after a transaction is committed or rolled back.
+	 */
+	public void afterTransactionCompletion(Transaction tx);
+
+	/**
+	 * Called when sql string is being prepared. 
+	 * @param sql sql to be prepared
+	 * @return original or modified sql
+	 */
+	public String onPrepareStatement(String sql);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/InvalidMappingException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-package org.hibernate;
-
-/**
- * Thrown when a mapping is found to be invalid.
- * Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url)
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class InvalidMappingException extends MappingException {
-
-	private final String path;
-	private final String type;
-
-	public InvalidMappingException(String customMessage, String type, String path, Throwable cause) {
-		super(customMessage, cause);
-		this.type=type;
-		this.path=path;
-	}
-	
-	public InvalidMappingException(String customMessage, String type, String path) {
-		super(customMessage);
-		this.type=type;
-		this.path=path;
-	}
-	
-	public InvalidMappingException(String type, String path) {
-		this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
-	}
-
-	public InvalidMappingException(String type, String path, Throwable cause) {
-		this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);		
-	}
-
-	public String getType() {
-		return type;
-	}
-	
-	public String getPath() {
-		return path;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/InvalidMappingException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/InvalidMappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Thrown when a mapping is found to be invalid.
+ * Similar to MappingException, but this contains more info about the path and type of mapping (e.g. file, resource or url)
+ * 
+ * @author Max Rydahl Andersen
+ *
+ */
+public class InvalidMappingException extends MappingException {
+
+	private final String path;
+	private final String type;
+
+	public InvalidMappingException(String customMessage, String type, String path, Throwable cause) {
+		super(customMessage, cause);
+		this.type=type;
+		this.path=path;
+	}
+	
+	public InvalidMappingException(String customMessage, String type, String path) {
+		super(customMessage);
+		this.type=type;
+		this.path=path;
+	}
+	
+	public InvalidMappingException(String type, String path) {
+		this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path);
+	}
+
+	public InvalidMappingException(String type, String path, Throwable cause) {
+		this("Could not parse mapping document from " + type + (path==null?"":" " + path), type, path, cause);		
+	}
+
+	public String getType() {
+		return type;
+	}
+	
+	public String getPath() {
+		return path;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/JDBCException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: JDBCException.java 4626 2004-09-27 15:24:38Z oneovthafew $
-package org.hibernate;
-
-import java.sql.SQLException;
-
-
-/**
- * Wraps an <tt>SQLException</tt>. Indicates that an exception
- * occurred during a JDBC call.
- *
- * @see java.sql.SQLException
- * @author Gavin King
- */
-public class JDBCException extends HibernateException {
-
-	private SQLException sqle;
-	private String sql;
-
-	public JDBCException(String string, SQLException root) {
-		super(string, root);
-		sqle=root;
-	}
-
-	public JDBCException(String string, SQLException root, String sql) {
-		this(string, root);
-		this.sql = sql;
-	}
-
-	/**
-	 * Get the SQLState of the underlying <tt>SQLException</tt>.
-	 * @see java.sql.SQLException
-	 * @return String
-	 */
-	public String getSQLState() {
-		return sqle.getSQLState();
-	}
-
-	/**
-	 * Get the <tt>errorCode</tt> of the underlying <tt>SQLException</tt>.
-	 * @see java.sql.SQLException
-	 * @return int the error code
-	 */
-	public int getErrorCode() {
-		return sqle.getErrorCode();
-	}
-
-	/**
-	 * Get the underlying <tt>SQLException</tt>.
-	 * @return SQLException
-	 */
-	public SQLException getSQLException() {
-		return sqle;
-	}
-	
-	/**
-	 * Get the actual SQL statement that caused the exception
-	 * (may be null)
-	 */
-	public String getSQL() {
-		return sql;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/JDBCException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/JDBCException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.sql.SQLException;
+
+
+/**
+ * Wraps an <tt>SQLException</tt>. Indicates that an exception
+ * occurred during a JDBC call.
+ *
+ * @see java.sql.SQLException
+ * @author Gavin King
+ */
+public class JDBCException extends HibernateException {
+
+	private SQLException sqle;
+	private String sql;
+
+	public JDBCException(String string, SQLException root) {
+		super(string, root);
+		sqle=root;
+	}
+
+	public JDBCException(String string, SQLException root, String sql) {
+		this(string, root);
+		this.sql = sql;
+	}
+
+	/**
+	 * Get the SQLState of the underlying <tt>SQLException</tt>.
+	 * @see java.sql.SQLException
+	 * @return String
+	 */
+	public String getSQLState() {
+		return sqle.getSQLState();
+	}
+
+	/**
+	 * Get the <tt>errorCode</tt> of the underlying <tt>SQLException</tt>.
+	 * @see java.sql.SQLException
+	 * @return int the error code
+	 */
+	public int getErrorCode() {
+		return sqle.getErrorCode();
+	}
+
+	/**
+	 * Get the underlying <tt>SQLException</tt>.
+	 * @return SQLException
+	 */
+	public SQLException getSQLException() {
+		return sqle;
+	}
+	
+	/**
+	 * Get the actual SQL statement that caused the exception
+	 * (may be null)
+	 */
+	public String getSQL() {
+		return sql;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/LazyInitializationException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: LazyInitializationException.java 4458 2004-08-29 09:59:17Z oneovthafew $
-package org.hibernate;
-
-import org.slf4j.LoggerFactory;
-
-/**
- * Indicates access to unfetched data outside of a session context.
- * For example, when an uninitialized proxy or collection is accessed 
- * after the session was closed.
- *
- * @see Hibernate#initialize(java.lang.Object)
- * @see Hibernate#isInitialized(java.lang.Object)
- * @author Gavin King
- */
-public class LazyInitializationException extends HibernateException {
-
-	public LazyInitializationException(String msg) {
-		super(msg);
-		LoggerFactory.getLogger( LazyInitializationException.class ).error( msg, this );
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/LazyInitializationException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LazyInitializationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import org.slf4j.LoggerFactory;
+
+/**
+ * Indicates access to unfetched data outside of a session context.
+ * For example, when an uninitialized proxy or collection is accessed 
+ * after the session was closed.
+ *
+ * @see Hibernate#initialize(java.lang.Object)
+ * @see Hibernate#isInitialized(java.lang.Object)
+ * @author Gavin King
+ */
+public class LazyInitializationException extends HibernateException {
+
+	public LazyInitializationException(String msg) {
+		super(msg);
+		LoggerFactory.getLogger( LazyInitializationException.class ).error( msg, this );
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/LockMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,106 +0,0 @@
-//$Id: LockMode.java 9581 2006-03-09 15:50:15Z epbernard $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Instances represent a lock mode for a row of a relational
- * database table. It is not intended that users spend much
- * time worrying about locking since Hibernate usually
- * obtains exactly the right lock level automatically.
- * Some "advanced" users may wish to explicitly specify lock
- * levels.
- *
- * @see Session#lock(Object,LockMode)
- * @author Gavin King
- */
-public final class LockMode implements Serializable {
-	private final int level;
-	private final String name;
-	private static final Map INSTANCES = new HashMap();
-
-	private LockMode(int level, String name) {
-		this.level=level;
-		this.name=name;
-	}
-	public String toString() {
-		return name;
-	}
-	/**
-	 * Check if this lock mode is more restrictive than the given lock mode.
-	 *
-	 * @param mode LockMode to check
-	 * @return true if this lock mode is more restrictive than given lock mode
-	 */
-	public boolean greaterThan(LockMode mode) {
-		return level > mode.level;
-	}
-	/**
-	 * Check if this lock mode is less restrictive than the given lock mode.
-	 *
-	 * @param mode LockMode to check
-	 * @return true if this lock mode is less restrictive than given lock mode
-	 */
-	public boolean lessThan(LockMode mode) {
-		return level < mode.level;
-	}
-	/**
-	 * No lock required. If an object is requested with this lock
-	 * mode, a <tt>READ</tt> lock will be obtained if it is
-	 * necessary to actually read the state from the database,
-	 * rather than pull it from a cache.<br>
-	 * <br>
-	 * This is the "default" lock mode.
-	 */
-	public static final LockMode NONE = new LockMode(0, "NONE");
-	/**
-	 * A shared lock. Objects in this lock mode were read from
-	 * the database in the current transaction, rather than being
-	 * pulled from a cache.
-	 */
-	public static final LockMode READ = new LockMode(5, "READ");
-	/**
-	 * An upgrade lock. Objects loaded in this lock mode are
-	 * materialized using an SQL <tt>select ... for update</tt>.
-	 */
-	public static final LockMode UPGRADE = new LockMode(10, "UPGRADE");
-	/**
-	 * Attempt to obtain an upgrade lock, using an Oracle-style
-	 * <tt>select for update nowait</tt>. The semantics of
-	 * this lock mode, once obtained, are the same as
-	 * <tt>UPGRADE</tt>.
-	 */
-	public static final LockMode UPGRADE_NOWAIT = new LockMode(10, "UPGRADE_NOWAIT");
-	/**
-	 * A <tt>WRITE</tt> lock is obtained when an object is updated
-	 * or inserted.   This lock mode is for internal use only and is
-	 * not a valid mode for <tt>load()</tt> or <tt>lock()</tt> (both
-	 * of which throw exceptions if WRITE is specified).
-	 */
-	public static final LockMode WRITE = new LockMode(10, "WRITE");
-
-	/**
-	 * Similiar to {@link #UPGRADE} except that, for versioned entities,
-	 * it results in a forced version increment.
-	 */
-	public static final LockMode FORCE = new LockMode( 15, "FORCE" );
-
-	static {
-		INSTANCES.put( NONE.name, NONE );
-		INSTANCES.put( READ.name, READ );
-		INSTANCES.put( UPGRADE.name, UPGRADE );
-		INSTANCES.put( UPGRADE_NOWAIT.name, UPGRADE_NOWAIT );
-		INSTANCES.put( WRITE.name, WRITE );
-		INSTANCES.put( FORCE.name, FORCE );
-	}
-
-	private Object readResolve() {
-		return parse( name );
-	}
-
-	public static LockMode parse(String name) {
-		return ( LockMode ) INSTANCES.get(name);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/LockMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/LockMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Instances represent a lock mode for a row of a relational
+ * database table. It is not intended that users spend much
+ * time worrying about locking since Hibernate usually
+ * obtains exactly the right lock level automatically.
+ * Some "advanced" users may wish to explicitly specify lock
+ * levels.
+ *
+ * @see Session#lock(Object,LockMode)
+ * @author Gavin King
+ */
+public final class LockMode implements Serializable {
+	private final int level;
+	private final String name;
+	private static final Map INSTANCES = new HashMap();
+
+	private LockMode(int level, String name) {
+		this.level=level;
+		this.name=name;
+	}
+	public String toString() {
+		return name;
+	}
+	/**
+	 * Check if this lock mode is more restrictive than the given lock mode.
+	 *
+	 * @param mode LockMode to check
+	 * @return true if this lock mode is more restrictive than given lock mode
+	 */
+	public boolean greaterThan(LockMode mode) {
+		return level > mode.level;
+	}
+	/**
+	 * Check if this lock mode is less restrictive than the given lock mode.
+	 *
+	 * @param mode LockMode to check
+	 * @return true if this lock mode is less restrictive than given lock mode
+	 */
+	public boolean lessThan(LockMode mode) {
+		return level < mode.level;
+	}
+	/**
+	 * No lock required. If an object is requested with this lock
+	 * mode, a <tt>READ</tt> lock will be obtained if it is
+	 * necessary to actually read the state from the database,
+	 * rather than pull it from a cache.<br>
+	 * <br>
+	 * This is the "default" lock mode.
+	 */
+	public static final LockMode NONE = new LockMode(0, "NONE");
+	/**
+	 * A shared lock. Objects in this lock mode were read from
+	 * the database in the current transaction, rather than being
+	 * pulled from a cache.
+	 */
+	public static final LockMode READ = new LockMode(5, "READ");
+	/**
+	 * An upgrade lock. Objects loaded in this lock mode are
+	 * materialized using an SQL <tt>select ... for update</tt>.
+	 */
+	public static final LockMode UPGRADE = new LockMode(10, "UPGRADE");
+	/**
+	 * Attempt to obtain an upgrade lock, using an Oracle-style
+	 * <tt>select for update nowait</tt>. The semantics of
+	 * this lock mode, once obtained, are the same as
+	 * <tt>UPGRADE</tt>.
+	 */
+	public static final LockMode UPGRADE_NOWAIT = new LockMode(10, "UPGRADE_NOWAIT");
+	/**
+	 * A <tt>WRITE</tt> lock is obtained when an object is updated
+	 * or inserted.   This lock mode is for internal use only and is
+	 * not a valid mode for <tt>load()</tt> or <tt>lock()</tt> (both
+	 * of which throw exceptions if WRITE is specified).
+	 */
+	public static final LockMode WRITE = new LockMode(10, "WRITE");
+
+	/**
+	 * Similiar to {@link #UPGRADE} except that, for versioned entities,
+	 * it results in a forced version increment.
+	 */
+	public static final LockMode FORCE = new LockMode( 15, "FORCE" );
+
+	static {
+		INSTANCES.put( NONE.name, NONE );
+		INSTANCES.put( READ.name, READ );
+		INSTANCES.put( UPGRADE.name, UPGRADE );
+		INSTANCES.put( UPGRADE_NOWAIT.name, UPGRADE_NOWAIT );
+		INSTANCES.put( WRITE.name, WRITE );
+		INSTANCES.put( FORCE.name, FORCE );
+	}
+
+	private Object readResolve() {
+		return parse( name );
+	}
+
+	public static LockMode parse(String name) {
+		return ( LockMode ) INSTANCES.get(name);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/MappingException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-//$Id: MappingException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-/**
- * An exception that usually occurs at configuration time, rather
- * than runtime, as a result of something screwy in the O-R mappings.
- *
- * @author Gavin King
- */
-
-public class MappingException extends HibernateException {
-
-	public MappingException(String msg, Throwable root) {
-		super( msg, root );
-	}
-
-	public MappingException(Throwable root) {
-		super(root);
-	}
-
-	public MappingException(String s) {
-		super(s);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/MappingException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+/**
+ * An exception that usually occurs at configuration time, rather
+ * than runtime, as a result of something screwy in the O-R mappings.
+ *
+ * @author Gavin King
+ */
+
+public class MappingException extends HibernateException {
+
+	public MappingException(String msg, Throwable root) {
+		super( msg, root );
+	}
+
+	public MappingException(Throwable root) {
+		super(root);
+	}
+
+	public MappingException(String s) {
+		super(s);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/MappingNotFoundException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-package org.hibernate;
-
-/**
- * Thrown when a resource for a mapping could not be found.
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class MappingNotFoundException extends MappingException {
-
-	private final String path;
-	private final String type;
-
-	public MappingNotFoundException(String customMessage, String type, String path, Throwable cause) {
-		super(customMessage, cause);
-		this.type=type;
-		this.path=path;
-	}
-	
-	public MappingNotFoundException(String customMessage, String type, String path) {
-		super(customMessage);
-		this.type=type;
-		this.path=path;
-	}
-	
-	public MappingNotFoundException(String type, String path) {
-		this(type + ": " + path + " not found", type, path);
-	}
-
-	public MappingNotFoundException(String type, String path, Throwable cause) {
-		this(type + ": " + path + " not found", type, path, cause);
-	}
-
-	public String getType() {
-		return type;
-	}
-	
-	public String getPath() {
-		return path;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/MappingNotFoundException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/MappingNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Thrown when a resource for a mapping could not be found.
+ * 
+ * @author Max Rydahl Andersen
+ */
+public class MappingNotFoundException extends MappingException {
+
+	private final String path;
+	private final String type;
+
+	public MappingNotFoundException(String customMessage, String type, String path, Throwable cause) {
+		super(customMessage, cause);
+		this.type=type;
+		this.path=path;
+	}
+	
+	public MappingNotFoundException(String customMessage, String type, String path) {
+		super(customMessage);
+		this.type=type;
+		this.path=path;
+	}
+	
+	public MappingNotFoundException(String type, String path) {
+		this(type + ": " + path + " not found", type, path);
+	}
+
+	public MappingNotFoundException(String type, String path, Throwable cause) {
+		this(type + ": " + path + " not found", type, path, cause);
+	}
+
+	public String getType() {
+		return type;
+	}
+	
+	public String getPath() {
+		return path;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/NonUniqueObjectException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-//$Id: NonUniqueObjectException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * This exception is thrown when an operation would
- * break session-scoped identity. This occurs if the
- * user tries to associate two different instances of
- * the same Java class with a particular identifier,
- * in the scope of a single <tt>Session</tt>.
- *
- * @author Gavin King
- */
-public class NonUniqueObjectException extends HibernateException {
-	private final Serializable identifier;
-	private final String entityName;
-
-	public NonUniqueObjectException(String message, Serializable id, String clazz) {
-		super(message);
-		this.entityName = clazz;
-		this.identifier = id;
-	}
-
-	public NonUniqueObjectException(Serializable id, String clazz) {
-		this("a different object with the same identifier value was already associated with the session", id, clazz);
-	}
-
-	public Serializable getIdentifier() {
-		return identifier;
-	}
-
-	public String getMessage() {
-		return super.getMessage() + ": " +
-			MessageHelper.infoString(entityName, identifier);
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/NonUniqueObjectException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * This exception is thrown when an operation would
+ * break session-scoped identity. This occurs if the
+ * user tries to associate two different instances of
+ * the same Java class with a particular identifier,
+ * in the scope of a single <tt>Session</tt>.
+ *
+ * @author Gavin King
+ */
+public class NonUniqueObjectException extends HibernateException {
+	private final Serializable identifier;
+	private final String entityName;
+
+	public NonUniqueObjectException(String message, Serializable id, String clazz) {
+		super(message);
+		this.entityName = clazz;
+		this.identifier = id;
+	}
+
+	public NonUniqueObjectException(Serializable id, String clazz) {
+		this("a different object with the same identifier value was already associated with the session", id, clazz);
+	}
+
+	public Serializable getIdentifier() {
+		return identifier;
+	}
+
+	public String getMessage() {
+		return super.getMessage() + ": " +
+			MessageHelper.infoString(entityName, identifier);
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/NonUniqueResultException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-//$Id: NonUniqueResultException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-/**
- * Thrown when the application calls <tt>Query.uniqueResult()</tt> and
- * the query returned more than one result. Unlike all other Hibernate
- * exceptions, this one is recoverable!
- *
- * @author Gavin King
- */
-public class NonUniqueResultException extends HibernateException {
-
-	public NonUniqueResultException(int resultCount) {
-		super( "query did not return a unique result: " + resultCount );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/NonUniqueResultException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/NonUniqueResultException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * Thrown when the application calls <tt>Query.uniqueResult()</tt> and
+ * the query returned more than one result. Unlike all other Hibernate
+ * exceptions, this one is recoverable!
+ *
+ * @author Gavin King
+ */
+public class NonUniqueResultException extends HibernateException {
+
+	public NonUniqueResultException(int resultCount) {
+		super( "query did not return a unique result: " + resultCount );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ObjectDeletedException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: ObjectDeletedException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-/**
- * Thrown when the user tries to do something illegal with a deleted
- * object.
- *
- * @author Gavin King
- */
-public class ObjectDeletedException extends UnresolvableObjectException {
-
-	public ObjectDeletedException(String message, Serializable identifier, String clazz) {
-		super(message, identifier, clazz);
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ObjectDeletedException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectDeletedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * Thrown when the user tries to do something illegal with a deleted
+ * object.
+ *
+ * @author Gavin King
+ */
+public class ObjectDeletedException extends UnresolvableObjectException {
+
+	public ObjectDeletedException(String message, Serializable identifier, String clazz) {
+		super(message, identifier, clazz);
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ObjectNotFoundException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: ObjectNotFoundException.java 9855 2006-05-02 18:55:45Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import java.io.Serializable;
-
-/**
- * Thrown when <tt>Session.load()</tt> fails to select a row with
- * the given primary key (identifier value). This exception might not
- * be thrown when <tt>load()</tt> is called, even if there was no
- * row on the database, because <tt>load()</tt> returns a proxy if
- * possible. Applications should use <tt>Session.get()</tt> to test if
- * a row exists in the database.<br>
- * <br> 
- * Like all Hibernate exceptions, this exception is considered 
- * unrecoverable.
- *
- * @author Gavin King
- */
-public class ObjectNotFoundException extends UnresolvableObjectException {
-
-	public ObjectNotFoundException(Serializable identifier, String clazz) {
-		super(identifier, clazz);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ObjectNotFoundException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ObjectNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.io.Serializable;
+
+/**
+ * Thrown when <tt>Session.load()</tt> fails to select a row with
+ * the given primary key (identifier value). This exception might not
+ * be thrown when <tt>load()</tt> is called, even if there was no
+ * row on the database, because <tt>load()</tt> returns a proxy if
+ * possible. Applications should use <tt>Session.get()</tt> to test if
+ * a row exists in the database.<br>
+ * <br> 
+ * Like all Hibernate exceptions, this exception is considered 
+ * unrecoverable.
+ *
+ * @author Gavin King
+ */
+public class ObjectNotFoundException extends UnresolvableObjectException {
+
+	public ObjectNotFoundException(Serializable identifier, String clazz) {
+		super(identifier, clazz);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/PersistentObjectException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: PersistentObjectException.java 6877 2005-05-23 15:00:25Z oneovthafew $
-package org.hibernate;
-
-/**
- * Thrown when the user passes a persistent instance to a <tt>Session</tt>
- * method that expects a transient instance.
- *
- * @author Gavin King
- */
-public class PersistentObjectException extends HibernateException {
-	
-	public PersistentObjectException(String s) {
-		super(s);
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/PersistentObjectException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PersistentObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Thrown when the user passes a persistent instance to a <tt>Session</tt>
+ * method that expects a transient instance.
+ *
+ * @author Gavin King
+ */
+public class PersistentObjectException extends HibernateException {
+	
+	public PersistentObjectException(String s) {
+		super(s);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/PropertyAccessException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: PropertyAccessException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * A problem occurred accessing a property of an instance of a
- * persistent class by reflection, or via CGLIB. There are a
- * number of possible underlying causes, including
- * <ul>
- * <li>failure of a security check
- * <li>an exception occurring inside the getter or setter method
- * <li>a nullable database column was mapped to a primitive-type property
- * <li>the Hibernate type was not castable to the property type (or vice-versa)
- * </ul>
- * @author Gavin King
- */
-public class PropertyAccessException extends HibernateException {
-
-	private final Class persistentClass;
-	private final String propertyName;
-	private final boolean wasSetter;
-
-	public PropertyAccessException(Throwable root, String s, boolean wasSetter, Class persistentClass, String propertyName) {
-		super(s, root);
-		this.persistentClass = persistentClass;
-		this.wasSetter = wasSetter;
-		this.propertyName = propertyName;
-	}
-
-	public Class getPersistentClass() {
-		return persistentClass;
-	}
-
-	public String getPropertyName() {
-		return propertyName;
-	}
-
-	public String getMessage() {
-		return super.getMessage() +
-		( wasSetter ? " setter of " : " getter of ") +
-		StringHelper.qualify( persistentClass.getName(), propertyName );
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/PropertyAccessException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyAccessException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * A problem occurred accessing a property of an instance of a
+ * persistent class by reflection, or via CGLIB. There are a
+ * number of possible underlying causes, including
+ * <ul>
+ * <li>failure of a security check
+ * <li>an exception occurring inside the getter or setter method
+ * <li>a nullable database column was mapped to a primitive-type property
+ * <li>the Hibernate type was not castable to the property type (or vice-versa)
+ * </ul>
+ * @author Gavin King
+ */
+public class PropertyAccessException extends HibernateException {
+
+	private final Class persistentClass;
+	private final String propertyName;
+	private final boolean wasSetter;
+
+	public PropertyAccessException(Throwable root, String s, boolean wasSetter, Class persistentClass, String propertyName) {
+		super(s, root);
+		this.persistentClass = persistentClass;
+		this.wasSetter = wasSetter;
+		this.propertyName = propertyName;
+	}
+
+	public Class getPersistentClass() {
+		return persistentClass;
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	public String getMessage() {
+		return super.getMessage() +
+		( wasSetter ? " setter of " : " getter of ") +
+		StringHelper.qualify( persistentClass.getName(), propertyName );
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/PropertyNotFoundException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: PropertyNotFoundException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-/**
- * Indicates that an expected getter or setter method could not be
- * found on a class.
- *
- * @author Gavin King
- */
-public class PropertyNotFoundException extends MappingException {
-
-	public PropertyNotFoundException(String s) {
-		super(s);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/PropertyNotFoundException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyNotFoundException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Indicates that an expected getter or setter method could not be
+ * found on a class.
+ *
+ * @author Gavin King
+ */
+public class PropertyNotFoundException extends MappingException {
+
+	public PropertyNotFoundException(String s) {
+		super(s);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/PropertyValueException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,56 +0,0 @@
-//$Id: PropertyValueException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * Thrown when the (illegal) value of a property can not be persisted.
- * There are two main causes:
- * <ul>
- * <li>a property declared <tt>not-null="true"</tt> is null
- * <li>an association references an unsaved transient instance
- * </ul>
- * @author Gavin King
- */
-public class PropertyValueException extends HibernateException {
-
-	private final String entityName;
-	private final String propertyName;
-
-	public PropertyValueException(String s, String entityName, String propertyName) {
-		super(s);
-		this.entityName = entityName;
-		this.propertyName = propertyName;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public String getPropertyName() {
-		return propertyName;
-	}
-
-	public String getMessage() {
-		return super.getMessage() + ": " +
-			StringHelper.qualify(entityName, propertyName);
-	}
-
-	/**
-	 * Return a well formed property path.
-	 * Basicaly, it will return parent.child
-	 *
-	 * @param parent parent in path
-	 * @param child child in path
-	 * @return parent-child path
-	 */
-	public static String buildPropertyPath(String parent, String child) {
-		return new StringBuffer(parent).append('.').append(child).toString();
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/PropertyValueException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/PropertyValueException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * Thrown when the (illegal) value of a property can not be persisted.
+ * There are two main causes:
+ * <ul>
+ * <li>a property declared <tt>not-null="true"</tt> is null
+ * <li>an association references an unsaved transient instance
+ * </ul>
+ * @author Gavin King
+ */
+public class PropertyValueException extends HibernateException {
+
+	private final String entityName;
+	private final String propertyName;
+
+	public PropertyValueException(String s, String entityName, String propertyName) {
+		super(s);
+		this.entityName = entityName;
+		this.propertyName = propertyName;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	public String getMessage() {
+		return super.getMessage() + ": " +
+			StringHelper.qualify(entityName, propertyName);
+	}
+
+	/**
+	 * Return a well formed property path.
+	 * Basicaly, it will return parent.child
+	 *
+	 * @param parent parent in path
+	 * @param child child in path
+	 * @return parent-child path
+	 */
+	public static String buildPropertyPath(String parent, String child) {
+		return new StringBuffer(parent).append('.').append(child).toString();
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Query.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,386 +0,0 @@
-//$Id: Query.java 10591 2006-10-17 08:57:26Z max.andersen at jboss.com $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-
-/**
- * An object-oriented representation of a Hibernate query. A <tt>Query</tt>
- * instance is obtained by calling <tt>Session.createQuery()</tt>. This
- * interface exposes some extra functionality beyond that provided by
- * <tt>Session.iterate()</tt> and <tt>Session.find()</tt>:
- * <ul>
- * <li>a particular page of the result set may be selected by calling <tt>
- * setMaxResults(), setFirstResult()</tt>
- * <li>named query parameters may be used
- * <li>the results may be returned as an instance of <tt>ScrollableResults</tt>
- * </ul>
- * <br>
- * Named query parameters are tokens of the form <tt>:name</tt> in the
- * query string. A value is bound to the <tt>integer</tt> parameter
- * <tt>:foo</tt> by calling<br>
- * <br>
- * <tt>setParameter("foo", foo, Hibernate.INTEGER);</tt><br>
- * <br>
- * for example. A name may appear multiple times in the query string.<br>
- * <br>
- * JDBC-style <tt>?</tt> parameters are also supported. To bind a
- * value to a JDBC-style parameter use a set method that accepts an
- * <tt>int</tt> positional argument (numbered from zero, contrary
- * to JDBC).<br>
- * <br>
- * You may not mix and match JDBC-style parameters and named parameters
- * in the same query.<br>
- * <br>
- * Queries are executed by calling <tt>list()</tt>, <tt>scroll()</tt> or
- * <tt>iterate()</tt>. A query may be re-executed by subsequent invocations.
- * Its lifespan is, however, bounded by the lifespan of the <tt>Session</tt>
- * that created it.<br>
- * <br>
- * Implementors are not intended to be threadsafe.
- *
- * @see org.hibernate.Session#createQuery(java.lang.String)
- * @see org.hibernate.ScrollableResults
- * @author Gavin King
- */
-public interface Query {
-	/**
-	 * Get the query string.
-	 *
-	 * @return the query string
-	 */
-	public String getQueryString();
-	/**
-	 * Return the Hibernate types of the query result set.
-	 * @return an array of types
-	 */
-	public Type[] getReturnTypes() throws HibernateException;
-	/**
-	 * Return the HQL select clause aliases (if any)
-	 * @return an array of aliases as strings
-	 */
-	public String[] getReturnAliases() throws HibernateException;
-	/**
-	 * Return the names of all named parameters of the query.
-	 * @return the parameter names, in no particular order
-	 */
-	public String[] getNamedParameters() throws HibernateException;
-	/**
-	 * Return the query results as an <tt>Iterator</tt>. If the query
-	 * contains multiple results pre row, the results are returned in
-	 * an instance of <tt>Object[]</tt>.<br>
-	 * <br>
-	 * Entities returned as results are initialized on demand. The first
-	 * SQL query returns identifiers only.<br>
-	 *
-	 * @return the result iterator
-	 * @throws HibernateException
-	 */
-	public Iterator iterate() throws HibernateException;
-	/**
-	 * Return the query results as <tt>ScrollableResults</tt>. The
-	 * scrollability of the returned results depends upon JDBC driver
-	 * support for scrollable <tt>ResultSet</tt>s.<br>
-	 *
-	 * @see ScrollableResults
-	 * @return the result iterator
-	 * @throws HibernateException
-	 */
-	public ScrollableResults scroll() throws HibernateException;
-	/**
-	 * Return the query results as <tt>ScrollableResults</tt>. The
-	 * scrollability of the returned results depends upon JDBC driver
-	 * support for scrollable <tt>ResultSet</tt>s.<br>
-	 *
-	 * @see ScrollableResults
-	 * @see ScrollMode
-	 * @return the result iterator
-	 * @throws HibernateException
-	 */
-	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException;
-	/**
-	 * Return the query results as a <tt>List</tt>. If the query contains
-	 * multiple results pre row, the results are returned in an instance
-	 * of <tt>Object[]</tt>.
-	 *
-	 * @return the result list
-	 * @throws HibernateException
-	 */
-	public List list() throws HibernateException;
-	/**
-	 * Convenience method to return a single instance that matches
-	 * the query, or null if the query returns no results.
-	 *
-	 * @return the single result or <tt>null</tt>
-	 * @throws NonUniqueResultException if there is more than one matching result
-	 */
-	public Object uniqueResult() throws HibernateException;
-
-	/**
-	 * Execute the update or delete statement.
-	 * </p>
-	 * The semantics are compliant with the ejb3 Query.executeUpdate()
-	 * method.
-	 *
-	 * @return The number of entities updated or deleted.
-	 * @throws HibernateException
-	 */
-	public int executeUpdate() throws HibernateException;
-
-	/**
-	 * Set the maximum number of rows to retrieve. If not set,
-	 * there is no limit to the number of rows retrieved.
-	 * @param maxResults the maximum number of rows
-	 */
-	public Query setMaxResults(int maxResults);
-	/**
-	 * Set the first row to retrieve. If not set, rows will be
-	 * retrieved beginnning from row <tt>0</tt>.
-	 * @param firstResult a row number, numbered from <tt>0</tt>
-	 */
-	public Query setFirstResult(int firstResult);
-	
-	/**
-	 * Entities retrieved by this query will be loaded in 
-	 * a read-only mode where Hibernate will never dirty-check
-	 * them or make changes persistent.
-	 *
-	 */
-	public Query setReadOnly(boolean readOnly);
-
-	/**
-	 * Enable caching of this query result set.
-	 * @param cacheable Should the query results be cacheable?
-	 */
-	public Query setCacheable(boolean cacheable);
-
-	/**
-	 * Set the name of the cache region.
-	 * @param cacheRegion the name of a query cache region, or <tt>null</tt>
-	 * for the default query cache
-	 */
-	public Query setCacheRegion(String cacheRegion);
-
-	/**
-	 * Set a timeout for the underlying JDBC query.
-	 * @param timeout the timeout in seconds
-	 */
-	public Query setTimeout(int timeout);
-	/**
-	 * Set a fetch size for the underlying JDBC query.
-	 * @param fetchSize the fetch size
-	 */
-	public Query setFetchSize(int fetchSize);
-
-	/**
-	 * Set the lockmode for the objects idententified by the
-	 * given alias that appears in the <tt>FROM</tt> clause.
-	 * @param alias a query alias, or <tt>this</tt> for a collection filter
-	 */
-	public Query setLockMode(String alias, LockMode lockMode);
-
-	/**
-	 * Add a comment to the generated SQL.
-	 * @param comment a human-readable string
-	 */
-	public Query setComment(String comment);
-	
-	/**
-	 * Override the current session flush mode, just for
-	 * this query.
-	 * @see org.hibernate.FlushMode
-	 */
-	public Query setFlushMode(FlushMode flushMode);
-
-	/**
-	 * Override the current session cache mode, just for
-	 * this query.
-	 * @see org.hibernate.CacheMode
-	 */
-	public Query setCacheMode(CacheMode cacheMode);
-
-	/**
-	 * Bind a value to a JDBC-style query parameter.
-	 * @param position the position of the parameter in the query
-	 * string, numbered from <tt>0</tt>.
-	 * @param val the possibly-null parameter value
-	 * @param type the Hibernate type
-	 */
-	public Query setParameter(int position, Object val, Type type);
-	/**
-	 * Bind a value to a named query parameter.
-	 * @param name the name of the parameter
-	 * @param val the possibly-null parameter value
-	 * @param type the Hibernate type
-	 */
-	public Query setParameter(String name, Object val, Type type);
-
-	/**
-	 * Bind a value to a JDBC-style query parameter. The Hibernate type of the parameter is
-	 * first detected via the usage/position in the query and if not sufficient secondly 
-	 * guessed from the class of the given object.
-	 * @param position the position of the parameter in the query
-	 * string, numbered from <tt>0</tt>.
-	 * @param val the non-null parameter value
-	 * @throws org.hibernate.HibernateException if no type could be determined
-	 */
-	public Query setParameter(int position, Object val) throws HibernateException;
-	/**
-	 * Bind a value to a named query parameter. The Hibernate type of the parameter is
-	 * first detected via the usage/position in the query and if not sufficient secondly 
-	 * guessed from the class of the given object.
-	 * @param name the name of the parameter
-	 * @param val the non-null parameter value
-	 * @throws org.hibernate.HibernateException if no type could be determined
-	 */
-	public Query setParameter(String name, Object val) throws HibernateException;
-	
-	/**
-	 * Bind values and types to positional parameters.
-	 */
-	public Query setParameters(Object[] values, Type[] types) throws HibernateException;
-
-	/**
-	 * Bind multiple values to a named query parameter. This is useful for binding
-	 * a list of values to an expression such as <tt>foo.bar in (:value_list)</tt>.
-	 * @param name the name of the parameter
-	 * @param vals a collection of values to list
-	 * @param type the Hibernate type of the values
-	 */
-	public Query setParameterList(String name, Collection vals, Type type) throws HibernateException;
-
-	/**
-	 * Bind multiple values to a named query parameter. The Hibernate type of the parameter is
-	 * first detected via the usage/position in the query and if not sufficient secondly 
-	 * guessed from the class of the first object in the collection. This is useful for binding a list of values
-	 * to an expression such as <tt>foo.bar in (:value_list)</tt>.
-	 * @param name the name of the parameter
-	 * @param vals a collection of values to list
-	 */
-	public Query setParameterList(String name, Collection vals) throws HibernateException;
-
-	/**
-	 * Bind multiple values to a named query parameter. This is useful for binding
-	 * a list of values to an expression such as <tt>foo.bar in (:value_list)</tt>.
-	 * @param name the name of the parameter
-	 * @param vals a collection of values to list
-	 * @param type the Hibernate type of the values
-	 */
-	public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException;
-
-	/**
-	 * Bind multiple values to a named query parameter. The Hibernate type of the parameter is
-	 * first detected via the usage/position in the query and if not sufficient secondly 
-	 * guessed from the class of the first object in the array. This is useful for binding a list of values
-	 * to an expression such as <tt>foo.bar in (:value_list)</tt>.
-	 * @param name the name of the parameter
-	 * @param vals a collection of values to list
-	 */
-	public Query setParameterList(String name, Object[] vals) throws HibernateException;
-
-	/**
-	 * Bind the property values of the given bean to named parameters of the query,
-	 * matching property names with parameter names and mapping property types to
-	 * Hibernate types using hueristics.
-	 * @param bean any JavaBean or POJO
-	 */	
-	public Query setProperties(Object bean) throws HibernateException;
-	
-	/**
-	 * Bind the values of the given Map for each named parameters of the query,
-	 * matching key names with parameter names and mapping value types to
-	 * Hibernate types using hueristics.
-	 * @param bean a java.util.Map
-	 */
-	public Query setProperties(Map bean) throws HibernateException;
-
-	public Query setString(int position, String val);
-	public Query setCharacter(int position, char val);
-	public Query setBoolean(int position, boolean val);
-	public Query setByte(int position, byte val);
-	public Query setShort(int position, short val);
-	public Query setInteger(int position, int val);
-	public Query setLong(int position, long val);
-	public Query setFloat(int position, float val);
-	public Query setDouble(int position, double val);
-	public Query setBinary(int position, byte[] val);
-	public Query setText(int position, String val);
-	public Query setSerializable(int position, Serializable val);
-	public Query setLocale(int position, Locale locale);
-	public Query setBigDecimal(int position, BigDecimal number);
-	public Query setBigInteger(int position, BigInteger number);
-
-	public Query setDate(int position, Date date);
-	public Query setTime(int position, Date date);
-	public Query setTimestamp(int position, Date date);
-
-	public Query setCalendar(int position, Calendar calendar);
-	public Query setCalendarDate(int position, Calendar calendar);
-
-	public Query setString(String name, String val);
-	public Query setCharacter(String name, char val);
-	public Query setBoolean(String name, boolean val);
-	public Query setByte(String name, byte val);
-	public Query setShort(String name, short val);
-	public Query setInteger(String name, int val);
-	public Query setLong(String name, long val);
-	public Query setFloat(String name, float val);
-	public Query setDouble(String name, double val);
-	public Query setBinary(String name, byte[] val);
-	public Query setText(String name, String val);
-	public Query setSerializable(String name, Serializable val);
-	public Query setLocale(String name, Locale locale);
-	public Query setBigDecimal(String name, BigDecimal number);
-	public Query setBigInteger(String name, BigInteger number);
-
-	public Query setDate(String name, Date date);
-	public Query setTime(String name, Date date);
-	public Query setTimestamp(String name, Date date);
-
-	public Query setCalendar(String name, Calendar calendar);
-	public Query setCalendarDate(String name, Calendar calendar);
-
-	/**
-	 * Bind an instance of a mapped persistent class to a JDBC-style query parameter.
-	 * @param position the position of the parameter in the query
-	 * string, numbered from <tt>0</tt>.
-	 * @param val a non-null instance of a persistent class
-	 */
-	public Query setEntity(int position, Object val); // use setParameter for null values
-
-	/**
-	 * Bind an instance of a mapped persistent class to a named query parameter.
-	 * @param name the name of the parameter
-	 * @param val a non-null instance of a persistent class
-	 */
-	public Query setEntity(String name, Object val); // use setParameter for null values
-	
-	
-	/**
-	 * Set a strategy for handling the query results. This can be used to change
-	 * "shape" of the query result.
-	 *
-	 * @param transformer The transformer to apply
-	 * @return this (for method chaining)	
-	 */
-	public Query setResultTransformer(ResultTransformer transformer);
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Query.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Query.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,409 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+
+/**
+ * An object-oriented representation of a Hibernate query. A <tt>Query</tt>
+ * instance is obtained by calling <tt>Session.createQuery()</tt>. This
+ * interface exposes some extra functionality beyond that provided by
+ * <tt>Session.iterate()</tt> and <tt>Session.find()</tt>:
+ * <ul>
+ * <li>a particular page of the result set may be selected by calling <tt>
+ * setMaxResults(), setFirstResult()</tt>
+ * <li>named query parameters may be used
+ * <li>the results may be returned as an instance of <tt>ScrollableResults</tt>
+ * </ul>
+ * <br>
+ * Named query parameters are tokens of the form <tt>:name</tt> in the
+ * query string. A value is bound to the <tt>integer</tt> parameter
+ * <tt>:foo</tt> by calling<br>
+ * <br>
+ * <tt>setParameter("foo", foo, Hibernate.INTEGER);</tt><br>
+ * <br>
+ * for example. A name may appear multiple times in the query string.<br>
+ * <br>
+ * JDBC-style <tt>?</tt> parameters are also supported. To bind a
+ * value to a JDBC-style parameter use a set method that accepts an
+ * <tt>int</tt> positional argument (numbered from zero, contrary
+ * to JDBC).<br>
+ * <br>
+ * You may not mix and match JDBC-style parameters and named parameters
+ * in the same query.<br>
+ * <br>
+ * Queries are executed by calling <tt>list()</tt>, <tt>scroll()</tt> or
+ * <tt>iterate()</tt>. A query may be re-executed by subsequent invocations.
+ * Its lifespan is, however, bounded by the lifespan of the <tt>Session</tt>
+ * that created it.<br>
+ * <br>
+ * Implementors are not intended to be threadsafe.
+ *
+ * @see org.hibernate.Session#createQuery(java.lang.String)
+ * @see org.hibernate.ScrollableResults
+ * @author Gavin King
+ */
+public interface Query {
+	/**
+	 * Get the query string.
+	 *
+	 * @return the query string
+	 */
+	public String getQueryString();
+	/**
+	 * Return the Hibernate types of the query result set.
+	 * @return an array of types
+	 */
+	public Type[] getReturnTypes() throws HibernateException;
+	/**
+	 * Return the HQL select clause aliases (if any)
+	 * @return an array of aliases as strings
+	 */
+	public String[] getReturnAliases() throws HibernateException;
+	/**
+	 * Return the names of all named parameters of the query.
+	 * @return the parameter names, in no particular order
+	 */
+	public String[] getNamedParameters() throws HibernateException;
+	/**
+	 * Return the query results as an <tt>Iterator</tt>. If the query
+	 * contains multiple results pre row, the results are returned in
+	 * an instance of <tt>Object[]</tt>.<br>
+	 * <br>
+	 * Entities returned as results are initialized on demand. The first
+	 * SQL query returns identifiers only.<br>
+	 *
+	 * @return the result iterator
+	 * @throws HibernateException
+	 */
+	public Iterator iterate() throws HibernateException;
+	/**
+	 * Return the query results as <tt>ScrollableResults</tt>. The
+	 * scrollability of the returned results depends upon JDBC driver
+	 * support for scrollable <tt>ResultSet</tt>s.<br>
+	 *
+	 * @see ScrollableResults
+	 * @return the result iterator
+	 * @throws HibernateException
+	 */
+	public ScrollableResults scroll() throws HibernateException;
+	/**
+	 * Return the query results as <tt>ScrollableResults</tt>. The
+	 * scrollability of the returned results depends upon JDBC driver
+	 * support for scrollable <tt>ResultSet</tt>s.<br>
+	 *
+	 * @see ScrollableResults
+	 * @see ScrollMode
+	 * @return the result iterator
+	 * @throws HibernateException
+	 */
+	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException;
+	/**
+	 * Return the query results as a <tt>List</tt>. If the query contains
+	 * multiple results pre row, the results are returned in an instance
+	 * of <tt>Object[]</tt>.
+	 *
+	 * @return the result list
+	 * @throws HibernateException
+	 */
+	public List list() throws HibernateException;
+	/**
+	 * Convenience method to return a single instance that matches
+	 * the query, or null if the query returns no results.
+	 *
+	 * @return the single result or <tt>null</tt>
+	 * @throws NonUniqueResultException if there is more than one matching result
+	 */
+	public Object uniqueResult() throws HibernateException;
+
+	/**
+	 * Execute the update or delete statement.
+	 * </p>
+	 * The semantics are compliant with the ejb3 Query.executeUpdate()
+	 * method.
+	 *
+	 * @return The number of entities updated or deleted.
+	 * @throws HibernateException
+	 */
+	public int executeUpdate() throws HibernateException;
+
+	/**
+	 * Set the maximum number of rows to retrieve. If not set,
+	 * there is no limit to the number of rows retrieved.
+	 * @param maxResults the maximum number of rows
+	 */
+	public Query setMaxResults(int maxResults);
+	/**
+	 * Set the first row to retrieve. If not set, rows will be
+	 * retrieved beginnning from row <tt>0</tt>.
+	 * @param firstResult a row number, numbered from <tt>0</tt>
+	 */
+	public Query setFirstResult(int firstResult);
+	
+	/**
+	 * Entities retrieved by this query will be loaded in 
+	 * a read-only mode where Hibernate will never dirty-check
+	 * them or make changes persistent.
+	 *
+	 */
+	public Query setReadOnly(boolean readOnly);
+
+	/**
+	 * Enable caching of this query result set.
+	 * @param cacheable Should the query results be cacheable?
+	 */
+	public Query setCacheable(boolean cacheable);
+
+	/**
+	 * Set the name of the cache region.
+	 * @param cacheRegion the name of a query cache region, or <tt>null</tt>
+	 * for the default query cache
+	 */
+	public Query setCacheRegion(String cacheRegion);
+
+	/**
+	 * Set a timeout for the underlying JDBC query.
+	 * @param timeout the timeout in seconds
+	 */
+	public Query setTimeout(int timeout);
+	/**
+	 * Set a fetch size for the underlying JDBC query.
+	 * @param fetchSize the fetch size
+	 */
+	public Query setFetchSize(int fetchSize);
+
+	/**
+	 * Set the lockmode for the objects idententified by the
+	 * given alias that appears in the <tt>FROM</tt> clause.
+	 * @param alias a query alias, or <tt>this</tt> for a collection filter
+	 */
+	public Query setLockMode(String alias, LockMode lockMode);
+
+	/**
+	 * Add a comment to the generated SQL.
+	 * @param comment a human-readable string
+	 */
+	public Query setComment(String comment);
+	
+	/**
+	 * Override the current session flush mode, just for
+	 * this query.
+	 * @see org.hibernate.FlushMode
+	 */
+	public Query setFlushMode(FlushMode flushMode);
+
+	/**
+	 * Override the current session cache mode, just for
+	 * this query.
+	 * @see org.hibernate.CacheMode
+	 */
+	public Query setCacheMode(CacheMode cacheMode);
+
+	/**
+	 * Bind a value to a JDBC-style query parameter.
+	 * @param position the position of the parameter in the query
+	 * string, numbered from <tt>0</tt>.
+	 * @param val the possibly-null parameter value
+	 * @param type the Hibernate type
+	 */
+	public Query setParameter(int position, Object val, Type type);
+	/**
+	 * Bind a value to a named query parameter.
+	 * @param name the name of the parameter
+	 * @param val the possibly-null parameter value
+	 * @param type the Hibernate type
+	 */
+	public Query setParameter(String name, Object val, Type type);
+
+	/**
+	 * Bind a value to a JDBC-style query parameter. The Hibernate type of the parameter is
+	 * first detected via the usage/position in the query and if not sufficient secondly 
+	 * guessed from the class of the given object.
+	 * @param position the position of the parameter in the query
+	 * string, numbered from <tt>0</tt>.
+	 * @param val the non-null parameter value
+	 * @throws org.hibernate.HibernateException if no type could be determined
+	 */
+	public Query setParameter(int position, Object val) throws HibernateException;
+	/**
+	 * Bind a value to a named query parameter. The Hibernate type of the parameter is
+	 * first detected via the usage/position in the query and if not sufficient secondly 
+	 * guessed from the class of the given object.
+	 * @param name the name of the parameter
+	 * @param val the non-null parameter value
+	 * @throws org.hibernate.HibernateException if no type could be determined
+	 */
+	public Query setParameter(String name, Object val) throws HibernateException;
+	
+	/**
+	 * Bind values and types to positional parameters.
+	 */
+	public Query setParameters(Object[] values, Type[] types) throws HibernateException;
+
+	/**
+	 * Bind multiple values to a named query parameter. This is useful for binding
+	 * a list of values to an expression such as <tt>foo.bar in (:value_list)</tt>.
+	 * @param name the name of the parameter
+	 * @param vals a collection of values to list
+	 * @param type the Hibernate type of the values
+	 */
+	public Query setParameterList(String name, Collection vals, Type type) throws HibernateException;
+
+	/**
+	 * Bind multiple values to a named query parameter. The Hibernate type of the parameter is
+	 * first detected via the usage/position in the query and if not sufficient secondly 
+	 * guessed from the class of the first object in the collection. This is useful for binding a list of values
+	 * to an expression such as <tt>foo.bar in (:value_list)</tt>.
+	 * @param name the name of the parameter
+	 * @param vals a collection of values to list
+	 */
+	public Query setParameterList(String name, Collection vals) throws HibernateException;
+
+	/**
+	 * Bind multiple values to a named query parameter. This is useful for binding
+	 * a list of values to an expression such as <tt>foo.bar in (:value_list)</tt>.
+	 * @param name the name of the parameter
+	 * @param vals a collection of values to list
+	 * @param type the Hibernate type of the values
+	 */
+	public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException;
+
+	/**
+	 * Bind multiple values to a named query parameter. The Hibernate type of the parameter is
+	 * first detected via the usage/position in the query and if not sufficient secondly 
+	 * guessed from the class of the first object in the array. This is useful for binding a list of values
+	 * to an expression such as <tt>foo.bar in (:value_list)</tt>.
+	 * @param name the name of the parameter
+	 * @param vals a collection of values to list
+	 */
+	public Query setParameterList(String name, Object[] vals) throws HibernateException;
+
+	/**
+	 * Bind the property values of the given bean to named parameters of the query,
+	 * matching property names with parameter names and mapping property types to
+	 * Hibernate types using hueristics.
+	 * @param bean any JavaBean or POJO
+	 */	
+	public Query setProperties(Object bean) throws HibernateException;
+	
+	/**
+	 * Bind the values of the given Map for each named parameters of the query,
+	 * matching key names with parameter names and mapping value types to
+	 * Hibernate types using hueristics.
+	 * @param bean a java.util.Map
+	 */
+	public Query setProperties(Map bean) throws HibernateException;
+
+	public Query setString(int position, String val);
+	public Query setCharacter(int position, char val);
+	public Query setBoolean(int position, boolean val);
+	public Query setByte(int position, byte val);
+	public Query setShort(int position, short val);
+	public Query setInteger(int position, int val);
+	public Query setLong(int position, long val);
+	public Query setFloat(int position, float val);
+	public Query setDouble(int position, double val);
+	public Query setBinary(int position, byte[] val);
+	public Query setText(int position, String val);
+	public Query setSerializable(int position, Serializable val);
+	public Query setLocale(int position, Locale locale);
+	public Query setBigDecimal(int position, BigDecimal number);
+	public Query setBigInteger(int position, BigInteger number);
+
+	public Query setDate(int position, Date date);
+	public Query setTime(int position, Date date);
+	public Query setTimestamp(int position, Date date);
+
+	public Query setCalendar(int position, Calendar calendar);
+	public Query setCalendarDate(int position, Calendar calendar);
+
+	public Query setString(String name, String val);
+	public Query setCharacter(String name, char val);
+	public Query setBoolean(String name, boolean val);
+	public Query setByte(String name, byte val);
+	public Query setShort(String name, short val);
+	public Query setInteger(String name, int val);
+	public Query setLong(String name, long val);
+	public Query setFloat(String name, float val);
+	public Query setDouble(String name, double val);
+	public Query setBinary(String name, byte[] val);
+	public Query setText(String name, String val);
+	public Query setSerializable(String name, Serializable val);
+	public Query setLocale(String name, Locale locale);
+	public Query setBigDecimal(String name, BigDecimal number);
+	public Query setBigInteger(String name, BigInteger number);
+
+	public Query setDate(String name, Date date);
+	public Query setTime(String name, Date date);
+	public Query setTimestamp(String name, Date date);
+
+	public Query setCalendar(String name, Calendar calendar);
+	public Query setCalendarDate(String name, Calendar calendar);
+
+	/**
+	 * Bind an instance of a mapped persistent class to a JDBC-style query parameter.
+	 * @param position the position of the parameter in the query
+	 * string, numbered from <tt>0</tt>.
+	 * @param val a non-null instance of a persistent class
+	 */
+	public Query setEntity(int position, Object val); // use setParameter for null values
+
+	/**
+	 * Bind an instance of a mapped persistent class to a named query parameter.
+	 * @param name the name of the parameter
+	 * @param val a non-null instance of a persistent class
+	 */
+	public Query setEntity(String name, Object val); // use setParameter for null values
+	
+	
+	/**
+	 * Set a strategy for handling the query results. This can be used to change
+	 * "shape" of the query result.
+	 *
+	 * @param transformer The transformer to apply
+	 * @return this (for method chaining)	
+	 */
+	public Query setResultTransformer(ResultTransformer transformer);
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/QueryException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-//$Id: QueryException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate;
-
-/**
- * A problem occurred translating a Hibernate query to SQL
- * due to invalid query syntax, etc.
- */
-public class QueryException extends HibernateException {
-
-	private String queryString;
-
-	public QueryException(String message) {
-		super(message);
-	}
-	public QueryException(String message, Throwable e) {
-		super(message, e);
-	}
-
-	public QueryException(String message, String queryString) {
-		super(message);
-		this.queryString = queryString;
-	}
-
-	public QueryException(Exception e) {
-		super(e);
-	}
-	public String getQueryString() {
-		return queryString;
-	}
-
-	public void setQueryString(String queryString) {
-		this.queryString = queryString;
-	}
-
-	public String getMessage() {
-		String msg = super.getMessage();
-		if ( queryString!=null ) msg += " [" + queryString + ']';
-		return msg;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/QueryException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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;
+
+/**
+ * A problem occurred translating a Hibernate query to SQL
+ * due to invalid query syntax, etc.
+ */
+public class QueryException extends HibernateException {
+
+	private String queryString;
+
+	public QueryException(String message) {
+		super(message);
+	}
+	public QueryException(String message, Throwable e) {
+		super(message, e);
+	}
+
+	public QueryException(String message, String queryString) {
+		super(message);
+		this.queryString = queryString;
+	}
+
+	public QueryException(Exception e) {
+		super(e);
+	}
+	public String getQueryString() {
+		return queryString;
+	}
+
+	public void setQueryString(String queryString) {
+		this.queryString = queryString;
+	}
+
+	public String getMessage() {
+		String msg = super.getMessage();
+		if ( queryString!=null ) msg += " [" + queryString + ']';
+		return msg;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/QueryParameterException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: $
-package org.hibernate;
-
-/**
- * Parameter invalid or not found in the query
- * 
- * @author Emmanuel Bernard
- */
-public class QueryParameterException extends QueryException {
-
-	public QueryParameterException(Exception e) {
-		super( e );
-	}
-
-	public QueryParameterException(String message) {
-		super( message );
-	}
-
-	public QueryParameterException(String message, Throwable e) {
-		super( message, e );
-	}
-
-	public QueryParameterException(String message, String queryString) {
-		super( message, queryString );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/QueryParameterException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/QueryParameterException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+/**
+ * Parameter invalid or not found in the query
+ * 
+ * @author Emmanuel Bernard
+ */
+public class QueryParameterException extends QueryException {
+
+	public QueryParameterException(Exception e) {
+		super( e );
+	}
+
+	public QueryParameterException(String message) {
+		super( message );
+	}
+
+	public QueryParameterException(String message, Throwable e) {
+		super( message, e );
+	}
+
+	public QueryParameterException(String message, String queryString) {
+		super( message, queryString );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ReplicationMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: ReplicationMode.java 5060 2004-12-24 03:11:05Z oneovthafew $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.type.VersionType;
-
-/**
- * Represents a replication strategy.
- *
- * @see Session#replicate(Object, ReplicationMode)
- * @author Gavin King
- */
-public abstract class ReplicationMode implements Serializable {
-	private final String name;
-	private static final Map INSTANCES = new HashMap();
-
-	public ReplicationMode(String name) {
-		this.name=name;
-	}
-	public String toString() {
-		return name;
-	}
-	public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType);
-	/**
-	 * Throw an exception when a row already exists.
-	 */
-	public static final ReplicationMode EXCEPTION = new ReplicationMode("EXCEPTION") {
-		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
-			throw new AssertionFailure("should not be called");
-		}
-	};
-	/**
-	 * Ignore replicated entities when a row already exists.
-	 */
-	public static final ReplicationMode IGNORE = new ReplicationMode("IGNORE") {
-		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
-			return false;
-		}
-	};
-	/**
-	 * Overwrite existing rows when a row already exists.
-	 */
-	public static final ReplicationMode OVERWRITE = new ReplicationMode("OVERWRITE") {
-		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
-			return true;
-		}
-	};
-	/**
-	 * When a row already exists, choose the latest version.
-	 */
-	public static final ReplicationMode LATEST_VERSION = new ReplicationMode("LATEST_VERSION") {
-		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
-			if (versionType==null) return true; //always overwrite nonversioned data
-			return versionType.getComparator().compare(currentVersion, newVersion) <= 0;
-		}
-	};
-
-	static {
-		INSTANCES.put( LATEST_VERSION.name, LATEST_VERSION );
-		INSTANCES.put( IGNORE.name, IGNORE );
-		INSTANCES.put( OVERWRITE.name, OVERWRITE );
-		INSTANCES.put( EXCEPTION.name, EXCEPTION );
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get(name);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ReplicationMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ReplicationMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.type.VersionType;
+
+/**
+ * Represents a replication strategy.
+ *
+ * @see Session#replicate(Object, ReplicationMode)
+ * @author Gavin King
+ */
+public abstract class ReplicationMode implements Serializable {
+	private final String name;
+	private static final Map INSTANCES = new HashMap();
+
+	public ReplicationMode(String name) {
+		this.name=name;
+	}
+	public String toString() {
+		return name;
+	}
+	public abstract boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType);
+	/**
+	 * Throw an exception when a row already exists.
+	 */
+	public static final ReplicationMode EXCEPTION = new ReplicationMode("EXCEPTION") {
+		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
+			throw new AssertionFailure("should not be called");
+		}
+	};
+	/**
+	 * Ignore replicated entities when a row already exists.
+	 */
+	public static final ReplicationMode IGNORE = new ReplicationMode("IGNORE") {
+		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
+			return false;
+		}
+	};
+	/**
+	 * Overwrite existing rows when a row already exists.
+	 */
+	public static final ReplicationMode OVERWRITE = new ReplicationMode("OVERWRITE") {
+		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
+			return true;
+		}
+	};
+	/**
+	 * When a row already exists, choose the latest version.
+	 */
+	public static final ReplicationMode LATEST_VERSION = new ReplicationMode("LATEST_VERSION") {
+		public boolean shouldOverwriteCurrentVersion(Object entity, Object currentVersion, Object newVersion, VersionType versionType) {
+			if (versionType==null) return true; //always overwrite nonversioned data
+			return versionType.getComparator().compare(currentVersion, newVersion) <= 0;
+		}
+	};
+
+	static {
+		INSTANCES.put( LATEST_VERSION.name, LATEST_VERSION );
+		INSTANCES.put( IGNORE.name, IGNORE );
+		INSTANCES.put( OVERWRITE.name, OVERWRITE );
+		INSTANCES.put( EXCEPTION.name, EXCEPTION );
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get(name);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/SQLQuery.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-//$Id: SQLQuery.java 10845 2006-11-18 04:20:30Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import org.hibernate.type.Type;
-
-/**
- * Allows the user to declare the types and select list injection
- * points of all entities returned by the query. Also allows
- * declaration of the type and column alias of any scalar results
- * of the query.
- * 
- * @author Gavin King
- */
-public interface SQLQuery extends Query {
-	/**
-	 * Declare a "root" entity, without specifying an alias
-	 */
-	public SQLQuery addEntity(String entityName);
-	/**
-	 * Declare a "root" entity
-	 */
-	public SQLQuery addEntity(String alias, String entityName);
-	/**
-	 * Declare a "root" entity, specifying a lock mode
-	 */
-	public SQLQuery addEntity(String alias, String entityName, LockMode lockMode);
-	/**
-	 * Declare a "root" entity, without specifying an alias
-	 */
-	public SQLQuery addEntity(Class entityClass);
-	/**
-	 * Declare a "root" entity
-	 */
-	public SQLQuery addEntity(String alias, Class entityClass);
-	/**
-	 * Declare a "root" entity, specifying a lock mode
-	 */
-	public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode);
-
-	/**
-	 * Declare a "joined" entity
-	 */
-	public SQLQuery addJoin(String alias, String path);
-	/**
-	 * Declare a "joined" entity, specifying a lock mode
-	 */
-	public SQLQuery addJoin(String alias, String path, LockMode lockMode);
-	
-	/**
-	 * Declare a scalar query result
-	 */
-	public SQLQuery addScalar(String columnAlias, Type type);
-
-	/**
-	 * Declare a scalar query. Hibernate will attempt to automatically detect the underlying type.
-	 */
-	public SQLQuery addScalar(String columnAlias);
-
-	/**
-	 * Use a predefined named ResultSetMapping
-	 */
-	public SQLQuery setResultSetMapping(String name);
-
-	/**
-	 * Adds a query space for auto-flush synchronization.
-	 *
-	 * @param querySpace The query space to be auto-flushed for this query.
-	 * @return this, for method chaning
-	 */
-	public SQLQuery addSynchronizedQuerySpace(String querySpace);
-
-	/**
-	 * Adds an entity name or auto-flush synchronization.
-	 *
-	 * @param entityName The name of the entity upon whose defined
-	 * query spaces we should additionally synchronize.
-	 * @return this, for method chaning
-	 * @throws MappingException Indicates the given entity name could not be
-	 * resolved.
-	 */
-	public SQLQuery addSynchronizedEntityName(String entityName) throws MappingException;
-
-	/**
-	 * Adds an entity name or auto-flush synchronization.
-	 *
-	 * @param entityClass The class of the entity upon whose defined
-	 * query spaces we should additionally synchronize.
-	 * @return this, for method chaning
-	 * @throws MappingException Indicates the given entity class could not be
-	 * resolved.
-	 */
-	public SQLQuery addSynchronizedEntityClass(Class entityClass) throws MappingException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/SQLQuery.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SQLQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.type.Type;
+
+/**
+ * Allows the user to declare the types and select list injection
+ * points of all entities returned by the query. Also allows
+ * declaration of the type and column alias of any scalar results
+ * of the query.
+ * 
+ * @author Gavin King
+ */
+public interface SQLQuery extends Query {
+	/**
+	 * Declare a "root" entity, without specifying an alias
+	 */
+	public SQLQuery addEntity(String entityName);
+	/**
+	 * Declare a "root" entity
+	 */
+	public SQLQuery addEntity(String alias, String entityName);
+	/**
+	 * Declare a "root" entity, specifying a lock mode
+	 */
+	public SQLQuery addEntity(String alias, String entityName, LockMode lockMode);
+	/**
+	 * Declare a "root" entity, without specifying an alias
+	 */
+	public SQLQuery addEntity(Class entityClass);
+	/**
+	 * Declare a "root" entity
+	 */
+	public SQLQuery addEntity(String alias, Class entityClass);
+	/**
+	 * Declare a "root" entity, specifying a lock mode
+	 */
+	public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode);
+
+	/**
+	 * Declare a "joined" entity
+	 */
+	public SQLQuery addJoin(String alias, String path);
+	/**
+	 * Declare a "joined" entity, specifying a lock mode
+	 */
+	public SQLQuery addJoin(String alias, String path, LockMode lockMode);
+	
+	/**
+	 * Declare a scalar query result
+	 */
+	public SQLQuery addScalar(String columnAlias, Type type);
+
+	/**
+	 * Declare a scalar query. Hibernate will attempt to automatically detect the underlying type.
+	 */
+	public SQLQuery addScalar(String columnAlias);
+
+	/**
+	 * Use a predefined named ResultSetMapping
+	 */
+	public SQLQuery setResultSetMapping(String name);
+
+	/**
+	 * Adds a query space for auto-flush synchronization.
+	 *
+	 * @param querySpace The query space to be auto-flushed for this query.
+	 * @return this, for method chaning
+	 */
+	public SQLQuery addSynchronizedQuerySpace(String querySpace);
+
+	/**
+	 * Adds an entity name or auto-flush synchronization.
+	 *
+	 * @param entityName The name of the entity upon whose defined
+	 * query spaces we should additionally synchronize.
+	 * @return this, for method chaning
+	 * @throws MappingException Indicates the given entity name could not be
+	 * resolved.
+	 */
+	public SQLQuery addSynchronizedEntityName(String entityName) throws MappingException;
+
+	/**
+	 * Adds an entity name or auto-flush synchronization.
+	 *
+	 * @param entityClass The class of the entity upon whose defined
+	 * query spaces we should additionally synchronize.
+	 * @return this, for method chaning
+	 * @throws MappingException Indicates the given entity class could not be
+	 * resolved.
+	 */
+	public SQLQuery addSynchronizedEntityClass(Class entityClass) throws MappingException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ScrollMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-//$Id: ScrollMode.java 4369 2004-08-18 00:28:43Z oneovthafew $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Specifies the type of JDBC scrollable result set to use
- * underneath a <tt>ScrollableResults</tt>
- *
- * @see Query#scroll(ScrollMode)
- * @see ScrollableResults
- * @author Gavin King
- */
-public final class ScrollMode implements Serializable {
-	private final int resultSetType;
-	private final String name;
-	private static final Map INSTANCES = new HashMap();
-
-	private ScrollMode(int level, String name) {
-		this.resultSetType=level;
-		this.name=name;
-	}
-	
-	public String toString() {
-		return name;
-	}
-	
-	/**
-	 * @return the JDBC result set type code
-	 */
-	public int toResultSetType() {
-		return resultSetType;
-	}
-	
-	/**
-	 * @see java.sql.ResultSet.TYPE_FORWARD_ONLY
-	 */
-	public static final ScrollMode FORWARD_ONLY = new ScrollMode(ResultSet.TYPE_FORWARD_ONLY, "FORWARD_ONLY");
-	/**
-	 * @see java.sql.ResultSet.TYPE_SCROLL_SENSITIVE
-	 */
-	public static final ScrollMode SCROLL_SENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_SENSITIVE, "SCROLL_SENSITIVE");
-	/**
-	 * Note that since the Hibernate session acts as a cache, you
-	 * might need to expicitly evict objects, if you need to see
-	 * changes made by other transactions. 
-	 * @see java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE
-	 */
-	public static final ScrollMode SCROLL_INSENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_INSENSITIVE, "SCROLL_INSENSITIVE");
-	
-	public boolean lessThan(ScrollMode other) {
-		return this.resultSetType<other.resultSetType;
-	}
-
-	static {
-		INSTANCES.put( FORWARD_ONLY.name, FORWARD_ONLY );
-		INSTANCES.put( SCROLL_INSENSITIVE.name, SCROLL_INSENSITIVE );
-		INSTANCES.put( SCROLL_SENSITIVE.name, SCROLL_SENSITIVE );
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get(name);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ScrollMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Specifies the type of JDBC scrollable result set to use
+ * underneath a <tt>ScrollableResults</tt>
+ *
+ * @see Query#scroll(ScrollMode)
+ * @see ScrollableResults
+ * @author Gavin King
+ */
+public final class ScrollMode implements Serializable {
+	private final int resultSetType;
+	private final String name;
+	private static final Map INSTANCES = new HashMap();
+
+	private ScrollMode(int level, String name) {
+		this.resultSetType=level;
+		this.name=name;
+	}
+	
+	public String toString() {
+		return name;
+	}
+	
+	/**
+	 * @return the JDBC result set type code
+	 */
+	public int toResultSetType() {
+		return resultSetType;
+	}
+	
+	/**
+	 * @see java.sql.ResultSet.TYPE_FORWARD_ONLY
+	 */
+	public static final ScrollMode FORWARD_ONLY = new ScrollMode(ResultSet.TYPE_FORWARD_ONLY, "FORWARD_ONLY");
+	/**
+	 * @see java.sql.ResultSet.TYPE_SCROLL_SENSITIVE
+	 */
+	public static final ScrollMode SCROLL_SENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_SENSITIVE, "SCROLL_SENSITIVE");
+	/**
+	 * Note that since the Hibernate session acts as a cache, you
+	 * might need to expicitly evict objects, if you need to see
+	 * changes made by other transactions. 
+	 * @see java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE
+	 */
+	public static final ScrollMode SCROLL_INSENSITIVE = new ScrollMode(ResultSet.TYPE_SCROLL_INSENSITIVE, "SCROLL_INSENSITIVE");
+	
+	public boolean lessThan(ScrollMode other) {
+		return this.resultSetType<other.resultSetType;
+	}
+
+	static {
+		INSTANCES.put( FORWARD_ONLY.name, FORWARD_ONLY );
+		INSTANCES.put( SCROLL_INSENSITIVE.name, SCROLL_INSENSITIVE );
+		INSTANCES.put( SCROLL_SENSITIVE.name, SCROLL_SENSITIVE );
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get(name);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/ScrollableResults.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,204 +0,0 @@
-//$Id: ScrollableResults.java 6411 2005-04-13 07:37:50Z oneovthafew $
-package org.hibernate;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.hibernate.type.Type;
-
-/**
- * A result iterator that allows moving around within the results
- * by arbitrary increments. The <tt>Query</tt> / <tt>ScrollableResults</tt>
- * pattern is very similar to the JDBC <tt>PreparedStatement</tt>/
- * <tt>ResultSet</tt> pattern and the semantics of methods of this interface
- * are similar to the similarly named methods on <tt>ResultSet</tt>.<br>
- * <br>
- * Contrary to JDBC, columns of results are numbered from zero.
- *
- * @see Query#scroll()
- * @author Gavin King
- */
-public interface ScrollableResults {
-	/**
-	 * Advance to the next result
-	 * @return <tt>true</tt> if there is another result
-	 */
-	public boolean next() throws HibernateException;
-	/**
-	 * Retreat to the previous result
-	 * @return <tt>true</tt> if there is a previous result
-	 */
-	public boolean previous() throws HibernateException;
-	/**
-	 * Scroll an arbitrary number of locations
-	 * @param i a positive (forward) or negative (backward) number of rows
-	 * @return <tt>true</tt> if there is a result at the new location
-	 */
-	public boolean scroll(int i) throws HibernateException;
-	/**
-	 * Go to the last result
-	 * @return <tt>true</tt> if there are any results
-	 */
-	public boolean last() throws HibernateException;
-	/**
-	 * Go to the first result
-	 * @return <tt>true</tt> if there are any results
-	 */
-	public boolean first() throws HibernateException;
-	/**
-	 * Go to a location just before first result (this is the initial location)
-	 */
-	public void beforeFirst() throws HibernateException;
-	/**
-	 * Go to a location just after the last result
-	 */
-	public void afterLast() throws HibernateException;
-	/**
-	 * Is this the first result?
-	 *
-	 * @return <tt>true</tt> if this is the first row of results
-	 * @throws HibernateException
-	 */
-	public boolean isFirst() throws HibernateException;
-	/**
-	 * Is this the last result?
-	 *
-	 * @return <tt>true</tt> if this is the last row of results
-	 * @throws HibernateException
-	 */
-	public boolean isLast() throws HibernateException;
-	/**
-	 * Release resources immediately.
-	 */
-	public void close() throws HibernateException;
-	/**
-	 * Get the current row of results
-	 * @return an object or array
-	 */
-	public Object[] get() throws HibernateException;
-	/**
-	 * Get the <tt>i</tt>th object in the current row of results, without
-	 * initializing any other results in the row. This method may be used
-	 * safely, regardless of the type of the column (ie. even for scalar
-	 * results).
-	 * @param i the column, numbered from zero
-	 * @return an object of any Hibernate type or <tt>null</tt>
-	 */
-	public Object get(int i) throws HibernateException;
-
-	/**
-	 * Get the type of the <tt>i</tt>th column of results
-	 * @param i the column, numbered from zero
-	 * @return the Hibernate type
-	 */
-	public Type getType(int i);
-
-	/**
-	 * Convenience method to read an <tt>integer</tt>
-	 */
-	public Integer getInteger(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>long</tt>
-	 */
-	public Long getLong(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>float</tt>
-	 */
-	public Float getFloat(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>boolean</tt>
-	 */
-	public Boolean getBoolean(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>double</tt>
-	 */
-	public Double getDouble(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>short</tt>
-	 */
-	public Short getShort(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>byte</tt>
-	 */
-	public Byte getByte(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>character</tt>
-	 */
-	public Character getCharacter(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>binary</tt>
-	 */
-	public byte[] getBinary(int col) throws HibernateException;
-	/**
-	 * Convenience method to read <tt>text</tt>
-	 */
-	public String getText(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>blob</tt>
-	 */
-	public Blob getBlob(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>clob</tt>
-	 */
-	public Clob getClob(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>string</tt>
-	 */
-	public String getString(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>big_decimal</tt>
-	 */
-	public BigDecimal getBigDecimal(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>big_integer</tt>
-	 */
-	public BigInteger getBigInteger(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>date</tt>, <tt>time</tt> or <tt>timestamp</tt>
-	 */
-	public Date getDate(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>locale</tt>
-	 */
-	public Locale getLocale(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>calendar</tt> or <tt>calendar_date</tt>
-	 */
-	public Calendar getCalendar(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>currency</tt>
-	 */
-	//public Currency getCurrency(int col) throws HibernateException;
-	/**
-	 * Convenience method to read a <tt>timezone</tt>
-	 */
-	public TimeZone getTimeZone(int col) throws HibernateException;
-	/**
-	 * Get the current location in the result set. The first
-	 * row is number <tt>0</tt>, contrary to JDBC.
-	 * @return the row number, numbered from <tt>0</tt>, or <tt>-1</tt> if
-	 * there is no current row
-	 */
-	public int getRowNumber() throws HibernateException;
-	/**
-	 * Set the current location in the result set, numbered from either the
-	 * first row (row number <tt>0</tt>), or the last row (row
-	 * number <tt>-1</tt>).
-	 * @param rowNumber the row number, numbered from the last row, in the
-	 * case of a negative row number
-	 * @return true if there is a row at that row number
-	 */
-	public boolean setRowNumber(int rowNumber) throws HibernateException;
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/ScrollableResults.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/ScrollableResults.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,227 @@
+/*
+ * 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;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.hibernate.type.Type;
+
+/**
+ * A result iterator that allows moving around within the results
+ * by arbitrary increments. The <tt>Query</tt> / <tt>ScrollableResults</tt>
+ * pattern is very similar to the JDBC <tt>PreparedStatement</tt>/
+ * <tt>ResultSet</tt> pattern and the semantics of methods of this interface
+ * are similar to the similarly named methods on <tt>ResultSet</tt>.<br>
+ * <br>
+ * Contrary to JDBC, columns of results are numbered from zero.
+ *
+ * @see Query#scroll()
+ * @author Gavin King
+ */
+public interface ScrollableResults {
+	/**
+	 * Advance to the next result
+	 * @return <tt>true</tt> if there is another result
+	 */
+	public boolean next() throws HibernateException;
+	/**
+	 * Retreat to the previous result
+	 * @return <tt>true</tt> if there is a previous result
+	 */
+	public boolean previous() throws HibernateException;
+	/**
+	 * Scroll an arbitrary number of locations
+	 * @param i a positive (forward) or negative (backward) number of rows
+	 * @return <tt>true</tt> if there is a result at the new location
+	 */
+	public boolean scroll(int i) throws HibernateException;
+	/**
+	 * Go to the last result
+	 * @return <tt>true</tt> if there are any results
+	 */
+	public boolean last() throws HibernateException;
+	/**
+	 * Go to the first result
+	 * @return <tt>true</tt> if there are any results
+	 */
+	public boolean first() throws HibernateException;
+	/**
+	 * Go to a location just before first result (this is the initial location)
+	 */
+	public void beforeFirst() throws HibernateException;
+	/**
+	 * Go to a location just after the last result
+	 */
+	public void afterLast() throws HibernateException;
+	/**
+	 * Is this the first result?
+	 *
+	 * @return <tt>true</tt> if this is the first row of results
+	 * @throws HibernateException
+	 */
+	public boolean isFirst() throws HibernateException;
+	/**
+	 * Is this the last result?
+	 *
+	 * @return <tt>true</tt> if this is the last row of results
+	 * @throws HibernateException
+	 */
+	public boolean isLast() throws HibernateException;
+	/**
+	 * Release resources immediately.
+	 */
+	public void close() throws HibernateException;
+	/**
+	 * Get the current row of results
+	 * @return an object or array
+	 */
+	public Object[] get() throws HibernateException;
+	/**
+	 * Get the <tt>i</tt>th object in the current row of results, without
+	 * initializing any other results in the row. This method may be used
+	 * safely, regardless of the type of the column (ie. even for scalar
+	 * results).
+	 * @param i the column, numbered from zero
+	 * @return an object of any Hibernate type or <tt>null</tt>
+	 */
+	public Object get(int i) throws HibernateException;
+
+	/**
+	 * Get the type of the <tt>i</tt>th column of results
+	 * @param i the column, numbered from zero
+	 * @return the Hibernate type
+	 */
+	public Type getType(int i);
+
+	/**
+	 * Convenience method to read an <tt>integer</tt>
+	 */
+	public Integer getInteger(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>long</tt>
+	 */
+	public Long getLong(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>float</tt>
+	 */
+	public Float getFloat(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>boolean</tt>
+	 */
+	public Boolean getBoolean(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>double</tt>
+	 */
+	public Double getDouble(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>short</tt>
+	 */
+	public Short getShort(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>byte</tt>
+	 */
+	public Byte getByte(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>character</tt>
+	 */
+	public Character getCharacter(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>binary</tt>
+	 */
+	public byte[] getBinary(int col) throws HibernateException;
+	/**
+	 * Convenience method to read <tt>text</tt>
+	 */
+	public String getText(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>blob</tt>
+	 */
+	public Blob getBlob(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>clob</tt>
+	 */
+	public Clob getClob(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>string</tt>
+	 */
+	public String getString(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>big_decimal</tt>
+	 */
+	public BigDecimal getBigDecimal(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>big_integer</tt>
+	 */
+	public BigInteger getBigInteger(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>date</tt>, <tt>time</tt> or <tt>timestamp</tt>
+	 */
+	public Date getDate(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>locale</tt>
+	 */
+	public Locale getLocale(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>calendar</tt> or <tt>calendar_date</tt>
+	 */
+	public Calendar getCalendar(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>currency</tt>
+	 */
+	//public Currency getCurrency(int col) throws HibernateException;
+	/**
+	 * Convenience method to read a <tt>timezone</tt>
+	 */
+	public TimeZone getTimeZone(int col) throws HibernateException;
+	/**
+	 * Get the current location in the result set. The first
+	 * row is number <tt>0</tt>, contrary to JDBC.
+	 * @return the row number, numbered from <tt>0</tt>, or <tt>-1</tt> if
+	 * there is no current row
+	 */
+	public int getRowNumber() throws HibernateException;
+	/**
+	 * Set the current location in the result set, numbered from either the
+	 * first row (row number <tt>0</tt>), or the last row (row
+	 * number <tt>-1</tt>).
+	 * @param rowNumber the row number, numbered from the last row, in the
+	 * case of a negative row number
+	 * @return true if there is a row at that row number
+	 */
+	public boolean setRowNumber(int rowNumber) throws HibernateException;
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Session.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,793 +0,0 @@
-//$Id: Session.java 11494 2007-05-09 02:00:16Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.sql.Connection;
-
-import org.hibernate.jdbc.Work;
-import org.hibernate.stat.SessionStatistics;
-
-/**
- * The main runtime interface between a Java application and Hibernate. This is the
- * central API class abstracting the notion of a persistence service.<br>
- * <br>
- * The lifecycle of a <tt>Session</tt> is bounded by the beginning and end of a logical
- * transaction. (Long transactions might span several database transactions.)<br>
- * <br>
- * The main function of the <tt>Session</tt> is to offer create, read and delete operations
- * for instances of mapped entity classes. Instances may exist in one of three states:<br>
- * <br>
- * <i>transient:</i> never persistent, not associated with any <tt>Session</tt><br>
- * <i>persistent:</i> associated with a unique <tt>Session</tt><br>
- * <i>detached:</i> previously persistent, not associated with any <tt>Session</tt><br>
- * <br>
- * Transient instances may be made persistent by calling <tt>save()</tt>,
- * <tt>persist()</tt> or <tt>saveOrUpdate()</tt>. Persistent instances may be made transient
- * by calling<tt> delete()</tt>. Any instance returned by a <tt>get()</tt> or
- * <tt>load()</tt> method is persistent. Detached instances may be made persistent
- * by calling <tt>update()</tt>, <tt>saveOrUpdate()</tt>, <tt>lock()</tt> or <tt>replicate()</tt>. 
- * The state of a transient or detached instance may also be made persistent as a new
- * persistent instance by calling <tt>merge()</tt>.<br>
- * <br>
- * <tt>save()</tt> and <tt>persist()</tt> result in an SQL <tt>INSERT</tt>, <tt>delete()</tt>
- * in an SQL <tt>DELETE</tt> and <tt>update()</tt> or <tt>merge()</tt> in an SQL <tt>UPDATE</tt>. 
- * Changes to <i>persistent</i> instances are detected at flush time and also result in an SQL
- * <tt>UPDATE</tt>. <tt>saveOrUpdate()</tt> and <tt>replicate()</tt> result in either an
- * <tt>INSERT</tt> or an <tt>UPDATE</tt>.<br>
- * <br>
- * It is not intended that implementors be threadsafe. Instead each thread/transaction
- * should obtain its own instance from a <tt>SessionFactory</tt>.<br>
- * <br>
- * A <tt>Session</tt> instance is serializable if its persistent classes are serializable.<br>
- * <br>
- * A typical transaction should use the following idiom:
- * <pre>
- * Session sess = factory.openSession();
- * Transaction tx;
- * try {
- *     tx = sess.beginTransaction();
- *     //do some work
- *     ...
- *     tx.commit();
- * }
- * catch (Exception e) {
- *     if (tx!=null) tx.rollback();
- *     throw e;
- * }
- * finally {
- *     sess.close();
- * }
- * </pre>
- * <br>
- * If the <tt>Session</tt> throws an exception, the transaction must be rolled back
- * and the session discarded. The internal state of the <tt>Session</tt> might not
- * be consistent with the database after the exception occurs.
- *
- * @see SessionFactory
- * @author Gavin King
- */
-public interface Session extends Serializable {
-
-	/**
-	 * Retrieve the entity mode in effect for this session.
-	 *
-	 * @return The entity mode for this session.
-	 */
-	public EntityMode getEntityMode();
-
-	/**
-	 * Starts a new Session with the given entity mode in effect. This secondary
-	 * Session inherits the connection, transaction, and other context
-	 * information from the primary Session. It doesn't need to be flushed
-	 * or closed by the developer.
-	 * 
-	 * @param entityMode The entity mode to use for the new session.
-	 * @return The new session
-	 */
-	public Session getSession(EntityMode entityMode);
-
-	/**
-	 * Force this session to flush. Must be called at the end of a
-	 * unit of work, before commiting the transaction and closing the
-	 * session (depending on {@link #setFlushMode flush-mode},
-	 * {@link Transaction#commit()} calls this method).
-	 * <p/>
-	 * <i>Flushing</i> is the process of synchronizing the underlying persistent
-	 * store with persistable state held in memory.
-	 *
-	 * @throws HibernateException Indicates problems flushing the session or
-	 * talking to the database.
-	 */
-	public void flush() throws HibernateException;
-
-	/**
-	 * Set the flush mode for this session.
-	 * <p/>
-	 * The flush mode determines the points at which the session is flushed.
-	 * <i>Flushing</i> is the process of synchronizing the underlying persistent
-	 * store with persistable state held in memory.
-	 * <p/>
-	 * For a logically "read only" session, it is reasonable to set the session's
-	 * flush mode to {@link FlushMode#MANUAL} at the start of the session (in
-	 * order to achieve some extra performance).
-	 *
-	 * @param flushMode the new flush mode
-	 * @see FlushMode
-	 */
-	public void setFlushMode(FlushMode flushMode);
-
-	/**
-	 * Get the current flush mode for this session.
-	 *
-	 * @return The flush mode
-	 */
-	public FlushMode getFlushMode();
-
-	/**
-	 * Set the cache mode.
-	 * <p/>
-	 * Cache mode determines the manner in which this session can interact with
-	 * the second level cache.
-	 *
-	 * @param cacheMode The new cache mode.
-	 */
-	public void setCacheMode(CacheMode cacheMode);
-
-	/**
-	 * Get the current cache mode.
-	 *
-	 * @return The current cache mode.
-	 */
-	public CacheMode getCacheMode();
-
-	/**
-	 * Get the session factory which created this session.
-	 *
-	 * @return The session factory.
-	 * @see SessionFactory
-
-	 */
-	public SessionFactory getSessionFactory();
-
-	/**
-	 * Get the JDBC connection of this Session.<br>
-	 * <br>
-	 * If the session is using aggressive collection release (as in a
-	 * CMT environment), it is the application's responsibility to
-	 * close the connection returned by this call. Otherwise, the
-	 * application should not close the connection.
-	 *
-	 * @return the JDBC connection in use by the <tt>Session</tt>
-	 * @throws HibernateException if the <tt>Session</tt> is disconnected
-	 * @deprecated (scheduled for removal in 4.x).  Replacement depends on need; for doing direct JDBC stuff use
-	 * {@link #doWork}; for opening a 'temporary Session' use (TBD).
-	 */
-	public Connection connection() throws HibernateException;
-
-	/**
-	 * End the session by releasing the JDBC connection and cleaning up.  It is
-	 * not strictly necessary to close the session but you must at least
-	 * {@link #disconnect()} it.
-	 *
-	 * @return the connection provided by the application or null.
-	 * @throws HibernateException Indicates problems cleaning up.
-	 */
-	public Connection close() throws HibernateException;
-
-	/**
-	 * Cancel the execution of the current query.
-	 * <p/>
-	 * This is the sole method on session which may be safely called from
-	 * another thread.
-	 *
-	 * @throws HibernateException There was a problem canceling the query
-	 */
-	public void cancelQuery() throws HibernateException;
-
-	/**
-	 * Check if the session is still open.
-	 *
-	 * @return boolean
-	 */
-	public boolean isOpen();
-
-	/**
-	 * Check if the session is currently connected.
-	 *
-	 * @return boolean
-	 */
-	public boolean isConnected();
-
-	/**
-	 * Does this session contain any changes which must be synchronized with
-	 * the database?  In other words, would any DML operations be executed if
-	 * we flushed this session?
-	 *
-	 * @return True if the session contains pending changes; false otherwise.
-	 * @throws HibernateException could not perform dirtying checking
-	 */
-	public boolean isDirty() throws HibernateException;
-
-	/**
-	 * Return the identifier value of the given entity as associated with this
-	 * session.  An exception is thrown if the given entity instance is transient
-	 * or detached in relation to this session.
-	 *
-	 * @param object a persistent instance
-	 * @return the identifier
-	 * @throws TransientObjectException if the instance is transient or associated with
-	 * a different session
-	 */
-	public Serializable getIdentifier(Object object) throws HibernateException;
-
-	/**
-	 * Check if this instance is associated with this <tt>Session</tt>.
-	 *
-	 * @param object an instance of a persistent class
-	 * @return true if the given instance is associated with this <tt>Session</tt>
-	 */
-	public boolean contains(Object object);
-
-	/**
-	 * Remove this instance from the session cache. Changes to the instance will
-	 * not be synchronized with the database. This operation cascades to associated
-	 * instances if the association is mapped with <tt>cascade="evict"</tt>.
-	 *
-	 * @param object a persistent instance
-	 * @throws HibernateException
-	 */
-	public void evict(Object object) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * obtaining the specified lock mode, assuming the instance exists.
-	 *
-	 * @param theClass a persistent class
-	 * @param id a valid identifier of an existing persistent instance of the class
-	 * @param lockMode the lock level
-	 * @return the persistent instance or proxy
-	 * @throws HibernateException
-	 */
-	public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * obtaining the specified lock mode, assuming the instance exists.
-	 *
-	 * @param entityName a persistent class
-	 * @param id a valid identifier of an existing persistent instance of the class
-	 * @param lockMode the lock level
-	 * @return the persistent instance or proxy
-	 * @throws HibernateException
-	 */
-	public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * assuming that the instance exists. This method might return a proxied instance that
-	 * is initialized on-demand, when a non-identifier method is accessed.
-	 * <br><br>
-	 * You should not use this method to determine if an instance exists (use <tt>get()</tt>
-	 * instead). Use this only to retrieve an instance that you assume exists, where non-existence
-	 * would be an actual error.
-	 *
-	 * @param theClass a persistent class
-	 * @param id a valid identifier of an existing persistent instance of the class
-	 * @return the persistent instance or proxy
-	 * @throws HibernateException
-	 */
-	public Object load(Class theClass, Serializable id) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * assuming that the instance exists. This method might return a proxied instance that
-	 * is initialized on-demand, when a non-identifier method is accessed.
-	 * <br><br>
-	 * You should not use this method to determine if an instance exists (use <tt>get()</tt>
-	 * instead). Use this only to retrieve an instance that you assume exists, where non-existence
-	 * would be an actual error.
-	 *
-	 * @param entityName a persistent class
-	 * @param id a valid identifier of an existing persistent instance of the class
-	 * @return the persistent instance or proxy
-	 * @throws HibernateException
-	 */
-	public Object load(String entityName, Serializable id) throws HibernateException;
-
-	/**
-	 * Read the persistent state associated with the given identifier into the given transient
-	 * instance.
-	 *
-	 * @param object an "empty" instance of the persistent class
-	 * @param id a valid identifier of an existing persistent instance of the class
-	 * @throws HibernateException
-	 */
-	public void load(Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Persist the state of the given detached instance, reusing the current
-	 * identifier value.  This operation cascades to associated instances if
-	 * the association is mapped with <tt>cascade="replicate"</tt>.
-	 *
-	 * @param object a detached instance of a persistent class
-	 */
-	public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException;
-
-	/**
-	 * Persist the state of the given detached instance, reusing the current
-	 * identifier value.  This operation cascades to associated instances if
-	 * the association is mapped with <tt>cascade="replicate"</tt>.
-	 *
-	 * @param object a detached instance of a persistent class
-	 */
-	public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException;
-
-	/**
-	 * Persist the given transient instance, first assigning a generated identifier. (Or
-	 * using the current value of the identifier property if the <tt>assigned</tt>
-	 * generator is used.) This operation cascades to associated instances if the
-	 * association is mapped with <tt>cascade="save-update"</tt>.
-	 *
-	 * @param object a transient instance of a persistent class
-	 * @return the generated identifier
-	 * @throws HibernateException
-	 */
-	public Serializable save(Object object) throws HibernateException;
-
-	/**
-	 * Persist the given transient instance, first assigning a generated identifier. (Or
-	 * using the current value of the identifier property if the <tt>assigned</tt>
-	 * generator is used.)  This operation cascades to associated instances if the
-	 * association is mapped with <tt>cascade="save-update"</tt>.
-	 *
-	 * @param object a transient instance of a persistent class
-	 * @return the generated identifier
-	 * @throws HibernateException
-	 */
-	public Serializable save(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Either {@link #save(Object)} or {@link #update(Object)} the given
-	 * instance, depending upon resolution of the unsaved-value checks (see the
-	 * manual for discussion of unsaved-value checking).
-	 * <p/>
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="save-update"</tt>.
-	 *
-	 * @see Session#save(java.lang.Object)
-	 * @see Session#update(Object object)
-	 * @param object a transient or detached instance containing new or updated state
-	 * @throws HibernateException
-	 */
-	public void saveOrUpdate(Object object) throws HibernateException;
-
-	/**
-	 * Either {@link #save(String, Object)} or {@link #update(String, Object)}
-	 * the given instance, depending upon resolution of the unsaved-value checks
-	 * (see the manual for discussion of unsaved-value checking).
-	 * <p/>
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="save-update"</tt>.
-	 *
-	 * @see Session#save(String,Object)
-	 * @see Session#update(String,Object)
-	 * @param object a transient or detached instance containing new or updated state
-	 * @throws HibernateException
-	 */
-	public void saveOrUpdate(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Update the persistent instance with the identifier of the given detached
-	 * instance. If there is a persistent instance with the same identifier,
-	 * an exception is thrown. This operation cascades to associated instances
-	 * if the association is mapped with <tt>cascade="save-update"</tt>.
-	 *
-	 * @param object a detached instance containing updated state
-	 * @throws HibernateException
-	 */
-	public void update(Object object) throws HibernateException;
-
-	/**
-	 * Update the persistent instance with the identifier of the given detached
-	 * instance. If there is a persistent instance with the same identifier,
-	 * an exception is thrown. This operation cascades to associated instances
-	 * if the association is mapped with <tt>cascade="save-update"</tt>.
-	 *
-	 * @param object a detached instance containing updated state
-	 * @throws HibernateException
-	 */
-	public void update(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the same
-	 * identifier. If there is no persistent instance currently associated with
-	 * the session, it will be loaded. Return the persistent instance. If the
-	 * given instance is unsaved, save a copy of and return it as a newly persistent
-	 * instance. The given instance does not become associated with the session.
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="merge"</tt>.<br>
-	 * <br>
-	 * The semantics of this method are defined by JSR-220.
-	 *
-	 * @param object a detached instance with state to be copied
-	 * @return an updated persistent instance
-	 */
-	public Object merge(Object object) throws HibernateException;
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the same
-	 * identifier. If there is no persistent instance currently associated with
-	 * the session, it will be loaded. Return the persistent instance. If the
-	 * given instance is unsaved, save a copy of and return it as a newly persistent
-	 * instance. The given instance does not become associated with the session.
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="merge"</tt>.<br>
-	 * <br>
-	 * The semantics of this method are defined by JSR-220.
-	 *
-	 * @param object a detached instance with state to be copied
-	 * @return an updated persistent instance
-	 */
-	public Object merge(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Make a transient instance persistent. This operation cascades to associated
-	 * instances if the association is mapped with <tt>cascade="persist"</tt>.<br>
-	 * <br>
-	 * The semantics of this method are defined by JSR-220.
-	 *
-	 * @param object a transient instance to be made persistent
-	 */
-	public void persist(Object object) throws HibernateException;
-	/**
-	 * Make a transient instance persistent. This operation cascades to associated
-	 * instances if the association is mapped with <tt>cascade="persist"</tt>.<br>
-	 * <br>
-	 * The semantics of this method are defined by JSR-220.
-	 *
-	 * @param object a transient instance to be made persistent
-	 */
-	public void persist(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Remove a persistent instance from the datastore. The argument may be
-	 * an instance associated with the receiving <tt>Session</tt> or a transient
-	 * instance with an identifier associated with existing persistent state.
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="delete"</tt>.
-	 *
-	 * @param object the instance to be removed
-	 * @throws HibernateException
-	 */
-	public void delete(Object object) throws HibernateException;
-
-	/**
-	 * Remove a persistent instance from the datastore. The <b>object</b> argument may be
-	 * an instance associated with the receiving <tt>Session</tt> or a transient
-	 * instance with an identifier associated with existing persistent state.
-	 * This operation cascades to associated instances if the association is mapped
-	 * with <tt>cascade="delete"</tt>.
-	 *
-	 * @param entityName The entity name for the instance to be removed.
-	 * @param object the instance to be removed
-	 * @throws HibernateException
-	 */
-	public void delete(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Obtain the specified lock level upon the given object. This may be used to
-	 * perform a version check (<tt>LockMode.READ</tt>), to upgrade to a pessimistic
-	 * lock (<tt>LockMode.UPGRADE</tt>), or to simply reassociate a transient instance
-	 * with a session (<tt>LockMode.NONE</tt>). This operation cascades to associated
-	 * instances if the association is mapped with <tt>cascade="lock"</tt>.
-	 *
-	 * @param object a persistent or transient instance
-	 * @param lockMode the lock level
-	 * @throws HibernateException
-	 */
-	public void lock(Object object, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Obtain the specified lock level upon the given object. This may be used to
-	 * perform a version check (<tt>LockMode.READ</tt>), to upgrade to a pessimistic
-	 * lock (<tt>LockMode.UPGRADE</tt>), or to simply reassociate a transient instance
-	 * with a session (<tt>LockMode.NONE</tt>). This operation cascades to associated
-	 * instances if the association is mapped with <tt>cascade="lock"</tt>.
-	 *
-	 * @param object a persistent or transient instance
-	 * @param lockMode the lock level
-	 * @throws HibernateException
-	 */
-	public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Re-read the state of the given instance from the underlying database. It is
-	 * inadvisable to use this to implement long-running sessions that span many
-	 * business tasks. This method is, however, useful in certain special circumstances.
-	 * For example
-	 * <ul>
-	 * <li>where a database trigger alters the object state upon insert or update
-	 * <li>after executing direct SQL (eg. a mass update) in the same session
-	 * <li>after inserting a <tt>Blob</tt> or <tt>Clob</tt>
-	 * </ul>
-	 *
-	 * @param object a persistent or detached instance
-	 * @throws HibernateException
-	 */
-	public void refresh(Object object) throws HibernateException;
-
-	/**
-	 * Re-read the state of the given instance from the underlying database, with
-	 * the given <tt>LockMode</tt>. It is inadvisable to use this to implement
-	 * long-running sessions that span many business tasks. This method is, however,
-	 * useful in certain special circumstances.
-	 *
-	 * @param object a persistent or detached instance
-	 * @param lockMode the lock mode to use
-	 * @throws HibernateException
-	 */
-	public void refresh(Object object, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Determine the current lock mode of the given object.
-	 *
-	 * @param object a persistent instance
-	 * @return the current lock mode
-	 * @throws HibernateException
-	 */
-	public LockMode getCurrentLockMode(Object object) throws HibernateException;
-
-	/**
-	 * Begin a unit of work and return the associated <tt>Transaction</tt> object.
-	 * If a new underlying transaction is required, begin the transaction. Otherwise
-	 * continue the new work in the context of the existing underlying transaction.
-	 * The class of the returned <tt>Transaction</tt> object is determined by the
-	 * property <tt>hibernate.transaction_factory</tt>.
-	 *
-	 * @return a Transaction instance
-	 * @throws HibernateException
-	 * @see Transaction
-	 */
-	public Transaction beginTransaction() throws HibernateException;
-
-	/**
-	 * Get the <tt>Transaction</tt> instance associated with this session.
-	 * The class of the returned <tt>Transaction</tt> object is determined by the
-	 * property <tt>hibernate.transaction_factory</tt>.
-	 *
-	 * @return a Transaction instance
-	 * @throws HibernateException
-	 * @see Transaction
-	 */
-	public Transaction getTransaction();
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
-	 * or a superclass of an entity class.
-	 *
-	 * @param persistentClass a class, which is persistent, or has persistent subclasses
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(Class persistentClass);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
-	 * or a superclass of an entity class, with the given alias.
-	 *
-	 * @param persistentClass a class, which is persistent, or has persistent subclasses
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(Class persistentClass, String alias);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity name.
-	 *
-	 * @param entityName
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(String entityName);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity name,
-	 * with the given alias.
-	 *
-	 * @param entityName
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(String entityName, String alias);
-
-	/**
-	 * Create a new instance of <tt>Query</tt> for the given HQL query string.
-	 *
-	 * @param queryString a HQL query
-	 * @return Query
-	 * @throws HibernateException
-	 */
-	public Query createQuery(String queryString) throws HibernateException;
-
-	/**
-	 * Create a new instance of <tt>SQLQuery</tt> for the given SQL query string.
-	 *
-	 * @param queryString a SQL query
-	 * @return SQLQuery
-	 * @throws HibernateException
-	 */
-	public SQLQuery createSQLQuery(String queryString) throws HibernateException;
-
-	/**
-	 * Create a new instance of <tt>Query</tt> for the given collection and filter string.
-	 *
-	 * @param collection a persistent collection
-	 * @param queryString a Hibernate query
-	 * @return Query
-	 * @throws HibernateException
-	 */
-	public Query createFilter(Object collection, String queryString) throws HibernateException;
-
-	/**
-	 * Obtain an instance of <tt>Query</tt> for a named query string defined in the
-	 * mapping file.
-	 *
-	 * @param queryName the name of a query defined externally
-	 * @return Query
-	 * @throws HibernateException
-	 */
-	public Query getNamedQuery(String queryName) throws HibernateException;
-
-	/**
-	 * Completely clear the session. Evict all loaded instances and cancel all pending
-	 * saves, updates and deletions. Do not close open iterators or instances of
-	 * <tt>ScrollableResults</tt>.
-	 */
-	public void clear();
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * or null if there is no such persistent instance. (If the instance is already associated
-	 * with the session, return that instance. This method never returns an uninitialized instance.)
-	 * Obtain the specified lock mode if the instance exists.
-	 *
-	 * @param clazz a persistent class
-	 * @param id an identifier
-	 * @return a persistent instance or null
-	 * @throws HibernateException
-	 */
-	public Object get(Class clazz, Serializable id) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * or null if there is no such persistent instance. (If the instance is already associated
-	 * with the session, return that instance. This method never returns an uninitialized instance.)
-	 * Obtain the specified lock mode if the instance exists.
-	 *
-	 * @param clazz a persistent class
-	 * @param id an identifier
-	 * @param lockMode the lock mode
-	 * @return a persistent instance or null
-	 * @throws HibernateException
-	 */
-	public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given named entity with the given identifier,
-	 * or null if there is no such persistent instance. (If the instance is already associated
-	 * with the session, return that instance. This method never returns an uninitialized instance.)
-	 *
-	 * @param entityName the entity name
-	 * @param id an identifier
-	 * @return a persistent instance or null
-	 * @throws HibernateException
-	 */
-	public Object get(String entityName, Serializable id) throws HibernateException;
-
-	/**
-	 * Return the persistent instance of the given entity class with the given identifier,
-	 * or null if there is no such persistent instance. (If the instance is already associated
-	 * with the session, return that instance. This method never returns an uninitialized instance.)
-	 * Obtain the specified lock mode if the instance exists.
-	 *
-	 * @param entityName the entity name
-	 * @param id an identifier
-	 * @param lockMode the lock mode
-	 * @return a persistent instance or null
-	 * @throws HibernateException
-	 */
-	public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
-
-	
-	/**
-	 * Return the entity name for a persistent entity
-	 *   
-	 * @param object a persistent entity
-	 * @return the entity name
-	 * @throws HibernateException
-	 */
-	public String getEntityName(Object object) throws HibernateException;
-
-	/**
-	 * Enable the named filter for this current session.
-	 *
-	 * @param filterName The name of the filter to be enabled.
-	 * @return The Filter instance representing the enabled fiter.
-	 */
-	public Filter enableFilter(String filterName);
-
-	/**
-	 * Retrieve a currently enabled filter by name.
-	 *
-	 * @param filterName The name of the filter to be retrieved.
-	 * @return The Filter instance representing the enabled fiter.
-	 */
-	public Filter getEnabledFilter(String filterName);
-
-	/**
-	 * Disable the named filter for the current session.
-	 *
-	 * @param filterName The name of the filter to be disabled.
-	 */
-	public void disableFilter(String filterName);
-	
-	/**
-	 * Get the statistics for this session.
-	 */
-	public SessionStatistics getStatistics();
-	
-	/**
-	 * Set an unmodified persistent object to read only mode, or a read only
-	 * object to modifiable mode. In read only mode, no snapshot is maintained
-	 * and the instance is never dirty checked.
-	 * 
-	 * @see Query#setReadOnly(boolean)
-	 */
-	public void setReadOnly(Object entity, boolean readOnly);
-
-	/**
-	 * Controller for allowing users to perform JDBC related work using the Connection
-	 * managed by this Session.
-	 *
-	 * @param work The work to be performed.
-	 * @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
-	 */
-	public void doWork(Work work) throws HibernateException;
-
-
-	/**
-	 * Disconnect the <tt>Session</tt> from the current JDBC connection. If
-	 * the connection was obtained by Hibernate close it and return it to
-	 * the connection pool; otherwise, return it to the application.
-	 * <p/>
-	 * This is used by applications which supply JDBC connections to Hibernate
-	 * and which require long-sessions (or long-conversations)
-	 * <p/>
-	 * Note that disconnect() called on a session where the connection was
-	 * retrieved by Hibernate through its configured
-	 * {@link org.hibernate.connection.ConnectionProvider} has no effect,
-	 * provided {@link ConnectionReleaseMode#ON_CLOSE} is not in effect.
-	 *
-	 * @return the application-supplied connection or <tt>null</tt>
-	 * @see #reconnect(Connection)
-	 * @see #reconnect()
-	 */
-	Connection disconnect() throws HibernateException;
-
-	/**
-	 * Obtain a new JDBC connection. This is used by applications which
-	 * require long transactions and do not supply connections to the
-	 * session.
-	 *
-	 * @see #disconnect()
-	 * @deprecated Manual reconnection is only needed in the case of
-	 * application-supplied connections, in which case the
-	 * {@link #reconnect(java.sql.Connection)} for should be used.
-	 */
-	void reconnect() throws HibernateException;
-
-	/**
-	 * Reconnect to the given JDBC connection. This is used by applications
-	 * which require long transactions and use application-supplied connections.
-	 *
-	 * @param connection a JDBC connection
-	 * @see #disconnect()
-	 */
-	void reconnect(Connection connection) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Session.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Session.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,816 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.sql.Connection;
+
+import org.hibernate.jdbc.Work;
+import org.hibernate.stat.SessionStatistics;
+
+/**
+ * The main runtime interface between a Java application and Hibernate. This is the
+ * central API class abstracting the notion of a persistence service.<br>
+ * <br>
+ * The lifecycle of a <tt>Session</tt> is bounded by the beginning and end of a logical
+ * transaction. (Long transactions might span several database transactions.)<br>
+ * <br>
+ * The main function of the <tt>Session</tt> is to offer create, read and delete operations
+ * for instances of mapped entity classes. Instances may exist in one of three states:<br>
+ * <br>
+ * <i>transient:</i> never persistent, not associated with any <tt>Session</tt><br>
+ * <i>persistent:</i> associated with a unique <tt>Session</tt><br>
+ * <i>detached:</i> previously persistent, not associated with any <tt>Session</tt><br>
+ * <br>
+ * Transient instances may be made persistent by calling <tt>save()</tt>,
+ * <tt>persist()</tt> or <tt>saveOrUpdate()</tt>. Persistent instances may be made transient
+ * by calling<tt> delete()</tt>. Any instance returned by a <tt>get()</tt> or
+ * <tt>load()</tt> method is persistent. Detached instances may be made persistent
+ * by calling <tt>update()</tt>, <tt>saveOrUpdate()</tt>, <tt>lock()</tt> or <tt>replicate()</tt>. 
+ * The state of a transient or detached instance may also be made persistent as a new
+ * persistent instance by calling <tt>merge()</tt>.<br>
+ * <br>
+ * <tt>save()</tt> and <tt>persist()</tt> result in an SQL <tt>INSERT</tt>, <tt>delete()</tt>
+ * in an SQL <tt>DELETE</tt> and <tt>update()</tt> or <tt>merge()</tt> in an SQL <tt>UPDATE</tt>. 
+ * Changes to <i>persistent</i> instances are detected at flush time and also result in an SQL
+ * <tt>UPDATE</tt>. <tt>saveOrUpdate()</tt> and <tt>replicate()</tt> result in either an
+ * <tt>INSERT</tt> or an <tt>UPDATE</tt>.<br>
+ * <br>
+ * It is not intended that implementors be threadsafe. Instead each thread/transaction
+ * should obtain its own instance from a <tt>SessionFactory</tt>.<br>
+ * <br>
+ * A <tt>Session</tt> instance is serializable if its persistent classes are serializable.<br>
+ * <br>
+ * A typical transaction should use the following idiom:
+ * <pre>
+ * Session sess = factory.openSession();
+ * Transaction tx;
+ * try {
+ *     tx = sess.beginTransaction();
+ *     //do some work
+ *     ...
+ *     tx.commit();
+ * }
+ * catch (Exception e) {
+ *     if (tx!=null) tx.rollback();
+ *     throw e;
+ * }
+ * finally {
+ *     sess.close();
+ * }
+ * </pre>
+ * <br>
+ * If the <tt>Session</tt> throws an exception, the transaction must be rolled back
+ * and the session discarded. The internal state of the <tt>Session</tt> might not
+ * be consistent with the database after the exception occurs.
+ *
+ * @see SessionFactory
+ * @author Gavin King
+ */
+public interface Session extends Serializable {
+
+	/**
+	 * Retrieve the entity mode in effect for this session.
+	 *
+	 * @return The entity mode for this session.
+	 */
+	public EntityMode getEntityMode();
+
+	/**
+	 * Starts a new Session with the given entity mode in effect. This secondary
+	 * Session inherits the connection, transaction, and other context
+	 * information from the primary Session. It doesn't need to be flushed
+	 * or closed by the developer.
+	 * 
+	 * @param entityMode The entity mode to use for the new session.
+	 * @return The new session
+	 */
+	public Session getSession(EntityMode entityMode);
+
+	/**
+	 * Force this session to flush. Must be called at the end of a
+	 * unit of work, before commiting the transaction and closing the
+	 * session (depending on {@link #setFlushMode flush-mode},
+	 * {@link Transaction#commit()} calls this method).
+	 * <p/>
+	 * <i>Flushing</i> is the process of synchronizing the underlying persistent
+	 * store with persistable state held in memory.
+	 *
+	 * @throws HibernateException Indicates problems flushing the session or
+	 * talking to the database.
+	 */
+	public void flush() throws HibernateException;
+
+	/**
+	 * Set the flush mode for this session.
+	 * <p/>
+	 * The flush mode determines the points at which the session is flushed.
+	 * <i>Flushing</i> is the process of synchronizing the underlying persistent
+	 * store with persistable state held in memory.
+	 * <p/>
+	 * For a logically "read only" session, it is reasonable to set the session's
+	 * flush mode to {@link FlushMode#MANUAL} at the start of the session (in
+	 * order to achieve some extra performance).
+	 *
+	 * @param flushMode the new flush mode
+	 * @see FlushMode
+	 */
+	public void setFlushMode(FlushMode flushMode);
+
+	/**
+	 * Get the current flush mode for this session.
+	 *
+	 * @return The flush mode
+	 */
+	public FlushMode getFlushMode();
+
+	/**
+	 * Set the cache mode.
+	 * <p/>
+	 * Cache mode determines the manner in which this session can interact with
+	 * the second level cache.
+	 *
+	 * @param cacheMode The new cache mode.
+	 */
+	public void setCacheMode(CacheMode cacheMode);
+
+	/**
+	 * Get the current cache mode.
+	 *
+	 * @return The current cache mode.
+	 */
+	public CacheMode getCacheMode();
+
+	/**
+	 * Get the session factory which created this session.
+	 *
+	 * @return The session factory.
+	 * @see SessionFactory
+
+	 */
+	public SessionFactory getSessionFactory();
+
+	/**
+	 * Get the JDBC connection of this Session.<br>
+	 * <br>
+	 * If the session is using aggressive collection release (as in a
+	 * CMT environment), it is the application's responsibility to
+	 * close the connection returned by this call. Otherwise, the
+	 * application should not close the connection.
+	 *
+	 * @return the JDBC connection in use by the <tt>Session</tt>
+	 * @throws HibernateException if the <tt>Session</tt> is disconnected
+	 * @deprecated (scheduled for removal in 4.x).  Replacement depends on need; for doing direct JDBC stuff use
+	 * {@link #doWork}; for opening a 'temporary Session' use (TBD).
+	 */
+	public Connection connection() throws HibernateException;
+
+	/**
+	 * End the session by releasing the JDBC connection and cleaning up.  It is
+	 * not strictly necessary to close the session but you must at least
+	 * {@link #disconnect()} it.
+	 *
+	 * @return the connection provided by the application or null.
+	 * @throws HibernateException Indicates problems cleaning up.
+	 */
+	public Connection close() throws HibernateException;
+
+	/**
+	 * Cancel the execution of the current query.
+	 * <p/>
+	 * This is the sole method on session which may be safely called from
+	 * another thread.
+	 *
+	 * @throws HibernateException There was a problem canceling the query
+	 */
+	public void cancelQuery() throws HibernateException;
+
+	/**
+	 * Check if the session is still open.
+	 *
+	 * @return boolean
+	 */
+	public boolean isOpen();
+
+	/**
+	 * Check if the session is currently connected.
+	 *
+	 * @return boolean
+	 */
+	public boolean isConnected();
+
+	/**
+	 * Does this session contain any changes which must be synchronized with
+	 * the database?  In other words, would any DML operations be executed if
+	 * we flushed this session?
+	 *
+	 * @return True if the session contains pending changes; false otherwise.
+	 * @throws HibernateException could not perform dirtying checking
+	 */
+	public boolean isDirty() throws HibernateException;
+
+	/**
+	 * Return the identifier value of the given entity as associated with this
+	 * session.  An exception is thrown if the given entity instance is transient
+	 * or detached in relation to this session.
+	 *
+	 * @param object a persistent instance
+	 * @return the identifier
+	 * @throws TransientObjectException if the instance is transient or associated with
+	 * a different session
+	 */
+	public Serializable getIdentifier(Object object) throws HibernateException;
+
+	/**
+	 * Check if this instance is associated with this <tt>Session</tt>.
+	 *
+	 * @param object an instance of a persistent class
+	 * @return true if the given instance is associated with this <tt>Session</tt>
+	 */
+	public boolean contains(Object object);
+
+	/**
+	 * Remove this instance from the session cache. Changes to the instance will
+	 * not be synchronized with the database. This operation cascades to associated
+	 * instances if the association is mapped with <tt>cascade="evict"</tt>.
+	 *
+	 * @param object a persistent instance
+	 * @throws HibernateException
+	 */
+	public void evict(Object object) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * obtaining the specified lock mode, assuming the instance exists.
+	 *
+	 * @param theClass a persistent class
+	 * @param id a valid identifier of an existing persistent instance of the class
+	 * @param lockMode the lock level
+	 * @return the persistent instance or proxy
+	 * @throws HibernateException
+	 */
+	public Object load(Class theClass, Serializable id, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * obtaining the specified lock mode, assuming the instance exists.
+	 *
+	 * @param entityName a persistent class
+	 * @param id a valid identifier of an existing persistent instance of the class
+	 * @param lockMode the lock level
+	 * @return the persistent instance or proxy
+	 * @throws HibernateException
+	 */
+	public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * assuming that the instance exists. This method might return a proxied instance that
+	 * is initialized on-demand, when a non-identifier method is accessed.
+	 * <br><br>
+	 * You should not use this method to determine if an instance exists (use <tt>get()</tt>
+	 * instead). Use this only to retrieve an instance that you assume exists, where non-existence
+	 * would be an actual error.
+	 *
+	 * @param theClass a persistent class
+	 * @param id a valid identifier of an existing persistent instance of the class
+	 * @return the persistent instance or proxy
+	 * @throws HibernateException
+	 */
+	public Object load(Class theClass, Serializable id) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * assuming that the instance exists. This method might return a proxied instance that
+	 * is initialized on-demand, when a non-identifier method is accessed.
+	 * <br><br>
+	 * You should not use this method to determine if an instance exists (use <tt>get()</tt>
+	 * instead). Use this only to retrieve an instance that you assume exists, where non-existence
+	 * would be an actual error.
+	 *
+	 * @param entityName a persistent class
+	 * @param id a valid identifier of an existing persistent instance of the class
+	 * @return the persistent instance or proxy
+	 * @throws HibernateException
+	 */
+	public Object load(String entityName, Serializable id) throws HibernateException;
+
+	/**
+	 * Read the persistent state associated with the given identifier into the given transient
+	 * instance.
+	 *
+	 * @param object an "empty" instance of the persistent class
+	 * @param id a valid identifier of an existing persistent instance of the class
+	 * @throws HibernateException
+	 */
+	public void load(Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Persist the state of the given detached instance, reusing the current
+	 * identifier value.  This operation cascades to associated instances if
+	 * the association is mapped with <tt>cascade="replicate"</tt>.
+	 *
+	 * @param object a detached instance of a persistent class
+	 */
+	public void replicate(Object object, ReplicationMode replicationMode) throws HibernateException;
+
+	/**
+	 * Persist the state of the given detached instance, reusing the current
+	 * identifier value.  This operation cascades to associated instances if
+	 * the association is mapped with <tt>cascade="replicate"</tt>.
+	 *
+	 * @param object a detached instance of a persistent class
+	 */
+	public void replicate(String entityName, Object object, ReplicationMode replicationMode) throws HibernateException;
+
+	/**
+	 * Persist the given transient instance, first assigning a generated identifier. (Or
+	 * using the current value of the identifier property if the <tt>assigned</tt>
+	 * generator is used.) This operation cascades to associated instances if the
+	 * association is mapped with <tt>cascade="save-update"</tt>.
+	 *
+	 * @param object a transient instance of a persistent class
+	 * @return the generated identifier
+	 * @throws HibernateException
+	 */
+	public Serializable save(Object object) throws HibernateException;
+
+	/**
+	 * Persist the given transient instance, first assigning a generated identifier. (Or
+	 * using the current value of the identifier property if the <tt>assigned</tt>
+	 * generator is used.)  This operation cascades to associated instances if the
+	 * association is mapped with <tt>cascade="save-update"</tt>.
+	 *
+	 * @param object a transient instance of a persistent class
+	 * @return the generated identifier
+	 * @throws HibernateException
+	 */
+	public Serializable save(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Either {@link #save(Object)} or {@link #update(Object)} the given
+	 * instance, depending upon resolution of the unsaved-value checks (see the
+	 * manual for discussion of unsaved-value checking).
+	 * <p/>
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="save-update"</tt>.
+	 *
+	 * @see Session#save(java.lang.Object)
+	 * @see Session#update(Object object)
+	 * @param object a transient or detached instance containing new or updated state
+	 * @throws HibernateException
+	 */
+	public void saveOrUpdate(Object object) throws HibernateException;
+
+	/**
+	 * Either {@link #save(String, Object)} or {@link #update(String, Object)}
+	 * the given instance, depending upon resolution of the unsaved-value checks
+	 * (see the manual for discussion of unsaved-value checking).
+	 * <p/>
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="save-update"</tt>.
+	 *
+	 * @see Session#save(String,Object)
+	 * @see Session#update(String,Object)
+	 * @param object a transient or detached instance containing new or updated state
+	 * @throws HibernateException
+	 */
+	public void saveOrUpdate(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Update the persistent instance with the identifier of the given detached
+	 * instance. If there is a persistent instance with the same identifier,
+	 * an exception is thrown. This operation cascades to associated instances
+	 * if the association is mapped with <tt>cascade="save-update"</tt>.
+	 *
+	 * @param object a detached instance containing updated state
+	 * @throws HibernateException
+	 */
+	public void update(Object object) throws HibernateException;
+
+	/**
+	 * Update the persistent instance with the identifier of the given detached
+	 * instance. If there is a persistent instance with the same identifier,
+	 * an exception is thrown. This operation cascades to associated instances
+	 * if the association is mapped with <tt>cascade="save-update"</tt>.
+	 *
+	 * @param object a detached instance containing updated state
+	 * @throws HibernateException
+	 */
+	public void update(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the same
+	 * identifier. If there is no persistent instance currently associated with
+	 * the session, it will be loaded. Return the persistent instance. If the
+	 * given instance is unsaved, save a copy of and return it as a newly persistent
+	 * instance. The given instance does not become associated with the session.
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="merge"</tt>.<br>
+	 * <br>
+	 * The semantics of this method are defined by JSR-220.
+	 *
+	 * @param object a detached instance with state to be copied
+	 * @return an updated persistent instance
+	 */
+	public Object merge(Object object) throws HibernateException;
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the same
+	 * identifier. If there is no persistent instance currently associated with
+	 * the session, it will be loaded. Return the persistent instance. If the
+	 * given instance is unsaved, save a copy of and return it as a newly persistent
+	 * instance. The given instance does not become associated with the session.
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="merge"</tt>.<br>
+	 * <br>
+	 * The semantics of this method are defined by JSR-220.
+	 *
+	 * @param object a detached instance with state to be copied
+	 * @return an updated persistent instance
+	 */
+	public Object merge(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Make a transient instance persistent. This operation cascades to associated
+	 * instances if the association is mapped with <tt>cascade="persist"</tt>.<br>
+	 * <br>
+	 * The semantics of this method are defined by JSR-220.
+	 *
+	 * @param object a transient instance to be made persistent
+	 */
+	public void persist(Object object) throws HibernateException;
+	/**
+	 * Make a transient instance persistent. This operation cascades to associated
+	 * instances if the association is mapped with <tt>cascade="persist"</tt>.<br>
+	 * <br>
+	 * The semantics of this method are defined by JSR-220.
+	 *
+	 * @param object a transient instance to be made persistent
+	 */
+	public void persist(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Remove a persistent instance from the datastore. The argument may be
+	 * an instance associated with the receiving <tt>Session</tt> or a transient
+	 * instance with an identifier associated with existing persistent state.
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="delete"</tt>.
+	 *
+	 * @param object the instance to be removed
+	 * @throws HibernateException
+	 */
+	public void delete(Object object) throws HibernateException;
+
+	/**
+	 * Remove a persistent instance from the datastore. The <b>object</b> argument may be
+	 * an instance associated with the receiving <tt>Session</tt> or a transient
+	 * instance with an identifier associated with existing persistent state.
+	 * This operation cascades to associated instances if the association is mapped
+	 * with <tt>cascade="delete"</tt>.
+	 *
+	 * @param entityName The entity name for the instance to be removed.
+	 * @param object the instance to be removed
+	 * @throws HibernateException
+	 */
+	public void delete(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Obtain the specified lock level upon the given object. This may be used to
+	 * perform a version check (<tt>LockMode.READ</tt>), to upgrade to a pessimistic
+	 * lock (<tt>LockMode.UPGRADE</tt>), or to simply reassociate a transient instance
+	 * with a session (<tt>LockMode.NONE</tt>). This operation cascades to associated
+	 * instances if the association is mapped with <tt>cascade="lock"</tt>.
+	 *
+	 * @param object a persistent or transient instance
+	 * @param lockMode the lock level
+	 * @throws HibernateException
+	 */
+	public void lock(Object object, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Obtain the specified lock level upon the given object. This may be used to
+	 * perform a version check (<tt>LockMode.READ</tt>), to upgrade to a pessimistic
+	 * lock (<tt>LockMode.UPGRADE</tt>), or to simply reassociate a transient instance
+	 * with a session (<tt>LockMode.NONE</tt>). This operation cascades to associated
+	 * instances if the association is mapped with <tt>cascade="lock"</tt>.
+	 *
+	 * @param object a persistent or transient instance
+	 * @param lockMode the lock level
+	 * @throws HibernateException
+	 */
+	public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Re-read the state of the given instance from the underlying database. It is
+	 * inadvisable to use this to implement long-running sessions that span many
+	 * business tasks. This method is, however, useful in certain special circumstances.
+	 * For example
+	 * <ul>
+	 * <li>where a database trigger alters the object state upon insert or update
+	 * <li>after executing direct SQL (eg. a mass update) in the same session
+	 * <li>after inserting a <tt>Blob</tt> or <tt>Clob</tt>
+	 * </ul>
+	 *
+	 * @param object a persistent or detached instance
+	 * @throws HibernateException
+	 */
+	public void refresh(Object object) throws HibernateException;
+
+	/**
+	 * Re-read the state of the given instance from the underlying database, with
+	 * the given <tt>LockMode</tt>. It is inadvisable to use this to implement
+	 * long-running sessions that span many business tasks. This method is, however,
+	 * useful in certain special circumstances.
+	 *
+	 * @param object a persistent or detached instance
+	 * @param lockMode the lock mode to use
+	 * @throws HibernateException
+	 */
+	public void refresh(Object object, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Determine the current lock mode of the given object.
+	 *
+	 * @param object a persistent instance
+	 * @return the current lock mode
+	 * @throws HibernateException
+	 */
+	public LockMode getCurrentLockMode(Object object) throws HibernateException;
+
+	/**
+	 * Begin a unit of work and return the associated <tt>Transaction</tt> object.
+	 * If a new underlying transaction is required, begin the transaction. Otherwise
+	 * continue the new work in the context of the existing underlying transaction.
+	 * The class of the returned <tt>Transaction</tt> object is determined by the
+	 * property <tt>hibernate.transaction_factory</tt>.
+	 *
+	 * @return a Transaction instance
+	 * @throws HibernateException
+	 * @see Transaction
+	 */
+	public Transaction beginTransaction() throws HibernateException;
+
+	/**
+	 * Get the <tt>Transaction</tt> instance associated with this session.
+	 * The class of the returned <tt>Transaction</tt> object is determined by the
+	 * property <tt>hibernate.transaction_factory</tt>.
+	 *
+	 * @return a Transaction instance
+	 * @throws HibernateException
+	 * @see Transaction
+	 */
+	public Transaction getTransaction();
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
+	 * or a superclass of an entity class.
+	 *
+	 * @param persistentClass a class, which is persistent, or has persistent subclasses
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(Class persistentClass);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
+	 * or a superclass of an entity class, with the given alias.
+	 *
+	 * @param persistentClass a class, which is persistent, or has persistent subclasses
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(Class persistentClass, String alias);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity name.
+	 *
+	 * @param entityName
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(String entityName);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity name,
+	 * with the given alias.
+	 *
+	 * @param entityName
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(String entityName, String alias);
+
+	/**
+	 * Create a new instance of <tt>Query</tt> for the given HQL query string.
+	 *
+	 * @param queryString a HQL query
+	 * @return Query
+	 * @throws HibernateException
+	 */
+	public Query createQuery(String queryString) throws HibernateException;
+
+	/**
+	 * Create a new instance of <tt>SQLQuery</tt> for the given SQL query string.
+	 *
+	 * @param queryString a SQL query
+	 * @return SQLQuery
+	 * @throws HibernateException
+	 */
+	public SQLQuery createSQLQuery(String queryString) throws HibernateException;
+
+	/**
+	 * Create a new instance of <tt>Query</tt> for the given collection and filter string.
+	 *
+	 * @param collection a persistent collection
+	 * @param queryString a Hibernate query
+	 * @return Query
+	 * @throws HibernateException
+	 */
+	public Query createFilter(Object collection, String queryString) throws HibernateException;
+
+	/**
+	 * Obtain an instance of <tt>Query</tt> for a named query string defined in the
+	 * mapping file.
+	 *
+	 * @param queryName the name of a query defined externally
+	 * @return Query
+	 * @throws HibernateException
+	 */
+	public Query getNamedQuery(String queryName) throws HibernateException;
+
+	/**
+	 * Completely clear the session. Evict all loaded instances and cancel all pending
+	 * saves, updates and deletions. Do not close open iterators or instances of
+	 * <tt>ScrollableResults</tt>.
+	 */
+	public void clear();
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * or null if there is no such persistent instance. (If the instance is already associated
+	 * with the session, return that instance. This method never returns an uninitialized instance.)
+	 * Obtain the specified lock mode if the instance exists.
+	 *
+	 * @param clazz a persistent class
+	 * @param id an identifier
+	 * @return a persistent instance or null
+	 * @throws HibernateException
+	 */
+	public Object get(Class clazz, Serializable id) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * or null if there is no such persistent instance. (If the instance is already associated
+	 * with the session, return that instance. This method never returns an uninitialized instance.)
+	 * Obtain the specified lock mode if the instance exists.
+	 *
+	 * @param clazz a persistent class
+	 * @param id an identifier
+	 * @param lockMode the lock mode
+	 * @return a persistent instance or null
+	 * @throws HibernateException
+	 */
+	public Object get(Class clazz, Serializable id, LockMode lockMode) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given named entity with the given identifier,
+	 * or null if there is no such persistent instance. (If the instance is already associated
+	 * with the session, return that instance. This method never returns an uninitialized instance.)
+	 *
+	 * @param entityName the entity name
+	 * @param id an identifier
+	 * @return a persistent instance or null
+	 * @throws HibernateException
+	 */
+	public Object get(String entityName, Serializable id) throws HibernateException;
+
+	/**
+	 * Return the persistent instance of the given entity class with the given identifier,
+	 * or null if there is no such persistent instance. (If the instance is already associated
+	 * with the session, return that instance. This method never returns an uninitialized instance.)
+	 * Obtain the specified lock mode if the instance exists.
+	 *
+	 * @param entityName the entity name
+	 * @param id an identifier
+	 * @param lockMode the lock mode
+	 * @return a persistent instance or null
+	 * @throws HibernateException
+	 */
+	public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException;
+
+	
+	/**
+	 * Return the entity name for a persistent entity
+	 *   
+	 * @param object a persistent entity
+	 * @return the entity name
+	 * @throws HibernateException
+	 */
+	public String getEntityName(Object object) throws HibernateException;
+
+	/**
+	 * Enable the named filter for this current session.
+	 *
+	 * @param filterName The name of the filter to be enabled.
+	 * @return The Filter instance representing the enabled fiter.
+	 */
+	public Filter enableFilter(String filterName);
+
+	/**
+	 * Retrieve a currently enabled filter by name.
+	 *
+	 * @param filterName The name of the filter to be retrieved.
+	 * @return The Filter instance representing the enabled fiter.
+	 */
+	public Filter getEnabledFilter(String filterName);
+
+	/**
+	 * Disable the named filter for the current session.
+	 *
+	 * @param filterName The name of the filter to be disabled.
+	 */
+	public void disableFilter(String filterName);
+	
+	/**
+	 * Get the statistics for this session.
+	 */
+	public SessionStatistics getStatistics();
+	
+	/**
+	 * Set an unmodified persistent object to read only mode, or a read only
+	 * object to modifiable mode. In read only mode, no snapshot is maintained
+	 * and the instance is never dirty checked.
+	 * 
+	 * @see Query#setReadOnly(boolean)
+	 */
+	public void setReadOnly(Object entity, boolean readOnly);
+
+	/**
+	 * Controller for allowing users to perform JDBC related work using the Connection
+	 * managed by this Session.
+	 *
+	 * @param work The work to be performed.
+	 * @throws HibernateException Generally indicates wrapped {@link java.sql.SQLException}
+	 */
+	public void doWork(Work work) throws HibernateException;
+
+
+	/**
+	 * Disconnect the <tt>Session</tt> from the current JDBC connection. If
+	 * the connection was obtained by Hibernate close it and return it to
+	 * the connection pool; otherwise, return it to the application.
+	 * <p/>
+	 * This is used by applications which supply JDBC connections to Hibernate
+	 * and which require long-sessions (or long-conversations)
+	 * <p/>
+	 * Note that disconnect() called on a session where the connection was
+	 * retrieved by Hibernate through its configured
+	 * {@link org.hibernate.connection.ConnectionProvider} has no effect,
+	 * provided {@link ConnectionReleaseMode#ON_CLOSE} is not in effect.
+	 *
+	 * @return the application-supplied connection or <tt>null</tt>
+	 * @see #reconnect(Connection)
+	 * @see #reconnect()
+	 */
+	Connection disconnect() throws HibernateException;
+
+	/**
+	 * Obtain a new JDBC connection. This is used by applications which
+	 * require long transactions and do not supply connections to the
+	 * session.
+	 *
+	 * @see #disconnect()
+	 * @deprecated Manual reconnection is only needed in the case of
+	 * application-supplied connections, in which case the
+	 * {@link #reconnect(java.sql.Connection)} for should be used.
+	 */
+	void reconnect() throws HibernateException;
+
+	/**
+	 * Reconnect to the given JDBC connection. This is used by applications
+	 * which require long transactions and use application-supplied connections.
+	 *
+	 * @param connection a JDBC connection
+	 * @see #disconnect()
+	 */
+	void reconnect(Connection connection) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/SessionException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: SessionException.java 9024 2006-01-11 22:38:24Z steveebersole $
-package org.hibernate;
-
-/**
- * Thrown when the user calls a method of a {@link Session} that is in an
- * inappropropriate state for the given call (for example, the the session
- * is closed or disconnected).
- *
- * @author Gavin King
- */
-public class SessionException extends HibernateException {
-
-	/**
-	 * Constructs a new SessionException with the given message.
-	 *
-	 * @param message The message indicating the specific problem.
-	 */
-	public SessionException(String message) {
-		super( message );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/SessionException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Thrown when the user calls a method of a {@link Session} that is in an
+ * inappropropriate state for the given call (for example, the the session
+ * is closed or disconnected).
+ *
+ * @author Gavin King
+ */
+public class SessionException extends HibernateException {
+
+	/**
+	 * Constructs a new SessionException with the given message.
+	 *
+	 * @param message The message indicating the specific problem.
+	 */
+	public SessionException(String message) {
+		super( message );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/SessionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,224 +0,0 @@
-//$Id: SessionFactory.java 8754 2005-12-05 23:36:59Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.Map;
-import java.util.Set;
-
-import javax.naming.Referenceable;
-
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.stat.Statistics;
-import org.hibernate.engine.FilterDefinition;
-
-/**
- * Creates <tt>Session</tt>s. Usually an application has a single <tt>SessionFactory</tt>.
- * Threads servicing client requests obtain <tt>Session</tt>s from the factory.<br>
- * <br>
- * Implementors must be threadsafe.<br>
- * <br>
- * <tt>SessionFactory</tt>s are immutable. The behaviour of a <tt>SessionFactory</tt> is
- * controlled by properties supplied at configuration time. These properties are defined
- * on <tt>Environment</tt>.
- *
- * @see Session
- * @see org.hibernate.cfg.Environment
- * @see org.hibernate.cfg.Configuration
- * @see org.hibernate.connection.ConnectionProvider
- * @see org.hibernate.transaction.TransactionFactory
- * @author Gavin King
- */
-public interface SessionFactory extends Referenceable, Serializable {
-
-	/**
-	 * Open a <tt>Session</tt> on the given connection.
-	 * <p>
-	 * Note that the second-level cache will be disabled if you
-	 * supply a JDBC connection. Hibernate will not be able to track
-	 * any statements you might have executed in the same transaction.
-	 * Consider implementing your own <tt>ConnectionProvider</tt>.
-	 *
-	 * @param connection a connection provided by the application.
-	 * @return Session
-	 */
-	public org.hibernate.classic.Session openSession(Connection connection);
-
-	/**
-	 * Create database connection and open a <tt>Session</tt> on it, specifying an
-	 * interceptor.
-	 *
-	 * @param interceptor a session-scoped interceptor
-	 * @return Session
-	 * @throws HibernateException
-	 */
-	public org.hibernate.classic.Session openSession(Interceptor interceptor) throws HibernateException;
-
-	/**
-	 * Open a <tt>Session</tt> on the given connection, specifying an interceptor.
-	 * <p>
-	 * Note that the second-level cache will be disabled if you
-	 * supply a JDBC connection. Hibernate will not be able to track
-	 * any statements you might have executed in the same transaction.
-	 * Consider implementing your own <tt>ConnectionProvider</tt>.
-	 *
-	 * @param connection a connection provided by the application.
-	 * @param interceptor a session-scoped interceptor
-	 * @return Session
-	 */
-	public org.hibernate.classic.Session openSession(Connection connection, Interceptor interceptor);
-
-	/**
-	 * Create database connection and open a <tt>Session</tt> on it.
-	 *
-	 * @return Session
-	 * @throws HibernateException
-	 */
-	public org.hibernate.classic.Session openSession() throws HibernateException;
-
-	/**
-	 * Obtains the current session.  The definition of what exactly "current"
-	 * means controlled by the {@link org.hibernate.context.CurrentSessionContext} impl configured
-	 * for use.
-	 * <p/>
-	 * Note that for backwards compatibility, if a {@link org.hibernate.context.CurrentSessionContext}
-	 * is not configured but a JTA {@link org.hibernate.transaction.TransactionManagerLookup}
-	 * is configured this will default to the {@link org.hibernate.context.JTASessionContext}
-	 * impl.
-	 *
-	 * @return The current session.
-	 * @throws HibernateException Indicates an issue locating a suitable current session.
-	 */
-	public org.hibernate.classic.Session getCurrentSession() throws HibernateException;
-
-	/**
-	 * Get the <tt>ClassMetadata</tt> associated with the given entity class
-	 *
-	 * @see org.hibernate.metadata.ClassMetadata
-	 */
-	public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException;
-
-	/**
-	 * Get the <tt>ClassMetadata</tt> associated with the given entity name
-	 *
-	 * @see org.hibernate.metadata.ClassMetadata
-	 * @since 3.0
-	 */
-	public ClassMetadata getClassMetadata(String entityName) throws HibernateException;
-
-	/**
-	 * Get the <tt>CollectionMetadata</tt> associated with the named collection role
-	 *
-	 * @see org.hibernate.metadata.CollectionMetadata
-	 */
-	public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException;
-
-
-	/**
-	 * Get all <tt>ClassMetadata</tt> as a <tt>Map</tt> from entityname <tt>String</tt>
-	 * to metadata object
-	 *
-	 * @see org.hibernate.metadata.ClassMetadata
-	 * @return a map from <tt>String</tt> an entity name to <tt>ClassMetaData</tt>
-	 * @since 3.0 changed key from <tt>Class</tt> to <tt>String</tt>
-	 */
-	public Map getAllClassMetadata() throws HibernateException;
-
-	/**
-	 * Get all <tt>CollectionMetadata</tt> as a <tt>Map</tt> from role name
-	 * to metadata object
-	 *
-	 * @see org.hibernate.metadata.CollectionMetadata
-	 * @return a map from <tt>String</tt> to <tt>CollectionMetadata</tt>
-	 */
-	public Map getAllCollectionMetadata() throws HibernateException;
-
-	/**
-	 * Get the statistics for this session factory
-	 */
-	public Statistics getStatistics();
-
-	/**
-	 * Destroy this <tt>SessionFactory</tt> and release all resources (caches,
-	 * connection pools, etc). It is the responsibility of the application
-	 * to ensure that there are no open <tt>Session</tt>s before calling
-	 * <tt>close()</tt>.
-	 */
-	public void close() throws HibernateException;
-
-	/**
-	 * Was this <tt>SessionFactory</tt> already closed?
-	 */
-	public boolean isClosed();
-
-	/**
-	 * Evict all entries from the second-level cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evict(Class persistentClass) throws HibernateException;
-	/**
-	 * Evict an entry from the second-level  cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evict(Class persistentClass, Serializable id) throws HibernateException;
-	/**
-	 * Evict all entries from the second-level cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evictEntity(String entityName) throws HibernateException;
-	/**
-	 * Evict an entry from the second-level  cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evictEntity(String entityName, Serializable id) throws HibernateException;
-	/**
-	 * Evict all entries from the second-level cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evictCollection(String roleName) throws HibernateException;
-	/**
-	 * Evict an entry from the second-level cache. This method occurs outside
-	 * of any transaction; it performs an immediate "hard" remove, so does not respect
-	 * any transaction isolation semantics of the usage strategy. Use with care.
-	 */
-	public void evictCollection(String roleName, Serializable id) throws HibernateException;
-
-	/**
-	 * Evict any query result sets cached in the default query cache region.
-	 */
-	public void evictQueries() throws HibernateException;
-	/**
-	 * Evict any query result sets cached in the named query cache region.
-	 */
-	public void evictQueries(String cacheRegion) throws HibernateException;
-	/**
-	 * Get a new stateless session.
-	 */
-	public StatelessSession openStatelessSession();
-	/**
-	 * Get a new stateless session for the given JDBC connection.
-	 */
-	public StatelessSession openStatelessSession(Connection connection);
-
-	/**
-	 * Obtain a set of the names of all filters defined on this SessionFactory.
-	 *
-	 * @return The set of filter names.
-	 */
-	public Set getDefinedFilterNames();
-
-	/**
-	 * Obtain the definition of a filter by name.
-	 *
-	 * @param filterName The name of the filter for which to obtain the definition.
-	 * @return The filter definition.
-	 * @throws HibernateException If no filter defined with the given name.
-	 */
-	public FilterDefinition getFilterDefinition(String filterName) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/SessionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,247 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Map;
+import java.util.Set;
+
+import javax.naming.Referenceable;
+
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.stat.Statistics;
+import org.hibernate.engine.FilterDefinition;
+
+/**
+ * Creates <tt>Session</tt>s. Usually an application has a single <tt>SessionFactory</tt>.
+ * Threads servicing client requests obtain <tt>Session</tt>s from the factory.<br>
+ * <br>
+ * Implementors must be threadsafe.<br>
+ * <br>
+ * <tt>SessionFactory</tt>s are immutable. The behaviour of a <tt>SessionFactory</tt> is
+ * controlled by properties supplied at configuration time. These properties are defined
+ * on <tt>Environment</tt>.
+ *
+ * @see Session
+ * @see org.hibernate.cfg.Environment
+ * @see org.hibernate.cfg.Configuration
+ * @see org.hibernate.connection.ConnectionProvider
+ * @see org.hibernate.transaction.TransactionFactory
+ * @author Gavin King
+ */
+public interface SessionFactory extends Referenceable, Serializable {
+
+	/**
+	 * Open a <tt>Session</tt> on the given connection.
+	 * <p>
+	 * Note that the second-level cache will be disabled if you
+	 * supply a JDBC connection. Hibernate will not be able to track
+	 * any statements you might have executed in the same transaction.
+	 * Consider implementing your own <tt>ConnectionProvider</tt>.
+	 *
+	 * @param connection a connection provided by the application.
+	 * @return Session
+	 */
+	public org.hibernate.classic.Session openSession(Connection connection);
+
+	/**
+	 * Create database connection and open a <tt>Session</tt> on it, specifying an
+	 * interceptor.
+	 *
+	 * @param interceptor a session-scoped interceptor
+	 * @return Session
+	 * @throws HibernateException
+	 */
+	public org.hibernate.classic.Session openSession(Interceptor interceptor) throws HibernateException;
+
+	/**
+	 * Open a <tt>Session</tt> on the given connection, specifying an interceptor.
+	 * <p>
+	 * Note that the second-level cache will be disabled if you
+	 * supply a JDBC connection. Hibernate will not be able to track
+	 * any statements you might have executed in the same transaction.
+	 * Consider implementing your own <tt>ConnectionProvider</tt>.
+	 *
+	 * @param connection a connection provided by the application.
+	 * @param interceptor a session-scoped interceptor
+	 * @return Session
+	 */
+	public org.hibernate.classic.Session openSession(Connection connection, Interceptor interceptor);
+
+	/**
+	 * Create database connection and open a <tt>Session</tt> on it.
+	 *
+	 * @return Session
+	 * @throws HibernateException
+	 */
+	public org.hibernate.classic.Session openSession() throws HibernateException;
+
+	/**
+	 * Obtains the current session.  The definition of what exactly "current"
+	 * means controlled by the {@link org.hibernate.context.CurrentSessionContext} impl configured
+	 * for use.
+	 * <p/>
+	 * Note that for backwards compatibility, if a {@link org.hibernate.context.CurrentSessionContext}
+	 * is not configured but a JTA {@link org.hibernate.transaction.TransactionManagerLookup}
+	 * is configured this will default to the {@link org.hibernate.context.JTASessionContext}
+	 * impl.
+	 *
+	 * @return The current session.
+	 * @throws HibernateException Indicates an issue locating a suitable current session.
+	 */
+	public org.hibernate.classic.Session getCurrentSession() throws HibernateException;
+
+	/**
+	 * Get the <tt>ClassMetadata</tt> associated with the given entity class
+	 *
+	 * @see org.hibernate.metadata.ClassMetadata
+	 */
+	public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException;
+
+	/**
+	 * Get the <tt>ClassMetadata</tt> associated with the given entity name
+	 *
+	 * @see org.hibernate.metadata.ClassMetadata
+	 * @since 3.0
+	 */
+	public ClassMetadata getClassMetadata(String entityName) throws HibernateException;
+
+	/**
+	 * Get the <tt>CollectionMetadata</tt> associated with the named collection role
+	 *
+	 * @see org.hibernate.metadata.CollectionMetadata
+	 */
+	public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException;
+
+
+	/**
+	 * Get all <tt>ClassMetadata</tt> as a <tt>Map</tt> from entityname <tt>String</tt>
+	 * to metadata object
+	 *
+	 * @see org.hibernate.metadata.ClassMetadata
+	 * @return a map from <tt>String</tt> an entity name to <tt>ClassMetaData</tt>
+	 * @since 3.0 changed key from <tt>Class</tt> to <tt>String</tt>
+	 */
+	public Map getAllClassMetadata() throws HibernateException;
+
+	/**
+	 * Get all <tt>CollectionMetadata</tt> as a <tt>Map</tt> from role name
+	 * to metadata object
+	 *
+	 * @see org.hibernate.metadata.CollectionMetadata
+	 * @return a map from <tt>String</tt> to <tt>CollectionMetadata</tt>
+	 */
+	public Map getAllCollectionMetadata() throws HibernateException;
+
+	/**
+	 * Get the statistics for this session factory
+	 */
+	public Statistics getStatistics();
+
+	/**
+	 * Destroy this <tt>SessionFactory</tt> and release all resources (caches,
+	 * connection pools, etc). It is the responsibility of the application
+	 * to ensure that there are no open <tt>Session</tt>s before calling
+	 * <tt>close()</tt>.
+	 */
+	public void close() throws HibernateException;
+
+	/**
+	 * Was this <tt>SessionFactory</tt> already closed?
+	 */
+	public boolean isClosed();
+
+	/**
+	 * Evict all entries from the second-level cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evict(Class persistentClass) throws HibernateException;
+	/**
+	 * Evict an entry from the second-level  cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evict(Class persistentClass, Serializable id) throws HibernateException;
+	/**
+	 * Evict all entries from the second-level cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evictEntity(String entityName) throws HibernateException;
+	/**
+	 * Evict an entry from the second-level  cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evictEntity(String entityName, Serializable id) throws HibernateException;
+	/**
+	 * Evict all entries from the second-level cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evictCollection(String roleName) throws HibernateException;
+	/**
+	 * Evict an entry from the second-level cache. This method occurs outside
+	 * of any transaction; it performs an immediate "hard" remove, so does not respect
+	 * any transaction isolation semantics of the usage strategy. Use with care.
+	 */
+	public void evictCollection(String roleName, Serializable id) throws HibernateException;
+
+	/**
+	 * Evict any query result sets cached in the default query cache region.
+	 */
+	public void evictQueries() throws HibernateException;
+	/**
+	 * Evict any query result sets cached in the named query cache region.
+	 */
+	public void evictQueries(String cacheRegion) throws HibernateException;
+	/**
+	 * Get a new stateless session.
+	 */
+	public StatelessSession openStatelessSession();
+	/**
+	 * Get a new stateless session for the given JDBC connection.
+	 */
+	public StatelessSession openStatelessSession(Connection connection);
+
+	/**
+	 * Obtain a set of the names of all filters defined on this SessionFactory.
+	 *
+	 * @return The set of filter names.
+	 */
+	public Set getDefinedFilterNames();
+
+	/**
+	 * Obtain the definition of a filter by name.
+	 *
+	 * @param filterName The name of the filter for which to obtain the definition.
+	 * @return The filter definition.
+	 * @throws HibernateException If no filter defined with the given name.
+	 */
+	public FilterDefinition getFilterDefinition(String filterName) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/SessionFactoryObserver.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +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;
-
-import java.io.Serializable;
-
-/**
- * Allows reaction to basic {@link SessionFactory} occurrences.
- *
- * @author Steve Ebersole
- */
-public interface SessionFactoryObserver extends Serializable {
-	/**
-	 * Callback to indicate that the given factory has been created and is now ready for use.
-	 *
-	 * @param factory The factory initialized.
-	 */
-	public void sessionFactoryCreated(SessionFactory factory);
-
-	/**
-	 * Callback to indicate that the given factory has been closed.  Care should be taken
-	 * in how (if at all) the passed factory reference is used since it is closed.
-	 *
-	 * @param factory The factory closed.
-	 */
-	public void sessionFactoryClosed(SessionFactory factory);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/SessionFactoryObserver.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/SessionFactoryObserver.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * Allows reaction to basic {@link SessionFactory} occurrences.
+ *
+ * @author Steve Ebersole
+ */
+public interface SessionFactoryObserver extends Serializable {
+	/**
+	 * Callback to indicate that the given factory has been created and is now ready for use.
+	 *
+	 * @param factory The factory initialized.
+	 */
+	public void sessionFactoryCreated(SessionFactory factory);
+
+	/**
+	 * Callback to indicate that the given factory has been closed.  Care should be taken
+	 * in how (if at all) the passed factory reference is used since it is closed.
+	 *
+	 * @param factory The factory closed.
+	 */
+	public void sessionFactoryClosed(SessionFactory factory);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/StaleObjectStateException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: StaleObjectStateException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * A <tt>StaleStateException</tt> that carries information 
- * about a particular entity instance that was the source
- * of the failure.
- *
- * @author Gavin King
- */
-public class StaleObjectStateException extends StaleStateException {
-	private final String entityName;
-	private final Serializable identifier;
-
-	public StaleObjectStateException(String persistentClass, Serializable identifier) {
-		super("Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)");
-		this.entityName = persistentClass;
-		this.identifier = identifier;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public Serializable getIdentifier() {
-		return identifier;
-	}
-
-	public String getMessage() {
-		return super.getMessage() + ": " +
-			MessageHelper.infoString(entityName, identifier);
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/StaleObjectStateException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleObjectStateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * A <tt>StaleStateException</tt> that carries information 
+ * about a particular entity instance that was the source
+ * of the failure.
+ *
+ * @author Gavin King
+ */
+public class StaleObjectStateException extends StaleStateException {
+	private final String entityName;
+	private final Serializable identifier;
+
+	public StaleObjectStateException(String persistentClass, Serializable identifier) {
+		super("Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)");
+		this.entityName = persistentClass;
+		this.identifier = identifier;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public Serializable getIdentifier() {
+		return identifier;
+	}
+
+	public String getMessage() {
+		return super.getMessage() + ": " +
+			MessageHelper.infoString(entityName, identifier);
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/StaleStateException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: StaleStateException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-/**
- * Thrown when a version number or timestamp check failed, indicating that the
- * <tt>Session</tt> contained stale data (when using long transactions
- * with versioning). Also occurs if we try delete or update a row that does
- * not exist.<br>
- * <br>
- * Note that this exception often indicates that the user failed to specify the
- * correct <tt>unsaved-value</tt> strategy for a class!
- *
- * @see StaleObjectStateException
- * @author Gavin King
- */
-public class StaleStateException extends HibernateException {
-
-	public StaleStateException(String s) {
-		super(s);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/StaleStateException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StaleStateException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Thrown when a version number or timestamp check failed, indicating that the
+ * <tt>Session</tt> contained stale data (when using long transactions
+ * with versioning). Also occurs if we try delete or update a row that does
+ * not exist.<br>
+ * <br>
+ * Note that this exception often indicates that the user failed to specify the
+ * correct <tt>unsaved-value</tt> strategy for a class!
+ *
+ * @see StaleObjectStateException
+ * @author Gavin King
+ */
+public class StaleStateException extends HibernateException {
+
+	public StaleStateException(String s) {
+		super(s);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/StatelessSession.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,217 +0,0 @@
-//$Id: StatelessSession.java 9705 2006-03-28 19:59:31Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import java.io.Serializable;
-import java.sql.Connection;
-
-/**
- * A command-oriented API for performing bulk operations
- * against a database.<br>
- * <br>
- * A stateless session does not implement a first-level cache nor
- * interact with any second-level cache, nor does it implement
- * transactional write-behind or automatic dirty checking, nor do
- * operations cascade to associated instances. Collections are
- * ignored by a stateless session. Operations performed via a
- * stateless session bypass Hibernate's event model and
- * interceptors. Stateless sessions are vulnerable to data
- * aliasing effects, due to the lack of a first-level cache.<br>
- * <br>
- * For certain kinds of transactions, a stateless session may
- * perform slightly faster than a stateful session.
- *
- * @author Gavin King
- */
-public interface StatelessSession extends Serializable {
-	/**
-	 * Close the stateless session and release the JDBC connection.
-	 */
-	public void close();
-
-	/**
-	 * Insert a row.
-	 *
-	 * @param entity a new transient instance
-	 */
-	public Serializable insert(Object entity);
-
-	/**
-	 * Insert a row.
-	 *
-	 * @param entityName The entityName for the entity to be inserted
-	 * @param entity a new transient instance
-	 * @return the identifier of the instance
-	 */
-	public Serializable insert(String entityName, Object entity);
-
-	/**
-	 * Update a row.
-	 *
-	 * @param entity a detached entity instance
-	 */
-	public void update(Object entity);
-
-	/**
-	 * Update a row.
-	 *
-	 * @param entityName The entityName for the entity to be updated
-	 * @param entity a detached entity instance
-	 */
-	public void update(String entityName, Object entity);
-
-	/**
-	 * Delete a row.
-	 *
-	 * @param entity a detached entity instance
-	 */
-	public void delete(Object entity);
-
-	/**
-	 * Delete a row.
-	 *
-	 * @param entityName The entityName for the entity to be deleted
-	 * @param entity a detached entity instance
-	 */
-	public void delete(String entityName, Object entity);
-
-	/**
-	 * Retrieve a row.
-	 *
-	 * @return a detached entity instance
-	 */
-	public Object get(String entityName, Serializable id);
-
-	/**
-	 * Retrieve a row.
-	 *
-	 * @return a detached entity instance
-	 */
-	public Object get(Class entityClass, Serializable id);
-
-	/**
-	 * Retrieve a row, obtaining the specified lock mode.
-	 *
-	 * @return a detached entity instance
-	 */
-	public Object get(String entityName, Serializable id, LockMode lockMode);
-
-	/**
-	 * Retrieve a row, obtaining the specified lock mode.
-	 *
-	 * @return a detached entity instance
-	 */
-	public Object get(Class entityClass, Serializable id, LockMode lockMode);
-
-	/**
-	 * Refresh the entity instance state from the database.
-	 *
-	 * @param entity The entity to be refreshed.
-	 */
-	public void refresh(Object entity);
-
-	/**
-	 * Refresh the entity instance state from the database.
-	 *
-	 * @param entityName The entityName for the entity to be refreshed.
-	 * @param entity The entity to be refreshed.
-	 */
-	public void refresh(String entityName, Object entity);
-
-	/**
-	 * Refresh the entity instance state from the database.
-	 *
-	 * @param entity The entity to be refreshed.
-	 * @param lockMode The LockMode to be applied.
-	 */
-	public void refresh(Object entity, LockMode lockMode);
-
-	/**
-	 * Refresh the entity instance state from the database.
-	 *
-	 * @param entityName The entityName for the entity to be refreshed.
-	 * @param entity The entity to be refreshed.
-	 * @param lockMode The LockMode to be applied.
-	 */
-	public void refresh(String entityName, Object entity, LockMode lockMode);
-
-	/**
-	 * Create a new instance of <tt>Query</tt> for the given HQL query string.
-	 * Entities returned by the query are detached.
-	 */
-	public Query createQuery(String queryString);
-
-	/**
-	 * Obtain an instance of <tt>Query</tt> for a named query string defined in
-	 * the mapping file. Entities returned by the query are detached.
-	 */
-	public Query getNamedQuery(String queryName);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
-	 * or a superclass of an entity class. Entities returned by the query are
-	 * detached.
-	 *
-	 * @param persistentClass a class, which is persistent, or has persistent subclasses
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(Class persistentClass);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
-	 * or a superclass of an entity class, with the given alias.
-	 * Entities returned by the query are detached.
-	 *
-	 * @param persistentClass a class, which is persistent, or has persistent subclasses
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(Class persistentClass, String alias);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity name.
-	 * Entities returned by the query are detached.
-	 *
-	 * @param entityName
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(String entityName);
-
-	/**
-	 * Create a new <tt>Criteria</tt> instance, for the given entity name,
-	 * with the given alias. Entities returned by the query are detached.
-	 *
-	 * @param entityName
-	 * @return Criteria
-	 */
-	public Criteria createCriteria(String entityName, String alias);
-
-	/**
-	 * Create a new instance of <tt>SQLQuery</tt> for the given SQL query string.
-	 * Entities returned by the query are detached.
-	 *
-	 * @param queryString a SQL query
-	 * @return SQLQuery
-	 * @throws HibernateException
-	 */
-	public SQLQuery createSQLQuery(String queryString) throws HibernateException;
-
-	/**
-	 * Begin a Hibernate transaction.
-	 */
-	public Transaction beginTransaction();
-
-	/**
-	 * Get the current Hibernate transaction.
-	 */
-	public Transaction getTransaction();
-
-	/**
-	 * Returns the current JDBC connection associated with this
-	 * instance.<br>
-	 * <br>
-	 * If the session is using aggressive connection release (as in a
-	 * CMT environment), it is the application's responsibility to
-	 * close the connection returned by this call. Otherwise, the
-	 * application should not close the connection.
-	 */
-	public Connection connection();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/StatelessSession.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/StatelessSession.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,240 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.sql.Connection;
+
+/**
+ * A command-oriented API for performing bulk operations
+ * against a database.<br>
+ * <br>
+ * A stateless session does not implement a first-level cache nor
+ * interact with any second-level cache, nor does it implement
+ * transactional write-behind or automatic dirty checking, nor do
+ * operations cascade to associated instances. Collections are
+ * ignored by a stateless session. Operations performed via a
+ * stateless session bypass Hibernate's event model and
+ * interceptors. Stateless sessions are vulnerable to data
+ * aliasing effects, due to the lack of a first-level cache.<br>
+ * <br>
+ * For certain kinds of transactions, a stateless session may
+ * perform slightly faster than a stateful session.
+ *
+ * @author Gavin King
+ */
+public interface StatelessSession extends Serializable {
+	/**
+	 * Close the stateless session and release the JDBC connection.
+	 */
+	public void close();
+
+	/**
+	 * Insert a row.
+	 *
+	 * @param entity a new transient instance
+	 */
+	public Serializable insert(Object entity);
+
+	/**
+	 * Insert a row.
+	 *
+	 * @param entityName The entityName for the entity to be inserted
+	 * @param entity a new transient instance
+	 * @return the identifier of the instance
+	 */
+	public Serializable insert(String entityName, Object entity);
+
+	/**
+	 * Update a row.
+	 *
+	 * @param entity a detached entity instance
+	 */
+	public void update(Object entity);
+
+	/**
+	 * Update a row.
+	 *
+	 * @param entityName The entityName for the entity to be updated
+	 * @param entity a detached entity instance
+	 */
+	public void update(String entityName, Object entity);
+
+	/**
+	 * Delete a row.
+	 *
+	 * @param entity a detached entity instance
+	 */
+	public void delete(Object entity);
+
+	/**
+	 * Delete a row.
+	 *
+	 * @param entityName The entityName for the entity to be deleted
+	 * @param entity a detached entity instance
+	 */
+	public void delete(String entityName, Object entity);
+
+	/**
+	 * Retrieve a row.
+	 *
+	 * @return a detached entity instance
+	 */
+	public Object get(String entityName, Serializable id);
+
+	/**
+	 * Retrieve a row.
+	 *
+	 * @return a detached entity instance
+	 */
+	public Object get(Class entityClass, Serializable id);
+
+	/**
+	 * Retrieve a row, obtaining the specified lock mode.
+	 *
+	 * @return a detached entity instance
+	 */
+	public Object get(String entityName, Serializable id, LockMode lockMode);
+
+	/**
+	 * Retrieve a row, obtaining the specified lock mode.
+	 *
+	 * @return a detached entity instance
+	 */
+	public Object get(Class entityClass, Serializable id, LockMode lockMode);
+
+	/**
+	 * Refresh the entity instance state from the database.
+	 *
+	 * @param entity The entity to be refreshed.
+	 */
+	public void refresh(Object entity);
+
+	/**
+	 * Refresh the entity instance state from the database.
+	 *
+	 * @param entityName The entityName for the entity to be refreshed.
+	 * @param entity The entity to be refreshed.
+	 */
+	public void refresh(String entityName, Object entity);
+
+	/**
+	 * Refresh the entity instance state from the database.
+	 *
+	 * @param entity The entity to be refreshed.
+	 * @param lockMode The LockMode to be applied.
+	 */
+	public void refresh(Object entity, LockMode lockMode);
+
+	/**
+	 * Refresh the entity instance state from the database.
+	 *
+	 * @param entityName The entityName for the entity to be refreshed.
+	 * @param entity The entity to be refreshed.
+	 * @param lockMode The LockMode to be applied.
+	 */
+	public void refresh(String entityName, Object entity, LockMode lockMode);
+
+	/**
+	 * Create a new instance of <tt>Query</tt> for the given HQL query string.
+	 * Entities returned by the query are detached.
+	 */
+	public Query createQuery(String queryString);
+
+	/**
+	 * Obtain an instance of <tt>Query</tt> for a named query string defined in
+	 * the mapping file. Entities returned by the query are detached.
+	 */
+	public Query getNamedQuery(String queryName);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
+	 * or a superclass of an entity class. Entities returned by the query are
+	 * detached.
+	 *
+	 * @param persistentClass a class, which is persistent, or has persistent subclasses
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(Class persistentClass);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity class,
+	 * or a superclass of an entity class, with the given alias.
+	 * Entities returned by the query are detached.
+	 *
+	 * @param persistentClass a class, which is persistent, or has persistent subclasses
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(Class persistentClass, String alias);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity name.
+	 * Entities returned by the query are detached.
+	 *
+	 * @param entityName
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(String entityName);
+
+	/**
+	 * Create a new <tt>Criteria</tt> instance, for the given entity name,
+	 * with the given alias. Entities returned by the query are detached.
+	 *
+	 * @param entityName
+	 * @return Criteria
+	 */
+	public Criteria createCriteria(String entityName, String alias);
+
+	/**
+	 * Create a new instance of <tt>SQLQuery</tt> for the given SQL query string.
+	 * Entities returned by the query are detached.
+	 *
+	 * @param queryString a SQL query
+	 * @return SQLQuery
+	 * @throws HibernateException
+	 */
+	public SQLQuery createSQLQuery(String queryString) throws HibernateException;
+
+	/**
+	 * Begin a Hibernate transaction.
+	 */
+	public Transaction beginTransaction();
+
+	/**
+	 * Get the current Hibernate transaction.
+	 */
+	public Transaction getTransaction();
+
+	/**
+	 * Returns the current JDBC connection associated with this
+	 * instance.<br>
+	 * <br>
+	 * If the session is using aggressive connection release (as in a
+	 * CMT environment), it is the application's responsibility to
+	 * close the connection returned by this call. Otherwise, the
+	 * application should not close the connection.
+	 */
+	public Connection connection();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/Transaction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,105 +0,0 @@
-//$Id: Transaction.java 9595 2006-03-10 18:14:21Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-import javax.transaction.Synchronization;
-
-/**
- * Allows the application to define units of work, while
- * maintaining abstraction from the underlying transaction
- * implementation (eg. JTA, JDBC).<br>
- * <br>
- * A transaction is associated with a <tt>Session</tt> and is
- * usually instantiated by a call to <tt>Session.beginTransaction()</tt>.
- * A single session might span multiple transactions since
- * the notion of a session (a conversation between the application
- * and the datastore) is of coarser granularity than the notion of
- * a transaction. However, it is intended that there be at most one
- * uncommitted <tt>Transaction</tt> associated with a particular
- * <tt>Session</tt> at any time.<br>
- * <br>
- * Implementors are not intended to be threadsafe.
- *
- * @see Session#beginTransaction()
- * @see org.hibernate.transaction.TransactionFactory
- * @author Anton van Straaten
- */
-public interface Transaction {
-	
-	/**
-	 * Begin a new transaction.
-	 */
-	public void begin() throws HibernateException;
-
-	/**
-	 * Flush the associated <tt>Session</tt> and end the unit of work (unless
-	 * we are in {@link FlushMode#MANUAL}.
-	 * </p>
-	 * This method will commit the underlying transaction if and only
-	 * if the underlying transaction was initiated by this object.
-	 *
-	 * @throws HibernateException
-	 */
-	public void commit() throws HibernateException;
-
-	/**
-	 * Force the underlying transaction to roll back.
-	 *
-	 * @throws HibernateException
-	 */
-	public void rollback() throws HibernateException;
-
-	/**
-	 * Was this transaction rolled back or set to rollback only?
-	 * <p/>
-	 * This only accounts for actions initiated from this local transaction.
-	 * If, for example, the underlying transaction is forced to rollback via
-	 * some other means, this method still reports false because the rollback
-	 * was not initiated from here.
-	 *
-	 * @return boolean True if the transaction was rolled back via this
-	 * local transaction; false otherwise.
-	 * @throws HibernateException
-	 */
-	public boolean wasRolledBack() throws HibernateException;
-
-	/**
-	 * Check if this transaction was successfully committed.
-	 * <p/>
-	 * This method could return <tt>false</tt> even after successful invocation
-	 * of {@link #commit}.  As an example, JTA based strategies no-op on
-	 * {@link #commit} calls if they did not start the transaction; in that case,
-	 * they also report {@link #wasCommitted} as false.
-	 *
-	 * @return boolean True if the transaction was (unequivocally) committed
-	 * via this local transaction; false otherwise.
-	 * @throws HibernateException
-	 */
-	public boolean wasCommitted() throws HibernateException;
-	
-	/**
-	 * Is this transaction still active?
-	 * <p/>
-	 * Again, this only returns information in relation to the
-	 * local transaction, not the actual underlying transaction.
-	 *
-	 * @return boolean Treu if this local transaction is still active.
-	 */
-	public boolean isActive() throws HibernateException;
-
-	/**
-	 * Register a user synchronization callback for this transaction.
-	 *
-	 * @param synchronization The Synchronization callback to register.
-	 * @throws HibernateException
-	 */
-	public void registerSynchronization(Synchronization synchronization) 
-	throws HibernateException;
-
-	/**
-	 * Set the transaction timeout for any transaction started by
-	 * a subsequent call to <tt>begin()</tt> on this instance.
-	 *
-	 * @param seconds The number of seconds before a timeout.
-	 */
-	public void setTimeout(int seconds);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/Transaction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/Transaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import javax.transaction.Synchronization;
+
+/**
+ * Allows the application to define units of work, while
+ * maintaining abstraction from the underlying transaction
+ * implementation (eg. JTA, JDBC).<br>
+ * <br>
+ * A transaction is associated with a <tt>Session</tt> and is
+ * usually instantiated by a call to <tt>Session.beginTransaction()</tt>.
+ * A single session might span multiple transactions since
+ * the notion of a session (a conversation between the application
+ * and the datastore) is of coarser granularity than the notion of
+ * a transaction. However, it is intended that there be at most one
+ * uncommitted <tt>Transaction</tt> associated with a particular
+ * <tt>Session</tt> at any time.<br>
+ * <br>
+ * Implementors are not intended to be threadsafe.
+ *
+ * @see Session#beginTransaction()
+ * @see org.hibernate.transaction.TransactionFactory
+ * @author Anton van Straaten
+ */
+public interface Transaction {
+	
+	/**
+	 * Begin a new transaction.
+	 */
+	public void begin() throws HibernateException;
+
+	/**
+	 * Flush the associated <tt>Session</tt> and end the unit of work (unless
+	 * we are in {@link FlushMode#MANUAL}.
+	 * </p>
+	 * This method will commit the underlying transaction if and only
+	 * if the underlying transaction was initiated by this object.
+	 *
+	 * @throws HibernateException
+	 */
+	public void commit() throws HibernateException;
+
+	/**
+	 * Force the underlying transaction to roll back.
+	 *
+	 * @throws HibernateException
+	 */
+	public void rollback() throws HibernateException;
+
+	/**
+	 * Was this transaction rolled back or set to rollback only?
+	 * <p/>
+	 * This only accounts for actions initiated from this local transaction.
+	 * If, for example, the underlying transaction is forced to rollback via
+	 * some other means, this method still reports false because the rollback
+	 * was not initiated from here.
+	 *
+	 * @return boolean True if the transaction was rolled back via this
+	 * local transaction; false otherwise.
+	 * @throws HibernateException
+	 */
+	public boolean wasRolledBack() throws HibernateException;
+
+	/**
+	 * Check if this transaction was successfully committed.
+	 * <p/>
+	 * This method could return <tt>false</tt> even after successful invocation
+	 * of {@link #commit}.  As an example, JTA based strategies no-op on
+	 * {@link #commit} calls if they did not start the transaction; in that case,
+	 * they also report {@link #wasCommitted} as false.
+	 *
+	 * @return boolean True if the transaction was (unequivocally) committed
+	 * via this local transaction; false otherwise.
+	 * @throws HibernateException
+	 */
+	public boolean wasCommitted() throws HibernateException;
+	
+	/**
+	 * Is this transaction still active?
+	 * <p/>
+	 * Again, this only returns information in relation to the
+	 * local transaction, not the actual underlying transaction.
+	 *
+	 * @return boolean Treu if this local transaction is still active.
+	 */
+	public boolean isActive() throws HibernateException;
+
+	/**
+	 * Register a user synchronization callback for this transaction.
+	 *
+	 * @param synchronization The Synchronization callback to register.
+	 * @throws HibernateException
+	 */
+	public void registerSynchronization(Synchronization synchronization) 
+	throws HibernateException;
+
+	/**
+	 * Set the transaction timeout for any transaction started by
+	 * a subsequent call to <tt>begin()</tt> on this instance.
+	 *
+	 * @param seconds The number of seconds before a timeout.
+	 */
+	public void setTimeout(int seconds);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/TransactionException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: TransactionException.java 10312 2006-08-23 12:43:54Z steve.ebersole at jboss.com $
-package org.hibernate;
-
-/**
- * Indicates that a transaction could not be begun, committed
- * or rolled back.
- *
- * @see Transaction
- * @author Anton van Straaten
- */
-
-public class TransactionException extends HibernateException {
-
-	public TransactionException(String message, Throwable root) {
-		super(message,root);
-	}
-
-	public TransactionException(String message) {
-		super(message);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/TransactionException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransactionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * Indicates that a transaction could not be begun, committed
+ * or rolled back.
+ *
+ * @see Transaction
+ * @author Anton van Straaten
+ */
+
+public class TransactionException extends HibernateException {
+
+	public TransactionException(String message, Throwable root) {
+		super(message,root);
+	}
+
+	public TransactionException(String message) {
+		super(message);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/TransientObjectException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: TransientObjectException.java 6877 2005-05-23 15:00:25Z oneovthafew $
-package org.hibernate;
-
-/**
- * Thrown when the user passes a transient instance to a <tt>Session</tt>
- * method that expects a persistent instance.
- *
- * @author Gavin King
- */
-
-public class TransientObjectException extends HibernateException {
-
-	public TransientObjectException(String s) {
-		super(s);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/TransientObjectException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TransientObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * Thrown when the user passes a transient instance to a <tt>Session</tt>
+ * method that expects a persistent instance.
+ *
+ * @author Gavin King
+ */
+
+public class TransientObjectException extends HibernateException {
+
+	public TransientObjectException(String s) {
+		super(s);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/TypeMismatchException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: $
-package org.hibernate;
-
-/**
- * Used when a user provided type does not match the expected one
- *
- * @author Emmanuel Bernard
- */
-public class TypeMismatchException extends HibernateException {
-	public TypeMismatchException(Throwable root) {
-		super( root );
-	}
-
-	public TypeMismatchException(String s) {
-		super( s );
-	}
-
-	public TypeMismatchException(String string, Throwable root) {
-		super( string, root );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/TypeMismatchException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/TypeMismatchException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+/**
+ * Used when a user provided type does not match the expected one
+ *
+ * @author Emmanuel Bernard
+ */
+public class TypeMismatchException extends HibernateException {
+	public TypeMismatchException(Throwable root) {
+		super( root );
+	}
+
+	public TypeMismatchException(String s) {
+		super( s );
+	}
+
+	public TypeMismatchException(String string, Throwable root) {
+		super( string, root );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/UnresolvableObjectException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-//$Id: UnresolvableObjectException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * Thrown when Hibernate could not resolve an object by id, especially when
- * loading an association.
- *
- * @author Gavin King
- */
-public class UnresolvableObjectException extends HibernateException {
-
-	private final Serializable identifier;
-	private final String entityName;
-
-	public UnresolvableObjectException(Serializable identifier, String clazz) {
-		this("No row with the given identifier exists", identifier, clazz);
-	}
-	UnresolvableObjectException(String message, Serializable identifier, String clazz) {
-		super(message);
-		this.identifier = identifier;
-		this.entityName = clazz;
-	}
-	public Serializable getIdentifier() {
-		return identifier;
-	}
-
-	public String getMessage() {
-		return super.getMessage() + ": " +
-			MessageHelper.infoString(entityName, identifier);
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public static void throwIfNull(Object o, Serializable id, String clazz)
-	throws UnresolvableObjectException {
-		if (o==null) throw new UnresolvableObjectException(id, clazz);
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/UnresolvableObjectException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/UnresolvableObjectException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * Thrown when Hibernate could not resolve an object by id, especially when
+ * loading an association.
+ *
+ * @author Gavin King
+ */
+public class UnresolvableObjectException extends HibernateException {
+
+	private final Serializable identifier;
+	private final String entityName;
+
+	public UnresolvableObjectException(Serializable identifier, String clazz) {
+		this("No row with the given identifier exists", identifier, clazz);
+	}
+	UnresolvableObjectException(String message, Serializable identifier, String clazz) {
+		super(message);
+		this.identifier = identifier;
+		this.entityName = clazz;
+	}
+	public Serializable getIdentifier() {
+		return identifier;
+	}
+
+	public String getMessage() {
+		return super.getMessage() + ": " +
+			MessageHelper.infoString(entityName, identifier);
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public static void throwIfNull(Object o, Serializable id, String clazz)
+	throws UnresolvableObjectException {
+		if (o==null) throw new UnresolvableObjectException(id, clazz);
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/WrongClassException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +0,0 @@
-//$Id: WrongClassException.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate;
-
-import java.io.Serializable;
-
-/**
- * Thrown when <tt>Session.load()</tt> selects a row with
- * the given primary key (identifier value) but the row's
- * discriminator value specifies a subclass that is not
- * assignable to the class requested by the user.
- *
- * @author Gavin King
- */
-public class WrongClassException extends HibernateException {
-
-	private final Serializable identifier;
-	private final String entityName;
-
-	public WrongClassException(String msg, Serializable identifier, String clazz) {
-		super(msg);
-		this.identifier = identifier;
-		this.entityName = clazz;
-	}
-	public Serializable getIdentifier() {
-		return identifier;
-	}
-
-	public String getMessage() {
-		return "Object with id: " +
-			identifier +
-			" was not of the specified subclass: " +
-			entityName +
-			" (" + super.getMessage() + ")" ;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/WrongClassException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/WrongClassException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+
+/**
+ * Thrown when <tt>Session.load()</tt> selects a row with
+ * the given primary key (identifier value) but the row's
+ * discriminator value specifies a subclass that is not
+ * assignable to the class requested by the user.
+ *
+ * @author Gavin King
+ */
+public class WrongClassException extends HibernateException {
+
+	private final Serializable identifier;
+	private final String entityName;
+
+	public WrongClassException(String msg, Serializable identifier, String clazz) {
+		super(msg);
+		this.identifier = identifier;
+		this.entityName = clazz;
+	}
+	public Serializable getIdentifier() {
+		return identifier;
+	}
+
+	public String getMessage() {
+		return "Object with id: " +
+			identifier +
+			" was not of the specified subclass: " +
+			entityName +
+			" (" + super.getMessage() + ")" ;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,146 +0,0 @@
-// $Id: BulkOperationCleanupAction.java 9897 2006-05-05 20:50:27Z max.andersen at jboss.com $
-package org.hibernate.action;
-
-import org.hibernate.HibernateException;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.HashSet;
-import java.util.ArrayList;
-
-/**
- * Implementation of BulkOperationCleanupAction.
- *
- * @author Steve Ebersole
- */
-public class BulkOperationCleanupAction implements Executable, Serializable {
-
-	private final SessionImplementor session;
-
-	private final Set affectedEntityNames = new HashSet();
-	private final Set affectedCollectionRoles = new HashSet();
-	private final Serializable[] spaces;
-
-	public BulkOperationCleanupAction(SessionImplementor session, Queryable[] affectedQueryables) {
-		this.session = session;
-		// TODO : probably better to calculate these and pass them in, as it'll be more performant
-		ArrayList tmpSpaces = new ArrayList();
-		for ( int i = 0; i < affectedQueryables.length; i++ ) {
-			if ( affectedQueryables[i].hasCache() ) {
-				affectedEntityNames.add( affectedQueryables[i].getEntityName() );
-			}
-			Set roles = session.getFactory().getCollectionRolesByEntityParticipant( affectedQueryables[i].getEntityName() );
-			if ( roles != null ) {
-				affectedCollectionRoles.addAll( roles );
-			}
-			for ( int y = 0; y < affectedQueryables[i].getQuerySpaces().length; y++ ) {
-				tmpSpaces.add( affectedQueryables[i].getQuerySpaces()[y] );
-			}
-		}
-		this.spaces = new Serializable[ tmpSpaces.size() ];
-		for ( int i = 0; i < tmpSpaces.size(); i++ ) {
-			this.spaces[i] = ( Serializable ) tmpSpaces.get( i );
-		}
-	}
-	
-	/** Create an action that will evict collection and entity regions based on queryspaces (table names).
-	 *  TODO: cache the autodetected information and pass it in instead.
-	 **/
-	public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) {
-		this.session = session;
-
-		Set tmpSpaces = new HashSet(querySpaces);
-		SessionFactoryImplementor factory = session.getFactory();
-		Iterator iterator = factory.getAllClassMetadata().entrySet().iterator();
-		while ( iterator.hasNext() ) {
-			Map.Entry entry = (Map.Entry) iterator.next();
-			String entityName = (String) entry.getKey();
-			EntityPersister persister = factory.getEntityPersister( entityName );
-			Serializable[] entitySpaces = persister.getQuerySpaces();
-
-			if (affectedEntity( querySpaces, entitySpaces )) {
-				if ( persister.hasCache() ) {
-					affectedEntityNames.add( persister.getEntityName() );
-				}
-				Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() );
-				if ( roles != null ) {
-					affectedCollectionRoles.addAll( roles );
-				}
-				for ( int y = 0; y < entitySpaces.length; y++ ) {
-					tmpSpaces.add( entitySpaces[y] );
-				}
-			}
-
-		}
-		this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] );		
-	}
-
-
-	/** returns true if no queryspaces or if there are a match */
-	private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces) {
-		if(querySpaces==null || querySpaces.isEmpty()) {
-			return true;
-		}
-		
-		for ( int i = 0; i < entitySpaces.length; i++ ) {
-			if ( querySpaces.contains( entitySpaces[i] ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public void init() {
-		evictEntityRegions();
-		evictCollectionRegions();
-	}
-
-	public boolean hasAfterTransactionCompletion() {
-		return true;
-	}
-
-	public void afterTransactionCompletion(boolean success) throws HibernateException {
-		evictEntityRegions();
-		evictCollectionRegions();
-	}
-
-	public Serializable[] getPropertySpaces() {
-		return spaces;
-	}
-
-	public void beforeExecutions() throws HibernateException {
-		// nothing to do
-	}
-
-	public void execute() throws HibernateException {
-		// nothing to do		
-	}
-
-	private void evictEntityRegions() {
-		if ( affectedEntityNames != null ) {
-			Iterator itr = affectedEntityNames.iterator();
-			while ( itr.hasNext() ) {
-				final String entityName = ( String ) itr.next();
-				session.getFactory().evictEntity( entityName );
-			}
-		}
-	}
-
-	private void evictCollectionRegions() {
-		if ( affectedCollectionRoles != null ) {
-			Iterator itr = affectedCollectionRoles.iterator();
-			while ( itr.hasNext() ) {
-				final String roleName = ( String ) itr.next();
-				session.getFactory().evictCollection( roleName );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/BulkOperationCleanupAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,167 @@
+/*
+ * 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.action;
+
+import org.hibernate.HibernateException;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.ArrayList;
+
+/**
+ * Implementation of BulkOperationCleanupAction.
+ *
+ * @author Steve Ebersole
+ */
+public class BulkOperationCleanupAction implements Executable, Serializable {
+
+	private final SessionImplementor session;
+
+	private final Set affectedEntityNames = new HashSet();
+	private final Set affectedCollectionRoles = new HashSet();
+	private final Serializable[] spaces;
+
+	public BulkOperationCleanupAction(SessionImplementor session, Queryable[] affectedQueryables) {
+		this.session = session;
+		// TODO : probably better to calculate these and pass them in, as it'll be more performant
+		ArrayList tmpSpaces = new ArrayList();
+		for ( int i = 0; i < affectedQueryables.length; i++ ) {
+			if ( affectedQueryables[i].hasCache() ) {
+				affectedEntityNames.add( affectedQueryables[i].getEntityName() );
+			}
+			Set roles = session.getFactory().getCollectionRolesByEntityParticipant( affectedQueryables[i].getEntityName() );
+			if ( roles != null ) {
+				affectedCollectionRoles.addAll( roles );
+			}
+			for ( int y = 0; y < affectedQueryables[i].getQuerySpaces().length; y++ ) {
+				tmpSpaces.add( affectedQueryables[i].getQuerySpaces()[y] );
+			}
+		}
+		this.spaces = new Serializable[ tmpSpaces.size() ];
+		for ( int i = 0; i < tmpSpaces.size(); i++ ) {
+			this.spaces[i] = ( Serializable ) tmpSpaces.get( i );
+		}
+	}
+	
+	/** Create an action that will evict collection and entity regions based on queryspaces (table names).
+	 *  TODO: cache the autodetected information and pass it in instead.
+	 **/
+	public BulkOperationCleanupAction(SessionImplementor session, Set querySpaces) {
+		this.session = session;
+
+		Set tmpSpaces = new HashSet(querySpaces);
+		SessionFactoryImplementor factory = session.getFactory();
+		Iterator iterator = factory.getAllClassMetadata().entrySet().iterator();
+		while ( iterator.hasNext() ) {
+			Map.Entry entry = (Map.Entry) iterator.next();
+			String entityName = (String) entry.getKey();
+			EntityPersister persister = factory.getEntityPersister( entityName );
+			Serializable[] entitySpaces = persister.getQuerySpaces();
+
+			if (affectedEntity( querySpaces, entitySpaces )) {
+				if ( persister.hasCache() ) {
+					affectedEntityNames.add( persister.getEntityName() );
+				}
+				Set roles = session.getFactory().getCollectionRolesByEntityParticipant( persister.getEntityName() );
+				if ( roles != null ) {
+					affectedCollectionRoles.addAll( roles );
+				}
+				for ( int y = 0; y < entitySpaces.length; y++ ) {
+					tmpSpaces.add( entitySpaces[y] );
+				}
+			}
+
+		}
+		this.spaces = (Serializable[]) tmpSpaces.toArray( new Serializable[tmpSpaces.size()] );		
+	}
+
+
+	/** returns true if no queryspaces or if there are a match */
+	private boolean affectedEntity(Set querySpaces, Serializable[] entitySpaces) {
+		if(querySpaces==null || querySpaces.isEmpty()) {
+			return true;
+		}
+		
+		for ( int i = 0; i < entitySpaces.length; i++ ) {
+			if ( querySpaces.contains( entitySpaces[i] ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public void init() {
+		evictEntityRegions();
+		evictCollectionRegions();
+	}
+
+	public boolean hasAfterTransactionCompletion() {
+		return true;
+	}
+
+	public void afterTransactionCompletion(boolean success) throws HibernateException {
+		evictEntityRegions();
+		evictCollectionRegions();
+	}
+
+	public Serializable[] getPropertySpaces() {
+		return spaces;
+	}
+
+	public void beforeExecutions() throws HibernateException {
+		// nothing to do
+	}
+
+	public void execute() throws HibernateException {
+		// nothing to do		
+	}
+
+	private void evictEntityRegions() {
+		if ( affectedEntityNames != null ) {
+			Iterator itr = affectedEntityNames.iterator();
+			while ( itr.hasNext() ) {
+				final String entityName = ( String ) itr.next();
+				session.getFactory().evictEntity( entityName );
+			}
+		}
+	}
+
+	private void evictCollectionRegions() {
+		if ( affectedCollectionRoles != null ) {
+			Iterator itr = affectedCollectionRoles.iterator();
+			while ( itr.hasNext() ) {
+				final String roleName = ( String ) itr.next();
+				session.getFactory().evictCollection( roleName );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/CollectionAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,150 +0,0 @@
-//$Id: CollectionAction.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.action;
-
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.util.StringHelper;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-
-/**
- * Any action relating to insert/update/delete of a collection
- * @author Gavin King
- */
-public abstract class CollectionAction implements Executable, Serializable, Comparable {
-
-	private transient CollectionPersister persister;
-	private final Serializable key;
-	private Serializable finalKey;
-	private final SessionImplementor session;
-	private SoftLock lock;
-	private final String collectionRole;
-	private final PersistentCollection collection;
-
-	public CollectionAction(
-			final CollectionPersister persister, 
-			final PersistentCollection collection, 
-			final Serializable key, 
-			final SessionImplementor session) throws CacheException {
-		this.persister = persister;
-		this.session = session;
-		this.key = key;
-		this.collectionRole = persister.getRole();
-		this.collection = collection;
-	}
-	
-	protected PersistentCollection getCollection() {
-		return collection;
-	}
-
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		persister = session.getFactory().getCollectionPersister( collectionRole );
-	}
-
-	public void afterTransactionCompletion(boolean success) throws CacheException {
-		if ( persister.hasCache() ) {
-			final CacheKey ck = new CacheKey( 
-					key, 
-					persister.getKeyType(), 
-					persister.getRole(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-				);
-			persister.getCacheAccessStrategy().unlockItem( ck, lock );
-		}
-	}
-
-	public boolean hasAfterTransactionCompletion() {
-		return persister.hasCache();
-	}
-
-	public Serializable[] getPropertySpaces() {
-		return persister.getCollectionSpaces();
-	}
-
-	protected final CollectionPersister getPersister() {
-		return persister;
-	}
-
-	protected final Serializable getKey() {
-		finalKey = key;
-		if ( key instanceof DelayedPostInsertIdentifier ) {
-			// need to look it up from the persistence-context
-			finalKey = session.getPersistenceContext().getEntry( collection.getOwner() ).getId();
-			if ( finalKey == key ) {
-				// we may be screwed here since the collection action is about to execute
-				// and we do not know the final owner key value
-			}
-		}
-		return finalKey;
-	}
-
-	protected final SessionImplementor getSession() {
-		return session;
-	}
-
-	public final void beforeExecutions() throws CacheException {
-		// we need to obtain the lock before any actions are
-		// executed, since this may be an inverse="true"
-		// bidirectional association and it is one of the
-		// earlier entity actions which actually updates
-		// the database (this action is resposible for
-		// second-level cache invalidation only)
-		if ( persister.hasCache() ) {
-			final CacheKey ck = new CacheKey( 
-					key, 
-					persister.getKeyType(), 
-					persister.getRole(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-			);
-			lock = persister.getCacheAccessStrategy().lockItem( ck, null );
-		}
-	}
-
-	protected final void evict() throws CacheException {
-		if ( persister.hasCache() ) {
-			CacheKey ck = new CacheKey( 
-					key, 
-					persister.getKeyType(), 
-					persister.getRole(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-				);
-			persister.getCacheAccessStrategy().remove( ck );
-		}
-	}
-
-	public String toString() {
-		return StringHelper.unqualify( getClass().getName() ) + 
-				MessageHelper.infoString( collectionRole, key );
-	}
-
-	public int compareTo(Object other) {
-		CollectionAction action = ( CollectionAction ) other;
-		//sort first by role name
-		int roleComparison = collectionRole.compareTo( action.collectionRole );
-		if ( roleComparison != 0 ) {
-			return roleComparison;
-		}
-		else {
-			//then by fk
-			return persister.getKeyType()
-					.compare( key, action.key, session.getEntityMode() );
-		}
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/CollectionAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,173 @@
+/*
+ * 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.action;
+
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.util.StringHelper;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * Any action relating to insert/update/delete of a collection
+ * @author Gavin King
+ */
+public abstract class CollectionAction implements Executable, Serializable, Comparable {
+
+	private transient CollectionPersister persister;
+	private final Serializable key;
+	private Serializable finalKey;
+	private final SessionImplementor session;
+	private SoftLock lock;
+	private final String collectionRole;
+	private final PersistentCollection collection;
+
+	public CollectionAction(
+			final CollectionPersister persister, 
+			final PersistentCollection collection, 
+			final Serializable key, 
+			final SessionImplementor session) throws CacheException {
+		this.persister = persister;
+		this.session = session;
+		this.key = key;
+		this.collectionRole = persister.getRole();
+		this.collection = collection;
+	}
+	
+	protected PersistentCollection getCollection() {
+		return collection;
+	}
+
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		persister = session.getFactory().getCollectionPersister( collectionRole );
+	}
+
+	public void afterTransactionCompletion(boolean success) throws CacheException {
+		if ( persister.hasCache() ) {
+			final CacheKey ck = new CacheKey( 
+					key, 
+					persister.getKeyType(), 
+					persister.getRole(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+				);
+			persister.getCacheAccessStrategy().unlockItem( ck, lock );
+		}
+	}
+
+	public boolean hasAfterTransactionCompletion() {
+		return persister.hasCache();
+	}
+
+	public Serializable[] getPropertySpaces() {
+		return persister.getCollectionSpaces();
+	}
+
+	protected final CollectionPersister getPersister() {
+		return persister;
+	}
+
+	protected final Serializable getKey() {
+		finalKey = key;
+		if ( key instanceof DelayedPostInsertIdentifier ) {
+			// need to look it up from the persistence-context
+			finalKey = session.getPersistenceContext().getEntry( collection.getOwner() ).getId();
+			if ( finalKey == key ) {
+				// we may be screwed here since the collection action is about to execute
+				// and we do not know the final owner key value
+			}
+		}
+		return finalKey;
+	}
+
+	protected final SessionImplementor getSession() {
+		return session;
+	}
+
+	public final void beforeExecutions() throws CacheException {
+		// we need to obtain the lock before any actions are
+		// executed, since this may be an inverse="true"
+		// bidirectional association and it is one of the
+		// earlier entity actions which actually updates
+		// the database (this action is resposible for
+		// second-level cache invalidation only)
+		if ( persister.hasCache() ) {
+			final CacheKey ck = new CacheKey( 
+					key, 
+					persister.getKeyType(), 
+					persister.getRole(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+			);
+			lock = persister.getCacheAccessStrategy().lockItem( ck, null );
+		}
+	}
+
+	protected final void evict() throws CacheException {
+		if ( persister.hasCache() ) {
+			CacheKey ck = new CacheKey( 
+					key, 
+					persister.getKeyType(), 
+					persister.getRole(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+				);
+			persister.getCacheAccessStrategy().remove( ck );
+		}
+	}
+
+	public String toString() {
+		return StringHelper.unqualify( getClass().getName() ) + 
+				MessageHelper.infoString( collectionRole, key );
+	}
+
+	public int compareTo(Object other) {
+		CollectionAction action = ( CollectionAction ) other;
+		//sort first by role name
+		int roleComparison = collectionRole.compareTo( action.collectionRole );
+		if ( roleComparison != 0 ) {
+			return roleComparison;
+		}
+		else {
+			//then by fk
+			return persister.getKeyType()
+					.compare( key, action.key, session.getEntityMode() );
+		}
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-//$Id: CollectionRecreateAction.java 7147 2005-06-15 13:20:13Z oneovthafew $
-package org.hibernate.action;
-
-import org.hibernate.HibernateException;
-import org.hibernate.event.PostCollectionRecreateEventListener;
-import org.hibernate.event.PostCollectionRecreateEvent;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PreCollectionRecreateEvent;
-import org.hibernate.event.PreCollectionRecreateEventListener;
-import org.hibernate.cache.CacheException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-import java.io.Serializable;
-
-public final class CollectionRecreateAction extends CollectionAction {
-
-	public CollectionRecreateAction(
-				final PersistentCollection collection, 
-				final CollectionPersister persister, 
-				final Serializable id, 
-				final SessionImplementor session)
-			throws CacheException {
-		super( persister, collection, id, session );
-	}
-
-	public void execute() throws HibernateException {
-		// this method is called when a new non-null collection is persisted
-		// or when an existing (non-null) collection is moved to a new owner
-		final PersistentCollection collection = getCollection();
-		
-		preRecreate();
-
-		getPersister().recreate( collection, getKey(), getSession() );
-		
-		getSession().getPersistenceContext()
-				.getCollectionEntry(collection)
-				.afterAction(collection);
-		
-		evict();
-
-		postRecreate();
-
-		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
-			getSession().getFactory().getStatisticsImplementor()
-					.recreateCollection( getPersister().getRole() );
-		}
-	}
-
-	private void preRecreate() {
-		PreCollectionRecreateEventListener[] preListeners = getSession().getListeners()
-				.getPreCollectionRecreateEventListeners();
-		if (preListeners.length > 0) {
-			PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession() );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				preListeners[i].onPreRecreateCollection( preEvent );
-			}
-		}
-	}
-
-	private void postRecreate() {
-		PostCollectionRecreateEventListener[] postListeners = getSession().getListeners()
-				.getPostCollectionRecreateEventListeners();
-		if (postListeners.length > 0) {
-			PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession() );
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostRecreateCollection( postEvent );
-			}
-		}
-	}
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRecreateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.action;
+
+import org.hibernate.HibernateException;
+import org.hibernate.event.PostCollectionRecreateEventListener;
+import org.hibernate.event.PostCollectionRecreateEvent;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PreCollectionRecreateEvent;
+import org.hibernate.event.PreCollectionRecreateEventListener;
+import org.hibernate.cache.CacheException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+import java.io.Serializable;
+
+public final class CollectionRecreateAction extends CollectionAction {
+
+	public CollectionRecreateAction(
+				final PersistentCollection collection, 
+				final CollectionPersister persister, 
+				final Serializable id, 
+				final SessionImplementor session)
+			throws CacheException {
+		super( persister, collection, id, session );
+	}
+
+	public void execute() throws HibernateException {
+		// this method is called when a new non-null collection is persisted
+		// or when an existing (non-null) collection is moved to a new owner
+		final PersistentCollection collection = getCollection();
+		
+		preRecreate();
+
+		getPersister().recreate( collection, getKey(), getSession() );
+		
+		getSession().getPersistenceContext()
+				.getCollectionEntry(collection)
+				.afterAction(collection);
+		
+		evict();
+
+		postRecreate();
+
+		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
+			getSession().getFactory().getStatisticsImplementor()
+					.recreateCollection( getPersister().getRole() );
+		}
+	}
+
+	private void preRecreate() {
+		PreCollectionRecreateEventListener[] preListeners = getSession().getListeners()
+				.getPreCollectionRecreateEventListeners();
+		if (preListeners.length > 0) {
+			PreCollectionRecreateEvent preEvent = new PreCollectionRecreateEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession() );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				preListeners[i].onPreRecreateCollection( preEvent );
+			}
+		}
+	}
+
+	private void postRecreate() {
+		PostCollectionRecreateEventListener[] postListeners = getSession().getListeners()
+				.getPostCollectionRecreateEventListeners();
+		if (postListeners.length > 0) {
+			PostCollectionRecreateEvent postEvent = new PostCollectionRecreateEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession() );
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostRecreateCollection( postEvent );
+			}
+		}
+	}
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,127 +0,0 @@
-//$Id: CollectionRemoveAction.java 7147 2005-06-15 13:20:13Z oneovthafew $
-package org.hibernate.action;
-
-import org.hibernate.HibernateException;
-import org.hibernate.AssertionFailure;
-import org.hibernate.event.PostCollectionRemoveEvent;
-import org.hibernate.event.PreCollectionRemoveEvent;
-import org.hibernate.event.PreCollectionRemoveEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PostCollectionRemoveEventListener;
-import org.hibernate.cache.CacheException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-import java.io.Serializable;
-
-public final class CollectionRemoveAction extends CollectionAction {
-
-	private boolean emptySnapshot;
-	private final Object affectedOwner;
-	
-	/**
-	 * Removes a persistent collection from its loaded owner.
-	 *
-	 * Use this constructor when the collection is non-null.
-	 *
-	 * @param collection The collection to to remove; must be non-null
-	 * @param persister  The collection's persister
-	 * @param id The collection key
-	 * @param emptySnapshot Indicates if the snapshot is empty
-	 * @param session The session
-	 * @throws AssertionFailure if collection is null.
-	 */
-	public CollectionRemoveAction(
-				final PersistentCollection collection,
-				final CollectionPersister persister,
-				final Serializable id,
-				final boolean emptySnapshot,
-				final SessionImplementor session)
-			throws CacheException {
-		super( persister, collection, id, session );
-		if (collection == null) { throw new AssertionFailure("collection == null"); }
-		this.emptySnapshot = emptySnapshot;
-		// the loaded owner will be set to null after the collection is removed,
-		// so capture its value as the affected owner so it is accessible to
-		// both pre- and post- events
-		this.affectedOwner = session.getPersistenceContext().getLoadedCollectionOwnerOrNull( collection );
-	}
-
-	/**
-	 * Removes a persistent collection from a specified owner.
-	 *
-	 * Use this constructor when the collection to be removed has not been loaded.
-	 *
-	 * @param affectedOwner The collection's owner; must be non-null
-	 * @param persister  The collection's persister
-	 * @param id The collection key
-	 * @param emptySnapshot Indicates if the snapshot is empty
-	 * @param session The session
-	 * @throws AssertionFailure if affectedOwner is null.
-	 */
-	public CollectionRemoveAction(
-				final Object affectedOwner,
-				final CollectionPersister persister,
-				final Serializable id,
-				final boolean emptySnapshot,
-				final SessionImplementor session)
-			throws CacheException {
-		super( persister, null, id, session );
-		if (affectedOwner == null) { throw new AssertionFailure("affectedOwner == null"); }
-		this.emptySnapshot = emptySnapshot;
-		this.affectedOwner = affectedOwner;
-	}
-	
-	public void execute() throws HibernateException {
-		preRemove();
-
-		if ( !emptySnapshot ) {
-			// an existing collection that was either non-empty or uninitialized
-			// is replaced by null or a different collection
-			// (if the collection is uninitialized, hibernate has no way of
-			// knowing if the collection is actually empty without querying the db)
-			getPersister().remove( getKey(), getSession() );
-		}
-		
-		final PersistentCollection collection = getCollection();
-		if (collection!=null) {
-			getSession().getPersistenceContext()
-				.getCollectionEntry(collection)
-				.afterAction(collection);
-		}
-		
-		evict();
-
-		postRemove();		
-
-		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
-			getSession().getFactory().getStatisticsImplementor()
-					.removeCollection( getPersister().getRole() );
-		}
-	}
-
-	private void preRemove() {
-		PreCollectionRemoveEventListener[] preListeners = getSession().getListeners()
-				.getPreCollectionRemoveEventListeners();
-		if (preListeners.length>0) {
-			PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				preListeners[i].onPreRemoveCollection(preEvent);
-			}
-		}
-	}
-
-	private void postRemove() {
-		PostCollectionRemoveEventListener[] postListeners = getSession().getListeners()
-				.getPostCollectionRemoveEventListeners();
-		if (postListeners.length>0) {
-			PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostRemoveCollection(postEvent);
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionRemoveAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,150 @@
+/*
+ * 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.action;
+
+import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.event.PostCollectionRemoveEvent;
+import org.hibernate.event.PreCollectionRemoveEvent;
+import org.hibernate.event.PreCollectionRemoveEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PostCollectionRemoveEventListener;
+import org.hibernate.cache.CacheException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+import java.io.Serializable;
+
+public final class CollectionRemoveAction extends CollectionAction {
+
+	private boolean emptySnapshot;
+	private final Object affectedOwner;
+	
+	/**
+	 * Removes a persistent collection from its loaded owner.
+	 *
+	 * Use this constructor when the collection is non-null.
+	 *
+	 * @param collection The collection to to remove; must be non-null
+	 * @param persister  The collection's persister
+	 * @param id The collection key
+	 * @param emptySnapshot Indicates if the snapshot is empty
+	 * @param session The session
+	 * @throws AssertionFailure if collection is null.
+	 */
+	public CollectionRemoveAction(
+				final PersistentCollection collection,
+				final CollectionPersister persister,
+				final Serializable id,
+				final boolean emptySnapshot,
+				final SessionImplementor session)
+			throws CacheException {
+		super( persister, collection, id, session );
+		if (collection == null) { throw new AssertionFailure("collection == null"); }
+		this.emptySnapshot = emptySnapshot;
+		// the loaded owner will be set to null after the collection is removed,
+		// so capture its value as the affected owner so it is accessible to
+		// both pre- and post- events
+		this.affectedOwner = session.getPersistenceContext().getLoadedCollectionOwnerOrNull( collection );
+	}
+
+	/**
+	 * Removes a persistent collection from a specified owner.
+	 *
+	 * Use this constructor when the collection to be removed has not been loaded.
+	 *
+	 * @param affectedOwner The collection's owner; must be non-null
+	 * @param persister  The collection's persister
+	 * @param id The collection key
+	 * @param emptySnapshot Indicates if the snapshot is empty
+	 * @param session The session
+	 * @throws AssertionFailure if affectedOwner is null.
+	 */
+	public CollectionRemoveAction(
+				final Object affectedOwner,
+				final CollectionPersister persister,
+				final Serializable id,
+				final boolean emptySnapshot,
+				final SessionImplementor session)
+			throws CacheException {
+		super( persister, null, id, session );
+		if (affectedOwner == null) { throw new AssertionFailure("affectedOwner == null"); }
+		this.emptySnapshot = emptySnapshot;
+		this.affectedOwner = affectedOwner;
+	}
+	
+	public void execute() throws HibernateException {
+		preRemove();
+
+		if ( !emptySnapshot ) {
+			// an existing collection that was either non-empty or uninitialized
+			// is replaced by null or a different collection
+			// (if the collection is uninitialized, hibernate has no way of
+			// knowing if the collection is actually empty without querying the db)
+			getPersister().remove( getKey(), getSession() );
+		}
+		
+		final PersistentCollection collection = getCollection();
+		if (collection!=null) {
+			getSession().getPersistenceContext()
+				.getCollectionEntry(collection)
+				.afterAction(collection);
+		}
+		
+		evict();
+
+		postRemove();		
+
+		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
+			getSession().getFactory().getStatisticsImplementor()
+					.removeCollection( getPersister().getRole() );
+		}
+	}
+
+	private void preRemove() {
+		PreCollectionRemoveEventListener[] preListeners = getSession().getListeners()
+				.getPreCollectionRemoveEventListeners();
+		if (preListeners.length>0) {
+			PreCollectionRemoveEvent preEvent = new PreCollectionRemoveEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				preListeners[i].onPreRemoveCollection(preEvent);
+			}
+		}
+	}
+
+	private void postRemove() {
+		PostCollectionRemoveEventListener[] postListeners = getSession().getListeners()
+				.getPostCollectionRemoveEventListeners();
+		if (postListeners.length>0) {
+			PostCollectionRemoveEvent postEvent = new PostCollectionRemoveEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession(), affectedOwner );
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostRemoveCollection(postEvent);
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,110 +0,0 @@
-//$Id: CollectionUpdateAction.java 7631 2005-07-24 21:26:21Z oneovthafew $
-package org.hibernate.action;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.event.PostCollectionUpdateEvent;
-import org.hibernate.event.PreCollectionUpdateEvent;
-import org.hibernate.event.PreCollectionUpdateEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PostCollectionUpdateEventListener;
-import org.hibernate.cache.CacheException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-
-import java.io.Serializable;
-
-public final class CollectionUpdateAction extends CollectionAction {
-
-	private final boolean emptySnapshot;
-
-	public CollectionUpdateAction(
-				final PersistentCollection collection,
-				final CollectionPersister persister,
-				final Serializable id,
-				final boolean emptySnapshot,
-				final SessionImplementor session)
-			throws CacheException {
-		super( persister, collection, id, session );
-		this.emptySnapshot = emptySnapshot;
-	}
-
-	public void execute() throws HibernateException {
-		final Serializable id = getKey();
-		final SessionImplementor session = getSession();
-		final CollectionPersister persister = getPersister();
-		final PersistentCollection collection = getCollection();
-		boolean affectedByFilters = persister.isAffectedByEnabledFilters(session);
-
-		preUpdate();
-
-		if ( !collection.wasInitialized() ) {
-			if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" );
-			//do nothing - we only need to notify the cache...
-		}
-		else if ( !affectedByFilters && collection.empty() ) {
-			if ( !emptySnapshot ) persister.remove( id, session );
-		}
-		else if ( collection.needsRecreate(persister) ) {
-			if (affectedByFilters) {
-				throw new HibernateException(
-					"cannot recreate collection while filter is enabled: " + 
-					MessageHelper.collectionInfoString( persister, id, persister.getFactory() )
-				);
-			}
-			if ( !emptySnapshot ) persister.remove( id, session );
-			persister.recreate( collection, id, session );
-		}
-		else {
-			persister.deleteRows( collection, id, session );
-			persister.updateRows( collection, id, session );
-			persister.insertRows( collection, id, session );
-		}
-
-		getSession().getPersistenceContext()
-			.getCollectionEntry(collection)
-			.afterAction(collection);
-
-		evict();
-
-		postUpdate();
-
-		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
-			getSession().getFactory().getStatisticsImplementor().
-					updateCollection( getPersister().getRole() );
-		}
-	}
-	
-	private void preUpdate() {
-		PreCollectionUpdateEventListener[] preListeners = getSession().getListeners()
-				.getPreCollectionUpdateEventListeners();
-		if (preListeners.length > 0) {
-			PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession() );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				preListeners[i].onPreUpdateCollection( preEvent );
-			}
-		}
-	}
-
-	private void postUpdate() {
-		PostCollectionUpdateEventListener[] postListeners = getSession().getListeners()
-				.getPostCollectionUpdateEventListeners();
-		if (postListeners.length > 0) {
-			PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(
-					getPersister(), getCollection(), ( EventSource ) getSession() );
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostUpdateCollection( postEvent );
-			}
-		}
-	}
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/CollectionUpdateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,133 @@
+/*
+ * 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.action;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.event.PostCollectionUpdateEvent;
+import org.hibernate.event.PreCollectionUpdateEvent;
+import org.hibernate.event.PreCollectionUpdateEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PostCollectionUpdateEventListener;
+import org.hibernate.cache.CacheException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+
+import java.io.Serializable;
+
+public final class CollectionUpdateAction extends CollectionAction {
+
+	private final boolean emptySnapshot;
+
+	public CollectionUpdateAction(
+				final PersistentCollection collection,
+				final CollectionPersister persister,
+				final Serializable id,
+				final boolean emptySnapshot,
+				final SessionImplementor session)
+			throws CacheException {
+		super( persister, collection, id, session );
+		this.emptySnapshot = emptySnapshot;
+	}
+
+	public void execute() throws HibernateException {
+		final Serializable id = getKey();
+		final SessionImplementor session = getSession();
+		final CollectionPersister persister = getPersister();
+		final PersistentCollection collection = getCollection();
+		boolean affectedByFilters = persister.isAffectedByEnabledFilters(session);
+
+		preUpdate();
+
+		if ( !collection.wasInitialized() ) {
+			if ( !collection.hasQueuedOperations() ) throw new AssertionFailure( "no queued adds" );
+			//do nothing - we only need to notify the cache...
+		}
+		else if ( !affectedByFilters && collection.empty() ) {
+			if ( !emptySnapshot ) persister.remove( id, session );
+		}
+		else if ( collection.needsRecreate(persister) ) {
+			if (affectedByFilters) {
+				throw new HibernateException(
+					"cannot recreate collection while filter is enabled: " + 
+					MessageHelper.collectionInfoString( persister, id, persister.getFactory() )
+				);
+			}
+			if ( !emptySnapshot ) persister.remove( id, session );
+			persister.recreate( collection, id, session );
+		}
+		else {
+			persister.deleteRows( collection, id, session );
+			persister.updateRows( collection, id, session );
+			persister.insertRows( collection, id, session );
+		}
+
+		getSession().getPersistenceContext()
+			.getCollectionEntry(collection)
+			.afterAction(collection);
+
+		evict();
+
+		postUpdate();
+
+		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
+			getSession().getFactory().getStatisticsImplementor().
+					updateCollection( getPersister().getRole() );
+		}
+	}
+	
+	private void preUpdate() {
+		PreCollectionUpdateEventListener[] preListeners = getSession().getListeners()
+				.getPreCollectionUpdateEventListeners();
+		if (preListeners.length > 0) {
+			PreCollectionUpdateEvent preEvent = new PreCollectionUpdateEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession() );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				preListeners[i].onPreUpdateCollection( preEvent );
+			}
+		}
+	}
+
+	private void postUpdate() {
+		PostCollectionUpdateEventListener[] postListeners = getSession().getListeners()
+				.getPostCollectionUpdateEventListeners();
+		if (postListeners.length > 0) {
+			PostCollectionUpdateEvent postEvent = new PostCollectionUpdateEvent(
+					getPersister(), getCollection(), ( EventSource ) getSession() );
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostUpdateCollection( postEvent );
+			}
+		}
+	}
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-package org.hibernate.action;
-
-import java.io.Serializable;
-
-/**
- * Acts as a stand-in for an entity identifier which is supposed to be
- * generated on insert (like an IDENTITY column) where the insert needed to
- * be delayed because we were outside a transaction when the persist
- * occurred (save currently still performs the insert).
- * <p/>
- * The stand-in is only used within the {@link org.hibernate.engine.PersistenceContext}
- * in order to distinguish one instance from another; it is never injected into
- * the entity instance or returned to the client...
- *
- * @author Steve Ebersole
- */
-public class DelayedPostInsertIdentifier implements Serializable {
-	private static long SEQUENCE = 0;
-	private final long sequence;
-
-	public DelayedPostInsertIdentifier() {
-		synchronized( DelayedPostInsertIdentifier.class ) {
-			if ( SEQUENCE == Long.MAX_VALUE ) {
-				SEQUENCE = 0;
-			}
-			this.sequence = SEQUENCE++;
-		}
-	}
-
-	public boolean equals(Object o) {
-		if ( this == o ) {
-			return true;
-		}
-		if ( o == null || getClass() != o.getClass() ) {
-			return false;
-		}
-		final DelayedPostInsertIdentifier that = ( DelayedPostInsertIdentifier ) o;
-		return sequence == that.sequence;
-	}
-
-	public int hashCode() {
-		return ( int ) ( sequence ^ ( sequence >>> 32 ) );
-	}
-
-	public String toString() {
-		return "<delayed:" + sequence + ">";
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/DelayedPostInsertIdentifier.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+/**
+ * Acts as a stand-in for an entity identifier which is supposed to be
+ * generated on insert (like an IDENTITY column) where the insert needed to
+ * be delayed because we were outside a transaction when the persist
+ * occurred (save currently still performs the insert).
+ * <p/>
+ * The stand-in is only used within the {@link org.hibernate.engine.PersistenceContext}
+ * in order to distinguish one instance from another; it is never injected into
+ * the entity instance or returned to the client...
+ *
+ * @author Steve Ebersole
+ */
+public class DelayedPostInsertIdentifier implements Serializable {
+	private static long SEQUENCE = 0;
+	private final long sequence;
+
+	public DelayedPostInsertIdentifier() {
+		synchronized( DelayedPostInsertIdentifier.class ) {
+			if ( SEQUENCE == Long.MAX_VALUE ) {
+				SEQUENCE = 0;
+			}
+			this.sequence = SEQUENCE++;
+		}
+	}
+
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+		final DelayedPostInsertIdentifier that = ( DelayedPostInsertIdentifier ) o;
+		return sequence == that.sequence;
+	}
+
+	public int hashCode() {
+		return ( int ) ( sequence ^ ( sequence >>> 32 ) );
+	}
+
+	public String toString() {
+		return "<delayed:" + sequence + ">";
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/EntityAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,136 +0,0 @@
-//$Id: EntityAction.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.action;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.util.StringHelper;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-
-/**
- * Base class for actions relating to insert/update/delete of an entity
- * instance.
- *
- * @author Gavin King
- */
-public abstract class EntityAction implements Executable, Serializable, Comparable {
-
-	private final String entityName;
-	private final Serializable id;
-	private final Object instance;
-	private final SessionImplementor session;
-
-	private transient EntityPersister persister;
-
-	/**
-	 * Instantiate an action.
-	 *
-	 * @param session The session from which this action is coming.
-	 * @param id The id of the entity
-	 * @param instance The entiyt instance
-	 * @param persister The entity persister
-	 */
-	protected EntityAction(SessionImplementor session, Serializable id, Object instance, EntityPersister persister) {
-		this.entityName = persister.getEntityName();
-		this.id = id;
-		this.instance = instance;
-		this.session = session;
-		this.persister = persister;
-	}
-
-	protected abstract boolean hasPostCommitEventListeners();
-
-	/**
-	 * entity name accessor
-	 *
-	 * @return The entity name
-	 */
-	public String getEntityName() {
-		return entityName;
-	}
-
-	/**
-	 * entity id accessor
-	 *
-	 * @return The entity id
-	 */
-	public final Serializable getId() {
-		if ( id instanceof DelayedPostInsertIdentifier ) {
-			return session.getPersistenceContext().getEntry( instance ).getId();
-		}
-		return id;
-	}
-
-	/**
-	 * entity instance accessor
-	 *
-	 * @return The entity instance
-	 */
-	public final Object getInstance() {
-		return instance;
-	}
-
-	/**
-	 * originating session accessor
-	 *
-	 * @return The session from which this action originated.
-	 */
-	public final SessionImplementor getSession() {
-		return session;
-	}
-
-	/**
-	 * entity persister accessor
-	 *
-	 * @return The entity persister
-	 */
-	public final EntityPersister getPersister() {
-		return persister;
-	}
-
-	public final Serializable[] getPropertySpaces() {
-		return persister.getPropertySpaces();
-	}
-
-	public void beforeExecutions() {
-		throw new AssertionFailure( "beforeExecutions() called for non-collection action" );
-	}
-
-	public boolean hasAfterTransactionCompletion() {
-		return persister.hasCache() || hasPostCommitEventListeners();
-	}
-
-	public String toString() {
-		return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( entityName, id );
-	}
-
-	public int compareTo(Object other) {
-		EntityAction action = ( EntityAction ) other;
-		//sort first by entity name
-		int roleComparison = entityName.compareTo( action.entityName );
-		if ( roleComparison != 0 ) {
-			return roleComparison;
-		}
-		else {
-			//then by id
-			return persister.getIdentifierType().compare( id, action.id, session.getEntityMode() );
-		}
-	}
-
-	/**
-	 * Serialization...
-	 *
-	 * @param ois Thed object stream
-	 * @throws IOException Problem performing the default stream reading
-	 * @throws ClassNotFoundException Problem performing the default stream reading
-	 */
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		persister = session.getFactory().getEntityPersister( entityName );
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/EntityAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,159 @@
+/*
+ * 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.action;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.util.StringHelper;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+
+/**
+ * Base class for actions relating to insert/update/delete of an entity
+ * instance.
+ *
+ * @author Gavin King
+ */
+public abstract class EntityAction implements Executable, Serializable, Comparable {
+
+	private final String entityName;
+	private final Serializable id;
+	private final Object instance;
+	private final SessionImplementor session;
+
+	private transient EntityPersister persister;
+
+	/**
+	 * Instantiate an action.
+	 *
+	 * @param session The session from which this action is coming.
+	 * @param id The id of the entity
+	 * @param instance The entiyt instance
+	 * @param persister The entity persister
+	 */
+	protected EntityAction(SessionImplementor session, Serializable id, Object instance, EntityPersister persister) {
+		this.entityName = persister.getEntityName();
+		this.id = id;
+		this.instance = instance;
+		this.session = session;
+		this.persister = persister;
+	}
+
+	protected abstract boolean hasPostCommitEventListeners();
+
+	/**
+	 * entity name accessor
+	 *
+	 * @return The entity name
+	 */
+	public String getEntityName() {
+		return entityName;
+	}
+
+	/**
+	 * entity id accessor
+	 *
+	 * @return The entity id
+	 */
+	public final Serializable getId() {
+		if ( id instanceof DelayedPostInsertIdentifier ) {
+			return session.getPersistenceContext().getEntry( instance ).getId();
+		}
+		return id;
+	}
+
+	/**
+	 * entity instance accessor
+	 *
+	 * @return The entity instance
+	 */
+	public final Object getInstance() {
+		return instance;
+	}
+
+	/**
+	 * originating session accessor
+	 *
+	 * @return The session from which this action originated.
+	 */
+	public final SessionImplementor getSession() {
+		return session;
+	}
+
+	/**
+	 * entity persister accessor
+	 *
+	 * @return The entity persister
+	 */
+	public final EntityPersister getPersister() {
+		return persister;
+	}
+
+	public final Serializable[] getPropertySpaces() {
+		return persister.getPropertySpaces();
+	}
+
+	public void beforeExecutions() {
+		throw new AssertionFailure( "beforeExecutions() called for non-collection action" );
+	}
+
+	public boolean hasAfterTransactionCompletion() {
+		return persister.hasCache() || hasPostCommitEventListeners();
+	}
+
+	public String toString() {
+		return StringHelper.unqualify( getClass().getName() ) + MessageHelper.infoString( entityName, id );
+	}
+
+	public int compareTo(Object other) {
+		EntityAction action = ( EntityAction ) other;
+		//sort first by entity name
+		int roleComparison = entityName.compareTo( action.entityName );
+		if ( roleComparison != 0 ) {
+			return roleComparison;
+		}
+		else {
+			//then by id
+			return persister.getIdentifierType().compare( id, action.id, session.getEntityMode() );
+		}
+	}
+
+	/**
+	 * Serialization...
+	 *
+	 * @param ois Thed object stream
+	 * @throws IOException Problem performing the default stream reading
+	 * @throws ClassNotFoundException Problem performing the default stream reading
+	 */
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		persister = session.getFactory().getEntityPersister( entityName );
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/EntityDeleteAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,174 +0,0 @@
-//$Id: EntityDeleteAction.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.action;
-
-import java.io.Serializable;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.PostDeleteEvent;
-import org.hibernate.event.PostDeleteEventListener;
-import org.hibernate.event.PreDeleteEvent;
-import org.hibernate.event.PreDeleteEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-
-public final class EntityDeleteAction extends EntityAction {
-
-	private final Object version;
-	private SoftLock lock;
-	private final boolean isCascadeDeleteEnabled;
-	private final Object[] state;
-
-	public EntityDeleteAction(
-			final Serializable id,
-	        final Object[] state,
-	        final Object version,
-	        final Object instance,
-	        final EntityPersister persister,
-	        final boolean isCascadeDeleteEnabled,
-	        final SessionImplementor session) {
-		super( session, id, instance, persister );
-		this.version = version;
-		this.isCascadeDeleteEnabled = isCascadeDeleteEnabled;
-		this.state = state;
-	}
-
-	public void execute() throws HibernateException {
-		Serializable id = getId();
-		EntityPersister persister = getPersister();
-		SessionImplementor session = getSession();
-		Object instance = getInstance();
-
-		boolean veto = preDelete();
-
-		Object version = this.version;
-		if ( persister.isVersionPropertyGenerated() ) {
-			// we need to grab the version value from the entity, otherwise
-			// we have issues with generated-version entities that may have
-			// multiple actions queued during the same flush
-			version = persister.getVersion( instance, session.getEntityMode() );
-		}
-
-		final CacheKey ck;
-		if ( persister.hasCache() ) {
-			ck = new CacheKey( 
-					id, 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-				);
-			lock = persister.getCacheAccessStrategy().lockItem( ck, version );
-		}
-		else {
-			ck = null;
-		}
-
-		if ( !isCascadeDeleteEnabled && !veto ) {
-			persister.delete( id, version, instance, session );
-		}
-		
-		//postDelete:
-		// After actually deleting a row, record the fact that the instance no longer 
-		// exists on the database (needed for identity-column key generation), and
-		// remove it from the session cache
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		EntityEntry entry = persistenceContext.removeEntry( instance );
-		if ( entry == null ) {
-			throw new AssertionFailure( "possible nonthreadsafe access to session" );
-		}
-		entry.postDelete();
-
-		EntityKey key = new EntityKey( entry.getId(), entry.getPersister(), session.getEntityMode() );
-		persistenceContext.removeEntity(key);
-		persistenceContext.removeProxy(key);
-		
-		if ( persister.hasCache() ) persister.getCacheAccessStrategy().remove( ck );
-
-		postDelete();
-
-		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
-			getSession().getFactory().getStatisticsImplementor()
-					.deleteEntity( getPersister().getEntityName() );
-		}
-	}
-
-	private boolean preDelete() {
-		PreDeleteEventListener[] preListeners = getSession().getListeners()
-				.getPreDeleteEventListeners();
-		boolean veto = false;
-		if (preListeners.length>0) {
-			PreDeleteEvent preEvent = new PreDeleteEvent( getInstance(), getId(), state, getPersister() );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				veto = preListeners[i].onPreDelete(preEvent) || veto;
-			}
-		}
-		return veto;
-	}
-
-	private void postDelete() {
-		PostDeleteEventListener[] postListeners = getSession().getListeners()
-				.getPostDeleteEventListeners();
-		if (postListeners.length>0) {
-			PostDeleteEvent postEvent = new PostDeleteEvent(
-					getInstance(),
-					getId(),
-					state,
-					getPersister(),
-					(EventSource) getSession() 
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostDelete(postEvent);
-			}
-		}
-	}
-
-	private void postCommitDelete() {
-		PostDeleteEventListener[] postListeners = getSession().getListeners()
-				.getPostCommitDeleteEventListeners();
-		if (postListeners.length>0) {
-			PostDeleteEvent postEvent = new PostDeleteEvent(
-					getInstance(),
-					getId(),
-					state,
-					getPersister(),
-					(EventSource) getSession()
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostDelete(postEvent);
-			}
-		}
-	}
-
-	public void afterTransactionCompletion(boolean success) throws HibernateException {
-		if ( getPersister().hasCache() ) {
-			final CacheKey ck = new CacheKey( 
-					getId(), 
-					getPersister().getIdentifierType(), 
-					getPersister().getRootEntityName(),
-					getSession().getEntityMode(), 
-					getSession().getFactory()
-				);
-			getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
-		}
-		postCommitDelete();
-	}
-
-	protected boolean hasPostCommitEventListeners() {
-		return getSession().getListeners().getPostCommitDeleteEventListeners().length>0;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/EntityDeleteAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityDeleteAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,197 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.PostDeleteEvent;
+import org.hibernate.event.PostDeleteEventListener;
+import org.hibernate.event.PreDeleteEvent;
+import org.hibernate.event.PreDeleteEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+
+public final class EntityDeleteAction extends EntityAction {
+
+	private final Object version;
+	private SoftLock lock;
+	private final boolean isCascadeDeleteEnabled;
+	private final Object[] state;
+
+	public EntityDeleteAction(
+			final Serializable id,
+	        final Object[] state,
+	        final Object version,
+	        final Object instance,
+	        final EntityPersister persister,
+	        final boolean isCascadeDeleteEnabled,
+	        final SessionImplementor session) {
+		super( session, id, instance, persister );
+		this.version = version;
+		this.isCascadeDeleteEnabled = isCascadeDeleteEnabled;
+		this.state = state;
+	}
+
+	public void execute() throws HibernateException {
+		Serializable id = getId();
+		EntityPersister persister = getPersister();
+		SessionImplementor session = getSession();
+		Object instance = getInstance();
+
+		boolean veto = preDelete();
+
+		Object version = this.version;
+		if ( persister.isVersionPropertyGenerated() ) {
+			// we need to grab the version value from the entity, otherwise
+			// we have issues with generated-version entities that may have
+			// multiple actions queued during the same flush
+			version = persister.getVersion( instance, session.getEntityMode() );
+		}
+
+		final CacheKey ck;
+		if ( persister.hasCache() ) {
+			ck = new CacheKey( 
+					id, 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+				);
+			lock = persister.getCacheAccessStrategy().lockItem( ck, version );
+		}
+		else {
+			ck = null;
+		}
+
+		if ( !isCascadeDeleteEnabled && !veto ) {
+			persister.delete( id, version, instance, session );
+		}
+		
+		//postDelete:
+		// After actually deleting a row, record the fact that the instance no longer 
+		// exists on the database (needed for identity-column key generation), and
+		// remove it from the session cache
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		EntityEntry entry = persistenceContext.removeEntry( instance );
+		if ( entry == null ) {
+			throw new AssertionFailure( "possible nonthreadsafe access to session" );
+		}
+		entry.postDelete();
+
+		EntityKey key = new EntityKey( entry.getId(), entry.getPersister(), session.getEntityMode() );
+		persistenceContext.removeEntity(key);
+		persistenceContext.removeProxy(key);
+		
+		if ( persister.hasCache() ) persister.getCacheAccessStrategy().remove( ck );
+
+		postDelete();
+
+		if ( getSession().getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
+			getSession().getFactory().getStatisticsImplementor()
+					.deleteEntity( getPersister().getEntityName() );
+		}
+	}
+
+	private boolean preDelete() {
+		PreDeleteEventListener[] preListeners = getSession().getListeners()
+				.getPreDeleteEventListeners();
+		boolean veto = false;
+		if (preListeners.length>0) {
+			PreDeleteEvent preEvent = new PreDeleteEvent( getInstance(), getId(), state, getPersister() );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				veto = preListeners[i].onPreDelete(preEvent) || veto;
+			}
+		}
+		return veto;
+	}
+
+	private void postDelete() {
+		PostDeleteEventListener[] postListeners = getSession().getListeners()
+				.getPostDeleteEventListeners();
+		if (postListeners.length>0) {
+			PostDeleteEvent postEvent = new PostDeleteEvent(
+					getInstance(),
+					getId(),
+					state,
+					getPersister(),
+					(EventSource) getSession() 
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostDelete(postEvent);
+			}
+		}
+	}
+
+	private void postCommitDelete() {
+		PostDeleteEventListener[] postListeners = getSession().getListeners()
+				.getPostCommitDeleteEventListeners();
+		if (postListeners.length>0) {
+			PostDeleteEvent postEvent = new PostDeleteEvent(
+					getInstance(),
+					getId(),
+					state,
+					getPersister(),
+					(EventSource) getSession()
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostDelete(postEvent);
+			}
+		}
+	}
+
+	public void afterTransactionCompletion(boolean success) throws HibernateException {
+		if ( getPersister().hasCache() ) {
+			final CacheKey ck = new CacheKey( 
+					getId(), 
+					getPersister().getIdentifierType(), 
+					getPersister().getRootEntityName(),
+					getSession().getEntityMode(), 
+					getSession().getFactory()
+				);
+			getPersister().getCacheAccessStrategy().unlockItem( ck, lock );
+		}
+		postCommitDelete();
+	}
+
+	protected boolean hasPostCommitEventListeners() {
+		return getSession().getListeners().getPostCommitDeleteEventListeners().length>0;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,159 +0,0 @@
-//$Id: EntityIdentityInsertAction.java 10680 2006-11-01 22:53:30Z epbernard $
-package org.hibernate.action;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.AssertionFailure;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.event.PostInsertEvent;
-import org.hibernate.event.PostInsertEventListener;
-import org.hibernate.event.PreInsertEvent;
-import org.hibernate.event.PreInsertEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-
-public final class EntityIdentityInsertAction extends EntityAction {
-	private final Object[] state;
-	private final boolean isDelayed;
-	private final EntityKey delayedEntityKey;
-	//private CacheEntry cacheEntry;
-	private Serializable generatedId;
-
-	public EntityIdentityInsertAction(
-			Object[] state,
-	        Object instance,
-	        EntityPersister persister,
-	        SessionImplementor session,
-	        boolean isDelayed) throws HibernateException {
-		super( session, null, instance, persister );
-		this.state = state;
-		this.isDelayed = isDelayed;
-		delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
-	}
-
-	public void execute() throws HibernateException {
-		
-		final EntityPersister persister = getPersister();
-		final SessionImplementor session = getSession();
-		final Object instance = getInstance();
-		
-		boolean veto = preInsert();
-
-		// Don't need to lock the cache here, since if someone
-		// else inserted the same pk first, the insert would fail
-
-		if ( !veto ) {
-			generatedId = persister.insert( state, instance, session );
-			if ( persister.hasInsertGeneratedProperties() ) {
-				persister.processInsertGeneratedProperties( generatedId, instance, state, session );
-			}
-			//need to do that here rather than in the save event listener to let
-			//the post insert events to have a id-filled entity when IDENTITY is used (EJB3)
-			persister.setIdentifier( instance, generatedId, session.getEntityMode() );
-		}
-
-
-		//TODO: this bit actually has to be called after all cascades!
-		//      but since identity insert is called *synchronously*,
-		//      instead of asynchronously as other actions, it isn't
-		/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
-			cacheEntry = new CacheEntry(object, persister, session);
-			persister.getCache().insert(generatedId, cacheEntry);
-		}*/
-		
-		postInsert();
-
-		if ( session.getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
-			session.getFactory().getStatisticsImplementor()
-					.insertEntity( getPersister().getEntityName() );
-		}
-
-	}
-
-	private void postInsert() {
-		if ( isDelayed ) {
-			getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
-		}
-		PostInsertEventListener[] postListeners = getSession().getListeners()
-				.getPostInsertEventListeners();
-		if (postListeners.length>0) {
-			PostInsertEvent postEvent = new PostInsertEvent(
-					getInstance(),
-					generatedId,
-					state,
-					getPersister(),
-					(EventSource) getSession()
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostInsert(postEvent);
-			}
-		}
-	}
-
-	private void postCommitInsert() {
-		PostInsertEventListener[] postListeners = getSession().getListeners()
-				.getPostCommitInsertEventListeners();
-		if (postListeners.length>0) {
-			PostInsertEvent postEvent = new PostInsertEvent(
-					getInstance(),
-					generatedId,
-					state,
-					getPersister(),
-					(EventSource) getSession() 
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostInsert(postEvent);
-			}
-		}
-	}
-
-	private boolean preInsert() {
-		PreInsertEventListener[] preListeners = getSession().getListeners()
-				.getPreInsertEventListeners();
-		boolean veto = false;
-		if (preListeners.length>0) {
-			PreInsertEvent preEvent = new PreInsertEvent( getInstance(), null, state, getPersister(), getSession() );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				veto = preListeners[i].onPreInsert(preEvent) || veto;
-			}
-		}
-		return veto;
-	}
-
-	//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
-	public void afterTransactionCompletion(boolean success) throws HibernateException {
-		//TODO: reenable if we also fix the above todo
-		/*EntityPersister persister = getEntityPersister();
-		if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
-			persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
-		}*/
-		postCommitInsert();
-	}
-
-	public boolean hasAfterTransactionCompletion() {
-		//TODO: simply remove this override
-		//      if we fix the above todos
-		return hasPostCommitEventListeners();
-	}
-
-	protected boolean hasPostCommitEventListeners() {
-		return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
-	}
-	
-	public final Serializable getGeneratedId() {
-		return generatedId;
-	}
-
-	public EntityKey getDelayedEntityKey() {
-		return delayedEntityKey;
-	}
-
-	private synchronized EntityKey generateDelayedEntityKey() {
-		if ( !isDelayed ) {
-			throw new AssertionFailure( "cannot request delayed entity-key for non-delayed post-insert-id generation" );
-		}
-		return new EntityKey( new DelayedPostInsertIdentifier(), getPersister(), getSession().getEntityMode() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityIdentityInsertAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,182 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.event.PostInsertEvent;
+import org.hibernate.event.PostInsertEventListener;
+import org.hibernate.event.PreInsertEvent;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+
+public final class EntityIdentityInsertAction extends EntityAction {
+	private final Object[] state;
+	private final boolean isDelayed;
+	private final EntityKey delayedEntityKey;
+	//private CacheEntry cacheEntry;
+	private Serializable generatedId;
+
+	public EntityIdentityInsertAction(
+			Object[] state,
+	        Object instance,
+	        EntityPersister persister,
+	        SessionImplementor session,
+	        boolean isDelayed) throws HibernateException {
+		super( session, null, instance, persister );
+		this.state = state;
+		this.isDelayed = isDelayed;
+		delayedEntityKey = isDelayed ? generateDelayedEntityKey() : null;
+	}
+
+	public void execute() throws HibernateException {
+		
+		final EntityPersister persister = getPersister();
+		final SessionImplementor session = getSession();
+		final Object instance = getInstance();
+		
+		boolean veto = preInsert();
+
+		// Don't need to lock the cache here, since if someone
+		// else inserted the same pk first, the insert would fail
+
+		if ( !veto ) {
+			generatedId = persister.insert( state, instance, session );
+			if ( persister.hasInsertGeneratedProperties() ) {
+				persister.processInsertGeneratedProperties( generatedId, instance, state, session );
+			}
+			//need to do that here rather than in the save event listener to let
+			//the post insert events to have a id-filled entity when IDENTITY is used (EJB3)
+			persister.setIdentifier( instance, generatedId, session.getEntityMode() );
+		}
+
+
+		//TODO: this bit actually has to be called after all cascades!
+		//      but since identity insert is called *synchronously*,
+		//      instead of asynchronously as other actions, it isn't
+		/*if ( persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
+			cacheEntry = new CacheEntry(object, persister, session);
+			persister.getCache().insert(generatedId, cacheEntry);
+		}*/
+		
+		postInsert();
+
+		if ( session.getFactory().getStatistics().isStatisticsEnabled() && !veto ) {
+			session.getFactory().getStatisticsImplementor()
+					.insertEntity( getPersister().getEntityName() );
+		}
+
+	}
+
+	private void postInsert() {
+		if ( isDelayed ) {
+			getSession().getPersistenceContext().replaceDelayedEntityIdentityInsertKeys( delayedEntityKey, generatedId );
+		}
+		PostInsertEventListener[] postListeners = getSession().getListeners()
+				.getPostInsertEventListeners();
+		if (postListeners.length>0) {
+			PostInsertEvent postEvent = new PostInsertEvent(
+					getInstance(),
+					generatedId,
+					state,
+					getPersister(),
+					(EventSource) getSession()
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostInsert(postEvent);
+			}
+		}
+	}
+
+	private void postCommitInsert() {
+		PostInsertEventListener[] postListeners = getSession().getListeners()
+				.getPostCommitInsertEventListeners();
+		if (postListeners.length>0) {
+			PostInsertEvent postEvent = new PostInsertEvent(
+					getInstance(),
+					generatedId,
+					state,
+					getPersister(),
+					(EventSource) getSession() 
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostInsert(postEvent);
+			}
+		}
+	}
+
+	private boolean preInsert() {
+		PreInsertEventListener[] preListeners = getSession().getListeners()
+				.getPreInsertEventListeners();
+		boolean veto = false;
+		if (preListeners.length>0) {
+			PreInsertEvent preEvent = new PreInsertEvent( getInstance(), null, state, getPersister(), getSession() );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				veto = preListeners[i].onPreInsert(preEvent) || veto;
+			}
+		}
+		return veto;
+	}
+
+	//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
+	public void afterTransactionCompletion(boolean success) throws HibernateException {
+		//TODO: reenable if we also fix the above todo
+		/*EntityPersister persister = getEntityPersister();
+		if ( success && persister.hasCache() && !persister.isCacheInvalidationRequired() ) {
+			persister.getCache().afterInsert( getGeneratedId(), cacheEntry );
+		}*/
+		postCommitInsert();
+	}
+
+	public boolean hasAfterTransactionCompletion() {
+		//TODO: simply remove this override
+		//      if we fix the above todos
+		return hasPostCommitEventListeners();
+	}
+
+	protected boolean hasPostCommitEventListeners() {
+		return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
+	}
+	
+	public final Serializable getGeneratedId() {
+		return generatedId;
+	}
+
+	public EntityKey getDelayedEntityKey() {
+		return delayedEntityKey;
+	}
+
+	private synchronized EntityKey generateDelayedEntityKey() {
+		if ( !isDelayed ) {
+			throw new AssertionFailure( "cannot request delayed entity-key for non-delayed post-insert-id generation" );
+		}
+		return new EntityKey( new DelayedPostInsertIdentifier(), getPersister(), getSession().getEntityMode() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/EntityInsertAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,199 +0,0 @@
-//$Id: EntityInsertAction.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.action;
-
-import java.io.Serializable;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.entry.CacheEntry;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.PostInsertEvent;
-import org.hibernate.event.PostInsertEventListener;
-import org.hibernate.event.PreInsertEvent;
-import org.hibernate.event.PreInsertEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-
-public final class EntityInsertAction extends EntityAction {
-
-	private Object[] state;
-	private Object version;
-	private Object cacheEntry;
-
-	public EntityInsertAction(
-	        Serializable id,
-	        Object[] state,
-	        Object instance,
-	        Object version,
-	        EntityPersister persister,
-	        SessionImplementor session) throws HibernateException {
-		super( session, id, instance, persister );
-		this.state = state;
-		this.version = version;
-	}
-
-	public Object[] getState() {
-		return state;
-	}
-
-	public void execute() throws HibernateException {
-		EntityPersister persister = getPersister();
-		SessionImplementor session = getSession();
-		Object instance = getInstance();
-		Serializable id = getId();
-
-		boolean veto = preInsert();
-
-		// Don't need to lock the cache here, since if someone
-		// else inserted the same pk first, the insert would fail
-
-		if ( !veto ) {
-			
-			persister.insert( id, state, instance, session );
-		
-			EntityEntry entry = session.getPersistenceContext().getEntry( instance );
-			if ( entry == null ) {
-				throw new AssertionFailure( "possible nonthreadsafe access to session" );
-			}
-			
-			entry.postInsert();
-	
-			if ( persister.hasInsertGeneratedProperties() ) {
-				persister.processInsertGeneratedProperties( id, instance, state, session );
-				if ( persister.isVersionPropertyGenerated() ) {
-					version = Versioning.getVersion(state, persister);
-				}
-				entry.postUpdate(instance, state, version);
-			}
-			
-		}
-
-		final SessionFactoryImplementor factory = getSession().getFactory();
-
-		if ( isCachePutEnabled( persister, session ) ) {
-			
-			CacheEntry ce = new CacheEntry(
-					state,
-					persister, 
-					persister.hasUninitializedLazyProperties( instance, session.getEntityMode() ),
-					version,
-					session,
-					instance
-				);
-			
-			cacheEntry = persister.getCacheEntryStructure().structure(ce);
-			final CacheKey ck = new CacheKey( 
-					id, 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-				);
-//			boolean put = persister.getCache().insert(ck, cacheEntry);
-			boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version );
-			
-			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
-				factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
-			}
-			
-		}
-
-		postInsert();
-
-		if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
-			factory.getStatisticsImplementor()
-					.insertEntity( getPersister().getEntityName() );
-		}
-
-	}
-
-	private void postInsert() {
-		PostInsertEventListener[] postListeners = getSession().getListeners()
-				.getPostInsertEventListeners();
-		if ( postListeners.length > 0 ) {
-			PostInsertEvent postEvent = new PostInsertEvent(
-					getInstance(),
-					getId(),
-					state,
-					getPersister(),
-					(EventSource) getSession()
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostInsert(postEvent);
-			}
-		}
-	}
-
-	private void postCommitInsert() {
-		PostInsertEventListener[] postListeners = getSession().getListeners()
-				.getPostCommitInsertEventListeners();
-		if ( postListeners.length > 0 ) {
-			PostInsertEvent postEvent = new PostInsertEvent(
-					getInstance(),
-					getId(),
-					state,
-					getPersister(),
-					(EventSource) getSession() 
-			);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostInsert(postEvent);
-			}
-		}
-	}
-
-	private boolean preInsert() {
-		PreInsertEventListener[] preListeners = getSession().getListeners()
-				.getPreInsertEventListeners();
-		boolean veto = false;
-		if (preListeners.length>0) {
-			PreInsertEvent preEvent = new PreInsertEvent( getInstance(), getId(), state, getPersister(), getSession() );
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				veto = preListeners[i].onPreInsert(preEvent) || veto;
-			}
-		}
-		return veto;
-	}
-
-	//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
-	public void afterTransactionCompletion(boolean success) throws HibernateException {
-		EntityPersister persister = getPersister();
-		if ( success && isCachePutEnabled( persister, getSession() ) ) {
-			final CacheKey ck = new CacheKey( 
-					getId(), 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					getSession().getEntityMode(), 
-					getSession().getFactory() 
-				);
-			boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
-			
-			if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
-				getSession().getFactory().getStatisticsImplementor()
-						.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
-			}
-		}
-		postCommitInsert();
-	}
-
-	protected boolean hasPostCommitEventListeners() {
-		return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
-	}
-	
-	private boolean isCachePutEnabled(EntityPersister persister, SessionImplementor session) {
-		return persister.hasCache() && 
-				!persister.isCacheInvalidationRequired() && 
-				session.getCacheMode().isPutEnabled();
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/EntityInsertAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityInsertAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,222 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.PostInsertEvent;
+import org.hibernate.event.PostInsertEventListener;
+import org.hibernate.event.PreInsertEvent;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+
+public final class EntityInsertAction extends EntityAction {
+
+	private Object[] state;
+	private Object version;
+	private Object cacheEntry;
+
+	public EntityInsertAction(
+	        Serializable id,
+	        Object[] state,
+	        Object instance,
+	        Object version,
+	        EntityPersister persister,
+	        SessionImplementor session) throws HibernateException {
+		super( session, id, instance, persister );
+		this.state = state;
+		this.version = version;
+	}
+
+	public Object[] getState() {
+		return state;
+	}
+
+	public void execute() throws HibernateException {
+		EntityPersister persister = getPersister();
+		SessionImplementor session = getSession();
+		Object instance = getInstance();
+		Serializable id = getId();
+
+		boolean veto = preInsert();
+
+		// Don't need to lock the cache here, since if someone
+		// else inserted the same pk first, the insert would fail
+
+		if ( !veto ) {
+			
+			persister.insert( id, state, instance, session );
+		
+			EntityEntry entry = session.getPersistenceContext().getEntry( instance );
+			if ( entry == null ) {
+				throw new AssertionFailure( "possible nonthreadsafe access to session" );
+			}
+			
+			entry.postInsert();
+	
+			if ( persister.hasInsertGeneratedProperties() ) {
+				persister.processInsertGeneratedProperties( id, instance, state, session );
+				if ( persister.isVersionPropertyGenerated() ) {
+					version = Versioning.getVersion(state, persister);
+				}
+				entry.postUpdate(instance, state, version);
+			}
+			
+		}
+
+		final SessionFactoryImplementor factory = getSession().getFactory();
+
+		if ( isCachePutEnabled( persister, session ) ) {
+			
+			CacheEntry ce = new CacheEntry(
+					state,
+					persister, 
+					persister.hasUninitializedLazyProperties( instance, session.getEntityMode() ),
+					version,
+					session,
+					instance
+				);
+			
+			cacheEntry = persister.getCacheEntryStructure().structure(ce);
+			final CacheKey ck = new CacheKey( 
+					id, 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+				);
+//			boolean put = persister.getCache().insert(ck, cacheEntry);
+			boolean put = persister.getCacheAccessStrategy().insert( ck, cacheEntry, version );
+			
+			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
+				factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+			}
+			
+		}
+
+		postInsert();
+
+		if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
+			factory.getStatisticsImplementor()
+					.insertEntity( getPersister().getEntityName() );
+		}
+
+	}
+
+	private void postInsert() {
+		PostInsertEventListener[] postListeners = getSession().getListeners()
+				.getPostInsertEventListeners();
+		if ( postListeners.length > 0 ) {
+			PostInsertEvent postEvent = new PostInsertEvent(
+					getInstance(),
+					getId(),
+					state,
+					getPersister(),
+					(EventSource) getSession()
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostInsert(postEvent);
+			}
+		}
+	}
+
+	private void postCommitInsert() {
+		PostInsertEventListener[] postListeners = getSession().getListeners()
+				.getPostCommitInsertEventListeners();
+		if ( postListeners.length > 0 ) {
+			PostInsertEvent postEvent = new PostInsertEvent(
+					getInstance(),
+					getId(),
+					state,
+					getPersister(),
+					(EventSource) getSession() 
+			);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostInsert(postEvent);
+			}
+		}
+	}
+
+	private boolean preInsert() {
+		PreInsertEventListener[] preListeners = getSession().getListeners()
+				.getPreInsertEventListeners();
+		boolean veto = false;
+		if (preListeners.length>0) {
+			PreInsertEvent preEvent = new PreInsertEvent( getInstance(), getId(), state, getPersister(), getSession() );
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				veto = preListeners[i].onPreInsert(preEvent) || veto;
+			}
+		}
+		return veto;
+	}
+
+	//Make 100% certain that this is called before any subsequent ScheduledUpdate.afterTransactionCompletion()!!
+	public void afterTransactionCompletion(boolean success) throws HibernateException {
+		EntityPersister persister = getPersister();
+		if ( success && isCachePutEnabled( persister, getSession() ) ) {
+			final CacheKey ck = new CacheKey( 
+					getId(), 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					getSession().getEntityMode(), 
+					getSession().getFactory() 
+				);
+			boolean put = persister.getCacheAccessStrategy().afterInsert( ck, cacheEntry, version );
+			
+			if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
+				getSession().getFactory().getStatisticsImplementor()
+						.secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+			}
+		}
+		postCommitInsert();
+	}
+
+	protected boolean hasPostCommitEventListeners() {
+		return getSession().getListeners().getPostCommitInsertEventListeners().length>0;
+	}
+	
+	private boolean isCachePutEnabled(EntityPersister persister, SessionImplementor session) {
+		return persister.hasCache() && 
+				!persister.isCacheInvalidationRequired() && 
+				session.getCacheMode().isPutEnabled();
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/EntityUpdateAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,257 +0,0 @@
-//$Id: EntityUpdateAction.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.action;
-
-import java.io.Serializable;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.cache.entry.CacheEntry;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.PostUpdateEvent;
-import org.hibernate.event.PostUpdateEventListener;
-import org.hibernate.event.PreUpdateEvent;
-import org.hibernate.event.PreUpdateEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.TypeFactory;
-
-public final class EntityUpdateAction extends EntityAction {
-
-	private final Object[] state;
-	private final Object[] previousState;
-	private final Object previousVersion;
-	private Object nextVersion;
-	private final int[] dirtyFields;
-	private final boolean hasDirtyCollection;
-	private final Object rowId;
-	private Object cacheEntry;
-	private SoftLock lock;
-
-	public EntityUpdateAction(
-	        final Serializable id,
-	        final Object[] state,
-	        final int[] dirtyProperties,
-	        final boolean hasDirtyCollection,
-	        final Object[] previousState,
-	        final Object previousVersion,
-	        final Object nextVersion,
-	        final Object instance,
-	        final Object rowId,
-	        final EntityPersister persister,
-	        final SessionImplementor session) throws HibernateException {
-		super( session, id, instance, persister );
-		this.state = state;
-		this.previousState = previousState;
-		this.previousVersion = previousVersion;
-		this.nextVersion = nextVersion;
-		this.dirtyFields = dirtyProperties;
-		this.hasDirtyCollection = hasDirtyCollection;
-		this.rowId = rowId;
-	}
-
-	public void execute() throws HibernateException {
-		Serializable id = getId();
-		EntityPersister persister = getPersister();
-		SessionImplementor session = getSession();
-		Object instance = getInstance();
-
-		boolean veto = preUpdate();
-
-		final SessionFactoryImplementor factory = getSession().getFactory();
-		Object previousVersion = this.previousVersion;
-		if ( persister.isVersionPropertyGenerated() ) {
-			// we need to grab the version value from the entity, otherwise
-			// we have issues with generated-version entities that may have
-			// multiple actions queued during the same flush
-			previousVersion = persister.getVersion( instance, session.getEntityMode() );
-		}
-		
-		final CacheKey ck;
-		if ( persister.hasCache() ) {
-			ck = new CacheKey( 
-					id, 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-			);
-			lock = persister.getCacheAccessStrategy().lockItem( ck, previousVersion );
-		}
-		else {
-			ck = null;
-		}
-
-		if ( !veto ) {
-			persister.update( 
-					id, 
-					state, 
-					dirtyFields, 
-					hasDirtyCollection, 
-					previousState, 
-					previousVersion, 
-					instance, 
-					rowId, 
-					session 
-			);
-		}
-
-		EntityEntry entry = getSession().getPersistenceContext().getEntry( instance );
-		if ( entry == null ) {
-			throw new AssertionFailure( "possible nonthreadsafe access to session" );
-		}
-		
-		if ( entry.getStatus()==Status.MANAGED || persister.isVersionPropertyGenerated() ) {
-			// get the updated snapshot of the entity state by cloning current state;
-			// it is safe to copy in place, since by this time no-one else (should have)
-			// has a reference  to the array
-			TypeFactory.deepCopy(
-					state,
-					persister.getPropertyTypes(),
-					persister.getPropertyCheckability(),
-					state,
-					session
-			);
-			if ( persister.hasUpdateGeneratedProperties() ) {
-				// this entity defines proeprty generation, so process those generated
-				// values...
-				persister.processUpdateGeneratedProperties( id, instance, state, session );
-				if ( persister.isVersionPropertyGenerated() ) {
-					nextVersion = Versioning.getVersion( state, persister );
-				}
-			}
-			// have the entity entry perform post-update processing, passing it the
-			// update state and the new version (if one).
-			entry.postUpdate( instance, state, nextVersion );
-		}
-
-		if ( persister.hasCache() ) {
-			if ( persister.isCacheInvalidationRequired() || entry.getStatus()!=Status.MANAGED ) {
-				persister.getCacheAccessStrategy().remove( ck );
-			}
-			else {
-				//TODO: inefficient if that cache is just going to ignore the updated state!
-				CacheEntry ce = new CacheEntry(
-						state, 
-						persister, 
-						persister.hasUninitializedLazyProperties( instance, session.getEntityMode() ), 
-						nextVersion,
-						getSession(),
-						instance
-				);
-				cacheEntry = persister.getCacheEntryStructure().structure( ce );
-				boolean put = persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion );
-				if ( put && factory.getStatistics().isStatisticsEnabled() ) {
-					factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
-				}
-			}
-		}
-
-		postUpdate();
-
-		if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
-			factory.getStatisticsImplementor()
-					.updateEntity( getPersister().getEntityName() );
-		}
-	}
-
-	private void postUpdate() {
-		PostUpdateEventListener[] postListeners = getSession().getListeners()
-				.getPostUpdateEventListeners();
-		if (postListeners.length>0) {
-			PostUpdateEvent postEvent = new PostUpdateEvent( 
-					getInstance(), 
-					getId(), 
-					state, 
-					previousState, 
-					getPersister(),
-					(EventSource) getSession() 
-				);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostUpdate(postEvent);
-			}
-		}
-	}
-
-	private void postCommitUpdate() {
-		PostUpdateEventListener[] postListeners = getSession().getListeners()
-				.getPostCommitUpdateEventListeners();
-		if (postListeners.length>0) {
-			PostUpdateEvent postEvent = new PostUpdateEvent( 
-					getInstance(), 
-					getId(), 
-					state, 
-					previousState, 
-					getPersister(),
-					(EventSource) getSession()
-				);
-			for ( int i = 0; i < postListeners.length; i++ ) {
-				postListeners[i].onPostUpdate(postEvent);
-			}
-		}
-	}
-
-	private boolean preUpdate() {
-		PreUpdateEventListener[] preListeners = getSession().getListeners()
-				.getPreUpdateEventListeners();
-		boolean veto = false;
-		if (preListeners.length>0) {
-			PreUpdateEvent preEvent = new PreUpdateEvent( 
-					getInstance(), 
-					getId(), 
-					state, 
-					previousState, 
-					getPersister(),
-					getSession()
-				);
-			for ( int i = 0; i < preListeners.length; i++ ) {
-				veto = preListeners[i].onPreUpdate(preEvent) || veto;
-			}
-		}
-		return veto;
-	}
-
-	public void afterTransactionCompletion(boolean success) throws CacheException {
-		EntityPersister persister = getPersister();
-		if ( persister.hasCache() ) {
-			
-			final CacheKey ck = new CacheKey( 
-					getId(), 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					getSession().getEntityMode(), 
-					getSession().getFactory() 
-				);
-			
-			if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) {
-				boolean put = persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
-				
-				if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
-					getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
-				}
-			}
-			else {
-				persister.getCacheAccessStrategy().unlockItem( ck, lock );
-			}
-		}
-		postCommitUpdate();
-	}
-
-	protected boolean hasPostCommitEventListeners() {
-		return getSession().getListeners().getPostCommitUpdateEventListeners().length>0;
-	}
-	
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/EntityUpdateAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/EntityUpdateAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,280 @@
+/*
+ * 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.action;
+
+import java.io.Serializable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.PostUpdateEvent;
+import org.hibernate.event.PostUpdateEventListener;
+import org.hibernate.event.PreUpdateEvent;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.TypeFactory;
+
+public final class EntityUpdateAction extends EntityAction {
+
+	private final Object[] state;
+	private final Object[] previousState;
+	private final Object previousVersion;
+	private Object nextVersion;
+	private final int[] dirtyFields;
+	private final boolean hasDirtyCollection;
+	private final Object rowId;
+	private Object cacheEntry;
+	private SoftLock lock;
+
+	public EntityUpdateAction(
+	        final Serializable id,
+	        final Object[] state,
+	        final int[] dirtyProperties,
+	        final boolean hasDirtyCollection,
+	        final Object[] previousState,
+	        final Object previousVersion,
+	        final Object nextVersion,
+	        final Object instance,
+	        final Object rowId,
+	        final EntityPersister persister,
+	        final SessionImplementor session) throws HibernateException {
+		super( session, id, instance, persister );
+		this.state = state;
+		this.previousState = previousState;
+		this.previousVersion = previousVersion;
+		this.nextVersion = nextVersion;
+		this.dirtyFields = dirtyProperties;
+		this.hasDirtyCollection = hasDirtyCollection;
+		this.rowId = rowId;
+	}
+
+	public void execute() throws HibernateException {
+		Serializable id = getId();
+		EntityPersister persister = getPersister();
+		SessionImplementor session = getSession();
+		Object instance = getInstance();
+
+		boolean veto = preUpdate();
+
+		final SessionFactoryImplementor factory = getSession().getFactory();
+		Object previousVersion = this.previousVersion;
+		if ( persister.isVersionPropertyGenerated() ) {
+			// we need to grab the version value from the entity, otherwise
+			// we have issues with generated-version entities that may have
+			// multiple actions queued during the same flush
+			previousVersion = persister.getVersion( instance, session.getEntityMode() );
+		}
+		
+		final CacheKey ck;
+		if ( persister.hasCache() ) {
+			ck = new CacheKey( 
+					id, 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+			);
+			lock = persister.getCacheAccessStrategy().lockItem( ck, previousVersion );
+		}
+		else {
+			ck = null;
+		}
+
+		if ( !veto ) {
+			persister.update( 
+					id, 
+					state, 
+					dirtyFields, 
+					hasDirtyCollection, 
+					previousState, 
+					previousVersion, 
+					instance, 
+					rowId, 
+					session 
+			);
+		}
+
+		EntityEntry entry = getSession().getPersistenceContext().getEntry( instance );
+		if ( entry == null ) {
+			throw new AssertionFailure( "possible nonthreadsafe access to session" );
+		}
+		
+		if ( entry.getStatus()==Status.MANAGED || persister.isVersionPropertyGenerated() ) {
+			// get the updated snapshot of the entity state by cloning current state;
+			// it is safe to copy in place, since by this time no-one else (should have)
+			// has a reference  to the array
+			TypeFactory.deepCopy(
+					state,
+					persister.getPropertyTypes(),
+					persister.getPropertyCheckability(),
+					state,
+					session
+			);
+			if ( persister.hasUpdateGeneratedProperties() ) {
+				// this entity defines proeprty generation, so process those generated
+				// values...
+				persister.processUpdateGeneratedProperties( id, instance, state, session );
+				if ( persister.isVersionPropertyGenerated() ) {
+					nextVersion = Versioning.getVersion( state, persister );
+				}
+			}
+			// have the entity entry perform post-update processing, passing it the
+			// update state and the new version (if one).
+			entry.postUpdate( instance, state, nextVersion );
+		}
+
+		if ( persister.hasCache() ) {
+			if ( persister.isCacheInvalidationRequired() || entry.getStatus()!=Status.MANAGED ) {
+				persister.getCacheAccessStrategy().remove( ck );
+			}
+			else {
+				//TODO: inefficient if that cache is just going to ignore the updated state!
+				CacheEntry ce = new CacheEntry(
+						state, 
+						persister, 
+						persister.hasUninitializedLazyProperties( instance, session.getEntityMode() ), 
+						nextVersion,
+						getSession(),
+						instance
+				);
+				cacheEntry = persister.getCacheEntryStructure().structure( ce );
+				boolean put = persister.getCacheAccessStrategy().update( ck, cacheEntry, nextVersion, previousVersion );
+				if ( put && factory.getStatistics().isStatisticsEnabled() ) {
+					factory.getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+				}
+			}
+		}
+
+		postUpdate();
+
+		if ( factory.getStatistics().isStatisticsEnabled() && !veto ) {
+			factory.getStatisticsImplementor()
+					.updateEntity( getPersister().getEntityName() );
+		}
+	}
+
+	private void postUpdate() {
+		PostUpdateEventListener[] postListeners = getSession().getListeners()
+				.getPostUpdateEventListeners();
+		if (postListeners.length>0) {
+			PostUpdateEvent postEvent = new PostUpdateEvent( 
+					getInstance(), 
+					getId(), 
+					state, 
+					previousState, 
+					getPersister(),
+					(EventSource) getSession() 
+				);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostUpdate(postEvent);
+			}
+		}
+	}
+
+	private void postCommitUpdate() {
+		PostUpdateEventListener[] postListeners = getSession().getListeners()
+				.getPostCommitUpdateEventListeners();
+		if (postListeners.length>0) {
+			PostUpdateEvent postEvent = new PostUpdateEvent( 
+					getInstance(), 
+					getId(), 
+					state, 
+					previousState, 
+					getPersister(),
+					(EventSource) getSession()
+				);
+			for ( int i = 0; i < postListeners.length; i++ ) {
+				postListeners[i].onPostUpdate(postEvent);
+			}
+		}
+	}
+
+	private boolean preUpdate() {
+		PreUpdateEventListener[] preListeners = getSession().getListeners()
+				.getPreUpdateEventListeners();
+		boolean veto = false;
+		if (preListeners.length>0) {
+			PreUpdateEvent preEvent = new PreUpdateEvent( 
+					getInstance(), 
+					getId(), 
+					state, 
+					previousState, 
+					getPersister(),
+					getSession()
+				);
+			for ( int i = 0; i < preListeners.length; i++ ) {
+				veto = preListeners[i].onPreUpdate(preEvent) || veto;
+			}
+		}
+		return veto;
+	}
+
+	public void afterTransactionCompletion(boolean success) throws CacheException {
+		EntityPersister persister = getPersister();
+		if ( persister.hasCache() ) {
+			
+			final CacheKey ck = new CacheKey( 
+					getId(), 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					getSession().getEntityMode(), 
+					getSession().getFactory() 
+				);
+			
+			if ( success && cacheEntry!=null /*!persister.isCacheInvalidationRequired()*/ ) {
+				boolean put = persister.getCacheAccessStrategy().afterUpdate( ck, cacheEntry, nextVersion, previousVersion, lock );
+				
+				if ( put && getSession().getFactory().getStatistics().isStatisticsEnabled() ) {
+					getSession().getFactory().getStatisticsImplementor().secondLevelCachePut( getPersister().getCacheAccessStrategy().getRegion().getName() );
+				}
+			}
+			else {
+				persister.getCacheAccessStrategy().unlockItem( ck, lock );
+			}
+		}
+		postCommitUpdate();
+	}
+
+	protected boolean hasPostCommitEventListeners() {
+		return getSession().getListeners().getPostCommitUpdateEventListeners().length>0;
+	}
+	
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/Executable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: Executable.java 6607 2005-04-29 15:26:11Z oneovthafew $
-package org.hibernate.action;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * An operation which may be scheduled for later execution.
- * Usually, the operation is a database insert/update/delete,
- * together with required second-level cache management.
- * 
- * @author Gavin King
- */
-public interface Executable {
-	/**
-	 * Called before executing any actions
-	 */
-	public void beforeExecutions() throws HibernateException;
-	/**
-	 * Execute this action
-	 */
-	public void execute() throws HibernateException;
-	/**
-	 * Do we need to retain this instance until after the
-	 * transaction completes?
-	 * @return false if this class defines a no-op
-	 * <tt>hasAfterTransactionCompletion()</tt>
-	 */
-	public boolean hasAfterTransactionCompletion();
-	/**
-	 * Called after the transaction completes
-	 */
-	public void afterTransactionCompletion(boolean success) throws HibernateException;
-	/**
-	 * What spaces (tables) are affected by this action?
-	 */
-	public Serializable[] getPropertySpaces();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/Executable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/Executable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.action;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * An operation which may be scheduled for later execution.
+ * Usually, the operation is a database insert/update/delete,
+ * together with required second-level cache management.
+ * 
+ * @author Gavin King
+ */
+public interface Executable {
+	/**
+	 * Called before executing any actions
+	 */
+	public void beforeExecutions() throws HibernateException;
+	/**
+	 * Execute this action
+	 */
+	public void execute() throws HibernateException;
+	/**
+	 * Do we need to retain this instance until after the
+	 * transaction completes?
+	 * @return false if this class defines a no-op
+	 * <tt>hasAfterTransactionCompletion()</tt>
+	 */
+	public boolean hasAfterTransactionCompletion();
+	/**
+	 * Called after the transaction completes
+	 */
+	public void afterTransactionCompletion(boolean success) throws HibernateException;
+	/**
+	 * What spaces (tables) are affected by this action?
+	 */
+	public Serializable[] getPropertySpaces();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/action/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head>
-</head>
-<body>
-<p>
-	This package defines "actions" that are scheduled for 
-	asycnchronous execution by the event listeners.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/action/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/action/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head>
+</head>
+<body>
+<p>
+	This package defines "actions" that are scheduled for 
+	asycnchronous execution by the event listeners.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: $
-package org.hibernate.bytecode;
-
-import org.hibernate.bytecode.util.ClassFilter;
-import org.hibernate.bytecode.util.FieldFilter;
-
-import java.security.ProtectionDomain;
-
-/**
- * @author Emmanuel Bernard
- * @author Steve Ebersole
- */
-public abstract class AbstractClassTransformerImpl implements ClassTransformer {
-
-	protected final ClassFilter classFilter;
-	protected final FieldFilter fieldFilter;
-
-	protected AbstractClassTransformerImpl(ClassFilter classFilter, FieldFilter fieldFilter) {
-		this.classFilter = classFilter;
-		this.fieldFilter = fieldFilter;
-	}
-
-	public byte[] transform(
-			ClassLoader loader,
-			String className,
-			Class classBeingRedefined,
-			ProtectionDomain protectionDomain,
-			byte[] classfileBuffer) {
-		// to be safe...
-		className = className.replace( '/', '.' );
-		if ( classFilter.shouldInstrumentClass( className ) ) {
-			return doTransform( loader, className, classBeingRedefined, protectionDomain, classfileBuffer );
-		}
-		else {
-			return classfileBuffer;
-		}
-	}
-
-	protected abstract byte[] doTransform(
-			ClassLoader loader,
-			String className,
-			Class classBeingRedefined,
-			ProtectionDomain protectionDomain,
-			byte[] classfileBuffer);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/AbstractClassTransformerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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.bytecode;
+
+import org.hibernate.bytecode.util.ClassFilter;
+import org.hibernate.bytecode.util.FieldFilter;
+
+import java.security.ProtectionDomain;
+
+/**
+ * Basic implementation of the {@link ClassTransformer} contract.
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public abstract class AbstractClassTransformerImpl implements ClassTransformer {
+
+	protected final ClassFilter classFilter;
+	protected final FieldFilter fieldFilter;
+
+	protected AbstractClassTransformerImpl(ClassFilter classFilter, FieldFilter fieldFilter) {
+		this.classFilter = classFilter;
+		this.fieldFilter = fieldFilter;
+	}
+
+	public byte[] transform(
+			ClassLoader loader,
+			String className,
+			Class classBeingRedefined,
+			ProtectionDomain protectionDomain,
+			byte[] classfileBuffer) {
+		// to be safe...
+		className = className.replace( '/', '.' );
+		if ( classFilter.shouldInstrumentClass( className ) ) {
+			return doTransform( loader, className, classBeingRedefined, protectionDomain, classfileBuffer );
+		}
+		else {
+			return classfileBuffer;
+		}
+	}
+
+	protected abstract byte[] doTransform(
+			ClassLoader loader,
+			String className,
+			Class classBeingRedefined,
+			ProtectionDomain protectionDomain,
+			byte[] classfileBuffer);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-package org.hibernate.bytecode;
-
-/**
- * A proxy factory for "basic proxy" generation
- *
- * @author Steve Ebersole
- */
-public interface BasicProxyFactory {
-	public Object getProxy();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BasicProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode;
+
+/**
+ * A proxy factory for "basic proxy" generation
+ *
+ * @author Steve Ebersole
+ */
+public interface BasicProxyFactory {
+	/**
+	 * Get a proxy reference.
+	 *
+	 * @return A proxy reference.
+	 */
+	public Object getProxy();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-package org.hibernate.bytecode;
-
-import org.hibernate.bytecode.util.ClassFilter;
-import org.hibernate.bytecode.util.FieldFilter;
-
-/**
- * Contract for providers of bytecode services to Hibernate.
- * <p/>
- * Bytecode requirements break down into basically 3 areas<ol>
- * <li>proxy generation (both for runtime-lazy-loading and basic proxy generation)
- * {@link #getProxyFactoryFactory()}
- * <li>bean relection optimization {@link #getReflectionOptimizer}
- * <li>field-access instumentation {@link #getTransformer}
- * </ol>
- *
- * @author Steve Ebersole
- */
-public interface BytecodeProvider {
-	/**
-	 * Retrieve the specific factory for this provider capable of
-	 * generating run-time proxies for lazy-loading purposes.
-	 *
-	 * @return The provider specifc factory.
-	 */
-	public ProxyFactoryFactory getProxyFactoryFactory();
-
-	/**
-	 * Retrieve the ReflectionOptimizer delegate for this provider
-	 * capable of generating reflection optimization components.
-	 *
-	 * @param clazz The class to be reflected upon.
-	 * @param getterNames Names of all property getters to be accessed via reflection.
-	 * @param setterNames Names of all property setters to be accessed via reflection.
-	 * @param types The types of all properties to be accessed.
-	 * @return The reflection optimization delegate.
-	 */
-	public ReflectionOptimizer getReflectionOptimizer(Class clazz, String[] getterNames, String[] setterNames, Class[] types);
-
-	/**
-	 * Generate a ClassTransformer capable of performing bytecode manipulation.
-	 *
-	 * @param classFilter filter used to limit which classes are to be instrumented
-	 * via this ClassTransformer.
-	 * @param fieldFilter filter used to limit which fields are to be instrumented
-	 * via this ClassTransformer.
-	 * @return The appropriate ClassTransformer.
-	 */
-	public ClassTransformer getTransformer(ClassFilter classFilter, FieldFilter fieldFilter);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/BytecodeProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.bytecode;
+
+import org.hibernate.bytecode.util.ClassFilter;
+import org.hibernate.bytecode.util.FieldFilter;
+
+/**
+ * Contract for providers of bytecode services to Hibernate.
+ * <p/>
+ * Bytecode requirements break down into basically 3 areas<ol>
+ * <li>proxy generation (both for runtime-lazy-loading and basic proxy generation)
+ * {@link #getProxyFactoryFactory()}
+ * <li>bean relection optimization {@link #getReflectionOptimizer}
+ * <li>field-access instumentation {@link #getTransformer}
+ * </ol>
+ *
+ * @author Steve Ebersole
+ */
+public interface BytecodeProvider {
+	/**
+	 * Retrieve the specific factory for this provider capable of
+	 * generating run-time proxies for lazy-loading purposes.
+	 *
+	 * @return The provider specifc factory.
+	 */
+	public ProxyFactoryFactory getProxyFactoryFactory();
+
+	/**
+	 * Retrieve the ReflectionOptimizer delegate for this provider
+	 * capable of generating reflection optimization components.
+	 *
+	 * @param clazz The class to be reflected upon.
+	 * @param getterNames Names of all property getters to be accessed via reflection.
+	 * @param setterNames Names of all property setters to be accessed via reflection.
+	 * @param types The types of all properties to be accessed.
+	 * @return The reflection optimization delegate.
+	 */
+	public ReflectionOptimizer getReflectionOptimizer(Class clazz, String[] getterNames, String[] setterNames, Class[] types);
+
+	/**
+	 * Generate a ClassTransformer capable of performing bytecode manipulation.
+	 *
+	 * @param classFilter filter used to limit which classes are to be instrumented
+	 * via this ClassTransformer.
+	 * @param fieldFilter filter used to limit which fields are to be instrumented
+	 * via this ClassTransformer.
+	 * @return The appropriate ClassTransformer.
+	 */
+	public ClassTransformer getTransformer(ClassFilter classFilter, FieldFilter fieldFilter);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-//$Id: $
-package org.hibernate.bytecode;
-
-import java.security.ProtectionDomain;
-
-/**
- * A persistence provider provides an instance of this interface
- * to the PersistenceUnitInfo.addTransformer method.
- * The supplied transformer instance will get called to transform
- * entity class files when they are loaded and redefined.  The transformation
- * occurs before the class is defined by the JVM
- *
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author Emmanuel Bernard
- */
-public interface ClassTransformer
-{
-   /**
-	* Invoked when a class is being loaded or redefined to add hooks for persistence bytecode manipulation
-	*
-	* @param loader the defining class loaderof the class being transformed.  It may be null if using bootstrap loader
-	* @param classname The name of the class being transformed
-	* @param classBeingRedefined If an already loaded class is being redefined, then pass this as a parameter
-	* @param protectionDomain ProtectionDomain of the class being (re)-defined
-	* @param classfileBuffer The input byte buffer in class file format
-	* @return A well-formed class file that can be loaded
-	*/
-   public byte[] transform(ClassLoader loader,
-					String classname,
-					Class classBeingRedefined,
-					ProtectionDomain protectionDomain,
-					byte[] classfileBuffer);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.bytecode;
+
+import java.security.ProtectionDomain;
+
+/**
+ * A persistence provider provides an instance of this interface
+ * to the PersistenceUnitInfo.addTransformer method.
+ * The supplied transformer instance will get called to transform
+ * entity class files when they are loaded and redefined.  The transformation
+ * occurs before the class is defined by the JVM
+ *
+ *
+ * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @author Emmanuel Bernard
+ */
+public interface ClassTransformer
+{
+   /**
+	* Invoked when a class is being loaded or redefined to add hooks for persistence bytecode manipulation
+	*
+	* @param loader the defining class loaderof the class being transformed.  It may be null if using bootstrap loader
+	* @param classname The name of the class being transformed
+	* @param classBeingRedefined If an already loaded class is being redefined, then pass this as a parameter
+	* @param protectionDomain ProtectionDomain of the class being (re)-defined
+	* @param classfileBuffer The input byte buffer in class file format
+	* @return A well-formed class file that can be loaded
+	*/
+   public byte[] transform(ClassLoader loader,
+					String classname,
+					Class classBeingRedefined,
+					ProtectionDomain protectionDomain,
+					byte[] classfileBuffer);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-package org.hibernate.bytecode;
-
-import org.hibernate.bytecode.util.ByteCodeHelper;
-
-import java.io.InputStream;
-
-/**
- * A specialized classloader which performs bytecode enhancement on class
- * definitions as they are loaded into the classloader scope.
- *
- * @author Emmanuel Bernard
- * @author Steve Ebersole
- */
-public class InstrumentedClassLoader extends ClassLoader {
-
-	private ClassTransformer classTransformer;
-
-	public InstrumentedClassLoader(ClassLoader parent, ClassTransformer classTransformer) {
-		super( parent );
-		this.classTransformer = classTransformer;
-	}
-
-	public Class loadClass(String name) throws ClassNotFoundException {
-		if ( name.startsWith( "java." ) || classTransformer == null ) {
-			return getParent().loadClass( name );
-		}
-
-		Class c = findLoadedClass( name );
-		if ( c != null ) {
-			return c;
-		}
-
-		InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" );
-		if ( is == null ) {
-			throw new ClassNotFoundException( name + " not found" );
-		}
-
-		try {
-			byte[] originalBytecode = ByteCodeHelper.readByteCode( is );
-			byte[] transformedBytecode = classTransformer.transform( getParent(), name, null, null, originalBytecode );
-			if ( originalBytecode == transformedBytecode ) {
-				// no transformations took place, so handle it as we would a
-				// non-instrumented class
-				return getParent().loadClass( name );
-			}
-			else {
-				return defineClass( name, transformedBytecode, 0, transformedBytecode.length );
-			}
-		}
-		catch( Throwable t ) {
-			throw new ClassNotFoundException( name + " not found", t );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/InstrumentedClassLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.bytecode;
+
+import org.hibernate.bytecode.util.ByteCodeHelper;
+
+import java.io.InputStream;
+
+/**
+ * A specialized classloader which performs bytecode enhancement on class
+ * definitions as they are loaded into the classloader scope.
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public class InstrumentedClassLoader extends ClassLoader {
+
+	private ClassTransformer classTransformer;
+
+	public InstrumentedClassLoader(ClassLoader parent, ClassTransformer classTransformer) {
+		super( parent );
+		this.classTransformer = classTransformer;
+	}
+
+	public Class loadClass(String name) throws ClassNotFoundException {
+		if ( name.startsWith( "java." ) || classTransformer == null ) {
+			return getParent().loadClass( name );
+		}
+
+		Class c = findLoadedClass( name );
+		if ( c != null ) {
+			return c;
+		}
+
+		InputStream is = this.getResourceAsStream( name.replace( '.', '/' ) + ".class" );
+		if ( is == null ) {
+			throw new ClassNotFoundException( name + " not found" );
+		}
+
+		try {
+			byte[] originalBytecode = ByteCodeHelper.readByteCode( is );
+			byte[] transformedBytecode = classTransformer.transform( getParent(), name, null, null, originalBytecode );
+			if ( originalBytecode == transformedBytecode ) {
+				// no transformations took place, so handle it as we would a
+				// non-instrumented class
+				return getParent().loadClass( name );
+			}
+			else {
+				return defineClass( name, transformedBytecode, 0, transformedBytecode.length );
+			}
+		}
+		catch( Throwable t ) {
+			throw new ClassNotFoundException( name + " not found", t );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-package org.hibernate.bytecode;
-
-import org.hibernate.proxy.ProxyFactory;
-
-/**
- * An interface for factories of {@link ProxyFactory proxy factory} instances.
- * <p/>
- * Currently used to abstract from the tupizer whether we are using CGLIB or
- * Javassist for lazy proxy generation.
- *
- * @author Steve Ebersole
- */
-public interface ProxyFactoryFactory {
-	/**
-	 * Build a proxy factory specifically for handling runtime
-	 * lazy loading.
-	 *
-	 * @return The lazy-load proxy factory.
-	 */
-	public ProxyFactory buildProxyFactory();
-
-	/**
-	 * Build a proxy factory for basic proxy concerns.  The return
-	 * should be capable of properly handling newInstance() calls.
-	 * <p/>
-	 * Should build basic proxies essentially equivalent to JDK proxies in
-	 * terms of capabilities, but should be able to deal with abstract super
-	 * classes in addition to proxy interfaces.
-	 * <p/>
-	 * Must pass in either superClass or interfaces (or both).
-	 *
-	 * @param superClass The abstract super class (or null if none).
-	 * @param interfaces Interfaces to be proxied (or null if none).
-	 * @return The proxy class
-	 */
-	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ProxyFactoryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode;
+
+import org.hibernate.proxy.ProxyFactory;
+
+/**
+ * An interface for factories of {@link ProxyFactory proxy factory} instances.
+ * <p/>
+ * Currently used to abstract from the tupizer whether we are using CGLIB or
+ * Javassist for lazy proxy generation.
+ *
+ * @author Steve Ebersole
+ */
+public interface ProxyFactoryFactory {
+	/**
+	 * Build a proxy factory specifically for handling runtime
+	 * lazy loading.
+	 *
+	 * @return The lazy-load proxy factory.
+	 */
+	public ProxyFactory buildProxyFactory();
+
+	/**
+	 * Build a proxy factory for basic proxy concerns.  The return
+	 * should be capable of properly handling newInstance() calls.
+	 * <p/>
+	 * Should build basic proxies essentially equivalent to JDK proxies in
+	 * terms of capabilities, but should be able to deal with abstract super
+	 * classes in addition to proxy interfaces.
+	 * <p/>
+	 * Must pass in either superClass or interfaces (or both).
+	 *
+	 * @param superClass The abstract super class (or null if none).
+	 * @param interfaces Interfaces to be proxied (or null if none).
+	 * @return The proxy class
+	 */
+	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-package org.hibernate.bytecode;
-
-/**
- * Represents reflection optimization for a particular class.
- *
- * @author Steve Ebersole
- */
-public interface ReflectionOptimizer {
-
-	public InstantiationOptimizer getInstantiationOptimizer();
-	public AccessOptimizer getAccessOptimizer();
-
-	/**
-	 * Represents optimized entity instantiation.
-	 */
-	public static interface InstantiationOptimizer {
-		/**
-		 * Perform instantiation of an instance of the underlying class.
-		 *
-		 * @return The new instance.
-		 */
-		public Object newInstance();
-	}
-
-	/**
-	 * Represents optimized entity property access.
-	 *
-	 * @author Steve Ebersole
-	 */
-	public interface AccessOptimizer {
-		public String[] getPropertyNames();
-		public Object[] getPropertyValues(Object object);
-		public void setPropertyValues(Object object, Object[] values);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/ReflectionOptimizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode;
+
+/**
+ * Represents reflection optimization for a particular class.
+ *
+ * @author Steve Ebersole
+ */
+public interface ReflectionOptimizer {
+
+	public InstantiationOptimizer getInstantiationOptimizer();
+	public AccessOptimizer getAccessOptimizer();
+
+	/**
+	 * Represents optimized entity instantiation.
+	 */
+	public static interface InstantiationOptimizer {
+		/**
+		 * Perform instantiation of an instance of the underlying class.
+		 *
+		 * @return The new instance.
+		 */
+		public Object newInstance();
+	}
+
+	/**
+	 * Represents optimized entity property access.
+	 *
+	 * @author Steve Ebersole
+	 */
+	public interface AccessOptimizer {
+		public String[] getPropertyNames();
+		public Object[] getPropertyValues(Object object);
+		public void setPropertyValues(Object object, Object[] values);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,101 +0,0 @@
-package org.hibernate.bytecode.cglib;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.PropertyAccessException;
-import org.hibernate.repackage.cglib.beans.BulkBean;
-import org.hibernate.repackage.cglib.beans.BulkBeanException;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * The {@link ReflectionOptimizer.AccessOptimizer} implementation for CGLIB
- * which simply acts as an adpater to the {@link BulkBean} class.
- *
- * @author Steve Ebersole
- */
-public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimizer, Serializable {
-
-	public static final String PROPERTY_GET_EXCEPTION =
-			"exception getting property value with CGLIB (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
-
-	public static final String PROPERTY_SET_EXCEPTION =
-			"exception setting property value with CGLIB (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
-
-	private Class mappedClass;
-	private BulkBean bulkBean;
-
-	public AccessOptimizerAdapter(BulkBean bulkBean, Class mappedClass) {
-		this.bulkBean = bulkBean;
-		this.mappedClass = mappedClass;
-	}
-
-	public String[] getPropertyNames() {
-		return bulkBean.getGetters();
-	}
-
-	public Object[] getPropertyValues(Object object) {
-		try {
-			return bulkBean.getPropertyValues( object );
-		}
-		catch ( Throwable t ) {
-			throw new PropertyAccessException(
-					t,
-			        PROPERTY_GET_EXCEPTION,
-			        false,
-			        mappedClass,
-			        getterName( t, bulkBean )
-			);
-		}
-	}
-
-	public void setPropertyValues(Object object, Object[] values) {
-		try {
-			bulkBean.setPropertyValues( object, values );
-		}
-		catch ( Throwable t ) {
-			throw new PropertyAccessException(
-					t,
-			        PROPERTY_SET_EXCEPTION,
-			        true,
-			        mappedClass,
-			        setterName( t, bulkBean )
-			);
-		}
-	}
-
-	private static String setterName(Throwable t, BulkBean optimizer) {
-		if ( t instanceof BulkBeanException ) {
-			return optimizer.getSetters()[( ( BulkBeanException ) t ).getIndex()];
-		}
-		else {
-			return "?";
-		}
-	}
-
-	private static String getterName(Throwable t, BulkBean optimizer) {
-		if ( t instanceof BulkBeanException ) {
-			return optimizer.getGetters()[( ( BulkBeanException ) t ).getIndex()];
-		}
-		else {
-			return "?";
-		}
-	}
-
-	private void writeObject(ObjectOutputStream out) throws IOException {
-		out.writeObject( mappedClass );
-		out.writeObject( bulkBean.getGetters() );
-		out.writeObject( bulkBean.getSetters() );
-		out.writeObject( bulkBean.getPropertyTypes() );
-	}
-
-	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-		Class beanClass = ( Class ) in.readObject();
-		String[] getters = ( String[] ) in.readObject();
-		String[] setters = ( String[] ) in.readObject();
-		Class[] types = ( Class[] ) in.readObject();
-		bulkBean = BulkBean.create( beanClass, getters, setters, types );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/AccessOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,125 @@
+/*
+ * 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.bytecode.cglib;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.PropertyAccessException;
+import org.hibernate.repackage.cglib.beans.BulkBean;
+import org.hibernate.repackage.cglib.beans.BulkBeanException;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * The {@link ReflectionOptimizer.AccessOptimizer} implementation for CGLIB
+ * which simply acts as an adpater to the {@link BulkBean} class.
+ *
+ * @author Steve Ebersole
+ */
+public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimizer, Serializable {
+
+	public static final String PROPERTY_GET_EXCEPTION =
+			"exception getting property value with CGLIB (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
+
+	public static final String PROPERTY_SET_EXCEPTION =
+			"exception setting property value with CGLIB (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
+
+	private Class mappedClass;
+	private BulkBean bulkBean;
+
+	public AccessOptimizerAdapter(BulkBean bulkBean, Class mappedClass) {
+		this.bulkBean = bulkBean;
+		this.mappedClass = mappedClass;
+	}
+
+	public String[] getPropertyNames() {
+		return bulkBean.getGetters();
+	}
+
+	public Object[] getPropertyValues(Object object) {
+		try {
+			return bulkBean.getPropertyValues( object );
+		}
+		catch ( Throwable t ) {
+			throw new PropertyAccessException(
+					t,
+			        PROPERTY_GET_EXCEPTION,
+			        false,
+			        mappedClass,
+			        getterName( t, bulkBean )
+			);
+		}
+	}
+
+	public void setPropertyValues(Object object, Object[] values) {
+		try {
+			bulkBean.setPropertyValues( object, values );
+		}
+		catch ( Throwable t ) {
+			throw new PropertyAccessException(
+					t,
+			        PROPERTY_SET_EXCEPTION,
+			        true,
+			        mappedClass,
+			        setterName( t, bulkBean )
+			);
+		}
+	}
+
+	private static String setterName(Throwable t, BulkBean optimizer) {
+		if ( t instanceof BulkBeanException ) {
+			return optimizer.getSetters()[( ( BulkBeanException ) t ).getIndex()];
+		}
+		else {
+			return "?";
+		}
+	}
+
+	private static String getterName(Throwable t, BulkBean optimizer) {
+		if ( t instanceof BulkBeanException ) {
+			return optimizer.getGetters()[( ( BulkBeanException ) t ).getIndex()];
+		}
+		else {
+			return "?";
+		}
+	}
+
+	private void writeObject(ObjectOutputStream out) throws IOException {
+		out.writeObject( mappedClass );
+		out.writeObject( bulkBean.getGetters() );
+		out.writeObject( bulkBean.getSetters() );
+		out.writeObject( bulkBean.getPropertyTypes() );
+	}
+
+	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+		Class beanClass = ( Class ) in.readObject();
+		String[] getters = ( String[] ) in.readObject();
+		String[] setters = ( String[] ) in.readObject();
+		Class[] types = ( Class[] ) in.readObject();
+		bulkBean = BulkBean.create( beanClass, getters, setters, types );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,89 +0,0 @@
-package org.hibernate.bytecode.cglib;
-
-import java.lang.reflect.Modifier;
-
-import org.hibernate.repackage.cglib.beans.BulkBean;
-import org.hibernate.repackage.cglib.beans.BulkBeanException;
-import org.hibernate.repackage.cglib.reflect.FastClass;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.bytecode.BytecodeProvider;
-import org.hibernate.bytecode.ProxyFactoryFactory;
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.util.StringHelper;
-
-/**
- * Bytecode provider implementation for CGLIB.
- *
- * @author Steve Ebersole
- */
-public class BytecodeProviderImpl implements BytecodeProvider {
-
-	private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
-
-	public BytecodeProviderImpl() {
-		log.warn( "The CGLIB BytecodeProvider impl is considered deprecated and not recommended for use" );
-	}
-
-	public ProxyFactoryFactory getProxyFactoryFactory() {
-		return new ProxyFactoryFactoryImpl();
-	}
-
-	public ReflectionOptimizer getReflectionOptimizer(
-			Class clazz,
-	        String[] getterNames,
-	        String[] setterNames,
-	        Class[] types) {
-		FastClass fastClass;
-		BulkBean bulkBean;
-		try {
-			fastClass = FastClass.create( clazz );
-			bulkBean = BulkBean.create( clazz, getterNames, setterNames, types );
-			if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
-				if ( fastClass == null ) {
-					bulkBean = null;
-				}
-				else {
-					//test out the optimizer:
-					Object instance = fastClass.newInstance();
-					bulkBean.setPropertyValues( instance, bulkBean.getPropertyValues( instance ) );
-				}
-			}
-		}
-		catch( Throwable t ) {
-			fastClass = null;
-			bulkBean = null;
-			String message = "reflection optimizer disabled for: " +
-			                 clazz.getName() +
-			                 " [" +
-			                 StringHelper.unqualify( t.getClass().getName() ) +
-			                 ": " +
-			                 t.getMessage();
-
-			if (t instanceof BulkBeanException ) {
-				int index = ( (BulkBeanException) t ).getIndex();
-				if (index >= 0) {
-					message += " (property " + setterNames[index] + ")";
-				}
-			}
-
-			log.debug( message );
-		}
-
-		if ( fastClass != null && bulkBean != null ) {
-			return new ReflectionOptimizerImpl(
-					new InstantiationOptimizerAdapter( fastClass ),
-			        new AccessOptimizerAdapter( bulkBean, clazz )
-			);
-		}
-		else {
-			return null;
-		}
-	}
-
-	public org.hibernate.bytecode.ClassTransformer getTransformer(org.hibernate.bytecode.util.ClassFilter classFilter, FieldFilter fieldFilter) {
-		return new CglibClassTransformer( classFilter, fieldFilter );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/BytecodeProviderImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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.bytecode.cglib;
+
+import java.lang.reflect.Modifier;
+
+import org.hibernate.repackage.cglib.beans.BulkBean;
+import org.hibernate.repackage.cglib.beans.BulkBeanException;
+import org.hibernate.repackage.cglib.reflect.FastClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.bytecode.BytecodeProvider;
+import org.hibernate.bytecode.ProxyFactoryFactory;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Bytecode provider implementation for CGLIB.
+ *
+ * @author Steve Ebersole
+ */
+public class BytecodeProviderImpl implements BytecodeProvider {
+
+	private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
+
+	public BytecodeProviderImpl() {
+		log.warn( "The CGLIB BytecodeProvider impl is considered deprecated and not recommended for use" );
+	}
+
+	public ProxyFactoryFactory getProxyFactoryFactory() {
+		return new ProxyFactoryFactoryImpl();
+	}
+
+	public ReflectionOptimizer getReflectionOptimizer(
+			Class clazz,
+	        String[] getterNames,
+	        String[] setterNames,
+	        Class[] types) {
+		FastClass fastClass;
+		BulkBean bulkBean;
+		try {
+			fastClass = FastClass.create( clazz );
+			bulkBean = BulkBean.create( clazz, getterNames, setterNames, types );
+			if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
+				if ( fastClass == null ) {
+					bulkBean = null;
+				}
+				else {
+					//test out the optimizer:
+					Object instance = fastClass.newInstance();
+					bulkBean.setPropertyValues( instance, bulkBean.getPropertyValues( instance ) );
+				}
+			}
+		}
+		catch( Throwable t ) {
+			fastClass = null;
+			bulkBean = null;
+			String message = "reflection optimizer disabled for: " +
+			                 clazz.getName() +
+			                 " [" +
+			                 StringHelper.unqualify( t.getClass().getName() ) +
+			                 ": " +
+			                 t.getMessage();
+
+			if (t instanceof BulkBeanException ) {
+				int index = ( (BulkBeanException) t ).getIndex();
+				if (index >= 0) {
+					message += " (property " + setterNames[index] + ")";
+				}
+			}
+
+			log.debug( message );
+		}
+
+		if ( fastClass != null && bulkBean != null ) {
+			return new ReflectionOptimizerImpl(
+					new InstantiationOptimizerAdapter( fastClass ),
+			        new AccessOptimizerAdapter( bulkBean, clazz )
+			);
+		}
+		else {
+			return null;
+		}
+	}
+
+	public org.hibernate.bytecode.ClassTransformer getTransformer(org.hibernate.bytecode.util.ClassFilter classFilter, FieldFilter fieldFilter) {
+		return new CglibClassTransformer( classFilter, fieldFilter );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,120 +0,0 @@
-//$Id: $
-package org.hibernate.bytecode.cglib;
-
-import java.security.ProtectionDomain;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.ByteArrayOutputStream;
-
-import org.hibernate.repackage.cglib.transform.ClassTransformer;
-import org.hibernate.repackage.cglib.transform.TransformingClassGenerator;
-import org.hibernate.repackage.cglib.transform.ClassReaderGenerator;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldFilter;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldTransformer;
-import org.hibernate.repackage.cglib.core.ClassNameReader;
-import org.hibernate.repackage.cglib.core.DebuggingClassWriter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.bytecode.AbstractClassTransformerImpl;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.bytecode.util.ClassFilter;
-import org.hibernate.HibernateException;
-import org.hibernate.repackage.cglib.asm.Attribute;
-import org.hibernate.repackage.cglib.asm.Type;
-import org.hibernate.repackage.cglib.asm.ClassReader;
-import org.hibernate.repackage.cglib.asm.ClassWriter;
-import org.hibernate.repackage.cglib.asm.attrs.Attributes;
-
-/**
- * Enhance the classes allowing them to implements InterceptFieldEnabled
- * This interface is then used by Hibernate for some optimizations.
- *
- * @author Emmanuel Bernard
- */
-public class CglibClassTransformer extends AbstractClassTransformerImpl {
-
-	private static Logger log = LoggerFactory.getLogger( CglibClassTransformer.class.getName() );
-
-	public CglibClassTransformer(ClassFilter classFilter, FieldFilter fieldFilter) {
-		super( classFilter, fieldFilter );
-	}
-
-	protected byte[] doTransform(
-			ClassLoader loader,
-			String className,
-			Class classBeingRedefined,
-			ProtectionDomain protectionDomain,
-			byte[] classfileBuffer) {
-		ClassReader reader;
-		try {
-			reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) );
-		}
-		catch (IOException e) {
-			log.error( "Unable to read class", e );
-			throw new HibernateException( "Unable to read class: " + e.getMessage() );
-		}
-
-		String[] names = ClassNameReader.getClassInfo( reader );
-		ClassWriter w = new DebuggingClassWriter( true );
-		ClassTransformer t = getClassTransformer( names );
-		if ( t != null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Enhancing " + className );
-			}
-			ByteArrayOutputStream out;
-			byte[] result;
-			try {
-				reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) );
-				new TransformingClassGenerator(
-						new ClassReaderGenerator( reader, attributes(), skipDebug() ), t
-				).generateClass( w );
-				out = new ByteArrayOutputStream();
-				out.write( w.toByteArray() );
-				result = out.toByteArray();
-				out.close();
-			}
-			catch (Exception e) {
-				log.error( "Unable to transform class", e );
-				throw new HibernateException( "Unable to transform class: " + e.getMessage() );
-			}
-			return result;
-		}
-		return classfileBuffer;
-	}
-
-
-	private Attribute[] attributes() {
-		return Attributes.getDefaultAttributes();
-	}
-
-	private boolean skipDebug() {
-		return false;
-	}
-
-	private ClassTransformer getClassTransformer(final String[] classInfo) {
-		if ( isAlreadyInstrumented( classInfo ) ) {
-			return null;
-		}
-		return new InterceptFieldTransformer(
-				new InterceptFieldFilter() {
-					public boolean acceptRead(Type owner, String name) {
-						return fieldFilter.shouldTransformFieldAccess( classInfo[0], owner.getClassName(), name );
-					}
-
-					public boolean acceptWrite(Type owner, String name) {
-						return fieldFilter.shouldTransformFieldAccess( classInfo[0], owner.getClassName(), name );
-					}
-				}
-		);
-	}
-
-	private boolean isAlreadyInstrumented(String[] classInfo) {
-		for ( int i = 1; i < classInfo.length; i++ ) {
-			if ( InterceptFieldEnabled.class.getName().equals( classInfo[i] ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/CglibClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,143 @@
+/*
+ * 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.bytecode.cglib;
+
+import java.security.ProtectionDomain;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+
+import org.hibernate.repackage.cglib.transform.ClassTransformer;
+import org.hibernate.repackage.cglib.transform.TransformingClassGenerator;
+import org.hibernate.repackage.cglib.transform.ClassReaderGenerator;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldFilter;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldTransformer;
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.core.DebuggingClassWriter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.bytecode.AbstractClassTransformerImpl;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.bytecode.util.ClassFilter;
+import org.hibernate.HibernateException;
+import org.hibernate.repackage.cglib.asm.Attribute;
+import org.hibernate.repackage.cglib.asm.Type;
+import org.hibernate.repackage.cglib.asm.ClassReader;
+import org.hibernate.repackage.cglib.asm.ClassWriter;
+import org.hibernate.repackage.cglib.asm.attrs.Attributes;
+
+/**
+ * Enhance the classes allowing them to implements InterceptFieldEnabled
+ * This interface is then used by Hibernate for some optimizations.
+ *
+ * @author Emmanuel Bernard
+ */
+public class CglibClassTransformer extends AbstractClassTransformerImpl {
+
+	private static Logger log = LoggerFactory.getLogger( CglibClassTransformer.class.getName() );
+
+	public CglibClassTransformer(ClassFilter classFilter, FieldFilter fieldFilter) {
+		super( classFilter, fieldFilter );
+	}
+
+	protected byte[] doTransform(
+			ClassLoader loader,
+			String className,
+			Class classBeingRedefined,
+			ProtectionDomain protectionDomain,
+			byte[] classfileBuffer) {
+		ClassReader reader;
+		try {
+			reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) );
+		}
+		catch (IOException e) {
+			log.error( "Unable to read class", e );
+			throw new HibernateException( "Unable to read class: " + e.getMessage() );
+		}
+
+		String[] names = ClassNameReader.getClassInfo( reader );
+		ClassWriter w = new DebuggingClassWriter( true );
+		ClassTransformer t = getClassTransformer( names );
+		if ( t != null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Enhancing " + className );
+			}
+			ByteArrayOutputStream out;
+			byte[] result;
+			try {
+				reader = new ClassReader( new ByteArrayInputStream( classfileBuffer ) );
+				new TransformingClassGenerator(
+						new ClassReaderGenerator( reader, attributes(), skipDebug() ), t
+				).generateClass( w );
+				out = new ByteArrayOutputStream();
+				out.write( w.toByteArray() );
+				result = out.toByteArray();
+				out.close();
+			}
+			catch (Exception e) {
+				log.error( "Unable to transform class", e );
+				throw new HibernateException( "Unable to transform class: " + e.getMessage() );
+			}
+			return result;
+		}
+		return classfileBuffer;
+	}
+
+
+	private Attribute[] attributes() {
+		return Attributes.getDefaultAttributes();
+	}
+
+	private boolean skipDebug() {
+		return false;
+	}
+
+	private ClassTransformer getClassTransformer(final String[] classInfo) {
+		if ( isAlreadyInstrumented( classInfo ) ) {
+			return null;
+		}
+		return new InterceptFieldTransformer(
+				new InterceptFieldFilter() {
+					public boolean acceptRead(Type owner, String name) {
+						return fieldFilter.shouldTransformFieldAccess( classInfo[0], owner.getClassName(), name );
+					}
+
+					public boolean acceptWrite(Type owner, String name) {
+						return fieldFilter.shouldTransformFieldAccess( classInfo[0], owner.getClassName(), name );
+					}
+				}
+		);
+	}
+
+	private boolean isAlreadyInstrumented(String[] classInfo) {
+		for ( int i = 1; i < classInfo.length; i++ ) {
+			if ( InterceptFieldEnabled.class.getName().equals( classInfo[i] ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-package org.hibernate.bytecode.cglib;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.repackage.cglib.reflect.FastClass;
-import org.hibernate.InstantiationException;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * The {@link ReflectionOptimizer.InstantiationOptimizer} implementation for CGLIB
- * which simply acts as an adpater to the {@link FastClass} class.
- *
- * @author Steve Ebersole
- */
-public class InstantiationOptimizerAdapter implements ReflectionOptimizer.InstantiationOptimizer, Serializable {
-	private FastClass fastClass;
-
-	public InstantiationOptimizerAdapter(FastClass fastClass) {
-		this.fastClass = fastClass;
-	}
-
-	public Object newInstance() {
-		try {
-			return fastClass.newInstance();
-		}
-		catch ( Throwable t ) {
-			throw new InstantiationException(
-					"Could not instantiate entity with CGLIB optimizer: ",
-			        fastClass.getJavaClass(),
-			        t
-			);
-		}
-	}
-
-	private void writeObject(ObjectOutputStream out) throws IOException {
-		out.writeObject( fastClass.getJavaClass() );
-	}
-
-	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-		Class beanClass = ( Class ) in.readObject();
-		fastClass = FastClass.create( beanClass );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/InstantiationOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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.bytecode.cglib;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.repackage.cglib.reflect.FastClass;
+import org.hibernate.InstantiationException;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * The {@link ReflectionOptimizer.InstantiationOptimizer} implementation for CGLIB
+ * which simply acts as an adpater to the {@link FastClass} class.
+ *
+ * @author Steve Ebersole
+ */
+public class InstantiationOptimizerAdapter implements ReflectionOptimizer.InstantiationOptimizer, Serializable {
+	private FastClass fastClass;
+
+	public InstantiationOptimizerAdapter(FastClass fastClass) {
+		this.fastClass = fastClass;
+	}
+
+	public Object newInstance() {
+		try {
+			return fastClass.newInstance();
+		}
+		catch ( Throwable t ) {
+			throw new InstantiationException(
+					"Could not instantiate entity with CGLIB optimizer: ",
+			        fastClass.getJavaClass(),
+			        t
+			);
+		}
+	}
+
+	private void writeObject(ObjectOutputStream out) throws IOException {
+		out.writeObject( fastClass.getJavaClass() );
+	}
+
+	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+		Class beanClass = ( Class ) in.readObject();
+		fastClass = FastClass.create( beanClass );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,141 +0,0 @@
-package org.hibernate.bytecode.cglib;
-
-import org.hibernate.bytecode.ProxyFactoryFactory;
-import org.hibernate.bytecode.BasicProxyFactory;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.repackage.cglib.proxy.Enhancer;
-import org.hibernate.repackage.cglib.proxy.CallbackFilter;
-import org.hibernate.repackage.cglib.proxy.MethodInterceptor;
-import org.hibernate.repackage.cglib.proxy.MethodProxy;
-import org.hibernate.repackage.cglib.proxy.NoOp;
-import org.hibernate.repackage.cglib.proxy.Callback;
-import org.hibernate.repackage.cglib.proxy.Factory;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-
-/**
- * A factory for CGLIB-based {@link ProxyFactory} instances.
- *
- * @author Steve Ebersole
- */
-public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
-
-	/**
-	 * Builds a CGLIB-based proxy factory.
-	 *
-	 * @return a new CGLIB-based proxy factory.
-	 */
-	public ProxyFactory buildProxyFactory() {
-		return new CGLIBProxyFactory();
-	}
-
-	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
-		return new BasicProxyFactoryImpl( superClass, interfaces );
-	}
-
-	public static class BasicProxyFactoryImpl implements BasicProxyFactory {
-		private final Class proxyClass;
-		private final Factory factory;
-
-		public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
-			if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
-				throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
-			}
-
-			Enhancer en = new Enhancer();
-			en.setUseCache( false );
-			en.setInterceptDuringConstruction( false );
-			en.setUseFactory( true );
-			en.setCallbackTypes( CALLBACK_TYPES );
-			en.setCallbackFilter( FINALIZE_FILTER );
-			if ( superClass != null ) {
-				en.setSuperclass( superClass );
-			}
-			if ( interfaces != null && interfaces.length > 0 ) {
-				en.setInterfaces( interfaces );
-			}
-			proxyClass = en.createClass();
-			try {
-				factory = ( Factory ) proxyClass.newInstance();
-			}
-			catch ( Throwable t ) {
-				throw new HibernateException( "Unable to build CGLIB Factory instance" );
-			}
-		}
-
-		public Object getProxy() {
-			try {
-				return factory.newInstance(
-						new Callback[] { new PassThroughInterceptor( proxyClass.getName() ), NoOp.INSTANCE }
-				);
-			}
-			catch ( Throwable t ) {
-				throw new HibernateException( "Unable to instantiate proxy instance" );
-			}
-		}
-	}
-
-	private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
-		public int accept(Method method) {
-			if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
-				return 1;
-			}
-			else {
-				return 0;
-			}
-		}
-	};
-
-	private static final Class[] CALLBACK_TYPES = new Class[] { MethodInterceptor.class, NoOp.class };
-
-	private static class PassThroughInterceptor implements MethodInterceptor {
-		private HashMap data = new HashMap();
-		private final String proxiedClassName;
-
-		public PassThroughInterceptor(String proxiedClassName) {
-			this.proxiedClassName = proxiedClassName;
-		}
-
-		public Object intercept(
-				Object obj,
-		        Method method,
-		        Object[] args,
-		        MethodProxy proxy) throws Throwable {
-			String name = method.getName();
-			if ( "toString".equals( name ) ) {
-				return proxiedClassName + "@" + System.identityHashCode( obj );
-			}
-			else if ( "equals".equals( name ) ) {
-				return args[0] instanceof Factory && ( ( Factory ) args[0] ).getCallback( 0 ) == this
-						? Boolean.TRUE
-			            : Boolean.FALSE;
-			}
-			else if ( "hashCode".equals( name ) ) {
-				return new Integer( System.identityHashCode( obj ) );
-			}
-			boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
-			boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
-			if ( name.startsWith( "get" ) && hasGetterSignature ) {
-				String propName = name.substring( 3 );
-				return data.get( propName );
-			}
-			else if ( name.startsWith( "is" ) && hasGetterSignature ) {
-				String propName = name.substring( 2 );
-				return data.get( propName );
-			}
-			else if ( name.startsWith( "set" ) && hasSetterSignature) {
-				String propName = name.substring( 3 );
-				data.put( propName, args[0] );
-				return null;
-			}
-			else {
-				// todo : what else to do here?
-				return null;
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ProxyFactoryFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,165 @@
+/*
+ * 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.bytecode.cglib;
+
+import org.hibernate.bytecode.ProxyFactoryFactory;
+import org.hibernate.bytecode.BasicProxyFactory;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.pojo.cglib.CGLIBProxyFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.repackage.cglib.proxy.Enhancer;
+import org.hibernate.repackage.cglib.proxy.CallbackFilter;
+import org.hibernate.repackage.cglib.proxy.MethodInterceptor;
+import org.hibernate.repackage.cglib.proxy.MethodProxy;
+import org.hibernate.repackage.cglib.proxy.NoOp;
+import org.hibernate.repackage.cglib.proxy.Callback;
+import org.hibernate.repackage.cglib.proxy.Factory;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * A factory for CGLIB-based {@link ProxyFactory} instances.
+ *
+ * @author Steve Ebersole
+ */
+public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
+
+	/**
+	 * Builds a CGLIB-based proxy factory.
+	 *
+	 * @return a new CGLIB-based proxy factory.
+	 */
+	public ProxyFactory buildProxyFactory() {
+		return new CGLIBProxyFactory();
+	}
+
+	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
+		return new BasicProxyFactoryImpl( superClass, interfaces );
+	}
+
+	public static class BasicProxyFactoryImpl implements BasicProxyFactory {
+		private final Class proxyClass;
+		private final Factory factory;
+
+		public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
+			if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
+				throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
+			}
+
+			Enhancer en = new Enhancer();
+			en.setUseCache( false );
+			en.setInterceptDuringConstruction( false );
+			en.setUseFactory( true );
+			en.setCallbackTypes( CALLBACK_TYPES );
+			en.setCallbackFilter( FINALIZE_FILTER );
+			if ( superClass != null ) {
+				en.setSuperclass( superClass );
+			}
+			if ( interfaces != null && interfaces.length > 0 ) {
+				en.setInterfaces( interfaces );
+			}
+			proxyClass = en.createClass();
+			try {
+				factory = ( Factory ) proxyClass.newInstance();
+			}
+			catch ( Throwable t ) {
+				throw new HibernateException( "Unable to build CGLIB Factory instance" );
+			}
+		}
+
+		public Object getProxy() {
+			try {
+				return factory.newInstance(
+						new Callback[] { new PassThroughInterceptor( proxyClass.getName() ), NoOp.INSTANCE }
+				);
+			}
+			catch ( Throwable t ) {
+				throw new HibernateException( "Unable to instantiate proxy instance" );
+			}
+		}
+	}
+
+	private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
+		public int accept(Method method) {
+			if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
+				return 1;
+			}
+			else {
+				return 0;
+			}
+		}
+	};
+
+	private static final Class[] CALLBACK_TYPES = new Class[] { MethodInterceptor.class, NoOp.class };
+
+	private static class PassThroughInterceptor implements MethodInterceptor {
+		private HashMap data = new HashMap();
+		private final String proxiedClassName;
+
+		public PassThroughInterceptor(String proxiedClassName) {
+			this.proxiedClassName = proxiedClassName;
+		}
+
+		public Object intercept(
+				Object obj,
+		        Method method,
+		        Object[] args,
+		        MethodProxy proxy) throws Throwable {
+			String name = method.getName();
+			if ( "toString".equals( name ) ) {
+				return proxiedClassName + "@" + System.identityHashCode( obj );
+			}
+			else if ( "equals".equals( name ) ) {
+				return args[0] instanceof Factory && ( ( Factory ) args[0] ).getCallback( 0 ) == this
+						? Boolean.TRUE
+			            : Boolean.FALSE;
+			}
+			else if ( "hashCode".equals( name ) ) {
+				return new Integer( System.identityHashCode( obj ) );
+			}
+			boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
+			boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
+			if ( name.startsWith( "get" ) && hasGetterSignature ) {
+				String propName = name.substring( 3 );
+				return data.get( propName );
+			}
+			else if ( name.startsWith( "is" ) && hasGetterSignature ) {
+				String propName = name.substring( 2 );
+				return data.get( propName );
+			}
+			else if ( name.startsWith( "set" ) && hasSetterSignature) {
+				String propName = name.substring( 3 );
+				data.put( propName, args[0] );
+				return null;
+			}
+			else {
+				// todo : what else to do here?
+				return null;
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-package org.hibernate.bytecode.cglib;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * ReflectionOptimizer implementation for CGLIB.
- *
- * @author Steve Ebersole
- */
-public class ReflectionOptimizerImpl implements ReflectionOptimizer, Serializable {
-	private transient InstantiationOptimizerAdapter instantiationOptimizer;
-	private transient AccessOptimizerAdapter accessOptimizer;
-
-	public ReflectionOptimizerImpl(
-			InstantiationOptimizerAdapter instantiationOptimizer,
-	        AccessOptimizerAdapter accessOptimizer) {
-		this.instantiationOptimizer = instantiationOptimizer;
-		this.accessOptimizer = accessOptimizer;
-	}
-
-	public InstantiationOptimizer getInstantiationOptimizer() {
-		return instantiationOptimizer;
-	}
-
-	public AccessOptimizer getAccessOptimizer() {
-		return accessOptimizer;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/cglib/ReflectionOptimizerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.cglib;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+
+import java.io.Serializable;
+
+/**
+ * ReflectionOptimizer implementation for CGLIB.
+ *
+ * @author Steve Ebersole
+ */
+public class ReflectionOptimizerImpl implements ReflectionOptimizer, Serializable {
+	private transient InstantiationOptimizerAdapter instantiationOptimizer;
+	private transient AccessOptimizerAdapter accessOptimizer;
+
+	public ReflectionOptimizerImpl(
+			InstantiationOptimizerAdapter instantiationOptimizer,
+	        AccessOptimizerAdapter accessOptimizer) {
+		this.instantiationOptimizer = instantiationOptimizer;
+		this.accessOptimizer = accessOptimizer;
+	}
+
+	public InstantiationOptimizer getInstantiationOptimizer() {
+		return instantiationOptimizer;
+	}
+
+	public AccessOptimizer getAccessOptimizer() {
+		return accessOptimizer;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.PropertyAccessException;
-
-import java.io.Serializable;
-
-/**
- * The {@link ReflectionOptimizer.AccessOptimizer} implementation for Javassist
- * which simply acts as an adpater to the {@link BulkAccessor} class.
- *
- * @author Steve Ebersole
- */
-public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimizer, Serializable {
-
-	public static final String PROPERTY_GET_EXCEPTION =
-		"exception getting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
-
-	public static final String PROPERTY_SET_EXCEPTION =
-		"exception setting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
-
-	private final BulkAccessor bulkAccessor;
-	private final Class mappedClass;
-
-	public AccessOptimizerAdapter(BulkAccessor bulkAccessor, Class mappedClass) {
-		this.bulkAccessor = bulkAccessor;
-		this.mappedClass = mappedClass;
-	}
-
-	public String[] getPropertyNames() {
-		return bulkAccessor.getGetters();
-	}
-
-	public Object[] getPropertyValues(Object object) {
-		try {
-			return bulkAccessor.getPropertyValues( object );
-		}
-		catch ( Throwable t ) {
-			throw new PropertyAccessException(
-					t,
-			        PROPERTY_GET_EXCEPTION,
-			        false,
-			        mappedClass,
-			        getterName( t, bulkAccessor )
-				);
-		}
-	}
-
-	public void setPropertyValues(Object object, Object[] values) {
-		try {
-			bulkAccessor.setPropertyValues( object, values );
-		}
-		catch ( Throwable t ) {
-			throw new PropertyAccessException(
-					t,
-			        PROPERTY_SET_EXCEPTION,
-			        true,
-			        mappedClass,
-			        setterName( t, bulkAccessor )
-			);
-		}
-	}
-
-	private static String setterName(Throwable t, BulkAccessor accessor) {
-		if (t instanceof BulkAccessorException ) {
-			return accessor.getSetters()[ ( (BulkAccessorException) t ).getIndex() ];
-		}
-		else {
-			return "?";
-		}
-	}
-
-	private static String getterName(Throwable t, BulkAccessor accessor) {
-		if (t instanceof BulkAccessorException ) {
-			return accessor.getGetters()[ ( (BulkAccessorException) t ).getIndex() ];
-		}
-		else {
-			return "?";
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/AccessOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.bytecode.javassist;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.PropertyAccessException;
+
+import java.io.Serializable;
+
+/**
+ * The {@link ReflectionOptimizer.AccessOptimizer} implementation for Javassist
+ * which simply acts as an adpater to the {@link BulkAccessor} class.
+ *
+ * @author Steve Ebersole
+ */
+public class AccessOptimizerAdapter implements ReflectionOptimizer.AccessOptimizer, Serializable {
+
+	public static final String PROPERTY_GET_EXCEPTION =
+		"exception getting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
+
+	public static final String PROPERTY_SET_EXCEPTION =
+		"exception setting property value with Javassist (set hibernate.bytecode.use_reflection_optimizer=false for more info)";
+
+	private final BulkAccessor bulkAccessor;
+	private final Class mappedClass;
+
+	public AccessOptimizerAdapter(BulkAccessor bulkAccessor, Class mappedClass) {
+		this.bulkAccessor = bulkAccessor;
+		this.mappedClass = mappedClass;
+	}
+
+	public String[] getPropertyNames() {
+		return bulkAccessor.getGetters();
+	}
+
+	public Object[] getPropertyValues(Object object) {
+		try {
+			return bulkAccessor.getPropertyValues( object );
+		}
+		catch ( Throwable t ) {
+			throw new PropertyAccessException(
+					t,
+			        PROPERTY_GET_EXCEPTION,
+			        false,
+			        mappedClass,
+			        getterName( t, bulkAccessor )
+				);
+		}
+	}
+
+	public void setPropertyValues(Object object, Object[] values) {
+		try {
+			bulkAccessor.setPropertyValues( object, values );
+		}
+		catch ( Throwable t ) {
+			throw new PropertyAccessException(
+					t,
+			        PROPERTY_SET_EXCEPTION,
+			        true,
+			        mappedClass,
+			        setterName( t, bulkAccessor )
+			);
+		}
+	}
+
+	private static String setterName(Throwable t, BulkAccessor accessor) {
+		if (t instanceof BulkAccessorException ) {
+			return accessor.getSetters()[ ( (BulkAccessorException) t ).getIndex() ];
+		}
+		else {
+			return "?";
+		}
+	}
+
+	private static String getterName(Throwable t, BulkAccessor accessor) {
+		if (t instanceof BulkAccessorException ) {
+			return accessor.getGetters()[ ( (BulkAccessorException) t ).getIndex() ];
+		}
+		else {
+			return "?";
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,92 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import java.io.Serializable;
-
-
-/**
- * A JavaBean accessor.
- * <p/>
- * <p>This object provides methods that set/get multiple properties
- * of a JavaBean at once.  This class and its support classes have been
- * developed for the comaptibility with cglib
- * (<tt>http://cglib.sourceforge.net/</tt>).
- *
- * @author Muga Nishizawa
- * @author modified by Shigeru Chiba
- */
-public abstract class BulkAccessor implements Serializable {
-	protected Class target;
-	protected String[] getters, setters;
-	protected Class[] types;
-
-	protected BulkAccessor() {
-	}
-
-	/**
-	 * Obtains the values of properties of a given bean.
-	 *
-	 * @param bean   JavaBean.
-	 * @param values the obtained values are stored in this array.
-	 */
-	public abstract void getPropertyValues(Object bean, Object[] values);
-
-	/**
-	 * Sets properties of a given bean to specified values.
-	 *
-	 * @param bean   JavaBean.
-	 * @param values the values assinged to properties.
-	 */
-	public abstract void setPropertyValues(Object bean, Object[] values);
-
-	/**
-	 * Returns the values of properties of a given bean.
-	 *
-	 * @param bean JavaBean.
-	 */
-	public Object[] getPropertyValues(Object bean) {
-		Object[] values = new Object[getters.length];
-		getPropertyValues( bean, values );
-		return values;
-	}
-
-	/**
-	 * Returns the types of properties.
-	 */
-	public Class[] getPropertyTypes() {
-		return ( Class[] ) types.clone();
-	}
-
-	/**
-	 * Returns the setter names of properties.
-	 */
-	public String[] getGetters() {
-		return ( String[] ) getters.clone();
-	}
-
-	/**
-	 * Returns the getter names of the properties.
-	 */
-	public String[] getSetters() {
-		return ( String[] ) setters.clone();
-	}
-
-	/**
-	 * Creates a new instance of <code>BulkAccessor</code>.
-	 * The created instance provides methods for setting/getting
-	 * specified properties at once.
-	 *
-	 * @param beanClass the class of the JavaBeans accessed
-	 *                  through the created object.
-	 * @param getters   the names of setter methods for specified properties.
-	 * @param setters   the names of getter methods for specified properties.
-	 * @param types     the types of specified properties.
-	 */
-	public static BulkAccessor create(
-			Class beanClass,
-	        String[] getters,
-	        String[] setters,
-	        Class[] types) {
-		BulkAccessorFactory factory = new BulkAccessorFactory( beanClass, getters, setters, types );
-		return factory.create();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.javassist;
+
+import java.io.Serializable;
+
+
+/**
+ * A JavaBean accessor.
+ * <p/>
+ * <p>This object provides methods that set/get multiple properties
+ * of a JavaBean at once.  This class and its support classes have been
+ * developed for the comaptibility with cglib
+ * (<tt>http://cglib.sourceforge.net/</tt>).
+ *
+ * @author Muga Nishizawa
+ * @author modified by Shigeru Chiba
+ */
+public abstract class BulkAccessor implements Serializable {
+	protected Class target;
+	protected String[] getters, setters;
+	protected Class[] types;
+
+	protected BulkAccessor() {
+	}
+
+	/**
+	 * Obtains the values of properties of a given bean.
+	 *
+	 * @param bean   JavaBean.
+	 * @param values the obtained values are stored in this array.
+	 */
+	public abstract void getPropertyValues(Object bean, Object[] values);
+
+	/**
+	 * Sets properties of a given bean to specified values.
+	 *
+	 * @param bean   JavaBean.
+	 * @param values the values assinged to properties.
+	 */
+	public abstract void setPropertyValues(Object bean, Object[] values);
+
+	/**
+	 * Returns the values of properties of a given bean.
+	 *
+	 * @param bean JavaBean.
+	 */
+	public Object[] getPropertyValues(Object bean) {
+		Object[] values = new Object[getters.length];
+		getPropertyValues( bean, values );
+		return values;
+	}
+
+	/**
+	 * Returns the types of properties.
+	 */
+	public Class[] getPropertyTypes() {
+		return ( Class[] ) types.clone();
+	}
+
+	/**
+	 * Returns the setter names of properties.
+	 */
+	public String[] getGetters() {
+		return ( String[] ) getters.clone();
+	}
+
+	/**
+	 * Returns the getter names of the properties.
+	 */
+	public String[] getSetters() {
+		return ( String[] ) setters.clone();
+	}
+
+	/**
+	 * Creates a new instance of <code>BulkAccessor</code>.
+	 * The created instance provides methods for setting/getting
+	 * specified properties at once.
+	 *
+	 * @param beanClass the class of the JavaBeans accessed
+	 *                  through the created object.
+	 * @param getters   the names of setter methods for specified properties.
+	 * @param setters   the names of getter methods for specified properties.
+	 * @param types     the types of specified properties.
+	 */
+	public static BulkAccessor create(
+			Class beanClass,
+	        String[] getters,
+	        String[] setters,
+	        Class[] types) {
+		BulkAccessorFactory factory = new BulkAccessorFactory( beanClass, getters, setters, types );
+		return factory.create();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-/**
- * An exception thrown while generating a bulk accessor.
- * 
- * @author Muga Nishizawa
- * @author modified by Shigeru Chiba
- */
-public class BulkAccessorException extends RuntimeException {
-    private Throwable myCause;
-
-    /**
-     * Gets the cause of this throwable.
-     * It is for JDK 1.3 compatibility.
-     */
-    public Throwable getCause() {
-        return (myCause == this ? null : myCause);
-    }
-
-    /**
-     * Initializes the cause of this throwable.
-     * It is for JDK 1.3 compatibility.
-     */
-    public synchronized Throwable initCause(Throwable cause) {
-        myCause = cause;
-        return this;
-    }
-
-    private int index;
-
-    /**
-     * Constructs an exception.
-     */
-    public BulkAccessorException(String message) {
-        super(message);
-        index = -1;
-        initCause(null);
-    }
-
-    /**
-     * Constructs an exception.
-     *
-     * @param index     the index of the property that causes an exception.
-     */
-    public BulkAccessorException(String message, int index) {
-        this(message + ": " + index);
-        this.index = index;
-    }
-
-    /**
-     * Constructs an exception.
-     */
-    public BulkAccessorException(String message, Throwable cause) {
-        super(message);
-        index = -1;
-        initCause(cause);
-    }
-
-    /**
-     * Constructs an exception.
-     *
-     * @param index     the index of the property that causes an exception.
-     */
-    public BulkAccessorException(Throwable cause, int index) {
-        this("Property " + index);
-        this.index = index;
-        initCause(cause);
-    }
-
-    /**
-     * Returns the index of the property that causes this exception.
-     *
-     * @return -1 if the index is not specified.
-     */
-    public int getIndex() {
-        return this.index;
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.bytecode.javassist;
+
+/**
+ * An exception thrown while generating a bulk accessor.
+ * 
+ * @author Muga Nishizawa
+ * @author modified by Shigeru Chiba
+ */
+public class BulkAccessorException extends RuntimeException {
+    private Throwable myCause;
+
+    /**
+     * Gets the cause of this throwable.
+     * It is for JDK 1.3 compatibility.
+     */
+    public Throwable getCause() {
+        return (myCause == this ? null : myCause);
+    }
+
+    /**
+     * Initializes the cause of this throwable.
+     * It is for JDK 1.3 compatibility.
+     */
+    public synchronized Throwable initCause(Throwable cause) {
+        myCause = cause;
+        return this;
+    }
+
+    private int index;
+
+    /**
+     * Constructs an exception.
+     */
+    public BulkAccessorException(String message) {
+        super(message);
+        index = -1;
+        initCause(null);
+    }
+
+    /**
+     * Constructs an exception.
+     *
+     * @param index     the index of the property that causes an exception.
+     */
+    public BulkAccessorException(String message, int index) {
+        this(message + ": " + index);
+        this.index = index;
+    }
+
+    /**
+     * Constructs an exception.
+     */
+    public BulkAccessorException(String message, Throwable cause) {
+        super(message);
+        index = -1;
+        initCause(cause);
+    }
+
+    /**
+     * Constructs an exception.
+     *
+     * @param index     the index of the property that causes an exception.
+     */
+    public BulkAccessorException(Throwable cause, int index) {
+        this("Property " + index);
+        this.index = index;
+        initCause(cause);
+    }
+
+    /**
+     * Returns the index of the property that causes this exception.
+     *
+     * @return -1 if the index is not specified.
+     */
+    public int getIndex() {
+        return this.index;
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,388 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.security.ProtectionDomain;
-
-import javassist.CannotCompileException;
-import javassist.bytecode.AccessFlag;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.ClassFile;
-import javassist.bytecode.ConstPool;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-import javassist.util.proxy.FactoryHelper;
-import javassist.util.proxy.RuntimeSupport;
-
-/**
- * A factory of bulk accessors.
- *
- * @author Muga Nishizawa
- * @author modified by Shigeru Chiba
- */
-class BulkAccessorFactory {
-	private static final String PACKAGE_NAME_PREFIX = "org.javassist.tmp.";
-	private static final String BULKACESSOR_CLASS_NAME = BulkAccessor.class.getName();
-	private static final String OBJECT_CLASS_NAME = Object.class.getName();
-	private static final String GENERATED_GETTER_NAME = "getPropertyValues";
-	private static final String GENERATED_SETTER_NAME = "setPropertyValues";
-	private static final String GET_SETTER_DESC = "(Ljava/lang/Object;[Ljava/lang/Object;)V";
-	private static final String THROWABLE_CLASS_NAME = Throwable.class.getName();
-	private static final String BULKEXCEPTION_CLASS_NAME = BulkAccessorException.class.getName();
-	private static int counter = 0;
-
-	private Class targetBean;
-	private String[] getterNames;
-	private String[] setterNames;
-	private Class[] types;
-	public String writeDirectory;
-
-	BulkAccessorFactory(
-			Class target,
-	        String[] getterNames,
-	        String[] setterNames,
-	        Class[] types) {
-		this.targetBean = target;
-		this.getterNames = getterNames;
-		this.setterNames = setterNames;
-		this.types = types;
-		this.writeDirectory = null;
-	}
-
-	BulkAccessor create() {
-		Method[] getters = new Method[getterNames.length];
-		Method[] setters = new Method[setterNames.length];
-		findAccessors( targetBean, getterNames, setterNames, types, getters, setters );
-
-		Class beanClass;
-		try {
-			ClassFile classfile = make( getters, setters );
-			ClassLoader loader = this.getClassLoader();
-			if ( writeDirectory != null ) {
-				FactoryHelper.writeFile( classfile, writeDirectory );
-			}
-
-			beanClass = FactoryHelper.toClass( classfile, loader, getDomain() );
-			return ( BulkAccessor ) this.newInstance( beanClass );
-		}
-		catch ( Exception e ) {
-			throw new BulkAccessorException( e.getMessage(), e );
-		}
-	}
-
-	private ProtectionDomain getDomain() {
-		Class cl;
-		if ( this.targetBean != null ) {
-			cl = this.targetBean;
-		}
-		else {
-			cl = this.getClass();
-		}
-		return cl.getProtectionDomain();
-	}
-
-	private ClassFile make(Method[] getters, Method[] setters) throws CannotCompileException {
-		String className = targetBean.getName();
-		// set the name of bulk accessor.
-		className = className + "_$$_bulkaccess_" + counter++;
-		if ( className.startsWith( "java." ) ) {
-			className = "org.javassist.tmp." + className;
-		}
-
-		ClassFile classfile = new ClassFile( false, className, BULKACESSOR_CLASS_NAME );
-		classfile.setAccessFlags( AccessFlag.PUBLIC );
-		addDefaultConstructor( classfile );
-		addGetter( classfile, getters );
-		addSetter( classfile, setters );
-		return classfile;
-	}
-
-	private ClassLoader getClassLoader() {
-		if ( targetBean != null && targetBean.getName().equals( OBJECT_CLASS_NAME ) ) {
-			return targetBean.getClassLoader();
-		}
-		else {
-			return getClass().getClassLoader();
-		}
-	}
-
-	private Object newInstance(Class type) throws Exception {
-		BulkAccessor instance = ( BulkAccessor ) type.newInstance();
-		instance.target = targetBean;
-		int len = getterNames.length;
-		instance.getters = new String[len];
-		instance.setters = new String[len];
-		instance.types = new Class[len];
-		for ( int i = 0; i < len; i++ ) {
-			instance.getters[i] = getterNames[i];
-			instance.setters[i] = setterNames[i];
-			instance.types[i] = types[i];
-		}
-
-		return instance;
-	}
-
-	/**
-	 * Declares a constructor that takes no parameter.
-	 *
-	 * @param classfile
-	 * @throws CannotCompileException
-	 */
-	private void addDefaultConstructor(ClassFile classfile) throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		String cons_desc = "()V";
-		MethodInfo mi = new MethodInfo( cp, MethodInfo.nameInit, cons_desc );
-
-		Bytecode code = new Bytecode( cp, 0, 1 );
-		// aload_0
-		code.addAload( 0 );
-		// invokespecial
-		code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, cons_desc );
-		// return
-		code.addOpcode( Opcode.RETURN );
-
-		mi.setCodeAttribute( code.toCodeAttribute() );
-		mi.setAccessFlags( AccessFlag.PUBLIC );
-		classfile.addMethod( mi );
-	}
-
-	private void addGetter(ClassFile classfile, final Method[] getters) throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int target_type_index = cp.addClassInfo( this.targetBean.getName() );
-		String desc = GET_SETTER_DESC;
-		MethodInfo mi = new MethodInfo( cp, GENERATED_GETTER_NAME, desc );
-
-		Bytecode code = new Bytecode( cp, 6, 4 );
-		/* | this | bean | args | raw bean | */
-		if ( getters.length >= 0 ) {
-			// aload_1 // load bean
-			code.addAload( 1 );
-			// checkcast // cast bean
-			code.addCheckcast( this.targetBean.getName() );
-			// astore_3 // store bean
-			code.addAstore( 3 );
-			for ( int i = 0; i < getters.length; ++i ) {
-				if ( getters[i] != null ) {
-					Method getter = getters[i];
-					// aload_2 // args
-					code.addAload( 2 );
-					// iconst_i // continue to aastore
-					code.addIconst( i ); // growing stack is 1
-					Class returnType = getter.getReturnType();
-					int typeIndex = -1;
-					if ( returnType.isPrimitive() ) {
-						typeIndex = FactoryHelper.typeIndex( returnType );
-						// new
-						code.addNew( FactoryHelper.wrapperTypes[typeIndex] );
-						// dup
-						code.addOpcode( Opcode.DUP );
-					}
-
-					// aload_3 // load the raw bean
-					code.addAload( 3 );
-					String getter_desc = RuntimeSupport.makeDescriptor( getter );
-					String getterName = getter.getName();
-					if ( this.targetBean.isInterface() ) {
-						// invokeinterface
-						code.addInvokeinterface( target_type_index, getterName, getter_desc, 1 );
-					}
-					else {
-						// invokevirtual
-						code.addInvokevirtual( target_type_index, getterName, getter_desc );
-					}
-
-					if ( typeIndex >= 0 ) {       // is a primitive type
-						// invokespecial
-						code.addInvokespecial(
-								FactoryHelper.wrapperTypes[typeIndex],
-						        MethodInfo.nameInit,
-						        FactoryHelper.wrapperDesc[typeIndex]
-						);
-					}
-
-					// aastore // args
-					code.add( Opcode.AASTORE );
-					code.growStack( -3 );
-				}
-			}
-		}
-		// return
-		code.addOpcode( Opcode.RETURN );
-
-		mi.setCodeAttribute( code.toCodeAttribute() );
-		mi.setAccessFlags( AccessFlag.PUBLIC );
-		classfile.addMethod( mi );
-	}
-
-	private void addSetter(ClassFile classfile, final Method[] setters) throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int target_type_index = cp.addClassInfo( this.targetBean.getName() );
-		String desc = GET_SETTER_DESC;
-		MethodInfo mi = new MethodInfo( cp, GENERATED_SETTER_NAME, desc );
-
-		Bytecode code = new Bytecode( cp, 4, 6 );
-		/* | this | bean | args | i | raw bean | exception | */
-		if ( setters.length > 0 ) {
-			int start, end; // required to exception table
-			// iconst_0 // i
-			code.addIconst( 0 );
-			// istore_3 // store i
-			code.addIstore( 3 );
-			// aload_1 // load the bean
-			code.addAload( 1 );
-			// checkcast // cast the bean into a raw bean
-			code.addCheckcast( this.targetBean.getName() );
-			// astore 4 // store the raw bean
-			code.addAstore( 4 );
-			/* current stack len = 0 */
-			// start region to handling exception (BulkAccessorException)
-			start = code.currentPc();
-			int lastIndex = 0;
-			for ( int i = 0; i < setters.length; ++i ) {
-				if ( setters[i] != null ) {
-					int diff = i - lastIndex;
-					if ( diff > 0 ) {
-						// iinc 3, 1
-						code.addOpcode( Opcode.IINC );
-						code.add( 3 );
-						code.add( diff );
-						lastIndex = i;
-					}
-				}
-				/* current stack len = 0 */
-				// aload 4 // load the raw bean
-				code.addAload( 4 );
-				// aload_2 // load the args
-				code.addAload( 2 );
-				// iconst_i
-				code.addIconst( i );
-				// aaload
-				code.addOpcode( Opcode.AALOAD );
-				// checkcast
-				Class[] setterParamTypes = setters[i].getParameterTypes();
-				Class setterParamType = setterParamTypes[0];
-				if ( setterParamType.isPrimitive() ) {
-					// checkcast (case of primitive type)
-					// invokevirtual (case of primitive type)
-					this.addUnwrapper( classfile, code, setterParamType );
-				}
-				else {
-					// checkcast (case of reference type)
-					code.addCheckcast( setterParamType.getName() );
-				}
-				/* current stack len = 2 */
-				String rawSetterMethod_desc = RuntimeSupport.makeDescriptor( setters[i] );
-				if ( !this.targetBean.isInterface() ) {
-					// invokevirtual
-					code.addInvokevirtual( target_type_index, setters[i].getName(), rawSetterMethod_desc );
-				}
-				else {
-					// invokeinterface
-					Class[] params = setters[i].getParameterTypes();
-					int size;
-					if ( params[0].equals( Double.TYPE ) || params[0].equals( Long.TYPE ) ) {
-						size = 3;
-					}
-					else {
-						size = 2;
-					}
-
-					code.addInvokeinterface( target_type_index, setters[i].getName(), rawSetterMethod_desc, size );
-				}
-			}
-
-			// end region to handling exception (BulkAccessorException)
-			end = code.currentPc();
-			// return
-			code.addOpcode( Opcode.RETURN );
-			/* current stack len = 0 */
-			// register in exception table
-			int throwableType_index = cp.addClassInfo( THROWABLE_CLASS_NAME );
-			code.addExceptionHandler( start, end, code.currentPc(), throwableType_index );
-			// astore 5 // store exception
-			code.addAstore( 5 );
-			// new // BulkAccessorException
-			code.addNew( BULKEXCEPTION_CLASS_NAME );
-			// dup
-			code.addOpcode( Opcode.DUP );
-			// aload 5 // load exception
-			code.addAload( 5 );
-			// iload_3 // i
-			code.addIload( 3 );
-			// invokespecial // BulkAccessorException.<init>
-			String cons_desc = "(Ljava/lang/Throwable;I)V";
-			code.addInvokespecial( BULKEXCEPTION_CLASS_NAME, MethodInfo.nameInit, cons_desc );
-			// athrow
-			code.addOpcode( Opcode.ATHROW );
-		}
-		else {
-			// return
-			code.addOpcode( Opcode.RETURN );
-		}
-
-		mi.setCodeAttribute( code.toCodeAttribute() );
-		mi.setAccessFlags( AccessFlag.PUBLIC );
-		classfile.addMethod( mi );
-	}
-
-	private void addUnwrapper(
-			ClassFile classfile,
-	        Bytecode code,
-	        Class type) {
-		int index = FactoryHelper.typeIndex( type );
-		String wrapperType = FactoryHelper.wrapperTypes[index];
-		// checkcast
-		code.addCheckcast( wrapperType );
-		// invokevirtual
-		code.addInvokevirtual( wrapperType, FactoryHelper.unwarpMethods[index], FactoryHelper.unwrapDesc[index] );
-	}
-
-	private static void findAccessors(
-			Class clazz,
-	        String[] getterNames,
-	        String[] setterNames,
-	        Class[] types,
-	        Method[] getters,
-	        Method[] setters) {
-		int length = types.length;
-		if ( setterNames.length != length || getterNames.length != length ) {
-			throw new BulkAccessorException( "bad number of accessors" );
-		}
-
-		Class[] getParam = new Class[0];
-		Class[] setParam = new Class[1];
-		for ( int i = 0; i < length; i++ ) {
-			if ( getterNames[i] != null ) {
-				Method getter = findAccessor( clazz, getterNames[i], getParam, i );
-				if ( getter.getReturnType() != types[i] ) {
-					throw new BulkAccessorException( "wrong return type: " + getterNames[i], i );
-				}
-
-				getters[i] = getter;
-			}
-
-			if ( setterNames[i] != null ) {
-				setParam[0] = types[i];
-				setters[i] = findAccessor( clazz, setterNames[i], setParam, i );
-			}
-		}
-	}
-
-	private static Method findAccessor(
-			Class clazz,
-	        String name,
-	        Class[] params,
-	        int index) throws BulkAccessorException {
-		try {
-			Method method = clazz.getDeclaredMethod( name, params );
-			if ( Modifier.isPrivate( method.getModifiers() ) ) {
-				throw new BulkAccessorException( "private property", index );
-			}
-
-			return method;
-		}
-		catch ( NoSuchMethodException e ) {
-			throw new BulkAccessorException( "cannot find an accessor", index );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BulkAccessorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,412 @@
+/*
+ * 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.bytecode.javassist;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.ProtectionDomain;
+
+import javassist.CannotCompileException;
+import javassist.bytecode.AccessFlag;
+import javassist.bytecode.Bytecode;
+import javassist.bytecode.ClassFile;
+import javassist.bytecode.ConstPool;
+import javassist.bytecode.MethodInfo;
+import javassist.bytecode.Opcode;
+import javassist.util.proxy.FactoryHelper;
+import javassist.util.proxy.RuntimeSupport;
+
+/**
+ * A factory of bulk accessors.
+ *
+ * @author Muga Nishizawa
+ * @author modified by Shigeru Chiba
+ */
+class BulkAccessorFactory {
+	private static final String PACKAGE_NAME_PREFIX = "org.javassist.tmp.";
+	private static final String BULKACESSOR_CLASS_NAME = BulkAccessor.class.getName();
+	private static final String OBJECT_CLASS_NAME = Object.class.getName();
+	private static final String GENERATED_GETTER_NAME = "getPropertyValues";
+	private static final String GENERATED_SETTER_NAME = "setPropertyValues";
+	private static final String GET_SETTER_DESC = "(Ljava/lang/Object;[Ljava/lang/Object;)V";
+	private static final String THROWABLE_CLASS_NAME = Throwable.class.getName();
+	private static final String BULKEXCEPTION_CLASS_NAME = BulkAccessorException.class.getName();
+	private static int counter = 0;
+
+	private Class targetBean;
+	private String[] getterNames;
+	private String[] setterNames;
+	private Class[] types;
+	public String writeDirectory;
+
+	BulkAccessorFactory(
+			Class target,
+	        String[] getterNames,
+	        String[] setterNames,
+	        Class[] types) {
+		this.targetBean = target;
+		this.getterNames = getterNames;
+		this.setterNames = setterNames;
+		this.types = types;
+		this.writeDirectory = null;
+	}
+
+	BulkAccessor create() {
+		Method[] getters = new Method[getterNames.length];
+		Method[] setters = new Method[setterNames.length];
+		findAccessors( targetBean, getterNames, setterNames, types, getters, setters );
+
+		Class beanClass;
+		try {
+			ClassFile classfile = make( getters, setters );
+			ClassLoader loader = this.getClassLoader();
+			if ( writeDirectory != null ) {
+				FactoryHelper.writeFile( classfile, writeDirectory );
+			}
+
+			beanClass = FactoryHelper.toClass( classfile, loader, getDomain() );
+			return ( BulkAccessor ) this.newInstance( beanClass );
+		}
+		catch ( Exception e ) {
+			throw new BulkAccessorException( e.getMessage(), e );
+		}
+	}
+
+	private ProtectionDomain getDomain() {
+		Class cl;
+		if ( this.targetBean != null ) {
+			cl = this.targetBean;
+		}
+		else {
+			cl = this.getClass();
+		}
+		return cl.getProtectionDomain();
+	}
+
+	private ClassFile make(Method[] getters, Method[] setters) throws CannotCompileException {
+		String className = targetBean.getName();
+		// set the name of bulk accessor.
+		className = className + "_$$_bulkaccess_" + counter++;
+		if ( className.startsWith( "java." ) ) {
+			className = "org.javassist.tmp." + className;
+		}
+
+		ClassFile classfile = new ClassFile( false, className, BULKACESSOR_CLASS_NAME );
+		classfile.setAccessFlags( AccessFlag.PUBLIC );
+		addDefaultConstructor( classfile );
+		addGetter( classfile, getters );
+		addSetter( classfile, setters );
+		return classfile;
+	}
+
+	private ClassLoader getClassLoader() {
+		if ( targetBean != null && targetBean.getName().equals( OBJECT_CLASS_NAME ) ) {
+			return targetBean.getClassLoader();
+		}
+		else {
+			return getClass().getClassLoader();
+		}
+	}
+
+	private Object newInstance(Class type) throws Exception {
+		BulkAccessor instance = ( BulkAccessor ) type.newInstance();
+		instance.target = targetBean;
+		int len = getterNames.length;
+		instance.getters = new String[len];
+		instance.setters = new String[len];
+		instance.types = new Class[len];
+		for ( int i = 0; i < len; i++ ) {
+			instance.getters[i] = getterNames[i];
+			instance.setters[i] = setterNames[i];
+			instance.types[i] = types[i];
+		}
+
+		return instance;
+	}
+
+	/**
+	 * Declares a constructor that takes no parameter.
+	 *
+	 * @param classfile
+	 * @throws CannotCompileException
+	 */
+	private void addDefaultConstructor(ClassFile classfile) throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		String cons_desc = "()V";
+		MethodInfo mi = new MethodInfo( cp, MethodInfo.nameInit, cons_desc );
+
+		Bytecode code = new Bytecode( cp, 0, 1 );
+		// aload_0
+		code.addAload( 0 );
+		// invokespecial
+		code.addInvokespecial( BulkAccessor.class.getName(), MethodInfo.nameInit, cons_desc );
+		// return
+		code.addOpcode( Opcode.RETURN );
+
+		mi.setCodeAttribute( code.toCodeAttribute() );
+		mi.setAccessFlags( AccessFlag.PUBLIC );
+		classfile.addMethod( mi );
+	}
+
+	private void addGetter(ClassFile classfile, final Method[] getters) throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int target_type_index = cp.addClassInfo( this.targetBean.getName() );
+		String desc = GET_SETTER_DESC;
+		MethodInfo mi = new MethodInfo( cp, GENERATED_GETTER_NAME, desc );
+
+		Bytecode code = new Bytecode( cp, 6, 4 );
+		/* | this | bean | args | raw bean | */
+		if ( getters.length >= 0 ) {
+			// aload_1 // load bean
+			code.addAload( 1 );
+			// checkcast // cast bean
+			code.addCheckcast( this.targetBean.getName() );
+			// astore_3 // store bean
+			code.addAstore( 3 );
+			for ( int i = 0; i < getters.length; ++i ) {
+				if ( getters[i] != null ) {
+					Method getter = getters[i];
+					// aload_2 // args
+					code.addAload( 2 );
+					// iconst_i // continue to aastore
+					code.addIconst( i ); // growing stack is 1
+					Class returnType = getter.getReturnType();
+					int typeIndex = -1;
+					if ( returnType.isPrimitive() ) {
+						typeIndex = FactoryHelper.typeIndex( returnType );
+						// new
+						code.addNew( FactoryHelper.wrapperTypes[typeIndex] );
+						// dup
+						code.addOpcode( Opcode.DUP );
+					}
+
+					// aload_3 // load the raw bean
+					code.addAload( 3 );
+					String getter_desc = RuntimeSupport.makeDescriptor( getter );
+					String getterName = getter.getName();
+					if ( this.targetBean.isInterface() ) {
+						// invokeinterface
+						code.addInvokeinterface( target_type_index, getterName, getter_desc, 1 );
+					}
+					else {
+						// invokevirtual
+						code.addInvokevirtual( target_type_index, getterName, getter_desc );
+					}
+
+					if ( typeIndex >= 0 ) {       // is a primitive type
+						// invokespecial
+						code.addInvokespecial(
+								FactoryHelper.wrapperTypes[typeIndex],
+						        MethodInfo.nameInit,
+						        FactoryHelper.wrapperDesc[typeIndex]
+						);
+					}
+
+					// aastore // args
+					code.add( Opcode.AASTORE );
+					code.growStack( -3 );
+				}
+			}
+		}
+		// return
+		code.addOpcode( Opcode.RETURN );
+
+		mi.setCodeAttribute( code.toCodeAttribute() );
+		mi.setAccessFlags( AccessFlag.PUBLIC );
+		classfile.addMethod( mi );
+	}
+
+	private void addSetter(ClassFile classfile, final Method[] setters) throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int target_type_index = cp.addClassInfo( this.targetBean.getName() );
+		String desc = GET_SETTER_DESC;
+		MethodInfo mi = new MethodInfo( cp, GENERATED_SETTER_NAME, desc );
+
+		Bytecode code = new Bytecode( cp, 4, 6 );
+		/* | this | bean | args | i | raw bean | exception | */
+		if ( setters.length > 0 ) {
+			int start, end; // required to exception table
+			// iconst_0 // i
+			code.addIconst( 0 );
+			// istore_3 // store i
+			code.addIstore( 3 );
+			// aload_1 // load the bean
+			code.addAload( 1 );
+			// checkcast // cast the bean into a raw bean
+			code.addCheckcast( this.targetBean.getName() );
+			// astore 4 // store the raw bean
+			code.addAstore( 4 );
+			/* current stack len = 0 */
+			// start region to handling exception (BulkAccessorException)
+			start = code.currentPc();
+			int lastIndex = 0;
+			for ( int i = 0; i < setters.length; ++i ) {
+				if ( setters[i] != null ) {
+					int diff = i - lastIndex;
+					if ( diff > 0 ) {
+						// iinc 3, 1
+						code.addOpcode( Opcode.IINC );
+						code.add( 3 );
+						code.add( diff );
+						lastIndex = i;
+					}
+				}
+				/* current stack len = 0 */
+				// aload 4 // load the raw bean
+				code.addAload( 4 );
+				// aload_2 // load the args
+				code.addAload( 2 );
+				// iconst_i
+				code.addIconst( i );
+				// aaload
+				code.addOpcode( Opcode.AALOAD );
+				// checkcast
+				Class[] setterParamTypes = setters[i].getParameterTypes();
+				Class setterParamType = setterParamTypes[0];
+				if ( setterParamType.isPrimitive() ) {
+					// checkcast (case of primitive type)
+					// invokevirtual (case of primitive type)
+					this.addUnwrapper( classfile, code, setterParamType );
+				}
+				else {
+					// checkcast (case of reference type)
+					code.addCheckcast( setterParamType.getName() );
+				}
+				/* current stack len = 2 */
+				String rawSetterMethod_desc = RuntimeSupport.makeDescriptor( setters[i] );
+				if ( !this.targetBean.isInterface() ) {
+					// invokevirtual
+					code.addInvokevirtual( target_type_index, setters[i].getName(), rawSetterMethod_desc );
+				}
+				else {
+					// invokeinterface
+					Class[] params = setters[i].getParameterTypes();
+					int size;
+					if ( params[0].equals( Double.TYPE ) || params[0].equals( Long.TYPE ) ) {
+						size = 3;
+					}
+					else {
+						size = 2;
+					}
+
+					code.addInvokeinterface( target_type_index, setters[i].getName(), rawSetterMethod_desc, size );
+				}
+			}
+
+			// end region to handling exception (BulkAccessorException)
+			end = code.currentPc();
+			// return
+			code.addOpcode( Opcode.RETURN );
+			/* current stack len = 0 */
+			// register in exception table
+			int throwableType_index = cp.addClassInfo( THROWABLE_CLASS_NAME );
+			code.addExceptionHandler( start, end, code.currentPc(), throwableType_index );
+			// astore 5 // store exception
+			code.addAstore( 5 );
+			// new // BulkAccessorException
+			code.addNew( BULKEXCEPTION_CLASS_NAME );
+			// dup
+			code.addOpcode( Opcode.DUP );
+			// aload 5 // load exception
+			code.addAload( 5 );
+			// iload_3 // i
+			code.addIload( 3 );
+			// invokespecial // BulkAccessorException.<init>
+			String cons_desc = "(Ljava/lang/Throwable;I)V";
+			code.addInvokespecial( BULKEXCEPTION_CLASS_NAME, MethodInfo.nameInit, cons_desc );
+			// athrow
+			code.addOpcode( Opcode.ATHROW );
+		}
+		else {
+			// return
+			code.addOpcode( Opcode.RETURN );
+		}
+
+		mi.setCodeAttribute( code.toCodeAttribute() );
+		mi.setAccessFlags( AccessFlag.PUBLIC );
+		classfile.addMethod( mi );
+	}
+
+	private void addUnwrapper(
+			ClassFile classfile,
+	        Bytecode code,
+	        Class type) {
+		int index = FactoryHelper.typeIndex( type );
+		String wrapperType = FactoryHelper.wrapperTypes[index];
+		// checkcast
+		code.addCheckcast( wrapperType );
+		// invokevirtual
+		code.addInvokevirtual( wrapperType, FactoryHelper.unwarpMethods[index], FactoryHelper.unwrapDesc[index] );
+	}
+
+	private static void findAccessors(
+			Class clazz,
+	        String[] getterNames,
+	        String[] setterNames,
+	        Class[] types,
+	        Method[] getters,
+	        Method[] setters) {
+		int length = types.length;
+		if ( setterNames.length != length || getterNames.length != length ) {
+			throw new BulkAccessorException( "bad number of accessors" );
+		}
+
+		Class[] getParam = new Class[0];
+		Class[] setParam = new Class[1];
+		for ( int i = 0; i < length; i++ ) {
+			if ( getterNames[i] != null ) {
+				Method getter = findAccessor( clazz, getterNames[i], getParam, i );
+				if ( getter.getReturnType() != types[i] ) {
+					throw new BulkAccessorException( "wrong return type: " + getterNames[i], i );
+				}
+
+				getters[i] = getter;
+			}
+
+			if ( setterNames[i] != null ) {
+				setParam[0] = types[i];
+				setters[i] = findAccessor( clazz, setterNames[i], setParam, i );
+			}
+		}
+	}
+
+	private static Method findAccessor(
+			Class clazz,
+	        String name,
+	        Class[] params,
+	        int index) throws BulkAccessorException {
+		try {
+			Method method = clazz.getDeclaredMethod( name, params );
+			if ( Modifier.isPrivate( method.getModifiers() ) ) {
+				throw new BulkAccessorException( "private property", index );
+			}
+
+			return method;
+		}
+		catch ( NoSuchMethodException e ) {
+			throw new BulkAccessorException( "cannot find an accessor", index );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,84 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import java.lang.reflect.Modifier;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.bytecode.BytecodeProvider;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.bytecode.ProxyFactoryFactory;
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.bytecode.util.ClassFilter;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.util.StringHelper;
-
-/**
- * Bytecode provider implementation for Javassist.
- *
- * @author Steve Ebersole
- */
-public class BytecodeProviderImpl implements BytecodeProvider {
-
-	private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
-
-	public ProxyFactoryFactory getProxyFactoryFactory() {
-		return new ProxyFactoryFactoryImpl();
-	}
-
-	public ReflectionOptimizer getReflectionOptimizer(
-			Class clazz,
-	        String[] getterNames,
-	        String[] setterNames,
-	        Class[] types) {
-		FastClass fastClass;
-		BulkAccessor bulkAccessor;
-		try {
-			fastClass = FastClass.create( clazz );
-			bulkAccessor = BulkAccessor.create( clazz, getterNames, setterNames, types );
-			if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
-				if ( fastClass == null ) {
-					bulkAccessor = null;
-				}
-				else {
-					//test out the optimizer:
-					Object instance = fastClass.newInstance();
-					bulkAccessor.setPropertyValues( instance, bulkAccessor.getPropertyValues( instance ) );
-				}
-			}
-		}
-		catch ( Throwable t ) {
-			fastClass = null;
-			bulkAccessor = null;
-			String message = "reflection optimizer disabled for: " +
-			                 clazz.getName() +
-			                 " [" +
-			                 StringHelper.unqualify( t.getClass().getName() ) +
-			                 ": " +
-			                 t.getMessage();
-
-			if ( t instanceof BulkAccessorException ) {
-				int index = ( ( BulkAccessorException ) t ).getIndex();
-				if ( index >= 0 ) {
-					message += " (property " + setterNames[index] + ")";
-				}
-			}
-
-			log.debug( message );
-		}
-
-		if ( fastClass != null && bulkAccessor != null ) {
-			return new ReflectionOptimizerImpl(
-					new InstantiationOptimizerAdapter( fastClass ),
-			        new AccessOptimizerAdapter( bulkAccessor, clazz )
-			);
-		}
-		else {
-			return null;
-		}
-	}
-
-	public ClassTransformer getTransformer(ClassFilter classFilter, FieldFilter fieldFilter) {
-		return new JavassistClassTransformer( classFilter, fieldFilter );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/BytecodeProviderImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,108 @@
+/*
+ * 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.bytecode.javassist;
+
+import java.lang.reflect.Modifier;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.bytecode.BytecodeProvider;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.ProxyFactoryFactory;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.bytecode.util.ClassFilter;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Bytecode provider implementation for Javassist.
+ *
+ * @author Steve Ebersole
+ */
+public class BytecodeProviderImpl implements BytecodeProvider {
+
+	private static final Logger log = LoggerFactory.getLogger( BytecodeProviderImpl.class );
+
+	public ProxyFactoryFactory getProxyFactoryFactory() {
+		return new ProxyFactoryFactoryImpl();
+	}
+
+	public ReflectionOptimizer getReflectionOptimizer(
+			Class clazz,
+	        String[] getterNames,
+	        String[] setterNames,
+	        Class[] types) {
+		FastClass fastClass;
+		BulkAccessor bulkAccessor;
+		try {
+			fastClass = FastClass.create( clazz );
+			bulkAccessor = BulkAccessor.create( clazz, getterNames, setterNames, types );
+			if ( !clazz.isInterface() && !Modifier.isAbstract( clazz.getModifiers() ) ) {
+				if ( fastClass == null ) {
+					bulkAccessor = null;
+				}
+				else {
+					//test out the optimizer:
+					Object instance = fastClass.newInstance();
+					bulkAccessor.setPropertyValues( instance, bulkAccessor.getPropertyValues( instance ) );
+				}
+			}
+		}
+		catch ( Throwable t ) {
+			fastClass = null;
+			bulkAccessor = null;
+			String message = "reflection optimizer disabled for: " +
+			                 clazz.getName() +
+			                 " [" +
+			                 StringHelper.unqualify( t.getClass().getName() ) +
+			                 ": " +
+			                 t.getMessage();
+
+			if ( t instanceof BulkAccessorException ) {
+				int index = ( ( BulkAccessorException ) t ).getIndex();
+				if ( index >= 0 ) {
+					message += " (property " + setterNames[index] + ")";
+				}
+			}
+
+			log.debug( message );
+		}
+
+		if ( fastClass != null && bulkAccessor != null ) {
+			return new ReflectionOptimizerImpl(
+					new InstantiationOptimizerAdapter( fastClass ),
+			        new AccessOptimizerAdapter( bulkAccessor, clazz )
+			);
+		}
+		else {
+			return null;
+		}
+	}
+
+	public ClassTransformer getTransformer(ClassFilter classFilter, FieldFilter fieldFilter) {
+		return new JavassistClassTransformer( classFilter, fieldFilter );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,170 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.io.Serializable;
-
-/**
- * @author Muga Nishizawa
- */
-public class FastClass implements Serializable {
-
-	private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
-
-	private Class type;
-
-	private FastClass() {
-	}
-
-	private FastClass(Class type) {
-		this.type = type;
-	}
-
-	public Object invoke(
-			String name,
-	        Class[] parameterTypes,
-	        Object obj,
-	        Object[] args) throws InvocationTargetException {
-		return this.invoke( this.getIndex( name, parameterTypes ), obj, args );
-	}
-
-	public Object invoke(
-			int index,
-	        Object obj,
-	        Object[] args) throws InvocationTargetException {
-		Method[] methods = this.type.getMethods();
-		try {
-			return methods[index].invoke( obj, args );
-		}
-		catch ( ArrayIndexOutOfBoundsException e ) {
-			throw new IllegalArgumentException(
-					"Cannot find matching method/constructor"
-			);
-		}
-		catch ( IllegalAccessException e ) {
-			throw new InvocationTargetException( e );
-		}
-	}
-
-	public Object newInstance() throws InvocationTargetException {
-		return this.newInstance( this.getIndex( EMPTY_CLASS_ARRAY ), null );
-	}
-
-	public Object newInstance(
-			Class[] parameterTypes,
-	        Object[] args) throws InvocationTargetException {
-		return this.newInstance( this.getIndex( parameterTypes ), args );
-	}
-
-	public Object newInstance(
-			int index,
-	        Object[] args) throws InvocationTargetException {
-		Constructor[] conss = this.type.getConstructors();
-		try {
-			return conss[index].newInstance( args );
-		}
-		catch ( ArrayIndexOutOfBoundsException e ) {
-			throw new IllegalArgumentException( "Cannot find matching method/constructor" );
-		}
-		catch ( InstantiationException e ) {
-			throw new InvocationTargetException( e );
-		}
-		catch ( IllegalAccessException e ) {
-			throw new InvocationTargetException( e );
-		}
-	}
-
-	public int getIndex(String name, Class[] parameterTypes) {
-		Method[] methods = this.type.getMethods();
-		boolean eq = true;
-		for ( int i = 0; i < methods.length; ++i ) {
-			if ( !Modifier.isPublic( methods[i].getModifiers() ) ) {
-				continue;
-			}
-			if ( !methods[i].getName().equals( name ) ) {
-				continue;
-			}
-			Class[] params = methods[i].getParameterTypes();
-			if ( params.length != parameterTypes.length ) {
-				continue;
-			}
-			eq = true;
-			for ( int j = 0; j < params.length; ++j ) {
-				if ( !params[j].equals( parameterTypes[j] ) ) {
-					eq = false;
-					break;
-				}
-			}
-			if ( eq ) {
-				return i;
-			}
-		}
-		return -1;
-	}
-
-	public int getIndex(Class[] parameterTypes) {
-		Constructor[] conss = this.type.getConstructors();
-		boolean eq = true;
-		for ( int i = 0; i < conss.length; ++i ) {
-			if ( !Modifier.isPublic( conss[i].getModifiers() ) ) {
-				continue;
-			}
-			Class[] params = conss[i].getParameterTypes();
-			if ( params.length != parameterTypes.length ) {
-				continue;
-			}
-			eq = true;
-			for ( int j = 0; j < params.length; ++j ) {
-				if ( !params[j].equals( parameterTypes[j] ) ) {
-					eq = false;
-					break;
-				}
-			}
-			if ( eq ) {
-				return i;
-			}
-		}
-		return -1;
-	}
-
-	public int getMaxIndex() {
-		Method[] methods = this.type.getMethods();
-		int count = 0;
-		for ( int i = 0; i < methods.length; ++i ) {
-			if ( Modifier.isPublic( methods[i].getModifiers() ) ) {
-				count++;
-			}
-		}
-		return count;
-	}
-
-	public String getName() {
-		return this.type.getName();
-	}
-
-	public Class getJavaClass() {
-		return this.type;
-	}
-
-	public String toString() {
-		return this.type.toString();
-	}
-
-	public int hashCode() {
-		return this.type.hashCode();
-	}
-
-	public boolean equals(Object o) {
-		if (! ( o instanceof FastClass ) ) {
-			return false;
-		}
-		return this.type.equals( ( ( FastClass ) o ).type );
-	}
-
-	public static FastClass create(Class type) {
-		FastClass fc = new FastClass( type );
-		return fc;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FastClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,194 @@
+/*
+ * 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.bytecode.javassist;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.io.Serializable;
+
+/**
+ * @author Muga Nishizawa
+ */
+public class FastClass implements Serializable {
+
+	private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
+
+	private Class type;
+
+	private FastClass() {
+	}
+
+	private FastClass(Class type) {
+		this.type = type;
+	}
+
+	public Object invoke(
+			String name,
+	        Class[] parameterTypes,
+	        Object obj,
+	        Object[] args) throws InvocationTargetException {
+		return this.invoke( this.getIndex( name, parameterTypes ), obj, args );
+	}
+
+	public Object invoke(
+			int index,
+	        Object obj,
+	        Object[] args) throws InvocationTargetException {
+		Method[] methods = this.type.getMethods();
+		try {
+			return methods[index].invoke( obj, args );
+		}
+		catch ( ArrayIndexOutOfBoundsException e ) {
+			throw new IllegalArgumentException(
+					"Cannot find matching method/constructor"
+			);
+		}
+		catch ( IllegalAccessException e ) {
+			throw new InvocationTargetException( e );
+		}
+	}
+
+	public Object newInstance() throws InvocationTargetException {
+		return this.newInstance( this.getIndex( EMPTY_CLASS_ARRAY ), null );
+	}
+
+	public Object newInstance(
+			Class[] parameterTypes,
+	        Object[] args) throws InvocationTargetException {
+		return this.newInstance( this.getIndex( parameterTypes ), args );
+	}
+
+	public Object newInstance(
+			int index,
+	        Object[] args) throws InvocationTargetException {
+		Constructor[] conss = this.type.getConstructors();
+		try {
+			return conss[index].newInstance( args );
+		}
+		catch ( ArrayIndexOutOfBoundsException e ) {
+			throw new IllegalArgumentException( "Cannot find matching method/constructor" );
+		}
+		catch ( InstantiationException e ) {
+			throw new InvocationTargetException( e );
+		}
+		catch ( IllegalAccessException e ) {
+			throw new InvocationTargetException( e );
+		}
+	}
+
+	public int getIndex(String name, Class[] parameterTypes) {
+		Method[] methods = this.type.getMethods();
+		boolean eq = true;
+		for ( int i = 0; i < methods.length; ++i ) {
+			if ( !Modifier.isPublic( methods[i].getModifiers() ) ) {
+				continue;
+			}
+			if ( !methods[i].getName().equals( name ) ) {
+				continue;
+			}
+			Class[] params = methods[i].getParameterTypes();
+			if ( params.length != parameterTypes.length ) {
+				continue;
+			}
+			eq = true;
+			for ( int j = 0; j < params.length; ++j ) {
+				if ( !params[j].equals( parameterTypes[j] ) ) {
+					eq = false;
+					break;
+				}
+			}
+			if ( eq ) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	public int getIndex(Class[] parameterTypes) {
+		Constructor[] conss = this.type.getConstructors();
+		boolean eq = true;
+		for ( int i = 0; i < conss.length; ++i ) {
+			if ( !Modifier.isPublic( conss[i].getModifiers() ) ) {
+				continue;
+			}
+			Class[] params = conss[i].getParameterTypes();
+			if ( params.length != parameterTypes.length ) {
+				continue;
+			}
+			eq = true;
+			for ( int j = 0; j < params.length; ++j ) {
+				if ( !params[j].equals( parameterTypes[j] ) ) {
+					eq = false;
+					break;
+				}
+			}
+			if ( eq ) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	public int getMaxIndex() {
+		Method[] methods = this.type.getMethods();
+		int count = 0;
+		for ( int i = 0; i < methods.length; ++i ) {
+			if ( Modifier.isPublic( methods[i].getModifiers() ) ) {
+				count++;
+			}
+		}
+		return count;
+	}
+
+	public String getName() {
+		return this.type.getName();
+	}
+
+	public Class getJavaClass() {
+		return this.type;
+	}
+
+	public String toString() {
+		return this.type.toString();
+	}
+
+	public int hashCode() {
+		return this.type.hashCode();
+	}
+
+	public boolean equals(Object o) {
+		if (! ( o instanceof FastClass ) ) {
+			return false;
+		}
+		return this.type.equals( ( ( FastClass ) o ).type );
+	}
+
+	public static FastClass create(Class type) {
+		FastClass fc = new FastClass( type );
+		return fc;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-/**
- * Contract for deciding whether fields should be read and/or write intercepted.
- *
- * @author Muga Nishizawa
- * @author Steve Ebersole
- */
-public interface FieldFilter {
-	/**
-	 * Should the given field be read intercepted?
-	 *
-	 * @param desc
-	 * @param name
-	 * @return true if the given field should be read intercepted; otherwise
-	 * false.
-	 */
-	boolean handleRead(String desc, String name);
-
-	/**
-	 * Should the given field be write intercepted?
-	 *
-	 * @param desc
-	 * @param name
-	 * @return true if the given field should be write intercepted; otherwise
-	 * false.
-	 */
-	boolean handleWrite(String desc, String name);
-
-	boolean handleReadAccess(String fieldOwnerClassName, String fieldName);
-
-	boolean handleWriteAccess(String fieldOwnerClassName, String fieldName);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.bytecode.javassist;
+
+/**
+ * Contract for deciding whether fields should be read and/or write intercepted.
+ *
+ * @author Muga Nishizawa
+ * @author Steve Ebersole
+ */
+public interface FieldFilter {
+	/**
+	 * Should the given field be read intercepted?
+	 *
+	 * @param desc
+	 * @param name
+	 * @return true if the given field should be read intercepted; otherwise
+	 * false.
+	 */
+	boolean handleRead(String desc, String name);
+
+	/**
+	 * Should the given field be write intercepted?
+	 *
+	 * @param desc
+	 * @param name
+	 * @return true if the given field should be write intercepted; otherwise
+	 * false.
+	 */
+	boolean handleWrite(String desc, String name);
+
+	boolean handleReadAccess(String fieldOwnerClassName, String fieldName);
+
+	boolean handleWriteAccess(String fieldOwnerClassName, String fieldName);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-/**
- * Interface introduced to the enhanced class in order to be able to
- * inject a {@link FieldHandler} to define the interception behavior.
- *
- * @author Muga Nishizawa
- */
-public interface FieldHandled {
-	/**
-	 * Inject the field interception handler to be used.
-	 *
-	 * @param handler The field interception handler.
-	 */
-	public void setFieldHandler(FieldHandler handler);
-
-	/**
-	 * Access to the current field interception handler.
-	 *
-	 * @return The current field interception handler.
-	 */
-	public FieldHandler getFieldHandler();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandled.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.javassist;
+
+/**
+ * Interface introduced to the enhanced class in order to be able to
+ * inject a {@link FieldHandler} to define the interception behavior.
+ *
+ * @author Muga Nishizawa
+ */
+public interface FieldHandled {
+	/**
+	 * Inject the field interception handler to be used.
+	 *
+	 * @param handler The field interception handler.
+	 */
+	public void setFieldHandler(FieldHandler handler);
+
+	/**
+	 * Access to the current field interception handler.
+	 *
+	 * @return The current field interception handler.
+	 */
+	public FieldHandler getFieldHandler();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,56 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-/**
- * The interface defining how interception of a field should be handled.
- *
- * @author Muga Nishizawa
- */
-public interface FieldHandler {
-
-	/**
-	 * Called to handle writing an int value to a given field.
-	 *
-	 * @param obj ?
-	 * @param name The name of the field being written
-	 * @param oldValue The old field value
-	 * @param newValue The new field value.
-	 * @return ?
-	 */
-	int writeInt(Object obj, String name, int oldValue, int newValue);
-
-	char writeChar(Object obj, String name, char oldValue, char newValue);
-
-	byte writeByte(Object obj, String name, byte oldValue, byte newValue);
-
-	boolean writeBoolean(Object obj, String name, boolean oldValue,
-			boolean newValue);
-
-	short writeShort(Object obj, String name, short oldValue, short newValue);
-
-	float writeFloat(Object obj, String name, float oldValue, float newValue);
-
-	double writeDouble(Object obj, String name, double oldValue, double newValue);
-
-	long writeLong(Object obj, String name, long oldValue, long newValue);
-
-	Object writeObject(Object obj, String name, Object oldValue, Object newValue);
-
-	int readInt(Object obj, String name, int oldValue);
-
-	char readChar(Object obj, String name, char oldValue);
-
-	byte readByte(Object obj, String name, byte oldValue);
-
-	boolean readBoolean(Object obj, String name, boolean oldValue);
-
-	short readShort(Object obj, String name, short oldValue);
-
-	float readFloat(Object obj, String name, float oldValue);
-
-	double readDouble(Object obj, String name, double oldValue);
-
-	long readLong(Object obj, String name, long oldValue);
-
-	Object readObject(Object obj, String name, Object oldValue);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldHandler.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.bytecode.javassist;
+
+/**
+ * The interface defining how interception of a field should be handled.
+ *
+ * @author Muga Nishizawa
+ */
+public interface FieldHandler {
+
+	/**
+	 * Called to handle writing an int value to a given field.
+	 *
+	 * @param obj ?
+	 * @param name The name of the field being written
+	 * @param oldValue The old field value
+	 * @param newValue The new field value.
+	 * @return ?
+	 */
+	int writeInt(Object obj, String name, int oldValue, int newValue);
+
+	char writeChar(Object obj, String name, char oldValue, char newValue);
+
+	byte writeByte(Object obj, String name, byte oldValue, byte newValue);
+
+	boolean writeBoolean(Object obj, String name, boolean oldValue,
+			boolean newValue);
+
+	short writeShort(Object obj, String name, short oldValue, short newValue);
+
+	float writeFloat(Object obj, String name, float oldValue, float newValue);
+
+	double writeDouble(Object obj, String name, double oldValue, double newValue);
+
+	long writeLong(Object obj, String name, long oldValue, long newValue);
+
+	Object writeObject(Object obj, String name, Object oldValue, Object newValue);
+
+	int readInt(Object obj, String name, int oldValue);
+
+	char readChar(Object obj, String name, char oldValue);
+
+	byte readByte(Object obj, String name, byte oldValue);
+
+	boolean readBoolean(Object obj, String name, boolean oldValue);
+
+	short readShort(Object obj, String name, short oldValue);
+
+	float readFloat(Object obj, String name, float oldValue);
+
+	double readDouble(Object obj, String name, double oldValue);
+
+	long readLong(Object obj, String name, long oldValue);
+
+	Object readObject(Object obj, String name, Object oldValue);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,581 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.util.Iterator;
-import java.util.List;
-
-import javassist.CannotCompileException;
-import javassist.bytecode.AccessFlag;
-import javassist.bytecode.BadBytecode;
-import javassist.bytecode.Bytecode;
-import javassist.bytecode.ClassFile;
-import javassist.bytecode.CodeAttribute;
-import javassist.bytecode.CodeIterator;
-import javassist.bytecode.ConstPool;
-import javassist.bytecode.Descriptor;
-import javassist.bytecode.FieldInfo;
-import javassist.bytecode.MethodInfo;
-import javassist.bytecode.Opcode;
-
-/**
- * The thing that handles actual class enhancement in regards to
- * intercepting field accesses.
- *
- * @author Muga Nishizawa
- * @author Steve Ebersole
- */
-public class FieldTransformer {
-
-	private static final String EACH_READ_METHOD_PREFIX = "$javassist_read_";
-
-	private static final String EACH_WRITE_METHOD_PREFIX = "$javassist_write_";
-
-	private static final String FIELD_HANDLED_TYPE_NAME = FieldHandled.class
-			.getName();
-
-	private static final String HANDLER_FIELD_NAME = "$JAVASSIST_READ_WRITE_HANDLER";
-
-	private static final String FIELD_HANDLER_TYPE_NAME = FieldHandler.class
-			.getName();
-
-	private static final String HANDLER_FIELD_DESCRIPTOR = 'L' + FIELD_HANDLER_TYPE_NAME
-			.replace('.', '/') + ';';
-
-	private static final String GETFIELDHANDLER_METHOD_NAME = "getFieldHandler";
-
-	private static final String SETFIELDHANDLER_METHOD_NAME = "setFieldHandler";
-
-	private static final String GETFIELDHANDLER_METHOD_DESCRIPTOR = "()"
-	                                                                + HANDLER_FIELD_DESCRIPTOR;
-
-	private static final String SETFIELDHANDLER_METHOD_DESCRIPTOR = "("
-	                                                                + HANDLER_FIELD_DESCRIPTOR + ")V";
-
-	private FieldFilter filter;
-
-	public FieldTransformer() {
-		this(null);
-	}
-
-	public FieldTransformer(FieldFilter f) {
-		filter = f;
-	}
-
-	public void setFieldFilter(FieldFilter f) {
-		filter = f;
-	}
-
-	public void transform(File file) throws Exception {
-		DataInputStream in = new DataInputStream(new FileInputStream(file));
-		ClassFile classfile = new ClassFile(in);
-		transform(classfile);
-		DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
-		try {
-			classfile.write(out);
-		} finally {
-			out.close();
-		}
-	}
-
-	public void transform(ClassFile classfile) throws Exception {
-		if (classfile.isInterface()) {
-			return;
-		}
-		try {
-			addFieldHandlerField(classfile);
-			addGetFieldHandlerMethod(classfile);
-			addSetFieldHandlerMethod(classfile);
-			addFieldHandledInterface(classfile);
-			addReadWriteMethods(classfile);
-			transformInvokevirtualsIntoPutAndGetfields(classfile);
-		} catch (CannotCompileException e) {
-			throw new RuntimeException(e.getMessage(), e);
-		}
-	}
-
-	private void addFieldHandlerField(ClassFile classfile)
-			throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		FieldInfo finfo = new FieldInfo(cp, HANDLER_FIELD_NAME,
-		                                HANDLER_FIELD_DESCRIPTOR);
-		finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.TRANSIENT);
-		classfile.addField(finfo);
-	}
-
-	private void addGetFieldHandlerMethod(ClassFile classfile)
-			throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int this_class_index = cp.getThisClassInfo();
-		MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME,
-		                                  GETFIELDHANDLER_METHOD_DESCRIPTOR);
-		/* local variable | this | */
-		Bytecode code = new Bytecode(cp, 2, 1);
-		// aload_0 // load this
-		code.addAload(0);
-		// getfield // get field "$JAVASSIST_CALLBACK" defined already
-		code.addOpcode(Opcode.GETFIELD);
-		int field_index = cp.addFieldrefInfo(this_class_index,
-		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
-		code.addIndex(field_index);
-		// areturn // return the value of the field
-		code.addOpcode(Opcode.ARETURN);
-		minfo.setCodeAttribute(code.toCodeAttribute());
-		minfo.setAccessFlags(AccessFlag.PUBLIC);
-		classfile.addMethod(minfo);
-	}
-
-	private void addSetFieldHandlerMethod(ClassFile classfile)
-			throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int this_class_index = cp.getThisClassInfo();
-		MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME,
-		                                  SETFIELDHANDLER_METHOD_DESCRIPTOR);
-		/* local variables | this | callback | */
-		Bytecode code = new Bytecode(cp, 3, 3);
-		// aload_0 // load this
-		code.addAload(0);
-		// aload_1 // load callback
-		code.addAload(1);
-		// putfield // put field "$JAVASSIST_CALLBACK" defined already
-		code.addOpcode(Opcode.PUTFIELD);
-		int field_index = cp.addFieldrefInfo(this_class_index,
-		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
-		code.addIndex(field_index);
-		// return
-		code.addOpcode(Opcode.RETURN);
-		minfo.setCodeAttribute(code.toCodeAttribute());
-		minfo.setAccessFlags(AccessFlag.PUBLIC);
-		classfile.addMethod(minfo);
-	}
-
-	private void addFieldHandledInterface(ClassFile classfile) {
-		String[] interfaceNames = classfile.getInterfaces();
-		String[] newInterfaceNames = new String[interfaceNames.length + 1];
-		System.arraycopy(interfaceNames, 0, newInterfaceNames, 0,
-		                 interfaceNames.length);
-		newInterfaceNames[newInterfaceNames.length - 1] = FIELD_HANDLED_TYPE_NAME;
-		classfile.setInterfaces(newInterfaceNames);
-	}
-
-	private void addReadWriteMethods(ClassFile classfile)
-			throws CannotCompileException {
-		List fields = classfile.getFields();
-		for (Iterator field_iter = fields.iterator(); field_iter.hasNext();) {
-			FieldInfo finfo = (FieldInfo) field_iter.next();
-			if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0
-			    && (!finfo.getName().equals(HANDLER_FIELD_NAME))) {
-				// case of non-static field
-				if (filter.handleRead(finfo.getDescriptor(), finfo
-						.getName())) {
-					addReadMethod(classfile, finfo);
-				}
-				if (filter.handleWrite(finfo.getDescriptor(), finfo
-						.getName())) {
-					addWriteMethod(classfile, finfo);
-				}
-			}
-		}
-	}
-
-	private void addReadMethod(ClassFile classfile, FieldInfo finfo)
-			throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int this_class_index = cp.getThisClassInfo();
-		String desc = "()" + finfo.getDescriptor();
-		MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX
-		                                      + finfo.getName(), desc);
-		/* local variables | target obj | each oldvalue | */
-		Bytecode code = new Bytecode(cp, 5, 3);
-		// aload_0
-		code.addAload(0);
-		// getfield // get each field
-		code.addOpcode(Opcode.GETFIELD);
-		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
-				.getName(), finfo.getDescriptor());
-		code.addIndex(base_field_index);
-		// aload_0
-		code.addAload(0);
-		// invokeinterface // invoke Enabled.getInterceptFieldCallback()
-		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
-		code.addInvokeinterface(enabled_class_index,
-		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
-		                        1);
-		// ifnonnull
-		code.addOpcode(Opcode.IFNONNULL);
-		code.addIndex(4);
-		// *return // each type
-		addTypeDependDataReturn(code, finfo.getDescriptor());
-		// *store_1 // each type
-		addTypeDependDataStore(code, finfo.getDescriptor(), 1);
-		// aload_0
-		code.addAload(0);
-		// invokeinterface // invoke Enabled.getInterceptFieldCallback()
-		code.addInvokeinterface(enabled_class_index,
-		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
-		                        1);
-		// aload_0
-		code.addAload(0);
-		// ldc // name of the field
-		code.addLdc(finfo.getName());
-		// *load_1 // each type
-		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
-		// invokeinterface // invoke Callback.read*() // each type
-		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
-		                            true);
-		// *return // each type
-		addTypeDependDataReturn(code, finfo.getDescriptor());
-
-		minfo.setCodeAttribute(code.toCodeAttribute());
-		minfo.setAccessFlags(AccessFlag.PUBLIC);
-		classfile.addMethod(minfo);
-	}
-
-	private void addWriteMethod(ClassFile classfile, FieldInfo finfo)
-			throws CannotCompileException {
-		ConstPool cp = classfile.getConstPool();
-		int this_class_index = cp.getThisClassInfo();
-		String desc = "(" + finfo.getDescriptor() + ")V";
-		MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX
-		                                      + finfo.getName(), desc);
-		/* local variables | target obj | each oldvalue | */
-		Bytecode code = new Bytecode(cp, 6, 3);
-		// aload_0
-		code.addAload(0);
-		// invokeinterface // enabled.getInterceptFieldCallback()
-		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
-		code.addInvokeinterface(enabled_class_index,
-		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
-		                        1);
-		// ifnonnull (label1)
-		code.addOpcode(Opcode.IFNONNULL);
-		code.addIndex(9);
-		// aload_0
-		code.addAload(0);
-		// *load_1
-		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
-		// putfield
-		code.addOpcode(Opcode.PUTFIELD);
-		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
-				.getName(), finfo.getDescriptor());
-		code.addIndex(base_field_index);
-		code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
-		// return ;
-		code.addOpcode(Opcode.RETURN);
-		// aload_0
-		code.addAload(0);
-		// dup
-		code.addOpcode(Opcode.DUP);
-		// invokeinterface // enabled.getInterceptFieldCallback()
-		code.addInvokeinterface(enabled_class_index,
-		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
-		                        1);
-		// aload_0
-		code.addAload(0);
-		// ldc // field name
-		code.addLdc(finfo.getName());
-		// aload_0
-		code.addAload(0);
-		// getfield // old value of the field
-		code.addOpcode(Opcode.GETFIELD);
-		code.addIndex(base_field_index);
-		code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);
-		// *load_1
-		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
-		// invokeinterface // callback.write*(..)
-		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
-		                            false);
-		// putfield // new value of the field
-		code.addOpcode(Opcode.PUTFIELD);
-		code.addIndex(base_field_index);
-		code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
-		// return
-		code.addOpcode(Opcode.RETURN);
-
-		minfo.setCodeAttribute(code.toCodeAttribute());
-		minfo.setAccessFlags(AccessFlag.PUBLIC);
-		classfile.addMethod(minfo);
-	}
-
-	private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile)
-			throws CannotCompileException {
-		List methods = classfile.getMethods();
-		for (Iterator method_iter = methods.iterator(); method_iter.hasNext();) {
-			MethodInfo minfo = (MethodInfo) method_iter.next();
-			String methodName = minfo.getName();
-			if (methodName.startsWith(EACH_READ_METHOD_PREFIX)
-			    || methodName.startsWith(EACH_WRITE_METHOD_PREFIX)
-			    || methodName.equals(GETFIELDHANDLER_METHOD_NAME)
-			    || methodName.equals(SETFIELDHANDLER_METHOD_NAME)) {
-				continue;
-			}
-			CodeAttribute codeAttr = minfo.getCodeAttribute();
-			if (codeAttr == null) {
-				return;
-			}
-			CodeIterator iter = codeAttr.iterator();
-			while (iter.hasNext()) {
-				try {
-					int pos = iter.next();
-					pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos);
-					pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos);
-
-				} catch (BadBytecode e) {
-					throw new CannotCompileException(e);
-				}
-			}
-		}
-	}
-
-	private int transformInvokevirtualsIntoGetfields(ClassFile classfile, CodeIterator iter, int pos) {
-		ConstPool cp = classfile.getConstPool();
-		int c = iter.byteAt(pos);
-		if (c != Opcode.GETFIELD) {
-			return pos;
-		}
-		int index = iter.u16bitAt(pos + 1);
-		String fieldName = cp.getFieldrefName(index);
-		String className = cp.getFieldrefClassName(index);
-		if ( !filter.handleReadAccess( className, fieldName ) ) {
-			return pos;
-		}
-		String desc = "()" + cp.getFieldrefType( index );
-		int read_method_index = cp.addMethodrefInfo(
-				cp.getThisClassInfo(),
-				EACH_READ_METHOD_PREFIX + fieldName,
-				desc
-		);
-		iter.writeByte(Opcode.INVOKEVIRTUAL, pos);
-		iter.write16bit(read_method_index, pos + 1);
-		return pos;
-	}
-
-	private int transformInvokevirtualsIntoPutfields(
-			ClassFile classfile,
-			CodeIterator iter, int pos) {
-		ConstPool cp = classfile.getConstPool();
-		int c = iter.byteAt(pos);
-		if (c != Opcode.PUTFIELD) {
-			return pos;
-		}
-		int index = iter.u16bitAt(pos + 1);
-		String fieldName = cp.getFieldrefName(index);
-		String className = cp.getFieldrefClassName(index);
-		if ( !filter.handleWriteAccess( className, fieldName ) ) {
-			return pos;
-		}
-		String desc = "(" + cp.getFieldrefType( index ) + ")V";
-		int write_method_index = cp.addMethodrefInfo(
-				cp.getThisClassInfo(),
-				EACH_WRITE_METHOD_PREFIX + fieldName,
-				desc
-		);
-		iter.writeByte(Opcode.INVOKEVIRTUAL, pos);
-		iter.write16bit(write_method_index, pos + 1);
-		return pos;
-	}
-
-	private static void addInvokeFieldHandlerMethod(ClassFile classfile,
-	                                                Bytecode code, String typeName, boolean isReadMethod) {
-		ConstPool cp = classfile.getConstPool();
-		// invokeinterface
-		int callback_type_index = cp.addClassInfo(FIELD_HANDLER_TYPE_NAME);
-		if ((typeName.charAt(0) == 'L')
-		    && (typeName.charAt(typeName.length() - 1) == ';')
-		    || (typeName.charAt(0) == '[')) {
-			// reference type
-			int indexOfL = typeName.indexOf('L');
-			String type;
-			if (indexOfL == 0) {
-				// not array
-				type = typeName.substring(1, typeName.length() - 1);
-				type = type.replace('/', '.');
-			} else if (indexOfL == -1) {
-				// array of primitive type
-				// do nothing
-				type = typeName;
-			} else {
-				// array of reference type
-				type = typeName.replace('/', '.');
-			}
-			if (isReadMethod) {
-				code
-						.addInvokeinterface(
-								callback_type_index,
-								"readObject",
-								"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;",
-								4);
-				// checkcast
-				code.addCheckcast(type);
-			} else {
-				code
-						.addInvokeinterface(
-								callback_type_index,
-								"writeObject",
-								"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
-								5);
-				// checkcast
-				code.addCheckcast(type);
-			}
-		} else if (typeName.equals("Z")) {
-			// boolean
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readBoolean",
-				                        "(Ljava/lang/Object;Ljava/lang/String;Z)Z", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeBoolean",
-				                        "(Ljava/lang/Object;Ljava/lang/String;ZZ)Z", 5);
-			}
-		} else if (typeName.equals("B")) {
-			// byte
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readByte",
-				                        "(Ljava/lang/Object;Ljava/lang/String;B)B", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeByte",
-				                        "(Ljava/lang/Object;Ljava/lang/String;BB)B", 5);
-			}
-		} else if (typeName.equals("C")) {
-			// char
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readChar",
-				                        "(Ljava/lang/Object;Ljava/lang/String;C)C", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeChar",
-				                        "(Ljava/lang/Object;Ljava/lang/String;CC)C", 5);
-			}
-		} else if (typeName.equals("I")) {
-			// int
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readInt",
-				                        "(Ljava/lang/Object;Ljava/lang/String;I)I", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeInt",
-				                        "(Ljava/lang/Object;Ljava/lang/String;II)I", 5);
-			}
-		} else if (typeName.equals("S")) {
-			// short
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readShort",
-				                        "(Ljava/lang/Object;Ljava/lang/String;S)S", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeShort",
-				                        "(Ljava/lang/Object;Ljava/lang/String;SS)S", 5);
-			}
-		} else if (typeName.equals("D")) {
-			// double
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readDouble",
-				                        "(Ljava/lang/Object;Ljava/lang/String;D)D", 5);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeDouble",
-				                        "(Ljava/lang/Object;Ljava/lang/String;DD)D", 7);
-			}
-		} else if (typeName.equals("F")) {
-			// float
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readFloat",
-				                        "(Ljava/lang/Object;Ljava/lang/String;F)F", 4);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeFloat",
-				                        "(Ljava/lang/Object;Ljava/lang/String;FF)F", 5);
-			}
-		} else if (typeName.equals("J")) {
-			// long
-			if (isReadMethod) {
-				code.addInvokeinterface(callback_type_index, "readLong",
-				                        "(Ljava/lang/Object;Ljava/lang/String;J)J", 5);
-			} else {
-				code.addInvokeinterface(callback_type_index, "writeLong",
-				                        "(Ljava/lang/Object;Ljava/lang/String;JJ)J", 7);
-			}
-		} else {
-			// bad type
-			throw new RuntimeException("bad type: " + typeName);
-		}
-	}
-
-	private static void addTypeDependDataLoad(Bytecode code, String typeName,
-	                                          int i) {
-		if ((typeName.charAt(0) == 'L')
-		    && (typeName.charAt(typeName.length() - 1) == ';')
-		    || (typeName.charAt(0) == '[')) {
-			// reference type
-			code.addAload(i);
-		} else if (typeName.equals("Z") || typeName.equals("B")
-		           || typeName.equals("C") || typeName.equals("I")
-		           || typeName.equals("S")) {
-			// boolean, byte, char, int, short
-			code.addIload(i);
-		} else if (typeName.equals("D")) {
-			// double
-			code.addDload(i);
-		} else if (typeName.equals("F")) {
-			// float
-			code.addFload(i);
-		} else if (typeName.equals("J")) {
-			// long
-			code.addLload(i);
-		} else {
-			// bad type
-			throw new RuntimeException("bad type: " + typeName);
-		}
-	}
-
-	private static void addTypeDependDataStore(Bytecode code, String typeName,
-	                                           int i) {
-		if ((typeName.charAt(0) == 'L')
-		    && (typeName.charAt(typeName.length() - 1) == ';')
-		    || (typeName.charAt(0) == '[')) {
-			// reference type
-			code.addAstore(i);
-		} else if (typeName.equals("Z") || typeName.equals("B")
-		           || typeName.equals("C") || typeName.equals("I")
-		           || typeName.equals("S")) {
-			// boolean, byte, char, int, short
-			code.addIstore(i);
-		} else if (typeName.equals("D")) {
-			// double
-			code.addDstore(i);
-		} else if (typeName.equals("F")) {
-			// float
-			code.addFstore(i);
-		} else if (typeName.equals("J")) {
-			// long
-			code.addLstore(i);
-		} else {
-			// bad type
-			throw new RuntimeException("bad type: " + typeName);
-		}
-	}
-
-	private static void addTypeDependDataReturn(Bytecode code, String typeName) {
-		if ((typeName.charAt(0) == 'L')
-		    && (typeName.charAt(typeName.length() - 1) == ';')
-		    || (typeName.charAt(0) == '[')) {
-			// reference type
-			code.addOpcode(Opcode.ARETURN);
-		} else if (typeName.equals("Z") || typeName.equals("B")
-		           || typeName.equals("C") || typeName.equals("I")
-		           || typeName.equals("S")) {
-			// boolean, byte, char, int, short
-			code.addOpcode(Opcode.IRETURN);
-		} else if (typeName.equals("D")) {
-			// double
-			code.addOpcode(Opcode.DRETURN);
-		} else if (typeName.equals("F")) {
-			// float
-			code.addOpcode(Opcode.FRETURN);
-		} else if (typeName.equals("J")) {
-			// long
-			code.addOpcode(Opcode.LRETURN);
-		} else {
-			// bad type
-			throw new RuntimeException("bad type: " + typeName);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/FieldTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,605 @@
+/*
+ * 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.bytecode.javassist;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.util.Iterator;
+import java.util.List;
+
+import javassist.CannotCompileException;
+import javassist.bytecode.AccessFlag;
+import javassist.bytecode.BadBytecode;
+import javassist.bytecode.Bytecode;
+import javassist.bytecode.ClassFile;
+import javassist.bytecode.CodeAttribute;
+import javassist.bytecode.CodeIterator;
+import javassist.bytecode.ConstPool;
+import javassist.bytecode.Descriptor;
+import javassist.bytecode.FieldInfo;
+import javassist.bytecode.MethodInfo;
+import javassist.bytecode.Opcode;
+
+/**
+ * The thing that handles actual class enhancement in regards to
+ * intercepting field accesses.
+ *
+ * @author Muga Nishizawa
+ * @author Steve Ebersole
+ */
+public class FieldTransformer {
+
+	private static final String EACH_READ_METHOD_PREFIX = "$javassist_read_";
+
+	private static final String EACH_WRITE_METHOD_PREFIX = "$javassist_write_";
+
+	private static final String FIELD_HANDLED_TYPE_NAME = FieldHandled.class
+			.getName();
+
+	private static final String HANDLER_FIELD_NAME = "$JAVASSIST_READ_WRITE_HANDLER";
+
+	private static final String FIELD_HANDLER_TYPE_NAME = FieldHandler.class
+			.getName();
+
+	private static final String HANDLER_FIELD_DESCRIPTOR = 'L' + FIELD_HANDLER_TYPE_NAME
+			.replace('.', '/') + ';';
+
+	private static final String GETFIELDHANDLER_METHOD_NAME = "getFieldHandler";
+
+	private static final String SETFIELDHANDLER_METHOD_NAME = "setFieldHandler";
+
+	private static final String GETFIELDHANDLER_METHOD_DESCRIPTOR = "()"
+	                                                                + HANDLER_FIELD_DESCRIPTOR;
+
+	private static final String SETFIELDHANDLER_METHOD_DESCRIPTOR = "("
+	                                                                + HANDLER_FIELD_DESCRIPTOR + ")V";
+
+	private FieldFilter filter;
+
+	public FieldTransformer() {
+		this(null);
+	}
+
+	public FieldTransformer(FieldFilter f) {
+		filter = f;
+	}
+
+	public void setFieldFilter(FieldFilter f) {
+		filter = f;
+	}
+
+	public void transform(File file) throws Exception {
+		DataInputStream in = new DataInputStream(new FileInputStream(file));
+		ClassFile classfile = new ClassFile(in);
+		transform(classfile);
+		DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
+		try {
+			classfile.write(out);
+		} finally {
+			out.close();
+		}
+	}
+
+	public void transform(ClassFile classfile) throws Exception {
+		if (classfile.isInterface()) {
+			return;
+		}
+		try {
+			addFieldHandlerField(classfile);
+			addGetFieldHandlerMethod(classfile);
+			addSetFieldHandlerMethod(classfile);
+			addFieldHandledInterface(classfile);
+			addReadWriteMethods(classfile);
+			transformInvokevirtualsIntoPutAndGetfields(classfile);
+		} catch (CannotCompileException e) {
+			throw new RuntimeException(e.getMessage(), e);
+		}
+	}
+
+	private void addFieldHandlerField(ClassFile classfile)
+			throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		FieldInfo finfo = new FieldInfo(cp, HANDLER_FIELD_NAME,
+		                                HANDLER_FIELD_DESCRIPTOR);
+		finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.TRANSIENT);
+		classfile.addField(finfo);
+	}
+
+	private void addGetFieldHandlerMethod(ClassFile classfile)
+			throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int this_class_index = cp.getThisClassInfo();
+		MethodInfo minfo = new MethodInfo(cp, GETFIELDHANDLER_METHOD_NAME,
+		                                  GETFIELDHANDLER_METHOD_DESCRIPTOR);
+		/* local variable | this | */
+		Bytecode code = new Bytecode(cp, 2, 1);
+		// aload_0 // load this
+		code.addAload(0);
+		// getfield // get field "$JAVASSIST_CALLBACK" defined already
+		code.addOpcode(Opcode.GETFIELD);
+		int field_index = cp.addFieldrefInfo(this_class_index,
+		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
+		code.addIndex(field_index);
+		// areturn // return the value of the field
+		code.addOpcode(Opcode.ARETURN);
+		minfo.setCodeAttribute(code.toCodeAttribute());
+		minfo.setAccessFlags(AccessFlag.PUBLIC);
+		classfile.addMethod(minfo);
+	}
+
+	private void addSetFieldHandlerMethod(ClassFile classfile)
+			throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int this_class_index = cp.getThisClassInfo();
+		MethodInfo minfo = new MethodInfo(cp, SETFIELDHANDLER_METHOD_NAME,
+		                                  SETFIELDHANDLER_METHOD_DESCRIPTOR);
+		/* local variables | this | callback | */
+		Bytecode code = new Bytecode(cp, 3, 3);
+		// aload_0 // load this
+		code.addAload(0);
+		// aload_1 // load callback
+		code.addAload(1);
+		// putfield // put field "$JAVASSIST_CALLBACK" defined already
+		code.addOpcode(Opcode.PUTFIELD);
+		int field_index = cp.addFieldrefInfo(this_class_index,
+		                                     HANDLER_FIELD_NAME, HANDLER_FIELD_DESCRIPTOR);
+		code.addIndex(field_index);
+		// return
+		code.addOpcode(Opcode.RETURN);
+		minfo.setCodeAttribute(code.toCodeAttribute());
+		minfo.setAccessFlags(AccessFlag.PUBLIC);
+		classfile.addMethod(minfo);
+	}
+
+	private void addFieldHandledInterface(ClassFile classfile) {
+		String[] interfaceNames = classfile.getInterfaces();
+		String[] newInterfaceNames = new String[interfaceNames.length + 1];
+		System.arraycopy(interfaceNames, 0, newInterfaceNames, 0,
+		                 interfaceNames.length);
+		newInterfaceNames[newInterfaceNames.length - 1] = FIELD_HANDLED_TYPE_NAME;
+		classfile.setInterfaces(newInterfaceNames);
+	}
+
+	private void addReadWriteMethods(ClassFile classfile)
+			throws CannotCompileException {
+		List fields = classfile.getFields();
+		for (Iterator field_iter = fields.iterator(); field_iter.hasNext();) {
+			FieldInfo finfo = (FieldInfo) field_iter.next();
+			if ((finfo.getAccessFlags() & AccessFlag.STATIC) == 0
+			    && (!finfo.getName().equals(HANDLER_FIELD_NAME))) {
+				// case of non-static field
+				if (filter.handleRead(finfo.getDescriptor(), finfo
+						.getName())) {
+					addReadMethod(classfile, finfo);
+				}
+				if (filter.handleWrite(finfo.getDescriptor(), finfo
+						.getName())) {
+					addWriteMethod(classfile, finfo);
+				}
+			}
+		}
+	}
+
+	private void addReadMethod(ClassFile classfile, FieldInfo finfo)
+			throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int this_class_index = cp.getThisClassInfo();
+		String desc = "()" + finfo.getDescriptor();
+		MethodInfo minfo = new MethodInfo(cp, EACH_READ_METHOD_PREFIX
+		                                      + finfo.getName(), desc);
+		/* local variables | target obj | each oldvalue | */
+		Bytecode code = new Bytecode(cp, 5, 3);
+		// aload_0
+		code.addAload(0);
+		// getfield // get each field
+		code.addOpcode(Opcode.GETFIELD);
+		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
+				.getName(), finfo.getDescriptor());
+		code.addIndex(base_field_index);
+		// aload_0
+		code.addAload(0);
+		// invokeinterface // invoke Enabled.getInterceptFieldCallback()
+		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
+		code.addInvokeinterface(enabled_class_index,
+		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
+		                        1);
+		// ifnonnull
+		code.addOpcode(Opcode.IFNONNULL);
+		code.addIndex(4);
+		// *return // each type
+		addTypeDependDataReturn(code, finfo.getDescriptor());
+		// *store_1 // each type
+		addTypeDependDataStore(code, finfo.getDescriptor(), 1);
+		// aload_0
+		code.addAload(0);
+		// invokeinterface // invoke Enabled.getInterceptFieldCallback()
+		code.addInvokeinterface(enabled_class_index,
+		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
+		                        1);
+		// aload_0
+		code.addAload(0);
+		// ldc // name of the field
+		code.addLdc(finfo.getName());
+		// *load_1 // each type
+		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
+		// invokeinterface // invoke Callback.read*() // each type
+		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
+		                            true);
+		// *return // each type
+		addTypeDependDataReturn(code, finfo.getDescriptor());
+
+		minfo.setCodeAttribute(code.toCodeAttribute());
+		minfo.setAccessFlags(AccessFlag.PUBLIC);
+		classfile.addMethod(minfo);
+	}
+
+	private void addWriteMethod(ClassFile classfile, FieldInfo finfo)
+			throws CannotCompileException {
+		ConstPool cp = classfile.getConstPool();
+		int this_class_index = cp.getThisClassInfo();
+		String desc = "(" + finfo.getDescriptor() + ")V";
+		MethodInfo minfo = new MethodInfo(cp, EACH_WRITE_METHOD_PREFIX
+		                                      + finfo.getName(), desc);
+		/* local variables | target obj | each oldvalue | */
+		Bytecode code = new Bytecode(cp, 6, 3);
+		// aload_0
+		code.addAload(0);
+		// invokeinterface // enabled.getInterceptFieldCallback()
+		int enabled_class_index = cp.addClassInfo(FIELD_HANDLED_TYPE_NAME);
+		code.addInvokeinterface(enabled_class_index,
+		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
+		                        1);
+		// ifnonnull (label1)
+		code.addOpcode(Opcode.IFNONNULL);
+		code.addIndex(9);
+		// aload_0
+		code.addAload(0);
+		// *load_1
+		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
+		// putfield
+		code.addOpcode(Opcode.PUTFIELD);
+		int base_field_index = cp.addFieldrefInfo(this_class_index, finfo
+				.getName(), finfo.getDescriptor());
+		code.addIndex(base_field_index);
+		code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
+		// return ;
+		code.addOpcode(Opcode.RETURN);
+		// aload_0
+		code.addAload(0);
+		// dup
+		code.addOpcode(Opcode.DUP);
+		// invokeinterface // enabled.getInterceptFieldCallback()
+		code.addInvokeinterface(enabled_class_index,
+		                        GETFIELDHANDLER_METHOD_NAME, GETFIELDHANDLER_METHOD_DESCRIPTOR,
+		                        1);
+		// aload_0
+		code.addAload(0);
+		// ldc // field name
+		code.addLdc(finfo.getName());
+		// aload_0
+		code.addAload(0);
+		// getfield // old value of the field
+		code.addOpcode(Opcode.GETFIELD);
+		code.addIndex(base_field_index);
+		code.growStack(Descriptor.dataSize(finfo.getDescriptor()) - 1);
+		// *load_1
+		addTypeDependDataLoad(code, finfo.getDescriptor(), 1);
+		// invokeinterface // callback.write*(..)
+		addInvokeFieldHandlerMethod(classfile, code, finfo.getDescriptor(),
+		                            false);
+		// putfield // new value of the field
+		code.addOpcode(Opcode.PUTFIELD);
+		code.addIndex(base_field_index);
+		code.growStack(-Descriptor.dataSize(finfo.getDescriptor()));
+		// return
+		code.addOpcode(Opcode.RETURN);
+
+		minfo.setCodeAttribute(code.toCodeAttribute());
+		minfo.setAccessFlags(AccessFlag.PUBLIC);
+		classfile.addMethod(minfo);
+	}
+
+	private void transformInvokevirtualsIntoPutAndGetfields(ClassFile classfile)
+			throws CannotCompileException {
+		List methods = classfile.getMethods();
+		for (Iterator method_iter = methods.iterator(); method_iter.hasNext();) {
+			MethodInfo minfo = (MethodInfo) method_iter.next();
+			String methodName = minfo.getName();
+			if (methodName.startsWith(EACH_READ_METHOD_PREFIX)
+			    || methodName.startsWith(EACH_WRITE_METHOD_PREFIX)
+			    || methodName.equals(GETFIELDHANDLER_METHOD_NAME)
+			    || methodName.equals(SETFIELDHANDLER_METHOD_NAME)) {
+				continue;
+			}
+			CodeAttribute codeAttr = minfo.getCodeAttribute();
+			if (codeAttr == null) {
+				return;
+			}
+			CodeIterator iter = codeAttr.iterator();
+			while (iter.hasNext()) {
+				try {
+					int pos = iter.next();
+					pos = transformInvokevirtualsIntoGetfields(classfile, iter, pos);
+					pos = transformInvokevirtualsIntoPutfields(classfile, iter, pos);
+
+				} catch (BadBytecode e) {
+					throw new CannotCompileException(e);
+				}
+			}
+		}
+	}
+
+	private int transformInvokevirtualsIntoGetfields(ClassFile classfile, CodeIterator iter, int pos) {
+		ConstPool cp = classfile.getConstPool();
+		int c = iter.byteAt(pos);
+		if (c != Opcode.GETFIELD) {
+			return pos;
+		}
+		int index = iter.u16bitAt(pos + 1);
+		String fieldName = cp.getFieldrefName(index);
+		String className = cp.getFieldrefClassName(index);
+		if ( !filter.handleReadAccess( className, fieldName ) ) {
+			return pos;
+		}
+		String desc = "()" + cp.getFieldrefType( index );
+		int read_method_index = cp.addMethodrefInfo(
+				cp.getThisClassInfo(),
+				EACH_READ_METHOD_PREFIX + fieldName,
+				desc
+		);
+		iter.writeByte(Opcode.INVOKEVIRTUAL, pos);
+		iter.write16bit(read_method_index, pos + 1);
+		return pos;
+	}
+
+	private int transformInvokevirtualsIntoPutfields(
+			ClassFile classfile,
+			CodeIterator iter, int pos) {
+		ConstPool cp = classfile.getConstPool();
+		int c = iter.byteAt(pos);
+		if (c != Opcode.PUTFIELD) {
+			return pos;
+		}
+		int index = iter.u16bitAt(pos + 1);
+		String fieldName = cp.getFieldrefName(index);
+		String className = cp.getFieldrefClassName(index);
+		if ( !filter.handleWriteAccess( className, fieldName ) ) {
+			return pos;
+		}
+		String desc = "(" + cp.getFieldrefType( index ) + ")V";
+		int write_method_index = cp.addMethodrefInfo(
+				cp.getThisClassInfo(),
+				EACH_WRITE_METHOD_PREFIX + fieldName,
+				desc
+		);
+		iter.writeByte(Opcode.INVOKEVIRTUAL, pos);
+		iter.write16bit(write_method_index, pos + 1);
+		return pos;
+	}
+
+	private static void addInvokeFieldHandlerMethod(ClassFile classfile,
+	                                                Bytecode code, String typeName, boolean isReadMethod) {
+		ConstPool cp = classfile.getConstPool();
+		// invokeinterface
+		int callback_type_index = cp.addClassInfo(FIELD_HANDLER_TYPE_NAME);
+		if ((typeName.charAt(0) == 'L')
+		    && (typeName.charAt(typeName.length() - 1) == ';')
+		    || (typeName.charAt(0) == '[')) {
+			// reference type
+			int indexOfL = typeName.indexOf('L');
+			String type;
+			if (indexOfL == 0) {
+				// not array
+				type = typeName.substring(1, typeName.length() - 1);
+				type = type.replace('/', '.');
+			} else if (indexOfL == -1) {
+				// array of primitive type
+				// do nothing
+				type = typeName;
+			} else {
+				// array of reference type
+				type = typeName.replace('/', '.');
+			}
+			if (isReadMethod) {
+				code
+						.addInvokeinterface(
+								callback_type_index,
+								"readObject",
+								"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;",
+								4);
+				// checkcast
+				code.addCheckcast(type);
+			} else {
+				code
+						.addInvokeinterface(
+								callback_type_index,
+								"writeObject",
+								"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
+								5);
+				// checkcast
+				code.addCheckcast(type);
+			}
+		} else if (typeName.equals("Z")) {
+			// boolean
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readBoolean",
+				                        "(Ljava/lang/Object;Ljava/lang/String;Z)Z", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeBoolean",
+				                        "(Ljava/lang/Object;Ljava/lang/String;ZZ)Z", 5);
+			}
+		} else if (typeName.equals("B")) {
+			// byte
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readByte",
+				                        "(Ljava/lang/Object;Ljava/lang/String;B)B", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeByte",
+				                        "(Ljava/lang/Object;Ljava/lang/String;BB)B", 5);
+			}
+		} else if (typeName.equals("C")) {
+			// char
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readChar",
+				                        "(Ljava/lang/Object;Ljava/lang/String;C)C", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeChar",
+				                        "(Ljava/lang/Object;Ljava/lang/String;CC)C", 5);
+			}
+		} else if (typeName.equals("I")) {
+			// int
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readInt",
+				                        "(Ljava/lang/Object;Ljava/lang/String;I)I", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeInt",
+				                        "(Ljava/lang/Object;Ljava/lang/String;II)I", 5);
+			}
+		} else if (typeName.equals("S")) {
+			// short
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readShort",
+				                        "(Ljava/lang/Object;Ljava/lang/String;S)S", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeShort",
+				                        "(Ljava/lang/Object;Ljava/lang/String;SS)S", 5);
+			}
+		} else if (typeName.equals("D")) {
+			// double
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readDouble",
+				                        "(Ljava/lang/Object;Ljava/lang/String;D)D", 5);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeDouble",
+				                        "(Ljava/lang/Object;Ljava/lang/String;DD)D", 7);
+			}
+		} else if (typeName.equals("F")) {
+			// float
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readFloat",
+				                        "(Ljava/lang/Object;Ljava/lang/String;F)F", 4);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeFloat",
+				                        "(Ljava/lang/Object;Ljava/lang/String;FF)F", 5);
+			}
+		} else if (typeName.equals("J")) {
+			// long
+			if (isReadMethod) {
+				code.addInvokeinterface(callback_type_index, "readLong",
+				                        "(Ljava/lang/Object;Ljava/lang/String;J)J", 5);
+			} else {
+				code.addInvokeinterface(callback_type_index, "writeLong",
+				                        "(Ljava/lang/Object;Ljava/lang/String;JJ)J", 7);
+			}
+		} else {
+			// bad type
+			throw new RuntimeException("bad type: " + typeName);
+		}
+	}
+
+	private static void addTypeDependDataLoad(Bytecode code, String typeName,
+	                                          int i) {
+		if ((typeName.charAt(0) == 'L')
+		    && (typeName.charAt(typeName.length() - 1) == ';')
+		    || (typeName.charAt(0) == '[')) {
+			// reference type
+			code.addAload(i);
+		} else if (typeName.equals("Z") || typeName.equals("B")
+		           || typeName.equals("C") || typeName.equals("I")
+		           || typeName.equals("S")) {
+			// boolean, byte, char, int, short
+			code.addIload(i);
+		} else if (typeName.equals("D")) {
+			// double
+			code.addDload(i);
+		} else if (typeName.equals("F")) {
+			// float
+			code.addFload(i);
+		} else if (typeName.equals("J")) {
+			// long
+			code.addLload(i);
+		} else {
+			// bad type
+			throw new RuntimeException("bad type: " + typeName);
+		}
+	}
+
+	private static void addTypeDependDataStore(Bytecode code, String typeName,
+	                                           int i) {
+		if ((typeName.charAt(0) == 'L')
+		    && (typeName.charAt(typeName.length() - 1) == ';')
+		    || (typeName.charAt(0) == '[')) {
+			// reference type
+			code.addAstore(i);
+		} else if (typeName.equals("Z") || typeName.equals("B")
+		           || typeName.equals("C") || typeName.equals("I")
+		           || typeName.equals("S")) {
+			// boolean, byte, char, int, short
+			code.addIstore(i);
+		} else if (typeName.equals("D")) {
+			// double
+			code.addDstore(i);
+		} else if (typeName.equals("F")) {
+			// float
+			code.addFstore(i);
+		} else if (typeName.equals("J")) {
+			// long
+			code.addLstore(i);
+		} else {
+			// bad type
+			throw new RuntimeException("bad type: " + typeName);
+		}
+	}
+
+	private static void addTypeDependDataReturn(Bytecode code, String typeName) {
+		if ((typeName.charAt(0) == 'L')
+		    && (typeName.charAt(typeName.length() - 1) == ';')
+		    || (typeName.charAt(0) == '[')) {
+			// reference type
+			code.addOpcode(Opcode.ARETURN);
+		} else if (typeName.equals("Z") || typeName.equals("B")
+		           || typeName.equals("C") || typeName.equals("I")
+		           || typeName.equals("S")) {
+			// boolean, byte, char, int, short
+			code.addOpcode(Opcode.IRETURN);
+		} else if (typeName.equals("D")) {
+			// double
+			code.addOpcode(Opcode.DRETURN);
+		} else if (typeName.equals("F")) {
+			// float
+			code.addOpcode(Opcode.FRETURN);
+		} else if (typeName.equals("J")) {
+			// long
+			code.addOpcode(Opcode.LRETURN);
+		} else {
+			// bad type
+			throw new RuntimeException("bad type: " + typeName);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.InstantiationException;
-
-import java.io.Serializable;
-
-/**
- * The {@link ReflectionOptimizer.InstantiationOptimizer} implementation for Javassist
- * which simply acts as an adpater to the {@link FastClass} class.
- *
- * @author Steve Ebersole
- */
-public class InstantiationOptimizerAdapter implements ReflectionOptimizer.InstantiationOptimizer, Serializable {
-	private final FastClass fastClass;
-
-	public InstantiationOptimizerAdapter(FastClass fastClass) {
-		this.fastClass = fastClass;
-	}
-
-	public Object newInstance() {
-		try {
-			return fastClass.newInstance();
-		}
-		catch ( Throwable t ) {
-			throw new InstantiationException(
-					"Could not instantiate entity with Javassist optimizer: ",
-			        fastClass.getJavaClass(), t
-			);
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/InstantiationOptimizerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.javassist;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.InstantiationException;
+
+import java.io.Serializable;
+
+/**
+ * The {@link ReflectionOptimizer.InstantiationOptimizer} implementation for Javassist
+ * which simply acts as an adpater to the {@link FastClass} class.
+ *
+ * @author Steve Ebersole
+ */
+public class InstantiationOptimizerAdapter implements ReflectionOptimizer.InstantiationOptimizer, Serializable {
+	private final FastClass fastClass;
+
+	public InstantiationOptimizerAdapter(FastClass fastClass) {
+		this.fastClass = fastClass;
+	}
+
+	public Object newInstance() {
+		try {
+			return fastClass.newInstance();
+		}
+		catch ( Throwable t ) {
+			throw new InstantiationException(
+					"Could not instantiate entity with Javassist optimizer: ",
+			        fastClass.getJavaClass(), t
+			);
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,111 +0,0 @@
-//$Id: $
-package org.hibernate.bytecode.javassist;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.security.ProtectionDomain;
-
-import javassist.bytecode.ClassFile;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.bytecode.AbstractClassTransformerImpl;
-import org.hibernate.bytecode.util.ClassFilter;
-
-/**
- * Enhance the classes allowing them to implements InterceptFieldEnabled
- * This interface is then used by Hibernate for some optimizations.
- *
- * @author Emmanuel Bernard
- * @author Steve Ebersole
- */
-public class JavassistClassTransformer extends AbstractClassTransformerImpl {
-
-	private static Logger log = LoggerFactory.getLogger( JavassistClassTransformer.class.getName() );
-
-	public JavassistClassTransformer(ClassFilter classFilter, org.hibernate.bytecode.util.FieldFilter fieldFilter) {
-		super( classFilter, fieldFilter );
-	}
-
-	protected byte[] doTransform(
-			ClassLoader loader,
-			String className,
-			Class classBeingRedefined,
-			ProtectionDomain protectionDomain,
-			byte[] classfileBuffer) {
-		ClassFile classfile;
-		try {
-			// WARNING: classfile only
-			classfile = new ClassFile( new DataInputStream( new ByteArrayInputStream( classfileBuffer ) ) );
-		}
-		catch (IOException e) {
-			log.error( "Unable to build enhancement metamodel for " + className );
-			return classfileBuffer;
-		}
-		FieldTransformer transformer = getFieldTransformer( classfile );
-		if ( transformer != null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Enhancing " + className );
-			}
-			DataOutputStream out = null;
-			try {
-				transformer.transform( classfile );
-				ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
-				out = new DataOutputStream( byteStream );
-				classfile.write( out );
-				return byteStream.toByteArray();
-			}
-			catch (Exception e) {
-				log.error( "Unable to transform class", e );
-				throw new HibernateException( "Unable to transform class: " + e.getMessage() );
-			}
-			finally {
-				try {
-					if ( out != null ) out.close();
-				}
-				catch (IOException e) {
-					//swallow
-				}
-			}
-		}
-		return classfileBuffer;
-	}
-
-	protected FieldTransformer getFieldTransformer(final ClassFile classfile) {
-		if ( alreadyInstrumented( classfile ) ) {
-			return null;
-		}
-		return new FieldTransformer(
-				new FieldFilter() {
-					public boolean handleRead(String desc, String name) {
-						return fieldFilter.shouldInstrumentField( classfile.getName(), name );
-					}
-
-					public boolean handleWrite(String desc, String name) {
-						return fieldFilter.shouldInstrumentField( classfile.getName(), name );
-					}
-
-					public boolean handleReadAccess(String fieldOwnerClassName, String fieldName) {
-						return fieldFilter.shouldTransformFieldAccess( classfile.getName(), fieldOwnerClassName, fieldName );
-					}
-
-					public boolean handleWriteAccess(String fieldOwnerClassName, String fieldName) {
-						return fieldFilter.shouldTransformFieldAccess( classfile.getName(), fieldOwnerClassName, fieldName );
-					}
-				}
-		);
-	}
-
-	private boolean alreadyInstrumented(ClassFile classfile) {
-		String[] intfs = classfile.getInterfaces();
-		for ( int i = 0; i < intfs.length; i++ ) {
-			if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/JavassistClassTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.bytecode.javassist;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.security.ProtectionDomain;
+
+import javassist.bytecode.ClassFile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.bytecode.AbstractClassTransformerImpl;
+import org.hibernate.bytecode.util.ClassFilter;
+
+/**
+ * Enhance the classes allowing them to implements InterceptFieldEnabled
+ * This interface is then used by Hibernate for some optimizations.
+ *
+ * @author Emmanuel Bernard
+ * @author Steve Ebersole
+ */
+public class JavassistClassTransformer extends AbstractClassTransformerImpl {
+
+	private static Logger log = LoggerFactory.getLogger( JavassistClassTransformer.class.getName() );
+
+	public JavassistClassTransformer(ClassFilter classFilter, org.hibernate.bytecode.util.FieldFilter fieldFilter) {
+		super( classFilter, fieldFilter );
+	}
+
+	protected byte[] doTransform(
+			ClassLoader loader,
+			String className,
+			Class classBeingRedefined,
+			ProtectionDomain protectionDomain,
+			byte[] classfileBuffer) {
+		ClassFile classfile;
+		try {
+			// WARNING: classfile only
+			classfile = new ClassFile( new DataInputStream( new ByteArrayInputStream( classfileBuffer ) ) );
+		}
+		catch (IOException e) {
+			log.error( "Unable to build enhancement metamodel for " + className );
+			return classfileBuffer;
+		}
+		FieldTransformer transformer = getFieldTransformer( classfile );
+		if ( transformer != null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Enhancing " + className );
+			}
+			DataOutputStream out = null;
+			try {
+				transformer.transform( classfile );
+				ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+				out = new DataOutputStream( byteStream );
+				classfile.write( out );
+				return byteStream.toByteArray();
+			}
+			catch (Exception e) {
+				log.error( "Unable to transform class", e );
+				throw new HibernateException( "Unable to transform class: " + e.getMessage() );
+			}
+			finally {
+				try {
+					if ( out != null ) out.close();
+				}
+				catch (IOException e) {
+					//swallow
+				}
+			}
+		}
+		return classfileBuffer;
+	}
+
+	protected FieldTransformer getFieldTransformer(final ClassFile classfile) {
+		if ( alreadyInstrumented( classfile ) ) {
+			return null;
+		}
+		return new FieldTransformer(
+				new FieldFilter() {
+					public boolean handleRead(String desc, String name) {
+						return fieldFilter.shouldInstrumentField( classfile.getName(), name );
+					}
+
+					public boolean handleWrite(String desc, String name) {
+						return fieldFilter.shouldInstrumentField( classfile.getName(), name );
+					}
+
+					public boolean handleReadAccess(String fieldOwnerClassName, String fieldName) {
+						return fieldFilter.shouldTransformFieldAccess( classfile.getName(), fieldOwnerClassName, fieldName );
+					}
+
+					public boolean handleWriteAccess(String fieldOwnerClassName, String fieldName) {
+						return fieldFilter.shouldTransformFieldAccess( classfile.getName(), fieldOwnerClassName, fieldName );
+					}
+				}
+		);
+	}
+
+	private boolean alreadyInstrumented(ClassFile classfile) {
+		String[] intfs = classfile.getInterfaces();
+		for ( int i = 0; i < intfs.length; i++ ) {
+			if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import org.hibernate.bytecode.ProxyFactoryFactory;
-import org.hibernate.bytecode.BasicProxyFactory;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import javassist.util.proxy.MethodFilter;
-import javassist.util.proxy.ProxyObject;
-import javassist.util.proxy.MethodHandler;
-
-import java.lang.reflect.Method;
-import java.util.HashMap;
-
-/**
- * A factory for Javassist-based {@link ProxyFactory} instances.
- *
- * @author Steve Ebersole
- */
-public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
-
-	/**
-	 * Builds a Javassist-based proxy factory.
-	 *
-	 * @return a new Javassist-based proxy factory.
-	 */
-	public ProxyFactory buildProxyFactory() {
-		return new JavassistProxyFactory();
-	}
-
-	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
-		return new BasicProxyFactoryImpl( superClass, interfaces );
-	}
-
-	private static class BasicProxyFactoryImpl implements BasicProxyFactory {
-		private final Class proxyClass;
-
-		public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
-			if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
-				throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
-			}
-			javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory();
-			factory.setFilter( FINALIZE_FILTER );
-			if ( superClass != null ) {
-				factory.setSuperclass( superClass );
-			}
-			if ( interfaces != null && interfaces.length > 0 ) {
-				factory.setInterfaces( interfaces );
-			}
-			proxyClass = factory.createClass();
-		}
-
-		public Object getProxy() {
-			try {
-				ProxyObject proxy = ( ProxyObject ) proxyClass.newInstance();
-				proxy.setHandler( new PassThroughHandler( proxy, proxyClass.getName() ) );
-				return proxy;
-			}
-			catch ( Throwable t ) {
-				throw new HibernateException( "Unable to instantiated proxy instance" );
-			}
-		}
-
-		public boolean isInstance(Object object) {
-			return proxyClass.isInstance( object );
-		}
-	}
-
-	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
-		public boolean isHandled(Method m) {
-			// skip finalize methods
-			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
-		}
-	};
-
-	private static class PassThroughHandler implements MethodHandler {
-		private HashMap data = new HashMap();
-		private final Object proxiedObject;
-		private final String proxiedClassName;
-
-		public PassThroughHandler(Object proxiedObject, String proxiedClassName) {
-			this.proxiedObject = proxiedObject;
-			this.proxiedClassName = proxiedClassName;
-		}
-
-		public Object invoke(
-				Object object,
-		        Method method,
-		        Method method1,
-		        Object[] args) throws Exception {
-			String name = method.getName();
-			if ( "toString".equals( name ) ) {
-				return proxiedClassName + "@" + System.identityHashCode( object );
-			}
-			else if ( "equals".equals( name ) ) {
-				return proxiedObject == object ? Boolean.TRUE : Boolean.FALSE;
-			}
-			else if ( "hashCode".equals( name ) ) {
-				return new Integer( System.identityHashCode( object ) );
-			}
-			boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
-			boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
-			if ( name.startsWith( "get" ) && hasGetterSignature ) {
-				String propName = name.substring( 3 );
-				return data.get( propName );
-			}
-			else if ( name.startsWith( "is" ) && hasGetterSignature ) {
-				String propName = name.substring( 2 );
-				return data.get( propName );
-			}
-			else if ( name.startsWith( "set" ) && hasSetterSignature) {
-				String propName = name.substring( 3 );
-				data.put( propName, args[0] );
-				return null;
-			}
-			else {
-				// todo : what else to do here?
-				return null;
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ProxyFactoryFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,147 @@
+/*
+ * 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.bytecode.javassist;
+
+import org.hibernate.bytecode.ProxyFactoryFactory;
+import org.hibernate.bytecode.BasicProxyFactory;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.ProxyObject;
+import javassist.util.proxy.MethodHandler;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * A factory for Javassist-based {@link ProxyFactory} instances.
+ *
+ * @author Steve Ebersole
+ */
+public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
+
+	/**
+	 * Builds a Javassist-based proxy factory.
+	 *
+	 * @return a new Javassist-based proxy factory.
+	 */
+	public ProxyFactory buildProxyFactory() {
+		return new JavassistProxyFactory();
+	}
+
+	public BasicProxyFactory buildBasicProxyFactory(Class superClass, Class[] interfaces) {
+		return new BasicProxyFactoryImpl( superClass, interfaces );
+	}
+
+	private static class BasicProxyFactoryImpl implements BasicProxyFactory {
+		private final Class proxyClass;
+
+		public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
+			if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
+				throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
+			}
+			javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory();
+			factory.setFilter( FINALIZE_FILTER );
+			if ( superClass != null ) {
+				factory.setSuperclass( superClass );
+			}
+			if ( interfaces != null && interfaces.length > 0 ) {
+				factory.setInterfaces( interfaces );
+			}
+			proxyClass = factory.createClass();
+		}
+
+		public Object getProxy() {
+			try {
+				ProxyObject proxy = ( ProxyObject ) proxyClass.newInstance();
+				proxy.setHandler( new PassThroughHandler( proxy, proxyClass.getName() ) );
+				return proxy;
+			}
+			catch ( Throwable t ) {
+				throw new HibernateException( "Unable to instantiated proxy instance" );
+			}
+		}
+
+		public boolean isInstance(Object object) {
+			return proxyClass.isInstance( object );
+		}
+	}
+
+	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
+		public boolean isHandled(Method m) {
+			// skip finalize methods
+			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
+		}
+	};
+
+	private static class PassThroughHandler implements MethodHandler {
+		private HashMap data = new HashMap();
+		private final Object proxiedObject;
+		private final String proxiedClassName;
+
+		public PassThroughHandler(Object proxiedObject, String proxiedClassName) {
+			this.proxiedObject = proxiedObject;
+			this.proxiedClassName = proxiedClassName;
+		}
+
+		public Object invoke(
+				Object object,
+		        Method method,
+		        Method method1,
+		        Object[] args) throws Exception {
+			String name = method.getName();
+			if ( "toString".equals( name ) ) {
+				return proxiedClassName + "@" + System.identityHashCode( object );
+			}
+			else if ( "equals".equals( name ) ) {
+				return proxiedObject == object ? Boolean.TRUE : Boolean.FALSE;
+			}
+			else if ( "hashCode".equals( name ) ) {
+				return new Integer( System.identityHashCode( object ) );
+			}
+			boolean hasGetterSignature = method.getParameterTypes().length == 0 && method.getReturnType() != null;
+			boolean hasSetterSignature = method.getParameterTypes().length == 1 && ( method.getReturnType() == null || method.getReturnType() == void.class );
+			if ( name.startsWith( "get" ) && hasGetterSignature ) {
+				String propName = name.substring( 3 );
+				return data.get( propName );
+			}
+			else if ( name.startsWith( "is" ) && hasGetterSignature ) {
+				String propName = name.substring( 2 );
+				return data.get( propName );
+			}
+			else if ( name.startsWith( "set" ) && hasSetterSignature) {
+				String propName = name.substring( 3 );
+				data.put( propName, args[0] );
+				return null;
+			}
+			else {
+				// todo : what else to do here?
+				return null;
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import org.hibernate.bytecode.ReflectionOptimizer;
-
-import java.io.Serializable;
-
-/**
- * ReflectionOptimizer implementation for Javassist.
- *
- * @author Steve Ebersole
- */
-public class ReflectionOptimizerImpl implements ReflectionOptimizer, Serializable {
-
-	private final InstantiationOptimizer instantiationOptimizer;
-	private final AccessOptimizer accessOptimizer;
-
-	public ReflectionOptimizerImpl(
-			InstantiationOptimizer instantiationOptimizer,
-	        AccessOptimizer accessOptimizer) {
-		this.instantiationOptimizer = instantiationOptimizer;
-		this.accessOptimizer = accessOptimizer;
-	}
-
-	public InstantiationOptimizer getInstantiationOptimizer() {
-		return instantiationOptimizer;
-	}
-
-	public AccessOptimizer getAccessOptimizer() {
-		return accessOptimizer;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/ReflectionOptimizerImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.javassist;
+
+import org.hibernate.bytecode.ReflectionOptimizer;
+
+import java.io.Serializable;
+
+/**
+ * ReflectionOptimizer implementation for Javassist.
+ *
+ * @author Steve Ebersole
+ */
+public class ReflectionOptimizerImpl implements ReflectionOptimizer, Serializable {
+
+	private final InstantiationOptimizer instantiationOptimizer;
+	private final AccessOptimizer accessOptimizer;
+
+	public ReflectionOptimizerImpl(
+			InstantiationOptimizer instantiationOptimizer,
+	        AccessOptimizer accessOptimizer) {
+		this.instantiationOptimizer = instantiationOptimizer;
+		this.accessOptimizer = accessOptimizer;
+	}
+
+	public InstantiationOptimizer getInstantiationOptimizer() {
+		return instantiationOptimizer;
+	}
+
+	public AccessOptimizer getAccessOptimizer() {
+		return accessOptimizer;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-package org.hibernate.bytecode.javassist;
-
-import javassist.ClassPool;
-import javassist.NotFoundException;
-import javassist.CtClass;
-import javassist.CannotCompileException;
-import org.hibernate.HibernateException;
-
-import java.io.IOException;
-import java.util.ArrayList;
-
-/**
- * @author Steve Ebersole
- */
-public class TransformingClassLoader extends ClassLoader {
-	private ClassLoader parent;
-	private ClassPool classPool;
-
-	/*package*/ TransformingClassLoader(ClassLoader parent, String[] classpath) {
-		this.parent = parent;
-		classPool = new ClassPool( true );
-		for ( int i = 0; i < classpath.length; i++ ) {
-			try {
-				classPool.appendClassPath( classpath[i] );
-			}
-			catch ( NotFoundException e ) {
-				throw new HibernateException(
-						"Unable to resolve requested classpath for transformation [" +
-						classpath[i] + "] : " + e.getMessage()
-				);
-			}
-		}
-	}
-
-	protected Class findClass(String name) throws ClassNotFoundException {
-        try {
-            CtClass cc = classPool.get( name );
-	        // todo : modify the class definition if not already transformed...
-            byte[] b = cc.toBytecode();
-            return defineClass( name, b, 0, b.length );
-        }
-        catch ( NotFoundException e ) {
-            throw new ClassNotFoundException();
-        }
-        catch ( IOException e ) {
-            throw new ClassNotFoundException();
-        }
-        catch ( CannotCompileException e ) {
-            throw new ClassNotFoundException();
-        }
-    }
-
-	public void release() {
-		classPool = null;
-		parent = null;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/javassist/TransformingClassLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.bytecode.javassist;
+
+import javassist.ClassPool;
+import javassist.NotFoundException;
+import javassist.CtClass;
+import javassist.CannotCompileException;
+import org.hibernate.HibernateException;
+
+import java.io.IOException;
+
+/**
+ * @author Steve Ebersole
+ */
+public class TransformingClassLoader extends ClassLoader {
+	private ClassLoader parent;
+	private ClassPool classPool;
+
+	/*package*/ TransformingClassLoader(ClassLoader parent, String[] classpath) {
+		this.parent = parent;
+		classPool = new ClassPool( true );
+		for ( int i = 0; i < classpath.length; i++ ) {
+			try {
+				classPool.appendClassPath( classpath[i] );
+			}
+			catch ( NotFoundException e ) {
+				throw new HibernateException(
+						"Unable to resolve requested classpath for transformation [" +
+						classpath[i] + "] : " + e.getMessage()
+				);
+			}
+		}
+	}
+
+	protected Class findClass(String name) throws ClassNotFoundException {
+        try {
+            CtClass cc = classPool.get( name );
+	        // todo : modify the class definition if not already transformed...
+            byte[] b = cc.toBytecode();
+            return defineClass( name, b, 0, b.length );
+        }
+        catch ( NotFoundException e ) {
+            throw new ClassNotFoundException();
+        }
+        catch ( IOException e ) {
+            throw new ClassNotFoundException();
+        }
+        catch ( CannotCompileException e ) {
+            throw new ClassNotFoundException();
+        }
+    }
+
+	public void release() {
+		classPool = null;
+		parent = null;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-<html>
-	<head></head>
-	<body>
-		<p>
-			This package defines the API for plugging in bytecode libraries
-			for usage by Hibernate.  Hibernate uses these bytecode libraries
-			in three scenarios:<ol>
-				<li>
-					<b>Reflection optimization</b> - to speed up the performance of
-					POJO entity and component conctruction and field/property access
-				</li>
-				<li>
-					<b>Proxy generation</b> - runtime building of proxies used for
-					deferred loading of lazy entities
-				</li>
-				<li>
-					<b>Field-level interception</b> - build-time instrumentation of entity
-					classes for the purpose of intercepting field-level access (read/write)
-					for both lazy loading and dirty tracking.
-				</li>
-			</ol>
-		</p>
-		<p>
-			Currently, both CGLIB and Javassist are supported out-of-the-box.
-		</p>
-		<p>
-			Note that for field-level interception, simply plugging in a new {@link BytecodeProvider}
-			is not enough for Hibernate to be able to recognize new providers.  You would additionally
-			need to make appropriate code changes to the {@link org.hibernate.intercept.Helper}
-			class.  This is because the detection of these enhanced classes is needed in a static
-			environment (i.e. outside the scope of any {@link org.hibernate.SessionFactory}.
-		</p>
-		<p>
-			Note that in the current form the ability to specify a different bytecode provider
-			is actually considered a global settings (global to the JVM).
-		</p>
-	</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+	<head></head>
+	<body>
+		<p>
+			This package defines the API for plugging in bytecode libraries
+			for usage by Hibernate.  Hibernate uses these bytecode libraries
+			in three scenarios:<ol>
+				<li>
+					<b>Reflection optimization</b> - to speed up the performance of
+					POJO entity and component conctruction and field/property access
+				</li>
+				<li>
+					<b>Proxy generation</b> - runtime building of proxies used for
+					deferred loading of lazy entities
+				</li>
+				<li>
+					<b>Field-level interception</b> - build-time instrumentation of entity
+					classes for the purpose of intercepting field-level access (read/write)
+					for both lazy loading and dirty tracking.
+				</li>
+			</ol>
+		</p>
+		<p>
+			Currently, both CGLIB and Javassist are supported out-of-the-box.
+		</p>
+		<p>
+			Note that for field-level interception, simply plugging in a new {@link BytecodeProvider}
+			is not enough for Hibernate to be able to recognize new providers.  You would additionally
+			need to make appropriate code changes to the {@link org.hibernate.intercept.Helper}
+			class.  This is because the detection of these enhanced classes is needed in a static
+			environment (i.e. outside the scope of any {@link org.hibernate.SessionFactory}.
+		</p>
+		<p>
+			Note that in the current form the ability to specify a different bytecode provider
+			is actually considered a global settings (global to the JVM).
+		</p>
+	</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-package org.hibernate.bytecode.util;
-
-import java.util.Set;
-import java.util.HashSet;
-
-/**
- * BasicClassFilter provides class filtering based on a series of packages to
- * be included and/or a series of explicit class names to be included.  If
- * neither is specified, then no restrictions are applied.
- *
- * @author Steve Ebersole
- */
-public class BasicClassFilter implements ClassFilter {
-	private final String[] includedPackages;
-	private final Set includedClassNames = new HashSet();
-	private final boolean isAllEmpty;
-
-	public BasicClassFilter() {
-		this( null, null );
-	}
-
-	public BasicClassFilter(String[] includedPackages, String[] includedClassNames) {
-		this.includedPackages = includedPackages;
-		if ( includedClassNames != null ) {
-			for ( int i = 0; i < includedClassNames.length; i++ ) {
-				this.includedClassNames.add( includedClassNames[i] );
-			}
-		}
-
-		isAllEmpty = ( this.includedPackages == null || this.includedPackages.length == 0 )
-		             && ( this.includedClassNames.isEmpty() );
-	}
-
-	public boolean shouldInstrumentClass(String className) {
-		if ( isAllEmpty ) {
-			return true;
-		}
-		else if ( includedClassNames.contains( className ) ) {
-			return true;
-		}
-		else if ( isInIncludedPackage( className ) ) {
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	private boolean isInIncludedPackage(String className) {
-		if ( includedPackages != null ) {
-			for ( int i = 0; i < includedPackages.length; i++ ) {
-				if ( className.startsWith( includedPackages[i] ) ) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/BasicClassFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.bytecode.util;
+
+import java.util.Set;
+import java.util.HashSet;
+
+/**
+ * BasicClassFilter provides class filtering based on a series of packages to
+ * be included and/or a series of explicit class names to be included.  If
+ * neither is specified, then no restrictions are applied.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicClassFilter implements ClassFilter {
+	private final String[] includedPackages;
+	private final Set includedClassNames = new HashSet();
+	private final boolean isAllEmpty;
+
+	public BasicClassFilter() {
+		this( null, null );
+	}
+
+	public BasicClassFilter(String[] includedPackages, String[] includedClassNames) {
+		this.includedPackages = includedPackages;
+		if ( includedClassNames != null ) {
+			for ( int i = 0; i < includedClassNames.length; i++ ) {
+				this.includedClassNames.add( includedClassNames[i] );
+			}
+		}
+
+		isAllEmpty = ( this.includedPackages == null || this.includedPackages.length == 0 )
+		             && ( this.includedClassNames.isEmpty() );
+	}
+
+	public boolean shouldInstrumentClass(String className) {
+		if ( isAllEmpty ) {
+			return true;
+		}
+		else if ( includedClassNames.contains( className ) ) {
+			return true;
+		}
+		else if ( isInIncludedPackage( className ) ) {
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	private boolean isInIncludedPackage(String className) {
+		if ( includedPackages != null ) {
+			for ( int i = 0; i < includedPackages.length; i++ ) {
+				if ( className.startsWith( includedPackages[i] ) ) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-package org.hibernate.bytecode.util;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.BufferedInputStream;
-import java.util.zip.ZipInputStream;
-
-/**
- * A helper for reading byte code from various input sources.
- *
- * @author Steve Ebersole
- */
-public class ByteCodeHelper {
-	private ByteCodeHelper() {
-	}
-
-	/**
-	 * Reads class byte array info from the given input stream.
-	 * <p/>
-	 * The stream is closed within this method!
-	 *
-	 * @param inputStream
-	 * @return
-	 * @throws IOException
-	 */
-	public static byte[] readByteCode(InputStream inputStream) throws IOException {
-		if ( inputStream == null ) {
-			throw new IOException( "null input stream" );
-		}
-
-		byte[] buffer = new byte[409600];
-		byte[] classBytes = new byte[0];
-		int r = 0;
-
-		try {
-			r = inputStream.read( buffer );
-			while ( r >= buffer.length ) {
-				byte[] temp = new byte[ classBytes.length + buffer.length ];
-				System.arraycopy( classBytes, 0, temp, 0, classBytes.length );
-				System.arraycopy( buffer, 0, temp, classBytes.length, buffer.length );
-				classBytes = temp;
-			}
-			if ( r != -1 ) {
-				byte[] temp = new byte[ classBytes.length + r ];
-				System.arraycopy( classBytes, 0, temp, 0, classBytes.length );
-				System.arraycopy( buffer, 0, temp, classBytes.length, r );
-				classBytes = temp;
-			}
-		}
-		finally {
-			try {
-				inputStream.close();
-			}
-			catch (IOException ignore) {
-				// intentionally empty
-			}
-		}
-
-		return classBytes;
-	}
-
-	public static byte[] readByteCode(File file) throws IOException {
-		return ByteCodeHelper.readByteCode( new FileInputStream( file ) );
-	}
-
-	public static byte[] readByteCode(ZipInputStream zip) throws IOException {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        InputStream in = new BufferedInputStream( zip );
-        int b;
-        while ( ( b = in.read() ) != -1 ) {
-            bout.write( b );
-        }
-        return bout.toByteArray();
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ByteCodeHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.bytecode.util;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.BufferedInputStream;
+import java.util.zip.ZipInputStream;
+
+/**
+ * A helper for reading byte code from various input sources.
+ *
+ * @author Steve Ebersole
+ */
+public class ByteCodeHelper {
+	private ByteCodeHelper() {
+	}
+
+	/**
+	 * Reads class byte array info from the given input stream.
+	 * <p/>
+	 * The stream is closed within this method!
+	 *
+	 * @param inputStream
+	 * @return
+	 * @throws IOException
+	 */
+	public static byte[] readByteCode(InputStream inputStream) throws IOException {
+		if ( inputStream == null ) {
+			throw new IOException( "null input stream" );
+		}
+
+		byte[] buffer = new byte[409600];
+		byte[] classBytes = new byte[0];
+		int r = 0;
+
+		try {
+			r = inputStream.read( buffer );
+			while ( r >= buffer.length ) {
+				byte[] temp = new byte[ classBytes.length + buffer.length ];
+				System.arraycopy( classBytes, 0, temp, 0, classBytes.length );
+				System.arraycopy( buffer, 0, temp, classBytes.length, buffer.length );
+				classBytes = temp;
+			}
+			if ( r != -1 ) {
+				byte[] temp = new byte[ classBytes.length + r ];
+				System.arraycopy( classBytes, 0, temp, 0, classBytes.length );
+				System.arraycopy( buffer, 0, temp, classBytes.length, r );
+				classBytes = temp;
+			}
+		}
+		finally {
+			try {
+				inputStream.close();
+			}
+			catch (IOException ignore) {
+				// intentionally empty
+			}
+		}
+
+		return classBytes;
+	}
+
+	public static byte[] readByteCode(File file) throws IOException {
+		return ByteCodeHelper.readByteCode( new FileInputStream( file ) );
+	}
+
+	public static byte[] readByteCode(ZipInputStream zip) throws IOException {
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        InputStream in = new BufferedInputStream( zip );
+        int b;
+        while ( ( b = in.read() ) != -1 ) {
+            bout.write( b );
+        }
+        return bout.toByteArray();
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,30 +0,0 @@
-package org.hibernate.bytecode.util;
-
-/**
- * Contract describing the information Hibernate needs in terms of instrumenting
- * a class, either via ant task or dynamic classloader.
- *
- * @author Steve Ebersole
- */
-public interface ClassDescriptor {
-	/**
-	 * The name of the class.
-	 *
-	 * @return The class name.
-	 */
-	public String getName();
-
-	/**
-	 * Determine if the class is already instrumented.
-	 *
-	 * @return True if already instrumented; false otherwise.
-	 */
-	public boolean isInstrumented();
-
-	/**
-	 * The bytes making up the class' bytecode.
-	 *
-	 * @return The bytecode bytes.
-	 */
-	public byte[] getBytes();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.bytecode.util;
+
+/**
+ * Contract describing the information Hibernate needs in terms of instrumenting
+ * a class, either via ant task or dynamic classloader.
+ *
+ * @author Steve Ebersole
+ */
+public interface ClassDescriptor {
+	/**
+	 * The name of the class.
+	 *
+	 * @return The class name.
+	 */
+	public String getName();
+
+	/**
+	 * Determine if the class is already instrumented.
+	 *
+	 * @return True if already instrumented; false otherwise.
+	 */
+	public boolean isInstrumented();
+
+	/**
+	 * The bytes making up the class' bytecode.
+	 *
+	 * @return The bytecode bytes.
+	 */
+	public byte[] getBytes();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-package org.hibernate.bytecode.util;
-
-/**
- * Used to determine whether a class should be instrumented.
- *
- * @author Steve Ebersole
- */
-public interface ClassFilter {
-		public boolean shouldInstrumentClass(String className);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/ClassFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+/*
+ * 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.bytecode.util;
+
+/**
+ * Used to determine whether a class should be instrumented.
+ *
+ * @author Steve Ebersole
+ */
+public interface ClassFilter {
+		public boolean shouldInstrumentClass(String className);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-package org.hibernate.bytecode.util;
-
-/**
- * Used to determine whether a field reference should be instrumented.
- *
- * @author Steve Ebersole
- */
-public interface FieldFilter {
-	/**
-	 * Should this field definition be instrumented?
-	 *
-	 * @param className The name of the class currently being processed
-	 * @param fieldName The name of the field being checked.
-	 * @return True if we should instrument this field.
-	 */
-	public boolean shouldInstrumentField(String className, String fieldName);
-
-	/**
-	 * Should we instrument *access to* the given field.  This differs from
-	 * {@link #shouldInstrumentField} in that here we are talking about a particular usage of
-	 * a field.
-	 *
-	 * @param transformingClassName The class currently being transformed.
-	 * @param fieldOwnerClassName The name of the class owning this field being checked.
-	 * @param fieldName The name of the field being checked.
-	 * @return True if this access should be transformed.
-	 */
-	public boolean shouldTransformFieldAccess(String transformingClassName, String fieldOwnerClassName, String fieldName);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/bytecode/util/FieldFilter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.bytecode.util;
+
+/**
+ * Used to determine whether a field reference should be instrumented.
+ *
+ * @author Steve Ebersole
+ */
+public interface FieldFilter {
+	/**
+	 * Should this field definition be instrumented?
+	 *
+	 * @param className The name of the class currently being processed
+	 * @param fieldName The name of the field being checked.
+	 * @return True if we should instrument this field.
+	 */
+	public boolean shouldInstrumentField(String className, String fieldName);
+
+	/**
+	 * Should we instrument *access to* the given field.  This differs from
+	 * {@link #shouldInstrumentField} in that here we are talking about a particular usage of
+	 * a field.
+	 *
+	 * @param transformingClassName The class currently being transformed.
+	 * @param fieldOwnerClassName The name of the class owning this field being checked.
+	 * @param fieldName The name of the field being checked.
+	 * @return True if this access should be transformed.
+	 */
+	public boolean shouldTransformFieldAccess(String transformingClassName, String fieldOwnerClassName, String fieldName);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,86 +0,0 @@
-// $Id: AbstractJndiBoundCacheProvider.java 6079 2005-03-16 06:01:18Z oneovthafew $
-package org.hibernate.cache;
-
-import java.util.Properties;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.NamingHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Support for CacheProvider implementations which are backed by caches bound
- * into JNDI namespace.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractJndiBoundCacheProvider implements CacheProvider {
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractJndiBoundCacheProvider.class );
-	private Object cache;
-
-	protected void prepare(Properties properties) {
-		// Do nothing; subclasses may override.
-	}
-
-	protected void release() {
-		// Do nothing; subclasses may override.
-	}
-
-	/**
-	 * Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
-	 * construction.
-	 *
-	 * @param properties current configuration settings.
-	 */
-	public final void start(Properties properties) throws CacheException {
-		String jndiNamespace = properties.getProperty( Environment.CACHE_NAMESPACE );
-		if ( StringHelper.isEmpty( jndiNamespace ) ) {
-			throw new CacheException( "No JNDI namespace specified for cache" );
-		}
-		cache = locateCache( jndiNamespace, NamingHelper.getJndiProperties( properties ) );
-		prepare( properties );
-	}
-
-	/**
-	 * Callback to perform any necessary cleanup of the underlying cache
-	 * implementation during SessionFactory.close().
-	 */
-	public final void stop() {
-		release();
-		cache = null;
-	}
-
-	private Object locateCache(String jndiNamespace, Properties jndiProperties) {
-
-		Context ctx = null;
-		try {
-			ctx = new InitialContext( jndiProperties );
-			return ctx.lookup( jndiNamespace );
-		}
-		catch (NamingException ne) {
-			String msg = "Unable to retreive Cache from JNDI [" + jndiNamespace + "]";
-			log.info( msg, ne );
-			throw new CacheException( msg );
-		}
-		finally {
-			if ( ctx != null ) {
-				try {
-					ctx.close();
-				}
-				catch( NamingException ne ) {
-					log.info( "Unable to release initial context", ne );
-				}
-			}
-		}
-	}
-	
-	public Object getCache() {
-		return cache;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/AbstractJndiBoundCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,109 @@
+/*
+ * 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.cache;
+
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.NamingHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Support for CacheProvider implementations which are backed by caches bound
+ * into JNDI namespace.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractJndiBoundCacheProvider implements CacheProvider {
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractJndiBoundCacheProvider.class );
+	private Object cache;
+
+	protected void prepare(Properties properties) {
+		// Do nothing; subclasses may override.
+	}
+
+	protected void release() {
+		// Do nothing; subclasses may override.
+	}
+
+	/**
+	 * Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
+	 * construction.
+	 *
+	 * @param properties current configuration settings.
+	 */
+	public final void start(Properties properties) throws CacheException {
+		String jndiNamespace = properties.getProperty( Environment.CACHE_NAMESPACE );
+		if ( StringHelper.isEmpty( jndiNamespace ) ) {
+			throw new CacheException( "No JNDI namespace specified for cache" );
+		}
+		cache = locateCache( jndiNamespace, NamingHelper.getJndiProperties( properties ) );
+		prepare( properties );
+	}
+
+	/**
+	 * Callback to perform any necessary cleanup of the underlying cache
+	 * implementation during SessionFactory.close().
+	 */
+	public final void stop() {
+		release();
+		cache = null;
+	}
+
+	private Object locateCache(String jndiNamespace, Properties jndiProperties) {
+
+		Context ctx = null;
+		try {
+			ctx = new InitialContext( jndiProperties );
+			return ctx.lookup( jndiNamespace );
+		}
+		catch (NamingException ne) {
+			String msg = "Unable to retreive Cache from JNDI [" + jndiNamespace + "]";
+			log.info( msg, ne );
+			throw new CacheException( msg );
+		}
+		finally {
+			if ( ctx != null ) {
+				try {
+					ctx.close();
+				}
+				catch( NamingException ne ) {
+					log.info( "Unable to release initial context", ne );
+				}
+			}
+		}
+	}
+	
+	public Object getCache() {
+		return cache;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/Cache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-//$Id: Cache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Map;
-
-/**
- * Implementors define a caching algorithm. All implementors
- * <b>must</b> be threadsafe.
- *
- * @deprecated As of 3.3; see <a href="package.html"/> for details.
- */
-public interface Cache {
-	/**
-	 * Get an item from the cache
-	 * @param key
-	 * @return the cached object or <tt>null</tt>
-	 * @throws CacheException
-	 */
-	public Object read(Object key) throws CacheException;
-	/**
-	 * Get an item from the cache, nontransactionally
-	 * @param key
-	 * @return the cached object or <tt>null</tt>
-	 * @throws CacheException
-	 */
-	public Object get(Object key) throws CacheException;
-	/**
-	 * Add an item to the cache, nontransactionally, with
-	 * failfast semantics
-	 * @param key
-	 * @param value
-	 * @throws CacheException
-	 */
-	public void put(Object key, Object value) throws CacheException;
-	/**
-	 * Add an item to the cache
-	 * @param key
-	 * @param value
-	 * @throws CacheException
-	 */
-	public void update(Object key, Object value) throws CacheException;
-	/**
-	 * Remove an item from the cache
-	 */
-	public void remove(Object key) throws CacheException;
-	/**
-	 * Clear the cache
-	 */
-	public void clear() throws CacheException;
-	/**
-	 * Clean up
-	 */
-	public void destroy() throws CacheException;
-	/**
-	 * If this is a clustered cache, lock the item
-	 */
-	public void lock(Object key) throws CacheException;
-	/**
-	 * If this is a clustered cache, unlock the item
-	 */
-	public void unlock(Object key) throws CacheException;
-	/**
-	 * Generate a timestamp
-	 */
-	public long nextTimestamp();
-	/**
-	 * Get a reasonable "lock timeout"
-	 */
-	public int getTimeout();
-	
-	/**
-	 * Get the name of the cache region
-	 */
-	public String getRegionName();
-
-	/**
-	 * The number of bytes is this cache region currently consuming in memory.
-	 *
-	 * @return The number of bytes consumed by this region; -1 if unknown or
-	 * unsupported.
-	 */
-	public long getSizeInMemory();
-
-	/**
-	 * The count of entries currently contained in the regions in-memory store.
-	 *
-	 * @return The count of entries in memory; -1 if unknown or unsupported.
-	 */
-	public long getElementCountInMemory();
-
-	/**
-	 * The count of entries currently contained in the regions disk store.
-	 *
-	 * @return The count of entries on disk; -1 if unknown or unsupported.
-	 */
-	public long getElementCountOnDisk();
-	
-	/**
-	 * optional operation
-	 */
-	public Map toMap();
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/Cache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Cache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,131 @@
+/*
+ * 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.cache;
+
+import java.util.Map;
+
+/**
+ * Implementors define a caching algorithm. All implementors
+ * <b>must</b> be threadsafe.
+ *
+ * @deprecated As of 3.3; see <a href="package.html"/> for details.
+ */
+public interface Cache {
+	/**
+	 * Get an item from the cache
+	 * @param key
+	 * @return the cached object or <tt>null</tt>
+	 * @throws CacheException
+	 */
+	public Object read(Object key) throws CacheException;
+	/**
+	 * Get an item from the cache, nontransactionally
+	 * @param key
+	 * @return the cached object or <tt>null</tt>
+	 * @throws CacheException
+	 */
+	public Object get(Object key) throws CacheException;
+	/**
+	 * Add an item to the cache, nontransactionally, with
+	 * failfast semantics
+	 * @param key
+	 * @param value
+	 * @throws CacheException
+	 */
+	public void put(Object key, Object value) throws CacheException;
+	/**
+	 * Add an item to the cache
+	 * @param key
+	 * @param value
+	 * @throws CacheException
+	 */
+	public void update(Object key, Object value) throws CacheException;
+	/**
+	 * Remove an item from the cache
+	 */
+	public void remove(Object key) throws CacheException;
+	/**
+	 * Clear the cache
+	 */
+	public void clear() throws CacheException;
+	/**
+	 * Clean up
+	 */
+	public void destroy() throws CacheException;
+	/**
+	 * If this is a clustered cache, lock the item
+	 */
+	public void lock(Object key) throws CacheException;
+	/**
+	 * If this is a clustered cache, unlock the item
+	 */
+	public void unlock(Object key) throws CacheException;
+	/**
+	 * Generate a timestamp
+	 */
+	public long nextTimestamp();
+	/**
+	 * Get a reasonable "lock timeout"
+	 */
+	public int getTimeout();
+	
+	/**
+	 * Get the name of the cache region
+	 */
+	public String getRegionName();
+
+	/**
+	 * The number of bytes is this cache region currently consuming in memory.
+	 *
+	 * @return The number of bytes consumed by this region; -1 if unknown or
+	 * unsupported.
+	 */
+	public long getSizeInMemory();
+
+	/**
+	 * The count of entries currently contained in the regions in-memory store.
+	 *
+	 * @return The count of entries in memory; -1 if unknown or unsupported.
+	 */
+	public long getElementCountInMemory();
+
+	/**
+	 * The count of entries currently contained in the regions disk store.
+	 *
+	 * @return The count of entries on disk; -1 if unknown or unsupported.
+	 */
+	public long getElementCountOnDisk();
+	
+	/**
+	 * optional operation
+	 */
+	public Map toMap();
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,174 +0,0 @@
-//$Id: CacheConcurrencyStrategy.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-import org.hibernate.cache.access.SoftLock;
-
-/**
- * Implementors manage transactional access to cached data. Transactions
- * pass in a timestamp indicating transaction start time. Two different
- * implementation patterns are provided for.<ul>
- * <li>A transaction-aware cache implementation might be wrapped by a
- * "synchronous" concurrency strategy, where updates to the cache are written
- * to the cache inside the transaction.</li>
- * <li>A non transaction-aware cache would be wrapped by an "asynchronous"
- * concurrency strategy, where items are merely "soft locked" during the 
- * transaction and then updated during the "after transaction completion"
- * phase; the soft lock is not an actual lock on the database row -
- * only upon the cached representation of the item.</li>
- * </ul>
- * <p/>
- * In terms of entity caches, the expected call sequences are: <ul>
- * <li><b>DELETES</b> : {@link #lock} -> {@link #evict} -> {@link #release}</li>
- * <li><b>UPDATES</b> : {@link #lock} -> {@link #update} -> {@link #afterUpdate}</li>
- * <li><b>INSERTS</b> : {@link #insert} -> {@link #afterInsert}</li>
- * </ul>
- * <p/>
- * In terms of collection caches, all modification actions actually just
- * invalidate the entry(s).  The call sequence here is:
- * {@link #lock} -> {@link #evict} -> {@link #release}
- * <p/>
- * Note that, for an asynchronous cache, cache invalidation must be a two 
- * step process (lock->release, or lock-afterUpdate), since this is the only 
- * way to guarantee consistency with the database for a nontransactional cache
- * implementation. For a synchronous cache, cache invalidation is a single 
- * step process (evict, or update). Hence, this interface defines a three
- * step process, to cater for both models.
- * <p/>
- * Note that query result caching does not go through a concurrency strategy; they
- * are managed directly against the underlying {@link Cache cache regions}.
- *
- * @deprecated As of 3.3; see <a href="package.html"/> for details.
- */
-public interface CacheConcurrencyStrategy {
-
-	/**
-	 * Attempt to retrieve an object from the cache. Mainly used in attempting
-	 * to resolve entities/collections from the second level cache.
-	 *
-	 * @param key
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @return the cached object or <tt>null</tt>
-	 * @throws CacheException
-	 */
-	public Object get(Object key, long txTimestamp) throws CacheException;
-
-	/**
-	 * Attempt to cache an object, after loading from the database.
-	 *
-	 * @param key
-	 * @param value
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @param version the item version number
-	 * @param versionComparator a comparator used to compare version numbers
-	 * @param minimalPut indicates that the cache should avoid a put is the item is already cached
-	 * @return <tt>true</tt> if the object was successfully cached
-	 * @throws CacheException
-	 */
-	public boolean put(
-			Object key, 
-			Object value, 
-			long txTimestamp, 
-			Object version, 
-			Comparator versionComparator,
-			boolean minimalPut) 
-	throws CacheException;
-
-	/**
-	 * We are going to attempt to update/delete the keyed object. This
-	 * method is used by "asynchronous" concurrency strategies.
-	 * <p/>
-	 * The returned object must be passed back to release(), to release the
-	 * lock. Concurrency strategies which do not support client-visible
-	 * locks may silently return null.
-	 * 
-	 * @param key
-	 * @param version 
-	 * @throws CacheException
-	 */
-	public SoftLock lock(Object key, Object version) throws CacheException;
-
-	/**
-	 * Called after an item has become stale (before the transaction completes).
-	 * This method is used by "synchronous" concurrency strategies.
-	 */
-	public void evict(Object key) throws CacheException;
-
-	/**
-	 * Called after an item has been updated (before the transaction completes),
-	 * instead of calling evict().
-	 * This method is used by "synchronous" concurrency strategies.
-	 */
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
-
-	/**
-	 * Called after an item has been inserted (before the transaction completes),
-	 * instead of calling evict().
-	 * This method is used by "synchronous" concurrency strategies.
-	 */
-	public boolean insert(Object key, Object value, Object currentVersion) throws CacheException;
-	
-	
-	/**
-	 * Called when we have finished the attempted update/delete (which may or 
-	 * may not have been successful), after transaction completion.
-	 * This method is used by "asynchronous" concurrency strategies.
-	 * @param key
-	 * @throws CacheException
-	 */
-	public void release(Object key, SoftLock lock) throws CacheException;
-	/**
-	 * Called after an item has been updated (after the transaction completes),
-	 * instead of calling release().
-	 * This method is used by "asynchronous" concurrency strategies.
-	 */
-	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock)
-	throws CacheException;
-	/**
-	 * Called after an item has been inserted (after the transaction completes),
-	 * instead of calling release().
-	 * This method is used by "asynchronous" concurrency strategies.
-	 */
-	public boolean afterInsert(Object key, Object value, Object version) 
-	throws CacheException;
-	
-	
-	/**
-	 * Evict an item from the cache immediately (without regard for transaction
-	 * isolation).
-	 * @param key
-	 * @throws CacheException
-	 */
-	public void remove(Object key) throws CacheException;
-	/**
-	 * Evict all items from the cache immediately.
-	 * @throws CacheException
-	 */
-	public void clear() throws CacheException;
-	/**
-	 * Clean up all resources.
-	 */
-	public void destroy();
-	/**
-	 * Set the underlying cache implementation.
-	 * @param cache
-	 */
-	public void setCache(Cache cache);
-		
-	/**
-	 * Get the cache region name
-	 */
-	public String getRegionName();
-	
-	/**
-	 * Get the wrapped cache implementation
-	 */
-	public Cache getCache();
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheConcurrencyStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,197 @@
+/*
+ * 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.cache;
+
+import java.util.Comparator;
+
+import org.hibernate.cache.access.SoftLock;
+
+/**
+ * Implementors manage transactional access to cached data. Transactions
+ * pass in a timestamp indicating transaction start time. Two different
+ * implementation patterns are provided for.<ul>
+ * <li>A transaction-aware cache implementation might be wrapped by a
+ * "synchronous" concurrency strategy, where updates to the cache are written
+ * to the cache inside the transaction.</li>
+ * <li>A non transaction-aware cache would be wrapped by an "asynchronous"
+ * concurrency strategy, where items are merely "soft locked" during the 
+ * transaction and then updated during the "after transaction completion"
+ * phase; the soft lock is not an actual lock on the database row -
+ * only upon the cached representation of the item.</li>
+ * </ul>
+ * <p/>
+ * In terms of entity caches, the expected call sequences are: <ul>
+ * <li><b>DELETES</b> : {@link #lock} -> {@link #evict} -> {@link #release}</li>
+ * <li><b>UPDATES</b> : {@link #lock} -> {@link #update} -> {@link #afterUpdate}</li>
+ * <li><b>INSERTS</b> : {@link #insert} -> {@link #afterInsert}</li>
+ * </ul>
+ * <p/>
+ * In terms of collection caches, all modification actions actually just
+ * invalidate the entry(s).  The call sequence here is:
+ * {@link #lock} -> {@link #evict} -> {@link #release}
+ * <p/>
+ * Note that, for an asynchronous cache, cache invalidation must be a two 
+ * step process (lock->release, or lock-afterUpdate), since this is the only 
+ * way to guarantee consistency with the database for a nontransactional cache
+ * implementation. For a synchronous cache, cache invalidation is a single 
+ * step process (evict, or update). Hence, this interface defines a three
+ * step process, to cater for both models.
+ * <p/>
+ * Note that query result caching does not go through a concurrency strategy; they
+ * are managed directly against the underlying {@link Cache cache regions}.
+ *
+ * @deprecated As of 3.3; see <a href="package.html"/> for details.
+ */
+public interface CacheConcurrencyStrategy {
+
+	/**
+	 * Attempt to retrieve an object from the cache. Mainly used in attempting
+	 * to resolve entities/collections from the second level cache.
+	 *
+	 * @param key
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @return the cached object or <tt>null</tt>
+	 * @throws CacheException
+	 */
+	public Object get(Object key, long txTimestamp) throws CacheException;
+
+	/**
+	 * Attempt to cache an object, after loading from the database.
+	 *
+	 * @param key
+	 * @param value
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @param version the item version number
+	 * @param versionComparator a comparator used to compare version numbers
+	 * @param minimalPut indicates that the cache should avoid a put is the item is already cached
+	 * @return <tt>true</tt> if the object was successfully cached
+	 * @throws CacheException
+	 */
+	public boolean put(
+			Object key, 
+			Object value, 
+			long txTimestamp, 
+			Object version, 
+			Comparator versionComparator,
+			boolean minimalPut) 
+	throws CacheException;
+
+	/**
+	 * We are going to attempt to update/delete the keyed object. This
+	 * method is used by "asynchronous" concurrency strategies.
+	 * <p/>
+	 * The returned object must be passed back to release(), to release the
+	 * lock. Concurrency strategies which do not support client-visible
+	 * locks may silently return null.
+	 * 
+	 * @param key
+	 * @param version 
+	 * @throws CacheException
+	 */
+	public SoftLock lock(Object key, Object version) throws CacheException;
+
+	/**
+	 * Called after an item has become stale (before the transaction completes).
+	 * This method is used by "synchronous" concurrency strategies.
+	 */
+	public void evict(Object key) throws CacheException;
+
+	/**
+	 * Called after an item has been updated (before the transaction completes),
+	 * instead of calling evict().
+	 * This method is used by "synchronous" concurrency strategies.
+	 */
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
+
+	/**
+	 * Called after an item has been inserted (before the transaction completes),
+	 * instead of calling evict().
+	 * This method is used by "synchronous" concurrency strategies.
+	 */
+	public boolean insert(Object key, Object value, Object currentVersion) throws CacheException;
+	
+	
+	/**
+	 * Called when we have finished the attempted update/delete (which may or 
+	 * may not have been successful), after transaction completion.
+	 * This method is used by "asynchronous" concurrency strategies.
+	 * @param key
+	 * @throws CacheException
+	 */
+	public void release(Object key, SoftLock lock) throws CacheException;
+	/**
+	 * Called after an item has been updated (after the transaction completes),
+	 * instead of calling release().
+	 * This method is used by "asynchronous" concurrency strategies.
+	 */
+	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock)
+	throws CacheException;
+	/**
+	 * Called after an item has been inserted (after the transaction completes),
+	 * instead of calling release().
+	 * This method is used by "asynchronous" concurrency strategies.
+	 */
+	public boolean afterInsert(Object key, Object value, Object version) 
+	throws CacheException;
+	
+	
+	/**
+	 * Evict an item from the cache immediately (without regard for transaction
+	 * isolation).
+	 * @param key
+	 * @throws CacheException
+	 */
+	public void remove(Object key) throws CacheException;
+	/**
+	 * Evict all items from the cache immediately.
+	 * @throws CacheException
+	 */
+	public void clear() throws CacheException;
+	/**
+	 * Clean up all resources.
+	 */
+	public void destroy();
+	/**
+	 * Set the underlying cache implementation.
+	 * @param cache
+	 */
+	public void setCache(Cache cache);
+		
+	/**
+	 * Get the cache region name
+	 */
+	public String getRegionName();
+	
+	/**
+	 * Get the wrapped cache implementation
+	 */
+	public Cache getCache();
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CacheDataDescription.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-/**
- * Describes attributes regarding the type of data to be cached.
- *
- * @author Steve Ebersole
- */
-public interface CacheDataDescription {
-	/**
-	 * Is the data marked as being mutable?
-	 *
-	 * @return True if the data is mutable; false otherwise.
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Is the data to be cached considered versioned?
-	 * <p/>
-	 * If true, it is illegal for {@link #getVersionComparator} to return
-	 * null.
-	 *
-	 * @return True if the data is versioned; false otherwise.
-	 */
-	public boolean isVersioned();
-
-	/**
-	 * Get the comparator used to compare two different version values.
-	 * <p/>
-	 * May return null <b>if</b> {@link #isVersioned()} returns false.
-	 * @return
-	 */
-	public Comparator getVersionComparator();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CacheDataDescription.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheDataDescription.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Comparator;
+
+/**
+ * Describes attributes regarding the type of data to be cached.
+ *
+ * @author Steve Ebersole
+ */
+public interface CacheDataDescription {
+	/**
+	 * Is the data marked as being mutable?
+	 *
+	 * @return True if the data is mutable; false otherwise.
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Is the data to be cached considered versioned?
+	 * <p/>
+	 * If true, it is illegal for {@link #getVersionComparator} to return
+	 * null.
+	 *
+	 * @return True if the data is versioned; false otherwise.
+	 */
+	public boolean isVersioned();
+
+	/**
+	 * Get the comparator used to compare two different version values.
+	 * <p/>
+	 * May return null <b>if</b> {@link #isVersioned()} returns false.
+	 * @return
+	 */
+	public Comparator getVersionComparator();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CacheException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: CacheException.java 11492 2007-05-09 01:57:11Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import org.hibernate.HibernateException;
-
-/**
- * Something went wrong in the cache
- */
-public class CacheException extends HibernateException {
-	
-	public CacheException(String s) {
-		super(s);
-	}
-
-	public CacheException(String s, Throwable e) {
-		super(s, e);
-	}
-	
-	public CacheException(Throwable e) {
-		super(e);
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CacheException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Something went wrong in the cache
+ */
+public class CacheException extends HibernateException {
+	
+	public CacheException(String s) {
+		super(s);
+	}
+
+	public CacheException(String s, Throwable e) {
+		super(s, e);
+	}
+	
+	public CacheException(Throwable e) {
+		super(e);
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CacheKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-//$Id: CacheKey.java 11499 2007-05-09 17:35:55Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-
-import org.hibernate.EntityMode;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Allows multiple entity classes / collection roles to be
- * stored in the same cache region. Also allows for composite
- * keys which do not properly implement equals()/hashCode().
- *
- * @author Gavin King
- */
-public class CacheKey implements Serializable {
-	private final Serializable key;
-	private final Type type;
-	private final String entityOrRoleName;
-	private final EntityMode entityMode;
-	private final int hashCode;
-
-	/**
-	 * Construct a new key for a collection or entity instance.
-	 * Note that an entity name should always be the root entity
-	 * name, not a subclass entity name.
-	 *
-	 * @param id The identifier associated with the cached data
-	 * @param type The Hibernate type mapping
-	 * @param entityOrRoleName The entity or collection-role name.
-	 * @param entityMode The entiyt mode of the originating session
-	 * @param factory The session factory for which we are caching
-	 */
-	public CacheKey(
-			final Serializable id,
-			final Type type,
-			final String entityOrRoleName,
-			final EntityMode entityMode,
-			final SessionFactoryImplementor factory) {
-		this.key = id;
-		this.type = type;
-		this.entityOrRoleName = entityOrRoleName;
-		this.entityMode = entityMode;
-		hashCode = type.getHashCode( key, entityMode, factory );
-	}
-
-	//Mainly for OSCache
-	public String toString() {
-		return entityOrRoleName + '#' + key.toString();//"CacheKey#" + type.toString(key, sf);
-	}
-
-	public boolean equals(Object other) {
-		if ( !(other instanceof CacheKey) ) return false;
-		CacheKey that = (CacheKey) other;
-		return entityOrRoleName.equals( that.entityOrRoleName )
-				&& type.isEqual( key, that.key, entityMode );
-	}
-
-	public int hashCode() {
-		return hashCode;
-	}
-
-	public Serializable getKey() {
-		return key;
-	}
-
-	public String getEntityOrRoleName() {
-		return entityOrRoleName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CacheKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+
+import org.hibernate.EntityMode;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Allows multiple entity classes / collection roles to be
+ * stored in the same cache region. Also allows for composite
+ * keys which do not properly implement equals()/hashCode().
+ *
+ * @author Gavin King
+ */
+public class CacheKey implements Serializable {
+	private final Serializable key;
+	private final Type type;
+	private final String entityOrRoleName;
+	private final EntityMode entityMode;
+	private final int hashCode;
+
+	/**
+	 * Construct a new key for a collection or entity instance.
+	 * Note that an entity name should always be the root entity
+	 * name, not a subclass entity name.
+	 *
+	 * @param id The identifier associated with the cached data
+	 * @param type The Hibernate type mapping
+	 * @param entityOrRoleName The entity or collection-role name.
+	 * @param entityMode The entiyt mode of the originating session
+	 * @param factory The session factory for which we are caching
+	 */
+	public CacheKey(
+			final Serializable id,
+			final Type type,
+			final String entityOrRoleName,
+			final EntityMode entityMode,
+			final SessionFactoryImplementor factory) {
+		this.key = id;
+		this.type = type;
+		this.entityOrRoleName = entityOrRoleName;
+		this.entityMode = entityMode;
+		hashCode = type.getHashCode( key, entityMode, factory );
+	}
+
+	//Mainly for OSCache
+	public String toString() {
+		return entityOrRoleName + '#' + key.toString();//"CacheKey#" + type.toString(key, sf);
+	}
+
+	public boolean equals(Object other) {
+		if ( !(other instanceof CacheKey) ) return false;
+		CacheKey that = (CacheKey) other;
+		return entityOrRoleName.equals( that.entityOrRoleName )
+				&& type.isEqual( key, that.key, entityMode );
+	}
+
+	public int hashCode() {
+		return hashCode;
+	}
+
+	public Serializable getKey() {
+		return key;
+	}
+
+	public String getEntityOrRoleName() {
+		return entityOrRoleName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CacheProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-//$Id: CacheProvider.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Properties;
-
-/**
- * Support for pluggable caches.
- *
- * @author Gavin King
- * @deprecated As of 3.3; see <a href="package.html"/> for details.
- */
-public interface CacheProvider {
-
-	/**
-	 * Configure the cache
-	 *
-	 * @param regionName the name of the cache region
-	 * @param properties configuration settings
-	 * @throws CacheException
-	 */
-	public Cache buildCache(String regionName, Properties properties) throws CacheException;
-
-	/**
-	 * Generate a timestamp
-	 */
-	public long nextTimestamp();
-
-	/**
-	 * Callback to perform any necessary initialization of the underlying cache implementation
-	 * during SessionFactory construction.
-	 *
-	 * @param properties current configuration settings.
-	 */
-	public void start(Properties properties) throws CacheException;
-
-	/**
-	 * Callback to perform any necessary cleanup of the underlying cache implementation
-	 * during SessionFactory.close().
-	 */
-	public void stop();
-	
-	public boolean isMinimalPutsEnabledByDefault();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CacheProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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.cache;
+
+import java.util.Properties;
+
+/**
+ * Support for pluggable caches.
+ *
+ * @author Gavin King
+ * @deprecated As of 3.3; see <a href="package.html"/> for details.
+ */
+public interface CacheProvider {
+
+	/**
+	 * Configure the cache
+	 *
+	 * @param regionName the name of the cache region
+	 * @param properties configuration settings
+	 * @throws CacheException
+	 */
+	public Cache buildCache(String regionName, Properties properties) throws CacheException;
+
+	/**
+	 * Generate a timestamp
+	 */
+	public long nextTimestamp();
+
+	/**
+	 * Callback to perform any necessary initialization of the underlying cache implementation
+	 * during SessionFactory construction.
+	 *
+	 * @param properties current configuration settings.
+	 */
+	public void start(Properties properties) throws CacheException;
+
+	/**
+	 * Callback to perform any necessary cleanup of the underlying cache implementation
+	 * during SessionFactory.close().
+	 */
+	public void stop();
+	
+	public boolean isMinimalPutsEnabledByDefault();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/CollectionRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-package org.hibernate.cache;
-
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.access.AccessType;
-
-/**
- * Defines the contract for a cache region which will specifically be used to
- * store collection data.
- * <p/>
- * Impl note: Hibernate always deals with changes to collections which
- * (potentially) has its data in the L2 cache by removing that collection
- * data; in other words it never tries to update the cached state, thereby
- * allowing it to avoid a bunch of concurrency problems.
- *
- * @author Steve Ebersole
- */
-public interface CollectionRegion extends TransactionalDataRegion {
-
-	/**
-	 * Build an access strategy for the requested access type.
-	 *
-	 * @param accessType The type of access strategy to build; never null.
-	 * @return The appropriate strategy contract for accessing this region
-	 * for the requested type of access.
-	 * @throws CacheException Usually indicates mis-configuration.
-	 */
-	public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/CollectionRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/CollectionRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.AccessType;
+
+/**
+ * Defines the contract for a cache region which will specifically be used to
+ * store collection data.
+ * <p/>
+ * Impl note: Hibernate always deals with changes to collections which
+ * (potentially) has its data in the L2 cache by removing that collection
+ * data; in other words it never tries to update the cached state, thereby
+ * allowing it to avoid a bunch of concurrency problems.
+ *
+ * @author Steve Ebersole
+ */
+public interface CollectionRegion extends TransactionalDataRegion {
+
+	/**
+	 * Build an access strategy for the requested access type.
+	 *
+	 * @param accessType The type of access strategy to build; never null.
+	 * @return The appropriate strategy contract for accessing this region
+	 * for the requested type of access.
+	 * @throws CacheException Usually indicates mis-configuration.
+	 */
+	public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/EntityRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-package org.hibernate.cache;
-
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.access.AccessType;
-
-/**
- * Defines the contract for a cache region which will specifically be used to
- * store entity data.
- *
- * @author Steve Ebersole
- */
-public interface EntityRegion extends TransactionalDataRegion {
-
-	/**
-	 * Build an access strategy for the requested access type.
-	 *
-	 * @param accessType The type of access strategy to build; never null.
-	 * @return The appropriate strategy contract for accessing this region
-	 * for the requested type of access.
-	 * @throws CacheException Usually indicates mis-configuration.
-	 */
-	public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/EntityRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/EntityRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.access.AccessType;
+
+/**
+ * Defines the contract for a cache region which will specifically be used to
+ * store entity data.
+ *
+ * @author Steve Ebersole
+ */
+public interface EntityRegion extends TransactionalDataRegion {
+
+	/**
+	 * Build an access strategy for the requested access type.
+	 *
+	 * @param accessType The type of access strategy to build; never null.
+	 * @return The appropriate strategy contract for accessing this region
+	 * for the requested type of access.
+	 * @throws CacheException Usually indicates mis-configuration.
+	 */
+	public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/FilterKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,70 +0,0 @@
-//$Id: FilterKey.java 8754 2005-12-05 23:36:59Z steveebersole $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.impl.FilterImpl;
-import org.hibernate.type.Type;
-
-/**
- * Allows cached queries to be keyed by enabled filters.
- * 
- * @author Gavin King
- */
-public final class FilterKey implements Serializable {
-	private String filterName;
-	private Map filterParameters = new HashMap();
-	
-	public FilterKey(String name, Map params, Map types, EntityMode entityMode) {
-		filterName = name;
-		Iterator iter = params.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			Type type = (Type) types.get( me.getKey() );
-			filterParameters.put( me.getKey(), new TypedValue( type, me.getValue(), entityMode ) );
-		}
-	}
-	
-	public int hashCode() {
-		int result = 13;
-		result = 37 * result + filterName.hashCode();
-		result = 37 * result + filterParameters.hashCode();
-		return result;
-	}
-	
-	public boolean equals(Object other) {
-		if ( !(other instanceof FilterKey) ) return false;
-		FilterKey that = (FilterKey) other;
-		if ( !that.filterName.equals(filterName) ) return false;
-		if ( !that.filterParameters.equals(filterParameters) ) return false;
-		return true;
-	}
-	
-	public String toString() {
-		return "FilterKey[" + filterName + filterParameters + ']';
-	}
-	
-	public static Set createFilterKeys(Map enabledFilters, EntityMode entityMode) {
-		if ( enabledFilters.size()==0 ) return null;
-		Set result = new HashSet();
-		Iterator iter = enabledFilters.values().iterator();
-		while ( iter.hasNext() ) {
-			FilterImpl filter = (FilterImpl) iter.next();
-			FilterKey key = new FilterKey(
-					filter.getName(), 
-					filter.getParameters(), 
-					filter.getFilterDefinition().getParameterTypes(), 
-					entityMode
-				);
-			result.add(key);
-		}
-		return result;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/FilterKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/FilterKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.EntityMode;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.impl.FilterImpl;
+import org.hibernate.type.Type;
+
+/**
+ * Allows cached queries to be keyed by enabled filters.
+ * 
+ * @author Gavin King
+ */
+public final class FilterKey implements Serializable {
+	private String filterName;
+	private Map filterParameters = new HashMap();
+	
+	public FilterKey(String name, Map params, Map types, EntityMode entityMode) {
+		filterName = name;
+		Iterator iter = params.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			Type type = (Type) types.get( me.getKey() );
+			filterParameters.put( me.getKey(), new TypedValue( type, me.getValue(), entityMode ) );
+		}
+	}
+	
+	public int hashCode() {
+		int result = 13;
+		result = 37 * result + filterName.hashCode();
+		result = 37 * result + filterParameters.hashCode();
+		return result;
+	}
+	
+	public boolean equals(Object other) {
+		if ( !(other instanceof FilterKey) ) return false;
+		FilterKey that = (FilterKey) other;
+		if ( !that.filterName.equals(filterName) ) return false;
+		if ( !that.filterParameters.equals(filterParameters) ) return false;
+		return true;
+	}
+	
+	public String toString() {
+		return "FilterKey[" + filterName + filterParameters + ']';
+	}
+	
+	public static Set createFilterKeys(Map enabledFilters, EntityMode entityMode) {
+		if ( enabledFilters.size()==0 ) return null;
+		Set result = new HashSet();
+		Iterator iter = enabledFilters.values().iterator();
+		while ( iter.hasNext() ) {
+			FilterImpl filter = (FilterImpl) iter.next();
+			FilterKey key = new FilterKey(
+					filter.getName(), 
+					filter.getParameters(), 
+					filter.getFilterDefinition().getParameterTypes(), 
+					entityMode
+				);
+			result.add(key);
+		}
+		return result;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * Contract for general-purpose cache regions.
- *
- * @author Steve Ebersole
- */
-public interface GeneralDataRegion extends Region {
-
-	/**
-	 * Get an item from the cache.
-	 *
-	 * @param key The key of the item to be retrieved.
-	 * @return the cached object or <tt>null</tt>
-	 * @throws CacheException Indicates a problem accessing the item or region.
-	 */
-	public Object get(Object key) throws CacheException;
-
-	/**
-	 * Put an item into the cache.
-	 *
-	 * @param key The key under which to cache the item.
-	 * @param value The item to cache.
-	 * @throws CacheException Indicates a problem accessing the region.
-	 */
-	public void put(Object key, Object value) throws CacheException;
-
-	/**
-	 * Evict an item from the cache immediately (without regard for transaction
-	 * isolation).
-	 *
-	 * @param key The key of the item to remove
-	 * @throws CacheException Indicates a problem accessing the item or region.
-	 */
-	public void evict(Object key) throws CacheException;
-
-	/**
-	 * Evict all contents of this particular cache region (without regard for transaction
-	 * isolation).
-	 *
-	 * @throws CacheException Indicates problem accessing the region.
-	 */
-	public void evictAll() throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/GeneralDataRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.cache;
+
+/**
+ * Contract for general-purpose cache regions.
+ *
+ * @author Steve Ebersole
+ */
+public interface GeneralDataRegion extends Region {
+
+	/**
+	 * Get an item from the cache.
+	 *
+	 * @param key The key of the item to be retrieved.
+	 * @return the cached object or <tt>null</tt>
+	 * @throws CacheException Indicates a problem accessing the item or region.
+	 */
+	public Object get(Object key) throws CacheException;
+
+	/**
+	 * Put an item into the cache.
+	 *
+	 * @param key The key under which to cache the item.
+	 * @param value The item to cache.
+	 * @throws CacheException Indicates a problem accessing the region.
+	 */
+	public void put(Object key, Object value) throws CacheException;
+
+	/**
+	 * Evict an item from the cache immediately (without regard for transaction
+	 * isolation).
+	 *
+	 * @param key The key of the item to remove
+	 * @throws CacheException Indicates a problem accessing the item or region.
+	 */
+	public void evict(Object key) throws CacheException;
+
+	/**
+	 * Evict all contents of this particular cache region (without regard for transaction
+	 * isolation).
+	 *
+	 * @throws CacheException Indicates problem accessing the region.
+	 */
+	public void evictAll() throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/HashtableCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,90 +0,0 @@
-//$Id: HashtableCache.java 6478 2005-04-21 07:57:19Z oneovthafew $
-package org.hibernate.cache;
-
-import java.util.Collections;
-import java.util.Hashtable;
-
-import java.util.Map;
-
-/**
- * A lightweight implementation of the <tt>Cache</tt> interface
- * @author Gavin King
- */
-public class HashtableCache implements Cache {
-	
-	private final Map hashtable = new Hashtable();
-	private final String regionName;
-	
-	public HashtableCache(String regionName) {
-		this.regionName = regionName;
-	}
-
-	public String getRegionName() {
-		return regionName;
-	}
-
-	public Object read(Object key) throws CacheException {
-		return hashtable.get(key);
-	}
-
-	public Object get(Object key) throws CacheException {
-		return hashtable.get(key);
-	}
-
-	public void update(Object key, Object value) throws CacheException {
-		put(key, value);
-	}
-	
-	public void put(Object key, Object value) throws CacheException {
-		hashtable.put(key, value);
-	}
-
-	public void remove(Object key) throws CacheException {
-		hashtable.remove(key);
-	}
-
-	public void clear() throws CacheException {
-		hashtable.clear();
-	}
-
-	public void destroy() throws CacheException {
-
-	}
-
-	public void lock(Object key) throws CacheException {
-		// local cache, so we use synchronization
-	}
-
-	public void unlock(Object key) throws CacheException {
-		// local cache, so we use synchronization
-	}
-
-	public long nextTimestamp() {
-		return Timestamper.next();
-	}
-
-	public int getTimeout() {
-		return Timestamper.ONE_MS * 60000; //ie. 60 seconds
-	}
-
-	public long getSizeInMemory() {
-		return -1;
-	}
-
-	public long getElementCountInMemory() {
-		return hashtable.size();
-	}
-
-	public long getElementCountOnDisk() {
-		return 0;
-	}
-	
-	public Map toMap() {
-		return Collections.unmodifiableMap(hashtable);
-	}
-
-	public String toString() {
-		return "HashtableCache(" + regionName + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/HashtableCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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.cache;
+
+import java.util.Collections;
+import java.util.Hashtable;
+
+import java.util.Map;
+
+/**
+ * A lightweight implementation of the <tt>Cache</tt> interface
+ * @author Gavin King
+ */
+public class HashtableCache implements Cache {
+	
+	private final Map hashtable = new Hashtable();
+	private final String regionName;
+	
+	public HashtableCache(String regionName) {
+		this.regionName = regionName;
+	}
+
+	public String getRegionName() {
+		return regionName;
+	}
+
+	public Object read(Object key) throws CacheException {
+		return hashtable.get(key);
+	}
+
+	public Object get(Object key) throws CacheException {
+		return hashtable.get(key);
+	}
+
+	public void update(Object key, Object value) throws CacheException {
+		put(key, value);
+	}
+	
+	public void put(Object key, Object value) throws CacheException {
+		hashtable.put(key, value);
+	}
+
+	public void remove(Object key) throws CacheException {
+		hashtable.remove(key);
+	}
+
+	public void clear() throws CacheException {
+		hashtable.clear();
+	}
+
+	public void destroy() throws CacheException {
+
+	}
+
+	public void lock(Object key) throws CacheException {
+		// local cache, so we use synchronization
+	}
+
+	public void unlock(Object key) throws CacheException {
+		// local cache, so we use synchronization
+	}
+
+	public long nextTimestamp() {
+		return Timestamper.next();
+	}
+
+	public int getTimeout() {
+		return Timestamper.ONE_MS * 60000; //ie. 60 seconds
+	}
+
+	public long getSizeInMemory() {
+		return -1;
+	}
+
+	public long getElementCountInMemory() {
+		return hashtable.size();
+	}
+
+	public long getElementCountOnDisk() {
+		return 0;
+	}
+	
+	public Map toMap() {
+		return Collections.unmodifiableMap(hashtable);
+	}
+
+	public String toString() {
+		return "HashtableCache(" + regionName + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: HashtableCacheProvider.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.cache;
-
-import java.util.Properties;
-
-/**
- * A simple in-memory Hashtable-based cache impl.
- * 
- * @author Gavin King
- */
-public class HashtableCacheProvider implements CacheProvider {
-
-	public Cache buildCache(String regionName, Properties properties) throws CacheException {
-		return new HashtableCache( regionName );
-	}
-
-	public long nextTimestamp() {
-		return Timestamper.next();
-	}
-
-	/**
-	 * Callback to perform any necessary initialization of the underlying cache implementation
-	 * during SessionFactory construction.
-	 *
-	 * @param properties current configuration settings.
-	 */
-	public void start(Properties properties) throws CacheException {
-	}
-
-	/**
-	 * Callback to perform any necessary cleanup of the underlying cache implementation
-	 * during SessionFactory.close().
-	 */
-	public void stop() {
-	}
-
-	public boolean isMinimalPutsEnabledByDefault() {
-		return false;
-	}
-
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/HashtableCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Properties;
+
+/**
+ * A simple in-memory Hashtable-based cache impl.
+ * 
+ * @author Gavin King
+ */
+public class HashtableCacheProvider implements CacheProvider {
+
+	public Cache buildCache(String regionName, Properties properties) throws CacheException {
+		return new HashtableCache( regionName );
+	}
+
+	public long nextTimestamp() {
+		return Timestamper.next();
+	}
+
+	/**
+	 * Callback to perform any necessary initialization of the underlying cache implementation
+	 * during SessionFactory construction.
+	 *
+	 * @param properties current configuration settings.
+	 */
+	public void start(Properties properties) throws CacheException {
+	}
+
+	/**
+	 * Callback to perform any necessary cleanup of the underlying cache implementation
+	 * during SessionFactory.close().
+	 */
+	public void stop() {
+	}
+
+	public boolean isMinimalPutsEnabledByDefault() {
+		return false;
+	}
+
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/NoCacheProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-// $Id: NoCacheProvider.java 6433 2005-04-15 18:20:03Z steveebersole $
-package org.hibernate.cache;
-
-import java.util.Properties;
-
-/**
- * Implementation of NoCacheProvider.
- *
- * @author Steve Ebersole
- */
-public class NoCacheProvider implements CacheProvider {
-	/**
-	 * Configure the cache
-	 *
-	 * @param regionName the name of the cache region
-	 * @param properties configuration settings
-	 *
-	 * @throws CacheException
-	 */
-	public Cache buildCache(String regionName, Properties properties) throws CacheException {
-		throw new NoCachingEnabledException();
-	}
-
-	/**
-	 * Generate a timestamp
-	 */
-	public long nextTimestamp() {
-		// This, is used by SessionFactoryImpl to hand to the generated SessionImpl;
-		// was the only reason I could see that we cannot just use null as
-		// Settings.cacheProvider
-		return System.currentTimeMillis() / 100;
-	}
-
-	/**
-	 * Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
-	 * construction.
-	 *
-	 * @param properties current configuration settings.
-	 */
-	public void start(Properties properties) throws CacheException {
-		// this is called by SessionFactory irregardless; we just disregard here;
-		// could also add a check to SessionFactory to only conditionally call start
-	}
-
-	/**
-	 * Callback to perform any necessary cleanup of the underlying cache implementation during SessionFactory.close().
-	 */
-	public void stop() {
-		// this is called by SessionFactory irregardless; we just disregard here;
-		// could also add a check to SessionFactory to only conditionally call stop
-	}
-
-	public boolean isMinimalPutsEnabledByDefault() {
-		// this is called from SettingsFactory irregardless; trivial to simply disregard
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/NoCacheProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCacheProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Properties;
+
+/**
+ * Implementation of NoCacheProvider.
+ *
+ * @author Steve Ebersole
+ */
+public class NoCacheProvider implements CacheProvider {
+	/**
+	 * Configure the cache
+	 *
+	 * @param regionName the name of the cache region
+	 * @param properties configuration settings
+	 *
+	 * @throws CacheException
+	 */
+	public Cache buildCache(String regionName, Properties properties) throws CacheException {
+		throw new NoCachingEnabledException();
+	}
+
+	/**
+	 * Generate a timestamp
+	 */
+	public long nextTimestamp() {
+		// This, is used by SessionFactoryImpl to hand to the generated SessionImpl;
+		// was the only reason I could see that we cannot just use null as
+		// Settings.cacheProvider
+		return System.currentTimeMillis() / 100;
+	}
+
+	/**
+	 * Callback to perform any necessary initialization of the underlying cache implementation during SessionFactory
+	 * construction.
+	 *
+	 * @param properties current configuration settings.
+	 */
+	public void start(Properties properties) throws CacheException {
+		// this is called by SessionFactory irregardless; we just disregard here;
+		// could also add a check to SessionFactory to only conditionally call start
+	}
+
+	/**
+	 * Callback to perform any necessary cleanup of the underlying cache implementation during SessionFactory.close().
+	 */
+	public void stop() {
+		// this is called by SessionFactory irregardless; we just disregard here;
+		// could also add a check to SessionFactory to only conditionally call stop
+	}
+
+	public boolean isMinimalPutsEnabledByDefault() {
+		// this is called from SettingsFactory irregardless; trivial to simply disregard
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-// $Id: NoCachingEnabledException.java 6433 2005-04-15 18:20:03Z steveebersole $
-package org.hibernate.cache;
-
-import org.hibernate.cfg.Environment;
-
-/**
- * Implementation of NoCachingEnabledException.
- *
- * @author Steve Ebersole
- */
-public class NoCachingEnabledException extends CacheException {
-	private static final String MSG =
-	        "Second-level cache is not enabled for usage [" +
-	        Environment.USE_SECOND_LEVEL_CACHE +
-	        " | " + Environment.USE_QUERY_CACHE + "]";
-
-	public NoCachingEnabledException() {
-		super( MSG );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NoCachingEnabledException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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.cache;
+
+import org.hibernate.cfg.Environment;
+
+/**
+ * Implementation of NoCachingEnabledException.
+ *
+ * @author Steve Ebersole
+ */
+public class NoCachingEnabledException extends CacheException {
+	private static final String MSG =
+	        "Second-level cache is not enabled for usage [" +
+	        Environment.USE_SECOND_LEVEL_CACHE +
+	        " | " + Environment.USE_QUERY_CACHE + "]";
+
+	public NoCachingEnabledException() {
+		super( MSG );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,172 +0,0 @@
-//$Id: NonstrictReadWriteCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.access.SoftLock;
-
-/**
- * Caches data that is sometimes updated without ever locking the cache.
- * If concurrent access to an item is possible, this concurrency strategy
- * makes no guarantee that the item returned from the cache is the latest
- * version available in the database. Configure your cache timeout accordingly!
- * This is an "asynchronous" concurrency strategy.
- *
- * @author Gavin King
- * @see ReadWriteCache for a much stricter algorithm
- */
-public class NonstrictReadWriteCache implements CacheConcurrencyStrategy {
-
-	private Cache cache;
-
-	private static final Logger log = LoggerFactory.getLogger( NonstrictReadWriteCache.class );
-
-	public NonstrictReadWriteCache() {
-	}
-
-	public void setCache(Cache cache) {
-		this.cache = cache;
-	}
-
-	public Cache getCache() {
-		return cache;
-	}
-
-	/**
-	 * Get the most recent version, if available.
-	 */
-	public Object get(Object key, long txTimestamp) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Cache lookup: " + key );
-		}
-
-		Object result = cache.get( key );
-		if ( result != null ) {
-			log.debug( "Cache hit" );
-		}
-		else {
-			log.debug( "Cache miss" );
-		}
-		return result;
-	}
-
-	/**
-	 * Add an item to the cache.
-	 */
-	public boolean put(
-			Object key,
-	        Object value,
-	        long txTimestamp,
-	        Object version,
-	        Comparator versionComparator,
-	        boolean minimalPut) throws CacheException {
-		if ( minimalPut && cache.get( key ) != null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "item already cached: " + key );
-			}
-			return false;
-		}
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Caching: " + key );
-		}
-
-		cache.put( key, value );
-		return true;
-
-	}
-
-	/**
-	 * Do nothing.
-	 *
-	 * @return null, no lock
-	 */
-	public SoftLock lock(Object key, Object version) throws CacheException {
-		return null;
-	}
-
-	public void remove(Object key) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Removing: " + key );
-		}
-		cache.remove( key );
-	}
-
-	public void clear() throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Clearing" );
-		}
-		cache.clear();
-	}
-
-	public void destroy() {
-		try {
-			cache.destroy();
-		}
-		catch ( Exception e ) {
-			log.warn( "could not destroy cache", e );
-		}
-	}
-
-	/**
-	 * Invalidate the item
-	 */
-	public void evict(Object key) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Invalidating: " + key );
-		}
-
-		cache.remove( key );
-	}
-
-	/**
-	 * Invalidate the item
-	 */
-	public boolean insert(Object key, Object value, Object currentVersion) {
-		return false;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
-		evict( key );
-		return false;
-	}
-
-	/**
-	 * Invalidate the item (again, for safety).
-	 */
-	public void release(Object key, SoftLock lock) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Invalidating (again): " + key );
-		}
-
-		cache.remove( key );
-	}
-
-	/**
-	 * Invalidate the item (again, for safety).
-	 */
-	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
-		release( key, lock );
-		return false;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
-		return false;
-	}
-
-	public String getRegionName() {
-		return cache.getRegionName();
-	}
-
-	public String toString() {
-		return cache + "(nonstrict-read-write)";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/NonstrictReadWriteCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,195 @@
+/*
+ * 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.cache;
+
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.access.SoftLock;
+
+/**
+ * Caches data that is sometimes updated without ever locking the cache.
+ * If concurrent access to an item is possible, this concurrency strategy
+ * makes no guarantee that the item returned from the cache is the latest
+ * version available in the database. Configure your cache timeout accordingly!
+ * This is an "asynchronous" concurrency strategy.
+ *
+ * @author Gavin King
+ * @see ReadWriteCache for a much stricter algorithm
+ */
+public class NonstrictReadWriteCache implements CacheConcurrencyStrategy {
+
+	private Cache cache;
+
+	private static final Logger log = LoggerFactory.getLogger( NonstrictReadWriteCache.class );
+
+	public NonstrictReadWriteCache() {
+	}
+
+	public void setCache(Cache cache) {
+		this.cache = cache;
+	}
+
+	public Cache getCache() {
+		return cache;
+	}
+
+	/**
+	 * Get the most recent version, if available.
+	 */
+	public Object get(Object key, long txTimestamp) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Cache lookup: " + key );
+		}
+
+		Object result = cache.get( key );
+		if ( result != null ) {
+			log.debug( "Cache hit" );
+		}
+		else {
+			log.debug( "Cache miss" );
+		}
+		return result;
+	}
+
+	/**
+	 * Add an item to the cache.
+	 */
+	public boolean put(
+			Object key,
+	        Object value,
+	        long txTimestamp,
+	        Object version,
+	        Comparator versionComparator,
+	        boolean minimalPut) throws CacheException {
+		if ( minimalPut && cache.get( key ) != null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "item already cached: " + key );
+			}
+			return false;
+		}
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Caching: " + key );
+		}
+
+		cache.put( key, value );
+		return true;
+
+	}
+
+	/**
+	 * Do nothing.
+	 *
+	 * @return null, no lock
+	 */
+	public SoftLock lock(Object key, Object version) throws CacheException {
+		return null;
+	}
+
+	public void remove(Object key) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Removing: " + key );
+		}
+		cache.remove( key );
+	}
+
+	public void clear() throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Clearing" );
+		}
+		cache.clear();
+	}
+
+	public void destroy() {
+		try {
+			cache.destroy();
+		}
+		catch ( Exception e ) {
+			log.warn( "could not destroy cache", e );
+		}
+	}
+
+	/**
+	 * Invalidate the item
+	 */
+	public void evict(Object key) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Invalidating: " + key );
+		}
+
+		cache.remove( key );
+	}
+
+	/**
+	 * Invalidate the item
+	 */
+	public boolean insert(Object key, Object value, Object currentVersion) {
+		return false;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
+		evict( key );
+		return false;
+	}
+
+	/**
+	 * Invalidate the item (again, for safety).
+	 */
+	public void release(Object key, SoftLock lock) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Invalidating (again): " + key );
+		}
+
+		cache.remove( key );
+	}
+
+	/**
+	 * Invalidate the item (again, for safety).
+	 */
+	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
+		release( key, lock );
+		return false;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
+		return false;
+	}
+
+	public String getRegionName() {
+		return cache.getRegionName();
+	}
+
+	public String toString() {
+		return cache + "(nonstrict-read-write)";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/OptimisticCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,64 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * A contract for transactional cache implementations which support
- * optimistic locking of items within the cache.
- * <p/>
- * The optimisitic locking capabilities are only utilized for
- * the entity cache regions.
- * <p/>
- * Unlike the methods on the {@link Cache} interface, all the methods
- * here will only ever be called from access scenarios where versioned
- * data is actually a possiblity (i.e., entity data).  Be sure to consult
- * with {@link OptimisticCacheSource#isVersioned()} to determine whether
- * versioning is actually in effect.
- *
- * @author Steve Ebersole
- */
-public interface OptimisticCache extends Cache {
-	/**
-	 * Indicates the "source" of the cached data.  Currently this will
-	 * only ever represent an {@link org.hibernate.persister.entity.EntityPersister}.
-	 * <p/>
-	 * Made available to the cache so that it can access certain information
-	 * about versioning strategy.
-	 *
-	 * @param source The source.
-	 */
-	public void setSource(OptimisticCacheSource source);
-
-	/**
-	 * Called during {@link CacheConcurrencyStrategy#insert} processing for
-	 * transactional strategies.  Indicates we have just performed an insert
-	 * into the DB and now need to cache that entity's data.
-	 *
-	 * @param key The cache key.
-	 * @param value The data to be cached.
-	 * @param currentVersion The entity's version; or null if not versioned.
-	 */
-	public void writeInsert(Object key, Object value, Object currentVersion);
-
-	/**
-	 * Called during {@link CacheConcurrencyStrategy#update} processing for
-	 * transactional strategies.  Indicates we have just performed an update
-	 * against the DB and now need to cache the updated state.
-	 *
-	 * @param key The cache key.
-	 * @param value The data to be cached.
-	 * @param currentVersion The entity's current version
-	 * @param previousVersion The entity's previous version (before the update);
-	 * or null if not versioned.
-	 */
-	public void writeUpdate(Object key, Object value, Object currentVersion, Object previousVersion);
-
-	/**
-	 * Called during {@link CacheConcurrencyStrategy#put} processing for
-	 * transactional strategies.  Indicates we have just loaded an entity's
-	 * state from the database and need it cached.
-	 *
-	 * @param key The cache key.
-	 * @param value The data to be cached.
-	 * @param currentVersion The entity's version; or null if not versioned.
-	 */
-	public void writeLoad(Object key, Object value, Object currentVersion);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/OptimisticCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+/*
+ * 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.cache;
+
+/**
+ * A contract for transactional cache implementations which support
+ * optimistic locking of items within the cache.
+ * <p/>
+ * The optimisitic locking capabilities are only utilized for
+ * the entity cache regions.
+ * <p/>
+ * Unlike the methods on the {@link Cache} interface, all the methods
+ * here will only ever be called from access scenarios where versioned
+ * data is actually a possiblity (i.e., entity data).  Be sure to consult
+ * with {@link OptimisticCacheSource#isVersioned()} to determine whether
+ * versioning is actually in effect.
+ *
+ * @author Steve Ebersole
+ */
+public interface OptimisticCache extends Cache {
+	/**
+	 * Indicates the "source" of the cached data.  Currently this will
+	 * only ever represent an {@link org.hibernate.persister.entity.EntityPersister}.
+	 * <p/>
+	 * Made available to the cache so that it can access certain information
+	 * about versioning strategy.
+	 *
+	 * @param source The source.
+	 */
+	public void setSource(OptimisticCacheSource source);
+
+	/**
+	 * Called during {@link CacheConcurrencyStrategy#insert} processing for
+	 * transactional strategies.  Indicates we have just performed an insert
+	 * into the DB and now need to cache that entity's data.
+	 *
+	 * @param key The cache key.
+	 * @param value The data to be cached.
+	 * @param currentVersion The entity's version; or null if not versioned.
+	 */
+	public void writeInsert(Object key, Object value, Object currentVersion);
+
+	/**
+	 * Called during {@link CacheConcurrencyStrategy#update} processing for
+	 * transactional strategies.  Indicates we have just performed an update
+	 * against the DB and now need to cache the updated state.
+	 *
+	 * @param key The cache key.
+	 * @param value The data to be cached.
+	 * @param currentVersion The entity's current version
+	 * @param previousVersion The entity's previous version (before the update);
+	 * or null if not versioned.
+	 */
+	public void writeUpdate(Object key, Object value, Object currentVersion, Object previousVersion);
+
+	/**
+	 * Called during {@link CacheConcurrencyStrategy#put} processing for
+	 * transactional strategies.  Indicates we have just loaded an entity's
+	 * state from the database and need it cached.
+	 *
+	 * @param key The cache key.
+	 * @param value The data to be cached.
+	 * @param currentVersion The entity's version; or null if not versioned.
+	 */
+	public void writeLoad(Object key, Object value, Object currentVersion);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-/**
- * Contract for sources of optimistically lockable data sent to the second level
- * cache.
- * <p/>
- * Note currently {@link org.hibernate.persister.entity.EntityPersister}s are
- * the only viable source.
- *
- * @author Steve Ebersole
- */
-public interface OptimisticCacheSource {
-	/**
-	 * Is the data to be cached considered versioned?
-	 * <p/>
-	 * If true, it is illegal for {@link #getVersionComparator} to return
-	 * null.
-	 *
-	 * @return True if the data is versioned; false otherwise.
-	 */
-	public boolean isVersioned();
-
-	/**
-	 * Get the comparator used to compare two different version values.
-	 * <p/>
-	 * May return null <b>if</b> {@link #isVersioned()} returns false.
-	 * @return
-	 */
-	public Comparator getVersionComparator();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/OptimisticCacheSource.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Comparator;
+
+/**
+ * Contract for sources of optimistically lockable data sent to the second level
+ * cache.
+ * <p/>
+ * Note currently {@link org.hibernate.persister.entity.EntityPersister}s are
+ * the only viable source.
+ *
+ * @author Steve Ebersole
+ */
+public interface OptimisticCacheSource {
+	/**
+	 * Is the data to be cached considered versioned?
+	 * <p/>
+	 * If true, it is illegal for {@link #getVersionComparator} to return
+	 * null.
+	 *
+	 * @return True if the data is versioned; false otherwise.
+	 */
+	public boolean isVersioned();
+
+	/**
+	 * Get the comparator used to compare two different version values.
+	 * <p/>
+	 * May return null <b>if</b> {@link #isVersioned()} returns false.
+	 * @return
+	 */
+	public Comparator getVersionComparator();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/QueryCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-//$Id: QueryCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.List;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Defines the contract for caches capable of storing query results.  These
- * caches should only concern themselves with storing the matching result ids.
- * The transactional semantics are necessarily less strict than the semantics
- * of an item cache.
- * 
- * @author Gavin King
- */
-public interface QueryCache {
-
-	public void clear() throws CacheException;
-	
-	public boolean put(QueryKey key, Type[] returnTypes, List result, boolean isNaturalKeyLookup, SessionImplementor session) throws HibernateException;
-
-	public List get(QueryKey key, Type[] returnTypes, boolean isNaturalKeyLookup, Set spaces, SessionImplementor session) throws HibernateException;
-
-	public void destroy();
-
-	public QueryResultsRegion getRegion();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/QueryCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.cache;
+
+import java.util.List;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Defines the contract for caches capable of storing query results.  These
+ * caches should only concern themselves with storing the matching result ids.
+ * The transactional semantics are necessarily less strict than the semantics
+ * of an item cache.
+ * 
+ * @author Gavin King
+ */
+public interface QueryCache {
+
+	public void clear() throws CacheException;
+	
+	public boolean put(QueryKey key, Type[] returnTypes, List result, boolean isNaturalKeyLookup, SessionImplementor session) throws HibernateException;
+
+	public List get(QueryKey key, Type[] returnTypes, boolean isNaturalKeyLookup, Set spaces, SessionImplementor session) throws HibernateException;
+
+	public void destroy();
+
+	public QueryResultsRegion getRegion();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-// $Id: QueryCacheFactory.java 4690 2004-10-26 09:35:46Z oneovthafew $
-package org.hibernate.cache;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Settings;
-
-import java.util.Properties;
-
-/**
- * Defines a factory for query cache instances.  These factories are responsible for
- * creating individual QueryCache instances.
- *
- * @author Steve Ebersole
- */
-public interface QueryCacheFactory {
-
-	public QueryCache getQueryCache(
-	        String regionName,
-	        UpdateTimestampsCache updateTimestampsCache,
-			Settings settings,
-	        Properties props) 
-	throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryCacheFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Settings;
+
+import java.util.Properties;
+
+/**
+ * Defines a factory for query cache instances.  These factories are responsible for
+ * creating individual QueryCache instances.
+ *
+ * @author Steve Ebersole
+ */
+public interface QueryCacheFactory {
+
+	public QueryCache getQueryCache(
+	        String regionName,
+	        UpdateTimestampsCache updateTimestampsCache,
+			Settings settings,
+	        Properties props) 
+	throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/QueryKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,118 +0,0 @@
-//$Id: QueryKey.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-import org.hibernate.util.EqualsHelper;
-
-/**
- * A key that identifies a particular query with bound parameter values
- * @author Gavin King
- */
-public class QueryKey implements Serializable {
-	private final String sqlQueryString;
-	private final Type[] types;
-	private final Object[] values;
-	private final Integer firstRow;
-	private final Integer maxRows;
-	private final Map namedParameters;
-	private final EntityMode entityMode;
-	private final Set filters;
-	private final int hashCode;
-	
-	// the user provided resulttransformer, not the one used with "select new". Here to avoid mangling transformed/non-transformed results.
-	private final ResultTransformer customTransformer;
-	
-	public QueryKey(String queryString, QueryParameters queryParameters, Set filters, EntityMode entityMode) {
-		this.sqlQueryString = queryString;
-		this.types = queryParameters.getPositionalParameterTypes();
-		this.values = queryParameters.getPositionalParameterValues();
-		RowSelection selection = queryParameters.getRowSelection();
-		if (selection!=null) {
-			firstRow = selection.getFirstRow();
-			maxRows = selection.getMaxRows();
-		}
-		else {
-			firstRow = null;
-			maxRows = null;
-		}
-		this.namedParameters = queryParameters.getNamedParameters();
-		this.entityMode = entityMode;
-		this.filters = filters;
-		this.customTransformer = queryParameters.getResultTransformer();
-		this.hashCode = getHashCode();
-	}
-	
-	public boolean equals(Object other) {
-		if (!(other instanceof QueryKey)) return false;
-		QueryKey that = (QueryKey) other;
-		if ( !sqlQueryString.equals(that.sqlQueryString) ) return false;
-		if ( !EqualsHelper.equals(firstRow, that.firstRow) || !EqualsHelper.equals(maxRows, that.maxRows) ) return false;
-		if ( !EqualsHelper.equals(customTransformer, that.customTransformer) ) return false;
-		if (types==null) {
-			if (that.types!=null) return false;
-		}
-		else {
-			if (that.types==null) return false;
-			if ( types.length!=that.types.length ) return false;
-			for ( int i=0; i<types.length; i++ ) {
-				if ( types[i].getReturnedClass() != that.types[i].getReturnedClass() ) return false;
-				if ( !types[i].isEqual( values[i], that.values[i], entityMode ) ) return false;
-			}
-		}
-		if ( !EqualsHelper.equals(filters, that.filters) ) return false;
-		if ( !EqualsHelper.equals(namedParameters, that.namedParameters) ) return false;
-		return true;
-	}
-	
-	public int hashCode() {
-		return hashCode;
-	}
-	
-	private int getHashCode() {
-		int result = 13;
-		result = 37 * result + ( firstRow==null ? 0 : firstRow.hashCode() );
-		result = 37 * result + ( maxRows==null ? 0 : maxRows.hashCode() );
-		for ( int i=0; i<values.length; i++ ) {
-			result = 37 * result + ( values[i]==null ? 0 : types[i].getHashCode( values[i], entityMode ) );
-		}
-		result = 37 * result + ( namedParameters==null ? 0 : namedParameters.hashCode() );
-		result = 37 * result + ( filters==null ? 0 : filters.hashCode() );
-		result = 37 * result + ( customTransformer==null ? 0 : customTransformer.hashCode() );
-		result = 37 * result + sqlQueryString.hashCode();
-		return result;
-	}
-
-	public String toString() {
-		StringBuffer buf = new StringBuffer()
-			.append("sql: ")
-			.append(sqlQueryString);
-		if (values!=null) {
-			buf.append("; parameters: ");
-			for (int i=0; i<values.length; i++) {
-				buf.append( values[i] )
-					.append(", ");
-			}
-		}
-		if (namedParameters!=null) {
-			buf.append("; named parameters: ")
-				.append(namedParameters);
-		}
-		if (filters!=null) {
-			buf.append("; filters: ")
-				.append(filters);
-		}
-		if (firstRow!=null) buf.append("; first row: ").append(firstRow);
-		if (maxRows!=null) buf.append("; max rows: ").append(maxRows);
-		if (customTransformer!=null) buf.append("; transformer: ").append(customTransformer);
-		return buf.toString();
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/QueryKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,141 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.EntityMode;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+import org.hibernate.util.EqualsHelper;
+
+/**
+ * A key that identifies a particular query with bound parameter values
+ * @author Gavin King
+ */
+public class QueryKey implements Serializable {
+	private final String sqlQueryString;
+	private final Type[] types;
+	private final Object[] values;
+	private final Integer firstRow;
+	private final Integer maxRows;
+	private final Map namedParameters;
+	private final EntityMode entityMode;
+	private final Set filters;
+	private final int hashCode;
+	
+	// the user provided resulttransformer, not the one used with "select new". Here to avoid mangling transformed/non-transformed results.
+	private final ResultTransformer customTransformer;
+	
+	public QueryKey(String queryString, QueryParameters queryParameters, Set filters, EntityMode entityMode) {
+		this.sqlQueryString = queryString;
+		this.types = queryParameters.getPositionalParameterTypes();
+		this.values = queryParameters.getPositionalParameterValues();
+		RowSelection selection = queryParameters.getRowSelection();
+		if (selection!=null) {
+			firstRow = selection.getFirstRow();
+			maxRows = selection.getMaxRows();
+		}
+		else {
+			firstRow = null;
+			maxRows = null;
+		}
+		this.namedParameters = queryParameters.getNamedParameters();
+		this.entityMode = entityMode;
+		this.filters = filters;
+		this.customTransformer = queryParameters.getResultTransformer();
+		this.hashCode = getHashCode();
+	}
+	
+	public boolean equals(Object other) {
+		if (!(other instanceof QueryKey)) return false;
+		QueryKey that = (QueryKey) other;
+		if ( !sqlQueryString.equals(that.sqlQueryString) ) return false;
+		if ( !EqualsHelper.equals(firstRow, that.firstRow) || !EqualsHelper.equals(maxRows, that.maxRows) ) return false;
+		if ( !EqualsHelper.equals(customTransformer, that.customTransformer) ) return false;
+		if (types==null) {
+			if (that.types!=null) return false;
+		}
+		else {
+			if (that.types==null) return false;
+			if ( types.length!=that.types.length ) return false;
+			for ( int i=0; i<types.length; i++ ) {
+				if ( types[i].getReturnedClass() != that.types[i].getReturnedClass() ) return false;
+				if ( !types[i].isEqual( values[i], that.values[i], entityMode ) ) return false;
+			}
+		}
+		if ( !EqualsHelper.equals(filters, that.filters) ) return false;
+		if ( !EqualsHelper.equals(namedParameters, that.namedParameters) ) return false;
+		return true;
+	}
+	
+	public int hashCode() {
+		return hashCode;
+	}
+	
+	private int getHashCode() {
+		int result = 13;
+		result = 37 * result + ( firstRow==null ? 0 : firstRow.hashCode() );
+		result = 37 * result + ( maxRows==null ? 0 : maxRows.hashCode() );
+		for ( int i=0; i<values.length; i++ ) {
+			result = 37 * result + ( values[i]==null ? 0 : types[i].getHashCode( values[i], entityMode ) );
+		}
+		result = 37 * result + ( namedParameters==null ? 0 : namedParameters.hashCode() );
+		result = 37 * result + ( filters==null ? 0 : filters.hashCode() );
+		result = 37 * result + ( customTransformer==null ? 0 : customTransformer.hashCode() );
+		result = 37 * result + sqlQueryString.hashCode();
+		return result;
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer()
+			.append("sql: ")
+			.append(sqlQueryString);
+		if (values!=null) {
+			buf.append("; parameters: ");
+			for (int i=0; i<values.length; i++) {
+				buf.append( values[i] )
+					.append(", ");
+			}
+		}
+		if (namedParameters!=null) {
+			buf.append("; named parameters: ")
+				.append(namedParameters);
+		}
+		if (filters!=null) {
+			buf.append("; filters: ")
+				.append(filters);
+		}
+		if (firstRow!=null) buf.append("; first row: ").append(firstRow);
+		if (maxRows!=null) buf.append("; max rows: ").append(maxRows);
+		if (customTransformer!=null) buf.append("; transformer: ").append(customTransformer);
+		return buf.toString();
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * Defines the contract for a cache region which will specifically be used to
- * store query results.
- *
- * @author Steve Ebersole
- */
-public interface QueryResultsRegion extends GeneralDataRegion {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/QueryResultsRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+/*
+ * 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.cache;
+
+/**
+ * Defines the contract for a cache region which will specifically be used to
+ * store query results.
+ *
+ * @author Steve Ebersole
+ */
+public interface QueryResultsRegion extends GeneralDataRegion {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,139 +0,0 @@
-//$Id: ReadOnlyCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.access.SoftLock;
-
-/**
- * Caches data that is never updated.
- * @see CacheConcurrencyStrategy
- */
-public class ReadOnlyCache implements CacheConcurrencyStrategy {
-	
-	private Cache cache;
-	private static final Logger log = LoggerFactory.getLogger(ReadOnlyCache.class);
-	
-	public ReadOnlyCache() {}
-	
-	public void setCache(Cache cache) {
-		this.cache=cache;
-	}
-
-	public Cache getCache() {
-		return cache;
-	}
-
-	public String getRegionName() {
-		return cache.getRegionName();
-	}
-	
-	public synchronized Object get(Object key, long timestamp) throws CacheException {
-		Object result = cache.get(key);
-		if ( result!=null && log.isDebugEnabled() ) log.debug("Cache hit: " + key);
-		return result;
-	}
-	
-	/**
-	 * Unsupported!
-	 */
-	public SoftLock lock(Object key, Object version) {
-		log.error("Application attempted to edit read only item: " + key);
-		throw new UnsupportedOperationException("Can't write to a readonly object");
-	}
-	
-	public synchronized boolean put(
-			Object key, 
-			Object value, 
-			long timestamp, 
-			Object version, 
-			Comparator versionComparator,
-			boolean minimalPut) 
-	throws CacheException {
-		if ( minimalPut && cache.get(key)!=null ) {
-			if ( log.isDebugEnabled() ) log.debug("item already cached: " + key);
-			return false;
-		}
-		if ( log.isDebugEnabled() ) log.debug("Caching: " + key);
-		cache.put(key, value);
-		return true;
-	}
-	
-	/**
-	 * Unsupported!
-	 */
-	public void release(Object key, SoftLock lock) {
-		log.error("Application attempted to edit read only item: " + key);
-		//throw new UnsupportedOperationException("Can't write to a readonly object");
-	}
-	
-	public void clear() throws CacheException {
-		cache.clear();
-	}
-
-	public void remove(Object key) throws CacheException {
-		cache.remove(key);
-	}
-	
-	public void destroy() {
-		try {
-			cache.destroy();
-		}
-		catch (Exception e) {
-			log.warn("could not destroy cache", e);
-		}
-	}
-
-	/**
-	 * Unsupported!
-	 */
-	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
-		log.error("Application attempted to edit read only item: " + key);
-		throw new UnsupportedOperationException("Can't write to a readonly object");
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {		
-		if ( log.isDebugEnabled() ) log.debug("Caching after insert: " + key);
-		cache.update(key, value);
-		return true;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public void evict(Object key) throws CacheException {
-		// noop
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean insert(Object key, Object value, Object currentVersion) {
-		return false;
-	}
-
-	/**
-	 * Unsupported!
-	 */
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
-		log.error("Application attempted to edit read only item: " + key);
-		throw new UnsupportedOperationException("Can't write to a readonly object");
-	}
-
-	public String toString() {
-		return cache + "(read-only)";
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadOnlyCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.access.SoftLock;
+
+/**
+ * Caches data that is never updated.
+ * @see CacheConcurrencyStrategy
+ */
+public class ReadOnlyCache implements CacheConcurrencyStrategy {
+	
+	private Cache cache;
+	private static final Logger log = LoggerFactory.getLogger(ReadOnlyCache.class);
+	
+	public ReadOnlyCache() {}
+	
+	public void setCache(Cache cache) {
+		this.cache=cache;
+	}
+
+	public Cache getCache() {
+		return cache;
+	}
+
+	public String getRegionName() {
+		return cache.getRegionName();
+	}
+	
+	public synchronized Object get(Object key, long timestamp) throws CacheException {
+		Object result = cache.get(key);
+		if ( result!=null && log.isDebugEnabled() ) log.debug("Cache hit: " + key);
+		return result;
+	}
+	
+	/**
+	 * Unsupported!
+	 */
+	public SoftLock lock(Object key, Object version) {
+		log.error("Application attempted to edit read only item: " + key);
+		throw new UnsupportedOperationException("Can't write to a readonly object");
+	}
+	
+	public synchronized boolean put(
+			Object key, 
+			Object value, 
+			long timestamp, 
+			Object version, 
+			Comparator versionComparator,
+			boolean minimalPut) 
+	throws CacheException {
+		if ( minimalPut && cache.get(key)!=null ) {
+			if ( log.isDebugEnabled() ) log.debug("item already cached: " + key);
+			return false;
+		}
+		if ( log.isDebugEnabled() ) log.debug("Caching: " + key);
+		cache.put(key, value);
+		return true;
+	}
+	
+	/**
+	 * Unsupported!
+	 */
+	public void release(Object key, SoftLock lock) {
+		log.error("Application attempted to edit read only item: " + key);
+		//throw new UnsupportedOperationException("Can't write to a readonly object");
+	}
+	
+	public void clear() throws CacheException {
+		cache.clear();
+	}
+
+	public void remove(Object key) throws CacheException {
+		cache.remove(key);
+	}
+	
+	public void destroy() {
+		try {
+			cache.destroy();
+		}
+		catch (Exception e) {
+			log.warn("could not destroy cache", e);
+		}
+	}
+
+	/**
+	 * Unsupported!
+	 */
+	public boolean afterUpdate(Object key, Object value, Object version, SoftLock lock) throws CacheException {
+		log.error("Application attempted to edit read only item: " + key);
+		throw new UnsupportedOperationException("Can't write to a readonly object");
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {		
+		if ( log.isDebugEnabled() ) log.debug("Caching after insert: " + key);
+		cache.update(key, value);
+		return true;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public void evict(Object key) throws CacheException {
+		// noop
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean insert(Object key, Object value, Object currentVersion) {
+		return false;
+	}
+
+	/**
+	 * Unsupported!
+	 */
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
+		log.error("Application attempted to edit read only item: " + key);
+		throw new UnsupportedOperationException("Can't write to a readonly object");
+	}
+
+	public String toString() {
+		return cache + "(read-only)";
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/ReadWriteCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,508 +0,0 @@
-//$Id: ReadWriteCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.access.SoftLock;
-
-/**
- * Caches data that is sometimes updated while maintaining the semantics of
- * "read committed" isolation level. If the database is set to "repeatable
- * read", this concurrency strategy <em>almost</em> maintains the semantics.
- * Repeatable read isolation is compromised in the case of concurrent writes.
- * This is an "asynchronous" concurrency strategy.<br>
- * <br>
- * If this strategy is used in a cluster, the underlying cache implementation
- * must support distributed hard locks (which are held only momentarily). This
- * strategy also assumes that the underlying cache implementation does not do
- * asynchronous replication and that state has been fully replicated as soon
- * as the lock is released.
- *
- * @see NonstrictReadWriteCache for a faster algorithm
- * @see CacheConcurrencyStrategy
- */
-public class ReadWriteCache implements CacheConcurrencyStrategy {
-
-	private static final Logger log = LoggerFactory.getLogger(ReadWriteCache.class);
-
-	private Cache cache;
-	private int nextLockId;
-
-	public ReadWriteCache() {}
-
-	public void setCache(Cache cache) {
-		this.cache=cache;
-	}
-
-	public Cache getCache() {
-		return cache;
-	}
-
-	public String getRegionName() {
-		return cache.getRegionName();
-	}
-	
-	/**
-	 * Generate an id for a new lock. Uniqueness per cache instance is very
-	 * desirable but not absolutely critical. Must be called from one of the
-	 * synchronized methods of this class.
-	 */
-	private int nextLockId() {
-		if (nextLockId==Integer.MAX_VALUE) nextLockId = Integer.MIN_VALUE;
-		return nextLockId++;
-	}
-
-	/**
-	 * Do not return an item whose timestamp is later than the current
-	 * transaction timestamp. (Otherwise we might compromise repeatable
-	 * read unnecessarily.) Do not return an item which is soft-locked.
-	 * Always go straight to the database instead.<br>
-	 * <br>
-	 * Note that since reading an item from that cache does not actually
-	 * go to the database, it is possible to see a kind of phantom read
-	 * due to the underlying row being updated after we have read it
-	 * from the cache. This would not be possible in a lock-based
-	 * implementation of repeatable read isolation. It is also possible
-	 * to overwrite changes made and committed by another transaction
-	 * after the current transaction read the item from the cache. This
-	 * problem would be caught by the update-time version-checking, if
-	 * the data is versioned or timestamped.
-	 */
-	public synchronized Object get(Object key, long txTimestamp) throws CacheException {
-
-		if ( log.isTraceEnabled() ) log.trace("Cache lookup: " + key);
-
-		/*try {
-			cache.lock(key);*/
-
-			Lockable lockable = (Lockable) cache.get(key);
-
-			boolean gettable = lockable!=null && lockable.isGettable(txTimestamp);
-
-			if (gettable) {
-				if ( log.isTraceEnabled() ) log.trace("Cache hit: " + key);
-				return ( (Item) lockable ).getValue();
-			}
-			else {
-				if ( log.isTraceEnabled() ) {
-					if (lockable==null) {
-						log.trace("Cache miss: " + key);
-					}
-					else {
-						log.trace("Cached item was locked: " + key);
-					}
-				}
-				return null;
-			}
-		/*}
-		finally {
-			cache.unlock(key);
-		}*/
-	}
-
-	/**
-	 * Stop any other transactions reading or writing this item to/from
-	 * the cache. Send them straight to the database instead. (The lock
-	 * does time out eventually.) This implementation tracks concurrent
-	 * locks of transactions which simultaneously attempt to write to an
-	 * item.
-	 */
-	public synchronized SoftLock lock(Object key, Object version) throws CacheException {
-		if ( log.isTraceEnabled() ) log.trace("Invalidating: " + key);
-
-		try {
-			cache.lock(key);
-
-			Lockable lockable = (Lockable) cache.get(key);
-			long timeout = cache.nextTimestamp() + cache.getTimeout();
-			final Lock lock = (lockable==null) ?
-				new Lock( timeout, nextLockId(), version ) :
-				lockable.lock( timeout, nextLockId() );
-			cache.update(key, lock);
-			return lock;
-		}
-		finally {
-			cache.unlock(key);
-		}
-
-	}
-
-	/**
-	 * Do not add an item to the cache unless the current transaction
-	 * timestamp is later than the timestamp at which the item was
-	 * invalidated. (Otherwise, a stale item might be re-added if the
-	 * database is operating in repeatable read isolation mode.)
-	 * For versioned data, don't add the item unless it is the later
-	 * version.
-	 */
-	public synchronized boolean put(
-			Object key, 
-			Object value, 
-			long txTimestamp, 
-			Object version, 
-			Comparator versionComparator,
-			boolean minimalPut) 
-	throws CacheException {
-		if ( log.isTraceEnabled() ) log.trace("Caching: " + key);
-
-		try {
-			cache.lock(key);
-
-			Lockable lockable = (Lockable) cache.get(key);
-
-			boolean puttable = lockable==null || 
-				lockable.isPuttable(txTimestamp, version, versionComparator);
-
-			if (puttable) {
-				cache.put( key, new Item( value, version, cache.nextTimestamp() ) );
-				if ( log.isTraceEnabled() ) log.trace("Cached: " + key);
-				return true;
-			}
-			else {
-				if ( log.isTraceEnabled() ) {
-					if ( lockable.isLock() ) {
-						log.trace("Item was locked: " + key);
-					}
-					else {
-						log.trace("Item was already cached: " + key);
-					}
-				}
-				return false;
-			}
-		}
-		finally {
-			cache.unlock(key);
-		}
-	}
-
-	/**
-	 * decrement a lock and put it back in the cache
-	 */
-	private void decrementLock(Object key, Lock lock) throws CacheException {
-		//decrement the lock
-		lock.unlock( cache.nextTimestamp() );
-		cache.update(key, lock);
-	}
-
-	/**
-	 * Release the soft lock on the item. Other transactions may now
-	 * re-cache the item (assuming that no other transaction holds a
-	 * simultaneous lock).
-	 */
-	public synchronized void release(Object key, SoftLock clientLock) throws CacheException {
-		if ( log.isTraceEnabled() ) log.trace("Releasing: " + key);
-
-		try {
-			cache.lock(key);
-
-			Lockable lockable = (Lockable) cache.get(key);
-			if ( isUnlockable(clientLock, lockable) ) {
-				decrementLock(key, (Lock) lockable);
-			}
-			else {
-				handleLockExpiry(key);
-			}
-		}
-		finally {
-			cache.unlock(key);
-		}
-	}
-
-	void handleLockExpiry(Object key) throws CacheException {
-		log.warn("An item was expired by the cache while it was locked (increase your cache timeout): " + key);
-		long ts = cache.nextTimestamp() + cache.getTimeout();
-		// create new lock that times out immediately
-		Lock lock = new Lock( ts, nextLockId(), null );
-		lock.unlock(ts);
-		cache.update(key, lock);
-	}
-
-	public void clear() throws CacheException {
-		cache.clear();
-	}
-
-	public void remove(Object key) throws CacheException {
-		cache.remove(key);
-	}
-
-	public void destroy() {
-		try {
-			cache.destroy();
-		}
-		catch (Exception e) {
-			log.warn("could not destroy cache", e);
-		}
-	}
-
-	/**
-	 * Re-cache the updated state, if and only if there there are
-	 * no other concurrent soft locks. Release our lock.
-	 */
-	public synchronized boolean afterUpdate(Object key, Object value, Object version, SoftLock clientLock) 
-	throws CacheException {
-		
-		if ( log.isTraceEnabled() ) log.trace("Updating: " + key);
-
-		try {
-			cache.lock(key);
-
-			Lockable lockable = (Lockable) cache.get(key);
-			if ( isUnlockable(clientLock, lockable) ) {
-				Lock lock = (Lock) lockable;
-				if ( lock.wasLockedConcurrently() ) {
-					// just decrement the lock, don't recache
-					// (we don't know which transaction won)
-					decrementLock(key, lock);
-					return false;
-				}
-				else {
-					//recache the updated state
-					cache.update( key, new Item( value, version, cache.nextTimestamp() ) );
-					if ( log.isTraceEnabled() ) log.trace("Updated: " + key);
-					return true;
-				}
-			}
-			else {
-				handleLockExpiry(key);
-				return false;
-			}
-
-		}
-		finally {
-			cache.unlock(key);
-		}
-	}
-
-	/**
-	 * Add the new item to the cache, checking that no other transaction has
-	 * accessed the item.
-	 */
-	public synchronized boolean afterInsert(Object key, Object value, Object version) 
-	throws CacheException {
-	
-		if ( log.isTraceEnabled() ) log.trace("Inserting: " + key);
-		try {
-			cache.lock(key);
-
-			Lockable lockable = (Lockable) cache.get(key);
-			if (lockable==null) {
-				cache.update( key, new Item( value, version, cache.nextTimestamp() ) );
-				if ( log.isTraceEnabled() ) log.trace("Inserted: " + key);
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		finally {
-			cache.unlock(key);
-		}
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public void evict(Object key) throws CacheException {
-		// noop
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean insert(Object key, Object value, Object currentVersion) {
-		return false;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
-		return false;
-	}
-
-	/**
-	 * Is the client's lock commensurate with the item in the cache?
-	 * If it is not, we know that the cache expired the original
-	 * lock.
-	 */
-	private boolean isUnlockable(SoftLock clientLock, Lockable myLock)
-	throws CacheException {
-		//null clientLock is remotely possible but will never happen in practice
-		return myLock!=null &&
-			myLock.isLock() &&
-			clientLock!=null &&
-			( (Lock) clientLock ).getId()==( (Lock) myLock ).getId();
-	}
-
-	public static interface Lockable {
-		public Lock lock(long timeout, int id);
-		public boolean isLock();
-		public boolean isGettable(long txTimestamp);
-		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator);
-	}
-
-	/**
-	 * An item of cached data, timestamped with the time it was cached,.
-	 * @see ReadWriteCache
-	 */
-	public static final class Item implements Serializable, Lockable {
-
-		private final long freshTimestamp;
-		private final Object value;
-		private final Object version;
-
-		public Item(Object value, Object version, long currentTimestamp) {
-			this.value = value;
-			this.version = version;
-			freshTimestamp = currentTimestamp;
-		}
-		/**
-		 * The timestamp on the cached data
-		 */
-		public long getFreshTimestamp() {
-			return freshTimestamp;
-		}
-		/**
-		 * The actual cached data
-		 */
-		public Object getValue() {
-			return value;
-		}
-
-		/**
-		 * Lock the item
-		 */
-		public Lock lock(long timeout, int id) {
-			return new Lock(timeout, id, version);
-		}
-		/**
-		 * Not a lock!
-		 */
-		public boolean isLock() {
-			return false;
-		}
-		/**
-		 * Is this item visible to the timestamped
-		 * transaction?
-		 */
-		public boolean isGettable(long txTimestamp) {
-			return freshTimestamp < txTimestamp;
-		}
-
-		/**
-		 * Don't overwite already cached items
-		 */
-		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
-			// we really could refresh the item if it
-			// is not a lock, but it might be slower
-			//return freshTimestamp < txTimestamp
-			return version!=null && comparator.compare(version, newVersion) < 0;
-		}
-
-		public String toString() {
-			return "Item{version=" + version +
-				",freshTimestamp=" + freshTimestamp;
-		}
-	}
-
-	/**
-	 * A soft lock which supports concurrent locking,
-	 * timestamped with the time it was released
-	 * @author Gavin King
-	 */
-	public static final class Lock implements Serializable, Lockable, SoftLock {
-		private long unlockTimestamp = -1;
-		private int multiplicity = 1;
-		private boolean concurrentLock = false;
-		private long timeout;
-		private final int id;
-		private final Object version;
-
-		public Lock(long timeout, int id, Object version) {
-			this.timeout = timeout;
-			this.id = id;
-			this.version = version;
-		}
-
-		public long getUnlockTimestamp() {
-			return unlockTimestamp;
-		}
-		/**
-		 * Increment the lock, setting the
-		 * new lock timeout
-		 */
-		public Lock lock(long timeout, int id) {
-			concurrentLock = true;
-			multiplicity++;
-			this.timeout = timeout;
-			return this;
-		}
-		/**
-		 * Decrement the lock, setting the unlock
-		 * timestamp if now unlocked
-		 * @param currentTimestamp
-		 */
-		public void unlock(long currentTimestamp) {
-			if ( --multiplicity == 0 ) {
-				unlockTimestamp = currentTimestamp;
-			}
-		}
-
-		/**
-		 * Can the timestamped transaction re-cache this
-		 * locked item now?
-		 */
-		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
-			if (timeout < txTimestamp) return true;
-			if (multiplicity>0) return false;
-			return version==null ? 
-				unlockTimestamp < txTimestamp :
-				comparator.compare(version, newVersion) < 0; //by requiring <, we rely on lock timeout in the case of an unsuccessful update!
-		}
-
-		/**
-		 * Was this lock held concurrently by multiple
-		 * transactions?
-		 */
-		public boolean wasLockedConcurrently() {
-			return concurrentLock;
-		}
-		/**
-		 * Yes, this is a lock
-		 */
-		public boolean isLock() {
-			return true;
-		}
-		/**
-		 * locks are not returned to the client!
-		 */
-		public boolean isGettable(long txTimestamp) {
-			return false;
-		}
-
-		public int getId() { return id; }
-
-		public String toString() {
-			return "Lock{id=" + id +
-				",version=" + version +
-				",multiplicity=" + multiplicity +
-				",unlockTimestamp=" + unlockTimestamp;
-		}
-
-	}
-
-	public String toString() {
-		return cache + "(read-write)";
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/ReadWriteCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/ReadWriteCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,531 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.access.SoftLock;
+
+/**
+ * Caches data that is sometimes updated while maintaining the semantics of
+ * "read committed" isolation level. If the database is set to "repeatable
+ * read", this concurrency strategy <em>almost</em> maintains the semantics.
+ * Repeatable read isolation is compromised in the case of concurrent writes.
+ * This is an "asynchronous" concurrency strategy.<br>
+ * <br>
+ * If this strategy is used in a cluster, the underlying cache implementation
+ * must support distributed hard locks (which are held only momentarily). This
+ * strategy also assumes that the underlying cache implementation does not do
+ * asynchronous replication and that state has been fully replicated as soon
+ * as the lock is released.
+ *
+ * @see NonstrictReadWriteCache for a faster algorithm
+ * @see CacheConcurrencyStrategy
+ */
+public class ReadWriteCache implements CacheConcurrencyStrategy {
+
+	private static final Logger log = LoggerFactory.getLogger(ReadWriteCache.class);
+
+	private Cache cache;
+	private int nextLockId;
+
+	public ReadWriteCache() {}
+
+	public void setCache(Cache cache) {
+		this.cache=cache;
+	}
+
+	public Cache getCache() {
+		return cache;
+	}
+
+	public String getRegionName() {
+		return cache.getRegionName();
+	}
+	
+	/**
+	 * Generate an id for a new lock. Uniqueness per cache instance is very
+	 * desirable but not absolutely critical. Must be called from one of the
+	 * synchronized methods of this class.
+	 */
+	private int nextLockId() {
+		if (nextLockId==Integer.MAX_VALUE) nextLockId = Integer.MIN_VALUE;
+		return nextLockId++;
+	}
+
+	/**
+	 * Do not return an item whose timestamp is later than the current
+	 * transaction timestamp. (Otherwise we might compromise repeatable
+	 * read unnecessarily.) Do not return an item which is soft-locked.
+	 * Always go straight to the database instead.<br>
+	 * <br>
+	 * Note that since reading an item from that cache does not actually
+	 * go to the database, it is possible to see a kind of phantom read
+	 * due to the underlying row being updated after we have read it
+	 * from the cache. This would not be possible in a lock-based
+	 * implementation of repeatable read isolation. It is also possible
+	 * to overwrite changes made and committed by another transaction
+	 * after the current transaction read the item from the cache. This
+	 * problem would be caught by the update-time version-checking, if
+	 * the data is versioned or timestamped.
+	 */
+	public synchronized Object get(Object key, long txTimestamp) throws CacheException {
+
+		if ( log.isTraceEnabled() ) log.trace("Cache lookup: " + key);
+
+		/*try {
+			cache.lock(key);*/
+
+			Lockable lockable = (Lockable) cache.get(key);
+
+			boolean gettable = lockable!=null && lockable.isGettable(txTimestamp);
+
+			if (gettable) {
+				if ( log.isTraceEnabled() ) log.trace("Cache hit: " + key);
+				return ( (Item) lockable ).getValue();
+			}
+			else {
+				if ( log.isTraceEnabled() ) {
+					if (lockable==null) {
+						log.trace("Cache miss: " + key);
+					}
+					else {
+						log.trace("Cached item was locked: " + key);
+					}
+				}
+				return null;
+			}
+		/*}
+		finally {
+			cache.unlock(key);
+		}*/
+	}
+
+	/**
+	 * Stop any other transactions reading or writing this item to/from
+	 * the cache. Send them straight to the database instead. (The lock
+	 * does time out eventually.) This implementation tracks concurrent
+	 * locks of transactions which simultaneously attempt to write to an
+	 * item.
+	 */
+	public synchronized SoftLock lock(Object key, Object version) throws CacheException {
+		if ( log.isTraceEnabled() ) log.trace("Invalidating: " + key);
+
+		try {
+			cache.lock(key);
+
+			Lockable lockable = (Lockable) cache.get(key);
+			long timeout = cache.nextTimestamp() + cache.getTimeout();
+			final Lock lock = (lockable==null) ?
+				new Lock( timeout, nextLockId(), version ) :
+				lockable.lock( timeout, nextLockId() );
+			cache.update(key, lock);
+			return lock;
+		}
+		finally {
+			cache.unlock(key);
+		}
+
+	}
+
+	/**
+	 * Do not add an item to the cache unless the current transaction
+	 * timestamp is later than the timestamp at which the item was
+	 * invalidated. (Otherwise, a stale item might be re-added if the
+	 * database is operating in repeatable read isolation mode.)
+	 * For versioned data, don't add the item unless it is the later
+	 * version.
+	 */
+	public synchronized boolean put(
+			Object key, 
+			Object value, 
+			long txTimestamp, 
+			Object version, 
+			Comparator versionComparator,
+			boolean minimalPut) 
+	throws CacheException {
+		if ( log.isTraceEnabled() ) log.trace("Caching: " + key);
+
+		try {
+			cache.lock(key);
+
+			Lockable lockable = (Lockable) cache.get(key);
+
+			boolean puttable = lockable==null || 
+				lockable.isPuttable(txTimestamp, version, versionComparator);
+
+			if (puttable) {
+				cache.put( key, new Item( value, version, cache.nextTimestamp() ) );
+				if ( log.isTraceEnabled() ) log.trace("Cached: " + key);
+				return true;
+			}
+			else {
+				if ( log.isTraceEnabled() ) {
+					if ( lockable.isLock() ) {
+						log.trace("Item was locked: " + key);
+					}
+					else {
+						log.trace("Item was already cached: " + key);
+					}
+				}
+				return false;
+			}
+		}
+		finally {
+			cache.unlock(key);
+		}
+	}
+
+	/**
+	 * decrement a lock and put it back in the cache
+	 */
+	private void decrementLock(Object key, Lock lock) throws CacheException {
+		//decrement the lock
+		lock.unlock( cache.nextTimestamp() );
+		cache.update(key, lock);
+	}
+
+	/**
+	 * Release the soft lock on the item. Other transactions may now
+	 * re-cache the item (assuming that no other transaction holds a
+	 * simultaneous lock).
+	 */
+	public synchronized void release(Object key, SoftLock clientLock) throws CacheException {
+		if ( log.isTraceEnabled() ) log.trace("Releasing: " + key);
+
+		try {
+			cache.lock(key);
+
+			Lockable lockable = (Lockable) cache.get(key);
+			if ( isUnlockable(clientLock, lockable) ) {
+				decrementLock(key, (Lock) lockable);
+			}
+			else {
+				handleLockExpiry(key);
+			}
+		}
+		finally {
+			cache.unlock(key);
+		}
+	}
+
+	void handleLockExpiry(Object key) throws CacheException {
+		log.warn("An item was expired by the cache while it was locked (increase your cache timeout): " + key);
+		long ts = cache.nextTimestamp() + cache.getTimeout();
+		// create new lock that times out immediately
+		Lock lock = new Lock( ts, nextLockId(), null );
+		lock.unlock(ts);
+		cache.update(key, lock);
+	}
+
+	public void clear() throws CacheException {
+		cache.clear();
+	}
+
+	public void remove(Object key) throws CacheException {
+		cache.remove(key);
+	}
+
+	public void destroy() {
+		try {
+			cache.destroy();
+		}
+		catch (Exception e) {
+			log.warn("could not destroy cache", e);
+		}
+	}
+
+	/**
+	 * Re-cache the updated state, if and only if there there are
+	 * no other concurrent soft locks. Release our lock.
+	 */
+	public synchronized boolean afterUpdate(Object key, Object value, Object version, SoftLock clientLock) 
+	throws CacheException {
+		
+		if ( log.isTraceEnabled() ) log.trace("Updating: " + key);
+
+		try {
+			cache.lock(key);
+
+			Lockable lockable = (Lockable) cache.get(key);
+			if ( isUnlockable(clientLock, lockable) ) {
+				Lock lock = (Lock) lockable;
+				if ( lock.wasLockedConcurrently() ) {
+					// just decrement the lock, don't recache
+					// (we don't know which transaction won)
+					decrementLock(key, lock);
+					return false;
+				}
+				else {
+					//recache the updated state
+					cache.update( key, new Item( value, version, cache.nextTimestamp() ) );
+					if ( log.isTraceEnabled() ) log.trace("Updated: " + key);
+					return true;
+				}
+			}
+			else {
+				handleLockExpiry(key);
+				return false;
+			}
+
+		}
+		finally {
+			cache.unlock(key);
+		}
+	}
+
+	/**
+	 * Add the new item to the cache, checking that no other transaction has
+	 * accessed the item.
+	 */
+	public synchronized boolean afterInsert(Object key, Object value, Object version) 
+	throws CacheException {
+	
+		if ( log.isTraceEnabled() ) log.trace("Inserting: " + key);
+		try {
+			cache.lock(key);
+
+			Lockable lockable = (Lockable) cache.get(key);
+			if (lockable==null) {
+				cache.update( key, new Item( value, version, cache.nextTimestamp() ) );
+				if ( log.isTraceEnabled() ) log.trace("Inserted: " + key);
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		finally {
+			cache.unlock(key);
+		}
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public void evict(Object key) throws CacheException {
+		// noop
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean insert(Object key, Object value, Object currentVersion) {
+		return false;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) {
+		return false;
+	}
+
+	/**
+	 * Is the client's lock commensurate with the item in the cache?
+	 * If it is not, we know that the cache expired the original
+	 * lock.
+	 */
+	private boolean isUnlockable(SoftLock clientLock, Lockable myLock)
+	throws CacheException {
+		//null clientLock is remotely possible but will never happen in practice
+		return myLock!=null &&
+			myLock.isLock() &&
+			clientLock!=null &&
+			( (Lock) clientLock ).getId()==( (Lock) myLock ).getId();
+	}
+
+	public static interface Lockable {
+		public Lock lock(long timeout, int id);
+		public boolean isLock();
+		public boolean isGettable(long txTimestamp);
+		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator);
+	}
+
+	/**
+	 * An item of cached data, timestamped with the time it was cached,.
+	 * @see ReadWriteCache
+	 */
+	public static final class Item implements Serializable, Lockable {
+
+		private final long freshTimestamp;
+		private final Object value;
+		private final Object version;
+
+		public Item(Object value, Object version, long currentTimestamp) {
+			this.value = value;
+			this.version = version;
+			freshTimestamp = currentTimestamp;
+		}
+		/**
+		 * The timestamp on the cached data
+		 */
+		public long getFreshTimestamp() {
+			return freshTimestamp;
+		}
+		/**
+		 * The actual cached data
+		 */
+		public Object getValue() {
+			return value;
+		}
+
+		/**
+		 * Lock the item
+		 */
+		public Lock lock(long timeout, int id) {
+			return new Lock(timeout, id, version);
+		}
+		/**
+		 * Not a lock!
+		 */
+		public boolean isLock() {
+			return false;
+		}
+		/**
+		 * Is this item visible to the timestamped
+		 * transaction?
+		 */
+		public boolean isGettable(long txTimestamp) {
+			return freshTimestamp < txTimestamp;
+		}
+
+		/**
+		 * Don't overwite already cached items
+		 */
+		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
+			// we really could refresh the item if it
+			// is not a lock, but it might be slower
+			//return freshTimestamp < txTimestamp
+			return version!=null && comparator.compare(version, newVersion) < 0;
+		}
+
+		public String toString() {
+			return "Item{version=" + version +
+				",freshTimestamp=" + freshTimestamp;
+		}
+	}
+
+	/**
+	 * A soft lock which supports concurrent locking,
+	 * timestamped with the time it was released
+	 * @author Gavin King
+	 */
+	public static final class Lock implements Serializable, Lockable, SoftLock {
+		private long unlockTimestamp = -1;
+		private int multiplicity = 1;
+		private boolean concurrentLock = false;
+		private long timeout;
+		private final int id;
+		private final Object version;
+
+		public Lock(long timeout, int id, Object version) {
+			this.timeout = timeout;
+			this.id = id;
+			this.version = version;
+		}
+
+		public long getUnlockTimestamp() {
+			return unlockTimestamp;
+		}
+		/**
+		 * Increment the lock, setting the
+		 * new lock timeout
+		 */
+		public Lock lock(long timeout, int id) {
+			concurrentLock = true;
+			multiplicity++;
+			this.timeout = timeout;
+			return this;
+		}
+		/**
+		 * Decrement the lock, setting the unlock
+		 * timestamp if now unlocked
+		 * @param currentTimestamp
+		 */
+		public void unlock(long currentTimestamp) {
+			if ( --multiplicity == 0 ) {
+				unlockTimestamp = currentTimestamp;
+			}
+		}
+
+		/**
+		 * Can the timestamped transaction re-cache this
+		 * locked item now?
+		 */
+		public boolean isPuttable(long txTimestamp, Object newVersion, Comparator comparator) {
+			if (timeout < txTimestamp) return true;
+			if (multiplicity>0) return false;
+			return version==null ? 
+				unlockTimestamp < txTimestamp :
+				comparator.compare(version, newVersion) < 0; //by requiring <, we rely on lock timeout in the case of an unsuccessful update!
+		}
+
+		/**
+		 * Was this lock held concurrently by multiple
+		 * transactions?
+		 */
+		public boolean wasLockedConcurrently() {
+			return concurrentLock;
+		}
+		/**
+		 * Yes, this is a lock
+		 */
+		public boolean isLock() {
+			return true;
+		}
+		/**
+		 * locks are not returned to the client!
+		 */
+		public boolean isGettable(long txTimestamp) {
+			return false;
+		}
+
+		public int getId() { return id; }
+
+		public String toString() {
+			return "Lock{id=" + id +
+				",version=" + version +
+				",multiplicity=" + multiplicity +
+				",unlockTimestamp=" + unlockTimestamp;
+		}
+
+	}
+
+	public String toString() {
+		return cache + "(read-write)";
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/Region.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-package org.hibernate.cache;
-
-import java.util.Map;
-
-/**
- * Defines a contract for accessing a particular named region within the 
- * underlying cache implementation.
- *
- * @author Steve Ebersole
- */
-public interface Region {
-	/**
-	 * Retrieve the name of this region.
-	 *
-	 * @return The region name
-	 */
-	public String getName();
-
-	/**
-	 * The "end state" contract of the region's lifecycle.  Called
-	 * during {@link org.hibernate.SessionFactory#close()} to give
-	 * the region a chance to cleanup.
-	 *
-	 * @throws CacheException Indicates problem shutting down
-	 */
-	public void destroy() throws CacheException;
-
-	/**
-	 * The number of bytes is this cache region currently consuming in memory.
-	 *
-	 * @return The number of bytes consumed by this region; -1 if unknown or
-	 * unsupported.
-	 */
-	public long getSizeInMemory();
-
-	/**
-	 * The count of entries currently contained in the regions in-memory store.
-	 *
-	 * @return The count of entries in memory; -1 if unknown or unsupported.
-	 */
-	public long getElementCountInMemory();
-
-	/**
-	 * The count of entries currently contained in the regions disk store.
-	 *
-	 * @return The count of entries on disk; -1 if unknown or unsupported.
-	 */
-	public long getElementCountOnDisk();
-
-	/**
-	 * Get the contents of this region as a map.
-	 * <p/>
-	 * Implementors which do not support this notion
-	 * should simply return an empty map.
-	 *
-	 * @return The content map.
-	 */
-	public Map toMap();
-
-	public long nextTimestamp();
-	public int getTimeout();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/Region.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Region.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import java.util.Map;
+
+/**
+ * Defines a contract for accessing a particular named region within the 
+ * underlying cache implementation.
+ *
+ * @author Steve Ebersole
+ */
+public interface Region {
+	/**
+	 * Retrieve the name of this region.
+	 *
+	 * @return The region name
+	 */
+	public String getName();
+
+	/**
+	 * The "end state" contract of the region's lifecycle.  Called
+	 * during {@link org.hibernate.SessionFactory#close()} to give
+	 * the region a chance to cleanup.
+	 *
+	 * @throws CacheException Indicates problem shutting down
+	 */
+	public void destroy() throws CacheException;
+
+	/**
+	 * The number of bytes is this cache region currently consuming in memory.
+	 *
+	 * @return The number of bytes consumed by this region; -1 if unknown or
+	 * unsupported.
+	 */
+	public long getSizeInMemory();
+
+	/**
+	 * The count of entries currently contained in the regions in-memory store.
+	 *
+	 * @return The count of entries in memory; -1 if unknown or unsupported.
+	 */
+	public long getElementCountInMemory();
+
+	/**
+	 * The count of entries currently contained in the regions disk store.
+	 *
+	 * @return The count of entries on disk; -1 if unknown or unsupported.
+	 */
+	public long getElementCountOnDisk();
+
+	/**
+	 * Get the contents of this region as a map.
+	 * <p/>
+	 * Implementors which do not support this notion
+	 * should simply return an empty map.
+	 *
+	 * @return The content map.
+	 */
+	public Map toMap();
+
+	public long nextTimestamp();
+	public int getTimeout();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/RegionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,106 +0,0 @@
-package org.hibernate.cache;
-
-import java.util.Properties;
-
-import org.hibernate.cfg.Settings;
-
-/**
- * Contract for building second level cache regions.
- * <p/>
- * Implementors should define a constructor in one of two forms:<ul>
- * <li>MyRegionFactoryImpl({@link java.util.Properties})</li>
- * <li>MyRegionFactoryImpl()</li>
- * </ul>
- * Use the first when we need to read config properties prior to
- * {@link #start} being called.  For an example, have a look at
- * {@link org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge}
- * where we need the properties in order to determine which legacy 
- * {@link CacheProvider} to use so that we can answer the
- * {@link #isMinimalPutsEnabledByDefault()} question for the
- * {@link org.hibernate.cfg.SettingsFactory}.
- *
- * @author Steve Ebersole
- */
-public interface RegionFactory {
-
-	/**
-	 * Lifecycle callback to perform any necessary initialization of the
-	 * underlying cache implementation(s).  Called exactly once during the
-	 * construction of a {@link org.hibernate.impl.SessionFactoryImpl}.
-	 *
-	 * @param settings The settings in effect.
-	 * @param properties The defined cfg properties
-	 * @throws CacheException Indicates problems starting the L2 cache impl;
-	 * considered as a sign to stop {@link org.hibernate.SessionFactory}
-	 * building.
-	 */
-	public void start(Settings settings, Properties properties) throws CacheException;
-
-	/**
-	 * Lifecycle callback to perform any necessary cleanup of the underlying
-	 * cache implementation(s).  Called exactly once during
-	 * {@link org.hibernate.SessionFactory#close}.
-	 */
-	public void stop();
-
-	/**
-	 * By default should we perform "minimal puts" when using this second
-	 * level cache implementation?
-	 *
-	 * @return True if "minimal puts" should be performed by default; false
-	 * otherwise.
-	 */
-	public boolean isMinimalPutsEnabledByDefault();
-
-	/**
-	 * Generate a timestamp.
-	 * <p/>
-	 * This is generally used for cache content locking/unlocking purposes
-	 * depending upon the access-strategy being used.
-	 *
-	 * @return The generated timestamp.
-	 */
-	public long nextTimestamp();
-
-	/**
-	 * Build a cache region specialized for storing entity data.
-	 *
-	 * @param regionName The name of the region.
-	 * @param properties Configuration properties.
-	 * @param metadata Information regarding the type of data to be cached
-	 * @return The built region
-	 * @throws CacheException Indicates problems building the region.
-	 */
-	public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException;
-
-	/**
-	 * Build a cache region specialized for storing collection data.
-	 *
-	 * @param regionName The name of the region.
-	 * @param properties Configuration properties.
-	 * @param metadata Information regarding the type of data to be cached
-	 * @return The built region
-	 * @throws CacheException Indicates problems building the region.
-	 */
-	public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException;
-
-	/**
-	 * Build a cache region specialized for storing query results
-	 *
-	 * @param regionName The name of the region.
-	 * @param properties Configuration properties.
-	 * @return The built region
-	 * @throws CacheException Indicates problems building the region.
-	 */
-	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException;
-
-	/**
-	 * Build a cache region specialized for storing update-timestamps data.
-	 *
-	 * @param regionName The name of the region.
-	 * @param properties Configuration properties.
-	 * @return The built region
-	 * @throws CacheException Indicates problems building the region.
-	 */
-	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/RegionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/RegionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.cache;
+
+import java.util.Properties;
+
+import org.hibernate.cfg.Settings;
+
+/**
+ * Contract for building second level cache regions.
+ * <p/>
+ * Implementors should define a constructor in one of two forms:<ul>
+ * <li>MyRegionFactoryImpl({@link java.util.Properties})</li>
+ * <li>MyRegionFactoryImpl()</li>
+ * </ul>
+ * Use the first when we need to read config properties prior to
+ * {@link #start} being called.  For an example, have a look at
+ * {@link org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge}
+ * where we need the properties in order to determine which legacy 
+ * {@link CacheProvider} to use so that we can answer the
+ * {@link #isMinimalPutsEnabledByDefault()} question for the
+ * {@link org.hibernate.cfg.SettingsFactory}.
+ *
+ * @author Steve Ebersole
+ */
+public interface RegionFactory {
+
+	/**
+	 * Lifecycle callback to perform any necessary initialization of the
+	 * underlying cache implementation(s).  Called exactly once during the
+	 * construction of a {@link org.hibernate.impl.SessionFactoryImpl}.
+	 *
+	 * @param settings The settings in effect.
+	 * @param properties The defined cfg properties
+	 * @throws CacheException Indicates problems starting the L2 cache impl;
+	 * considered as a sign to stop {@link org.hibernate.SessionFactory}
+	 * building.
+	 */
+	public void start(Settings settings, Properties properties) throws CacheException;
+
+	/**
+	 * Lifecycle callback to perform any necessary cleanup of the underlying
+	 * cache implementation(s).  Called exactly once during
+	 * {@link org.hibernate.SessionFactory#close}.
+	 */
+	public void stop();
+
+	/**
+	 * By default should we perform "minimal puts" when using this second
+	 * level cache implementation?
+	 *
+	 * @return True if "minimal puts" should be performed by default; false
+	 * otherwise.
+	 */
+	public boolean isMinimalPutsEnabledByDefault();
+
+	/**
+	 * Generate a timestamp.
+	 * <p/>
+	 * This is generally used for cache content locking/unlocking purposes
+	 * depending upon the access-strategy being used.
+	 *
+	 * @return The generated timestamp.
+	 */
+	public long nextTimestamp();
+
+	/**
+	 * Build a cache region specialized for storing entity data.
+	 *
+	 * @param regionName The name of the region.
+	 * @param properties Configuration properties.
+	 * @param metadata Information regarding the type of data to be cached
+	 * @return The built region
+	 * @throws CacheException Indicates problems building the region.
+	 */
+	public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException;
+
+	/**
+	 * Build a cache region specialized for storing collection data.
+	 *
+	 * @param regionName The name of the region.
+	 * @param properties Configuration properties.
+	 * @param metadata Information regarding the type of data to be cached
+	 * @return The built region
+	 * @throws CacheException Indicates problems building the region.
+	 */
+	public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata) throws CacheException;
+
+	/**
+	 * Build a cache region specialized for storing query results
+	 *
+	 * @param regionName The name of the region.
+	 * @param properties Configuration properties.
+	 * @return The built region
+	 * @throws CacheException Indicates problems building the region.
+	 */
+	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException;
+
+	/**
+	 * Build a cache region specialized for storing update-timestamps data.
+	 *
+	 * @param regionName The name of the region.
+	 * @param properties Configuration properties.
+	 * @return The built region
+	 * @throws CacheException Indicates problems building the region.
+	 */
+	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/StandardQueryCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,184 +0,0 @@
-//$Id: StandardQueryCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cfg.Settings;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * The standard implementation of the Hibernate QueryCache interface.  This
- * implementation is very good at recognizing stale query results and
- * and re-running queries when it detects this condition, recaching the new
- * results.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class StandardQueryCache implements QueryCache {
-
-	private static final Logger log = LoggerFactory.getLogger( StandardQueryCache.class );
-
-	private QueryResultsRegion cacheRegion;
-	private UpdateTimestampsCache updateTimestampsCache;
-
-	public void clear() throws CacheException {
-		cacheRegion.evictAll();
-	}
-
-	public StandardQueryCache(
-			final Settings settings,
-			final Properties props,
-			final UpdateTimestampsCache updateTimestampsCache,
-			String regionName) throws HibernateException {
-		if ( regionName == null ) {
-			regionName = StandardQueryCache.class.getName();
-		}
-		String prefix = settings.getCacheRegionPrefix();
-		if ( prefix != null ) {
-			regionName = prefix + '.' + regionName;
-		}
-		log.info( "starting query cache at region: " + regionName );
-
-		this.cacheRegion = settings.getRegionFactory().buildQueryResultsRegion( regionName, props );
-		this.updateTimestampsCache = updateTimestampsCache;
-	}
-
-	public boolean put(
-			QueryKey key,
-			Type[] returnTypes,
-			List result,
-			boolean isNaturalKeyLookup,
-			SessionImplementor session) throws HibernateException {
-		if ( isNaturalKeyLookup && result.size() == 0 ) {
-			return false;
-		}
-		else {
-			Long ts = new Long( session.getTimestamp() );
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( "caching query results in region: " + cacheRegion.getName() + "; timestamp=" + ts );
-			}
-
-			List cacheable = new ArrayList( result.size() + 1 );
-			cacheable.add( ts );
-			for ( int i = 0; i < result.size(); i++ ) {
-				if ( returnTypes.length == 1 ) {
-					cacheable.add( returnTypes[0].disassemble( result.get( i ), session, null ) );
-				}
-				else {
-					cacheable.add(
-							TypeFactory.disassemble(
-									( Object[] ) result.get( i ), returnTypes, null, session, null
-							)
-					);
-				}
-			}
-
-			cacheRegion.put( key, cacheable );
-
-			return true;
-
-		}
-
-	}
-
-	public List get(
-			QueryKey key,
-			Type[] returnTypes,
-			boolean isNaturalKeyLookup,
-			Set spaces,
-			SessionImplementor session) throws HibernateException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "checking cached query results in region: " + cacheRegion.getName() );
-		}
-
-		List cacheable = ( List ) cacheRegion.get( key );
-		if ( cacheable == null ) {
-			log.debug( "query results were not found in cache" );
-			return null;
-		}
-
-		Long timestamp = ( Long ) cacheable.get( 0 );
-		if ( !isNaturalKeyLookup && !isUpToDate( spaces, timestamp ) ) {
-			log.debug( "cached query results were not up to date" );
-			return null;
-		}
-
-		log.debug( "returning cached query results" );
-		for ( int i = 1; i < cacheable.size(); i++ ) {
-			if ( returnTypes.length == 1 ) {
-				returnTypes[0].beforeAssemble( ( Serializable ) cacheable.get( i ), session );
-			}
-			else {
-				TypeFactory.beforeAssemble( ( Serializable[] ) cacheable.get( i ), returnTypes, session );
-			}
-		}
-		List result = new ArrayList( cacheable.size() - 1 );
-		for ( int i = 1; i < cacheable.size(); i++ ) {
-			try {
-				if ( returnTypes.length == 1 ) {
-					result.add( returnTypes[0].assemble( ( Serializable ) cacheable.get( i ), session, null ) );
-				}
-				else {
-					result.add(
-							TypeFactory.assemble(
-									( Serializable[] ) cacheable.get( i ), returnTypes, session, null
-							)
-					);
-				}
-			}
-			catch ( UnresolvableObjectException uoe ) {
-				if ( isNaturalKeyLookup ) {
-					//TODO: not really completely correct, since
-					//      the uoe could occur while resolving
-					//      associations, leaving the PC in an
-					//      inconsistent state
-					log.debug( "could not reassemble cached result set" );
-					cacheRegion.evict( key );
-					return null;
-				}
-				else {
-					throw uoe;
-				}
-			}
-		}
-		return result;
-	}
-
-	protected boolean isUpToDate(Set spaces, Long timestamp) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Checking query spaces for up-to-dateness: " + spaces );
-		}
-		return updateTimestampsCache.isUpToDate( spaces, timestamp );
-	}
-
-	public void destroy() {
-		try {
-			cacheRegion.destroy();
-		}
-		catch ( Exception e ) {
-			log.warn( "could not destroy query cache: " + cacheRegion.getName(), e );
-		}
-	}
-
-	public QueryResultsRegion getRegion() {
-		return cacheRegion;
-	}
-
-	public String toString() {
-		return "StandardQueryCache(" + cacheRegion.getName() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/StandardQueryCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,207 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.cfg.Settings;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * The standard implementation of the Hibernate QueryCache interface.  This
+ * implementation is very good at recognizing stale query results and
+ * and re-running queries when it detects this condition, recaching the new
+ * results.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class StandardQueryCache implements QueryCache {
+
+	private static final Logger log = LoggerFactory.getLogger( StandardQueryCache.class );
+
+	private QueryResultsRegion cacheRegion;
+	private UpdateTimestampsCache updateTimestampsCache;
+
+	public void clear() throws CacheException {
+		cacheRegion.evictAll();
+	}
+
+	public StandardQueryCache(
+			final Settings settings,
+			final Properties props,
+			final UpdateTimestampsCache updateTimestampsCache,
+			String regionName) throws HibernateException {
+		if ( regionName == null ) {
+			regionName = StandardQueryCache.class.getName();
+		}
+		String prefix = settings.getCacheRegionPrefix();
+		if ( prefix != null ) {
+			regionName = prefix + '.' + regionName;
+		}
+		log.info( "starting query cache at region: " + regionName );
+
+		this.cacheRegion = settings.getRegionFactory().buildQueryResultsRegion( regionName, props );
+		this.updateTimestampsCache = updateTimestampsCache;
+	}
+
+	public boolean put(
+			QueryKey key,
+			Type[] returnTypes,
+			List result,
+			boolean isNaturalKeyLookup,
+			SessionImplementor session) throws HibernateException {
+		if ( isNaturalKeyLookup && result.size() == 0 ) {
+			return false;
+		}
+		else {
+			Long ts = new Long( session.getTimestamp() );
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( "caching query results in region: " + cacheRegion.getName() + "; timestamp=" + ts );
+			}
+
+			List cacheable = new ArrayList( result.size() + 1 );
+			cacheable.add( ts );
+			for ( int i = 0; i < result.size(); i++ ) {
+				if ( returnTypes.length == 1 ) {
+					cacheable.add( returnTypes[0].disassemble( result.get( i ), session, null ) );
+				}
+				else {
+					cacheable.add(
+							TypeFactory.disassemble(
+									( Object[] ) result.get( i ), returnTypes, null, session, null
+							)
+					);
+				}
+			}
+
+			cacheRegion.put( key, cacheable );
+
+			return true;
+
+		}
+
+	}
+
+	public List get(
+			QueryKey key,
+			Type[] returnTypes,
+			boolean isNaturalKeyLookup,
+			Set spaces,
+			SessionImplementor session) throws HibernateException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "checking cached query results in region: " + cacheRegion.getName() );
+		}
+
+		List cacheable = ( List ) cacheRegion.get( key );
+		if ( cacheable == null ) {
+			log.debug( "query results were not found in cache" );
+			return null;
+		}
+
+		Long timestamp = ( Long ) cacheable.get( 0 );
+		if ( !isNaturalKeyLookup && !isUpToDate( spaces, timestamp ) ) {
+			log.debug( "cached query results were not up to date" );
+			return null;
+		}
+
+		log.debug( "returning cached query results" );
+		for ( int i = 1; i < cacheable.size(); i++ ) {
+			if ( returnTypes.length == 1 ) {
+				returnTypes[0].beforeAssemble( ( Serializable ) cacheable.get( i ), session );
+			}
+			else {
+				TypeFactory.beforeAssemble( ( Serializable[] ) cacheable.get( i ), returnTypes, session );
+			}
+		}
+		List result = new ArrayList( cacheable.size() - 1 );
+		for ( int i = 1; i < cacheable.size(); i++ ) {
+			try {
+				if ( returnTypes.length == 1 ) {
+					result.add( returnTypes[0].assemble( ( Serializable ) cacheable.get( i ), session, null ) );
+				}
+				else {
+					result.add(
+							TypeFactory.assemble(
+									( Serializable[] ) cacheable.get( i ), returnTypes, session, null
+							)
+					);
+				}
+			}
+			catch ( UnresolvableObjectException uoe ) {
+				if ( isNaturalKeyLookup ) {
+					//TODO: not really completely correct, since
+					//      the uoe could occur while resolving
+					//      associations, leaving the PC in an
+					//      inconsistent state
+					log.debug( "could not reassemble cached result set" );
+					cacheRegion.evict( key );
+					return null;
+				}
+				else {
+					throw uoe;
+				}
+			}
+		}
+		return result;
+	}
+
+	protected boolean isUpToDate(Set spaces, Long timestamp) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Checking query spaces for up-to-dateness: " + spaces );
+		}
+		return updateTimestampsCache.isUpToDate( spaces, timestamp );
+	}
+
+	public void destroy() {
+		try {
+			cacheRegion.destroy();
+		}
+		catch ( Exception e ) {
+			log.warn( "could not destroy query cache: " + cacheRegion.getName(), e );
+		}
+	}
+
+	public QueryResultsRegion getRegion() {
+		return cacheRegion;
+	}
+
+	public String toString() {
+		return "StandardQueryCache(" + cacheRegion.getName() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-// $Id: StandardQueryCacheFactory.java 4690 2004-10-26 09:35:46Z oneovthafew $
-package org.hibernate.cache;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Settings;
-
-import java.util.Properties;
-
-/**
- * Standard Hibernate implementation of the QueryCacheFactory interface.  Returns
- * instances of {@link StandardQueryCache}.
- */
-public class StandardQueryCacheFactory implements QueryCacheFactory {
-
-	public QueryCache getQueryCache(
-	        final String regionName,
-	        final UpdateTimestampsCache updateTimestampsCache,
-	        final Settings settings,
-	        final Properties props) 
-	throws HibernateException {
-		return new StandardQueryCache(settings, props, updateTimestampsCache, regionName);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/StandardQueryCacheFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Settings;
+
+import java.util.Properties;
+
+/**
+ * Standard Hibernate implementation of the QueryCacheFactory interface.  Returns
+ * instances of {@link StandardQueryCache}.
+ */
+public class StandardQueryCacheFactory implements QueryCacheFactory {
+
+	public QueryCache getQueryCache(
+	        final String regionName,
+	        final UpdateTimestampsCache updateTimestampsCache,
+	        final Settings settings,
+	        final Properties props) 
+	throws HibernateException {
+		return new StandardQueryCache(settings, props, updateTimestampsCache, regionName);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/Timestamper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: Timestamper.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.cache;
-
-/**
- * Generates increasing identifiers (in a single VM only).
- * Not valid across multiple VMs. Identifiers are not necessarily
- * strictly increasing, but usually are.
- */
-public final class Timestamper {
-	private static short counter = 0;
-	private static long time;
-	private static final int BIN_DIGITS = 12;
-	public static final short ONE_MS = 1<<BIN_DIGITS;
-	
-	public static long next() {
-		synchronized(Timestamper.class) {
-			long newTime = System.currentTimeMillis() << BIN_DIGITS;
-			if (time<newTime) {
-				time = newTime;
-				counter = 0;
-			}
-			else if (counter < ONE_MS - 1 ) {
-				counter++;
-			}
-			
-			return time + counter;
-		}
-	}
-
-	private Timestamper() {}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/Timestamper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/Timestamper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.cache;
+
+/**
+ * Generates increasing identifiers (in a single VM only).
+ * Not valid across multiple VMs. Identifiers are not necessarily
+ * strictly increasing, but usually are.
+ */
+public final class Timestamper {
+	private static short counter = 0;
+	private static long time;
+	private static final int BIN_DIGITS = 12;
+	public static final short ONE_MS = 1<<BIN_DIGITS;
+	
+	public static long next() {
+		synchronized(Timestamper.class) {
+			long newTime = System.currentTimeMillis() << BIN_DIGITS;
+			if (time<newTime) {
+				time = newTime;
+				counter = 0;
+			}
+			else if (counter < ONE_MS - 1 ) {
+				counter++;
+			}
+			
+			return time + counter;
+		}
+	}
+
+	private Timestamper() {}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/TimestampsRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * Defines the contract for a cache region which will specifically be used to
- * store entity "update timestamps".
- *
- * @author Steve Ebersole
- */
-public interface TimestampsRegion extends GeneralDataRegion {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/TimestampsRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TimestampsRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+/*
+ * 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.cache;
+
+/**
+ * Defines the contract for a cache region which will specifically be used to
+ * store entity "update timestamps".
+ *
+ * @author Steve Ebersole
+ */
+public interface TimestampsRegion extends GeneralDataRegion {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,11 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * Marker interface for identifying cache impls which are aware of
- * JTA transactions
- *
- * @author Steve Ebersole
- */
-public interface TransactionAwareCache {
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionAwareCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+/**
+ * Marker interface for identifying cache impls which are aware of
+ * JTA transactions
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionAwareCache {
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/TransactionalCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,171 +0,0 @@
-//$Id: TransactionalCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.util.Comparator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.access.SoftLock;
-
-/**
- * Support for fully transactional cache implementations like
- * JBoss TreeCache. Note that this might be a less scalable
- * concurrency strategy than <tt>ReadWriteCache</tt>. This is
- * a "synchronous" concurrency strategy.
- *
- * @author Gavin King
- */
-public class TransactionalCache implements CacheConcurrencyStrategy {
-
-	private static final Logger log = LoggerFactory.getLogger( TransactionalCache.class );
-
-	private Cache cache;
-
-	public String getRegionName() {
-		return cache.getRegionName();
-	}
-
-	public Object get(Object key, long txTimestamp) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "cache lookup: " + key );
-		}
-		Object result = cache.read( key );
-		if ( log.isDebugEnabled() ) {
-			log.debug( result == null ? "cache miss" : "cache hit" );
-		}
-		return result;
-	}
-
-	public boolean put(
-			Object key,
-	        Object value,
-	        long txTimestamp,
-	        Object version,
-	        Comparator versionComparator,
-	        boolean minimalPut) throws CacheException {
-		if ( minimalPut && cache.read( key ) != null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "item already cached: " + key );
-			}
-			return false;
-		}
-		if ( log.isDebugEnabled() ) {
-			log.debug( "caching: " + key );
-		}
-		if ( cache instanceof OptimisticCache ) {
-			( ( OptimisticCache ) cache ).writeLoad( key, value, version );
-		}
-		else {
-			cache.put( key, value );
-		}
-		return true;
-	}
-
-	/**
-	 * Do nothing, returning null.
-	 */
-	public SoftLock lock(Object key, Object version) throws CacheException {
-		//noop
-		return null;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public void release(Object key, SoftLock clientLock) throws CacheException {
-		//noop
-	}
-
-	public boolean update(
-			Object key,
-	        Object value,
-	        Object currentVersion,
-	        Object previousVersion) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "updating: " + key );
-		}
-		if ( cache instanceof OptimisticCache ) {
-			( ( OptimisticCache ) cache ).writeUpdate( key, value, currentVersion, previousVersion );
-		}
-		else {
-			cache.update( key, value );
-		}
-		return true;
-	}
-
-	public boolean insert(
-			Object key,
-	        Object value,
-	        Object currentVersion) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "inserting: " + key );
-		}
-		if ( cache instanceof OptimisticCache ) {
-			( ( OptimisticCache ) cache ).writeInsert( key, value, currentVersion );
-		}
-		else {
-			cache.update( key, value );
-		}
-		return true;
-	}
-
-	public void evict(Object key) throws CacheException {
-		cache.remove( key );
-	}
-
-	public void remove(Object key) throws CacheException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "removing: " + key );
-		}
-		cache.remove( key );
-	}
-
-	public void clear() throws CacheException {
-		log.debug( "clearing" );
-		cache.clear();
-	}
-
-	public void destroy() {
-		try {
-			cache.destroy();
-		}
-		catch ( Exception e ) {
-			log.warn( "could not destroy cache", e );
-		}
-	}
-
-	public void setCache(Cache cache) {
-		this.cache = cache;
-	}
-
-	public Cache getCache() {
-		return cache;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean afterInsert(
-			Object key,
-	        Object value,
-	        Object version) throws CacheException {
-		return false;
-	}
-
-	/**
-	 * Do nothing.
-	 */
-	public boolean afterUpdate(
-			Object key,
-	        Object value,
-	        Object version,
-	        SoftLock clientLock) throws CacheException {
-		return false;
-	}
-
-	public String toString() {
-		return cache + "(transactional)";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/TransactionalCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,194 @@
+/*
+ * 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.cache;
+
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.access.SoftLock;
+
+/**
+ * Support for fully transactional cache implementations like
+ * JBoss TreeCache. Note that this might be a less scalable
+ * concurrency strategy than <tt>ReadWriteCache</tt>. This is
+ * a "synchronous" concurrency strategy.
+ *
+ * @author Gavin King
+ */
+public class TransactionalCache implements CacheConcurrencyStrategy {
+
+	private static final Logger log = LoggerFactory.getLogger( TransactionalCache.class );
+
+	private Cache cache;
+
+	public String getRegionName() {
+		return cache.getRegionName();
+	}
+
+	public Object get(Object key, long txTimestamp) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "cache lookup: " + key );
+		}
+		Object result = cache.read( key );
+		if ( log.isDebugEnabled() ) {
+			log.debug( result == null ? "cache miss" : "cache hit" );
+		}
+		return result;
+	}
+
+	public boolean put(
+			Object key,
+	        Object value,
+	        long txTimestamp,
+	        Object version,
+	        Comparator versionComparator,
+	        boolean minimalPut) throws CacheException {
+		if ( minimalPut && cache.read( key ) != null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "item already cached: " + key );
+			}
+			return false;
+		}
+		if ( log.isDebugEnabled() ) {
+			log.debug( "caching: " + key );
+		}
+		if ( cache instanceof OptimisticCache ) {
+			( ( OptimisticCache ) cache ).writeLoad( key, value, version );
+		}
+		else {
+			cache.put( key, value );
+		}
+		return true;
+	}
+
+	/**
+	 * Do nothing, returning null.
+	 */
+	public SoftLock lock(Object key, Object version) throws CacheException {
+		//noop
+		return null;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public void release(Object key, SoftLock clientLock) throws CacheException {
+		//noop
+	}
+
+	public boolean update(
+			Object key,
+	        Object value,
+	        Object currentVersion,
+	        Object previousVersion) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "updating: " + key );
+		}
+		if ( cache instanceof OptimisticCache ) {
+			( ( OptimisticCache ) cache ).writeUpdate( key, value, currentVersion, previousVersion );
+		}
+		else {
+			cache.update( key, value );
+		}
+		return true;
+	}
+
+	public boolean insert(
+			Object key,
+	        Object value,
+	        Object currentVersion) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "inserting: " + key );
+		}
+		if ( cache instanceof OptimisticCache ) {
+			( ( OptimisticCache ) cache ).writeInsert( key, value, currentVersion );
+		}
+		else {
+			cache.update( key, value );
+		}
+		return true;
+	}
+
+	public void evict(Object key) throws CacheException {
+		cache.remove( key );
+	}
+
+	public void remove(Object key) throws CacheException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "removing: " + key );
+		}
+		cache.remove( key );
+	}
+
+	public void clear() throws CacheException {
+		log.debug( "clearing" );
+		cache.clear();
+	}
+
+	public void destroy() {
+		try {
+			cache.destroy();
+		}
+		catch ( Exception e ) {
+			log.warn( "could not destroy cache", e );
+		}
+	}
+
+	public void setCache(Cache cache) {
+		this.cache = cache;
+	}
+
+	public Cache getCache() {
+		return cache;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean afterInsert(
+			Object key,
+	        Object value,
+	        Object version) throws CacheException {
+		return false;
+	}
+
+	/**
+	 * Do nothing.
+	 */
+	public boolean afterUpdate(
+			Object key,
+	        Object value,
+	        Object version,
+	        SoftLock clientLock) throws CacheException {
+		return false;
+	}
+
+	public String toString() {
+		return cache + "(transactional)";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-package org.hibernate.cache;
-
-/**
- * Defines contract for regions which hold transactionally-managed data.
- * <p/>
- * The data is not transactionally managed within the region; merely it is
- * transactionally-managed in relation to its association with a particular
- * {@link org.hibernate.Session}.
- *
- * @author Steve Ebersole
- */
-public interface TransactionalDataRegion extends Region {
-	/**
-	 * Is the underlying cache implementation aware of (and "participating in")
-	 * ongoing JTA transactions?
-	 * <p/>
-	 * Regions which report that they are transaction-aware are considered
-	 * "synchronous", in that we assume we can immediately (i.e. synchronously)
-	 * write the changes to the cache and that the cache will properly manage
-	 * application of the written changes within the bounds of ongoing JTA
-	 * transactions.  Conversely, regions reporting false are considered
-	 * "asynchronous", where it is assumed that changes must be manually
-	 * delayed by Hibernate until we are certain that the current transaction
-	 * is successful (i.e. maintaining READ_COMMITTED isolation).
-	 *
-	 * @return True if transaction aware; false otherwise.
-	 */
-	public boolean isTransactionAware();
-
-	public CacheDataDescription getCacheDataDescription();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/TransactionalDataRegion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache;
+
+/**
+ * Defines contract for regions which hold transactionally-managed data.
+ * <p/>
+ * The data is not transactionally managed within the region; merely it is
+ * transactionally-managed in relation to its association with a particular
+ * {@link org.hibernate.Session}.
+ *
+ * @author Steve Ebersole
+ */
+public interface TransactionalDataRegion extends Region {
+	/**
+	 * Is the underlying cache implementation aware of (and "participating in")
+	 * ongoing JTA transactions?
+	 * <p/>
+	 * Regions which report that they are transaction-aware are considered
+	 * "synchronous", in that we assume we can immediately (i.e. synchronously)
+	 * write the changes to the cache and that the cache will properly manage
+	 * application of the written changes within the bounds of ongoing JTA
+	 * transactions.  Conversely, regions reporting false are considered
+	 * "asynchronous", where it is assumed that changes must be manually
+	 * delayed by Hibernate until we are certain that the current transaction
+	 * is successful (i.e. maintaining READ_COMMITTED isolation).
+	 *
+	 * @return True if transaction aware; false otherwise.
+	 */
+	public boolean isTransactionAware();
+
+	public CacheDataDescription getCacheDataDescription();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,110 +0,0 @@
-//$Id: UpdateTimestampsCache.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.cache;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Settings;
-
-/**
- * Tracks the timestamps of the most recent updates to particular tables. It is
- * important that the cache timeout of the underlying cache implementation be set
- * to a higher value than the timeouts of any of the query caches. In fact, we
- * recommend that the the underlying cache not be configured for expiry at all.
- * Note, in particular, that an LRU cache expiry policy is never appropriate.
- *
- * @author Gavin King
- * @author Mikheil Kapanadze
- */
-public class UpdateTimestampsCache {
-	public static final String REGION_NAME = UpdateTimestampsCache.class.getName();
-	private static final Logger log = LoggerFactory.getLogger( UpdateTimestampsCache.class );
-
-	private final TimestampsRegion region;
-
-	public UpdateTimestampsCache(Settings settings, Properties props) throws HibernateException {
-		String prefix = settings.getCacheRegionPrefix();
-		String regionName = prefix == null ? REGION_NAME : prefix + '.' + REGION_NAME;
-		log.info( "starting update timestamps cache at region: " + regionName );
-		this.region = settings.getRegionFactory().buildTimestampsRegion( regionName, props );
-	}
-
-	public synchronized void preinvalidate(Serializable[] spaces) throws CacheException {
-		//TODO: to handle concurrent writes correctly, this should return a Lock to the client
-		Long ts = new Long( region.nextTimestamp() + region.getTimeout() );
-		for ( int i=0; i<spaces.length; i++ ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Pre-invalidating space [" + spaces[i] + "]" );
-			}
-			//put() has nowait semantics, is this really appropriate?
-			//note that it needs to be async replication, never local or sync
-			region.put( spaces[i], ts );
-		}
-		//TODO: return new Lock(ts);
-	}
-
-	 public synchronized void invalidate(Serializable[] spaces) throws CacheException {
-	 	//TODO: to handle concurrent writes correctly, the client should pass in a Lock
-		Long ts = new Long( region.nextTimestamp() );
-		//TODO: if lock.getTimestamp().equals(ts)
-		for ( int i=0; i<spaces.length; i++ ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Invalidating space [" + spaces[i] + "], timestamp: " + ts);
-			}
-			//put() has nowait semantics, is this really appropriate?
-			//note that it needs to be async replication, never local or sync
-			region.put( spaces[i], ts );
-		}
-	}
-
-	public synchronized boolean isUpToDate(Set spaces, Long timestamp) throws HibernateException {
-		Iterator iter = spaces.iterator();
-		while ( iter.hasNext() ) {
-			Serializable space = (Serializable) iter.next();
-			Long lastUpdate = (Long) region.get(space);
-			if ( lastUpdate==null ) {
-				//the last update timestamp was lost from the cache
-				//(or there were no updates since startup!)
-				//updateTimestamps.put( space, new Long( updateTimestamps.nextTimestamp() ) );
-				//result = false; // safer
-			}
-			else {
-				if ( log.isDebugEnabled() ) {
-					log.debug("[" + space + "] last update timestamp: " + lastUpdate + ", result set timestamp: " + timestamp );
-				}
-				if ( lastUpdate.longValue() >= timestamp.longValue() ) {
-					return false;
-				}
-			}
-		}
-		return true;
-	}
-
-	public void clear() throws CacheException {
-		region.evictAll();
-	}
-
-	public void destroy() {
-		try {
-			region.destroy();
-		}
-		catch (Exception e) {
-			log.warn("could not destroy UpdateTimestamps cache", e);
-		}
-	}
-
-	public TimestampsRegion getRegion() {
-		return region;
-	}
-	
-	public String toString() {
-		return "UpdateTimestampeCache";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/UpdateTimestampsCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,133 @@
+/*
+ * 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.cache;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Tracks the timestamps of the most recent updates to particular tables. It is
+ * important that the cache timeout of the underlying cache implementation be set
+ * to a higher value than the timeouts of any of the query caches. In fact, we
+ * recommend that the the underlying cache not be configured for expiry at all.
+ * Note, in particular, that an LRU cache expiry policy is never appropriate.
+ *
+ * @author Gavin King
+ * @author Mikheil Kapanadze
+ */
+public class UpdateTimestampsCache {
+	public static final String REGION_NAME = UpdateTimestampsCache.class.getName();
+	private static final Logger log = LoggerFactory.getLogger( UpdateTimestampsCache.class );
+
+	private final TimestampsRegion region;
+
+	public UpdateTimestampsCache(Settings settings, Properties props) throws HibernateException {
+		String prefix = settings.getCacheRegionPrefix();
+		String regionName = prefix == null ? REGION_NAME : prefix + '.' + REGION_NAME;
+		log.info( "starting update timestamps cache at region: " + regionName );
+		this.region = settings.getRegionFactory().buildTimestampsRegion( regionName, props );
+	}
+
+	public synchronized void preinvalidate(Serializable[] spaces) throws CacheException {
+		//TODO: to handle concurrent writes correctly, this should return a Lock to the client
+		Long ts = new Long( region.nextTimestamp() + region.getTimeout() );
+		for ( int i=0; i<spaces.length; i++ ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Pre-invalidating space [" + spaces[i] + "]" );
+			}
+			//put() has nowait semantics, is this really appropriate?
+			//note that it needs to be async replication, never local or sync
+			region.put( spaces[i], ts );
+		}
+		//TODO: return new Lock(ts);
+	}
+
+	 public synchronized void invalidate(Serializable[] spaces) throws CacheException {
+	 	//TODO: to handle concurrent writes correctly, the client should pass in a Lock
+		Long ts = new Long( region.nextTimestamp() );
+		//TODO: if lock.getTimestamp().equals(ts)
+		for ( int i=0; i<spaces.length; i++ ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Invalidating space [" + spaces[i] + "], timestamp: " + ts);
+			}
+			//put() has nowait semantics, is this really appropriate?
+			//note that it needs to be async replication, never local or sync
+			region.put( spaces[i], ts );
+		}
+	}
+
+	public synchronized boolean isUpToDate(Set spaces, Long timestamp) throws HibernateException {
+		Iterator iter = spaces.iterator();
+		while ( iter.hasNext() ) {
+			Serializable space = (Serializable) iter.next();
+			Long lastUpdate = (Long) region.get(space);
+			if ( lastUpdate==null ) {
+				//the last update timestamp was lost from the cache
+				//(or there were no updates since startup!)
+				//updateTimestamps.put( space, new Long( updateTimestamps.nextTimestamp() ) );
+				//result = false; // safer
+			}
+			else {
+				if ( log.isDebugEnabled() ) {
+					log.debug("[" + space + "] last update timestamp: " + lastUpdate + ", result set timestamp: " + timestamp );
+				}
+				if ( lastUpdate.longValue() >= timestamp.longValue() ) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
+
+	public void clear() throws CacheException {
+		region.evictAll();
+	}
+
+	public void destroy() {
+		try {
+			region.destroy();
+		}
+		catch (Exception e) {
+			log.warn("could not destroy UpdateTimestamps cache", e);
+		}
+	}
+
+	public TimestampsRegion getRegion() {
+		return region;
+	}
+	
+	public String toString() {
+		return "UpdateTimestampeCache";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/access/AccessType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-package org.hibernate.cache.access;
-
-import java.io.Serializable;
-
-/**
- * The types of access strategies available.
- *
- * @author Steve Ebersole
- */
-public class AccessType implements Serializable {
-	public static final AccessType READ_ONLY = new AccessType( "read-only" );
-	public static final AccessType READ_WRITE = new AccessType( "read-write" );
-	public static final AccessType NONSTRICT_READ_WRITE = new AccessType( "nonstrict-read-write" );
-	public static final AccessType TRANSACTIONAL = new AccessType( "transactional" );
-
-	private final String name;
-
-	private AccessType(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String toString() {
-		return "AccessType[" + name + "]";
-	}
-
-	private static AccessType resolve(String name) {
-		if ( READ_ONLY.name.equals( name ) ) {
-			return READ_ONLY;
-		}
-		else if ( READ_WRITE.name.equals( name ) ) {
-			return READ_WRITE;
-		}
-		else if ( NONSTRICT_READ_WRITE.name.equals( name ) ) {
-			return NONSTRICT_READ_WRITE;
-		}
-		else if ( TRANSACTIONAL.name.equals( name ) ) {
-			return TRANSACTIONAL;
-		}
-		else {
-			return null;
-		}
-	}
-
-	public static AccessType parse(String name) {
-		return resolve( name );
-	}
-
-	private Object readResolve() {
-		return resolve( name );
-	}
-
-	public static String getValidUsageString() {
-		return "cache usage attribute should be " + READ_ONLY.name +
-				", " + READ_WRITE.name +
-				", " + NONSTRICT_READ_WRITE.name +
-				", or " + TRANSACTIONAL.name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/access/AccessType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/AccessType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.access;
+
+import java.io.Serializable;
+
+/**
+ * The types of access strategies available.
+ *
+ * @author Steve Ebersole
+ */
+public class AccessType implements Serializable {
+	public static final AccessType READ_ONLY = new AccessType( "read-only" );
+	public static final AccessType READ_WRITE = new AccessType( "read-write" );
+	public static final AccessType NONSTRICT_READ_WRITE = new AccessType( "nonstrict-read-write" );
+	public static final AccessType TRANSACTIONAL = new AccessType( "transactional" );
+
+	private final String name;
+
+	private AccessType(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return "AccessType[" + name + "]";
+	}
+
+	private static AccessType resolve(String name) {
+		if ( READ_ONLY.name.equals( name ) ) {
+			return READ_ONLY;
+		}
+		else if ( READ_WRITE.name.equals( name ) ) {
+			return READ_WRITE;
+		}
+		else if ( NONSTRICT_READ_WRITE.name.equals( name ) ) {
+			return NONSTRICT_READ_WRITE;
+		}
+		else if ( TRANSACTIONAL.name.equals( name ) ) {
+			return TRANSACTIONAL;
+		}
+		else {
+			return null;
+		}
+	}
+
+	public static AccessType parse(String name) {
+		return resolve( name );
+	}
+
+	private Object readResolve() {
+		return resolve( name );
+	}
+
+	public static String getValidUsageString() {
+		return "cache usage attribute should be " + READ_ONLY.name +
+				", " + READ_WRITE.name +
+				", " + NONSTRICT_READ_WRITE.name +
+				", or " + TRANSACTIONAL.name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,149 +0,0 @@
-package org.hibernate.cache.access;
-
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.CollectionRegion;
-
-/**
- * Contract for managing transactional and concurrent access to cached collection
- * data.  For cached collection data, all modification actions actually just
- * invalidate the entry(s).  The call sequence here is:
- * {@link #lockItem} -> {@link #remove} -> {@link #unlockItem}
- * <p/>
- * There is another usage pattern that is used to invalidate entries
- * after performing "bulk" HQL/SQL operations:
- * {@link #lockRegion} -> {@link #removeAll} -> {@link #unlockRegion}
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public interface CollectionRegionAccessStrategy {
-
-	/**
-	 * Get the wrapped collection cache region
-	 *
-	 * @return The underlying region
-	 */
-	public CollectionRegion getRegion();
-
-	/**
-	 * Attempt to retrieve an object from the cache. Mainly used in attempting
-	 * to resolve entities/collections from the second level cache.
-	 *
-	 * @param key The key of the item to be retrieved.
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @return the cached object or <tt>null</tt>
-	 * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public Object get(Object key, long txTimestamp) throws CacheException;
-
-	/**
-	 * Attempt to cache an object, after loading from the database.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @param version the item version number
-	 * @return <tt>true</tt> if the object was successfully cached
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean putFromLoad(
-			Object key,
-			Object value,
-			long txTimestamp,
-			Object version) throws CacheException;
-
-	/**
-	 * Attempt to cache an object, after loading from the database, explicitly
-	 * specifying the minimalPut behavior.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @param version the item version number
-	 * @param minimalPutOverride Explicit minimalPut flag
-	 * @return <tt>true</tt> if the object was successfully cached
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean putFromLoad(
-			Object key,
-			Object value,
-			long txTimestamp,
-			Object version,
-			boolean minimalPutOverride) throws CacheException;
-
-	/**
-	 * We are going to attempt to update/delete the keyed object. This
-	 * method is used by "asynchronous" concurrency strategies.
-	 * <p/>
-	 * The returned object must be passed back to release(), to release the
-	 * lock. Concurrency strategies which do not support client-visible
-	 * locks may silently return null.
-	 *
-	 * @param key The key of the item to lock
-	 * @param version The item's current version value
-	 * @return A representation of our lock on the item; or null.
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public SoftLock lockItem(Object key, Object version) throws CacheException;
-
-	/**
-	 * Lock the entire region
-	 *
-	 * @return A representation of our lock on the item; or null.
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public SoftLock lockRegion() throws CacheException;
-
-	/**
-	 * Called when we have finished the attempted update/delete (which may or
-	 * may not have been successful), after transaction completion.  This method
-	 * is used by "asynchronous" concurrency strategies.
-	 *
-	 * @param key The item key
-	 * @param lock The lock previously obtained from {@link #lockItem}
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void unlockItem(Object key, SoftLock lock) throws CacheException;
-
-	/**
-	 * Called after we have finished the attempted invalidation of the entire
-	 * region
-	 *
-	 * @param lock The lock previously obtained from {@link #lockRegion}
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void unlockRegion(SoftLock lock) throws CacheException;
-
-	/**
-	 * Called after an item has become stale (before the transaction completes).
-	 * This method is used by "synchronous" concurrency strategies.
-	 *
-	 * @param key The key of the item to remove
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void remove(Object key) throws CacheException;
-
-	/**
-	 * Called to evict data from the entire region
-	 *
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void removeAll() throws CacheException;
-
-	/**
-	 * Forcibly evict an item from the cache immediately without regard for transaction
-	 * isolation.
-	 *
-	 * @param key The key of the item to remove
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void evict(Object key) throws CacheException;
-
-	/**
-	 * Forcibly evict all items from the cache immediately without regard for transaction
-	 * isolation.
-	 *
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void evictAll() throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/CollectionRegionAccessStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,173 @@
+/*
+ * 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.cache.access;
+
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CollectionRegion;
+
+/**
+ * Contract for managing transactional and concurrent access to cached collection
+ * data.  For cached collection data, all modification actions actually just
+ * invalidate the entry(s).  The call sequence here is:
+ * {@link #lockItem} -> {@link #remove} -> {@link #unlockItem}
+ * <p/>
+ * There is another usage pattern that is used to invalidate entries
+ * after performing "bulk" HQL/SQL operations:
+ * {@link #lockRegion} -> {@link #removeAll} -> {@link #unlockRegion}
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public interface CollectionRegionAccessStrategy {
+
+	/**
+	 * Get the wrapped collection cache region
+	 *
+	 * @return The underlying region
+	 */
+	public CollectionRegion getRegion();
+
+	/**
+	 * Attempt to retrieve an object from the cache. Mainly used in attempting
+	 * to resolve entities/collections from the second level cache.
+	 *
+	 * @param key The key of the item to be retrieved.
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @return the cached object or <tt>null</tt>
+	 * @throws org.hibernate.cache.CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public Object get(Object key, long txTimestamp) throws CacheException;
+
+	/**
+	 * Attempt to cache an object, after loading from the database.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @param version the item version number
+	 * @return <tt>true</tt> if the object was successfully cached
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean putFromLoad(
+			Object key,
+			Object value,
+			long txTimestamp,
+			Object version) throws CacheException;
+
+	/**
+	 * Attempt to cache an object, after loading from the database, explicitly
+	 * specifying the minimalPut behavior.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @param version the item version number
+	 * @param minimalPutOverride Explicit minimalPut flag
+	 * @return <tt>true</tt> if the object was successfully cached
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean putFromLoad(
+			Object key,
+			Object value,
+			long txTimestamp,
+			Object version,
+			boolean minimalPutOverride) throws CacheException;
+
+	/**
+	 * We are going to attempt to update/delete the keyed object. This
+	 * method is used by "asynchronous" concurrency strategies.
+	 * <p/>
+	 * The returned object must be passed back to release(), to release the
+	 * lock. Concurrency strategies which do not support client-visible
+	 * locks may silently return null.
+	 *
+	 * @param key The key of the item to lock
+	 * @param version The item's current version value
+	 * @return A representation of our lock on the item; or null.
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public SoftLock lockItem(Object key, Object version) throws CacheException;
+
+	/**
+	 * Lock the entire region
+	 *
+	 * @return A representation of our lock on the item; or null.
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public SoftLock lockRegion() throws CacheException;
+
+	/**
+	 * Called when we have finished the attempted update/delete (which may or
+	 * may not have been successful), after transaction completion.  This method
+	 * is used by "asynchronous" concurrency strategies.
+	 *
+	 * @param key The item key
+	 * @param lock The lock previously obtained from {@link #lockItem}
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void unlockItem(Object key, SoftLock lock) throws CacheException;
+
+	/**
+	 * Called after we have finished the attempted invalidation of the entire
+	 * region
+	 *
+	 * @param lock The lock previously obtained from {@link #lockRegion}
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void unlockRegion(SoftLock lock) throws CacheException;
+
+	/**
+	 * Called after an item has become stale (before the transaction completes).
+	 * This method is used by "synchronous" concurrency strategies.
+	 *
+	 * @param key The key of the item to remove
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void remove(Object key) throws CacheException;
+
+	/**
+	 * Called to evict data from the entire region
+	 *
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void removeAll() throws CacheException;
+
+	/**
+	 * Forcibly evict an item from the cache immediately without regard for transaction
+	 * isolation.
+	 *
+	 * @param key The key of the item to remove
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void evict(Object key) throws CacheException;
+
+	/**
+	 * Forcibly evict all items from the cache immediately without regard for transaction
+	 * isolation.
+	 *
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void evictAll() throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,206 +0,0 @@
-package org.hibernate.cache.access;
-
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.CacheException;
-
-/**
- * Contract for managing transactional and concurrent access to cached entity
- * data.  The expected call sequences related to various operations are:<ul>
- * <li><b>INSERTS</b> : {@link #insert} -> {@link #afterInsert}</li>
- * <li><b>UPDATES</b> : {@link #lockItem} -> {@link #update} -> {@link #afterUpdate}</li>
- * <li><b>DELETES</b> : {@link #lockItem} -> {@link #remove} -> {@link #unlockItem}</li>
- * </ul>
- * <p/>
- * There is another usage pattern that is used to invalidate entries
- * after performing "bulk" HQL/SQL operations:
- * {@link #lockRegion} -> {@link #removeAll} -> {@link #unlockRegion}
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public interface EntityRegionAccessStrategy {
-
-	/**
-	 * Get the wrapped entity cache region
-	 *
-	 * @return The underlying region
-	 */
-	public EntityRegion getRegion();
-
-	/**
-	 * Attempt to retrieve an object from the cache. Mainly used in attempting
-	 * to resolve entities/collections from the second level cache.
-	 *
-	 * @param key The key of the item to be retrieved.
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @return the cached object or <tt>null</tt>
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public Object get(Object key, long txTimestamp) throws CacheException;
-
-	/**
-	 * Attempt to cache an object, after loading from the database.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @param version the item version number
-	 * @return <tt>true</tt> if the object was successfully cached
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean putFromLoad(
-			Object key,
-			Object value,
-			long txTimestamp,
-			Object version) throws CacheException;
-
-	/**
-	 * Attempt to cache an object, after loading from the database, explicitly
-	 * specifying the minimalPut behavior.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param txTimestamp a timestamp prior to the transaction start time
-	 * @param version the item version number
-	 * @param minimalPutOverride Explicit minimalPut flag
-	 * @return <tt>true</tt> if the object was successfully cached
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean putFromLoad(
-			Object key,
-			Object value,
-			long txTimestamp,
-			Object version,
-			boolean minimalPutOverride) throws CacheException;
-
-	/**
-	 * We are going to attempt to update/delete the keyed object. This
-	 * method is used by "asynchronous" concurrency strategies.
-	 * <p/>
-	 * The returned object must be passed back to release(), to release the
-	 * lock. Concurrency strategies which do not support client-visible
-	 * locks may silently return null.
-	 *
-	 * @param key The key of the item to lock
-	 * @param version The item's current version value
-	 * @return A representation of our lock on the item; or null.
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public SoftLock lockItem(Object key, Object version) throws CacheException;
-
-	/**
-	 * Lock the entire region
-	 *
-	 * @return A representation of our lock on the item; or null.
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public SoftLock lockRegion() throws CacheException;
-
-	/**
-	 * Called when we have finished the attempted update/delete (which may or
-	 * may not have been successful), after transaction completion.  This method
-	 * is used by "asynchronous" concurrency strategies.
-	 *
-	 * @param key The item key
-	 * @param lock The lock previously obtained from {@link #lockItem}
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void unlockItem(Object key, SoftLock lock) throws CacheException;
-
-	/**
-	 * Called after we have finished the attempted invalidation of the entire
-	 * region
-	 *
-	 * @param lock The lock previously obtained from {@link #lockRegion}
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void unlockRegion(SoftLock lock) throws CacheException;
-
-	/**
-	 * Called after an item has been inserted (before the transaction completes),
-	 * instead of calling evict().
-	 * This method is used by "synchronous" concurrency strategies.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param version The item's version value
-	 * @return Were the contents of the cache actual changed by this operation?
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean insert(Object key, Object value, Object version) throws CacheException;
-
-	/**
-	 * Called after an item has been inserted (after the transaction completes),
-	 * instead of calling release().
-	 * This method is used by "asynchronous" concurrency strategies.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param version The item's version value
-	 * @return Were the contents of the cache actual changed by this operation?
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean afterInsert(Object key, Object value, Object version) throws CacheException;
-
-	/**
-	 * Called after an item has been updated (before the transaction completes),
-	 * instead of calling evict(). This method is used by "synchronous" concurrency
-	 * strategies.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param currentVersion The item's current version value
-	 * @param previousVersion The item's previous version value
-	 * @return Were the contents of the cache actual changed by this operation?
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
-
-	/**
-	 * Called after an item has been updated (after the transaction completes),
-	 * instead of calling release().  This method is used by "asynchronous"
-	 * concurrency strategies.
-	 *
-	 * @param key The item key
-	 * @param value The item
-	 * @param currentVersion The item's current version value
-	 * @param previousVersion The item's previous version value
-	 * @param lock The lock previously obtained from {@link #lockItem}
-	 * @return Were the contents of the cache actual changed by this operation?
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;
-
-	/**
-	 * Called after an item has become stale (before the transaction completes).
-	 * This method is used by "synchronous" concurrency strategies.
-	 *
-	 * @param key The key of the item to remove
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void remove(Object key) throws CacheException;
-
-	/**
-	 * Called to evict data from the entire region
-	 *
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void removeAll() throws CacheException;
-
-	/**
-	 * Forcibly evict an item from the cache immediately without regard for transaction
-	 * isolation.
-	 *
-	 * @param key The key of the item to remove
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void evict(Object key) throws CacheException;
-
-	/**
-	 * Forcibly evict all items from the cache immediately without regard for transaction
-	 * isolation.
-	 *
-	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
-	 */
-	public void evictAll() throws CacheException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/EntityRegionAccessStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,230 @@
+/*
+ * 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.cache.access;
+
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.CacheException;
+
+/**
+ * Contract for managing transactional and concurrent access to cached entity
+ * data.  The expected call sequences related to various operations are:<ul>
+ * <li><b>INSERTS</b> : {@link #insert} -> {@link #afterInsert}</li>
+ * <li><b>UPDATES</b> : {@link #lockItem} -> {@link #update} -> {@link #afterUpdate}</li>
+ * <li><b>DELETES</b> : {@link #lockItem} -> {@link #remove} -> {@link #unlockItem}</li>
+ * </ul>
+ * <p/>
+ * There is another usage pattern that is used to invalidate entries
+ * after performing "bulk" HQL/SQL operations:
+ * {@link #lockRegion} -> {@link #removeAll} -> {@link #unlockRegion}
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public interface EntityRegionAccessStrategy {
+
+	/**
+	 * Get the wrapped entity cache region
+	 *
+	 * @return The underlying region
+	 */
+	public EntityRegion getRegion();
+
+	/**
+	 * Attempt to retrieve an object from the cache. Mainly used in attempting
+	 * to resolve entities/collections from the second level cache.
+	 *
+	 * @param key The key of the item to be retrieved.
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @return the cached object or <tt>null</tt>
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public Object get(Object key, long txTimestamp) throws CacheException;
+
+	/**
+	 * Attempt to cache an object, after loading from the database.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @param version the item version number
+	 * @return <tt>true</tt> if the object was successfully cached
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean putFromLoad(
+			Object key,
+			Object value,
+			long txTimestamp,
+			Object version) throws CacheException;
+
+	/**
+	 * Attempt to cache an object, after loading from the database, explicitly
+	 * specifying the minimalPut behavior.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param txTimestamp a timestamp prior to the transaction start time
+	 * @param version the item version number
+	 * @param minimalPutOverride Explicit minimalPut flag
+	 * @return <tt>true</tt> if the object was successfully cached
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean putFromLoad(
+			Object key,
+			Object value,
+			long txTimestamp,
+			Object version,
+			boolean minimalPutOverride) throws CacheException;
+
+	/**
+	 * We are going to attempt to update/delete the keyed object. This
+	 * method is used by "asynchronous" concurrency strategies.
+	 * <p/>
+	 * The returned object must be passed back to release(), to release the
+	 * lock. Concurrency strategies which do not support client-visible
+	 * locks may silently return null.
+	 *
+	 * @param key The key of the item to lock
+	 * @param version The item's current version value
+	 * @return A representation of our lock on the item; or null.
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public SoftLock lockItem(Object key, Object version) throws CacheException;
+
+	/**
+	 * Lock the entire region
+	 *
+	 * @return A representation of our lock on the item; or null.
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public SoftLock lockRegion() throws CacheException;
+
+	/**
+	 * Called when we have finished the attempted update/delete (which may or
+	 * may not have been successful), after transaction completion.  This method
+	 * is used by "asynchronous" concurrency strategies.
+	 *
+	 * @param key The item key
+	 * @param lock The lock previously obtained from {@link #lockItem}
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void unlockItem(Object key, SoftLock lock) throws CacheException;
+
+	/**
+	 * Called after we have finished the attempted invalidation of the entire
+	 * region
+	 *
+	 * @param lock The lock previously obtained from {@link #lockRegion}
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void unlockRegion(SoftLock lock) throws CacheException;
+
+	/**
+	 * Called after an item has been inserted (before the transaction completes),
+	 * instead of calling evict().
+	 * This method is used by "synchronous" concurrency strategies.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param version The item's version value
+	 * @return Were the contents of the cache actual changed by this operation?
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean insert(Object key, Object value, Object version) throws CacheException;
+
+	/**
+	 * Called after an item has been inserted (after the transaction completes),
+	 * instead of calling release().
+	 * This method is used by "asynchronous" concurrency strategies.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param version The item's version value
+	 * @return Were the contents of the cache actual changed by this operation?
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean afterInsert(Object key, Object value, Object version) throws CacheException;
+
+	/**
+	 * Called after an item has been updated (before the transaction completes),
+	 * instead of calling evict(). This method is used by "synchronous" concurrency
+	 * strategies.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param currentVersion The item's current version value
+	 * @param previousVersion The item's previous version value
+	 * @return Were the contents of the cache actual changed by this operation?
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion) throws CacheException;
+
+	/**
+	 * Called after an item has been updated (after the transaction completes),
+	 * instead of calling release().  This method is used by "asynchronous"
+	 * concurrency strategies.
+	 *
+	 * @param key The item key
+	 * @param value The item
+	 * @param currentVersion The item's current version value
+	 * @param previousVersion The item's previous version value
+	 * @param lock The lock previously obtained from {@link #lockItem}
+	 * @return Were the contents of the cache actual changed by this operation?
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock) throws CacheException;
+
+	/**
+	 * Called after an item has become stale (before the transaction completes).
+	 * This method is used by "synchronous" concurrency strategies.
+	 *
+	 * @param key The key of the item to remove
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void remove(Object key) throws CacheException;
+
+	/**
+	 * Called to evict data from the entire region
+	 *
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void removeAll() throws CacheException;
+
+	/**
+	 * Forcibly evict an item from the cache immediately without regard for transaction
+	 * isolation.
+	 *
+	 * @param key The key of the item to remove
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void evict(Object key) throws CacheException;
+
+	/**
+	 * Forcibly evict all items from the cache immediately without regard for transaction
+	 * isolation.
+	 *
+	 * @throws CacheException Propogated from underlying {@link org.hibernate.cache.Region}
+	 */
+	public void evictAll() throws CacheException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/access/SoftLock.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-package org.hibernate.cache.access;
-
-/**
- * Moved up from inner definition on the now deprecated
- * {@link org.hibernate.cache.CacheConcurrencyStrategy}.
- *
- * @author Steve Ebersole
- */
-public interface SoftLock {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/access/SoftLock.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/SoftLock.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+/*
+ * 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.cache.access;
+
+/**
+ * Moved up from inner definition on the now deprecated
+ * {@link org.hibernate.cache.CacheConcurrencyStrategy}.
+ *
+ * @author Steve Ebersole
+ */
+public interface SoftLock {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/access/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Defines contracts for transactional and concurrent access to cached
-    {@link org.hibernate.cache.access.EntityRegionAccessStrategy entity} and
-    {@link org.hibernate.cache.access.CollectionRegionAccessStrategy collection} data.  Transactions pass in a
-    timestamp indicating transaction start time which is then used to protect against concurrent access (exactly how
-    that occurs is based on the actual access-strategy impl used). Two different implementation patterns are provided
-    for.
-    <ul>
-        <li>
-            A transaction-aware cache implementation might be wrapped by a <i>synchronous</i> access strategy,
-            where updates to the cache are written to the cache inside the transaction.
-        </li>
-        <li>
-            A non-transaction-aware cache would be wrapped by an <i>asynchronous</i> access strategy, where items
-            are merely "soft locked" during the transaction and then updated during the "after transaction completion"
-            phase; the soft lock is not an actual lock on the database row - only upon the cached representation of the
-            item.
-        </li>
-    </ul>
-    The <i>asynchronous</i> access strategies are: {@link org.hibernate.cache.access.AccessType.READ_ONLY read-only},
-    {@link org.hibernate.cache.access.AccessType.READ_WRITE read-write} and
-    {@link org.hibernate.cache.access.AccessType.NONSTRICT_READ_WRITE nonstrict-read-write}.  The only
-    <i>synchronous</i> access strategy is {@link org.hibernate.cache.access.AccessType.TRANSACTIONAL transactional}.
-</p>
-<p>
-    Note that, for an <i>asynchronous</i> cache, cache invalidation must be a two step process (lock->unlock or
-    lock->afterUpdate), since this is the only way to guarantee consistency with the database for a nontransactional
-    cache implementation. For a <i>synchronous</i> cache, cache invalidation is a single step process (evict or update).
-    Hence, these contracts ({@link org.hibernate.cache.access.EntityRegionAcessStrategy} and
-    {@link org.hibernate.cache.access.CollectionRegionAccessStrategy}) define a three step process to cater for both 
-    models (see the individual contracts for details).
-</p>
-<p>
-    Note that query result caching does not go through an access strategy; those caches are managed directly against
-    the underlying {@link org.hibernate.cache.QueryResultsRegion}.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/access/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/access/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Defines contracts for transactional and concurrent access to cached
+    {@link org.hibernate.cache.access.EntityRegionAccessStrategy entity} and
+    {@link org.hibernate.cache.access.CollectionRegionAccessStrategy collection} data.  Transactions pass in a
+    timestamp indicating transaction start time which is then used to protect against concurrent access (exactly how
+    that occurs is based on the actual access-strategy impl used). Two different implementation patterns are provided
+    for.
+    <ul>
+        <li>
+            A transaction-aware cache implementation might be wrapped by a <i>synchronous</i> access strategy,
+            where updates to the cache are written to the cache inside the transaction.
+        </li>
+        <li>
+            A non-transaction-aware cache would be wrapped by an <i>asynchronous</i> access strategy, where items
+            are merely "soft locked" during the transaction and then updated during the "after transaction completion"
+            phase; the soft lock is not an actual lock on the database row - only upon the cached representation of the
+            item.
+        </li>
+    </ul>
+    The <i>asynchronous</i> access strategies are: {@link org.hibernate.cache.access.AccessType.READ_ONLY read-only},
+    {@link org.hibernate.cache.access.AccessType.READ_WRITE read-write} and
+    {@link org.hibernate.cache.access.AccessType.NONSTRICT_READ_WRITE nonstrict-read-write}.  The only
+    <i>synchronous</i> access strategy is {@link org.hibernate.cache.access.AccessType.TRANSACTIONAL transactional}.
+</p>
+<p>
+    Note that, for an <i>asynchronous</i> cache, cache invalidation must be a two step process (lock->unlock or
+    lock->afterUpdate), since this is the only way to guarantee consistency with the database for a nontransactional
+    cache implementation. For a <i>synchronous</i> cache, cache invalidation is a single step process (evict or update).
+    Hence, these contracts ({@link org.hibernate.cache.access.EntityRegionAcessStrategy} and
+    {@link org.hibernate.cache.access.CollectionRegionAccessStrategy}) define a three step process to cater for both 
+    models (see the individual contracts for details).
+</p>
+<p>
+    Note that query result caching does not go through an access strategy; those caches are managed directly against
+    the underlying {@link org.hibernate.cache.QueryResultsRegion}.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,143 +0,0 @@
-//$Id: CacheEntry.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import java.io.Serializable;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PreLoadEvent;
-import org.hibernate.event.PreLoadEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * A cached instance of a persistent class
- *
- * @author Gavin King
- */
-public final class CacheEntry implements Serializable {
-
-	private final Serializable[] disassembledState;
-	private final String subclass;
-	private final boolean lazyPropertiesAreUnfetched;
-	private final Object version;
-	
-	public String getSubclass() {
-		return subclass;
-	}
-	
-	public boolean areLazyPropertiesUnfetched() {
-		return lazyPropertiesAreUnfetched;
-	}
-	
-	public CacheEntry(
-			final Object[] state, 
-			final EntityPersister persister, 
-			final boolean unfetched, 
-			final Object version,
-			final SessionImplementor session, 
-			final Object owner) 
-	throws HibernateException {
-		//disassembled state gets put in a new array (we write to cache by value!)
-		this.disassembledState = TypeFactory.disassemble( 
-				state, 
-				persister.getPropertyTypes(), 
-				persister.isLazyPropertiesCacheable() ? 
-					null : persister.getPropertyLaziness(),
-				session, 
-				owner 
-			);
-		subclass = persister.getEntityName();
-		lazyPropertiesAreUnfetched = unfetched || !persister.isLazyPropertiesCacheable();
-		this.version = version;
-	}
-	
-	public Object getVersion() {
-		return version;
-	}
-
-	CacheEntry(Serializable[] state, String subclass, boolean unfetched, Object version) {
-		this.disassembledState = state;
-		this.subclass = subclass;
-		this.lazyPropertiesAreUnfetched = unfetched;
-		this.version = version;
-	}
-
-	public Object[] assemble(
-			final Object instance, 
-			final Serializable id, 
-			final EntityPersister persister, 
-			final Interceptor interceptor, 
-			final EventSource session) 
-	throws HibernateException {
-
-		if ( !persister.getEntityName().equals(subclass) ) {
-			throw new AssertionFailure("Tried to assemble a different subclass instance");
-		}
-
-		return assemble(disassembledState, instance, id, persister, interceptor, session);
-
-	}
-
-	private static Object[] assemble(
-			final Serializable[] values, 
-			final Object result, 
-			final Serializable id, 
-			final EntityPersister persister, 
-			final Interceptor interceptor, 
-			final EventSource session) 
-	throws HibernateException {
-			
-		//assembled state gets put in a new array (we read from cache by value!)
-		Object[] assembledProps = TypeFactory.assemble( 
-				values, 
-				persister.getPropertyTypes(), 
-				session, result 
-			);
-
-		//persister.setIdentifier(result, id); //before calling interceptor, for consistency with normal load
-
-		//TODO: reuse the PreLoadEvent
-		PreLoadEvent preLoadEvent = new PreLoadEvent( session )
-				.setEntity(result)
-				.setState(assembledProps)
-				.setId(id)
-				.setPersister(persister);
-		
-		PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
-		for ( int i = 0; i < listeners.length; i++ ) {
-			listeners[i].onPreLoad(preLoadEvent);
-		}
-		
-		persister.setPropertyValues( 
-				result, 
-				assembledProps, 
-				session.getEntityMode() 
-			);
-
-		return assembledProps;
-	}
-
-    public Serializable[] getDisassembledState() {
-	    // todo: this was added to support initializing an entity's EntityEntry snapshot during reattach;
-	    // this should be refactored to instead expose a method to assemble a EntityEntry based on this
-	    // state for return.
-	    return disassembledState;
-    }
-
-	public String toString() {
-		return "CacheEntry(" + subclass + ')' + 
-				ArrayHelper.toString(disassembledState);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,166 @@
+/*
+ * 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.cache.entry;
+
+import java.io.Serializable;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PreLoadEvent;
+import org.hibernate.event.PreLoadEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * A cached instance of a persistent class
+ *
+ * @author Gavin King
+ */
+public final class CacheEntry implements Serializable {
+
+	private final Serializable[] disassembledState;
+	private final String subclass;
+	private final boolean lazyPropertiesAreUnfetched;
+	private final Object version;
+	
+	public String getSubclass() {
+		return subclass;
+	}
+	
+	public boolean areLazyPropertiesUnfetched() {
+		return lazyPropertiesAreUnfetched;
+	}
+	
+	public CacheEntry(
+			final Object[] state, 
+			final EntityPersister persister, 
+			final boolean unfetched, 
+			final Object version,
+			final SessionImplementor session, 
+			final Object owner) 
+	throws HibernateException {
+		//disassembled state gets put in a new array (we write to cache by value!)
+		this.disassembledState = TypeFactory.disassemble( 
+				state, 
+				persister.getPropertyTypes(), 
+				persister.isLazyPropertiesCacheable() ? 
+					null : persister.getPropertyLaziness(),
+				session, 
+				owner 
+			);
+		subclass = persister.getEntityName();
+		lazyPropertiesAreUnfetched = unfetched || !persister.isLazyPropertiesCacheable();
+		this.version = version;
+	}
+	
+	public Object getVersion() {
+		return version;
+	}
+
+	CacheEntry(Serializable[] state, String subclass, boolean unfetched, Object version) {
+		this.disassembledState = state;
+		this.subclass = subclass;
+		this.lazyPropertiesAreUnfetched = unfetched;
+		this.version = version;
+	}
+
+	public Object[] assemble(
+			final Object instance, 
+			final Serializable id, 
+			final EntityPersister persister, 
+			final Interceptor interceptor, 
+			final EventSource session) 
+	throws HibernateException {
+
+		if ( !persister.getEntityName().equals(subclass) ) {
+			throw new AssertionFailure("Tried to assemble a different subclass instance");
+		}
+
+		return assemble(disassembledState, instance, id, persister, interceptor, session);
+
+	}
+
+	private static Object[] assemble(
+			final Serializable[] values, 
+			final Object result, 
+			final Serializable id, 
+			final EntityPersister persister, 
+			final Interceptor interceptor, 
+			final EventSource session) 
+	throws HibernateException {
+			
+		//assembled state gets put in a new array (we read from cache by value!)
+		Object[] assembledProps = TypeFactory.assemble( 
+				values, 
+				persister.getPropertyTypes(), 
+				session, result 
+			);
+
+		//persister.setIdentifier(result, id); //before calling interceptor, for consistency with normal load
+
+		//TODO: reuse the PreLoadEvent
+		PreLoadEvent preLoadEvent = new PreLoadEvent( session )
+				.setEntity(result)
+				.setState(assembledProps)
+				.setId(id)
+				.setPersister(persister);
+		
+		PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
+		for ( int i = 0; i < listeners.length; i++ ) {
+			listeners[i].onPreLoad(preLoadEvent);
+		}
+		
+		persister.setPropertyValues( 
+				result, 
+				assembledProps, 
+				session.getEntityMode() 
+			);
+
+		return assembledProps;
+	}
+
+    public Serializable[] getDisassembledState() {
+	    // todo: this was added to support initializing an entity's EntityEntry snapshot during reattach;
+	    // this should be refactored to instead expose a method to assemble a EntityEntry based on this
+	    // state for return.
+	    return disassembledState;
+    }
+
+	public String toString() {
+		return "CacheEntry(" + subclass + ')' + 
+				ArrayHelper.toString(disassembledState);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-//$Id: CacheEntryStructure.java 5707 2005-02-13 12:47:01Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-
-
-/**
- * @author Gavin King
- */
-public interface CacheEntryStructure {
-	public Object structure(Object item);
-	public Object destructure(Object map, SessionFactoryImplementor factory);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CacheEntryStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.entry;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+
+/**
+ * @author Gavin King
+ */
+public interface CacheEntryStructure {
+	public Object structure(Object item);
+	public Object destructure(Object map, SessionFactoryImplementor factory);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-//$Id: CollectionCacheEntry.java 6838 2005-05-20 19:50:07Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import java.io.Serializable;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @author Gavin King
- */
-public class CollectionCacheEntry implements Serializable {
-
-	private final Serializable state;
-	
-	public Serializable[] getState() {
-		//TODO: assumes all collections disassemble to an array!
-		return (Serializable[]) state;
-	}
-
-	public CollectionCacheEntry(PersistentCollection collection, CollectionPersister persister) {
-		this.state = collection.disassemble(persister);
-	}
-	
-	CollectionCacheEntry(Serializable state) {
-		this.state = state;
-	}
-	
-	public void assemble(
-		final PersistentCollection collection, 
-		final CollectionPersister persister,
-		final Object owner
-	) {
-		collection.initializeFromCache(persister, state, owner);
-		collection.afterInitialize();
-	}
-	
-	public String toString() {
-		return "CollectionCacheEntry" + ArrayHelper.toString( getState() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/CollectionCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.entry;
+
+import java.io.Serializable;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @author Gavin King
+ */
+public class CollectionCacheEntry implements Serializable {
+
+	private final Serializable state;
+	
+	public Serializable[] getState() {
+		//TODO: assumes all collections disassemble to an array!
+		return (Serializable[]) state;
+	}
+
+	public CollectionCacheEntry(PersistentCollection collection, CollectionPersister persister) {
+		this.state = collection.disassemble(persister);
+	}
+	
+	CollectionCacheEntry(Serializable state) {
+		this.state = state;
+	}
+	
+	public void assemble(
+		final PersistentCollection collection, 
+		final CollectionPersister persister,
+		final Object owner
+	) {
+		collection.initializeFromCache(persister, state, owner);
+		collection.afterInitialize();
+	}
+	
+	public String toString() {
+		return "CollectionCacheEntry" + ArrayHelper.toString( getState() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-//$Id: StructuredCacheEntry.java 7764 2005-08-05 16:16:46Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * @author Gavin King
- */
-public class StructuredCacheEntry implements CacheEntryStructure {
-
-	private EntityPersister persister;
-
-	public StructuredCacheEntry(EntityPersister persister) {
-		this.persister = persister;
-	}
-	
-	public Object destructure(Object item, SessionFactoryImplementor factory) {
-		Map map = (Map) item;
-		boolean lazyPropertiesUnfetched = ( (Boolean) map.get("_lazyPropertiesUnfetched") ).booleanValue();
-		String subclass = (String) map.get("_subclass");
-		Object version = map.get("_version");
-		EntityPersister subclassPersister = factory.getEntityPersister(subclass);
-		String[] names = subclassPersister.getPropertyNames();
-		Serializable[] state = new Serializable[names.length];
-		for ( int i=0; i<names.length; i++ ) {
-			state[i] = (Serializable) map.get( names[i] );
-		}
-		return new CacheEntry(state, subclass, lazyPropertiesUnfetched, version);
-	}
-
-	public Object structure(Object item) {
-		CacheEntry entry = (CacheEntry) item;
-		String[] names = persister.getPropertyNames();
-		Map map = new HashMap(names.length+2);
-		map.put( "_subclass", entry.getSubclass() );
-		map.put( "_version", entry.getVersion() );
-		map.put( "_lazyPropertiesUnfetched", entry.areLazyPropertiesUnfetched() ? Boolean.TRUE : Boolean.FALSE );
-		for ( int i=0; i<names.length; i++ ) {
-			map.put( names[i], entry.getDisassembledState()[i] );
-		}
-		return map;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.cache.entry;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * @author Gavin King
+ */
+public class StructuredCacheEntry implements CacheEntryStructure {
+
+	private EntityPersister persister;
+
+	public StructuredCacheEntry(EntityPersister persister) {
+		this.persister = persister;
+	}
+	
+	public Object destructure(Object item, SessionFactoryImplementor factory) {
+		Map map = (Map) item;
+		boolean lazyPropertiesUnfetched = ( (Boolean) map.get("_lazyPropertiesUnfetched") ).booleanValue();
+		String subclass = (String) map.get("_subclass");
+		Object version = map.get("_version");
+		EntityPersister subclassPersister = factory.getEntityPersister(subclass);
+		String[] names = subclassPersister.getPropertyNames();
+		Serializable[] state = new Serializable[names.length];
+		for ( int i=0; i<names.length; i++ ) {
+			state[i] = (Serializable) map.get( names[i] );
+		}
+		return new CacheEntry(state, subclass, lazyPropertiesUnfetched, version);
+	}
+
+	public Object structure(Object item) {
+		CacheEntry entry = (CacheEntry) item;
+		String[] names = persister.getPropertyNames();
+		Map map = new HashMap(names.length+2);
+		map.put( "_subclass", entry.getSubclass() );
+		map.put( "_version", entry.getVersion() );
+		map.put( "_lazyPropertiesUnfetched", entry.areLazyPropertiesUnfetched() ? Boolean.TRUE : Boolean.FALSE );
+		for ( int i=0; i<names.length; i++ ) {
+			map.put( names[i], entry.getDisassembledState()[i] );
+		}
+		return map;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: StructuredCollectionCacheEntry.java 5707 2005-02-13 12:47:01Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.List;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * @author Gavin King
- */
-public class StructuredCollectionCacheEntry implements CacheEntryStructure {
-
-	public Object structure(Object item) {
-		CollectionCacheEntry entry = (CollectionCacheEntry) item;
-		return Arrays.asList( entry.getState() );
-	}
-	
-	public Object destructure(Object item, SessionFactoryImplementor factory) {
-		List list = (List) item;
-		return new CollectionCacheEntry( list.toArray( new Serializable[list.size()] ) );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredCollectionCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.cache.entry;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.List;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class StructuredCollectionCacheEntry implements CacheEntryStructure {
+
+	public Object structure(Object item) {
+		CollectionCacheEntry entry = (CollectionCacheEntry) item;
+		return Arrays.asList( entry.getState() );
+	}
+	
+	public Object destructure(Object item, SessionFactoryImplementor factory) {
+		List list = (List) item;
+		return new CollectionCacheEntry( list.toArray( new Serializable[list.size()] ) );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: StructuredMapCacheEntry.java 5707 2005-02-13 12:47:01Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * @author Gavin King
- */
-public class StructuredMapCacheEntry implements CacheEntryStructure {
-
-	public Object structure(Object item) {
-		CollectionCacheEntry entry = (CollectionCacheEntry) item;
-		Serializable[] state = entry.getState();
-		Map map = new HashMap(state.length);
-		for ( int i=0; i<state.length; ) {
-			map.put( state[i++], state[i++] );
-		}
-		return map;
-	}
-	
-	public Object destructure(Object item, SessionFactoryImplementor factory) {
-		Map map = (Map) item;
-		Serializable[] state = new Serializable[ map.size()*2 ];
-		int i=0;
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			state[i++] = (Serializable) me.getKey();
-			state[i++] = (Serializable) me.getValue();
-		}
-		return new CollectionCacheEntry(state);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/StructuredMapCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.cache.entry;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class StructuredMapCacheEntry implements CacheEntryStructure {
+
+	public Object structure(Object item) {
+		CollectionCacheEntry entry = (CollectionCacheEntry) item;
+		Serializable[] state = entry.getState();
+		Map map = new HashMap(state.length);
+		for ( int i=0; i<state.length; ) {
+			map.put( state[i++], state[i++] );
+		}
+		return map;
+	}
+	
+	public Object destructure(Object item, SessionFactoryImplementor factory) {
+		Map map = (Map) item;
+		Serializable[] state = new Serializable[ map.size()*2 ];
+		int i=0;
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			state[i++] = (Serializable) me.getKey();
+			state[i++] = (Serializable) me.getValue();
+		}
+		return new CollectionCacheEntry(state);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-//$Id: UnstructuredCacheEntry.java 5707 2005-02-13 12:47:01Z oneovthafew $
-package org.hibernate.cache.entry;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-
-/**
- * @author Gavin King
- */
-public class UnstructuredCacheEntry implements CacheEntryStructure {
-
-	public Object structure(Object item) {
-		return item;
-	}
-
-	public Object destructure(Object map, SessionFactoryImplementor factory) {
-		return map;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/UnstructuredCacheEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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.cache.entry;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+
+/**
+ * @author Gavin King
+ */
+public class UnstructuredCacheEntry implements CacheEntryStructure {
+
+	public Object structure(Object item) {
+		return item;
+	}
+
+	public Object destructure(Object map, SessionFactoryImplementor factory) {
+		return map;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/entry/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head>
-</head>
-<body>
-<p>
-	This package defines formats for disassembled state
-	kept in the second level cache.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/entry/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/entry/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head>
+</head>
+<body>
+<p>
+	This package defines formats for disassembled state
+	kept in the second level cache.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-package org.hibernate.cache.impl;
-
-import java.util.Comparator;
-
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Collection;
-import org.hibernate.type.VersionType;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class CacheDataDescriptionImpl implements CacheDataDescription {
-	private final boolean mutable;
-	private final boolean versioned;
-	private final Comparator versionComparator;
-
-	public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator) {
-		this.mutable = mutable;
-		this.versioned = versioned;
-		this.versionComparator = versionComparator;
-	}
-
-	public boolean isMutable() {
-		return mutable;
-	}
-
-	public boolean isVersioned() {
-		return versioned;
-	}
-
-	public Comparator getVersionComparator() {
-		return versionComparator;
-	}
-
-	public static CacheDataDescriptionImpl decode(PersistentClass model) {
-		return new CacheDataDescriptionImpl(
-				model.isMutable(),
-				model.isVersioned(),
-				model.isVersioned() ? ( ( VersionType ) model.getVersion().getType() ).getComparator() : null
-		);
-	}
-
-	public static CacheDataDescriptionImpl decode(Collection model) {
-		return new CacheDataDescriptionImpl(
-				model.isMutable(),
-				model.getOwner().isVersioned(),
-				model.getOwner().isVersioned() ? ( ( VersionType ) model.getOwner().getVersion().getType() ).getComparator() : null
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/CacheDataDescriptionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.impl;
+
+import java.util.Comparator;
+
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Collection;
+import org.hibernate.type.VersionType;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class CacheDataDescriptionImpl implements CacheDataDescription {
+	private final boolean mutable;
+	private final boolean versioned;
+	private final Comparator versionComparator;
+
+	public CacheDataDescriptionImpl(boolean mutable, boolean versioned, Comparator versionComparator) {
+		this.mutable = mutable;
+		this.versioned = versioned;
+		this.versionComparator = versionComparator;
+	}
+
+	public boolean isMutable() {
+		return mutable;
+	}
+
+	public boolean isVersioned() {
+		return versioned;
+	}
+
+	public Comparator getVersionComparator() {
+		return versionComparator;
+	}
+
+	public static CacheDataDescriptionImpl decode(PersistentClass model) {
+		return new CacheDataDescriptionImpl(
+				model.isMutable(),
+				model.isVersioned(),
+				model.isVersioned() ? ( ( VersionType ) model.getVersion().getType() ).getComparator() : null
+		);
+	}
+
+	public static CacheDataDescriptionImpl decode(Collection model) {
+		return new CacheDataDescriptionImpl(
+				model.isMutable(),
+				model.getOwner().isVersioned(),
+				model.getOwner().isVersioned() ? ( ( VersionType ) model.getOwner().getVersion().getType() ).getComparator() : null
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-package org.hibernate.cache.impl;
-
-import java.util.Properties;
-
-import org.hibernate.cache.RegionFactory;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.CollectionRegion;
-import org.hibernate.cache.QueryResultsRegion;
-import org.hibernate.cache.TimestampsRegion;
-import org.hibernate.cache.NoCachingEnabledException;
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.cfg.Settings;
-
-/**
- * Factory used if no caching enabled in config...
- *
- * @author Steve Ebersole
- */
-public class NoCachingRegionFactory implements RegionFactory {
-
-
-	public NoCachingRegionFactory(Properties properties) {
-	}
-
-	public void start(Settings settings, Properties properties) throws CacheException {
-	}
-
-	public void stop() {
-	}
-
-	public boolean isMinimalPutsEnabledByDefault() {
-		return false;
-	}
-
-	public long nextTimestamp() {
-		return System.currentTimeMillis() / 100;
-	}
-
-	public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
-			throws CacheException {
-		throw new NoCachingEnabledException();
-	}
-
-	public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata)
-			throws CacheException {
-		throw new NoCachingEnabledException();
-	}
-
-	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
-		throw new NoCachingEnabledException();
-	}
-
-	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
-		throw new NoCachingEnabledException();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/NoCachingRegionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.impl;
+
+import java.util.Properties;
+
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.QueryResultsRegion;
+import org.hibernate.cache.TimestampsRegion;
+import org.hibernate.cache.NoCachingEnabledException;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Factory used if no caching enabled in config...
+ *
+ * @author Steve Ebersole
+ */
+public class NoCachingRegionFactory implements RegionFactory {
+
+
+	public NoCachingRegionFactory(Properties properties) {
+	}
+
+	public void start(Settings settings, Properties properties) throws CacheException {
+	}
+
+	public void stop() {
+	}
+
+	public boolean isMinimalPutsEnabledByDefault() {
+		return false;
+	}
+
+	public long nextTimestamp() {
+		return System.currentTimeMillis() / 100;
+	}
+
+	public EntityRegion buildEntityRegion(String regionName, Properties properties, CacheDataDescription metadata)
+			throws CacheException {
+		throw new NoCachingEnabledException();
+	}
+
+	public CollectionRegion buildCollectionRegion(String regionName, Properties properties, CacheDataDescription metadata)
+			throws CacheException {
+		throw new NoCachingEnabledException();
+	}
+
+	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
+		throw new NoCachingEnabledException();
+	}
+
+	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
+		throw new NoCachingEnabledException();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.GeneralDataRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cfg.Settings;
-
-/**
- * {@inheritDoc}
-*
-* @author Steve Ebersole
-*/
-public abstract class BaseGeneralDataRegionAdapter extends BaseRegionAdapter implements GeneralDataRegion {
-
-	protected BaseGeneralDataRegionAdapter(Cache underlyingCache, Settings settings) {
-		super( underlyingCache, settings );
-	}
-
-	public Object get(Object key) throws CacheException {
-		return underlyingCache.get( key );
-	}
-
-	public void put(Object key, Object value) throws CacheException {
-		underlyingCache.put( key, value );
-	}
-
-	public void evict(Object key) throws CacheException {
-		underlyingCache.remove( key );
-	}
-
-	public void evictAll() throws CacheException {
-		underlyingCache.clear();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseGeneralDataRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.impl.bridge;
+
+import org.hibernate.cache.GeneralDataRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class BaseGeneralDataRegionAdapter extends BaseRegionAdapter implements GeneralDataRegion {
+
+	protected BaseGeneralDataRegionAdapter(Cache underlyingCache, Settings settings) {
+		super( underlyingCache, settings );
+	}
+
+	public Object get(Object key) throws CacheException {
+		return underlyingCache.get( key );
+	}
+
+	public void put(Object key, Object value) throws CacheException {
+		underlyingCache.put( key, value );
+	}
+
+	public void evict(Object key) throws CacheException {
+		underlyingCache.remove( key );
+	}
+
+	public void evictAll() throws CacheException {
+		underlyingCache.clear();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import java.util.Map;
-
-import org.hibernate.cache.Region;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cfg.Settings;
-
-/**
- * Basic adapter bridging between {@link Region} and {@link Cache}.
- *
- * @author Steve Ebersole
- */
-public abstract class BaseRegionAdapter implements Region {
-	protected final Cache underlyingCache;
-	protected final Settings settings;
-
-	protected BaseRegionAdapter(Cache underlyingCache, Settings settings) {
-		this.underlyingCache = underlyingCache;
-		this.settings = settings;
-	}
-
-	public String getName() {
-		return underlyingCache.getRegionName();
-	}
-
-	public void clear() throws CacheException {
-		underlyingCache.clear();
-	}
-
-	public void destroy() throws CacheException {
-		underlyingCache.destroy();
-	}
-
-	public long getSizeInMemory() {
-		return underlyingCache.getSizeInMemory();
-	}
-
-	public long getElementCountInMemory() {
-		return underlyingCache.getElementCountInMemory();
-	}
-
-	public long getElementCountOnDisk() {
-		return underlyingCache.getElementCountOnDisk();
-	}
-
-	public Map toMap() {
-		return underlyingCache.toMap();
-	}
-
-	public long nextTimestamp() {
-		return underlyingCache.nextTimestamp();
-	}
-
-	public int getTimeout() {
-		return underlyingCache.getTimeout();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.cache.impl.bridge;
+
+import java.util.Map;
+
+import org.hibernate.cache.Region;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Basic adapter bridging between {@link Region} and {@link Cache}.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class BaseRegionAdapter implements Region {
+	protected final Cache underlyingCache;
+	protected final Settings settings;
+
+	protected BaseRegionAdapter(Cache underlyingCache, Settings settings) {
+		this.underlyingCache = underlyingCache;
+		this.settings = settings;
+	}
+
+	public String getName() {
+		return underlyingCache.getRegionName();
+	}
+
+	public void clear() throws CacheException {
+		underlyingCache.clear();
+	}
+
+	public void destroy() throws CacheException {
+		underlyingCache.destroy();
+	}
+
+	public long getSizeInMemory() {
+		return underlyingCache.getSizeInMemory();
+	}
+
+	public long getElementCountInMemory() {
+		return underlyingCache.getElementCountInMemory();
+	}
+
+	public long getElementCountOnDisk() {
+		return underlyingCache.getElementCountOnDisk();
+	}
+
+	public Map toMap() {
+		return underlyingCache.toMap();
+	}
+
+	public long nextTimestamp() {
+		return underlyingCache.nextTimestamp();
+	}
+
+	public int getTimeout() {
+		return underlyingCache.getTimeout();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.TransactionalDataRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.cfg.Settings;
-
-/**
- * {@inheritDoc}
-*
-* @author Steve Ebersole
-*/
-public abstract class BaseTransactionalDataRegionAdapter
-		extends BaseRegionAdapter
-		implements TransactionalDataRegion {
-
-	protected final CacheDataDescription metadata;
-
-	protected BaseTransactionalDataRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
-		super( underlyingCache, settings );
-		this.metadata = metadata;
-	}
-
-	public boolean isTransactionAware() {
-		return underlyingCache instanceof org.hibernate.cache.TransactionAwareCache;
-	}
-
-	public CacheDataDescription getCacheDataDescription() {
-		return metadata;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/BaseTransactionalDataRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.impl.bridge;
+
+import org.hibernate.cache.TransactionalDataRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cfg.Settings;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class BaseTransactionalDataRegionAdapter
+		extends BaseRegionAdapter
+		implements TransactionalDataRegion {
+
+	protected final CacheDataDescription metadata;
+
+	protected BaseTransactionalDataRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
+		super( underlyingCache, settings );
+		this.metadata = metadata;
+	}
+
+	public boolean isTransactionAware() {
+		return underlyingCache instanceof org.hibernate.cache.TransactionAwareCache;
+	}
+
+	public CacheDataDescription getCacheDataDescription() {
+		return metadata;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,91 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.CollectionRegion;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically bridging {@link CollectionRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
- *
- * @author Steve Ebersole
- */
-public class CollectionAccessStrategyAdapter implements CollectionRegionAccessStrategy {
-	private final CollectionRegion region;
-	private final CacheConcurrencyStrategy ccs;
-	private final Settings settings;
-
-	public CollectionAccessStrategyAdapter(CollectionRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
-		this.region = region;
-		this.ccs = ccs;
-		this.settings = settings;
-	}
-
-	public CollectionRegion getRegion() {
-		return region;
-	}
-
-	public Object get(Object key, long txTimestamp) throws CacheException {
-		return ccs.get( key, txTimestamp );
-	}
-
-	public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
-		return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
-	}
-
-	public boolean putFromLoad(
-			Object key, 
-			Object value,
-			long txTimestamp,
-			Object version,
-			boolean minimalPutOverride) throws CacheException {
-		return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
-	}
-
-	public SoftLock lockItem(Object key, Object version) throws CacheException {
-		return ccs.lock( key, version );
-	}
-
-	public SoftLock lockRegion() throws CacheException {
-		// no-op; CCS did not have such a concept
-		return null;
-	}
-
-	public void unlockItem(Object key, SoftLock lock) throws CacheException {
-		ccs.release( key, lock );
-	}
-
-	public void unlockRegion(SoftLock lock) throws CacheException {
-		// again, CCS did not have such a concept; but a reasonable
-		// proximity is to clear the cache after transaction *as long as*
-		// the underlying cache is not JTA aware.
-		if ( !region.isTransactionAware() ) {
-			ccs.clear();
-		}
-	}
-
-	public void remove(Object key) throws CacheException {
-		ccs.evict( key );
-	}
-
-	public void removeAll() throws CacheException {
-		// again, CCS did not have such a concept; however a reasonable
-		// proximity is to clear the cache.  For non-transaction aware
-		// caches, we will also do a clear at the end of the transaction
-		ccs.clear();
-	}
-
-	public void evict(Object key) throws CacheException {
-		ccs.remove( key );
-	}
-
-	public void evictAll() throws CacheException {
-		ccs.clear();
-	}
-
-	public void destroy() {
-		ccs.destroy();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionAccessStrategyAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.cache.impl.bridge;
+
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.CacheConcurrencyStrategy;
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically bridging {@link CollectionRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionAccessStrategyAdapter implements CollectionRegionAccessStrategy {
+	private final CollectionRegion region;
+	private final CacheConcurrencyStrategy ccs;
+	private final Settings settings;
+
+	public CollectionAccessStrategyAdapter(CollectionRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
+		this.region = region;
+		this.ccs = ccs;
+		this.settings = settings;
+	}
+
+	public CollectionRegion getRegion() {
+		return region;
+	}
+
+	public Object get(Object key, long txTimestamp) throws CacheException {
+		return ccs.get( key, txTimestamp );
+	}
+
+	public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+		return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
+	}
+
+	public boolean putFromLoad(
+			Object key, 
+			Object value,
+			long txTimestamp,
+			Object version,
+			boolean minimalPutOverride) throws CacheException {
+		return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
+	}
+
+	public SoftLock lockItem(Object key, Object version) throws CacheException {
+		return ccs.lock( key, version );
+	}
+
+	public SoftLock lockRegion() throws CacheException {
+		// no-op; CCS did not have such a concept
+		return null;
+	}
+
+	public void unlockItem(Object key, SoftLock lock) throws CacheException {
+		ccs.release( key, lock );
+	}
+
+	public void unlockRegion(SoftLock lock) throws CacheException {
+		// again, CCS did not have such a concept; but a reasonable
+		// proximity is to clear the cache after transaction *as long as*
+		// the underlying cache is not JTA aware.
+		if ( !region.isTransactionAware() ) {
+			ccs.clear();
+		}
+	}
+
+	public void remove(Object key) throws CacheException {
+		ccs.evict( key );
+	}
+
+	public void removeAll() throws CacheException {
+		// again, CCS did not have such a concept; however a reasonable
+		// proximity is to clear the cache.  For non-transaction aware
+		// caches, we will also do a clear at the end of the transaction
+		ccs.clear();
+	}
+
+	public void evict(Object key) throws CacheException {
+		ccs.remove( key );
+	}
+
+	public void evictAll() throws CacheException {
+		ccs.clear();
+	}
+
+	public void destroy() {
+		ccs.destroy();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.CollectionRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.cache.OptimisticCache;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.TransactionalCache;
-import org.hibernate.cache.ReadWriteCache;
-import org.hibernate.cache.NonstrictReadWriteCache;
-import org.hibernate.cache.ReadOnlyCache;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.access.AccessType;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically bridging {@link CollectionRegion} to {@link Cache}.
- *
- * @author Steve Ebersole
- */
-public class CollectionRegionAdapter extends BaseTransactionalDataRegionAdapter implements CollectionRegion {
-	private static final Logger log = LoggerFactory.getLogger( CollectionRegionAdapter.class );
-
-	public CollectionRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
-		super( underlyingCache, settings, metadata );
-		if ( underlyingCache instanceof OptimisticCache ) {
-			( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
-		}
-	}
-
-	public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
-		CacheConcurrencyStrategy ccs;
-		if ( AccessType.READ_ONLY.equals( accessType ) ) {
-			if ( metadata.isMutable() ) {
-				log.warn( "read-only cache configured for mutable collection [" + getName() + "]" );
-			}
-			ccs = new ReadOnlyCache();
-		}
-		else if ( AccessType.READ_WRITE.equals( accessType ) ) {
-			ccs = new ReadWriteCache();
-		}
-		else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
-			ccs = new NonstrictReadWriteCache();
-		}
-		else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
-			ccs = new TransactionalCache();
-		}
-		else {
-			throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
-		}
-		ccs.setCache( underlyingCache );
-		return new CollectionAccessStrategyAdapter( this, ccs, settings );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/CollectionRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cache.impl.bridge;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cache.OptimisticCache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CacheConcurrencyStrategy;
+import org.hibernate.cache.TransactionalCache;
+import org.hibernate.cache.ReadWriteCache;
+import org.hibernate.cache.NonstrictReadWriteCache;
+import org.hibernate.cache.ReadOnlyCache;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.AccessType;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically bridging {@link CollectionRegion} to {@link Cache}.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionRegionAdapter extends BaseTransactionalDataRegionAdapter implements CollectionRegion {
+	private static final Logger log = LoggerFactory.getLogger( CollectionRegionAdapter.class );
+
+	public CollectionRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
+		super( underlyingCache, settings, metadata );
+		if ( underlyingCache instanceof OptimisticCache ) {
+			( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
+		}
+	}
+
+	public CollectionRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
+		CacheConcurrencyStrategy ccs;
+		if ( AccessType.READ_ONLY.equals( accessType ) ) {
+			if ( metadata.isMutable() ) {
+				log.warn( "read-only cache configured for mutable collection [" + getName() + "]" );
+			}
+			ccs = new ReadOnlyCache();
+		}
+		else if ( AccessType.READ_WRITE.equals( accessType ) ) {
+			ccs = new ReadWriteCache();
+		}
+		else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
+			ccs = new NonstrictReadWriteCache();
+		}
+		else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
+			ccs = new TransactionalCache();
+		}
+		else {
+			throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
+		}
+		ccs.setCache( underlyingCache );
+		return new CollectionAccessStrategyAdapter( this, ccs, settings );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,109 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically bridging {@link EntityRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
- *
- * @author Steve Ebersole
- */
-public class EntityAccessStrategyAdapter implements EntityRegionAccessStrategy {
-	private final EntityRegion region;
-	private final CacheConcurrencyStrategy ccs;
-	private final Settings settings;
-
-	public EntityAccessStrategyAdapter(EntityRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
-		this.region = region;
-		this.ccs = ccs;
-		this.settings = settings;
-	}
-
-	public EntityRegion getRegion() {
-		return region;
-	}
-
-	public Object get(Object key, long txTimestamp) throws CacheException {
-		return ccs.get( key, txTimestamp );
-	}
-
-	public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
-		return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
-	}
-
-	public boolean putFromLoad(
-			Object key,
-			Object value,
-			long txTimestamp,
-			Object version,
-			boolean minimalPutOverride) throws CacheException {
-		return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
-	}
-
-	public SoftLock lockItem(Object key, Object version) throws CacheException {
-		return ccs.lock( key, version );
-	}
-
-	public SoftLock lockRegion() throws CacheException {
-		// no-op; CCS did not have such a concept
-		return null;
-	}
-
-	public void unlockItem(Object key, SoftLock lock) throws CacheException {
-		ccs.release( key, lock );
-	}
-
-	public void unlockRegion(SoftLock lock) throws CacheException {
-		// again, CCS did not have such a concept; but a reasonable
-		// proximity is to clear the cache after transaction *as long as*
-		// the underlying cache is not JTA aware.
-		if ( !region.isTransactionAware() ) {
-			ccs.clear();
-		}
-	}
-
-	public boolean insert(Object key, Object value, Object version) throws CacheException {
-		return ccs.insert( key, value, version );
-	}
-
-	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
-		return ccs.afterInsert( key, value, version );
-	}
-
-	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
-			throws CacheException {
-		return ccs.update( key, value, currentVersion, previousVersion );
-	}
-
-	public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
-			throws CacheException {
-		return ccs.afterUpdate( key, value, currentVersion, lock );
-	}
-
-	public void remove(Object key) throws CacheException {
-		ccs.evict( key );
-	}
-
-	public void removeAll() throws CacheException {
-		// again, CCS did not have such a concept; however a reasonable
-		// proximity is to clear the cache.  For non-transaction aware
-		// caches, we will also do a clear at the end of the transaction
-		ccs.clear();
-	}
-
-	public void evict(Object key) throws CacheException {
-		ccs.remove( key );
-	}
-
-	public void evictAll() throws CacheException {
-		ccs.clear();
-	}
-
-	public void destroy() {
-		ccs.destroy();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityAccessStrategyAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,133 @@
+/*
+ * 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.cache.impl.bridge;
+
+import org.hibernate.cache.CacheConcurrencyStrategy;
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically bridging {@link EntityRegionAccessStrategy} to {@link CacheConcurrencyStrategy}.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityAccessStrategyAdapter implements EntityRegionAccessStrategy {
+	private final EntityRegion region;
+	private final CacheConcurrencyStrategy ccs;
+	private final Settings settings;
+
+	public EntityAccessStrategyAdapter(EntityRegion region, CacheConcurrencyStrategy ccs, Settings settings) {
+		this.region = region;
+		this.ccs = ccs;
+		this.settings = settings;
+	}
+
+	public EntityRegion getRegion() {
+		return region;
+	}
+
+	public Object get(Object key, long txTimestamp) throws CacheException {
+		return ccs.get( key, txTimestamp );
+	}
+
+	public boolean putFromLoad(Object key, Object value, long txTimestamp, Object version) throws CacheException {
+		return putFromLoad( key, value, txTimestamp, version, settings.isMinimalPutsEnabled() );
+	}
+
+	public boolean putFromLoad(
+			Object key,
+			Object value,
+			long txTimestamp,
+			Object version,
+			boolean minimalPutOverride) throws CacheException {
+		return ccs.put( key, value, txTimestamp, version, region.getCacheDataDescription().getVersionComparator(), minimalPutOverride );
+	}
+
+	public SoftLock lockItem(Object key, Object version) throws CacheException {
+		return ccs.lock( key, version );
+	}
+
+	public SoftLock lockRegion() throws CacheException {
+		// no-op; CCS did not have such a concept
+		return null;
+	}
+
+	public void unlockItem(Object key, SoftLock lock) throws CacheException {
+		ccs.release( key, lock );
+	}
+
+	public void unlockRegion(SoftLock lock) throws CacheException {
+		// again, CCS did not have such a concept; but a reasonable
+		// proximity is to clear the cache after transaction *as long as*
+		// the underlying cache is not JTA aware.
+		if ( !region.isTransactionAware() ) {
+			ccs.clear();
+		}
+	}
+
+	public boolean insert(Object key, Object value, Object version) throws CacheException {
+		return ccs.insert( key, value, version );
+	}
+
+	public boolean afterInsert(Object key, Object value, Object version) throws CacheException {
+		return ccs.afterInsert( key, value, version );
+	}
+
+	public boolean update(Object key, Object value, Object currentVersion, Object previousVersion)
+			throws CacheException {
+		return ccs.update( key, value, currentVersion, previousVersion );
+	}
+
+	public boolean afterUpdate(Object key, Object value, Object currentVersion, Object previousVersion, SoftLock lock)
+			throws CacheException {
+		return ccs.afterUpdate( key, value, currentVersion, lock );
+	}
+
+	public void remove(Object key) throws CacheException {
+		ccs.evict( key );
+	}
+
+	public void removeAll() throws CacheException {
+		// again, CCS did not have such a concept; however a reasonable
+		// proximity is to clear the cache.  For non-transaction aware
+		// caches, we will also do a clear at the end of the transaction
+		ccs.clear();
+	}
+
+	public void evict(Object key) throws CacheException {
+		ccs.remove( key );
+	}
+
+	public void evictAll() throws CacheException {
+		ccs.clear();
+	}
+
+	public void destroy() {
+		ccs.destroy();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.cache.OptimisticCache;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.ReadOnlyCache;
-import org.hibernate.cache.ReadWriteCache;
-import org.hibernate.cache.NonstrictReadWriteCache;
-import org.hibernate.cache.TransactionalCache;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.access.AccessType;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically bridging {@link EntityRegion} to {@link Cache}.
- *
- * @author Steve Ebersole
- */
-public class EntityRegionAdapter extends BaseTransactionalDataRegionAdapter implements EntityRegion {
-	private static final Logger log = LoggerFactory.getLogger( EntityRegionAdapter.class );
-
-	public EntityRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
-		super( underlyingCache, settings, metadata );
-		if ( underlyingCache instanceof OptimisticCache ) {
-			( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
-		}
-	}
-
-	public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
-		CacheConcurrencyStrategy ccs;
-		if ( AccessType.READ_ONLY.equals( accessType ) ) {
-			if ( metadata.isMutable() ) {
-				log.warn( "read-only cache configured for mutable entity [" + getName() + "]" );
-			}
-			ccs = new ReadOnlyCache();
-		}
-		else if ( AccessType.READ_WRITE.equals( accessType ) ) {
-			ccs = new ReadWriteCache();
-		}
-		else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
-			ccs = new NonstrictReadWriteCache();
-		}
-		else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
-			ccs = new TransactionalCache();
-		}
-		else {
-			throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
-		}
-		ccs.setCache( underlyingCache );
-		return new EntityAccessStrategyAdapter( this, ccs, settings );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/EntityRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.cache.impl.bridge;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.cache.OptimisticCache;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.CacheConcurrencyStrategy;
+import org.hibernate.cache.ReadOnlyCache;
+import org.hibernate.cache.ReadWriteCache;
+import org.hibernate.cache.NonstrictReadWriteCache;
+import org.hibernate.cache.TransactionalCache;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.access.AccessType;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically bridging {@link EntityRegion} to {@link Cache}.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityRegionAdapter extends BaseTransactionalDataRegionAdapter implements EntityRegion {
+	private static final Logger log = LoggerFactory.getLogger( EntityRegionAdapter.class );
+
+	public EntityRegionAdapter(Cache underlyingCache, Settings settings, CacheDataDescription metadata) {
+		super( underlyingCache, settings, metadata );
+		if ( underlyingCache instanceof OptimisticCache ) {
+			( ( OptimisticCache ) underlyingCache ).setSource( new OptimisticCacheSourceAdapter( metadata ) );
+		}
+	}
+
+	public EntityRegionAccessStrategy buildAccessStrategy(AccessType accessType) throws CacheException {
+		CacheConcurrencyStrategy ccs;
+		if ( AccessType.READ_ONLY.equals( accessType ) ) {
+			if ( metadata.isMutable() ) {
+				log.warn( "read-only cache configured for mutable entity [" + getName() + "]" );
+			}
+			ccs = new ReadOnlyCache();
+		}
+		else if ( AccessType.READ_WRITE.equals( accessType ) ) {
+			ccs = new ReadWriteCache();
+		}
+		else if ( AccessType.NONSTRICT_READ_WRITE.equals( accessType ) ) {
+			ccs = new NonstrictReadWriteCache();
+		}
+		else if ( AccessType.TRANSACTIONAL.equals( accessType ) ) {
+			ccs = new TransactionalCache();
+		}
+		else {
+			throw new IllegalArgumentException( "unrecognized access strategy type [" + accessType + "]" );
+		}
+		ccs.setCache( underlyingCache );
+		return new EntityAccessStrategyAdapter( this, ccs, settings );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import java.util.Comparator;
-
-import org.hibernate.cache.OptimisticCacheSource;
-import org.hibernate.cache.CacheDataDescription;
-
-/**
- * {@inheritDoc}
-*
-* @author Steve Ebersole
-*/
-public class OptimisticCacheSourceAdapter implements OptimisticCacheSource {
-	private final CacheDataDescription dataDescription;
-
-	public OptimisticCacheSourceAdapter(CacheDataDescription dataDescription) {
-		this.dataDescription = dataDescription;
-	}
-
-	public boolean isVersioned() {
-		return dataDescription.isVersioned();
-	}
-
-	public Comparator getVersionComparator() {
-		return dataDescription.getVersionComparator();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/OptimisticCacheSourceAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.cache.impl.bridge;
+
+import java.util.Comparator;
+
+import org.hibernate.cache.OptimisticCacheSource;
+import org.hibernate.cache.CacheDataDescription;
+
+/**
+ * {@inheritDoc}
+*
+* @author Steve Ebersole
+*/
+public class OptimisticCacheSourceAdapter implements OptimisticCacheSource {
+	private final CacheDataDescription dataDescription;
+
+	public OptimisticCacheSourceAdapter(CacheDataDescription dataDescription) {
+		this.dataDescription = dataDescription;
+	}
+
+	public boolean isVersioned() {
+		return dataDescription.isVersioned();
+	}
+
+	public Comparator getVersionComparator() {
+		return dataDescription.getVersionComparator();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.QueryResultsRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically briding {@link QueryResultsRegion} to {@link Cache}.
-*
-* @author Steve Ebersole
- */
-public class QueryResultsRegionAdapter extends BaseGeneralDataRegionAdapter implements QueryResultsRegion {
-	protected QueryResultsRegionAdapter(Cache underlyingCache, Settings settings) {
-		super( underlyingCache, settings );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/QueryResultsRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.cache.impl.bridge;
+
+import org.hibernate.cache.QueryResultsRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically briding {@link QueryResultsRegion} to {@link Cache}.
+*
+* @author Steve Ebersole
+ */
+public class QueryResultsRegionAdapter extends BaseGeneralDataRegionAdapter implements QueryResultsRegion {
+	protected QueryResultsRegionAdapter(Cache underlyingCache, Settings settings) {
+		super( underlyingCache, settings );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,91 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cache.RegionFactory;
-import org.hibernate.cache.CacheProvider;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.CollectionRegion;
-import org.hibernate.cache.QueryResultsRegion;
-import org.hibernate.cache.NoCacheProvider;
-import org.hibernate.cache.TimestampsRegion;
-import org.hibernate.cache.CacheDataDescription;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.cfg.Environment;
-import org.hibernate.cfg.Settings;
-
-/**
- * Acts as a bridge between the {@link RegionFactory} contract and the older
- * {@link CacheProvider} contract.
- *
- * @author Steve Ebersole
- */
-public class RegionFactoryCacheProviderBridge implements RegionFactory {
-	public static final String DEF_PROVIDER = NoCacheProvider.class.getName();
-	private static final Logger log = LoggerFactory.getLogger( RegionFactoryCacheProviderBridge.class );
-
-	private CacheProvider cacheProvider;
-	private Settings settings;
-
-	public RegionFactoryCacheProviderBridge(Properties properties) {
-		String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, DEF_PROVIDER );
-		log.info( "Cache provider: " + providerClassName );
-		try {
-			cacheProvider = ( CacheProvider ) ReflectHelper.classForName( providerClassName ).newInstance();
-		}
-		catch ( Exception cnfe ) {
-			throw new CacheException( "could not instantiate CacheProvider [" + providerClassName + "]", cnfe );
-		}
-	}
-
-	public void start(Settings settings, Properties properties) throws CacheException {
-		this.settings = settings;
-		cacheProvider.start( properties );
-	}
-
-	public void stop() {
-		cacheProvider.stop();
-		cacheProvider = null;
-	}
-
-	public boolean isMinimalPutsEnabledByDefault() {
-		return cacheProvider.isMinimalPutsEnabledByDefault();
-	}
-
-	public long nextTimestamp() {
-		return cacheProvider.nextTimestamp();
-	}
-
-	public CacheProvider getCacheProvider() {
-		return cacheProvider;
-	}
-
-	public EntityRegion buildEntityRegion(
-			String regionName,
-			Properties properties,
-			CacheDataDescription metadata) throws CacheException {
-		return new EntityRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
-	}
-
-	public CollectionRegion buildCollectionRegion(
-			String regionName,
-			Properties properties,
-			CacheDataDescription metadata) throws CacheException {
-		return new CollectionRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
-	}
-
-	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
-		return new QueryResultsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
-	}
-
-	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
-		return new TimestampsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/RegionFactoryCacheProviderBridge.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.cache.impl.bridge;
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.CacheProvider;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.QueryResultsRegion;
+import org.hibernate.cache.NoCacheProvider;
+import org.hibernate.cache.TimestampsRegion;
+import org.hibernate.cache.CacheDataDescription;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Acts as a bridge between the {@link RegionFactory} contract and the older
+ * {@link CacheProvider} contract.
+ *
+ * @author Steve Ebersole
+ */
+public class RegionFactoryCacheProviderBridge implements RegionFactory {
+	public static final String DEF_PROVIDER = NoCacheProvider.class.getName();
+	private static final Logger log = LoggerFactory.getLogger( RegionFactoryCacheProviderBridge.class );
+
+	private CacheProvider cacheProvider;
+	private Settings settings;
+
+	public RegionFactoryCacheProviderBridge(Properties properties) {
+		String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, DEF_PROVIDER );
+		log.info( "Cache provider: " + providerClassName );
+		try {
+			cacheProvider = ( CacheProvider ) ReflectHelper.classForName( providerClassName ).newInstance();
+		}
+		catch ( Exception cnfe ) {
+			throw new CacheException( "could not instantiate CacheProvider [" + providerClassName + "]", cnfe );
+		}
+	}
+
+	public void start(Settings settings, Properties properties) throws CacheException {
+		this.settings = settings;
+		cacheProvider.start( properties );
+	}
+
+	public void stop() {
+		cacheProvider.stop();
+		cacheProvider = null;
+	}
+
+	public boolean isMinimalPutsEnabledByDefault() {
+		return cacheProvider.isMinimalPutsEnabledByDefault();
+	}
+
+	public long nextTimestamp() {
+		return cacheProvider.nextTimestamp();
+	}
+
+	public CacheProvider getCacheProvider() {
+		return cacheProvider;
+	}
+
+	public EntityRegion buildEntityRegion(
+			String regionName,
+			Properties properties,
+			CacheDataDescription metadata) throws CacheException {
+		return new EntityRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
+	}
+
+	public CollectionRegion buildCollectionRegion(
+			String regionName,
+			Properties properties,
+			CacheDataDescription metadata) throws CacheException {
+		return new CollectionRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings, metadata );
+	}
+
+	public QueryResultsRegion buildQueryResultsRegion(String regionName, Properties properties) throws CacheException {
+		return new QueryResultsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
+	}
+
+	public TimestampsRegion buildTimestampsRegion(String regionName, Properties properties) throws CacheException {
+		return new TimestampsRegionAdapter( cacheProvider.buildCache( regionName, properties ), settings );
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-package org.hibernate.cache.impl.bridge;
-
-import org.hibernate.cache.TimestampsRegion;
-import org.hibernate.cache.Cache;
-import org.hibernate.cfg.Settings;
-
-/**
- * Adapter specifically briding {@link TimestampsRegion} to {@link Cache}.
-*
-* @author Steve Ebersole
- */
-public class TimestampsRegionAdapter extends BaseGeneralDataRegionAdapter implements TimestampsRegion {
-	protected TimestampsRegionAdapter(Cache underlyingCache, Settings settings) {
-		super( underlyingCache, settings );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/impl/bridge/TimestampsRegionAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.cache.impl.bridge;
+
+import org.hibernate.cache.TimestampsRegion;
+import org.hibernate.cache.Cache;
+import org.hibernate.cfg.Settings;
+
+/**
+ * Adapter specifically briding {@link TimestampsRegion} to {@link Cache}.
+*
+* @author Steve Ebersole
+ */
+public class TimestampsRegionAdapter extends BaseGeneralDataRegionAdapter implements TimestampsRegion {
+	protected TimestampsRegionAdapter(Cache underlyingCache, Settings settings) {
+		super( underlyingCache, settings );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cache/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-<html>
-    <head>
-    </head>
-
-    <body>
-        <p>
-            This package defines APIs/SPIs and implementations for the Hibernate second-level cache.
-        </p>
-        <p>
-            The legacy (and now deprecated) approach to caching is defined by the {@link org.hibernate.cache.CacheProvider} and
-            {@link org.hibernate.cache.Cache} interfaces as well as the {@link org.hibernate.cache.CacheConcurrencyStrategy}
-            interface along with the various implementations of all these interfaces.  In that scheme, a
-            {@link org.hibernate.cache.CacheProvider} defined how to configure and perform lifecycle operations
-            in regards to a particular underlying caching library; it also defined how to build {@link org.hibernate.cache.Cache}
-            instances which in turn defined how to access the "regions" of the underlying cache instance.
-            For entity and collection data cache regions, {@link org.hibernate.cache.CacheConcurrencyStrategy} wrapped
-            access to those cache regions to apply transactional/concurrent access semantics.
-        </p>
-        <p>
-            The improved approach is based on {@link org.hibernate.cache.RegionFactory}, the various
-            {@link org.hibernate.cache.Region} specializations and the two access strategies contracts
-            ({@link org.hibernate.cache.access.EntityRegionAccessStrategy} and
-            {@link org.hibernate.cache.access.CollectionRegionAccessStrategy}).  The general approach here is that
-            {@link org.hibernate.cache.RegionFactory} defined how to configure and perform lifecycle operations
-            in regards to a particular underlying caching library (<b>or libraries</b>).
-            {@link org.hibernate.cache.RegionFactory} also defines how to build specialized
-            {@link org.hibernate.cache.Region} instances based on the type of data we will be storing in that given
-            region.  The fact that {@link org.hibernate.cache.RegionFactory} is asked to build <b>specialized</b>
-            regions (as opposed to just general access) is the first <i>improvement</i> over the legacy scheme.  The
-            second <i>improvement</i> is the fact that the regions (well the ones like entity and collection regions
-            that are responsible for storing {@link org.hibernate.cache.TransactionalDataRegion transactional} data) are
-            asked to build their own access strategies (see {@link org.hibernate.cache.EntityRegion#buildAccessStrategy}
-            and {@link org.hibernate.cache.CollectionRegion#buildAccessStrategy}).
-        </p>
-    </body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cache/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cache/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+    <head>
+    </head>
+
+    <body>
+        <p>
+            This package defines APIs/SPIs and implementations for the Hibernate second-level cache.
+        </p>
+        <p>
+            The legacy (and now deprecated) approach to caching is defined by the {@link org.hibernate.cache.CacheProvider} and
+            {@link org.hibernate.cache.Cache} interfaces as well as the {@link org.hibernate.cache.CacheConcurrencyStrategy}
+            interface along with the various implementations of all these interfaces.  In that scheme, a
+            {@link org.hibernate.cache.CacheProvider} defined how to configure and perform lifecycle operations
+            in regards to a particular underlying caching library; it also defined how to build {@link org.hibernate.cache.Cache}
+            instances which in turn defined how to access the "regions" of the underlying cache instance.
+            For entity and collection data cache regions, {@link org.hibernate.cache.CacheConcurrencyStrategy} wrapped
+            access to those cache regions to apply transactional/concurrent access semantics.
+        </p>
+        <p>
+            The improved approach is based on {@link org.hibernate.cache.RegionFactory}, the various
+            {@link org.hibernate.cache.Region} specializations and the two access strategies contracts
+            ({@link org.hibernate.cache.access.EntityRegionAccessStrategy} and
+            {@link org.hibernate.cache.access.CollectionRegionAccessStrategy}).  The general approach here is that
+            {@link org.hibernate.cache.RegionFactory} defined how to configure and perform lifecycle operations
+            in regards to a particular underlying caching library (<b>or libraries</b>).
+            {@link org.hibernate.cache.RegionFactory} also defines how to build specialized
+            {@link org.hibernate.cache.Region} instances based on the type of data we will be storing in that given
+            region.  The fact that {@link org.hibernate.cache.RegionFactory} is asked to build <b>specialized</b>
+            regions (as opposed to just general access) is the first <i>improvement</i> over the legacy scheme.  The
+            second <i>improvement</i> is the fact that the regions (well the ones like entity and collection regions
+            that are responsible for storing {@link org.hibernate.cache.TransactionalDataRegion transactional} data) are
+            asked to build their own access strategies (see {@link org.hibernate.cache.EntityRegion#buildAccessStrategy}
+            and {@link org.hibernate.cache.CollectionRegion#buildAccessStrategy}).
+        </p>
+    </body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,73 +0,0 @@
-//$Id: CollectionSecondPass.java 10196 2006-08-03 07:53:27Z max.andersen at jboss.com $
-package org.hibernate.cfg;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.IndexedCollection;
-import org.hibernate.mapping.OneToMany;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.mapping.Value;
-
-/**
- * Collection second pass
- *
- * @author Emmanuel Bernard
- */
-public abstract class CollectionSecondPass implements SecondPass {
-	private static Logger log = LoggerFactory.getLogger( CollectionSecondPass.class );
-	Mappings mappings;
-	Collection collection;
-	private Map localInheritedMetas;
-
-	public CollectionSecondPass(Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
-		this.collection = collection;
-		this.mappings = mappings;
-		this.localInheritedMetas = inheritedMetas;
-	}
-
-	public CollectionSecondPass(Mappings mappings, Collection collection) {
-		this(mappings, collection, Collections.EMPTY_MAP);
-	}
-
-	public void doSecondPass(java.util.Map persistentClasses)
-			throws MappingException {
-		if ( log.isDebugEnabled() )
-			log.debug( "Second pass for collection: " + collection.getRole() );
-
-		secondPass( persistentClasses, localInheritedMetas ); // using local since the inheritedMetas at this point is not the correct map since it is always the empty map
-		collection.createAllKeys();
-
-		if ( log.isDebugEnabled() ) {
-			String msg = "Mapped collection key: " + columns( collection.getKey() );
-			if ( collection.isIndexed() )
-				msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() );
-			if ( collection.isOneToMany() ) {
-				msg += ", one-to-many: "
-					+ ( (OneToMany) collection.getElement() ).getReferencedEntityName();
-			}
-			else {
-				msg += ", element: " + columns( collection.getElement() );
-			}
-			log.debug( msg );
-		}
-	}
-
-	abstract public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
-			throws MappingException;
-
-	private static String columns(Value val) {
-		StringBuffer columns = new StringBuffer();
-		Iterator iter = val.getColumnIterator();
-		while ( iter.hasNext() ) {
-			columns.append( ( (Selectable) iter.next() ).getText() );
-			if ( iter.hasNext() ) columns.append( ", " );
-		}
-		return columns.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cfg;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.IndexedCollection;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.Value;
+
+/**
+ * Collection second pass
+ *
+ * @author Emmanuel Bernard
+ */
+public abstract class CollectionSecondPass implements SecondPass {
+	private static Logger log = LoggerFactory.getLogger( CollectionSecondPass.class );
+	Mappings mappings;
+	Collection collection;
+	private Map localInheritedMetas;
+
+	public CollectionSecondPass(Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
+		this.collection = collection;
+		this.mappings = mappings;
+		this.localInheritedMetas = inheritedMetas;
+	}
+
+	public CollectionSecondPass(Mappings mappings, Collection collection) {
+		this(mappings, collection, Collections.EMPTY_MAP);
+	}
+
+	public void doSecondPass(java.util.Map persistentClasses)
+			throws MappingException {
+		if ( log.isDebugEnabled() )
+			log.debug( "Second pass for collection: " + collection.getRole() );
+
+		secondPass( persistentClasses, localInheritedMetas ); // using local since the inheritedMetas at this point is not the correct map since it is always the empty map
+		collection.createAllKeys();
+
+		if ( log.isDebugEnabled() ) {
+			String msg = "Mapped collection key: " + columns( collection.getKey() );
+			if ( collection.isIndexed() )
+				msg += ", index: " + columns( ( (IndexedCollection) collection ).getIndex() );
+			if ( collection.isOneToMany() ) {
+				msg += ", one-to-many: "
+					+ ( (OneToMany) collection.getElement() ).getReferencedEntityName();
+			}
+			else {
+				msg += ", element: " + columns( collection.getElement() );
+			}
+			log.debug( msg );
+		}
+	}
+
+	abstract public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+			throws MappingException;
+
+	private static String columns(Value val) {
+		StringBuffer columns = new StringBuffer();
+		Iterator iter = val.getColumnIterator();
+		while ( iter.hasNext() ) {
+			columns.append( ( (Selectable) iter.next() ).getText() );
+			if ( iter.hasNext() ) columns.append( ", " );
+		}
+		return columns.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,2180 +0,0 @@
-//$Id: Configuration.java 10841 2006-11-17 18:29:10Z max.andersen at jboss.com $
-package org.hibernate.cfg;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.io.StringReader;
-import java.lang.reflect.Array;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.jar.JarFile;
-import java.util.zip.ZipEntry;
-
-import org.dom4j.Attribute;
-import org.dom4j.DocumentException;
-import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-import org.hibernate.EmptyInterceptor;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.InvalidMappingException;
-import org.hibernate.MappingException;
-import org.hibernate.MappingNotFoundException;
-import org.hibernate.SessionFactory;
-import org.hibernate.SessionFactoryObserver;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.MySQLDialect;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.engine.Mapping;
-import org.hibernate.event.AutoFlushEventListener;
-import org.hibernate.event.DeleteEventListener;
-import org.hibernate.event.DirtyCheckEventListener;
-import org.hibernate.event.EventListeners;
-import org.hibernate.event.EvictEventListener;
-import org.hibernate.event.FlushEntityEventListener;
-import org.hibernate.event.FlushEventListener;
-import org.hibernate.event.InitializeCollectionEventListener;
-import org.hibernate.event.LoadEventListener;
-import org.hibernate.event.LockEventListener;
-import org.hibernate.event.MergeEventListener;
-import org.hibernate.event.PersistEventListener;
-import org.hibernate.event.PostCollectionRecreateEventListener;
-import org.hibernate.event.PostCollectionRemoveEventListener;
-import org.hibernate.event.PostCollectionUpdateEventListener;
-import org.hibernate.event.PostDeleteEventListener;
-import org.hibernate.event.PostInsertEventListener;
-import org.hibernate.event.PostLoadEventListener;
-import org.hibernate.event.PostUpdateEventListener;
-import org.hibernate.event.PreCollectionRecreateEventListener;
-import org.hibernate.event.PreCollectionRemoveEventListener;
-import org.hibernate.event.PreCollectionUpdateEventListener;
-import org.hibernate.event.PreDeleteEventListener;
-import org.hibernate.event.PreInsertEventListener;
-import org.hibernate.event.PreLoadEventListener;
-import org.hibernate.event.PreUpdateEventListener;
-import org.hibernate.event.RefreshEventListener;
-import org.hibernate.event.ReplicateEventListener;
-import org.hibernate.event.SaveOrUpdateEventListener;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.impl.SessionFactoryImpl;
-import org.hibernate.mapping.AuxiliaryDatabaseObject;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.ForeignKey;
-import org.hibernate.mapping.IdentifierCollection;
-import org.hibernate.mapping.Index;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.RootClass;
-import org.hibernate.mapping.SimpleValue;
-import org.hibernate.mapping.Table;
-import org.hibernate.mapping.UniqueKey;
-import org.hibernate.proxy.EntityNotFoundDelegate;
-import org.hibernate.secure.JACCConfiguration;
-import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
-import org.hibernate.tool.hbm2ddl.TableMetadata;
-import org.hibernate.type.SerializationException;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.ConfigHelper;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.SerializationHelper;
-import org.hibernate.util.StringHelper;
-import org.hibernate.util.XMLHelper;
-
-/**
- * An instance of <tt>Configuration</tt> allows the application
- * to specify properties and mapping documents to be used when
- * creating a <tt>SessionFactory</tt>. Usually an application will create
- * a single <tt>Configuration</tt>, build a single instance of
- * <tt>SessionFactory</tt> and then instantiate <tt>Session</tt>s in
- * threads servicing client requests. The <tt>Configuration</tt> is meant
- * only as an initialization-time object. <tt>SessionFactory</tt>s are
- * immutable and do not retain any association back to the
- * <tt>Configuration</tt>.<br>
- * <br>
- * A new <tt>Configuration</tt> will use the properties specified in
- * <tt>hibernate.properties</tt> by default.
- *
- * @author Gavin King
- * @see org.hibernate.SessionFactory
- */
-public class Configuration implements Serializable {
-
-	private static Logger log = LoggerFactory.getLogger( Configuration.class );
-
-	protected Map classes;
-	protected Map imports;
-	protected Map collections;
-	protected Map tables;
-	protected List auxiliaryDatabaseObjects;
-	protected Map sqlFunctions;
-	protected Map namedQueries;
-	protected Map namedSqlQueries;
-	/**
-	 * Map<String, SqlResultSetMapping> result set name, result set description
-	 */
-	protected Map sqlResultSetMappings;
-	protected Map filterDefinitions;
-	protected List secondPasses;
-	protected List propertyReferences;
-//	protected List extendsQueue;
-	protected Map extendsQueue;
-	protected Map tableNameBinding;
-	protected Map columnNameBindingPerTable;
-	private Interceptor interceptor;
-	private Properties properties;
-	private EntityResolver entityResolver;
-	private EntityNotFoundDelegate entityNotFoundDelegate;
-
-	protected transient XMLHelper xmlHelper;
-	protected transient Map typeDefs;
-
-	protected NamingStrategy namingStrategy;
-
-	private EventListeners eventListeners;
-
-	protected final SettingsFactory settingsFactory;
-
-	private SessionFactoryObserver sessionFactoryObserver;
-
-	protected void reset() {
-		classes = new HashMap();
-		imports = new HashMap();
-		collections = new HashMap();
-		tables = new TreeMap();
-		namedQueries = new HashMap();
-		namedSqlQueries = new HashMap();
-		sqlResultSetMappings = new HashMap();
-		xmlHelper = new XMLHelper();
-		typeDefs = new HashMap();
-		propertyReferences = new ArrayList();
-		secondPasses = new ArrayList();
-		interceptor = EmptyInterceptor.INSTANCE;
-		properties = Environment.getProperties();
-		entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
-		eventListeners = new EventListeners();
-		filterDefinitions = new HashMap();
-//		extendsQueue = new ArrayList();
-		extendsQueue = new HashMap();
-		auxiliaryDatabaseObjects = new ArrayList();
-		tableNameBinding = new HashMap();
-		columnNameBindingPerTable = new HashMap();
-		namingStrategy = DefaultNamingStrategy.INSTANCE;
-		sqlFunctions = new HashMap();
-	}
-
-	private transient Mapping mapping = buildMapping();
-
-
-
-	protected Configuration(SettingsFactory settingsFactory) {
-		this.settingsFactory = settingsFactory;
-		reset();
-	}
-
-	public Configuration() {
-		this( new SettingsFactory() );
-	}
-
-	/**
-	 * Iterate the entity mappings
-	 *
-	 * @return Iterator of the entity mappings currently contained in the configuration.
-	 */
-	public Iterator getClassMappings() {
-		return classes.values().iterator();
-	}
-
-	/**
-	 * Iterate the collection mappings
-	 *
-	 * @return Iterator of the collection mappings currently contained in the configuration.
-	 */
-	public Iterator getCollectionMappings() {
-		return collections.values().iterator();
-	}
-
-	/**
-	 * Iterate the table mappings
-	 *
-	 * @return Iterator of the table mappings currently contained in the configuration.
-	 */
-	public Iterator getTableMappings() {
-		return tables.values().iterator();
-	}
-
-	/**
-	 * Get the mapping for a particular entity
-	 *
-	 * @param entityName An entity name.
-	 * @return the entity mapping information
-	 */
-	public PersistentClass getClassMapping(String entityName) {
-		return (PersistentClass) classes.get( entityName );
-	}
-
-	/**
-	 * Get the mapping for a particular collection role
-	 *
-	 * @param role a collection role
-	 * @return The collection mapping information
-	 */
-	public Collection getCollectionMapping(String role) {
-		return (Collection) collections.get( role );
-	}
-
-	/**
-	 * Set a custom entity resolver. This entity resolver must be
-	 * set before addXXX(misc) call.
-	 * Default value is {@link org.hibernate.util.DTDEntityResolver}
-	 *
-	 * @param entityResolver entity resolver to use
-	 */
-	public void setEntityResolver(EntityResolver entityResolver) {
-		this.entityResolver = entityResolver;
-	}
-
-	public EntityResolver getEntityResolver() {
-		return entityResolver;
-	}
-
-	/**
-	 * Retrieve the user-supplied delegate to handle non-existent entity
-	 * scenarios.  May be null.
-	 *
-	 * @return The user-supplied delegate
-	 */
-	public EntityNotFoundDelegate getEntityNotFoundDelegate() {
-		return entityNotFoundDelegate;
-	}
-
-	/**
-	 * Specify a user-supplied delegate to be used to handle scenarios where an entity could not be
-	 * located by specified id.  This is mainly intended for EJB3 implementations to be able to
-	 * control how proxy initialization errors should be handled...
-	 *
-	 * @param entityNotFoundDelegate The delegate to use
-	 */
-	public void setEntityNotFoundDelegate(EntityNotFoundDelegate entityNotFoundDelegate) {
-		this.entityNotFoundDelegate = entityNotFoundDelegate;
-	}
-
-	/**
-	 * Read mappings from a particular XML file
-	 *
-	 * @param xmlFile a path to a file
-	 * @return this (for method chaining purposes)
-	 * @throws org.hibernate.MappingException Indicates inability to locate or parse
-	 * the specified mapping file.
-	 * @see #addFile(java.io.File)
-	 */
-	public Configuration addFile(String xmlFile) throws MappingException {
-		return addFile( new File( xmlFile ) );
-	}
-
-	/**
-	 * Read mappings from a particular XML file
-	 *
-	 * @param xmlFile a path to a file
-	 * @return this (for method chaining purposes)
-	 * @throws org.hibernate.MappingException Indicates inability to locate or parse
-	 * the specified mapping file.
-	 */
-	public Configuration addFile(File xmlFile) throws MappingException {
-		log.info( "Reading mappings from file: " + xmlFile.getPath() );
-		if ( !xmlFile.exists() ) {
-			throw new MappingNotFoundException( "file", xmlFile.toString() );
-		}
-		try {
-			List errors = new ArrayList();
-			org.dom4j.Document doc = xmlHelper.createSAXReader( xmlFile.toString(), errors, entityResolver ).read( xmlFile );
-			if ( errors.size() != 0 ) {
-				throw new InvalidMappingException( "file", xmlFile.toString(), ( Throwable ) errors.get( 0 ) );
-			}
-			add( doc );
-			return this;
-		}
-		catch ( InvalidMappingException e ) {
-			throw e;
-		}
-		catch  ( MappingNotFoundException e ) {
-			throw e;
-		}
-		catch ( Exception e ) {
-			throw new InvalidMappingException( "file", xmlFile.toString(), e );
-		}
-	}
-
-	/**
-	 * Add a cached mapping file.  A cached file is a serialized representation
-	 * of the DOM structure of a particular mapping.  It is saved from a previous
-	 * call as a file with the name <tt>xmlFile + ".bin"</tt> where xmlFile is
-	 * the name of the original mapping file.
-	 * </p>
-	 * If a cached <tt>xmlFile + ".bin"</tt> exists and is newer than
-	 * <tt>xmlFile</tt> the <tt>".bin"</tt> file will be read directly. Otherwise
-	 * xmlFile is read and then serialized to <tt>xmlFile + ".bin"</tt> for use
-	 * the next time.
-	 *
-	 * @param xmlFile The cacheable mapping file to be added.
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the cached file or processing
-	 * the non-cached file.
-	 */
-	public Configuration addCacheableFile(File xmlFile) throws MappingException {
-		try {
-			File cachedFile = new File( xmlFile.getAbsolutePath() + ".bin" );
-			org.dom4j.Document doc = null;
-
-			final boolean useCachedFile = xmlFile.exists() &&
-					cachedFile.exists() &&
-					xmlFile.lastModified() < cachedFile.lastModified();
-
-			if ( useCachedFile ) {
-				try {
-					log.info( "Reading mappings from cache file: " + cachedFile );
-					doc = ( org.dom4j.Document ) SerializationHelper.deserialize( new FileInputStream( cachedFile ) );
-				}
-				catch ( SerializationException e ) {
-					log.warn( "Could not deserialize cache file: " + cachedFile.getPath(), e );
-				}
-				catch ( FileNotFoundException e ) {
-					log.warn( "I/O reported cached file could not be found : " + cachedFile.getPath(), e );
-				}
-			}
-
-			// if doc is null, then for whatever reason, the cached file cannot be used...
-			if ( doc == null ) {
-				if ( !xmlFile.exists() ) {
-					throw new MappingNotFoundException( "file", xmlFile.toString() );
-				}
-
-				log.info( "Reading mappings from file: " + xmlFile );
-				List errors = new ArrayList();
-				try {
-					doc = xmlHelper.createSAXReader( xmlFile.getAbsolutePath(), errors, entityResolver ).read( xmlFile );
-					if ( errors.size() != 0 ) {
-						throw new MappingException( "invalid mapping", ( Throwable ) errors.get( 0 ) );
-					}
-				}
-				catch( DocumentException e){
-					throw new MappingException( "invalid mapping", e );
-				}
-
-				try {
-					log.debug( "Writing cache file for: " + xmlFile + " to: " + cachedFile );
-					SerializationHelper.serialize( ( Serializable ) doc, new FileOutputStream( cachedFile ) );
-				}
-				catch ( SerializationException e ) {
-					log.warn( "Could not write cached file: " + cachedFile, e );
-				}
-				catch ( FileNotFoundException e ) {
-					log.warn( "I/O reported error writing cached file : " + cachedFile.getPath(), e );
-				}
-			}
-
-			add( doc );
-			return this;
-
-		}
-		catch ( InvalidMappingException e ) {
-			throw e;
-		}
-		catch  ( MappingNotFoundException e ) {
-			throw e;
-		}
-		catch ( Exception e ) {
-			throw new InvalidMappingException( "file", xmlFile.toString(), e );
-		}
-	}
-
-	/**
-	 * Add a cacheable mapping file.
-	 *
-	 * @param xmlFile The name of the file to be added.  This must be in a form
-	 * useable to simply construct a {@link java.io.File} instance.
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the cached file or processing
-	 * the non-cached file.
-	 * @see #addCacheableFile(java.io.File)
-	 */
-	public Configuration addCacheableFile(String xmlFile) throws MappingException {
-		return addCacheableFile( new File( xmlFile ) );
-	}
-
-
-	/**
-	 * Read mappings from a <tt>String</tt>
-	 *
-	 * @param xml an XML string
-	 * @return this (for method chaining purposes)
-	 * @throws org.hibernate.MappingException Indicates problems parsing the
-	 * given XML string
-	 */
-	public Configuration addXML(String xml) throws MappingException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Mapping XML:\n" + xml );
-		}
-		try {
-			List errors = new ArrayList();
-			org.dom4j.Document doc = xmlHelper.createSAXReader( "XML String", errors, entityResolver )
-					.read( new StringReader( xml ) );
-			if ( errors.size() != 0 ) {
-				throw new MappingException( "invalid mapping", (Throwable) errors.get( 0 ) );
-			}
-			add( doc );
-		}
-		catch (DocumentException e) {
-			throw new MappingException( "Could not parse mapping document in XML string", e );
-		}
-		return this;
-	}
-
-	/**
-	 * Read mappings from a <tt>URL</tt>
-	 *
-	 * @param url The url for the mapping document to be read.
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the URL or processing
-	 * the mapping document.
-	 */
-	public Configuration addURL(URL url) throws MappingException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Reading mapping document from URL:" + url.toExternalForm() );
-		}
-		try {
-			addInputStream( url.openStream() );
-		}
-		catch ( InvalidMappingException e ) {
-			throw new InvalidMappingException( "URL", url.toExternalForm(), e.getCause() );
-		}
-		catch (Exception e) {
-			throw new InvalidMappingException( "URL", url.toExternalForm(), e );
-		}
-		return this;
-	}
-
-	/**
-	 * Read mappings from a DOM <tt>Document</tt>
-	 *
-	 * @param doc The DOM document
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the DOM or processing
-	 * the mapping document.
-	 */
-	public Configuration addDocument(Document doc) throws MappingException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Mapping document:\n" + doc );
-		}
-		add( xmlHelper.createDOMReader().read( doc ) );
-		return this;
-	}
-
-	/**
-	 * Read mappings from an {@link java.io.InputStream}.
-	 *
-	 * @param xmlInputStream The input stream containing a DOM.
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the stream, or
-	 * processing the contained mapping document.
-	 */
-	public Configuration addInputStream(InputStream xmlInputStream) throws MappingException {
-		try {
-			List errors = new ArrayList();
-			org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver )
-					.read( new InputSource( xmlInputStream ) );
-			if ( errors.size() != 0 ) {
-				throw new InvalidMappingException( "invalid mapping", null, (Throwable) errors.get( 0 ) );
-			}
-			add( doc );
-			return this;
-		}
-		catch (DocumentException e) {
-			throw new InvalidMappingException( "input stream", null, e );
-		}
-		finally {
-			try {
-				xmlInputStream.close();
-			}
-			catch (IOException ioe) {
-				log.warn( "Could not close input stream", ioe );
-			}
-		}
-	}
-
-	/**
-	 * Read mappings as a application resource (i.e. classpath lookup).
-	 *
-	 * @param resourceName The resource name
-	 * @param classLoader The class loader to use.
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems locating the resource or
-	 * processing the contained mapping document.
-	 */
-	public Configuration addResource(String resourceName, ClassLoader classLoader) throws MappingException {
-		log.info( "Reading mappings from resource: " + resourceName );
-		InputStream rsrc = classLoader.getResourceAsStream( resourceName );
-		if ( rsrc == null ) {
-			throw new MappingNotFoundException( "resource", resourceName );
-		}
-		try {
-			return addInputStream( rsrc );
-		}
-		catch (MappingException me) {
-			throw new InvalidMappingException( "resource", resourceName, me );
-		}
-	}
-
-	/**
-	 * Read mappings as a application resourceName (i.e. classpath lookup)
-	 * trying different classloaders.
-	 *
-	 * @param resourceName The resource name
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems locating the resource or
-	 * processing the contained mapping document.
-	 */
-	public Configuration addResource(String resourceName) throws MappingException {
-		log.info( "Reading mappings from resource : " + resourceName );
-		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-		InputStream rsrc = null;
-		if (contextClassLoader!=null) {
-			rsrc = contextClassLoader.getResourceAsStream( resourceName );
-		}
-		if ( rsrc == null ) {
-			rsrc = Environment.class.getClassLoader().getResourceAsStream( resourceName );
-		}
-		if ( rsrc == null ) {
-			throw new MappingNotFoundException( "resource", resourceName );
-		}
-		try {
-			return addInputStream( rsrc );
-		}
-		catch (MappingException me) {
-			throw new InvalidMappingException( "resource", resourceName, me );
-		}
-	}
-
-	/**
-	 * Read a mapping as an application resouurce using the convention that a class
-	 * named <tt>foo.bar.Foo</tt> is mapped by a file <tt>foo/bar/Foo.hbm.xml</tt>
-	 * which can be resolved as a classpath resource.
-	 *
-	 * @param persistentClass The mapped class
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems locating the resource or
-	 * processing the contained mapping document.
-	 */
-	public Configuration addClass(Class persistentClass) throws MappingException {
-		String mappingResourceName = persistentClass.getName().replace( '.', '/' ) + ".hbm.xml";
-		log.info( "Reading mappings from resource: " + mappingResourceName );
-		return addResource( mappingResourceName, persistentClass.getClassLoader() );
-	}
-
-	/**
-	 * Read all mappings from a jar file
-	 * <p/>
-	 * Assumes that any file named <tt>*.hbm.xml</tt> is a mapping document.
-	 *
-	 * @param jar a jar file
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the jar file or
-	 * processing the contained mapping documents.
-	 */
-	public Configuration addJar(File jar) throws MappingException {
-		log.info( "Searching for mapping documents in jar: " + jar.getName() );
-		JarFile jarFile = null;
-		try {
-			try {
-				jarFile = new JarFile( jar );
-			}
-			catch (IOException ioe) {
-				throw new InvalidMappingException(
-						"Could not read mapping documents from jar: " + jar.getName(), "jar", jar.getName(),
-						ioe
-				);
-			}
-			Enumeration jarEntries = jarFile.entries();
-			while ( jarEntries.hasMoreElements() ) {
-				ZipEntry ze = (ZipEntry) jarEntries.nextElement();
-				if ( ze.getName().endsWith( ".hbm.xml" ) ) {
-					log.info( "Found mapping document in jar: " + ze.getName() );
-					try {
-						addInputStream( jarFile.getInputStream( ze ) );
-					}
-					catch (Exception e) {
-						throw new InvalidMappingException(
-								"Could not read mapping documents from jar: " + jar.getName(),
-								"jar",
-								jar.getName(),
-								e
-						);
-					}
-				}
-			}
-		}
-		finally {
-			try {
-				if ( jarFile != null ) {
-					jarFile.close();
-				}
-			}
-			catch (IOException ioe) {
-				log.error("could not close jar", ioe);
-			}
-		}
-
-		return this;
-	}
-
-	/**
-	 * Read all mapping documents from a directory tree.
-	 * <p/>
-	 * Assumes that any file named <tt>*.hbm.xml</tt> is a mapping document.
-	 *
-	 * @param dir The directory
-	 * @return this (for method chaining purposes)
-	 * @throws MappingException Indicates problems reading the jar file or
-	 * processing the contained mapping documents.
-	 */
-	public Configuration addDirectory(File dir) throws MappingException {
-		File[] files = dir.listFiles();
-		for ( int i = 0; i < files.length ; i++ ) {
-			if ( files[i].isDirectory() ) {
-				addDirectory( files[i] );
-			}
-			else if ( files[i].getName().endsWith( ".hbm.xml" ) ) {
-				addFile( files[i] );
-			}
-		}
-		return this;
-	}
-
-	protected void add(org.dom4j.Document doc) throws MappingException {
-		HbmBinder.bindRoot( doc, createMappings(), CollectionHelper.EMPTY_MAP );
-	}
-
-	/**
-	 * Create a new <tt>Mappings</tt> to add class and collection
-	 * mappings to.
-	 */
-	public Mappings createMappings() {
-		return new Mappings(
-				classes,
-				collections,
-				tables,
-				namedQueries,
-				namedSqlQueries,
-				sqlResultSetMappings,
-				imports,
-				secondPasses,
-				propertyReferences,
-				namingStrategy,
-				typeDefs,
-				filterDefinitions,
-				extendsQueue,
-				auxiliaryDatabaseObjects,
-				tableNameBinding,
-				columnNameBindingPerTable
-			);
-	}
-
-
-	private Iterator iterateGenerators(Dialect dialect) throws MappingException {
-
-		TreeMap generators = new TreeMap();
-		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
-		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
-
-		Iterator iter = classes.values().iterator();
-		while ( iter.hasNext() ) {
-			PersistentClass pc = (PersistentClass) iter.next();
-
-			if ( !pc.isInherited() ) {
-
-				IdentifierGenerator ig = pc.getIdentifier()
-						.createIdentifierGenerator(
-								dialect,
-								defaultCatalog,
-								defaultSchema,
-								(RootClass) pc
-							);
-
-				if ( ig instanceof PersistentIdentifierGenerator ) {
-					generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
-				}
-
-			}
-		}
-
-		iter = collections.values().iterator();
-		while ( iter.hasNext() ) {
-			Collection collection = (Collection) iter.next();
-
-			if ( collection.isIdentified() ) {
-
-				IdentifierGenerator ig = ( (IdentifierCollection) collection ).getIdentifier()
-						.createIdentifierGenerator(
-								dialect,
-								defaultCatalog,
-								defaultSchema,
-								null
-							);
-
-				if ( ig instanceof PersistentIdentifierGenerator ) {
-					generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
-				}
-
-			}
-		}
-
-		return generators.values().iterator();
-	}
-
-	/**
-	 * Generate DDL for dropping tables
-	 *
-	 * @see org.hibernate.tool.hbm2ddl.SchemaExport
-	 */
-	public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
-
-		secondPassCompile();
-
-		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
-		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
-
-		ArrayList script = new ArrayList( 50 );
-
-		// drop them in reverse order in case db needs it done that way...
-		ListIterator itr = auxiliaryDatabaseObjects.listIterator( auxiliaryDatabaseObjects.size() );
-		while ( itr.hasPrevious() ) {
-			AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.previous();
-			if ( object.appliesToDialect( dialect ) ) {
-				script.add( object.sqlDropString( dialect, defaultCatalog, defaultSchema ) );
-			}
-		}
-
-		if ( dialect.dropConstraints() ) {
-			Iterator iter = getTableMappings();
-			while ( iter.hasNext() ) {
-				Table table = (Table) iter.next();
-				if ( table.isPhysicalTable() ) {
-					Iterator subIter = table.getForeignKeyIterator();
-					while ( subIter.hasNext() ) {
-						ForeignKey fk = (ForeignKey) subIter.next();
-						if ( fk.isPhysicalConstraint() ) {
-							script.add(
-									fk.sqlDropString(
-											dialect,
-											defaultCatalog,
-											defaultSchema
-										)
-								);
-						}
-					}
-				}
-			}
-		}
-
-
-		Iterator iter = getTableMappings();
-		while ( iter.hasNext() ) {
-
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-
-				/*Iterator subIter = table.getIndexIterator();
-				while ( subIter.hasNext() ) {
-					Index index = (Index) subIter.next();
-					if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
-						script.add( index.sqlDropString(dialect) );
-					}
-				}*/
-
-				script.add(
-						table.sqlDropString(
-								dialect,
-								defaultCatalog,
-								defaultSchema
-							)
-					);
-
-			}
-
-		}
-
-		iter = iterateGenerators( dialect );
-		while ( iter.hasNext() ) {
-			String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlDropStrings( dialect );
-			for ( int i = 0; i < lines.length ; i++ ) {
-				script.add( lines[i] );
-			}
-		}
-
-		return ArrayHelper.toStringArray( script );
-	}
-
-	/**
-	 * Generate DDL for creating tables
-	 *
-	 * @see org.hibernate.tool.hbm2ddl.SchemaExport
-	 */
-	public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
-		secondPassCompile();
-
-		ArrayList script = new ArrayList( 50 );
-		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
-		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
-
-		Iterator iter = getTableMappings();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-				script.add(
-						table.sqlCreateString(
-								dialect,
-								mapping,
-								defaultCatalog,
-								defaultSchema
-							)
-					);
-				Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
-				while ( comments.hasNext() ) {
-					script.add( comments.next() );
-				}
-			}
-		}
-
-		iter = getTableMappings();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-
-				if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
-					Iterator subIter = table.getUniqueKeyIterator();
-					while ( subIter.hasNext() ) {
-						UniqueKey uk = (UniqueKey) subIter.next();
-						String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema );
-						if (constraintString != null) script.add( constraintString );
-					}
-				}
-
-
-				Iterator subIter = table.getIndexIterator();
-				while ( subIter.hasNext() ) {
-					Index index = (Index) subIter.next();
-					script.add(
-							index.sqlCreateString(
-									dialect,
-									mapping,
-									defaultCatalog,
-									defaultSchema
-								)
-						);
-				}
-
-				if ( dialect.hasAlterTable() ) {
-					subIter = table.getForeignKeyIterator();
-					while ( subIter.hasNext() ) {
-						ForeignKey fk = (ForeignKey) subIter.next();
-						if ( fk.isPhysicalConstraint() ) {
-							script.add(
-									fk.sqlCreateString(
-											dialect, mapping,
-											defaultCatalog,
-											defaultSchema
-										)
-								);
-						}
-					}
-				}
-
-			}
-		}
-
-		iter = iterateGenerators( dialect );
-		while ( iter.hasNext() ) {
-			String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlCreateStrings( dialect );
-			for ( int i = 0; i < lines.length ; i++ ) {
-				script.add( lines[i] );
-			}
-		}
-
-		Iterator itr = auxiliaryDatabaseObjects.iterator();
-		while ( itr.hasNext() ) {
-			AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.next();
-			if ( object.appliesToDialect( dialect ) ) {
-				script.add( object.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ) );
-			}
-		}
-
-		return ArrayHelper.toStringArray( script );
-	}
-
-	/**
-	 * Generate DDL for altering tables
-	 *
-	 * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
-	 */
-	public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
-			throws HibernateException {
-		secondPassCompile();
-
-		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
-		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
-
-		ArrayList script = new ArrayList( 50 );
-
-		Iterator iter = getTableMappings();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-				
-				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
-						table.getName(),
-						( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
-						( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
-								table.isQuoted()
-
-					);
-				if ( tableInfo == null ) {
-					script.add(
-							table.sqlCreateString(
-									dialect,
-									mapping,
-									defaultCatalog,
-									defaultSchema
-								)
-						);
-				}
-				else {
-					Iterator subiter = table.sqlAlterStrings(
-							dialect,
-							mapping,
-							tableInfo,
-							defaultCatalog,
-							defaultSchema
-						);
-					while ( subiter.hasNext() ) {
-						script.add( subiter.next() );
-					}
-				}
-
-				Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
-				while ( comments.hasNext() ) {
-					script.add( comments.next() );
-				}
-
-			}
-		}
-
-		iter = getTableMappings();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-
-				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
-						table.getName(),
-						table.getSchema(),
-						table.getCatalog(),
-						table.isQuoted()
-					);
-
-				if ( dialect.hasAlterTable() ) {
-					Iterator subIter = table.getForeignKeyIterator();
-					while ( subIter.hasNext() ) {
-						ForeignKey fk = (ForeignKey) subIter.next();
-						if ( fk.isPhysicalConstraint() ) {
-							boolean create = tableInfo == null || (
-									tableInfo.getForeignKeyMetadata( fk.getName() ) == null && (
-											//Icky workaround for MySQL bug:
-											!( dialect instanceof MySQLDialect ) ||
-													tableInfo.getIndexMetadata( fk.getName() ) == null
-										)
-								);
-							if ( create ) {
-								script.add(
-										fk.sqlCreateString(
-												dialect,
-												mapping,
-												defaultCatalog,
-												defaultSchema
-											)
-									);
-							}
-						}
-					}
-				}
-
-			}
-
-			/*//broken, 'cos we don't generate these with names in SchemaExport
-			subIter = table.getIndexIterator();
-			while ( subIter.hasNext() ) {
-				Index index = (Index) subIter.next();
-				if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
-					if ( tableInfo==null || tableInfo.getIndexMetadata( index.getFilterName() ) == null ) {
-						script.add( index.sqlCreateString(dialect, mapping) );
-					}
-				}
-			}
-			//broken, 'cos we don't generate these with names in SchemaExport
-			subIter = table.getUniqueKeyIterator();
-			while ( subIter.hasNext() ) {
-				UniqueKey uk = (UniqueKey) subIter.next();
-				if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) {
-					script.add( uk.sqlCreateString(dialect, mapping) );
-				}
-			}*/
-		}
-
-		iter = iterateGenerators( dialect );
-		while ( iter.hasNext() ) {
-			PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
-			Object key = generator.generatorKey();
-			if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
-				String[] lines = generator.sqlCreateStrings( dialect );
-				for ( int i = 0; i < lines.length ; i++ ) {
-					script.add( lines[i] );
-				}
-			}
-		}
-
-		return ArrayHelper.toStringArray( script );
-	}
-
-	public void validateSchema(Dialect dialect, DatabaseMetadata databaseMetadata)
-			throws HibernateException {
-		secondPassCompile();
-
-		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
-		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
-		
-		Iterator iter = getTableMappings();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			if ( table.isPhysicalTable() ) {
-				
-
-				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
-						table.getName(),
-						( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
-						( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
-								table.isQuoted());
-				if ( tableInfo == null ) {
-					throw new HibernateException( "Missing table: " + table.getName() );
-				}
-				else {
-					table.validateColumns( dialect, mapping, tableInfo );
-				}
-
-			}
-		}
-
-		iter = iterateGenerators( dialect );
-		while ( iter.hasNext() ) {
-			PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
-			Object key = generator.generatorKey();
-			if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
-				throw new HibernateException( "Missing sequence or table: " + key );
-			}
-		}
-	}
-
-	private void validate() throws MappingException {
-		Iterator iter = classes.values().iterator();
-		while ( iter.hasNext() ) {
-			( (PersistentClass) iter.next() ).validate( mapping );
-		}
-		iter = collections.values().iterator();
-		while ( iter.hasNext() ) {
-			( (Collection) iter.next() ).validate( mapping );
-		}
-	}
-
-	/**
-	 * Call this to ensure the mappings are fully compiled/built. Usefull to ensure getting
-	 * access to all information in the metamodel when calling e.g. getClassMappings().
-	 */
-	public void buildMappings() {
-		secondPassCompile();
-	}
-
-	// This method may be called many times!!
-	protected void secondPassCompile() throws MappingException {
-		log.debug( "processing extends queue" );
-
-		processExtendsQueue();
-
-		log.debug( "processing collection mappings" );
-
-		Iterator iter = secondPasses.iterator();
-		while ( iter.hasNext() ) {
-			SecondPass sp = (SecondPass) iter.next();
-			if ( ! (sp instanceof QuerySecondPass) ) {
-				sp.doSecondPass( classes );
-				iter.remove();
-			}
-		}
-
-		log.debug( "processing native query and ResultSetMapping mappings" );
-		iter = secondPasses.iterator();
-		while ( iter.hasNext() ) {
-			SecondPass sp = (SecondPass) iter.next();
-			sp.doSecondPass( classes );
-			iter.remove();
-		}
-
-		log.debug( "processing association property references" );
-
-		iter = propertyReferences.iterator();
-		while ( iter.hasNext() ) {
-			Mappings.PropertyReference upr = (Mappings.PropertyReference) iter.next();
-
-			PersistentClass clazz = getClassMapping( upr.referencedClass );
-			if ( clazz == null ) {
-				throw new MappingException(
-						"property-ref to unmapped class: " +
-						upr.referencedClass
-					);
-			}
-
-			Property prop = clazz.getReferencedProperty( upr.propertyName );
-			if ( upr.unique ) {
-				( (SimpleValue) prop.getValue() ).setAlternateUniqueKey( true );
-			}
-		}
-
-		//TODO: Somehow add the newly created foreign keys to the internal collection
-
-		log.debug( "processing foreign key constraints" );
-
-		iter = getTableMappings();
-		Set done = new HashSet();
-		while ( iter.hasNext() ) {
-			secondPassCompileForeignKeys( (Table) iter.next(), done );
-		}
-
-	}
-
-	/**
-	 * Try to empty the extends queue.
-	 */
-	private void processExtendsQueue() {
-		// todo : would love to have this work on a notification basis
-		//    where the successful binding of an entity/subclass would
-		//    emit a notification which the extendsQueue entries could
-		//    react to...
-		org.dom4j.Document document = findPossibleExtends();
-		while ( document != null ) {
-			add( document );
-			document = findPossibleExtends();
-		}
-
-		if ( extendsQueue.size() > 0 ) {
-//			Iterator iterator = extendsQueue.iterator();
-			Iterator iterator = extendsQueue.keySet().iterator();
-			StringBuffer buf = new StringBuffer( "Following superclasses referenced in extends not found: " );
-			while ( iterator.hasNext() ) {
-				final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
-				buf.append( entry.getExplicitName() );
-				if ( entry.getMappingPackage() != null ) {
-					buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
-				}
-				if ( iterator.hasNext() ) {
-					buf.append( "," );
-				}
-			}
-			throw new MappingException( buf.toString() );
-		}
-	}
-
-	/**
-	 * Find the first possible element in the queue of extends.
-	 */
-	protected org.dom4j.Document findPossibleExtends() {
-//		Iterator iter = extendsQueue.iterator();
-		Iterator iter = extendsQueue.keySet().iterator();
-		while ( iter.hasNext() ) {
-			final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iter.next();
-			if ( getClassMapping( entry.getExplicitName() ) != null ) {
-				// found
-				iter.remove();
-				return entry.getDocument();
-			}
-			else if ( getClassMapping( HbmBinder.getClassName( entry.getExplicitName(), entry.getMappingPackage() ) ) != null ) {
-				// found
-				iter.remove();
-				return entry.getDocument();
-			}
-		}
-		return null;
-	}
-
-	protected void secondPassCompileForeignKeys(Table table, Set done) throws MappingException {
-
-		table.createForeignKeys();
-
-		Iterator iter = table.getForeignKeyIterator();
-		while ( iter.hasNext() ) {
-
-			ForeignKey fk = (ForeignKey) iter.next();
-			if ( !done.contains( fk ) ) {
-				done.add( fk );
-				final String referencedEntityName = fk.getReferencedEntityName();
-				if ( referencedEntityName == null ) {
-					throw new MappingException(
-							"An association from the table " +
-							fk.getTable().getName() +
-							" does not specify the referenced entity"
-						);
-				}
-				if ( log.isDebugEnabled() ) {
-					log.debug( "resolving reference to class: " + referencedEntityName );
-				}
-				PersistentClass referencedClass = (PersistentClass) classes.get( referencedEntityName );
-				if ( referencedClass == null ) {
-					throw new MappingException(
-							"An association from the table " +
-							fk.getTable().getName() +
-							" refers to an unmapped class: " +
-							referencedEntityName
-						);
-				}
-				if ( referencedClass.isJoinedSubclass() ) {
-					secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done );
-				}
-				fk.setReferencedTable( referencedClass.getTable() );
-				fk.alignColumns();
-			}
-		}
-	}
-
-	/**
-	 * Get the named queries
-	 */
-	public Map getNamedQueries() {
-		return namedQueries;
-	}
-
-	/**
-	 * Instantiate a new <tt>SessionFactory</tt>, using the properties and
-	 * mappings in this configuration. The <tt>SessionFactory</tt> will be
-	 * immutable, so changes made to the <tt>Configuration</tt> after
-	 * building the <tt>SessionFactory</tt> will not affect it.
-	 *
-	 * @return a new factory for <tt>Session</tt>s
-	 * @see org.hibernate.SessionFactory
-	 */
-	public SessionFactory buildSessionFactory() throws HibernateException {
-		log.debug( "Preparing to build session factory with filters : " + filterDefinitions );
-		secondPassCompile();
-		validate();
-		Environment.verifyProperties( properties );
-		Properties copy = new Properties();
-		copy.putAll( properties );
-		PropertiesHelper.resolvePlaceHolders( copy );
-		Settings settings = buildSettings( copy );
-
-		return new SessionFactoryImpl(
-				this,
-				mapping,
-				settings,
-				getInitializedEventListeners(),
-				sessionFactoryObserver
-			);
-	}
-
-	private EventListeners getInitializedEventListeners() {
-		EventListeners result = (EventListeners) eventListeners.shallowCopy();
-		result.initializeListeners( this );
-		return result;
-	}
-
-	/**
-	 * Return the configured <tt>Interceptor</tt>
-	 */
-	public Interceptor getInterceptor() {
-		return interceptor;
-	}
-
-	/**
-	 * Get all properties
-	 */
-	public Properties getProperties() {
-		return properties;
-	}
-
-	/**
-	 * Configure an <tt>Interceptor</tt>
-	 */
-	public Configuration setInterceptor(Interceptor interceptor) {
-		this.interceptor = interceptor;
-		return this;
-	}
-
-	/**
-	 * Specify a completely new set of properties
-	 */
-	public Configuration setProperties(Properties properties) {
-		this.properties = properties;
-		return this;
-	}
-
-	/**
-	 * Set the given properties
-	 */
-	public Configuration addProperties(Properties extraProperties) {
-		this.properties.putAll( extraProperties );
-		return this;
-	}
-
-	/**
-	 * Adds the incoming properties to the internap properties structure,
-	 * as long as the internal structure does not already contain an
-	 * entry for the given key.
-	 *
-	 * @param properties
-	 * @return this
-	 */
-	public Configuration mergeProperties(Properties properties) {
-		Iterator itr = properties.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			if ( this.properties.containsKey( entry.getKey() ) ) {
-				continue;
-			}
-			this.properties.setProperty( ( String ) entry.getKey(), ( String ) entry.getValue() );
-		}
-		return this;
-	}
-
-	/**
-	 * Set a property
-	 */
-	public Configuration setProperty(String propertyName, String value) {
-		properties.setProperty( propertyName, value );
-		return this;
-	}
-
-	/**
-	 * Get a property
-	 */
-	public String getProperty(String propertyName) {
-		return properties.getProperty( propertyName );
-	}
-
-	private void addProperties(Element parent) {
-		Iterator iter = parent.elementIterator( "property" );
-		while ( iter.hasNext() ) {
-			Element node = (Element) iter.next();
-			String name = node.attributeValue( "name" );
-			String value = node.getText().trim();
-			log.debug( name + "=" + value );
-			properties.setProperty( name, value );
-			if ( !name.startsWith( "hibernate" ) ) {
-				properties.setProperty( "hibernate." + name, value );
-			}
-		}
-		Environment.verifyProperties( properties );
-	}
-
-	/**
-	 * Get the configuration file as an <tt>InputStream</tt>. Might be overridden
-	 * by subclasses to allow the configuration to be located by some arbitrary
-	 * mechanism.
-	 */
-	protected InputStream getConfigurationInputStream(String resource) throws HibernateException {
-
-		log.info( "Configuration resource: " + resource );
-
-		return ConfigHelper.getResourceAsStream( resource );
-
-	}
-
-	/**
-	 * Use the mappings and properties specified in an application
-	 * resource named <tt>hibernate.cfg.xml</tt>.
-	 */
-	public Configuration configure() throws HibernateException {
-		configure( "/hibernate.cfg.xml" );
-		return this;
-	}
-
-	/**
-	 * Use the mappings and properties specified in the given application
-	 * resource. The format of the resource is defined in
-	 * <tt>hibernate-configuration-3.0.dtd</tt>.
-	 * <p/>
-	 * The resource is found via <tt>getConfigurationInputStream(resource)</tt>.
-	 */
-	public Configuration configure(String resource) throws HibernateException {
-		log.info( "configuring from resource: " + resource );
-		InputStream stream = getConfigurationInputStream( resource );
-		return doConfigure( stream, resource );
-	}
-
-	/**
-	 * Use the mappings and properties specified in the given document.
-	 * The format of the document is defined in
-	 * <tt>hibernate-configuration-3.0.dtd</tt>.
-	 *
-	 * @param url URL from which you wish to load the configuration
-	 * @return A configuration configured via the file
-	 * @throws HibernateException
-	 */
-	public Configuration configure(URL url) throws HibernateException {
-		log.info( "configuring from url: " + url.toString() );
-		try {
-			return doConfigure( url.openStream(), url.toString() );
-		}
-		catch (IOException ioe) {
-			throw new HibernateException( "could not configure from URL: " + url, ioe );
-		}
-	}
-
-	/**
-	 * Use the mappings and properties specified in the given application
-	 * file. The format of the file is defined in
-	 * <tt>hibernate-configuration-3.0.dtd</tt>.
-	 *
-	 * @param configFile <tt>File</tt> from which you wish to load the configuration
-	 * @return A configuration configured via the file
-	 * @throws HibernateException
-	 */
-	public Configuration configure(File configFile) throws HibernateException {
-		log.info( "configuring from file: " + configFile.getName() );
-		try {
-			return doConfigure( new FileInputStream( configFile ), configFile.toString() );
-		}
-		catch (FileNotFoundException fnfe) {
-			throw new HibernateException( "could not find file: " + configFile, fnfe );
-		}
-	}
-
-	/**
-	 * Use the mappings and properties specified in the given application
-	 * resource. The format of the resource is defined in
-	 * <tt>hibernate-configuration-3.0.dtd</tt>.
-	 *
-	 * @param stream	   Inputstream to be read from
-	 * @param resourceName The name to use in warning/error messages
-	 * @return A configuration configured via the stream
-	 * @throws HibernateException
-	 */
-	protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
-
-		org.dom4j.Document doc;
-		try {
-			List errors = new ArrayList();
-			doc = xmlHelper.createSAXReader( resourceName, errors, entityResolver )
-					.read( new InputSource( stream ) );
-			if ( errors.size() != 0 ) {
-				throw new MappingException(
-						"invalid configuration",
-						(Throwable) errors.get( 0 )
-					);
-			}
-		}
-		catch (DocumentException e) {
-			throw new HibernateException(
-					"Could not parse configuration: " + resourceName,
-					e
-				);
-		}
-		finally {
-			try {
-				stream.close();
-			}
-			catch (IOException ioe) {
-				log.warn( "could not close input stream for: " + resourceName, ioe );
-			}
-		}
-
-		return doConfigure( doc );
-
-	}
-
-	/**
-	 * Use the mappings and properties specified in the given XML document.
-	 * The format of the file is defined in
-	 * <tt>hibernate-configuration-3.0.dtd</tt>.
-	 *
-	 * @param document an XML document from which you wish to load the configuration
-	 * @return A configuration configured via the <tt>Document</tt>
-	 * @throws HibernateException if there is problem in accessing the file.
-	 */
-	public Configuration configure(Document document) throws HibernateException {
-		log.info( "configuring from XML document" );
-		return doConfigure( xmlHelper.createDOMReader().read( document ) );
-	}
-
-	protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
-
-		Element sfNode = doc.getRootElement().element( "session-factory" );
-		String name = sfNode.attributeValue( "name" );
-		if ( name != null ) {
-			properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
-		}
-		addProperties( sfNode );
-		parseSessionFactory( sfNode, name );
-
-		Element secNode = doc.getRootElement().element( "security" );
-		if ( secNode != null ) {
-			parseSecurity( secNode );
-		}
-
-		log.info( "Configured SessionFactory: " + name );
-		log.debug( "properties: " + properties );
-
-		return this;
-
-	}
-
-
-	private void parseSessionFactory(Element sfNode, String name) {
-		Iterator elements = sfNode.elementIterator();
-		while ( elements.hasNext() ) {
-			Element subelement = (Element) elements.next();
-			String subelementName = subelement.getName();
-			if ( "mapping".equals( subelementName ) ) {
-				parseMappingElement( subelement, name );
-			}
-			else if ( "class-cache".equals( subelementName ) ) {
-				String className = subelement.attributeValue( "class" );
-				Attribute regionNode = subelement.attribute( "region" );
-				final String region = ( regionNode == null ) ? className : regionNode.getValue();
-				boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) );
-				setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy );
-			}
-			else if ( "collection-cache".equals( subelementName ) ) {
-				String role = subelement.attributeValue( "collection" );
-				Attribute regionNode = subelement.attribute( "region" );
-				final String region = ( regionNode == null ) ? role : regionNode.getValue();
-				setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
-			}
-			else if ( "listener".equals( subelementName ) ) {
-				parseListener( subelement );
-			}
-			else if ( "event".equals( subelementName ) ) {
-				parseEvent( subelement );
-			}
-		}
-	}
-
-	protected void parseMappingElement(Element subelement, String name) {
-		Attribute rsrc = subelement.attribute( "resource" );
-		Attribute file = subelement.attribute( "file" );
-		Attribute jar = subelement.attribute( "jar" );
-		Attribute pkg = subelement.attribute( "package" );
-		Attribute clazz = subelement.attribute( "class" );
-		if ( rsrc != null ) {
-			log.debug( name + "<-" + rsrc );
-			addResource( rsrc.getValue() );
-		}
-		else if ( jar != null ) {
-			log.debug( name + "<-" + jar );
-			addJar( new File( jar.getValue() ) );
-		}
-		else if ( pkg != null ) {
-			throw new MappingException(
-					"An AnnotationConfiguration instance is required to use <mapping package=\"" +
-					pkg.getValue() + "\"/>"
-				);
-		}
-		else if ( clazz != null ) {
-			throw new MappingException(
-					"An AnnotationConfiguration instance is required to use <mapping class=\"" +
-					clazz.getValue() + "\"/>"
-				);
-		}
-		else {
-			if ( file == null ) {
-				throw new MappingException(
-						"<mapping> element in configuration specifies no attributes"
-					);
-			}
-			log.debug( name + "<-" + file );
-			addFile( file.getValue() );
-		}
-	}
-
-	private void parseSecurity(Element secNode) {
-		String contextId = secNode.attributeValue( "context" );
-      setProperty(Environment.JACC_CONTEXTID, contextId);
-		log.info( "JACC contextID: " + contextId );
-		JACCConfiguration jcfg = new JACCConfiguration( contextId );
-		Iterator grantElements = secNode.elementIterator();
-		while ( grantElements.hasNext() ) {
-			Element grantElement = (Element) grantElements.next();
-			String elementName = grantElement.getName();
-			if ( "grant".equals( elementName ) ) {
-				jcfg.addPermission(
-						grantElement.attributeValue( "role" ),
-						grantElement.attributeValue( "entity-name" ),
-						grantElement.attributeValue( "actions" )
-					);
-			}
-		}
-	}
-
-	private void parseEvent(Element element) {
-		String type = element.attributeValue( "type" );
-		List listeners = element.elements();
-		String[] listenerClasses = new String[ listeners.size() ];
-		for ( int i = 0; i < listeners.size() ; i++ ) {
-			listenerClasses[i] = ( (Element) listeners.get( i ) ).attributeValue( "class" );
-		}
-		log.debug( "Event listeners: " + type + "=" + StringHelper.toString( listenerClasses ) );
-		setListeners( type, listenerClasses );
-	}
-
-	private void parseListener(Element element) {
-		String type = element.attributeValue( "type" );
-		if ( type == null ) {
-			throw new MappingException( "No type specified for listener" );
-		}
-		String impl = element.attributeValue( "class" );
-		log.debug( "Event listener: " + type + "=" + impl );
-		setListeners( type, new String[]{impl} );
-	}
-
-	public void setListener(String type, String listener) {
-		String[] listeners = null;
-		if ( listener != null ) {
-			listeners = (String[]) Array.newInstance( String.class, 1 );
-			listeners[0] = listener;
-		}
-		setListeners( type, listeners );
-	}
-
-	public void setListeners(String type, String[] listenerClasses) {
-		Object[] listeners = null;
-		if ( listenerClasses != null ) {
-			listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), listenerClasses.length );
-			for ( int i = 0; i < listeners.length ; i++ ) {
-				try {
-					listeners[i] = ReflectHelper.classForName( listenerClasses[i] ).newInstance();
-				}
-				catch (Exception e) {
-					throw new MappingException(
-							"Unable to instantiate specified event (" + type + ") listener class: " + listenerClasses[i],
-							e
-						);
-				}
-			}
-		}
-		setListeners( type, listeners );
-	}
-
-	public void setListener(String type, Object listener) {
-		Object[] listeners = null;
-		if ( listener != null ) {
-			listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), 1 );
-			listeners[0] = listener;
-		}
-		setListeners( type, listeners );
-	}
-
-	public void setListeners(String type, Object[] listeners) {
-		if ( "auto-flush".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setAutoFlushEventListeners( new AutoFlushEventListener[]{} );
-			}
-			else {
-				eventListeners.setAutoFlushEventListeners( (AutoFlushEventListener[]) listeners );
-			}
-		}
-		else if ( "merge".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setMergeEventListeners( new MergeEventListener[]{} );
-			}
-			else {
-				eventListeners.setMergeEventListeners( (MergeEventListener[]) listeners );
-			}
-		}
-		else if ( "create".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPersistEventListeners( new PersistEventListener[]{} );
-			}
-			else {
-				eventListeners.setPersistEventListeners( (PersistEventListener[]) listeners );
-			}
-		}
-		else if ( "create-onflush".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPersistOnFlushEventListeners( new PersistEventListener[]{} );
-			}
-			else {
-				eventListeners.setPersistOnFlushEventListeners( (PersistEventListener[]) listeners );
-			}
-		}
-		else if ( "delete".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setDeleteEventListeners( new DeleteEventListener[]{} );
-			}
-			else {
-				eventListeners.setDeleteEventListeners( (DeleteEventListener[]) listeners );
-			}
-		}
-		else if ( "dirty-check".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setDirtyCheckEventListeners( new DirtyCheckEventListener[]{} );
-			}
-			else {
-				eventListeners.setDirtyCheckEventListeners( (DirtyCheckEventListener[]) listeners );
-			}
-		}
-		else if ( "evict".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setEvictEventListeners( new EvictEventListener[]{} );
-			}
-			else {
-				eventListeners.setEvictEventListeners( (EvictEventListener[]) listeners );
-			}
-		}
-		else if ( "flush".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setFlushEventListeners( new FlushEventListener[]{} );
-			}
-			else {
-				eventListeners.setFlushEventListeners( (FlushEventListener[]) listeners );
-			}
-		}
-		else if ( "flush-entity".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setFlushEntityEventListeners( new FlushEntityEventListener[]{} );
-			}
-			else {
-				eventListeners.setFlushEntityEventListeners( (FlushEntityEventListener[]) listeners );
-			}
-		}
-		else if ( "load".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setLoadEventListeners( new LoadEventListener[]{} );
-			}
-			else {
-				eventListeners.setLoadEventListeners( (LoadEventListener[]) listeners );
-			}
-		}
-		else if ( "load-collection".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setInitializeCollectionEventListeners(
-						new InitializeCollectionEventListener[]{}
-					);
-			}
-			else {
-				eventListeners.setInitializeCollectionEventListeners(
-						(InitializeCollectionEventListener[]) listeners
-					);
-			}
-		}
-		else if ( "lock".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setLockEventListeners( new LockEventListener[]{} );
-			}
-			else {
-				eventListeners.setLockEventListeners( (LockEventListener[]) listeners );
-			}
-		}
-		else if ( "refresh".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setRefreshEventListeners( new RefreshEventListener[]{} );
-			}
-			else {
-				eventListeners.setRefreshEventListeners( (RefreshEventListener[]) listeners );
-			}
-		}
-		else if ( "replicate".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setReplicateEventListeners( new ReplicateEventListener[]{} );
-			}
-			else {
-				eventListeners.setReplicateEventListeners( (ReplicateEventListener[]) listeners );
-			}
-		}
-		else if ( "save-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setSaveOrUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setSaveOrUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "save".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setSaveEventListeners( new SaveOrUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setSaveEventListeners( (SaveOrUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-load".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreLoadEventListeners( new PreLoadEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreLoadEventListeners( (PreLoadEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreUpdateEventListeners( new PreUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreUpdateEventListeners( (PreUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-delete".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreDeleteEventListeners( new PreDeleteEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreDeleteEventListeners( (PreDeleteEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-insert".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreInsertEventListeners( new PreInsertEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreInsertEventListeners( (PreInsertEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-collection-recreate".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreCollectionRecreateEventListeners( new PreCollectionRecreateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreCollectionRecreateEventListeners( (PreCollectionRecreateEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-collection-remove".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreCollectionRemoveEventListeners( new PreCollectionRemoveEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreCollectionRemoveEventListeners( ( PreCollectionRemoveEventListener[]) listeners );
-			}
-		}
-		else if ( "pre-collection-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPreCollectionUpdateEventListeners( new PreCollectionUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPreCollectionUpdateEventListeners( ( PreCollectionUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "post-load".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostLoadEventListeners( new PostLoadEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostLoadEventListeners( (PostLoadEventListener[]) listeners );
-			}
-		}
-		else if ( "post-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostUpdateEventListeners( new PostUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostUpdateEventListeners( (PostUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "post-delete".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostDeleteEventListeners( new PostDeleteEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostDeleteEventListeners( (PostDeleteEventListener[]) listeners );
-			}
-		}
-		else if ( "post-insert".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostInsertEventListeners( new PostInsertEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostInsertEventListeners( (PostInsertEventListener[]) listeners );
-			}
-		}
-		else if ( "post-commit-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCommitUpdateEventListeners(
-						new PostUpdateEventListener[]{}
-					);
-			}
-			else {
-				eventListeners.setPostCommitUpdateEventListeners( (PostUpdateEventListener[]) listeners );
-			}
-		}
-		else if ( "post-commit-delete".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCommitDeleteEventListeners(
-						new PostDeleteEventListener[]{}
-					);
-			}
-			else {
-				eventListeners.setPostCommitDeleteEventListeners( (PostDeleteEventListener[]) listeners );
-			}
-		}
-		else if ( "post-commit-insert".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCommitInsertEventListeners(
-						new PostInsertEventListener[]{}
-				);
-			}
-			else {
-				eventListeners.setPostCommitInsertEventListeners( (PostInsertEventListener[]) listeners );
-			}
-		}
-		else if ( "post-collection-recreate".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCollectionRecreateEventListeners( new PostCollectionRecreateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostCollectionRecreateEventListeners( (PostCollectionRecreateEventListener[]) listeners );
-			}
-		}
-		else if ( "post-collection-remove".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCollectionRemoveEventListeners( new PostCollectionRemoveEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostCollectionRemoveEventListeners( ( PostCollectionRemoveEventListener[]) listeners );
-			}
-		}
-		else if ( "post-collection-update".equals( type ) ) {
-			if ( listeners == null ) {
-				eventListeners.setPostCollectionUpdateEventListeners( new PostCollectionUpdateEventListener[]{} );
-			}
-			else {
-				eventListeners.setPostCollectionUpdateEventListeners( ( PostCollectionUpdateEventListener[]) listeners );
-			}
-		}
-		else {
-			throw new MappingException("Unrecognized listener type [" + type + "]");
-		}
-	}
-
-	public EventListeners getEventListeners() {
-		return eventListeners;
-	}
-
-	RootClass getRootClassMapping(String clazz) throws MappingException {
-		try {
-			return (RootClass) getClassMapping( clazz );
-		}
-		catch (ClassCastException cce) {
-			throw new MappingException( "You may only specify a cache for root <class> mappings" );
-		}
-	}
-
-	/**
-	 * Set up a cache for an entity class
-	 *
-	 * @param clazz
-	 * @param concurrencyStrategy
-	 * @return Configuration
-	 * @throws MappingException
-	 */
-	public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)
-			throws MappingException {
-		setCacheConcurrencyStrategy( clazz, concurrencyStrategy, clazz );
-		return this;
-	}
-
-	public void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
-			throws MappingException {
-		setCacheConcurrencyStrategy( clazz, concurrencyStrategy, region, true );
-	}
-
-	void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, boolean includeLazy)
-			throws MappingException {
-		RootClass rootClass = getRootClassMapping( clazz );
-		if ( rootClass == null ) {
-			throw new MappingException( "Cannot cache an unknown entity: " + clazz );
-		}
-		rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
-		rootClass.setCacheRegionName( region );
-		rootClass.setLazyPropertiesCacheable( includeLazy );
-	}
-
-	/**
-	 * Set up a cache for a collection role
-	 *
-	 * @param collectionRole
-	 * @param concurrencyStrategy
-	 * @return Configuration
-	 * @throws MappingException
-	 */
-	public Configuration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy)
-			throws MappingException {
-		setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy, collectionRole );
-		return this;
-	}
-
-	public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String region)
-			throws MappingException {
-		Collection collection = getCollectionMapping( collectionRole );
-		if ( collection == null ) {
-			throw new MappingException( "Cannot cache an unknown collection: " + collectionRole );
-		}
-		collection.setCacheConcurrencyStrategy( concurrencyStrategy );
-		collection.setCacheRegionName( region );
-	}
-
-	/**
-	 * Get the query language imports
-	 *
-	 * @return a mapping from "import" names to fully qualified class names
-	 */
-	public Map getImports() {
-		return imports;
-	}
-
-	/**
-	 * Create an object-oriented view of the configuration properties
-	 */
-	public Settings buildSettings() throws HibernateException {
-		Properties clone = ( Properties ) properties.clone();
-		PropertiesHelper.resolvePlaceHolders( clone );
-		return settingsFactory.buildSettings( clone );
-	}
-
-	public Settings buildSettings(Properties props) throws HibernateException {
-		return settingsFactory.buildSettings( props );
-	}
-
-	public Map getNamedSQLQueries() {
-		return namedSqlQueries;
-	}
-
-	public Map getSqlResultSetMappings() {
-		return sqlResultSetMappings;
-	}
-
-	/**
-	 * @return the NamingStrategy.
-	 */
-	public NamingStrategy getNamingStrategy() {
-		return namingStrategy;
-	}
-
-	/**
-	 * Set a custom naming strategy
-	 *
-	 * @param namingStrategy the NamingStrategy to set
-	 */
-	public Configuration setNamingStrategy(NamingStrategy namingStrategy) {
-		this.namingStrategy = namingStrategy;
-		return this;
-	}
-
-	public Mapping buildMapping() {
-		return new Mapping() {
-			/**
-			 * Returns the identifier type of a mapped class
-			 */
-			public Type getIdentifierType(String persistentClass) throws MappingException {
-				PersistentClass pc = ( (PersistentClass) classes.get( persistentClass ) );
-				if ( pc == null ) {
-					throw new MappingException( "persistent class not known: " + persistentClass );
-				}
-				return pc.getIdentifier().getType();
-			}
-
-			public String getIdentifierPropertyName(String persistentClass) throws MappingException {
-				final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
-				if ( pc == null ) {
-					throw new MappingException( "persistent class not known: " + persistentClass );
-				}
-				if ( !pc.hasIdentifierProperty() ) {
-					return null;
-				}
-				return pc.getIdentifierProperty().getName();
-			}
-
-			public Type getReferencedPropertyType(String persistentClass, String propertyName) throws MappingException {
-				final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
-				if ( pc == null ) {
-					throw new MappingException( "persistent class not known: " + persistentClass );
-				}
-				Property prop = pc.getReferencedProperty( propertyName );
-				if ( prop == null ) {
-					throw new MappingException(
-							"property not known: " +
-							persistentClass + '.' + propertyName
-						);
-				}
-				return prop.getType();
-			}
-		};
-	}
-
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		this.mapping = buildMapping();
-		xmlHelper = new XMLHelper();
-	}
-
-	public Map getFilterDefinitions() {
-		return filterDefinitions;
-	}
-
-	public void addFilterDefinition(FilterDefinition definition) {
-		filterDefinitions.put( definition.getFilterName(), definition );
-	}
-
-	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject object) {
-		auxiliaryDatabaseObjects.add( object );
-	}
-
-	public Map getSqlFunctions() {
-		return sqlFunctions;
-	}
-
-	public void addSqlFunction(String functionName, SQLFunction function) {
-		sqlFunctions.put( functionName, function );
-	}
-
-	public SessionFactoryObserver getSessionFactoryObserver() {
-		return sessionFactoryObserver;
-	}
-
-	public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) {
-		this.sessionFactoryObserver = sessionFactoryObserver;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/Configuration.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Configuration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,2203 @@
+/*
+ * 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.cfg;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.io.StringReader;
+import java.lang.reflect.Array;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.dom4j.Attribute;
+import org.dom4j.DocumentException;
+import org.dom4j.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.InvalidMappingException;
+import org.hibernate.MappingException;
+import org.hibernate.MappingNotFoundException;
+import org.hibernate.SessionFactory;
+import org.hibernate.SessionFactoryObserver;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.Mapping;
+import org.hibernate.event.AutoFlushEventListener;
+import org.hibernate.event.DeleteEventListener;
+import org.hibernate.event.DirtyCheckEventListener;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.EvictEventListener;
+import org.hibernate.event.FlushEntityEventListener;
+import org.hibernate.event.FlushEventListener;
+import org.hibernate.event.InitializeCollectionEventListener;
+import org.hibernate.event.LoadEventListener;
+import org.hibernate.event.LockEventListener;
+import org.hibernate.event.MergeEventListener;
+import org.hibernate.event.PersistEventListener;
+import org.hibernate.event.PostCollectionRecreateEventListener;
+import org.hibernate.event.PostCollectionRemoveEventListener;
+import org.hibernate.event.PostCollectionUpdateEventListener;
+import org.hibernate.event.PostDeleteEventListener;
+import org.hibernate.event.PostInsertEventListener;
+import org.hibernate.event.PostLoadEventListener;
+import org.hibernate.event.PostUpdateEventListener;
+import org.hibernate.event.PreCollectionRecreateEventListener;
+import org.hibernate.event.PreCollectionRemoveEventListener;
+import org.hibernate.event.PreCollectionUpdateEventListener;
+import org.hibernate.event.PreDeleteEventListener;
+import org.hibernate.event.PreInsertEventListener;
+import org.hibernate.event.PreLoadEventListener;
+import org.hibernate.event.PreUpdateEventListener;
+import org.hibernate.event.RefreshEventListener;
+import org.hibernate.event.ReplicateEventListener;
+import org.hibernate.event.SaveOrUpdateEventListener;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.mapping.AuxiliaryDatabaseObject;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.ForeignKey;
+import org.hibernate.mapping.IdentifierCollection;
+import org.hibernate.mapping.Index;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.UniqueKey;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.secure.JACCConfiguration;
+import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
+import org.hibernate.tool.hbm2ddl.TableMetadata;
+import org.hibernate.type.SerializationException;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.ConfigHelper;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.SerializationHelper;
+import org.hibernate.util.StringHelper;
+import org.hibernate.util.XMLHelper;
+
+/**
+ * An instance of <tt>Configuration</tt> allows the application
+ * to specify properties and mapping documents to be used when
+ * creating a <tt>SessionFactory</tt>. Usually an application will create
+ * a single <tt>Configuration</tt>, build a single instance of
+ * <tt>SessionFactory</tt> and then instantiate <tt>Session</tt>s in
+ * threads servicing client requests. The <tt>Configuration</tt> is meant
+ * only as an initialization-time object. <tt>SessionFactory</tt>s are
+ * immutable and do not retain any association back to the
+ * <tt>Configuration</tt>.<br>
+ * <br>
+ * A new <tt>Configuration</tt> will use the properties specified in
+ * <tt>hibernate.properties</tt> by default.
+ *
+ * @author Gavin King
+ * @see org.hibernate.SessionFactory
+ */
+public class Configuration implements Serializable {
+
+	private static Logger log = LoggerFactory.getLogger( Configuration.class );
+
+	protected Map classes;
+	protected Map imports;
+	protected Map collections;
+	protected Map tables;
+	protected List auxiliaryDatabaseObjects;
+	protected Map sqlFunctions;
+	protected Map namedQueries;
+	protected Map namedSqlQueries;
+	/**
+	 * Map<String, SqlResultSetMapping> result set name, result set description
+	 */
+	protected Map sqlResultSetMappings;
+	protected Map filterDefinitions;
+	protected List secondPasses;
+	protected List propertyReferences;
+//	protected List extendsQueue;
+	protected Map extendsQueue;
+	protected Map tableNameBinding;
+	protected Map columnNameBindingPerTable;
+	private Interceptor interceptor;
+	private Properties properties;
+	private EntityResolver entityResolver;
+	private EntityNotFoundDelegate entityNotFoundDelegate;
+
+	protected transient XMLHelper xmlHelper;
+	protected transient Map typeDefs;
+
+	protected NamingStrategy namingStrategy;
+
+	private EventListeners eventListeners;
+
+	protected final SettingsFactory settingsFactory;
+
+	private SessionFactoryObserver sessionFactoryObserver;
+
+	protected void reset() {
+		classes = new HashMap();
+		imports = new HashMap();
+		collections = new HashMap();
+		tables = new TreeMap();
+		namedQueries = new HashMap();
+		namedSqlQueries = new HashMap();
+		sqlResultSetMappings = new HashMap();
+		xmlHelper = new XMLHelper();
+		typeDefs = new HashMap();
+		propertyReferences = new ArrayList();
+		secondPasses = new ArrayList();
+		interceptor = EmptyInterceptor.INSTANCE;
+		properties = Environment.getProperties();
+		entityResolver = XMLHelper.DEFAULT_DTD_RESOLVER;
+		eventListeners = new EventListeners();
+		filterDefinitions = new HashMap();
+//		extendsQueue = new ArrayList();
+		extendsQueue = new HashMap();
+		auxiliaryDatabaseObjects = new ArrayList();
+		tableNameBinding = new HashMap();
+		columnNameBindingPerTable = new HashMap();
+		namingStrategy = DefaultNamingStrategy.INSTANCE;
+		sqlFunctions = new HashMap();
+	}
+
+	private transient Mapping mapping = buildMapping();
+
+
+
+	protected Configuration(SettingsFactory settingsFactory) {
+		this.settingsFactory = settingsFactory;
+		reset();
+	}
+
+	public Configuration() {
+		this( new SettingsFactory() );
+	}
+
+	/**
+	 * Iterate the entity mappings
+	 *
+	 * @return Iterator of the entity mappings currently contained in the configuration.
+	 */
+	public Iterator getClassMappings() {
+		return classes.values().iterator();
+	}
+
+	/**
+	 * Iterate the collection mappings
+	 *
+	 * @return Iterator of the collection mappings currently contained in the configuration.
+	 */
+	public Iterator getCollectionMappings() {
+		return collections.values().iterator();
+	}
+
+	/**
+	 * Iterate the table mappings
+	 *
+	 * @return Iterator of the table mappings currently contained in the configuration.
+	 */
+	public Iterator getTableMappings() {
+		return tables.values().iterator();
+	}
+
+	/**
+	 * Get the mapping for a particular entity
+	 *
+	 * @param entityName An entity name.
+	 * @return the entity mapping information
+	 */
+	public PersistentClass getClassMapping(String entityName) {
+		return (PersistentClass) classes.get( entityName );
+	}
+
+	/**
+	 * Get the mapping for a particular collection role
+	 *
+	 * @param role a collection role
+	 * @return The collection mapping information
+	 */
+	public Collection getCollectionMapping(String role) {
+		return (Collection) collections.get( role );
+	}
+
+	/**
+	 * Set a custom entity resolver. This entity resolver must be
+	 * set before addXXX(misc) call.
+	 * Default value is {@link org.hibernate.util.DTDEntityResolver}
+	 *
+	 * @param entityResolver entity resolver to use
+	 */
+	public void setEntityResolver(EntityResolver entityResolver) {
+		this.entityResolver = entityResolver;
+	}
+
+	public EntityResolver getEntityResolver() {
+		return entityResolver;
+	}
+
+	/**
+	 * Retrieve the user-supplied delegate to handle non-existent entity
+	 * scenarios.  May be null.
+	 *
+	 * @return The user-supplied delegate
+	 */
+	public EntityNotFoundDelegate getEntityNotFoundDelegate() {
+		return entityNotFoundDelegate;
+	}
+
+	/**
+	 * Specify a user-supplied delegate to be used to handle scenarios where an entity could not be
+	 * located by specified id.  This is mainly intended for EJB3 implementations to be able to
+	 * control how proxy initialization errors should be handled...
+	 *
+	 * @param entityNotFoundDelegate The delegate to use
+	 */
+	public void setEntityNotFoundDelegate(EntityNotFoundDelegate entityNotFoundDelegate) {
+		this.entityNotFoundDelegate = entityNotFoundDelegate;
+	}
+
+	/**
+	 * Read mappings from a particular XML file
+	 *
+	 * @param xmlFile a path to a file
+	 * @return this (for method chaining purposes)
+	 * @throws org.hibernate.MappingException Indicates inability to locate or parse
+	 * the specified mapping file.
+	 * @see #addFile(java.io.File)
+	 */
+	public Configuration addFile(String xmlFile) throws MappingException {
+		return addFile( new File( xmlFile ) );
+	}
+
+	/**
+	 * Read mappings from a particular XML file
+	 *
+	 * @param xmlFile a path to a file
+	 * @return this (for method chaining purposes)
+	 * @throws org.hibernate.MappingException Indicates inability to locate or parse
+	 * the specified mapping file.
+	 */
+	public Configuration addFile(File xmlFile) throws MappingException {
+		log.info( "Reading mappings from file: " + xmlFile.getPath() );
+		if ( !xmlFile.exists() ) {
+			throw new MappingNotFoundException( "file", xmlFile.toString() );
+		}
+		try {
+			List errors = new ArrayList();
+			org.dom4j.Document doc = xmlHelper.createSAXReader( xmlFile.toString(), errors, entityResolver ).read( xmlFile );
+			if ( errors.size() != 0 ) {
+				throw new InvalidMappingException( "file", xmlFile.toString(), ( Throwable ) errors.get( 0 ) );
+			}
+			add( doc );
+			return this;
+		}
+		catch ( InvalidMappingException e ) {
+			throw e;
+		}
+		catch  ( MappingNotFoundException e ) {
+			throw e;
+		}
+		catch ( Exception e ) {
+			throw new InvalidMappingException( "file", xmlFile.toString(), e );
+		}
+	}
+
+	/**
+	 * Add a cached mapping file.  A cached file is a serialized representation
+	 * of the DOM structure of a particular mapping.  It is saved from a previous
+	 * call as a file with the name <tt>xmlFile + ".bin"</tt> where xmlFile is
+	 * the name of the original mapping file.
+	 * </p>
+	 * If a cached <tt>xmlFile + ".bin"</tt> exists and is newer than
+	 * <tt>xmlFile</tt> the <tt>".bin"</tt> file will be read directly. Otherwise
+	 * xmlFile is read and then serialized to <tt>xmlFile + ".bin"</tt> for use
+	 * the next time.
+	 *
+	 * @param xmlFile The cacheable mapping file to be added.
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the cached file or processing
+	 * the non-cached file.
+	 */
+	public Configuration addCacheableFile(File xmlFile) throws MappingException {
+		try {
+			File cachedFile = new File( xmlFile.getAbsolutePath() + ".bin" );
+			org.dom4j.Document doc = null;
+
+			final boolean useCachedFile = xmlFile.exists() &&
+					cachedFile.exists() &&
+					xmlFile.lastModified() < cachedFile.lastModified();
+
+			if ( useCachedFile ) {
+				try {
+					log.info( "Reading mappings from cache file: " + cachedFile );
+					doc = ( org.dom4j.Document ) SerializationHelper.deserialize( new FileInputStream( cachedFile ) );
+				}
+				catch ( SerializationException e ) {
+					log.warn( "Could not deserialize cache file: " + cachedFile.getPath(), e );
+				}
+				catch ( FileNotFoundException e ) {
+					log.warn( "I/O reported cached file could not be found : " + cachedFile.getPath(), e );
+				}
+			}
+
+			// if doc is null, then for whatever reason, the cached file cannot be used...
+			if ( doc == null ) {
+				if ( !xmlFile.exists() ) {
+					throw new MappingNotFoundException( "file", xmlFile.toString() );
+				}
+
+				log.info( "Reading mappings from file: " + xmlFile );
+				List errors = new ArrayList();
+				try {
+					doc = xmlHelper.createSAXReader( xmlFile.getAbsolutePath(), errors, entityResolver ).read( xmlFile );
+					if ( errors.size() != 0 ) {
+						throw new MappingException( "invalid mapping", ( Throwable ) errors.get( 0 ) );
+					}
+				}
+				catch( DocumentException e){
+					throw new MappingException( "invalid mapping", e );
+				}
+
+				try {
+					log.debug( "Writing cache file for: " + xmlFile + " to: " + cachedFile );
+					SerializationHelper.serialize( ( Serializable ) doc, new FileOutputStream( cachedFile ) );
+				}
+				catch ( SerializationException e ) {
+					log.warn( "Could not write cached file: " + cachedFile, e );
+				}
+				catch ( FileNotFoundException e ) {
+					log.warn( "I/O reported error writing cached file : " + cachedFile.getPath(), e );
+				}
+			}
+
+			add( doc );
+			return this;
+
+		}
+		catch ( InvalidMappingException e ) {
+			throw e;
+		}
+		catch  ( MappingNotFoundException e ) {
+			throw e;
+		}
+		catch ( Exception e ) {
+			throw new InvalidMappingException( "file", xmlFile.toString(), e );
+		}
+	}
+
+	/**
+	 * Add a cacheable mapping file.
+	 *
+	 * @param xmlFile The name of the file to be added.  This must be in a form
+	 * useable to simply construct a {@link java.io.File} instance.
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the cached file or processing
+	 * the non-cached file.
+	 * @see #addCacheableFile(java.io.File)
+	 */
+	public Configuration addCacheableFile(String xmlFile) throws MappingException {
+		return addCacheableFile( new File( xmlFile ) );
+	}
+
+
+	/**
+	 * Read mappings from a <tt>String</tt>
+	 *
+	 * @param xml an XML string
+	 * @return this (for method chaining purposes)
+	 * @throws org.hibernate.MappingException Indicates problems parsing the
+	 * given XML string
+	 */
+	public Configuration addXML(String xml) throws MappingException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Mapping XML:\n" + xml );
+		}
+		try {
+			List errors = new ArrayList();
+			org.dom4j.Document doc = xmlHelper.createSAXReader( "XML String", errors, entityResolver )
+					.read( new StringReader( xml ) );
+			if ( errors.size() != 0 ) {
+				throw new MappingException( "invalid mapping", (Throwable) errors.get( 0 ) );
+			}
+			add( doc );
+		}
+		catch (DocumentException e) {
+			throw new MappingException( "Could not parse mapping document in XML string", e );
+		}
+		return this;
+	}
+
+	/**
+	 * Read mappings from a <tt>URL</tt>
+	 *
+	 * @param url The url for the mapping document to be read.
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the URL or processing
+	 * the mapping document.
+	 */
+	public Configuration addURL(URL url) throws MappingException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Reading mapping document from URL:" + url.toExternalForm() );
+		}
+		try {
+			addInputStream( url.openStream() );
+		}
+		catch ( InvalidMappingException e ) {
+			throw new InvalidMappingException( "URL", url.toExternalForm(), e.getCause() );
+		}
+		catch (Exception e) {
+			throw new InvalidMappingException( "URL", url.toExternalForm(), e );
+		}
+		return this;
+	}
+
+	/**
+	 * Read mappings from a DOM <tt>Document</tt>
+	 *
+	 * @param doc The DOM document
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the DOM or processing
+	 * the mapping document.
+	 */
+	public Configuration addDocument(Document doc) throws MappingException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Mapping document:\n" + doc );
+		}
+		add( xmlHelper.createDOMReader().read( doc ) );
+		return this;
+	}
+
+	/**
+	 * Read mappings from an {@link java.io.InputStream}.
+	 *
+	 * @param xmlInputStream The input stream containing a DOM.
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the stream, or
+	 * processing the contained mapping document.
+	 */
+	public Configuration addInputStream(InputStream xmlInputStream) throws MappingException {
+		try {
+			List errors = new ArrayList();
+			org.dom4j.Document doc = xmlHelper.createSAXReader( "XML InputStream", errors, entityResolver )
+					.read( new InputSource( xmlInputStream ) );
+			if ( errors.size() != 0 ) {
+				throw new InvalidMappingException( "invalid mapping", null, (Throwable) errors.get( 0 ) );
+			}
+			add( doc );
+			return this;
+		}
+		catch (DocumentException e) {
+			throw new InvalidMappingException( "input stream", null, e );
+		}
+		finally {
+			try {
+				xmlInputStream.close();
+			}
+			catch (IOException ioe) {
+				log.warn( "Could not close input stream", ioe );
+			}
+		}
+	}
+
+	/**
+	 * Read mappings as a application resource (i.e. classpath lookup).
+	 *
+	 * @param resourceName The resource name
+	 * @param classLoader The class loader to use.
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems locating the resource or
+	 * processing the contained mapping document.
+	 */
+	public Configuration addResource(String resourceName, ClassLoader classLoader) throws MappingException {
+		log.info( "Reading mappings from resource: " + resourceName );
+		InputStream rsrc = classLoader.getResourceAsStream( resourceName );
+		if ( rsrc == null ) {
+			throw new MappingNotFoundException( "resource", resourceName );
+		}
+		try {
+			return addInputStream( rsrc );
+		}
+		catch (MappingException me) {
+			throw new InvalidMappingException( "resource", resourceName, me );
+		}
+	}
+
+	/**
+	 * Read mappings as a application resourceName (i.e. classpath lookup)
+	 * trying different classloaders.
+	 *
+	 * @param resourceName The resource name
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems locating the resource or
+	 * processing the contained mapping document.
+	 */
+	public Configuration addResource(String resourceName) throws MappingException {
+		log.info( "Reading mappings from resource : " + resourceName );
+		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+		InputStream rsrc = null;
+		if (contextClassLoader!=null) {
+			rsrc = contextClassLoader.getResourceAsStream( resourceName );
+		}
+		if ( rsrc == null ) {
+			rsrc = Environment.class.getClassLoader().getResourceAsStream( resourceName );
+		}
+		if ( rsrc == null ) {
+			throw new MappingNotFoundException( "resource", resourceName );
+		}
+		try {
+			return addInputStream( rsrc );
+		}
+		catch (MappingException me) {
+			throw new InvalidMappingException( "resource", resourceName, me );
+		}
+	}
+
+	/**
+	 * Read a mapping as an application resouurce using the convention that a class
+	 * named <tt>foo.bar.Foo</tt> is mapped by a file <tt>foo/bar/Foo.hbm.xml</tt>
+	 * which can be resolved as a classpath resource.
+	 *
+	 * @param persistentClass The mapped class
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems locating the resource or
+	 * processing the contained mapping document.
+	 */
+	public Configuration addClass(Class persistentClass) throws MappingException {
+		String mappingResourceName = persistentClass.getName().replace( '.', '/' ) + ".hbm.xml";
+		log.info( "Reading mappings from resource: " + mappingResourceName );
+		return addResource( mappingResourceName, persistentClass.getClassLoader() );
+	}
+
+	/**
+	 * Read all mappings from a jar file
+	 * <p/>
+	 * Assumes that any file named <tt>*.hbm.xml</tt> is a mapping document.
+	 *
+	 * @param jar a jar file
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the jar file or
+	 * processing the contained mapping documents.
+	 */
+	public Configuration addJar(File jar) throws MappingException {
+		log.info( "Searching for mapping documents in jar: " + jar.getName() );
+		JarFile jarFile = null;
+		try {
+			try {
+				jarFile = new JarFile( jar );
+			}
+			catch (IOException ioe) {
+				throw new InvalidMappingException(
+						"Could not read mapping documents from jar: " + jar.getName(), "jar", jar.getName(),
+						ioe
+				);
+			}
+			Enumeration jarEntries = jarFile.entries();
+			while ( jarEntries.hasMoreElements() ) {
+				ZipEntry ze = (ZipEntry) jarEntries.nextElement();
+				if ( ze.getName().endsWith( ".hbm.xml" ) ) {
+					log.info( "Found mapping document in jar: " + ze.getName() );
+					try {
+						addInputStream( jarFile.getInputStream( ze ) );
+					}
+					catch (Exception e) {
+						throw new InvalidMappingException(
+								"Could not read mapping documents from jar: " + jar.getName(),
+								"jar",
+								jar.getName(),
+								e
+						);
+					}
+				}
+			}
+		}
+		finally {
+			try {
+				if ( jarFile != null ) {
+					jarFile.close();
+				}
+			}
+			catch (IOException ioe) {
+				log.error("could not close jar", ioe);
+			}
+		}
+
+		return this;
+	}
+
+	/**
+	 * Read all mapping documents from a directory tree.
+	 * <p/>
+	 * Assumes that any file named <tt>*.hbm.xml</tt> is a mapping document.
+	 *
+	 * @param dir The directory
+	 * @return this (for method chaining purposes)
+	 * @throws MappingException Indicates problems reading the jar file or
+	 * processing the contained mapping documents.
+	 */
+	public Configuration addDirectory(File dir) throws MappingException {
+		File[] files = dir.listFiles();
+		for ( int i = 0; i < files.length ; i++ ) {
+			if ( files[i].isDirectory() ) {
+				addDirectory( files[i] );
+			}
+			else if ( files[i].getName().endsWith( ".hbm.xml" ) ) {
+				addFile( files[i] );
+			}
+		}
+		return this;
+	}
+
+	protected void add(org.dom4j.Document doc) throws MappingException {
+		HbmBinder.bindRoot( doc, createMappings(), CollectionHelper.EMPTY_MAP );
+	}
+
+	/**
+	 * Create a new <tt>Mappings</tt> to add class and collection
+	 * mappings to.
+	 */
+	public Mappings createMappings() {
+		return new Mappings(
+				classes,
+				collections,
+				tables,
+				namedQueries,
+				namedSqlQueries,
+				sqlResultSetMappings,
+				imports,
+				secondPasses,
+				propertyReferences,
+				namingStrategy,
+				typeDefs,
+				filterDefinitions,
+				extendsQueue,
+				auxiliaryDatabaseObjects,
+				tableNameBinding,
+				columnNameBindingPerTable
+			);
+	}
+
+
+	private Iterator iterateGenerators(Dialect dialect) throws MappingException {
+
+		TreeMap generators = new TreeMap();
+		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
+		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
+
+		Iterator iter = classes.values().iterator();
+		while ( iter.hasNext() ) {
+			PersistentClass pc = (PersistentClass) iter.next();
+
+			if ( !pc.isInherited() ) {
+
+				IdentifierGenerator ig = pc.getIdentifier()
+						.createIdentifierGenerator(
+								dialect,
+								defaultCatalog,
+								defaultSchema,
+								(RootClass) pc
+							);
+
+				if ( ig instanceof PersistentIdentifierGenerator ) {
+					generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
+				}
+
+			}
+		}
+
+		iter = collections.values().iterator();
+		while ( iter.hasNext() ) {
+			Collection collection = (Collection) iter.next();
+
+			if ( collection.isIdentified() ) {
+
+				IdentifierGenerator ig = ( (IdentifierCollection) collection ).getIdentifier()
+						.createIdentifierGenerator(
+								dialect,
+								defaultCatalog,
+								defaultSchema,
+								null
+							);
+
+				if ( ig instanceof PersistentIdentifierGenerator ) {
+					generators.put( ( (PersistentIdentifierGenerator) ig ).generatorKey(), ig );
+				}
+
+			}
+		}
+
+		return generators.values().iterator();
+	}
+
+	/**
+	 * Generate DDL for dropping tables
+	 *
+	 * @see org.hibernate.tool.hbm2ddl.SchemaExport
+	 */
+	public String[] generateDropSchemaScript(Dialect dialect) throws HibernateException {
+
+		secondPassCompile();
+
+		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
+		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
+
+		ArrayList script = new ArrayList( 50 );
+
+		// drop them in reverse order in case db needs it done that way...
+		ListIterator itr = auxiliaryDatabaseObjects.listIterator( auxiliaryDatabaseObjects.size() );
+		while ( itr.hasPrevious() ) {
+			AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.previous();
+			if ( object.appliesToDialect( dialect ) ) {
+				script.add( object.sqlDropString( dialect, defaultCatalog, defaultSchema ) );
+			}
+		}
+
+		if ( dialect.dropConstraints() ) {
+			Iterator iter = getTableMappings();
+			while ( iter.hasNext() ) {
+				Table table = (Table) iter.next();
+				if ( table.isPhysicalTable() ) {
+					Iterator subIter = table.getForeignKeyIterator();
+					while ( subIter.hasNext() ) {
+						ForeignKey fk = (ForeignKey) subIter.next();
+						if ( fk.isPhysicalConstraint() ) {
+							script.add(
+									fk.sqlDropString(
+											dialect,
+											defaultCatalog,
+											defaultSchema
+										)
+								);
+						}
+					}
+				}
+			}
+		}
+
+
+		Iterator iter = getTableMappings();
+		while ( iter.hasNext() ) {
+
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+
+				/*Iterator subIter = table.getIndexIterator();
+				while ( subIter.hasNext() ) {
+					Index index = (Index) subIter.next();
+					if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
+						script.add( index.sqlDropString(dialect) );
+					}
+				}*/
+
+				script.add(
+						table.sqlDropString(
+								dialect,
+								defaultCatalog,
+								defaultSchema
+							)
+					);
+
+			}
+
+		}
+
+		iter = iterateGenerators( dialect );
+		while ( iter.hasNext() ) {
+			String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlDropStrings( dialect );
+			for ( int i = 0; i < lines.length ; i++ ) {
+				script.add( lines[i] );
+			}
+		}
+
+		return ArrayHelper.toStringArray( script );
+	}
+
+	/**
+	 * Generate DDL for creating tables
+	 *
+	 * @see org.hibernate.tool.hbm2ddl.SchemaExport
+	 */
+	public String[] generateSchemaCreationScript(Dialect dialect) throws HibernateException {
+		secondPassCompile();
+
+		ArrayList script = new ArrayList( 50 );
+		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
+		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
+
+		Iterator iter = getTableMappings();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+				script.add(
+						table.sqlCreateString(
+								dialect,
+								mapping,
+								defaultCatalog,
+								defaultSchema
+							)
+					);
+				Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
+				while ( comments.hasNext() ) {
+					script.add( comments.next() );
+				}
+			}
+		}
+
+		iter = getTableMappings();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+
+				if ( !dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+					Iterator subIter = table.getUniqueKeyIterator();
+					while ( subIter.hasNext() ) {
+						UniqueKey uk = (UniqueKey) subIter.next();
+						String constraintString = uk.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema );
+						if (constraintString != null) script.add( constraintString );
+					}
+				}
+
+
+				Iterator subIter = table.getIndexIterator();
+				while ( subIter.hasNext() ) {
+					Index index = (Index) subIter.next();
+					script.add(
+							index.sqlCreateString(
+									dialect,
+									mapping,
+									defaultCatalog,
+									defaultSchema
+								)
+						);
+				}
+
+				if ( dialect.hasAlterTable() ) {
+					subIter = table.getForeignKeyIterator();
+					while ( subIter.hasNext() ) {
+						ForeignKey fk = (ForeignKey) subIter.next();
+						if ( fk.isPhysicalConstraint() ) {
+							script.add(
+									fk.sqlCreateString(
+											dialect, mapping,
+											defaultCatalog,
+											defaultSchema
+										)
+								);
+						}
+					}
+				}
+
+			}
+		}
+
+		iter = iterateGenerators( dialect );
+		while ( iter.hasNext() ) {
+			String[] lines = ( (PersistentIdentifierGenerator) iter.next() ).sqlCreateStrings( dialect );
+			for ( int i = 0; i < lines.length ; i++ ) {
+				script.add( lines[i] );
+			}
+		}
+
+		Iterator itr = auxiliaryDatabaseObjects.iterator();
+		while ( itr.hasNext() ) {
+			AuxiliaryDatabaseObject object = (AuxiliaryDatabaseObject) itr.next();
+			if ( object.appliesToDialect( dialect ) ) {
+				script.add( object.sqlCreateString( dialect, mapping, defaultCatalog, defaultSchema ) );
+			}
+		}
+
+		return ArrayHelper.toStringArray( script );
+	}
+
+	/**
+	 * Generate DDL for altering tables
+	 *
+	 * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
+	 */
+	public String[] generateSchemaUpdateScript(Dialect dialect, DatabaseMetadata databaseMetadata)
+			throws HibernateException {
+		secondPassCompile();
+
+		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
+		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
+
+		ArrayList script = new ArrayList( 50 );
+
+		Iterator iter = getTableMappings();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+				
+				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
+						table.getName(),
+						( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
+						( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
+								table.isQuoted()
+
+					);
+				if ( tableInfo == null ) {
+					script.add(
+							table.sqlCreateString(
+									dialect,
+									mapping,
+									defaultCatalog,
+									defaultSchema
+								)
+						);
+				}
+				else {
+					Iterator subiter = table.sqlAlterStrings(
+							dialect,
+							mapping,
+							tableInfo,
+							defaultCatalog,
+							defaultSchema
+						);
+					while ( subiter.hasNext() ) {
+						script.add( subiter.next() );
+					}
+				}
+
+				Iterator comments = table.sqlCommentStrings( dialect, defaultCatalog, defaultSchema );
+				while ( comments.hasNext() ) {
+					script.add( comments.next() );
+				}
+
+			}
+		}
+
+		iter = getTableMappings();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+
+				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
+						table.getName(),
+						table.getSchema(),
+						table.getCatalog(),
+						table.isQuoted()
+					);
+
+				if ( dialect.hasAlterTable() ) {
+					Iterator subIter = table.getForeignKeyIterator();
+					while ( subIter.hasNext() ) {
+						ForeignKey fk = (ForeignKey) subIter.next();
+						if ( fk.isPhysicalConstraint() ) {
+							boolean create = tableInfo == null || (
+									tableInfo.getForeignKeyMetadata( fk.getName() ) == null && (
+											//Icky workaround for MySQL bug:
+											!( dialect instanceof MySQLDialect ) ||
+													tableInfo.getIndexMetadata( fk.getName() ) == null
+										)
+								);
+							if ( create ) {
+								script.add(
+										fk.sqlCreateString(
+												dialect,
+												mapping,
+												defaultCatalog,
+												defaultSchema
+											)
+									);
+							}
+						}
+					}
+				}
+
+			}
+
+			/*//broken, 'cos we don't generate these with names in SchemaExport
+			subIter = table.getIndexIterator();
+			while ( subIter.hasNext() ) {
+				Index index = (Index) subIter.next();
+				if ( !index.isForeignKey() || !dialect.hasImplicitIndexForForeignKey() ) {
+					if ( tableInfo==null || tableInfo.getIndexMetadata( index.getFilterName() ) == null ) {
+						script.add( index.sqlCreateString(dialect, mapping) );
+					}
+				}
+			}
+			//broken, 'cos we don't generate these with names in SchemaExport
+			subIter = table.getUniqueKeyIterator();
+			while ( subIter.hasNext() ) {
+				UniqueKey uk = (UniqueKey) subIter.next();
+				if ( tableInfo==null || tableInfo.getIndexMetadata( uk.getFilterName() ) == null ) {
+					script.add( uk.sqlCreateString(dialect, mapping) );
+				}
+			}*/
+		}
+
+		iter = iterateGenerators( dialect );
+		while ( iter.hasNext() ) {
+			PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
+			Object key = generator.generatorKey();
+			if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
+				String[] lines = generator.sqlCreateStrings( dialect );
+				for ( int i = 0; i < lines.length ; i++ ) {
+					script.add( lines[i] );
+				}
+			}
+		}
+
+		return ArrayHelper.toStringArray( script );
+	}
+
+	public void validateSchema(Dialect dialect, DatabaseMetadata databaseMetadata)
+			throws HibernateException {
+		secondPassCompile();
+
+		String defaultCatalog = properties.getProperty( Environment.DEFAULT_CATALOG );
+		String defaultSchema = properties.getProperty( Environment.DEFAULT_SCHEMA );
+		
+		Iterator iter = getTableMappings();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			if ( table.isPhysicalTable() ) {
+				
+
+				TableMetadata tableInfo = databaseMetadata.getTableMetadata(
+						table.getName(),
+						( table.getSchema() == null ) ? defaultSchema : table.getSchema(),
+						( table.getCatalog() == null ) ? defaultCatalog : table.getCatalog(),
+								table.isQuoted());
+				if ( tableInfo == null ) {
+					throw new HibernateException( "Missing table: " + table.getName() );
+				}
+				else {
+					table.validateColumns( dialect, mapping, tableInfo );
+				}
+
+			}
+		}
+
+		iter = iterateGenerators( dialect );
+		while ( iter.hasNext() ) {
+			PersistentIdentifierGenerator generator = (PersistentIdentifierGenerator) iter.next();
+			Object key = generator.generatorKey();
+			if ( !databaseMetadata.isSequence( key ) && !databaseMetadata.isTable( key ) ) {
+				throw new HibernateException( "Missing sequence or table: " + key );
+			}
+		}
+	}
+
+	private void validate() throws MappingException {
+		Iterator iter = classes.values().iterator();
+		while ( iter.hasNext() ) {
+			( (PersistentClass) iter.next() ).validate( mapping );
+		}
+		iter = collections.values().iterator();
+		while ( iter.hasNext() ) {
+			( (Collection) iter.next() ).validate( mapping );
+		}
+	}
+
+	/**
+	 * Call this to ensure the mappings are fully compiled/built. Usefull to ensure getting
+	 * access to all information in the metamodel when calling e.g. getClassMappings().
+	 */
+	public void buildMappings() {
+		secondPassCompile();
+	}
+
+	// This method may be called many times!!
+	protected void secondPassCompile() throws MappingException {
+		log.debug( "processing extends queue" );
+
+		processExtendsQueue();
+
+		log.debug( "processing collection mappings" );
+
+		Iterator iter = secondPasses.iterator();
+		while ( iter.hasNext() ) {
+			SecondPass sp = (SecondPass) iter.next();
+			if ( ! (sp instanceof QuerySecondPass) ) {
+				sp.doSecondPass( classes );
+				iter.remove();
+			}
+		}
+
+		log.debug( "processing native query and ResultSetMapping mappings" );
+		iter = secondPasses.iterator();
+		while ( iter.hasNext() ) {
+			SecondPass sp = (SecondPass) iter.next();
+			sp.doSecondPass( classes );
+			iter.remove();
+		}
+
+		log.debug( "processing association property references" );
+
+		iter = propertyReferences.iterator();
+		while ( iter.hasNext() ) {
+			Mappings.PropertyReference upr = (Mappings.PropertyReference) iter.next();
+
+			PersistentClass clazz = getClassMapping( upr.referencedClass );
+			if ( clazz == null ) {
+				throw new MappingException(
+						"property-ref to unmapped class: " +
+						upr.referencedClass
+					);
+			}
+
+			Property prop = clazz.getReferencedProperty( upr.propertyName );
+			if ( upr.unique ) {
+				( (SimpleValue) prop.getValue() ).setAlternateUniqueKey( true );
+			}
+		}
+
+		//TODO: Somehow add the newly created foreign keys to the internal collection
+
+		log.debug( "processing foreign key constraints" );
+
+		iter = getTableMappings();
+		Set done = new HashSet();
+		while ( iter.hasNext() ) {
+			secondPassCompileForeignKeys( (Table) iter.next(), done );
+		}
+
+	}
+
+	/**
+	 * Try to empty the extends queue.
+	 */
+	private void processExtendsQueue() {
+		// todo : would love to have this work on a notification basis
+		//    where the successful binding of an entity/subclass would
+		//    emit a notification which the extendsQueue entries could
+		//    react to...
+		org.dom4j.Document document = findPossibleExtends();
+		while ( document != null ) {
+			add( document );
+			document = findPossibleExtends();
+		}
+
+		if ( extendsQueue.size() > 0 ) {
+//			Iterator iterator = extendsQueue.iterator();
+			Iterator iterator = extendsQueue.keySet().iterator();
+			StringBuffer buf = new StringBuffer( "Following superclasses referenced in extends not found: " );
+			while ( iterator.hasNext() ) {
+				final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iterator.next();
+				buf.append( entry.getExplicitName() );
+				if ( entry.getMappingPackage() != null ) {
+					buf.append( "[" ).append( entry.getMappingPackage() ).append( "]" );
+				}
+				if ( iterator.hasNext() ) {
+					buf.append( "," );
+				}
+			}
+			throw new MappingException( buf.toString() );
+		}
+	}
+
+	/**
+	 * Find the first possible element in the queue of extends.
+	 */
+	protected org.dom4j.Document findPossibleExtends() {
+//		Iterator iter = extendsQueue.iterator();
+		Iterator iter = extendsQueue.keySet().iterator();
+		while ( iter.hasNext() ) {
+			final ExtendsQueueEntry entry = ( ExtendsQueueEntry ) iter.next();
+			if ( getClassMapping( entry.getExplicitName() ) != null ) {
+				// found
+				iter.remove();
+				return entry.getDocument();
+			}
+			else if ( getClassMapping( HbmBinder.getClassName( entry.getExplicitName(), entry.getMappingPackage() ) ) != null ) {
+				// found
+				iter.remove();
+				return entry.getDocument();
+			}
+		}
+		return null;
+	}
+
+	protected void secondPassCompileForeignKeys(Table table, Set done) throws MappingException {
+
+		table.createForeignKeys();
+
+		Iterator iter = table.getForeignKeyIterator();
+		while ( iter.hasNext() ) {
+
+			ForeignKey fk = (ForeignKey) iter.next();
+			if ( !done.contains( fk ) ) {
+				done.add( fk );
+				final String referencedEntityName = fk.getReferencedEntityName();
+				if ( referencedEntityName == null ) {
+					throw new MappingException(
+							"An association from the table " +
+							fk.getTable().getName() +
+							" does not specify the referenced entity"
+						);
+				}
+				if ( log.isDebugEnabled() ) {
+					log.debug( "resolving reference to class: " + referencedEntityName );
+				}
+				PersistentClass referencedClass = (PersistentClass) classes.get( referencedEntityName );
+				if ( referencedClass == null ) {
+					throw new MappingException(
+							"An association from the table " +
+							fk.getTable().getName() +
+							" refers to an unmapped class: " +
+							referencedEntityName
+						);
+				}
+				if ( referencedClass.isJoinedSubclass() ) {
+					secondPassCompileForeignKeys( referencedClass.getSuperclass().getTable(), done );
+				}
+				fk.setReferencedTable( referencedClass.getTable() );
+				fk.alignColumns();
+			}
+		}
+	}
+
+	/**
+	 * Get the named queries
+	 */
+	public Map getNamedQueries() {
+		return namedQueries;
+	}
+
+	/**
+	 * Instantiate a new <tt>SessionFactory</tt>, using the properties and
+	 * mappings in this configuration. The <tt>SessionFactory</tt> will be
+	 * immutable, so changes made to the <tt>Configuration</tt> after
+	 * building the <tt>SessionFactory</tt> will not affect it.
+	 *
+	 * @return a new factory for <tt>Session</tt>s
+	 * @see org.hibernate.SessionFactory
+	 */
+	public SessionFactory buildSessionFactory() throws HibernateException {
+		log.debug( "Preparing to build session factory with filters : " + filterDefinitions );
+		secondPassCompile();
+		validate();
+		Environment.verifyProperties( properties );
+		Properties copy = new Properties();
+		copy.putAll( properties );
+		PropertiesHelper.resolvePlaceHolders( copy );
+		Settings settings = buildSettings( copy );
+
+		return new SessionFactoryImpl(
+				this,
+				mapping,
+				settings,
+				getInitializedEventListeners(),
+				sessionFactoryObserver
+			);
+	}
+
+	private EventListeners getInitializedEventListeners() {
+		EventListeners result = (EventListeners) eventListeners.shallowCopy();
+		result.initializeListeners( this );
+		return result;
+	}
+
+	/**
+	 * Return the configured <tt>Interceptor</tt>
+	 */
+	public Interceptor getInterceptor() {
+		return interceptor;
+	}
+
+	/**
+	 * Get all properties
+	 */
+	public Properties getProperties() {
+		return properties;
+	}
+
+	/**
+	 * Configure an <tt>Interceptor</tt>
+	 */
+	public Configuration setInterceptor(Interceptor interceptor) {
+		this.interceptor = interceptor;
+		return this;
+	}
+
+	/**
+	 * Specify a completely new set of properties
+	 */
+	public Configuration setProperties(Properties properties) {
+		this.properties = properties;
+		return this;
+	}
+
+	/**
+	 * Set the given properties
+	 */
+	public Configuration addProperties(Properties extraProperties) {
+		this.properties.putAll( extraProperties );
+		return this;
+	}
+
+	/**
+	 * Adds the incoming properties to the internap properties structure,
+	 * as long as the internal structure does not already contain an
+	 * entry for the given key.
+	 *
+	 * @param properties
+	 * @return this
+	 */
+	public Configuration mergeProperties(Properties properties) {
+		Iterator itr = properties.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			if ( this.properties.containsKey( entry.getKey() ) ) {
+				continue;
+			}
+			this.properties.setProperty( ( String ) entry.getKey(), ( String ) entry.getValue() );
+		}
+		return this;
+	}
+
+	/**
+	 * Set a property
+	 */
+	public Configuration setProperty(String propertyName, String value) {
+		properties.setProperty( propertyName, value );
+		return this;
+	}
+
+	/**
+	 * Get a property
+	 */
+	public String getProperty(String propertyName) {
+		return properties.getProperty( propertyName );
+	}
+
+	private void addProperties(Element parent) {
+		Iterator iter = parent.elementIterator( "property" );
+		while ( iter.hasNext() ) {
+			Element node = (Element) iter.next();
+			String name = node.attributeValue( "name" );
+			String value = node.getText().trim();
+			log.debug( name + "=" + value );
+			properties.setProperty( name, value );
+			if ( !name.startsWith( "hibernate" ) ) {
+				properties.setProperty( "hibernate." + name, value );
+			}
+		}
+		Environment.verifyProperties( properties );
+	}
+
+	/**
+	 * Get the configuration file as an <tt>InputStream</tt>. Might be overridden
+	 * by subclasses to allow the configuration to be located by some arbitrary
+	 * mechanism.
+	 */
+	protected InputStream getConfigurationInputStream(String resource) throws HibernateException {
+
+		log.info( "Configuration resource: " + resource );
+
+		return ConfigHelper.getResourceAsStream( resource );
+
+	}
+
+	/**
+	 * Use the mappings and properties specified in an application
+	 * resource named <tt>hibernate.cfg.xml</tt>.
+	 */
+	public Configuration configure() throws HibernateException {
+		configure( "/hibernate.cfg.xml" );
+		return this;
+	}
+
+	/**
+	 * Use the mappings and properties specified in the given application
+	 * resource. The format of the resource is defined in
+	 * <tt>hibernate-configuration-3.0.dtd</tt>.
+	 * <p/>
+	 * The resource is found via <tt>getConfigurationInputStream(resource)</tt>.
+	 */
+	public Configuration configure(String resource) throws HibernateException {
+		log.info( "configuring from resource: " + resource );
+		InputStream stream = getConfigurationInputStream( resource );
+		return doConfigure( stream, resource );
+	}
+
+	/**
+	 * Use the mappings and properties specified in the given document.
+	 * The format of the document is defined in
+	 * <tt>hibernate-configuration-3.0.dtd</tt>.
+	 *
+	 * @param url URL from which you wish to load the configuration
+	 * @return A configuration configured via the file
+	 * @throws HibernateException
+	 */
+	public Configuration configure(URL url) throws HibernateException {
+		log.info( "configuring from url: " + url.toString() );
+		try {
+			return doConfigure( url.openStream(), url.toString() );
+		}
+		catch (IOException ioe) {
+			throw new HibernateException( "could not configure from URL: " + url, ioe );
+		}
+	}
+
+	/**
+	 * Use the mappings and properties specified in the given application
+	 * file. The format of the file is defined in
+	 * <tt>hibernate-configuration-3.0.dtd</tt>.
+	 *
+	 * @param configFile <tt>File</tt> from which you wish to load the configuration
+	 * @return A configuration configured via the file
+	 * @throws HibernateException
+	 */
+	public Configuration configure(File configFile) throws HibernateException {
+		log.info( "configuring from file: " + configFile.getName() );
+		try {
+			return doConfigure( new FileInputStream( configFile ), configFile.toString() );
+		}
+		catch (FileNotFoundException fnfe) {
+			throw new HibernateException( "could not find file: " + configFile, fnfe );
+		}
+	}
+
+	/**
+	 * Use the mappings and properties specified in the given application
+	 * resource. The format of the resource is defined in
+	 * <tt>hibernate-configuration-3.0.dtd</tt>.
+	 *
+	 * @param stream	   Inputstream to be read from
+	 * @param resourceName The name to use in warning/error messages
+	 * @return A configuration configured via the stream
+	 * @throws HibernateException
+	 */
+	protected Configuration doConfigure(InputStream stream, String resourceName) throws HibernateException {
+
+		org.dom4j.Document doc;
+		try {
+			List errors = new ArrayList();
+			doc = xmlHelper.createSAXReader( resourceName, errors, entityResolver )
+					.read( new InputSource( stream ) );
+			if ( errors.size() != 0 ) {
+				throw new MappingException(
+						"invalid configuration",
+						(Throwable) errors.get( 0 )
+					);
+			}
+		}
+		catch (DocumentException e) {
+			throw new HibernateException(
+					"Could not parse configuration: " + resourceName,
+					e
+				);
+		}
+		finally {
+			try {
+				stream.close();
+			}
+			catch (IOException ioe) {
+				log.warn( "could not close input stream for: " + resourceName, ioe );
+			}
+		}
+
+		return doConfigure( doc );
+
+	}
+
+	/**
+	 * Use the mappings and properties specified in the given XML document.
+	 * The format of the file is defined in
+	 * <tt>hibernate-configuration-3.0.dtd</tt>.
+	 *
+	 * @param document an XML document from which you wish to load the configuration
+	 * @return A configuration configured via the <tt>Document</tt>
+	 * @throws HibernateException if there is problem in accessing the file.
+	 */
+	public Configuration configure(Document document) throws HibernateException {
+		log.info( "configuring from XML document" );
+		return doConfigure( xmlHelper.createDOMReader().read( document ) );
+	}
+
+	protected Configuration doConfigure(org.dom4j.Document doc) throws HibernateException {
+
+		Element sfNode = doc.getRootElement().element( "session-factory" );
+		String name = sfNode.attributeValue( "name" );
+		if ( name != null ) {
+			properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
+		}
+		addProperties( sfNode );
+		parseSessionFactory( sfNode, name );
+
+		Element secNode = doc.getRootElement().element( "security" );
+		if ( secNode != null ) {
+			parseSecurity( secNode );
+		}
+
+		log.info( "Configured SessionFactory: " + name );
+		log.debug( "properties: " + properties );
+
+		return this;
+
+	}
+
+
+	private void parseSessionFactory(Element sfNode, String name) {
+		Iterator elements = sfNode.elementIterator();
+		while ( elements.hasNext() ) {
+			Element subelement = (Element) elements.next();
+			String subelementName = subelement.getName();
+			if ( "mapping".equals( subelementName ) ) {
+				parseMappingElement( subelement, name );
+			}
+			else if ( "class-cache".equals( subelementName ) ) {
+				String className = subelement.attributeValue( "class" );
+				Attribute regionNode = subelement.attribute( "region" );
+				final String region = ( regionNode == null ) ? className : regionNode.getValue();
+				boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) );
+				setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy );
+			}
+			else if ( "collection-cache".equals( subelementName ) ) {
+				String role = subelement.attributeValue( "collection" );
+				Attribute regionNode = subelement.attribute( "region" );
+				final String region = ( regionNode == null ) ? role : regionNode.getValue();
+				setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
+			}
+			else if ( "listener".equals( subelementName ) ) {
+				parseListener( subelement );
+			}
+			else if ( "event".equals( subelementName ) ) {
+				parseEvent( subelement );
+			}
+		}
+	}
+
+	protected void parseMappingElement(Element subelement, String name) {
+		Attribute rsrc = subelement.attribute( "resource" );
+		Attribute file = subelement.attribute( "file" );
+		Attribute jar = subelement.attribute( "jar" );
+		Attribute pkg = subelement.attribute( "package" );
+		Attribute clazz = subelement.attribute( "class" );
+		if ( rsrc != null ) {
+			log.debug( name + "<-" + rsrc );
+			addResource( rsrc.getValue() );
+		}
+		else if ( jar != null ) {
+			log.debug( name + "<-" + jar );
+			addJar( new File( jar.getValue() ) );
+		}
+		else if ( pkg != null ) {
+			throw new MappingException(
+					"An AnnotationConfiguration instance is required to use <mapping package=\"" +
+					pkg.getValue() + "\"/>"
+				);
+		}
+		else if ( clazz != null ) {
+			throw new MappingException(
+					"An AnnotationConfiguration instance is required to use <mapping class=\"" +
+					clazz.getValue() + "\"/>"
+				);
+		}
+		else {
+			if ( file == null ) {
+				throw new MappingException(
+						"<mapping> element in configuration specifies no attributes"
+					);
+			}
+			log.debug( name + "<-" + file );
+			addFile( file.getValue() );
+		}
+	}
+
+	private void parseSecurity(Element secNode) {
+		String contextId = secNode.attributeValue( "context" );
+      setProperty(Environment.JACC_CONTEXTID, contextId);
+		log.info( "JACC contextID: " + contextId );
+		JACCConfiguration jcfg = new JACCConfiguration( contextId );
+		Iterator grantElements = secNode.elementIterator();
+		while ( grantElements.hasNext() ) {
+			Element grantElement = (Element) grantElements.next();
+			String elementName = grantElement.getName();
+			if ( "grant".equals( elementName ) ) {
+				jcfg.addPermission(
+						grantElement.attributeValue( "role" ),
+						grantElement.attributeValue( "entity-name" ),
+						grantElement.attributeValue( "actions" )
+					);
+			}
+		}
+	}
+
+	private void parseEvent(Element element) {
+		String type = element.attributeValue( "type" );
+		List listeners = element.elements();
+		String[] listenerClasses = new String[ listeners.size() ];
+		for ( int i = 0; i < listeners.size() ; i++ ) {
+			listenerClasses[i] = ( (Element) listeners.get( i ) ).attributeValue( "class" );
+		}
+		log.debug( "Event listeners: " + type + "=" + StringHelper.toString( listenerClasses ) );
+		setListeners( type, listenerClasses );
+	}
+
+	private void parseListener(Element element) {
+		String type = element.attributeValue( "type" );
+		if ( type == null ) {
+			throw new MappingException( "No type specified for listener" );
+		}
+		String impl = element.attributeValue( "class" );
+		log.debug( "Event listener: " + type + "=" + impl );
+		setListeners( type, new String[]{impl} );
+	}
+
+	public void setListener(String type, String listener) {
+		String[] listeners = null;
+		if ( listener != null ) {
+			listeners = (String[]) Array.newInstance( String.class, 1 );
+			listeners[0] = listener;
+		}
+		setListeners( type, listeners );
+	}
+
+	public void setListeners(String type, String[] listenerClasses) {
+		Object[] listeners = null;
+		if ( listenerClasses != null ) {
+			listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), listenerClasses.length );
+			for ( int i = 0; i < listeners.length ; i++ ) {
+				try {
+					listeners[i] = ReflectHelper.classForName( listenerClasses[i] ).newInstance();
+				}
+				catch (Exception e) {
+					throw new MappingException(
+							"Unable to instantiate specified event (" + type + ") listener class: " + listenerClasses[i],
+							e
+						);
+				}
+			}
+		}
+		setListeners( type, listeners );
+	}
+
+	public void setListener(String type, Object listener) {
+		Object[] listeners = null;
+		if ( listener != null ) {
+			listeners = (Object[]) Array.newInstance( eventListeners.getListenerClassFor(type), 1 );
+			listeners[0] = listener;
+		}
+		setListeners( type, listeners );
+	}
+
+	public void setListeners(String type, Object[] listeners) {
+		if ( "auto-flush".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setAutoFlushEventListeners( new AutoFlushEventListener[]{} );
+			}
+			else {
+				eventListeners.setAutoFlushEventListeners( (AutoFlushEventListener[]) listeners );
+			}
+		}
+		else if ( "merge".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setMergeEventListeners( new MergeEventListener[]{} );
+			}
+			else {
+				eventListeners.setMergeEventListeners( (MergeEventListener[]) listeners );
+			}
+		}
+		else if ( "create".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPersistEventListeners( new PersistEventListener[]{} );
+			}
+			else {
+				eventListeners.setPersistEventListeners( (PersistEventListener[]) listeners );
+			}
+		}
+		else if ( "create-onflush".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPersistOnFlushEventListeners( new PersistEventListener[]{} );
+			}
+			else {
+				eventListeners.setPersistOnFlushEventListeners( (PersistEventListener[]) listeners );
+			}
+		}
+		else if ( "delete".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setDeleteEventListeners( new DeleteEventListener[]{} );
+			}
+			else {
+				eventListeners.setDeleteEventListeners( (DeleteEventListener[]) listeners );
+			}
+		}
+		else if ( "dirty-check".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setDirtyCheckEventListeners( new DirtyCheckEventListener[]{} );
+			}
+			else {
+				eventListeners.setDirtyCheckEventListeners( (DirtyCheckEventListener[]) listeners );
+			}
+		}
+		else if ( "evict".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setEvictEventListeners( new EvictEventListener[]{} );
+			}
+			else {
+				eventListeners.setEvictEventListeners( (EvictEventListener[]) listeners );
+			}
+		}
+		else if ( "flush".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setFlushEventListeners( new FlushEventListener[]{} );
+			}
+			else {
+				eventListeners.setFlushEventListeners( (FlushEventListener[]) listeners );
+			}
+		}
+		else if ( "flush-entity".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setFlushEntityEventListeners( new FlushEntityEventListener[]{} );
+			}
+			else {
+				eventListeners.setFlushEntityEventListeners( (FlushEntityEventListener[]) listeners );
+			}
+		}
+		else if ( "load".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setLoadEventListeners( new LoadEventListener[]{} );
+			}
+			else {
+				eventListeners.setLoadEventListeners( (LoadEventListener[]) listeners );
+			}
+		}
+		else if ( "load-collection".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setInitializeCollectionEventListeners(
+						new InitializeCollectionEventListener[]{}
+					);
+			}
+			else {
+				eventListeners.setInitializeCollectionEventListeners(
+						(InitializeCollectionEventListener[]) listeners
+					);
+			}
+		}
+		else if ( "lock".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setLockEventListeners( new LockEventListener[]{} );
+			}
+			else {
+				eventListeners.setLockEventListeners( (LockEventListener[]) listeners );
+			}
+		}
+		else if ( "refresh".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setRefreshEventListeners( new RefreshEventListener[]{} );
+			}
+			else {
+				eventListeners.setRefreshEventListeners( (RefreshEventListener[]) listeners );
+			}
+		}
+		else if ( "replicate".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setReplicateEventListeners( new ReplicateEventListener[]{} );
+			}
+			else {
+				eventListeners.setReplicateEventListeners( (ReplicateEventListener[]) listeners );
+			}
+		}
+		else if ( "save-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setSaveOrUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setSaveOrUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "save".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setSaveEventListeners( new SaveOrUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setSaveEventListeners( (SaveOrUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setUpdateEventListeners( new SaveOrUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setUpdateEventListeners( (SaveOrUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-load".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreLoadEventListeners( new PreLoadEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreLoadEventListeners( (PreLoadEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreUpdateEventListeners( new PreUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreUpdateEventListeners( (PreUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-delete".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreDeleteEventListeners( new PreDeleteEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreDeleteEventListeners( (PreDeleteEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-insert".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreInsertEventListeners( new PreInsertEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreInsertEventListeners( (PreInsertEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-collection-recreate".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreCollectionRecreateEventListeners( new PreCollectionRecreateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreCollectionRecreateEventListeners( (PreCollectionRecreateEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-collection-remove".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreCollectionRemoveEventListeners( new PreCollectionRemoveEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreCollectionRemoveEventListeners( ( PreCollectionRemoveEventListener[]) listeners );
+			}
+		}
+		else if ( "pre-collection-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPreCollectionUpdateEventListeners( new PreCollectionUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPreCollectionUpdateEventListeners( ( PreCollectionUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "post-load".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostLoadEventListeners( new PostLoadEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostLoadEventListeners( (PostLoadEventListener[]) listeners );
+			}
+		}
+		else if ( "post-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostUpdateEventListeners( new PostUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostUpdateEventListeners( (PostUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "post-delete".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostDeleteEventListeners( new PostDeleteEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostDeleteEventListeners( (PostDeleteEventListener[]) listeners );
+			}
+		}
+		else if ( "post-insert".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostInsertEventListeners( new PostInsertEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostInsertEventListeners( (PostInsertEventListener[]) listeners );
+			}
+		}
+		else if ( "post-commit-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCommitUpdateEventListeners(
+						new PostUpdateEventListener[]{}
+					);
+			}
+			else {
+				eventListeners.setPostCommitUpdateEventListeners( (PostUpdateEventListener[]) listeners );
+			}
+		}
+		else if ( "post-commit-delete".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCommitDeleteEventListeners(
+						new PostDeleteEventListener[]{}
+					);
+			}
+			else {
+				eventListeners.setPostCommitDeleteEventListeners( (PostDeleteEventListener[]) listeners );
+			}
+		}
+		else if ( "post-commit-insert".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCommitInsertEventListeners(
+						new PostInsertEventListener[]{}
+				);
+			}
+			else {
+				eventListeners.setPostCommitInsertEventListeners( (PostInsertEventListener[]) listeners );
+			}
+		}
+		else if ( "post-collection-recreate".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCollectionRecreateEventListeners( new PostCollectionRecreateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostCollectionRecreateEventListeners( (PostCollectionRecreateEventListener[]) listeners );
+			}
+		}
+		else if ( "post-collection-remove".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCollectionRemoveEventListeners( new PostCollectionRemoveEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostCollectionRemoveEventListeners( ( PostCollectionRemoveEventListener[]) listeners );
+			}
+		}
+		else if ( "post-collection-update".equals( type ) ) {
+			if ( listeners == null ) {
+				eventListeners.setPostCollectionUpdateEventListeners( new PostCollectionUpdateEventListener[]{} );
+			}
+			else {
+				eventListeners.setPostCollectionUpdateEventListeners( ( PostCollectionUpdateEventListener[]) listeners );
+			}
+		}
+		else {
+			throw new MappingException("Unrecognized listener type [" + type + "]");
+		}
+	}
+
+	public EventListeners getEventListeners() {
+		return eventListeners;
+	}
+
+	RootClass getRootClassMapping(String clazz) throws MappingException {
+		try {
+			return (RootClass) getClassMapping( clazz );
+		}
+		catch (ClassCastException cce) {
+			throw new MappingException( "You may only specify a cache for root <class> mappings" );
+		}
+	}
+
+	/**
+	 * Set up a cache for an entity class
+	 *
+	 * @param clazz
+	 * @param concurrencyStrategy
+	 * @return Configuration
+	 * @throws MappingException
+	 */
+	public Configuration setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy)
+			throws MappingException {
+		setCacheConcurrencyStrategy( clazz, concurrencyStrategy, clazz );
+		return this;
+	}
+
+	public void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region)
+			throws MappingException {
+		setCacheConcurrencyStrategy( clazz, concurrencyStrategy, region, true );
+	}
+
+	void setCacheConcurrencyStrategy(String clazz, String concurrencyStrategy, String region, boolean includeLazy)
+			throws MappingException {
+		RootClass rootClass = getRootClassMapping( clazz );
+		if ( rootClass == null ) {
+			throw new MappingException( "Cannot cache an unknown entity: " + clazz );
+		}
+		rootClass.setCacheConcurrencyStrategy( concurrencyStrategy );
+		rootClass.setCacheRegionName( region );
+		rootClass.setLazyPropertiesCacheable( includeLazy );
+	}
+
+	/**
+	 * Set up a cache for a collection role
+	 *
+	 * @param collectionRole
+	 * @param concurrencyStrategy
+	 * @return Configuration
+	 * @throws MappingException
+	 */
+	public Configuration setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy)
+			throws MappingException {
+		setCollectionCacheConcurrencyStrategy( collectionRole, concurrencyStrategy, collectionRole );
+		return this;
+	}
+
+	public void setCollectionCacheConcurrencyStrategy(String collectionRole, String concurrencyStrategy, String region)
+			throws MappingException {
+		Collection collection = getCollectionMapping( collectionRole );
+		if ( collection == null ) {
+			throw new MappingException( "Cannot cache an unknown collection: " + collectionRole );
+		}
+		collection.setCacheConcurrencyStrategy( concurrencyStrategy );
+		collection.setCacheRegionName( region );
+	}
+
+	/**
+	 * Get the query language imports
+	 *
+	 * @return a mapping from "import" names to fully qualified class names
+	 */
+	public Map getImports() {
+		return imports;
+	}
+
+	/**
+	 * Create an object-oriented view of the configuration properties
+	 */
+	public Settings buildSettings() throws HibernateException {
+		Properties clone = ( Properties ) properties.clone();
+		PropertiesHelper.resolvePlaceHolders( clone );
+		return settingsFactory.buildSettings( clone );
+	}
+
+	public Settings buildSettings(Properties props) throws HibernateException {
+		return settingsFactory.buildSettings( props );
+	}
+
+	public Map getNamedSQLQueries() {
+		return namedSqlQueries;
+	}
+
+	public Map getSqlResultSetMappings() {
+		return sqlResultSetMappings;
+	}
+
+	/**
+	 * @return the NamingStrategy.
+	 */
+	public NamingStrategy getNamingStrategy() {
+		return namingStrategy;
+	}
+
+	/**
+	 * Set a custom naming strategy
+	 *
+	 * @param namingStrategy the NamingStrategy to set
+	 */
+	public Configuration setNamingStrategy(NamingStrategy namingStrategy) {
+		this.namingStrategy = namingStrategy;
+		return this;
+	}
+
+	public Mapping buildMapping() {
+		return new Mapping() {
+			/**
+			 * Returns the identifier type of a mapped class
+			 */
+			public Type getIdentifierType(String persistentClass) throws MappingException {
+				PersistentClass pc = ( (PersistentClass) classes.get( persistentClass ) );
+				if ( pc == null ) {
+					throw new MappingException( "persistent class not known: " + persistentClass );
+				}
+				return pc.getIdentifier().getType();
+			}
+
+			public String getIdentifierPropertyName(String persistentClass) throws MappingException {
+				final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
+				if ( pc == null ) {
+					throw new MappingException( "persistent class not known: " + persistentClass );
+				}
+				if ( !pc.hasIdentifierProperty() ) {
+					return null;
+				}
+				return pc.getIdentifierProperty().getName();
+			}
+
+			public Type getReferencedPropertyType(String persistentClass, String propertyName) throws MappingException {
+				final PersistentClass pc = (PersistentClass) classes.get( persistentClass );
+				if ( pc == null ) {
+					throw new MappingException( "persistent class not known: " + persistentClass );
+				}
+				Property prop = pc.getReferencedProperty( propertyName );
+				if ( prop == null ) {
+					throw new MappingException(
+							"property not known: " +
+							persistentClass + '.' + propertyName
+						);
+				}
+				return prop.getType();
+			}
+		};
+	}
+
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		this.mapping = buildMapping();
+		xmlHelper = new XMLHelper();
+	}
+
+	public Map getFilterDefinitions() {
+		return filterDefinitions;
+	}
+
+	public void addFilterDefinition(FilterDefinition definition) {
+		filterDefinitions.put( definition.getFilterName(), definition );
+	}
+
+	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject object) {
+		auxiliaryDatabaseObjects.add( object );
+	}
+
+	public Map getSqlFunctions() {
+		return sqlFunctions;
+	}
+
+	public void addSqlFunction(String functionName, SQLFunction function) {
+		sqlFunctions.put( functionName, function );
+	}
+
+	public SessionFactoryObserver getSessionFactoryObserver() {
+		return sessionFactoryObserver;
+	}
+
+	public void setSessionFactoryObserver(SessionFactoryObserver sessionFactoryObserver) {
+		this.sessionFactoryObserver = sessionFactoryObserver;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,110 +0,0 @@
-//$Id: DefaultNamingStrategy.java 9874 2006-05-04 15:10:22Z epbernard $
-package org.hibernate.cfg;
-
-import java.io.Serializable;
-
-import org.hibernate.util.StringHelper;
-import org.hibernate.AssertionFailure;
-
-/**
- * The default <tt>NamingStrategy</tt>
- * @see ImprovedNamingStrategy a better alternative
- * @author Gavin King
- */
-public class DefaultNamingStrategy implements NamingStrategy, Serializable {
-
-	/**
-	 * The singleton instance
-	 */
-	public static final NamingStrategy INSTANCE = new DefaultNamingStrategy();
-
-	/**
-	 * Return the unqualified class name
-	 */
-	public String classToTableName(String className) {
-		return StringHelper.unqualify(className);
-	}
-	/**
-	 * Return the unqualified property name
-	 */
-	public String propertyToColumnName(String propertyName) {
-		return StringHelper.unqualify(propertyName);
-	}
-	/**
-	 * Return the argument
-	 */
-	public String tableName(String tableName) {
-		return tableName;
-	}
-	/**
-	 * Return the argument
-	 */
-	public String columnName(String columnName) {
-		return columnName;
-	}
-
-	/**
-	 * Return the unqualified property name, not the best strategy but a backward compatible one
-	 */
-	public String collectionTableName(
-			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
-			String propertyName
-	) {
-		//use a degenerated strategy for backward compatibility
-		return StringHelper.unqualify(propertyName);
-	}
-
-	/**
-	 * Return the argument
-	 */
-	public String joinKeyColumnName(String joinedColumn, String joinedTable) {
-		return columnName( joinedColumn );
-	}
-
-	/**
-	 * Return the property name or propertyTableName
-	 */
-	public String foreignKeyColumnName(
-			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
-	) {
-		String header = propertyName != null ? StringHelper.unqualify( propertyName ) : propertyTableName;
-		if (header == null) throw new AssertionFailure("NammingStrategy not properly filled");
-		return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
-	}
-
-	/**
-	 * Return the column name or the unqualified property name
-	 */
-	public String logicalColumnName(String columnName, String propertyName) {
-		return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );
-	}
-
-	/**
-	 * Returns either the table name if explicit or
-	 * if there is an associated table, the concatenation of owner entity table and associated table
-	 * otherwise the concatenation of owner entity table and the unqualified property name
-	 */
-	public String logicalCollectionTableName(String tableName,
-											 String ownerEntityTable, String associatedEntityTable, String propertyName
-	) {
-		if ( tableName != null ) {
-			return tableName;
-		}
-		else {
-			//use of a stringbuffer to workaround a JDK bug
-			return new StringBuffer(ownerEntityTable).append("_")
-					.append(
-						associatedEntityTable != null ?
-						associatedEntityTable :
-						StringHelper.unqualify( propertyName )
-					).toString();
-		}
-	}
-	/**
-	 * Return the column name if explicit or the concatenation of the property name and the referenced column
-	 *
-	 */
-	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) {
-		return StringHelper.isNotEmpty( columnName ) ? columnName : propertyName + "_" + referencedColumn;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,133 @@
+/*
+ * 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.cfg;
+
+import java.io.Serializable;
+
+import org.hibernate.util.StringHelper;
+import org.hibernate.AssertionFailure;
+
+/**
+ * The default <tt>NamingStrategy</tt>
+ * @see ImprovedNamingStrategy a better alternative
+ * @author Gavin King
+ */
+public class DefaultNamingStrategy implements NamingStrategy, Serializable {
+
+	/**
+	 * The singleton instance
+	 */
+	public static final NamingStrategy INSTANCE = new DefaultNamingStrategy();
+
+	/**
+	 * Return the unqualified class name
+	 */
+	public String classToTableName(String className) {
+		return StringHelper.unqualify(className);
+	}
+	/**
+	 * Return the unqualified property name
+	 */
+	public String propertyToColumnName(String propertyName) {
+		return StringHelper.unqualify(propertyName);
+	}
+	/**
+	 * Return the argument
+	 */
+	public String tableName(String tableName) {
+		return tableName;
+	}
+	/**
+	 * Return the argument
+	 */
+	public String columnName(String columnName) {
+		return columnName;
+	}
+
+	/**
+	 * Return the unqualified property name, not the best strategy but a backward compatible one
+	 */
+	public String collectionTableName(
+			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
+			String propertyName
+	) {
+		//use a degenerated strategy for backward compatibility
+		return StringHelper.unqualify(propertyName);
+	}
+
+	/**
+	 * Return the argument
+	 */
+	public String joinKeyColumnName(String joinedColumn, String joinedTable) {
+		return columnName( joinedColumn );
+	}
+
+	/**
+	 * Return the property name or propertyTableName
+	 */
+	public String foreignKeyColumnName(
+			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
+	) {
+		String header = propertyName != null ? StringHelper.unqualify( propertyName ) : propertyTableName;
+		if (header == null) throw new AssertionFailure("NammingStrategy not properly filled");
+		return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
+	}
+
+	/**
+	 * Return the column name or the unqualified property name
+	 */
+	public String logicalColumnName(String columnName, String propertyName) {
+		return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );
+	}
+
+	/**
+	 * Returns either the table name if explicit or
+	 * if there is an associated table, the concatenation of owner entity table and associated table
+	 * otherwise the concatenation of owner entity table and the unqualified property name
+	 */
+	public String logicalCollectionTableName(String tableName,
+											 String ownerEntityTable, String associatedEntityTable, String propertyName
+	) {
+		if ( tableName != null ) {
+			return tableName;
+		}
+		else {
+			//use of a stringbuffer to workaround a JDK bug
+			return new StringBuffer(ownerEntityTable).append("_")
+					.append(
+						associatedEntityTable != null ?
+						associatedEntityTable :
+						StringHelper.unqualify( propertyName )
+					).toString();
+		}
+	}
+	/**
+	 * Return the column name if explicit or the concatenation of the property name and the referenced column
+	 *
+	 */
+	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) {
+		return StringHelper.isNotEmpty( columnName ) ? columnName : propertyName + "_" + referencedColumn;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,702 +0,0 @@
-//$Id: Environment.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.cfg;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.Statement;
-import java.sql.Timestamp;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.bytecode.BytecodeProvider;
-import org.hibernate.util.ConfigHelper;
-import org.hibernate.util.PropertiesHelper;
-
-
-/**
- * Provides access to configuration info passed in <tt>Properties</tt> objects.
- * <br><br>
- * Hibernate has two property scopes:
- * <ul>
- * <li><b>Factory-level</b> properties may be passed to the <tt>SessionFactory</tt> when it
- * instantiated. Each instance might have different property values. If no
- * properties are specified, the factory calls <tt>Environment.getProperties()</tt>.
- * <li><b>System-level</b> properties are shared by all factory instances and are always
- * determined by the <tt>Environment</tt> properties.
- * </ul>
- * The only system-level properties are
- * <ul>
- * <li><tt>hibernate.jdbc.use_streams_for_binary</tt>
- * <li><tt>hibernate.cglib.use_reflection_optimizer</tt>
- * </ul>
- * <tt>Environment</tt> properties are populated by calling <tt>System.getProperties()</tt>
- * and then from a resource named <tt>/hibernate.properties</tt> if it exists. System
- * properties override properties specified in <tt>hibernate.properties</tt>.<br>
- * <br>
- * The <tt>SessionFactory</tt> is controlled by the following properties.
- * Properties may be either be <tt>System</tt> properties, properties
- * defined in a resource named <tt>/hibernate.properties</tt> or an instance of
- * <tt>java.util.Properties</tt> passed to
- * <tt>Configuration.buildSessionFactory()</tt><br>
- * <br>
- * <table>
- * <tr><td><b>property</b></td><td><b>meaning</b></td></tr>
- * <tr>
- *   <td><tt>hibernate.dialect</tt></td>
- *   <td>classname of <tt>org.hibernate.dialect.Dialect</tt> subclass</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.cache.provider_class</tt></td>
- *   <td>classname of <tt>org.hibernate.cache.CacheProvider</tt>
- *   subclass (if not specified EHCache is used)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.connection.provider_class</tt></td>
- *   <td>classname of <tt>org.hibernate.connection.ConnectionProvider</tt>
- *   subclass (if not specified hueristics are used)</td>
- * </tr>
- * <tr><td><tt>hibernate.connection.username</tt></td><td>database username</td></tr>
- * <tr><td><tt>hibernate.connection.password</tt></td><td>database password</td></tr>
- * <tr>
- *   <td><tt>hibernate.connection.url</tt></td>
- *   <td>JDBC URL (when using <tt>java.sql.DriverManager</tt>)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.connection.driver_class</tt></td>
- *   <td>classname of JDBC driver</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.connection.isolation</tt></td>
- *   <td>JDBC transaction isolation level (only when using
- *     <tt>java.sql.DriverManager</tt>)
- *   </td>
- * </tr>
- *   <td><tt>hibernate.connection.pool_size</tt></td>
- *   <td>the maximum size of the connection pool (only when using
- *     <tt>java.sql.DriverManager</tt>)
- *   </td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.connection.datasource</tt></td>
- *   <td>databasource JNDI name (when using <tt>javax.sql.Datasource</tt>)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jndi.url</tt></td><td>JNDI <tt>InitialContext</tt> URL</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jndi.class</tt></td><td>JNDI <tt>InitialContext</tt> classname</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.max_fetch_depth</tt></td>
- *   <td>maximum depth of outer join fetching</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jdbc.batch_size</tt></td>
- *   <td>enable use of JDBC2 batch API for drivers which support it</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jdbc.fetch_size</tt></td>
- *   <td>set the JDBC fetch size</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jdbc.use_scrollable_resultset</tt></td>
- *   <td>enable use of JDBC2 scrollable resultsets (you only need this specify
- *   this property when using user supplied connections)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.jdbc.use_getGeneratedKeys</tt></td>
- *   <td>enable use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve
- *   natively generated keys after insert. Requires JDBC3+ driver and JRE1.4+</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.hbm2ddl.auto</tt></td>
- *   <td>enable auto DDL export</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.default_schema</tt></td>
- *   <td>use given schema name for unqualified tables (always optional)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.default_catalog</tt></td>
- *   <td>use given catalog name for unqualified tables (always optional)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.session_factory_name</tt></td>
- *   <td>If set, the factory attempts to bind this name to itself in the
- *   JNDI context. This name is also used to support cross JVM <tt>
- *   Session</tt> (de)serialization.</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.transaction.manager_lookup_class</tt></td>
- *   <td>classname of <tt>org.hibernate.transaction.TransactionManagerLookup</tt>
- *   implementor</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.transaction.factory_class</tt></td>
- *   <td>the factory to use for instantiating <tt>Transaction</tt>s.
- *   (Defaults to <tt>JDBCTransactionFactory</tt>.)</td>
- * </tr>
- * <tr>
- *   <td><tt>hibernate.query.substitutions</tt></td><td>query language token substitutions</td>
- * </tr>
- * </table>
- *
- * @see org.hibernate.SessionFactory
- * @author Gavin King
- */
-public final class Environment {
-
-	public static final String VERSION = "3.3.0.CR1";
-
-	/**
-	 * <tt>ConnectionProvider</tt> implementor to use when obtaining connections
-	 */
-	public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
-	/**
-	 * JDBC driver class
-	 */
-	public static final String DRIVER ="hibernate.connection.driver_class";
-	/**
-	 * JDBC transaction isolation level
-	 */
-	public static final String ISOLATION ="hibernate.connection.isolation";
-	/**
-	 * JDBC URL
-	 */
-	public static final String URL ="hibernate.connection.url";
-	/**
-	 * JDBC user
-	 */
-	public static final String USER ="hibernate.connection.username";
-	/**
-	 * JDBC password
-	 */
-	public static final String PASS ="hibernate.connection.password";
-	/**
-	 * JDBC autocommit mode
-	 */
-	public static final String AUTOCOMMIT ="hibernate.connection.autocommit";
-	/**
-	 * Maximum number of inactive connections for Hibernate's connection pool
-	 */
-	public static final String POOL_SIZE ="hibernate.connection.pool_size";
-	/**
-	 * <tt>java.sql.Datasource</tt> JNDI name
-	 */
-	public static final String DATASOURCE ="hibernate.connection.datasource";
-	/**
-	 * prefix for arbitrary JDBC connection properties
-	 */
-	public static final String CONNECTION_PREFIX = "hibernate.connection";
-
-	/**
-	 * JNDI initial context class, <tt>Context.INITIAL_CONTEXT_FACTORY</tt>
-	 */
-	public static final String JNDI_CLASS ="hibernate.jndi.class";
-	/**
-	 * JNDI provider URL, <tt>Context.PROVIDER_URL</tt>
-	 */
-	public static final String JNDI_URL ="hibernate.jndi.url";
-	/**
-	 * prefix for arbitrary JNDI <tt>InitialContext</tt> properties
-	 */
-	public static final String JNDI_PREFIX = "hibernate.jndi";
-	/**
-	 * JNDI name to bind to <tt>SessionFactory</tt>
-	 */
-	public static final String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
-
-	/**
-	 * Hibernate SQL <tt>Dialect</tt> class
-	 */
-	public static final String DIALECT ="hibernate.dialect";
-	/**
-	 * A default database schema (owner) name to use for unqualified tablenames
-	 */
-	public static final String DEFAULT_SCHEMA = "hibernate.default_schema";
-	/**
-	 * A default database catalog name to use for unqualified tablenames
-	 */
-	public static final String DEFAULT_CATALOG = "hibernate.default_catalog";
-
-	/**
-	 * Enable logging of generated SQL to the console
-	 */
-	public static final String SHOW_SQL ="hibernate.show_sql";
-	/**
-	 * Enable formatting of SQL logged to the console
-	 */
-	public static final String FORMAT_SQL ="hibernate.format_sql";
-	/**
-	 * Add comments to the generated SQL
-	 */
-	public static final String USE_SQL_COMMENTS ="hibernate.use_sql_comments";
-	/**
-	 * Maximum depth of outer join fetching
-	 */
-	public static final String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth";
-	/**
-	 * The default batch size for batch fetching
-	 */
-	public static final String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size";
-	/**
-	 * Use <tt>java.io</tt> streams to read / write binary data from / to JDBC
-	 */
-	public static final String USE_STREAMS_FOR_BINARY = "hibernate.jdbc.use_streams_for_binary";
-	/**
-	 * Use JDBC scrollable <tt>ResultSet</tt>s. This property is only necessary when there is
-	 * no <tt>ConnectionProvider</tt>, ie. the user is supplying JDBC connections.
-	 */
-	public static final String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset";
-	/**
-	 * Tells the JDBC driver to attempt to retrieve row Id with the JDBC 3.0 PreparedStatement.getGeneratedKeys()
-	 * method. In general, performance will be better if this property is set to true and the underlying
-	 * JDBC driver supports getGeneratedKeys().
-	 */
-	public static final String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys";
-	/**
-	 * Gives the JDBC driver a hint as to the number of rows that should be fetched from the database
-	 * when more rows are needed. If <tt>0</tt>, JDBC driver default settings will be used.
-	 */
-	public static final String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size";
-	/**
-	 * Maximum JDBC batch size. A nonzero value enables batch updates.
-	 */
-	public static final String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size";
-	/**
-	 * Select a custom batcher.
-	 */
-	public static final String BATCH_STRATEGY = "hibernate.jdbc.factory_class";
-	/**
-	 * Should versioned data be included in batching?
-	 */
-	public static final String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data";
-	/**
-	 * An XSLT resource used to generate "custom" XML
-	 */
-	public static final String OUTPUT_STYLESHEET ="hibernate.xml.output_stylesheet";
-
-	/**
-	 * Maximum size of C3P0 connection pool
-	 */
-	public static final String C3P0_MAX_SIZE = "hibernate.c3p0.max_size";
-	/**
-	 * Minimum size of C3P0 connection pool
-	 */
-	public static final String C3P0_MIN_SIZE = "hibernate.c3p0.min_size";
-
-	/**
-	 * Maximum idle time for C3P0 connection pool
-	 */
-	public static final String C3P0_TIMEOUT = "hibernate.c3p0.timeout";
-	/**
-	 * Maximum size of C3P0 statement cache
-	 */
-	public static final String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements";
-	/**
-	 * Number of connections acquired when pool is exhausted
-	 */
-	public static final String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment";
-	/**
-	 * Idle time before a C3P0 pooled connection is validated
-	 */
-	public static final String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period";
-
-	/**
-	 * Proxool/Hibernate property prefix
-	 */
-	public static final String PROXOOL_PREFIX = "hibernate.proxool";
-	/**
-	 * Proxool property to configure the Proxool Provider using an XML (<tt>/path/to/file.xml</tt>)
-	 */
-	public static final String PROXOOL_XML = "hibernate.proxool.xml";
-	/**
-	 * Proxool property to configure the Proxool Provider  using a properties file (<tt>/path/to/proxool.properties</tt>)
-	 */
-	public static final String PROXOOL_PROPERTIES = "hibernate.proxool.properties";
-	/**
-	 * Proxool property to configure the Proxool Provider from an already existing pool (<tt>true</tt> / <tt>false</tt>)
-	 */
-	public static final String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool";
-	/**
-	 * Proxool property with the Proxool pool alias to use
-	 * (Required for <tt>PROXOOL_EXISTING_POOL</tt>, <tt>PROXOOL_PROPERTIES</tt>, or
-	 * <tt>PROXOOL_XML</tt>)
-	 */
-	public static final String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias";
-
-	/**
-	 * Enable automatic session close at end of transaction
-	 */
-	public static final String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session";
-	/**
-	 * Enable automatic flush during the JTA <tt>beforeCompletion()</tt> callback
-	 */
-	public static final String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion";
-	/**
-	 * Specifies how Hibernate should release JDBC connections.
-	 */
-	public static final String RELEASE_CONNECTIONS = "hibernate.connection.release_mode";
-	/**
-	 * Context scoping impl for {@link org.hibernate.SessionFactory#getCurrentSession()} processing.
-	 */
-	public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
-	/**
-	 * <tt>TransactionFactory</tt> implementor to use for creating <tt>Transaction</tt>s
-	 */
-	public static final String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
-	/**
-	 * <tt>TransactionManagerLookup</tt> implementor to use for obtaining the <tt>TransactionManager</tt>
-	 */
-	public static final String TRANSACTION_MANAGER_STRATEGY = "hibernate.transaction.manager_lookup_class";
-	/**
-	 * JNDI name of JTA <tt>UserTransaction</tt> object
-	 */
-	public static final String USER_TRANSACTION = "jta.UserTransaction";
-
-	/**
-	 * The <tt>CacheProvider</tt> implementation class
-	 */
-	public static final String CACHE_PROVIDER = "hibernate.cache.provider_class";
-
-	/**
-	 * The {@link org.hibernate.cache.RegionFactory} implementation class
-	 */
-	public static final String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class";
-
-	/**
-	 * The <tt>CacheProvider</tt> implementation class
-	 */
-	public static final String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
-	/**
-	 * The <tt>CacheProvider</tt> JNDI namespace, if pre-bound to JNDI.
-	 */
-	public static final String CACHE_NAMESPACE = "hibernate.cache.jndi";
-	/**
-	 * Enable the query cache (disabled by default)
-	 */
-	public static final String USE_QUERY_CACHE = "hibernate.cache.use_query_cache";
-	/**
-	 * The <tt>QueryCacheFactory</tt> implementation class.
-	 */
-	public static final String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory";
-	/**
-	 * Enable the second-level cache (enabled by default)
-	 */
-	public static final String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache";
-	/**
-	 * Optimize the cache for mimimal puts instead of minimal gets
-	 */
-	public static final String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts";
-	/**
-	 * The <tt>CacheProvider</tt> region name prefix
-	 */
-	public static final String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix";
-	/**
-	 * Enable use of structured second-level cache entries
-	 */
-	public static final String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries";
-
-	/**
-	 * Enable statistics collection
-	 */
-	public static final String GENERATE_STATISTICS = "hibernate.generate_statistics";
-
-	public static final String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback";
-
-	/**
-	 * Use bytecode libraries optimized property access
-	 */
-	public static final String USE_REFLECTION_OPTIMIZER = "hibernate.bytecode.use_reflection_optimizer";
-
-	/**
-	 * The classname of the HQL query parser factory
-	 */
-	public static final String QUERY_TRANSLATOR = "hibernate.query.factory_class";
-
-	/**
-	 * A comma-seperated list of token substitutions to use when translating a Hibernate
-	 * query to SQL
-	 */
-	public static final String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
-
-	/**
-	 * Should named queries be checked during startup (the default is enabled).
-	 * <p/>
-	 * Mainly intended for test environments.
-	 */
-	public static final String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
-
-	/**
-	 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
-	 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
-	 */
-	public static final String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
-
-	/**
-	 * The {@link org.hibernate.exception.SQLExceptionConverter} to use for converting SQLExceptions
-	 * to Hibernate's JDBCException hierarchy.  The default is to use the configured
-	 * {@link org.hibernate.dialect.Dialect}'s preferred SQLExceptionConverter.
-	 */
-	public static final String SQL_EXCEPTION_CONVERTER = "hibernate.jdbc.sql_exception_converter";
-
-	/**
-	 * Enable wrapping of JDBC result sets in order to speed up column name lookups for
-	 * broken JDBC drivers
-	 */
-	public static final String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
-
-	/**
-	 * Enable ordering of update statements by primary key value
-	 */
-	public static final String ORDER_UPDATES = "hibernate.order_updates";
-
-	/**
-	 * Enable ordering of insert statements for the purpose of more effecient JDBC batching.
-	 */
-	public static final String ORDER_INSERTS = "hibernate.order_inserts";
-
-	/**
-	 * The EntityMode in which set the Session opened from the SessionFactory.
-	 */
-    public static final String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
-
-    /**
-     * The jacc context id of the deployment
-     */
-    public static final String JACC_CONTEXTID = "hibernate.jacc_context_id";
-
-	public static final String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
-
-	public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
-
-	private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
-	private static final boolean ENABLE_BINARY_STREAMS;
-	private static final boolean ENABLE_REFLECTION_OPTIMIZER;
-	private static final boolean JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
-	private static final boolean JVM_HAS_TIMESTAMP_BUG;
-	private static final boolean JVM_HAS_JDK14_TIMESTAMP;
-	private static final boolean JVM_SUPPORTS_GET_GENERATED_KEYS;
-
-	private static final Properties GLOBAL_PROPERTIES;
-	private static final HashMap ISOLATION_LEVELS = new HashMap();
-	private static final Map OBSOLETE_PROPERTIES = new HashMap();
-	private static final Map RENAMED_PROPERTIES = new HashMap();
-
-	private static final Logger log = LoggerFactory.getLogger(Environment.class);
-
-	/**
-	 * Issues warnings to the user when any obsolete property names are used.
-	 */
-	public static void verifyProperties(Properties props) {
-		Iterator iter = props.keySet().iterator();
-		Map propertiesToAdd = new HashMap();
-		while ( iter.hasNext() ) {
-			final Object propertyName = iter.next();
-			Object newPropertyName = OBSOLETE_PROPERTIES.get( propertyName );
-			if ( newPropertyName != null ) {
-				log.warn( "Usage of obsolete property: " + propertyName + " no longer supported, use: " + newPropertyName );
-			}
-			newPropertyName = RENAMED_PROPERTIES.get( propertyName );
-			if ( newPropertyName != null ) {
-				log.warn( "Property [" + propertyName + "] has been renamed to [" + newPropertyName + "]; update your properties appropriately" );
-				if ( ! props.containsKey( newPropertyName ) ) {
-					propertiesToAdd.put( newPropertyName, props.get( propertyName ) );
-				}
-			}
-		}
-		props.putAll(propertiesToAdd);
-	}
-
-	static {
-
-		log.info("Hibernate " + VERSION);
-
-		RENAMED_PROPERTIES.put( "hibernate.cglib.use_reflection_optimizer", USE_REFLECTION_OPTIMIZER );
-
-		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_NONE), "NONE" );
-		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_UNCOMMITTED), "READ_UNCOMMITTED" );
-		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_COMMITTED), "READ_COMMITTED" );
-		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_REPEATABLE_READ), "REPEATABLE_READ" );
-		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_SERIALIZABLE), "SERIALIZABLE" );
-
-		GLOBAL_PROPERTIES = new Properties();
-		//Set USE_REFLECTION_OPTIMIZER to false to fix HHH-227
-		GLOBAL_PROPERTIES.setProperty( USE_REFLECTION_OPTIMIZER, Boolean.FALSE.toString() );
-
-		try {
-			InputStream stream = ConfigHelper.getResourceAsStream("/hibernate.properties");
-			try {
-				GLOBAL_PROPERTIES.load(stream);
-				log.info( "loaded properties from resource hibernate.properties: " + PropertiesHelper.maskOut(GLOBAL_PROPERTIES, PASS) );
-			}
-			catch (Exception e) {
-				log.error("problem loading properties from hibernate.properties");
-			}
-			finally {
-				try{
-					stream.close();
-				}
-				catch (IOException ioe){
-					log.error("could not close stream on hibernate.properties", ioe);
-				}
-			}
-		}
-		catch (HibernateException he) {
-			log.info("hibernate.properties not found");
-		}
-
-		try {
-			GLOBAL_PROPERTIES.putAll( System.getProperties() );
-		}
-		catch (SecurityException se) {
-			log.warn("could not copy system properties, system properties will be ignored");
-		}
-
-		verifyProperties(GLOBAL_PROPERTIES);
-
-		ENABLE_BINARY_STREAMS = PropertiesHelper.getBoolean(USE_STREAMS_FOR_BINARY, GLOBAL_PROPERTIES);
-		ENABLE_REFLECTION_OPTIMIZER = PropertiesHelper.getBoolean(USE_REFLECTION_OPTIMIZER, GLOBAL_PROPERTIES);
-
-		if (ENABLE_BINARY_STREAMS) {
-			log.info("using java.io streams to persist binary types");
-		}
-		if (ENABLE_REFLECTION_OPTIMIZER) {
-			log.info("using bytecode reflection optimizer");
-		}
-		BYTECODE_PROVIDER_INSTANCE = buildBytecodeProvider( GLOBAL_PROPERTIES );
-
-		boolean getGeneratedKeysSupport;
-		try {
-			Statement.class.getMethod("getGeneratedKeys", null);
-			getGeneratedKeysSupport = true;
-		}
-		catch (NoSuchMethodException nsme) {
-			getGeneratedKeysSupport = false;
-		}
-		JVM_SUPPORTS_GET_GENERATED_KEYS = getGeneratedKeysSupport;
-		if (!JVM_SUPPORTS_GET_GENERATED_KEYS) log.info("JVM does not support Statement.getGeneratedKeys()");
-
-		boolean linkedHashSupport;
-		try {
-			Class.forName("java.util.LinkedHashSet");
-			linkedHashSupport = true;
-		}
-		catch (ClassNotFoundException cnfe) {
-			linkedHashSupport = false;
-		}
-		JVM_SUPPORTS_LINKED_HASH_COLLECTIONS = linkedHashSupport;
-		if (!JVM_SUPPORTS_LINKED_HASH_COLLECTIONS) log.info("JVM does not support LinkedHasMap, LinkedHashSet - ordered maps and sets disabled");
-
-		JVM_HAS_TIMESTAMP_BUG = new Timestamp(123456789).getTime() != 123456789;
-		if (JVM_HAS_TIMESTAMP_BUG) log.info("using workaround for JVM bug in java.sql.Timestamp");
-		Timestamp t = new Timestamp(0);
-		t.setNanos(5 * 1000000);
-		JVM_HAS_JDK14_TIMESTAMP = t.getTime() == 5;
-		if (JVM_HAS_JDK14_TIMESTAMP) {
-			log.info("using JDK 1.4 java.sql.Timestamp handling");
-		}
-		else {
-			log.info("using pre JDK 1.4 java.sql.Timestamp handling");
-		}
-	}
-
-	public static BytecodeProvider getBytecodeProvider() {
-		return BYTECODE_PROVIDER_INSTANCE;
-	}
-
-	/**
-	 * Does this JVM have the IBM JDK 1.3.1. The bug is <tt>new Timestamp(x).getTime()!=x</tt>.
-	 */
-	public static boolean jvmHasTimestampBug() {
-		return JVM_HAS_TIMESTAMP_BUG;
-	}
-
-	/**
-	 * Does this JVM handle <tt>Timestamp</tt> in the JDK 1.4 compliant way?
-	 */
-	public static boolean jvmHasJDK14Timestamp() {
-		return JVM_HAS_JDK14_TIMESTAMP;
-	}
-
-	/**
-	 * Does this JVM support <tt>LinkedHashSet</tt>, <tt>LinkedHashMap</tt>.
-	 * @see java.util.LinkedHashSet
-	 * @see java.util.LinkedHashMap
-	 */
-	public static boolean jvmSupportsLinkedHashCollections() {
-		return JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
-	}
-
-	public static boolean jvmSupportsGetGeneratedKeys() {
-		return JVM_SUPPORTS_GET_GENERATED_KEYS;
-	}
-
-	/**
-	 * Should we use streams to bind binary types to JDBC IN parameters.
-	 * Property <tt>hibernate.jdbc.use_streams_for_binary</tt>.
-	 * @see Environment#USE_STREAMS_FOR_BINARY
-	 */
-	public static boolean useStreamsForBinary() {
-		return ENABLE_BINARY_STREAMS;
-	}
-
-	/**
-	 * Should we use CGLIB reflection optimizer.
-	 * Property <tt>hibernate.jdbc.use_refection_optimizer</tt>.
-	 * @see Environment#USE_REFLECTION_OPTIMIZER
-	 */
-	public static boolean useReflectionOptimizer() {
-		return ENABLE_REFLECTION_OPTIMIZER;
-	}
-
-	private Environment() { throw new UnsupportedOperationException(); }
-
-	/**
-	 * Return <tt>System</tt> properties, extended by any properties specified
-	 * in <tt>hibernate.properties</tt>.
-	 * @return Properties
-	 */
-	public static Properties getProperties() {
-		Properties copy = new Properties();
-		copy.putAll(GLOBAL_PROPERTIES);
-		return copy;
-	}
-
-	/**
-	 * Get the name of a JDBC transaction isolation level
-	 *
-	 * @see java.sql.Connection
-	 * @param isolation as defined by <tt>java.sql.Connection</tt>
-	 * @return a human-readable name
-	 */
-	public static String isolationLevelToString(int isolation) {
-		return (String) ISOLATION_LEVELS.get( new Integer(isolation) );
-	}
-
-	public static BytecodeProvider buildBytecodeProvider(Properties properties) {
-		String provider = PropertiesHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
-		log.info( "Bytecode provider name : " + provider );
-		return buildBytecodeProvider( provider );
-	}
-
-	private static BytecodeProvider buildBytecodeProvider(String providerName) {
-		if ( "javassist".equals( providerName ) ) {
-			return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
-		}
-		else if ( "cglib".equals( providerName ) ) {
-			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
-		}
-
-		log.warn( "unrecognized bytecode provider [" + providerName + "], using javassist by default" );
-		return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java (from rev 15001, core/trunk/core/src/main/java/org/hibernate/cfg/Environment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Environment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,725 @@
+/*
+ * 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.cfg;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.Timestamp;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.bytecode.BytecodeProvider;
+import org.hibernate.util.ConfigHelper;
+import org.hibernate.util.PropertiesHelper;
+
+
+/**
+ * Provides access to configuration info passed in <tt>Properties</tt> objects.
+ * <br><br>
+ * Hibernate has two property scopes:
+ * <ul>
+ * <li><b>Factory-level</b> properties may be passed to the <tt>SessionFactory</tt> when it
+ * instantiated. Each instance might have different property values. If no
+ * properties are specified, the factory calls <tt>Environment.getProperties()</tt>.
+ * <li><b>System-level</b> properties are shared by all factory instances and are always
+ * determined by the <tt>Environment</tt> properties.
+ * </ul>
+ * The only system-level properties are
+ * <ul>
+ * <li><tt>hibernate.jdbc.use_streams_for_binary</tt>
+ * <li><tt>hibernate.cglib.use_reflection_optimizer</tt>
+ * </ul>
+ * <tt>Environment</tt> properties are populated by calling <tt>System.getProperties()</tt>
+ * and then from a resource named <tt>/hibernate.properties</tt> if it exists. System
+ * properties override properties specified in <tt>hibernate.properties</tt>.<br>
+ * <br>
+ * The <tt>SessionFactory</tt> is controlled by the following properties.
+ * Properties may be either be <tt>System</tt> properties, properties
+ * defined in a resource named <tt>/hibernate.properties</tt> or an instance of
+ * <tt>java.util.Properties</tt> passed to
+ * <tt>Configuration.buildSessionFactory()</tt><br>
+ * <br>
+ * <table>
+ * <tr><td><b>property</b></td><td><b>meaning</b></td></tr>
+ * <tr>
+ *   <td><tt>hibernate.dialect</tt></td>
+ *   <td>classname of <tt>org.hibernate.dialect.Dialect</tt> subclass</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.cache.provider_class</tt></td>
+ *   <td>classname of <tt>org.hibernate.cache.CacheProvider</tt>
+ *   subclass (if not specified EHCache is used)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.connection.provider_class</tt></td>
+ *   <td>classname of <tt>org.hibernate.connection.ConnectionProvider</tt>
+ *   subclass (if not specified hueristics are used)</td>
+ * </tr>
+ * <tr><td><tt>hibernate.connection.username</tt></td><td>database username</td></tr>
+ * <tr><td><tt>hibernate.connection.password</tt></td><td>database password</td></tr>
+ * <tr>
+ *   <td><tt>hibernate.connection.url</tt></td>
+ *   <td>JDBC URL (when using <tt>java.sql.DriverManager</tt>)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.connection.driver_class</tt></td>
+ *   <td>classname of JDBC driver</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.connection.isolation</tt></td>
+ *   <td>JDBC transaction isolation level (only when using
+ *     <tt>java.sql.DriverManager</tt>)
+ *   </td>
+ * </tr>
+ *   <td><tt>hibernate.connection.pool_size</tt></td>
+ *   <td>the maximum size of the connection pool (only when using
+ *     <tt>java.sql.DriverManager</tt>)
+ *   </td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.connection.datasource</tt></td>
+ *   <td>databasource JNDI name (when using <tt>javax.sql.Datasource</tt>)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jndi.url</tt></td><td>JNDI <tt>InitialContext</tt> URL</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jndi.class</tt></td><td>JNDI <tt>InitialContext</tt> classname</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.max_fetch_depth</tt></td>
+ *   <td>maximum depth of outer join fetching</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jdbc.batch_size</tt></td>
+ *   <td>enable use of JDBC2 batch API for drivers which support it</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jdbc.fetch_size</tt></td>
+ *   <td>set the JDBC fetch size</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jdbc.use_scrollable_resultset</tt></td>
+ *   <td>enable use of JDBC2 scrollable resultsets (you only need this specify
+ *   this property when using user supplied connections)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.jdbc.use_getGeneratedKeys</tt></td>
+ *   <td>enable use of JDBC3 PreparedStatement.getGeneratedKeys() to retrieve
+ *   natively generated keys after insert. Requires JDBC3+ driver and JRE1.4+</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.hbm2ddl.auto</tt></td>
+ *   <td>enable auto DDL export</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.default_schema</tt></td>
+ *   <td>use given schema name for unqualified tables (always optional)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.default_catalog</tt></td>
+ *   <td>use given catalog name for unqualified tables (always optional)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.session_factory_name</tt></td>
+ *   <td>If set, the factory attempts to bind this name to itself in the
+ *   JNDI context. This name is also used to support cross JVM <tt>
+ *   Session</tt> (de)serialization.</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.transaction.manager_lookup_class</tt></td>
+ *   <td>classname of <tt>org.hibernate.transaction.TransactionManagerLookup</tt>
+ *   implementor</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.transaction.factory_class</tt></td>
+ *   <td>the factory to use for instantiating <tt>Transaction</tt>s.
+ *   (Defaults to <tt>JDBCTransactionFactory</tt>.)</td>
+ * </tr>
+ * <tr>
+ *   <td><tt>hibernate.query.substitutions</tt></td><td>query language token substitutions</td>
+ * </tr>
+ * </table>
+ *
+ * @see org.hibernate.SessionFactory
+ * @author Gavin King
+ */
+public final class Environment {
+
+	public static final String VERSION = "3.3.0.CR2";
+
+	/**
+	 * <tt>ConnectionProvider</tt> implementor to use when obtaining connections
+	 */
+	public static final String CONNECTION_PROVIDER ="hibernate.connection.provider_class";
+	/**
+	 * JDBC driver class
+	 */
+	public static final String DRIVER ="hibernate.connection.driver_class";
+	/**
+	 * JDBC transaction isolation level
+	 */
+	public static final String ISOLATION ="hibernate.connection.isolation";
+	/**
+	 * JDBC URL
+	 */
+	public static final String URL ="hibernate.connection.url";
+	/**
+	 * JDBC user
+	 */
+	public static final String USER ="hibernate.connection.username";
+	/**
+	 * JDBC password
+	 */
+	public static final String PASS ="hibernate.connection.password";
+	/**
+	 * JDBC autocommit mode
+	 */
+	public static final String AUTOCOMMIT ="hibernate.connection.autocommit";
+	/**
+	 * Maximum number of inactive connections for Hibernate's connection pool
+	 */
+	public static final String POOL_SIZE ="hibernate.connection.pool_size";
+	/**
+	 * <tt>java.sql.Datasource</tt> JNDI name
+	 */
+	public static final String DATASOURCE ="hibernate.connection.datasource";
+	/**
+	 * prefix for arbitrary JDBC connection properties
+	 */
+	public static final String CONNECTION_PREFIX = "hibernate.connection";
+
+	/**
+	 * JNDI initial context class, <tt>Context.INITIAL_CONTEXT_FACTORY</tt>
+	 */
+	public static final String JNDI_CLASS ="hibernate.jndi.class";
+	/**
+	 * JNDI provider URL, <tt>Context.PROVIDER_URL</tt>
+	 */
+	public static final String JNDI_URL ="hibernate.jndi.url";
+	/**
+	 * prefix for arbitrary JNDI <tt>InitialContext</tt> properties
+	 */
+	public static final String JNDI_PREFIX = "hibernate.jndi";
+	/**
+	 * JNDI name to bind to <tt>SessionFactory</tt>
+	 */
+	public static final String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
+
+	/**
+	 * Hibernate SQL <tt>Dialect</tt> class
+	 */
+	public static final String DIALECT ="hibernate.dialect";
+	/**
+	 * A default database schema (owner) name to use for unqualified tablenames
+	 */
+	public static final String DEFAULT_SCHEMA = "hibernate.default_schema";
+	/**
+	 * A default database catalog name to use for unqualified tablenames
+	 */
+	public static final String DEFAULT_CATALOG = "hibernate.default_catalog";
+
+	/**
+	 * Enable logging of generated SQL to the console
+	 */
+	public static final String SHOW_SQL ="hibernate.show_sql";
+	/**
+	 * Enable formatting of SQL logged to the console
+	 */
+	public static final String FORMAT_SQL ="hibernate.format_sql";
+	/**
+	 * Add comments to the generated SQL
+	 */
+	public static final String USE_SQL_COMMENTS ="hibernate.use_sql_comments";
+	/**
+	 * Maximum depth of outer join fetching
+	 */
+	public static final String MAX_FETCH_DEPTH = "hibernate.max_fetch_depth";
+	/**
+	 * The default batch size for batch fetching
+	 */
+	public static final String DEFAULT_BATCH_FETCH_SIZE = "hibernate.default_batch_fetch_size";
+	/**
+	 * Use <tt>java.io</tt> streams to read / write binary data from / to JDBC
+	 */
+	public static final String USE_STREAMS_FOR_BINARY = "hibernate.jdbc.use_streams_for_binary";
+	/**
+	 * Use JDBC scrollable <tt>ResultSet</tt>s. This property is only necessary when there is
+	 * no <tt>ConnectionProvider</tt>, ie. the user is supplying JDBC connections.
+	 */
+	public static final String USE_SCROLLABLE_RESULTSET = "hibernate.jdbc.use_scrollable_resultset";
+	/**
+	 * Tells the JDBC driver to attempt to retrieve row Id with the JDBC 3.0 PreparedStatement.getGeneratedKeys()
+	 * method. In general, performance will be better if this property is set to true and the underlying
+	 * JDBC driver supports getGeneratedKeys().
+	 */
+	public static final String USE_GET_GENERATED_KEYS = "hibernate.jdbc.use_get_generated_keys";
+	/**
+	 * Gives the JDBC driver a hint as to the number of rows that should be fetched from the database
+	 * when more rows are needed. If <tt>0</tt>, JDBC driver default settings will be used.
+	 */
+	public static final String STATEMENT_FETCH_SIZE = "hibernate.jdbc.fetch_size";
+	/**
+	 * Maximum JDBC batch size. A nonzero value enables batch updates.
+	 */
+	public static final String STATEMENT_BATCH_SIZE = "hibernate.jdbc.batch_size";
+	/**
+	 * Select a custom batcher.
+	 */
+	public static final String BATCH_STRATEGY = "hibernate.jdbc.factory_class";
+	/**
+	 * Should versioned data be included in batching?
+	 */
+	public static final String BATCH_VERSIONED_DATA = "hibernate.jdbc.batch_versioned_data";
+	/**
+	 * An XSLT resource used to generate "custom" XML
+	 */
+	public static final String OUTPUT_STYLESHEET ="hibernate.xml.output_stylesheet";
+
+	/**
+	 * Maximum size of C3P0 connection pool
+	 */
+	public static final String C3P0_MAX_SIZE = "hibernate.c3p0.max_size";
+	/**
+	 * Minimum size of C3P0 connection pool
+	 */
+	public static final String C3P0_MIN_SIZE = "hibernate.c3p0.min_size";
+
+	/**
+	 * Maximum idle time for C3P0 connection pool
+	 */
+	public static final String C3P0_TIMEOUT = "hibernate.c3p0.timeout";
+	/**
+	 * Maximum size of C3P0 statement cache
+	 */
+	public static final String C3P0_MAX_STATEMENTS = "hibernate.c3p0.max_statements";
+	/**
+	 * Number of connections acquired when pool is exhausted
+	 */
+	public static final String C3P0_ACQUIRE_INCREMENT = "hibernate.c3p0.acquire_increment";
+	/**
+	 * Idle time before a C3P0 pooled connection is validated
+	 */
+	public static final String C3P0_IDLE_TEST_PERIOD = "hibernate.c3p0.idle_test_period";
+
+	/**
+	 * Proxool/Hibernate property prefix
+	 */
+	public static final String PROXOOL_PREFIX = "hibernate.proxool";
+	/**
+	 * Proxool property to configure the Proxool Provider using an XML (<tt>/path/to/file.xml</tt>)
+	 */
+	public static final String PROXOOL_XML = "hibernate.proxool.xml";
+	/**
+	 * Proxool property to configure the Proxool Provider  using a properties file (<tt>/path/to/proxool.properties</tt>)
+	 */
+	public static final String PROXOOL_PROPERTIES = "hibernate.proxool.properties";
+	/**
+	 * Proxool property to configure the Proxool Provider from an already existing pool (<tt>true</tt> / <tt>false</tt>)
+	 */
+	public static final String PROXOOL_EXISTING_POOL = "hibernate.proxool.existing_pool";
+	/**
+	 * Proxool property with the Proxool pool alias to use
+	 * (Required for <tt>PROXOOL_EXISTING_POOL</tt>, <tt>PROXOOL_PROPERTIES</tt>, or
+	 * <tt>PROXOOL_XML</tt>)
+	 */
+	public static final String PROXOOL_POOL_ALIAS = "hibernate.proxool.pool_alias";
+
+	/**
+	 * Enable automatic session close at end of transaction
+	 */
+	public static final String AUTO_CLOSE_SESSION = "hibernate.transaction.auto_close_session";
+	/**
+	 * Enable automatic flush during the JTA <tt>beforeCompletion()</tt> callback
+	 */
+	public static final String FLUSH_BEFORE_COMPLETION = "hibernate.transaction.flush_before_completion";
+	/**
+	 * Specifies how Hibernate should release JDBC connections.
+	 */
+	public static final String RELEASE_CONNECTIONS = "hibernate.connection.release_mode";
+	/**
+	 * Context scoping impl for {@link org.hibernate.SessionFactory#getCurrentSession()} processing.
+	 */
+	public static final String CURRENT_SESSION_CONTEXT_CLASS = "hibernate.current_session_context_class";
+	/**
+	 * <tt>TransactionFactory</tt> implementor to use for creating <tt>Transaction</tt>s
+	 */
+	public static final String TRANSACTION_STRATEGY = "hibernate.transaction.factory_class";
+	/**
+	 * <tt>TransactionManagerLookup</tt> implementor to use for obtaining the <tt>TransactionManager</tt>
+	 */
+	public static final String TRANSACTION_MANAGER_STRATEGY = "hibernate.transaction.manager_lookup_class";
+	/**
+	 * JNDI name of JTA <tt>UserTransaction</tt> object
+	 */
+	public static final String USER_TRANSACTION = "jta.UserTransaction";
+
+	/**
+	 * The <tt>CacheProvider</tt> implementation class
+	 */
+	public static final String CACHE_PROVIDER = "hibernate.cache.provider_class";
+
+	/**
+	 * The {@link org.hibernate.cache.RegionFactory} implementation class
+	 */
+	public static final String CACHE_REGION_FACTORY = "hibernate.cache.region.factory_class";
+
+	/**
+	 * The <tt>CacheProvider</tt> implementation class
+	 */
+	public static final String CACHE_PROVIDER_CONFIG = "hibernate.cache.provider_configuration_file_resource_path";
+	/**
+	 * The <tt>CacheProvider</tt> JNDI namespace, if pre-bound to JNDI.
+	 */
+	public static final String CACHE_NAMESPACE = "hibernate.cache.jndi";
+	/**
+	 * Enable the query cache (disabled by default)
+	 */
+	public static final String USE_QUERY_CACHE = "hibernate.cache.use_query_cache";
+	/**
+	 * The <tt>QueryCacheFactory</tt> implementation class.
+	 */
+	public static final String QUERY_CACHE_FACTORY = "hibernate.cache.query_cache_factory";
+	/**
+	 * Enable the second-level cache (enabled by default)
+	 */
+	public static final String USE_SECOND_LEVEL_CACHE = "hibernate.cache.use_second_level_cache";
+	/**
+	 * Optimize the cache for mimimal puts instead of minimal gets
+	 */
+	public static final String USE_MINIMAL_PUTS = "hibernate.cache.use_minimal_puts";
+	/**
+	 * The <tt>CacheProvider</tt> region name prefix
+	 */
+	public static final String CACHE_REGION_PREFIX = "hibernate.cache.region_prefix";
+	/**
+	 * Enable use of structured second-level cache entries
+	 */
+	public static final String USE_STRUCTURED_CACHE = "hibernate.cache.use_structured_entries";
+
+	/**
+	 * Enable statistics collection
+	 */
+	public static final String GENERATE_STATISTICS = "hibernate.generate_statistics";
+
+	public static final String USE_IDENTIFIER_ROLLBACK = "hibernate.use_identifier_rollback";
+
+	/**
+	 * Use bytecode libraries optimized property access
+	 */
+	public static final String USE_REFLECTION_OPTIMIZER = "hibernate.bytecode.use_reflection_optimizer";
+
+	/**
+	 * The classname of the HQL query parser factory
+	 */
+	public static final String QUERY_TRANSLATOR = "hibernate.query.factory_class";
+
+	/**
+	 * A comma-seperated list of token substitutions to use when translating a Hibernate
+	 * query to SQL
+	 */
+	public static final String QUERY_SUBSTITUTIONS = "hibernate.query.substitutions";
+
+	/**
+	 * Should named queries be checked during startup (the default is enabled).
+	 * <p/>
+	 * Mainly intended for test environments.
+	 */
+	public static final String QUERY_STARTUP_CHECKING = "hibernate.query.startup_check";
+
+	/**
+	 * Auto export/update schema using hbm2ddl tool. Valid values are <tt>update</tt>,
+	 * <tt>create</tt>, <tt>create-drop</tt> and <tt>validate</tt>.
+	 */
+	public static final String HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
+
+	/**
+	 * The {@link org.hibernate.exception.SQLExceptionConverter} to use for converting SQLExceptions
+	 * to Hibernate's JDBCException hierarchy.  The default is to use the configured
+	 * {@link org.hibernate.dialect.Dialect}'s preferred SQLExceptionConverter.
+	 */
+	public static final String SQL_EXCEPTION_CONVERTER = "hibernate.jdbc.sql_exception_converter";
+
+	/**
+	 * Enable wrapping of JDBC result sets in order to speed up column name lookups for
+	 * broken JDBC drivers
+	 */
+	public static final String WRAP_RESULT_SETS = "hibernate.jdbc.wrap_result_sets";
+
+	/**
+	 * Enable ordering of update statements by primary key value
+	 */
+	public static final String ORDER_UPDATES = "hibernate.order_updates";
+
+	/**
+	 * Enable ordering of insert statements for the purpose of more effecient JDBC batching.
+	 */
+	public static final String ORDER_INSERTS = "hibernate.order_inserts";
+
+	/**
+	 * The EntityMode in which set the Session opened from the SessionFactory.
+	 */
+    public static final String DEFAULT_ENTITY_MODE = "hibernate.default_entity_mode";
+
+    /**
+     * The jacc context id of the deployment
+     */
+    public static final String JACC_CONTEXTID = "hibernate.jacc_context_id";
+
+	public static final String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
+
+	public static final String JPAQL_STRICT_COMPLIANCE= "hibernate.query.jpaql_strict_compliance";
+
+	private static final BytecodeProvider BYTECODE_PROVIDER_INSTANCE;
+	private static final boolean ENABLE_BINARY_STREAMS;
+	private static final boolean ENABLE_REFLECTION_OPTIMIZER;
+	private static final boolean JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
+	private static final boolean JVM_HAS_TIMESTAMP_BUG;
+	private static final boolean JVM_HAS_JDK14_TIMESTAMP;
+	private static final boolean JVM_SUPPORTS_GET_GENERATED_KEYS;
+
+	private static final Properties GLOBAL_PROPERTIES;
+	private static final HashMap ISOLATION_LEVELS = new HashMap();
+	private static final Map OBSOLETE_PROPERTIES = new HashMap();
+	private static final Map RENAMED_PROPERTIES = new HashMap();
+
+	private static final Logger log = LoggerFactory.getLogger(Environment.class);
+
+	/**
+	 * Issues warnings to the user when any obsolete property names are used.
+	 */
+	public static void verifyProperties(Properties props) {
+		Iterator iter = props.keySet().iterator();
+		Map propertiesToAdd = new HashMap();
+		while ( iter.hasNext() ) {
+			final Object propertyName = iter.next();
+			Object newPropertyName = OBSOLETE_PROPERTIES.get( propertyName );
+			if ( newPropertyName != null ) {
+				log.warn( "Usage of obsolete property: " + propertyName + " no longer supported, use: " + newPropertyName );
+			}
+			newPropertyName = RENAMED_PROPERTIES.get( propertyName );
+			if ( newPropertyName != null ) {
+				log.warn( "Property [" + propertyName + "] has been renamed to [" + newPropertyName + "]; update your properties appropriately" );
+				if ( ! props.containsKey( newPropertyName ) ) {
+					propertiesToAdd.put( newPropertyName, props.get( propertyName ) );
+				}
+			}
+		}
+		props.putAll(propertiesToAdd);
+	}
+
+	static {
+
+		log.info("Hibernate " + VERSION);
+
+		RENAMED_PROPERTIES.put( "hibernate.cglib.use_reflection_optimizer", USE_REFLECTION_OPTIMIZER );
+
+		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_NONE), "NONE" );
+		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_UNCOMMITTED), "READ_UNCOMMITTED" );
+		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_READ_COMMITTED), "READ_COMMITTED" );
+		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_REPEATABLE_READ), "REPEATABLE_READ" );
+		ISOLATION_LEVELS.put( new Integer(Connection.TRANSACTION_SERIALIZABLE), "SERIALIZABLE" );
+
+		GLOBAL_PROPERTIES = new Properties();
+		//Set USE_REFLECTION_OPTIMIZER to false to fix HHH-227
+		GLOBAL_PROPERTIES.setProperty( USE_REFLECTION_OPTIMIZER, Boolean.FALSE.toString() );
+
+		try {
+			InputStream stream = ConfigHelper.getResourceAsStream("/hibernate.properties");
+			try {
+				GLOBAL_PROPERTIES.load(stream);
+				log.info( "loaded properties from resource hibernate.properties: " + PropertiesHelper.maskOut(GLOBAL_PROPERTIES, PASS) );
+			}
+			catch (Exception e) {
+				log.error("problem loading properties from hibernate.properties");
+			}
+			finally {
+				try{
+					stream.close();
+				}
+				catch (IOException ioe){
+					log.error("could not close stream on hibernate.properties", ioe);
+				}
+			}
+		}
+		catch (HibernateException he) {
+			log.info("hibernate.properties not found");
+		}
+
+		try {
+			GLOBAL_PROPERTIES.putAll( System.getProperties() );
+		}
+		catch (SecurityException se) {
+			log.warn("could not copy system properties, system properties will be ignored");
+		}
+
+		verifyProperties(GLOBAL_PROPERTIES);
+
+		ENABLE_BINARY_STREAMS = PropertiesHelper.getBoolean(USE_STREAMS_FOR_BINARY, GLOBAL_PROPERTIES);
+		ENABLE_REFLECTION_OPTIMIZER = PropertiesHelper.getBoolean(USE_REFLECTION_OPTIMIZER, GLOBAL_PROPERTIES);
+
+		if (ENABLE_BINARY_STREAMS) {
+			log.info("using java.io streams to persist binary types");
+		}
+		if (ENABLE_REFLECTION_OPTIMIZER) {
+			log.info("using bytecode reflection optimizer");
+		}
+		BYTECODE_PROVIDER_INSTANCE = buildBytecodeProvider( GLOBAL_PROPERTIES );
+
+		boolean getGeneratedKeysSupport;
+		try {
+			Statement.class.getMethod("getGeneratedKeys", null);
+			getGeneratedKeysSupport = true;
+		}
+		catch (NoSuchMethodException nsme) {
+			getGeneratedKeysSupport = false;
+		}
+		JVM_SUPPORTS_GET_GENERATED_KEYS = getGeneratedKeysSupport;
+		if (!JVM_SUPPORTS_GET_GENERATED_KEYS) log.info("JVM does not support Statement.getGeneratedKeys()");
+
+		boolean linkedHashSupport;
+		try {
+			Class.forName("java.util.LinkedHashSet");
+			linkedHashSupport = true;
+		}
+		catch (ClassNotFoundException cnfe) {
+			linkedHashSupport = false;
+		}
+		JVM_SUPPORTS_LINKED_HASH_COLLECTIONS = linkedHashSupport;
+		if (!JVM_SUPPORTS_LINKED_HASH_COLLECTIONS) log.info("JVM does not support LinkedHasMap, LinkedHashSet - ordered maps and sets disabled");
+
+		JVM_HAS_TIMESTAMP_BUG = new Timestamp(123456789).getTime() != 123456789;
+		if (JVM_HAS_TIMESTAMP_BUG) log.info("using workaround for JVM bug in java.sql.Timestamp");
+		Timestamp t = new Timestamp(0);
+		t.setNanos(5 * 1000000);
+		JVM_HAS_JDK14_TIMESTAMP = t.getTime() == 5;
+		if (JVM_HAS_JDK14_TIMESTAMP) {
+			log.info("using JDK 1.4 java.sql.Timestamp handling");
+		}
+		else {
+			log.info("using pre JDK 1.4 java.sql.Timestamp handling");
+		}
+	}
+
+	public static BytecodeProvider getBytecodeProvider() {
+		return BYTECODE_PROVIDER_INSTANCE;
+	}
+
+	/**
+	 * Does this JVM have the IBM JDK 1.3.1. The bug is <tt>new Timestamp(x).getTime()!=x</tt>.
+	 */
+	public static boolean jvmHasTimestampBug() {
+		return JVM_HAS_TIMESTAMP_BUG;
+	}
+
+	/**
+	 * Does this JVM handle <tt>Timestamp</tt> in the JDK 1.4 compliant way?
+	 */
+	public static boolean jvmHasJDK14Timestamp() {
+		return JVM_HAS_JDK14_TIMESTAMP;
+	}
+
+	/**
+	 * Does this JVM support <tt>LinkedHashSet</tt>, <tt>LinkedHashMap</tt>.
+	 * @see java.util.LinkedHashSet
+	 * @see java.util.LinkedHashMap
+	 */
+	public static boolean jvmSupportsLinkedHashCollections() {
+		return JVM_SUPPORTS_LINKED_HASH_COLLECTIONS;
+	}
+
+	public static boolean jvmSupportsGetGeneratedKeys() {
+		return JVM_SUPPORTS_GET_GENERATED_KEYS;
+	}
+
+	/**
+	 * Should we use streams to bind binary types to JDBC IN parameters.
+	 * Property <tt>hibernate.jdbc.use_streams_for_binary</tt>.
+	 * @see Environment#USE_STREAMS_FOR_BINARY
+	 */
+	public static boolean useStreamsForBinary() {
+		return ENABLE_BINARY_STREAMS;
+	}
+
+	/**
+	 * Should we use CGLIB reflection optimizer.
+	 * Property <tt>hibernate.jdbc.use_refection_optimizer</tt>.
+	 * @see Environment#USE_REFLECTION_OPTIMIZER
+	 */
+	public static boolean useReflectionOptimizer() {
+		return ENABLE_REFLECTION_OPTIMIZER;
+	}
+
+	private Environment() { throw new UnsupportedOperationException(); }
+
+	/**
+	 * Return <tt>System</tt> properties, extended by any properties specified
+	 * in <tt>hibernate.properties</tt>.
+	 * @return Properties
+	 */
+	public static Properties getProperties() {
+		Properties copy = new Properties();
+		copy.putAll(GLOBAL_PROPERTIES);
+		return copy;
+	}
+
+	/**
+	 * Get the name of a JDBC transaction isolation level
+	 *
+	 * @see java.sql.Connection
+	 * @param isolation as defined by <tt>java.sql.Connection</tt>
+	 * @return a human-readable name
+	 */
+	public static String isolationLevelToString(int isolation) {
+		return (String) ISOLATION_LEVELS.get( new Integer(isolation) );
+	}
+
+	public static BytecodeProvider buildBytecodeProvider(Properties properties) {
+		String provider = PropertiesHelper.getString( BYTECODE_PROVIDER, properties, "javassist" );
+		log.info( "Bytecode provider name : " + provider );
+		return buildBytecodeProvider( provider );
+	}
+
+	private static BytecodeProvider buildBytecodeProvider(String providerName) {
+		if ( "javassist".equals( providerName ) ) {
+			return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
+		}
+		else if ( "cglib".equals( providerName ) ) {
+			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
+		}
+
+		log.warn( "unrecognized bytecode provider [" + providerName + "], using javassist by default" );
+		return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-package org.hibernate.cfg;
-
-import org.dom4j.Document;
-
-/**
- * Represents a mapping queued for delayed processing to await
- * processing of an extends entity upon which it depends.
- *
- * @author Steve Ebersole
- */
-public class ExtendsQueueEntry {
-	private final String explicitName;
-	private final String mappingPackage;
-	private final Document document;
-
-	public ExtendsQueueEntry(String explicitName, String mappingPackage, Document document) {
-		this.explicitName = explicitName;
-		this.mappingPackage = mappingPackage;
-		this.document = document;
-	}
-
-	public String getExplicitName() {
-		return explicitName;
-	}
-
-	public String getMappingPackage() {
-		return mappingPackage;
-	}
-
-	public Document getDocument() {
-		return document;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ExtendsQueueEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.cfg;
+
+import org.dom4j.Document;
+
+/**
+ * Represents a mapping queued for delayed processing to await
+ * processing of an extends entity upon which it depends.
+ *
+ * @author Steve Ebersole
+ */
+public class ExtendsQueueEntry {
+	private final String explicitName;
+	private final String mappingPackage;
+	private final Document document;
+
+	public ExtendsQueueEntry(String explicitName, String mappingPackage, Document document) {
+		this.explicitName = explicitName;
+		this.mappingPackage = mappingPackage;
+		this.document = document;
+	}
+
+	public String getExplicitName() {
+		return explicitName;
+	}
+
+	public String getMappingPackage() {
+		return mappingPackage;
+	}
+
+	public Document getDocument() {
+		return document;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,3056 +0,0 @@
-// $Id: HbmBinder.java 11496 2007-05-09 03:54:06Z steve.ebersole at jboss.com $
-package org.hibernate.cfg;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.StringTokenizer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.dom4j.Attribute;
-import org.dom4j.Document;
-import org.dom4j.Element;
-import org.hibernate.CacheMode;
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.FlushMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.Versioning;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.mapping.Any;
-import org.hibernate.mapping.Array;
-import org.hibernate.mapping.AuxiliaryDatabaseObject;
-import org.hibernate.mapping.Backref;
-import org.hibernate.mapping.Bag;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.DependantValue;
-import org.hibernate.mapping.Fetchable;
-import org.hibernate.mapping.Filterable;
-import org.hibernate.mapping.Formula;
-import org.hibernate.mapping.IdentifierBag;
-import org.hibernate.mapping.IdentifierCollection;
-import org.hibernate.mapping.IndexBackref;
-import org.hibernate.mapping.IndexedCollection;
-import org.hibernate.mapping.Join;
-import org.hibernate.mapping.JoinedSubclass;
-import org.hibernate.mapping.KeyValue;
-import org.hibernate.mapping.List;
-import org.hibernate.mapping.ManyToOne;
-import org.hibernate.mapping.Map;
-import org.hibernate.mapping.MetaAttribute;
-import org.hibernate.mapping.OneToMany;
-import org.hibernate.mapping.OneToOne;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.PrimitiveArray;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.PropertyGeneration;
-import org.hibernate.mapping.RootClass;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.mapping.Set;
-import org.hibernate.mapping.SimpleAuxiliaryDatabaseObject;
-import org.hibernate.mapping.SimpleValue;
-import org.hibernate.mapping.SingleTableSubclass;
-import org.hibernate.mapping.Subclass;
-import org.hibernate.mapping.Table;
-import org.hibernate.mapping.ToOne;
-import org.hibernate.mapping.TypeDef;
-import org.hibernate.mapping.UnionSubclass;
-import org.hibernate.mapping.UniqueKey;
-import org.hibernate.mapping.Value;
-import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
-import org.hibernate.persister.entity.SingleTableEntityPersister;
-import org.hibernate.persister.entity.UnionSubclassEntityPersister;
-import org.hibernate.type.DiscriminatorType;
-import org.hibernate.type.ForeignKeyDirection;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Walks an XML mapping document and produces the Hibernate configuration-time metamodel (the
- * classes in the <tt>mapping</tt> package)
- *
- * @author Gavin King
- */
-public final class HbmBinder {
-
-	private static final Logger log = LoggerFactory.getLogger( HbmBinder.class );
-
-	/**
-	 * Private constructor to disallow instantiation.
-	 */
-	private HbmBinder() {
-	}
-
-	/**
-	 * The main contract into the hbm.xml-based binder. Performs necessary binding operations
-	 * represented by the given DOM.
-	 *
-	 * @param doc The DOM to be parsed and bound.
-	 * @param mappings Current bind state.
-	 * @param inheritedMetas Any inherited meta-tag information.
-	 * @throws MappingException
-	 */
-	public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas)
-			throws MappingException {
-
-		java.util.List names = HbmBinder.getExtendsNeeded( doc, mappings );
-		if ( !names.isEmpty() ) {
-			// classes mentioned in extends not available - so put it in queue
-			Element hmNode = doc.getRootElement();
-			Attribute packNode = hmNode.attribute( "package" );
-			String packageName = null;
-			if ( packNode != null ) {
-				packageName = packNode.getValue();
-			}
-			Iterator itr = names.iterator();
-			while ( itr.hasNext() ) {
-				String extendsName = (String) itr.next();
-				mappings.addToExtendsQueue( new ExtendsQueueEntry( extendsName, packageName, doc ) );
-			}
-			return;
-		}
-
-		Element hmNode = doc.getRootElement();
-		// get meta's from <hibernate-mapping>
-		inheritedMetas = getMetas( hmNode, inheritedMetas, true );
-		extractRootAttributes( hmNode, mappings );
-
-		Iterator rootChildren = hmNode.elementIterator();
-		while ( rootChildren.hasNext() ) {
-			final Element element = (Element) rootChildren.next();
-			final String elementName = element.getName();
-
-			if ( "filter-def".equals( elementName ) ) {
-				parseFilterDef( element, mappings );
-			}
-			else if ( "typedef".equals( elementName ) ) {
-				bindTypeDef( element, mappings );
-			}
-			else if ( "class".equals( elementName ) ) {
-				RootClass rootclass = new RootClass();
-				bindRootClass( element, rootclass, mappings, inheritedMetas );
-				mappings.addClass( rootclass );
-			}
-			else if ( "subclass".equals( elementName ) ) {
-				PersistentClass superModel = getSuperclass( mappings, element );
-				handleSubclass( superModel, mappings, element, inheritedMetas );
-			}
-			else if ( "joined-subclass".equals( elementName ) ) {
-				PersistentClass superModel = getSuperclass( mappings, element );
-				handleJoinedSubclass( superModel, mappings, element, inheritedMetas );
-			}
-			else if ( "union-subclass".equals( elementName ) ) {
-				PersistentClass superModel = getSuperclass( mappings, element );
-				handleUnionSubclass( superModel, mappings, element, inheritedMetas );
-			}
-			else if ( "query".equals( elementName ) ) {
-				bindNamedQuery( element, null, mappings );
-			}
-			else if ( "sql-query".equals( elementName ) ) {
-				bindNamedSQLQuery( element, null, mappings );
-			}
-			else if ( "resultset".equals( elementName ) ) {
-				bindResultSetMappingDefinition( element, null, mappings );
-			}
-			else if ( "import".equals( elementName ) ) {
-				bindImport( element, mappings );
-			}
-			else if ( "database-object".equals( elementName ) ) {
-				bindAuxiliaryDatabaseObject( element, mappings );
-			}
-		}
-	}
-
-	private static void bindImport(Element importNode, Mappings mappings) {
-		String className = getClassName( importNode.attribute( "class" ), mappings );
-		Attribute renameNode = importNode.attribute( "rename" );
-		String rename = ( renameNode == null ) ?
-						StringHelper.unqualify( className ) :
-						renameNode.getValue();
-		log.debug( "Import: " + rename + " -> " + className );
-		mappings.addImport( className, rename );
-	}
-
-	private static void bindTypeDef(Element typedefNode, Mappings mappings) {
-		String typeClass = typedefNode.attributeValue( "class" );
-		String typeName = typedefNode.attributeValue( "name" );
-		Iterator paramIter = typedefNode.elementIterator( "param" );
-		Properties parameters = new Properties();
-		while ( paramIter.hasNext() ) {
-			Element param = (Element) paramIter.next();
-			parameters.setProperty( param.attributeValue( "name" ), param.getTextTrim() );
-		}
-		mappings.addTypeDef( typeName, typeClass, parameters );
-	}
-
-	private static void bindAuxiliaryDatabaseObject(Element auxDbObjectNode, Mappings mappings) {
-		AuxiliaryDatabaseObject auxDbObject = null;
-		Element definitionNode = auxDbObjectNode.element( "definition" );
-		if ( definitionNode != null ) {
-			try {
-				auxDbObject = ( AuxiliaryDatabaseObject ) ReflectHelper
-						.classForName( definitionNode.attributeValue( "class" ) )
-						.newInstance();
-			}
-			catch( ClassNotFoundException e ) {
-				throw new MappingException(
-						"could not locate custom database object class [" +
-						definitionNode.attributeValue( "class" ) + "]"
-					);
-			}
-			catch( Throwable t ) {
-				throw new MappingException(
-						"could not instantiate custom database object class [" +
-						definitionNode.attributeValue( "class" ) + "]"
-					);
-			}
-		}
-		else {
-			auxDbObject = new SimpleAuxiliaryDatabaseObject(
-					auxDbObjectNode.elementTextTrim( "create" ),
-					auxDbObjectNode.elementTextTrim( "drop" )
-				);
-		}
-
-		Iterator dialectScopings = auxDbObjectNode.elementIterator( "dialect-scope" );
-		while ( dialectScopings.hasNext() ) {
-			Element dialectScoping = ( Element ) dialectScopings.next();
-			auxDbObject.addDialectScope( dialectScoping.attributeValue( "name" ) );
-		}
-
-		mappings.addAuxiliaryDatabaseObject( auxDbObject );
-	}
-
-	private static void extractRootAttributes(Element hmNode, Mappings mappings) {
-		Attribute schemaNode = hmNode.attribute( "schema" );
-		mappings.setSchemaName( ( schemaNode == null ) ? null : schemaNode.getValue() );
-
-		Attribute catalogNode = hmNode.attribute( "catalog" );
-		mappings.setCatalogName( ( catalogNode == null ) ? null : catalogNode.getValue() );
-
-		Attribute dcNode = hmNode.attribute( "default-cascade" );
-		mappings.setDefaultCascade( ( dcNode == null ) ? "none" : dcNode.getValue() );
-
-		Attribute daNode = hmNode.attribute( "default-access" );
-		mappings.setDefaultAccess( ( daNode == null ) ? "property" : daNode.getValue() );
-
-		Attribute dlNode = hmNode.attribute( "default-lazy" );
-		mappings.setDefaultLazy( dlNode == null || dlNode.getValue().equals( "true" ) );
-
-		Attribute aiNode = hmNode.attribute( "auto-import" );
-		mappings.setAutoImport( ( aiNode == null ) || "true".equals( aiNode.getValue() ) );
-
-		Attribute packNode = hmNode.attribute( "package" );
-		if ( packNode != null ) mappings.setDefaultPackage( packNode.getValue() );
-	}
-
-	/**
-	 * Responsible for perfoming the bind operation related to an &lt;class/&gt; mapping element.
-	 *
-	 * @param node The DOM Element for the &lt;class/&gt; element.
-	 * @param rootClass The mapping instance to which to bind the information.
-	 * @param mappings The current bind state.
-	 * @param inheritedMetas Any inherited meta-tag information.
-	 * @throws MappingException
-	 */
-	public static void bindRootClass(Element node, RootClass rootClass, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-		bindClass( node, rootClass, mappings, inheritedMetas );
-		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <class>
-		bindRootPersistentClassCommonValues( node, inheritedMetas, mappings, rootClass );
-	}
-
-	private static void bindRootPersistentClassCommonValues(Element node,
-			java.util.Map inheritedMetas, Mappings mappings, RootClass entity)
-			throws MappingException {
-
-		// DB-OBJECTNAME
-
-		Attribute schemaNode = node.attribute( "schema" );
-		String schema = schemaNode == null ?
-				mappings.getSchemaName() : schemaNode.getValue();
-
-		Attribute catalogNode = node.attribute( "catalog" );
-		String catalog = catalogNode == null ?
-				mappings.getCatalogName() : catalogNode.getValue();
-
-		Table table = mappings.addTable(
-				schema,
-				catalog,
-				getClassTableName( entity, node, schema, catalog, null, mappings ),
-				getSubselect( node ),
-		        entity.isAbstract() != null && entity.isAbstract().booleanValue()
-			);
-		entity.setTable( table );
-		bindComment(table, node);
-
-		log.info(
-				"Mapping class: " + entity.getEntityName() +
-				" -> " + entity.getTable().getName()
-			);
-
-		// MUTABLE
-		Attribute mutableNode = node.attribute( "mutable" );
-		entity.setMutable( ( mutableNode == null ) || mutableNode.getValue().equals( "true" ) );
-
-		// WHERE
-		Attribute whereNode = node.attribute( "where" );
-		if ( whereNode != null ) entity.setWhere( whereNode.getValue() );
-
-		// CHECK
-		Attribute chNode = node.attribute( "check" );
-		if ( chNode != null ) table.addCheckConstraint( chNode.getValue() );
-
-		// POLYMORPHISM
-		Attribute polyNode = node.attribute( "polymorphism" );
-		entity.setExplicitPolymorphism( ( polyNode != null )
-			&& polyNode.getValue().equals( "explicit" ) );
-
-		// ROW ID
-		Attribute rowidNode = node.attribute( "rowid" );
-		if ( rowidNode != null ) table.setRowId( rowidNode.getValue() );
-
-		Iterator subnodes = node.elementIterator();
-		while ( subnodes.hasNext() ) {
-
-			Element subnode = (Element) subnodes.next();
-			String name = subnode.getName();
-
-			if ( "id".equals( name ) ) {
-				// ID
-				bindSimpleId( subnode, entity, mappings, inheritedMetas );
-			}
-			else if ( "composite-id".equals( name ) ) {
-				// COMPOSITE-ID
-				bindCompositeId( subnode, entity, mappings, inheritedMetas );
-			}
-			else if ( "version".equals( name ) || "timestamp".equals( name ) ) {
-				// VERSION / TIMESTAMP
-				bindVersioningProperty( table, subnode, mappings, name, entity, inheritedMetas );
-			}
-			else if ( "discriminator".equals( name ) ) {
-				// DISCRIMINATOR
-				bindDiscriminatorProperty( table, entity, subnode, mappings );
-			}
-			else if ( "cache".equals( name ) ) {
-				entity.setCacheConcurrencyStrategy( subnode.attributeValue( "usage" ) );
-				entity.setCacheRegionName( subnode.attributeValue( "region" ) );
-				entity.setLazyPropertiesCacheable( !"non-lazy".equals( subnode.attributeValue( "include" ) ) );
-			}
-
-		}
-
-		// Primary key constraint
-		entity.createPrimaryKey();
-
-		createClassProperties( node, entity, mappings, inheritedMetas );
-	}
-
-	private static void bindSimpleId(Element idNode, RootClass entity, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-		String propertyName = idNode.attributeValue( "name" );
-
-		SimpleValue id = new SimpleValue( entity.getTable() );
-		entity.setIdentifier( id );
-
-		// if ( propertyName == null || entity.getPojoRepresentation() == null ) {
-		// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
-		// if ( !id.isTypeSpecified() ) {
-		// throw new MappingException( "must specify an identifier type: " + entity.getEntityName()
-		// );
-		// }
-		// }
-		// else {
-		// bindSimpleValue( idNode, id, false, propertyName, mappings );
-		// PojoRepresentation pojo = entity.getPojoRepresentation();
-		// id.setTypeUsingReflection( pojo.getClassName(), propertyName );
-		//
-		// Property prop = new Property();
-		// prop.setValue( id );
-		// bindProperty( idNode, prop, mappings, inheritedMetas );
-		// entity.setIdentifierProperty( prop );
-		// }
-
-		if ( propertyName == null ) {
-			bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
-		}
-		else {
-			bindSimpleValue( idNode, id, false, propertyName, mappings );
-		}
-
-		if ( propertyName == null || !entity.hasPojoRepresentation() ) {
-			if ( !id.isTypeSpecified() ) {
-				throw new MappingException( "must specify an identifier type: "
-					+ entity.getEntityName() );
-			}
-		}
-		else {
-			id.setTypeUsingReflection( entity.getClassName(), propertyName );
-		}
-
-		if ( propertyName != null ) {
-			Property prop = new Property();
-			prop.setValue( id );
-			bindProperty( idNode, prop, mappings, inheritedMetas );
-			entity.setIdentifierProperty( prop );
-		}
-
-		// TODO:
-		/*
-		 * if ( id.getHibernateType().getReturnedClass().isArray() ) throw new MappingException(
-		 * "illegal use of an array as an identifier (arrays don't reimplement equals)" );
-		 */
-		makeIdentifier( idNode, id, mappings );
-	}
-
-	private static void bindCompositeId(Element idNode, RootClass entity, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-		String propertyName = idNode.attributeValue( "name" );
-		Component id = new Component( entity );
-		entity.setIdentifier( id );
-		bindCompositeId( idNode, id, entity, propertyName, mappings, inheritedMetas );
-		if ( propertyName == null ) {
-			entity.setEmbeddedIdentifier( id.isEmbedded() );
-			if ( id.isEmbedded() ) {
-				// todo : what is the implication of this?
-				id.setDynamic( !entity.hasPojoRepresentation() );
-				/*
-				 * Property prop = new Property(); prop.setName("id");
-				 * prop.setPropertyAccessorName("embedded"); prop.setValue(id);
-				 * entity.setIdentifierProperty(prop);
-				 */
-			}
-		}
-		else {
-			Property prop = new Property();
-			prop.setValue( id );
-			bindProperty( idNode, prop, mappings, inheritedMetas );
-			entity.setIdentifierProperty( prop );
-		}
-
-		makeIdentifier( idNode, id, mappings );
-
-	}
-
-	private static void bindVersioningProperty(Table table, Element subnode, Mappings mappings,
-			String name, RootClass entity, java.util.Map inheritedMetas) {
-
-		String propertyName = subnode.attributeValue( "name" );
-		SimpleValue val = new SimpleValue( table );
-		bindSimpleValue( subnode, val, false, propertyName, mappings );
-		if ( !val.isTypeSpecified() ) {
-			// this is either a <version/> tag with no type attribute,
-			// or a <timestamp/> tag
-			if ( "version".equals( name ) ) {
-				val.setTypeName( "integer" );
-			}
-			else {
-				if ( "db".equals( subnode.attributeValue( "source" ) ) ) {
-					val.setTypeName( "dbtimestamp" );
-				}
-				else {
-					val.setTypeName( "timestamp" );
-				}
-			}
-		}
-		Property prop = new Property();
-		prop.setValue( val );
-		bindProperty( subnode, prop, mappings, inheritedMetas );
-		// for version properties marked as being generated, make sure they are "always"
-		// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
-		// but just to make sure...
-		if ( prop.getGeneration() == PropertyGeneration.INSERT ) {
-			throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
-		}
-		makeVersion( subnode, val );
-		entity.setVersion( prop );
-		entity.addProperty( prop );
-	}
-
-	private static void bindDiscriminatorProperty(Table table, RootClass entity, Element subnode,
-			Mappings mappings) {
-		SimpleValue discrim = new SimpleValue( table );
-		entity.setDiscriminator( discrim );
-		bindSimpleValue(
-				subnode,
-				discrim,
-				false,
-				RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME,
-				mappings
-			);
-		if ( !discrim.isTypeSpecified() ) {
-			discrim.setTypeName( "string" );
-			// ( (Column) discrim.getColumnIterator().next() ).setType(type);
-		}
-		entity.setPolymorphic( true );
-		if ( "true".equals( subnode.attributeValue( "force" ) ) )
-			entity.setForceDiscriminator( true );
-		if ( "false".equals( subnode.attributeValue( "insert" ) ) )
-			entity.setDiscriminatorInsertable( false );
-	}
-
-	public static void bindClass(Element node, PersistentClass persistentClass, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-		// transfer an explicitly defined entity name
-		// handle the lazy attribute
-		Attribute lazyNode = node.attribute( "lazy" );
-		boolean lazy = lazyNode == null ?
-				mappings.isDefaultLazy() :
-				"true".equals( lazyNode.getValue() );
-		// go ahead and set the lazy here, since pojo.proxy can override it.
-		persistentClass.setLazy( lazy );
-
-		String entityName = node.attributeValue( "entity-name" );
-		if ( entityName == null ) entityName = getClassName( node.attribute("name"), mappings );
-		if ( entityName==null ) {
-			throw new MappingException( "Unable to determine entity name" );
-		}
-		persistentClass.setEntityName( entityName );
-
-		bindPojoRepresentation( node, persistentClass, mappings, inheritedMetas );
-		bindDom4jRepresentation( node, persistentClass, mappings, inheritedMetas );
-		bindMapRepresentation( node, persistentClass, mappings, inheritedMetas );
-
-		bindPersistentClassCommonValues( node, persistentClass, mappings, inheritedMetas );
-
-	}
-
-	private static void bindPojoRepresentation(Element node, PersistentClass entity,
-			Mappings mappings, java.util.Map metaTags) {
-
-		String className = getClassName( node.attribute( "name" ), mappings );
-		String proxyName = getClassName( node.attribute( "proxy" ), mappings );
-
-		entity.setClassName( className );
-
-		if ( proxyName != null ) {
-			entity.setProxyInterfaceName( proxyName );
-			entity.setLazy( true );
-		}
-		else if ( entity.isLazy() ) {
-			entity.setProxyInterfaceName( className );
-		}
-
-		Element tuplizer = locateTuplizerDefinition( node, EntityMode.POJO );
-		if ( tuplizer != null ) {
-			entity.addTuplizer( EntityMode.POJO, tuplizer.attributeValue( "class" ) );
-		}
-	}
-
-	private static void bindDom4jRepresentation(Element node, PersistentClass entity,
-			Mappings mappings, java.util.Map inheritedMetas) {
-		String nodeName = node.attributeValue( "node" );
-		if (nodeName==null) nodeName = StringHelper.unqualify( entity.getEntityName() );
-		entity.setNodeName(nodeName);
-
-		Element tuplizer = locateTuplizerDefinition( node, EntityMode.DOM4J );
-		if ( tuplizer != null ) {
-			entity.addTuplizer( EntityMode.DOM4J, tuplizer.attributeValue( "class" ) );
-		}
-	}
-
-	private static void bindMapRepresentation(Element node, PersistentClass entity,
-			Mappings mappings, java.util.Map inheritedMetas) {
-		Element tuplizer = locateTuplizerDefinition( node, EntityMode.MAP );
-		if ( tuplizer != null ) {
-			entity.addTuplizer( EntityMode.MAP, tuplizer.attributeValue( "class" ) );
-		}
-	}
-
-	/**
-	 * Locate any explicit tuplizer definition in the metadata, for the given entity-mode.
-	 *
-	 * @param container The containing element (representing the entity/component)
-	 * @param entityMode The entity-mode for which to locate the tuplizer element
-	 * @return The tuplizer element, or null.
-	 */
-	private static Element locateTuplizerDefinition(Element container, EntityMode entityMode) {
-		Iterator itr = container.elements( "tuplizer" ).iterator();
-		while( itr.hasNext() ) {
-			final Element tuplizerElem = ( Element ) itr.next();
-			if ( entityMode.toString().equals( tuplizerElem.attributeValue( "entity-mode") ) ) {
-				return tuplizerElem;
-			}
-		}
-		return null;
-	}
-
-	private static void bindPersistentClassCommonValues(Element node, PersistentClass entity,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-		// DISCRIMINATOR
-		Attribute discriminatorNode = node.attribute( "discriminator-value" );
-		entity.setDiscriminatorValue( ( discriminatorNode == null )
-			? entity.getEntityName()
-			: discriminatorNode.getValue() );
-
-		// DYNAMIC UPDATE
-		Attribute dynamicNode = node.attribute( "dynamic-update" );
-		entity.setDynamicUpdate(
-				dynamicNode != null && "true".equals( dynamicNode.getValue() )
-		);
-
-		// DYNAMIC INSERT
-		Attribute insertNode = node.attribute( "dynamic-insert" );
-		entity.setDynamicInsert(
-				insertNode != null && "true".equals( insertNode.getValue() )
-		);
-
-		// IMPORT
-		mappings.addImport( entity.getEntityName(), entity.getEntityName() );
-		if ( mappings.isAutoImport() && entity.getEntityName().indexOf( '.' ) > 0 ) {
-			mappings.addImport(
-					entity.getEntityName(),
-					StringHelper.unqualify( entity.getEntityName() )
-				);
-		}
-
-		// BATCH SIZE
-		Attribute batchNode = node.attribute( "batch-size" );
-		if ( batchNode != null ) entity.setBatchSize( Integer.parseInt( batchNode.getValue() ) );
-
-		// SELECT BEFORE UPDATE
-		Attribute sbuNode = node.attribute( "select-before-update" );
-		if ( sbuNode != null ) entity.setSelectBeforeUpdate( "true".equals( sbuNode.getValue() ) );
-
-		// OPTIMISTIC LOCK MODE
-		Attribute olNode = node.attribute( "optimistic-lock" );
-		entity.setOptimisticLockMode( getOptimisticLockMode( olNode ) );
-
-		entity.setMetaAttributes( getMetas( node, inheritedMetas ) );
-
-		// PERSISTER
-		Attribute persisterNode = node.attribute( "persister" );
-		if ( persisterNode != null ) {
-			try {
-				entity.setEntityPersisterClass( ReflectHelper.classForName( persisterNode
-					.getValue() ) );
-			}
-			catch (ClassNotFoundException cnfe) {
-				throw new MappingException( "Could not find persister class: "
-					+ persisterNode.getValue() );
-			}
-		}
-
-		// CUSTOM SQL
-		handleCustomSQL( node, entity );
-
-		Iterator tables = node.elementIterator( "synchronize" );
-		while ( tables.hasNext() ) {
-			entity.addSynchronizedTable( ( (Element) tables.next() ).attributeValue( "table" ) );
-		}
-
-		Attribute abstractNode = node.attribute( "abstract" );
-		Boolean isAbstract = abstractNode == null
-				? null
-		        : "true".equals( abstractNode.getValue() )
-						? Boolean.TRUE
-	                    : "false".equals( abstractNode.getValue() )
-								? Boolean.FALSE
-	                            : null;
-		entity.setAbstract( isAbstract );
-	}
-
-	private static void handleCustomSQL(Element node, PersistentClass model)
-			throws MappingException {
-		Element element = node.element( "sql-insert" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-delete" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-update" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "loader" );
-		if ( element != null ) {
-			model.setLoaderName( element.attributeValue( "query-ref" ) );
-		}
-	}
-
-	private static void handleCustomSQL(Element node, Join model) throws MappingException {
-		Element element = node.element( "sql-insert" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-delete" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-update" );
-		if ( element != null ) {
-			boolean callable = isCallable( element );
-			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-	}
-
-	private static void handleCustomSQL(Element node, Collection model) throws MappingException {
-		Element element = node.element( "sql-insert" );
-		if ( element != null ) {
-			boolean callable = isCallable( element, true );
-			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-delete" );
-		if ( element != null ) {
-			boolean callable = isCallable( element, true );
-			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-update" );
-		if ( element != null ) {
-			boolean callable = isCallable( element, true );
-			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-
-		element = node.element( "sql-delete-all" );
-		if ( element != null ) {
-			boolean callable = isCallable( element, true );
-			model.setCustomSQLDeleteAll( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
-		}
-	}
-
-	private static boolean isCallable(Element e) throws MappingException {
-		return isCallable( e, true );
-	}
-
-	private static boolean isCallable(Element element, boolean supportsCallable)
-			throws MappingException {
-		Attribute attrib = element.attribute( "callable" );
-		if ( attrib != null && "true".equals( attrib.getValue() ) ) {
-			if ( !supportsCallable ) {
-				throw new MappingException( "callable attribute not supported yet!" );
-			}
-			return true;
-		}
-		return false;
-	}
-
-	private static ExecuteUpdateResultCheckStyle getResultCheckStyle(Element element, boolean callable) throws MappingException {
-		Attribute attr = element.attribute( "check" );
-		if ( attr == null ) {
-			// use COUNT as the default.  This mimics the old behavior, although
-			// NONE might be a better option moving forward in the case of callable
-			return ExecuteUpdateResultCheckStyle.COUNT;
-		}
-		return ExecuteUpdateResultCheckStyle.parse( attr.getValue() );
-	}
-
-	public static void bindUnionSubclass(Element node, UnionSubclass unionSubclass,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		bindClass( node, unionSubclass, mappings, inheritedMetas );
-		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <subclass>
-
-		if ( unionSubclass.getEntityPersisterClass() == null ) {
-			unionSubclass.getRootClass().setEntityPersisterClass(
-				UnionSubclassEntityPersister.class );
-		}
-
-		Attribute schemaNode = node.attribute( "schema" );
-		String schema = schemaNode == null ?
-				mappings.getSchemaName() : schemaNode.getValue();
-
-		Attribute catalogNode = node.attribute( "catalog" );
-		String catalog = catalogNode == null ?
-				mappings.getCatalogName() : catalogNode.getValue();
-
-		Table denormalizedSuperTable = unionSubclass.getSuperclass().getTable();
-		Table mytable = mappings.addDenormalizedTable(
-				schema,
-				catalog,
-				getClassTableName(unionSubclass, node, schema, catalog, denormalizedSuperTable, mappings ),
-		        unionSubclass.isAbstract() != null && unionSubclass.isAbstract().booleanValue(),
-				getSubselect( node ),
-				denormalizedSuperTable
-			);
-		unionSubclass.setTable( mytable );
-
-		log.info(
-				"Mapping union-subclass: " + unionSubclass.getEntityName() +
-				" -> " + unionSubclass.getTable().getName()
-			);
-
-		createClassProperties( node, unionSubclass, mappings, inheritedMetas );
-
-	}
-
-	public static void bindSubclass(Element node, Subclass subclass, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		bindClass( node, subclass, mappings, inheritedMetas );
-		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <subclass>
-
-		if ( subclass.getEntityPersisterClass() == null ) {
-			subclass.getRootClass()
-					.setEntityPersisterClass( SingleTableEntityPersister.class );
-		}
-
-		log.info(
-				"Mapping subclass: " + subclass.getEntityName() +
-				" -> " + subclass.getTable().getName()
-			);
-
-		// properties
-		createClassProperties( node, subclass, mappings, inheritedMetas );
-	}
-
-	private static String getClassTableName(
-			PersistentClass model, Element node, String schema, String catalog, Table denormalizedSuperTable,
-			Mappings mappings
-	) {
-		Attribute tableNameNode = node.attribute( "table" );
-		String logicalTableName;
-		String physicalTableName;
-		if ( tableNameNode == null ) {
-			logicalTableName = StringHelper.unqualify( model.getEntityName() );
-			physicalTableName = mappings.getNamingStrategy().classToTableName( model.getEntityName() );
-		}
-		else {
-			logicalTableName = tableNameNode.getValue();
-			physicalTableName = mappings.getNamingStrategy().tableName( logicalTableName );
-		}
-		mappings.addTableBinding( schema, catalog, logicalTableName, physicalTableName, denormalizedSuperTable );
-		return physicalTableName;
-	}
-
-	public static void bindJoinedSubclass(Element node, JoinedSubclass joinedSubclass,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		bindClass( node, joinedSubclass, mappings, inheritedMetas );
-		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from
-																	// <joined-subclass>
-
-		// joined subclasses
-		if ( joinedSubclass.getEntityPersisterClass() == null ) {
-			joinedSubclass.getRootClass()
-				.setEntityPersisterClass( JoinedSubclassEntityPersister.class );
-		}
-
-		Attribute schemaNode = node.attribute( "schema" );
-		String schema = schemaNode == null ?
-				mappings.getSchemaName() : schemaNode.getValue();
-
-		Attribute catalogNode = node.attribute( "catalog" );
-		String catalog = catalogNode == null ?
-				mappings.getCatalogName() : catalogNode.getValue();
-
-		Table mytable = mappings.addTable(
-				schema,
-				catalog,
-				getClassTableName( joinedSubclass, node, schema, catalog, null, mappings ),
-				getSubselect( node ),
-				false
-			);
-		joinedSubclass.setTable( mytable );
-		bindComment(mytable, node);
-
-		log.info(
-				"Mapping joined-subclass: " + joinedSubclass.getEntityName() +
-				" -> " + joinedSubclass.getTable().getName()
-			);
-
-		// KEY
-		Element keyNode = node.element( "key" );
-		SimpleValue key = new DependantValue( mytable, joinedSubclass.getIdentifier() );
-		joinedSubclass.setKey( key );
-		key.setCascadeDeleteEnabled( "cascade".equals( keyNode.attributeValue( "on-delete" ) ) );
-		bindSimpleValue( keyNode, key, false, joinedSubclass.getEntityName(), mappings );
-
-		// model.getKey().setType( new Type( model.getIdentifier() ) );
-		joinedSubclass.createPrimaryKey();
-		joinedSubclass.createForeignKey();
-
-		// CHECK
-		Attribute chNode = node.attribute( "check" );
-		if ( chNode != null ) mytable.addCheckConstraint( chNode.getValue() );
-
-		// properties
-		createClassProperties( node, joinedSubclass, mappings, inheritedMetas );
-
-	}
-
-	private static void bindJoin(Element node, Join join, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		PersistentClass persistentClass = join.getPersistentClass();
-		String path = persistentClass.getEntityName();
-
-		// TABLENAME
-
-		Attribute schemaNode = node.attribute( "schema" );
-		String schema = schemaNode == null ?
-				mappings.getSchemaName() : schemaNode.getValue();
-		Attribute catalogNode = node.attribute( "catalog" );
-		String catalog = catalogNode == null ?
-				mappings.getCatalogName() : catalogNode.getValue();
-		Table primaryTable = persistentClass.getTable();
-		Table table = mappings.addTable(
-				schema,
-				catalog,
-				getClassTableName( persistentClass, node, schema, catalog, primaryTable, mappings ),
-				getSubselect( node ),
-				false
-			);
-		join.setTable( table );
-		bindComment(table, node);
-
-		Attribute fetchNode = node.attribute( "fetch" );
-		if ( fetchNode != null ) {
-			join.setSequentialSelect( "select".equals( fetchNode.getValue() ) );
-		}
-
-		Attribute invNode = node.attribute( "inverse" );
-		if ( invNode != null ) {
-			join.setInverse( "true".equals( invNode.getValue() ) );
-		}
-
-		Attribute nullNode = node.attribute( "optional" );
-		if ( nullNode != null ) {
-			join.setOptional( "true".equals( nullNode.getValue() ) );
-		}
-
-		log.info(
-				"Mapping class join: " + persistentClass.getEntityName() +
-				" -> " + join.getTable().getName()
-			);
-
-		// KEY
-		Element keyNode = node.element( "key" );
-		SimpleValue key = new DependantValue( table, persistentClass.getIdentifier() );
-		join.setKey( key );
-		key.setCascadeDeleteEnabled( "cascade".equals( keyNode.attributeValue( "on-delete" ) ) );
-		bindSimpleValue( keyNode, key, false, persistentClass.getEntityName(), mappings );
-
-		// join.getKey().setType( new Type( lazz.getIdentifier() ) );
-		join.createPrimaryKey();
-		join.createForeignKey();
-
-		// PROPERTIES
-		Iterator iter = node.elementIterator();
-		while ( iter.hasNext() ) {
-			Element subnode = (Element) iter.next();
-			String name = subnode.getName();
-			String propertyName = subnode.attributeValue( "name" );
-
-			Value value = null;
-			if ( "many-to-one".equals( name ) ) {
-				value = new ManyToOne( table );
-				bindManyToOne( subnode, (ManyToOne) value, propertyName, true, mappings );
-			}
-			else if ( "any".equals( name ) ) {
-				value = new Any( table );
-				bindAny( subnode, (Any) value, true, mappings );
-			}
-			else if ( "property".equals( name ) ) {
-				value = new SimpleValue( table );
-				bindSimpleValue( subnode, (SimpleValue) value, true, propertyName, mappings );
-			}
-			else if ( "component".equals( name ) || "dynamic-component".equals( name ) ) {
-				String subpath = StringHelper.qualify( path, propertyName );
-				value = new Component( join );
-				bindComponent(
-						subnode,
-						(Component) value,
-						join.getPersistentClass().getClassName(),
-						propertyName,
-						subpath,
-						true,
-						false,
-						mappings,
-						inheritedMetas,
-						false
-					);
-			}
-
-			if ( value != null ) {
-				Property prop = createProperty( value, propertyName, persistentClass
-					.getEntityName(), subnode, mappings, inheritedMetas );
-				prop.setOptional( join.isOptional() );
-				join.addProperty( prop );
-			}
-
-		}
-
-		// CUSTOM SQL
-		handleCustomSQL( node, join );
-
-	}
-
-	public static void bindColumns(final Element node, final SimpleValue simpleValue,
-			final boolean isNullable, final boolean autoColumn, final String propertyPath,
-			final Mappings mappings) throws MappingException {
-
-		Table table = simpleValue.getTable();
-
-		// COLUMN(S)
-		Attribute columnAttribute = node.attribute( "column" );
-		if ( columnAttribute == null ) {
-			Iterator iter = node.elementIterator();
-			int count = 0;
-			while ( iter.hasNext() ) {
-				Element columnElement = (Element) iter.next();
-				if ( columnElement.getName().equals( "column" ) ) {
-					Column column = new Column();
-					column.setValue( simpleValue );
-					column.setTypeIndex( count++ );
-					bindColumn( columnElement, column, isNullable );
-					String logicalColumnName = mappings.getNamingStrategy().logicalColumnName(
-							columnElement.attributeValue( "name" ), propertyPath
-					);
-					column.setName( mappings.getNamingStrategy().columnName(
-						logicalColumnName ) );
-					if ( table != null ) {
-						table.addColumn( column ); // table=null -> an association
-						                           // - fill it in later
-						//TODO fill in the mappings for table == null
-						mappings.addColumnBinding( logicalColumnName, column, table );
-					}
-
-
-					simpleValue.addColumn( column );
-					// column index
-					bindIndex( columnElement.attribute( "index" ), table, column, mappings );
-					bindIndex( node.attribute( "index" ), table, column, mappings );
-					//column unique-key
-					bindUniqueKey( columnElement.attribute( "unique-key" ), table, column, mappings );
-					bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
-				}
-				else if ( columnElement.getName().equals( "formula" ) ) {
-					Formula formula = new Formula();
-					formula.setFormula( columnElement.getText() );
-					simpleValue.addFormula( formula );
-				}
-			}
-		}
-		else {
-			if ( node.elementIterator( "column" ).hasNext() ) {
-				throw new MappingException(
-					"column attribute may not be used together with <column> subelement" );
-			}
-			if ( node.elementIterator( "formula" ).hasNext() ) {
-				throw new MappingException(
-					"column attribute may not be used together with <formula> subelement" );
-			}
-
-			Column column = new Column();
-			column.setValue( simpleValue );
-			bindColumn( node, column, isNullable );
-			String logicalColumnName = mappings.getNamingStrategy().logicalColumnName(
-					columnAttribute.getValue(), propertyPath
-			);
-			column.setName( mappings.getNamingStrategy().columnName( logicalColumnName ) );
-			if ( table != null ) {
-				table.addColumn( column ); // table=null -> an association - fill
-				                           // it in later
-				//TODO fill in the mappings for table == null
-				mappings.addColumnBinding( logicalColumnName, column, table );
-			}
-			simpleValue.addColumn( column );
-			bindIndex( node.attribute( "index" ), table, column, mappings );
-			bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
-		}
-
-		if ( autoColumn && simpleValue.getColumnSpan() == 0 ) {
-			Column column = new Column();
-			column.setValue( simpleValue );
-			bindColumn( node, column, isNullable );
-			column.setName( mappings.getNamingStrategy().propertyToColumnName( propertyPath ) );
-			String logicalName = mappings.getNamingStrategy().logicalColumnName( null, propertyPath );
-			mappings.addColumnBinding( logicalName, column, table );
-			/* TODO: joinKeyColumnName & foreignKeyColumnName should be called either here or at a
-			 * slightly higer level in the stack (to get all the information we need)
-			 * Right now HbmBinder does not support the
-			 */
-			simpleValue.getTable().addColumn( column );
-			simpleValue.addColumn( column );
-			bindIndex( node.attribute( "index" ), table, column, mappings );
-			bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
-		}
-
-	}
-
-	private static void bindIndex(Attribute indexAttribute, Table table, Column column, Mappings mappings) {
-		if ( indexAttribute != null && table != null ) {
-			StringTokenizer tokens = new StringTokenizer( indexAttribute.getValue(), ", " );
-			while ( tokens.hasMoreTokens() ) {
-				table.getOrCreateIndex( tokens.nextToken() ).addColumn( column );
-			}
-		}
-	}
-
-	private static void bindUniqueKey(Attribute uniqueKeyAttribute, Table table, Column column, Mappings mappings) {
-		if ( uniqueKeyAttribute != null && table != null ) {
-			StringTokenizer tokens = new StringTokenizer( uniqueKeyAttribute.getValue(), ", " );
-			while ( tokens.hasMoreTokens() ) {
-				table.getOrCreateUniqueKey( tokens.nextToken() ).addColumn( column );
-			}
-		}
-	}
-
-	// automatically makes a column with the default name if none is specifed by XML
-	public static void bindSimpleValue(Element node, SimpleValue simpleValue, boolean isNullable,
-			String path, Mappings mappings) throws MappingException {
-		bindSimpleValueType( node, simpleValue, mappings );
-
-		bindColumnsOrFormula( node, simpleValue, path, isNullable, mappings );
-
-		Attribute fkNode = node.attribute( "foreign-key" );
-		if ( fkNode != null ) simpleValue.setForeignKeyName( fkNode.getValue() );
-	}
-
-	private static void bindSimpleValueType(Element node, SimpleValue simpleValue, Mappings mappings)
-			throws MappingException {
-		String typeName = null;
-
-		Properties parameters = new Properties();
-
-		Attribute typeNode = node.attribute( "type" );
-		if ( typeNode == null ) typeNode = node.attribute( "id-type" ); // for an any
-		if ( typeNode != null ) typeName = typeNode.getValue();
-
-		Element typeChild = node.element( "type" );
-		if ( typeName == null && typeChild != null ) {
-			typeName = typeChild.attribute( "name" ).getValue();
-			Iterator typeParameters = typeChild.elementIterator( "param" );
-
-			while ( typeParameters.hasNext() ) {
-				Element paramElement = (Element) typeParameters.next();
-				parameters.setProperty(
-						paramElement.attributeValue( "name" ),
-						paramElement.getTextTrim()
-					);
-			}
-		}
-
-		TypeDef typeDef = mappings.getTypeDef( typeName );
-		if ( typeDef != null ) {
-			typeName = typeDef.getTypeClass();
-			// parameters on the property mapping should
-			// override parameters in the typedef
-			Properties allParameters = new Properties();
-			allParameters.putAll( typeDef.getParameters() );
-			allParameters.putAll( parameters );
-			parameters = allParameters;
-		}
-
-		if ( !parameters.isEmpty() ) simpleValue.setTypeParameters( parameters );
-
-		if ( typeName != null ) simpleValue.setTypeName( typeName );
-	}
-
-	public static void bindProperty(
-			Element node,
-	        Property property,
-	        Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		String propName = node.attributeValue( "name" );
-		property.setName( propName );
-		String nodeName = node.attributeValue( "node" );
-		if (nodeName==null) nodeName = propName;
-		property.setNodeName( nodeName );
-
-		// TODO:
-		//Type type = model.getValue().getType();
-		//if (type==null) throw new MappingException(
-		//"Could not determine a property type for: " + model.getName() );
-
-		Attribute accessNode = node.attribute( "access" );
-		if ( accessNode != null ) {
-			property.setPropertyAccessorName( accessNode.getValue() );
-		}
-		else if ( node.getName().equals( "properties" ) ) {
-			property.setPropertyAccessorName( "embedded" );
-		}
-		else {
-			property.setPropertyAccessorName( mappings.getDefaultAccess() );
-		}
-
-		Attribute cascadeNode = node.attribute( "cascade" );
-		property.setCascade( cascadeNode == null ? mappings.getDefaultCascade() : cascadeNode
-			.getValue() );
-
-		Attribute updateNode = node.attribute( "update" );
-		property.setUpdateable( updateNode == null || "true".equals( updateNode.getValue() ) );
-
-		Attribute insertNode = node.attribute( "insert" );
-		property.setInsertable( insertNode == null || "true".equals( insertNode.getValue() ) );
-
-		Attribute lockNode = node.attribute( "optimistic-lock" );
-		property.setOptimisticLocked( lockNode == null || "true".equals( lockNode.getValue() ) );
-
-		Attribute generatedNode = node.attribute( "generated" );
-        String generationName = generatedNode == null ? null : generatedNode.getValue();
-        PropertyGeneration generation = PropertyGeneration.parse( generationName );
-		property.setGeneration( generation );
-
-        if ( generation == PropertyGeneration.ALWAYS || generation == PropertyGeneration.INSERT ) {
-	        // generated properties can *never* be insertable...
-	        if ( property.isInsertable() ) {
-		        if ( insertNode == null ) {
-			        // insertable simply because that is the user did not specify
-			        // anything; just override it
-					property.setInsertable( false );
-		        }
-		        else {
-			        // the user specifically supplied insert="true",
-			        // which constitutes an illegal combo
-					throw new MappingException(
-							"cannot specify both insert=\"true\" and generated=\"" + generation.getName() +
-							"\" for property: " +
-							propName
-					);
-		        }
-	        }
-
-	        // properties generated on update can never be updateable...
-	        if ( property.isUpdateable() && generation == PropertyGeneration.ALWAYS ) {
-		        if ( updateNode == null ) {
-			        // updateable only because the user did not specify 
-			        // anything; just override it
-			        property.setUpdateable( false );
-		        }
-		        else {
-			        // the user specifically supplied update="true",
-			        // which constitutes an illegal combo
-					throw new MappingException(
-							"cannot specify both update=\"true\" and generated=\"" + generation.getName() +
-							"\" for property: " +
-							propName
-					);
-		        }
-	        }
-        }
-
-		boolean isLazyable = "property".equals( node.getName() ) ||
-				"component".equals( node.getName() ) ||
-				"many-to-one".equals( node.getName() ) ||
-				"one-to-one".equals( node.getName() ) ||
-				"any".equals( node.getName() );
-		if ( isLazyable ) {
-			Attribute lazyNode = node.attribute( "lazy" );
-			property.setLazy( lazyNode != null && "true".equals( lazyNode.getValue() ) );
-		}
-
-		if ( log.isDebugEnabled() ) {
-			String msg = "Mapped property: " + property.getName();
-			String columns = columns( property.getValue() );
-			if ( columns.length() > 0 ) msg += " -> " + columns;
-			// TODO: this fails if we run with debug on!
-			// if ( model.getType()!=null ) msg += ", type: " + model.getType().getName();
-			log.debug( msg );
-		}
-
-		property.setMetaAttributes( getMetas( node, inheritedMetas ) );
-
-	}
-
-	private static String columns(Value val) {
-		StringBuffer columns = new StringBuffer();
-		Iterator iter = val.getColumnIterator();
-		while ( iter.hasNext() ) {
-			columns.append( ( (Selectable) iter.next() ).getText() );
-			if ( iter.hasNext() ) columns.append( ", " );
-		}
-		return columns.toString();
-	}
-
-	/**
-	 * Called for all collections
-	 */
-	public static void bindCollection(Element node, Collection collection, String className,
-			String path, Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		// ROLENAME
-		collection.setRole(path);
-
-		Attribute inverseNode = node.attribute( "inverse" );
-		if ( inverseNode != null ) {
-			collection.setInverse( "true".equals( inverseNode.getValue() ) );
-		}
-
-		Attribute mutableNode = node.attribute( "mutable" );
-		if ( mutableNode != null ) {
-			collection.setMutable( !"false".equals( mutableNode.getValue() ) );
-		}
-
-		Attribute olNode = node.attribute( "optimistic-lock" );
-		collection.setOptimisticLocked( olNode == null || "true".equals( olNode.getValue() ) );
-
-		Attribute orderNode = node.attribute( "order-by" );
-		if ( orderNode != null ) {
-			if ( Environment.jvmSupportsLinkedHashCollections() || ( collection instanceof Bag ) ) {
-				collection.setOrderBy( orderNode.getValue() );
-			}
-			else {
-				log.warn( "Attribute \"order-by\" ignored in JDK1.3 or less" );
-			}
-		}
-		Attribute whereNode = node.attribute( "where" );
-		if ( whereNode != null ) {
-			collection.setWhere( whereNode.getValue() );
-		}
-		Attribute batchNode = node.attribute( "batch-size" );
-		if ( batchNode != null ) {
-			collection.setBatchSize( Integer.parseInt( batchNode.getValue() ) );
-		}
-
-		String nodeName = node.attributeValue( "node" );
-		if ( nodeName == null ) nodeName = node.attributeValue( "name" );
-		collection.setNodeName( nodeName );
-		String embed = node.attributeValue( "embed-xml" );
-		collection.setEmbedded( embed==null || "true".equals(embed) );
-
-
-		// PERSISTER
-		Attribute persisterNode = node.attribute( "persister" );
-		if ( persisterNode != null ) {
-			try {
-				collection.setCollectionPersisterClass( ReflectHelper.classForName( persisterNode
-					.getValue() ) );
-			}
-			catch (ClassNotFoundException cnfe) {
-				throw new MappingException( "Could not find collection persister class: "
-					+ persisterNode.getValue() );
-			}
-		}
-
-		Attribute typeNode = node.attribute( "collection-type" );
-		if ( typeNode != null ) {
-			String typeName = typeNode.getValue();
-			TypeDef typeDef = mappings.getTypeDef( typeName );
-			if ( typeDef != null ) {
-				collection.setTypeName( typeDef.getTypeClass() );
-				collection.setTypeParameters( typeDef.getParameters() );
-			}
-			else {
-				collection.setTypeName( typeName );
-			}
-		}
-
-		// FETCH STRATEGY
-
-		initOuterJoinFetchSetting( node, collection );
-
-		if ( "subselect".equals( node.attributeValue("fetch") ) ) {
-			collection.setSubselectLoadable(true);
-			collection.getOwner().setSubselectLoadableCollections(true);
-		}
-
-		initLaziness( node, collection, mappings, "true", mappings.isDefaultLazy() );
-		//TODO: suck this into initLaziness!
-		if ( "extra".equals( node.attributeValue("lazy") ) ) {
-			collection.setLazy(true);
-			collection.setExtraLazy(true);
-		}
-
-		Element oneToManyNode = node.element( "one-to-many" );
-		if ( oneToManyNode != null ) {
-			OneToMany oneToMany = new OneToMany( collection.getOwner() );
-			collection.setElement( oneToMany );
-			bindOneToMany( oneToManyNode, oneToMany, mappings );
-			// we have to set up the table later!! yuck
-		}
-		else {
-			// TABLE
-			Attribute tableNode = node.attribute( "table" );
-			String tableName;
-			if ( tableNode != null ) {
-				tableName = mappings.getNamingStrategy().tableName( tableNode.getValue() );
-			}
-			else {
-				//tableName = mappings.getNamingStrategy().propertyToTableName( className, path );
-				Table ownerTable = collection.getOwner().getTable();
-				//TODO mappings.getLogicalTableName(ownerTable)
-				String logicalOwnerTableName = ownerTable.getName();
-				//FIXME we don't have the associated entity table name here, has to be done in a second pass
-				tableName = mappings.getNamingStrategy().collectionTableName(
-						collection.getOwner().getEntityName(),
-						logicalOwnerTableName ,
-						null,
-						null,
-						path
-				);
-			}
-			Attribute schemaNode = node.attribute( "schema" );
-			String schema = schemaNode == null ?
-					mappings.getSchemaName() : schemaNode.getValue();
-
-			Attribute catalogNode = node.attribute( "catalog" );
-			String catalog = catalogNode == null ?
-					mappings.getCatalogName() : catalogNode.getValue();
-
-			Table table = mappings.addTable(
-					schema,
-					catalog,
-					tableName,
-					getSubselect( node ),
-					false
-				);
-			collection.setCollectionTable( table );
-			bindComment(table, node);
-
-			log.info(
-					"Mapping collection: " + collection.getRole() +
-					" -> " + collection.getCollectionTable().getName()
-				);
-		}
-
-		// SORT
-		Attribute sortedAtt = node.attribute( "sort" );
-		// unsorted, natural, comparator.class.name
-		if ( sortedAtt == null || sortedAtt.getValue().equals( "unsorted" ) ) {
-			collection.setSorted( false );
-		}
-		else {
-			collection.setSorted( true );
-			String comparatorClassName = sortedAtt.getValue();
-			if ( !comparatorClassName.equals( "natural" ) ) {
-				collection.setComparatorClassName(comparatorClassName);
-			}
-		}
-
-		// ORPHAN DELETE (used for programmer error detection)
-		Attribute cascadeAtt = node.attribute( "cascade" );
-		if ( cascadeAtt != null && cascadeAtt.getValue().indexOf( "delete-orphan" ) >= 0 ) {
-			collection.setOrphanDelete( true );
-		}
-
-		// CUSTOM SQL
-		handleCustomSQL( node, collection );
-		// set up second pass
-		if ( collection instanceof List ) {
-			mappings.addSecondPass( new ListSecondPass( node, mappings, (List) collection, inheritedMetas ) );
-		}
-		else if ( collection instanceof Map ) {
-			mappings.addSecondPass( new MapSecondPass( node, mappings, (Map) collection, inheritedMetas ) );
-		}
-		else if ( collection instanceof IdentifierCollection ) {
-			mappings.addSecondPass( new IdentifierCollectionSecondPass(
-					node,
-					mappings,
-					collection,
-					inheritedMetas
-				) );
-		}
-		else {
-			mappings.addSecondPass( new CollectionSecondPass( node, mappings, collection, inheritedMetas ) );
-		}
-
-		Iterator iter = node.elementIterator( "filter" );
-		while ( iter.hasNext() ) {
-			final Element filter = (Element) iter.next();
-			parseFilter( filter, collection, mappings );
-		}
-
-		Iterator tables = node.elementIterator( "synchronize" );
-		while ( tables.hasNext() ) {
-			collection.getSynchronizedTables().add(
-				( (Element) tables.next() ).attributeValue( "table" ) );
-		}
-
-		Element element = node.element( "loader" );
-		if ( element != null ) {
-			collection.setLoaderName( element.attributeValue( "query-ref" ) );
-		}
-
-		collection.setReferencedPropertyName( node.element( "key" ).attributeValue( "property-ref" ) );
-	}
-
-	private static void initLaziness(
-			Element node,
-			Fetchable fetchable,
-			Mappings mappings,
-			String proxyVal,
-			boolean defaultLazy
-	) {
-		Attribute lazyNode = node.attribute( "lazy" );
-		boolean isLazyTrue = lazyNode == null ?
-				defaultLazy && fetchable.isLazy() : //fetch="join" overrides default laziness
-				lazyNode.getValue().equals(proxyVal); //fetch="join" overrides default laziness
-		fetchable.setLazy( isLazyTrue );
-	}
-
-	private static void initLaziness(
-			Element node,
-			ToOne fetchable,
-			Mappings mappings,
-			boolean defaultLazy
-	) {
-		if ( "no-proxy".equals( node.attributeValue( "lazy" ) ) ) {
-			fetchable.setUnwrapProxy(true);
-			fetchable.setLazy(true);
-			//TODO: better to degrade to lazy="false" if uninstrumented
-		}
-		else {
-			initLaziness(node, fetchable, mappings, "proxy", defaultLazy);
-		}
-	}
-
-	private static void bindColumnsOrFormula(Element node, SimpleValue simpleValue, String path,
-			boolean isNullable, Mappings mappings) {
-		Attribute formulaNode = node.attribute( "formula" );
-		if ( formulaNode != null ) {
-			Formula f = new Formula();
-			f.setFormula( formulaNode.getText() );
-			simpleValue.addFormula( f );
-		}
-		else {
-			bindColumns( node, simpleValue, isNullable, true, path, mappings );
-		}
-	}
-
-	private static void bindComment(Table table, Element node) {
-		Element comment = node.element("comment");
-		if (comment!=null) table.setComment( comment.getTextTrim() );
-	}
-
-	public static void bindManyToOne(Element node, ManyToOne manyToOne, String path,
-			boolean isNullable, Mappings mappings) throws MappingException {
-
-		bindColumnsOrFormula( node, manyToOne, path, isNullable, mappings );
-		initOuterJoinFetchSetting( node, manyToOne );
-		initLaziness( node, manyToOne, mappings, true );
-
-		Attribute ukName = node.attribute( "property-ref" );
-		if ( ukName != null ) {
-			manyToOne.setReferencedPropertyName( ukName.getValue() );
-		}
-
-		manyToOne.setReferencedEntityName( getEntityName( node, mappings ) );
-
-		String embed = node.attributeValue( "embed-xml" );
-		manyToOne.setEmbedded( embed == null || "true".equals( embed ) );
-
-		String notFound = node.attributeValue( "not-found" );
-		manyToOne.setIgnoreNotFound( "ignore".equals( notFound ) );
-
-		if( ukName != null && !manyToOne.isIgnoreNotFound() ) {
-			if ( !node.getName().equals("many-to-many") ) { //TODO: really bad, evil hack to fix!!!
-				mappings.addSecondPass( new ManyToOneSecondPass(manyToOne) );
-			}
-		}
-
-		Attribute fkNode = node.attribute( "foreign-key" );
-		if ( fkNode != null ) manyToOne.setForeignKeyName( fkNode.getValue() );
-
-		validateCascade( node, path );
-	}
-
-	private static void validateCascade(Element node, String path) {
-		String cascade = node.attributeValue( "cascade" );
-		if ( cascade != null && cascade.indexOf( "delete-orphan" ) >= 0 ) {
-			throw new MappingException( "single-valued associations do not support orphan delete: " + path );
-		}
-	}
-
-	public static void bindAny(Element node, Any any, boolean isNullable, Mappings mappings)
-			throws MappingException {
-		any.setIdentifierType( getTypeFromXML( node ) );
-		Attribute metaAttribute = node.attribute( "meta-type" );
-		if ( metaAttribute != null ) {
-			any.setMetaType( metaAttribute.getValue() );
-
-			Iterator iter = node.elementIterator( "meta-value" );
-			if ( iter.hasNext() ) {
-				HashMap values = new HashMap();
-				org.hibernate.type.Type metaType = TypeFactory.heuristicType( any.getMetaType() );
-				while ( iter.hasNext() ) {
-					Element metaValue = (Element) iter.next();
-					try {
-						Object value = ( (DiscriminatorType) metaType ).stringToObject( metaValue
-							.attributeValue( "value" ) );
-						String entityName = getClassName( metaValue.attribute( "class" ), mappings );
-						values.put( value, entityName );
-					}
-					catch (ClassCastException cce) {
-						throw new MappingException( "meta-type was not a DiscriminatorType: "
-							+ metaType.getName() );
-					}
-					catch (Exception e) {
-						throw new MappingException( "could not interpret meta-value", e );
-					}
-				}
-				any.setMetaValues( values );
-			}
-
-		}
-
-		bindColumns( node, any, isNullable, false, null, mappings );
-	}
-
-	public static void bindOneToOne(Element node, OneToOne oneToOne, String path, boolean isNullable,
-			Mappings mappings) throws MappingException {
-
-		bindColumns( node, oneToOne, isNullable, false, null, mappings );
-
-		Attribute constrNode = node.attribute( "constrained" );
-		boolean constrained = constrNode != null && constrNode.getValue().equals( "true" );
-		oneToOne.setConstrained( constrained );
-
-		oneToOne.setForeignKeyType( constrained ?
-				ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT :
-				ForeignKeyDirection.FOREIGN_KEY_TO_PARENT );
-
-		initOuterJoinFetchSetting( node, oneToOne );
-		initLaziness( node, oneToOne, mappings, true );
-
-		oneToOne.setEmbedded( "true".equals( node.attributeValue( "embed-xml" ) ) );
-
-		Attribute fkNode = node.attribute( "foreign-key" );
-		if ( fkNode != null ) oneToOne.setForeignKeyName( fkNode.getValue() );
-
-		Attribute ukName = node.attribute( "property-ref" );
-		if ( ukName != null ) oneToOne.setReferencedPropertyName( ukName.getValue() );
-
-		oneToOne.setPropertyName( node.attributeValue( "name" ) );
-
-		oneToOne.setReferencedEntityName( getEntityName( node, mappings ) );
-
-		validateCascade( node, path );
-	}
-
-	public static void bindOneToMany(Element node, OneToMany oneToMany, Mappings mappings)
-			throws MappingException {
-
-		oneToMany.setReferencedEntityName( getEntityName( node, mappings ) );
-
-		String embed = node.attributeValue( "embed-xml" );
-		oneToMany.setEmbedded( embed == null || "true".equals( embed ) );
-
-		String notFound = node.attributeValue( "not-found" );
-		oneToMany.setIgnoreNotFound( "ignore".equals( notFound ) );
-
-	}
-
-	public static void bindColumn(Element node, Column column, boolean isNullable) {
-		Attribute lengthNode = node.attribute( "length" );
-		if ( lengthNode != null ) column.setLength( Integer.parseInt( lengthNode.getValue() ) );
-		Attribute scalNode = node.attribute( "scale" );
-		if ( scalNode != null ) column.setScale( Integer.parseInt( scalNode.getValue() ) );
-		Attribute precNode = node.attribute( "precision" );
-		if ( precNode != null ) column.setPrecision( Integer.parseInt( precNode.getValue() ) );
-
-		Attribute nullNode = node.attribute( "not-null" );
-		column.setNullable( nullNode == null ? isNullable : nullNode.getValue().equals( "false" ) );
-
-		Attribute unqNode = node.attribute( "unique" );
-		if ( unqNode != null ) column.setUnique( unqNode.getValue().equals( "true" ) );
-
-		column.setCheckConstraint( node.attributeValue( "check" ) );
-		column.setDefaultValue( node.attributeValue( "default" ) );
-
-		Attribute typeNode = node.attribute( "sql-type" );
-		if ( typeNode != null ) column.setSqlType( typeNode.getValue() );
-
-		Element comment = node.element("comment");
-		if (comment!=null) column.setComment( comment.getTextTrim() );
-
-	}
-
-	/**
-	 * Called for arrays and primitive arrays
-	 */
-	public static void bindArray(Element node, Array array, String prefix, String path,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		bindCollection( node, array, prefix, path, mappings, inheritedMetas );
-
-		Attribute att = node.attribute( "element-class" );
-		if ( att != null ) array.setElementClassName( getClassName( att, mappings ) );
-
-	}
-
-	private static Class reflectedPropertyClass(String className, String propertyName)
-			throws MappingException {
-		if ( className == null ) return null;
-		return ReflectHelper.reflectedPropertyClass( className, propertyName );
-	}
-
-	public static void bindComposite(Element node, Component component, String path,
-			boolean isNullable, Mappings mappings, java.util.Map inheritedMetas)
-			throws MappingException {
-		bindComponent(
-				node,
-				component,
-				null,
-				null,
-				path,
-				isNullable,
-				false,
-				mappings,
-				inheritedMetas,
-				false
-			);
-	}
-
-	public static void bindCompositeId(Element node, Component component,
-			PersistentClass persistentClass, String propertyName, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		component.setKey( true );
-
-		String path = StringHelper.qualify(
-				persistentClass.getEntityName(),
-				propertyName == null ? "id" : propertyName );
-
-		bindComponent(
-				node,
-				component,
-				persistentClass.getClassName(),
-				propertyName,
-				path,
-				false,
-				node.attribute( "class" ) == null
-						&& propertyName == null,
-				mappings,
-				inheritedMetas,
-				false
-			);
-
-		if ( "true".equals( node.attributeValue("mapped") ) ) {
-			if ( propertyName!=null ) {
-				throw new MappingException("cannot combine mapped=\"true\" with specified name");
-			}
-			Component mapper = new Component(persistentClass);
-			bindComponent(
-					node,
-					mapper,
-					persistentClass.getClassName(),
-					null,
-					path,
-					false,
-					true,
-					mappings,
-					inheritedMetas,
-					true
-				);
-			persistentClass.setIdentifierMapper(mapper);
-			Property property = new Property();
-			property.setName("_identifierMapper");
-			property.setNodeName("id");
-			property.setUpdateable(false);
-			property.setInsertable(false);
-			property.setValue(mapper);
-			property.setPropertyAccessorName( "embedded" );
-			persistentClass.addProperty(property);
-		}
-
-	}
-
-	public static void bindComponent(
-			Element node,
-			Component component,
-			String ownerClassName,
-			String parentProperty,
-			String path,
-			boolean isNullable,
-			boolean isEmbedded,
-			Mappings mappings,
-			java.util.Map inheritedMetas,
-			boolean isIdentifierMapper) throws MappingException {
-
-		component.setEmbedded( isEmbedded );
-		component.setRoleName( path );
-
-		inheritedMetas = getMetas( node, inheritedMetas );
-		component.setMetaAttributes( inheritedMetas );
-
-		Attribute classNode = isIdentifierMapper ? null : node.attribute( "class" );
-		if ( classNode != null ) {
-			component.setComponentClassName( getClassName( classNode, mappings ) );
-		}
-		else if ( "dynamic-component".equals( node.getName() ) ) {
-			component.setDynamic( true );
-		}
-		else if ( isEmbedded ) {
-			// an "embedded" component (composite ids and unique)
-			// note that this does not handle nested components
-			if ( component.getOwner().hasPojoRepresentation() ) {
-				component.setComponentClassName( component.getOwner().getClassName() );
-			}
-			else {
-				component.setDynamic(true);
-			}
-		}
-		else {
-			// todo : again, how *should* this work for non-pojo entities?
-			if ( component.getOwner().hasPojoRepresentation() ) {
-				Class reflectedClass = reflectedPropertyClass( ownerClassName, parentProperty );
-				if ( reflectedClass != null ) {
-					component.setComponentClassName( reflectedClass.getName() );
-				}
-			}
-			else {
-				component.setDynamic(true);
-			}
-		}
-
-		String nodeName = node.attributeValue( "node" );
-		if ( nodeName == null ) nodeName = node.attributeValue( "name" );
-		if ( nodeName == null ) nodeName = component.getOwner().getNodeName();
-		component.setNodeName( nodeName );
-
-		Iterator iter = node.elementIterator();
-		while ( iter.hasNext() ) {
-
-			Element subnode = (Element) iter.next();
-			String name = subnode.getName();
-			String propertyName = getPropertyName( subnode );
-			String subpath = propertyName == null ? null : StringHelper
-				.qualify( path, propertyName );
-
-			CollectionType collectType = CollectionType.collectionTypeFromString( name );
-			Value value = null;
-			if ( collectType != null ) {
-				Collection collection = collectType.create(
-						subnode,
-						subpath,
-						component.getOwner(),
-						mappings, inheritedMetas
-					);
-				mappings.addCollection( collection );
-				value = collection;
-			}
-			else if ( "many-to-one".equals( name ) || "key-many-to-one".equals( name ) ) {
-				value = new ManyToOne( component.getTable() );
-				String relativePath;
-				if (isEmbedded) {
-					relativePath = propertyName;
-				}
-				else {
-					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
-				}
-				bindManyToOne( subnode, (ManyToOne) value, relativePath, isNullable, mappings );
-			}
-			else if ( "one-to-one".equals( name ) ) {
-				value = new OneToOne( component.getTable(), component.getOwner() );
-				String relativePath;
-				if (isEmbedded) {
-					relativePath = propertyName;
-				}
-				else {
-					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
-				}
-				bindOneToOne( subnode, (OneToOne) value, relativePath, isNullable, mappings );
-			}
-			else if ( "any".equals( name ) ) {
-				value = new Any( component.getTable() );
-				bindAny( subnode, (Any) value, isNullable, mappings );
-			}
-			else if ( "property".equals( name ) || "key-property".equals( name ) ) {
-				value = new SimpleValue( component.getTable() );
-				String relativePath;
-				if (isEmbedded) {
-					relativePath = propertyName;
-				}
-				else {
-					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
-				}
-				bindSimpleValue( subnode, (SimpleValue) value, isNullable, relativePath, mappings );
-			}
-			else if ( "component".equals( name )
-				|| "dynamic-component".equals( name )
-				|| "nested-composite-element".equals( name ) ) {
-				value = new Component( component ); // a nested composite element
-				bindComponent(
-						subnode,
-						(Component) value,
-						component.getComponentClassName(),
-						propertyName,
-						subpath,
-						isNullable,
-						isEmbedded,
-						mappings,
-						inheritedMetas,
-						isIdentifierMapper
-					);
-			}
-			else if ( "parent".equals( name ) ) {
-				component.setParentProperty( propertyName );
-			}
-
-			if ( value != null ) {
-				Property property = createProperty( value, propertyName, component
-					.getComponentClassName(), subnode, mappings, inheritedMetas );
-				if (isIdentifierMapper) {
-					property.setInsertable(false);
-					property.setUpdateable(false);
-				}
-				component.addProperty( property );
-			}
-		}
-
-		if ( "true".equals( node.attributeValue( "unique" ) ) ) {
-			iter = component.getColumnIterator();
-			ArrayList cols = new ArrayList();
-			while ( iter.hasNext() ) {
-				cols.add( iter.next() );
-			}
-			component.getOwner().getTable().createUniqueKey( cols );
-		}
-
-		iter = node.elementIterator( "tuplizer" );
-		while ( iter.hasNext() ) {
-			final Element tuplizerElem = ( Element ) iter.next();
-			EntityMode mode = EntityMode.parse( tuplizerElem.attributeValue( "entity-mode" ) );
-			component.addTuplizer( mode, tuplizerElem.attributeValue( "class" ) );
-		}
-	}
-
-	public static String getTypeFromXML(Element node) throws MappingException {
-		// TODO: handle TypeDefs
-		Attribute typeNode = node.attribute( "type" );
-		if ( typeNode == null ) typeNode = node.attribute( "id-type" ); // for an any
-		if ( typeNode == null ) return null; // we will have to use reflection
-		return typeNode.getValue();
-	}
-
-	private static void initOuterJoinFetchSetting(Element node, Fetchable model) {
-		Attribute fetchNode = node.attribute( "fetch" );
-		final FetchMode fetchStyle;
-		boolean lazy = true;
-		if ( fetchNode == null ) {
-			Attribute jfNode = node.attribute( "outer-join" );
-			if ( jfNode == null ) {
-				if ( "many-to-many".equals( node.getName() ) ) {
-					//NOTE SPECIAL CASE:
-					// default to join and non-lazy for the "second join"
-					// of the many-to-many
-					lazy = false;
-					fetchStyle = FetchMode.JOIN;
-				}
-				else if ( "one-to-one".equals( node.getName() ) ) {
-					//NOTE SPECIAL CASE:
-					// one-to-one constrained=false cannot be proxied,
-					// so default to join and non-lazy
-					lazy = ( (OneToOne) model ).isConstrained();
-					fetchStyle = lazy ? FetchMode.DEFAULT : FetchMode.JOIN;
-				}
-				else {
-					fetchStyle = FetchMode.DEFAULT;
-				}
-			}
-			else {
-				// use old (HB 2.1) defaults if outer-join is specified
-				String eoj = jfNode.getValue();
-				if ( "auto".equals( eoj ) ) {
-					fetchStyle = FetchMode.DEFAULT;
-				}
-				else {
-					boolean join = "true".equals( eoj );
-					fetchStyle = join ? FetchMode.JOIN : FetchMode.SELECT;
-				}
-			}
-		}
-		else {
-			boolean join = "join".equals( fetchNode.getValue() );
-			//lazy = !join;
-			fetchStyle = join ? FetchMode.JOIN : FetchMode.SELECT;
-		}
-		model.setFetchMode( fetchStyle );
-		model.setLazy(lazy);
-	}
-
-	private static void makeIdentifier(Element node, SimpleValue model, Mappings mappings) {
-
-		// GENERATOR
-		Element subnode = node.element( "generator" );
-		if ( subnode != null ) {
-			model.setIdentifierGeneratorStrategy( subnode.attributeValue( "class" ) );
-
-			Properties params = new Properties();
-
-			if ( mappings.getSchemaName() != null ) {
-				params.setProperty( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
-			}
-			if ( mappings.getCatalogName() != null ) {
-				params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
-			}
-
-			Iterator iter = subnode.elementIterator( "param" );
-			while ( iter.hasNext() ) {
-				Element childNode = (Element) iter.next();
-				params.setProperty( childNode.attributeValue( "name" ), childNode.getTextTrim() );
-			}
-
-			model.setIdentifierGeneratorProperties( params );
-		}
-
-		model.getTable().setIdentifierValue( model );
-
-		// ID UNSAVED-VALUE
-		Attribute nullValueNode = node.attribute( "unsaved-value" );
-		if ( nullValueNode != null ) {
-			model.setNullValue( nullValueNode.getValue() );
-		}
-		else {
-			if ( "assigned".equals( model.getIdentifierGeneratorStrategy() ) ) {
-				model.setNullValue( "undefined" );
-			}
-			else {
-				model.setNullValue( null );
-			}
-		}
-	}
-
-	private static final void makeVersion(Element node, SimpleValue model) {
-
-		// VERSION UNSAVED-VALUE
-		Attribute nullValueNode = node.attribute( "unsaved-value" );
-		if ( nullValueNode != null ) {
-			model.setNullValue( nullValueNode.getValue() );
-		}
-		else {
-			model.setNullValue( "undefined" );
-		}
-
-	}
-
-	protected static void createClassProperties(Element node, PersistentClass persistentClass,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-		createClassProperties(node, persistentClass, mappings, inheritedMetas, null, true, true, false);
-	}
-
-	protected static void createClassProperties(Element node, PersistentClass persistentClass,
-			Mappings mappings, java.util.Map inheritedMetas, UniqueKey uniqueKey,
-			boolean mutable, boolean nullable, boolean naturalId) throws MappingException {
-
-		String entityName = persistentClass.getEntityName();
-		Table table = persistentClass.getTable();
-
-		Iterator iter = node.elementIterator();
-		while ( iter.hasNext() ) {
-			Element subnode = (Element) iter.next();
-			String name = subnode.getName();
-			String propertyName = subnode.attributeValue( "name" );
-
-			CollectionType collectType = CollectionType.collectionTypeFromString( name );
-			Value value = null;
-			if ( collectType != null ) {
-				Collection collection = collectType.create(
-						subnode,
-						StringHelper.qualify( entityName, propertyName ),
-						persistentClass,
-						mappings, inheritedMetas
-					);
-				mappings.addCollection( collection );
-				value = collection;
-			}
-			else if ( "many-to-one".equals( name ) ) {
-				value = new ManyToOne( table );
-				bindManyToOne( subnode, (ManyToOne) value, propertyName, nullable, mappings );
-			}
-			else if ( "any".equals( name ) ) {
-				value = new Any( table );
-				bindAny( subnode, (Any) value, nullable, mappings );
-			}
-			else if ( "one-to-one".equals( name ) ) {
-				value = new OneToOne( table, persistentClass );
-				bindOneToOne( subnode, (OneToOne) value, propertyName, true, mappings );
-			}
-			else if ( "property".equals( name ) ) {
-				value = new SimpleValue( table );
-				bindSimpleValue( subnode, (SimpleValue) value, nullable, propertyName, mappings );
-			}
-			else if ( "component".equals( name )
-				|| "dynamic-component".equals( name )
-				|| "properties".equals( name ) ) {
-				String subpath = StringHelper.qualify( entityName, propertyName );
-				value = new Component( persistentClass );
-
-				bindComponent(
-						subnode,
-						(Component) value,
-						persistentClass.getClassName(),
-						propertyName,
-						subpath,
-						true,
-						"properties".equals( name ),
-						mappings,
-						inheritedMetas,
-						false
-					);
-			}
-			else if ( "join".equals( name ) ) {
-				Join join = new Join();
-				join.setPersistentClass( persistentClass );
-				bindJoin( subnode, join, mappings, inheritedMetas );
-				persistentClass.addJoin( join );
-			}
-			else if ( "subclass".equals( name ) ) {
-				handleSubclass( persistentClass, mappings, subnode, inheritedMetas );
-			}
-			else if ( "joined-subclass".equals( name ) ) {
-				handleJoinedSubclass( persistentClass, mappings, subnode, inheritedMetas );
-			}
-			else if ( "union-subclass".equals( name ) ) {
-				handleUnionSubclass( persistentClass, mappings, subnode, inheritedMetas );
-			}
-			else if ( "filter".equals( name ) ) {
-				parseFilter( subnode, persistentClass, mappings );
-			}
-			else if ( "natural-id".equals( name ) ) {
-				UniqueKey uk = new UniqueKey();
-				uk.setName("_UniqueKey");
-				uk.setTable(table);
-				//by default, natural-ids are "immutable" (constant)
-				boolean mutableId = "true".equals( subnode.attributeValue("mutable") );
-				createClassProperties(
-						subnode,
-						persistentClass,
-						mappings,
-						inheritedMetas,
-						uk,
-						mutableId,
-						false,
-						true
-					);
-				table.addUniqueKey(uk);
-			}
-			else if ( "query".equals(name) ) {
-				bindNamedQuery(subnode, persistentClass.getEntityName(), mappings);
-			}
-			else if ( "sql-query".equals(name) ) {
-				bindNamedSQLQuery(subnode, persistentClass.getEntityName(), mappings);
-			}
-			else if ( "resultset".equals(name) ) {
-				bindResultSetMappingDefinition( subnode, persistentClass.getEntityName(), mappings );
-			}
-
-			if ( value != null ) {
-				Property property = createProperty( value, propertyName, persistentClass
-					.getClassName(), subnode, mappings, inheritedMetas );
-				if ( !mutable ) property.setUpdateable(false);
-				if ( naturalId ) property.setNaturalIdentifier(true);
-				persistentClass.addProperty( property );
-				if ( uniqueKey!=null ) uniqueKey.addColumns( property.getColumnIterator() );
-			}
-
-		}
-	}
-
-	private static Property createProperty(
-			final Value value,
-	        final String propertyName,
-			final String className,
-	        final Element subnode,
-	        final Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		if ( StringHelper.isEmpty( propertyName ) ) {
-			throw new MappingException( subnode.getName() + " mapping must defined a name attribute [" + className + "]" );
-		}
-
-		value.setTypeUsingReflection( className, propertyName );
-
-		// this is done here 'cos we might only know the type here (ugly!)
-		// TODO: improve this a lot:
-		if ( value instanceof ToOne ) {
-			ToOne toOne = (ToOne) value;
-			String propertyRef = toOne.getReferencedPropertyName();
-			if ( propertyRef != null ) {
-				mappings.addUniquePropertyReference( toOne.getReferencedEntityName(), propertyRef );
-			}
-		}
-		else if ( value instanceof Collection ) {
-			Collection coll = (Collection) value;
-			String propertyRef = coll.getReferencedPropertyName();
-			// not necessarily a *unique* property reference
-			if ( propertyRef != null ) {
-				mappings.addPropertyReference( coll.getOwnerEntityName(), propertyRef );
-			}
-		}
-
-		value.createForeignKey();
-		Property prop = new Property();
-		prop.setValue( value );
-		bindProperty( subnode, prop, mappings, inheritedMetas );
-		return prop;
-	}
-
-	private static void handleUnionSubclass(PersistentClass model, Mappings mappings,
-			Element subnode, java.util.Map inheritedMetas) throws MappingException {
-		UnionSubclass subclass = new UnionSubclass( model );
-		bindUnionSubclass( subnode, subclass, mappings, inheritedMetas );
-		model.addSubclass( subclass );
-		mappings.addClass( subclass );
-	}
-
-	private static void handleJoinedSubclass(PersistentClass model, Mappings mappings,
-			Element subnode, java.util.Map inheritedMetas) throws MappingException {
-		JoinedSubclass subclass = new JoinedSubclass( model );
-		bindJoinedSubclass( subnode, subclass, mappings, inheritedMetas );
-		model.addSubclass( subclass );
-		mappings.addClass( subclass );
-	}
-
-	private static void handleSubclass(PersistentClass model, Mappings mappings, Element subnode,
-			java.util.Map inheritedMetas) throws MappingException {
-		Subclass subclass = new SingleTableSubclass( model );
-		bindSubclass( subnode, subclass, mappings, inheritedMetas );
-		model.addSubclass( subclass );
-		mappings.addClass( subclass );
-	}
-
-	/**
-	 * Called for Lists, arrays, primitive arrays
-	 */
-	public static void bindListSecondPass(Element node, List list, java.util.Map classes,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		bindCollectionSecondPass( node, list, classes, mappings, inheritedMetas );
-
-		Element subnode = node.element( "list-index" );
-		if ( subnode == null ) subnode = node.element( "index" );
-		SimpleValue iv = new SimpleValue( list.getCollectionTable() );
-		bindSimpleValue(
-				subnode,
-				iv,
-				list.isOneToMany(),
-				IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
-				mappings
-			);
-		iv.setTypeName( "integer" );
-		list.setIndex( iv );
-		String baseIndex = subnode.attributeValue( "base" );
-		if ( baseIndex != null ) list.setBaseIndex( Integer.parseInt( baseIndex ) );
-		list.setIndexNodeName( subnode.attributeValue("node") );
-
-		if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) {
-			String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName();
-			PersistentClass referenced = mappings.getClass( entityName );
-			IndexBackref ib = new IndexBackref();
-			ib.setName( '_' + list.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "IndexBackref" );
-			ib.setUpdateable( false );
-			ib.setSelectable( false );
-			ib.setCollectionRole( list.getRole() );
-			ib.setEntityName( list.getOwner().getEntityName() );
-			ib.setValue( list.getIndex() );
-			// ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next()
-			// ).setNullable(false);
-			referenced.addProperty( ib );
-		}
-	}
-
-	public static void bindIdentifierCollectionSecondPass(Element node,
-			IdentifierCollection collection, java.util.Map persistentClasses, Mappings mappings,
-			java.util.Map inheritedMetas) throws MappingException {
-
-		bindCollectionSecondPass( node, collection, persistentClasses, mappings, inheritedMetas );
-
-		Element subnode = node.element( "collection-id" );
-		SimpleValue id = new SimpleValue( collection.getCollectionTable() );
-		bindSimpleValue(
-				subnode,
-				id,
-				false,
-				IdentifierCollection.DEFAULT_IDENTIFIER_COLUMN_NAME,
-				mappings
-			);
-		collection.setIdentifier( id );
-		makeIdentifier( subnode, id, mappings );
-
-	}
-
-	/**
-	 * Called for Maps
-	 */
-	public static void bindMapSecondPass(Element node, Map map, java.util.Map classes,
-			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-
-		bindCollectionSecondPass( node, map, classes, mappings, inheritedMetas );
-
-		Iterator iter = node.elementIterator();
-		while ( iter.hasNext() ) {
-			Element subnode = (Element) iter.next();
-			String name = subnode.getName();
-
-			if ( "index".equals( name ) || "map-key".equals( name ) ) {
-				SimpleValue value = new SimpleValue( map.getCollectionTable() );
-				bindSimpleValue(
-						subnode,
-						value,
-						map.isOneToMany(),
-						IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
-						mappings
-					);
-				if ( !value.isTypeSpecified() ) {
-					throw new MappingException( "map index element must specify a type: "
-						+ map.getRole() );
-				}
-				map.setIndex( value );
-				map.setIndexNodeName( subnode.attributeValue("node") );
-			}
-			else if ( "index-many-to-many".equals( name ) || "map-key-many-to-many".equals( name ) ) {
-				ManyToOne mto = new ManyToOne( map.getCollectionTable() );
-				bindManyToOne(
-						subnode,
-						mto,
-						IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
-						map.isOneToMany(),
-						mappings
-					);
-				map.setIndex( mto );
-
-			}
-			else if ( "composite-index".equals( name ) || "composite-map-key".equals( name ) ) {
-				Component component = new Component( map );
-				bindComposite(
-						subnode,
-						component,
-						map.getRole() + ".index",
-						map.isOneToMany(),
-						mappings,
-						inheritedMetas
-					);
-				map.setIndex( component );
-			}
-			else if ( "index-many-to-any".equals( name ) ) {
-				Any any = new Any( map.getCollectionTable() );
-				bindAny( subnode, any, map.isOneToMany(), mappings );
-				map.setIndex( any );
-			}
-		}
-
-		// TODO: this is a bit of copy/paste from IndexedCollection.createPrimaryKey()
-		boolean indexIsFormula = false;
-		Iterator colIter = map.getIndex().getColumnIterator();
-		while ( colIter.hasNext() ) {
-			if ( ( (Selectable) colIter.next() ).isFormula() ) indexIsFormula = true;
-		}
-
-		if ( map.isOneToMany() && !map.getKey().isNullable() && !map.isInverse() && !indexIsFormula ) {
-			String entityName = ( (OneToMany) map.getElement() ).getReferencedEntityName();
-			PersistentClass referenced = mappings.getClass( entityName );
-			IndexBackref ib = new IndexBackref();
-			ib.setName( '_' + map.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "IndexBackref" );
-			ib.setUpdateable( false );
-			ib.setSelectable( false );
-			ib.setCollectionRole( map.getRole() );
-			ib.setEntityName( map.getOwner().getEntityName() );
-			ib.setValue( map.getIndex() );
-			// ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next()
-			// ).setNullable(false);
-			referenced.addProperty( ib );
-		}
-	}
-
-	/**
-	 * Called for all collections
-	 */
-	public static void bindCollectionSecondPass(Element node, Collection collection,
-			java.util.Map persistentClasses, Mappings mappings, java.util.Map inheritedMetas)
-			throws MappingException {
-
-		if ( collection.isOneToMany() ) {
-			OneToMany oneToMany = (OneToMany) collection.getElement();
-			String assocClass = oneToMany.getReferencedEntityName();
-			PersistentClass persistentClass = (PersistentClass) persistentClasses.get( assocClass );
-			if ( persistentClass == null ) {
-				throw new MappingException( "Association references unmapped class: " + assocClass );
-			}
-			oneToMany.setAssociatedClass( persistentClass );
-			collection.setCollectionTable( persistentClass.getTable() );
-
-			log.info(
-					"Mapping collection: " + collection.getRole() +
-					" -> " + collection.getCollectionTable().getName()
-				);
-		}
-
-		// CHECK
-		Attribute chNode = node.attribute( "check" );
-		if ( chNode != null ) {
-			collection.getCollectionTable().addCheckConstraint( chNode.getValue() );
-		}
-
-		// contained elements:
-		Iterator iter = node.elementIterator();
-		while ( iter.hasNext() ) {
-			Element subnode = (Element) iter.next();
-			String name = subnode.getName();
-
-			if ( "key".equals( name ) ) {
-				KeyValue keyVal;
-				String propRef = collection.getReferencedPropertyName();
-				if ( propRef == null ) {
-					keyVal = collection.getOwner().getIdentifier();
-				}
-				else {
-					keyVal = (KeyValue) collection.getOwner().getRecursiveProperty( propRef ).getValue();
-				}
-				SimpleValue key = new DependantValue( collection.getCollectionTable(), keyVal );
-				key.setCascadeDeleteEnabled( "cascade"
-					.equals( subnode.attributeValue( "on-delete" ) ) );
-				bindSimpleValue(
-						subnode,
-						key,
-						collection.isOneToMany(),
-						Collection.DEFAULT_KEY_COLUMN_NAME,
-						mappings
-					);
-				collection.setKey( key );
-
-				Attribute notNull = subnode.attribute( "not-null" );
-				( (DependantValue) key ).setNullable( notNull == null
-					|| notNull.getValue().equals( "false" ) );
-				Attribute updateable = subnode.attribute( "update" );
-				( (DependantValue) key ).setUpdateable( updateable == null
-					|| updateable.getValue().equals( "true" ) );
-
-			}
-			else if ( "element".equals( name ) ) {
-				SimpleValue elt = new SimpleValue( collection.getCollectionTable() );
-				collection.setElement( elt );
-				bindSimpleValue(
-						subnode,
-						elt,
-						true,
-						Collection.DEFAULT_ELEMENT_COLUMN_NAME,
-						mappings
-					);
-			}
-			else if ( "many-to-many".equals( name ) ) {
-				ManyToOne element = new ManyToOne( collection.getCollectionTable() );
-				collection.setElement( element );
-				bindManyToOne(
-						subnode,
-						element,
-						Collection.DEFAULT_ELEMENT_COLUMN_NAME,
-						false,
-						mappings
-					);
-				bindManyToManySubelements( collection, subnode, mappings );
-			}
-			else if ( "composite-element".equals( name ) ) {
-				Component element = new Component( collection );
-				collection.setElement( element );
-				bindComposite(
-						subnode,
-						element,
-						collection.getRole() + ".element",
-						true,
-						mappings,
-						inheritedMetas
-					);
-			}
-			else if ( "many-to-any".equals( name ) ) {
-				Any element = new Any( collection.getCollectionTable() );
-				collection.setElement( element );
-				bindAny( subnode, element, true, mappings );
-			}
-			else if ( "cache".equals( name ) ) {
-				collection.setCacheConcurrencyStrategy( subnode.attributeValue( "usage" ) );
-				collection.setCacheRegionName( subnode.attributeValue( "region" ) );
-			}
-
-			String nodeName = subnode.attributeValue( "node" );
-			if ( nodeName != null ) collection.setElementNodeName( nodeName );
-
-		}
-
-		if ( collection.isOneToMany()
-			&& !collection.isInverse()
-			&& !collection.getKey().isNullable() ) {
-			// for non-inverse one-to-many, with a not-null fk, add a backref!
-			String entityName = ( (OneToMany) collection.getElement() ).getReferencedEntityName();
-			PersistentClass referenced = mappings.getClass( entityName );
-			Backref prop = new Backref();
-			prop.setName( '_' + collection.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "Backref" );
-			prop.setUpdateable( false );
-			prop.setSelectable( false );
-			prop.setCollectionRole( collection.getRole() );
-			prop.setEntityName( collection.getOwner().getEntityName() );
-			prop.setValue( collection.getKey() );
-			referenced.addProperty( prop );
-		}
-	}
-
-	private static void bindManyToManySubelements(
-	        Collection collection,
-	        Element manyToManyNode,
-	        Mappings model) throws MappingException {
-		// Bind the where
-		Attribute where = manyToManyNode.attribute( "where" );
-		String whereCondition = where == null ? null : where.getValue();
-		collection.setManyToManyWhere( whereCondition );
-
-		// Bind the order-by
-		Attribute order = manyToManyNode.attribute( "order-by" );
-		String orderFragment = order == null ? null : order.getValue();
-		collection.setManyToManyOrdering( orderFragment );
-
-		// Bind the filters
-		Iterator filters = manyToManyNode.elementIterator( "filter" );
-		if ( ( filters.hasNext() || whereCondition != null ) &&
-		        collection.getFetchMode() == FetchMode.JOIN &&
-		        collection.getElement().getFetchMode() != FetchMode.JOIN ) {
-			throw new MappingException(
-			        "many-to-many defining filter or where without join fetching " +
-			        "not valid within collection using join fetching [" + collection.getRole() + "]"
-				);
-		}
-		while ( filters.hasNext() ) {
-			final Element filterElement = ( Element ) filters.next();
-			final String name = filterElement.attributeValue( "name" );
-			String condition = filterElement.getTextTrim();
-			if ( StringHelper.isEmpty(condition) ) condition = filterElement.attributeValue( "condition" );
-			if ( StringHelper.isEmpty(condition) ) {
-				condition = model.getFilterDefinition(name).getDefaultFilterCondition();
-			}
-			if ( condition==null) {
-				throw new MappingException("no filter condition found for filter: " + name);
-			}
-			log.debug(
-					"Applying many-to-many filter [" + name +
-					"] as [" + condition +
-					"] to role [" + collection.getRole() + "]"
-				);
-			collection.addManyToManyFilter( name, condition );
-		}
-	}
-
-	public static final FlushMode getFlushMode(String flushMode) {
-		if ( flushMode == null ) {
-			return null;
-		}
-		else if ( "auto".equals( flushMode ) ) {
-			return FlushMode.AUTO;
-		}
-		else if ( "commit".equals( flushMode ) ) {
-			return FlushMode.COMMIT;
-		}
-		else if ( "never".equals( flushMode ) ) {
-			return FlushMode.NEVER;
-		}
-		else if ( "manual".equals( flushMode ) ) {
-			return FlushMode.MANUAL;
-		}
-		else if ( "always".equals( flushMode ) ) {
-			return FlushMode.ALWAYS;
-		}
-		else {
-			throw new MappingException( "unknown flushmode" );
-		}
-	}
-
-	private static void bindNamedQuery(Element queryElem, String path, Mappings mappings) {
-		String queryName = queryElem.attributeValue( "name" );
-		if (path!=null) queryName = path + '.' + queryName;
-		String query = queryElem.getText();
-		log.debug( "Named query: " + queryName + " -> " + query );
-
-		boolean cacheable = "true".equals( queryElem.attributeValue( "cacheable" ) );
-		String region = queryElem.attributeValue( "cache-region" );
-		Attribute tAtt = queryElem.attribute( "timeout" );
-		Integer timeout = tAtt == null ? null : new Integer( tAtt.getValue() );
-		Attribute fsAtt = queryElem.attribute( "fetch-size" );
-		Integer fetchSize = fsAtt == null ? null : new Integer( fsAtt.getValue() );
-		Attribute roAttr = queryElem.attribute( "read-only" );
-		boolean readOnly = roAttr != null && "true".equals( roAttr.getValue() );
-		Attribute cacheModeAtt = queryElem.attribute( "cache-mode" );
-		String cacheMode = cacheModeAtt == null ? null : cacheModeAtt.getValue();
-		Attribute cmAtt = queryElem.attribute( "comment" );
-		String comment = cmAtt == null ? null : cmAtt.getValue();
-
-		NamedQueryDefinition namedQuery = new NamedQueryDefinition(
-				query,
-				cacheable,
-				region,
-				timeout,
-				fetchSize,
-				getFlushMode( queryElem.attributeValue( "flush-mode" ) ) ,
-				getCacheMode( cacheMode ),
-				readOnly,
-				comment,
-				getParameterTypes(queryElem)
-			);
-
-		mappings.addQuery( queryName, namedQuery );
-	}
-
-	public static CacheMode getCacheMode(String cacheMode) {
-		if (cacheMode == null) return null;
-		if ( "get".equals( cacheMode ) ) return CacheMode.GET;
-		if ( "ignore".equals( cacheMode ) ) return CacheMode.IGNORE;
-		if ( "normal".equals( cacheMode ) ) return CacheMode.NORMAL;
-		if ( "put".equals( cacheMode ) ) return CacheMode.PUT;
-		if ( "refresh".equals( cacheMode ) ) return CacheMode.REFRESH;
-		throw new MappingException("Unknown Cache Mode: " + cacheMode);
-	}
-
-	public static java.util.Map getParameterTypes(Element queryElem) {
-		java.util.Map result = new java.util.LinkedHashMap();
-		Iterator iter = queryElem.elementIterator("query-param");
-		while ( iter.hasNext() ) {
-			Element element = (Element) iter.next();
-			result.put( element.attributeValue("name"), element.attributeValue("type") );
-		}
-		return result;
-	}
-
-	private static void bindResultSetMappingDefinition(Element resultSetElem, String path, Mappings mappings) {
-		mappings.addSecondPass( new ResultSetMappingSecondPass( resultSetElem, path, mappings ) );
-	}
-
-	private static void bindNamedSQLQuery(Element queryElem, String path, Mappings mappings) {
-		mappings.addSecondPass( new NamedSQLQuerySecondPass( queryElem, path, mappings ) );
-	}
-
-	private static String getPropertyName(Element node) {
-		return node.attributeValue( "name" );
-	}
-
-	private static PersistentClass getSuperclass(Mappings mappings, Element subnode)
-			throws MappingException {
-		String extendsName = subnode.attributeValue( "extends" );
-		PersistentClass superModel = mappings.getClass( extendsName );
-		if ( superModel == null ) {
-			String qualifiedExtendsName = getClassName( extendsName, mappings );
-			superModel = mappings.getClass( qualifiedExtendsName );
-		}
-
-		if ( superModel == null ) {
-			throw new MappingException( "Cannot extend unmapped class " + extendsName );
-		}
-		return superModel;
-	}
-
-	static class CollectionSecondPass extends org.hibernate.cfg.CollectionSecondPass {
-		Element node;
-
-		CollectionSecondPass(Element node, Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
-			super(mappings, collection, inheritedMetas);
-			this.node = node;
-		}
-
-		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
-				throws MappingException {
-			HbmBinder.bindCollectionSecondPass(
-					node,
-					collection,
-					persistentClasses,
-					mappings,
-					inheritedMetas
-				);
-		}
-	}
-
-	static class IdentifierCollectionSecondPass extends CollectionSecondPass {
-		IdentifierCollectionSecondPass(Element node, Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
-			super( node, mappings, collection, inheritedMetas );
-		}
-
-		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
-				throws MappingException {
-			HbmBinder.bindIdentifierCollectionSecondPass(
-					node,
-					(IdentifierCollection) collection,
-					persistentClasses,
-					mappings,
-					inheritedMetas 
-				);
-		}
-
-	}
-
-	static class MapSecondPass extends CollectionSecondPass {
-		MapSecondPass(Element node, Mappings mappings, Map collection, java.util.Map inheritedMetas) {
-			super( node, mappings, collection, inheritedMetas );
-		}
-
-		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
-				throws MappingException {
-			HbmBinder.bindMapSecondPass(
-					node,
-					(Map) collection,
-					persistentClasses,
-					mappings,
-					inheritedMetas 
-				);
-		}
-
-	}
-
-
-	static class ManyToOneSecondPass implements SecondPass {
-		private final ManyToOne manyToOne;
-
-		ManyToOneSecondPass(ManyToOne manyToOne) {
-			this.manyToOne = manyToOne;
-		}
-
-		public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
-			manyToOne.createPropertyRefConstraints(persistentClasses);
-		}
-
-	}
-	
-	static class ListSecondPass extends CollectionSecondPass {
-		ListSecondPass(Element node, Mappings mappings, List collection, java.util.Map inheritedMetas) {
-			super( node, mappings, collection, inheritedMetas );
-		}
-
-		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
-				throws MappingException {
-			HbmBinder.bindListSecondPass(
-					node,
-					(List) collection,
-					persistentClasses,
-					mappings,
-					inheritedMetas 
-				);
-		}
-
-	}
-
-	// This inner class implements a case statement....perhaps im being a bit over-clever here
-	abstract static class CollectionType {
-		private String xmlTag;
-
-		public abstract Collection create(Element node, String path, PersistentClass owner,
-				Mappings mappings, java.util.Map inheritedMetas) throws MappingException;
-
-		CollectionType(String xmlTag) {
-			this.xmlTag = xmlTag;
-		}
-
-		public String toString() {
-			return xmlTag;
-		}
-
-		private static final CollectionType MAP = new CollectionType( "map" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				Map map = new Map( owner );
-				bindCollection( node, map, owner.getEntityName(), path, mappings, inheritedMetas );
-				return map;
-			}
-		};
-		private static final CollectionType SET = new CollectionType( "set" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				Set set = new Set( owner );
-				bindCollection( node, set, owner.getEntityName(), path, mappings, inheritedMetas );
-				return set;
-			}
-		};
-		private static final CollectionType LIST = new CollectionType( "list" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				List list = new List( owner );
-				bindCollection( node, list, owner.getEntityName(), path, mappings, inheritedMetas );
-				return list;
-			}
-		};
-		private static final CollectionType BAG = new CollectionType( "bag" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				Bag bag = new Bag( owner );
-				bindCollection( node, bag, owner.getEntityName(), path, mappings, inheritedMetas );
-				return bag;
-			}
-		};
-		private static final CollectionType IDBAG = new CollectionType( "idbag" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				IdentifierBag bag = new IdentifierBag( owner );
-				bindCollection( node, bag, owner.getEntityName(), path, mappings, inheritedMetas );
-				return bag;
-			}
-		};
-		private static final CollectionType ARRAY = new CollectionType( "array" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				Array array = new Array( owner );
-				bindArray( node, array, owner.getEntityName(), path, mappings, inheritedMetas );
-				return array;
-			}
-		};
-		private static final CollectionType PRIMITIVE_ARRAY = new CollectionType( "primitive-array" ) {
-			public Collection create(Element node, String path, PersistentClass owner,
-					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
-				PrimitiveArray array = new PrimitiveArray( owner );
-				bindArray( node, array, owner.getEntityName(), path, mappings, inheritedMetas );
-				return array;
-			}
-		};
-		private static final HashMap INSTANCES = new HashMap();
-
-		static {
-			INSTANCES.put( MAP.toString(), MAP );
-			INSTANCES.put( BAG.toString(), BAG );
-			INSTANCES.put( IDBAG.toString(), IDBAG );
-			INSTANCES.put( SET.toString(), SET );
-			INSTANCES.put( LIST.toString(), LIST );
-			INSTANCES.put( ARRAY.toString(), ARRAY );
-			INSTANCES.put( PRIMITIVE_ARRAY.toString(), PRIMITIVE_ARRAY );
-		}
-
-		public static CollectionType collectionTypeFromString(String xmlTagName) {
-			return (CollectionType) INSTANCES.get( xmlTagName );
-		}
-	}
-
-	private static int getOptimisticLockMode(Attribute olAtt) throws MappingException {
-
-		if ( olAtt == null ) return Versioning.OPTIMISTIC_LOCK_VERSION;
-		String olMode = olAtt.getValue();
-		if ( olMode == null || "version".equals( olMode ) ) {
-			return Versioning.OPTIMISTIC_LOCK_VERSION;
-		}
-		else if ( "dirty".equals( olMode ) ) {
-			return Versioning.OPTIMISTIC_LOCK_DIRTY;
-		}
-		else if ( "all".equals( olMode ) ) {
-			return Versioning.OPTIMISTIC_LOCK_ALL;
-		}
-		else if ( "none".equals( olMode ) ) {
-			return Versioning.OPTIMISTIC_LOCK_NONE;
-		}
-		else {
-			throw new MappingException( "Unsupported optimistic-lock style: " + olMode );
-		}
-	}
-
-	private static final java.util.Map getMetas(Element node, java.util.Map inheritedMeta) {
-		return getMetas( node, inheritedMeta, false );
-	}
-
-	public static final java.util.Map getMetas(Element node, java.util.Map inheritedMeta,
-			boolean onlyInheritable) {
-		java.util.Map map = new HashMap();
-		map.putAll( inheritedMeta );
-
-		Iterator iter = node.elementIterator( "meta" );
-		while ( iter.hasNext() ) {
-			Element metaNode = (Element) iter.next();
-			boolean inheritable = Boolean
-				.valueOf( metaNode.attributeValue( "inherit" ) )
-				.booleanValue();
-			if ( onlyInheritable & !inheritable ) {
-				continue;
-			}
-			String name = metaNode.attributeValue( "attribute" );
-
-			MetaAttribute meta = (MetaAttribute) map.get( name );
-			MetaAttribute inheritedAttribute = (MetaAttribute) inheritedMeta.get( name );
-			if ( meta == null  ) {
-				meta = new MetaAttribute( name );
-				map.put( name, meta );
-			} else if (meta == inheritedAttribute) { // overriding inherited meta attribute. HBX-621 & HBX-793			
-				meta = new MetaAttribute( name );				
-				map.put( name, meta );				
-			}			
-			meta.addValue( metaNode.getText() );
-		}
-		return map;
-	}
-
-	public static String getEntityName(Element elem, Mappings model) {
-		String entityName = elem.attributeValue( "entity-name" );
-		return entityName == null ? getClassName( elem.attribute( "class" ), model ) : entityName;
-	}
-
-	private static String getClassName(Attribute att, Mappings model) {
-		if ( att == null ) return null;
-		return getClassName( att.getValue(), model );
-	}
-
-	public static String getClassName(String unqualifiedName, Mappings model) {
-		return getClassName( unqualifiedName, model.getDefaultPackage() );
-	}
-
-	public static String getClassName(String unqualifiedName, String defaultPackage) {
-		if ( unqualifiedName == null ) return null;
-		if ( unqualifiedName.indexOf( '.' ) < 0 && defaultPackage != null ) {
-			return defaultPackage + '.' + unqualifiedName;
-		}
-		return unqualifiedName;
-	}
-
-	private static void parseFilterDef(Element element, Mappings mappings) {
-		String name = element.attributeValue( "name" );
-		log.debug( "Parsing filter-def [" + name + "]" );
-		String defaultCondition = element.getTextTrim();
-		if ( StringHelper.isEmpty( defaultCondition ) ) {
-			defaultCondition = element.attributeValue( "condition" );
-		}
-		HashMap paramMappings = new HashMap();
-		Iterator params = element.elementIterator( "filter-param" );
-		while ( params.hasNext() ) {
-			final Element param = (Element) params.next();
-			final String paramName = param.attributeValue( "name" );
-			final String paramType = param.attributeValue( "type" );
-			log.debug( "adding filter parameter : " + paramName + " -> " + paramType );
-			final Type heuristicType = TypeFactory.heuristicType( paramType );
-			log.debug( "parameter heuristic type : " + heuristicType );
-			paramMappings.put( paramName, heuristicType );
-		}
-		log.debug( "Parsed filter-def [" + name + "]" );
-		FilterDefinition def = new FilterDefinition( name, defaultCondition, paramMappings );
-		mappings.addFilterDefinition( def );
-	}
-
-	private static void parseFilter(Element filterElement, Filterable filterable, Mappings model) {
-		final String name = filterElement.attributeValue( "name" );
-		String condition = filterElement.getTextTrim();
-		if ( StringHelper.isEmpty(condition) ) {
-			condition = filterElement.attributeValue( "condition" );
-		}
-		//TODO: bad implementation, cos it depends upon ordering of mapping doc
-		//      fixing this requires that Collection/PersistentClass gain access
-		//      to the Mappings reference from Configuration (or the filterDefinitions
-		//      map directly) sometime during Configuration.buildSessionFactory
-		//      (after all the types/filter-defs are known and before building
-		//      persisters).
-		if ( StringHelper.isEmpty(condition) ) {
-			condition = model.getFilterDefinition(name).getDefaultFilterCondition();
-		}
-		if ( condition==null) {
-			throw new MappingException("no filter condition found for filter: " + name);
-		}
-		log.debug( "Applying filter [" + name + "] as [" + condition + "]" );
-		filterable.addFilter( name, condition );
-	}
-
-	private static String getSubselect(Element element) {
-		String subselect = element.attributeValue( "subselect" );
-		if ( subselect != null ) {
-			return subselect;
-		}
-		else {
-			Element subselectElement = element.element( "subselect" );
-			return subselectElement == null ? null : subselectElement.getText();
-		}
-	}
-
-	/**
-	 * For the given document, locate all extends attributes which refer to
-	 * entities (entity-name or class-name) not defined within said document.
-	 *
-	 * @param doc The document to check
-	 * @param mappings The already processed mappings.
-	 * @return The list of unresolved extends names.
-	 */
-	public static java.util.List getExtendsNeeded(Document doc, Mappings mappings) {
-		java.util.List extendz = new ArrayList();
-		Iterator[] subclasses = new Iterator[3];
-		final Element hmNode = doc.getRootElement();
-
-		Attribute packNode = hmNode.attribute( "package" );
-		final String packageName = packNode == null ? null : packNode.getValue();
-		if ( packageName != null ) {
-			mappings.setDefaultPackage( packageName );
-		}
-
-		// first, iterate over all elements capable of defining an extends attribute
-		// collecting all found extends references if they cannot be resolved
-		// against the already processed mappings.
-		subclasses[0] = hmNode.elementIterator( "subclass" );
-		subclasses[1] = hmNode.elementIterator( "joined-subclass" );
-		subclasses[2] = hmNode.elementIterator( "union-subclass" );
-
-		Iterator iterator = new JoinedIterator( subclasses );
-		while ( iterator.hasNext() ) {
-			final Element element = (Element) iterator.next();
-			final String extendsName = element.attributeValue( "extends" );
-			// mappings might contain either the "raw" extends name (in the case of
-			// an entity-name mapping) or a FQN (in the case of a POJO mapping).
-			if ( mappings.getClass( extendsName ) == null && mappings.getClass( getClassName( extendsName, mappings ) ) == null ) {
-				extendz.add( extendsName );
-			}
-		}
-
-		if ( !extendz.isEmpty() ) {
-			// we found some extends attributes referencing entities which were
-			// not already processed.  here we need to locate all entity-names
-			// and class-names contained in this document itself, making sure
-			// that these get removed from the extendz list such that only
-			// extends names which require us to delay processing (i.e.
-			// external to this document and not yet processed) are contained
-			// in the returned result
-			final java.util.Set set = new HashSet( extendz );
-			EntityElementHandler handler = new EntityElementHandler() {
-				public void handleEntity(String entityName, String className, Mappings mappings) {
-					if ( entityName != null ) {
-						set.remove( entityName );
-					}
-					else {
-						String fqn = getClassName( className, packageName );
-						set.remove( fqn );
-						if ( packageName != null ) {
-							set.remove( StringHelper.unqualify( fqn ) );
-						}
-					}
-				}
-			};
-			recognizeEntities( mappings, hmNode, handler );
-			extendz.clear();
-			extendz.addAll( set );
-		}
-
-		return extendz;
-	}
-
-	/**
-	 * Given an entity-containing-element (startNode) recursively locate all
-	 * entity names defined within that element.
-	 *
-	 * @param mappings The already processed mappings
-	 * @param startNode The containing element
-	 * @param handler The thing that knows what to do whenever we recognize an
-	 * entity-name
-	 */
-	private static void recognizeEntities(
-			Mappings mappings,
-	        final Element startNode,
-			EntityElementHandler handler) {
-		Iterator[] classes = new Iterator[4];
-		classes[0] = startNode.elementIterator( "class" );
-		classes[1] = startNode.elementIterator( "subclass" );
-		classes[2] = startNode.elementIterator( "joined-subclass" );
-		classes[3] = startNode.elementIterator( "union-subclass" );
-
-		Iterator classIterator = new JoinedIterator( classes );
-		while ( classIterator.hasNext() ) {
-			Element element = (Element) classIterator.next();
-			handler.handleEntity(
-					element.attributeValue( "entity-name" ),
-		            element.attributeValue( "name" ),
-			        mappings
-			);
-			recognizeEntities( mappings, element, handler );
-		}
-	}
-
-	private static interface EntityElementHandler {
-		public void handleEntity(String entityName, String className, Mappings mappings);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/HbmBinder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/HbmBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,3079 @@
+/*
+ * 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.cfg;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.dom4j.Attribute;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.hibernate.CacheMode;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.FlushMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.Versioning;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.mapping.Any;
+import org.hibernate.mapping.Array;
+import org.hibernate.mapping.AuxiliaryDatabaseObject;
+import org.hibernate.mapping.Backref;
+import org.hibernate.mapping.Bag;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.DependantValue;
+import org.hibernate.mapping.Fetchable;
+import org.hibernate.mapping.Filterable;
+import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.IdentifierBag;
+import org.hibernate.mapping.IdentifierCollection;
+import org.hibernate.mapping.IndexBackref;
+import org.hibernate.mapping.IndexedCollection;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.JoinedSubclass;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.List;
+import org.hibernate.mapping.ManyToOne;
+import org.hibernate.mapping.Map;
+import org.hibernate.mapping.MetaAttribute;
+import org.hibernate.mapping.OneToMany;
+import org.hibernate.mapping.OneToOne;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.PrimitiveArray;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.PropertyGeneration;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.Set;
+import org.hibernate.mapping.SimpleAuxiliaryDatabaseObject;
+import org.hibernate.mapping.SimpleValue;
+import org.hibernate.mapping.SingleTableSubclass;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.mapping.TypeDef;
+import org.hibernate.mapping.UnionSubclass;
+import org.hibernate.mapping.UniqueKey;
+import org.hibernate.mapping.Value;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+import org.hibernate.type.DiscriminatorType;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Walks an XML mapping document and produces the Hibernate configuration-time metamodel (the
+ * classes in the <tt>mapping</tt> package)
+ *
+ * @author Gavin King
+ */
+public final class HbmBinder {
+
+	private static final Logger log = LoggerFactory.getLogger( HbmBinder.class );
+
+	/**
+	 * Private constructor to disallow instantiation.
+	 */
+	private HbmBinder() {
+	}
+
+	/**
+	 * The main contract into the hbm.xml-based binder. Performs necessary binding operations
+	 * represented by the given DOM.
+	 *
+	 * @param doc The DOM to be parsed and bound.
+	 * @param mappings Current bind state.
+	 * @param inheritedMetas Any inherited meta-tag information.
+	 * @throws MappingException
+	 */
+	public static void bindRoot(Document doc, Mappings mappings, java.util.Map inheritedMetas)
+			throws MappingException {
+
+		java.util.List names = HbmBinder.getExtendsNeeded( doc, mappings );
+		if ( !names.isEmpty() ) {
+			// classes mentioned in extends not available - so put it in queue
+			Element hmNode = doc.getRootElement();
+			Attribute packNode = hmNode.attribute( "package" );
+			String packageName = null;
+			if ( packNode != null ) {
+				packageName = packNode.getValue();
+			}
+			Iterator itr = names.iterator();
+			while ( itr.hasNext() ) {
+				String extendsName = (String) itr.next();
+				mappings.addToExtendsQueue( new ExtendsQueueEntry( extendsName, packageName, doc ) );
+			}
+			return;
+		}
+
+		Element hmNode = doc.getRootElement();
+		// get meta's from <hibernate-mapping>
+		inheritedMetas = getMetas( hmNode, inheritedMetas, true );
+		extractRootAttributes( hmNode, mappings );
+
+		Iterator rootChildren = hmNode.elementIterator();
+		while ( rootChildren.hasNext() ) {
+			final Element element = (Element) rootChildren.next();
+			final String elementName = element.getName();
+
+			if ( "filter-def".equals( elementName ) ) {
+				parseFilterDef( element, mappings );
+			}
+			else if ( "typedef".equals( elementName ) ) {
+				bindTypeDef( element, mappings );
+			}
+			else if ( "class".equals( elementName ) ) {
+				RootClass rootclass = new RootClass();
+				bindRootClass( element, rootclass, mappings, inheritedMetas );
+				mappings.addClass( rootclass );
+			}
+			else if ( "subclass".equals( elementName ) ) {
+				PersistentClass superModel = getSuperclass( mappings, element );
+				handleSubclass( superModel, mappings, element, inheritedMetas );
+			}
+			else if ( "joined-subclass".equals( elementName ) ) {
+				PersistentClass superModel = getSuperclass( mappings, element );
+				handleJoinedSubclass( superModel, mappings, element, inheritedMetas );
+			}
+			else if ( "union-subclass".equals( elementName ) ) {
+				PersistentClass superModel = getSuperclass( mappings, element );
+				handleUnionSubclass( superModel, mappings, element, inheritedMetas );
+			}
+			else if ( "query".equals( elementName ) ) {
+				bindNamedQuery( element, null, mappings );
+			}
+			else if ( "sql-query".equals( elementName ) ) {
+				bindNamedSQLQuery( element, null, mappings );
+			}
+			else if ( "resultset".equals( elementName ) ) {
+				bindResultSetMappingDefinition( element, null, mappings );
+			}
+			else if ( "import".equals( elementName ) ) {
+				bindImport( element, mappings );
+			}
+			else if ( "database-object".equals( elementName ) ) {
+				bindAuxiliaryDatabaseObject( element, mappings );
+			}
+		}
+	}
+
+	private static void bindImport(Element importNode, Mappings mappings) {
+		String className = getClassName( importNode.attribute( "class" ), mappings );
+		Attribute renameNode = importNode.attribute( "rename" );
+		String rename = ( renameNode == null ) ?
+						StringHelper.unqualify( className ) :
+						renameNode.getValue();
+		log.debug( "Import: " + rename + " -> " + className );
+		mappings.addImport( className, rename );
+	}
+
+	private static void bindTypeDef(Element typedefNode, Mappings mappings) {
+		String typeClass = typedefNode.attributeValue( "class" );
+		String typeName = typedefNode.attributeValue( "name" );
+		Iterator paramIter = typedefNode.elementIterator( "param" );
+		Properties parameters = new Properties();
+		while ( paramIter.hasNext() ) {
+			Element param = (Element) paramIter.next();
+			parameters.setProperty( param.attributeValue( "name" ), param.getTextTrim() );
+		}
+		mappings.addTypeDef( typeName, typeClass, parameters );
+	}
+
+	private static void bindAuxiliaryDatabaseObject(Element auxDbObjectNode, Mappings mappings) {
+		AuxiliaryDatabaseObject auxDbObject = null;
+		Element definitionNode = auxDbObjectNode.element( "definition" );
+		if ( definitionNode != null ) {
+			try {
+				auxDbObject = ( AuxiliaryDatabaseObject ) ReflectHelper
+						.classForName( definitionNode.attributeValue( "class" ) )
+						.newInstance();
+			}
+			catch( ClassNotFoundException e ) {
+				throw new MappingException(
+						"could not locate custom database object class [" +
+						definitionNode.attributeValue( "class" ) + "]"
+					);
+			}
+			catch( Throwable t ) {
+				throw new MappingException(
+						"could not instantiate custom database object class [" +
+						definitionNode.attributeValue( "class" ) + "]"
+					);
+			}
+		}
+		else {
+			auxDbObject = new SimpleAuxiliaryDatabaseObject(
+					auxDbObjectNode.elementTextTrim( "create" ),
+					auxDbObjectNode.elementTextTrim( "drop" )
+				);
+		}
+
+		Iterator dialectScopings = auxDbObjectNode.elementIterator( "dialect-scope" );
+		while ( dialectScopings.hasNext() ) {
+			Element dialectScoping = ( Element ) dialectScopings.next();
+			auxDbObject.addDialectScope( dialectScoping.attributeValue( "name" ) );
+		}
+
+		mappings.addAuxiliaryDatabaseObject( auxDbObject );
+	}
+
+	private static void extractRootAttributes(Element hmNode, Mappings mappings) {
+		Attribute schemaNode = hmNode.attribute( "schema" );
+		mappings.setSchemaName( ( schemaNode == null ) ? null : schemaNode.getValue() );
+
+		Attribute catalogNode = hmNode.attribute( "catalog" );
+		mappings.setCatalogName( ( catalogNode == null ) ? null : catalogNode.getValue() );
+
+		Attribute dcNode = hmNode.attribute( "default-cascade" );
+		mappings.setDefaultCascade( ( dcNode == null ) ? "none" : dcNode.getValue() );
+
+		Attribute daNode = hmNode.attribute( "default-access" );
+		mappings.setDefaultAccess( ( daNode == null ) ? "property" : daNode.getValue() );
+
+		Attribute dlNode = hmNode.attribute( "default-lazy" );
+		mappings.setDefaultLazy( dlNode == null || dlNode.getValue().equals( "true" ) );
+
+		Attribute aiNode = hmNode.attribute( "auto-import" );
+		mappings.setAutoImport( ( aiNode == null ) || "true".equals( aiNode.getValue() ) );
+
+		Attribute packNode = hmNode.attribute( "package" );
+		if ( packNode != null ) mappings.setDefaultPackage( packNode.getValue() );
+	}
+
+	/**
+	 * Responsible for perfoming the bind operation related to an &lt;class/&gt; mapping element.
+	 *
+	 * @param node The DOM Element for the &lt;class/&gt; element.
+	 * @param rootClass The mapping instance to which to bind the information.
+	 * @param mappings The current bind state.
+	 * @param inheritedMetas Any inherited meta-tag information.
+	 * @throws MappingException
+	 */
+	public static void bindRootClass(Element node, RootClass rootClass, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+		bindClass( node, rootClass, mappings, inheritedMetas );
+		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <class>
+		bindRootPersistentClassCommonValues( node, inheritedMetas, mappings, rootClass );
+	}
+
+	private static void bindRootPersistentClassCommonValues(Element node,
+			java.util.Map inheritedMetas, Mappings mappings, RootClass entity)
+			throws MappingException {
+
+		// DB-OBJECTNAME
+
+		Attribute schemaNode = node.attribute( "schema" );
+		String schema = schemaNode == null ?
+				mappings.getSchemaName() : schemaNode.getValue();
+
+		Attribute catalogNode = node.attribute( "catalog" );
+		String catalog = catalogNode == null ?
+				mappings.getCatalogName() : catalogNode.getValue();
+
+		Table table = mappings.addTable(
+				schema,
+				catalog,
+				getClassTableName( entity, node, schema, catalog, null, mappings ),
+				getSubselect( node ),
+		        entity.isAbstract() != null && entity.isAbstract().booleanValue()
+			);
+		entity.setTable( table );
+		bindComment(table, node);
+
+		log.info(
+				"Mapping class: " + entity.getEntityName() +
+				" -> " + entity.getTable().getName()
+			);
+
+		// MUTABLE
+		Attribute mutableNode = node.attribute( "mutable" );
+		entity.setMutable( ( mutableNode == null ) || mutableNode.getValue().equals( "true" ) );
+
+		// WHERE
+		Attribute whereNode = node.attribute( "where" );
+		if ( whereNode != null ) entity.setWhere( whereNode.getValue() );
+
+		// CHECK
+		Attribute chNode = node.attribute( "check" );
+		if ( chNode != null ) table.addCheckConstraint( chNode.getValue() );
+
+		// POLYMORPHISM
+		Attribute polyNode = node.attribute( "polymorphism" );
+		entity.setExplicitPolymorphism( ( polyNode != null )
+			&& polyNode.getValue().equals( "explicit" ) );
+
+		// ROW ID
+		Attribute rowidNode = node.attribute( "rowid" );
+		if ( rowidNode != null ) table.setRowId( rowidNode.getValue() );
+
+		Iterator subnodes = node.elementIterator();
+		while ( subnodes.hasNext() ) {
+
+			Element subnode = (Element) subnodes.next();
+			String name = subnode.getName();
+
+			if ( "id".equals( name ) ) {
+				// ID
+				bindSimpleId( subnode, entity, mappings, inheritedMetas );
+			}
+			else if ( "composite-id".equals( name ) ) {
+				// COMPOSITE-ID
+				bindCompositeId( subnode, entity, mappings, inheritedMetas );
+			}
+			else if ( "version".equals( name ) || "timestamp".equals( name ) ) {
+				// VERSION / TIMESTAMP
+				bindVersioningProperty( table, subnode, mappings, name, entity, inheritedMetas );
+			}
+			else if ( "discriminator".equals( name ) ) {
+				// DISCRIMINATOR
+				bindDiscriminatorProperty( table, entity, subnode, mappings );
+			}
+			else if ( "cache".equals( name ) ) {
+				entity.setCacheConcurrencyStrategy( subnode.attributeValue( "usage" ) );
+				entity.setCacheRegionName( subnode.attributeValue( "region" ) );
+				entity.setLazyPropertiesCacheable( !"non-lazy".equals( subnode.attributeValue( "include" ) ) );
+			}
+
+		}
+
+		// Primary key constraint
+		entity.createPrimaryKey();
+
+		createClassProperties( node, entity, mappings, inheritedMetas );
+	}
+
+	private static void bindSimpleId(Element idNode, RootClass entity, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+		String propertyName = idNode.attributeValue( "name" );
+
+		SimpleValue id = new SimpleValue( entity.getTable() );
+		entity.setIdentifier( id );
+
+		// if ( propertyName == null || entity.getPojoRepresentation() == null ) {
+		// bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
+		// if ( !id.isTypeSpecified() ) {
+		// throw new MappingException( "must specify an identifier type: " + entity.getEntityName()
+		// );
+		// }
+		// }
+		// else {
+		// bindSimpleValue( idNode, id, false, propertyName, mappings );
+		// PojoRepresentation pojo = entity.getPojoRepresentation();
+		// id.setTypeUsingReflection( pojo.getClassName(), propertyName );
+		//
+		// Property prop = new Property();
+		// prop.setValue( id );
+		// bindProperty( idNode, prop, mappings, inheritedMetas );
+		// entity.setIdentifierProperty( prop );
+		// }
+
+		if ( propertyName == null ) {
+			bindSimpleValue( idNode, id, false, RootClass.DEFAULT_IDENTIFIER_COLUMN_NAME, mappings );
+		}
+		else {
+			bindSimpleValue( idNode, id, false, propertyName, mappings );
+		}
+
+		if ( propertyName == null || !entity.hasPojoRepresentation() ) {
+			if ( !id.isTypeSpecified() ) {
+				throw new MappingException( "must specify an identifier type: "
+					+ entity.getEntityName() );
+			}
+		}
+		else {
+			id.setTypeUsingReflection( entity.getClassName(), propertyName );
+		}
+
+		if ( propertyName != null ) {
+			Property prop = new Property();
+			prop.setValue( id );
+			bindProperty( idNode, prop, mappings, inheritedMetas );
+			entity.setIdentifierProperty( prop );
+		}
+
+		// TODO:
+		/*
+		 * if ( id.getHibernateType().getReturnedClass().isArray() ) throw new MappingException(
+		 * "illegal use of an array as an identifier (arrays don't reimplement equals)" );
+		 */
+		makeIdentifier( idNode, id, mappings );
+	}
+
+	private static void bindCompositeId(Element idNode, RootClass entity, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+		String propertyName = idNode.attributeValue( "name" );
+		Component id = new Component( entity );
+		entity.setIdentifier( id );
+		bindCompositeId( idNode, id, entity, propertyName, mappings, inheritedMetas );
+		if ( propertyName == null ) {
+			entity.setEmbeddedIdentifier( id.isEmbedded() );
+			if ( id.isEmbedded() ) {
+				// todo : what is the implication of this?
+				id.setDynamic( !entity.hasPojoRepresentation() );
+				/*
+				 * Property prop = new Property(); prop.setName("id");
+				 * prop.setPropertyAccessorName("embedded"); prop.setValue(id);
+				 * entity.setIdentifierProperty(prop);
+				 */
+			}
+		}
+		else {
+			Property prop = new Property();
+			prop.setValue( id );
+			bindProperty( idNode, prop, mappings, inheritedMetas );
+			entity.setIdentifierProperty( prop );
+		}
+
+		makeIdentifier( idNode, id, mappings );
+
+	}
+
+	private static void bindVersioningProperty(Table table, Element subnode, Mappings mappings,
+			String name, RootClass entity, java.util.Map inheritedMetas) {
+
+		String propertyName = subnode.attributeValue( "name" );
+		SimpleValue val = new SimpleValue( table );
+		bindSimpleValue( subnode, val, false, propertyName, mappings );
+		if ( !val.isTypeSpecified() ) {
+			// this is either a <version/> tag with no type attribute,
+			// or a <timestamp/> tag
+			if ( "version".equals( name ) ) {
+				val.setTypeName( "integer" );
+			}
+			else {
+				if ( "db".equals( subnode.attributeValue( "source" ) ) ) {
+					val.setTypeName( "dbtimestamp" );
+				}
+				else {
+					val.setTypeName( "timestamp" );
+				}
+			}
+		}
+		Property prop = new Property();
+		prop.setValue( val );
+		bindProperty( subnode, prop, mappings, inheritedMetas );
+		// for version properties marked as being generated, make sure they are "always"
+		// generated; aka, "insert" is invalid; this is dis-allowed by the DTD,
+		// but just to make sure...
+		if ( prop.getGeneration() == PropertyGeneration.INSERT ) {
+			throw new MappingException( "'generated' attribute cannot be 'insert' for versioning property" );
+		}
+		makeVersion( subnode, val );
+		entity.setVersion( prop );
+		entity.addProperty( prop );
+	}
+
+	private static void bindDiscriminatorProperty(Table table, RootClass entity, Element subnode,
+			Mappings mappings) {
+		SimpleValue discrim = new SimpleValue( table );
+		entity.setDiscriminator( discrim );
+		bindSimpleValue(
+				subnode,
+				discrim,
+				false,
+				RootClass.DEFAULT_DISCRIMINATOR_COLUMN_NAME,
+				mappings
+			);
+		if ( !discrim.isTypeSpecified() ) {
+			discrim.setTypeName( "string" );
+			// ( (Column) discrim.getColumnIterator().next() ).setType(type);
+		}
+		entity.setPolymorphic( true );
+		if ( "true".equals( subnode.attributeValue( "force" ) ) )
+			entity.setForceDiscriminator( true );
+		if ( "false".equals( subnode.attributeValue( "insert" ) ) )
+			entity.setDiscriminatorInsertable( false );
+	}
+
+	public static void bindClass(Element node, PersistentClass persistentClass, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+		// transfer an explicitly defined entity name
+		// handle the lazy attribute
+		Attribute lazyNode = node.attribute( "lazy" );
+		boolean lazy = lazyNode == null ?
+				mappings.isDefaultLazy() :
+				"true".equals( lazyNode.getValue() );
+		// go ahead and set the lazy here, since pojo.proxy can override it.
+		persistentClass.setLazy( lazy );
+
+		String entityName = node.attributeValue( "entity-name" );
+		if ( entityName == null ) entityName = getClassName( node.attribute("name"), mappings );
+		if ( entityName==null ) {
+			throw new MappingException( "Unable to determine entity name" );
+		}
+		persistentClass.setEntityName( entityName );
+
+		bindPojoRepresentation( node, persistentClass, mappings, inheritedMetas );
+		bindDom4jRepresentation( node, persistentClass, mappings, inheritedMetas );
+		bindMapRepresentation( node, persistentClass, mappings, inheritedMetas );
+
+		bindPersistentClassCommonValues( node, persistentClass, mappings, inheritedMetas );
+
+	}
+
+	private static void bindPojoRepresentation(Element node, PersistentClass entity,
+			Mappings mappings, java.util.Map metaTags) {
+
+		String className = getClassName( node.attribute( "name" ), mappings );
+		String proxyName = getClassName( node.attribute( "proxy" ), mappings );
+
+		entity.setClassName( className );
+
+		if ( proxyName != null ) {
+			entity.setProxyInterfaceName( proxyName );
+			entity.setLazy( true );
+		}
+		else if ( entity.isLazy() ) {
+			entity.setProxyInterfaceName( className );
+		}
+
+		Element tuplizer = locateTuplizerDefinition( node, EntityMode.POJO );
+		if ( tuplizer != null ) {
+			entity.addTuplizer( EntityMode.POJO, tuplizer.attributeValue( "class" ) );
+		}
+	}
+
+	private static void bindDom4jRepresentation(Element node, PersistentClass entity,
+			Mappings mappings, java.util.Map inheritedMetas) {
+		String nodeName = node.attributeValue( "node" );
+		if (nodeName==null) nodeName = StringHelper.unqualify( entity.getEntityName() );
+		entity.setNodeName(nodeName);
+
+		Element tuplizer = locateTuplizerDefinition( node, EntityMode.DOM4J );
+		if ( tuplizer != null ) {
+			entity.addTuplizer( EntityMode.DOM4J, tuplizer.attributeValue( "class" ) );
+		}
+	}
+
+	private static void bindMapRepresentation(Element node, PersistentClass entity,
+			Mappings mappings, java.util.Map inheritedMetas) {
+		Element tuplizer = locateTuplizerDefinition( node, EntityMode.MAP );
+		if ( tuplizer != null ) {
+			entity.addTuplizer( EntityMode.MAP, tuplizer.attributeValue( "class" ) );
+		}
+	}
+
+	/**
+	 * Locate any explicit tuplizer definition in the metadata, for the given entity-mode.
+	 *
+	 * @param container The containing element (representing the entity/component)
+	 * @param entityMode The entity-mode for which to locate the tuplizer element
+	 * @return The tuplizer element, or null.
+	 */
+	private static Element locateTuplizerDefinition(Element container, EntityMode entityMode) {
+		Iterator itr = container.elements( "tuplizer" ).iterator();
+		while( itr.hasNext() ) {
+			final Element tuplizerElem = ( Element ) itr.next();
+			if ( entityMode.toString().equals( tuplizerElem.attributeValue( "entity-mode") ) ) {
+				return tuplizerElem;
+			}
+		}
+		return null;
+	}
+
+	private static void bindPersistentClassCommonValues(Element node, PersistentClass entity,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+		// DISCRIMINATOR
+		Attribute discriminatorNode = node.attribute( "discriminator-value" );
+		entity.setDiscriminatorValue( ( discriminatorNode == null )
+			? entity.getEntityName()
+			: discriminatorNode.getValue() );
+
+		// DYNAMIC UPDATE
+		Attribute dynamicNode = node.attribute( "dynamic-update" );
+		entity.setDynamicUpdate(
+				dynamicNode != null && "true".equals( dynamicNode.getValue() )
+		);
+
+		// DYNAMIC INSERT
+		Attribute insertNode = node.attribute( "dynamic-insert" );
+		entity.setDynamicInsert(
+				insertNode != null && "true".equals( insertNode.getValue() )
+		);
+
+		// IMPORT
+		mappings.addImport( entity.getEntityName(), entity.getEntityName() );
+		if ( mappings.isAutoImport() && entity.getEntityName().indexOf( '.' ) > 0 ) {
+			mappings.addImport(
+					entity.getEntityName(),
+					StringHelper.unqualify( entity.getEntityName() )
+				);
+		}
+
+		// BATCH SIZE
+		Attribute batchNode = node.attribute( "batch-size" );
+		if ( batchNode != null ) entity.setBatchSize( Integer.parseInt( batchNode.getValue() ) );
+
+		// SELECT BEFORE UPDATE
+		Attribute sbuNode = node.attribute( "select-before-update" );
+		if ( sbuNode != null ) entity.setSelectBeforeUpdate( "true".equals( sbuNode.getValue() ) );
+
+		// OPTIMISTIC LOCK MODE
+		Attribute olNode = node.attribute( "optimistic-lock" );
+		entity.setOptimisticLockMode( getOptimisticLockMode( olNode ) );
+
+		entity.setMetaAttributes( getMetas( node, inheritedMetas ) );
+
+		// PERSISTER
+		Attribute persisterNode = node.attribute( "persister" );
+		if ( persisterNode != null ) {
+			try {
+				entity.setEntityPersisterClass( ReflectHelper.classForName( persisterNode
+					.getValue() ) );
+			}
+			catch (ClassNotFoundException cnfe) {
+				throw new MappingException( "Could not find persister class: "
+					+ persisterNode.getValue() );
+			}
+		}
+
+		// CUSTOM SQL
+		handleCustomSQL( node, entity );
+
+		Iterator tables = node.elementIterator( "synchronize" );
+		while ( tables.hasNext() ) {
+			entity.addSynchronizedTable( ( (Element) tables.next() ).attributeValue( "table" ) );
+		}
+
+		Attribute abstractNode = node.attribute( "abstract" );
+		Boolean isAbstract = abstractNode == null
+				? null
+		        : "true".equals( abstractNode.getValue() )
+						? Boolean.TRUE
+	                    : "false".equals( abstractNode.getValue() )
+								? Boolean.FALSE
+	                            : null;
+		entity.setAbstract( isAbstract );
+	}
+
+	private static void handleCustomSQL(Element node, PersistentClass model)
+			throws MappingException {
+		Element element = node.element( "sql-insert" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-delete" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-update" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "loader" );
+		if ( element != null ) {
+			model.setLoaderName( element.attributeValue( "query-ref" ) );
+		}
+	}
+
+	private static void handleCustomSQL(Element node, Join model) throws MappingException {
+		Element element = node.element( "sql-insert" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-delete" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-update" );
+		if ( element != null ) {
+			boolean callable = isCallable( element );
+			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+	}
+
+	private static void handleCustomSQL(Element node, Collection model) throws MappingException {
+		Element element = node.element( "sql-insert" );
+		if ( element != null ) {
+			boolean callable = isCallable( element, true );
+			model.setCustomSQLInsert( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-delete" );
+		if ( element != null ) {
+			boolean callable = isCallable( element, true );
+			model.setCustomSQLDelete( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-update" );
+		if ( element != null ) {
+			boolean callable = isCallable( element, true );
+			model.setCustomSQLUpdate( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+
+		element = node.element( "sql-delete-all" );
+		if ( element != null ) {
+			boolean callable = isCallable( element, true );
+			model.setCustomSQLDeleteAll( element.getTextTrim(), callable, getResultCheckStyle( element, callable ) );
+		}
+	}
+
+	private static boolean isCallable(Element e) throws MappingException {
+		return isCallable( e, true );
+	}
+
+	private static boolean isCallable(Element element, boolean supportsCallable)
+			throws MappingException {
+		Attribute attrib = element.attribute( "callable" );
+		if ( attrib != null && "true".equals( attrib.getValue() ) ) {
+			if ( !supportsCallable ) {
+				throw new MappingException( "callable attribute not supported yet!" );
+			}
+			return true;
+		}
+		return false;
+	}
+
+	private static ExecuteUpdateResultCheckStyle getResultCheckStyle(Element element, boolean callable) throws MappingException {
+		Attribute attr = element.attribute( "check" );
+		if ( attr == null ) {
+			// use COUNT as the default.  This mimics the old behavior, although
+			// NONE might be a better option moving forward in the case of callable
+			return ExecuteUpdateResultCheckStyle.COUNT;
+		}
+		return ExecuteUpdateResultCheckStyle.parse( attr.getValue() );
+	}
+
+	public static void bindUnionSubclass(Element node, UnionSubclass unionSubclass,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		bindClass( node, unionSubclass, mappings, inheritedMetas );
+		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <subclass>
+
+		if ( unionSubclass.getEntityPersisterClass() == null ) {
+			unionSubclass.getRootClass().setEntityPersisterClass(
+				UnionSubclassEntityPersister.class );
+		}
+
+		Attribute schemaNode = node.attribute( "schema" );
+		String schema = schemaNode == null ?
+				mappings.getSchemaName() : schemaNode.getValue();
+
+		Attribute catalogNode = node.attribute( "catalog" );
+		String catalog = catalogNode == null ?
+				mappings.getCatalogName() : catalogNode.getValue();
+
+		Table denormalizedSuperTable = unionSubclass.getSuperclass().getTable();
+		Table mytable = mappings.addDenormalizedTable(
+				schema,
+				catalog,
+				getClassTableName(unionSubclass, node, schema, catalog, denormalizedSuperTable, mappings ),
+		        unionSubclass.isAbstract() != null && unionSubclass.isAbstract().booleanValue(),
+				getSubselect( node ),
+				denormalizedSuperTable
+			);
+		unionSubclass.setTable( mytable );
+
+		log.info(
+				"Mapping union-subclass: " + unionSubclass.getEntityName() +
+				" -> " + unionSubclass.getTable().getName()
+			);
+
+		createClassProperties( node, unionSubclass, mappings, inheritedMetas );
+
+	}
+
+	public static void bindSubclass(Element node, Subclass subclass, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		bindClass( node, subclass, mappings, inheritedMetas );
+		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from <subclass>
+
+		if ( subclass.getEntityPersisterClass() == null ) {
+			subclass.getRootClass()
+					.setEntityPersisterClass( SingleTableEntityPersister.class );
+		}
+
+		log.info(
+				"Mapping subclass: " + subclass.getEntityName() +
+				" -> " + subclass.getTable().getName()
+			);
+
+		// properties
+		createClassProperties( node, subclass, mappings, inheritedMetas );
+	}
+
+	private static String getClassTableName(
+			PersistentClass model, Element node, String schema, String catalog, Table denormalizedSuperTable,
+			Mappings mappings
+	) {
+		Attribute tableNameNode = node.attribute( "table" );
+		String logicalTableName;
+		String physicalTableName;
+		if ( tableNameNode == null ) {
+			logicalTableName = StringHelper.unqualify( model.getEntityName() );
+			physicalTableName = mappings.getNamingStrategy().classToTableName( model.getEntityName() );
+		}
+		else {
+			logicalTableName = tableNameNode.getValue();
+			physicalTableName = mappings.getNamingStrategy().tableName( logicalTableName );
+		}
+		mappings.addTableBinding( schema, catalog, logicalTableName, physicalTableName, denormalizedSuperTable );
+		return physicalTableName;
+	}
+
+	public static void bindJoinedSubclass(Element node, JoinedSubclass joinedSubclass,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		bindClass( node, joinedSubclass, mappings, inheritedMetas );
+		inheritedMetas = getMetas( node, inheritedMetas, true ); // get meta's from
+																	// <joined-subclass>
+
+		// joined subclasses
+		if ( joinedSubclass.getEntityPersisterClass() == null ) {
+			joinedSubclass.getRootClass()
+				.setEntityPersisterClass( JoinedSubclassEntityPersister.class );
+		}
+
+		Attribute schemaNode = node.attribute( "schema" );
+		String schema = schemaNode == null ?
+				mappings.getSchemaName() : schemaNode.getValue();
+
+		Attribute catalogNode = node.attribute( "catalog" );
+		String catalog = catalogNode == null ?
+				mappings.getCatalogName() : catalogNode.getValue();
+
+		Table mytable = mappings.addTable(
+				schema,
+				catalog,
+				getClassTableName( joinedSubclass, node, schema, catalog, null, mappings ),
+				getSubselect( node ),
+				false
+			);
+		joinedSubclass.setTable( mytable );
+		bindComment(mytable, node);
+
+		log.info(
+				"Mapping joined-subclass: " + joinedSubclass.getEntityName() +
+				" -> " + joinedSubclass.getTable().getName()
+			);
+
+		// KEY
+		Element keyNode = node.element( "key" );
+		SimpleValue key = new DependantValue( mytable, joinedSubclass.getIdentifier() );
+		joinedSubclass.setKey( key );
+		key.setCascadeDeleteEnabled( "cascade".equals( keyNode.attributeValue( "on-delete" ) ) );
+		bindSimpleValue( keyNode, key, false, joinedSubclass.getEntityName(), mappings );
+
+		// model.getKey().setType( new Type( model.getIdentifier() ) );
+		joinedSubclass.createPrimaryKey();
+		joinedSubclass.createForeignKey();
+
+		// CHECK
+		Attribute chNode = node.attribute( "check" );
+		if ( chNode != null ) mytable.addCheckConstraint( chNode.getValue() );
+
+		// properties
+		createClassProperties( node, joinedSubclass, mappings, inheritedMetas );
+
+	}
+
+	private static void bindJoin(Element node, Join join, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		PersistentClass persistentClass = join.getPersistentClass();
+		String path = persistentClass.getEntityName();
+
+		// TABLENAME
+
+		Attribute schemaNode = node.attribute( "schema" );
+		String schema = schemaNode == null ?
+				mappings.getSchemaName() : schemaNode.getValue();
+		Attribute catalogNode = node.attribute( "catalog" );
+		String catalog = catalogNode == null ?
+				mappings.getCatalogName() : catalogNode.getValue();
+		Table primaryTable = persistentClass.getTable();
+		Table table = mappings.addTable(
+				schema,
+				catalog,
+				getClassTableName( persistentClass, node, schema, catalog, primaryTable, mappings ),
+				getSubselect( node ),
+				false
+			);
+		join.setTable( table );
+		bindComment(table, node);
+
+		Attribute fetchNode = node.attribute( "fetch" );
+		if ( fetchNode != null ) {
+			join.setSequentialSelect( "select".equals( fetchNode.getValue() ) );
+		}
+
+		Attribute invNode = node.attribute( "inverse" );
+		if ( invNode != null ) {
+			join.setInverse( "true".equals( invNode.getValue() ) );
+		}
+
+		Attribute nullNode = node.attribute( "optional" );
+		if ( nullNode != null ) {
+			join.setOptional( "true".equals( nullNode.getValue() ) );
+		}
+
+		log.info(
+				"Mapping class join: " + persistentClass.getEntityName() +
+				" -> " + join.getTable().getName()
+			);
+
+		// KEY
+		Element keyNode = node.element( "key" );
+		SimpleValue key = new DependantValue( table, persistentClass.getIdentifier() );
+		join.setKey( key );
+		key.setCascadeDeleteEnabled( "cascade".equals( keyNode.attributeValue( "on-delete" ) ) );
+		bindSimpleValue( keyNode, key, false, persistentClass.getEntityName(), mappings );
+
+		// join.getKey().setType( new Type( lazz.getIdentifier() ) );
+		join.createPrimaryKey();
+		join.createForeignKey();
+
+		// PROPERTIES
+		Iterator iter = node.elementIterator();
+		while ( iter.hasNext() ) {
+			Element subnode = (Element) iter.next();
+			String name = subnode.getName();
+			String propertyName = subnode.attributeValue( "name" );
+
+			Value value = null;
+			if ( "many-to-one".equals( name ) ) {
+				value = new ManyToOne( table );
+				bindManyToOne( subnode, (ManyToOne) value, propertyName, true, mappings );
+			}
+			else if ( "any".equals( name ) ) {
+				value = new Any( table );
+				bindAny( subnode, (Any) value, true, mappings );
+			}
+			else if ( "property".equals( name ) ) {
+				value = new SimpleValue( table );
+				bindSimpleValue( subnode, (SimpleValue) value, true, propertyName, mappings );
+			}
+			else if ( "component".equals( name ) || "dynamic-component".equals( name ) ) {
+				String subpath = StringHelper.qualify( path, propertyName );
+				value = new Component( join );
+				bindComponent(
+						subnode,
+						(Component) value,
+						join.getPersistentClass().getClassName(),
+						propertyName,
+						subpath,
+						true,
+						false,
+						mappings,
+						inheritedMetas,
+						false
+					);
+			}
+
+			if ( value != null ) {
+				Property prop = createProperty( value, propertyName, persistentClass
+					.getEntityName(), subnode, mappings, inheritedMetas );
+				prop.setOptional( join.isOptional() );
+				join.addProperty( prop );
+			}
+
+		}
+
+		// CUSTOM SQL
+		handleCustomSQL( node, join );
+
+	}
+
+	public static void bindColumns(final Element node, final SimpleValue simpleValue,
+			final boolean isNullable, final boolean autoColumn, final String propertyPath,
+			final Mappings mappings) throws MappingException {
+
+		Table table = simpleValue.getTable();
+
+		// COLUMN(S)
+		Attribute columnAttribute = node.attribute( "column" );
+		if ( columnAttribute == null ) {
+			Iterator iter = node.elementIterator();
+			int count = 0;
+			while ( iter.hasNext() ) {
+				Element columnElement = (Element) iter.next();
+				if ( columnElement.getName().equals( "column" ) ) {
+					Column column = new Column();
+					column.setValue( simpleValue );
+					column.setTypeIndex( count++ );
+					bindColumn( columnElement, column, isNullable );
+					String logicalColumnName = mappings.getNamingStrategy().logicalColumnName(
+							columnElement.attributeValue( "name" ), propertyPath
+					);
+					column.setName( mappings.getNamingStrategy().columnName(
+						logicalColumnName ) );
+					if ( table != null ) {
+						table.addColumn( column ); // table=null -> an association
+						                           // - fill it in later
+						//TODO fill in the mappings for table == null
+						mappings.addColumnBinding( logicalColumnName, column, table );
+					}
+
+
+					simpleValue.addColumn( column );
+					// column index
+					bindIndex( columnElement.attribute( "index" ), table, column, mappings );
+					bindIndex( node.attribute( "index" ), table, column, mappings );
+					//column unique-key
+					bindUniqueKey( columnElement.attribute( "unique-key" ), table, column, mappings );
+					bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
+				}
+				else if ( columnElement.getName().equals( "formula" ) ) {
+					Formula formula = new Formula();
+					formula.setFormula( columnElement.getText() );
+					simpleValue.addFormula( formula );
+				}
+			}
+		}
+		else {
+			if ( node.elementIterator( "column" ).hasNext() ) {
+				throw new MappingException(
+					"column attribute may not be used together with <column> subelement" );
+			}
+			if ( node.elementIterator( "formula" ).hasNext() ) {
+				throw new MappingException(
+					"column attribute may not be used together with <formula> subelement" );
+			}
+
+			Column column = new Column();
+			column.setValue( simpleValue );
+			bindColumn( node, column, isNullable );
+			String logicalColumnName = mappings.getNamingStrategy().logicalColumnName(
+					columnAttribute.getValue(), propertyPath
+			);
+			column.setName( mappings.getNamingStrategy().columnName( logicalColumnName ) );
+			if ( table != null ) {
+				table.addColumn( column ); // table=null -> an association - fill
+				                           // it in later
+				//TODO fill in the mappings for table == null
+				mappings.addColumnBinding( logicalColumnName, column, table );
+			}
+			simpleValue.addColumn( column );
+			bindIndex( node.attribute( "index" ), table, column, mappings );
+			bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
+		}
+
+		if ( autoColumn && simpleValue.getColumnSpan() == 0 ) {
+			Column column = new Column();
+			column.setValue( simpleValue );
+			bindColumn( node, column, isNullable );
+			column.setName( mappings.getNamingStrategy().propertyToColumnName( propertyPath ) );
+			String logicalName = mappings.getNamingStrategy().logicalColumnName( null, propertyPath );
+			mappings.addColumnBinding( logicalName, column, table );
+			/* TODO: joinKeyColumnName & foreignKeyColumnName should be called either here or at a
+			 * slightly higer level in the stack (to get all the information we need)
+			 * Right now HbmBinder does not support the
+			 */
+			simpleValue.getTable().addColumn( column );
+			simpleValue.addColumn( column );
+			bindIndex( node.attribute( "index" ), table, column, mappings );
+			bindUniqueKey( node.attribute( "unique-key" ), table, column, mappings );
+		}
+
+	}
+
+	private static void bindIndex(Attribute indexAttribute, Table table, Column column, Mappings mappings) {
+		if ( indexAttribute != null && table != null ) {
+			StringTokenizer tokens = new StringTokenizer( indexAttribute.getValue(), ", " );
+			while ( tokens.hasMoreTokens() ) {
+				table.getOrCreateIndex( tokens.nextToken() ).addColumn( column );
+			}
+		}
+	}
+
+	private static void bindUniqueKey(Attribute uniqueKeyAttribute, Table table, Column column, Mappings mappings) {
+		if ( uniqueKeyAttribute != null && table != null ) {
+			StringTokenizer tokens = new StringTokenizer( uniqueKeyAttribute.getValue(), ", " );
+			while ( tokens.hasMoreTokens() ) {
+				table.getOrCreateUniqueKey( tokens.nextToken() ).addColumn( column );
+			}
+		}
+	}
+
+	// automatically makes a column with the default name if none is specifed by XML
+	public static void bindSimpleValue(Element node, SimpleValue simpleValue, boolean isNullable,
+			String path, Mappings mappings) throws MappingException {
+		bindSimpleValueType( node, simpleValue, mappings );
+
+		bindColumnsOrFormula( node, simpleValue, path, isNullable, mappings );
+
+		Attribute fkNode = node.attribute( "foreign-key" );
+		if ( fkNode != null ) simpleValue.setForeignKeyName( fkNode.getValue() );
+	}
+
+	private static void bindSimpleValueType(Element node, SimpleValue simpleValue, Mappings mappings)
+			throws MappingException {
+		String typeName = null;
+
+		Properties parameters = new Properties();
+
+		Attribute typeNode = node.attribute( "type" );
+		if ( typeNode == null ) typeNode = node.attribute( "id-type" ); // for an any
+		if ( typeNode != null ) typeName = typeNode.getValue();
+
+		Element typeChild = node.element( "type" );
+		if ( typeName == null && typeChild != null ) {
+			typeName = typeChild.attribute( "name" ).getValue();
+			Iterator typeParameters = typeChild.elementIterator( "param" );
+
+			while ( typeParameters.hasNext() ) {
+				Element paramElement = (Element) typeParameters.next();
+				parameters.setProperty(
+						paramElement.attributeValue( "name" ),
+						paramElement.getTextTrim()
+					);
+			}
+		}
+
+		TypeDef typeDef = mappings.getTypeDef( typeName );
+		if ( typeDef != null ) {
+			typeName = typeDef.getTypeClass();
+			// parameters on the property mapping should
+			// override parameters in the typedef
+			Properties allParameters = new Properties();
+			allParameters.putAll( typeDef.getParameters() );
+			allParameters.putAll( parameters );
+			parameters = allParameters;
+		}
+
+		if ( !parameters.isEmpty() ) simpleValue.setTypeParameters( parameters );
+
+		if ( typeName != null ) simpleValue.setTypeName( typeName );
+	}
+
+	public static void bindProperty(
+			Element node,
+	        Property property,
+	        Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		String propName = node.attributeValue( "name" );
+		property.setName( propName );
+		String nodeName = node.attributeValue( "node" );
+		if (nodeName==null) nodeName = propName;
+		property.setNodeName( nodeName );
+
+		// TODO:
+		//Type type = model.getValue().getType();
+		//if (type==null) throw new MappingException(
+		//"Could not determine a property type for: " + model.getName() );
+
+		Attribute accessNode = node.attribute( "access" );
+		if ( accessNode != null ) {
+			property.setPropertyAccessorName( accessNode.getValue() );
+		}
+		else if ( node.getName().equals( "properties" ) ) {
+			property.setPropertyAccessorName( "embedded" );
+		}
+		else {
+			property.setPropertyAccessorName( mappings.getDefaultAccess() );
+		}
+
+		Attribute cascadeNode = node.attribute( "cascade" );
+		property.setCascade( cascadeNode == null ? mappings.getDefaultCascade() : cascadeNode
+			.getValue() );
+
+		Attribute updateNode = node.attribute( "update" );
+		property.setUpdateable( updateNode == null || "true".equals( updateNode.getValue() ) );
+
+		Attribute insertNode = node.attribute( "insert" );
+		property.setInsertable( insertNode == null || "true".equals( insertNode.getValue() ) );
+
+		Attribute lockNode = node.attribute( "optimistic-lock" );
+		property.setOptimisticLocked( lockNode == null || "true".equals( lockNode.getValue() ) );
+
+		Attribute generatedNode = node.attribute( "generated" );
+        String generationName = generatedNode == null ? null : generatedNode.getValue();
+        PropertyGeneration generation = PropertyGeneration.parse( generationName );
+		property.setGeneration( generation );
+
+        if ( generation == PropertyGeneration.ALWAYS || generation == PropertyGeneration.INSERT ) {
+	        // generated properties can *never* be insertable...
+	        if ( property.isInsertable() ) {
+		        if ( insertNode == null ) {
+			        // insertable simply because that is the user did not specify
+			        // anything; just override it
+					property.setInsertable( false );
+		        }
+		        else {
+			        // the user specifically supplied insert="true",
+			        // which constitutes an illegal combo
+					throw new MappingException(
+							"cannot specify both insert=\"true\" and generated=\"" + generation.getName() +
+							"\" for property: " +
+							propName
+					);
+		        }
+	        }
+
+	        // properties generated on update can never be updateable...
+	        if ( property.isUpdateable() && generation == PropertyGeneration.ALWAYS ) {
+		        if ( updateNode == null ) {
+			        // updateable only because the user did not specify 
+			        // anything; just override it
+			        property.setUpdateable( false );
+		        }
+		        else {
+			        // the user specifically supplied update="true",
+			        // which constitutes an illegal combo
+					throw new MappingException(
+							"cannot specify both update=\"true\" and generated=\"" + generation.getName() +
+							"\" for property: " +
+							propName
+					);
+		        }
+	        }
+        }
+
+		boolean isLazyable = "property".equals( node.getName() ) ||
+				"component".equals( node.getName() ) ||
+				"many-to-one".equals( node.getName() ) ||
+				"one-to-one".equals( node.getName() ) ||
+				"any".equals( node.getName() );
+		if ( isLazyable ) {
+			Attribute lazyNode = node.attribute( "lazy" );
+			property.setLazy( lazyNode != null && "true".equals( lazyNode.getValue() ) );
+		}
+
+		if ( log.isDebugEnabled() ) {
+			String msg = "Mapped property: " + property.getName();
+			String columns = columns( property.getValue() );
+			if ( columns.length() > 0 ) msg += " -> " + columns;
+			// TODO: this fails if we run with debug on!
+			// if ( model.getType()!=null ) msg += ", type: " + model.getType().getName();
+			log.debug( msg );
+		}
+
+		property.setMetaAttributes( getMetas( node, inheritedMetas ) );
+
+	}
+
+	private static String columns(Value val) {
+		StringBuffer columns = new StringBuffer();
+		Iterator iter = val.getColumnIterator();
+		while ( iter.hasNext() ) {
+			columns.append( ( (Selectable) iter.next() ).getText() );
+			if ( iter.hasNext() ) columns.append( ", " );
+		}
+		return columns.toString();
+	}
+
+	/**
+	 * Called for all collections
+	 */
+	public static void bindCollection(Element node, Collection collection, String className,
+			String path, Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		// ROLENAME
+		collection.setRole(path);
+
+		Attribute inverseNode = node.attribute( "inverse" );
+		if ( inverseNode != null ) {
+			collection.setInverse( "true".equals( inverseNode.getValue() ) );
+		}
+
+		Attribute mutableNode = node.attribute( "mutable" );
+		if ( mutableNode != null ) {
+			collection.setMutable( !"false".equals( mutableNode.getValue() ) );
+		}
+
+		Attribute olNode = node.attribute( "optimistic-lock" );
+		collection.setOptimisticLocked( olNode == null || "true".equals( olNode.getValue() ) );
+
+		Attribute orderNode = node.attribute( "order-by" );
+		if ( orderNode != null ) {
+			if ( Environment.jvmSupportsLinkedHashCollections() || ( collection instanceof Bag ) ) {
+				collection.setOrderBy( orderNode.getValue() );
+			}
+			else {
+				log.warn( "Attribute \"order-by\" ignored in JDK1.3 or less" );
+			}
+		}
+		Attribute whereNode = node.attribute( "where" );
+		if ( whereNode != null ) {
+			collection.setWhere( whereNode.getValue() );
+		}
+		Attribute batchNode = node.attribute( "batch-size" );
+		if ( batchNode != null ) {
+			collection.setBatchSize( Integer.parseInt( batchNode.getValue() ) );
+		}
+
+		String nodeName = node.attributeValue( "node" );
+		if ( nodeName == null ) nodeName = node.attributeValue( "name" );
+		collection.setNodeName( nodeName );
+		String embed = node.attributeValue( "embed-xml" );
+		collection.setEmbedded( embed==null || "true".equals(embed) );
+
+
+		// PERSISTER
+		Attribute persisterNode = node.attribute( "persister" );
+		if ( persisterNode != null ) {
+			try {
+				collection.setCollectionPersisterClass( ReflectHelper.classForName( persisterNode
+					.getValue() ) );
+			}
+			catch (ClassNotFoundException cnfe) {
+				throw new MappingException( "Could not find collection persister class: "
+					+ persisterNode.getValue() );
+			}
+		}
+
+		Attribute typeNode = node.attribute( "collection-type" );
+		if ( typeNode != null ) {
+			String typeName = typeNode.getValue();
+			TypeDef typeDef = mappings.getTypeDef( typeName );
+			if ( typeDef != null ) {
+				collection.setTypeName( typeDef.getTypeClass() );
+				collection.setTypeParameters( typeDef.getParameters() );
+			}
+			else {
+				collection.setTypeName( typeName );
+			}
+		}
+
+		// FETCH STRATEGY
+
+		initOuterJoinFetchSetting( node, collection );
+
+		if ( "subselect".equals( node.attributeValue("fetch") ) ) {
+			collection.setSubselectLoadable(true);
+			collection.getOwner().setSubselectLoadableCollections(true);
+		}
+
+		initLaziness( node, collection, mappings, "true", mappings.isDefaultLazy() );
+		//TODO: suck this into initLaziness!
+		if ( "extra".equals( node.attributeValue("lazy") ) ) {
+			collection.setLazy(true);
+			collection.setExtraLazy(true);
+		}
+
+		Element oneToManyNode = node.element( "one-to-many" );
+		if ( oneToManyNode != null ) {
+			OneToMany oneToMany = new OneToMany( collection.getOwner() );
+			collection.setElement( oneToMany );
+			bindOneToMany( oneToManyNode, oneToMany, mappings );
+			// we have to set up the table later!! yuck
+		}
+		else {
+			// TABLE
+			Attribute tableNode = node.attribute( "table" );
+			String tableName;
+			if ( tableNode != null ) {
+				tableName = mappings.getNamingStrategy().tableName( tableNode.getValue() );
+			}
+			else {
+				//tableName = mappings.getNamingStrategy().propertyToTableName( className, path );
+				Table ownerTable = collection.getOwner().getTable();
+				//TODO mappings.getLogicalTableName(ownerTable)
+				String logicalOwnerTableName = ownerTable.getName();
+				//FIXME we don't have the associated entity table name here, has to be done in a second pass
+				tableName = mappings.getNamingStrategy().collectionTableName(
+						collection.getOwner().getEntityName(),
+						logicalOwnerTableName ,
+						null,
+						null,
+						path
+				);
+			}
+			Attribute schemaNode = node.attribute( "schema" );
+			String schema = schemaNode == null ?
+					mappings.getSchemaName() : schemaNode.getValue();
+
+			Attribute catalogNode = node.attribute( "catalog" );
+			String catalog = catalogNode == null ?
+					mappings.getCatalogName() : catalogNode.getValue();
+
+			Table table = mappings.addTable(
+					schema,
+					catalog,
+					tableName,
+					getSubselect( node ),
+					false
+				);
+			collection.setCollectionTable( table );
+			bindComment(table, node);
+
+			log.info(
+					"Mapping collection: " + collection.getRole() +
+					" -> " + collection.getCollectionTable().getName()
+				);
+		}
+
+		// SORT
+		Attribute sortedAtt = node.attribute( "sort" );
+		// unsorted, natural, comparator.class.name
+		if ( sortedAtt == null || sortedAtt.getValue().equals( "unsorted" ) ) {
+			collection.setSorted( false );
+		}
+		else {
+			collection.setSorted( true );
+			String comparatorClassName = sortedAtt.getValue();
+			if ( !comparatorClassName.equals( "natural" ) ) {
+				collection.setComparatorClassName(comparatorClassName);
+			}
+		}
+
+		// ORPHAN DELETE (used for programmer error detection)
+		Attribute cascadeAtt = node.attribute( "cascade" );
+		if ( cascadeAtt != null && cascadeAtt.getValue().indexOf( "delete-orphan" ) >= 0 ) {
+			collection.setOrphanDelete( true );
+		}
+
+		// CUSTOM SQL
+		handleCustomSQL( node, collection );
+		// set up second pass
+		if ( collection instanceof List ) {
+			mappings.addSecondPass( new ListSecondPass( node, mappings, (List) collection, inheritedMetas ) );
+		}
+		else if ( collection instanceof Map ) {
+			mappings.addSecondPass( new MapSecondPass( node, mappings, (Map) collection, inheritedMetas ) );
+		}
+		else if ( collection instanceof IdentifierCollection ) {
+			mappings.addSecondPass( new IdentifierCollectionSecondPass(
+					node,
+					mappings,
+					collection,
+					inheritedMetas
+				) );
+		}
+		else {
+			mappings.addSecondPass( new CollectionSecondPass( node, mappings, collection, inheritedMetas ) );
+		}
+
+		Iterator iter = node.elementIterator( "filter" );
+		while ( iter.hasNext() ) {
+			final Element filter = (Element) iter.next();
+			parseFilter( filter, collection, mappings );
+		}
+
+		Iterator tables = node.elementIterator( "synchronize" );
+		while ( tables.hasNext() ) {
+			collection.getSynchronizedTables().add(
+				( (Element) tables.next() ).attributeValue( "table" ) );
+		}
+
+		Element element = node.element( "loader" );
+		if ( element != null ) {
+			collection.setLoaderName( element.attributeValue( "query-ref" ) );
+		}
+
+		collection.setReferencedPropertyName( node.element( "key" ).attributeValue( "property-ref" ) );
+	}
+
+	private static void initLaziness(
+			Element node,
+			Fetchable fetchable,
+			Mappings mappings,
+			String proxyVal,
+			boolean defaultLazy
+	) {
+		Attribute lazyNode = node.attribute( "lazy" );
+		boolean isLazyTrue = lazyNode == null ?
+				defaultLazy && fetchable.isLazy() : //fetch="join" overrides default laziness
+				lazyNode.getValue().equals(proxyVal); //fetch="join" overrides default laziness
+		fetchable.setLazy( isLazyTrue );
+	}
+
+	private static void initLaziness(
+			Element node,
+			ToOne fetchable,
+			Mappings mappings,
+			boolean defaultLazy
+	) {
+		if ( "no-proxy".equals( node.attributeValue( "lazy" ) ) ) {
+			fetchable.setUnwrapProxy(true);
+			fetchable.setLazy(true);
+			//TODO: better to degrade to lazy="false" if uninstrumented
+		}
+		else {
+			initLaziness(node, fetchable, mappings, "proxy", defaultLazy);
+		}
+	}
+
+	private static void bindColumnsOrFormula(Element node, SimpleValue simpleValue, String path,
+			boolean isNullable, Mappings mappings) {
+		Attribute formulaNode = node.attribute( "formula" );
+		if ( formulaNode != null ) {
+			Formula f = new Formula();
+			f.setFormula( formulaNode.getText() );
+			simpleValue.addFormula( f );
+		}
+		else {
+			bindColumns( node, simpleValue, isNullable, true, path, mappings );
+		}
+	}
+
+	private static void bindComment(Table table, Element node) {
+		Element comment = node.element("comment");
+		if (comment!=null) table.setComment( comment.getTextTrim() );
+	}
+
+	public static void bindManyToOne(Element node, ManyToOne manyToOne, String path,
+			boolean isNullable, Mappings mappings) throws MappingException {
+
+		bindColumnsOrFormula( node, manyToOne, path, isNullable, mappings );
+		initOuterJoinFetchSetting( node, manyToOne );
+		initLaziness( node, manyToOne, mappings, true );
+
+		Attribute ukName = node.attribute( "property-ref" );
+		if ( ukName != null ) {
+			manyToOne.setReferencedPropertyName( ukName.getValue() );
+		}
+
+		manyToOne.setReferencedEntityName( getEntityName( node, mappings ) );
+
+		String embed = node.attributeValue( "embed-xml" );
+		manyToOne.setEmbedded( embed == null || "true".equals( embed ) );
+
+		String notFound = node.attributeValue( "not-found" );
+		manyToOne.setIgnoreNotFound( "ignore".equals( notFound ) );
+
+		if( ukName != null && !manyToOne.isIgnoreNotFound() ) {
+			if ( !node.getName().equals("many-to-many") ) { //TODO: really bad, evil hack to fix!!!
+				mappings.addSecondPass( new ManyToOneSecondPass(manyToOne) );
+			}
+		}
+
+		Attribute fkNode = node.attribute( "foreign-key" );
+		if ( fkNode != null ) manyToOne.setForeignKeyName( fkNode.getValue() );
+
+		validateCascade( node, path );
+	}
+
+	private static void validateCascade(Element node, String path) {
+		String cascade = node.attributeValue( "cascade" );
+		if ( cascade != null && cascade.indexOf( "delete-orphan" ) >= 0 ) {
+			throw new MappingException( "single-valued associations do not support orphan delete: " + path );
+		}
+	}
+
+	public static void bindAny(Element node, Any any, boolean isNullable, Mappings mappings)
+			throws MappingException {
+		any.setIdentifierType( getTypeFromXML( node ) );
+		Attribute metaAttribute = node.attribute( "meta-type" );
+		if ( metaAttribute != null ) {
+			any.setMetaType( metaAttribute.getValue() );
+
+			Iterator iter = node.elementIterator( "meta-value" );
+			if ( iter.hasNext() ) {
+				HashMap values = new HashMap();
+				org.hibernate.type.Type metaType = TypeFactory.heuristicType( any.getMetaType() );
+				while ( iter.hasNext() ) {
+					Element metaValue = (Element) iter.next();
+					try {
+						Object value = ( (DiscriminatorType) metaType ).stringToObject( metaValue
+							.attributeValue( "value" ) );
+						String entityName = getClassName( metaValue.attribute( "class" ), mappings );
+						values.put( value, entityName );
+					}
+					catch (ClassCastException cce) {
+						throw new MappingException( "meta-type was not a DiscriminatorType: "
+							+ metaType.getName() );
+					}
+					catch (Exception e) {
+						throw new MappingException( "could not interpret meta-value", e );
+					}
+				}
+				any.setMetaValues( values );
+			}
+
+		}
+
+		bindColumns( node, any, isNullable, false, null, mappings );
+	}
+
+	public static void bindOneToOne(Element node, OneToOne oneToOne, String path, boolean isNullable,
+			Mappings mappings) throws MappingException {
+
+		bindColumns( node, oneToOne, isNullable, false, null, mappings );
+
+		Attribute constrNode = node.attribute( "constrained" );
+		boolean constrained = constrNode != null && constrNode.getValue().equals( "true" );
+		oneToOne.setConstrained( constrained );
+
+		oneToOne.setForeignKeyType( constrained ?
+				ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT :
+				ForeignKeyDirection.FOREIGN_KEY_TO_PARENT );
+
+		initOuterJoinFetchSetting( node, oneToOne );
+		initLaziness( node, oneToOne, mappings, true );
+
+		oneToOne.setEmbedded( "true".equals( node.attributeValue( "embed-xml" ) ) );
+
+		Attribute fkNode = node.attribute( "foreign-key" );
+		if ( fkNode != null ) oneToOne.setForeignKeyName( fkNode.getValue() );
+
+		Attribute ukName = node.attribute( "property-ref" );
+		if ( ukName != null ) oneToOne.setReferencedPropertyName( ukName.getValue() );
+
+		oneToOne.setPropertyName( node.attributeValue( "name" ) );
+
+		oneToOne.setReferencedEntityName( getEntityName( node, mappings ) );
+
+		validateCascade( node, path );
+	}
+
+	public static void bindOneToMany(Element node, OneToMany oneToMany, Mappings mappings)
+			throws MappingException {
+
+		oneToMany.setReferencedEntityName( getEntityName( node, mappings ) );
+
+		String embed = node.attributeValue( "embed-xml" );
+		oneToMany.setEmbedded( embed == null || "true".equals( embed ) );
+
+		String notFound = node.attributeValue( "not-found" );
+		oneToMany.setIgnoreNotFound( "ignore".equals( notFound ) );
+
+	}
+
+	public static void bindColumn(Element node, Column column, boolean isNullable) {
+		Attribute lengthNode = node.attribute( "length" );
+		if ( lengthNode != null ) column.setLength( Integer.parseInt( lengthNode.getValue() ) );
+		Attribute scalNode = node.attribute( "scale" );
+		if ( scalNode != null ) column.setScale( Integer.parseInt( scalNode.getValue() ) );
+		Attribute precNode = node.attribute( "precision" );
+		if ( precNode != null ) column.setPrecision( Integer.parseInt( precNode.getValue() ) );
+
+		Attribute nullNode = node.attribute( "not-null" );
+		column.setNullable( nullNode == null ? isNullable : nullNode.getValue().equals( "false" ) );
+
+		Attribute unqNode = node.attribute( "unique" );
+		if ( unqNode != null ) column.setUnique( unqNode.getValue().equals( "true" ) );
+
+		column.setCheckConstraint( node.attributeValue( "check" ) );
+		column.setDefaultValue( node.attributeValue( "default" ) );
+
+		Attribute typeNode = node.attribute( "sql-type" );
+		if ( typeNode != null ) column.setSqlType( typeNode.getValue() );
+
+		Element comment = node.element("comment");
+		if (comment!=null) column.setComment( comment.getTextTrim() );
+
+	}
+
+	/**
+	 * Called for arrays and primitive arrays
+	 */
+	public static void bindArray(Element node, Array array, String prefix, String path,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		bindCollection( node, array, prefix, path, mappings, inheritedMetas );
+
+		Attribute att = node.attribute( "element-class" );
+		if ( att != null ) array.setElementClassName( getClassName( att, mappings ) );
+
+	}
+
+	private static Class reflectedPropertyClass(String className, String propertyName)
+			throws MappingException {
+		if ( className == null ) return null;
+		return ReflectHelper.reflectedPropertyClass( className, propertyName );
+	}
+
+	public static void bindComposite(Element node, Component component, String path,
+			boolean isNullable, Mappings mappings, java.util.Map inheritedMetas)
+			throws MappingException {
+		bindComponent(
+				node,
+				component,
+				null,
+				null,
+				path,
+				isNullable,
+				false,
+				mappings,
+				inheritedMetas,
+				false
+			);
+	}
+
+	public static void bindCompositeId(Element node, Component component,
+			PersistentClass persistentClass, String propertyName, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		component.setKey( true );
+
+		String path = StringHelper.qualify(
+				persistentClass.getEntityName(),
+				propertyName == null ? "id" : propertyName );
+
+		bindComponent(
+				node,
+				component,
+				persistentClass.getClassName(),
+				propertyName,
+				path,
+				false,
+				node.attribute( "class" ) == null
+						&& propertyName == null,
+				mappings,
+				inheritedMetas,
+				false
+			);
+
+		if ( "true".equals( node.attributeValue("mapped") ) ) {
+			if ( propertyName!=null ) {
+				throw new MappingException("cannot combine mapped=\"true\" with specified name");
+			}
+			Component mapper = new Component(persistentClass);
+			bindComponent(
+					node,
+					mapper,
+					persistentClass.getClassName(),
+					null,
+					path,
+					false,
+					true,
+					mappings,
+					inheritedMetas,
+					true
+				);
+			persistentClass.setIdentifierMapper(mapper);
+			Property property = new Property();
+			property.setName("_identifierMapper");
+			property.setNodeName("id");
+			property.setUpdateable(false);
+			property.setInsertable(false);
+			property.setValue(mapper);
+			property.setPropertyAccessorName( "embedded" );
+			persistentClass.addProperty(property);
+		}
+
+	}
+
+	public static void bindComponent(
+			Element node,
+			Component component,
+			String ownerClassName,
+			String parentProperty,
+			String path,
+			boolean isNullable,
+			boolean isEmbedded,
+			Mappings mappings,
+			java.util.Map inheritedMetas,
+			boolean isIdentifierMapper) throws MappingException {
+
+		component.setEmbedded( isEmbedded );
+		component.setRoleName( path );
+
+		inheritedMetas = getMetas( node, inheritedMetas );
+		component.setMetaAttributes( inheritedMetas );
+
+		Attribute classNode = isIdentifierMapper ? null : node.attribute( "class" );
+		if ( classNode != null ) {
+			component.setComponentClassName( getClassName( classNode, mappings ) );
+		}
+		else if ( "dynamic-component".equals( node.getName() ) ) {
+			component.setDynamic( true );
+		}
+		else if ( isEmbedded ) {
+			// an "embedded" component (composite ids and unique)
+			// note that this does not handle nested components
+			if ( component.getOwner().hasPojoRepresentation() ) {
+				component.setComponentClassName( component.getOwner().getClassName() );
+			}
+			else {
+				component.setDynamic(true);
+			}
+		}
+		else {
+			// todo : again, how *should* this work for non-pojo entities?
+			if ( component.getOwner().hasPojoRepresentation() ) {
+				Class reflectedClass = reflectedPropertyClass( ownerClassName, parentProperty );
+				if ( reflectedClass != null ) {
+					component.setComponentClassName( reflectedClass.getName() );
+				}
+			}
+			else {
+				component.setDynamic(true);
+			}
+		}
+
+		String nodeName = node.attributeValue( "node" );
+		if ( nodeName == null ) nodeName = node.attributeValue( "name" );
+		if ( nodeName == null ) nodeName = component.getOwner().getNodeName();
+		component.setNodeName( nodeName );
+
+		Iterator iter = node.elementIterator();
+		while ( iter.hasNext() ) {
+
+			Element subnode = (Element) iter.next();
+			String name = subnode.getName();
+			String propertyName = getPropertyName( subnode );
+			String subpath = propertyName == null ? null : StringHelper
+				.qualify( path, propertyName );
+
+			CollectionType collectType = CollectionType.collectionTypeFromString( name );
+			Value value = null;
+			if ( collectType != null ) {
+				Collection collection = collectType.create(
+						subnode,
+						subpath,
+						component.getOwner(),
+						mappings, inheritedMetas
+					);
+				mappings.addCollection( collection );
+				value = collection;
+			}
+			else if ( "many-to-one".equals( name ) || "key-many-to-one".equals( name ) ) {
+				value = new ManyToOne( component.getTable() );
+				String relativePath;
+				if (isEmbedded) {
+					relativePath = propertyName;
+				}
+				else {
+					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
+				}
+				bindManyToOne( subnode, (ManyToOne) value, relativePath, isNullable, mappings );
+			}
+			else if ( "one-to-one".equals( name ) ) {
+				value = new OneToOne( component.getTable(), component.getOwner() );
+				String relativePath;
+				if (isEmbedded) {
+					relativePath = propertyName;
+				}
+				else {
+					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
+				}
+				bindOneToOne( subnode, (OneToOne) value, relativePath, isNullable, mappings );
+			}
+			else if ( "any".equals( name ) ) {
+				value = new Any( component.getTable() );
+				bindAny( subnode, (Any) value, isNullable, mappings );
+			}
+			else if ( "property".equals( name ) || "key-property".equals( name ) ) {
+				value = new SimpleValue( component.getTable() );
+				String relativePath;
+				if (isEmbedded) {
+					relativePath = propertyName;
+				}
+				else {
+					relativePath = subpath.substring( component.getOwner().getEntityName().length() + 1 );
+				}
+				bindSimpleValue( subnode, (SimpleValue) value, isNullable, relativePath, mappings );
+			}
+			else if ( "component".equals( name )
+				|| "dynamic-component".equals( name )
+				|| "nested-composite-element".equals( name ) ) {
+				value = new Component( component ); // a nested composite element
+				bindComponent(
+						subnode,
+						(Component) value,
+						component.getComponentClassName(),
+						propertyName,
+						subpath,
+						isNullable,
+						isEmbedded,
+						mappings,
+						inheritedMetas,
+						isIdentifierMapper
+					);
+			}
+			else if ( "parent".equals( name ) ) {
+				component.setParentProperty( propertyName );
+			}
+
+			if ( value != null ) {
+				Property property = createProperty( value, propertyName, component
+					.getComponentClassName(), subnode, mappings, inheritedMetas );
+				if (isIdentifierMapper) {
+					property.setInsertable(false);
+					property.setUpdateable(false);
+				}
+				component.addProperty( property );
+			}
+		}
+
+		if ( "true".equals( node.attributeValue( "unique" ) ) ) {
+			iter = component.getColumnIterator();
+			ArrayList cols = new ArrayList();
+			while ( iter.hasNext() ) {
+				cols.add( iter.next() );
+			}
+			component.getOwner().getTable().createUniqueKey( cols );
+		}
+
+		iter = node.elementIterator( "tuplizer" );
+		while ( iter.hasNext() ) {
+			final Element tuplizerElem = ( Element ) iter.next();
+			EntityMode mode = EntityMode.parse( tuplizerElem.attributeValue( "entity-mode" ) );
+			component.addTuplizer( mode, tuplizerElem.attributeValue( "class" ) );
+		}
+	}
+
+	public static String getTypeFromXML(Element node) throws MappingException {
+		// TODO: handle TypeDefs
+		Attribute typeNode = node.attribute( "type" );
+		if ( typeNode == null ) typeNode = node.attribute( "id-type" ); // for an any
+		if ( typeNode == null ) return null; // we will have to use reflection
+		return typeNode.getValue();
+	}
+
+	private static void initOuterJoinFetchSetting(Element node, Fetchable model) {
+		Attribute fetchNode = node.attribute( "fetch" );
+		final FetchMode fetchStyle;
+		boolean lazy = true;
+		if ( fetchNode == null ) {
+			Attribute jfNode = node.attribute( "outer-join" );
+			if ( jfNode == null ) {
+				if ( "many-to-many".equals( node.getName() ) ) {
+					//NOTE SPECIAL CASE:
+					// default to join and non-lazy for the "second join"
+					// of the many-to-many
+					lazy = false;
+					fetchStyle = FetchMode.JOIN;
+				}
+				else if ( "one-to-one".equals( node.getName() ) ) {
+					//NOTE SPECIAL CASE:
+					// one-to-one constrained=false cannot be proxied,
+					// so default to join and non-lazy
+					lazy = ( (OneToOne) model ).isConstrained();
+					fetchStyle = lazy ? FetchMode.DEFAULT : FetchMode.JOIN;
+				}
+				else {
+					fetchStyle = FetchMode.DEFAULT;
+				}
+			}
+			else {
+				// use old (HB 2.1) defaults if outer-join is specified
+				String eoj = jfNode.getValue();
+				if ( "auto".equals( eoj ) ) {
+					fetchStyle = FetchMode.DEFAULT;
+				}
+				else {
+					boolean join = "true".equals( eoj );
+					fetchStyle = join ? FetchMode.JOIN : FetchMode.SELECT;
+				}
+			}
+		}
+		else {
+			boolean join = "join".equals( fetchNode.getValue() );
+			//lazy = !join;
+			fetchStyle = join ? FetchMode.JOIN : FetchMode.SELECT;
+		}
+		model.setFetchMode( fetchStyle );
+		model.setLazy(lazy);
+	}
+
+	private static void makeIdentifier(Element node, SimpleValue model, Mappings mappings) {
+
+		// GENERATOR
+		Element subnode = node.element( "generator" );
+		if ( subnode != null ) {
+			model.setIdentifierGeneratorStrategy( subnode.attributeValue( "class" ) );
+
+			Properties params = new Properties();
+
+			if ( mappings.getSchemaName() != null ) {
+				params.setProperty( PersistentIdentifierGenerator.SCHEMA, mappings.getSchemaName() );
+			}
+			if ( mappings.getCatalogName() != null ) {
+				params.setProperty( PersistentIdentifierGenerator.CATALOG, mappings.getCatalogName() );
+			}
+
+			Iterator iter = subnode.elementIterator( "param" );
+			while ( iter.hasNext() ) {
+				Element childNode = (Element) iter.next();
+				params.setProperty( childNode.attributeValue( "name" ), childNode.getTextTrim() );
+			}
+
+			model.setIdentifierGeneratorProperties( params );
+		}
+
+		model.getTable().setIdentifierValue( model );
+
+		// ID UNSAVED-VALUE
+		Attribute nullValueNode = node.attribute( "unsaved-value" );
+		if ( nullValueNode != null ) {
+			model.setNullValue( nullValueNode.getValue() );
+		}
+		else {
+			if ( "assigned".equals( model.getIdentifierGeneratorStrategy() ) ) {
+				model.setNullValue( "undefined" );
+			}
+			else {
+				model.setNullValue( null );
+			}
+		}
+	}
+
+	private static final void makeVersion(Element node, SimpleValue model) {
+
+		// VERSION UNSAVED-VALUE
+		Attribute nullValueNode = node.attribute( "unsaved-value" );
+		if ( nullValueNode != null ) {
+			model.setNullValue( nullValueNode.getValue() );
+		}
+		else {
+			model.setNullValue( "undefined" );
+		}
+
+	}
+
+	protected static void createClassProperties(Element node, PersistentClass persistentClass,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+		createClassProperties(node, persistentClass, mappings, inheritedMetas, null, true, true, false);
+	}
+
+	protected static void createClassProperties(Element node, PersistentClass persistentClass,
+			Mappings mappings, java.util.Map inheritedMetas, UniqueKey uniqueKey,
+			boolean mutable, boolean nullable, boolean naturalId) throws MappingException {
+
+		String entityName = persistentClass.getEntityName();
+		Table table = persistentClass.getTable();
+
+		Iterator iter = node.elementIterator();
+		while ( iter.hasNext() ) {
+			Element subnode = (Element) iter.next();
+			String name = subnode.getName();
+			String propertyName = subnode.attributeValue( "name" );
+
+			CollectionType collectType = CollectionType.collectionTypeFromString( name );
+			Value value = null;
+			if ( collectType != null ) {
+				Collection collection = collectType.create(
+						subnode,
+						StringHelper.qualify( entityName, propertyName ),
+						persistentClass,
+						mappings, inheritedMetas
+					);
+				mappings.addCollection( collection );
+				value = collection;
+			}
+			else if ( "many-to-one".equals( name ) ) {
+				value = new ManyToOne( table );
+				bindManyToOne( subnode, (ManyToOne) value, propertyName, nullable, mappings );
+			}
+			else if ( "any".equals( name ) ) {
+				value = new Any( table );
+				bindAny( subnode, (Any) value, nullable, mappings );
+			}
+			else if ( "one-to-one".equals( name ) ) {
+				value = new OneToOne( table, persistentClass );
+				bindOneToOne( subnode, (OneToOne) value, propertyName, true, mappings );
+			}
+			else if ( "property".equals( name ) ) {
+				value = new SimpleValue( table );
+				bindSimpleValue( subnode, (SimpleValue) value, nullable, propertyName, mappings );
+			}
+			else if ( "component".equals( name )
+				|| "dynamic-component".equals( name )
+				|| "properties".equals( name ) ) {
+				String subpath = StringHelper.qualify( entityName, propertyName );
+				value = new Component( persistentClass );
+
+				bindComponent(
+						subnode,
+						(Component) value,
+						persistentClass.getClassName(),
+						propertyName,
+						subpath,
+						true,
+						"properties".equals( name ),
+						mappings,
+						inheritedMetas,
+						false
+					);
+			}
+			else if ( "join".equals( name ) ) {
+				Join join = new Join();
+				join.setPersistentClass( persistentClass );
+				bindJoin( subnode, join, mappings, inheritedMetas );
+				persistentClass.addJoin( join );
+			}
+			else if ( "subclass".equals( name ) ) {
+				handleSubclass( persistentClass, mappings, subnode, inheritedMetas );
+			}
+			else if ( "joined-subclass".equals( name ) ) {
+				handleJoinedSubclass( persistentClass, mappings, subnode, inheritedMetas );
+			}
+			else if ( "union-subclass".equals( name ) ) {
+				handleUnionSubclass( persistentClass, mappings, subnode, inheritedMetas );
+			}
+			else if ( "filter".equals( name ) ) {
+				parseFilter( subnode, persistentClass, mappings );
+			}
+			else if ( "natural-id".equals( name ) ) {
+				UniqueKey uk = new UniqueKey();
+				uk.setName("_UniqueKey");
+				uk.setTable(table);
+				//by default, natural-ids are "immutable" (constant)
+				boolean mutableId = "true".equals( subnode.attributeValue("mutable") );
+				createClassProperties(
+						subnode,
+						persistentClass,
+						mappings,
+						inheritedMetas,
+						uk,
+						mutableId,
+						false,
+						true
+					);
+				table.addUniqueKey(uk);
+			}
+			else if ( "query".equals(name) ) {
+				bindNamedQuery(subnode, persistentClass.getEntityName(), mappings);
+			}
+			else if ( "sql-query".equals(name) ) {
+				bindNamedSQLQuery(subnode, persistentClass.getEntityName(), mappings);
+			}
+			else if ( "resultset".equals(name) ) {
+				bindResultSetMappingDefinition( subnode, persistentClass.getEntityName(), mappings );
+			}
+
+			if ( value != null ) {
+				Property property = createProperty( value, propertyName, persistentClass
+					.getClassName(), subnode, mappings, inheritedMetas );
+				if ( !mutable ) property.setUpdateable(false);
+				if ( naturalId ) property.setNaturalIdentifier(true);
+				persistentClass.addProperty( property );
+				if ( uniqueKey!=null ) uniqueKey.addColumns( property.getColumnIterator() );
+			}
+
+		}
+	}
+
+	private static Property createProperty(
+			final Value value,
+	        final String propertyName,
+			final String className,
+	        final Element subnode,
+	        final Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		if ( StringHelper.isEmpty( propertyName ) ) {
+			throw new MappingException( subnode.getName() + " mapping must defined a name attribute [" + className + "]" );
+		}
+
+		value.setTypeUsingReflection( className, propertyName );
+
+		// this is done here 'cos we might only know the type here (ugly!)
+		// TODO: improve this a lot:
+		if ( value instanceof ToOne ) {
+			ToOne toOne = (ToOne) value;
+			String propertyRef = toOne.getReferencedPropertyName();
+			if ( propertyRef != null ) {
+				mappings.addUniquePropertyReference( toOne.getReferencedEntityName(), propertyRef );
+			}
+		}
+		else if ( value instanceof Collection ) {
+			Collection coll = (Collection) value;
+			String propertyRef = coll.getReferencedPropertyName();
+			// not necessarily a *unique* property reference
+			if ( propertyRef != null ) {
+				mappings.addPropertyReference( coll.getOwnerEntityName(), propertyRef );
+			}
+		}
+
+		value.createForeignKey();
+		Property prop = new Property();
+		prop.setValue( value );
+		bindProperty( subnode, prop, mappings, inheritedMetas );
+		return prop;
+	}
+
+	private static void handleUnionSubclass(PersistentClass model, Mappings mappings,
+			Element subnode, java.util.Map inheritedMetas) throws MappingException {
+		UnionSubclass subclass = new UnionSubclass( model );
+		bindUnionSubclass( subnode, subclass, mappings, inheritedMetas );
+		model.addSubclass( subclass );
+		mappings.addClass( subclass );
+	}
+
+	private static void handleJoinedSubclass(PersistentClass model, Mappings mappings,
+			Element subnode, java.util.Map inheritedMetas) throws MappingException {
+		JoinedSubclass subclass = new JoinedSubclass( model );
+		bindJoinedSubclass( subnode, subclass, mappings, inheritedMetas );
+		model.addSubclass( subclass );
+		mappings.addClass( subclass );
+	}
+
+	private static void handleSubclass(PersistentClass model, Mappings mappings, Element subnode,
+			java.util.Map inheritedMetas) throws MappingException {
+		Subclass subclass = new SingleTableSubclass( model );
+		bindSubclass( subnode, subclass, mappings, inheritedMetas );
+		model.addSubclass( subclass );
+		mappings.addClass( subclass );
+	}
+
+	/**
+	 * Called for Lists, arrays, primitive arrays
+	 */
+	public static void bindListSecondPass(Element node, List list, java.util.Map classes,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		bindCollectionSecondPass( node, list, classes, mappings, inheritedMetas );
+
+		Element subnode = node.element( "list-index" );
+		if ( subnode == null ) subnode = node.element( "index" );
+		SimpleValue iv = new SimpleValue( list.getCollectionTable() );
+		bindSimpleValue(
+				subnode,
+				iv,
+				list.isOneToMany(),
+				IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
+				mappings
+			);
+		iv.setTypeName( "integer" );
+		list.setIndex( iv );
+		String baseIndex = subnode.attributeValue( "base" );
+		if ( baseIndex != null ) list.setBaseIndex( Integer.parseInt( baseIndex ) );
+		list.setIndexNodeName( subnode.attributeValue("node") );
+
+		if ( list.isOneToMany() && !list.getKey().isNullable() && !list.isInverse() ) {
+			String entityName = ( (OneToMany) list.getElement() ).getReferencedEntityName();
+			PersistentClass referenced = mappings.getClass( entityName );
+			IndexBackref ib = new IndexBackref();
+			ib.setName( '_' + list.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "IndexBackref" );
+			ib.setUpdateable( false );
+			ib.setSelectable( false );
+			ib.setCollectionRole( list.getRole() );
+			ib.setEntityName( list.getOwner().getEntityName() );
+			ib.setValue( list.getIndex() );
+			// ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next()
+			// ).setNullable(false);
+			referenced.addProperty( ib );
+		}
+	}
+
+	public static void bindIdentifierCollectionSecondPass(Element node,
+			IdentifierCollection collection, java.util.Map persistentClasses, Mappings mappings,
+			java.util.Map inheritedMetas) throws MappingException {
+
+		bindCollectionSecondPass( node, collection, persistentClasses, mappings, inheritedMetas );
+
+		Element subnode = node.element( "collection-id" );
+		SimpleValue id = new SimpleValue( collection.getCollectionTable() );
+		bindSimpleValue(
+				subnode,
+				id,
+				false,
+				IdentifierCollection.DEFAULT_IDENTIFIER_COLUMN_NAME,
+				mappings
+			);
+		collection.setIdentifier( id );
+		makeIdentifier( subnode, id, mappings );
+
+	}
+
+	/**
+	 * Called for Maps
+	 */
+	public static void bindMapSecondPass(Element node, Map map, java.util.Map classes,
+			Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+
+		bindCollectionSecondPass( node, map, classes, mappings, inheritedMetas );
+
+		Iterator iter = node.elementIterator();
+		while ( iter.hasNext() ) {
+			Element subnode = (Element) iter.next();
+			String name = subnode.getName();
+
+			if ( "index".equals( name ) || "map-key".equals( name ) ) {
+				SimpleValue value = new SimpleValue( map.getCollectionTable() );
+				bindSimpleValue(
+						subnode,
+						value,
+						map.isOneToMany(),
+						IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
+						mappings
+					);
+				if ( !value.isTypeSpecified() ) {
+					throw new MappingException( "map index element must specify a type: "
+						+ map.getRole() );
+				}
+				map.setIndex( value );
+				map.setIndexNodeName( subnode.attributeValue("node") );
+			}
+			else if ( "index-many-to-many".equals( name ) || "map-key-many-to-many".equals( name ) ) {
+				ManyToOne mto = new ManyToOne( map.getCollectionTable() );
+				bindManyToOne(
+						subnode,
+						mto,
+						IndexedCollection.DEFAULT_INDEX_COLUMN_NAME,
+						map.isOneToMany(),
+						mappings
+					);
+				map.setIndex( mto );
+
+			}
+			else if ( "composite-index".equals( name ) || "composite-map-key".equals( name ) ) {
+				Component component = new Component( map );
+				bindComposite(
+						subnode,
+						component,
+						map.getRole() + ".index",
+						map.isOneToMany(),
+						mappings,
+						inheritedMetas
+					);
+				map.setIndex( component );
+			}
+			else if ( "index-many-to-any".equals( name ) ) {
+				Any any = new Any( map.getCollectionTable() );
+				bindAny( subnode, any, map.isOneToMany(), mappings );
+				map.setIndex( any );
+			}
+		}
+
+		// TODO: this is a bit of copy/paste from IndexedCollection.createPrimaryKey()
+		boolean indexIsFormula = false;
+		Iterator colIter = map.getIndex().getColumnIterator();
+		while ( colIter.hasNext() ) {
+			if ( ( (Selectable) colIter.next() ).isFormula() ) indexIsFormula = true;
+		}
+
+		if ( map.isOneToMany() && !map.getKey().isNullable() && !map.isInverse() && !indexIsFormula ) {
+			String entityName = ( (OneToMany) map.getElement() ).getReferencedEntityName();
+			PersistentClass referenced = mappings.getClass( entityName );
+			IndexBackref ib = new IndexBackref();
+			ib.setName( '_' + map.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "IndexBackref" );
+			ib.setUpdateable( false );
+			ib.setSelectable( false );
+			ib.setCollectionRole( map.getRole() );
+			ib.setEntityName( map.getOwner().getEntityName() );
+			ib.setValue( map.getIndex() );
+			// ( (Column) ( (SimpleValue) ic.getIndex() ).getColumnIterator().next()
+			// ).setNullable(false);
+			referenced.addProperty( ib );
+		}
+	}
+
+	/**
+	 * Called for all collections
+	 */
+	public static void bindCollectionSecondPass(Element node, Collection collection,
+			java.util.Map persistentClasses, Mappings mappings, java.util.Map inheritedMetas)
+			throws MappingException {
+
+		if ( collection.isOneToMany() ) {
+			OneToMany oneToMany = (OneToMany) collection.getElement();
+			String assocClass = oneToMany.getReferencedEntityName();
+			PersistentClass persistentClass = (PersistentClass) persistentClasses.get( assocClass );
+			if ( persistentClass == null ) {
+				throw new MappingException( "Association references unmapped class: " + assocClass );
+			}
+			oneToMany.setAssociatedClass( persistentClass );
+			collection.setCollectionTable( persistentClass.getTable() );
+
+			log.info(
+					"Mapping collection: " + collection.getRole() +
+					" -> " + collection.getCollectionTable().getName()
+				);
+		}
+
+		// CHECK
+		Attribute chNode = node.attribute( "check" );
+		if ( chNode != null ) {
+			collection.getCollectionTable().addCheckConstraint( chNode.getValue() );
+		}
+
+		// contained elements:
+		Iterator iter = node.elementIterator();
+		while ( iter.hasNext() ) {
+			Element subnode = (Element) iter.next();
+			String name = subnode.getName();
+
+			if ( "key".equals( name ) ) {
+				KeyValue keyVal;
+				String propRef = collection.getReferencedPropertyName();
+				if ( propRef == null ) {
+					keyVal = collection.getOwner().getIdentifier();
+				}
+				else {
+					keyVal = (KeyValue) collection.getOwner().getRecursiveProperty( propRef ).getValue();
+				}
+				SimpleValue key = new DependantValue( collection.getCollectionTable(), keyVal );
+				key.setCascadeDeleteEnabled( "cascade"
+					.equals( subnode.attributeValue( "on-delete" ) ) );
+				bindSimpleValue(
+						subnode,
+						key,
+						collection.isOneToMany(),
+						Collection.DEFAULT_KEY_COLUMN_NAME,
+						mappings
+					);
+				collection.setKey( key );
+
+				Attribute notNull = subnode.attribute( "not-null" );
+				( (DependantValue) key ).setNullable( notNull == null
+					|| notNull.getValue().equals( "false" ) );
+				Attribute updateable = subnode.attribute( "update" );
+				( (DependantValue) key ).setUpdateable( updateable == null
+					|| updateable.getValue().equals( "true" ) );
+
+			}
+			else if ( "element".equals( name ) ) {
+				SimpleValue elt = new SimpleValue( collection.getCollectionTable() );
+				collection.setElement( elt );
+				bindSimpleValue(
+						subnode,
+						elt,
+						true,
+						Collection.DEFAULT_ELEMENT_COLUMN_NAME,
+						mappings
+					);
+			}
+			else if ( "many-to-many".equals( name ) ) {
+				ManyToOne element = new ManyToOne( collection.getCollectionTable() );
+				collection.setElement( element );
+				bindManyToOne(
+						subnode,
+						element,
+						Collection.DEFAULT_ELEMENT_COLUMN_NAME,
+						false,
+						mappings
+					);
+				bindManyToManySubelements( collection, subnode, mappings );
+			}
+			else if ( "composite-element".equals( name ) ) {
+				Component element = new Component( collection );
+				collection.setElement( element );
+				bindComposite(
+						subnode,
+						element,
+						collection.getRole() + ".element",
+						true,
+						mappings,
+						inheritedMetas
+					);
+			}
+			else if ( "many-to-any".equals( name ) ) {
+				Any element = new Any( collection.getCollectionTable() );
+				collection.setElement( element );
+				bindAny( subnode, element, true, mappings );
+			}
+			else if ( "cache".equals( name ) ) {
+				collection.setCacheConcurrencyStrategy( subnode.attributeValue( "usage" ) );
+				collection.setCacheRegionName( subnode.attributeValue( "region" ) );
+			}
+
+			String nodeName = subnode.attributeValue( "node" );
+			if ( nodeName != null ) collection.setElementNodeName( nodeName );
+
+		}
+
+		if ( collection.isOneToMany()
+			&& !collection.isInverse()
+			&& !collection.getKey().isNullable() ) {
+			// for non-inverse one-to-many, with a not-null fk, add a backref!
+			String entityName = ( (OneToMany) collection.getElement() ).getReferencedEntityName();
+			PersistentClass referenced = mappings.getClass( entityName );
+			Backref prop = new Backref();
+			prop.setName( '_' + collection.getOwnerEntityName() + "." + node.attributeValue( "name" ) + "Backref" );
+			prop.setUpdateable( false );
+			prop.setSelectable( false );
+			prop.setCollectionRole( collection.getRole() );
+			prop.setEntityName( collection.getOwner().getEntityName() );
+			prop.setValue( collection.getKey() );
+			referenced.addProperty( prop );
+		}
+	}
+
+	private static void bindManyToManySubelements(
+	        Collection collection,
+	        Element manyToManyNode,
+	        Mappings model) throws MappingException {
+		// Bind the where
+		Attribute where = manyToManyNode.attribute( "where" );
+		String whereCondition = where == null ? null : where.getValue();
+		collection.setManyToManyWhere( whereCondition );
+
+		// Bind the order-by
+		Attribute order = manyToManyNode.attribute( "order-by" );
+		String orderFragment = order == null ? null : order.getValue();
+		collection.setManyToManyOrdering( orderFragment );
+
+		// Bind the filters
+		Iterator filters = manyToManyNode.elementIterator( "filter" );
+		if ( ( filters.hasNext() || whereCondition != null ) &&
+		        collection.getFetchMode() == FetchMode.JOIN &&
+		        collection.getElement().getFetchMode() != FetchMode.JOIN ) {
+			throw new MappingException(
+			        "many-to-many defining filter or where without join fetching " +
+			        "not valid within collection using join fetching [" + collection.getRole() + "]"
+				);
+		}
+		while ( filters.hasNext() ) {
+			final Element filterElement = ( Element ) filters.next();
+			final String name = filterElement.attributeValue( "name" );
+			String condition = filterElement.getTextTrim();
+			if ( StringHelper.isEmpty(condition) ) condition = filterElement.attributeValue( "condition" );
+			if ( StringHelper.isEmpty(condition) ) {
+				condition = model.getFilterDefinition(name).getDefaultFilterCondition();
+			}
+			if ( condition==null) {
+				throw new MappingException("no filter condition found for filter: " + name);
+			}
+			log.debug(
+					"Applying many-to-many filter [" + name +
+					"] as [" + condition +
+					"] to role [" + collection.getRole() + "]"
+				);
+			collection.addManyToManyFilter( name, condition );
+		}
+	}
+
+	public static final FlushMode getFlushMode(String flushMode) {
+		if ( flushMode == null ) {
+			return null;
+		}
+		else if ( "auto".equals( flushMode ) ) {
+			return FlushMode.AUTO;
+		}
+		else if ( "commit".equals( flushMode ) ) {
+			return FlushMode.COMMIT;
+		}
+		else if ( "never".equals( flushMode ) ) {
+			return FlushMode.NEVER;
+		}
+		else if ( "manual".equals( flushMode ) ) {
+			return FlushMode.MANUAL;
+		}
+		else if ( "always".equals( flushMode ) ) {
+			return FlushMode.ALWAYS;
+		}
+		else {
+			throw new MappingException( "unknown flushmode" );
+		}
+	}
+
+	private static void bindNamedQuery(Element queryElem, String path, Mappings mappings) {
+		String queryName = queryElem.attributeValue( "name" );
+		if (path!=null) queryName = path + '.' + queryName;
+		String query = queryElem.getText();
+		log.debug( "Named query: " + queryName + " -> " + query );
+
+		boolean cacheable = "true".equals( queryElem.attributeValue( "cacheable" ) );
+		String region = queryElem.attributeValue( "cache-region" );
+		Attribute tAtt = queryElem.attribute( "timeout" );
+		Integer timeout = tAtt == null ? null : new Integer( tAtt.getValue() );
+		Attribute fsAtt = queryElem.attribute( "fetch-size" );
+		Integer fetchSize = fsAtt == null ? null : new Integer( fsAtt.getValue() );
+		Attribute roAttr = queryElem.attribute( "read-only" );
+		boolean readOnly = roAttr != null && "true".equals( roAttr.getValue() );
+		Attribute cacheModeAtt = queryElem.attribute( "cache-mode" );
+		String cacheMode = cacheModeAtt == null ? null : cacheModeAtt.getValue();
+		Attribute cmAtt = queryElem.attribute( "comment" );
+		String comment = cmAtt == null ? null : cmAtt.getValue();
+
+		NamedQueryDefinition namedQuery = new NamedQueryDefinition(
+				query,
+				cacheable,
+				region,
+				timeout,
+				fetchSize,
+				getFlushMode( queryElem.attributeValue( "flush-mode" ) ) ,
+				getCacheMode( cacheMode ),
+				readOnly,
+				comment,
+				getParameterTypes(queryElem)
+			);
+
+		mappings.addQuery( queryName, namedQuery );
+	}
+
+	public static CacheMode getCacheMode(String cacheMode) {
+		if (cacheMode == null) return null;
+		if ( "get".equals( cacheMode ) ) return CacheMode.GET;
+		if ( "ignore".equals( cacheMode ) ) return CacheMode.IGNORE;
+		if ( "normal".equals( cacheMode ) ) return CacheMode.NORMAL;
+		if ( "put".equals( cacheMode ) ) return CacheMode.PUT;
+		if ( "refresh".equals( cacheMode ) ) return CacheMode.REFRESH;
+		throw new MappingException("Unknown Cache Mode: " + cacheMode);
+	}
+
+	public static java.util.Map getParameterTypes(Element queryElem) {
+		java.util.Map result = new java.util.LinkedHashMap();
+		Iterator iter = queryElem.elementIterator("query-param");
+		while ( iter.hasNext() ) {
+			Element element = (Element) iter.next();
+			result.put( element.attributeValue("name"), element.attributeValue("type") );
+		}
+		return result;
+	}
+
+	private static void bindResultSetMappingDefinition(Element resultSetElem, String path, Mappings mappings) {
+		mappings.addSecondPass( new ResultSetMappingSecondPass( resultSetElem, path, mappings ) );
+	}
+
+	private static void bindNamedSQLQuery(Element queryElem, String path, Mappings mappings) {
+		mappings.addSecondPass( new NamedSQLQuerySecondPass( queryElem, path, mappings ) );
+	}
+
+	private static String getPropertyName(Element node) {
+		return node.attributeValue( "name" );
+	}
+
+	private static PersistentClass getSuperclass(Mappings mappings, Element subnode)
+			throws MappingException {
+		String extendsName = subnode.attributeValue( "extends" );
+		PersistentClass superModel = mappings.getClass( extendsName );
+		if ( superModel == null ) {
+			String qualifiedExtendsName = getClassName( extendsName, mappings );
+			superModel = mappings.getClass( qualifiedExtendsName );
+		}
+
+		if ( superModel == null ) {
+			throw new MappingException( "Cannot extend unmapped class " + extendsName );
+		}
+		return superModel;
+	}
+
+	static class CollectionSecondPass extends org.hibernate.cfg.CollectionSecondPass {
+		Element node;
+
+		CollectionSecondPass(Element node, Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
+			super(mappings, collection, inheritedMetas);
+			this.node = node;
+		}
+
+		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+				throws MappingException {
+			HbmBinder.bindCollectionSecondPass(
+					node,
+					collection,
+					persistentClasses,
+					mappings,
+					inheritedMetas
+				);
+		}
+	}
+
+	static class IdentifierCollectionSecondPass extends CollectionSecondPass {
+		IdentifierCollectionSecondPass(Element node, Mappings mappings, Collection collection, java.util.Map inheritedMetas) {
+			super( node, mappings, collection, inheritedMetas );
+		}
+
+		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+				throws MappingException {
+			HbmBinder.bindIdentifierCollectionSecondPass(
+					node,
+					(IdentifierCollection) collection,
+					persistentClasses,
+					mappings,
+					inheritedMetas 
+				);
+		}
+
+	}
+
+	static class MapSecondPass extends CollectionSecondPass {
+		MapSecondPass(Element node, Mappings mappings, Map collection, java.util.Map inheritedMetas) {
+			super( node, mappings, collection, inheritedMetas );
+		}
+
+		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+				throws MappingException {
+			HbmBinder.bindMapSecondPass(
+					node,
+					(Map) collection,
+					persistentClasses,
+					mappings,
+					inheritedMetas 
+				);
+		}
+
+	}
+
+
+	static class ManyToOneSecondPass implements SecondPass {
+		private final ManyToOne manyToOne;
+
+		ManyToOneSecondPass(ManyToOne manyToOne) {
+			this.manyToOne = manyToOne;
+		}
+
+		public void doSecondPass(java.util.Map persistentClasses) throws MappingException {
+			manyToOne.createPropertyRefConstraints(persistentClasses);
+		}
+
+	}
+	
+	static class ListSecondPass extends CollectionSecondPass {
+		ListSecondPass(Element node, Mappings mappings, List collection, java.util.Map inheritedMetas) {
+			super( node, mappings, collection, inheritedMetas );
+		}
+
+		public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
+				throws MappingException {
+			HbmBinder.bindListSecondPass(
+					node,
+					(List) collection,
+					persistentClasses,
+					mappings,
+					inheritedMetas 
+				);
+		}
+
+	}
+
+	// This inner class implements a case statement....perhaps im being a bit over-clever here
+	abstract static class CollectionType {
+		private String xmlTag;
+
+		public abstract Collection create(Element node, String path, PersistentClass owner,
+				Mappings mappings, java.util.Map inheritedMetas) throws MappingException;
+
+		CollectionType(String xmlTag) {
+			this.xmlTag = xmlTag;
+		}
+
+		public String toString() {
+			return xmlTag;
+		}
+
+		private static final CollectionType MAP = new CollectionType( "map" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				Map map = new Map( owner );
+				bindCollection( node, map, owner.getEntityName(), path, mappings, inheritedMetas );
+				return map;
+			}
+		};
+		private static final CollectionType SET = new CollectionType( "set" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				Set set = new Set( owner );
+				bindCollection( node, set, owner.getEntityName(), path, mappings, inheritedMetas );
+				return set;
+			}
+		};
+		private static final CollectionType LIST = new CollectionType( "list" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				List list = new List( owner );
+				bindCollection( node, list, owner.getEntityName(), path, mappings, inheritedMetas );
+				return list;
+			}
+		};
+		private static final CollectionType BAG = new CollectionType( "bag" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				Bag bag = new Bag( owner );
+				bindCollection( node, bag, owner.getEntityName(), path, mappings, inheritedMetas );
+				return bag;
+			}
+		};
+		private static final CollectionType IDBAG = new CollectionType( "idbag" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				IdentifierBag bag = new IdentifierBag( owner );
+				bindCollection( node, bag, owner.getEntityName(), path, mappings, inheritedMetas );
+				return bag;
+			}
+		};
+		private static final CollectionType ARRAY = new CollectionType( "array" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				Array array = new Array( owner );
+				bindArray( node, array, owner.getEntityName(), path, mappings, inheritedMetas );
+				return array;
+			}
+		};
+		private static final CollectionType PRIMITIVE_ARRAY = new CollectionType( "primitive-array" ) {
+			public Collection create(Element node, String path, PersistentClass owner,
+					Mappings mappings, java.util.Map inheritedMetas) throws MappingException {
+				PrimitiveArray array = new PrimitiveArray( owner );
+				bindArray( node, array, owner.getEntityName(), path, mappings, inheritedMetas );
+				return array;
+			}
+		};
+		private static final HashMap INSTANCES = new HashMap();
+
+		static {
+			INSTANCES.put( MAP.toString(), MAP );
+			INSTANCES.put( BAG.toString(), BAG );
+			INSTANCES.put( IDBAG.toString(), IDBAG );
+			INSTANCES.put( SET.toString(), SET );
+			INSTANCES.put( LIST.toString(), LIST );
+			INSTANCES.put( ARRAY.toString(), ARRAY );
+			INSTANCES.put( PRIMITIVE_ARRAY.toString(), PRIMITIVE_ARRAY );
+		}
+
+		public static CollectionType collectionTypeFromString(String xmlTagName) {
+			return (CollectionType) INSTANCES.get( xmlTagName );
+		}
+	}
+
+	private static int getOptimisticLockMode(Attribute olAtt) throws MappingException {
+
+		if ( olAtt == null ) return Versioning.OPTIMISTIC_LOCK_VERSION;
+		String olMode = olAtt.getValue();
+		if ( olMode == null || "version".equals( olMode ) ) {
+			return Versioning.OPTIMISTIC_LOCK_VERSION;
+		}
+		else if ( "dirty".equals( olMode ) ) {
+			return Versioning.OPTIMISTIC_LOCK_DIRTY;
+		}
+		else if ( "all".equals( olMode ) ) {
+			return Versioning.OPTIMISTIC_LOCK_ALL;
+		}
+		else if ( "none".equals( olMode ) ) {
+			return Versioning.OPTIMISTIC_LOCK_NONE;
+		}
+		else {
+			throw new MappingException( "Unsupported optimistic-lock style: " + olMode );
+		}
+	}
+
+	private static final java.util.Map getMetas(Element node, java.util.Map inheritedMeta) {
+		return getMetas( node, inheritedMeta, false );
+	}
+
+	public static final java.util.Map getMetas(Element node, java.util.Map inheritedMeta,
+			boolean onlyInheritable) {
+		java.util.Map map = new HashMap();
+		map.putAll( inheritedMeta );
+
+		Iterator iter = node.elementIterator( "meta" );
+		while ( iter.hasNext() ) {
+			Element metaNode = (Element) iter.next();
+			boolean inheritable = Boolean
+				.valueOf( metaNode.attributeValue( "inherit" ) )
+				.booleanValue();
+			if ( onlyInheritable & !inheritable ) {
+				continue;
+			}
+			String name = metaNode.attributeValue( "attribute" );
+
+			MetaAttribute meta = (MetaAttribute) map.get( name );
+			MetaAttribute inheritedAttribute = (MetaAttribute) inheritedMeta.get( name );
+			if ( meta == null  ) {
+				meta = new MetaAttribute( name );
+				map.put( name, meta );
+			} else if (meta == inheritedAttribute) { // overriding inherited meta attribute. HBX-621 & HBX-793			
+				meta = new MetaAttribute( name );				
+				map.put( name, meta );				
+			}			
+			meta.addValue( metaNode.getText() );
+		}
+		return map;
+	}
+
+	public static String getEntityName(Element elem, Mappings model) {
+		String entityName = elem.attributeValue( "entity-name" );
+		return entityName == null ? getClassName( elem.attribute( "class" ), model ) : entityName;
+	}
+
+	private static String getClassName(Attribute att, Mappings model) {
+		if ( att == null ) return null;
+		return getClassName( att.getValue(), model );
+	}
+
+	public static String getClassName(String unqualifiedName, Mappings model) {
+		return getClassName( unqualifiedName, model.getDefaultPackage() );
+	}
+
+	public static String getClassName(String unqualifiedName, String defaultPackage) {
+		if ( unqualifiedName == null ) return null;
+		if ( unqualifiedName.indexOf( '.' ) < 0 && defaultPackage != null ) {
+			return defaultPackage + '.' + unqualifiedName;
+		}
+		return unqualifiedName;
+	}
+
+	private static void parseFilterDef(Element element, Mappings mappings) {
+		String name = element.attributeValue( "name" );
+		log.debug( "Parsing filter-def [" + name + "]" );
+		String defaultCondition = element.getTextTrim();
+		if ( StringHelper.isEmpty( defaultCondition ) ) {
+			defaultCondition = element.attributeValue( "condition" );
+		}
+		HashMap paramMappings = new HashMap();
+		Iterator params = element.elementIterator( "filter-param" );
+		while ( params.hasNext() ) {
+			final Element param = (Element) params.next();
+			final String paramName = param.attributeValue( "name" );
+			final String paramType = param.attributeValue( "type" );
+			log.debug( "adding filter parameter : " + paramName + " -> " + paramType );
+			final Type heuristicType = TypeFactory.heuristicType( paramType );
+			log.debug( "parameter heuristic type : " + heuristicType );
+			paramMappings.put( paramName, heuristicType );
+		}
+		log.debug( "Parsed filter-def [" + name + "]" );
+		FilterDefinition def = new FilterDefinition( name, defaultCondition, paramMappings );
+		mappings.addFilterDefinition( def );
+	}
+
+	private static void parseFilter(Element filterElement, Filterable filterable, Mappings model) {
+		final String name = filterElement.attributeValue( "name" );
+		String condition = filterElement.getTextTrim();
+		if ( StringHelper.isEmpty(condition) ) {
+			condition = filterElement.attributeValue( "condition" );
+		}
+		//TODO: bad implementation, cos it depends upon ordering of mapping doc
+		//      fixing this requires that Collection/PersistentClass gain access
+		//      to the Mappings reference from Configuration (or the filterDefinitions
+		//      map directly) sometime during Configuration.buildSessionFactory
+		//      (after all the types/filter-defs are known and before building
+		//      persisters).
+		if ( StringHelper.isEmpty(condition) ) {
+			condition = model.getFilterDefinition(name).getDefaultFilterCondition();
+		}
+		if ( condition==null) {
+			throw new MappingException("no filter condition found for filter: " + name);
+		}
+		log.debug( "Applying filter [" + name + "] as [" + condition + "]" );
+		filterable.addFilter( name, condition );
+	}
+
+	private static String getSubselect(Element element) {
+		String subselect = element.attributeValue( "subselect" );
+		if ( subselect != null ) {
+			return subselect;
+		}
+		else {
+			Element subselectElement = element.element( "subselect" );
+			return subselectElement == null ? null : subselectElement.getText();
+		}
+	}
+
+	/**
+	 * For the given document, locate all extends attributes which refer to
+	 * entities (entity-name or class-name) not defined within said document.
+	 *
+	 * @param doc The document to check
+	 * @param mappings The already processed mappings.
+	 * @return The list of unresolved extends names.
+	 */
+	public static java.util.List getExtendsNeeded(Document doc, Mappings mappings) {
+		java.util.List extendz = new ArrayList();
+		Iterator[] subclasses = new Iterator[3];
+		final Element hmNode = doc.getRootElement();
+
+		Attribute packNode = hmNode.attribute( "package" );
+		final String packageName = packNode == null ? null : packNode.getValue();
+		if ( packageName != null ) {
+			mappings.setDefaultPackage( packageName );
+		}
+
+		// first, iterate over all elements capable of defining an extends attribute
+		// collecting all found extends references if they cannot be resolved
+		// against the already processed mappings.
+		subclasses[0] = hmNode.elementIterator( "subclass" );
+		subclasses[1] = hmNode.elementIterator( "joined-subclass" );
+		subclasses[2] = hmNode.elementIterator( "union-subclass" );
+
+		Iterator iterator = new JoinedIterator( subclasses );
+		while ( iterator.hasNext() ) {
+			final Element element = (Element) iterator.next();
+			final String extendsName = element.attributeValue( "extends" );
+			// mappings might contain either the "raw" extends name (in the case of
+			// an entity-name mapping) or a FQN (in the case of a POJO mapping).
+			if ( mappings.getClass( extendsName ) == null && mappings.getClass( getClassName( extendsName, mappings ) ) == null ) {
+				extendz.add( extendsName );
+			}
+		}
+
+		if ( !extendz.isEmpty() ) {
+			// we found some extends attributes referencing entities which were
+			// not already processed.  here we need to locate all entity-names
+			// and class-names contained in this document itself, making sure
+			// that these get removed from the extendz list such that only
+			// extends names which require us to delay processing (i.e.
+			// external to this document and not yet processed) are contained
+			// in the returned result
+			final java.util.Set set = new HashSet( extendz );
+			EntityElementHandler handler = new EntityElementHandler() {
+				public void handleEntity(String entityName, String className, Mappings mappings) {
+					if ( entityName != null ) {
+						set.remove( entityName );
+					}
+					else {
+						String fqn = getClassName( className, packageName );
+						set.remove( fqn );
+						if ( packageName != null ) {
+							set.remove( StringHelper.unqualify( fqn ) );
+						}
+					}
+				}
+			};
+			recognizeEntities( mappings, hmNode, handler );
+			extendz.clear();
+			extendz.addAll( set );
+		}
+
+		return extendz;
+	}
+
+	/**
+	 * Given an entity-containing-element (startNode) recursively locate all
+	 * entity names defined within that element.
+	 *
+	 * @param mappings The already processed mappings
+	 * @param startNode The containing element
+	 * @param handler The thing that knows what to do whenever we recognize an
+	 * entity-name
+	 */
+	private static void recognizeEntities(
+			Mappings mappings,
+	        final Element startNode,
+			EntityElementHandler handler) {
+		Iterator[] classes = new Iterator[4];
+		classes[0] = startNode.elementIterator( "class" );
+		classes[1] = startNode.elementIterator( "subclass" );
+		classes[2] = startNode.elementIterator( "joined-subclass" );
+		classes[3] = startNode.elementIterator( "union-subclass" );
+
+		Iterator classIterator = new JoinedIterator( classes );
+		while ( classIterator.hasNext() ) {
+			Element element = (Element) classIterator.next();
+			handler.handleEntity(
+					element.attributeValue( "entity-name" ),
+		            element.attributeValue( "name" ),
+			        mappings
+			);
+			recognizeEntities( mappings, element, handler );
+		}
+	}
+
+	private static interface EntityElementHandler {
+		public void handleEntity(String entityName, String className, Mappings mappings);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,124 +0,0 @@
-//$Id: ImprovedNamingStrategy.java 9941 2006-05-22 18:28:53Z epbernard $
-package org.hibernate.cfg;
-
-import java.io.Serializable;
-
-import org.hibernate.util.StringHelper;
-import org.hibernate.AssertionFailure;
-
-/**
- * An improved naming strategy that prefers embedded
- * underscores to mixed case names
- * @see DefaultNamingStrategy the default strategy
- * @author Gavin King
- */
-public class ImprovedNamingStrategy implements NamingStrategy, Serializable {
-
-	/**
-	 * A convenient singleton instance
-	 */
-	public static final NamingStrategy INSTANCE = new ImprovedNamingStrategy();
-
-	/**
-	 * Return the unqualified class name, mixed case converted to
-	 * underscores
-	 */
-	public String classToTableName(String className) {
-		return addUnderscores( StringHelper.unqualify(className) );
-	}
-	/**
-	 * Return the full property path with underscore seperators, mixed
-	 * case converted to underscores
-	 */
-	public String propertyToColumnName(String propertyName) {
-		return addUnderscores( StringHelper.unqualify(propertyName) );
-	}
-	/**
-	 * Convert mixed case to underscores
-	 */
-	public String tableName(String tableName) {
-		return addUnderscores(tableName);
-	}
-	/**
-	 * Convert mixed case to underscores
-	 */
-	public String columnName(String columnName) {
-		return addUnderscores(columnName);
-	}
-
-	protected static String addUnderscores(String name) {
-		StringBuffer buf = new StringBuffer( name.replace('.', '_') );
-		for (int i=1; i<buf.length()-1; i++) {
-			if (
-				Character.isLowerCase( buf.charAt(i-1) ) &&
-				Character.isUpperCase( buf.charAt(i) ) &&
-				Character.isLowerCase( buf.charAt(i+1) )
-			) {
-				buf.insert(i++, '_');
-			}
-		}
-		return buf.toString().toLowerCase();
-	}
-
-	public String collectionTableName(
-			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
-			String propertyName
-	) {
-		return tableName( ownerEntityTable + '_' + propertyToColumnName(propertyName) );
-	}
-
-	/**
-	 * Return the argument
-	 */
-	public String joinKeyColumnName(String joinedColumn, String joinedTable) {
-		return columnName( joinedColumn );
-	}
-
-	/**
-	 * Return the property name or propertyTableName
-	 */
-	public String foreignKeyColumnName(
-			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
-	) {
-		String header = propertyName != null ? StringHelper.unqualify( propertyName ) : propertyTableName;
-		if (header == null) throw new AssertionFailure("NamingStrategy not properly filled");
-		return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
-	}
-
-	/**
-	 * Return the column name or the unqualified property name
-	 */
-	public String logicalColumnName(String columnName, String propertyName) {
-		return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );
-	}
-
-	/**
-	 * Returns either the table name if explicit or
-	 * if there is an associated table, the concatenation of owner entity table and associated table
-	 * otherwise the concatenation of owner entity table and the unqualified property name
-	 */
-	public String logicalCollectionTableName(String tableName,
-											 String ownerEntityTable, String associatedEntityTable, String propertyName
-	) {
-		if ( tableName != null ) {
-			return tableName;
-		}
-		else {
-			//use of a stringbuffer to workaround a JDK bug
-			return new StringBuffer(ownerEntityTable).append("_")
-					.append(
-						associatedEntityTable != null ?
-						associatedEntityTable :
-						StringHelper.unqualify( propertyName )
-					).toString();
-		}
-	}
-	/**
-	 * Return the column name if explicit or the concatenation of the property name and the referenced column
-	 */
-	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) {
-		return StringHelper.isNotEmpty( columnName ) ?
-				columnName :
-				StringHelper.unqualify( propertyName ) + "_" + referencedColumn;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,147 @@
+/*
+ * 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.cfg;
+
+import java.io.Serializable;
+
+import org.hibernate.util.StringHelper;
+import org.hibernate.AssertionFailure;
+
+/**
+ * An improved naming strategy that prefers embedded
+ * underscores to mixed case names
+ * @see DefaultNamingStrategy the default strategy
+ * @author Gavin King
+ */
+public class ImprovedNamingStrategy implements NamingStrategy, Serializable {
+
+	/**
+	 * A convenient singleton instance
+	 */
+	public static final NamingStrategy INSTANCE = new ImprovedNamingStrategy();
+
+	/**
+	 * Return the unqualified class name, mixed case converted to
+	 * underscores
+	 */
+	public String classToTableName(String className) {
+		return addUnderscores( StringHelper.unqualify(className) );
+	}
+	/**
+	 * Return the full property path with underscore seperators, mixed
+	 * case converted to underscores
+	 */
+	public String propertyToColumnName(String propertyName) {
+		return addUnderscores( StringHelper.unqualify(propertyName) );
+	}
+	/**
+	 * Convert mixed case to underscores
+	 */
+	public String tableName(String tableName) {
+		return addUnderscores(tableName);
+	}
+	/**
+	 * Convert mixed case to underscores
+	 */
+	public String columnName(String columnName) {
+		return addUnderscores(columnName);
+	}
+
+	protected static String addUnderscores(String name) {
+		StringBuffer buf = new StringBuffer( name.replace('.', '_') );
+		for (int i=1; i<buf.length()-1; i++) {
+			if (
+				Character.isLowerCase( buf.charAt(i-1) ) &&
+				Character.isUpperCase( buf.charAt(i) ) &&
+				Character.isLowerCase( buf.charAt(i+1) )
+			) {
+				buf.insert(i++, '_');
+			}
+		}
+		return buf.toString().toLowerCase();
+	}
+
+	public String collectionTableName(
+			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
+			String propertyName
+	) {
+		return tableName( ownerEntityTable + '_' + propertyToColumnName(propertyName) );
+	}
+
+	/**
+	 * Return the argument
+	 */
+	public String joinKeyColumnName(String joinedColumn, String joinedTable) {
+		return columnName( joinedColumn );
+	}
+
+	/**
+	 * Return the property name or propertyTableName
+	 */
+	public String foreignKeyColumnName(
+			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
+	) {
+		String header = propertyName != null ? StringHelper.unqualify( propertyName ) : propertyTableName;
+		if (header == null) throw new AssertionFailure("NamingStrategy not properly filled");
+		return columnName( header ); //+ "_" + referencedColumnName not used for backward compatibility
+	}
+
+	/**
+	 * Return the column name or the unqualified property name
+	 */
+	public String logicalColumnName(String columnName, String propertyName) {
+		return StringHelper.isNotEmpty( columnName ) ? columnName : StringHelper.unqualify( propertyName );
+	}
+
+	/**
+	 * Returns either the table name if explicit or
+	 * if there is an associated table, the concatenation of owner entity table and associated table
+	 * otherwise the concatenation of owner entity table and the unqualified property name
+	 */
+	public String logicalCollectionTableName(String tableName,
+											 String ownerEntityTable, String associatedEntityTable, String propertyName
+	) {
+		if ( tableName != null ) {
+			return tableName;
+		}
+		else {
+			//use of a stringbuffer to workaround a JDK bug
+			return new StringBuffer(ownerEntityTable).append("_")
+					.append(
+						associatedEntityTable != null ?
+						associatedEntityTable :
+						StringHelper.unqualify( propertyName )
+					).toString();
+		}
+	}
+	/**
+	 * Return the column name if explicit or the concatenation of the property name and the referenced column
+	 */
+	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn) {
+		return StringHelper.isNotEmpty( columnName ) ?
+				columnName :
+				StringHelper.unqualify( propertyName ) + "_" + referencedColumn;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,542 +0,0 @@
-//$Id: Mappings.java 11051 2007-01-16 23:24:17Z epbernard $
-package org.hibernate.cfg;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.HashMap;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.DuplicateMappingException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.DenormalizedTable;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Table;
-import org.hibernate.mapping.TypeDef;
-import org.hibernate.mapping.AuxiliaryDatabaseObject;
-import org.hibernate.mapping.Column;
-import org.hibernate.util.StringHelper;
-
-/**
- * A collection of mappings from classes and collections to
- * relational database tables. (Represents a single
- * <tt>&lt;hibernate-mapping&gt;</tt> element.)
- * @author Gavin King
- */
-public class Mappings implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger(Mappings.class);
-
-	protected final Map classes;
-	protected final Map collections;
-	protected final Map tables;
-	protected final Map queries;
-	protected final Map sqlqueries;
-	protected final Map resultSetMappings;
-	protected final Map typeDefs;
-	protected final List secondPasses;
-	protected final Map imports;
-	protected String schemaName;
-    protected String catalogName;
-	protected String defaultCascade;
-	protected String defaultPackage;
-	protected String defaultAccess;
-	protected boolean autoImport;
-	protected boolean defaultLazy;
-	protected final List propertyReferences;
-	protected final NamingStrategy namingStrategy;
-	protected final Map filterDefinitions;
-	protected final List auxiliaryDatabaseObjects;
-
-	protected final Map extendsQueue;
-//	private final List extendsQueue;
-
-	/**
-	 * binding table between the logical column name and the name out of the naming strategy
-	 * for each table.
-	 * According that when the column name is not set, the property name is considered as such
-	 * This means that while theorically possible through the naming strategy contract, it is
-	 * forbidden to have 2 real columns having the same logical name
-	 * <Table, ColumnNames >
-	 */
-	protected final Map columnNameBindingPerTable;
-	/**
-	 * binding between logical table name and physical one (ie after the naming strategy has been applied)
-	 * <String, TableDescription>
-	 */
-	protected final Map tableNameBinding;
-
-
-	Mappings(
-			final Map classes,
-			final Map collections,
-			final Map tables,
-			final Map queries,
-			final Map sqlqueries,
-			final Map sqlResultSetMappings,
-			final Map imports,
-			final List secondPasses,
-			final List propertyReferences,
-			final NamingStrategy namingStrategy,
-			final Map typeDefs,
-			final Map filterDefinitions,
-//			final List extendsQueue,
-			final Map extendsQueue,
-			final List auxiliaryDatabaseObjects,
-			final Map tableNamebinding,
-			final Map columnNameBindingPerTable
-			) {
-		this.classes = classes;
-		this.collections = collections;
-		this.queries = queries;
-		this.sqlqueries = sqlqueries;
-		this.resultSetMappings = sqlResultSetMappings;
-		this.tables = tables;
-		this.imports = imports;
-		this.secondPasses = secondPasses;
-		this.propertyReferences = propertyReferences;
-		this.namingStrategy = namingStrategy;
-		this.typeDefs = typeDefs;
-		this.filterDefinitions = filterDefinitions;
-		this.extendsQueue = extendsQueue;
-		this.auxiliaryDatabaseObjects = auxiliaryDatabaseObjects;
-		this.tableNameBinding = tableNamebinding;
-		this.columnNameBindingPerTable = columnNameBindingPerTable;
-	}
-
-	public void addClass(PersistentClass persistentClass) throws MappingException {
-		Object old = classes.put( persistentClass.getEntityName(), persistentClass );
-		if ( old!=null ) {
-			throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() );
-		}
-	}
-	public void addCollection(Collection collection) throws MappingException {
-		Object old = collections.put( collection.getRole(), collection );
-		if ( old!=null ) {
-			throw new DuplicateMappingException( "collection role", collection.getRole() );
-		}
-	}
-	public PersistentClass getClass(String className) {
-		return (PersistentClass) classes.get(className);
-	}
-	public Collection getCollection(String role) {
-		return (Collection) collections.get(role);
-	}
-
-	public void addImport(String className, String rename) throws MappingException {
-		String existing = (String) imports.put(rename, className);
-		if ( existing!=null ) {
-			if ( existing.equals(className) ) {
-				log.info( "duplicate import: " + className + "->" + rename );
-			}
-			else {
-				throw new DuplicateMappingException(
-						"duplicate import: " + rename + 
-						" refers to both " + className + 
-						" and " + existing + 
-						" (try using auto-import=\"false\")",
-						"import",
-						rename
-					);
-			}
-		}
-	}
-
-	public Table addTable(String schema, 
-			String catalog, 
-			String name,
-			String subselect,
-			boolean isAbstract
-	) {
-        String key = subselect==null ?
-			Table.qualify(catalog, schema, name) :
-			subselect;
-		Table table = (Table) tables.get(key);
-
-		if (table == null) {
-			table = new Table();
-			table.setAbstract(isAbstract);
-			table.setName(name);
-			table.setSchema(schema);
-			table.setCatalog(catalog);
-			table.setSubselect(subselect);
-			tables.put(key, table);
-		}
-		else {
-			if (!isAbstract) table.setAbstract(false);
-		}
-
-		return table;
-	}
-
-	public Table addDenormalizedTable(
-			String schema, 
-			String catalog, 
-			String name,
-			boolean isAbstract, 
-			String subselect,
-			Table includedTable)
-	throws MappingException {
-        String key = subselect==null ?
-        		Table.qualify(catalog, schema, name) :
-        		subselect;
-		if ( tables.containsKey(key) ) {
-			throw new DuplicateMappingException("table", name);
-		}
-		
-		Table table = new DenormalizedTable(includedTable);
-		table.setAbstract(isAbstract);
-		table.setName(name);
-		table.setSchema(schema);
-		table.setCatalog(catalog);
-		table.setSubselect(subselect);
-		tables.put(key, table);
-		return table;
-	}
-
-	public Table getTable(String schema, String catalog, String name) {
-        String key = Table.qualify(catalog, schema, name);
-		return (Table) tables.get(key);
-	}
-
-	public String getSchemaName() {
-		return schemaName;
-	}
-
-    public String getCatalogName() {
-        return catalogName;
-    }
-
-	public String getDefaultCascade() {
-		return defaultCascade;
-	}
-
-	/**
-	 * Sets the schemaName.
-	 * @param schemaName The schemaName to set
-	 */
-	public void setSchemaName(String schemaName) {
-		this.schemaName = schemaName;
-	}
-
-    /**
-     * Sets the catalogName.
-     * @param catalogName The catalogName to set
-     */
-    public void setCatalogName(String catalogName) {
-        this.catalogName = catalogName;
-    }
-
-	/**
-	 * Sets the defaultCascade.
-	 * @param defaultCascade The defaultCascade to set
-	 */
-	public void setDefaultCascade(String defaultCascade) {
-		this.defaultCascade = defaultCascade;
-	}
-
-	/**
-	 * sets the default access strategy
-	 * @param defaultAccess the default access strategy.
-	 */
-	public void setDefaultAccess(String defaultAccess) {
-		this.defaultAccess = defaultAccess;
-	}
-
-	public String getDefaultAccess() {
-		return defaultAccess;
-	}
-
-	public void addQuery(String name, NamedQueryDefinition query) throws MappingException {
-		checkQueryExist(name);
-		queries.put( name.intern(), query );
-	}
-
-	public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException {
-		checkQueryExist(name);
-		sqlqueries.put( name.intern(), query );
-	}
-
-	private void checkQueryExist(String name) throws MappingException {
-		if ( sqlqueries.containsKey(name) || queries.containsKey(name) ) {
-			throw new DuplicateMappingException("query", name);
-		}
-	}
-
-	public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) {
-		final String name = sqlResultSetMapping.getName();
-		if ( resultSetMappings.containsKey(name) ) {
-			throw new DuplicateMappingException("resultSet",  name);
-		}
-		resultSetMappings.put(name, sqlResultSetMapping);
-	}
-
-	public ResultSetMappingDefinition getResultSetMapping(String name) {
-		return (ResultSetMappingDefinition) resultSetMappings.get(name);
-	}
-
-
-	public NamedQueryDefinition getQuery(String name) {
-		return (NamedQueryDefinition) queries.get(name);
-	}
-
-	public void addSecondPass(SecondPass sp) {
-		addSecondPass(sp, false);
-	}
-    
-    public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue) {
-		if (onTopOfTheQueue) {
-			secondPasses.add(0, sp);
-		}
-		else {
-			secondPasses.add(sp);
-		}
-	}
-
-	/**
-	 * Returns the autoImport.
-	 * @return boolean
-	 */
-	public boolean isAutoImport() {
-		return autoImport;
-	}
-
-	/**
-	 * Sets the autoImport.
-	 * @param autoImport The autoImport to set
-	 */
-	public void setAutoImport(boolean autoImport) {
-		this.autoImport = autoImport;
-	}
-
-	void addUniquePropertyReference(String referencedClass, String propertyName) {
-		PropertyReference upr = new PropertyReference();
-		upr.referencedClass = referencedClass;
-		upr.propertyName = propertyName;
-		upr.unique = true;
-		propertyReferences.add(upr);
-	}
-
-	void addPropertyReference(String referencedClass, String propertyName) {
-		PropertyReference upr = new PropertyReference();
-		upr.referencedClass = referencedClass;
-		upr.propertyName = propertyName;
-		propertyReferences.add(upr);
-	}
-
-	private String buildTableNameKey(String schema, String catalog, String finalName) {
-		StringBuffer keyBuilder = new StringBuffer();
-		if (schema != null) keyBuilder.append( schema );
-		keyBuilder.append( ".");
-		if (catalog != null) keyBuilder.append( catalog );
-		keyBuilder.append( ".");
-		keyBuilder.append( finalName );
-		return keyBuilder.toString();
-	}
-
-	static final class PropertyReference implements Serializable {
-		String referencedClass;
-		String propertyName;
-		boolean unique;
-	}
-
-	/**
-	 * @return Returns the defaultPackage.
-	 */
-	public String getDefaultPackage() {
-		return defaultPackage;
-	}
-
-	/**
-	 * @param defaultPackage The defaultPackage to set.
-	 */
-	public void setDefaultPackage(String defaultPackage) {
-		this.defaultPackage = defaultPackage;
-	}
-
-	public NamingStrategy getNamingStrategy() {
-		return namingStrategy;
-	}
-
-	public void addTypeDef(String typeName, String typeClass, Properties paramMap) {
-		TypeDef def = new TypeDef(typeClass, paramMap);
-		typeDefs.put(typeName, def);
-		log.debug("Added " + typeName + " with class " + typeClass);
-	}
-
-	public TypeDef getTypeDef(String typeName) {
-		return (TypeDef) typeDefs.get(typeName);
-	}
-
-    public Iterator iterateCollections() {
-        return collections.values().iterator();
-    }
-    
-    public Iterator iterateTables() {
-    	return tables.values().iterator();
-    }
-
-	public Map getFilterDefinitions() {
-		return filterDefinitions;
-	}
-
-	public void addFilterDefinition(FilterDefinition definition) {
-		filterDefinitions.put( definition.getFilterName(), definition );
-	}
-	
-	public FilterDefinition getFilterDefinition(String name) {
-		return (FilterDefinition) filterDefinitions.get(name);
-	}
-	
-	public boolean isDefaultLazy() {
-		return defaultLazy;
-	}
-	public void setDefaultLazy(boolean defaultLazy) {
-		this.defaultLazy = defaultLazy;
-	}
-
-    public void addToExtendsQueue(ExtendsQueueEntry entry) {
-	    extendsQueue.put( entry, null );
-    }
-
-	public PersistentClass locatePersistentClassByEntityName(String entityName) {
-		PersistentClass persistentClass = ( PersistentClass ) classes.get( entityName );
-		if ( persistentClass == null ) {
-			String actualEntityName = ( String ) imports.get( entityName );
-			if ( StringHelper.isNotEmpty( actualEntityName ) ) {
-				persistentClass = ( PersistentClass ) classes.get( actualEntityName );
-			}
-		}
-		return persistentClass;
-	}
-
-	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
-		auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
-	}
-
-	public void addTableBinding(
-			String schema, String catalog, String logicalName, String physicalName, Table denormalizedSuperTable
-	) {
-		String key = buildTableNameKey( schema, catalog, physicalName );
-		TableDescription tableDescription = new TableDescription(
-				logicalName, denormalizedSuperTable
-		);
-		TableDescription oldDescriptor = (TableDescription) tableNameBinding.put( key, tableDescription );
-		if ( oldDescriptor != null && ! oldDescriptor.logicalName.equals( logicalName ) ) {
-			//TODO possibly relax that
-			throw new MappingException("Same physical table name reference several logical table names: "
-					+ physicalName + " => " + "'" + oldDescriptor.logicalName + "' and '" + logicalName + "'");
-		}
-	}
-
-	public void addColumnBinding(String logicalName, Column finalColumn, Table table) {
-		ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(table);
-		if (binding == null) {
-			binding = new ColumnNames();
-			columnNameBindingPerTable.put(table, binding);
-		}
-		String oldFinalName = (String) binding.logicalToPhysical.put(
-				logicalName.toLowerCase(),
-				finalColumn.getQuotedName()
-		);
-		if ( oldFinalName != null &&
-				! ( finalColumn.isQuoted() ?
-						oldFinalName.equals( finalColumn.getQuotedName() ) :
-						oldFinalName.equalsIgnoreCase( finalColumn.getQuotedName() ) ) ) {
-			//TODO possibly relax that
-			throw new MappingException("Same logical column name referenced by different physical ones: "
-					+ table.getName() + "." + logicalName + " => '" + oldFinalName + "' and '" + finalColumn.getQuotedName() + "'" );
-		}
-		String oldLogicalName = (String) binding.physicalToLogical.put(
-				finalColumn.getQuotedName(),
-				logicalName
-		);
-		if ( oldLogicalName != null && ! oldLogicalName.equals( logicalName ) ) {
-			//TODO possibly relax that
-			throw new MappingException("Same physical column represented by different logical column names: "
-					+ table.getName() + "." + finalColumn.getQuotedName() + " => '" + oldLogicalName + "' and '" + logicalName + "'");
-		}
-	}
-
-	private String getLogicalTableName(String schema, String catalog, String physicalName) {
-		String key = buildTableNameKey( schema, catalog, physicalName );
-		TableDescription descriptor = (TableDescription) tableNameBinding.get( key );
-		if (descriptor == null) {
-			throw new MappingException( "Unable to find physical table: " + physicalName);
-		}
-		return descriptor.logicalName;
-	}
-
-	public String getPhysicalColumnName(String logicalName, Table table) {
-		logicalName = logicalName.toLowerCase();
-		String finalName = null;
-		Table currentTable = table;
-		do {
-			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
-			if (binding != null) {
-				finalName = (String) binding.logicalToPhysical.get( logicalName );
-			}
-			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
-			TableDescription description = (TableDescription) tableNameBinding.get(key);
-			if (description != null) currentTable = description.denormalizedSupertable;
-		}
-		while (finalName == null && currentTable != null);
-		if (finalName == null) {
-			throw new MappingException( "Unable to find column with logical name "
-					+ logicalName + " in table " + table.getName() );
-		}
-		return finalName;
-	}
-
-	public String getLogicalColumnName(String physicalName, Table table) {
-		String logical = null;
-		Table currentTable = table;
-		TableDescription description = null;
-		do {
-			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
-			if (binding != null) {
-				logical = (String) binding.physicalToLogical.get( physicalName );
-			}
-			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
-			description = (TableDescription) tableNameBinding.get(key);
-			if (description != null) currentTable = description.denormalizedSupertable;
-		}
-		while (logical == null && currentTable != null && description != null);
-		if (logical == null) {
-			throw new MappingException( "Unable to find logical column name from physical name "
-					+ physicalName + " in table " + table.getName() );
-		}
-		return logical;
-	}
-
-	public String getLogicalTableName(Table table) {
-		return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() );
-	}
-
-	static public class ColumnNames implements Serializable {
-		//<String, String>
-		public Map logicalToPhysical = new HashMap();
-		//<String, String>
-		public Map physicalToLogical = new HashMap();
-		public ColumnNames() {
-		}
-	}
-
-	static public class TableDescription implements Serializable {
-		public TableDescription(String logicalName, Table denormalizedSupertable) {
-			this.logicalName = logicalName;
-			this.denormalizedSupertable = denormalizedSupertable;
-		}
-
-		public String logicalName;
-		public Table denormalizedSupertable;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/Mappings.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Mappings.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,565 @@
+/*
+ * 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.cfg;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.HashMap;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.DuplicateMappingException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.DenormalizedTable;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.TypeDef;
+import org.hibernate.mapping.AuxiliaryDatabaseObject;
+import org.hibernate.mapping.Column;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A collection of mappings from classes and collections to
+ * relational database tables. (Represents a single
+ * <tt>&lt;hibernate-mapping&gt;</tt> element.)
+ * @author Gavin King
+ */
+public class Mappings implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(Mappings.class);
+
+	protected final Map classes;
+	protected final Map collections;
+	protected final Map tables;
+	protected final Map queries;
+	protected final Map sqlqueries;
+	protected final Map resultSetMappings;
+	protected final Map typeDefs;
+	protected final List secondPasses;
+	protected final Map imports;
+	protected String schemaName;
+    protected String catalogName;
+	protected String defaultCascade;
+	protected String defaultPackage;
+	protected String defaultAccess;
+	protected boolean autoImport;
+	protected boolean defaultLazy;
+	protected final List propertyReferences;
+	protected final NamingStrategy namingStrategy;
+	protected final Map filterDefinitions;
+	protected final List auxiliaryDatabaseObjects;
+
+	protected final Map extendsQueue;
+//	private final List extendsQueue;
+
+	/**
+	 * binding table between the logical column name and the name out of the naming strategy
+	 * for each table.
+	 * According that when the column name is not set, the property name is considered as such
+	 * This means that while theorically possible through the naming strategy contract, it is
+	 * forbidden to have 2 real columns having the same logical name
+	 * <Table, ColumnNames >
+	 */
+	protected final Map columnNameBindingPerTable;
+	/**
+	 * binding between logical table name and physical one (ie after the naming strategy has been applied)
+	 * <String, TableDescription>
+	 */
+	protected final Map tableNameBinding;
+
+
+	Mappings(
+			final Map classes,
+			final Map collections,
+			final Map tables,
+			final Map queries,
+			final Map sqlqueries,
+			final Map sqlResultSetMappings,
+			final Map imports,
+			final List secondPasses,
+			final List propertyReferences,
+			final NamingStrategy namingStrategy,
+			final Map typeDefs,
+			final Map filterDefinitions,
+//			final List extendsQueue,
+			final Map extendsQueue,
+			final List auxiliaryDatabaseObjects,
+			final Map tableNamebinding,
+			final Map columnNameBindingPerTable
+			) {
+		this.classes = classes;
+		this.collections = collections;
+		this.queries = queries;
+		this.sqlqueries = sqlqueries;
+		this.resultSetMappings = sqlResultSetMappings;
+		this.tables = tables;
+		this.imports = imports;
+		this.secondPasses = secondPasses;
+		this.propertyReferences = propertyReferences;
+		this.namingStrategy = namingStrategy;
+		this.typeDefs = typeDefs;
+		this.filterDefinitions = filterDefinitions;
+		this.extendsQueue = extendsQueue;
+		this.auxiliaryDatabaseObjects = auxiliaryDatabaseObjects;
+		this.tableNameBinding = tableNamebinding;
+		this.columnNameBindingPerTable = columnNameBindingPerTable;
+	}
+
+	public void addClass(PersistentClass persistentClass) throws MappingException {
+		Object old = classes.put( persistentClass.getEntityName(), persistentClass );
+		if ( old!=null ) {
+			throw new DuplicateMappingException( "class/entity", persistentClass.getEntityName() );
+		}
+	}
+	public void addCollection(Collection collection) throws MappingException {
+		Object old = collections.put( collection.getRole(), collection );
+		if ( old!=null ) {
+			throw new DuplicateMappingException( "collection role", collection.getRole() );
+		}
+	}
+	public PersistentClass getClass(String className) {
+		return (PersistentClass) classes.get(className);
+	}
+	public Collection getCollection(String role) {
+		return (Collection) collections.get(role);
+	}
+
+	public void addImport(String className, String rename) throws MappingException {
+		String existing = (String) imports.put(rename, className);
+		if ( existing!=null ) {
+			if ( existing.equals(className) ) {
+				log.info( "duplicate import: " + className + "->" + rename );
+			}
+			else {
+				throw new DuplicateMappingException(
+						"duplicate import: " + rename + 
+						" refers to both " + className + 
+						" and " + existing + 
+						" (try using auto-import=\"false\")",
+						"import",
+						rename
+					);
+			}
+		}
+	}
+
+	public Table addTable(String schema, 
+			String catalog, 
+			String name,
+			String subselect,
+			boolean isAbstract
+	) {
+        String key = subselect==null ?
+			Table.qualify(catalog, schema, name) :
+			subselect;
+		Table table = (Table) tables.get(key);
+
+		if (table == null) {
+			table = new Table();
+			table.setAbstract(isAbstract);
+			table.setName(name);
+			table.setSchema(schema);
+			table.setCatalog(catalog);
+			table.setSubselect(subselect);
+			tables.put(key, table);
+		}
+		else {
+			if (!isAbstract) table.setAbstract(false);
+		}
+
+		return table;
+	}
+
+	public Table addDenormalizedTable(
+			String schema, 
+			String catalog, 
+			String name,
+			boolean isAbstract, 
+			String subselect,
+			Table includedTable)
+	throws MappingException {
+        String key = subselect==null ?
+        		Table.qualify(catalog, schema, name) :
+        		subselect;
+		if ( tables.containsKey(key) ) {
+			throw new DuplicateMappingException("table", name);
+		}
+		
+		Table table = new DenormalizedTable(includedTable);
+		table.setAbstract(isAbstract);
+		table.setName(name);
+		table.setSchema(schema);
+		table.setCatalog(catalog);
+		table.setSubselect(subselect);
+		tables.put(key, table);
+		return table;
+	}
+
+	public Table getTable(String schema, String catalog, String name) {
+        String key = Table.qualify(catalog, schema, name);
+		return (Table) tables.get(key);
+	}
+
+	public String getSchemaName() {
+		return schemaName;
+	}
+
+    public String getCatalogName() {
+        return catalogName;
+    }
+
+	public String getDefaultCascade() {
+		return defaultCascade;
+	}
+
+	/**
+	 * Sets the schemaName.
+	 * @param schemaName The schemaName to set
+	 */
+	public void setSchemaName(String schemaName) {
+		this.schemaName = schemaName;
+	}
+
+    /**
+     * Sets the catalogName.
+     * @param catalogName The catalogName to set
+     */
+    public void setCatalogName(String catalogName) {
+        this.catalogName = catalogName;
+    }
+
+	/**
+	 * Sets the defaultCascade.
+	 * @param defaultCascade The defaultCascade to set
+	 */
+	public void setDefaultCascade(String defaultCascade) {
+		this.defaultCascade = defaultCascade;
+	}
+
+	/**
+	 * sets the default access strategy
+	 * @param defaultAccess the default access strategy.
+	 */
+	public void setDefaultAccess(String defaultAccess) {
+		this.defaultAccess = defaultAccess;
+	}
+
+	public String getDefaultAccess() {
+		return defaultAccess;
+	}
+
+	public void addQuery(String name, NamedQueryDefinition query) throws MappingException {
+		checkQueryExist(name);
+		queries.put( name.intern(), query );
+	}
+
+	public void addSQLQuery(String name, NamedSQLQueryDefinition query) throws MappingException {
+		checkQueryExist(name);
+		sqlqueries.put( name.intern(), query );
+	}
+
+	private void checkQueryExist(String name) throws MappingException {
+		if ( sqlqueries.containsKey(name) || queries.containsKey(name) ) {
+			throw new DuplicateMappingException("query", name);
+		}
+	}
+
+	public void addResultSetMapping(ResultSetMappingDefinition sqlResultSetMapping) {
+		final String name = sqlResultSetMapping.getName();
+		if ( resultSetMappings.containsKey(name) ) {
+			throw new DuplicateMappingException("resultSet",  name);
+		}
+		resultSetMappings.put(name, sqlResultSetMapping);
+	}
+
+	public ResultSetMappingDefinition getResultSetMapping(String name) {
+		return (ResultSetMappingDefinition) resultSetMappings.get(name);
+	}
+
+
+	public NamedQueryDefinition getQuery(String name) {
+		return (NamedQueryDefinition) queries.get(name);
+	}
+
+	public void addSecondPass(SecondPass sp) {
+		addSecondPass(sp, false);
+	}
+    
+    public void addSecondPass(SecondPass sp, boolean onTopOfTheQueue) {
+		if (onTopOfTheQueue) {
+			secondPasses.add(0, sp);
+		}
+		else {
+			secondPasses.add(sp);
+		}
+	}
+
+	/**
+	 * Returns the autoImport.
+	 * @return boolean
+	 */
+	public boolean isAutoImport() {
+		return autoImport;
+	}
+
+	/**
+	 * Sets the autoImport.
+	 * @param autoImport The autoImport to set
+	 */
+	public void setAutoImport(boolean autoImport) {
+		this.autoImport = autoImport;
+	}
+
+	void addUniquePropertyReference(String referencedClass, String propertyName) {
+		PropertyReference upr = new PropertyReference();
+		upr.referencedClass = referencedClass;
+		upr.propertyName = propertyName;
+		upr.unique = true;
+		propertyReferences.add(upr);
+	}
+
+	void addPropertyReference(String referencedClass, String propertyName) {
+		PropertyReference upr = new PropertyReference();
+		upr.referencedClass = referencedClass;
+		upr.propertyName = propertyName;
+		propertyReferences.add(upr);
+	}
+
+	private String buildTableNameKey(String schema, String catalog, String finalName) {
+		StringBuffer keyBuilder = new StringBuffer();
+		if (schema != null) keyBuilder.append( schema );
+		keyBuilder.append( ".");
+		if (catalog != null) keyBuilder.append( catalog );
+		keyBuilder.append( ".");
+		keyBuilder.append( finalName );
+		return keyBuilder.toString();
+	}
+
+	static final class PropertyReference implements Serializable {
+		String referencedClass;
+		String propertyName;
+		boolean unique;
+	}
+
+	/**
+	 * @return Returns the defaultPackage.
+	 */
+	public String getDefaultPackage() {
+		return defaultPackage;
+	}
+
+	/**
+	 * @param defaultPackage The defaultPackage to set.
+	 */
+	public void setDefaultPackage(String defaultPackage) {
+		this.defaultPackage = defaultPackage;
+	}
+
+	public NamingStrategy getNamingStrategy() {
+		return namingStrategy;
+	}
+
+	public void addTypeDef(String typeName, String typeClass, Properties paramMap) {
+		TypeDef def = new TypeDef(typeClass, paramMap);
+		typeDefs.put(typeName, def);
+		log.debug("Added " + typeName + " with class " + typeClass);
+	}
+
+	public TypeDef getTypeDef(String typeName) {
+		return (TypeDef) typeDefs.get(typeName);
+	}
+
+    public Iterator iterateCollections() {
+        return collections.values().iterator();
+    }
+    
+    public Iterator iterateTables() {
+    	return tables.values().iterator();
+    }
+
+	public Map getFilterDefinitions() {
+		return filterDefinitions;
+	}
+
+	public void addFilterDefinition(FilterDefinition definition) {
+		filterDefinitions.put( definition.getFilterName(), definition );
+	}
+	
+	public FilterDefinition getFilterDefinition(String name) {
+		return (FilterDefinition) filterDefinitions.get(name);
+	}
+	
+	public boolean isDefaultLazy() {
+		return defaultLazy;
+	}
+	public void setDefaultLazy(boolean defaultLazy) {
+		this.defaultLazy = defaultLazy;
+	}
+
+    public void addToExtendsQueue(ExtendsQueueEntry entry) {
+	    extendsQueue.put( entry, null );
+    }
+
+	public PersistentClass locatePersistentClassByEntityName(String entityName) {
+		PersistentClass persistentClass = ( PersistentClass ) classes.get( entityName );
+		if ( persistentClass == null ) {
+			String actualEntityName = ( String ) imports.get( entityName );
+			if ( StringHelper.isNotEmpty( actualEntityName ) ) {
+				persistentClass = ( PersistentClass ) classes.get( actualEntityName );
+			}
+		}
+		return persistentClass;
+	}
+
+	public void addAuxiliaryDatabaseObject(AuxiliaryDatabaseObject auxiliaryDatabaseObject) {
+		auxiliaryDatabaseObjects.add( auxiliaryDatabaseObject );
+	}
+
+	public void addTableBinding(
+			String schema, String catalog, String logicalName, String physicalName, Table denormalizedSuperTable
+	) {
+		String key = buildTableNameKey( schema, catalog, physicalName );
+		TableDescription tableDescription = new TableDescription(
+				logicalName, denormalizedSuperTable
+		);
+		TableDescription oldDescriptor = (TableDescription) tableNameBinding.put( key, tableDescription );
+		if ( oldDescriptor != null && ! oldDescriptor.logicalName.equals( logicalName ) ) {
+			//TODO possibly relax that
+			throw new MappingException("Same physical table name reference several logical table names: "
+					+ physicalName + " => " + "'" + oldDescriptor.logicalName + "' and '" + logicalName + "'");
+		}
+	}
+
+	public void addColumnBinding(String logicalName, Column finalColumn, Table table) {
+		ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(table);
+		if (binding == null) {
+			binding = new ColumnNames();
+			columnNameBindingPerTable.put(table, binding);
+		}
+		String oldFinalName = (String) binding.logicalToPhysical.put(
+				logicalName.toLowerCase(),
+				finalColumn.getQuotedName()
+		);
+		if ( oldFinalName != null &&
+				! ( finalColumn.isQuoted() ?
+						oldFinalName.equals( finalColumn.getQuotedName() ) :
+						oldFinalName.equalsIgnoreCase( finalColumn.getQuotedName() ) ) ) {
+			//TODO possibly relax that
+			throw new MappingException("Same logical column name referenced by different physical ones: "
+					+ table.getName() + "." + logicalName + " => '" + oldFinalName + "' and '" + finalColumn.getQuotedName() + "'" );
+		}
+		String oldLogicalName = (String) binding.physicalToLogical.put(
+				finalColumn.getQuotedName(),
+				logicalName
+		);
+		if ( oldLogicalName != null && ! oldLogicalName.equals( logicalName ) ) {
+			//TODO possibly relax that
+			throw new MappingException("Same physical column represented by different logical column names: "
+					+ table.getName() + "." + finalColumn.getQuotedName() + " => '" + oldLogicalName + "' and '" + logicalName + "'");
+		}
+	}
+
+	private String getLogicalTableName(String schema, String catalog, String physicalName) {
+		String key = buildTableNameKey( schema, catalog, physicalName );
+		TableDescription descriptor = (TableDescription) tableNameBinding.get( key );
+		if (descriptor == null) {
+			throw new MappingException( "Unable to find physical table: " + physicalName);
+		}
+		return descriptor.logicalName;
+	}
+
+	public String getPhysicalColumnName(String logicalName, Table table) {
+		logicalName = logicalName.toLowerCase();
+		String finalName = null;
+		Table currentTable = table;
+		do {
+			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
+			if (binding != null) {
+				finalName = (String) binding.logicalToPhysical.get( logicalName );
+			}
+			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
+			TableDescription description = (TableDescription) tableNameBinding.get(key);
+			if (description != null) currentTable = description.denormalizedSupertable;
+		}
+		while (finalName == null && currentTable != null);
+		if (finalName == null) {
+			throw new MappingException( "Unable to find column with logical name "
+					+ logicalName + " in table " + table.getName() );
+		}
+		return finalName;
+	}
+
+	public String getLogicalColumnName(String physicalName, Table table) {
+		String logical = null;
+		Table currentTable = table;
+		TableDescription description = null;
+		do {
+			ColumnNames binding = (ColumnNames) columnNameBindingPerTable.get(currentTable);
+			if (binding != null) {
+				logical = (String) binding.physicalToLogical.get( physicalName );
+			}
+			String key = buildTableNameKey( currentTable.getSchema(), currentTable.getCatalog(), currentTable.getName() );
+			description = (TableDescription) tableNameBinding.get(key);
+			if (description != null) currentTable = description.denormalizedSupertable;
+		}
+		while (logical == null && currentTable != null && description != null);
+		if (logical == null) {
+			throw new MappingException( "Unable to find logical column name from physical name "
+					+ physicalName + " in table " + table.getName() );
+		}
+		return logical;
+	}
+
+	public String getLogicalTableName(Table table) {
+		return getLogicalTableName( table.getQuotedSchema(), table.getCatalog(), table.getQuotedName() );
+	}
+
+	static public class ColumnNames implements Serializable {
+		//<String, String>
+		public Map logicalToPhysical = new HashMap();
+		//<String, String>
+		public Map physicalToLogical = new HashMap();
+		public ColumnNames() {
+		}
+	}
+
+	static public class TableDescription implements Serializable {
+		public TableDescription(String logicalName, Table denormalizedSupertable) {
+			this.logicalName = logicalName;
+			this.denormalizedSupertable = denormalizedSupertable;
+		}
+
+		public String logicalName;
+		public Table denormalizedSupertable;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,99 +0,0 @@
-//$Id: NamedSQLQuerySecondPass.java 10196 2006-08-03 07:53:27Z max.andersen at jboss.com $
-package org.hibernate.cfg;
-
-import java.util.Map;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.util.StringHelper;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.dom4j.Attribute;
-import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author Emmanuel Bernard
- */
-public class NamedSQLQuerySecondPass extends ResultSetMappingBinder implements QuerySecondPass {
-	private static Logger log = LoggerFactory.getLogger( NamedSQLQuerySecondPass.class);
-	private Element queryElem;
-	private String path;
-	private Mappings mappings;
-
-	public NamedSQLQuerySecondPass(Element queryElem, String path, Mappings mappings) {
-		this.queryElem = queryElem;
-		this.path = path;
-		this.mappings = mappings;
-	}
-
-	public void doSecondPass(Map persistentClasses) throws MappingException {
-		String queryName = queryElem.attribute( "name" ).getValue();
-		if (path!=null) queryName = path + '.' + queryName;
-
-		boolean cacheable = "true".equals( queryElem.attributeValue( "cacheable" ) );
-		String region = queryElem.attributeValue( "cache-region" );
-		Attribute tAtt = queryElem.attribute( "timeout" );
-		Integer timeout = tAtt == null ? null : new Integer( tAtt.getValue() );
-		Attribute fsAtt = queryElem.attribute( "fetch-size" );
-		Integer fetchSize = fsAtt == null ? null : new Integer( fsAtt.getValue() );
-		Attribute roAttr = queryElem.attribute( "read-only" );
-		boolean readOnly = roAttr != null && "true".equals( roAttr.getValue() );
-		Attribute cacheModeAtt = queryElem.attribute( "cache-mode" );
-		String cacheMode = cacheModeAtt == null ? null : cacheModeAtt.getValue();
-		Attribute cmAtt = queryElem.attribute( "comment" );
-		String comment = cmAtt == null ? null : cmAtt.getValue();
-
-		java.util.List synchronizedTables = new ArrayList();
-		Iterator tables = queryElem.elementIterator( "synchronize" );
-		while ( tables.hasNext() ) {
-			synchronizedTables.add( ( (Element) tables.next() ).attributeValue( "table" ) );
-		}
-		boolean callable = "true".equals( queryElem.attributeValue( "callable" ) );
-
-		NamedSQLQueryDefinition namedQuery;
-		Attribute ref = queryElem.attribute( "resultset-ref" );
-		String resultSetRef = ref == null ? null : ref.getValue();
-		if ( StringHelper.isNotEmpty( resultSetRef ) ) {
-			namedQuery = new NamedSQLQueryDefinition(
-					queryElem.getText(),
-					resultSetRef,
-					synchronizedTables,
-					cacheable,
-					region,
-					timeout,
-					fetchSize,
-					HbmBinder.getFlushMode( queryElem.attributeValue( "flush-mode" ) ),
-					HbmBinder.getCacheMode( cacheMode ),
-					readOnly,
-					comment,
-					HbmBinder.getParameterTypes( queryElem ),
-					callable
-			);
-			//TODO check there is no actual definition elemnents when a ref is defined
-		}
-		else {
-			ResultSetMappingDefinition definition = buildResultSetMappingDefinition( queryElem, path, mappings );
-			namedQuery = new NamedSQLQueryDefinition(
-					queryElem.getText(),
-					definition.getQueryReturns(),
-					synchronizedTables,
-					cacheable,
-					region,
-					timeout,
-					fetchSize,
-					HbmBinder.getFlushMode( queryElem.attributeValue( "flush-mode" ) ),
-					HbmBinder.getCacheMode( cacheMode ),
-					readOnly,
-					comment,
-					HbmBinder.getParameterTypes( queryElem ),
-					callable
-			);
-		}
-
-		log.debug( "Named SQL query: " + queryName + " -> " + namedQuery.getQueryString() );
-		mappings.addSQLQuery( queryName, namedQuery );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamedSQLQuerySecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,122 @@
+/*
+ * 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.cfg;
+
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.util.StringHelper;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class NamedSQLQuerySecondPass extends ResultSetMappingBinder implements QuerySecondPass {
+	private static Logger log = LoggerFactory.getLogger( NamedSQLQuerySecondPass.class);
+	private Element queryElem;
+	private String path;
+	private Mappings mappings;
+
+	public NamedSQLQuerySecondPass(Element queryElem, String path, Mappings mappings) {
+		this.queryElem = queryElem;
+		this.path = path;
+		this.mappings = mappings;
+	}
+
+	public void doSecondPass(Map persistentClasses) throws MappingException {
+		String queryName = queryElem.attribute( "name" ).getValue();
+		if (path!=null) queryName = path + '.' + queryName;
+
+		boolean cacheable = "true".equals( queryElem.attributeValue( "cacheable" ) );
+		String region = queryElem.attributeValue( "cache-region" );
+		Attribute tAtt = queryElem.attribute( "timeout" );
+		Integer timeout = tAtt == null ? null : new Integer( tAtt.getValue() );
+		Attribute fsAtt = queryElem.attribute( "fetch-size" );
+		Integer fetchSize = fsAtt == null ? null : new Integer( fsAtt.getValue() );
+		Attribute roAttr = queryElem.attribute( "read-only" );
+		boolean readOnly = roAttr != null && "true".equals( roAttr.getValue() );
+		Attribute cacheModeAtt = queryElem.attribute( "cache-mode" );
+		String cacheMode = cacheModeAtt == null ? null : cacheModeAtt.getValue();
+		Attribute cmAtt = queryElem.attribute( "comment" );
+		String comment = cmAtt == null ? null : cmAtt.getValue();
+
+		java.util.List synchronizedTables = new ArrayList();
+		Iterator tables = queryElem.elementIterator( "synchronize" );
+		while ( tables.hasNext() ) {
+			synchronizedTables.add( ( (Element) tables.next() ).attributeValue( "table" ) );
+		}
+		boolean callable = "true".equals( queryElem.attributeValue( "callable" ) );
+
+		NamedSQLQueryDefinition namedQuery;
+		Attribute ref = queryElem.attribute( "resultset-ref" );
+		String resultSetRef = ref == null ? null : ref.getValue();
+		if ( StringHelper.isNotEmpty( resultSetRef ) ) {
+			namedQuery = new NamedSQLQueryDefinition(
+					queryElem.getText(),
+					resultSetRef,
+					synchronizedTables,
+					cacheable,
+					region,
+					timeout,
+					fetchSize,
+					HbmBinder.getFlushMode( queryElem.attributeValue( "flush-mode" ) ),
+					HbmBinder.getCacheMode( cacheMode ),
+					readOnly,
+					comment,
+					HbmBinder.getParameterTypes( queryElem ),
+					callable
+			);
+			//TODO check there is no actual definition elemnents when a ref is defined
+		}
+		else {
+			ResultSetMappingDefinition definition = buildResultSetMappingDefinition( queryElem, path, mappings );
+			namedQuery = new NamedSQLQueryDefinition(
+					queryElem.getText(),
+					definition.getQueryReturns(),
+					synchronizedTables,
+					cacheable,
+					region,
+					timeout,
+					fetchSize,
+					HbmBinder.getFlushMode( queryElem.attributeValue( "flush-mode" ) ),
+					HbmBinder.getCacheMode( cacheMode ),
+					readOnly,
+					comment,
+					HbmBinder.getParameterTypes( queryElem ),
+					callable
+			);
+		}
+
+		log.debug( "Named SQL query: " + queryName + " -> " + namedQuery.getQueryString() );
+		mappings.addSQLQuery( queryName, namedQuery );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/NamingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,101 +0,0 @@
-//$Id: NamingStrategy.java 9874 2006-05-04 15:10:22Z epbernard $
-package org.hibernate.cfg;
-
-/**
- * A set of rules for determining the physical column
- * and table names given the information in the mapping
- * document. May be used to implement project-scoped
- * naming standards for database objects.
- *
- * #propertyToTableName(String, String) should be replaced by
- * {@link #collectionTableName(String,String,String,String,String)}
- *
- * @see DefaultNamingStrategy
- * @see ImprovedNamingStrategy
- * @author Gavin King
- * @author Emmanuel Bernard
- */
-public interface NamingStrategy {
-	/**
-	 * Return a table name for an entity class
-	 * @param className the fully-qualified class name
-	 * @return a table name
-	 */
-	public String classToTableName(String className);
-	/**
-	 * Return a column name for a property path expression
-	 * @param propertyName a property path
-	 * @return a column name
-	 */
-	public String propertyToColumnName(String propertyName);
-	/**
-	 * Alter the table name given in the mapping document
-	 * @param tableName a table name
-	 * @return a table name
-	 */
-	public String tableName(String tableName);
-	/**
-	 * Alter the column name given in the mapping document
-	 * @param columnName a column name
-	 * @return a column name
-	 */
-	public String columnName(String columnName);
-	/**
-	 * Return a collection table name ie an association having a join table
-	 *
-	 * @param ownerEntity
-	 * @param ownerEntityTable owner side table name
-	 * @param associatedEntity
-	 * @param associatedEntityTable reverse side table name if any
-	 * @param propertyName collection role
-	 */
-	public String collectionTableName(
-			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
-			String propertyName
-	);
-	/**
-	 * Return the join key column name ie a FK column used in a JOINED strategy or for a secondary table
-	 *
-	 * @param joinedColumn joined column name (logical one) used to join with
-	 * @param joinedTable joined table name (ie the referenced table) used to join with
-	 */
-	public String joinKeyColumnName(String joinedColumn, String joinedTable);
-	/**
-	 * Return the foreign key column name for the given parameters
-	 * @param propertyName the property name involved
-	 * @param propertyEntityName
-	 * @param propertyTableName the property table name involved (logical one)
-	 * @param referencedColumnName the referenced column name involved (logical one)
-	 */
-	public String foreignKeyColumnName(
-			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
-	);
-	/**
-	 * Return the logical column name used to refer to a column in the metadata
-	 * (like index, unique constraints etc)
-	 * A full bijection is required between logicalNames and physical ones
-	 * logicalName have to be case insersitively unique for a given table
-	 *
-	 * @param columnName given column name if any
-	 * @param propertyName property name of this column
-	 */
-	public String logicalColumnName(String columnName, String propertyName);
-	/**
-	 * Returns the logical collection table name used to refer to a table in the mapping metadata
-	 *
-	 * @param tableName the metadata explicit name
-	 * @param ownerEntityTable owner table entity table name (logical one)
-	 * @param associatedEntityTable reverse side table name if any (logical one)
-	 * @param propertyName collection role
-	 */
-	public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName);
-
-	/**
-	 * Returns the logical foreign key column name used to refer to this column in the mapping metadata
-	 *
-	 * @param columnName given column name in the metadata if any
-	 * @param propertyName property name
-	 * @param referencedColumn referenced column name (logical one) in the join
-	 */
-	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/NamingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/NamingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cfg;
+
+/**
+ * A set of rules for determining the physical column
+ * and table names given the information in the mapping
+ * document. May be used to implement project-scoped
+ * naming standards for database objects.
+ *
+ * #propertyToTableName(String, String) should be replaced by
+ * {@link #collectionTableName(String,String,String,String,String)}
+ *
+ * @see DefaultNamingStrategy
+ * @see ImprovedNamingStrategy
+ * @author Gavin King
+ * @author Emmanuel Bernard
+ */
+public interface NamingStrategy {
+	/**
+	 * Return a table name for an entity class
+	 * @param className the fully-qualified class name
+	 * @return a table name
+	 */
+	public String classToTableName(String className);
+	/**
+	 * Return a column name for a property path expression
+	 * @param propertyName a property path
+	 * @return a column name
+	 */
+	public String propertyToColumnName(String propertyName);
+	/**
+	 * Alter the table name given in the mapping document
+	 * @param tableName a table name
+	 * @return a table name
+	 */
+	public String tableName(String tableName);
+	/**
+	 * Alter the column name given in the mapping document
+	 * @param columnName a column name
+	 * @return a column name
+	 */
+	public String columnName(String columnName);
+	/**
+	 * Return a collection table name ie an association having a join table
+	 *
+	 * @param ownerEntity
+	 * @param ownerEntityTable owner side table name
+	 * @param associatedEntity
+	 * @param associatedEntityTable reverse side table name if any
+	 * @param propertyName collection role
+	 */
+	public String collectionTableName(
+			String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable,
+			String propertyName
+	);
+	/**
+	 * Return the join key column name ie a FK column used in a JOINED strategy or for a secondary table
+	 *
+	 * @param joinedColumn joined column name (logical one) used to join with
+	 * @param joinedTable joined table name (ie the referenced table) used to join with
+	 */
+	public String joinKeyColumnName(String joinedColumn, String joinedTable);
+	/**
+	 * Return the foreign key column name for the given parameters
+	 * @param propertyName the property name involved
+	 * @param propertyEntityName
+	 * @param propertyTableName the property table name involved (logical one)
+	 * @param referencedColumnName the referenced column name involved (logical one)
+	 */
+	public String foreignKeyColumnName(
+			String propertyName, String propertyEntityName, String propertyTableName, String referencedColumnName
+	);
+	/**
+	 * Return the logical column name used to refer to a column in the metadata
+	 * (like index, unique constraints etc)
+	 * A full bijection is required between logicalNames and physical ones
+	 * logicalName have to be case insersitively unique for a given table
+	 *
+	 * @param columnName given column name if any
+	 * @param propertyName property name of this column
+	 */
+	public String logicalColumnName(String columnName, String propertyName);
+	/**
+	 * Returns the logical collection table name used to refer to a table in the mapping metadata
+	 *
+	 * @param tableName the metadata explicit name
+	 * @param ownerEntityTable owner table entity table name (logical one)
+	 * @param associatedEntityTable reverse side table name if any (logical one)
+	 * @param propertyName collection role
+	 */
+	public String logicalCollectionTableName(String tableName, String ownerEntityTable, String associatedEntityTable, String propertyName);
+
+	/**
+	 * Returns the logical foreign key column name used to refer to this column in the mapping metadata
+	 *
+	 * @param columnName given column name in the metadata if any
+	 * @param propertyName property name
+	 * @param referencedColumn referenced column name (logical one) in the join
+	 */
+	public String logicalCollectionColumnName(String columnName, String propertyName, String referencedColumn);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-//$Id: QuerySecondPass.java 9019 2006-01-11 18:50:33Z epbernard $
-package org.hibernate.cfg;
-
-/**
- * Bind query
- *
- * @author Emmanuel Bernard
- */
-public interface QuerySecondPass extends SecondPass {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/QuerySecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+/*
+ * 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.cfg;
+
+/**
+ * Bind query
+ *
+ * @author Emmanuel Bernard
+ */
+public interface QuerySecondPass extends SecondPass {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,366 +0,0 @@
-//$Id: ResultSetMappingBinder.java 10180 2006-07-28 20:17:01Z epbernard $
-package org.hibernate.cfg;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Value;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.ToOne;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Emmanuel Bernard
- */
-public abstract class ResultSetMappingBinder {
-	/**
-	 * Build a ResultSetMappingDefinition given a containing element for the "return-XXX" elements
-	 *
-	 * @param resultSetElem The element containing the return definitions.
-	 * @param path No clue...
-	 * @param mappings The current processing state.
-	 * @return The description of the mappings...
-	 */
-	protected static ResultSetMappingDefinition buildResultSetMappingDefinition(Element resultSetElem, String path, Mappings mappings) {
-		String resultSetName = resultSetElem.attribute( "name" ).getValue();
-		if ( path != null ) {
-			resultSetName = path + '.' + resultSetName;
-		}
-		ResultSetMappingDefinition definition = new ResultSetMappingDefinition( resultSetName );
-
-		int cnt = 0;
-		Iterator returns = resultSetElem.elementIterator();
-		while ( returns.hasNext() ) {
-			cnt++;
-			Element returnElem = (Element) returns.next();
-			String name = returnElem.getName();
-			if ( "return-scalar".equals( name ) ) {
-				String column = returnElem.attributeValue( "column" );
-				String typeFromXML = HbmBinder.getTypeFromXML( returnElem );
-				Type type = null;
-				if(typeFromXML!=null) {
-					type = TypeFactory.heuristicType( typeFromXML );
-					if ( type == null ) {
-						throw new MappingException( "could not determine type " + type );
-					}
-				}
-				definition.addQueryReturn( new NativeSQLQueryScalarReturn( column, type ) );
-			}
-			else if ( "return".equals( name ) ) {
-				definition.addQueryReturn( bindReturn( returnElem, mappings, cnt ) );
-			}
-			else if ( "return-join".equals( name ) ) {
-				definition.addQueryReturn( bindReturnJoin( returnElem, mappings ) );
-			}
-			else if ( "load-collection".equals( name ) ) {
-				definition.addQueryReturn( bindLoadCollection( returnElem, mappings ) );
-			}
-		}
-		return definition;
-	}
-
-	private static NativeSQLQueryRootReturn bindReturn(Element returnElem, Mappings mappings, int elementCount) {
-		String alias = returnElem.attributeValue( "alias" );
-		if( StringHelper.isEmpty(alias)) {
-			alias = "alias_" + elementCount; // hack/workaround as sqlquery impl depend on having a key.
-		}
-
-		String entityName = HbmBinder.getEntityName(returnElem, mappings);
-		if(entityName==null) {
-			throw new MappingException( "<return alias='" + alias + "'> must specify either a class or entity-name");
-		}
-		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
-
-		PersistentClass pc = mappings.getClass( entityName );
-		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, pc, mappings );
-
-		return new NativeSQLQueryRootReturn(
-				alias,
-				entityName,
-				propertyResults,
-				lockMode
-			);
-	}
-
-	private static NativeSQLQueryJoinReturn bindReturnJoin(Element returnElem, Mappings mappings) {
-		String alias = returnElem.attributeValue( "alias" );
-		String roleAttribute = returnElem.attributeValue( "property" );
-		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
-		int dot = roleAttribute.lastIndexOf( '.' );
-		if ( dot == -1 ) {
-			throw new MappingException(
-					"Role attribute for sql query return [alias=" + alias +
-					"] not formatted correctly {owningAlias.propertyName}"
-				);
-		}
-		String roleOwnerAlias = roleAttribute.substring( 0, dot );
-		String roleProperty = roleAttribute.substring( dot + 1 );
-
-		//FIXME: get the PersistentClass
-		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
-
-		return new NativeSQLQueryJoinReturn(
-				alias,
-				roleOwnerAlias,
-				roleProperty,
-				propertyResults, // TODO: bindpropertyresults(alias, returnElem)
-				lockMode
-			);
-	}
-
-	private static NativeSQLQueryCollectionReturn bindLoadCollection(Element returnElem, Mappings mappings) {
-		String alias = returnElem.attributeValue( "alias" );
-		String collectionAttribute = returnElem.attributeValue( "role" );
-		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
-		int dot = collectionAttribute.lastIndexOf( '.' );
-		if ( dot == -1 ) {
-			throw new MappingException(
-					"Collection attribute for sql query return [alias=" + alias +
-					"] not formatted correctly {OwnerClassName.propertyName}"
-				);
-		}
-		String ownerClassName = HbmBinder.getClassName( collectionAttribute.substring( 0, dot ), mappings );
-		String ownerPropertyName = collectionAttribute.substring( dot + 1 );
-
-		//FIXME: get the PersistentClass
-		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
-
-		return new NativeSQLQueryCollectionReturn(
-				alias,
-				ownerClassName,
-				ownerPropertyName,
-				propertyResults,
-				lockMode
-			);
-	}
-
-	private static java.util.Map bindPropertyResults(
-			String alias, Element returnElement, PersistentClass pc, Mappings mappings
-	) {
-
-		HashMap propertyresults = new HashMap(); // maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment
-
-		Element discriminatorResult = returnElement.element("return-discriminator");
-		if(discriminatorResult!=null) {
-			ArrayList resultColumns = getResultColumns(discriminatorResult);
-			propertyresults.put("class", ArrayHelper.toStringArray(resultColumns) );
-		}
-		Iterator iterator = returnElement.elementIterator("return-property");
-		List properties = new ArrayList();
-		List propertyNames = new ArrayList();
-		while ( iterator.hasNext() ) {
-			Element propertyresult = (Element) iterator.next();
-			String name = propertyresult.attributeValue("name");
-			if ( pc == null || name.indexOf( '.') == -1) { //if dotted and not load-collection nor return-join
-				//regular property
-				properties.add(propertyresult);
-				propertyNames.add(name);
-			}
-			else {
-				/**
-				 * Reorder properties
-				 * 1. get the parent property
-				 * 2. list all the properties following the expected one in the parent property
-				 * 3. calculate the lowest index and insert the property
-				 */
-				if (pc == null)
-					throw new MappingException("dotted notation in <return-join> or <load_collection> not yet supported");
-				int dotIndex = name.lastIndexOf( '.' );
-				String reducedName = name.substring( 0, dotIndex );
-				Value value = pc.getRecursiveProperty( reducedName ).getValue();
-				Iterator parentPropIter;
-				if ( value instanceof Component ) {
-					Component comp = (Component) value;
-					parentPropIter = comp.getPropertyIterator();
-				}
-				else if ( value instanceof ToOne ) {
-					ToOne toOne = (ToOne) value;
-					PersistentClass referencedPc = mappings.getClass( toOne.getReferencedEntityName() );
-					if ( toOne.getReferencedPropertyName() != null ) {
-						try {
-							parentPropIter = ( (Component) referencedPc.getRecursiveProperty( toOne.getReferencedPropertyName() ).getValue() ).getPropertyIterator();
-						} catch (ClassCastException e) {
-							throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
-						}
-					}
-					else {
-						try {
-							if ( referencedPc.getIdentifierMapper() == null ) {
-								parentPropIter = ( (Component) referencedPc.getIdentifierProperty().getValue() ).getPropertyIterator();
-							}
-							else {
-								parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator();
-							}
-						}
-						catch (ClassCastException e) {
-							throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
-						}
-					}
-				}
-				else {
-					throw new MappingException("dotted notation reference neither a component nor a many/one to one");
-				}
-				boolean hasFollowers = false;
-				List followers = new ArrayList();
-				while ( parentPropIter.hasNext() ) {
-					String currentPropertyName = ( (Property) parentPropIter.next() ).getName();
-					String currentName = reducedName + '.' + currentPropertyName;
-					if (hasFollowers) {
-						followers.add( currentName );
-					}
-					if ( name.equals( currentName ) ) hasFollowers = true;
-				}
-
-				int index = propertyNames.size();
-				int followersSize = followers.size();
-				for (int loop = 0 ; loop < followersSize ; loop++) {
-					String follower = (String) followers.get(loop);
-					int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
-					index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
-				}
-				propertyNames.add(index, name);
-				properties.add(index, propertyresult);
-			}
-		}
-
-		Set uniqueReturnProperty = new HashSet();
-		iterator = properties.iterator();
-		while ( iterator.hasNext() ) {
-			Element propertyresult = (Element) iterator.next();
-			String name = propertyresult.attributeValue("name");
-			if ( "class".equals(name) ) {
-				throw new MappingException(
-						"class is not a valid property name to use in a <return-property>, use <return-discriminator> instead"
-					);
-			}
-			//TODO: validate existing of property with the chosen name. (secondpass )
-			ArrayList allResultColumns = getResultColumns(propertyresult);
-
-			if ( allResultColumns.isEmpty() ) {
-				throw new MappingException(
-						"return-property for alias " + alias +
-						" must specify at least one column or return-column name"
-					);
-			}
-			if ( uniqueReturnProperty.contains( name ) ) {
-				throw new MappingException(
-						"duplicate return-property for property " + name +
-						" on alias " + alias
-					);
-			}
-			uniqueReturnProperty.add(name);
-
-			// the issue here is that for <return-join/> representing an entity collection,
-			// the collection element values (the property values of the associated entity)
-			// are represented as 'element.{propertyname}'.  Thus the StringHelper.root()
-			// here puts everything under 'element' (which additionally has significant
-			// meaning).  Probably what we need to do is to something like this instead:
-			//      String root = StringHelper.root( name );
-			//      String key = root; // by default
-			//      if ( !root.equals( name ) ) {
-			//	        // we had a dot
-			//          if ( !root.equals( alias ) {
-			//              // the root does not apply to the specific alias
-			//              if ( "elements".equals( root ) {
-			//                  // we specifically have a <return-join/> representing an entity collection
-			//                  // and this <return-property/> is one of that entity's properties
-			//                  key = name;
-			//              }
-			//          }
-			//      }
-			// but I am not clear enough on the intended purpose of this code block, especially
-			// in relation to the "Reorder properties" code block above... 
-//			String key = StringHelper.root( name );
-			String key = name;
-			ArrayList intermediateResults = (ArrayList) propertyresults.get( key );
-			if (intermediateResults == null) {
-				propertyresults.put( key, allResultColumns );
-			}
-			else {
-				intermediateResults.addAll( allResultColumns );
-			}
-		}
-
-		Iterator entries = propertyresults.entrySet().iterator();
-		while ( entries.hasNext() ) {
-			Map.Entry entry = (Map.Entry) entries.next();
-			if (entry.getValue() instanceof ArrayList) {
-				ArrayList list = (ArrayList) entry.getValue();
-				entry.setValue( list.toArray( new String[ list.size() ] ) );
-			}
-		}
-		return propertyresults.isEmpty() ? CollectionHelper.EMPTY_MAP : propertyresults;
-	}
-
-	private static int getIndexOfFirstMatchingProperty(List propertyNames, String follower) {
-		int propertySize = propertyNames.size();
-		for (int propIndex = 0 ; propIndex < propertySize ; propIndex++) {
-			if ( ( (String) propertyNames.get(propIndex) ).startsWith( follower ) ) {
-				return propIndex;
-			}
-		}
-		return -1;
-	}
-
-	private static ArrayList getResultColumns(Element propertyresult) {
-		String column = unquote(propertyresult.attributeValue("column"));
-		ArrayList allResultColumns = new ArrayList();
-		if(column!=null) allResultColumns.add(column);
-		Iterator resultColumns = propertyresult.elementIterator("return-column");
-		while ( resultColumns.hasNext() ) {
-			Element element = (Element) resultColumns.next();
-			allResultColumns.add( unquote(element.attributeValue("name")) );
-		}
-		return allResultColumns;
-	}
-
-	private static String unquote(String name) {
-		if (name!=null && name.charAt(0)=='`') {
-			name=name.substring( 1, name.length()-1 );
-		}
-		return name;
-	}
-
-	private static LockMode getLockMode(String lockMode) {
-		if ( lockMode == null || "read".equals( lockMode ) ) {
-			return LockMode.READ;
-		}
-		else if ( "none".equals( lockMode ) ) {
-			return LockMode.NONE;
-		}
-		else if ( "upgrade".equals( lockMode ) ) {
-			return LockMode.UPGRADE;
-		}
-		else if ( "upgrade-nowait".equals( lockMode ) ) {
-			return LockMode.UPGRADE_NOWAIT;
-		}
-		else if ( "write".equals( lockMode ) ) {
-			return LockMode.WRITE;
-		}
-		else if ( "force".equals( lockMode ) ) {
-			return LockMode.FORCE;
-		}
-		else {
-			throw new MappingException( "unknown lockmode" );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,389 @@
+/*
+ * 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.cfg;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Value;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.ToOne;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public abstract class ResultSetMappingBinder {
+	/**
+	 * Build a ResultSetMappingDefinition given a containing element for the "return-XXX" elements
+	 *
+	 * @param resultSetElem The element containing the return definitions.
+	 * @param path No clue...
+	 * @param mappings The current processing state.
+	 * @return The description of the mappings...
+	 */
+	protected static ResultSetMappingDefinition buildResultSetMappingDefinition(Element resultSetElem, String path, Mappings mappings) {
+		String resultSetName = resultSetElem.attribute( "name" ).getValue();
+		if ( path != null ) {
+			resultSetName = path + '.' + resultSetName;
+		}
+		ResultSetMappingDefinition definition = new ResultSetMappingDefinition( resultSetName );
+
+		int cnt = 0;
+		Iterator returns = resultSetElem.elementIterator();
+		while ( returns.hasNext() ) {
+			cnt++;
+			Element returnElem = (Element) returns.next();
+			String name = returnElem.getName();
+			if ( "return-scalar".equals( name ) ) {
+				String column = returnElem.attributeValue( "column" );
+				String typeFromXML = HbmBinder.getTypeFromXML( returnElem );
+				Type type = null;
+				if(typeFromXML!=null) {
+					type = TypeFactory.heuristicType( typeFromXML );
+					if ( type == null ) {
+						throw new MappingException( "could not determine type " + type );
+					}
+				}
+				definition.addQueryReturn( new NativeSQLQueryScalarReturn( column, type ) );
+			}
+			else if ( "return".equals( name ) ) {
+				definition.addQueryReturn( bindReturn( returnElem, mappings, cnt ) );
+			}
+			else if ( "return-join".equals( name ) ) {
+				definition.addQueryReturn( bindReturnJoin( returnElem, mappings ) );
+			}
+			else if ( "load-collection".equals( name ) ) {
+				definition.addQueryReturn( bindLoadCollection( returnElem, mappings ) );
+			}
+		}
+		return definition;
+	}
+
+	private static NativeSQLQueryRootReturn bindReturn(Element returnElem, Mappings mappings, int elementCount) {
+		String alias = returnElem.attributeValue( "alias" );
+		if( StringHelper.isEmpty(alias)) {
+			alias = "alias_" + elementCount; // hack/workaround as sqlquery impl depend on having a key.
+		}
+
+		String entityName = HbmBinder.getEntityName(returnElem, mappings);
+		if(entityName==null) {
+			throw new MappingException( "<return alias='" + alias + "'> must specify either a class or entity-name");
+		}
+		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
+
+		PersistentClass pc = mappings.getClass( entityName );
+		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, pc, mappings );
+
+		return new NativeSQLQueryRootReturn(
+				alias,
+				entityName,
+				propertyResults,
+				lockMode
+			);
+	}
+
+	private static NativeSQLQueryJoinReturn bindReturnJoin(Element returnElem, Mappings mappings) {
+		String alias = returnElem.attributeValue( "alias" );
+		String roleAttribute = returnElem.attributeValue( "property" );
+		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
+		int dot = roleAttribute.lastIndexOf( '.' );
+		if ( dot == -1 ) {
+			throw new MappingException(
+					"Role attribute for sql query return [alias=" + alias +
+					"] not formatted correctly {owningAlias.propertyName}"
+				);
+		}
+		String roleOwnerAlias = roleAttribute.substring( 0, dot );
+		String roleProperty = roleAttribute.substring( dot + 1 );
+
+		//FIXME: get the PersistentClass
+		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
+
+		return new NativeSQLQueryJoinReturn(
+				alias,
+				roleOwnerAlias,
+				roleProperty,
+				propertyResults, // TODO: bindpropertyresults(alias, returnElem)
+				lockMode
+			);
+	}
+
+	private static NativeSQLQueryCollectionReturn bindLoadCollection(Element returnElem, Mappings mappings) {
+		String alias = returnElem.attributeValue( "alias" );
+		String collectionAttribute = returnElem.attributeValue( "role" );
+		LockMode lockMode = getLockMode( returnElem.attributeValue( "lock-mode" ) );
+		int dot = collectionAttribute.lastIndexOf( '.' );
+		if ( dot == -1 ) {
+			throw new MappingException(
+					"Collection attribute for sql query return [alias=" + alias +
+					"] not formatted correctly {OwnerClassName.propertyName}"
+				);
+		}
+		String ownerClassName = HbmBinder.getClassName( collectionAttribute.substring( 0, dot ), mappings );
+		String ownerPropertyName = collectionAttribute.substring( dot + 1 );
+
+		//FIXME: get the PersistentClass
+		java.util.Map propertyResults = bindPropertyResults(alias, returnElem, null, mappings );
+
+		return new NativeSQLQueryCollectionReturn(
+				alias,
+				ownerClassName,
+				ownerPropertyName,
+				propertyResults,
+				lockMode
+			);
+	}
+
+	private static java.util.Map bindPropertyResults(
+			String alias, Element returnElement, PersistentClass pc, Mappings mappings
+	) {
+
+		HashMap propertyresults = new HashMap(); // maybe a concrete SQLpropertyresult type, but Map is exactly what is required at the moment
+
+		Element discriminatorResult = returnElement.element("return-discriminator");
+		if(discriminatorResult!=null) {
+			ArrayList resultColumns = getResultColumns(discriminatorResult);
+			propertyresults.put("class", ArrayHelper.toStringArray(resultColumns) );
+		}
+		Iterator iterator = returnElement.elementIterator("return-property");
+		List properties = new ArrayList();
+		List propertyNames = new ArrayList();
+		while ( iterator.hasNext() ) {
+			Element propertyresult = (Element) iterator.next();
+			String name = propertyresult.attributeValue("name");
+			if ( pc == null || name.indexOf( '.') == -1) { //if dotted and not load-collection nor return-join
+				//regular property
+				properties.add(propertyresult);
+				propertyNames.add(name);
+			}
+			else {
+				/**
+				 * Reorder properties
+				 * 1. get the parent property
+				 * 2. list all the properties following the expected one in the parent property
+				 * 3. calculate the lowest index and insert the property
+				 */
+				if (pc == null)
+					throw new MappingException("dotted notation in <return-join> or <load_collection> not yet supported");
+				int dotIndex = name.lastIndexOf( '.' );
+				String reducedName = name.substring( 0, dotIndex );
+				Value value = pc.getRecursiveProperty( reducedName ).getValue();
+				Iterator parentPropIter;
+				if ( value instanceof Component ) {
+					Component comp = (Component) value;
+					parentPropIter = comp.getPropertyIterator();
+				}
+				else if ( value instanceof ToOne ) {
+					ToOne toOne = (ToOne) value;
+					PersistentClass referencedPc = mappings.getClass( toOne.getReferencedEntityName() );
+					if ( toOne.getReferencedPropertyName() != null ) {
+						try {
+							parentPropIter = ( (Component) referencedPc.getRecursiveProperty( toOne.getReferencedPropertyName() ).getValue() ).getPropertyIterator();
+						} catch (ClassCastException e) {
+							throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
+						}
+					}
+					else {
+						try {
+							if ( referencedPc.getIdentifierMapper() == null ) {
+								parentPropIter = ( (Component) referencedPc.getIdentifierProperty().getValue() ).getPropertyIterator();
+							}
+							else {
+								parentPropIter = referencedPc.getIdentifierMapper().getPropertyIterator();
+							}
+						}
+						catch (ClassCastException e) {
+							throw new MappingException("dotted notation reference neither a component nor a many/one to one", e);
+						}
+					}
+				}
+				else {
+					throw new MappingException("dotted notation reference neither a component nor a many/one to one");
+				}
+				boolean hasFollowers = false;
+				List followers = new ArrayList();
+				while ( parentPropIter.hasNext() ) {
+					String currentPropertyName = ( (Property) parentPropIter.next() ).getName();
+					String currentName = reducedName + '.' + currentPropertyName;
+					if (hasFollowers) {
+						followers.add( currentName );
+					}
+					if ( name.equals( currentName ) ) hasFollowers = true;
+				}
+
+				int index = propertyNames.size();
+				int followersSize = followers.size();
+				for (int loop = 0 ; loop < followersSize ; loop++) {
+					String follower = (String) followers.get(loop);
+					int currentIndex = getIndexOfFirstMatchingProperty(propertyNames, follower);
+					index = currentIndex != -1 && currentIndex < index ? currentIndex : index;
+				}
+				propertyNames.add(index, name);
+				properties.add(index, propertyresult);
+			}
+		}
+
+		Set uniqueReturnProperty = new HashSet();
+		iterator = properties.iterator();
+		while ( iterator.hasNext() ) {
+			Element propertyresult = (Element) iterator.next();
+			String name = propertyresult.attributeValue("name");
+			if ( "class".equals(name) ) {
+				throw new MappingException(
+						"class is not a valid property name to use in a <return-property>, use <return-discriminator> instead"
+					);
+			}
+			//TODO: validate existing of property with the chosen name. (secondpass )
+			ArrayList allResultColumns = getResultColumns(propertyresult);
+
+			if ( allResultColumns.isEmpty() ) {
+				throw new MappingException(
+						"return-property for alias " + alias +
+						" must specify at least one column or return-column name"
+					);
+			}
+			if ( uniqueReturnProperty.contains( name ) ) {
+				throw new MappingException(
+						"duplicate return-property for property " + name +
+						" on alias " + alias
+					);
+			}
+			uniqueReturnProperty.add(name);
+
+			// the issue here is that for <return-join/> representing an entity collection,
+			// the collection element values (the property values of the associated entity)
+			// are represented as 'element.{propertyname}'.  Thus the StringHelper.root()
+			// here puts everything under 'element' (which additionally has significant
+			// meaning).  Probably what we need to do is to something like this instead:
+			//      String root = StringHelper.root( name );
+			//      String key = root; // by default
+			//      if ( !root.equals( name ) ) {
+			//	        // we had a dot
+			//          if ( !root.equals( alias ) {
+			//              // the root does not apply to the specific alias
+			//              if ( "elements".equals( root ) {
+			//                  // we specifically have a <return-join/> representing an entity collection
+			//                  // and this <return-property/> is one of that entity's properties
+			//                  key = name;
+			//              }
+			//          }
+			//      }
+			// but I am not clear enough on the intended purpose of this code block, especially
+			// in relation to the "Reorder properties" code block above... 
+//			String key = StringHelper.root( name );
+			String key = name;
+			ArrayList intermediateResults = (ArrayList) propertyresults.get( key );
+			if (intermediateResults == null) {
+				propertyresults.put( key, allResultColumns );
+			}
+			else {
+				intermediateResults.addAll( allResultColumns );
+			}
+		}
+
+		Iterator entries = propertyresults.entrySet().iterator();
+		while ( entries.hasNext() ) {
+			Map.Entry entry = (Map.Entry) entries.next();
+			if (entry.getValue() instanceof ArrayList) {
+				ArrayList list = (ArrayList) entry.getValue();
+				entry.setValue( list.toArray( new String[ list.size() ] ) );
+			}
+		}
+		return propertyresults.isEmpty() ? CollectionHelper.EMPTY_MAP : propertyresults;
+	}
+
+	private static int getIndexOfFirstMatchingProperty(List propertyNames, String follower) {
+		int propertySize = propertyNames.size();
+		for (int propIndex = 0 ; propIndex < propertySize ; propIndex++) {
+			if ( ( (String) propertyNames.get(propIndex) ).startsWith( follower ) ) {
+				return propIndex;
+			}
+		}
+		return -1;
+	}
+
+	private static ArrayList getResultColumns(Element propertyresult) {
+		String column = unquote(propertyresult.attributeValue("column"));
+		ArrayList allResultColumns = new ArrayList();
+		if(column!=null) allResultColumns.add(column);
+		Iterator resultColumns = propertyresult.elementIterator("return-column");
+		while ( resultColumns.hasNext() ) {
+			Element element = (Element) resultColumns.next();
+			allResultColumns.add( unquote(element.attributeValue("name")) );
+		}
+		return allResultColumns;
+	}
+
+	private static String unquote(String name) {
+		if (name!=null && name.charAt(0)=='`') {
+			name=name.substring( 1, name.length()-1 );
+		}
+		return name;
+	}
+
+	private static LockMode getLockMode(String lockMode) {
+		if ( lockMode == null || "read".equals( lockMode ) ) {
+			return LockMode.READ;
+		}
+		else if ( "none".equals( lockMode ) ) {
+			return LockMode.NONE;
+		}
+		else if ( "upgrade".equals( lockMode ) ) {
+			return LockMode.UPGRADE;
+		}
+		else if ( "upgrade-nowait".equals( lockMode ) ) {
+			return LockMode.UPGRADE_NOWAIT;
+		}
+		else if ( "write".equals( lockMode ) ) {
+			return LockMode.WRITE;
+		}
+		else if ( "force".equals( lockMode ) ) {
+			return LockMode.FORCE;
+		}
+		else {
+			throw new MappingException( "unknown lockmode" );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: ResultSetMappingSecondPass.java 10196 2006-08-03 07:53:27Z max.andersen at jboss.com $
-package org.hibernate.cfg;
-
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.hibernate.MappingException;
-import org.hibernate.engine.ResultSetMappingDefinition;
-
-/**
- * @author Emmanuel Bernard
- */
-public class ResultSetMappingSecondPass extends ResultSetMappingBinder implements QuerySecondPass {
-	private Element element;
-	private String path;
-	private Mappings mappings;
-
-	public ResultSetMappingSecondPass(Element element, String path, Mappings mappings) {
-		this.element = element;
-		this.path = path;
-		this.mappings = mappings;
-	}
-
-	public void doSecondPass(Map persistentClasses) throws MappingException {
-		ResultSetMappingDefinition definition = buildResultSetMappingDefinition( element, path, mappings);
-		mappings.addResultSetMapping( definition );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/ResultSetMappingSecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.hibernate.MappingException;
+import org.hibernate.engine.ResultSetMappingDefinition;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class ResultSetMappingSecondPass extends ResultSetMappingBinder implements QuerySecondPass {
+	private Element element;
+	private String path;
+	private Mappings mappings;
+
+	public ResultSetMappingSecondPass(Element element, String path, Mappings mappings) {
+		this.element = element;
+		this.path = path;
+		this.mappings = mappings;
+	}
+
+	public void doSecondPass(Map persistentClasses) throws MappingException {
+		ResultSetMappingDefinition definition = buildResultSetMappingDefinition( element, path, mappings);
+		mappings.addResultSetMapping( definition );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SecondPass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-//$Id: SecondPass.java 10196 2006-08-03 07:53:27Z max.andersen at jboss.com $
-package org.hibernate.cfg;
-
-import java.io.Serializable;
-
-import org.hibernate.MappingException;
-
-/**
- * Second pass operation
- *
- * @author Emmanuel Bernard
- */
-public interface SecondPass extends Serializable {
-
-	void doSecondPass(java.util.Map persistentClasses)
-				throws MappingException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/SecondPass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SecondPass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.cfg;
+
+import java.io.Serializable;
+
+import org.hibernate.MappingException;
+
+/**
+ * Second pass operation
+ *
+ * @author Emmanuel Bernard
+ */
+public interface SecondPass extends Serializable {
+
+	void doSecondPass(java.util.Map persistentClasses)
+				throws MappingException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,461 +0,0 @@
-//$Id: Settings.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.cfg;
-
-import java.util.Map;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.EntityMode;
-import org.hibernate.cache.QueryCacheFactory;
-import org.hibernate.cache.RegionFactory;
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.hql.QueryTranslatorFactory;
-import org.hibernate.jdbc.BatcherFactory;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.TransactionManagerLookup;
-
-/**
- * Settings that affect the behaviour of Hibernate at runtime.
- *
- * @author Gavin King
- */
-public final class Settings {
-
-//	private boolean showSql;
-//	private boolean formatSql;
-	private SQLStatementLogger sqlStatementLogger;
-	private Integer maximumFetchDepth;
-	private Map querySubstitutions;
-	private Dialect dialect;
-	private int jdbcBatchSize;
-	private int defaultBatchFetchSize;
-	private boolean scrollableResultSetsEnabled;
-	private boolean getGeneratedKeysEnabled;
-	private String defaultSchemaName;
-	private String defaultCatalogName;
-	private Integer jdbcFetchSize;
-	private String sessionFactoryName;
-	private boolean autoCreateSchema;
-	private boolean autoDropSchema;
-	private boolean autoUpdateSchema;
-	private boolean autoValidateSchema;
-	private boolean queryCacheEnabled;
-	private boolean structuredCacheEntriesEnabled;
-	private boolean secondLevelCacheEnabled;
-	private String cacheRegionPrefix;
-	private boolean minimalPutsEnabled;
-	private boolean commentsEnabled;
-	private boolean statisticsEnabled;
-	private boolean jdbcBatchVersionedData;
-	private boolean identifierRollbackEnabled;
-	private boolean flushBeforeCompletionEnabled;
-	private boolean autoCloseSessionEnabled;
-	private ConnectionReleaseMode connectionReleaseMode;
-	private RegionFactory regionFactory;
-	private QueryCacheFactory queryCacheFactory;
-	private ConnectionProvider connectionProvider;
-	private TransactionFactory transactionFactory;
-	private TransactionManagerLookup transactionManagerLookup;
-	private BatcherFactory batcherFactory;
-	private QueryTranslatorFactory queryTranslatorFactory;
-	private SQLExceptionConverter sqlExceptionConverter;
-	private boolean wrapResultSetsEnabled;
-	private boolean orderUpdatesEnabled;
-	private boolean orderInsertsEnabled;
-	private EntityMode defaultEntityMode;
-	private boolean dataDefinitionImplicitCommit;
-	private boolean dataDefinitionInTransactionSupported;
-	private boolean strictJPAQLCompliance;
-	private boolean namedQueryStartupCheckingEnabled;
-//	private BytecodeProvider bytecodeProvider;
-
-	/**
-	 * Package protected constructor
-	 */
-	Settings() {
-	}
-
-	// public getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-//	public boolean isShowSqlEnabled() {
-//		return showSql;
-//	}
-//
-//	public boolean isFormatSqlEnabled() {
-//		return formatSql;
-//	}
-
-	public SQLStatementLogger getSqlStatementLogger() {
-		return sqlStatementLogger;
-	}
-
-	public String getDefaultSchemaName() {
-		return defaultSchemaName;
-	}
-
-	public String getDefaultCatalogName() {
-		return defaultCatalogName;
-	}
-
-	public Dialect getDialect() {
-		return dialect;
-	}
-
-	public int getJdbcBatchSize() {
-		return jdbcBatchSize;
-	}
-
-	public int getDefaultBatchFetchSize() {
-		return defaultBatchFetchSize;
-	}
-
-	public Map getQuerySubstitutions() {
-		return querySubstitutions;
-	}
-
-	public boolean isIdentifierRollbackEnabled() {
-		return identifierRollbackEnabled;
-	}
-
-	public boolean isScrollableResultSetsEnabled() {
-		return scrollableResultSetsEnabled;
-	}
-
-	public boolean isGetGeneratedKeysEnabled() {
-		return getGeneratedKeysEnabled;
-	}
-
-	public boolean isMinimalPutsEnabled() {
-		return minimalPutsEnabled;
-	}
-
-	public Integer getJdbcFetchSize() {
-		return jdbcFetchSize;
-	}
-
-	public ConnectionProvider getConnectionProvider() {
-		return connectionProvider;
-	}
-
-	public TransactionFactory getTransactionFactory() {
-		return transactionFactory;
-	}
-
-	public String getSessionFactoryName() {
-		return sessionFactoryName;
-	}
-
-	public boolean isAutoCreateSchema() {
-		return autoCreateSchema;
-	}
-
-	public boolean isAutoDropSchema() {
-		return autoDropSchema;
-	}
-
-	public boolean isAutoUpdateSchema() {
-		return autoUpdateSchema;
-	}
-
-	public Integer getMaximumFetchDepth() {
-		return maximumFetchDepth;
-	}
-
-	public RegionFactory getRegionFactory() {
-		return regionFactory;
-	}
-
-	public TransactionManagerLookup getTransactionManagerLookup() {
-		return transactionManagerLookup;
-	}
-
-	public boolean isQueryCacheEnabled() {
-		return queryCacheEnabled;
-	}
-
-	public boolean isCommentsEnabled() {
-		return commentsEnabled;
-	}
-
-	public boolean isSecondLevelCacheEnabled() {
-		return secondLevelCacheEnabled;
-	}
-
-	public String getCacheRegionPrefix() {
-		return cacheRegionPrefix;
-	}
-
-	public QueryCacheFactory getQueryCacheFactory() {
-		return queryCacheFactory;
-	}
-
-	public boolean isStatisticsEnabled() {
-		return statisticsEnabled;
-	}
-
-	public boolean isJdbcBatchVersionedData() {
-		return jdbcBatchVersionedData;
-	}
-
-	public boolean isFlushBeforeCompletionEnabled() {
-		return flushBeforeCompletionEnabled;
-	}
-
-	public BatcherFactory getBatcherFactory() {
-		return batcherFactory;
-	}
-
-	public boolean isAutoCloseSessionEnabled() {
-		return autoCloseSessionEnabled;
-	}
-
-	public ConnectionReleaseMode getConnectionReleaseMode() {
-		return connectionReleaseMode;
-	}
-
-	public QueryTranslatorFactory getQueryTranslatorFactory() {
-		return queryTranslatorFactory;
-	}
-
-	public SQLExceptionConverter getSQLExceptionConverter() {
-		return sqlExceptionConverter;
-	}
-
-	public boolean isWrapResultSetsEnabled() {
-		return wrapResultSetsEnabled;
-	}
-
-	public boolean isOrderUpdatesEnabled() {
-		return orderUpdatesEnabled;
-	}
-
-	public boolean isOrderInsertsEnabled() {
-		return orderInsertsEnabled;
-	}
-
-	public boolean isStructuredCacheEntriesEnabled() {
-		return structuredCacheEntriesEnabled;
-	}
-
-	public EntityMode getDefaultEntityMode() {
-		return defaultEntityMode;
-	}
-
-	public boolean isAutoValidateSchema() {
-		return autoValidateSchema;
-	}
-
-	public boolean isDataDefinitionImplicitCommit() {
-		return dataDefinitionImplicitCommit;
-	}
-
-	public boolean isDataDefinitionInTransactionSupported() {
-		return dataDefinitionInTransactionSupported;
-	}
-
-	public boolean isStrictJPAQLCompliance() {
-		return strictJPAQLCompliance;
-	}
-
-	public boolean isNamedQueryStartupCheckingEnabled() {
-		return namedQueryStartupCheckingEnabled;
-	}
-
-
-	// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-//	void setShowSqlEnabled(boolean b) {
-//		showSql = b;
-//	}
-//
-//	void setFormatSqlEnabled(boolean b) {
-//		formatSql = b;
-//	}
-
-	void setSqlStatementLogger(SQLStatementLogger sqlStatementLogger) {
-		this.sqlStatementLogger = sqlStatementLogger;
-	}
-
-	void setDefaultSchemaName(String string) {
-		defaultSchemaName = string;
-	}
-
-	void setDefaultCatalogName(String string) {
-		defaultCatalogName = string;
-	}
-
-	void setDialect(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	void setJdbcBatchSize(int i) {
-		jdbcBatchSize = i;
-	}
-
-	void setDefaultBatchFetchSize(int i) {
-		defaultBatchFetchSize = i;
-	}
-
-	void setQuerySubstitutions(Map map) {
-		querySubstitutions = map;
-	}
-
-	void setIdentifierRollbackEnabled(boolean b) {
-		identifierRollbackEnabled = b;
-	}
-
-	void setMinimalPutsEnabled(boolean b) {
-		minimalPutsEnabled = b;
-	}
-
-	void setScrollableResultSetsEnabled(boolean b) {
-		scrollableResultSetsEnabled = b;
-	}
-
-	void setGetGeneratedKeysEnabled(boolean b) {
-		getGeneratedKeysEnabled = b;
-	}
-
-	void setJdbcFetchSize(Integer integer) {
-		jdbcFetchSize = integer;
-	}
-
-	void setConnectionProvider(ConnectionProvider provider) {
-		connectionProvider = provider;
-	}
-
-	void setTransactionFactory(TransactionFactory factory) {
-		transactionFactory = factory;
-	}
-
-	void setSessionFactoryName(String string) {
-		sessionFactoryName = string;
-	}
-
-	void setAutoCreateSchema(boolean b) {
-		autoCreateSchema = b;
-	}
-
-	void setAutoDropSchema(boolean b) {
-		autoDropSchema = b;
-	}
-
-	void setAutoUpdateSchema(boolean b) {
-		autoUpdateSchema = b;
-	}
-
-	void setMaximumFetchDepth(Integer i) {
-		maximumFetchDepth = i;
-	}
-
-	void setRegionFactory(RegionFactory regionFactory) {
-		this.regionFactory = regionFactory;
-	}
-
-	void setTransactionManagerLookup(TransactionManagerLookup lookup) {
-		transactionManagerLookup = lookup;
-	}
-
-	void setQueryCacheEnabled(boolean b) {
-		queryCacheEnabled = b;
-	}
-
-	void setCommentsEnabled(boolean commentsEnabled) {
-		this.commentsEnabled = commentsEnabled;
-	}
-
-	void setSecondLevelCacheEnabled(boolean secondLevelCacheEnabled) {
-		this.secondLevelCacheEnabled = secondLevelCacheEnabled;
-	}
-
-	void setCacheRegionPrefix(String cacheRegionPrefix) {
-		this.cacheRegionPrefix = cacheRegionPrefix;
-	}
-
-	void setQueryCacheFactory(QueryCacheFactory queryCacheFactory) {
-		this.queryCacheFactory = queryCacheFactory;
-	}
-
-	void setStatisticsEnabled(boolean statisticsEnabled) {
-		this.statisticsEnabled = statisticsEnabled;
-	}
-
-	void setJdbcBatchVersionedData(boolean jdbcBatchVersionedData) {
-		this.jdbcBatchVersionedData = jdbcBatchVersionedData;
-	}
-
-	void setFlushBeforeCompletionEnabled(boolean flushBeforeCompletionEnabled) {
-		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
-	}
-
-	void setBatcherFactory(BatcherFactory batcher) {
-		this.batcherFactory = batcher;
-	}
-
-	void setAutoCloseSessionEnabled(boolean autoCloseSessionEnabled) {
-		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
-	}
-
-	void setConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) {
-		this.connectionReleaseMode = connectionReleaseMode;
-	}
-
-	void setQueryTranslatorFactory(QueryTranslatorFactory queryTranslatorFactory) {
-		this.queryTranslatorFactory = queryTranslatorFactory;
-	}
-
-	void setSQLExceptionConverter(SQLExceptionConverter sqlExceptionConverter) {
-		this.sqlExceptionConverter = sqlExceptionConverter;
-	}
-
-	void setWrapResultSetsEnabled(boolean wrapResultSetsEnabled) {
-		this.wrapResultSetsEnabled = wrapResultSetsEnabled;
-	}
-
-	void setOrderUpdatesEnabled(boolean orderUpdatesEnabled) {
-		this.orderUpdatesEnabled = orderUpdatesEnabled;
-	}
-
-	void setOrderInsertsEnabled(boolean orderInsertsEnabled) {
-		this.orderInsertsEnabled = orderInsertsEnabled;
-	}
-
-	void setStructuredCacheEntriesEnabled(boolean structuredCacheEntriesEnabled) {
-		this.structuredCacheEntriesEnabled = structuredCacheEntriesEnabled;
-	}
-
-	void setDefaultEntityMode(EntityMode defaultEntityMode) {
-		this.defaultEntityMode = defaultEntityMode;
-	}
-
-	void setAutoValidateSchema(boolean autoValidateSchema) {
-		this.autoValidateSchema = autoValidateSchema;
-	}
-
-	void setDataDefinitionImplicitCommit(boolean dataDefinitionImplicitCommit) {
-		this.dataDefinitionImplicitCommit = dataDefinitionImplicitCommit;
-	}
-
-	void setDataDefinitionInTransactionSupported(boolean dataDefinitionInTransactionSupported) {
-		this.dataDefinitionInTransactionSupported = dataDefinitionInTransactionSupported;
-	}
-
-	void setStrictJPAQLCompliance(boolean strictJPAQLCompliance) {
-		this.strictJPAQLCompliance = strictJPAQLCompliance;
-	}
-
-	void setNamedQueryStartupCheckingEnabled(boolean namedQueryStartupCheckingEnabled) {
-		this.namedQueryStartupCheckingEnabled = namedQueryStartupCheckingEnabled;
-	}
-
-
-//	public BytecodeProvider getBytecodeProvider() {
-//		return bytecodeProvider;
-//	}
-//
-//	void setBytecodeProvider(BytecodeProvider bytecodeProvider) {
-//		this.bytecodeProvider = bytecodeProvider;
-//	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/Settings.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/Settings.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,484 @@
+/*
+ * 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.cfg;
+
+import java.util.Map;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.EntityMode;
+import org.hibernate.cache.QueryCacheFactory;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.hql.QueryTranslatorFactory;
+import org.hibernate.jdbc.BatcherFactory;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.transaction.TransactionManagerLookup;
+
+/**
+ * Settings that affect the behaviour of Hibernate at runtime.
+ *
+ * @author Gavin King
+ */
+public final class Settings {
+
+//	private boolean showSql;
+//	private boolean formatSql;
+	private SQLStatementLogger sqlStatementLogger;
+	private Integer maximumFetchDepth;
+	private Map querySubstitutions;
+	private Dialect dialect;
+	private int jdbcBatchSize;
+	private int defaultBatchFetchSize;
+	private boolean scrollableResultSetsEnabled;
+	private boolean getGeneratedKeysEnabled;
+	private String defaultSchemaName;
+	private String defaultCatalogName;
+	private Integer jdbcFetchSize;
+	private String sessionFactoryName;
+	private boolean autoCreateSchema;
+	private boolean autoDropSchema;
+	private boolean autoUpdateSchema;
+	private boolean autoValidateSchema;
+	private boolean queryCacheEnabled;
+	private boolean structuredCacheEntriesEnabled;
+	private boolean secondLevelCacheEnabled;
+	private String cacheRegionPrefix;
+	private boolean minimalPutsEnabled;
+	private boolean commentsEnabled;
+	private boolean statisticsEnabled;
+	private boolean jdbcBatchVersionedData;
+	private boolean identifierRollbackEnabled;
+	private boolean flushBeforeCompletionEnabled;
+	private boolean autoCloseSessionEnabled;
+	private ConnectionReleaseMode connectionReleaseMode;
+	private RegionFactory regionFactory;
+	private QueryCacheFactory queryCacheFactory;
+	private ConnectionProvider connectionProvider;
+	private TransactionFactory transactionFactory;
+	private TransactionManagerLookup transactionManagerLookup;
+	private BatcherFactory batcherFactory;
+	private QueryTranslatorFactory queryTranslatorFactory;
+	private SQLExceptionConverter sqlExceptionConverter;
+	private boolean wrapResultSetsEnabled;
+	private boolean orderUpdatesEnabled;
+	private boolean orderInsertsEnabled;
+	private EntityMode defaultEntityMode;
+	private boolean dataDefinitionImplicitCommit;
+	private boolean dataDefinitionInTransactionSupported;
+	private boolean strictJPAQLCompliance;
+	private boolean namedQueryStartupCheckingEnabled;
+//	private BytecodeProvider bytecodeProvider;
+
+	/**
+	 * Package protected constructor
+	 */
+	Settings() {
+	}
+
+	// public getters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+//	public boolean isShowSqlEnabled() {
+//		return showSql;
+//	}
+//
+//	public boolean isFormatSqlEnabled() {
+//		return formatSql;
+//	}
+
+	public SQLStatementLogger getSqlStatementLogger() {
+		return sqlStatementLogger;
+	}
+
+	public String getDefaultSchemaName() {
+		return defaultSchemaName;
+	}
+
+	public String getDefaultCatalogName() {
+		return defaultCatalogName;
+	}
+
+	public Dialect getDialect() {
+		return dialect;
+	}
+
+	public int getJdbcBatchSize() {
+		return jdbcBatchSize;
+	}
+
+	public int getDefaultBatchFetchSize() {
+		return defaultBatchFetchSize;
+	}
+
+	public Map getQuerySubstitutions() {
+		return querySubstitutions;
+	}
+
+	public boolean isIdentifierRollbackEnabled() {
+		return identifierRollbackEnabled;
+	}
+
+	public boolean isScrollableResultSetsEnabled() {
+		return scrollableResultSetsEnabled;
+	}
+
+	public boolean isGetGeneratedKeysEnabled() {
+		return getGeneratedKeysEnabled;
+	}
+
+	public boolean isMinimalPutsEnabled() {
+		return minimalPutsEnabled;
+	}
+
+	public Integer getJdbcFetchSize() {
+		return jdbcFetchSize;
+	}
+
+	public ConnectionProvider getConnectionProvider() {
+		return connectionProvider;
+	}
+
+	public TransactionFactory getTransactionFactory() {
+		return transactionFactory;
+	}
+
+	public String getSessionFactoryName() {
+		return sessionFactoryName;
+	}
+
+	public boolean isAutoCreateSchema() {
+		return autoCreateSchema;
+	}
+
+	public boolean isAutoDropSchema() {
+		return autoDropSchema;
+	}
+
+	public boolean isAutoUpdateSchema() {
+		return autoUpdateSchema;
+	}
+
+	public Integer getMaximumFetchDepth() {
+		return maximumFetchDepth;
+	}
+
+	public RegionFactory getRegionFactory() {
+		return regionFactory;
+	}
+
+	public TransactionManagerLookup getTransactionManagerLookup() {
+		return transactionManagerLookup;
+	}
+
+	public boolean isQueryCacheEnabled() {
+		return queryCacheEnabled;
+	}
+
+	public boolean isCommentsEnabled() {
+		return commentsEnabled;
+	}
+
+	public boolean isSecondLevelCacheEnabled() {
+		return secondLevelCacheEnabled;
+	}
+
+	public String getCacheRegionPrefix() {
+		return cacheRegionPrefix;
+	}
+
+	public QueryCacheFactory getQueryCacheFactory() {
+		return queryCacheFactory;
+	}
+
+	public boolean isStatisticsEnabled() {
+		return statisticsEnabled;
+	}
+
+	public boolean isJdbcBatchVersionedData() {
+		return jdbcBatchVersionedData;
+	}
+
+	public boolean isFlushBeforeCompletionEnabled() {
+		return flushBeforeCompletionEnabled;
+	}
+
+	public BatcherFactory getBatcherFactory() {
+		return batcherFactory;
+	}
+
+	public boolean isAutoCloseSessionEnabled() {
+		return autoCloseSessionEnabled;
+	}
+
+	public ConnectionReleaseMode getConnectionReleaseMode() {
+		return connectionReleaseMode;
+	}
+
+	public QueryTranslatorFactory getQueryTranslatorFactory() {
+		return queryTranslatorFactory;
+	}
+
+	public SQLExceptionConverter getSQLExceptionConverter() {
+		return sqlExceptionConverter;
+	}
+
+	public boolean isWrapResultSetsEnabled() {
+		return wrapResultSetsEnabled;
+	}
+
+	public boolean isOrderUpdatesEnabled() {
+		return orderUpdatesEnabled;
+	}
+
+	public boolean isOrderInsertsEnabled() {
+		return orderInsertsEnabled;
+	}
+
+	public boolean isStructuredCacheEntriesEnabled() {
+		return structuredCacheEntriesEnabled;
+	}
+
+	public EntityMode getDefaultEntityMode() {
+		return defaultEntityMode;
+	}
+
+	public boolean isAutoValidateSchema() {
+		return autoValidateSchema;
+	}
+
+	public boolean isDataDefinitionImplicitCommit() {
+		return dataDefinitionImplicitCommit;
+	}
+
+	public boolean isDataDefinitionInTransactionSupported() {
+		return dataDefinitionInTransactionSupported;
+	}
+
+	public boolean isStrictJPAQLCompliance() {
+		return strictJPAQLCompliance;
+	}
+
+	public boolean isNamedQueryStartupCheckingEnabled() {
+		return namedQueryStartupCheckingEnabled;
+	}
+
+
+	// package protected setters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+//	void setShowSqlEnabled(boolean b) {
+//		showSql = b;
+//	}
+//
+//	void setFormatSqlEnabled(boolean b) {
+//		formatSql = b;
+//	}
+
+	void setSqlStatementLogger(SQLStatementLogger sqlStatementLogger) {
+		this.sqlStatementLogger = sqlStatementLogger;
+	}
+
+	void setDefaultSchemaName(String string) {
+		defaultSchemaName = string;
+	}
+
+	void setDefaultCatalogName(String string) {
+		defaultCatalogName = string;
+	}
+
+	void setDialect(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	void setJdbcBatchSize(int i) {
+		jdbcBatchSize = i;
+	}
+
+	void setDefaultBatchFetchSize(int i) {
+		defaultBatchFetchSize = i;
+	}
+
+	void setQuerySubstitutions(Map map) {
+		querySubstitutions = map;
+	}
+
+	void setIdentifierRollbackEnabled(boolean b) {
+		identifierRollbackEnabled = b;
+	}
+
+	void setMinimalPutsEnabled(boolean b) {
+		minimalPutsEnabled = b;
+	}
+
+	void setScrollableResultSetsEnabled(boolean b) {
+		scrollableResultSetsEnabled = b;
+	}
+
+	void setGetGeneratedKeysEnabled(boolean b) {
+		getGeneratedKeysEnabled = b;
+	}
+
+	void setJdbcFetchSize(Integer integer) {
+		jdbcFetchSize = integer;
+	}
+
+	void setConnectionProvider(ConnectionProvider provider) {
+		connectionProvider = provider;
+	}
+
+	void setTransactionFactory(TransactionFactory factory) {
+		transactionFactory = factory;
+	}
+
+	void setSessionFactoryName(String string) {
+		sessionFactoryName = string;
+	}
+
+	void setAutoCreateSchema(boolean b) {
+		autoCreateSchema = b;
+	}
+
+	void setAutoDropSchema(boolean b) {
+		autoDropSchema = b;
+	}
+
+	void setAutoUpdateSchema(boolean b) {
+		autoUpdateSchema = b;
+	}
+
+	void setMaximumFetchDepth(Integer i) {
+		maximumFetchDepth = i;
+	}
+
+	void setRegionFactory(RegionFactory regionFactory) {
+		this.regionFactory = regionFactory;
+	}
+
+	void setTransactionManagerLookup(TransactionManagerLookup lookup) {
+		transactionManagerLookup = lookup;
+	}
+
+	void setQueryCacheEnabled(boolean b) {
+		queryCacheEnabled = b;
+	}
+
+	void setCommentsEnabled(boolean commentsEnabled) {
+		this.commentsEnabled = commentsEnabled;
+	}
+
+	void setSecondLevelCacheEnabled(boolean secondLevelCacheEnabled) {
+		this.secondLevelCacheEnabled = secondLevelCacheEnabled;
+	}
+
+	void setCacheRegionPrefix(String cacheRegionPrefix) {
+		this.cacheRegionPrefix = cacheRegionPrefix;
+	}
+
+	void setQueryCacheFactory(QueryCacheFactory queryCacheFactory) {
+		this.queryCacheFactory = queryCacheFactory;
+	}
+
+	void setStatisticsEnabled(boolean statisticsEnabled) {
+		this.statisticsEnabled = statisticsEnabled;
+	}
+
+	void setJdbcBatchVersionedData(boolean jdbcBatchVersionedData) {
+		this.jdbcBatchVersionedData = jdbcBatchVersionedData;
+	}
+
+	void setFlushBeforeCompletionEnabled(boolean flushBeforeCompletionEnabled) {
+		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
+	}
+
+	void setBatcherFactory(BatcherFactory batcher) {
+		this.batcherFactory = batcher;
+	}
+
+	void setAutoCloseSessionEnabled(boolean autoCloseSessionEnabled) {
+		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
+	}
+
+	void setConnectionReleaseMode(ConnectionReleaseMode connectionReleaseMode) {
+		this.connectionReleaseMode = connectionReleaseMode;
+	}
+
+	void setQueryTranslatorFactory(QueryTranslatorFactory queryTranslatorFactory) {
+		this.queryTranslatorFactory = queryTranslatorFactory;
+	}
+
+	void setSQLExceptionConverter(SQLExceptionConverter sqlExceptionConverter) {
+		this.sqlExceptionConverter = sqlExceptionConverter;
+	}
+
+	void setWrapResultSetsEnabled(boolean wrapResultSetsEnabled) {
+		this.wrapResultSetsEnabled = wrapResultSetsEnabled;
+	}
+
+	void setOrderUpdatesEnabled(boolean orderUpdatesEnabled) {
+		this.orderUpdatesEnabled = orderUpdatesEnabled;
+	}
+
+	void setOrderInsertsEnabled(boolean orderInsertsEnabled) {
+		this.orderInsertsEnabled = orderInsertsEnabled;
+	}
+
+	void setStructuredCacheEntriesEnabled(boolean structuredCacheEntriesEnabled) {
+		this.structuredCacheEntriesEnabled = structuredCacheEntriesEnabled;
+	}
+
+	void setDefaultEntityMode(EntityMode defaultEntityMode) {
+		this.defaultEntityMode = defaultEntityMode;
+	}
+
+	void setAutoValidateSchema(boolean autoValidateSchema) {
+		this.autoValidateSchema = autoValidateSchema;
+	}
+
+	void setDataDefinitionImplicitCommit(boolean dataDefinitionImplicitCommit) {
+		this.dataDefinitionImplicitCommit = dataDefinitionImplicitCommit;
+	}
+
+	void setDataDefinitionInTransactionSupported(boolean dataDefinitionInTransactionSupported) {
+		this.dataDefinitionInTransactionSupported = dataDefinitionInTransactionSupported;
+	}
+
+	void setStrictJPAQLCompliance(boolean strictJPAQLCompliance) {
+		this.strictJPAQLCompliance = strictJPAQLCompliance;
+	}
+
+	void setNamedQueryStartupCheckingEnabled(boolean namedQueryStartupCheckingEnabled) {
+		this.namedQueryStartupCheckingEnabled = namedQueryStartupCheckingEnabled;
+	}
+
+
+//	public BytecodeProvider getBytecodeProvider() {
+//		return bytecodeProvider;
+//	}
+//
+//	void setBytecodeProvider(BytecodeProvider bytecodeProvider) {
+//		this.bytecodeProvider = bytecodeProvider;
+//	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,440 +0,0 @@
-//$Id: SettingsFactory.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.cfg;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.bytecode.BytecodeProvider;
-import org.hibernate.cache.QueryCacheFactory;
-import org.hibernate.cache.RegionFactory;
-import org.hibernate.cache.impl.NoCachingRegionFactory;
-import org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge;
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.connection.ConnectionProviderFactory;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.DialectFactory;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.exception.SQLExceptionConverterFactory;
-import org.hibernate.hql.QueryTranslatorFactory;
-import org.hibernate.jdbc.BatcherFactory;
-import org.hibernate.jdbc.BatchingBatcherFactory;
-import org.hibernate.jdbc.NonBatchingBatcherFactory;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.transaction.TransactionFactoryFactory;
-import org.hibernate.transaction.TransactionManagerLookup;
-import org.hibernate.transaction.TransactionManagerLookupFactory;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Reads configuration properties and configures a <tt>Settings</tt> instance.
- *
- * @author Gavin King
- */
-public class SettingsFactory implements Serializable {
-
-	public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
-	private static final Logger log = LoggerFactory.getLogger(SettingsFactory.class);
-
-	protected SettingsFactory() {
-	}
-	
-	public Settings buildSettings(Properties props) {
-		Settings settings = new Settings();
-		
-		//SessionFactory name:
-		
-		String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
-		settings.setSessionFactoryName(sessionFactoryName);
-
-		//JDBC and connection settings:
-
-		ConnectionProvider connections = createConnectionProvider(props);
-		settings.setConnectionProvider(connections);
-
-		//Interrogate JDBC metadata
-
-		String databaseName = null;
-		int databaseMajorVersion = 0;
-		boolean metaSupportsScrollable = false;
-		boolean metaSupportsGetGeneratedKeys = false;
-		boolean metaSupportsBatchUpdates = false;
-		boolean metaReportsDDLCausesTxnCommit = false;
-		boolean metaReportsDDLInTxnSupported = true;
-
-		// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
-		// The need for it is intended to be alleviated with 3.3 developement, thus it is
-		// not defined as an Environment constant...
-		// it is used to control whether we should consult the JDBC metadata to determine
-		// certain Settings default values; it is useful to *not* do this when the database
-		// may not be available (mainly in tools usage).
-		boolean useJdbcMetadata = PropertiesHelper.getBoolean( "hibernate.temp.use_jdbc_metadata_defaults", props, true );
-		if ( useJdbcMetadata ) {
-			try {
-				Connection conn = connections.getConnection();
-				try {
-					DatabaseMetaData meta = conn.getMetaData();
-					databaseName = meta.getDatabaseProductName();
-					databaseMajorVersion = getDatabaseMajorVersion(meta);
-					log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() );
-					log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
-
-					metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
-					metaSupportsBatchUpdates = meta.supportsBatchUpdates();
-					metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
-					metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
-
-					if ( Environment.jvmSupportsGetGeneratedKeys() ) {
-						try {
-							Boolean result = (Boolean) DatabaseMetaData.class.getMethod("supportsGetGeneratedKeys", null)
-								.invoke(meta, null);
-							metaSupportsGetGeneratedKeys = result.booleanValue();
-						}
-						catch (AbstractMethodError ame) {
-							metaSupportsGetGeneratedKeys = false;
-						}
-						catch (Exception e) {
-							metaSupportsGetGeneratedKeys = false;
-						}
-					}
-
-				}
-				finally {
-					connections.closeConnection(conn);
-				}
-			}
-			catch (SQLException sqle) {
-				log.warn("Could not obtain connection metadata", sqle);
-			}
-			catch (UnsupportedOperationException uoe) {
-				// user supplied JDBC connections
-			}
-		}
-		settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
-		settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
-
-
-		//SQL Dialect:
-		Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
-		settings.setDialect(dialect);
-		
-		//use dialect default properties
-		final Properties properties = new Properties();
-		properties.putAll( dialect.getDefaultProperties() );
-		properties.putAll(props);
-		
-		// Transaction settings:
-		
-		TransactionFactory transactionFactory = createTransactionFactory(properties);
-		settings.setTransactionFactory(transactionFactory);
-		settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
-
-		boolean flushBeforeCompletion = PropertiesHelper.getBoolean(Environment.FLUSH_BEFORE_COMPLETION, properties);
-		log.info("Automatic flush during beforeCompletion(): " + enabledDisabled(flushBeforeCompletion) );
-		settings.setFlushBeforeCompletionEnabled(flushBeforeCompletion);
-
-		boolean autoCloseSession = PropertiesHelper.getBoolean(Environment.AUTO_CLOSE_SESSION, properties);
-		log.info("Automatic session close at end of transaction: " + enabledDisabled(autoCloseSession) );
-		settings.setAutoCloseSessionEnabled(autoCloseSession);
-
-		//JDBC and connection settings:
-
-		int batchSize = PropertiesHelper.getInt(Environment.STATEMENT_BATCH_SIZE, properties, 0);
-		if ( !metaSupportsBatchUpdates ) batchSize = 0;
-		if (batchSize>0) log.info("JDBC batch size: " + batchSize);
-		settings.setJdbcBatchSize(batchSize);
-		boolean jdbcBatchVersionedData = PropertiesHelper.getBoolean(Environment.BATCH_VERSIONED_DATA, properties, false);
-		if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
-		settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
-		settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
-		
-		boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable);
-		log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
-		settings.setScrollableResultSetsEnabled(useScrollableResultSets);
-
-		boolean wrapResultSets = PropertiesHelper.getBoolean(Environment.WRAP_RESULT_SETS, properties, false);
-		log.debug( "Wrap result sets: " + enabledDisabled(wrapResultSets) );
-		settings.setWrapResultSetsEnabled(wrapResultSets);
-
-		boolean useGetGeneratedKeys = PropertiesHelper.getBoolean(Environment.USE_GET_GENERATED_KEYS, properties, metaSupportsGetGeneratedKeys);
-		log.info("JDBC3 getGeneratedKeys(): " + enabledDisabled(useGetGeneratedKeys) );
-		settings.setGetGeneratedKeysEnabled(useGetGeneratedKeys);
-
-		Integer statementFetchSize = PropertiesHelper.getInteger(Environment.STATEMENT_FETCH_SIZE, properties);
-		if (statementFetchSize!=null) log.info("JDBC result set fetch size: " + statementFetchSize);
-		settings.setJdbcFetchSize(statementFetchSize);
-
-		String releaseModeName = PropertiesHelper.getString( Environment.RELEASE_CONNECTIONS, properties, "auto" );
-		log.info( "Connection release mode: " + releaseModeName );
-		ConnectionReleaseMode releaseMode;
-		if ( "auto".equals(releaseModeName) ) {
-			releaseMode = transactionFactory.getDefaultReleaseMode();
-		}
-		else {
-			releaseMode = ConnectionReleaseMode.parse( releaseModeName );
-			if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT && !connections.supportsAggressiveRelease() ) {
-				log.warn( "Overriding release mode as connection provider does not support 'after_statement'" );
-				releaseMode = ConnectionReleaseMode.AFTER_TRANSACTION;
-			}
-		}
-		settings.setConnectionReleaseMode( releaseMode );
-
-		//SQL Generation settings:
-
-		String defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
-		String defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
-		if (defaultSchema!=null) log.info("Default schema: " + defaultSchema);
-		if (defaultCatalog!=null) log.info("Default catalog: " + defaultCatalog);
-		settings.setDefaultSchemaName(defaultSchema);
-		settings.setDefaultCatalogName(defaultCatalog);
-
-		Integer maxFetchDepth = PropertiesHelper.getInteger(Environment.MAX_FETCH_DEPTH, properties);
-		if (maxFetchDepth!=null) log.info("Maximum outer join fetch depth: " + maxFetchDepth);
-		settings.setMaximumFetchDepth(maxFetchDepth);
-		int batchFetchSize = PropertiesHelper.getInt(Environment.DEFAULT_BATCH_FETCH_SIZE, properties, 1);
-		log.info("Default batch fetch size: " + batchFetchSize);
-		settings.setDefaultBatchFetchSize(batchFetchSize);
-
-		boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties);
-		log.info( "Generate SQL with comments: " + enabledDisabled(comments) );
-		settings.setCommentsEnabled(comments);
-		
-		boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties);
-		log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) );
-		settings.setOrderUpdatesEnabled(orderUpdates);
-
-		boolean orderInserts = PropertiesHelper.getBoolean(Environment.ORDER_INSERTS, properties);
-		log.info( "Order SQL inserts for batching: " + enabledDisabled( orderInserts ) );
-		settings.setOrderInsertsEnabled( orderInserts );
-		
-		//Query parser settings:
-		
-		settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
-
-		Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties);
-		log.info("Query language substitutions: " + querySubstitutions);
-		settings.setQuerySubstitutions(querySubstitutions);
-
-		boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false );
-		settings.setStrictJPAQLCompliance( jpaqlCompliance );
-		log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) );
-		
-		// Second-level / query cache:
-
-		boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true);
-		log.info( "Second-level cache: " + enabledDisabled(useSecondLevelCache) );
-		settings.setSecondLevelCacheEnabled(useSecondLevelCache);
-
-		boolean useQueryCache = PropertiesHelper.getBoolean(Environment.USE_QUERY_CACHE, properties);
-		log.info( "Query cache: " + enabledDisabled(useQueryCache) );
-		settings.setQueryCacheEnabled(useQueryCache);
-
-		// The cache provider is needed when we either have second-level cache enabled
-		// or query cache enabled.  Note that useSecondLevelCache is enabled by default
-		settings.setRegionFactory( createRegionFactory( properties, ( useSecondLevelCache || useQueryCache ) ) );
-
-		boolean useMinimalPuts = PropertiesHelper.getBoolean(
-				Environment.USE_MINIMAL_PUTS, properties, settings.getRegionFactory().isMinimalPutsEnabledByDefault()
-		);
-		log.info( "Optimize cache for minimal puts: " + enabledDisabled(useMinimalPuts) );
-		settings.setMinimalPutsEnabled(useMinimalPuts);
-
-		String prefix = properties.getProperty(Environment.CACHE_REGION_PREFIX);
-		if ( StringHelper.isEmpty(prefix) ) prefix=null;
-		if (prefix!=null) log.info("Cache region prefix: "+ prefix);
-		settings.setCacheRegionPrefix(prefix);
-
-		boolean useStructuredCacheEntries = PropertiesHelper.getBoolean(Environment.USE_STRUCTURED_CACHE, properties, false);
-		log.info( "Structured second-level cache entries: " + enabledDisabled(useStructuredCacheEntries) );
-		settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
-
-		if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
-		
-		//SQL Exception converter:
-		
-		SQLExceptionConverter sqlExceptionConverter;
-		try {
-			sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
-		}
-		catch(HibernateException e) {
-			log.warn("Error building SQLExceptionConverter; using minimal converter");
-			sqlExceptionConverter = SQLExceptionConverterFactory.buildMinimalSQLExceptionConverter();
-		}
-		settings.setSQLExceptionConverter(sqlExceptionConverter);
-
-		//Statistics and logging:
-
-		boolean showSql = PropertiesHelper.getBoolean(Environment.SHOW_SQL, properties);
-		if (showSql) log.info("Echoing all SQL to stdout");
-//		settings.setShowSqlEnabled(showSql);
-
-		boolean formatSql = PropertiesHelper.getBoolean(Environment.FORMAT_SQL, properties);
-//		settings.setFormatSqlEnabled(formatSql);
-
-		settings.setSqlStatementLogger( new SQLStatementLogger( showSql, formatSql ) );
-
-		boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
-		log.info( "Statistics: " + enabledDisabled(useStatistics) );
-		settings.setStatisticsEnabled(useStatistics);
-		
-		boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties);
-		log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) );
-		settings.setIdentifierRollbackEnabled(useIdentifierRollback);
-		
-		//Schema export:
-		
-		String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO);
-		if ( "validate".equals(autoSchemaExport) ) settings.setAutoValidateSchema(true);
-		if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true);
-		if ( "create".equals(autoSchemaExport) ) settings.setAutoCreateSchema(true);
-		if ( "create-drop".equals(autoSchemaExport) ) {
-			settings.setAutoCreateSchema(true);
-			settings.setAutoDropSchema(true);
-		}
-
-		EntityMode defaultEntityMode = EntityMode.parse( properties.getProperty( Environment.DEFAULT_ENTITY_MODE ) );
-		log.info( "Default entity-mode: " + defaultEntityMode );
-		settings.setDefaultEntityMode( defaultEntityMode );
-
-		boolean namedQueryChecking = PropertiesHelper.getBoolean( Environment.QUERY_STARTUP_CHECKING, properties, true );
-		log.info( "Named query checking : " + enabledDisabled( namedQueryChecking ) );
-		settings.setNamedQueryStartupCheckingEnabled( namedQueryChecking );
-
-//		String provider = properties.getProperty( Environment.BYTECODE_PROVIDER );
-//		log.info( "Bytecode provider name : " + provider );
-//		BytecodeProvider bytecodeProvider = buildBytecodeProvider( provider );
-//		settings.setBytecodeProvider( bytecodeProvider );
-
-		return settings;
-
-	}
-
-	protected BytecodeProvider buildBytecodeProvider(String providerName) {
-		if ( "javassist".equals( providerName ) ) {
-			return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
-		}
-		else if ( "cglib".equals( providerName ) ) {
-			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
-		}
-		else {
-			log.debug( "using cglib as bytecode provider by default" );
-			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
-		}
-	}
-
-	private int getDatabaseMajorVersion(DatabaseMetaData meta) {
-		try {
-			Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", null);
-			return ( (Integer) gdbmvMethod.invoke(meta, null) ).intValue();
-		}
-		catch (NoSuchMethodException nsme) {
-			return 0;
-		}
-		catch (Throwable t) {
-			log.debug("could not get database version from JDBC metadata");
-			return 0;
-		}
-	}
-
-	private static String enabledDisabled(boolean value) {
-		return value ? "enabled" : "disabled";
-	}
-	
-	protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
-		String queryCacheFactoryClassName = PropertiesHelper.getString(
-				Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory"
-		);
-		log.info("Query cache factory: " + queryCacheFactoryClassName);
-		try {
-			return (QueryCacheFactory) ReflectHelper.classForName(queryCacheFactoryClassName).newInstance();
-		}
-		catch (Exception cnfe) {
-			throw new HibernateException("could not instantiate QueryCacheFactory: " + queryCacheFactoryClassName, cnfe);
-		}
-	}
-
-	protected RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
-		String regionFactoryClassName = PropertiesHelper.getString( Environment.CACHE_REGION_FACTORY, properties, null );
-		if ( regionFactoryClassName == null && cachingEnabled ) {
-			String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, null );
-			if ( providerClassName != null ) {
-				// legacy behavior, apply the bridge...
-				regionFactoryClassName = RegionFactoryCacheProviderBridge.class.getName();
-			}
-		}
-		if ( regionFactoryClassName == null ) {
-			regionFactoryClassName = DEF_CACHE_REG_FACTORY;
-		}
-		log.info( "Cache region factory : " + regionFactoryClassName );
-		try {
-			return ( RegionFactory ) ReflectHelper.classForName( regionFactoryClassName )
-					.getConstructor( new Class[] { Properties.class } )
-					.newInstance( new Object[] { properties } );
-		}
-		catch ( Exception e ) {
-			throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
-		}
-	}
-	
-	protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
-		String className = PropertiesHelper.getString(
-				Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory"
-		);
-		log.info("Query translator: " + className);
-		try {
-			return (QueryTranslatorFactory) ReflectHelper.classForName(className).newInstance();
-		}
-		catch (Exception cnfe) {
-			throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
-		}
-	}
-	
-	protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
-		String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
-		if (batcherClass==null) {
-			return batchSize==0 ?
-					(BatcherFactory) new NonBatchingBatcherFactory() :
-					(BatcherFactory) new BatchingBatcherFactory();
-		}
-		else {
-			log.info("Batcher factory: " + batcherClass);
-			try {
-				return (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance();
-			}
-			catch (Exception cnfe) {
-				throw new HibernateException("could not instantiate BatcherFactory: " + batcherClass, cnfe);
-			}
-		}
-	}
-	
-	protected ConnectionProvider createConnectionProvider(Properties properties) {
-		return ConnectionProviderFactory.newConnectionProvider(properties);
-	}
-	
-	protected TransactionFactory createTransactionFactory(Properties properties) {
-		return TransactionFactoryFactory.buildTransactionFactory(properties);
-	}
-	
-	protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
-		return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);		
-	}
-
-	private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
-		return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/SettingsFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/SettingsFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,463 @@
+/*
+ * 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.cfg;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.bytecode.BytecodeProvider;
+import org.hibernate.cache.QueryCacheFactory;
+import org.hibernate.cache.RegionFactory;
+import org.hibernate.cache.impl.NoCachingRegionFactory;
+import org.hibernate.cache.impl.bridge.RegionFactoryCacheProviderBridge;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.connection.ConnectionProviderFactory;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.DialectFactory;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.exception.SQLExceptionConverterFactory;
+import org.hibernate.hql.QueryTranslatorFactory;
+import org.hibernate.jdbc.BatcherFactory;
+import org.hibernate.jdbc.BatchingBatcherFactory;
+import org.hibernate.jdbc.NonBatchingBatcherFactory;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.transaction.TransactionFactoryFactory;
+import org.hibernate.transaction.TransactionManagerLookup;
+import org.hibernate.transaction.TransactionManagerLookupFactory;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Reads configuration properties and configures a <tt>Settings</tt> instance.
+ *
+ * @author Gavin King
+ */
+public class SettingsFactory implements Serializable {
+
+	public static final String DEF_CACHE_REG_FACTORY = NoCachingRegionFactory.class.getName();
+	private static final Logger log = LoggerFactory.getLogger(SettingsFactory.class);
+
+	protected SettingsFactory() {
+	}
+	
+	public Settings buildSettings(Properties props) {
+		Settings settings = new Settings();
+		
+		//SessionFactory name:
+		
+		String sessionFactoryName = props.getProperty(Environment.SESSION_FACTORY_NAME);
+		settings.setSessionFactoryName(sessionFactoryName);
+
+		//JDBC and connection settings:
+
+		ConnectionProvider connections = createConnectionProvider(props);
+		settings.setConnectionProvider(connections);
+
+		//Interrogate JDBC metadata
+
+		String databaseName = null;
+		int databaseMajorVersion = 0;
+		boolean metaSupportsScrollable = false;
+		boolean metaSupportsGetGeneratedKeys = false;
+		boolean metaSupportsBatchUpdates = false;
+		boolean metaReportsDDLCausesTxnCommit = false;
+		boolean metaReportsDDLInTxnSupported = true;
+
+		// 'hibernate.temp.use_jdbc_metadata_defaults' is a temporary magic value.
+		// The need for it is intended to be alleviated with 3.3 developement, thus it is
+		// not defined as an Environment constant...
+		// it is used to control whether we should consult the JDBC metadata to determine
+		// certain Settings default values; it is useful to *not* do this when the database
+		// may not be available (mainly in tools usage).
+		boolean useJdbcMetadata = PropertiesHelper.getBoolean( "hibernate.temp.use_jdbc_metadata_defaults", props, true );
+		if ( useJdbcMetadata ) {
+			try {
+				Connection conn = connections.getConnection();
+				try {
+					DatabaseMetaData meta = conn.getMetaData();
+					databaseName = meta.getDatabaseProductName();
+					databaseMajorVersion = getDatabaseMajorVersion(meta);
+					log.info("RDBMS: " + databaseName + ", version: " + meta.getDatabaseProductVersion() );
+					log.info("JDBC driver: " + meta.getDriverName() + ", version: " + meta.getDriverVersion() );
+
+					metaSupportsScrollable = meta.supportsResultSetType(ResultSet.TYPE_SCROLL_INSENSITIVE);
+					metaSupportsBatchUpdates = meta.supportsBatchUpdates();
+					metaReportsDDLCausesTxnCommit = meta.dataDefinitionCausesTransactionCommit();
+					metaReportsDDLInTxnSupported = !meta.dataDefinitionIgnoredInTransactions();
+
+					if ( Environment.jvmSupportsGetGeneratedKeys() ) {
+						try {
+							Boolean result = (Boolean) DatabaseMetaData.class.getMethod("supportsGetGeneratedKeys", null)
+								.invoke(meta, null);
+							metaSupportsGetGeneratedKeys = result.booleanValue();
+						}
+						catch (AbstractMethodError ame) {
+							metaSupportsGetGeneratedKeys = false;
+						}
+						catch (Exception e) {
+							metaSupportsGetGeneratedKeys = false;
+						}
+					}
+
+				}
+				finally {
+					connections.closeConnection(conn);
+				}
+			}
+			catch (SQLException sqle) {
+				log.warn("Could not obtain connection metadata", sqle);
+			}
+			catch (UnsupportedOperationException uoe) {
+				// user supplied JDBC connections
+			}
+		}
+		settings.setDataDefinitionImplicitCommit( metaReportsDDLCausesTxnCommit );
+		settings.setDataDefinitionInTransactionSupported( metaReportsDDLInTxnSupported );
+
+
+		//SQL Dialect:
+		Dialect dialect = determineDialect( props, databaseName, databaseMajorVersion );
+		settings.setDialect(dialect);
+		
+		//use dialect default properties
+		final Properties properties = new Properties();
+		properties.putAll( dialect.getDefaultProperties() );
+		properties.putAll(props);
+		
+		// Transaction settings:
+		
+		TransactionFactory transactionFactory = createTransactionFactory(properties);
+		settings.setTransactionFactory(transactionFactory);
+		settings.setTransactionManagerLookup( createTransactionManagerLookup(properties) );
+
+		boolean flushBeforeCompletion = PropertiesHelper.getBoolean(Environment.FLUSH_BEFORE_COMPLETION, properties);
+		log.info("Automatic flush during beforeCompletion(): " + enabledDisabled(flushBeforeCompletion) );
+		settings.setFlushBeforeCompletionEnabled(flushBeforeCompletion);
+
+		boolean autoCloseSession = PropertiesHelper.getBoolean(Environment.AUTO_CLOSE_SESSION, properties);
+		log.info("Automatic session close at end of transaction: " + enabledDisabled(autoCloseSession) );
+		settings.setAutoCloseSessionEnabled(autoCloseSession);
+
+		//JDBC and connection settings:
+
+		int batchSize = PropertiesHelper.getInt(Environment.STATEMENT_BATCH_SIZE, properties, 0);
+		if ( !metaSupportsBatchUpdates ) batchSize = 0;
+		if (batchSize>0) log.info("JDBC batch size: " + batchSize);
+		settings.setJdbcBatchSize(batchSize);
+		boolean jdbcBatchVersionedData = PropertiesHelper.getBoolean(Environment.BATCH_VERSIONED_DATA, properties, false);
+		if (batchSize>0) log.info("JDBC batch updates for versioned data: " + enabledDisabled(jdbcBatchVersionedData) );
+		settings.setJdbcBatchVersionedData(jdbcBatchVersionedData);
+		settings.setBatcherFactory( createBatcherFactory(properties, batchSize) );
+		
+		boolean useScrollableResultSets = PropertiesHelper.getBoolean(Environment.USE_SCROLLABLE_RESULTSET, properties, metaSupportsScrollable);
+		log.info("Scrollable result sets: " + enabledDisabled(useScrollableResultSets) );
+		settings.setScrollableResultSetsEnabled(useScrollableResultSets);
+
+		boolean wrapResultSets = PropertiesHelper.getBoolean(Environment.WRAP_RESULT_SETS, properties, false);
+		log.debug( "Wrap result sets: " + enabledDisabled(wrapResultSets) );
+		settings.setWrapResultSetsEnabled(wrapResultSets);
+
+		boolean useGetGeneratedKeys = PropertiesHelper.getBoolean(Environment.USE_GET_GENERATED_KEYS, properties, metaSupportsGetGeneratedKeys);
+		log.info("JDBC3 getGeneratedKeys(): " + enabledDisabled(useGetGeneratedKeys) );
+		settings.setGetGeneratedKeysEnabled(useGetGeneratedKeys);
+
+		Integer statementFetchSize = PropertiesHelper.getInteger(Environment.STATEMENT_FETCH_SIZE, properties);
+		if (statementFetchSize!=null) log.info("JDBC result set fetch size: " + statementFetchSize);
+		settings.setJdbcFetchSize(statementFetchSize);
+
+		String releaseModeName = PropertiesHelper.getString( Environment.RELEASE_CONNECTIONS, properties, "auto" );
+		log.info( "Connection release mode: " + releaseModeName );
+		ConnectionReleaseMode releaseMode;
+		if ( "auto".equals(releaseModeName) ) {
+			releaseMode = transactionFactory.getDefaultReleaseMode();
+		}
+		else {
+			releaseMode = ConnectionReleaseMode.parse( releaseModeName );
+			if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT && !connections.supportsAggressiveRelease() ) {
+				log.warn( "Overriding release mode as connection provider does not support 'after_statement'" );
+				releaseMode = ConnectionReleaseMode.AFTER_TRANSACTION;
+			}
+		}
+		settings.setConnectionReleaseMode( releaseMode );
+
+		//SQL Generation settings:
+
+		String defaultSchema = properties.getProperty(Environment.DEFAULT_SCHEMA);
+		String defaultCatalog = properties.getProperty(Environment.DEFAULT_CATALOG);
+		if (defaultSchema!=null) log.info("Default schema: " + defaultSchema);
+		if (defaultCatalog!=null) log.info("Default catalog: " + defaultCatalog);
+		settings.setDefaultSchemaName(defaultSchema);
+		settings.setDefaultCatalogName(defaultCatalog);
+
+		Integer maxFetchDepth = PropertiesHelper.getInteger(Environment.MAX_FETCH_DEPTH, properties);
+		if (maxFetchDepth!=null) log.info("Maximum outer join fetch depth: " + maxFetchDepth);
+		settings.setMaximumFetchDepth(maxFetchDepth);
+		int batchFetchSize = PropertiesHelper.getInt(Environment.DEFAULT_BATCH_FETCH_SIZE, properties, 1);
+		log.info("Default batch fetch size: " + batchFetchSize);
+		settings.setDefaultBatchFetchSize(batchFetchSize);
+
+		boolean comments = PropertiesHelper.getBoolean(Environment.USE_SQL_COMMENTS, properties);
+		log.info( "Generate SQL with comments: " + enabledDisabled(comments) );
+		settings.setCommentsEnabled(comments);
+		
+		boolean orderUpdates = PropertiesHelper.getBoolean(Environment.ORDER_UPDATES, properties);
+		log.info( "Order SQL updates by primary key: " + enabledDisabled(orderUpdates) );
+		settings.setOrderUpdatesEnabled(orderUpdates);
+
+		boolean orderInserts = PropertiesHelper.getBoolean(Environment.ORDER_INSERTS, properties);
+		log.info( "Order SQL inserts for batching: " + enabledDisabled( orderInserts ) );
+		settings.setOrderInsertsEnabled( orderInserts );
+		
+		//Query parser settings:
+		
+		settings.setQueryTranslatorFactory( createQueryTranslatorFactory(properties) );
+
+		Map querySubstitutions = PropertiesHelper.toMap(Environment.QUERY_SUBSTITUTIONS, " ,=;:\n\t\r\f", properties);
+		log.info("Query language substitutions: " + querySubstitutions);
+		settings.setQuerySubstitutions(querySubstitutions);
+
+		boolean jpaqlCompliance = PropertiesHelper.getBoolean( Environment.JPAQL_STRICT_COMPLIANCE, properties, false );
+		settings.setStrictJPAQLCompliance( jpaqlCompliance );
+		log.info( "JPA-QL strict compliance: " + enabledDisabled( jpaqlCompliance ) );
+		
+		// Second-level / query cache:
+
+		boolean useSecondLevelCache = PropertiesHelper.getBoolean(Environment.USE_SECOND_LEVEL_CACHE, properties, true);
+		log.info( "Second-level cache: " + enabledDisabled(useSecondLevelCache) );
+		settings.setSecondLevelCacheEnabled(useSecondLevelCache);
+
+		boolean useQueryCache = PropertiesHelper.getBoolean(Environment.USE_QUERY_CACHE, properties);
+		log.info( "Query cache: " + enabledDisabled(useQueryCache) );
+		settings.setQueryCacheEnabled(useQueryCache);
+
+		// The cache provider is needed when we either have second-level cache enabled
+		// or query cache enabled.  Note that useSecondLevelCache is enabled by default
+		settings.setRegionFactory( createRegionFactory( properties, ( useSecondLevelCache || useQueryCache ) ) );
+
+		boolean useMinimalPuts = PropertiesHelper.getBoolean(
+				Environment.USE_MINIMAL_PUTS, properties, settings.getRegionFactory().isMinimalPutsEnabledByDefault()
+		);
+		log.info( "Optimize cache for minimal puts: " + enabledDisabled(useMinimalPuts) );
+		settings.setMinimalPutsEnabled(useMinimalPuts);
+
+		String prefix = properties.getProperty(Environment.CACHE_REGION_PREFIX);
+		if ( StringHelper.isEmpty(prefix) ) prefix=null;
+		if (prefix!=null) log.info("Cache region prefix: "+ prefix);
+		settings.setCacheRegionPrefix(prefix);
+
+		boolean useStructuredCacheEntries = PropertiesHelper.getBoolean(Environment.USE_STRUCTURED_CACHE, properties, false);
+		log.info( "Structured second-level cache entries: " + enabledDisabled(useStructuredCacheEntries) );
+		settings.setStructuredCacheEntriesEnabled(useStructuredCacheEntries);
+
+		if (useQueryCache) settings.setQueryCacheFactory( createQueryCacheFactory(properties) );
+		
+		//SQL Exception converter:
+		
+		SQLExceptionConverter sqlExceptionConverter;
+		try {
+			sqlExceptionConverter = SQLExceptionConverterFactory.buildSQLExceptionConverter( dialect, properties );
+		}
+		catch(HibernateException e) {
+			log.warn("Error building SQLExceptionConverter; using minimal converter");
+			sqlExceptionConverter = SQLExceptionConverterFactory.buildMinimalSQLExceptionConverter();
+		}
+		settings.setSQLExceptionConverter(sqlExceptionConverter);
+
+		//Statistics and logging:
+
+		boolean showSql = PropertiesHelper.getBoolean(Environment.SHOW_SQL, properties);
+		if (showSql) log.info("Echoing all SQL to stdout");
+//		settings.setShowSqlEnabled(showSql);
+
+		boolean formatSql = PropertiesHelper.getBoolean(Environment.FORMAT_SQL, properties);
+//		settings.setFormatSqlEnabled(formatSql);
+
+		settings.setSqlStatementLogger( new SQLStatementLogger( showSql, formatSql ) );
+
+		boolean useStatistics = PropertiesHelper.getBoolean(Environment.GENERATE_STATISTICS, properties);
+		log.info( "Statistics: " + enabledDisabled(useStatistics) );
+		settings.setStatisticsEnabled(useStatistics);
+		
+		boolean useIdentifierRollback = PropertiesHelper.getBoolean(Environment.USE_IDENTIFIER_ROLLBACK, properties);
+		log.info( "Deleted entity synthetic identifier rollback: " + enabledDisabled(useIdentifierRollback) );
+		settings.setIdentifierRollbackEnabled(useIdentifierRollback);
+		
+		//Schema export:
+		
+		String autoSchemaExport = properties.getProperty(Environment.HBM2DDL_AUTO);
+		if ( "validate".equals(autoSchemaExport) ) settings.setAutoValidateSchema(true);
+		if ( "update".equals(autoSchemaExport) ) settings.setAutoUpdateSchema(true);
+		if ( "create".equals(autoSchemaExport) ) settings.setAutoCreateSchema(true);
+		if ( "create-drop".equals(autoSchemaExport) ) {
+			settings.setAutoCreateSchema(true);
+			settings.setAutoDropSchema(true);
+		}
+
+		EntityMode defaultEntityMode = EntityMode.parse( properties.getProperty( Environment.DEFAULT_ENTITY_MODE ) );
+		log.info( "Default entity-mode: " + defaultEntityMode );
+		settings.setDefaultEntityMode( defaultEntityMode );
+
+		boolean namedQueryChecking = PropertiesHelper.getBoolean( Environment.QUERY_STARTUP_CHECKING, properties, true );
+		log.info( "Named query checking : " + enabledDisabled( namedQueryChecking ) );
+		settings.setNamedQueryStartupCheckingEnabled( namedQueryChecking );
+
+//		String provider = properties.getProperty( Environment.BYTECODE_PROVIDER );
+//		log.info( "Bytecode provider name : " + provider );
+//		BytecodeProvider bytecodeProvider = buildBytecodeProvider( provider );
+//		settings.setBytecodeProvider( bytecodeProvider );
+
+		return settings;
+
+	}
+
+	protected BytecodeProvider buildBytecodeProvider(String providerName) {
+		if ( "javassist".equals( providerName ) ) {
+			return new org.hibernate.bytecode.javassist.BytecodeProviderImpl();
+		}
+		else if ( "cglib".equals( providerName ) ) {
+			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
+		}
+		else {
+			log.debug( "using cglib as bytecode provider by default" );
+			return new org.hibernate.bytecode.cglib.BytecodeProviderImpl();
+		}
+	}
+
+	private int getDatabaseMajorVersion(DatabaseMetaData meta) {
+		try {
+			Method gdbmvMethod = DatabaseMetaData.class.getMethod("getDatabaseMajorVersion", null);
+			return ( (Integer) gdbmvMethod.invoke(meta, null) ).intValue();
+		}
+		catch (NoSuchMethodException nsme) {
+			return 0;
+		}
+		catch (Throwable t) {
+			log.debug("could not get database version from JDBC metadata");
+			return 0;
+		}
+	}
+
+	private static String enabledDisabled(boolean value) {
+		return value ? "enabled" : "disabled";
+	}
+	
+	protected QueryCacheFactory createQueryCacheFactory(Properties properties) {
+		String queryCacheFactoryClassName = PropertiesHelper.getString(
+				Environment.QUERY_CACHE_FACTORY, properties, "org.hibernate.cache.StandardQueryCacheFactory"
+		);
+		log.info("Query cache factory: " + queryCacheFactoryClassName);
+		try {
+			return (QueryCacheFactory) ReflectHelper.classForName(queryCacheFactoryClassName).newInstance();
+		}
+		catch (Exception cnfe) {
+			throw new HibernateException("could not instantiate QueryCacheFactory: " + queryCacheFactoryClassName, cnfe);
+		}
+	}
+
+	protected RegionFactory createRegionFactory(Properties properties, boolean cachingEnabled) {
+		String regionFactoryClassName = PropertiesHelper.getString( Environment.CACHE_REGION_FACTORY, properties, null );
+		if ( regionFactoryClassName == null && cachingEnabled ) {
+			String providerClassName = PropertiesHelper.getString( Environment.CACHE_PROVIDER, properties, null );
+			if ( providerClassName != null ) {
+				// legacy behavior, apply the bridge...
+				regionFactoryClassName = RegionFactoryCacheProviderBridge.class.getName();
+			}
+		}
+		if ( regionFactoryClassName == null ) {
+			regionFactoryClassName = DEF_CACHE_REG_FACTORY;
+		}
+		log.info( "Cache region factory : " + regionFactoryClassName );
+		try {
+			return ( RegionFactory ) ReflectHelper.classForName( regionFactoryClassName )
+					.getConstructor( new Class[] { Properties.class } )
+					.newInstance( new Object[] { properties } );
+		}
+		catch ( Exception e ) {
+			throw new HibernateException( "could not instantiate RegionFactory [" + regionFactoryClassName + "]", e );
+		}
+	}
+	
+	protected QueryTranslatorFactory createQueryTranslatorFactory(Properties properties) {
+		String className = PropertiesHelper.getString(
+				Environment.QUERY_TRANSLATOR, properties, "org.hibernate.hql.ast.ASTQueryTranslatorFactory"
+		);
+		log.info("Query translator: " + className);
+		try {
+			return (QueryTranslatorFactory) ReflectHelper.classForName(className).newInstance();
+		}
+		catch (Exception cnfe) {
+			throw new HibernateException("could not instantiate QueryTranslatorFactory: " + className, cnfe);
+		}
+	}
+	
+	protected BatcherFactory createBatcherFactory(Properties properties, int batchSize) {
+		String batcherClass = properties.getProperty(Environment.BATCH_STRATEGY);
+		if (batcherClass==null) {
+			return batchSize==0 ?
+					(BatcherFactory) new NonBatchingBatcherFactory() :
+					(BatcherFactory) new BatchingBatcherFactory();
+		}
+		else {
+			log.info("Batcher factory: " + batcherClass);
+			try {
+				return (BatcherFactory) ReflectHelper.classForName(batcherClass).newInstance();
+			}
+			catch (Exception cnfe) {
+				throw new HibernateException("could not instantiate BatcherFactory: " + batcherClass, cnfe);
+			}
+		}
+	}
+	
+	protected ConnectionProvider createConnectionProvider(Properties properties) {
+		return ConnectionProviderFactory.newConnectionProvider(properties);
+	}
+	
+	protected TransactionFactory createTransactionFactory(Properties properties) {
+		return TransactionFactoryFactory.buildTransactionFactory(properties);
+	}
+	
+	protected TransactionManagerLookup createTransactionManagerLookup(Properties properties) {
+		return TransactionManagerLookupFactory.getTransactionManagerLookup(properties);		
+	}
+
+	private Dialect determineDialect(Properties props, String databaseName, int databaseMajorVersion) {
+		return DialectFactory.buildDialect( props, databaseName, databaseMajorVersion );
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/cfg/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines APIs for configuring Hibernate, and classes
-	for building the Hibernate configuration-time metamodel.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/cfg/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/cfg/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines APIs for configuring Hibernate, and classes
+	for building the Hibernate configuration-time metamodel.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/classic/Lifecycle.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-//$Id: Lifecycle.java 7566 2005-07-20 07:16:33Z oneovthafew $
-package org.hibernate.classic;
-
-import java.io.Serializable;
-
-import org.hibernate.CallbackException;
-import org.hibernate.Session;
-
-/**
- * Provides callbacks from the <tt>Session</tt> to the persistent object.
- * Persistent classes <b>may</b> implement this interface but they are not
- * required to.<br>
- * <br>
- * <b>onSave:</b> called just before the object is saved<br>
- * <b>onUpdate:</b> called just before an object is updated,
- * ie. when <tt>Session.update()</tt> is called<br>
- * <b>onDelete:</b> called just before an object is deleted<br>
- * <b>onLoad:</b> called just after an object is loaded<br>
- * <br>
- * <tt>onLoad()</tt> may be used to initialize transient properties of the
- * object from its persistent state. It may <b>not</b> be used to load
- * dependent objects since the <tt>Session</tt> interface may not be
- * invoked from inside this method.<br>
- * <br>
- * A further intended usage of <tt>onLoad()</tt>, <tt>onSave()</tt> and
- * <tt>onUpdate()</tt> is to store a reference to the <tt>Session</tt>
- * for later use.<br>
- * <br>
- * If <tt>onSave()</tt>, <tt>onUpdate()</tt> or <tt>onDelete()</tt> return
- * <tt>VETO</tt>, the operation is silently vetoed. If a
- * <tt>CallbackException</tt> is thrown, the operation is vetoed and the
- * exception is passed back to the application.<br>
- * <br>
- * Note that <tt>onSave()</tt> is called after an identifier is assigned
- * to the object, except when identity column key generation is used.
- *
- * @see CallbackException
- * @author Gavin King
- */
-public interface Lifecycle {
-
-	/**
-	 * Return value to veto the action (true)
-	 */
-	public static final boolean VETO = true;
-
-	/**
-	 * Return value to accept the action (false)
-	 */
-	public static final boolean NO_VETO = false;
-
-	/**
-	 * Called when an entity is saved.
-	 * @param s the session
-	 * @return true to veto save
-	 * @throws CallbackException
-	 */
-	public boolean onSave(Session s) throws CallbackException;
-
-	/**
-	 * Called when an entity is passed to <tt>Session.update()</tt>.
-	 * This method is <em>not</em> called every time the object's
-	 * state is persisted during a flush.
-	 * @param s the session
-	 * @return true to veto update
-	 * @throws CallbackException
-	 */
-	public boolean onUpdate(Session s) throws CallbackException;
-
-	/**
-	 * Called when an entity is deleted.
-	 * @param s the session
-	 * @return true to veto delete
-	 * @throws CallbackException
-	 */
-	public boolean onDelete(Session s) throws CallbackException;
-
-	/**
-	 * Called after an entity is loaded. <em>It is illegal to
-	 * access the <tt>Session</tt> from inside this method.</em>
-	 * However, the object may keep a reference to the session
-	 * for later use.
-	 *
-	 * @param s the session
-	 * @param id the identifier
-	 */
-	public void onLoad(Session s, Serializable id);
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/classic/Lifecycle.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Lifecycle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.classic;
+
+import java.io.Serializable;
+
+import org.hibernate.CallbackException;
+import org.hibernate.Session;
+
+/**
+ * Provides callbacks from the <tt>Session</tt> to the persistent object.
+ * Persistent classes <b>may</b> implement this interface but they are not
+ * required to.<br>
+ * <br>
+ * <b>onSave:</b> called just before the object is saved<br>
+ * <b>onUpdate:</b> called just before an object is updated,
+ * ie. when <tt>Session.update()</tt> is called<br>
+ * <b>onDelete:</b> called just before an object is deleted<br>
+ * <b>onLoad:</b> called just after an object is loaded<br>
+ * <br>
+ * <tt>onLoad()</tt> may be used to initialize transient properties of the
+ * object from its persistent state. It may <b>not</b> be used to load
+ * dependent objects since the <tt>Session</tt> interface may not be
+ * invoked from inside this method.<br>
+ * <br>
+ * A further intended usage of <tt>onLoad()</tt>, <tt>onSave()</tt> and
+ * <tt>onUpdate()</tt> is to store a reference to the <tt>Session</tt>
+ * for later use.<br>
+ * <br>
+ * If <tt>onSave()</tt>, <tt>onUpdate()</tt> or <tt>onDelete()</tt> return
+ * <tt>VETO</tt>, the operation is silently vetoed. If a
+ * <tt>CallbackException</tt> is thrown, the operation is vetoed and the
+ * exception is passed back to the application.<br>
+ * <br>
+ * Note that <tt>onSave()</tt> is called after an identifier is assigned
+ * to the object, except when identity column key generation is used.
+ *
+ * @see CallbackException
+ * @author Gavin King
+ */
+public interface Lifecycle {
+
+	/**
+	 * Return value to veto the action (true)
+	 */
+	public static final boolean VETO = true;
+
+	/**
+	 * Return value to accept the action (false)
+	 */
+	public static final boolean NO_VETO = false;
+
+	/**
+	 * Called when an entity is saved.
+	 * @param s the session
+	 * @return true to veto save
+	 * @throws CallbackException
+	 */
+	public boolean onSave(Session s) throws CallbackException;
+
+	/**
+	 * Called when an entity is passed to <tt>Session.update()</tt>.
+	 * This method is <em>not</em> called every time the object's
+	 * state is persisted during a flush.
+	 * @param s the session
+	 * @return true to veto update
+	 * @throws CallbackException
+	 */
+	public boolean onUpdate(Session s) throws CallbackException;
+
+	/**
+	 * Called when an entity is deleted.
+	 * @param s the session
+	 * @return true to veto delete
+	 * @throws CallbackException
+	 */
+	public boolean onDelete(Session s) throws CallbackException;
+
+	/**
+	 * Called after an entity is loaded. <em>It is illegal to
+	 * access the <tt>Session</tt> from inside this method.</em>
+	 * However, the object may keep a reference to the session
+	 * for later use.
+	 *
+	 * @param s the session
+	 * @param id the identifier
+	 */
+	public void onLoad(Session s, Serializable id);
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/classic/Session.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,352 +0,0 @@
-//$Id: Session.java 9652 2006-03-17 18:59:03Z steve.ebersole at jboss.com $
-package org.hibernate.classic;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Query;
-import org.hibernate.type.Type;
-
-/**
- * An extension of the <tt>Session</tt> API, including all
- * deprecated methods from Hibernate2. This interface is
- * provided to allow easier migration of existing applications.
- * New code should use <tt>org.hibernate.Session</tt>.
- * @author Gavin King
- */
-public interface Session extends org.hibernate.Session {
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the same
-	 * identifier. If there is no persistent instance currently associated with
-	 * the session, it will be loaded. Return the persistent instance. If the
-	 * given instance is unsaved or does not exist in the database, save it and
-	 * return it as a newly persistent instance. Otherwise, the given instance
-	 * does not become associated with the session.
-	 *
-	 * @deprecated use {@link org.hibernate.Session#merge(Object)}
-	 *
-	 * @param object a transient instance with state to be copied
-	 * @return an updated persistent instance
-	 */
-	public Object saveOrUpdateCopy(Object object) throws HibernateException;
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the
-	 * given identifier. If there is no persistent instance currently associated
-	 * with the session, it will be loaded. Return the persistent instance. If
-	 * there is no database row with the given identifier, save the given instance
-	 * and return it as a newly persistent instance. Otherwise, the given instance
-	 * does not become associated with the session.
-	 *
-	 * @deprecated with no replacement
-	 *
-	 * @param object a persistent or transient instance with state to be copied
-	 * @param id the identifier of the instance to copy to
-	 * @return an updated persistent instance
-	 */
-	public Object saveOrUpdateCopy(Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the same
-	 * identifier. If there is no persistent instance currently associated with
-	 * the session, it will be loaded. Return the persistent instance. If the
-	 * given instance is unsaved or does not exist in the database, save it and
-	 * return it as a newly persistent instance. Otherwise, the given instance
-	 * does not become associated with the session.
-	 *
-	 * @deprecated use {@link org.hibernate.Session#merge(String, Object)}
-	 *
-	 * @param object a transient instance with state to be copied
-	 * @return an updated persistent instance
-	 */
-	public Object saveOrUpdateCopy(String entityName, Object object) throws HibernateException;
-
-	/**
-	 * Copy the state of the given object onto the persistent object with the
-	 * given identifier. If there is no persistent instance currently associated
-	 * with the session, it will be loaded. Return the persistent instance. If
-	 * there is no database row with the given identifier, save the given instance
-	 * and return it as a newly persistent instance. Otherwise, the given instance
-	 * does not become associated with the session.
-	 *
-	 * @deprecated with no replacement
-	 *
-	 * @param object a persistent or transient instance with state to be copied
-	 * @param id the identifier of the instance to copy to
-	 * @return an updated persistent instance
-	 */
-	public Object saveOrUpdateCopy(String entityName, Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Execute a query.
-	 *
-	 * @deprecated use {@link #createQuery}.{@link Query#list()}
-	 *
-	 * @param query a query expressed in Hibernate's query language
-	 * @return a distinct list of instances (or arrays of instances)
-	 * @throws HibernateException
-	 */
-	public List find(String query) throws HibernateException;
-			
-	/**
-	 * Execute a query with bind parameters, binding a value to a "?" parameter
-	 * in the query string.
-	 *
-	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#list()}
-	 *
-	 * @param query the query string
-	 * @param value a value to be bound to a "?" placeholder (JDBC IN parameter).
-	 * @param type the Hibernate type of the value
-	 * @see org.hibernate.Hibernate for access to <tt>Type</tt> instances
-	 * @return a distinct list of instances (or arrays of instances)
-	 * @throws HibernateException
-	 */
-	public List find(String query, Object value, Type type) throws HibernateException;
-	
-	/**
-	 * Execute a query with bind parameters, binding an array of values to "?"
-	 * parameters in the query string.
-	 *
-	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#list()}
-	 *
-	 * @param query the query string
-	 * @param values an array of values to be bound to the "?" placeholders (JDBC IN parameters).
-	 * @param types an array of Hibernate types of the values
-	 * @see org.hibernate.Hibernate for access to <tt>Type</tt> instances
-	 * @return a distinct list of instances
-	 * @throws HibernateException
-	 */
-	public List find(String query, Object[] values, Type[] types) throws HibernateException;
-	
-	/**
-	 * Execute a query and return the results in an iterator. If the query has multiple
-	 * return values, values will be returned in an array of type <tt>Object[].</tt><br>
-	 * <br>
-	 * Entities returned as results are initialized on demand. The first SQL query returns
-	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
-	 * objects than <tt>find()</tt>.
-	 * 
-	 * @deprecated use {@link #createQuery}.{@link Query#iterate}
-	 *
-	 * @param query the query string
-	 * @return an iterator
-	 * @throws HibernateException
-	 */
-	public Iterator iterate(String query) throws HibernateException;
-	
-	/**
-	 * Execute a query and return the results in an iterator. Write the given value to "?"
-	 * in the query string. If the query has multiple return values, values will be returned
-	 * in an array of type <tt>Object[]</tt>.<br>
-	 * <br>
-	 * Entities returned as results are initialized on demand. The first SQL query returns
-	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
-	 * objects than <tt>find()</tt>.
-	 *
-	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#iterate}
-	 *
-	 * @param query the query string
-	 * @param value a value to be witten to a "?" placeholder in the query string
-	 * @param type the hibernate type of value
-	 * @return an iterator
-	 * @throws HibernateException
-	 */
-	public Iterator iterate(String query, Object value, Type type) throws HibernateException;
-	
-	/**
-	 * Execute a query and return the results in an iterator. Write the given values to "?"
-	 * in the query string. If the query has multiple return values, values will be returned
-	 * in an array of type <tt>Object[]</tt>.<br>
-	 * <br>
-	 * Entities returned as results are initialized on demand. The first SQL query returns
-	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
-	 * objects than <tt>find()</tt>.
-	 *
-	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#iterate}
-	 *
-	 * @param query the query string
-	 * @param values a list of values to be written to "?" placeholders in the query
-	 * @param types a list of Hibernate types of the values
-	 * @return an iterator
-	 * @throws HibernateException
-	 */
-	public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException;
-	
-	/**
-	 * Apply a filter to a persistent collection. A filter is a Hibernate query that may refer to
-	 * <tt>this</tt>, the collection element. Filters allow efficient access to very large lazy
-	 * collections. (Executing the filter does not initialize the collection.)
-	 * 
-	 * @deprecated use {@link #createFilter(Object, String)}.{@link Query#list}
-	 *
-	 * @param collection a persistent collection to filter
-	 * @param filter a filter query string
-	 * @return Collection the resulting collection
-	 * @throws HibernateException
-	 */
-	public Collection filter(Object collection, String filter) throws HibernateException;
-	
-	/**
-	 * Apply a filter to a persistent collection. A filter is a Hibernate query that may refer to
-	 * <tt>this</tt>, the collection element.
-	 *
-	 * @deprecated use {@link #createFilter(Object, String)}.setXYZ.{@link Query#list}
-	 *
-	 * @param collection a persistent collection to filter
-	 * @param filter a filter query string
-	 * @param value a value to be witten to a "?" placeholder in the query string
-	 * @param type the hibernate type of value
-	 * @return Collection
-	 * @throws HibernateException
-	 */
-	public Collection filter(Object collection, String filter, Object value, Type type) throws HibernateException;
-	
-	/**
-	 * Apply a filter to a persistent collection.
-	 *
-	 * Bind the given parameters to "?" placeholders. A filter is a Hibernate query that
-	 * may refer to <tt>this</tt>, the collection element.
-	 *
-	 * @deprecated use {@link #createFilter(Object, String)}.setXYZ.{@link Query#list}
-	 *
-	 * @param collection a persistent collection to filter
-	 * @param filter a filter query string
-	 * @param values a list of values to be written to "?" placeholders in the query
-	 * @param types a list of Hibernate types of the values
-	 * @return Collection
-	 * @throws HibernateException
-	 */
-	public Collection filter(Object collection, String filter, Object[] values, Type[] types) throws HibernateException;
-	
-	/**
-	 * Delete all objects returned by the query. Return the number of objects deleted.
-	 * <p/>
-	 * Note that this is very different from the delete-statement support added in HQL
-	 * since 3.1.  The functionality here is to actually peform the query and then iterate
-	 * the results calling {@link #delete(Object)} individually.
-	 * 
-	 * @deprecated consider using HQL delete statements
-	 *
-	 * @param query the query string
-	 * @return the number of instances deleted
-	 * @throws HibernateException
-	 */
-	public int delete(String query) throws HibernateException;
-	
-	/**
-	 * Delete all objects returned by the query. Return the number of objects deleted.
-	 * <p/>
-	 * Note that this is very different from the delete-statement support added in HQL
-	 * since 3.1.  The functionality here is to actually peform the query and then iterate
-	 * the results calling {@link #delete(Object)} individually.
-	 *
-	 * @deprecated consider using HQL delete statements
-	 *
-	 * @param query the query string
-	 * @param value a value to be witten to a "?" placeholder in the query string.
-	 * @param type the hibernate type of value.
-	 * @return the number of instances deleted
-	 * @throws HibernateException
-	 */
-	public int delete(String query, Object value, Type type) throws HibernateException;
-	
-	/**
-	 * Delete all objects returned by the query. Return the number of objects deleted.
-	 * <p/>
-	 * Note that this is very different from the delete-statement support added in HQL
-	 * since 3.1.  The functionality here is to actually peform the query and then iterate
-	 * the results calling {@link #delete(Object)} individually.
-	 *
-	 * @deprecated consider using HQL delete statements
-	 *
-	 * @param query the query string
-	 * @param values a list of values to be written to "?" placeholders in the query.
-	 * @param types a list of Hibernate types of the values
-	 * @return the number of instances deleted
-	 * @throws HibernateException
-	 */
-	public int delete(String query, Object[] values, Type[] types) throws HibernateException;
-
-
-	/**
-	 * Create a new instance of <tt>Query</tt> for the given SQL string.
-	 *
-	 * @deprecated will be replaced with a more Query like interface in later release
-	 *
-	 * @param sql a query expressed in SQL
-	 * @param returnAlias a table alias that appears inside <tt>{}</tt> in the SQL string
-	 * @param returnClass the returned persistent class
-	 */
-	public Query createSQLQuery(String sql, String returnAlias, Class returnClass);
-	
-	/**
-	 * Create a new instance of <tt>Query</tt> for the given SQL string.
-	 *
-	 * @deprecated will be replaced with a more Query like interface in later release
-	 *
-	 * @param sql a query expressed in SQL
-	 * @param returnAliases an array of table aliases that appear inside <tt>{}</tt> in the SQL string
-	 * @param returnClasses the returned persistent classes
-	 */
-	public Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses);
-	
-	
-	/**
-	 * Persist the given transient instance, using the given identifier.  This operation 
-	 * cascades to associated instances if the association is mapped with 
-	 * <tt>cascade="save-update"</tt>.
-	 *
-	 * @deprecated declare identifier properties for all classes
-	 *
-	 * @param object a transient instance of a persistent class
-	 * @param id an unused valid identifier
-	 * @throws HibernateException
-	 */
-	public void save(Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Persist the given transient instance, using the given identifier. This operation 
-	 * cascades to associated instances if the association is mapped with 
-	 * <tt>cascade="save-update"</tt>.
-	 *
-	 * @deprecated declare identifier properties for all classes
-	 *
-	 * @param object a transient instance of a persistent class
-	 * @param id an unused valid identifier
-	 * @throws HibernateException
-	 */
-	public void save(String entityName, Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Update the persistent state associated with the given identifier. An exception
-	 * is thrown if there is a persistent instance with the same identifier in the
-	 * current session. This operation cascades to associated instances 
-	 * if the association is mapped with <tt>cascade="save-update"</tt>.
-	 *
-	 * @deprecated declare identifier properties for all classes
-	 *
-	 * @param object a detached instance containing updated state
-	 * @param id identifier of persistent instance
-	 * @throws HibernateException
-	 */
-	public void update(Object object, Serializable id) throws HibernateException;
-
-	/**
-	 * Update the persistent state associated with the given identifier. An exception
-	 * is thrown if there is a persistent instance with the same identifier in the
-	 * current session. This operation cascades to associated instances 
-	 * if the association is mapped with <tt>cascade="save-update"</tt>.
-	 * 
-	 * @deprecated declare identifier properties for all classes
-	 *
-	 * @param object a detached instance containing updated state
-	 * @param id identifier of persistent instance
-	 * @throws HibernateException
-	 */
-	public void update(String entityName, Object object, Serializable id) throws HibernateException;
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/classic/Session.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Session.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,375 @@
+/*
+ * 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.classic;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Query;
+import org.hibernate.type.Type;
+
+/**
+ * An extension of the <tt>Session</tt> API, including all
+ * deprecated methods from Hibernate2. This interface is
+ * provided to allow easier migration of existing applications.
+ * New code should use <tt>org.hibernate.Session</tt>.
+ * @author Gavin King
+ */
+public interface Session extends org.hibernate.Session {
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the same
+	 * identifier. If there is no persistent instance currently associated with
+	 * the session, it will be loaded. Return the persistent instance. If the
+	 * given instance is unsaved or does not exist in the database, save it and
+	 * return it as a newly persistent instance. Otherwise, the given instance
+	 * does not become associated with the session.
+	 *
+	 * @deprecated use {@link org.hibernate.Session#merge(Object)}
+	 *
+	 * @param object a transient instance with state to be copied
+	 * @return an updated persistent instance
+	 */
+	public Object saveOrUpdateCopy(Object object) throws HibernateException;
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the
+	 * given identifier. If there is no persistent instance currently associated
+	 * with the session, it will be loaded. Return the persistent instance. If
+	 * there is no database row with the given identifier, save the given instance
+	 * and return it as a newly persistent instance. Otherwise, the given instance
+	 * does not become associated with the session.
+	 *
+	 * @deprecated with no replacement
+	 *
+	 * @param object a persistent or transient instance with state to be copied
+	 * @param id the identifier of the instance to copy to
+	 * @return an updated persistent instance
+	 */
+	public Object saveOrUpdateCopy(Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the same
+	 * identifier. If there is no persistent instance currently associated with
+	 * the session, it will be loaded. Return the persistent instance. If the
+	 * given instance is unsaved or does not exist in the database, save it and
+	 * return it as a newly persistent instance. Otherwise, the given instance
+	 * does not become associated with the session.
+	 *
+	 * @deprecated use {@link org.hibernate.Session#merge(String, Object)}
+	 *
+	 * @param object a transient instance with state to be copied
+	 * @return an updated persistent instance
+	 */
+	public Object saveOrUpdateCopy(String entityName, Object object) throws HibernateException;
+
+	/**
+	 * Copy the state of the given object onto the persistent object with the
+	 * given identifier. If there is no persistent instance currently associated
+	 * with the session, it will be loaded. Return the persistent instance. If
+	 * there is no database row with the given identifier, save the given instance
+	 * and return it as a newly persistent instance. Otherwise, the given instance
+	 * does not become associated with the session.
+	 *
+	 * @deprecated with no replacement
+	 *
+	 * @param object a persistent or transient instance with state to be copied
+	 * @param id the identifier of the instance to copy to
+	 * @return an updated persistent instance
+	 */
+	public Object saveOrUpdateCopy(String entityName, Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Execute a query.
+	 *
+	 * @deprecated use {@link #createQuery}.{@link Query#list()}
+	 *
+	 * @param query a query expressed in Hibernate's query language
+	 * @return a distinct list of instances (or arrays of instances)
+	 * @throws HibernateException
+	 */
+	public List find(String query) throws HibernateException;
+			
+	/**
+	 * Execute a query with bind parameters, binding a value to a "?" parameter
+	 * in the query string.
+	 *
+	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#list()}
+	 *
+	 * @param query the query string
+	 * @param value a value to be bound to a "?" placeholder (JDBC IN parameter).
+	 * @param type the Hibernate type of the value
+	 * @see org.hibernate.Hibernate for access to <tt>Type</tt> instances
+	 * @return a distinct list of instances (or arrays of instances)
+	 * @throws HibernateException
+	 */
+	public List find(String query, Object value, Type type) throws HibernateException;
+	
+	/**
+	 * Execute a query with bind parameters, binding an array of values to "?"
+	 * parameters in the query string.
+	 *
+	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#list()}
+	 *
+	 * @param query the query string
+	 * @param values an array of values to be bound to the "?" placeholders (JDBC IN parameters).
+	 * @param types an array of Hibernate types of the values
+	 * @see org.hibernate.Hibernate for access to <tt>Type</tt> instances
+	 * @return a distinct list of instances
+	 * @throws HibernateException
+	 */
+	public List find(String query, Object[] values, Type[] types) throws HibernateException;
+	
+	/**
+	 * Execute a query and return the results in an iterator. If the query has multiple
+	 * return values, values will be returned in an array of type <tt>Object[].</tt><br>
+	 * <br>
+	 * Entities returned as results are initialized on demand. The first SQL query returns
+	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
+	 * objects than <tt>find()</tt>.
+	 * 
+	 * @deprecated use {@link #createQuery}.{@link Query#iterate}
+	 *
+	 * @param query the query string
+	 * @return an iterator
+	 * @throws HibernateException
+	 */
+	public Iterator iterate(String query) throws HibernateException;
+	
+	/**
+	 * Execute a query and return the results in an iterator. Write the given value to "?"
+	 * in the query string. If the query has multiple return values, values will be returned
+	 * in an array of type <tt>Object[]</tt>.<br>
+	 * <br>
+	 * Entities returned as results are initialized on demand. The first SQL query returns
+	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
+	 * objects than <tt>find()</tt>.
+	 *
+	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#iterate}
+	 *
+	 * @param query the query string
+	 * @param value a value to be witten to a "?" placeholder in the query string
+	 * @param type the hibernate type of value
+	 * @return an iterator
+	 * @throws HibernateException
+	 */
+	public Iterator iterate(String query, Object value, Type type) throws HibernateException;
+	
+	/**
+	 * Execute a query and return the results in an iterator. Write the given values to "?"
+	 * in the query string. If the query has multiple return values, values will be returned
+	 * in an array of type <tt>Object[]</tt>.<br>
+	 * <br>
+	 * Entities returned as results are initialized on demand. The first SQL query returns
+	 * identifiers only. So <tt>iterate()</tt> is usually a less efficient way to retrieve
+	 * objects than <tt>find()</tt>.
+	 *
+	 * @deprecated use {@link #createQuery}.setXYZ.{@link Query#iterate}
+	 *
+	 * @param query the query string
+	 * @param values a list of values to be written to "?" placeholders in the query
+	 * @param types a list of Hibernate types of the values
+	 * @return an iterator
+	 * @throws HibernateException
+	 */
+	public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException;
+	
+	/**
+	 * Apply a filter to a persistent collection. A filter is a Hibernate query that may refer to
+	 * <tt>this</tt>, the collection element. Filters allow efficient access to very large lazy
+	 * collections. (Executing the filter does not initialize the collection.)
+	 * 
+	 * @deprecated use {@link #createFilter(Object, String)}.{@link Query#list}
+	 *
+	 * @param collection a persistent collection to filter
+	 * @param filter a filter query string
+	 * @return Collection the resulting collection
+	 * @throws HibernateException
+	 */
+	public Collection filter(Object collection, String filter) throws HibernateException;
+	
+	/**
+	 * Apply a filter to a persistent collection. A filter is a Hibernate query that may refer to
+	 * <tt>this</tt>, the collection element.
+	 *
+	 * @deprecated use {@link #createFilter(Object, String)}.setXYZ.{@link Query#list}
+	 *
+	 * @param collection a persistent collection to filter
+	 * @param filter a filter query string
+	 * @param value a value to be witten to a "?" placeholder in the query string
+	 * @param type the hibernate type of value
+	 * @return Collection
+	 * @throws HibernateException
+	 */
+	public Collection filter(Object collection, String filter, Object value, Type type) throws HibernateException;
+	
+	/**
+	 * Apply a filter to a persistent collection.
+	 *
+	 * Bind the given parameters to "?" placeholders. A filter is a Hibernate query that
+	 * may refer to <tt>this</tt>, the collection element.
+	 *
+	 * @deprecated use {@link #createFilter(Object, String)}.setXYZ.{@link Query#list}
+	 *
+	 * @param collection a persistent collection to filter
+	 * @param filter a filter query string
+	 * @param values a list of values to be written to "?" placeholders in the query
+	 * @param types a list of Hibernate types of the values
+	 * @return Collection
+	 * @throws HibernateException
+	 */
+	public Collection filter(Object collection, String filter, Object[] values, Type[] types) throws HibernateException;
+	
+	/**
+	 * Delete all objects returned by the query. Return the number of objects deleted.
+	 * <p/>
+	 * Note that this is very different from the delete-statement support added in HQL
+	 * since 3.1.  The functionality here is to actually peform the query and then iterate
+	 * the results calling {@link #delete(Object)} individually.
+	 * 
+	 * @deprecated consider using HQL delete statements
+	 *
+	 * @param query the query string
+	 * @return the number of instances deleted
+	 * @throws HibernateException
+	 */
+	public int delete(String query) throws HibernateException;
+	
+	/**
+	 * Delete all objects returned by the query. Return the number of objects deleted.
+	 * <p/>
+	 * Note that this is very different from the delete-statement support added in HQL
+	 * since 3.1.  The functionality here is to actually peform the query and then iterate
+	 * the results calling {@link #delete(Object)} individually.
+	 *
+	 * @deprecated consider using HQL delete statements
+	 *
+	 * @param query the query string
+	 * @param value a value to be witten to a "?" placeholder in the query string.
+	 * @param type the hibernate type of value.
+	 * @return the number of instances deleted
+	 * @throws HibernateException
+	 */
+	public int delete(String query, Object value, Type type) throws HibernateException;
+	
+	/**
+	 * Delete all objects returned by the query. Return the number of objects deleted.
+	 * <p/>
+	 * Note that this is very different from the delete-statement support added in HQL
+	 * since 3.1.  The functionality here is to actually peform the query and then iterate
+	 * the results calling {@link #delete(Object)} individually.
+	 *
+	 * @deprecated consider using HQL delete statements
+	 *
+	 * @param query the query string
+	 * @param values a list of values to be written to "?" placeholders in the query.
+	 * @param types a list of Hibernate types of the values
+	 * @return the number of instances deleted
+	 * @throws HibernateException
+	 */
+	public int delete(String query, Object[] values, Type[] types) throws HibernateException;
+
+
+	/**
+	 * Create a new instance of <tt>Query</tt> for the given SQL string.
+	 *
+	 * @deprecated will be replaced with a more Query like interface in later release
+	 *
+	 * @param sql a query expressed in SQL
+	 * @param returnAlias a table alias that appears inside <tt>{}</tt> in the SQL string
+	 * @param returnClass the returned persistent class
+	 */
+	public Query createSQLQuery(String sql, String returnAlias, Class returnClass);
+	
+	/**
+	 * Create a new instance of <tt>Query</tt> for the given SQL string.
+	 *
+	 * @deprecated will be replaced with a more Query like interface in later release
+	 *
+	 * @param sql a query expressed in SQL
+	 * @param returnAliases an array of table aliases that appear inside <tt>{}</tt> in the SQL string
+	 * @param returnClasses the returned persistent classes
+	 */
+	public Query createSQLQuery(String sql, String[] returnAliases, Class[] returnClasses);
+	
+	
+	/**
+	 * Persist the given transient instance, using the given identifier.  This operation 
+	 * cascades to associated instances if the association is mapped with 
+	 * <tt>cascade="save-update"</tt>.
+	 *
+	 * @deprecated declare identifier properties for all classes
+	 *
+	 * @param object a transient instance of a persistent class
+	 * @param id an unused valid identifier
+	 * @throws HibernateException
+	 */
+	public void save(Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Persist the given transient instance, using the given identifier. This operation 
+	 * cascades to associated instances if the association is mapped with 
+	 * <tt>cascade="save-update"</tt>.
+	 *
+	 * @deprecated declare identifier properties for all classes
+	 *
+	 * @param object a transient instance of a persistent class
+	 * @param id an unused valid identifier
+	 * @throws HibernateException
+	 */
+	public void save(String entityName, Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Update the persistent state associated with the given identifier. An exception
+	 * is thrown if there is a persistent instance with the same identifier in the
+	 * current session. This operation cascades to associated instances 
+	 * if the association is mapped with <tt>cascade="save-update"</tt>.
+	 *
+	 * @deprecated declare identifier properties for all classes
+	 *
+	 * @param object a detached instance containing updated state
+	 * @param id identifier of persistent instance
+	 * @throws HibernateException
+	 */
+	public void update(Object object, Serializable id) throws HibernateException;
+
+	/**
+	 * Update the persistent state associated with the given identifier. An exception
+	 * is thrown if there is a persistent instance with the same identifier in the
+	 * current session. This operation cascades to associated instances 
+	 * if the association is mapped with <tt>cascade="save-update"</tt>.
+	 * 
+	 * @deprecated declare identifier properties for all classes
+	 *
+	 * @param object a detached instance containing updated state
+	 * @param id identifier of persistent instance
+	 * @throws HibernateException
+	 */
+	public void update(String entityName, Object object, Serializable id) throws HibernateException;
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/classic/Validatable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: Validatable.java 4112 2004-07-28 03:33:35Z oneovthafew $
-package org.hibernate.classic;
-
-
-/**
- * Implemented by persistent classes with invariants that must
- * be checked before inserting into or updating the database.
- *
- * @author Gavin King
- */
-public interface Validatable {
-	/**
-	 * Validate the state of the object before persisting it.
-	 * If a violation occurs, throw a <tt>ValidationFailure</tt>.
-	 * This method must not change the state of the object by
-	 * side-effect.
-	 * @throws ValidationFailure if an invariant is violated
-	 */
-	public void validate() throws ValidationFailure;
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/classic/Validatable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/Validatable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.classic;
+
+/**
+ * Implemented by persistent classes with invariants that must
+ * be checked before inserting into or updating the database.
+ *
+ * @author Gavin King
+ */
+public interface Validatable {
+	/**
+	 * Validate the state of the object before persisting it.
+	 * If a violation occurs, throw a <tt>ValidationFailure</tt>.
+	 * This method must not change the state of the object by
+	 * side-effect.
+	 * @throws ValidationFailure if an invariant is violated
+	 */
+	public void validate() throws ValidationFailure;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/classic/ValidationFailure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-//$Id: ValidationFailure.java 4112 2004-07-28 03:33:35Z oneovthafew $
-package org.hibernate.classic;
-
-import org.hibernate.HibernateException;
-
-/**
- * Thrown from <tt>Validatable.validate()</tt> when an invariant
- * was violated. Some applications might subclass this exception
- * in order to provide more information about the violation.
- *
- * @author Gavin King
- */
-public class ValidationFailure extends HibernateException {
-
-	public ValidationFailure(String message) {
-		super(message);
-	}
-
-	public ValidationFailure(String message, Exception e) {
-		super(message, e);
-	}
-
-	public ValidationFailure(Exception e) {
-		super("A validation failure occurred", e);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/classic/ValidationFailure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/ValidationFailure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.classic;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Thrown from <tt>Validatable.validate()</tt> when an invariant
+ * was violated. Some applications might subclass this exception
+ * in order to provide more information about the violation.
+ *
+ * @author Gavin King
+ */
+public class ValidationFailure extends HibernateException {
+
+	public ValidationFailure(String message) {
+		super(message);
+	}
+
+	public ValidationFailure(String message, Exception e) {
+		super(message, e);
+	}
+
+	public ValidationFailure(Exception e) {
+		super("A validation failure occurred", e);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/classic/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package implements backward-compatibility with Hibernate 2.1
-	APIs now deprecated in Hibernate3.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/classic/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/classic/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package implements backward-compatibility with Hibernate 2.1
+	APIs now deprecated in Hibernate3.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,943 +0,0 @@
-//$Id: AbstractPersistentCollection.java 11302 2007-03-19 20:44:11Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.LazyInitializationException;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.EmptyIterator;
-import org.hibernate.util.MarkerObject;
-
-/**
- * Base class implementing <tt>PersistentCollection</tt>
- * @see PersistentCollection
- * @author Gavin King
- */
-public abstract class AbstractPersistentCollection 
-	implements Serializable, PersistentCollection {
-
-	private transient SessionImplementor session;
-	private boolean initialized;
-	private transient List operationQueue;
-	private transient boolean directlyAccessible;
-	private transient boolean initializing;
-	private Object owner;
-	private int cachedSize = -1;
-	
-	private String role;
-	private Serializable key;
-	// collections detect changes made via their public interface and mark
-	// themselves as dirty as a performance optimization
-	private boolean dirty;
-	private Serializable storedSnapshot;
-
-	public final String getRole() {
-		return role;
-	}
-	
-	public final Serializable getKey() {
-		return key;
-	}
-	
-	public final boolean isUnreferenced() {
-		return role==null;
-	}
-	
-	public final boolean isDirty() {
-		return dirty;
-	}
-	
-	public final void clearDirty() {
-		dirty = false;
-	}
-	
-	public final void dirty() {
-		dirty = true;
-	}
-	
-	public final Serializable getStoredSnapshot() {
-		return storedSnapshot;
-	}
-	
-	//Careful: these methods do not initialize the collection.
-	/**
-	 * Is the initialized collection empty?
-	 */
-	public abstract boolean empty();
-	/**
-	 * Called by any read-only method of the collection interface
-	 */
-	protected final void read() {
-		initialize(false);
-	}
-	/**
-	 * Called by the <tt>size()</tt> method
-	 */
-	protected boolean readSize() {
-		if (!initialized) {
-			if ( cachedSize!=-1 && !hasQueuedOperations() ) {
-				return true;
-			}
-			else {
-				throwLazyInitializationExceptionIfNotConnected();
-				CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
-				CollectionPersister persister = entry.getLoadedPersister();
-				if ( persister.isExtraLazy() ) {
-					if ( hasQueuedOperations() ) {
-						session.flush();
-					}
-					cachedSize = persister.getSize( entry.getLoadedKey(), session );
-					return true;
-				}
-			}
-		}
-		read();
-		return false;
-	}
-	
-	protected Boolean readIndexExistence(Object index) {
-		if (!initialized) {
-			throwLazyInitializationExceptionIfNotConnected();
-			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
-			CollectionPersister persister = entry.getLoadedPersister();
-			if ( persister.isExtraLazy() ) {
-				if ( hasQueuedOperations() ) {
-					session.flush();
-				}
-				return new Boolean( persister.indexExists( entry.getLoadedKey(), index, session ) );
-			}
-		}
-		read();
-		return null;
-		
-	}
-	
-	protected Boolean readElementExistence(Object element) {
-		if (!initialized) {
-			throwLazyInitializationExceptionIfNotConnected();
-			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
-			CollectionPersister persister = entry.getLoadedPersister();
-			if ( persister.isExtraLazy() ) {
-				if ( hasQueuedOperations() ) {
-					session.flush();
-				}
-				return new Boolean( persister.elementExists( entry.getLoadedKey(), element, session ) );
-			}
-		}
-		read();
-		return null;
-		
-	}
-	
-	protected static final Object UNKNOWN = new MarkerObject("UNKNOWN");
-	
-	protected Object readElementByIndex(Object index) {
-		if (!initialized) {
-			throwLazyInitializationExceptionIfNotConnected();
-			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
-			CollectionPersister persister = entry.getLoadedPersister();
-			if ( persister.isExtraLazy() ) {
-				if ( hasQueuedOperations() ) {
-					session.flush();
-				}
-				return persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
-			}
-		}
-		read();
-		return UNKNOWN;
-		
-	}
-	
-	protected int getCachedSize() {
-		return cachedSize;
-	}
-	
-	/**
-	 * Is the collection currently connected to an open session?
-	 */
-	private final boolean isConnectedToSession() {
-		return session!=null && 
-				session.isOpen() &&
-				session.getPersistenceContext().containsCollection(this);
-	}
-
-	/**
-	 * Called by any writer method of the collection interface
-	 */
-	protected final void write() {
-		initialize(true);
-		dirty();
-	}
-	/**
-	 * Is this collection in a state that would allow us to
-	 * "queue" operations?
-	 */
-	protected boolean isOperationQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseCollection();
-	}
-	/**
-	 * Is this collection in a state that would allow us to
-	 * "queue" puts? This is a special case, because of orphan
-	 * delete.
-	 */
-	protected boolean isPutQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseOneToManyOrNoOrphanDelete();
-	}
-	/**
-	 * Is this collection in a state that would allow us to
-	 * "queue" clear? This is a special case, because of orphan
-	 * delete.
-	 */
-	protected boolean isClearQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseCollectionNoOrphanDelete();
-	}
-
-	/**
-	 * Is this the "inverse" end of a bidirectional association?
-	 */
-	private boolean isInverseCollection() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
-		return ce != null && ce.getLoadedPersister().isInverse();
-	}
-
-	/**
-	 * Is this the "inverse" end of a bidirectional association with
-	 * no orphan delete enabled?
-	 */
-	private boolean isInverseCollectionNoOrphanDelete() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
-		return ce != null && 
-				ce.getLoadedPersister().isInverse() &&
-				!ce.getLoadedPersister().hasOrphanDelete();
-	}
-
-	/**
-	 * Is this the "inverse" end of a bidirectional one-to-many, or 
-	 * of a collection with no orphan delete?
-	 */
-	private boolean isInverseOneToManyOrNoOrphanDelete() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
-		return ce != null && ce.getLoadedPersister().isInverse() && (
-				ce.getLoadedPersister().isOneToMany() || 
-				!ce.getLoadedPersister().hasOrphanDelete() 
-			);
-	}
-
-	/**
-	 * Queue an addition
-	 */
-	protected final void queueOperation(Object element) {
-		if (operationQueue==null) operationQueue = new ArrayList(10);
-		operationQueue.add(element);
-		dirty = true; //needed so that we remove this collection from the second-level cache
-	}
-
-	/**
-	 * After reading all existing elements from the database,
-	 * add the queued elements to the underlying collection.
-	 */
-	protected final void performQueuedOperations() {
-		for ( int i=0; i<operationQueue.size(); i++ ) {
-			( (DelayedOperation) operationQueue.get(i) ).operate();
-		}
-	}
-
-	/**
-	 * After flushing, re-init snapshot state.
-	 */
-	public void setSnapshot(Serializable key, String role, Serializable snapshot) {
-		this.key = key;
-		this.role = role;
-		this.storedSnapshot = snapshot;
-	}
-
-	/**
-	 * After flushing, clear any "queued" additions, since the
-	 * database state is now synchronized with the memory state.
-	 */
-	public void postAction() {
-		operationQueue=null;
-		cachedSize = -1;
-		clearDirty();
-	}
-	
-	/**
-	 * Not called by Hibernate, but used by non-JDK serialization,
-	 * eg. SOAP libraries.
-	 */
-	public AbstractPersistentCollection() {}
-
-	protected AbstractPersistentCollection(SessionImplementor session) {
-		this.session = session;
-	}
-
-	/**
-	 * return the user-visible collection (or array) instance
-	 */
-	public Object getValue() {
-		return this;
-	}
-
-	/**
-	 * Called just before reading any rows from the JDBC result set
-	 */
-	public void beginRead() {
-		// override on some subclasses
-		initializing = true;
-	}
-
-	/**
-	 * Called after reading all rows from the JDBC result set
-	 */
-	public boolean endRead() {
-		//override on some subclasses
-		return afterInitialize();
-	}
-	
-	public boolean afterInitialize() {
-		setInitialized();
-		//do this bit after setting initialized to true or it will recurse
-		if (operationQueue!=null) {
-			performQueuedOperations();
-			operationQueue=null;
-			cachedSize = -1;
-			return false;
-		}
-		else {
-			return true;
-		}
-	}
-
-	/**
-	 * Initialize the collection, if possible, wrapping any exceptions
-	 * in a runtime exception
-	 * @param writing currently obsolete
-	 * @throws LazyInitializationException if we cannot initialize
-	 */
-	protected final void initialize(boolean writing) {
-		if (!initialized) {
-			if (initializing) {
-				throw new LazyInitializationException("illegal access to loading collection");
-			}
-			throwLazyInitializationExceptionIfNotConnected();
-			session.initializeCollection(this, writing);
-		}
-	}
-	
-	private void throwLazyInitializationExceptionIfNotConnected() {
-		if ( !isConnectedToSession() )  {
-			throwLazyInitializationException("no session or session was closed");
-		}
-		if ( !session.isConnected() ) {
-            throwLazyInitializationException("session is disconnected");
-		}		
-	}
-	
-	private void throwLazyInitializationException(String message) {
-		throw new LazyInitializationException(
-				"failed to lazily initialize a collection" + 
-				( role==null ?  "" : " of role: " + role ) + 
-				", " + message
-			);
-	}
-
-	protected final void setInitialized() {
-		this.initializing = false;
-		this.initialized = true;
-	}
-
-	protected final void setDirectlyAccessible(boolean directlyAccessible) {
-		this.directlyAccessible = directlyAccessible;
-	}
-
-	/**
-	 * Could the application possibly have a direct reference to
-	 * the underlying collection implementation?
-	 */
-	public boolean isDirectlyAccessible() {
-		return directlyAccessible;
-	}
-
-	/**
-	 * Disassociate this collection from the given session.
-	 * @return true if this was currently associated with the given session
-	 */
-	public final boolean unsetSession(SessionImplementor currentSession) {
-		if (currentSession==this.session) {
-			this.session=null;
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * Associate the collection with the given session.
-	 * @return false if the collection was already associated with the session
-	 * @throws HibernateException if the collection was already associated
-	 * with another open session
-	 */
-	public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
-		if (session==this.session) {
-			return false;
-		}
-		else {
-			if ( isConnectedToSession() ) {
-				CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
-				if (ce==null) {
-					throw new HibernateException(
-							"Illegal attempt to associate a collection with two open sessions"
-						);
-				}
-				else {
-					throw new HibernateException(
-							"Illegal attempt to associate a collection with two open sessions: " +
-							MessageHelper.collectionInfoString( 
-									ce.getLoadedPersister(), 
-									ce.getLoadedKey(), 
-									session.getFactory() 
-								)
-						);
-				}
-			}
-			else {
-				this.session = session;
-				return true;
-			}
-		}
-	}
-
-	/**
-	 * Do we need to completely recreate this collection when it changes?
-	 */
-	public boolean needsRecreate(CollectionPersister persister) {
-		return false;
-	}
-	
-	/**
-	 * To be called internally by the session, forcing
-	 * immediate initialization.
-	 */
-	public final void forceInitialization() throws HibernateException {
-		if (!initialized) {
-			if (initializing) {
-				throw new AssertionFailure("force initialize loading collection");
-			}
-			if (session==null) {
-				throw new HibernateException("collection is not associated with any session");
-			}
-			if ( !session.isConnected() ) {
-				throw new HibernateException("disconnected session");
-			}
-			session.initializeCollection(this, false);
-		}
-	}
-
-
-	/**
-	 * Get the current snapshot from the session
-	 */
-	protected final Serializable getSnapshot() {
-		return session.getPersistenceContext().getSnapshot(this);
-	}
-
-	/**
-	 * Is this instance initialized?
-	 */
-	public final boolean wasInitialized() {
-		return initialized;
-	}
-	
-	public boolean isRowUpdatePossible() {
-		return true;
-	}
-
-	/**
-	 * Does this instance have any "queued" additions?
-	 */
-	public final boolean hasQueuedOperations() {
-		return operationQueue!=null;
-	}
-	/**
-	 * Iterate the "queued" additions
-	 */
-	public final Iterator queuedAdditionIterator() {
-		if ( hasQueuedOperations() ) {
-			return new Iterator() {
-				int i = 0;
-				public Object next() {
-					return ( (DelayedOperation) operationQueue.get(i++) ).getAddedInstance();
-				}
-				public boolean hasNext() {
-					return i<operationQueue.size();
-				}
-				public void remove() {
-					throw new UnsupportedOperationException();
-				}
-			};
-		}
-		else {
-			return EmptyIterator.INSTANCE;
-		}
-	}
-	/**
-	 * Iterate the "queued" additions
-	 */
-	public final Collection getQueuedOrphans(String entityName) {
-		if ( hasQueuedOperations() ) {
-			Collection additions = new ArrayList( operationQueue.size() );
-			Collection removals = new ArrayList( operationQueue.size() );
-			for ( int i = 0; i < operationQueue.size(); i++ ) {
-				DelayedOperation op = (DelayedOperation) operationQueue.get(i);
-				additions.add( op.getAddedInstance() );
-				removals.add( op.getOrphan() );
-			}
-			return getOrphans(removals, additions, entityName, session);
-		}
-		else {
-			return CollectionHelper.EMPTY_COLLECTION;
-		}
-	}
-
-	/**
-	 * Called before inserting rows, to ensure that any surrogate keys
-	 * are fully generated
-	 */
-	public void preInsert(CollectionPersister persister) throws HibernateException {}
-	/**
-	 * Called after inserting a row, to fetch the natively generated id
-	 */
-	public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {}
-	/**
-	 * get all "orphaned" elements
-	 */
-	public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
-
-	/**
-	 * Get the current session
-	 */
-	public final SessionImplementor getSession() {
-		return session;
-	}
-
-	final class IteratorProxy implements Iterator {
-		private final Iterator iter;
-		IteratorProxy(Iterator iter) {
-			this.iter=iter;
-		}
-		public boolean hasNext() {
-			return iter.hasNext();
-		}
-
-		public Object next() {
-			return iter.next();
-		}
-
-		public void remove() {
-			write();
-			iter.remove();
-		}
-
-	}
-
-	final class ListIteratorProxy implements ListIterator {
-		private final ListIterator iter;
-		ListIteratorProxy(ListIterator iter) {
-			this.iter = iter;
-		}
-		public void add(Object o) {
-			write();
-			iter.add(o);
-		}
-
-		public boolean hasNext() {
-			return iter.hasNext();
-		}
-
-		public boolean hasPrevious() {
-			return iter.hasPrevious();
-		}
-
-		public Object next() {
-			return iter.next();
-		}
-
-		public int nextIndex() {
-			return iter.nextIndex();
-		}
-
-		public Object previous() {
-			return iter.previous();
-		}
-
-		public int previousIndex() {
-			return iter.previousIndex();
-		}
-
-		public void remove() {
-			write();
-			iter.remove();
-		}
-
-		public void set(Object o) {
-			write();
-			iter.set(o);
-		}
-
-	}
-
-	class SetProxy implements java.util.Set {
-
-		final Collection set;
-
-		SetProxy(Collection set) {
-			this.set=set;
-		}
-		public boolean add(Object o) {
-			write();
-			return set.add(o);
-		}
-
-		public boolean addAll(Collection c) {
-			write();
-			return set.addAll(c);
-		}
-
-		public void clear() {
-			write();
-			set.clear();
-		}
-
-		public boolean contains(Object o) {
-			return set.contains(o);
-		}
-
-		public boolean containsAll(Collection c) {
-			return set.containsAll(c);
-		}
-
-		public boolean isEmpty() {
-			return set.isEmpty();
-		}
-
-		public Iterator iterator() {
-			return new IteratorProxy( set.iterator() );
-		}
-
-		public boolean remove(Object o) {
-			write();
-			return set.remove(o);
-		}
-
-		public boolean removeAll(Collection c) {
-			write();
-			return set.removeAll(c);
-		}
-
-		public boolean retainAll(Collection c) {
-			write();
-			return set.retainAll(c);
-		}
-
-		public int size() {
-			return set.size();
-		}
-
-		public Object[] toArray() {
-			return set.toArray();
-		}
-
-		public Object[] toArray(Object[] array) {
-			return set.toArray(array);
-		}
-
-	}
-
-	final class ListProxy implements java.util.List {
-
-		private final java.util.List list;
-
-		ListProxy(java.util.List list) {
-			this.list = list;
-		}
-
-		public void add(int index, Object value) {
-			write();
-			list.add(index, value);
-		}
-
-		/**
-		 * @see java.util.Collection#add(Object)
-		 */
-		public boolean add(Object o) {
-			write();
-			return list.add(o);
-		}
-
-		/**
-		 * @see java.util.Collection#addAll(Collection)
-		 */
-		public boolean addAll(Collection c) {
-			write();
-			return list.addAll(c);
-		}
-
-		/**
-		 * @see java.util.List#addAll(int, Collection)
-		 */
-		public boolean addAll(int i, Collection c) {
-			write();
-			return list.addAll(i, c);
-		}
-
-		/**
-		 * @see java.util.Collection#clear()
-		 */
-		public void clear() {
-			write();
-			list.clear();
-		}
-
-		/**
-		 * @see java.util.Collection#contains(Object)
-		 */
-		public boolean contains(Object o) {
-			return list.contains(o);
-		}
-
-		/**
-		 * @see java.util.Collection#containsAll(Collection)
-		 */
-		public boolean containsAll(Collection c) {
-			return list.containsAll(c);
-		}
-
-		/**
-		 * @see java.util.List#get(int)
-		 */
-		public Object get(int i) {
-			return list.get(i);
-		}
-
-		/**
-		 * @see java.util.List#indexOf(Object)
-		 */
-		public int indexOf(Object o) {
-			return list.indexOf(o);
-		}
-
-		/**
-		 * @see java.util.Collection#isEmpty()
-		 */
-		public boolean isEmpty() {
-			return list.isEmpty();
-		}
-
-		/**
-		 * @see java.util.Collection#iterator()
-		 */
-		public Iterator iterator() {
-			return new IteratorProxy( list.iterator() );
-		}
-
-		/**
-		 * @see java.util.List#lastIndexOf(Object)
-		 */
-		public int lastIndexOf(Object o) {
-			return list.lastIndexOf(o);
-		}
-
-		/**
-		 * @see java.util.List#listIterator()
-		 */
-		public ListIterator listIterator() {
-			return new ListIteratorProxy( list.listIterator() );
-		}
-
-		/**
-		 * @see java.util.List#listIterator(int)
-		 */
-		public ListIterator listIterator(int i) {
-			return new ListIteratorProxy( list.listIterator(i) );
-		}
-
-		/**
-		 * @see java.util.List#remove(int)
-		 */
-		public Object remove(int i) {
-			write();
-			return list.remove(i);
-		}
-
-		/**
-		 * @see java.util.Collection#remove(Object)
-		 */
-		public boolean remove(Object o) {
-			write();
-			return list.remove(o);
-		}
-
-		/**
-		 * @see java.util.Collection#removeAll(Collection)
-		 */
-		public boolean removeAll(Collection c) {
-			write();
-			return list.removeAll(c);
-		}
-
-		/**
-		 * @see java.util.Collection#retainAll(Collection)
-		 */
-		public boolean retainAll(Collection c) {
-			write();
-			return list.retainAll(c);
-		}
-
-		/**
-		 * @see java.util.List#set(int, Object)
-		 */
-		public Object set(int i, Object o) {
-			write();
-			return list.set(i, o);
-		}
-
-		/**
-		 * @see java.util.Collection#size()
-		 */
-		public int size() {
-			return list.size();
-		}
-
-		/**
-		 * @see java.util.List#subList(int, int)
-		 */
-		public List subList(int i, int j) {
-			return list.subList(i, j);
-		}
-
-		/**
-		 * @see java.util.Collection#toArray()
-		 */
-		public Object[] toArray() {
-			return list.toArray();
-		}
-
-		/**
-		 * @see java.util.Collection#toArray(Object[])
-		 */
-		public Object[] toArray(Object[] array) {
-			return list.toArray(array);
-		}
-
-	}
-
-
-	protected interface DelayedOperation {
-		public void operate();
-		public Object getAddedInstance();
-		public Object getOrphan();
-	}
-	
-	/**
-	 * Given a collection of entity instances that used to
-	 * belong to the collection, and a collection of instances
-	 * that currently belong, return a collection of orphans
-	 */
-	protected static Collection getOrphans(
-			Collection oldElements, 
-			Collection currentElements, 
-			String entityName, 
-			SessionImplementor session)
-	throws HibernateException {
-
-		// short-circuit(s)
-		if ( currentElements.size()==0 ) return oldElements; // no new elements, the old list contains only Orphans
-		if ( oldElements.size()==0) return oldElements; // no old elements, so no Orphans neither
-		
-		Type idType = session.getFactory().getEntityPersister(entityName).getIdentifierType();
-
-		// create the collection holding the Orphans
-		Collection res = new ArrayList();
-
-		// collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
-		java.util.Set currentIds = new HashSet();
-		for ( Iterator it=currentElements.iterator(); it.hasNext(); ) {
-			Object current = it.next();
-			if ( current!=null && ForeignKeys.isNotTransient(entityName, current, null, session) ) {
-				Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, current, session);
-				currentIds.add( new TypedValue( idType, currentId, session.getEntityMode() ) );
-			}
-		}
-
-		// iterate over the *old* list
-		for ( Iterator it=oldElements.iterator(); it.hasNext(); ) {
-			Object old = it.next();
-			Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old, session);
-			if ( !currentIds.contains( new TypedValue( idType, oldId, session.getEntityMode() ) ) ) {
-				res.add(old);
-			}
-		}
-
-		return res;
-	}
-
-	static void identityRemove(
-			Collection list, 
-			Object object, 
-			String entityName, 
-			SessionImplementor session)
-	throws HibernateException {
-
-		if ( object!=null && ForeignKeys.isNotTransient(entityName, object, null, session) ) {
-			
-			Type idType = session.getFactory().getEntityPersister(entityName).getIdentifierType();
-
-			Serializable idOfCurrent = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, object, session);
-			Iterator iter = list.iterator();
-			while ( iter.hasNext() ) {
-				Serializable idOfOld = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, iter.next(), session);
-				if ( idType.isEqual( idOfCurrent, idOfOld, session.getEntityMode(), session.getFactory() ) ) {
-					iter.remove();
-					break;
-				}
-			}
-
-		}
-	}
-	
-	public Object getIdentifier(Object entry, int i) {
-		throw new UnsupportedOperationException();
-	}
-	
-	public Object getOwner() {
-		return owner;
-	}
-	
-	public void setOwner(Object owner) {
-		this.owner = owner;
-	}
-	
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/AbstractPersistentCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,965 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.util.MarkerObject;
+
+/**
+ * Base class implementing {@link PersistentCollection}
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection {
+
+	private transient SessionImplementor session;
+	private boolean initialized;
+	private transient List operationQueue;
+	private transient boolean directlyAccessible;
+	private transient boolean initializing;
+	private Object owner;
+	private int cachedSize = -1;
+	
+	private String role;
+	private Serializable key;
+	// collections detect changes made via their public interface and mark
+	// themselves as dirty as a performance optimization
+	private boolean dirty;
+	private Serializable storedSnapshot;
+
+	public final String getRole() {
+		return role;
+	}
+	
+	public final Serializable getKey() {
+		return key;
+	}
+	
+	public final boolean isUnreferenced() {
+		return role==null;
+	}
+	
+	public final boolean isDirty() {
+		return dirty;
+	}
+	
+	public final void clearDirty() {
+		dirty = false;
+	}
+	
+	public final void dirty() {
+		dirty = true;
+	}
+	
+	public final Serializable getStoredSnapshot() {
+		return storedSnapshot;
+	}
+	
+	//Careful: these methods do not initialize the collection.
+	/**
+	 * Is the initialized collection empty?
+	 */
+	public abstract boolean empty();
+	/**
+	 * Called by any read-only method of the collection interface
+	 */
+	protected final void read() {
+		initialize(false);
+	}
+	/**
+	 * Called by the <tt>size()</tt> method
+	 */
+	protected boolean readSize() {
+		if (!initialized) {
+			if ( cachedSize!=-1 && !hasQueuedOperations() ) {
+				return true;
+			}
+			else {
+				throwLazyInitializationExceptionIfNotConnected();
+				CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
+				CollectionPersister persister = entry.getLoadedPersister();
+				if ( persister.isExtraLazy() ) {
+					if ( hasQueuedOperations() ) {
+						session.flush();
+					}
+					cachedSize = persister.getSize( entry.getLoadedKey(), session );
+					return true;
+				}
+			}
+		}
+		read();
+		return false;
+	}
+	
+	protected Boolean readIndexExistence(Object index) {
+		if (!initialized) {
+			throwLazyInitializationExceptionIfNotConnected();
+			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
+			CollectionPersister persister = entry.getLoadedPersister();
+			if ( persister.isExtraLazy() ) {
+				if ( hasQueuedOperations() ) {
+					session.flush();
+				}
+				return new Boolean( persister.indexExists( entry.getLoadedKey(), index, session ) );
+			}
+		}
+		read();
+		return null;
+		
+	}
+	
+	protected Boolean readElementExistence(Object element) {
+		if (!initialized) {
+			throwLazyInitializationExceptionIfNotConnected();
+			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
+			CollectionPersister persister = entry.getLoadedPersister();
+			if ( persister.isExtraLazy() ) {
+				if ( hasQueuedOperations() ) {
+					session.flush();
+				}
+				return new Boolean( persister.elementExists( entry.getLoadedKey(), element, session ) );
+			}
+		}
+		read();
+		return null;
+		
+	}
+	
+	protected static final Object UNKNOWN = new MarkerObject("UNKNOWN");
+	
+	protected Object readElementByIndex(Object index) {
+		if (!initialized) {
+			throwLazyInitializationExceptionIfNotConnected();
+			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);
+			CollectionPersister persister = entry.getLoadedPersister();
+			if ( persister.isExtraLazy() ) {
+				if ( hasQueuedOperations() ) {
+					session.flush();
+				}
+				return persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
+			}
+		}
+		read();
+		return UNKNOWN;
+		
+	}
+	
+	protected int getCachedSize() {
+		return cachedSize;
+	}
+	
+	/**
+	 * Is the collection currently connected to an open session?
+	 */
+	private final boolean isConnectedToSession() {
+		return session!=null && 
+				session.isOpen() &&
+				session.getPersistenceContext().containsCollection(this);
+	}
+
+	/**
+	 * Called by any writer method of the collection interface
+	 */
+	protected final void write() {
+		initialize(true);
+		dirty();
+	}
+	/**
+	 * Is this collection in a state that would allow us to
+	 * "queue" operations?
+	 */
+	protected boolean isOperationQueueEnabled() {
+		return !initialized &&
+				isConnectedToSession() &&
+				isInverseCollection();
+	}
+	/**
+	 * Is this collection in a state that would allow us to
+	 * "queue" puts? This is a special case, because of orphan
+	 * delete.
+	 */
+	protected boolean isPutQueueEnabled() {
+		return !initialized &&
+				isConnectedToSession() &&
+				isInverseOneToManyOrNoOrphanDelete();
+	}
+	/**
+	 * Is this collection in a state that would allow us to
+	 * "queue" clear? This is a special case, because of orphan
+	 * delete.
+	 */
+	protected boolean isClearQueueEnabled() {
+		return !initialized &&
+				isConnectedToSession() &&
+				isInverseCollectionNoOrphanDelete();
+	}
+
+	/**
+	 * Is this the "inverse" end of a bidirectional association?
+	 */
+	private boolean isInverseCollection() {
+		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
+		return ce != null && ce.getLoadedPersister().isInverse();
+	}
+
+	/**
+	 * Is this the "inverse" end of a bidirectional association with
+	 * no orphan delete enabled?
+	 */
+	private boolean isInverseCollectionNoOrphanDelete() {
+		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
+		return ce != null && 
+				ce.getLoadedPersister().isInverse() &&
+				!ce.getLoadedPersister().hasOrphanDelete();
+	}
+
+	/**
+	 * Is this the "inverse" end of a bidirectional one-to-many, or 
+	 * of a collection with no orphan delete?
+	 */
+	private boolean isInverseOneToManyOrNoOrphanDelete() {
+		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
+		return ce != null && ce.getLoadedPersister().isInverse() && (
+				ce.getLoadedPersister().isOneToMany() || 
+				!ce.getLoadedPersister().hasOrphanDelete() 
+			);
+	}
+
+	/**
+	 * Queue an addition
+	 */
+	protected final void queueOperation(Object element) {
+		if (operationQueue==null) operationQueue = new ArrayList(10);
+		operationQueue.add(element);
+		dirty = true; //needed so that we remove this collection from the second-level cache
+	}
+
+	/**
+	 * After reading all existing elements from the database,
+	 * add the queued elements to the underlying collection.
+	 */
+	protected final void performQueuedOperations() {
+		for ( int i=0; i<operationQueue.size(); i++ ) {
+			( (DelayedOperation) operationQueue.get(i) ).operate();
+		}
+	}
+
+	/**
+	 * After flushing, re-init snapshot state.
+	 */
+	public void setSnapshot(Serializable key, String role, Serializable snapshot) {
+		this.key = key;
+		this.role = role;
+		this.storedSnapshot = snapshot;
+	}
+
+	/**
+	 * After flushing, clear any "queued" additions, since the
+	 * database state is now synchronized with the memory state.
+	 */
+	public void postAction() {
+		operationQueue=null;
+		cachedSize = -1;
+		clearDirty();
+	}
+	
+	/**
+	 * Not called by Hibernate, but used by non-JDK serialization,
+	 * eg. SOAP libraries.
+	 */
+	public AbstractPersistentCollection() {}
+
+	protected AbstractPersistentCollection(SessionImplementor session) {
+		this.session = session;
+	}
+
+	/**
+	 * return the user-visible collection (or array) instance
+	 */
+	public Object getValue() {
+		return this;
+	}
+
+	/**
+	 * Called just before reading any rows from the JDBC result set
+	 */
+	public void beginRead() {
+		// override on some subclasses
+		initializing = true;
+	}
+
+	/**
+	 * Called after reading all rows from the JDBC result set
+	 */
+	public boolean endRead() {
+		//override on some subclasses
+		return afterInitialize();
+	}
+	
+	public boolean afterInitialize() {
+		setInitialized();
+		//do this bit after setting initialized to true or it will recurse
+		if (operationQueue!=null) {
+			performQueuedOperations();
+			operationQueue=null;
+			cachedSize = -1;
+			return false;
+		}
+		else {
+			return true;
+		}
+	}
+
+	/**
+	 * Initialize the collection, if possible, wrapping any exceptions
+	 * in a runtime exception
+	 * @param writing currently obsolete
+	 * @throws LazyInitializationException if we cannot initialize
+	 */
+	protected final void initialize(boolean writing) {
+		if (!initialized) {
+			if (initializing) {
+				throw new LazyInitializationException("illegal access to loading collection");
+			}
+			throwLazyInitializationExceptionIfNotConnected();
+			session.initializeCollection(this, writing);
+		}
+	}
+	
+	private void throwLazyInitializationExceptionIfNotConnected() {
+		if ( !isConnectedToSession() )  {
+			throwLazyInitializationException("no session or session was closed");
+		}
+		if ( !session.isConnected() ) {
+            throwLazyInitializationException("session is disconnected");
+		}		
+	}
+	
+	private void throwLazyInitializationException(String message) {
+		throw new LazyInitializationException(
+				"failed to lazily initialize a collection" + 
+				( role==null ?  "" : " of role: " + role ) + 
+				", " + message
+			);
+	}
+
+	protected final void setInitialized() {
+		this.initializing = false;
+		this.initialized = true;
+	}
+
+	protected final void setDirectlyAccessible(boolean directlyAccessible) {
+		this.directlyAccessible = directlyAccessible;
+	}
+
+	/**
+	 * Could the application possibly have a direct reference to
+	 * the underlying collection implementation?
+	 */
+	public boolean isDirectlyAccessible() {
+		return directlyAccessible;
+	}
+
+	/**
+	 * Disassociate this collection from the given session.
+	 * @return true if this was currently associated with the given session
+	 */
+	public final boolean unsetSession(SessionImplementor currentSession) {
+		if (currentSession==this.session) {
+			this.session=null;
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * Associate the collection with the given session.
+	 * @return false if the collection was already associated with the session
+	 * @throws HibernateException if the collection was already associated
+	 * with another open session
+	 */
+	public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
+		if (session==this.session) {
+			return false;
+		}
+		else {
+			if ( isConnectedToSession() ) {
+				CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);
+				if (ce==null) {
+					throw new HibernateException(
+							"Illegal attempt to associate a collection with two open sessions"
+						);
+				}
+				else {
+					throw new HibernateException(
+							"Illegal attempt to associate a collection with two open sessions: " +
+							MessageHelper.collectionInfoString( 
+									ce.getLoadedPersister(), 
+									ce.getLoadedKey(), 
+									session.getFactory() 
+								)
+						);
+				}
+			}
+			else {
+				this.session = session;
+				return true;
+			}
+		}
+	}
+
+	/**
+	 * Do we need to completely recreate this collection when it changes?
+	 */
+	public boolean needsRecreate(CollectionPersister persister) {
+		return false;
+	}
+	
+	/**
+	 * To be called internally by the session, forcing
+	 * immediate initialization.
+	 */
+	public final void forceInitialization() throws HibernateException {
+		if (!initialized) {
+			if (initializing) {
+				throw new AssertionFailure("force initialize loading collection");
+			}
+			if (session==null) {
+				throw new HibernateException("collection is not associated with any session");
+			}
+			if ( !session.isConnected() ) {
+				throw new HibernateException("disconnected session");
+			}
+			session.initializeCollection(this, false);
+		}
+	}
+
+
+	/**
+	 * Get the current snapshot from the session
+	 */
+	protected final Serializable getSnapshot() {
+		return session.getPersistenceContext().getSnapshot(this);
+	}
+
+	/**
+	 * Is this instance initialized?
+	 */
+	public final boolean wasInitialized() {
+		return initialized;
+	}
+	
+	public boolean isRowUpdatePossible() {
+		return true;
+	}
+
+	/**
+	 * Does this instance have any "queued" additions?
+	 */
+	public final boolean hasQueuedOperations() {
+		return operationQueue!=null;
+	}
+	/**
+	 * Iterate the "queued" additions
+	 */
+	public final Iterator queuedAdditionIterator() {
+		if ( hasQueuedOperations() ) {
+			return new Iterator() {
+				int i = 0;
+				public Object next() {
+					return ( (DelayedOperation) operationQueue.get(i++) ).getAddedInstance();
+				}
+				public boolean hasNext() {
+					return i<operationQueue.size();
+				}
+				public void remove() {
+					throw new UnsupportedOperationException();
+				}
+			};
+		}
+		else {
+			return EmptyIterator.INSTANCE;
+		}
+	}
+	/**
+	 * Iterate the "queued" additions
+	 */
+	public final Collection getQueuedOrphans(String entityName) {
+		if ( hasQueuedOperations() ) {
+			Collection additions = new ArrayList( operationQueue.size() );
+			Collection removals = new ArrayList( operationQueue.size() );
+			for ( int i = 0; i < operationQueue.size(); i++ ) {
+				DelayedOperation op = (DelayedOperation) operationQueue.get(i);
+				additions.add( op.getAddedInstance() );
+				removals.add( op.getOrphan() );
+			}
+			return getOrphans(removals, additions, entityName, session);
+		}
+		else {
+			return CollectionHelper.EMPTY_COLLECTION;
+		}
+	}
+
+	/**
+	 * Called before inserting rows, to ensure that any surrogate keys
+	 * are fully generated
+	 */
+	public void preInsert(CollectionPersister persister) throws HibernateException {}
+	/**
+	 * Called after inserting a row, to fetch the natively generated id
+	 */
+	public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {}
+	/**
+	 * get all "orphaned" elements
+	 */
+	public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
+
+	/**
+	 * Get the current session
+	 */
+	public final SessionImplementor getSession() {
+		return session;
+	}
+
+	final class IteratorProxy implements Iterator {
+		private final Iterator iter;
+		IteratorProxy(Iterator iter) {
+			this.iter=iter;
+		}
+		public boolean hasNext() {
+			return iter.hasNext();
+		}
+
+		public Object next() {
+			return iter.next();
+		}
+
+		public void remove() {
+			write();
+			iter.remove();
+		}
+
+	}
+
+	final class ListIteratorProxy implements ListIterator {
+		private final ListIterator iter;
+		ListIteratorProxy(ListIterator iter) {
+			this.iter = iter;
+		}
+		public void add(Object o) {
+			write();
+			iter.add(o);
+		}
+
+		public boolean hasNext() {
+			return iter.hasNext();
+		}
+
+		public boolean hasPrevious() {
+			return iter.hasPrevious();
+		}
+
+		public Object next() {
+			return iter.next();
+		}
+
+		public int nextIndex() {
+			return iter.nextIndex();
+		}
+
+		public Object previous() {
+			return iter.previous();
+		}
+
+		public int previousIndex() {
+			return iter.previousIndex();
+		}
+
+		public void remove() {
+			write();
+			iter.remove();
+		}
+
+		public void set(Object o) {
+			write();
+			iter.set(o);
+		}
+
+	}
+
+	class SetProxy implements java.util.Set {
+
+		final Collection set;
+
+		SetProxy(Collection set) {
+			this.set=set;
+		}
+		public boolean add(Object o) {
+			write();
+			return set.add(o);
+		}
+
+		public boolean addAll(Collection c) {
+			write();
+			return set.addAll(c);
+		}
+
+		public void clear() {
+			write();
+			set.clear();
+		}
+
+		public boolean contains(Object o) {
+			return set.contains(o);
+		}
+
+		public boolean containsAll(Collection c) {
+			return set.containsAll(c);
+		}
+
+		public boolean isEmpty() {
+			return set.isEmpty();
+		}
+
+		public Iterator iterator() {
+			return new IteratorProxy( set.iterator() );
+		}
+
+		public boolean remove(Object o) {
+			write();
+			return set.remove(o);
+		}
+
+		public boolean removeAll(Collection c) {
+			write();
+			return set.removeAll(c);
+		}
+
+		public boolean retainAll(Collection c) {
+			write();
+			return set.retainAll(c);
+		}
+
+		public int size() {
+			return set.size();
+		}
+
+		public Object[] toArray() {
+			return set.toArray();
+		}
+
+		public Object[] toArray(Object[] array) {
+			return set.toArray(array);
+		}
+
+	}
+
+	final class ListProxy implements java.util.List {
+
+		private final java.util.List list;
+
+		ListProxy(java.util.List list) {
+			this.list = list;
+		}
+
+		public void add(int index, Object value) {
+			write();
+			list.add(index, value);
+		}
+
+		/**
+		 * @see java.util.Collection#add(Object)
+		 */
+		public boolean add(Object o) {
+			write();
+			return list.add(o);
+		}
+
+		/**
+		 * @see java.util.Collection#addAll(Collection)
+		 */
+		public boolean addAll(Collection c) {
+			write();
+			return list.addAll(c);
+		}
+
+		/**
+		 * @see java.util.List#addAll(int, Collection)
+		 */
+		public boolean addAll(int i, Collection c) {
+			write();
+			return list.addAll(i, c);
+		}
+
+		/**
+		 * @see java.util.Collection#clear()
+		 */
+		public void clear() {
+			write();
+			list.clear();
+		}
+
+		/**
+		 * @see java.util.Collection#contains(Object)
+		 */
+		public boolean contains(Object o) {
+			return list.contains(o);
+		}
+
+		/**
+		 * @see java.util.Collection#containsAll(Collection)
+		 */
+		public boolean containsAll(Collection c) {
+			return list.containsAll(c);
+		}
+
+		/**
+		 * @see java.util.List#get(int)
+		 */
+		public Object get(int i) {
+			return list.get(i);
+		}
+
+		/**
+		 * @see java.util.List#indexOf(Object)
+		 */
+		public int indexOf(Object o) {
+			return list.indexOf(o);
+		}
+
+		/**
+		 * @see java.util.Collection#isEmpty()
+		 */
+		public boolean isEmpty() {
+			return list.isEmpty();
+		}
+
+		/**
+		 * @see java.util.Collection#iterator()
+		 */
+		public Iterator iterator() {
+			return new IteratorProxy( list.iterator() );
+		}
+
+		/**
+		 * @see java.util.List#lastIndexOf(Object)
+		 */
+		public int lastIndexOf(Object o) {
+			return list.lastIndexOf(o);
+		}
+
+		/**
+		 * @see java.util.List#listIterator()
+		 */
+		public ListIterator listIterator() {
+			return new ListIteratorProxy( list.listIterator() );
+		}
+
+		/**
+		 * @see java.util.List#listIterator(int)
+		 */
+		public ListIterator listIterator(int i) {
+			return new ListIteratorProxy( list.listIterator(i) );
+		}
+
+		/**
+		 * @see java.util.List#remove(int)
+		 */
+		public Object remove(int i) {
+			write();
+			return list.remove(i);
+		}
+
+		/**
+		 * @see java.util.Collection#remove(Object)
+		 */
+		public boolean remove(Object o) {
+			write();
+			return list.remove(o);
+		}
+
+		/**
+		 * @see java.util.Collection#removeAll(Collection)
+		 */
+		public boolean removeAll(Collection c) {
+			write();
+			return list.removeAll(c);
+		}
+
+		/**
+		 * @see java.util.Collection#retainAll(Collection)
+		 */
+		public boolean retainAll(Collection c) {
+			write();
+			return list.retainAll(c);
+		}
+
+		/**
+		 * @see java.util.List#set(int, Object)
+		 */
+		public Object set(int i, Object o) {
+			write();
+			return list.set(i, o);
+		}
+
+		/**
+		 * @see java.util.Collection#size()
+		 */
+		public int size() {
+			return list.size();
+		}
+
+		/**
+		 * @see java.util.List#subList(int, int)
+		 */
+		public List subList(int i, int j) {
+			return list.subList(i, j);
+		}
+
+		/**
+		 * @see java.util.Collection#toArray()
+		 */
+		public Object[] toArray() {
+			return list.toArray();
+		}
+
+		/**
+		 * @see java.util.Collection#toArray(Object[])
+		 */
+		public Object[] toArray(Object[] array) {
+			return list.toArray(array);
+		}
+
+	}
+
+
+	protected interface DelayedOperation {
+		public void operate();
+		public Object getAddedInstance();
+		public Object getOrphan();
+	}
+	
+	/**
+	 * Given a collection of entity instances that used to
+	 * belong to the collection, and a collection of instances
+	 * that currently belong, return a collection of orphans
+	 */
+	protected static Collection getOrphans(
+			Collection oldElements, 
+			Collection currentElements, 
+			String entityName, 
+			SessionImplementor session)
+	throws HibernateException {
+
+		// short-circuit(s)
+		if ( currentElements.size()==0 ) return oldElements; // no new elements, the old list contains only Orphans
+		if ( oldElements.size()==0) return oldElements; // no old elements, so no Orphans neither
+		
+		Type idType = session.getFactory().getEntityPersister(entityName).getIdentifierType();
+
+		// create the collection holding the Orphans
+		Collection res = new ArrayList();
+
+		// collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
+		java.util.Set currentIds = new HashSet();
+		for ( Iterator it=currentElements.iterator(); it.hasNext(); ) {
+			Object current = it.next();
+			if ( current!=null && ForeignKeys.isNotTransient(entityName, current, null, session) ) {
+				Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, current, session);
+				currentIds.add( new TypedValue( idType, currentId, session.getEntityMode() ) );
+			}
+		}
+
+		// iterate over the *old* list
+		for ( Iterator it=oldElements.iterator(); it.hasNext(); ) {
+			Object old = it.next();
+			Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, old, session);
+			if ( !currentIds.contains( new TypedValue( idType, oldId, session.getEntityMode() ) ) ) {
+				res.add(old);
+			}
+		}
+
+		return res;
+	}
+
+	static void identityRemove(
+			Collection list, 
+			Object object, 
+			String entityName, 
+			SessionImplementor session)
+	throws HibernateException {
+
+		if ( object!=null && ForeignKeys.isNotTransient(entityName, object, null, session) ) {
+			
+			Type idType = session.getFactory().getEntityPersister(entityName).getIdentifierType();
+
+			Serializable idOfCurrent = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, object, session);
+			Iterator iter = list.iterator();
+			while ( iter.hasNext() ) {
+				Serializable idOfOld = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, iter.next(), session);
+				if ( idType.isEqual( idOfCurrent, idOfOld, session.getEntityMode(), session.getFactory() ) ) {
+					iter.remove();
+					break;
+				}
+			}
+
+		}
+	}
+	
+	public Object getIdentifier(Object entry, int i) {
+		throw new UnsupportedOperationException();
+	}
+	
+	public Object getOwner() {
+		return owner;
+	}
+	
+	public void setOwner(Object owner) {
+		this.owner = owner;
+	}
+	
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,229 +0,0 @@
-//$Id: PersistentArrayHolder.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * A persistent wrapper for an array. Lazy initialization
- * is NOT supported. Use of Hibernate arrays is not really
- * recommended.
- *
- * @author Gavin King
- */
-public class PersistentArrayHolder extends AbstractPersistentCollection {
-	protected Object array;
-
-	private static final Logger log = LoggerFactory.getLogger(PersistentArrayHolder.class);
-
-	//just to help out during the load (ugly, i know)
-	private transient Class elementClass;
-	private transient java.util.List tempList;
-
-	public PersistentArrayHolder(SessionImplementor session, Object array) {
-		super(session);
-		this.array = array;
-		setInitialized();
-	}
-
-	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
-		EntityMode entityMode = getSession().getEntityMode();
-		int length = /*(array==null) ? tempList.size() :*/ Array.getLength(array);
-		Serializable result = (Serializable) Array.newInstance( persister.getElementClass(), length );
-		for ( int i=0; i<length; i++ ) {
-			Object elt = /*(array==null) ? tempList.get(i) :*/ Array.get(array, i);
-			try {
-				Array.set( result, i, persister.getElementType().deepCopy(elt, entityMode, persister.getFactory()) );
-			}
-			catch (IllegalArgumentException iae) {
-				log.error("Array element type error", iae);
-				throw new HibernateException( "Array element type error", iae );
-			}
-		}
-		return result;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return Array.getLength( snapshot ) == 0;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-		Object[] sn = (Object[]) snapshot;
-		Object[] arr = (Object[]) array;
-		ArrayList result = new ArrayList();
-		for (int i=0; i<sn.length; i++) result.add( sn[i] );
-		for (int i=0; i<sn.length; i++) identityRemove( result, arr[i], entityName, getSession() );
-		return result;
-	}
-
-	public PersistentArrayHolder(SessionImplementor session, CollectionPersister persister) throws HibernateException {
-		super(session);
-		elementClass = persister.getElementClass();
-	}
-
-	public Object getArray() {
-		return array;
-	}
-
-	public boolean isWrapper(Object collection) {
-		return array==collection;
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		Serializable snapshot = getSnapshot();
-		int xlen = Array.getLength(snapshot);
-		if ( xlen!= Array.getLength(array) ) return false;
-		for ( int i=0; i<xlen; i++) {
-			if ( elementType.isDirty( Array.get(snapshot, i), Array.get(array, i), getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public Iterator elements() {
-		//if (array==null) return tempList.iterator();
-		int length = Array.getLength(array);
-		java.util.List list = new ArrayList(length);
-		for (int i=0; i<length; i++) {
-			list.add( Array.get(array, i) );
-		}
-		return list.iterator();
-	}
-	public boolean empty() {
-		return false;
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		int index = ( (Integer) persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ) ).intValue();
-		for ( int i = tempList.size(); i<=index; i++) {
-			tempList.add(i, null);
-		}
-		tempList.set(index, element);
-		return element;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return elements();
-	}
-
-	public void beginRead() {
-		super.beginRead();
-		tempList = new ArrayList();
-	}
-	public boolean endRead() {
-		setInitialized();
-		array = Array.newInstance( elementClass, tempList.size() );
-		for ( int i=0; i<tempList.size(); i++) {
-			Array.set(array, i, tempList.get(i) );
-		}
-		tempList=null;
-		return true;
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		//if (tempList==null) throw new UnsupportedOperationException("Can't lazily initialize arrays");
-	}
-
-	public boolean isDirectlyAccessible() {
-		return true;
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] cached = (Serializable[]) disassembled;
-
-		array = Array.newInstance( persister.getElementClass(), cached.length );
-
-		for ( int i=0; i<cached.length; i++ ) {
-			Array.set( array, i, persister.getElementType().assemble( cached[i], getSession(), owner ) );
-		}
-	}
-
-	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
-		int length = Array.getLength(array);
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = persister.getElementType().disassemble( Array.get(array,i), getSession(), null );
-		}
-
-		/*int length = tempList.size();
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = persister.getElementType().disassemble( tempList.get(i), session );
-		}*/
-
-		return result;
-
-	}
-
-	public Object getValue() {
-		return array;
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
-		java.util.List deletes = new ArrayList();
-		Serializable sn = getSnapshot();
-		int snSize = Array.getLength(sn);
-		int arraySize = Array.getLength(array);
-		int end;
-		if ( snSize > arraySize ) {
-			for ( int i=arraySize; i<snSize; i++ ) deletes.add( new Integer(i) );
-			end = arraySize;
-		}
-		else {
-			end = snSize;
-		}
-		for ( int i=0; i<end; i++ ) {
-			if ( Array.get(array, i)==null && Array.get(sn, i)!=null ) deletes.add( new Integer(i) );
-		}
-		return deletes.iterator();
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
-		Serializable sn = getSnapshot();
-		return Array.get(array, i)!=null && ( i >= Array.getLength(sn) || Array.get(sn, i)==null );
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
-		Serializable sn = getSnapshot();
-		return i<Array.getLength(sn) &&
-				Array.get(sn, i)!=null &&
-				Array.get(array, i)!=null &&
-				elemType.isDirty( Array.get(array, i), Array.get(sn, i), getSession() );
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		return new Integer(i);
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		Serializable sn = getSnapshot();
-		return Array.get(sn, i);
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentArrayHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,252 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * A persistent wrapper for an array. Lazy initialization
+ * is NOT supported. Use of Hibernate arrays is not really
+ * recommended.
+ *
+ * @author Gavin King
+ */
+public class PersistentArrayHolder extends AbstractPersistentCollection {
+	protected Object array;
+
+	private static final Logger log = LoggerFactory.getLogger(PersistentArrayHolder.class);
+
+	//just to help out during the load (ugly, i know)
+	private transient Class elementClass;
+	private transient java.util.List tempList;
+
+	public PersistentArrayHolder(SessionImplementor session, Object array) {
+		super(session);
+		this.array = array;
+		setInitialized();
+	}
+
+	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
+		EntityMode entityMode = getSession().getEntityMode();
+		int length = /*(array==null) ? tempList.size() :*/ Array.getLength(array);
+		Serializable result = (Serializable) Array.newInstance( persister.getElementClass(), length );
+		for ( int i=0; i<length; i++ ) {
+			Object elt = /*(array==null) ? tempList.get(i) :*/ Array.get(array, i);
+			try {
+				Array.set( result, i, persister.getElementType().deepCopy(elt, entityMode, persister.getFactory()) );
+			}
+			catch (IllegalArgumentException iae) {
+				log.error("Array element type error", iae);
+				throw new HibernateException( "Array element type error", iae );
+			}
+		}
+		return result;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return Array.getLength( snapshot ) == 0;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+		Object[] sn = (Object[]) snapshot;
+		Object[] arr = (Object[]) array;
+		ArrayList result = new ArrayList();
+		for (int i=0; i<sn.length; i++) result.add( sn[i] );
+		for (int i=0; i<sn.length; i++) identityRemove( result, arr[i], entityName, getSession() );
+		return result;
+	}
+
+	public PersistentArrayHolder(SessionImplementor session, CollectionPersister persister) throws HibernateException {
+		super(session);
+		elementClass = persister.getElementClass();
+	}
+
+	public Object getArray() {
+		return array;
+	}
+
+	public boolean isWrapper(Object collection) {
+		return array==collection;
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		Serializable snapshot = getSnapshot();
+		int xlen = Array.getLength(snapshot);
+		if ( xlen!= Array.getLength(array) ) return false;
+		for ( int i=0; i<xlen; i++) {
+			if ( elementType.isDirty( Array.get(snapshot, i), Array.get(array, i), getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public Iterator elements() {
+		//if (array==null) return tempList.iterator();
+		int length = Array.getLength(array);
+		java.util.List list = new ArrayList(length);
+		for (int i=0; i<length; i++) {
+			list.add( Array.get(array, i) );
+		}
+		return list.iterator();
+	}
+	public boolean empty() {
+		return false;
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		int index = ( (Integer) persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ) ).intValue();
+		for ( int i = tempList.size(); i<=index; i++) {
+			tempList.add(i, null);
+		}
+		tempList.set(index, element);
+		return element;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return elements();
+	}
+
+	public void beginRead() {
+		super.beginRead();
+		tempList = new ArrayList();
+	}
+	public boolean endRead() {
+		setInitialized();
+		array = Array.newInstance( elementClass, tempList.size() );
+		for ( int i=0; i<tempList.size(); i++) {
+			Array.set(array, i, tempList.get(i) );
+		}
+		tempList=null;
+		return true;
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		//if (tempList==null) throw new UnsupportedOperationException("Can't lazily initialize arrays");
+	}
+
+	public boolean isDirectlyAccessible() {
+		return true;
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] cached = (Serializable[]) disassembled;
+
+		array = Array.newInstance( persister.getElementClass(), cached.length );
+
+		for ( int i=0; i<cached.length; i++ ) {
+			Array.set( array, i, persister.getElementType().assemble( cached[i], getSession(), owner ) );
+		}
+	}
+
+	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
+		int length = Array.getLength(array);
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = persister.getElementType().disassemble( Array.get(array,i), getSession(), null );
+		}
+
+		/*int length = tempList.size();
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = persister.getElementType().disassemble( tempList.get(i), session );
+		}*/
+
+		return result;
+
+	}
+
+	public Object getValue() {
+		return array;
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
+		java.util.List deletes = new ArrayList();
+		Serializable sn = getSnapshot();
+		int snSize = Array.getLength(sn);
+		int arraySize = Array.getLength(array);
+		int end;
+		if ( snSize > arraySize ) {
+			for ( int i=arraySize; i<snSize; i++ ) deletes.add( new Integer(i) );
+			end = arraySize;
+		}
+		else {
+			end = snSize;
+		}
+		for ( int i=0; i<end; i++ ) {
+			if ( Array.get(array, i)==null && Array.get(sn, i)!=null ) deletes.add( new Integer(i) );
+		}
+		return deletes.iterator();
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
+		Serializable sn = getSnapshot();
+		return Array.get(array, i)!=null && ( i >= Array.getLength(sn) || Array.get(sn, i)==null );
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
+		Serializable sn = getSnapshot();
+		return i<Array.getLength(sn) &&
+				Array.get(sn, i)!=null &&
+				Array.get(array, i)!=null &&
+				elemType.isDirty( Array.get(array, i), Array.get(sn, i), getSession() );
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		return new Integer(i);
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		Serializable sn = getSnapshot();
+		return Array.get(sn, i);
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentBag.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,548 +0,0 @@
-//$Id: PersistentBag.java 10738 2006-11-06 21:56:38Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * An unordered, unkeyed collection that can contain the same element
- * multiple times. The Java collections API, curiously, has no <tt>Bag</tt>.
- * Most developers seem to use <tt>List</tt>s to represent bag semantics,
- * so Hibernate follows this practice.
- *
- * @author Gavin King
- */
-public class PersistentBag extends AbstractPersistentCollection implements List {
-
-	protected List bag;
-
-	public PersistentBag(SessionImplementor session) {
-		super(session);
-	}
-
-	public PersistentBag(SessionImplementor session, Collection coll) {
-		super(session);
-		if (coll instanceof List) {
-			bag = (List) coll;
-		}
-		else {
-			bag = new ArrayList();
-			Iterator iter = coll.iterator();
-			while ( iter.hasNext() ) {
-				bag.add( iter.next() );
-			}
-		}
-		setInitialized();
-		setDirectlyAccessible(true);
-	}
-
-	public PersistentBag() {} //needed for SOAP libraries, etc
-
-	public boolean isWrapper(Object collection) {
-		return bag==collection;
-	}
-	public boolean empty() {
-		return bag.isEmpty();
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return bag.iterator();
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-		// note that if we load this collection from a cartesian product
-		// the multiplicity would be broken ... so use an idbag instead
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
-		if (element!=null) bag.add(element);
-		return element;
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		this.bag = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		EntityMode entityMode = getSession().getEntityMode();
-		List sn = (List) getSnapshot();
-		if ( sn.size()!=bag.size() ) return false;
-		Iterator iter = bag.iterator();
-		while ( iter.hasNext() ) {
-			Object elt = iter.next();
-			final boolean unequal = countOccurrences(elt, bag, elementType, entityMode) !=
-				countOccurrences(elt, sn, elementType, entityMode);
-			if ( unequal ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (Collection) snapshot ).isEmpty();
-	}
-
-	private int countOccurrences(Object element, List list, Type elementType, EntityMode entityMode)
-	throws HibernateException {
-		Iterator iter = list.iterator();
-		int result=0;
-		while ( iter.hasNext() ) {
-			if ( elementType.isSame( element, iter.next(), entityMode ) ) result++;
-		}
-		return result;
-	}
-
-	public Serializable getSnapshot(CollectionPersister persister)
-	throws HibernateException {
-		EntityMode entityMode = getSession().getEntityMode();
-		ArrayList clonedList = new ArrayList( bag.size() );
-		Iterator iter = bag.iterator();
-		while ( iter.hasNext() ) {
-			clonedList.add( persister.getElementType().deepCopy( iter.next(), entityMode, persister.getFactory() ) );
-		}
-		return clonedList;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-	    List sn = (List) snapshot;
-	    return getOrphans( sn, bag, entityName, getSession() );
-	}
-
-
-	public Serializable disassemble(CollectionPersister persister)
-	throws HibernateException {
-
-		int length = bag.size();
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = persister.getElementType().disassemble( bag.get(i), getSession(), null );
-		}
-		return result;
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] array = (Serializable[]) disassembled;
-		int size = array.length;
-		beforeInitialize( persister, size );
-		for ( int i = 0; i < size; i++ ) {
-			Object element = persister.getElementType().assemble( array[i], getSession(), owner );
-			if ( element!=null ) {
-				bag.add( element );
-			}
-		}
-	}
-
-	public boolean needsRecreate(CollectionPersister persister) {
-		return !persister.isOneToMany();
-	}
-
-
-	// For a one-to-many, a <bag> is not really a bag;
-	// it is *really* a set, since it can't contain the
-	// same element twice. It could be considered a bug
-	// in the mapping dtd that <bag> allows <one-to-many>.
-
-	// Anyway, here we implement <set> semantics for a
-	// <one-to-many> <bag>!
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
-		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
-		Type elementType = persister.getElementType();
-		EntityMode entityMode = getSession().getEntityMode();
-		ArrayList deletes = new ArrayList();
-		List sn = (List) getSnapshot();
-		Iterator olditer = sn.iterator();
-		int i=0;
-		while ( olditer.hasNext() ) {
-			Object old = olditer.next();
-			Iterator newiter = bag.iterator();
-			boolean found = false;
-			if ( bag.size()>i && elementType.isSame( old, bag.get(i++), entityMode ) ) {
-			//a shortcut if its location didn't change!
-				found = true;
-			}
-			else {
-				//search for it
-				//note that this code is incorrect for other than one-to-many
-				while ( newiter.hasNext() ) {
-					if ( elementType.isSame( old, newiter.next(), entityMode ) ) {
-						found = true;
-						break;
-					}
-				}
-			}
-			if (!found) deletes.add(old);
-		}
-		return deletes.iterator();
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
-		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
-		List sn = (List) getSnapshot();
-		final EntityMode entityMode = getSession().getEntityMode();
-		if ( sn.size()>i && elemType.isSame( sn.get(i), entry, entityMode ) ) {
-		//a shortcut if its location didn't change!
-			return false;
-		}
-		else {
-			//search for it
-			//note that this code is incorrect for other than one-to-many
-			Iterator olditer = sn.iterator();
-			while ( olditer.hasNext() ) {
-				Object old = olditer.next();
-				if ( elemType.isSame( old, entry, entityMode ) ) return false;
-			}
-			return true;
-		}
-	}
-
-	public boolean isRowUpdatePossible() {
-		return false;
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) {
-		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
-		return false;
-	}
-
-	/**
-	 * @see java.util.Collection#size()
-	 */
-	public int size() {
-		return readSize() ? getCachedSize() : bag.size();
-	}
-
-	/**
-	 * @see java.util.Collection#isEmpty()
-	 */
-	public boolean isEmpty() {
-		return readSize() ? getCachedSize()==0 : bag.isEmpty();
-	}
-
-	/**
-	 * @see java.util.Collection#contains(Object)
-	 */
-	public boolean contains(Object object) {
-		Boolean exists = readElementExistence(object);
-		return exists==null ?
-				bag.contains(object) :
-				exists.booleanValue();
-	}
-
-	/**
-	 * @see java.util.Collection#iterator()
-	 */
-	public Iterator iterator() {
-		read();
-		return new IteratorProxy( bag.iterator() );
-	}
-
-	/**
-	 * @see java.util.Collection#toArray()
-	 */
-	public Object[] toArray() {
-		read();
-		return bag.toArray();
-	}
-
-	/**
-	 * @see java.util.Collection#toArray(Object[])
-	 */
-	public Object[] toArray(Object[] a) {
-		read();
-		return bag.toArray(a);
-	}
-
-	/**
-	 * @see java.util.Collection#add(Object)
-	 */
-	public boolean add(Object object) {
-		if ( !isOperationQueueEnabled() ) {
-			write();
-			return bag.add(object);
-		}
-		else {
-			queueOperation( new SimpleAdd(object) );
-			return true;
-		}
-	}
-
-	/**
-	 * @see java.util.Collection#remove(Object)
-	 */
-	public boolean remove(Object o) {
-		initialize( true );
-		if ( bag.remove( o ) ) {
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Collection#containsAll(Collection)
-	 */
-	public boolean containsAll(Collection c) {
-		read();
-		return bag.containsAll(c);
-	}
-
-	/**
-	 * @see java.util.Collection#addAll(Collection)
-	 */
-	public boolean addAll(Collection values) {
-		if ( values.size()==0 ) return false;
-		if ( !isOperationQueueEnabled() ) {
-			write();
-			return bag.addAll(values);
-		}
-		else {
-			Iterator iter = values.iterator();
-			while ( iter.hasNext() ) {
-				queueOperation( new SimpleAdd( iter.next() ) );
-			}
-			return values.size()>0;
-		}
-	}
-
-	/**
-	 * @see java.util.Collection#removeAll(Collection)
-	 */
-	public boolean removeAll(Collection c) {
-		if ( c.size()>0 ) {
-			initialize( true );
-			if ( bag.removeAll( c ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Collection#retainAll(Collection)
-	 */
-	public boolean retainAll(Collection c) {
-		initialize( true );
-		if ( bag.retainAll( c ) ) {
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Collection#clear()
-	 */
-	public void clear() {
-		if ( isClearQueueEnabled() ) {
-			queueOperation( new Clear() );
-		}
-		else {
-			initialize( true );
-			if ( ! bag.isEmpty() ) {
-				bag.clear();
-				dirty();
-			}
-		}
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		throw new UnsupportedOperationException("Bags don't have indexes");
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		List sn = (List) getSnapshot();
-		return sn.get(i);
-	}
-
-	public int occurrences(Object o) {
-		read();
-		Iterator iter = bag.iterator();
-		int result=0;
-		while ( iter.hasNext() ) {
-			if ( o.equals( iter.next() ) ) result++;
-		}
-		return result;
-	}
-
-	// List OPERATIONS:
-
-	/**
-	 * @see java.util.List#add(int, Object)
-	 */
-	public void add(int i, Object o) {
-		write();
-		bag.add(i, o);
-	}
-
-	/**
-	 * @see java.util.List#addAll(int, Collection)
-	 */
-	public boolean addAll(int i, Collection c) {
-		if ( c.size()>0 ) {
-			write();
-			return bag.addAll(i, c);
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.List#get(int)
-	 */
-	public Object get(int i) {
-		read();
-		return bag.get(i);
-	}
-
-	/**
-	 * @see java.util.List#indexOf(Object)
-	 */
-	public int indexOf(Object o) {
-		read();
-		return bag.indexOf(o);
-	}
-
-	/**
-	 * @see java.util.List#lastIndexOf(Object)
-	 */
-	public int lastIndexOf(Object o) {
-		read();
-		return bag.lastIndexOf(o);
-	}
-
-	/**
-	 * @see java.util.List#listIterator()
-	 */
-	public ListIterator listIterator() {
-		read();
-		return new ListIteratorProxy( bag.listIterator() );
-	}
-
-	/**
-	 * @see java.util.List#listIterator(int)
-	 */
-	public ListIterator listIterator(int i) {
-		read();
-		return new ListIteratorProxy( bag.listIterator(i) );
-	}
-
-	/**
-	 * @see java.util.List#remove(int)
-	 */
-	public Object remove(int i) {
-		write();
-		return bag.remove(i);
-	}
-
-	/**
-	 * @see java.util.List#set(int, Object)
-	 */
-	public Object set(int i, Object o) {
-		write();
-		return bag.set(i, o);
-	}
-
-	/**
-	 * @see java.util.List#subList(int, int)
-	 */
-	public List subList(int start, int end) {
-		read();
-		return new ListProxy( bag.subList(start, end) );
-	}
-
-	public String toString() {
-		read();
-		return bag.toString();
-	}
-
-	/*public boolean equals(Object other) {
-		read();
-		return bag.equals(other);
-	}
-
-	public int hashCode(Object other) {
-		read();
-		return bag.hashCode();
-	}*/
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-	/**
-	 * Bag does not respect the collection API and do an
-	 * JVM instance comparison to do the equals.
-	 * The semantic is broken not to have to initialize a
-	 * collection for a simple equals() operation.
-	 * @see java.lang.Object#equals(java.lang.Object)
-	 */
-	public boolean equals(Object obj) {
-		return super.equals(obj);
-	}
-
-	/**
-	 * @see java.lang.Object#hashCode()
-	 */
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-	final class Clear implements DelayedOperation {
-		public void operate() {
-			bag.clear();
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
-		}
-	}
-
-	final class SimpleAdd implements DelayedOperation {
-		private Object value;
-
-		public SimpleAdd(Object value) {
-			this.value = value;
-		}
-		public void operate() {
-			bag.add(value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return null;
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentBag.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,571 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * An unordered, unkeyed collection that can contain the same element
+ * multiple times. The Java collections API, curiously, has no <tt>Bag</tt>.
+ * Most developers seem to use <tt>List</tt>s to represent bag semantics,
+ * so Hibernate follows this practice.
+ *
+ * @author Gavin King
+ */
+public class PersistentBag extends AbstractPersistentCollection implements List {
+
+	protected List bag;
+
+	public PersistentBag(SessionImplementor session) {
+		super(session);
+	}
+
+	public PersistentBag(SessionImplementor session, Collection coll) {
+		super(session);
+		if (coll instanceof List) {
+			bag = (List) coll;
+		}
+		else {
+			bag = new ArrayList();
+			Iterator iter = coll.iterator();
+			while ( iter.hasNext() ) {
+				bag.add( iter.next() );
+			}
+		}
+		setInitialized();
+		setDirectlyAccessible(true);
+	}
+
+	public PersistentBag() {} //needed for SOAP libraries, etc
+
+	public boolean isWrapper(Object collection) {
+		return bag==collection;
+	}
+	public boolean empty() {
+		return bag.isEmpty();
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return bag.iterator();
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+		// note that if we load this collection from a cartesian product
+		// the multiplicity would be broken ... so use an idbag instead
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
+		if (element!=null) bag.add(element);
+		return element;
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		this.bag = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		EntityMode entityMode = getSession().getEntityMode();
+		List sn = (List) getSnapshot();
+		if ( sn.size()!=bag.size() ) return false;
+		Iterator iter = bag.iterator();
+		while ( iter.hasNext() ) {
+			Object elt = iter.next();
+			final boolean unequal = countOccurrences(elt, bag, elementType, entityMode) !=
+				countOccurrences(elt, sn, elementType, entityMode);
+			if ( unequal ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (Collection) snapshot ).isEmpty();
+	}
+
+	private int countOccurrences(Object element, List list, Type elementType, EntityMode entityMode)
+	throws HibernateException {
+		Iterator iter = list.iterator();
+		int result=0;
+		while ( iter.hasNext() ) {
+			if ( elementType.isSame( element, iter.next(), entityMode ) ) result++;
+		}
+		return result;
+	}
+
+	public Serializable getSnapshot(CollectionPersister persister)
+	throws HibernateException {
+		EntityMode entityMode = getSession().getEntityMode();
+		ArrayList clonedList = new ArrayList( bag.size() );
+		Iterator iter = bag.iterator();
+		while ( iter.hasNext() ) {
+			clonedList.add( persister.getElementType().deepCopy( iter.next(), entityMode, persister.getFactory() ) );
+		}
+		return clonedList;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+	    List sn = (List) snapshot;
+	    return getOrphans( sn, bag, entityName, getSession() );
+	}
+
+
+	public Serializable disassemble(CollectionPersister persister)
+	throws HibernateException {
+
+		int length = bag.size();
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = persister.getElementType().disassemble( bag.get(i), getSession(), null );
+		}
+		return result;
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] array = (Serializable[]) disassembled;
+		int size = array.length;
+		beforeInitialize( persister, size );
+		for ( int i = 0; i < size; i++ ) {
+			Object element = persister.getElementType().assemble( array[i], getSession(), owner );
+			if ( element!=null ) {
+				bag.add( element );
+			}
+		}
+	}
+
+	public boolean needsRecreate(CollectionPersister persister) {
+		return !persister.isOneToMany();
+	}
+
+
+	// For a one-to-many, a <bag> is not really a bag;
+	// it is *really* a set, since it can't contain the
+	// same element twice. It could be considered a bug
+	// in the mapping dtd that <bag> allows <one-to-many>.
+
+	// Anyway, here we implement <set> semantics for a
+	// <one-to-many> <bag>!
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
+		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
+		Type elementType = persister.getElementType();
+		EntityMode entityMode = getSession().getEntityMode();
+		ArrayList deletes = new ArrayList();
+		List sn = (List) getSnapshot();
+		Iterator olditer = sn.iterator();
+		int i=0;
+		while ( olditer.hasNext() ) {
+			Object old = olditer.next();
+			Iterator newiter = bag.iterator();
+			boolean found = false;
+			if ( bag.size()>i && elementType.isSame( old, bag.get(i++), entityMode ) ) {
+			//a shortcut if its location didn't change!
+				found = true;
+			}
+			else {
+				//search for it
+				//note that this code is incorrect for other than one-to-many
+				while ( newiter.hasNext() ) {
+					if ( elementType.isSame( old, newiter.next(), entityMode ) ) {
+						found = true;
+						break;
+					}
+				}
+			}
+			if (!found) deletes.add(old);
+		}
+		return deletes.iterator();
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
+		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
+		List sn = (List) getSnapshot();
+		final EntityMode entityMode = getSession().getEntityMode();
+		if ( sn.size()>i && elemType.isSame( sn.get(i), entry, entityMode ) ) {
+		//a shortcut if its location didn't change!
+			return false;
+		}
+		else {
+			//search for it
+			//note that this code is incorrect for other than one-to-many
+			Iterator olditer = sn.iterator();
+			while ( olditer.hasNext() ) {
+				Object old = olditer.next();
+				if ( elemType.isSame( old, entry, entityMode ) ) return false;
+			}
+			return true;
+		}
+	}
+
+	public boolean isRowUpdatePossible() {
+		return false;
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) {
+		//if ( !persister.isOneToMany() ) throw new AssertionFailure("Not implemented for Bags");
+		return false;
+	}
+
+	/**
+	 * @see java.util.Collection#size()
+	 */
+	public int size() {
+		return readSize() ? getCachedSize() : bag.size();
+	}
+
+	/**
+	 * @see java.util.Collection#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return readSize() ? getCachedSize()==0 : bag.isEmpty();
+	}
+
+	/**
+	 * @see java.util.Collection#contains(Object)
+	 */
+	public boolean contains(Object object) {
+		Boolean exists = readElementExistence(object);
+		return exists==null ?
+				bag.contains(object) :
+				exists.booleanValue();
+	}
+
+	/**
+	 * @see java.util.Collection#iterator()
+	 */
+	public Iterator iterator() {
+		read();
+		return new IteratorProxy( bag.iterator() );
+	}
+
+	/**
+	 * @see java.util.Collection#toArray()
+	 */
+	public Object[] toArray() {
+		read();
+		return bag.toArray();
+	}
+
+	/**
+	 * @see java.util.Collection#toArray(Object[])
+	 */
+	public Object[] toArray(Object[] a) {
+		read();
+		return bag.toArray(a);
+	}
+
+	/**
+	 * @see java.util.Collection#add(Object)
+	 */
+	public boolean add(Object object) {
+		if ( !isOperationQueueEnabled() ) {
+			write();
+			return bag.add(object);
+		}
+		else {
+			queueOperation( new SimpleAdd(object) );
+			return true;
+		}
+	}
+
+	/**
+	 * @see java.util.Collection#remove(Object)
+	 */
+	public boolean remove(Object o) {
+		initialize( true );
+		if ( bag.remove( o ) ) {
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Collection#containsAll(Collection)
+	 */
+	public boolean containsAll(Collection c) {
+		read();
+		return bag.containsAll(c);
+	}
+
+	/**
+	 * @see java.util.Collection#addAll(Collection)
+	 */
+	public boolean addAll(Collection values) {
+		if ( values.size()==0 ) return false;
+		if ( !isOperationQueueEnabled() ) {
+			write();
+			return bag.addAll(values);
+		}
+		else {
+			Iterator iter = values.iterator();
+			while ( iter.hasNext() ) {
+				queueOperation( new SimpleAdd( iter.next() ) );
+			}
+			return values.size()>0;
+		}
+	}
+
+	/**
+	 * @see java.util.Collection#removeAll(Collection)
+	 */
+	public boolean removeAll(Collection c) {
+		if ( c.size()>0 ) {
+			initialize( true );
+			if ( bag.removeAll( c ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Collection#retainAll(Collection)
+	 */
+	public boolean retainAll(Collection c) {
+		initialize( true );
+		if ( bag.retainAll( c ) ) {
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Collection#clear()
+	 */
+	public void clear() {
+		if ( isClearQueueEnabled() ) {
+			queueOperation( new Clear() );
+		}
+		else {
+			initialize( true );
+			if ( ! bag.isEmpty() ) {
+				bag.clear();
+				dirty();
+			}
+		}
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		throw new UnsupportedOperationException("Bags don't have indexes");
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		List sn = (List) getSnapshot();
+		return sn.get(i);
+	}
+
+	public int occurrences(Object o) {
+		read();
+		Iterator iter = bag.iterator();
+		int result=0;
+		while ( iter.hasNext() ) {
+			if ( o.equals( iter.next() ) ) result++;
+		}
+		return result;
+	}
+
+	// List OPERATIONS:
+
+	/**
+	 * @see java.util.List#add(int, Object)
+	 */
+	public void add(int i, Object o) {
+		write();
+		bag.add(i, o);
+	}
+
+	/**
+	 * @see java.util.List#addAll(int, Collection)
+	 */
+	public boolean addAll(int i, Collection c) {
+		if ( c.size()>0 ) {
+			write();
+			return bag.addAll(i, c);
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.List#get(int)
+	 */
+	public Object get(int i) {
+		read();
+		return bag.get(i);
+	}
+
+	/**
+	 * @see java.util.List#indexOf(Object)
+	 */
+	public int indexOf(Object o) {
+		read();
+		return bag.indexOf(o);
+	}
+
+	/**
+	 * @see java.util.List#lastIndexOf(Object)
+	 */
+	public int lastIndexOf(Object o) {
+		read();
+		return bag.lastIndexOf(o);
+	}
+
+	/**
+	 * @see java.util.List#listIterator()
+	 */
+	public ListIterator listIterator() {
+		read();
+		return new ListIteratorProxy( bag.listIterator() );
+	}
+
+	/**
+	 * @see java.util.List#listIterator(int)
+	 */
+	public ListIterator listIterator(int i) {
+		read();
+		return new ListIteratorProxy( bag.listIterator(i) );
+	}
+
+	/**
+	 * @see java.util.List#remove(int)
+	 */
+	public Object remove(int i) {
+		write();
+		return bag.remove(i);
+	}
+
+	/**
+	 * @see java.util.List#set(int, Object)
+	 */
+	public Object set(int i, Object o) {
+		write();
+		return bag.set(i, o);
+	}
+
+	/**
+	 * @see java.util.List#subList(int, int)
+	 */
+	public List subList(int start, int end) {
+		read();
+		return new ListProxy( bag.subList(start, end) );
+	}
+
+	public String toString() {
+		read();
+		return bag.toString();
+	}
+
+	/*public boolean equals(Object other) {
+		read();
+		return bag.equals(other);
+	}
+
+	public int hashCode(Object other) {
+		read();
+		return bag.hashCode();
+	}*/
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+	/**
+	 * Bag does not respect the collection API and do an
+	 * JVM instance comparison to do the equals.
+	 * The semantic is broken not to have to initialize a
+	 * collection for a simple equals() operation.
+	 * @see java.lang.Object#equals(java.lang.Object)
+	 */
+	public boolean equals(Object obj) {
+		return super.equals(obj);
+	}
+
+	/**
+	 * @see java.lang.Object#hashCode()
+	 */
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+	final class Clear implements DelayedOperation {
+		public void operate() {
+			bag.clear();
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
+		}
+	}
+
+	final class SimpleAdd implements DelayedOperation {
+		private Object value;
+
+		public SimpleAdd(Object value) {
+			this.value = value;
+		}
+		public void operate() {
+			bag.add(value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return null;
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,303 +0,0 @@
-//$Id: PersistentCollection.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * Persistent collections are treated as value objects by Hibernate.
- * ie. they have no independent existence beyond the object holding
- * a reference to them. Unlike instances of entity classes, they are
- * automatically deleted when unreferenced and automatically become
- * persistent when held by a persistent object. Collections can be
- * passed between different objects (change "roles") and this might
- * cause their elements to move from one database table to another.<br>
- * <br>
- * Hibernate "wraps" a java collection in an instance of
- * PersistentCollection. This mechanism is designed to support
- * tracking of changes to the collection's persistent state and
- * lazy instantiation of collection elements. The downside is that
- * only certain abstract collection types are supported and any
- * extra semantics are lost<br>
- * <br>
- * Applications should <em>never</em> use classes in this package
- * directly, unless extending the "framework" here.<br>
- * <br>
- * Changes to <em>structure</em> of the collection are recorded by the
- * collection calling back to the session. Changes to mutable
- * elements (ie. composite elements) are discovered by cloning their
- * state when the collection is initialized and comparing at flush
- * time.
- *
- * @author Gavin King
- */
-public interface PersistentCollection {
-	
-	/**
-	 * Get the owning entity. Note that the owner is only
-	 * set during the flush cycle, and when a new collection
-	 * wrapper is created while loading an entity.
-	 */
-	public Object getOwner();
-	/**
-	 * Set the reference to the owning entity
-	 */
-	public void setOwner(Object entity);
-	
-	/**
-	 * Is the collection empty? (don't try to initialize the collection)
-	 */
-	public boolean empty();
-
-	/**
-	 * After flushing, re-init snapshot state.
-	 */
-	public void setSnapshot(Serializable key, String role, Serializable snapshot);
-	
-	/**
-	 * After flushing, clear any "queued" additions, since the
-	 * database state is now synchronized with the memory state.
-	 */
-	public void postAction();
-	
-	/**
-	 * return the user-visible collection (or array) instance
-	 */
-	public Object getValue();
-
-	/**
-	 * Called just before reading any rows from the JDBC result set
-	 */
-	public void beginRead();
-
-	/**
-	 * Called after reading all rows from the JDBC result set
-	 */
-	public boolean endRead();
-	
-	/**
-	 * Called after initializing from cache
-	 */
-	public boolean afterInitialize();
-
-	/**
-	 * Could the application possibly have a direct reference to
-	 * the underlying collection implementation?
-	 */
-	public boolean isDirectlyAccessible();
-
-	/**
-	 * Disassociate this collection from the given session.
-	 * @return true if this was currently associated with the given session
-	 */
-	public boolean unsetSession(SessionImplementor currentSession);
-
-	/**
-	 * Associate the collection with the given session.
-	 * @return false if the collection was already associated with the session
-	 * @throws HibernateException if the collection was already associated
-	 * with another open session
-	 */
-	public boolean setCurrentSession(SessionImplementor session)
-			throws HibernateException;
-
-	/**
-	 * Read the state of the collection from a disassembled cached value
-	 */
-	public void initializeFromCache(CollectionPersister persister,
-			Serializable disassembled, Object owner) throws HibernateException;
-
-	/**
-	 * Iterate all collection entries, during update of the database
-	 */
-	public Iterator entries(CollectionPersister persister);
-
-	/**
-	 * Read a row from the JDBC result set
-	 */
-	public Object readFrom(ResultSet rs, CollectionPersister role, CollectionAliases descriptor, Object owner)
-			throws HibernateException, SQLException;
-
-	/**
-	 * Get the index of the given collection entry
-	 */
-	public Object getIdentifier(Object entry, int i);
-	
-	/**
-	 * Get the index of the given collection entry
-	 * @param persister it was more elegant before we added this...
-	 */
-	public Object getIndex(Object entry, int i, CollectionPersister persister);
-	
-	/**
-	 * Get the value of the given collection entry
-	 */
-	public Object getElement(Object entry);
-	
-	/**
-	 * Get the snapshot value of the given collection entry
-	 */
-	public Object getSnapshotElement(Object entry, int i);
-
-	/**
-	 * Called before any elements are read into the collection,
-	 * allowing appropriate initializations to occur.
-	 *
-	 * @param persister The underlying collection persister.
-	 * @param anticipatedSize The anticipated size of the collection after initilization is complete.
-	 */
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize);
-
-	/**
-	 * Does the current state exactly match the snapshot?
-	 */
-	public boolean equalsSnapshot(CollectionPersister persister) 
-		throws HibernateException;
-
-	/**
-	 * Is the snapshot empty?
-	 */
-	public boolean isSnapshotEmpty(Serializable snapshot);
-	
-	/**
-	 * Disassemble the collection, ready for the cache
-	 */
-	public Serializable disassemble(CollectionPersister persister)
-	throws HibernateException;
-
-	/**
-	 * Do we need to completely recreate this collection when it changes?
-	 */
-	public boolean needsRecreate(CollectionPersister persister);
-
-	/**
-	 * Return a new snapshot of the current state of the collection
-	 */
-	public Serializable getSnapshot(CollectionPersister persister)
-			throws HibernateException;
-
-	/**
-	 * To be called internally by the session, forcing
-	 * immediate initialization.
-	 */
-	public void forceInitialization() throws HibernateException;
-
-	/**
-	 * Does an element exist at this entry in the collection?
-	 */
-	public boolean entryExists(Object entry, int i); //note that i parameter is now unused (delete it?)
-
-	/**
-	 * Do we need to insert this element?
-	 */
-	public boolean needsInserting(Object entry, int i, Type elemType)
-			throws HibernateException;
-
-	/**
-	 * Do we need to update this element?
-	 */
-	public boolean needsUpdating(Object entry, int i, Type elemType)
-			throws HibernateException;
-	
-	public boolean isRowUpdatePossible();
-
-	/**
-	 * Get all the elements that need deleting
-	 */
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
-			throws HibernateException;
-
-	/**
-	 * Is this the wrapper for the given underlying collection instance?
-	 */
-	public boolean isWrapper(Object collection);
-
-	/**
-	 * Is this instance initialized?
-	 */
-	public boolean wasInitialized();
-
-	/**
-	 * Does this instance have any "queued" additions?
-	 */
-	public boolean hasQueuedOperations();
-
-	/**
-	 * Iterate the "queued" additions
-	 */
-	public Iterator queuedAdditionIterator();
-	
-	/**
-	 * Get the "queued" orphans
-	 */
-	public Collection getQueuedOrphans(String entityName);
-	
-	/**
-	 * Get the current collection key value
-	 */
-	public Serializable getKey();
-	
-	/**
-	 * Get the current role name
-	 */
-	public String getRole();
-	
-	/**
-	 * Is the collection unreferenced?
-	 */
-	public boolean isUnreferenced();
-	
-	/**
-	 * Is the collection dirty? Note that this is only
-	 * reliable during the flush cycle, after the 
-	 * collection elements are dirty checked against
-	 * the snapshot.
-	 */
-	public boolean isDirty();
-	
-	/**
-	 * Clear the dirty flag, after flushing changes
-	 * to the database.
-	 */
-	public void clearDirty();
-	
-	/**
-	 * Get the snapshot cached by the collection
-	 * instance
-	 */
-	public Serializable getStoredSnapshot();
-	
-	/**
-	 * Mark the collection as dirty
-	 */
-	public void dirty();
-	
-	/**
-	 * Called before inserting rows, to ensure that any surrogate keys
-	 * are fully generated
-	 */
-	public void preInsert(CollectionPersister persister)
-	throws HibernateException;
-
-	/**
-	 * Called after inserting a row, to fetch the natively generated id
-	 */
-	public void afterRowInsert(CollectionPersister persister, Object entry, int i) 
-	throws HibernateException;
-
-	/**
-	 * get all "orphaned" elements
-	 */
-	public Collection getOrphans(Serializable snapshot, String entityName)
-	throws HibernateException;
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,326 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * Persistent collections are treated as value objects by Hibernate.
+ * ie. they have no independent existence beyond the object holding
+ * a reference to them. Unlike instances of entity classes, they are
+ * automatically deleted when unreferenced and automatically become
+ * persistent when held by a persistent object. Collections can be
+ * passed between different objects (change "roles") and this might
+ * cause their elements to move from one database table to another.<br>
+ * <br>
+ * Hibernate "wraps" a java collection in an instance of
+ * PersistentCollection. This mechanism is designed to support
+ * tracking of changes to the collection's persistent state and
+ * lazy instantiation of collection elements. The downside is that
+ * only certain abstract collection types are supported and any
+ * extra semantics are lost<br>
+ * <br>
+ * Applications should <em>never</em> use classes in this package
+ * directly, unless extending the "framework" here.<br>
+ * <br>
+ * Changes to <em>structure</em> of the collection are recorded by the
+ * collection calling back to the session. Changes to mutable
+ * elements (ie. composite elements) are discovered by cloning their
+ * state when the collection is initialized and comparing at flush
+ * time.
+ *
+ * @author Gavin King
+ */
+public interface PersistentCollection {
+	
+	/**
+	 * Get the owning entity. Note that the owner is only
+	 * set during the flush cycle, and when a new collection
+	 * wrapper is created while loading an entity.
+	 */
+	public Object getOwner();
+	/**
+	 * Set the reference to the owning entity
+	 */
+	public void setOwner(Object entity);
+	
+	/**
+	 * Is the collection empty? (don't try to initialize the collection)
+	 */
+	public boolean empty();
+
+	/**
+	 * After flushing, re-init snapshot state.
+	 */
+	public void setSnapshot(Serializable key, String role, Serializable snapshot);
+	
+	/**
+	 * After flushing, clear any "queued" additions, since the
+	 * database state is now synchronized with the memory state.
+	 */
+	public void postAction();
+	
+	/**
+	 * return the user-visible collection (or array) instance
+	 */
+	public Object getValue();
+
+	/**
+	 * Called just before reading any rows from the JDBC result set
+	 */
+	public void beginRead();
+
+	/**
+	 * Called after reading all rows from the JDBC result set
+	 */
+	public boolean endRead();
+	
+	/**
+	 * Called after initializing from cache
+	 */
+	public boolean afterInitialize();
+
+	/**
+	 * Could the application possibly have a direct reference to
+	 * the underlying collection implementation?
+	 */
+	public boolean isDirectlyAccessible();
+
+	/**
+	 * Disassociate this collection from the given session.
+	 * @return true if this was currently associated with the given session
+	 */
+	public boolean unsetSession(SessionImplementor currentSession);
+
+	/**
+	 * Associate the collection with the given session.
+	 * @return false if the collection was already associated with the session
+	 * @throws HibernateException if the collection was already associated
+	 * with another open session
+	 */
+	public boolean setCurrentSession(SessionImplementor session)
+			throws HibernateException;
+
+	/**
+	 * Read the state of the collection from a disassembled cached value
+	 */
+	public void initializeFromCache(CollectionPersister persister,
+			Serializable disassembled, Object owner) throws HibernateException;
+
+	/**
+	 * Iterate all collection entries, during update of the database
+	 */
+	public Iterator entries(CollectionPersister persister);
+
+	/**
+	 * Read a row from the JDBC result set
+	 */
+	public Object readFrom(ResultSet rs, CollectionPersister role, CollectionAliases descriptor, Object owner)
+			throws HibernateException, SQLException;
+
+	/**
+	 * Get the index of the given collection entry
+	 */
+	public Object getIdentifier(Object entry, int i);
+	
+	/**
+	 * Get the index of the given collection entry
+	 * @param persister it was more elegant before we added this...
+	 */
+	public Object getIndex(Object entry, int i, CollectionPersister persister);
+	
+	/**
+	 * Get the value of the given collection entry
+	 */
+	public Object getElement(Object entry);
+	
+	/**
+	 * Get the snapshot value of the given collection entry
+	 */
+	public Object getSnapshotElement(Object entry, int i);
+
+	/**
+	 * Called before any elements are read into the collection,
+	 * allowing appropriate initializations to occur.
+	 *
+	 * @param persister The underlying collection persister.
+	 * @param anticipatedSize The anticipated size of the collection after initilization is complete.
+	 */
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize);
+
+	/**
+	 * Does the current state exactly match the snapshot?
+	 */
+	public boolean equalsSnapshot(CollectionPersister persister) 
+		throws HibernateException;
+
+	/**
+	 * Is the snapshot empty?
+	 */
+	public boolean isSnapshotEmpty(Serializable snapshot);
+	
+	/**
+	 * Disassemble the collection, ready for the cache
+	 */
+	public Serializable disassemble(CollectionPersister persister)
+	throws HibernateException;
+
+	/**
+	 * Do we need to completely recreate this collection when it changes?
+	 */
+	public boolean needsRecreate(CollectionPersister persister);
+
+	/**
+	 * Return a new snapshot of the current state of the collection
+	 */
+	public Serializable getSnapshot(CollectionPersister persister)
+			throws HibernateException;
+
+	/**
+	 * To be called internally by the session, forcing
+	 * immediate initialization.
+	 */
+	public void forceInitialization() throws HibernateException;
+
+	/**
+	 * Does an element exist at this entry in the collection?
+	 */
+	public boolean entryExists(Object entry, int i); //note that i parameter is now unused (delete it?)
+
+	/**
+	 * Do we need to insert this element?
+	 */
+	public boolean needsInserting(Object entry, int i, Type elemType)
+			throws HibernateException;
+
+	/**
+	 * Do we need to update this element?
+	 */
+	public boolean needsUpdating(Object entry, int i, Type elemType)
+			throws HibernateException;
+	
+	public boolean isRowUpdatePossible();
+
+	/**
+	 * Get all the elements that need deleting
+	 */
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
+			throws HibernateException;
+
+	/**
+	 * Is this the wrapper for the given underlying collection instance?
+	 */
+	public boolean isWrapper(Object collection);
+
+	/**
+	 * Is this instance initialized?
+	 */
+	public boolean wasInitialized();
+
+	/**
+	 * Does this instance have any "queued" additions?
+	 */
+	public boolean hasQueuedOperations();
+
+	/**
+	 * Iterate the "queued" additions
+	 */
+	public Iterator queuedAdditionIterator();
+	
+	/**
+	 * Get the "queued" orphans
+	 */
+	public Collection getQueuedOrphans(String entityName);
+	
+	/**
+	 * Get the current collection key value
+	 */
+	public Serializable getKey();
+	
+	/**
+	 * Get the current role name
+	 */
+	public String getRole();
+	
+	/**
+	 * Is the collection unreferenced?
+	 */
+	public boolean isUnreferenced();
+	
+	/**
+	 * Is the collection dirty? Note that this is only
+	 * reliable during the flush cycle, after the 
+	 * collection elements are dirty checked against
+	 * the snapshot.
+	 */
+	public boolean isDirty();
+	
+	/**
+	 * Clear the dirty flag, after flushing changes
+	 * to the database.
+	 */
+	public void clearDirty();
+	
+	/**
+	 * Get the snapshot cached by the collection
+	 * instance
+	 */
+	public Serializable getStoredSnapshot();
+	
+	/**
+	 * Mark the collection as dirty
+	 */
+	public void dirty();
+	
+	/**
+	 * Called before inserting rows, to ensure that any surrogate keys
+	 * are fully generated
+	 */
+	public void preInsert(CollectionPersister persister)
+	throws HibernateException;
+
+	/**
+	 * Called after inserting a row, to fetch the natively generated id
+	 */
+	public void afterRowInsert(CollectionPersister persister, Object entry, int i) 
+	throws HibernateException;
+
+	/**
+	 * get all "orphaned" elements
+	 */
+	public Collection getOrphans(Serializable snapshot, String entityName)
+	throws HibernateException;
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,209 +0,0 @@
-//$Id: PersistentElementHolder.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.dom4j.Element;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * A persistent wrapper for an XML element
- *
- * @author Gavin King
- */
-public class PersistentElementHolder extends AbstractPersistentCollection {
-	protected Element element;
-	
-	public PersistentElementHolder(SessionImplementor session, Element element) {
-		super(session);
-		this.element = element;
-		setInitialized();
-	}
-
-	public Serializable getSnapshot(CollectionPersister persister) 
-	throws HibernateException {
-		
-		final Type elementType = persister.getElementType();		
-		List elements = element.elements( persister.getElementNodeName() );
-		ArrayList snapshot = new ArrayList( elements.size() );
-		for ( int i=0; i<elements.size(); i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object value = elementType.fromXMLNode( elem, persister.getFactory() );
-			Object copy = elementType.deepCopy(value , getSession().getEntityMode(), persister.getFactory() );
-			snapshot.add(copy);
-		}
-		return snapshot;
-		
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) 
-	throws HibernateException {
-		//orphan delete not supported for EntityMode.DOM4J
-		return CollectionHelper.EMPTY_COLLECTION; 
-	}
-
-	public PersistentElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key) 
-	throws HibernateException {
-		super(session);
-		Element owner = (Element) session.getPersistenceContext().getCollectionOwner(key, persister);
-		if (owner==null) throw new AssertionFailure("null owner");
-		//element = XMLHelper.generateDom4jElement( persister.getNodeName() );
-		final String nodeName = persister.getNodeName();
-		if ( ".".equals(nodeName) ) {
-			element = owner;
-		}
-		else {
-			element = owner.element( nodeName );
-			if (element==null) element = owner.addElement( nodeName );
-		}
-	}
-
-	public boolean isWrapper(Object collection) {
-		return element==collection;
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		
-		ArrayList snapshot = (ArrayList) getSnapshot();
-		List elements = element.elements( persister.getElementNodeName() );
-		if ( snapshot.size()!= elements.size() ) return false;
-		for ( int i=0; i<snapshot.size(); i++ ) {
-			Object old = snapshot.get(i);
-			Element elem = (Element) elements.get(i);
-			Object current = elementType.fromXMLNode( elem, persister.getFactory() );
-			if ( elementType.isDirty( old, current, getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (Collection) snapshot ).isEmpty();
-	}
-	
-	public boolean empty() {
-		return !element.elementIterator().hasNext();
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-		Object object = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		final Type elementType = persister.getElementType();
-		Element subelement = element.addElement( persister.getElementNodeName() );
-		elementType.setToXMLNode( subelement, object, persister.getFactory() ); 
-		return object;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		
-		final Type elementType = persister.getElementType();
-		List elements =  element.elements( persister.getElementNodeName() );
-		int length = elements.size();
-		List result = new ArrayList(length);
-		for ( int i=0; i<length; i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-			result.add(object);
-		}
-		return result.iterator();
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
-
-	public boolean isDirectlyAccessible() {
-		return true;
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		Serializable[] cached = (Serializable[]) disassembled;
-		for ( int i=0; i<cached.length; i++ ) {
-			Object object = elementType.assemble( cached[i], getSession(), owner );
-			Element subelement = element.addElement( persister.getElementNodeName() );
-			elementType.setToXMLNode( subelement, object, persister.getFactory() );
-		}
-		
-	}
-
-	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		List elements =  element.elements( persister.getElementNodeName() );
-		int length = elements.size();
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-			result[i] = elementType.disassemble( object, getSession(), null );
-		}
-		return result;
-	}
-
-	public Object getValue() {
-		return element;
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
-	throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		ArrayList snapshot = (ArrayList) getSnapshot();
-		List elements = element.elements( persister.getElementNodeName() );
-		ArrayList result = new ArrayList();
-		for ( int i=0; i<snapshot.size(); i++ ) {
-			Object old = snapshot.get(i);
-			if ( i >= elements.size() ) {
-				result.add(old);
-			}
-			else {
-				Element elem = (Element) elements.get(i);
-				Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-				if ( elementType.isDirty( old, object, getSession() ) ) result.add(old);
-			}
-		}
-		return result.iterator();
-		
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elementType) 
-	throws HibernateException {
-		ArrayList snapshot = (ArrayList) getSnapshot();
-		return i>=snapshot.size() || elementType.isDirty( snapshot.get(i), entry, getSession() );
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elementType) 
-	throws HibernateException {
-		return false;
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		throw new UnsupportedOperationException();
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		throw new UnsupportedOperationException();
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,232 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.dom4j.Element;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * A persistent wrapper for an XML element
+ *
+ * @author Gavin King
+ */
+public class PersistentElementHolder extends AbstractPersistentCollection {
+	protected Element element;
+	
+	public PersistentElementHolder(SessionImplementor session, Element element) {
+		super(session);
+		this.element = element;
+		setInitialized();
+	}
+
+	public Serializable getSnapshot(CollectionPersister persister) 
+	throws HibernateException {
+		
+		final Type elementType = persister.getElementType();		
+		List elements = element.elements( persister.getElementNodeName() );
+		ArrayList snapshot = new ArrayList( elements.size() );
+		for ( int i=0; i<elements.size(); i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object value = elementType.fromXMLNode( elem, persister.getFactory() );
+			Object copy = elementType.deepCopy(value , getSession().getEntityMode(), persister.getFactory() );
+			snapshot.add(copy);
+		}
+		return snapshot;
+		
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) 
+	throws HibernateException {
+		//orphan delete not supported for EntityMode.DOM4J
+		return CollectionHelper.EMPTY_COLLECTION; 
+	}
+
+	public PersistentElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key) 
+	throws HibernateException {
+		super(session);
+		Element owner = (Element) session.getPersistenceContext().getCollectionOwner(key, persister);
+		if (owner==null) throw new AssertionFailure("null owner");
+		//element = XMLHelper.generateDom4jElement( persister.getNodeName() );
+		final String nodeName = persister.getNodeName();
+		if ( ".".equals(nodeName) ) {
+			element = owner;
+		}
+		else {
+			element = owner.element( nodeName );
+			if (element==null) element = owner.addElement( nodeName );
+		}
+	}
+
+	public boolean isWrapper(Object collection) {
+		return element==collection;
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		
+		ArrayList snapshot = (ArrayList) getSnapshot();
+		List elements = element.elements( persister.getElementNodeName() );
+		if ( snapshot.size()!= elements.size() ) return false;
+		for ( int i=0; i<snapshot.size(); i++ ) {
+			Object old = snapshot.get(i);
+			Element elem = (Element) elements.get(i);
+			Object current = elementType.fromXMLNode( elem, persister.getFactory() );
+			if ( elementType.isDirty( old, current, getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (Collection) snapshot ).isEmpty();
+	}
+	
+	public boolean empty() {
+		return !element.elementIterator().hasNext();
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+		Object object = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		final Type elementType = persister.getElementType();
+		Element subelement = element.addElement( persister.getElementNodeName() );
+		elementType.setToXMLNode( subelement, object, persister.getFactory() ); 
+		return object;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		
+		final Type elementType = persister.getElementType();
+		List elements =  element.elements( persister.getElementNodeName() );
+		int length = elements.size();
+		List result = new ArrayList(length);
+		for ( int i=0; i<length; i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+			result.add(object);
+		}
+		return result.iterator();
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
+
+	public boolean isDirectlyAccessible() {
+		return true;
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		Serializable[] cached = (Serializable[]) disassembled;
+		for ( int i=0; i<cached.length; i++ ) {
+			Object object = elementType.assemble( cached[i], getSession(), owner );
+			Element subelement = element.addElement( persister.getElementNodeName() );
+			elementType.setToXMLNode( subelement, object, persister.getFactory() );
+		}
+		
+	}
+
+	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		List elements =  element.elements( persister.getElementNodeName() );
+		int length = elements.size();
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+			result[i] = elementType.disassemble( object, getSession(), null );
+		}
+		return result;
+	}
+
+	public Object getValue() {
+		return element;
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
+	throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		ArrayList snapshot = (ArrayList) getSnapshot();
+		List elements = element.elements( persister.getElementNodeName() );
+		ArrayList result = new ArrayList();
+		for ( int i=0; i<snapshot.size(); i++ ) {
+			Object old = snapshot.get(i);
+			if ( i >= elements.size() ) {
+				result.add(old);
+			}
+			else {
+				Element elem = (Element) elements.get(i);
+				Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+				if ( elementType.isDirty( old, object, getSession() ) ) result.add(old);
+			}
+		}
+		return result.iterator();
+		
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elementType) 
+	throws HibernateException {
+		ArrayList snapshot = (ArrayList) getSnapshot();
+		return i>=snapshot.size() || elementType.isDirty( snapshot.get(i), entry, getSession() );
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elementType) 
+	throws HibernateException {
+		return false;
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,412 +0,0 @@
-//$Id: PersistentIdentifierBag.java 10738 2006-11-06 21:56:38Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * An <tt>IdentifierBag</tt> implements "bag" semantics more efficiently than
- * a regular <tt>Bag</tt> by adding a synthetic identifier column to the
- * table. This identifier is unique for all rows in the table, allowing very
- * efficient updates and deletes. The value of the identifier is never exposed
- * to the application.<br>
- * <br>
- * <tt>IdentifierBag</tt>s may not be used for a many-to-one association.
- * Furthermore, there is no reason to use <tt>inverse="true"</tt>.
- *
- * @author Gavin King
- */
-public class PersistentIdentifierBag extends AbstractPersistentCollection implements List {
-
-	protected List values; //element
-	protected Map identifiers; //index -> id
-
-	public PersistentIdentifierBag(SessionImplementor session) {
-		super(session);
-	}
-
-	public PersistentIdentifierBag() {} //needed for SOAP libraries, etc
-
-	public PersistentIdentifierBag(SessionImplementor session, Collection coll) {
-		super(session);
-		if (coll instanceof List) {
-			values = (List) coll;
-		}
-		else {
-			values = new ArrayList();
-			Iterator iter = coll.iterator();
-			while ( iter.hasNext() ) {
-				values.add( iter.next() );
-			}
-		}
-		setInitialized();
-		setDirectlyAccessible(true);
-		identifiers = new HashMap();
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] array = (Serializable[]) disassembled;
-		int size = array.length;
-		beforeInitialize( persister, size );
-		for ( int i = 0; i < size; i+=2 ) {
-			identifiers.put(
-				new Integer(i/2),
-				persister.getIdentifierType().assemble( array[i], getSession(), owner )
-			);
-			values.add( persister.getElementType().assemble( array[i+1], getSession(), owner ) );
-		}
-	}
-
-	public Object getIdentifier(Object entry, int i) {
-		return identifiers.get( new Integer(i) );
-	}
-
-	public boolean isWrapper(Object collection) {
-		return values==collection;
-	}
-
-	public boolean add(Object o) {
-		write();
-		values.add(o);
-		return true;
-	}
-
-	public void clear() {
-		initialize( true );
-		if ( ! values.isEmpty() || ! identifiers.isEmpty() ) {
-			values.clear();
-			identifiers.clear();
-			dirty();
-		}
-	}
-
-	public boolean contains(Object o) {
-		read();
-		return values.contains(o);
-	}
-
-	public boolean containsAll(Collection c) {
-		read();
-		return values.containsAll(c);
-	}
-
-	public boolean isEmpty() {
-		return readSize() ? getCachedSize()==0 : values.isEmpty();
-	}
-
-	public Iterator iterator() {
-		read();
-		return new IteratorProxy( values.iterator() );
-	}
-
-	public boolean remove(Object o) {
-		initialize( true );
-		int index = values.indexOf(o);
-		if (index>=0) {
-			beforeRemove(index);
-			values.remove(index);
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	public boolean removeAll(Collection c) {
-		if ( c.size() > 0 ) {
-			boolean result = false;
-			Iterator iter = c.iterator();
-			while ( iter.hasNext() ) {
-				if ( remove( iter.next() ) ) result=true;
-			}
-			return result;
-		}
-		else {
-			return false;
-		}
-	}
-
-	public boolean retainAll(Collection c) {
-		initialize( true );
-		if ( values.retainAll( c ) ) {
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	public int size() {
-		return readSize() ? getCachedSize() : values.size();
-	}
-
-	public Object[] toArray() {
-		read();
-		return values.toArray();
-	}
-
-	public Object[] toArray(Object[] a) {
-		read();
-		return values.toArray(a);
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		identifiers = anticipatedSize <= 0 ? new HashMap() : new HashMap( anticipatedSize + 1 + (int)( anticipatedSize * .75f ), .75f );
-		values = anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize );
-	}
-
-	public Serializable disassemble(CollectionPersister persister)
-			throws HibernateException {
-		Serializable[] result = new Serializable[ values.size() * 2 ];
-		int i=0;
-		for (int j=0; j< values.size(); j++) {
-			Object value = values.get(j);
-			result[i++] = persister.getIdentifierType().disassemble( identifiers.get( new Integer(j) ), getSession(), null );
-			result[i++] = persister.getElementType().disassemble( value, getSession(), null );
-		}
-		return result;
-	}
-
-	public boolean empty() {
-		return values.isEmpty();
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return values.iterator();
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		Map snap = (Map) getSnapshot();
-		if ( snap.size()!= values.size() ) return false;
-		for ( int i=0; i<values.size(); i++ ) {
-			Object value = values.get(i);
-			Object id = identifiers.get( new Integer(i) );
-			if (id==null) return false;
-			Object old = snap.get(id);
-			if ( elementType.isDirty( old, value, getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (Map) snapshot ).isEmpty();
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
-		Map snap = (Map) getSnapshot();
-		List deletes = new ArrayList( snap.keySet() );
-		for ( int i=0; i<values.size(); i++ ) {
-			if ( values.get(i)!=null ) deletes.remove( identifiers.get( new Integer(i) ) );
-		}
-		return deletes.iterator();
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		throw new UnsupportedOperationException("Bags don't have indexes");
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		Map snap = (Map) getSnapshot();
-		Object id = identifiers.get( new Integer(i) );
-		return snap.get(id);
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType)
-		throws HibernateException {
-
-		Map snap = (Map) getSnapshot();
-		Object id = identifiers.get( new Integer(i) );
-		return entry!=null && ( id==null || snap.get(id)==null );
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
-
-		if (entry==null) return false;
-		Map snap = (Map) getSnapshot();
-		Object id = identifiers.get( new Integer(i) );
-		if (id==null) return false;
-		Object old = snap.get(id);
-		return old!=null && elemType.isDirty( old, entry, getSession() );
-	}
-
-
-	public Object readFrom(
-		ResultSet rs,
-		CollectionPersister persister,
-		CollectionAliases descriptor,
-		Object owner)
-		throws HibernateException, SQLException {
-
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		Object old = identifiers.put(
-			new Integer( values.size() ),
-			persister.readIdentifier( rs, descriptor.getSuffixedIdentifierAlias(), getSession() )
-		);
-		if ( old==null ) values.add(element); //maintain correct duplication if loaded in a cartesian product
-		return element;
-	}
-
-	public Serializable getSnapshot(CollectionPersister persister)
-		throws HibernateException {
-
-		EntityMode entityMode = getSession().getEntityMode();
-
-		HashMap map = new HashMap( values.size() );
-		Iterator iter = values.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			Object value = iter.next();
-			map.put(
-				identifiers.get( new Integer(i++) ),
-				persister.getElementType().deepCopy(value, entityMode, persister.getFactory())
-			);
-		}
-		return map;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-		Map sn = (Map) snapshot;
-		return getOrphans( sn.values(), values, entityName, getSession() );
-	}
-
-	public void preInsert(CollectionPersister persister) throws HibernateException {
-		Iterator iter = values.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			Object entry = iter.next();
-			Integer loc = new Integer(i++);
-			if ( !identifiers.containsKey(loc) ) { //TODO: native ids
-				Serializable id = persister.getIdentifierGenerator().generate( getSession(), entry );
-				identifiers.put(loc, id);
-			}
-		}
-	}
-
-	public void add(int index, Object element) {
-		write();
-		beforeAdd(index);
-		values.add(index, element);
-	}
-
-	public boolean addAll(int index, Collection c) {
-		if ( c.size() > 0 ) {
-			Iterator iter = c.iterator();
-			while ( iter.hasNext() ) {
-				add( index++, iter.next() );
-			}
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	public Object get(int index) {
-		read();
-		return values.get(index);
-	}
-
-	public int indexOf(Object o) {
-		read();
-		return values.indexOf(o);
-	}
-
-	public int lastIndexOf(Object o) {
-		read();
-		return values.lastIndexOf(o);
-	}
-
-	public ListIterator listIterator() {
-		read();
-		return new ListIteratorProxy( values.listIterator() );
-	}
-
-	public ListIterator listIterator(int index) {
-		read();
-		return new ListIteratorProxy( values.listIterator(index) );
-	}
-
-	private void beforeRemove(int index) {
-		Object removedId = identifiers.get( new Integer(index) );
-		int last = values.size()-1;
-		for ( int i=index; i<last; i++ ) {
-			Object id = identifiers.get( new Integer(i+1) );
-	        if ( id==null ) {
-				identifiers.remove( new Integer(i) );
-	        }
-	        else {
-				identifiers.put( new Integer(i), id );
-	        }
-		}
-		identifiers.put( new Integer(last), removedId );
-	}
-
-	private void beforeAdd(int index) {
-		for ( int i=index; i<values.size(); i++ ) {
-			identifiers.put( new Integer(i+1), identifiers.get( new Integer(i) ) );
-		}
-		identifiers.remove( new Integer(index) );
-	}
-
-	public Object remove(int index) {
-		write();
-		beforeRemove(index);
-		return values.remove(index);
-	}
-
-	public Object set(int index, Object element) {
-		write();
-		return values.set(index, element);
-	}
-
-	public List subList(int fromIndex, int toIndex) {
-		read();
-		return new ListProxy( values.subList(fromIndex, toIndex) );
-	}
-
-	public boolean addAll(Collection c) {
-		if ( c.size()> 0 ) {
-			write();
-			return values.addAll(c);
-		}
-		else {
-			return false;
-		}
-	}
-
-	public void afterRowInsert(
-		CollectionPersister persister,
-		Object entry,
-		int i)
-		throws HibernateException {
-		//TODO: if we are using identity columns, fetch the identifier
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIdentifierBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,435 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * An <tt>IdentifierBag</tt> implements "bag" semantics more efficiently than
+ * a regular <tt>Bag</tt> by adding a synthetic identifier column to the
+ * table. This identifier is unique for all rows in the table, allowing very
+ * efficient updates and deletes. The value of the identifier is never exposed
+ * to the application.<br>
+ * <br>
+ * <tt>IdentifierBag</tt>s may not be used for a many-to-one association.
+ * Furthermore, there is no reason to use <tt>inverse="true"</tt>.
+ *
+ * @author Gavin King
+ */
+public class PersistentIdentifierBag extends AbstractPersistentCollection implements List {
+
+	protected List values; //element
+	protected Map identifiers; //index -> id
+
+	public PersistentIdentifierBag(SessionImplementor session) {
+		super(session);
+	}
+
+	public PersistentIdentifierBag() {} //needed for SOAP libraries, etc
+
+	public PersistentIdentifierBag(SessionImplementor session, Collection coll) {
+		super(session);
+		if (coll instanceof List) {
+			values = (List) coll;
+		}
+		else {
+			values = new ArrayList();
+			Iterator iter = coll.iterator();
+			while ( iter.hasNext() ) {
+				values.add( iter.next() );
+			}
+		}
+		setInitialized();
+		setDirectlyAccessible(true);
+		identifiers = new HashMap();
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] array = (Serializable[]) disassembled;
+		int size = array.length;
+		beforeInitialize( persister, size );
+		for ( int i = 0; i < size; i+=2 ) {
+			identifiers.put(
+				new Integer(i/2),
+				persister.getIdentifierType().assemble( array[i], getSession(), owner )
+			);
+			values.add( persister.getElementType().assemble( array[i+1], getSession(), owner ) );
+		}
+	}
+
+	public Object getIdentifier(Object entry, int i) {
+		return identifiers.get( new Integer(i) );
+	}
+
+	public boolean isWrapper(Object collection) {
+		return values==collection;
+	}
+
+	public boolean add(Object o) {
+		write();
+		values.add(o);
+		return true;
+	}
+
+	public void clear() {
+		initialize( true );
+		if ( ! values.isEmpty() || ! identifiers.isEmpty() ) {
+			values.clear();
+			identifiers.clear();
+			dirty();
+		}
+	}
+
+	public boolean contains(Object o) {
+		read();
+		return values.contains(o);
+	}
+
+	public boolean containsAll(Collection c) {
+		read();
+		return values.containsAll(c);
+	}
+
+	public boolean isEmpty() {
+		return readSize() ? getCachedSize()==0 : values.isEmpty();
+	}
+
+	public Iterator iterator() {
+		read();
+		return new IteratorProxy( values.iterator() );
+	}
+
+	public boolean remove(Object o) {
+		initialize( true );
+		int index = values.indexOf(o);
+		if (index>=0) {
+			beforeRemove(index);
+			values.remove(index);
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	public boolean removeAll(Collection c) {
+		if ( c.size() > 0 ) {
+			boolean result = false;
+			Iterator iter = c.iterator();
+			while ( iter.hasNext() ) {
+				if ( remove( iter.next() ) ) result=true;
+			}
+			return result;
+		}
+		else {
+			return false;
+		}
+	}
+
+	public boolean retainAll(Collection c) {
+		initialize( true );
+		if ( values.retainAll( c ) ) {
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	public int size() {
+		return readSize() ? getCachedSize() : values.size();
+	}
+
+	public Object[] toArray() {
+		read();
+		return values.toArray();
+	}
+
+	public Object[] toArray(Object[] a) {
+		read();
+		return values.toArray(a);
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		identifiers = anticipatedSize <= 0 ? new HashMap() : new HashMap( anticipatedSize + 1 + (int)( anticipatedSize * .75f ), .75f );
+		values = anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize );
+	}
+
+	public Serializable disassemble(CollectionPersister persister)
+			throws HibernateException {
+		Serializable[] result = new Serializable[ values.size() * 2 ];
+		int i=0;
+		for (int j=0; j< values.size(); j++) {
+			Object value = values.get(j);
+			result[i++] = persister.getIdentifierType().disassemble( identifiers.get( new Integer(j) ), getSession(), null );
+			result[i++] = persister.getElementType().disassemble( value, getSession(), null );
+		}
+		return result;
+	}
+
+	public boolean empty() {
+		return values.isEmpty();
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return values.iterator();
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		Map snap = (Map) getSnapshot();
+		if ( snap.size()!= values.size() ) return false;
+		for ( int i=0; i<values.size(); i++ ) {
+			Object value = values.get(i);
+			Object id = identifiers.get( new Integer(i) );
+			if (id==null) return false;
+			Object old = snap.get(id);
+			if ( elementType.isDirty( old, value, getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (Map) snapshot ).isEmpty();
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
+		Map snap = (Map) getSnapshot();
+		List deletes = new ArrayList( snap.keySet() );
+		for ( int i=0; i<values.size(); i++ ) {
+			if ( values.get(i)!=null ) deletes.remove( identifiers.get( new Integer(i) ) );
+		}
+		return deletes.iterator();
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		throw new UnsupportedOperationException("Bags don't have indexes");
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		Map snap = (Map) getSnapshot();
+		Object id = identifiers.get( new Integer(i) );
+		return snap.get(id);
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType)
+		throws HibernateException {
+
+		Map snap = (Map) getSnapshot();
+		Object id = identifiers.get( new Integer(i) );
+		return entry!=null && ( id==null || snap.get(id)==null );
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
+
+		if (entry==null) return false;
+		Map snap = (Map) getSnapshot();
+		Object id = identifiers.get( new Integer(i) );
+		if (id==null) return false;
+		Object old = snap.get(id);
+		return old!=null && elemType.isDirty( old, entry, getSession() );
+	}
+
+
+	public Object readFrom(
+		ResultSet rs,
+		CollectionPersister persister,
+		CollectionAliases descriptor,
+		Object owner)
+		throws HibernateException, SQLException {
+
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		Object old = identifiers.put(
+			new Integer( values.size() ),
+			persister.readIdentifier( rs, descriptor.getSuffixedIdentifierAlias(), getSession() )
+		);
+		if ( old==null ) values.add(element); //maintain correct duplication if loaded in a cartesian product
+		return element;
+	}
+
+	public Serializable getSnapshot(CollectionPersister persister)
+		throws HibernateException {
+
+		EntityMode entityMode = getSession().getEntityMode();
+
+		HashMap map = new HashMap( values.size() );
+		Iterator iter = values.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			Object value = iter.next();
+			map.put(
+				identifiers.get( new Integer(i++) ),
+				persister.getElementType().deepCopy(value, entityMode, persister.getFactory())
+			);
+		}
+		return map;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+		Map sn = (Map) snapshot;
+		return getOrphans( sn.values(), values, entityName, getSession() );
+	}
+
+	public void preInsert(CollectionPersister persister) throws HibernateException {
+		Iterator iter = values.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			Object entry = iter.next();
+			Integer loc = new Integer(i++);
+			if ( !identifiers.containsKey(loc) ) { //TODO: native ids
+				Serializable id = persister.getIdentifierGenerator().generate( getSession(), entry );
+				identifiers.put(loc, id);
+			}
+		}
+	}
+
+	public void add(int index, Object element) {
+		write();
+		beforeAdd(index);
+		values.add(index, element);
+	}
+
+	public boolean addAll(int index, Collection c) {
+		if ( c.size() > 0 ) {
+			Iterator iter = c.iterator();
+			while ( iter.hasNext() ) {
+				add( index++, iter.next() );
+			}
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	public Object get(int index) {
+		read();
+		return values.get(index);
+	}
+
+	public int indexOf(Object o) {
+		read();
+		return values.indexOf(o);
+	}
+
+	public int lastIndexOf(Object o) {
+		read();
+		return values.lastIndexOf(o);
+	}
+
+	public ListIterator listIterator() {
+		read();
+		return new ListIteratorProxy( values.listIterator() );
+	}
+
+	public ListIterator listIterator(int index) {
+		read();
+		return new ListIteratorProxy( values.listIterator(index) );
+	}
+
+	private void beforeRemove(int index) {
+		Object removedId = identifiers.get( new Integer(index) );
+		int last = values.size()-1;
+		for ( int i=index; i<last; i++ ) {
+			Object id = identifiers.get( new Integer(i+1) );
+	        if ( id==null ) {
+				identifiers.remove( new Integer(i) );
+	        }
+	        else {
+				identifiers.put( new Integer(i), id );
+	        }
+		}
+		identifiers.put( new Integer(last), removedId );
+	}
+
+	private void beforeAdd(int index) {
+		for ( int i=index; i<values.size(); i++ ) {
+			identifiers.put( new Integer(i+1), identifiers.get( new Integer(i) ) );
+		}
+		identifiers.remove( new Integer(index) );
+	}
+
+	public Object remove(int index) {
+		write();
+		beforeRemove(index);
+		return values.remove(index);
+	}
+
+	public Object set(int index, Object element) {
+		write();
+		return values.set(index, element);
+	}
+
+	public List subList(int fromIndex, int toIndex) {
+		read();
+		return new ListProxy( values.subList(fromIndex, toIndex) );
+	}
+
+	public boolean addAll(Collection c) {
+		if ( c.size()> 0 ) {
+			write();
+			return values.addAll(c);
+		}
+		else {
+			return false;
+		}
+	}
+
+	public void afterRowInsert(
+		CollectionPersister persister,
+		Object entry,
+		int i)
+		throws HibernateException {
+		//TODO: if we are using identity columns, fetch the identifier
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,228 +0,0 @@
-//$Id: PersistentIndexedElementHolder.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.NullableType;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * A persistent wrapper for an XML element
- *
- * @author Gavin King
- */
-public abstract class PersistentIndexedElementHolder extends AbstractPersistentCollection {
-	protected Element element;
-	
-	public PersistentIndexedElementHolder(SessionImplementor session, Element element) {
-		super(session);
-		this.element = element;
-		setInitialized();
-	}
-	
-	public static final class IndexedValue {
-		String index;
-		Object value;
-		IndexedValue(String index, Object value) {
-			this.index = index;
-			this.value = value;
-		}
-	}
-	
-	protected static String getIndex(Element element, String indexNodeName, int i) {
-		if (indexNodeName!=null) {
-			return element.attributeValue(indexNodeName);
-		}
-		else {
-			return Integer.toString(i);
-		}
-	}
-	
-	protected static void setIndex(Element element, String indexNodeName, String index) {
-		if (indexNodeName!=null) element.addAttribute(indexNodeName, index);
-	}
-	
-	protected static String getIndexAttributeName(CollectionPersister persister) {
-		String node = persister.getIndexNodeName();
-		return node==null ? null : node.substring(1);
-	}
-	
-	public Serializable getSnapshot(CollectionPersister persister) 
-	throws HibernateException {
-		
-		final Type elementType = persister.getElementType();
-		String indexNode = getIndexAttributeName(persister);		
-		List elements = element.elements( persister.getElementNodeName() );
-		HashMap snapshot = new HashMap( elements.size() );
-		for ( int i=0; i<elements.size(); i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object value = elementType.fromXMLNode( elem, persister.getFactory() );
-			Object copy = elementType.deepCopy( value, getSession().getEntityMode(), persister.getFactory() );
-			snapshot.put( getIndex(elem, indexNode, i), copy );
-		}
-		return snapshot;
-		
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) 
-	throws HibernateException {
-		//orphan delete not supported for EntityMode.DOM4J
-		return CollectionHelper.EMPTY_COLLECTION; 
-	}
-
-	public PersistentIndexedElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key) 
-	throws HibernateException {
-		super(session);
-		Element owner = (Element) session.getPersistenceContext().getCollectionOwner(key, persister);
-		if (owner==null) throw new AssertionFailure("null owner");
-		//element = XMLHelper.generateDom4jElement( persister.getNodeName() );
-		final String nodeName = persister.getNodeName();
-		if ( ".".equals(nodeName) ) {
-			element = owner;
-		}
-		else {
-			element = owner.element( nodeName );
-			if (element==null) element = owner.addElement( nodeName );
-		}
-	}
-
-	public boolean isWrapper(Object collection) {
-		return element==collection;
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		String indexNode = getIndexAttributeName(persister);		
-		HashMap snapshot = (HashMap) getSnapshot();
-		List elements = element.elements( persister.getElementNodeName() );
-		if ( snapshot.size()!= elements.size() ) return false;
-		for ( int i=0; i<snapshot.size(); i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object old = snapshot.get( getIndex(elem, indexNode, i) );
-			Object current = elementType.fromXMLNode( elem, persister.getFactory() );
-			if ( elementType.isDirty( old, current, getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (HashMap) snapshot ).isEmpty();
-	}
-	
-	public boolean empty() {
-		return !element.elementIterator().hasNext();
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-		Object object = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		final Type elementType = persister.getElementType();
-		final SessionFactoryImplementor factory = persister.getFactory();
-		String indexNode = getIndexAttributeName(persister);
-
-		Element elem = element.addElement( persister.getElementNodeName() );
-		elementType.setToXMLNode( elem, object, factory ); 
-		
-		final Type indexType = persister.getIndexType();
-		final Object indexValue = persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() );
-		final String index = ( (NullableType) indexType ).toXMLString( indexValue, factory );
-		setIndex(elem, indexNode, index);
-		return object;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		
-		final Type elementType = persister.getElementType();
-		String indexNode = getIndexAttributeName(persister);
-		List elements =  element.elements( persister.getElementNodeName() );
-		int length = elements.size();
-		List result = new ArrayList(length);
-		for ( int i=0; i<length; i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-			result.add( new IndexedValue( getIndex(elem, indexNode, i), object ) );
-		}
-		return result.iterator();
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
-
-	public boolean isDirectlyAccessible() {
-		return true;
-	}
-
-	public Object getValue() {
-		return element;
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
-	throws HibernateException {
-		
-		final Type indexType = persister.getIndexType();
-		HashMap snapshot = (HashMap) getSnapshot();
-		HashMap deletes = (HashMap) snapshot.clone();
-		deletes.keySet().removeAll( ( (HashMap) getSnapshot(persister) ).keySet() );
-		ArrayList deleteList = new ArrayList( deletes.size() );
-		Iterator iter = deletes.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			final Object object = indexIsFormula ?
-				me.getValue() :
-				( (NullableType) indexType ).fromXMLString( (String) me.getKey(), persister.getFactory() );
-			if (object!=null) deleteList.add(object);
-		}
-		
-		return deleteList.iterator();
-		
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elementType) 
-	throws HibernateException {
-		HashMap snapshot = (HashMap) getSnapshot();
-		IndexedValue iv = (IndexedValue) entry;
-		return iv.value!=null && snapshot.get( iv.index )==null;
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elementType) 
-	throws HibernateException {
-		HashMap snapshot = (HashMap) getSnapshot();
-		IndexedValue iv = (IndexedValue) entry;
-		Object old = snapshot.get( iv.index );
-		return old!=null && elementType.isDirty( old, iv.value, getSession() );
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		String index = ( (IndexedValue) entry ).index;
-		final Type indexType = persister.getIndexType();
-		return ( (NullableType) indexType ).fromXMLString( index, persister.getFactory() );
-	}
-
-	public Object getElement(Object entry) {
-		return ( (IndexedValue) entry ).value;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		return ( (HashMap) getSnapshot() ).get( ( (IndexedValue) entry ).index );
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentIndexedElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,251 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.NullableType;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * A persistent wrapper for an XML element
+ *
+ * @author Gavin King
+ */
+public abstract class PersistentIndexedElementHolder extends AbstractPersistentCollection {
+	protected Element element;
+	
+	public PersistentIndexedElementHolder(SessionImplementor session, Element element) {
+		super(session);
+		this.element = element;
+		setInitialized();
+	}
+	
+	public static final class IndexedValue {
+		String index;
+		Object value;
+		IndexedValue(String index, Object value) {
+			this.index = index;
+			this.value = value;
+		}
+	}
+	
+	protected static String getIndex(Element element, String indexNodeName, int i) {
+		if (indexNodeName!=null) {
+			return element.attributeValue(indexNodeName);
+		}
+		else {
+			return Integer.toString(i);
+		}
+	}
+	
+	protected static void setIndex(Element element, String indexNodeName, String index) {
+		if (indexNodeName!=null) element.addAttribute(indexNodeName, index);
+	}
+	
+	protected static String getIndexAttributeName(CollectionPersister persister) {
+		String node = persister.getIndexNodeName();
+		return node==null ? null : node.substring(1);
+	}
+	
+	public Serializable getSnapshot(CollectionPersister persister) 
+	throws HibernateException {
+		
+		final Type elementType = persister.getElementType();
+		String indexNode = getIndexAttributeName(persister);		
+		List elements = element.elements( persister.getElementNodeName() );
+		HashMap snapshot = new HashMap( elements.size() );
+		for ( int i=0; i<elements.size(); i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object value = elementType.fromXMLNode( elem, persister.getFactory() );
+			Object copy = elementType.deepCopy( value, getSession().getEntityMode(), persister.getFactory() );
+			snapshot.put( getIndex(elem, indexNode, i), copy );
+		}
+		return snapshot;
+		
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) 
+	throws HibernateException {
+		//orphan delete not supported for EntityMode.DOM4J
+		return CollectionHelper.EMPTY_COLLECTION; 
+	}
+
+	public PersistentIndexedElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key) 
+	throws HibernateException {
+		super(session);
+		Element owner = (Element) session.getPersistenceContext().getCollectionOwner(key, persister);
+		if (owner==null) throw new AssertionFailure("null owner");
+		//element = XMLHelper.generateDom4jElement( persister.getNodeName() );
+		final String nodeName = persister.getNodeName();
+		if ( ".".equals(nodeName) ) {
+			element = owner;
+		}
+		else {
+			element = owner.element( nodeName );
+			if (element==null) element = owner.addElement( nodeName );
+		}
+	}
+
+	public boolean isWrapper(Object collection) {
+		return element==collection;
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		String indexNode = getIndexAttributeName(persister);		
+		HashMap snapshot = (HashMap) getSnapshot();
+		List elements = element.elements( persister.getElementNodeName() );
+		if ( snapshot.size()!= elements.size() ) return false;
+		for ( int i=0; i<snapshot.size(); i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object old = snapshot.get( getIndex(elem, indexNode, i) );
+			Object current = elementType.fromXMLNode( elem, persister.getFactory() );
+			if ( elementType.isDirty( old, current, getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (HashMap) snapshot ).isEmpty();
+	}
+	
+	public boolean empty() {
+		return !element.elementIterator().hasNext();
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+		Object object = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		final Type elementType = persister.getElementType();
+		final SessionFactoryImplementor factory = persister.getFactory();
+		String indexNode = getIndexAttributeName(persister);
+
+		Element elem = element.addElement( persister.getElementNodeName() );
+		elementType.setToXMLNode( elem, object, factory ); 
+		
+		final Type indexType = persister.getIndexType();
+		final Object indexValue = persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() );
+		final String index = ( (NullableType) indexType ).toXMLString( indexValue, factory );
+		setIndex(elem, indexNode, index);
+		return object;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		
+		final Type elementType = persister.getElementType();
+		String indexNode = getIndexAttributeName(persister);
+		List elements =  element.elements( persister.getElementNodeName() );
+		int length = elements.size();
+		List result = new ArrayList(length);
+		for ( int i=0; i<length; i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+			result.add( new IndexedValue( getIndex(elem, indexNode, i), object ) );
+		}
+		return result.iterator();
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}
+
+	public boolean isDirectlyAccessible() {
+		return true;
+	}
+
+	public Object getValue() {
+		return element;
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
+	throws HibernateException {
+		
+		final Type indexType = persister.getIndexType();
+		HashMap snapshot = (HashMap) getSnapshot();
+		HashMap deletes = (HashMap) snapshot.clone();
+		deletes.keySet().removeAll( ( (HashMap) getSnapshot(persister) ).keySet() );
+		ArrayList deleteList = new ArrayList( deletes.size() );
+		Iterator iter = deletes.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			final Object object = indexIsFormula ?
+				me.getValue() :
+				( (NullableType) indexType ).fromXMLString( (String) me.getKey(), persister.getFactory() );
+			if (object!=null) deleteList.add(object);
+		}
+		
+		return deleteList.iterator();
+		
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elementType) 
+	throws HibernateException {
+		HashMap snapshot = (HashMap) getSnapshot();
+		IndexedValue iv = (IndexedValue) entry;
+		return iv.value!=null && snapshot.get( iv.index )==null;
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elementType) 
+	throws HibernateException {
+		HashMap snapshot = (HashMap) getSnapshot();
+		IndexedValue iv = (IndexedValue) entry;
+		Object old = snapshot.get( iv.index );
+		return old!=null && elementType.isDirty( old, iv.value, getSession() );
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		String index = ( (IndexedValue) entry ).index;
+		final Type indexType = persister.getIndexType();
+		return ( (NullableType) indexType ).fromXMLString( index, persister.getFactory() );
+	}
+
+	public Object getElement(Object entry) {
+		return ( (IndexedValue) entry ).value;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		return ( (HashMap) getSnapshot() ).get( ( (IndexedValue) entry ).index );
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentList.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,579 +0,0 @@
-//$Id: PersistentList.java 10738 2006-11-06 21:56:38Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.ListIterator;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * A persistent wrapper for a <tt>java.util.List</tt>. Underlying
- * collection is an <tt>ArrayList</tt>.
- *
- * @see java.util.ArrayList
- * @author Gavin King
- */
-public class PersistentList extends AbstractPersistentCollection implements List {
-
-	protected List list;
-
-	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
-
-		EntityMode entityMode = getSession().getEntityMode();
-
-		ArrayList clonedList = new ArrayList( list.size() );
-		Iterator iter = list.iterator();
-		while ( iter.hasNext() ) {
-			Object deepCopy = persister.getElementType()
-					.deepCopy( iter.next(), entityMode, persister.getFactory() );
-			clonedList.add( deepCopy );
-		}
-		return clonedList;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-		List sn = (List) snapshot;
-	    return getOrphans( sn, list, entityName, getSession() );
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		List sn = (List) getSnapshot();
-		if ( sn.size()!=this.list.size() ) return false;
-		Iterator iter = list.iterator();
-		Iterator sniter = sn.iterator();
-		while ( iter.hasNext() ) {
-			if ( elementType.isDirty( iter.next(), sniter.next(), getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (Collection) snapshot ).isEmpty();
-	}
-
-	public PersistentList(SessionImplementor session) {
-		super(session);
-	}
-
-	public PersistentList(SessionImplementor session, List list) {
-		super(session);
-		this.list = list;
-		setInitialized();
-		setDirectlyAccessible(true);
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		this.list = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
-	}
-
-	public boolean isWrapper(Object collection) {
-		return list==collection;
-	}
-
-	public PersistentList() {} //needed for SOAP libraries, etc
-
-	/**
-	 * @see java.util.List#size()
-	 */
-	public int size() {
-		return readSize() ? getCachedSize() : list.size();
-	}
-
-	/**
-	 * @see java.util.List#isEmpty()
-	 */
-	public boolean isEmpty() {
-		return readSize() ? getCachedSize()==0 : list.isEmpty();
-	}
-
-	/**
-	 * @see java.util.List#contains(Object)
-	 */
-	public boolean contains(Object object) {
-		Boolean exists = readElementExistence(object);
-		return exists==null ?
-				list.contains(object) :
-				exists.booleanValue();
-	}
-
-	/**
-	 * @see java.util.List#iterator()
-	 */
-	public Iterator iterator() {
-		read();
-		return new IteratorProxy( list.iterator() );
-	}
-
-	/**
-	 * @see java.util.List#toArray()
-	 */
-	public Object[] toArray() {
-		read();
-		return list.toArray();
-	}
-
-	/**
-	 * @see java.util.List#toArray(Object[])
-	 */
-	public Object[] toArray(Object[] array) {
-		read();
-		return list.toArray(array);
-	}
-
-	/**
-	 * @see java.util.List#add(Object)
-	 */
-	public boolean add(Object object) {
-		if ( !isOperationQueueEnabled() ) {
-			write();
-			return list.add(object);
-		}
-		else {
-			queueOperation( new SimpleAdd(object) );
-			return true;
-		}
-	}
-
-	/**
-	 * @see java.util.List#remove(Object)
-	 */
-	public boolean remove(Object value) {
-		Boolean exists = isPutQueueEnabled() ? readElementExistence(value) : null;
-		if ( exists == null ) {
-			initialize( true );
-			if ( list.remove( value ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else if ( exists.booleanValue() ) {
-			queueOperation( new SimpleRemove(value) );
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.List#containsAll(Collection)
-	 */
-	public boolean containsAll(Collection coll) {
-		read();
-		return list.containsAll(coll);
-	}
-
-	/**
-	 * @see java.util.List#addAll(Collection)
-	 */
-	public boolean addAll(Collection values) {
-		if ( values.size()==0 ) {
-			return false;
-		}
-		if ( !isOperationQueueEnabled() ) {
-			write();
-			return list.addAll(values);
-		}
-		else {
-			Iterator iter = values.iterator();
-			while ( iter.hasNext() ) {
-				queueOperation( new SimpleAdd( iter.next() ) );
-			}
-			return values.size()>0;
-		}
-	}
-
-	/**
-	 * @see java.util.List#addAll(int, Collection)
-	 */
-	public boolean addAll(int index, Collection coll) {
-		if ( coll.size()>0 ) {
-			write();
-			return list.addAll(index,  coll);
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.List#removeAll(Collection)
-	 */
-	public boolean removeAll(Collection coll) {
-		if ( coll.size()>0 ) {
-			initialize( true );
-			if ( list.removeAll( coll ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.List#retainAll(Collection)
-	 */
-	public boolean retainAll(Collection coll) {
-		initialize( true );
-		if ( list.retainAll( coll ) ) {
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.List#clear()
-	 */
-	public void clear() {
-		if ( isClearQueueEnabled() ) {
-			queueOperation( new Clear() );
-		}
-		else {
-			initialize( true );
-			if ( ! list.isEmpty() ) {
-				list.clear();
-				dirty();
-			}
-		}
-	}
-
-	/**
-	 * @see java.util.List#get(int)
-	 */
-	public Object get(int index) {
-		if (index<0) {
-			throw new ArrayIndexOutOfBoundsException("negative index");
-		}
-		Object result = readElementByIndex( new Integer(index) );
-		return result==UNKNOWN ? list.get(index) : result;
-	}
-
-	/**
-	 * @see java.util.List#set(int, Object)
-	 */
-	public Object set(int index, Object value) {
-		if (index<0) {
-			throw new ArrayIndexOutOfBoundsException("negative index");
-		}
-		Object old = isPutQueueEnabled() ? readElementByIndex( new Integer(index) ) : UNKNOWN;
-		if ( old==UNKNOWN ) {
-			write();
-			return list.set(index, value);
-		}
-		else {
-			queueOperation( new Set(index, value, old) );
-			return old;
-		}
-	}
-
-	/**
-	 * @see java.util.List#add(int, Object)
-	 */
-	public void add(int index, Object value) {
-		if (index<0) {
-			throw new ArrayIndexOutOfBoundsException("negative index");
-		}
-		if ( !isOperationQueueEnabled() ) {
-			write();
-			list.add(index, value);
-		}
-		else {
-			queueOperation( new Add(index, value) );
-		}
-	}
-
-	/**
-	 * @see java.util.List#remove(int)
-	 */
-	public Object remove(int index) {
-		if (index<0) {
-			throw new ArrayIndexOutOfBoundsException("negative index");
-		}
-		Object old = isPutQueueEnabled() ?
-				readElementByIndex( new Integer(index) ) : UNKNOWN;
-		if ( old==UNKNOWN ) {
-			write();
-			return list.remove(index);
-		}
-		else {
-			queueOperation( new Remove(index, old) );
-			return old;
-		}
-	}
-
-	/**
-	 * @see java.util.List#indexOf(Object)
-	 */
-	public int indexOf(Object value) {
-		read();
-		return list.indexOf(value);
-	}
-
-	/**
-	 * @see java.util.List#lastIndexOf(Object)
-	 */
-	public int lastIndexOf(Object value) {
-		read();
-		return list.lastIndexOf(value);
-	}
-
-	/**
-	 * @see java.util.List#listIterator()
-	 */
-	public ListIterator listIterator() {
-		read();
-		return new ListIteratorProxy( list.listIterator() );
-	}
-
-	/**
-	 * @see java.util.List#listIterator(int)
-	 */
-	public ListIterator listIterator(int index) {
-		read();
-		return new ListIteratorProxy( list.listIterator(index) );
-	}
-
-	/**
-	 * @see java.util.List#subList(int, int)
-	 */
-	public java.util.List subList(int from, int to) {
-		read();
-		return new ListProxy( list.subList(from, to) );
-	}
-
-	public boolean empty() {
-		return list.isEmpty();
-	}
-
-	public String toString() {
-		read();
-		return list.toString();
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
-		int index = ( (Integer) persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ) ).intValue();
-
-		//pad with nulls from the current last element up to the new index
-		for ( int i = list.size(); i<=index; i++) {
-			list.add(i, null);
-		}
-
-		list.set(index, element);
-		return element;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return list.iterator();
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] array = ( Serializable[] ) disassembled;
-		int size = array.length;
-		beforeInitialize( persister, size );
-		for ( int i = 0; i < size; i++ ) {
-			list.add( persister.getElementType().assemble( array[i], getSession(), owner ) );
-		}
-	}
-
-	public Serializable disassemble(CollectionPersister persister)
-	throws HibernateException {
-
-		int length = list.size();
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = persister.getElementType().disassemble( list.get(i), getSession(), null );
-		}
-		return result;
-	}
-
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
-		List deletes = new ArrayList();
-		List sn = (List) getSnapshot();
-		int end;
-		if ( sn.size() > list.size() ) {
-			for ( int i=list.size(); i<sn.size(); i++ ) {
-				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
-			}
-			end = list.size();
-		}
-		else {
-			end = sn.size();
-		}
-		for ( int i=0; i<end; i++ ) {
-			if ( list.get(i)==null && sn.get(i)!=null ) {
-				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
-			}
-		}
-		return deletes.iterator();
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
-		final List sn = (List) getSnapshot();
-		return list.get(i)!=null && ( i >= sn.size() || sn.get(i)==null );
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
-		final List sn = (List) getSnapshot();
-		return i<sn.size() && sn.get(i)!=null && list.get(i)!=null &&
-			elemType.isDirty( list.get(i), sn.get(i), getSession() );
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		return new Integer(i);
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		final List sn = (List) getSnapshot();
-		return sn.get(i);
-	}
-
-	public boolean equals(Object other) {
-		read();
-		return list.equals(other);
-	}
-
-	public int hashCode() {
-		read();
-		return list.hashCode();
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return entry!=null;
-	}
-
-	final class Clear implements DelayedOperation {
-		public void operate() {
-			list.clear();
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
-		}
-	}
-
-	final class SimpleAdd implements DelayedOperation {
-		private Object value;
-
-		public SimpleAdd(Object value) {
-			this.value = value;
-		}
-		public void operate() {
-			list.add(value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return null;
-		}
-	}
-
-	final class Add implements DelayedOperation {
-		private int index;
-		private Object value;
-
-		public Add(int index, Object value) {
-			this.index = index;
-			this.value = value;
-		}
-		public void operate() {
-			list.add(index, value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return null;
-		}
-	}
-
-	final class Set implements DelayedOperation {
-		private int index;
-		private Object value;
-		private Object old;
-
-		public Set(int index, Object value, Object old) {
-			this.index = index;
-			this.value = value;
-			this.old = old;
-		}
-		public void operate() {
-			list.set(index, value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return old;
-		}
-	}
-
-	final class Remove implements DelayedOperation {
-		private int index;
-		private Object old;
-
-		public Remove(int index, Object old) {
-			this.index = index;
-			this.old = old;
-		}
-		public void operate() {
-			list.remove(index);
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			return old;
-		}
-	}
-
-	final class SimpleRemove implements DelayedOperation {
-		private Object value;
-
-		public SimpleRemove(Object value) {
-			this.value = value;
-		}
-		public void operate() {
-			list.remove(value);
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			return value;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentList.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,602 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * A persistent wrapper for a <tt>java.util.List</tt>. Underlying
+ * collection is an <tt>ArrayList</tt>.
+ *
+ * @see java.util.ArrayList
+ * @author Gavin King
+ */
+public class PersistentList extends AbstractPersistentCollection implements List {
+
+	protected List list;
+
+	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
+
+		EntityMode entityMode = getSession().getEntityMode();
+
+		ArrayList clonedList = new ArrayList( list.size() );
+		Iterator iter = list.iterator();
+		while ( iter.hasNext() ) {
+			Object deepCopy = persister.getElementType()
+					.deepCopy( iter.next(), entityMode, persister.getFactory() );
+			clonedList.add( deepCopy );
+		}
+		return clonedList;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+		List sn = (List) snapshot;
+	    return getOrphans( sn, list, entityName, getSession() );
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		List sn = (List) getSnapshot();
+		if ( sn.size()!=this.list.size() ) return false;
+		Iterator iter = list.iterator();
+		Iterator sniter = sn.iterator();
+		while ( iter.hasNext() ) {
+			if ( elementType.isDirty( iter.next(), sniter.next(), getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (Collection) snapshot ).isEmpty();
+	}
+
+	public PersistentList(SessionImplementor session) {
+		super(session);
+	}
+
+	public PersistentList(SessionImplementor session, List list) {
+		super(session);
+		this.list = list;
+		setInitialized();
+		setDirectlyAccessible(true);
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		this.list = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
+	}
+
+	public boolean isWrapper(Object collection) {
+		return list==collection;
+	}
+
+	public PersistentList() {} //needed for SOAP libraries, etc
+
+	/**
+	 * @see java.util.List#size()
+	 */
+	public int size() {
+		return readSize() ? getCachedSize() : list.size();
+	}
+
+	/**
+	 * @see java.util.List#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return readSize() ? getCachedSize()==0 : list.isEmpty();
+	}
+
+	/**
+	 * @see java.util.List#contains(Object)
+	 */
+	public boolean contains(Object object) {
+		Boolean exists = readElementExistence(object);
+		return exists==null ?
+				list.contains(object) :
+				exists.booleanValue();
+	}
+
+	/**
+	 * @see java.util.List#iterator()
+	 */
+	public Iterator iterator() {
+		read();
+		return new IteratorProxy( list.iterator() );
+	}
+
+	/**
+	 * @see java.util.List#toArray()
+	 */
+	public Object[] toArray() {
+		read();
+		return list.toArray();
+	}
+
+	/**
+	 * @see java.util.List#toArray(Object[])
+	 */
+	public Object[] toArray(Object[] array) {
+		read();
+		return list.toArray(array);
+	}
+
+	/**
+	 * @see java.util.List#add(Object)
+	 */
+	public boolean add(Object object) {
+		if ( !isOperationQueueEnabled() ) {
+			write();
+			return list.add(object);
+		}
+		else {
+			queueOperation( new SimpleAdd(object) );
+			return true;
+		}
+	}
+
+	/**
+	 * @see java.util.List#remove(Object)
+	 */
+	public boolean remove(Object value) {
+		Boolean exists = isPutQueueEnabled() ? readElementExistence(value) : null;
+		if ( exists == null ) {
+			initialize( true );
+			if ( list.remove( value ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else if ( exists.booleanValue() ) {
+			queueOperation( new SimpleRemove(value) );
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.List#containsAll(Collection)
+	 */
+	public boolean containsAll(Collection coll) {
+		read();
+		return list.containsAll(coll);
+	}
+
+	/**
+	 * @see java.util.List#addAll(Collection)
+	 */
+	public boolean addAll(Collection values) {
+		if ( values.size()==0 ) {
+			return false;
+		}
+		if ( !isOperationQueueEnabled() ) {
+			write();
+			return list.addAll(values);
+		}
+		else {
+			Iterator iter = values.iterator();
+			while ( iter.hasNext() ) {
+				queueOperation( new SimpleAdd( iter.next() ) );
+			}
+			return values.size()>0;
+		}
+	}
+
+	/**
+	 * @see java.util.List#addAll(int, Collection)
+	 */
+	public boolean addAll(int index, Collection coll) {
+		if ( coll.size()>0 ) {
+			write();
+			return list.addAll(index,  coll);
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.List#removeAll(Collection)
+	 */
+	public boolean removeAll(Collection coll) {
+		if ( coll.size()>0 ) {
+			initialize( true );
+			if ( list.removeAll( coll ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.List#retainAll(Collection)
+	 */
+	public boolean retainAll(Collection coll) {
+		initialize( true );
+		if ( list.retainAll( coll ) ) {
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.List#clear()
+	 */
+	public void clear() {
+		if ( isClearQueueEnabled() ) {
+			queueOperation( new Clear() );
+		}
+		else {
+			initialize( true );
+			if ( ! list.isEmpty() ) {
+				list.clear();
+				dirty();
+			}
+		}
+	}
+
+	/**
+	 * @see java.util.List#get(int)
+	 */
+	public Object get(int index) {
+		if (index<0) {
+			throw new ArrayIndexOutOfBoundsException("negative index");
+		}
+		Object result = readElementByIndex( new Integer(index) );
+		return result==UNKNOWN ? list.get(index) : result;
+	}
+
+	/**
+	 * @see java.util.List#set(int, Object)
+	 */
+	public Object set(int index, Object value) {
+		if (index<0) {
+			throw new ArrayIndexOutOfBoundsException("negative index");
+		}
+		Object old = isPutQueueEnabled() ? readElementByIndex( new Integer(index) ) : UNKNOWN;
+		if ( old==UNKNOWN ) {
+			write();
+			return list.set(index, value);
+		}
+		else {
+			queueOperation( new Set(index, value, old) );
+			return old;
+		}
+	}
+
+	/**
+	 * @see java.util.List#add(int, Object)
+	 */
+	public void add(int index, Object value) {
+		if (index<0) {
+			throw new ArrayIndexOutOfBoundsException("negative index");
+		}
+		if ( !isOperationQueueEnabled() ) {
+			write();
+			list.add(index, value);
+		}
+		else {
+			queueOperation( new Add(index, value) );
+		}
+	}
+
+	/**
+	 * @see java.util.List#remove(int)
+	 */
+	public Object remove(int index) {
+		if (index<0) {
+			throw new ArrayIndexOutOfBoundsException("negative index");
+		}
+		Object old = isPutQueueEnabled() ?
+				readElementByIndex( new Integer(index) ) : UNKNOWN;
+		if ( old==UNKNOWN ) {
+			write();
+			return list.remove(index);
+		}
+		else {
+			queueOperation( new Remove(index, old) );
+			return old;
+		}
+	}
+
+	/**
+	 * @see java.util.List#indexOf(Object)
+	 */
+	public int indexOf(Object value) {
+		read();
+		return list.indexOf(value);
+	}
+
+	/**
+	 * @see java.util.List#lastIndexOf(Object)
+	 */
+	public int lastIndexOf(Object value) {
+		read();
+		return list.lastIndexOf(value);
+	}
+
+	/**
+	 * @see java.util.List#listIterator()
+	 */
+	public ListIterator listIterator() {
+		read();
+		return new ListIteratorProxy( list.listIterator() );
+	}
+
+	/**
+	 * @see java.util.List#listIterator(int)
+	 */
+	public ListIterator listIterator(int index) {
+		read();
+		return new ListIteratorProxy( list.listIterator(index) );
+	}
+
+	/**
+	 * @see java.util.List#subList(int, int)
+	 */
+	public java.util.List subList(int from, int to) {
+		read();
+		return new ListProxy( list.subList(from, to) );
+	}
+
+	public boolean empty() {
+		return list.isEmpty();
+	}
+
+	public String toString() {
+		read();
+		return list.toString();
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
+		int index = ( (Integer) persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ) ).intValue();
+
+		//pad with nulls from the current last element up to the new index
+		for ( int i = list.size(); i<=index; i++) {
+			list.add(i, null);
+		}
+
+		list.set(index, element);
+		return element;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return list.iterator();
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] array = ( Serializable[] ) disassembled;
+		int size = array.length;
+		beforeInitialize( persister, size );
+		for ( int i = 0; i < size; i++ ) {
+			list.add( persister.getElementType().assemble( array[i], getSession(), owner ) );
+		}
+	}
+
+	public Serializable disassemble(CollectionPersister persister)
+	throws HibernateException {
+
+		int length = list.size();
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = persister.getElementType().disassemble( list.get(i), getSession(), null );
+		}
+		return result;
+	}
+
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
+		List deletes = new ArrayList();
+		List sn = (List) getSnapshot();
+		int end;
+		if ( sn.size() > list.size() ) {
+			for ( int i=list.size(); i<sn.size(); i++ ) {
+				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
+			}
+			end = list.size();
+		}
+		else {
+			end = sn.size();
+		}
+		for ( int i=0; i<end; i++ ) {
+			if ( list.get(i)==null && sn.get(i)!=null ) {
+				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
+			}
+		}
+		return deletes.iterator();
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
+		final List sn = (List) getSnapshot();
+		return list.get(i)!=null && ( i >= sn.size() || sn.get(i)==null );
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
+		final List sn = (List) getSnapshot();
+		return i<sn.size() && sn.get(i)!=null && list.get(i)!=null &&
+			elemType.isDirty( list.get(i), sn.get(i), getSession() );
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		return new Integer(i);
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		final List sn = (List) getSnapshot();
+		return sn.get(i);
+	}
+
+	public boolean equals(Object other) {
+		read();
+		return list.equals(other);
+	}
+
+	public int hashCode() {
+		read();
+		return list.hashCode();
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return entry!=null;
+	}
+
+	final class Clear implements DelayedOperation {
+		public void operate() {
+			list.clear();
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
+		}
+	}
+
+	final class SimpleAdd implements DelayedOperation {
+		private Object value;
+
+		public SimpleAdd(Object value) {
+			this.value = value;
+		}
+		public void operate() {
+			list.add(value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return null;
+		}
+	}
+
+	final class Add implements DelayedOperation {
+		private int index;
+		private Object value;
+
+		public Add(int index, Object value) {
+			this.index = index;
+			this.value = value;
+		}
+		public void operate() {
+			list.add(index, value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return null;
+		}
+	}
+
+	final class Set implements DelayedOperation {
+		private int index;
+		private Object value;
+		private Object old;
+
+		public Set(int index, Object value, Object old) {
+			this.index = index;
+			this.value = value;
+			this.old = old;
+		}
+		public void operate() {
+			list.set(index, value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return old;
+		}
+	}
+
+	final class Remove implements DelayedOperation {
+		private int index;
+		private Object old;
+
+		public Remove(int index, Object old) {
+			this.index = index;
+			this.old = old;
+		}
+		public void operate() {
+			list.remove(index);
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			return old;
+		}
+	}
+
+	final class SimpleRemove implements DelayedOperation {
+		private Object value;
+
+		public SimpleRemove(Object value) {
+			this.value = value;
+		}
+		public void operate() {
+			list.remove(value);
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			return value;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-//$Id: PersistentListElementHolder.java 6838 2005-05-20 19:50:07Z oneovthafew $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.dom4j.Element;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class PersistentListElementHolder extends PersistentIndexedElementHolder {
-
-	public PersistentListElementHolder(SessionImplementor session, Element element) {
-		super( session, element );
-	}
-
-	public PersistentListElementHolder(SessionImplementor session, CollectionPersister persister,
-			Serializable key) throws HibernateException {
-		super( session, persister, key );
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		final String indexNodeName = getIndexAttributeName(persister);
-		Serializable[] cached = (Serializable[]) disassembled;
-		for ( int i=0; i<cached.length; i++ ) {
-			Object object = elementType.assemble( cached[i], getSession(), owner );
-			Element subelement = element.addElement( persister.getElementNodeName() );
-			elementType.setToXMLNode( subelement, object, persister.getFactory() );
-			setIndex( subelement, indexNodeName, Integer.toString(i) );
-		}
-		
-	}
-
-	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
-				
-		Type elementType = persister.getElementType();
-		final String indexNodeName = getIndexAttributeName(persister);
-		List elements =  element.elements( persister.getElementNodeName() );
-		int length = elements.size();
-		Serializable[] result = new Serializable[length];
-		for ( int i=0; i<length; i++ ) {
-			Element elem = (Element) elements.get(i);
-			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-			Integer index = (Integer) Hibernate.INTEGER.fromStringValue( getIndex(elem, indexNodeName, i) );
-			result[ index.intValue() ] = elementType.disassemble( object, getSession(), null );
-		}
-		return result;
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentListElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.dom4j.Element;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class PersistentListElementHolder extends PersistentIndexedElementHolder {
+
+	public PersistentListElementHolder(SessionImplementor session, Element element) {
+		super( session, element );
+	}
+
+	public PersistentListElementHolder(SessionImplementor session, CollectionPersister persister,
+			Serializable key) throws HibernateException {
+		super( session, persister, key );
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		final String indexNodeName = getIndexAttributeName(persister);
+		Serializable[] cached = (Serializable[]) disassembled;
+		for ( int i=0; i<cached.length; i++ ) {
+			Object object = elementType.assemble( cached[i], getSession(), owner );
+			Element subelement = element.addElement( persister.getElementNodeName() );
+			elementType.setToXMLNode( subelement, object, persister.getFactory() );
+			setIndex( subelement, indexNodeName, Integer.toString(i) );
+		}
+		
+	}
+
+	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
+				
+		Type elementType = persister.getElementType();
+		final String indexNodeName = getIndexAttributeName(persister);
+		List elements =  element.elements( persister.getElementNodeName() );
+		int length = elements.size();
+		Serializable[] result = new Serializable[length];
+		for ( int i=0; i<length; i++ ) {
+			Element elem = (Element) elements.get(i);
+			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+			Integer index = (Integer) Hibernate.INTEGER.fromStringValue( getIndex(elem, indexNodeName, i) );
+			result[ index.intValue() ] = elementType.disassemble( object, getSession(), null );
+		}
+		return result;
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentMap.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,491 +0,0 @@
-//$Id: PersistentMap.java 11255 2007-03-07 19:30:27Z steve.ebersole at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-
-/**
- * A persistent wrapper for a <tt>java.util.Map</tt>. Underlying collection
- * is a <tt>HashMap</tt>.
- *
- * @see java.util.HashMap
- * @author Gavin King
- */
-public class PersistentMap extends AbstractPersistentCollection implements Map {
-
-	protected Map map;
-
-	/**
-	 * Empty constructor.
-	 * <p/>
-	 * Note: this form is not ever ever ever used by Hibernate; it is, however,
-	 * needed for SOAP libraries and other such marshalling code.
-	 */
-	public PersistentMap() {
-		// intentionally empty
-	}
-
-	/**
-	 * Instantiates a lazy map (the underlying map is un-initialized).
-	 *
-	 * @param session The session to which this map will belong.
-	 */
-	public PersistentMap(SessionImplementor session) {
-		super(session);
-	}
-
-	/**
-	 * Instantiates a non-lazy map (the underlying map is constructed
-	 * from the incoming map reference).
-	 *
-	 * @param session The session to which this map will belong.
-	 * @param map The underlying map data.
-	 */
-	public PersistentMap(SessionImplementor session, Map map) {
-		super(session);
-		this.map = map;
-		setInitialized();
-		setDirectlyAccessible(true);
-	}
-
-	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
-		EntityMode entityMode = getSession().getEntityMode();
-		HashMap clonedMap = new HashMap( map.size() );
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry e = (Map.Entry) iter.next();
-			final Object copy = persister.getElementType()
-				.deepCopy( e.getValue(), entityMode, persister.getFactory() );
-			clonedMap.put( e.getKey(), copy );
-		}
-		return clonedMap;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-		Map sn = (Map) snapshot;
-		return getOrphans( sn.values(), map.values(), entityName, getSession() );
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		Map xmap = (Map) getSnapshot();
-		if ( xmap.size()!=this.map.size() ) return false;
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry entry = (Map.Entry) iter.next();
-			if ( elementType.isDirty( entry.getValue(), xmap.get( entry.getKey() ), getSession() ) ) return false;
-		}
-		return true;
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (Map) snapshot ).isEmpty();
-	}
-
-	public boolean isWrapper(Object collection) {
-		return map==collection;
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		this.map = ( Map ) persister.getCollectionType().instantiate( anticipatedSize );
-	}
-
-
-	/**
-	 * @see java.util.Map#size()
-	 */
-	public int size() {
-		return readSize() ? getCachedSize() : map.size();
-	}
-
-	/**
-	 * @see java.util.Map#isEmpty()
-	 */
-	public boolean isEmpty() {
-		return readSize() ? getCachedSize()==0 : map.isEmpty();
-	}
-
-	/**
-	 * @see java.util.Map#containsKey(Object)
-	 */
-	public boolean containsKey(Object key) {
-		Boolean exists = readIndexExistence(key);
-		return exists==null ? map.containsKey(key) : exists.booleanValue();
-	}
-
-	/**
-	 * @see java.util.Map#containsValue(Object)
-	 */
-	public boolean containsValue(Object value) {
-		Boolean exists = readElementExistence(value);
-		return exists==null ? 
-				map.containsValue(value) : 
-				exists.booleanValue();
-	}
-
-	/**
-	 * @see java.util.Map#get(Object)
-	 */
-	public Object get(Object key) {
-		Object result = readElementByIndex(key);
-		return result==UNKNOWN ? map.get(key) : result;
-	}
-
-	/**
-	 * @see java.util.Map#put(Object, Object)
-	 */
-	public Object put(Object key, Object value) {
-		if ( isPutQueueEnabled() ) {
-			Object old = readElementByIndex( key );
-			if ( old != UNKNOWN ) {
-				queueOperation( new Put( key, value, old ) );
-				return old;
-			}
-		}
-		initialize( true );
-		Object old = map.put( key, value );
-		// would be better to use the element-type to determine
-		// whether the old and the new are equal here; the problem being
-		// we do not necessarily have access to the element type in all
-		// cases
-		if ( value != old ) {
-			dirty();
-		}
-		return old;
-	}
-
-	/**
-	 * @see java.util.Map#remove(Object)
-	 */
-	public Object remove(Object key) {
-		if ( isPutQueueEnabled() ) {
-			Object old = readElementByIndex( key );
-			queueOperation( new Remove( key, old ) );
-			return old;
-		}
-		else {
-			// TODO : safe to interpret "map.remove(key) == null" as non-dirty?
-			initialize( true );
-			if ( map.containsKey( key ) ) {
-				dirty();
-			}
-			return map.remove( key );
-		}
-	}
-
-	/**
-	 * @see java.util.Map#putAll(java.util.Map puts)
-	 */
-	public void putAll(Map puts) {
-		if ( puts.size()>0 ) {
-			initialize( true );
-			Iterator itr = puts.entrySet().iterator();
-			while ( itr.hasNext() ) {
-				Map.Entry entry = ( Entry ) itr.next();
-				put( entry.getKey(), entry.getValue() );
-			}
-		}
-	}
-
-	/**
-	 * @see java.util.Map#clear()
-	 */
-	public void clear() {
-		if ( isClearQueueEnabled() ) {
-			queueOperation( new Clear() );
-		}
-		else {
-			initialize( true );
-			if ( ! map.isEmpty() ) {
-				dirty();
-				map.clear();
-			}
-		}
-	}
-
-	/**
-	 * @see java.util.Map#keySet()
-	 */
-	public Set keySet() {
-		read();
-		return new SetProxy( map.keySet() );
-	}
-
-	/**
-	 * @see java.util.Map#values()
-	 */
-	public Collection values() {
-		read();
-		return new SetProxy( map.values() );
-	}
-
-	/**
-	 * @see java.util.Map#entrySet()
-	 */
-	public Set entrySet() {
-		read();
-		return new EntrySetProxy( map.entrySet() );
-	}
-
-	public boolean empty() {
-		return map.isEmpty();
-	}
-
-	public String toString() {
-		read();
-		return map.toString();
-	}
-
-	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
-	throws HibernateException, SQLException {
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		Object index = persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() );
-		if ( element!=null ) map.put(index, element);
-		return element;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return map.entrySet().iterator();
-	}
-
-	/** a wrapper for Map.Entry sets */
-	class EntrySetProxy implements Set {
-		private final Set set;
-		EntrySetProxy(Set set) {
-			this.set=set;
-		}
-		public boolean add(Object entry) {
-			//write(); -- doesn't
-			return set.add(entry);
-		}
-		public boolean addAll(Collection entries) {
-			//write(); -- doesn't
-			return set.addAll(entries);
-		}
-		public void clear() {
-			write();
-			set.clear();
-		}
-		public boolean contains(Object entry) {
-			return set.contains(entry);
-		}
-		public boolean containsAll(Collection entries) {
-			return set.containsAll(entries);
-		}
-		public boolean isEmpty() {
-			return set.isEmpty();
-		}
-		public Iterator iterator() {
-			return new EntryIteratorProxy( set.iterator() );
-		}
-		public boolean remove(Object entry) {
-			write();
-			return set.remove(entry);
-		}
-		public boolean removeAll(Collection entries) {
-			write();
-			return set.removeAll(entries);
-		}
-		public boolean retainAll(Collection entries) {
-			write();
-			return set.retainAll(entries);
-		}
-		public int size() {
-			return set.size();
-		}
-		// amazingly, these two will work because AbstractCollection
-		// uses iterator() to fill the array
-		public Object[] toArray() {
-			return set.toArray();
-		}
-		public Object[] toArray(Object[] array) {
-			return set.toArray(array);
-		}
-	}
-	final class EntryIteratorProxy implements Iterator {
-		private final Iterator iter;
-		EntryIteratorProxy(Iterator iter) {
-			this.iter=iter;
-		}
-		public boolean hasNext() {
-			return iter.hasNext();
-		}
-		public Object next() {
-			return new MapEntryProxy( (Map.Entry) iter.next() );
-		}
-		public void remove() {
-			write();
-			iter.remove();
-		}
-	}
-
-	final class MapEntryProxy implements Map.Entry {
-		private final Map.Entry me;
-		MapEntryProxy( Map.Entry me ) {
-			this.me = me;
-		}
-		public Object getKey() { return me.getKey(); }
-		public Object getValue() { return me.getValue(); }
-		public boolean equals(Object o) { return me.equals(o); }
-		public int hashCode() { return me.hashCode(); }
-		// finally, what it's all about...
-		public Object setValue(Object value) {
-			write();
-			return me.setValue(value);
-		}
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] array = ( Serializable[] ) disassembled;
-		int size = array.length;
-		beforeInitialize( persister, size );
-		for ( int i = 0; i < size; i+=2 ) {
-			map.put(
-					persister.getIndexType().assemble( array[i], getSession(), owner ),
-					persister.getElementType().assemble( array[i+1], getSession(), owner )
-				);
-		}
-	}
-
-	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
-
-		Serializable[] result = new Serializable[ map.size() * 2 ];
-		Iterator iter = map.entrySet().iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			Map.Entry e = (Map.Entry) iter.next();
-			result[i++] = persister.getIndexType().disassemble( e.getKey(), getSession(), null );
-			result[i++] = persister.getElementType().disassemble( e.getValue(), getSession(), null );
-		}
-		return result;
-
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
-	throws HibernateException {
-		List deletes = new ArrayList();
-		Iterator iter = ( (Map) getSnapshot() ).entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry e = (Map.Entry) iter.next();
-			Object key = e.getKey();
-			if ( e.getValue()!=null && map.get(key)==null ) {
-				deletes.add( indexIsFormula ? e.getValue() : key );
-			}
-		}
-		return deletes.iterator();
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType) 
-	throws HibernateException {
-		final Map sn = (Map) getSnapshot();
-		Map.Entry e = (Map.Entry) entry;
-		return e.getValue()!=null && sn.get( e.getKey() )==null;
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) 
-	throws HibernateException {
-		final Map sn = (Map) getSnapshot();
-		Map.Entry e = (Map.Entry) entry;
-		Object snValue = sn.get( e.getKey() );
-		return e.getValue()!=null &&
-			snValue!=null &&
-			elemType.isDirty( snValue, e.getValue(), getSession() );
-	}
-
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		return ( (Map.Entry) entry ).getKey();
-	}
-
-	public Object getElement(Object entry) {
-		return ( (Map.Entry) entry ).getValue();
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		final Map sn = (Map) getSnapshot();
-		return sn.get( ( (Map.Entry) entry ).getKey() );
-	}
-
-	public boolean equals(Object other) {
-		read();
-		return map.equals(other);
-	}
-
-	public int hashCode() {
-		read();
-		return map.hashCode();
-	}
-
-	public boolean entryExists(Object entry, int i) {
-		return ( (Map.Entry) entry ).getValue()!=null;
-	}
-
-	final class Clear implements DelayedOperation {
-		public void operate() {
-			map.clear();
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
-		}
-	}
-
-	final class Put implements DelayedOperation {
-		private Object index;
-		private Object value;
-		private Object old;
-		
-		public Put(Object index, Object value, Object old) {
-			this.index = index;
-			this.value = value;
-			this.old = old;
-		}
-		public void operate() {
-			map.put(index, value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return old;
-		}
-	}
-
-	final class Remove implements DelayedOperation {
-		private Object index;
-		private Object old;
-		
-		public Remove(Object index, Object old) {
-			this.index = index;
-			this.old = old;
-		}
-		public void operate() {
-			map.remove(index);
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			return old;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentMap.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,514 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+
+/**
+ * A persistent wrapper for a <tt>java.util.Map</tt>. Underlying collection
+ * is a <tt>HashMap</tt>.
+ *
+ * @see java.util.HashMap
+ * @author Gavin King
+ */
+public class PersistentMap extends AbstractPersistentCollection implements Map {
+
+	protected Map map;
+
+	/**
+	 * Empty constructor.
+	 * <p/>
+	 * Note: this form is not ever ever ever used by Hibernate; it is, however,
+	 * needed for SOAP libraries and other such marshalling code.
+	 */
+	public PersistentMap() {
+		// intentionally empty
+	}
+
+	/**
+	 * Instantiates a lazy map (the underlying map is un-initialized).
+	 *
+	 * @param session The session to which this map will belong.
+	 */
+	public PersistentMap(SessionImplementor session) {
+		super(session);
+	}
+
+	/**
+	 * Instantiates a non-lazy map (the underlying map is constructed
+	 * from the incoming map reference).
+	 *
+	 * @param session The session to which this map will belong.
+	 * @param map The underlying map data.
+	 */
+	public PersistentMap(SessionImplementor session, Map map) {
+		super(session);
+		this.map = map;
+		setInitialized();
+		setDirectlyAccessible(true);
+	}
+
+	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
+		EntityMode entityMode = getSession().getEntityMode();
+		HashMap clonedMap = new HashMap( map.size() );
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry e = (Map.Entry) iter.next();
+			final Object copy = persister.getElementType()
+				.deepCopy( e.getValue(), entityMode, persister.getFactory() );
+			clonedMap.put( e.getKey(), copy );
+		}
+		return clonedMap;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+		Map sn = (Map) snapshot;
+		return getOrphans( sn.values(), map.values(), entityName, getSession() );
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		Map xmap = (Map) getSnapshot();
+		if ( xmap.size()!=this.map.size() ) return false;
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry entry = (Map.Entry) iter.next();
+			if ( elementType.isDirty( entry.getValue(), xmap.get( entry.getKey() ), getSession() ) ) return false;
+		}
+		return true;
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (Map) snapshot ).isEmpty();
+	}
+
+	public boolean isWrapper(Object collection) {
+		return map==collection;
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		this.map = ( Map ) persister.getCollectionType().instantiate( anticipatedSize );
+	}
+
+
+	/**
+	 * @see java.util.Map#size()
+	 */
+	public int size() {
+		return readSize() ? getCachedSize() : map.size();
+	}
+
+	/**
+	 * @see java.util.Map#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return readSize() ? getCachedSize()==0 : map.isEmpty();
+	}
+
+	/**
+	 * @see java.util.Map#containsKey(Object)
+	 */
+	public boolean containsKey(Object key) {
+		Boolean exists = readIndexExistence(key);
+		return exists==null ? map.containsKey(key) : exists.booleanValue();
+	}
+
+	/**
+	 * @see java.util.Map#containsValue(Object)
+	 */
+	public boolean containsValue(Object value) {
+		Boolean exists = readElementExistence(value);
+		return exists==null ? 
+				map.containsValue(value) : 
+				exists.booleanValue();
+	}
+
+	/**
+	 * @see java.util.Map#get(Object)
+	 */
+	public Object get(Object key) {
+		Object result = readElementByIndex(key);
+		return result==UNKNOWN ? map.get(key) : result;
+	}
+
+	/**
+	 * @see java.util.Map#put(Object, Object)
+	 */
+	public Object put(Object key, Object value) {
+		if ( isPutQueueEnabled() ) {
+			Object old = readElementByIndex( key );
+			if ( old != UNKNOWN ) {
+				queueOperation( new Put( key, value, old ) );
+				return old;
+			}
+		}
+		initialize( true );
+		Object old = map.put( key, value );
+		// would be better to use the element-type to determine
+		// whether the old and the new are equal here; the problem being
+		// we do not necessarily have access to the element type in all
+		// cases
+		if ( value != old ) {
+			dirty();
+		}
+		return old;
+	}
+
+	/**
+	 * @see java.util.Map#remove(Object)
+	 */
+	public Object remove(Object key) {
+		if ( isPutQueueEnabled() ) {
+			Object old = readElementByIndex( key );
+			queueOperation( new Remove( key, old ) );
+			return old;
+		}
+		else {
+			// TODO : safe to interpret "map.remove(key) == null" as non-dirty?
+			initialize( true );
+			if ( map.containsKey( key ) ) {
+				dirty();
+			}
+			return map.remove( key );
+		}
+	}
+
+	/**
+	 * @see java.util.Map#putAll(java.util.Map puts)
+	 */
+	public void putAll(Map puts) {
+		if ( puts.size()>0 ) {
+			initialize( true );
+			Iterator itr = puts.entrySet().iterator();
+			while ( itr.hasNext() ) {
+				Map.Entry entry = ( Entry ) itr.next();
+				put( entry.getKey(), entry.getValue() );
+			}
+		}
+	}
+
+	/**
+	 * @see java.util.Map#clear()
+	 */
+	public void clear() {
+		if ( isClearQueueEnabled() ) {
+			queueOperation( new Clear() );
+		}
+		else {
+			initialize( true );
+			if ( ! map.isEmpty() ) {
+				dirty();
+				map.clear();
+			}
+		}
+	}
+
+	/**
+	 * @see java.util.Map#keySet()
+	 */
+	public Set keySet() {
+		read();
+		return new SetProxy( map.keySet() );
+	}
+
+	/**
+	 * @see java.util.Map#values()
+	 */
+	public Collection values() {
+		read();
+		return new SetProxy( map.values() );
+	}
+
+	/**
+	 * @see java.util.Map#entrySet()
+	 */
+	public Set entrySet() {
+		read();
+		return new EntrySetProxy( map.entrySet() );
+	}
+
+	public boolean empty() {
+		return map.isEmpty();
+	}
+
+	public String toString() {
+		read();
+		return map.toString();
+	}
+
+	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
+	throws HibernateException, SQLException {
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		Object index = persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() );
+		if ( element!=null ) map.put(index, element);
+		return element;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return map.entrySet().iterator();
+	}
+
+	/** a wrapper for Map.Entry sets */
+	class EntrySetProxy implements Set {
+		private final Set set;
+		EntrySetProxy(Set set) {
+			this.set=set;
+		}
+		public boolean add(Object entry) {
+			//write(); -- doesn't
+			return set.add(entry);
+		}
+		public boolean addAll(Collection entries) {
+			//write(); -- doesn't
+			return set.addAll(entries);
+		}
+		public void clear() {
+			write();
+			set.clear();
+		}
+		public boolean contains(Object entry) {
+			return set.contains(entry);
+		}
+		public boolean containsAll(Collection entries) {
+			return set.containsAll(entries);
+		}
+		public boolean isEmpty() {
+			return set.isEmpty();
+		}
+		public Iterator iterator() {
+			return new EntryIteratorProxy( set.iterator() );
+		}
+		public boolean remove(Object entry) {
+			write();
+			return set.remove(entry);
+		}
+		public boolean removeAll(Collection entries) {
+			write();
+			return set.removeAll(entries);
+		}
+		public boolean retainAll(Collection entries) {
+			write();
+			return set.retainAll(entries);
+		}
+		public int size() {
+			return set.size();
+		}
+		// amazingly, these two will work because AbstractCollection
+		// uses iterator() to fill the array
+		public Object[] toArray() {
+			return set.toArray();
+		}
+		public Object[] toArray(Object[] array) {
+			return set.toArray(array);
+		}
+	}
+	final class EntryIteratorProxy implements Iterator {
+		private final Iterator iter;
+		EntryIteratorProxy(Iterator iter) {
+			this.iter=iter;
+		}
+		public boolean hasNext() {
+			return iter.hasNext();
+		}
+		public Object next() {
+			return new MapEntryProxy( (Map.Entry) iter.next() );
+		}
+		public void remove() {
+			write();
+			iter.remove();
+		}
+	}
+
+	final class MapEntryProxy implements Map.Entry {
+		private final Map.Entry me;
+		MapEntryProxy( Map.Entry me ) {
+			this.me = me;
+		}
+		public Object getKey() { return me.getKey(); }
+		public Object getValue() { return me.getValue(); }
+		public boolean equals(Object o) { return me.equals(o); }
+		public int hashCode() { return me.hashCode(); }
+		// finally, what it's all about...
+		public Object setValue(Object value) {
+			write();
+			return me.setValue(value);
+		}
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] array = ( Serializable[] ) disassembled;
+		int size = array.length;
+		beforeInitialize( persister, size );
+		for ( int i = 0; i < size; i+=2 ) {
+			map.put(
+					persister.getIndexType().assemble( array[i], getSession(), owner ),
+					persister.getElementType().assemble( array[i+1], getSession(), owner )
+				);
+		}
+	}
+
+	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
+
+		Serializable[] result = new Serializable[ map.size() * 2 ];
+		Iterator iter = map.entrySet().iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			Map.Entry e = (Map.Entry) iter.next();
+			result[i++] = persister.getIndexType().disassemble( e.getKey(), getSession(), null );
+			result[i++] = persister.getElementType().disassemble( e.getValue(), getSession(), null );
+		}
+		return result;
+
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 
+	throws HibernateException {
+		List deletes = new ArrayList();
+		Iterator iter = ( (Map) getSnapshot() ).entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry e = (Map.Entry) iter.next();
+			Object key = e.getKey();
+			if ( e.getValue()!=null && map.get(key)==null ) {
+				deletes.add( indexIsFormula ? e.getValue() : key );
+			}
+		}
+		return deletes.iterator();
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType) 
+	throws HibernateException {
+		final Map sn = (Map) getSnapshot();
+		Map.Entry e = (Map.Entry) entry;
+		return e.getValue()!=null && sn.get( e.getKey() )==null;
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) 
+	throws HibernateException {
+		final Map sn = (Map) getSnapshot();
+		Map.Entry e = (Map.Entry) entry;
+		Object snValue = sn.get( e.getKey() );
+		return e.getValue()!=null &&
+			snValue!=null &&
+			elemType.isDirty( snValue, e.getValue(), getSession() );
+	}
+
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		return ( (Map.Entry) entry ).getKey();
+	}
+
+	public Object getElement(Object entry) {
+		return ( (Map.Entry) entry ).getValue();
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		final Map sn = (Map) getSnapshot();
+		return sn.get( ( (Map.Entry) entry ).getKey() );
+	}
+
+	public boolean equals(Object other) {
+		read();
+		return map.equals(other);
+	}
+
+	public int hashCode() {
+		read();
+		return map.hashCode();
+	}
+
+	public boolean entryExists(Object entry, int i) {
+		return ( (Map.Entry) entry ).getValue()!=null;
+	}
+
+	final class Clear implements DelayedOperation {
+		public void operate() {
+			map.clear();
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
+		}
+	}
+
+	final class Put implements DelayedOperation {
+		private Object index;
+		private Object value;
+		private Object old;
+		
+		public Put(Object index, Object value, Object old) {
+			this.index = index;
+			this.value = value;
+			this.old = old;
+		}
+		public void operate() {
+			map.put(index, value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return old;
+		}
+	}
+
+	final class Remove implements DelayedOperation {
+		private Object index;
+		private Object old;
+		
+		public Remove(Object index, Object old) {
+			this.index = index;
+			this.old = old;
+		}
+		public void operate() {
+			map.remove(index);
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			return old;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-//$Id: PersistentMapElementHolder.java 6838 2005-05-20 19:50:07Z oneovthafew $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.util.List;
-
-import org.dom4j.Element;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.NullableType;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class PersistentMapElementHolder extends PersistentIndexedElementHolder {
-
-	public PersistentMapElementHolder(SessionImplementor session, Element element) {
-		super( session, element );
-	}
-
-	public PersistentMapElementHolder(SessionImplementor session, CollectionPersister persister,
-			Serializable key) throws HibernateException {
-		super( session, persister, key );
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		Type indexType = persister.getIndexType();
-		final String indexNodeName = getIndexAttributeName(persister);
-
-		Serializable[] cached = (Serializable[]) disassembled;
-
-		for ( int i=0; i<cached.length; ) {
-			Object index = indexType.assemble( cached[i++], getSession(), owner );
-			Object object = elementType.assemble( cached[i++], getSession(), owner );
-			
-			Element subelement = element.addElement( persister.getElementNodeName() );
-			elementType.setToXMLNode( subelement, object, persister.getFactory() );
-			
-			String indexString = ( (NullableType) indexType ).toXMLString( index, persister.getFactory() );
-			setIndex( subelement, indexNodeName, indexString );
-		}
-		
-	}
-
-	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
-		
-		Type elementType = persister.getElementType();
-		Type indexType = persister.getIndexType();
-		final String indexNodeName = getIndexAttributeName(persister);
-
-		List elements =  element.elements( persister.getElementNodeName() );
-		int length = elements.size();
-		Serializable[] result = new Serializable[length*2];
-		for ( int i=0; i<length*2; ) {
-			Element elem = (Element) elements.get(i/2);
-			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
-			final String indexString = getIndex(elem, indexNodeName, i);
-			Object index = ( (NullableType) indexType ).fromXMLString( indexString, persister.getFactory() );
-			result[i++] = indexType.disassemble( index, getSession(), null );
-			result[i++] = elementType.disassemble( object, getSession(), null );
-		}
-		return result;
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentMapElementHolder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.util.List;
+
+import org.dom4j.Element;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.NullableType;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class PersistentMapElementHolder extends PersistentIndexedElementHolder {
+
+	public PersistentMapElementHolder(SessionImplementor session, Element element) {
+		super( session, element );
+	}
+
+	public PersistentMapElementHolder(SessionImplementor session, CollectionPersister persister,
+			Serializable key) throws HibernateException {
+		super( session, persister, key );
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		Type indexType = persister.getIndexType();
+		final String indexNodeName = getIndexAttributeName(persister);
+
+		Serializable[] cached = (Serializable[]) disassembled;
+
+		for ( int i=0; i<cached.length; ) {
+			Object index = indexType.assemble( cached[i++], getSession(), owner );
+			Object object = elementType.assemble( cached[i++], getSession(), owner );
+			
+			Element subelement = element.addElement( persister.getElementNodeName() );
+			elementType.setToXMLNode( subelement, object, persister.getFactory() );
+			
+			String indexString = ( (NullableType) indexType ).toXMLString( index, persister.getFactory() );
+			setIndex( subelement, indexNodeName, indexString );
+		}
+		
+	}
+
+	public Serializable disassemble(CollectionPersister persister) throws HibernateException {
+		
+		Type elementType = persister.getElementType();
+		Type indexType = persister.getIndexType();
+		final String indexNodeName = getIndexAttributeName(persister);
+
+		List elements =  element.elements( persister.getElementNodeName() );
+		int length = elements.size();
+		Serializable[] result = new Serializable[length*2];
+		for ( int i=0; i<length*2; ) {
+			Element elem = (Element) elements.get(i/2);
+			Object object = elementType.fromXMLNode( elem, persister.getFactory() );
+			final String indexString = getIndex(elem, indexNodeName, i);
+			Object index = ( (NullableType) indexType ).fromXMLString( indexString, persister.getFactory() );
+			result[i++] = indexType.disassemble( index, getSession(), null );
+			result[i++] = elementType.disassemble( object, getSession(), null );
+		}
+		return result;
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentSet.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,468 +0,0 @@
-//$Id: PersistentSet.java 10589 2006-10-16 15:47:37Z max.andersen at jboss.com $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.Type;
-
-
-/**
- * A persistent wrapper for a <tt>java.util.Set</tt>. The underlying
- * collection is a <tt>HashSet</tt>.
- *
- * @see java.util.HashSet
- * @author Gavin King
- */
-public class PersistentSet extends AbstractPersistentCollection implements java.util.Set {
-
-	protected Set set;
-	protected transient List tempList;
-
-	/**
-	 * Empty constructor.
-	 * <p/>
-	 * Note: this form is not ever ever ever used by Hibernate; it is, however,
-	 * needed for SOAP libraries and other such marshalling code.
-	 */
-	public PersistentSet() {
-		// intentionally empty
-	}
-
-	/**
-	 * Constructor matching super.  Instantiates a lazy set (the underlying
-	 * set is un-initialized).
-	 *
-	 * @param session The session to which this set will belong.
-	 */
-	public PersistentSet(SessionImplementor session) {
-		super( session );
-	}
-
-	/**
-	 * Instantiates a non-lazy set (the underlying set is constructed
-	 * from the incoming set reference).
-	 *
-	 * @param session The session to which this set will belong.
-	 * @param set The underlying set data.
-	 */
-	public PersistentSet(SessionImplementor session, java.util.Set set) {
-		super(session);
-		// Sets can be just a view of a part of another collection.
-		// do we need to copy it to be sure it won't be changing
-		// underneath us?
-		// ie. this.set.addAll(set);
-		this.set = set;
-		setInitialized();
-		setDirectlyAccessible(true);
-	}
-
-
-	public Serializable getSnapshot(CollectionPersister persister) 
-	throws HibernateException {
-		EntityMode entityMode = getSession().getEntityMode();
-		
-		//if (set==null) return new Set(session);
-		HashMap clonedSet = new HashMap( set.size() );
-		Iterator iter = set.iterator();
-		while ( iter.hasNext() ) {
-			Object copied = persister.getElementType()
-					.deepCopy( iter.next(), entityMode, persister.getFactory() );
-			clonedSet.put(copied, copied);
-		}
-		return clonedSet;
-	}
-
-	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
-		java.util.Map sn = (java.util.Map) snapshot;
-		return getOrphans( sn.keySet(), set, entityName, getSession() );
-	}
-
-	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
-		Type elementType = persister.getElementType();
-		java.util.Map sn = (java.util.Map) getSnapshot();
-		if ( sn.size()!=set.size() ) {
-			return false;
-		}
-		else {
-			Iterator iter = set.iterator();
-			while ( iter.hasNext() ) {
-				Object test = iter.next();
-				Object oldValue = sn.get(test);
-				if ( oldValue==null || elementType.isDirty( oldValue, test, getSession() ) ) return false;
-			}
-			return true;
-		}
-	}
-
-	public boolean isSnapshotEmpty(Serializable snapshot) {
-		return ( (java.util.Map) snapshot ).isEmpty();
-	}
-
-	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
-		this.set = ( Set ) persister.getCollectionType().instantiate( anticipatedSize );
-	}
-
-	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
-	throws HibernateException {
-		Serializable[] array = ( Serializable[] ) disassembled;
-		int size = array.length;
-		beforeInitialize( persister, size );
-		for (int i = 0; i < size; i++ ) {
-			Object element = persister.getElementType().assemble( array[i], getSession(), owner );
-			if ( element != null ) {
-				set.add( element );
-			}
-		}
-	}
-
-	public boolean empty() {
-		return set.isEmpty();
-	}
-
-	/**
-	 * @see java.util.Set#size()
-	 */
-	public int size() {
-		return readSize() ? getCachedSize() : set.size();
-	}
-
-	/**
-	 * @see java.util.Set#isEmpty()
-	 */
-	public boolean isEmpty() {
-		return readSize() ? getCachedSize()==0 : set.isEmpty();
-	}
-
-	/**
-	 * @see java.util.Set#contains(Object)
-	 */
-	public boolean contains(Object object) {
-		Boolean exists = readElementExistence(object);
-		return exists==null ? 
-				set.contains(object) : 
-				exists.booleanValue();
-	}
-
-	/**
-	 * @see java.util.Set#iterator()
-	 */
-	public Iterator iterator() {
-		read();
-		return new IteratorProxy( set.iterator() );
-	}
-
-	/**
-	 * @see java.util.Set#toArray()
-	 */
-	public Object[] toArray() {
-		read();
-		return set.toArray();
-	}
-
-	/**
-	 * @see java.util.Set#toArray(Object[])
-	 */
-	public Object[] toArray(Object[] array) {
-		read();
-		return set.toArray(array);
-	}
-
-	/**
-	 * @see java.util.Set#add(Object)
-	 */
-	public boolean add(Object value) {
-		Boolean exists = isOperationQueueEnabled() ? readElementExistence( value ) : null;
-		if ( exists == null ) {
-			initialize( true );
-			if ( set.add( value ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else if ( exists.booleanValue() ) {
-			return false;
-		}
-		else {
-			queueOperation( new SimpleAdd(value) );
-			return true;
-		}
-	}
-
-	/**
-	 * @see java.util.Set#remove(Object)
-	 */
-	public boolean remove(Object value) {
-		Boolean exists = isPutQueueEnabled() ? readElementExistence( value ) : null;
-		if ( exists==null ) {
-			initialize( true );
-			if ( set.remove( value ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else if ( exists.booleanValue() ) {
-			queueOperation( new SimpleRemove(value) );
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Set#containsAll(Collection)
-	 */
-	public boolean containsAll(Collection coll) {
-		read();
-		return set.containsAll(coll);
-	}
-
-	/**
-	 * @see java.util.Set#addAll(Collection)
-	 */
-	public boolean addAll(Collection coll) {
-		if ( coll.size() > 0 ) {
-			initialize( true );
-			if ( set.addAll( coll ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Set#retainAll(Collection)
-	 */
-	public boolean retainAll(Collection coll) {
-		initialize( true );
-		if ( set.retainAll( coll ) ) {
-			dirty();
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Set#removeAll(Collection)
-	 */
-	public boolean removeAll(Collection coll) {
-		if ( coll.size() > 0 ) {
-			initialize( true );
-			if ( set.removeAll( coll ) ) {
-				dirty();
-				return true;
-			}
-			else {
-				return false;
-			}
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * @see java.util.Set#clear()
-	 */
-	public void clear() {
-		if ( isClearQueueEnabled() ) {
-			queueOperation( new Clear() );
-		}
-		else {
-			initialize( true );
-			if ( !set.isEmpty() ) {
-				set.clear();
-				dirty();
-			}
-		}
-	}
-
-	public String toString() {
-		//if (needLoading) return "asleep";
-		read();
-		return set.toString();
-	}
-
-	public Object readFrom(
-	        ResultSet rs,
-	        CollectionPersister persister,
-	        CollectionAliases descriptor,
-	        Object owner) throws HibernateException, SQLException {
-		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
-		if (element!=null) tempList.add(element);
-		return element;
-	}
-
-	public void beginRead() {
-		super.beginRead();
-		tempList = new ArrayList();
-	}
-
-	public boolean endRead() {
-		set.addAll(tempList);
-		tempList = null;
-		setInitialized();
-		return true;
-	}
-
-	public Iterator entries(CollectionPersister persister) {
-		return set.iterator();
-	}
-
-	public Serializable disassemble(CollectionPersister persister)
-	throws HibernateException {
-
-		Serializable[] result = new Serializable[ set.size() ];
-		Iterator iter = set.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			result[i++] = persister.getElementType().disassemble( iter.next(), getSession(), null );
-		}
-		return result;
-
-	}
-
-	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
-		Type elementType = persister.getElementType();
-		final java.util.Map sn = (java.util.Map) getSnapshot();
-		ArrayList deletes = new ArrayList( sn.size() );
-		Iterator iter = sn.keySet().iterator();
-		while ( iter.hasNext() ) {
-			Object test = iter.next();
-			if ( !set.contains(test) ) {
-				// the element has been removed from the set
-				deletes.add(test);
-			}
-		}
-		iter = set.iterator();
-		while ( iter.hasNext() ) {
-			Object test = iter.next();
-			Object oldValue = sn.get(test);
-			if ( oldValue!=null && elementType.isDirty( test, oldValue, getSession() ) ) {
-				// the element has changed
-				deletes.add(oldValue);
-			}
-		}
-		return deletes.iterator();
-	}
-
-	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
-		final java.util.Map sn = (java.util.Map) getSnapshot();
-		Object oldValue = sn.get(entry);
-		// note that it might be better to iterate the snapshot but this is safe,
-		// assuming the user implements equals() properly, as required by the Set
-		// contract!
-		return oldValue==null || elemType.isDirty( oldValue, entry, getSession() );
-	}
-
-	public boolean needsUpdating(Object entry, int i, Type elemType) {
-		return false;
-	}
-
-	public boolean isRowUpdatePossible() {
-		return false;
-	}
-
-	public Object getIndex(Object entry, int i, CollectionPersister persister) {
-		throw new UnsupportedOperationException("Sets don't have indexes");
-	}
-
-	public Object getElement(Object entry) {
-		return entry;
-	}
-
-	public Object getSnapshotElement(Object entry, int i) {
-		throw new UnsupportedOperationException("Sets don't support updating by element");
-	}
-
-	public boolean equals(Object other) {
-		read();
-		return set.equals(other);
-	}
-
-	public int hashCode() {
-		read();
-		return set.hashCode();
-	}
-
-	public boolean entryExists(Object key, int i) {
-		return true;
-	}
-
-	public boolean isWrapper(Object collection) {
-		return set==collection;
-	}
-
-	final class Clear implements DelayedOperation {
-		public void operate() {
-			set.clear();
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
-		}
-	}
-
-	final class SimpleAdd implements DelayedOperation {
-		private Object value;
-		
-		public SimpleAdd(Object value) {
-			this.value = value;
-		}
-		public void operate() {
-			set.add(value);
-		}
-		public Object getAddedInstance() {
-			return value;
-		}
-		public Object getOrphan() {
-			return null;
-		}
-	}
-
-	final class SimpleRemove implements DelayedOperation {
-		private Object value;
-		
-		public SimpleRemove(Object value) {
-			this.value = value;
-		}
-		public void operate() {
-			set.remove(value);
-		}
-		public Object getAddedInstance() {
-			return null;
-		}
-		public Object getOrphan() {
-			return value;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentSet.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,491 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.Type;
+
+
+/**
+ * A persistent wrapper for a <tt>java.util.Set</tt>. The underlying
+ * collection is a <tt>HashSet</tt>.
+ *
+ * @see java.util.HashSet
+ * @author Gavin King
+ */
+public class PersistentSet extends AbstractPersistentCollection implements java.util.Set {
+
+	protected Set set;
+	protected transient List tempList;
+
+	/**
+	 * Empty constructor.
+	 * <p/>
+	 * Note: this form is not ever ever ever used by Hibernate; it is, however,
+	 * needed for SOAP libraries and other such marshalling code.
+	 */
+	public PersistentSet() {
+		// intentionally empty
+	}
+
+	/**
+	 * Constructor matching super.  Instantiates a lazy set (the underlying
+	 * set is un-initialized).
+	 *
+	 * @param session The session to which this set will belong.
+	 */
+	public PersistentSet(SessionImplementor session) {
+		super( session );
+	}
+
+	/**
+	 * Instantiates a non-lazy set (the underlying set is constructed
+	 * from the incoming set reference).
+	 *
+	 * @param session The session to which this set will belong.
+	 * @param set The underlying set data.
+	 */
+	public PersistentSet(SessionImplementor session, java.util.Set set) {
+		super(session);
+		// Sets can be just a view of a part of another collection.
+		// do we need to copy it to be sure it won't be changing
+		// underneath us?
+		// ie. this.set.addAll(set);
+		this.set = set;
+		setInitialized();
+		setDirectlyAccessible(true);
+	}
+
+
+	public Serializable getSnapshot(CollectionPersister persister) 
+	throws HibernateException {
+		EntityMode entityMode = getSession().getEntityMode();
+		
+		//if (set==null) return new Set(session);
+		HashMap clonedSet = new HashMap( set.size() );
+		Iterator iter = set.iterator();
+		while ( iter.hasNext() ) {
+			Object copied = persister.getElementType()
+					.deepCopy( iter.next(), entityMode, persister.getFactory() );
+			clonedSet.put(copied, copied);
+		}
+		return clonedSet;
+	}
+
+	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
+		java.util.Map sn = (java.util.Map) snapshot;
+		return getOrphans( sn.keySet(), set, entityName, getSession() );
+	}
+
+	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
+		Type elementType = persister.getElementType();
+		java.util.Map sn = (java.util.Map) getSnapshot();
+		if ( sn.size()!=set.size() ) {
+			return false;
+		}
+		else {
+			Iterator iter = set.iterator();
+			while ( iter.hasNext() ) {
+				Object test = iter.next();
+				Object oldValue = sn.get(test);
+				if ( oldValue==null || elementType.isDirty( oldValue, test, getSession() ) ) return false;
+			}
+			return true;
+		}
+	}
+
+	public boolean isSnapshotEmpty(Serializable snapshot) {
+		return ( (java.util.Map) snapshot ).isEmpty();
+	}
+
+	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
+		this.set = ( Set ) persister.getCollectionType().instantiate( anticipatedSize );
+	}
+
+	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
+	throws HibernateException {
+		Serializable[] array = ( Serializable[] ) disassembled;
+		int size = array.length;
+		beforeInitialize( persister, size );
+		for (int i = 0; i < size; i++ ) {
+			Object element = persister.getElementType().assemble( array[i], getSession(), owner );
+			if ( element != null ) {
+				set.add( element );
+			}
+		}
+	}
+
+	public boolean empty() {
+		return set.isEmpty();
+	}
+
+	/**
+	 * @see java.util.Set#size()
+	 */
+	public int size() {
+		return readSize() ? getCachedSize() : set.size();
+	}
+
+	/**
+	 * @see java.util.Set#isEmpty()
+	 */
+	public boolean isEmpty() {
+		return readSize() ? getCachedSize()==0 : set.isEmpty();
+	}
+
+	/**
+	 * @see java.util.Set#contains(Object)
+	 */
+	public boolean contains(Object object) {
+		Boolean exists = readElementExistence(object);
+		return exists==null ? 
+				set.contains(object) : 
+				exists.booleanValue();
+	}
+
+	/**
+	 * @see java.util.Set#iterator()
+	 */
+	public Iterator iterator() {
+		read();
+		return new IteratorProxy( set.iterator() );
+	}
+
+	/**
+	 * @see java.util.Set#toArray()
+	 */
+	public Object[] toArray() {
+		read();
+		return set.toArray();
+	}
+
+	/**
+	 * @see java.util.Set#toArray(Object[])
+	 */
+	public Object[] toArray(Object[] array) {
+		read();
+		return set.toArray(array);
+	}
+
+	/**
+	 * @see java.util.Set#add(Object)
+	 */
+	public boolean add(Object value) {
+		Boolean exists = isOperationQueueEnabled() ? readElementExistence( value ) : null;
+		if ( exists == null ) {
+			initialize( true );
+			if ( set.add( value ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else if ( exists.booleanValue() ) {
+			return false;
+		}
+		else {
+			queueOperation( new SimpleAdd(value) );
+			return true;
+		}
+	}
+
+	/**
+	 * @see java.util.Set#remove(Object)
+	 */
+	public boolean remove(Object value) {
+		Boolean exists = isPutQueueEnabled() ? readElementExistence( value ) : null;
+		if ( exists==null ) {
+			initialize( true );
+			if ( set.remove( value ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else if ( exists.booleanValue() ) {
+			queueOperation( new SimpleRemove(value) );
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Set#containsAll(Collection)
+	 */
+	public boolean containsAll(Collection coll) {
+		read();
+		return set.containsAll(coll);
+	}
+
+	/**
+	 * @see java.util.Set#addAll(Collection)
+	 */
+	public boolean addAll(Collection coll) {
+		if ( coll.size() > 0 ) {
+			initialize( true );
+			if ( set.addAll( coll ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Set#retainAll(Collection)
+	 */
+	public boolean retainAll(Collection coll) {
+		initialize( true );
+		if ( set.retainAll( coll ) ) {
+			dirty();
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Set#removeAll(Collection)
+	 */
+	public boolean removeAll(Collection coll) {
+		if ( coll.size() > 0 ) {
+			initialize( true );
+			if ( set.removeAll( coll ) ) {
+				dirty();
+				return true;
+			}
+			else {
+				return false;
+			}
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * @see java.util.Set#clear()
+	 */
+	public void clear() {
+		if ( isClearQueueEnabled() ) {
+			queueOperation( new Clear() );
+		}
+		else {
+			initialize( true );
+			if ( !set.isEmpty() ) {
+				set.clear();
+				dirty();
+			}
+		}
+	}
+
+	public String toString() {
+		//if (needLoading) return "asleep";
+		read();
+		return set.toString();
+	}
+
+	public Object readFrom(
+	        ResultSet rs,
+	        CollectionPersister persister,
+	        CollectionAliases descriptor,
+	        Object owner) throws HibernateException, SQLException {
+		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() );
+		if (element!=null) tempList.add(element);
+		return element;
+	}
+
+	public void beginRead() {
+		super.beginRead();
+		tempList = new ArrayList();
+	}
+
+	public boolean endRead() {
+		set.addAll(tempList);
+		tempList = null;
+		setInitialized();
+		return true;
+	}
+
+	public Iterator entries(CollectionPersister persister) {
+		return set.iterator();
+	}
+
+	public Serializable disassemble(CollectionPersister persister)
+	throws HibernateException {
+
+		Serializable[] result = new Serializable[ set.size() ];
+		Iterator iter = set.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			result[i++] = persister.getElementType().disassemble( iter.next(), getSession(), null );
+		}
+		return result;
+
+	}
+
+	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
+		Type elementType = persister.getElementType();
+		final java.util.Map sn = (java.util.Map) getSnapshot();
+		ArrayList deletes = new ArrayList( sn.size() );
+		Iterator iter = sn.keySet().iterator();
+		while ( iter.hasNext() ) {
+			Object test = iter.next();
+			if ( !set.contains(test) ) {
+				// the element has been removed from the set
+				deletes.add(test);
+			}
+		}
+		iter = set.iterator();
+		while ( iter.hasNext() ) {
+			Object test = iter.next();
+			Object oldValue = sn.get(test);
+			if ( oldValue!=null && elementType.isDirty( test, oldValue, getSession() ) ) {
+				// the element has changed
+				deletes.add(oldValue);
+			}
+		}
+		return deletes.iterator();
+	}
+
+	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
+		final java.util.Map sn = (java.util.Map) getSnapshot();
+		Object oldValue = sn.get(entry);
+		// note that it might be better to iterate the snapshot but this is safe,
+		// assuming the user implements equals() properly, as required by the Set
+		// contract!
+		return oldValue==null || elemType.isDirty( oldValue, entry, getSession() );
+	}
+
+	public boolean needsUpdating(Object entry, int i, Type elemType) {
+		return false;
+	}
+
+	public boolean isRowUpdatePossible() {
+		return false;
+	}
+
+	public Object getIndex(Object entry, int i, CollectionPersister persister) {
+		throw new UnsupportedOperationException("Sets don't have indexes");
+	}
+
+	public Object getElement(Object entry) {
+		return entry;
+	}
+
+	public Object getSnapshotElement(Object entry, int i) {
+		throw new UnsupportedOperationException("Sets don't support updating by element");
+	}
+
+	public boolean equals(Object other) {
+		read();
+		return set.equals(other);
+	}
+
+	public int hashCode() {
+		read();
+		return set.hashCode();
+	}
+
+	public boolean entryExists(Object key, int i) {
+		return true;
+	}
+
+	public boolean isWrapper(Object collection) {
+		return set==collection;
+	}
+
+	final class Clear implements DelayedOperation {
+		public void operate() {
+			set.clear();
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
+		}
+	}
+
+	final class SimpleAdd implements DelayedOperation {
+		private Object value;
+		
+		public SimpleAdd(Object value) {
+			this.value = value;
+		}
+		public void operate() {
+			set.add(value);
+		}
+		public Object getAddedInstance() {
+			return value;
+		}
+		public Object getOrphan() {
+			return null;
+		}
+	}
+
+	final class SimpleRemove implements DelayedOperation {
+		private Object value;
+		
+		public SimpleRemove(Object value) {
+			this.value = value;
+		}
+		public void operate() {
+			set.remove(value);
+		}
+		public Object getAddedInstance() {
+			return null;
+		}
+		public Object getOrphan() {
+			return value;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,191 +0,0 @@
-//$Id: PersistentSortedMap.java 7714 2005-08-01 16:29:33Z oneovthafew $
-package org.hibernate.collection;
-
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedMap;
-import java.util.TreeMap;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.BasicCollectionPersister;
-
-
-/**
- * A persistent wrapper for a <tt>java.util.SortedMap</tt>. Underlying
- * collection is a <tt>TreeMap</tt>.
- *
- * @see java.util.TreeMap
- * @author <a href="mailto:doug.currie at alum.mit.edu">e</a>
- */
-public class PersistentSortedMap extends PersistentMap implements SortedMap {
-
-	protected Comparator comparator;
-
-	protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) throws HibernateException {
-		TreeMap clonedMap = new TreeMap(comparator);
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry e = (Map.Entry) iter.next();
-			clonedMap.put( e.getKey(), persister.getElementType().deepCopy( e.getValue(), entityMode, persister.getFactory() ) );
-		}
-		return clonedMap;
-	}
-
-	public PersistentSortedMap(SessionImplementor session) {
-		super(session);
-	}
-
-	public void setComparator(Comparator comparator) {
-		this.comparator = comparator;
-	}
-
-	public PersistentSortedMap(SessionImplementor session, SortedMap map) {
-		super(session, map);
-		comparator = map.comparator();
-	}
-
-	public PersistentSortedMap() {} //needed for SOAP libraries, etc
-
-	/**
-	 * @see PersistentSortedMap#comparator()
-	 */
-	public Comparator comparator() {
-		return comparator;
-	}
-
-	/**
-	 * @see PersistentSortedMap#subMap(Object, Object)
-	 */
-	public SortedMap subMap(Object fromKey, Object toKey) {
-		read();
-		SortedMap m = ( (SortedMap) map ).subMap(fromKey, toKey);
-		return new SortedSubMap(m);
-	}
-
-	/**
-	 * @see PersistentSortedMap#headMap(Object)
-	 */
-	public SortedMap headMap(Object toKey) {
-		read();
-		SortedMap m;
-		m = ( (SortedMap) map ).headMap(toKey);
-		return new SortedSubMap(m);
-	}
-
-	/**
-	 * @see PersistentSortedMap#tailMap(Object)
-	 */
-	public SortedMap tailMap(Object fromKey) {
-		read();
-		SortedMap m;
-		m = ( (SortedMap) map ).tailMap(fromKey);
-		return new SortedSubMap(m);
-	}
-
-	/**
-	 * @see PersistentSortedMap#firstKey()
-	 */
-	public Object firstKey() {
-		read();
-		return ( (SortedMap) map ).firstKey();
-	}
-
-	/**
-	 * @see PersistentSortedMap#lastKey()
-	 */
-	public Object lastKey() {
-		read();
-		return ( (SortedMap) map ).lastKey();
-	}
-
-	class SortedSubMap implements SortedMap {
-
-		SortedMap submap;
-
-		SortedSubMap(SortedMap m) {
-			this.submap = m;
-		}
-		// from Map
-		public int size() {
-			return submap.size();
-		}
-		public boolean isEmpty() {
-			return submap.isEmpty();
-		}
-		public boolean containsKey(Object key) {
-			return submap.containsKey(key);
-		}
-		public boolean containsValue(Object key) {
-			return submap.containsValue(key) ;
-		}
-		public Object get(Object key) {
-			return submap.get(key);
-		}
-		public Object put(Object key, Object value) {
-			write();
-			return submap.put(key,  value);
-		}
-		public Object remove(Object key) {
-			write();
-			return submap.remove(key);
-		}
-		public void putAll(Map other) {
-			write();
-			submap.putAll(other);
-		}
-		public void clear() {
-			write();
-			submap.clear();
-		}
-		public Set keySet() {
-			return new SetProxy( submap.keySet() );
-		}
-		public Collection values() {
-			return new SetProxy( submap.values() );
-		}
-		public Set entrySet() {
-			return new EntrySetProxy( submap.entrySet() );
-		}
-		// from SortedMap
-		public Comparator comparator() {
-			return submap.comparator();
-		}
-		public SortedMap subMap(Object fromKey, Object toKey) {
-			SortedMap m;
-			m = submap.subMap(fromKey, toKey);
-			return new SortedSubMap( m );
-		}
-		public SortedMap headMap(Object toKey) {
-			SortedMap m;
-			m = submap.headMap(toKey);
-			return new SortedSubMap(m);
-		}
-		public SortedMap tailMap(Object fromKey) {
-			SortedMap m;
-			m = submap.tailMap(fromKey);
-			return new SortedSubMap(m);
-		}
-		public Object firstKey() {
-			return  submap.firstKey();
-		}
-		public Object lastKey() {
-			return submap.lastKey();
-		}
-
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.collection;
+
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.BasicCollectionPersister;
+
+
+/**
+ * A persistent wrapper for a <tt>java.util.SortedMap</tt>. Underlying
+ * collection is a <tt>TreeMap</tt>.
+ *
+ * @see java.util.TreeMap
+ * @author <a href="mailto:doug.currie at alum.mit.edu">e</a>
+ */
+public class PersistentSortedMap extends PersistentMap implements SortedMap {
+
+	protected Comparator comparator;
+
+	protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) throws HibernateException {
+		TreeMap clonedMap = new TreeMap(comparator);
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry e = (Map.Entry) iter.next();
+			clonedMap.put( e.getKey(), persister.getElementType().deepCopy( e.getValue(), entityMode, persister.getFactory() ) );
+		}
+		return clonedMap;
+	}
+
+	public PersistentSortedMap(SessionImplementor session) {
+		super(session);
+	}
+
+	public void setComparator(Comparator comparator) {
+		this.comparator = comparator;
+	}
+
+	public PersistentSortedMap(SessionImplementor session, SortedMap map) {
+		super(session, map);
+		comparator = map.comparator();
+	}
+
+	public PersistentSortedMap() {} //needed for SOAP libraries, etc
+
+	/**
+	 * @see PersistentSortedMap#comparator()
+	 */
+	public Comparator comparator() {
+		return comparator;
+	}
+
+	/**
+	 * @see PersistentSortedMap#subMap(Object, Object)
+	 */
+	public SortedMap subMap(Object fromKey, Object toKey) {
+		read();
+		SortedMap m = ( (SortedMap) map ).subMap(fromKey, toKey);
+		return new SortedSubMap(m);
+	}
+
+	/**
+	 * @see PersistentSortedMap#headMap(Object)
+	 */
+	public SortedMap headMap(Object toKey) {
+		read();
+		SortedMap m;
+		m = ( (SortedMap) map ).headMap(toKey);
+		return new SortedSubMap(m);
+	}
+
+	/**
+	 * @see PersistentSortedMap#tailMap(Object)
+	 */
+	public SortedMap tailMap(Object fromKey) {
+		read();
+		SortedMap m;
+		m = ( (SortedMap) map ).tailMap(fromKey);
+		return new SortedSubMap(m);
+	}
+
+	/**
+	 * @see PersistentSortedMap#firstKey()
+	 */
+	public Object firstKey() {
+		read();
+		return ( (SortedMap) map ).firstKey();
+	}
+
+	/**
+	 * @see PersistentSortedMap#lastKey()
+	 */
+	public Object lastKey() {
+		read();
+		return ( (SortedMap) map ).lastKey();
+	}
+
+	class SortedSubMap implements SortedMap {
+
+		SortedMap submap;
+
+		SortedSubMap(SortedMap m) {
+			this.submap = m;
+		}
+		// from Map
+		public int size() {
+			return submap.size();
+		}
+		public boolean isEmpty() {
+			return submap.isEmpty();
+		}
+		public boolean containsKey(Object key) {
+			return submap.containsKey(key);
+		}
+		public boolean containsValue(Object key) {
+			return submap.containsValue(key) ;
+		}
+		public Object get(Object key) {
+			return submap.get(key);
+		}
+		public Object put(Object key, Object value) {
+			write();
+			return submap.put(key,  value);
+		}
+		public Object remove(Object key) {
+			write();
+			return submap.remove(key);
+		}
+		public void putAll(Map other) {
+			write();
+			submap.putAll(other);
+		}
+		public void clear() {
+			write();
+			submap.clear();
+		}
+		public Set keySet() {
+			return new SetProxy( submap.keySet() );
+		}
+		public Collection values() {
+			return new SetProxy( submap.values() );
+		}
+		public Set entrySet() {
+			return new EntrySetProxy( submap.entrySet() );
+		}
+		// from SortedMap
+		public Comparator comparator() {
+			return submap.comparator();
+		}
+		public SortedMap subMap(Object fromKey, Object toKey) {
+			SortedMap m;
+			m = submap.subMap(fromKey, toKey);
+			return new SortedSubMap( m );
+		}
+		public SortedMap headMap(Object toKey) {
+			SortedMap m;
+			m = submap.headMap(toKey);
+			return new SortedSubMap(m);
+		}
+		public SortedMap tailMap(Object fromKey) {
+			SortedMap m;
+			m = submap.tailMap(fromKey);
+			return new SortedSubMap(m);
+		}
+		public Object firstKey() {
+			return  submap.firstKey();
+		}
+		public Object lastKey() {
+			return submap.lastKey();
+		}
+
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,145 +0,0 @@
-//$Id: PersistentSortedSet.java 7714 2005-08-01 16:29:33Z oneovthafew $
-package org.hibernate.collection;
-
-import java.io.Serializable;
-import java.util.Comparator;
-import java.util.Iterator;
-import java.util.SortedSet;
-import java.util.TreeMap;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.BasicCollectionPersister;
-
-
-/**
- * A persistent wrapper for a <tt>java.util.SortedSet</tt>. Underlying
- * collection is a <tt>TreeSet</tt>.
- *
- * @see java.util.TreeSet
- * @author <a href="mailto:doug.currie at alum.mit.edu">e</a>
- */
-public class PersistentSortedSet extends PersistentSet implements SortedSet {
-
-	protected Comparator comparator;
-
-	protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) 
-	throws HibernateException {
-		//if (set==null) return new Set(session);
-		TreeMap clonedSet = new TreeMap(comparator);
-		Iterator iter = set.iterator();
-		while ( iter.hasNext() ) {
-			Object copy = persister.getElementType().deepCopy( iter.next(), entityMode, persister.getFactory() );
-			clonedSet.put(copy, copy);
-		}
-		return clonedSet;
-	}
-
-	public void setComparator(Comparator comparator) {
-		this.comparator = comparator;
-	}
-
-	public PersistentSortedSet(SessionImplementor session) {
-		super(session);
-	}
-
-	public PersistentSortedSet(SessionImplementor session, SortedSet set) {
-		super(session, set);
-		comparator = set.comparator();
-	}
-
-	public PersistentSortedSet() {} //needed for SOAP libraries, etc
-
-	/**
-	 * @see PersistentSortedSet#comparator()
-	 */
-	public Comparator comparator() {
-		return comparator;
-	}
-
-	/**
-	 * @see PersistentSortedSet#subSet(Object,Object)
-	 */
-	public SortedSet subSet(Object fromElement, Object toElement) {
-		read();
-		SortedSet s;
-		s = ( (SortedSet) set ).subSet(fromElement, toElement);
-		return new SubSetProxy(s);
-	}
-
-	/**
-	 * @see PersistentSortedSet#headSet(Object)
-	 */
-	public SortedSet headSet(Object toElement) {
-		read();
-		SortedSet s = ( (SortedSet) set ).headSet(toElement);
-		return new SubSetProxy(s);
-	}
-
-	/**
-	 * @see PersistentSortedSet#tailSet(Object)
-	 */
-	public SortedSet tailSet(Object fromElement) {
-		read();
-		SortedSet s = ( (SortedSet) set ).tailSet(fromElement);
-		return new SubSetProxy(s);
-	}
-
-	/**
-	 * @see PersistentSortedSet#first()
-	 */
-	public Object first() {
-		read();
-		return ( (SortedSet) set ).first();
-	}
-
-	/**
-	 * @see PersistentSortedSet#last()
-	 */
-	public Object last() {
-		read();
-		return ( (SortedSet) set ).last();
-	}
-
-	/** wrapper for subSets to propagate write to its backing set */
-	class SubSetProxy extends SetProxy implements SortedSet {
-
-		SubSetProxy(SortedSet s) {
-			super(s);
-		}
-
-		public Comparator comparator() {
-			return ( (SortedSet) this.set ).comparator();
-		}
-
-		public Object first() {
-			return ( (SortedSet) this.set ).first();
-		}
-
-		public SortedSet headSet(Object toValue) {
-			return new SubSetProxy( ( (SortedSet) this.set ).headSet(toValue) );
-		}
-
-		public Object last() {
-			return ( (SortedSet) this.set ).last();
-		}
-
-		public SortedSet subSet(Object fromValue, Object toValue) {
-			return new SubSetProxy( ( (SortedSet) this.set ).subSet(fromValue, toValue) );
-		}
-
-		public SortedSet tailSet(Object fromValue) {
-			return new SubSetProxy( ( (SortedSet) this.set ).tailSet(fromValue) );
-		}
-
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/PersistentSortedSet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,168 @@
+/*
+ * 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.collection;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeMap;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.BasicCollectionPersister;
+
+
+/**
+ * A persistent wrapper for a <tt>java.util.SortedSet</tt>. Underlying
+ * collection is a <tt>TreeSet</tt>.
+ *
+ * @see java.util.TreeSet
+ * @author <a href="mailto:doug.currie at alum.mit.edu">e</a>
+ */
+public class PersistentSortedSet extends PersistentSet implements SortedSet {
+
+	protected Comparator comparator;
+
+	protected Serializable snapshot(BasicCollectionPersister persister, EntityMode entityMode) 
+	throws HibernateException {
+		//if (set==null) return new Set(session);
+		TreeMap clonedSet = new TreeMap(comparator);
+		Iterator iter = set.iterator();
+		while ( iter.hasNext() ) {
+			Object copy = persister.getElementType().deepCopy( iter.next(), entityMode, persister.getFactory() );
+			clonedSet.put(copy, copy);
+		}
+		return clonedSet;
+	}
+
+	public void setComparator(Comparator comparator) {
+		this.comparator = comparator;
+	}
+
+	public PersistentSortedSet(SessionImplementor session) {
+		super(session);
+	}
+
+	public PersistentSortedSet(SessionImplementor session, SortedSet set) {
+		super(session, set);
+		comparator = set.comparator();
+	}
+
+	public PersistentSortedSet() {} //needed for SOAP libraries, etc
+
+	/**
+	 * @see PersistentSortedSet#comparator()
+	 */
+	public Comparator comparator() {
+		return comparator;
+	}
+
+	/**
+	 * @see PersistentSortedSet#subSet(Object,Object)
+	 */
+	public SortedSet subSet(Object fromElement, Object toElement) {
+		read();
+		SortedSet s;
+		s = ( (SortedSet) set ).subSet(fromElement, toElement);
+		return new SubSetProxy(s);
+	}
+
+	/**
+	 * @see PersistentSortedSet#headSet(Object)
+	 */
+	public SortedSet headSet(Object toElement) {
+		read();
+		SortedSet s = ( (SortedSet) set ).headSet(toElement);
+		return new SubSetProxy(s);
+	}
+
+	/**
+	 * @see PersistentSortedSet#tailSet(Object)
+	 */
+	public SortedSet tailSet(Object fromElement) {
+		read();
+		SortedSet s = ( (SortedSet) set ).tailSet(fromElement);
+		return new SubSetProxy(s);
+	}
+
+	/**
+	 * @see PersistentSortedSet#first()
+	 */
+	public Object first() {
+		read();
+		return ( (SortedSet) set ).first();
+	}
+
+	/**
+	 * @see PersistentSortedSet#last()
+	 */
+	public Object last() {
+		read();
+		return ( (SortedSet) set ).last();
+	}
+
+	/** wrapper for subSets to propagate write to its backing set */
+	class SubSetProxy extends SetProxy implements SortedSet {
+
+		SubSetProxy(SortedSet s) {
+			super(s);
+		}
+
+		public Comparator comparator() {
+			return ( (SortedSet) this.set ).comparator();
+		}
+
+		public Object first() {
+			return ( (SortedSet) this.set ).first();
+		}
+
+		public SortedSet headSet(Object toValue) {
+			return new SubSetProxy( ( (SortedSet) this.set ).headSet(toValue) );
+		}
+
+		public Object last() {
+			return ( (SortedSet) this.set ).last();
+		}
+
+		public SortedSet subSet(Object fromValue, Object toValue) {
+			return new SubSetProxy( ( (SortedSet) this.set ).subSet(fromValue, toValue) );
+		}
+
+		public SortedSet tailSet(Object fromValue) {
+			return new SubSetProxy( ( (SortedSet) this.set ).tailSet(fromValue) );
+		}
+
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/collection/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a framework for collection wrappers.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/collection/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a framework for collection wrappers.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/ConnectionProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-//$Id: ConnectionProvider.java 9191 2006-02-01 14:40:34Z epbernard $
-package org.hibernate.connection;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-
-/**
- * A strategy for obtaining JDBC connections.
- * <br><br>
- * Implementors might also implement connection pooling.<br>
- * <br>
- * The <tt>ConnectionProvider</tt> interface is not intended to be
- * exposed to the application. Instead it is used internally by
- * Hibernate to obtain connections.<br>
- * <br>
- * Implementors should provide a public default constructor.
- *
- * @see ConnectionProviderFactory
- * @author Gavin King
- */
-public interface ConnectionProvider {
-	/**
-	 * Initialize the connection provider from given properties.
-	 * @param props <tt>SessionFactory</tt> properties
-	 */
-	public void configure(Properties props) throws HibernateException;
-	/**
-	 * Grab a connection, with the autocommit mode specified by
-	 * <tt>hibernate.connection.autocommit</tt>.
-	 * @return a JDBC connection
-	 * @throws SQLException
-	 */
-	public Connection getConnection() throws SQLException;
-	/**
-	 * Dispose of a used connection.
-	 * @param conn a JDBC connection
-	 * @throws SQLException
-	 */
-	public void closeConnection(Connection conn) throws SQLException;
-
-	/**
-	 * Release all resources held by this provider. JavaDoc requires a second sentence.
-	 * @throws HibernateException
-	 */
-	public void close() throws HibernateException;
-
-	/**
-	 * Does this connection provider support aggressive release of JDBC
-	 * connections and re-acquistion of those connections (if need be) later?
-	 * <p/>
-	 * This is used in conjunction with {@link org.hibernate.cfg.Environment.RELEASE_CONNECTIONS}
-	 * to aggressively release JDBC connections.  However, the configured ConnectionProvider
-	 * must support re-acquisition of the same underlying connection for that semantic to work.
-	 * <p/>
-	 * Typically, this is only true in managed environments where a container
-	 * tracks connections by transaction or thread.
-	 *
-	 * Note that JTA semantic depends on the fact that the underlying connection provider does
-	 * support aggressive release.
-	 */
-	public boolean supportsAggressiveRelease();
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/ConnectionProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.connection;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+
+/**
+ * A strategy for obtaining JDBC connections.
+ * <br><br>
+ * Implementors might also implement connection pooling.<br>
+ * <br>
+ * The <tt>ConnectionProvider</tt> interface is not intended to be
+ * exposed to the application. Instead it is used internally by
+ * Hibernate to obtain connections.<br>
+ * <br>
+ * Implementors should provide a public default constructor.
+ *
+ * @see ConnectionProviderFactory
+ * @author Gavin King
+ */
+public interface ConnectionProvider {
+	/**
+	 * Initialize the connection provider from given properties.
+	 * @param props <tt>SessionFactory</tt> properties
+	 */
+	public void configure(Properties props) throws HibernateException;
+	/**
+	 * Grab a connection, with the autocommit mode specified by
+	 * <tt>hibernate.connection.autocommit</tt>.
+	 * @return a JDBC connection
+	 * @throws SQLException
+	 */
+	public Connection getConnection() throws SQLException;
+	/**
+	 * Dispose of a used connection.
+	 * @param conn a JDBC connection
+	 * @throws SQLException
+	 */
+	public void closeConnection(Connection conn) throws SQLException;
+
+	/**
+	 * Release all resources held by this provider. JavaDoc requires a second sentence.
+	 * @throws HibernateException
+	 */
+	public void close() throws HibernateException;
+
+	/**
+	 * Does this connection provider support aggressive release of JDBC
+	 * connections and re-acquistion of those connections (if need be) later?
+	 * <p/>
+	 * This is used in conjunction with {@link org.hibernate.cfg.Environment.RELEASE_CONNECTIONS}
+	 * to aggressively release JDBC connections.  However, the configured ConnectionProvider
+	 * must support re-acquisition of the same underlying connection for that semantic to work.
+	 * <p/>
+	 * Typically, this is only true in managed environments where a container
+	 * tracks connections by transaction or thread.
+	 *
+	 * Note that JTA semantic depends on the fact that the underlying connection provider does
+	 * support aggressive release.
+	 */
+	public boolean supportsAggressiveRelease();
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,164 +0,0 @@
-//$Id: ConnectionProviderFactory.java 7541 2005-07-18 22:37:31Z epbernard $
-package org.hibernate.connection;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.Set;
-import java.util.Map;
-import java.beans.Introspector;
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.PropertyDescriptor;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Instantiates a connection provider given either <tt>System</tt> properties or
- * a <tt>java.util.Properties</tt> instance. The <tt>ConnectionProviderFactory</tt>
- * first attempts to find a name of a <tt>ConnectionProvider</tt> subclass in the
- * property <tt>hibernate.connection.provider_class</tt>. If missing, heuristics are used
- * to choose either <tt>DriverManagerConnectionProvider</tt>,
- * <tt>DatasourceConnectionProvider</tt>, <tt>C3P0ConnectionProvider</tt> or
- * <tt>DBCPConnectionProvider</tt>.
- * @see ConnectionProvider
- * @author Gavin King
- */
-
-public final class ConnectionProviderFactory {
-
-	private static final Logger log = LoggerFactory.getLogger(ConnectionProviderFactory.class);
-
-	/**
-	 * Instantiate a <tt>ConnectionProvider</tt> using <tt>System</tt> properties.
-	 * @return The created connection provider.
-	 * @throws HibernateException
-	 */
-	public static ConnectionProvider newConnectionProvider() throws HibernateException {
-		return newConnectionProvider( Environment.getProperties() );
-	}
-
-	/**
-	 * Instantiate a <tt>ConnectionProvider</tt> using given properties.
-	 * Method newConnectionProvider.
-	 * @param properties hibernate <tt>SessionFactory</tt> properties
-	 * @return ConnectionProvider
-	 * @throws HibernateException
-	 */
-	public static ConnectionProvider newConnectionProvider(Properties properties) throws HibernateException {
-		return newConnectionProvider( properties, null );
-	}
-
-	/**
-	 * Create a connection provider based on the given information.
-	 *
-	 * @param properties Properties being used to build the {@link org.hibernate.SessionFactory}.
-	 * @param connectionProviderInjectionData Soemthing to be injected in the conenction provided
-	 * @return The created connection provider
-	 * @throws HibernateException
-	 */
-	public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {
-		ConnectionProvider connections;
-		String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);
-		if ( providerClass!=null ) {
-			try {
-				log.info("Initializing connection provider: " + providerClass);
-				connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();
-			}
-			catch ( Exception e ) {
-				log.error( "Could not instantiate connection provider", e );
-				throw new HibernateException("Could not instantiate connection provider: " + providerClass);
-			}
-		}
-		else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {
-			connections = new DatasourceConnectionProvider();
-		}
-		else if ( properties.getProperty(Environment.URL)!=null ) {
-			connections = new DriverManagerConnectionProvider();
-		}
-		else {
-			connections = new UserSuppliedConnectionProvider();
-		}
-
-		if ( connectionProviderInjectionData != null && connectionProviderInjectionData.size() != 0 ) {
-			//inject the data
-			try {
-				BeanInfo info = Introspector.getBeanInfo( connections.getClass() );
-				PropertyDescriptor[] descritors = info.getPropertyDescriptors();
-				int size = descritors.length;
-				for (int index = 0 ; index < size ; index++) {
-					String propertyName = descritors[index].getName();
-					if ( connectionProviderInjectionData.containsKey( propertyName ) ) {
-						Method method = descritors[index].getWriteMethod();
-						method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );
-					}
-				}
-			}
-			catch (IntrospectionException e) {
-				throw new HibernateException("Unable to inject objects into the conenction provider", e);
-			}
-			catch (IllegalAccessException e) {
-				throw new HibernateException("Unable to inject objects into the conenction provider", e);
-			}
-			catch (InvocationTargetException e) {
-				throw new HibernateException("Unable to inject objects into the conenction provider", e);
-			}
-		}
-		connections.configure(properties);
-		return connections;
-	}
-
-	// cannot be instantiated
-	private ConnectionProviderFactory() { throw new UnsupportedOperationException(); }
-
-	/**
-	 * Transform JDBC connection properties.
-	 *
-	 * Passed in the form <tt>hibernate.connection.*</tt> to the
-	 * format accepted by <tt>DriverManager</tt> by triming the leading "<tt>hibernate.connection</tt>".
-	 */
-	public static Properties getConnectionProperties(Properties properties) {
-
-		Iterator iter = properties.keySet().iterator();
-		Properties result = new Properties();
-		while ( iter.hasNext() ) {
-			String prop = (String) iter.next();
-			if ( prop.indexOf(Environment.CONNECTION_PREFIX) > -1 && !SPECIAL_PROPERTIES.contains(prop) ) {
-				result.setProperty(
-					prop.substring( Environment.CONNECTION_PREFIX.length()+1 ),
-					properties.getProperty(prop)
-				);
-			}
-		}
-		String userName = properties.getProperty(Environment.USER);
-		if (userName!=null) result.setProperty( "user", userName );
-		return result;
-	}
-
-	private static final Set SPECIAL_PROPERTIES;
-	static {
-		SPECIAL_PROPERTIES = new HashSet();
-		SPECIAL_PROPERTIES.add(Environment.DATASOURCE);
-		SPECIAL_PROPERTIES.add(Environment.URL);
-		SPECIAL_PROPERTIES.add(Environment.CONNECTION_PROVIDER);
-		SPECIAL_PROPERTIES.add(Environment.POOL_SIZE);
-		SPECIAL_PROPERTIES.add(Environment.ISOLATION);
-		SPECIAL_PROPERTIES.add(Environment.DRIVER);
-		SPECIAL_PROPERTIES.add(Environment.USER);
-
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/ConnectionProviderFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,187 @@
+/*
+ * 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.connection;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Map;
+import java.beans.Introspector;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Instantiates a connection provider given either <tt>System</tt> properties or
+ * a <tt>java.util.Properties</tt> instance. The <tt>ConnectionProviderFactory</tt>
+ * first attempts to find a name of a <tt>ConnectionProvider</tt> subclass in the
+ * property <tt>hibernate.connection.provider_class</tt>. If missing, heuristics are used
+ * to choose either <tt>DriverManagerConnectionProvider</tt>,
+ * <tt>DatasourceConnectionProvider</tt>, <tt>C3P0ConnectionProvider</tt> or
+ * <tt>DBCPConnectionProvider</tt>.
+ * @see ConnectionProvider
+ * @author Gavin King
+ */
+
+public final class ConnectionProviderFactory {
+
+	private static final Logger log = LoggerFactory.getLogger(ConnectionProviderFactory.class);
+
+	/**
+	 * Instantiate a <tt>ConnectionProvider</tt> using <tt>System</tt> properties.
+	 * @return The created connection provider.
+	 * @throws HibernateException
+	 */
+	public static ConnectionProvider newConnectionProvider() throws HibernateException {
+		return newConnectionProvider( Environment.getProperties() );
+	}
+
+	/**
+	 * Instantiate a <tt>ConnectionProvider</tt> using given properties.
+	 * Method newConnectionProvider.
+	 * @param properties hibernate <tt>SessionFactory</tt> properties
+	 * @return ConnectionProvider
+	 * @throws HibernateException
+	 */
+	public static ConnectionProvider newConnectionProvider(Properties properties) throws HibernateException {
+		return newConnectionProvider( properties, null );
+	}
+
+	/**
+	 * Create a connection provider based on the given information.
+	 *
+	 * @param properties Properties being used to build the {@link org.hibernate.SessionFactory}.
+	 * @param connectionProviderInjectionData Soemthing to be injected in the conenction provided
+	 * @return The created connection provider
+	 * @throws HibernateException
+	 */
+	public static ConnectionProvider newConnectionProvider(Properties properties, Map connectionProviderInjectionData) throws HibernateException {
+		ConnectionProvider connections;
+		String providerClass = properties.getProperty(Environment.CONNECTION_PROVIDER);
+		if ( providerClass!=null ) {
+			try {
+				log.info("Initializing connection provider: " + providerClass);
+				connections = (ConnectionProvider) ReflectHelper.classForName(providerClass).newInstance();
+			}
+			catch ( Exception e ) {
+				log.error( "Could not instantiate connection provider", e );
+				throw new HibernateException("Could not instantiate connection provider: " + providerClass);
+			}
+		}
+		else if ( properties.getProperty(Environment.DATASOURCE)!=null ) {
+			connections = new DatasourceConnectionProvider();
+		}
+		else if ( properties.getProperty(Environment.URL)!=null ) {
+			connections = new DriverManagerConnectionProvider();
+		}
+		else {
+			connections = new UserSuppliedConnectionProvider();
+		}
+
+		if ( connectionProviderInjectionData != null && connectionProviderInjectionData.size() != 0 ) {
+			//inject the data
+			try {
+				BeanInfo info = Introspector.getBeanInfo( connections.getClass() );
+				PropertyDescriptor[] descritors = info.getPropertyDescriptors();
+				int size = descritors.length;
+				for (int index = 0 ; index < size ; index++) {
+					String propertyName = descritors[index].getName();
+					if ( connectionProviderInjectionData.containsKey( propertyName ) ) {
+						Method method = descritors[index].getWriteMethod();
+						method.invoke( connections, new Object[] { connectionProviderInjectionData.get( propertyName ) } );
+					}
+				}
+			}
+			catch (IntrospectionException e) {
+				throw new HibernateException("Unable to inject objects into the conenction provider", e);
+			}
+			catch (IllegalAccessException e) {
+				throw new HibernateException("Unable to inject objects into the conenction provider", e);
+			}
+			catch (InvocationTargetException e) {
+				throw new HibernateException("Unable to inject objects into the conenction provider", e);
+			}
+		}
+		connections.configure(properties);
+		return connections;
+	}
+
+	// cannot be instantiated
+	private ConnectionProviderFactory() { throw new UnsupportedOperationException(); }
+
+	/**
+	 * Transform JDBC connection properties.
+	 *
+	 * Passed in the form <tt>hibernate.connection.*</tt> to the
+	 * format accepted by <tt>DriverManager</tt> by triming the leading "<tt>hibernate.connection</tt>".
+	 */
+	public static Properties getConnectionProperties(Properties properties) {
+
+		Iterator iter = properties.keySet().iterator();
+		Properties result = new Properties();
+		while ( iter.hasNext() ) {
+			String prop = (String) iter.next();
+			if ( prop.indexOf(Environment.CONNECTION_PREFIX) > -1 && !SPECIAL_PROPERTIES.contains(prop) ) {
+				result.setProperty(
+					prop.substring( Environment.CONNECTION_PREFIX.length()+1 ),
+					properties.getProperty(prop)
+				);
+			}
+		}
+		String userName = properties.getProperty(Environment.USER);
+		if (userName!=null) result.setProperty( "user", userName );
+		return result;
+	}
+
+	private static final Set SPECIAL_PROPERTIES;
+	static {
+		SPECIAL_PROPERTIES = new HashSet();
+		SPECIAL_PROPERTIES.add(Environment.DATASOURCE);
+		SPECIAL_PROPERTIES.add(Environment.URL);
+		SPECIAL_PROPERTIES.add(Environment.CONNECTION_PROVIDER);
+		SPECIAL_PROPERTIES.add(Environment.POOL_SIZE);
+		SPECIAL_PROPERTIES.add(Environment.ISOLATION);
+		SPECIAL_PROPERTIES.add(Environment.DRIVER);
+		SPECIAL_PROPERTIES.add(Environment.USER);
+
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-//$Id: DatasourceConnectionProvider.java 10075 2006-07-01 12:50:34Z epbernard $
-package org.hibernate.connection;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import javax.sql.DataSource;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.NamingHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A connection provider that uses a <tt>DataSource</tt> registered with JNDI.
- * Hibernate will use this <tt>ConnectionProvider</tt> by default if the
- * property <tt>hibernate.connection.datasource</tt> is set.
- * @see ConnectionProvider
- * @author Gavin King
- */
-public class DatasourceConnectionProvider implements ConnectionProvider {
-	private DataSource ds;
-	private String user;
-	private String pass;
-
-	private static final Logger log = LoggerFactory.getLogger(DatasourceConnectionProvider.class);
-
-	public DataSource getDataSource() {
-		return ds;
-	}
-
-	public void setDataSource(DataSource ds) {
-		this.ds = ds;
-	}
-
-	public void configure(Properties props) throws HibernateException {
-
-		String jndiName = props.getProperty( Environment.DATASOURCE );
-		if ( jndiName == null ) {
-			String msg = "datasource JNDI name was not specified by property " + Environment.DATASOURCE;
-			log.error( msg );
-			throw new HibernateException( msg );
-		}
-
-		user = props.getProperty( Environment.USER );
-		pass = props.getProperty( Environment.PASS );
-
-		try {
-			ds = ( DataSource ) NamingHelper.getInitialContext( props ).lookup( jndiName );
-		}
-		catch ( Exception e ) {
-			log.error( "Could not find datasource: " + jndiName, e );
-			throw new HibernateException( "Could not find datasource", e );
-		}
-		if ( ds == null ) {
-			throw new HibernateException( "Could not find datasource: " + jndiName );
-		}
-		log.info( "Using datasource: " + jndiName );
-	}
-
-	public Connection getConnection() throws SQLException {
-		if (user != null || pass != null) {
-			return ds.getConnection(user, pass);
-		}
-		else {
-			return ds.getConnection();
-		}
-	}
-
-	public void closeConnection(Connection conn) throws SQLException {
-		conn.close();
-	}
-
-	public void close() {}
-
-	/**
-	 * @see ConnectionProvider#supportsAggressiveRelease()
-	 */
-	public boolean supportsAggressiveRelease() {
-		return true;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DatasourceConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.connection;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import javax.sql.DataSource;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.NamingHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A connection provider that uses a <tt>DataSource</tt> registered with JNDI.
+ * Hibernate will use this <tt>ConnectionProvider</tt> by default if the
+ * property <tt>hibernate.connection.datasource</tt> is set.
+ * @see ConnectionProvider
+ * @author Gavin King
+ */
+public class DatasourceConnectionProvider implements ConnectionProvider {
+	private DataSource ds;
+	private String user;
+	private String pass;
+
+	private static final Logger log = LoggerFactory.getLogger(DatasourceConnectionProvider.class);
+
+	public DataSource getDataSource() {
+		return ds;
+	}
+
+	public void setDataSource(DataSource ds) {
+		this.ds = ds;
+	}
+
+	public void configure(Properties props) throws HibernateException {
+
+		String jndiName = props.getProperty( Environment.DATASOURCE );
+		if ( jndiName == null ) {
+			String msg = "datasource JNDI name was not specified by property " + Environment.DATASOURCE;
+			log.error( msg );
+			throw new HibernateException( msg );
+		}
+
+		user = props.getProperty( Environment.USER );
+		pass = props.getProperty( Environment.PASS );
+
+		try {
+			ds = ( DataSource ) NamingHelper.getInitialContext( props ).lookup( jndiName );
+		}
+		catch ( Exception e ) {
+			log.error( "Could not find datasource: " + jndiName, e );
+			throw new HibernateException( "Could not find datasource", e );
+		}
+		if ( ds == null ) {
+			throw new HibernateException( "Could not find datasource: " + jndiName );
+		}
+		log.info( "Using datasource: " + jndiName );
+	}
+
+	public Connection getConnection() throws SQLException {
+		if (user != null || pass != null) {
+			return ds.getConnection(user, pass);
+		}
+		else {
+			return ds.getConnection();
+		}
+	}
+
+	public void closeConnection(Connection conn) throws SQLException {
+		conn.close();
+	}
+
+	public void close() {}
+
+	/**
+	 * @see ConnectionProvider#supportsAggressiveRelease()
+	 */
+	public boolean supportsAggressiveRelease() {
+		return true;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,176 +0,0 @@
-//$Id: DriverManagerConnectionProvider.java 7888 2005-08-12 21:22:38Z oneovthafew $
-package org.hibernate.connection;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A connection provider that uses <tt>java.sql.DriverManager</tt>. This provider
- * also implements a very rudimentary connection pool.
- * @see ConnectionProvider
- * @author Gavin King
- */
-public class DriverManagerConnectionProvider implements ConnectionProvider {
-
-	private String url;
-	private Properties connectionProps;
-	private Integer isolation;
-	private final ArrayList pool = new ArrayList();
-	private int poolSize;
-	private int checkedOut = 0;
-	private boolean autocommit;
-
-	private static final Logger log = LoggerFactory.getLogger(DriverManagerConnectionProvider.class);
-
-	public void configure(Properties props) throws HibernateException {
-
-		String driverClass = props.getProperty(Environment.DRIVER);
-
-		poolSize = PropertiesHelper.getInt(Environment.POOL_SIZE, props, 20); //default pool size 20
-		log.info("Using Hibernate built-in connection pool (not for production use!)");
-		log.info("Hibernate connection pool size: " + poolSize);
-		
-		autocommit = PropertiesHelper.getBoolean(Environment.AUTOCOMMIT, props);
-		log.info("autocommit mode: " + autocommit);
-
-		isolation = PropertiesHelper.getInteger(Environment.ISOLATION, props);
-		if (isolation!=null)
-		log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
-
-		if (driverClass==null) {
-			log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
-		}
-		else {
-			try {
-				// trying via forName() first to be as close to DriverManager's semantics
-				Class.forName(driverClass);
-			}
-			catch (ClassNotFoundException cnfe) {
-				try {
-					ReflectHelper.classForName(driverClass);
-				}
-				catch (ClassNotFoundException e) {
-					String msg = "JDBC Driver class not found: " + driverClass;
-					log.error( msg, e );
-					throw new HibernateException(msg, e);
-				}
-			}
-		}
-
-		url = props.getProperty( Environment.URL );
-		if ( url == null ) {
-			String msg = "JDBC URL was not specified by property " + Environment.URL;
-			log.error( msg );
-			throw new HibernateException( msg );
-		}
-
-		connectionProps = ConnectionProviderFactory.getConnectionProperties( props );
-
-		log.info( "using driver: " + driverClass + " at URL: " + url );
-		// if debug level is enabled, then log the password, otherwise mask it
-		if ( log.isDebugEnabled() ) {
-			log.info( "connection properties: " + connectionProps );
-		} 
-		else if ( log.isInfoEnabled() ) {
-			log.info( "connection properties: " + PropertiesHelper.maskOut(connectionProps, "password") );
-		}
-
-	}
-
-	public Connection getConnection() throws SQLException {
-
-		if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );
-
-		synchronized (pool) {
-			if ( !pool.isEmpty() ) {
-				int last = pool.size() - 1;
-				if ( log.isTraceEnabled() ) {
-					log.trace("using pooled JDBC connection, pool size: " + last);
-					checkedOut++;
-				}
-				Connection pooled = (Connection) pool.remove(last);
-				if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
-				if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
-				return pooled;
-			}
-		}
-
-		log.debug("opening new JDBC connection");
-		Connection conn = DriverManager.getConnection(url, connectionProps);
-		if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
-		if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
-		}
-		if ( log.isTraceEnabled() ) checkedOut++;
-
-		return conn;
-	}
-
-	public void closeConnection(Connection conn) throws SQLException {
-
-		if ( log.isDebugEnabled() ) checkedOut--;
-
-		synchronized (pool) {
-			int currentSize = pool.size();
-			if ( currentSize < poolSize ) {
-				if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );
-				pool.add(conn);
-				return;
-			}
-		}
-
-		log.debug("closing JDBC connection");
-
-		conn.close();
-
-	}
-
-	protected void finalize() {
-		close();
-	}
-
-	public void close() {
-
-		log.info("cleaning up connection pool: " + url);
-
-		Iterator iter = pool.iterator();
-		while ( iter.hasNext() ) {
-			try {
-				( (Connection) iter.next() ).close();
-			}
-			catch (SQLException sqle) {
-				log.warn("problem closing pooled connection", sqle);
-			}
-		}
-		pool.clear();
-
-	}
-
-	/**
-	 * @see ConnectionProvider#supportsAggressiveRelease()
-	 */
-	public boolean supportsAggressiveRelease() {
-		return false;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/DriverManagerConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,199 @@
+/*
+ * 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.connection;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A connection provider that uses <tt>java.sql.DriverManager</tt>. This provider
+ * also implements a very rudimentary connection pool.
+ * @see ConnectionProvider
+ * @author Gavin King
+ */
+public class DriverManagerConnectionProvider implements ConnectionProvider {
+
+	private String url;
+	private Properties connectionProps;
+	private Integer isolation;
+	private final ArrayList pool = new ArrayList();
+	private int poolSize;
+	private int checkedOut = 0;
+	private boolean autocommit;
+
+	private static final Logger log = LoggerFactory.getLogger(DriverManagerConnectionProvider.class);
+
+	public void configure(Properties props) throws HibernateException {
+
+		String driverClass = props.getProperty(Environment.DRIVER);
+
+		poolSize = PropertiesHelper.getInt(Environment.POOL_SIZE, props, 20); //default pool size 20
+		log.info("Using Hibernate built-in connection pool (not for production use!)");
+		log.info("Hibernate connection pool size: " + poolSize);
+		
+		autocommit = PropertiesHelper.getBoolean(Environment.AUTOCOMMIT, props);
+		log.info("autocommit mode: " + autocommit);
+
+		isolation = PropertiesHelper.getInteger(Environment.ISOLATION, props);
+		if (isolation!=null)
+		log.info( "JDBC isolation level: " + Environment.isolationLevelToString( isolation.intValue() ) );
+
+		if (driverClass==null) {
+			log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
+		}
+		else {
+			try {
+				// trying via forName() first to be as close to DriverManager's semantics
+				Class.forName(driverClass);
+			}
+			catch (ClassNotFoundException cnfe) {
+				try {
+					ReflectHelper.classForName(driverClass);
+				}
+				catch (ClassNotFoundException e) {
+					String msg = "JDBC Driver class not found: " + driverClass;
+					log.error( msg, e );
+					throw new HibernateException(msg, e);
+				}
+			}
+		}
+
+		url = props.getProperty( Environment.URL );
+		if ( url == null ) {
+			String msg = "JDBC URL was not specified by property " + Environment.URL;
+			log.error( msg );
+			throw new HibernateException( msg );
+		}
+
+		connectionProps = ConnectionProviderFactory.getConnectionProperties( props );
+
+		log.info( "using driver: " + driverClass + " at URL: " + url );
+		// if debug level is enabled, then log the password, otherwise mask it
+		if ( log.isDebugEnabled() ) {
+			log.info( "connection properties: " + connectionProps );
+		} 
+		else if ( log.isInfoEnabled() ) {
+			log.info( "connection properties: " + PropertiesHelper.maskOut(connectionProps, "password") );
+		}
+
+	}
+
+	public Connection getConnection() throws SQLException {
+
+		if ( log.isTraceEnabled() ) log.trace( "total checked-out connections: " + checkedOut );
+
+		synchronized (pool) {
+			if ( !pool.isEmpty() ) {
+				int last = pool.size() - 1;
+				if ( log.isTraceEnabled() ) {
+					log.trace("using pooled JDBC connection, pool size: " + last);
+					checkedOut++;
+				}
+				Connection pooled = (Connection) pool.remove(last);
+				if (isolation!=null) pooled.setTransactionIsolation( isolation.intValue() );
+				if ( pooled.getAutoCommit()!=autocommit ) pooled.setAutoCommit(autocommit);
+				return pooled;
+			}
+		}
+
+		log.debug("opening new JDBC connection");
+		Connection conn = DriverManager.getConnection(url, connectionProps);
+		if (isolation!=null) conn.setTransactionIsolation( isolation.intValue() );
+		if ( conn.getAutoCommit()!=autocommit ) conn.setAutoCommit(autocommit);
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "created connection to: " + url + ", Isolation Level: " + conn.getTransactionIsolation() );
+		}
+		if ( log.isTraceEnabled() ) checkedOut++;
+
+		return conn;
+	}
+
+	public void closeConnection(Connection conn) throws SQLException {
+
+		if ( log.isDebugEnabled() ) checkedOut--;
+
+		synchronized (pool) {
+			int currentSize = pool.size();
+			if ( currentSize < poolSize ) {
+				if ( log.isTraceEnabled() ) log.trace("returning connection to pool, pool size: " + (currentSize + 1) );
+				pool.add(conn);
+				return;
+			}
+		}
+
+		log.debug("closing JDBC connection");
+
+		conn.close();
+
+	}
+
+	protected void finalize() {
+		close();
+	}
+
+	public void close() {
+
+		log.info("cleaning up connection pool: " + url);
+
+		Iterator iter = pool.iterator();
+		while ( iter.hasNext() ) {
+			try {
+				( (Connection) iter.next() ).close();
+			}
+			catch (SQLException sqle) {
+				log.warn("problem closing pooled connection", sqle);
+			}
+		}
+		pool.clear();
+
+	}
+
+	/**
+	 * @see ConnectionProvider#supportsAggressiveRelease()
+	 */
+	public boolean supportsAggressiveRelease() {
+		return false;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-//$Id: UserSuppliedConnectionProvider.java 6463 2005-04-19 15:39:07Z steveebersole $
-package org.hibernate.connection;
-
-import java.sql.Connection;
-import java.util.Properties;
-
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-
-/**
- * An implementation of the <literal>ConnectionProvider</literal> interface that
- * simply throws an exception when a connection is requested. This implementation
- * indicates that the user is expected to supply a JDBC connection.
- * @see ConnectionProvider
- * @author Gavin King
- */
-public class UserSuppliedConnectionProvider implements ConnectionProvider {
-
-	/**
-	 * @see org.hibernate.connection.ConnectionProvider#configure(Properties)
-	 */
-	public void configure(Properties props) throws HibernateException {
-		LoggerFactory.getLogger( UserSuppliedConnectionProvider.class )
-				.warn( "No connection properties specified - the user must supply JDBC connections" );
-	}
-
-	/**
-	 * @see org.hibernate.connection.ConnectionProvider#getConnection()
-	 */
-	public Connection getConnection() {
-		throw new UnsupportedOperationException("The user must supply a JDBC connection");
-	}
-
-	/**
-	 * @see org.hibernate.connection.ConnectionProvider#closeConnection(Connection)
-	 */
-	public void closeConnection(Connection conn) {
-		throw new UnsupportedOperationException("The user must supply a JDBC connection");
-	}
-
-	public void close() {
-	}
-
-	/**
-	 * @see ConnectionProvider#supportsAggressiveRelease()
-	 */
-	public boolean supportsAggressiveRelease() {
-		return false;
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/UserSuppliedConnectionProvider.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.connection;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+
+/**
+ * An implementation of the <literal>ConnectionProvider</literal> interface that
+ * simply throws an exception when a connection is requested. This implementation
+ * indicates that the user is expected to supply a JDBC connection.
+ * @see ConnectionProvider
+ * @author Gavin King
+ */
+public class UserSuppliedConnectionProvider implements ConnectionProvider {
+
+	/**
+	 * @see org.hibernate.connection.ConnectionProvider#configure(Properties)
+	 */
+	public void configure(Properties props) throws HibernateException {
+		LoggerFactory.getLogger( UserSuppliedConnectionProvider.class )
+				.warn( "No connection properties specified - the user must supply JDBC connections" );
+	}
+
+	/**
+	 * @see org.hibernate.connection.ConnectionProvider#getConnection()
+	 */
+	public Connection getConnection() {
+		throw new UnsupportedOperationException("The user must supply a JDBC connection");
+	}
+
+	/**
+	 * @see org.hibernate.connection.ConnectionProvider#closeConnection(Connection)
+	 */
+	public void closeConnection(Connection conn) {
+		throw new UnsupportedOperationException("The user must supply a JDBC connection");
+	}
+
+	public void close() {
+	}
+
+	/**
+	 * @see ConnectionProvider#supportsAggressiveRelease()
+	 */
+	public boolean supportsAggressiveRelease() {
+		return false;
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/connection/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the mechanism for obtaining
-	a JDBC connection.
-</p>
-<p>
-	A concrete implementation of <tt>ConnectionProvider</tt> may be 
-	selected by specifying <tt>hibernate.connection.provider_class</tt>.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/connection/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/connection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the mechanism for obtaining
+	a JDBC connection.
+</p>
+<p>
+	A concrete implementation of <tt>ConnectionProvider</tt> may be 
+	selected by specifying <tt>hibernate.connection.provider_class</tt>.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/context/CurrentSessionContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +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.context;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for implementations which know how to scope the notion
- * of a {@link org.hibernate.SessionFactory#getCurrentSession() current session}.
- * <p/>
- * Implementations should adhere to the following:
- * <ul>
- * <li>contain a constructor accepting a single argument of type
- * {@link org.hibernate.engine.SessionFactoryImplementor}
- * <li>should be thread safe
- * <li>should be fully serializable
- * </ul>
- * <p/>
- * Implementors should be aware that they are also fully responsible for
- * cleanup of any generated current-sessions.
- * <p/>
- * Note that there will be exactly one instance of the configured
- * CurrentSessionContext implementation per {@link org.hibernate.SessionFactory}.
- *
- * @author Steve Ebersole
- */
-public interface CurrentSessionContext extends Serializable {
-	/**
-	 * Retrieve the current session according to the scoping defined
-	 * by this implementation.
-	 *
-	 * @return The current session.
-	 * @throws HibernateException Typically indicates an issue
-	 * locating or creating the current session.
-	 */
-	public org.hibernate.classic.Session currentSession() throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/context/CurrentSessionContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/CurrentSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.context;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for implementations which know how to scope the notion
+ * of a {@link org.hibernate.SessionFactory#getCurrentSession() current session}.
+ * <p/>
+ * Implementations should adhere to the following:
+ * <ul>
+ * <li>contain a constructor accepting a single argument of type
+ * {@link org.hibernate.engine.SessionFactoryImplementor}
+ * <li>should be thread safe
+ * <li>should be fully serializable
+ * </ul>
+ * <p/>
+ * Implementors should be aware that they are also fully responsible for
+ * cleanup of any generated current-sessions.
+ * <p/>
+ * Note that there will be exactly one instance of the configured
+ * CurrentSessionContext implementation per {@link org.hibernate.SessionFactory}.
+ *
+ * @author Steve Ebersole
+ */
+public interface CurrentSessionContext extends Serializable {
+	/**
+	 * Retrieve the current session according to the scoping defined
+	 * by this implementation.
+	 *
+	 * @return The current session.
+	 * @throws HibernateException Typically indicates an issue
+	 * locating or creating the current session.
+	 */
+	public org.hibernate.classic.Session currentSession() throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,203 +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.context;
-
-import org.hibernate.HibernateException;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.util.JTAHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.Synchronization;
-import java.util.Map;
-import java.util.Hashtable;
-
-/**
- * An implementation of {@link CurrentSessionContext} which scopes the notion
- * of a current session to a JTA transaction.  Because JTA gives us a nice
- * tie-in to clean up after ourselves, this implementation will generate
- * Sessions as needed provided a JTA transaction is in effect.  If a session
- * is not already associated with the current JTA transaction at the time
- * {@link #currentSession()} is called, a new session will be opened and it
- * will be associated with that JTA transaction.
- * <p/>
- * Note that the sessions returned from this method are automatically configured with
- * both the {@link org.hibernate.cfg.Environment#FLUSH_BEFORE_COMPLETION auto-flush} and
- * {@link org.hibernate.cfg.Environment#AUTO_CLOSE_SESSION auto-close} attributes set to
- * true, meaning that the Session will be automatically flushed and closed
- * as part of the lifecycle for the JTA transaction to which it is associated.
- * Additionally, it will also be configured to aggressively release JDBC
- * connections after each statement is executed.  These settings are governed
- * by the {@link #isAutoFlushEnabled()}, {@link #isAutoCloseEnabled()}, and
- * {@link #getConnectionReleaseMode()} methods; these are provided (along with
- * the {@link #buildOrObtainSession()} method) for easier subclassing for custom
- * JTA-based session tracking logic (like maybe long-session semantics).
- *
- * @author Steve Ebersole
- */
-public class JTASessionContext implements CurrentSessionContext {
-
-	private static final Logger log = LoggerFactory.getLogger( JTASessionContext.class );
-
-	protected final SessionFactoryImplementor factory;
-	private transient Map currentSessionMap = new Hashtable();
-
-	public JTASessionContext(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Session currentSession() throws HibernateException {
-		TransactionManager transactionManager = factory.getTransactionManager();
-		if ( transactionManager == null ) {
-			throw new HibernateException( "No TransactionManagerLookup specified" );
-		}
-
-		Transaction txn;
-		try {
-			txn = transactionManager.getTransaction();
-			if ( txn == null ) {
-				throw new HibernateException( "Unable to locate current JTA transaction" );
-			}
-			if ( !JTAHelper.isInProgress( txn.getStatus() ) ) {
-				// We could register the session against the transaction even though it is
-				// not started, but we'd have no guarentee of ever getting the map
-				// entries cleaned up (aside from spawning threads).
-				throw new HibernateException( "Current transaction is not in progress" );
-			}
-		}
-		catch ( HibernateException e ) {
-			throw e;
-		}
-		catch ( Throwable t ) {
-			throw new HibernateException( "Problem locating/validating JTA transaction", t );
-		}
-
-		Session currentSession = ( Session ) currentSessionMap.get( txn );
-
-		if ( currentSession == null ) {
-			currentSession = buildOrObtainSession();
-
-			try {
-				txn.registerSynchronization( buildCleanupSynch( txn ) );
-			}
-			catch ( Throwable t ) {
-				try {
-					currentSession.close();
-				}
-				catch ( Throwable ignore ) {
-					log.debug( "Unable to release generated current-session on failed synch registration", ignore );
-				}
-				throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" );
-			}
-
-			Object txnIdentifier = factory.getSettings().getTransactionManagerLookup() == null
-					? txn
-					: factory.getSettings().getTransactionManagerLookup().getTransactionIdentifier( txn );
-			currentSessionMap.put( txnIdentifier, currentSession );
-		}
-
-		return currentSession;
-	}
-
-	private CleanupSynch buildCleanupSynch(Transaction txn) {
-		return new CleanupSynch( txn, this );
-	}
-
-	/**
-	 * Strictly provided for subclassing purposes; specifically to allow long-session
-	 * support.
-	 * <p/>
-	 * This implementation always just opens a new session.
-	 *
-	 * @return the built or (re)obtained session.
-	 */
-	protected Session buildOrObtainSession() {
-		return factory.openSession(
-				null,
-		        isAutoFlushEnabled(),
-		        isAutoCloseEnabled(),
-		        getConnectionReleaseMode()
-			);
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns true.
-	 *
-	 * @return Whether or not the the session should be closed by transaction completion.
-	 */
-	protected boolean isAutoCloseEnabled() {
-		return true;
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns true.
-	 *
-	 * @return Whether or not the the session should be flushed prior transaction completion.
-	 */
-	protected boolean isAutoFlushEnabled() {
-		return true;
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns after_statement.
-	 *
-	 * @return The connection release mode for any built sessions.
-	 */
-	protected ConnectionReleaseMode getConnectionReleaseMode() {
-		return ConnectionReleaseMode.AFTER_STATEMENT;
-	}
-
-	/**
-	 * JTA transaction synch used for cleanup of the internal session map.
-	 */
-	protected static class CleanupSynch implements Synchronization {
-		private Transaction txn;
-		private JTASessionContext context;
-
-		public CleanupSynch(Transaction txn, JTASessionContext context) {
-			this.txn = txn;
-			this.context = context;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void beforeCompletion() {
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void afterCompletion(int i) {
-			context.currentSessionMap.remove( txn );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/context/JTASessionContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/JTASessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,204 @@
+/*
+ * 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.context;
+
+import org.hibernate.HibernateException;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.util.JTAHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.Synchronization;
+import java.util.Map;
+import java.util.Hashtable;
+
+/**
+ * An implementation of {@link CurrentSessionContext} which scopes the notion
+ * of a current session to a JTA transaction.  Because JTA gives us a nice
+ * tie-in to clean up after ourselves, this implementation will generate
+ * Sessions as needed provided a JTA transaction is in effect.  If a session
+ * is not already associated with the current JTA transaction at the time
+ * {@link #currentSession()} is called, a new session will be opened and it
+ * will be associated with that JTA transaction.
+ * <p/>
+ * Note that the sessions returned from this method are automatically configured with
+ * both the {@link org.hibernate.cfg.Environment#FLUSH_BEFORE_COMPLETION auto-flush} and
+ * {@link org.hibernate.cfg.Environment#AUTO_CLOSE_SESSION auto-close} attributes set to
+ * true, meaning that the Session will be automatically flushed and closed
+ * as part of the lifecycle for the JTA transaction to which it is associated.
+ * Additionally, it will also be configured to aggressively release JDBC
+ * connections after each statement is executed.  These settings are governed
+ * by the {@link #isAutoFlushEnabled()}, {@link #isAutoCloseEnabled()}, and
+ * {@link #getConnectionReleaseMode()} methods; these are provided (along with
+ * the {@link #buildOrObtainSession()} method) for easier subclassing for custom
+ * JTA-based session tracking logic (like maybe long-session semantics).
+ *
+ * @author Steve Ebersole
+ */
+public class JTASessionContext implements CurrentSessionContext {
+
+	private static final Logger log = LoggerFactory.getLogger( JTASessionContext.class );
+
+	protected final SessionFactoryImplementor factory;
+	private transient Map currentSessionMap = new Hashtable();
+
+	public JTASessionContext(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Session currentSession() throws HibernateException {
+		TransactionManager transactionManager = factory.getTransactionManager();
+		if ( transactionManager == null ) {
+			throw new HibernateException( "No TransactionManagerLookup specified" );
+		}
+
+		Transaction txn;
+		try {
+			txn = transactionManager.getTransaction();
+			if ( txn == null ) {
+				throw new HibernateException( "Unable to locate current JTA transaction" );
+			}
+			if ( !JTAHelper.isInProgress( txn.getStatus() ) ) {
+				// We could register the session against the transaction even though it is
+				// not started, but we'd have no guarentee of ever getting the map
+				// entries cleaned up (aside from spawning threads).
+				throw new HibernateException( "Current transaction is not in progress" );
+			}
+		}
+		catch ( HibernateException e ) {
+			throw e;
+		}
+		catch ( Throwable t ) {
+			throw new HibernateException( "Problem locating/validating JTA transaction", t );
+		}
+
+		Session currentSession = ( Session ) currentSessionMap.get( txn );
+
+		if ( currentSession == null ) {
+			currentSession = buildOrObtainSession();
+
+			try {
+				txn.registerSynchronization( buildCleanupSynch( txn ) );
+			}
+			catch ( Throwable t ) {
+				try {
+					currentSession.close();
+				}
+				catch ( Throwable ignore ) {
+					log.debug( "Unable to release generated current-session on failed synch registration", ignore );
+				}
+				throw new HibernateException( "Unable to register cleanup Synchronization with TransactionManager" );
+			}
+
+			Object txnIdentifier = factory.getSettings().getTransactionManagerLookup() == null
+					? txn
+					: factory.getSettings().getTransactionManagerLookup().getTransactionIdentifier( txn );
+			currentSessionMap.put( txnIdentifier, currentSession );
+		}
+
+		return currentSession;
+	}
+
+	private CleanupSynch buildCleanupSynch(Transaction txn) {
+		return new CleanupSynch( txn, this );
+	}
+
+	/**
+	 * Strictly provided for subclassing purposes; specifically to allow long-session
+	 * support.
+	 * <p/>
+	 * This implementation always just opens a new session.
+	 *
+	 * @return the built or (re)obtained session.
+	 */
+	protected Session buildOrObtainSession() {
+		return factory.openSession(
+				null,
+		        isAutoFlushEnabled(),
+		        isAutoCloseEnabled(),
+		        getConnectionReleaseMode()
+			);
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns true.
+	 *
+	 * @return Whether or not the the session should be closed by transaction completion.
+	 */
+	protected boolean isAutoCloseEnabled() {
+		return true;
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns true.
+	 *
+	 * @return Whether or not the the session should be flushed prior transaction completion.
+	 */
+	protected boolean isAutoFlushEnabled() {
+		return true;
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns after_statement.
+	 *
+	 * @return The connection release mode for any built sessions.
+	 */
+	protected ConnectionReleaseMode getConnectionReleaseMode() {
+		return ConnectionReleaseMode.AFTER_STATEMENT;
+	}
+
+	/**
+	 * JTA transaction synch used for cleanup of the internal session map.
+	 */
+	protected static class CleanupSynch implements Synchronization {
+		private Transaction txn;
+		private JTASessionContext context;
+
+		public CleanupSynch(Transaction txn, JTASessionContext context) {
+			this.txn = txn;
+			this.context = context;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void beforeCompletion() {
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void afterCompletion(int i) {
+			context.currentSessionMap.remove( txn );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/context/ManagedSessionContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,148 +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.context;
-
-import org.hibernate.classic.Session;
-import org.hibernate.HibernateException;
-import org.hibernate.SessionFactory;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Represents a {@link CurrentSessionContext} the notion of a contextual session
- * is managed by some external entity (generally some form of interceptor, etc).
- * This external manager is responsible for scoping these contextual sessions
- * appropriately binding/unbinding them here for exposure to the application
- * through {@link SessionFactory#getCurrentSession} calls.
- * <p/>
- *  Basically exposes two interfaces.  <ul>
- * <li>First is the implementation of CurrentSessionContext which is then used
- * by the {@link SessionFactory#getCurrentSession()} calls.  This
- * portion is instance-based specific to the session factory owning the given
- * instance of this impl (there will be one instance of this per each session
- * factory using this strategy).
- * <li>Second is the externally facing methods {@link #hasBind}, {@link #bind},
- * and {@link #unbind} used by the external thing to manage exposure of the
- * current session it is scoping.  This portion is static to allow easy
- * reference from that external thing.
- * </ul>
- * The underlying storage of the current sessions here is a static
- * {@link ThreadLocal}-based map where the sessions are keyed by the
- * the owning session factory.
- *
- * @author Steve Ebersole
- */
-public class ManagedSessionContext implements CurrentSessionContext {
-
-	private static final ThreadLocal context = new ThreadLocal();
-	private final SessionFactoryImplementor factory;
-
-	public ManagedSessionContext(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Session currentSession() {
-		Session current = existingSession( factory );
-		if ( current == null ) {
-			throw new HibernateException( "No session currently bound to execution context" );
-		}
-		return current;
-	}
-
-	/**
-	 * Check to see if there is already a session associated with the current
-	 * thread for the given session factory.
-	 *
-	 * @param factory The factory against which to check for a given session
-	 * within the current thread.
-	 * @return True if there is currently a session bound.
-	 */
-	public static boolean hasBind(SessionFactory factory) {
-		return existingSession( factory ) != null;
-	}
-
-	/**
-	 * Binds the given session to the current context for its session factory.
-	 *
-	 * @param session The session to be bound.
-	 * @return Any previously bound session (should be null in most cases).
-	 */
-	public static Session bind(Session session) {
-		return ( Session ) sessionMap( true ).put( session.getSessionFactory(), session );
-	}
-
-	/**
-	 * Unbinds the session (if one) current associated with the context for the
-	 * given session.
-	 *
-	 * @param factory The factory for which to unbind the current session.
-	 * @return The bound session if one, else null.
-	 */
-	public static Session unbind(SessionFactory factory) {
-		Session existing = null;
-		Map sessionMap = sessionMap();
-		if ( sessionMap != null ) {
-			existing = ( Session ) sessionMap.remove( factory );
-			doCleanup();
-		}
-		return existing;
-	}
-
-	private static Session existingSession(SessionFactory factory) {
-		Map sessionMap = sessionMap();
-		if ( sessionMap == null ) {
-			return null;
-		}
-		else {
-			return ( Session ) sessionMap.get( factory );
-		}
-	}
-
-	protected static Map sessionMap() {
-		return sessionMap( false );
-	}
-
-	private static synchronized Map sessionMap(boolean createMap) {
-		Map sessionMap = ( Map ) context.get();
-		if ( sessionMap == null && createMap ) {
-			sessionMap = new HashMap();
-			context.set( sessionMap );
-		}
-		return sessionMap;
-	}
-
-	private static synchronized void doCleanup() {
-		Map sessionMap = sessionMap( false );
-		if ( sessionMap != null ) {
-			if ( sessionMap.isEmpty() ) {
-				context.set( null );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/context/ManagedSessionContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ManagedSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,149 @@
+/*
+ * 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.context;
+
+import org.hibernate.classic.Session;
+import org.hibernate.HibernateException;
+import org.hibernate.SessionFactory;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Represents a {@link CurrentSessionContext} the notion of a contextual session
+ * is managed by some external entity (generally some form of interceptor, etc).
+ * This external manager is responsible for scoping these contextual sessions
+ * appropriately binding/unbinding them here for exposure to the application
+ * through {@link SessionFactory#getCurrentSession} calls.
+ * <p/>
+ *  Basically exposes two interfaces.  <ul>
+ * <li>First is the implementation of CurrentSessionContext which is then used
+ * by the {@link SessionFactory#getCurrentSession()} calls.  This
+ * portion is instance-based specific to the session factory owning the given
+ * instance of this impl (there will be one instance of this per each session
+ * factory using this strategy).
+ * <li>Second is the externally facing methods {@link #hasBind}, {@link #bind},
+ * and {@link #unbind} used by the external thing to manage exposure of the
+ * current session it is scoping.  This portion is static to allow easy
+ * reference from that external thing.
+ * </ul>
+ * The underlying storage of the current sessions here is a static
+ * {@link ThreadLocal}-based map where the sessions are keyed by the
+ * the owning session factory.
+ *
+ * @author Steve Ebersole
+ */
+public class ManagedSessionContext implements CurrentSessionContext {
+
+	private static final ThreadLocal context = new ThreadLocal();
+	private final SessionFactoryImplementor factory;
+
+	public ManagedSessionContext(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Session currentSession() {
+		Session current = existingSession( factory );
+		if ( current == null ) {
+			throw new HibernateException( "No session currently bound to execution context" );
+		}
+		return current;
+	}
+
+	/**
+	 * Check to see if there is already a session associated with the current
+	 * thread for the given session factory.
+	 *
+	 * @param factory The factory against which to check for a given session
+	 * within the current thread.
+	 * @return True if there is currently a session bound.
+	 */
+	public static boolean hasBind(SessionFactory factory) {
+		return existingSession( factory ) != null;
+	}
+
+	/**
+	 * Binds the given session to the current context for its session factory.
+	 *
+	 * @param session The session to be bound.
+	 * @return Any previously bound session (should be null in most cases).
+	 */
+	public static Session bind(Session session) {
+		return ( Session ) sessionMap( true ).put( session.getSessionFactory(), session );
+	}
+
+	/**
+	 * Unbinds the session (if one) current associated with the context for the
+	 * given session.
+	 *
+	 * @param factory The factory for which to unbind the current session.
+	 * @return The bound session if one, else null.
+	 */
+	public static Session unbind(SessionFactory factory) {
+		Session existing = null;
+		Map sessionMap = sessionMap();
+		if ( sessionMap != null ) {
+			existing = ( Session ) sessionMap.remove( factory );
+			doCleanup();
+		}
+		return existing;
+	}
+
+	private static Session existingSession(SessionFactory factory) {
+		Map sessionMap = sessionMap();
+		if ( sessionMap == null ) {
+			return null;
+		}
+		else {
+			return ( Session ) sessionMap.get( factory );
+		}
+	}
+
+	protected static Map sessionMap() {
+		return sessionMap( false );
+	}
+
+	private static synchronized Map sessionMap(boolean createMap) {
+		Map sessionMap = ( Map ) context.get();
+		if ( sessionMap == null && createMap ) {
+			sessionMap = new HashMap();
+			context.set( sessionMap );
+		}
+		return sessionMap;
+	}
+
+	private static synchronized void doCleanup() {
+		Map sessionMap = sessionMap( false );
+		if ( sessionMap != null ) {
+			if ( sessionMap.isEmpty() ) {
+				context.set( null );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,361 +0,0 @@
-package org.hibernate.context;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.HashMap;
-import java.util.Map;
-import javax.transaction.Synchronization;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.SessionFactory;
-import org.hibernate.classic.Session;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * A {@link CurrentSessionContext} impl which scopes the notion of current
- * session by the current thread of execution.  Unlike the JTA counterpart,
- * threads do not give us a nice hook to perform any type of cleanup making
- * it questionable for this impl to actually generate Session instances.  In
- * the interest of usability, it was decided to have this default impl
- * actually generate a session upon first request and then clean it up
- * after the {@link org.hibernate.Transaction} associated with that session
- * is committed/rolled-back.  In order for ensuring that happens, the sessions
- * generated here are unusable until after {@link Session#beginTransaction()}
- * has been called. If <tt>close()</tt> is called on a session managed by
- * this class, it will be automatically unbound.
- * <p/>
- * Additionally, the static {@link #bind} and {@link #unbind} methods are
- * provided to allow application code to explicitly control opening and
- * closing of these sessions.  This, with some from of interception,
- * is the preferred approach.  It also allows easy framework integration
- * and one possible approach for implementing long-sessions.
- * <p/>
- * The {@link #buildOrObtainSession}, {@link #isAutoCloseEnabled},
- * {@link #isAutoFlushEnabled}, {@link #getConnectionReleaseMode}, and
- * {@link #buildCleanupSynch} methods are all provided to allow easy
- * subclassing (for long-running session scenarios, for example).
- *
- * @author Steve Ebersole
- */
-public class ThreadLocalSessionContext implements CurrentSessionContext {
-
-	private static final Logger log = LoggerFactory.getLogger( ThreadLocalSessionContext.class );
-	private static final Class[] SESS_PROXY_INTERFACES = new Class[] {
-			org.hibernate.classic.Session.class,
-	        org.hibernate.engine.SessionImplementor.class,
-	        org.hibernate.jdbc.JDBCContext.Context.class,
-	        org.hibernate.event.EventSource.class
-	};
-
-	/**
-	 * A ThreadLocal maintaining current sessions for the given execution thread.
-	 * The actual ThreadLocal variable is a java.util.Map to account for
-	 * the possibility for multiple SessionFactorys being used during execution
-	 * of the given thread.
-	 */
-	private static final ThreadLocal context = new ThreadLocal();
-
-	protected final SessionFactoryImplementor factory;
-
-	public ThreadLocalSessionContext(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public final Session currentSession() throws HibernateException {
-		Session current = existingSession( factory );
-		if (current == null) {
-			current = buildOrObtainSession();
-			// register a cleanup synch
-			current.getTransaction().registerSynchronization( buildCleanupSynch() );
-			// wrap the session in the transaction-protection proxy
-			if ( needsWrapping( current ) ) {
-				current = wrap( current );
-			}
-			// then bind it
-			doBind( current, factory );
-		}
-		return current;
-	}
-
-	private boolean needsWrapping(Session session) {
-		// try to make sure we don't wrap and already wrapped session
-		return session != null
-		       && ! Proxy.isProxyClass( session.getClass() )
-		       || ( Proxy.getInvocationHandler( session ) != null
-		       && ! ( Proxy.getInvocationHandler( session ) instanceof TransactionProtectionWrapper ) );
-	}
-
-	/**
-	 * Getter for property 'factory'.
-	 *
-	 * @return Value for property 'factory'.
-	 */
-	protected SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	/**
-	 * Strictly provided for subclassing purposes; specifically to allow long-session
-	 * support.
-	 * <p/>
-	 * This implementation always just opens a new session.
-	 *
-	 * @return the built or (re)obtained session.
-	 */
-	protected Session buildOrObtainSession() {
-		return factory.openSession(
-				null,
-		        isAutoFlushEnabled(),
-		        isAutoCloseEnabled(),
-		        getConnectionReleaseMode()
-			);
-	}
-
-	protected CleanupSynch buildCleanupSynch() {
-		return new CleanupSynch( factory );
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns true.
-	 *
-	 * @return Whether or not the the session should be closed by transaction completion.
-	 */
-	protected boolean isAutoCloseEnabled() {
-		return true;
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns true.
-	 *
-	 * @return Whether or not the the session should be flushed prior transaction completion.
-	 */
-	protected boolean isAutoFlushEnabled() {
-		return true;
-	}
-
-	/**
-	 * Mainly for subclass usage.  This impl always returns after_transaction.
-	 *
-	 * @return The connection release mode for any built sessions.
-	 */
-	protected ConnectionReleaseMode getConnectionReleaseMode() {
-		return factory.getSettings().getConnectionReleaseMode();
-	}
-
-	protected Session wrap(Session session) {
-		TransactionProtectionWrapper wrapper = new TransactionProtectionWrapper( session );
-		Session wrapped = ( Session ) Proxy.newProxyInstance(
-				Session.class.getClassLoader(),
-		        SESS_PROXY_INTERFACES,
-		        wrapper
-			);
-		// yick!  need this for proper serialization/deserialization handling...
-		wrapper.setWrapped( wrapped );
-		return wrapped;
-	}
-
-	/**
-	 * Associates the given session with the current thread of execution.
-	 *
-	 * @param session The session to bind.
-	 */
-	public static void bind(org.hibernate.Session session) {
-		SessionFactory factory = session.getSessionFactory();
-		cleanupAnyOrphanedSession( factory );
-		doBind( session, factory );
-	}
-
-	private static void cleanupAnyOrphanedSession(SessionFactory factory) {
-		Session orphan = doUnbind( factory, false );
-		if ( orphan != null ) {
-			log.warn( "Already session bound on call to bind(); make sure you clean up your sessions!" );
-			try {
-				if ( orphan.getTransaction() != null && orphan.getTransaction().isActive() ) {
-					try {
-						orphan.getTransaction().rollback();
-					}
-					catch( Throwable t ) {
-						log.debug( "Unable to rollback transaction for orphaned session", t );
-					}
-				}
-				orphan.close();
-			}
-			catch( Throwable t ) {
-				log.debug( "Unable to close orphaned session", t );
-			}
-		}
-	}
-
-	/**
-	 * Unassociate a previously bound session from the current thread of execution.
-	 *
-	 * @return The session which was unbound.
-	 */
-	public static Session unbind(SessionFactory factory) {
-		return doUnbind( factory, true );
-	}
-
-	private static Session existingSession(SessionFactory factory) {
-		Map sessionMap = sessionMap();
-		if ( sessionMap == null ) {
-			return null;
-		}
-		else {
-			return ( Session ) sessionMap.get( factory );
-		}
-	}
-
-	protected static Map sessionMap() {
-		return ( Map ) context.get();
-	}
-
-	private static void doBind(org.hibernate.Session session, SessionFactory factory) {
-		Map sessionMap = sessionMap();
-		if ( sessionMap == null ) {
-			sessionMap = new HashMap();
-			context.set( sessionMap );
-		}
-		sessionMap.put( factory, session );
-	}
-
-	private static Session doUnbind(SessionFactory factory, boolean releaseMapIfEmpty) {
-		Map sessionMap = sessionMap();
-		Session session = null;
-		if ( sessionMap != null ) {
-			session = ( Session ) sessionMap.remove( factory );
-			if ( releaseMapIfEmpty && sessionMap.isEmpty() ) {
-				context.set( null );
-			}
-		}
-		return session;
-	}
-
-	/**
-	 * JTA transaction synch used for cleanup of the internal session map.
-	 */
-	protected static class CleanupSynch implements Synchronization, Serializable {
-		protected final SessionFactory factory;
-
-		public CleanupSynch(SessionFactory factory) {
-			this.factory = factory;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void beforeCompletion() {
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void afterCompletion(int i) {
-			unbind( factory );
-		}
-	}
-
-	private class TransactionProtectionWrapper implements InvocationHandler, Serializable {
-		private final Session realSession;
-		private Session wrappedSession;
-
-		public TransactionProtectionWrapper(Session realSession) {
-			this.realSession = realSession;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-			try {
-				// If close() is called, guarantee unbind()
-				if ( "close".equals( method.getName()) ) {
-					unbind( realSession.getSessionFactory() );
-				}
-				else if ( "toString".equals( method.getName() )
-					     || "equals".equals( method.getName() )
-					     || "hashCode".equals( method.getName() )
-				         || "getStatistics".equals( method.getName() )
-					     || "isOpen".equals( method.getName() ) ) {
-					// allow these to go through the the real session no matter what
-				}
-				else if ( !realSession.isOpen() ) {
-					// essentially, if the real session is closed allow any
-					// method call to pass through since the real session
-					// will complain by throwing an appropriate exception;
-					// NOTE that allowing close() above has the same basic effect,
-					//   but we capture that there simply to perform the unbind...
-				}
-				else if ( !realSession.getTransaction().isActive() ) {
-					// limit the methods available if no transaction is active
-					if ( "beginTransaction".equals( method.getName() )
-					     || "getTransaction".equals( method.getName() )
-					     || "isTransactionInProgress".equals( method.getName() )
-					     || "setFlushMode".equals( method.getName() )
-					     || "getSessionFactory".equals( method.getName() ) ) {
-						log.trace( "allowing method [" + method.getName() + "] in non-transacted context" );
-					}
-					else if ( "reconnect".equals( method.getName() )
-					          || "disconnect".equals( method.getName() ) ) {
-						// allow these (deprecated) methods to pass through
-					}
-					else {
-						throw new HibernateException( method.getName() + " is not valid without active transaction" );
-					}
-				}
-				log.trace( "allowing proxied method [" + method.getName() + "] to proceed to real session" );
-				return method.invoke( realSession, args );
-			}
-			catch ( InvocationTargetException e ) {
-				if ( e.getTargetException() instanceof RuntimeException ) {
-					throw ( RuntimeException ) e.getTargetException();
-				}
-				else {
-					throw e;
-				}
-			}
-		}
-
-		/**
-		 * Setter for property 'wrapped'.
-		 *
-		 * @param wrapped Value to set for property 'wrapped'.
-		 */
-		public void setWrapped(Session wrapped) {
-			this.wrappedSession = wrapped;
-		}
-
-
-		// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		private void writeObject(ObjectOutputStream oos) throws IOException {
-			// if a ThreadLocalSessionContext-bound session happens to get
-			// serialized, to be completely correct, we need to make sure
-			// that unbinding of that session occurs.
-			oos.defaultWriteObject();
-			if ( existingSession( factory ) == wrappedSession ) {
-				unbind( factory );
-			}
-		}
-
-		private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-			// on the inverse, it makes sense that if a ThreadLocalSessionContext-
-			// bound session then gets deserialized to go ahead and re-bind it to
-			// the ThreadLocalSessionContext session map.
-			ois.defaultReadObject();
-			realSession.getTransaction().registerSynchronization( buildCleanupSynch() );
-			doBind( wrappedSession, factory );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/context/ThreadLocalSessionContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,385 @@
+/*
+ * 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.context;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import javax.transaction.Synchronization;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.SessionFactory;
+import org.hibernate.classic.Session;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * A {@link CurrentSessionContext} impl which scopes the notion of current
+ * session by the current thread of execution.  Unlike the JTA counterpart,
+ * threads do not give us a nice hook to perform any type of cleanup making
+ * it questionable for this impl to actually generate Session instances.  In
+ * the interest of usability, it was decided to have this default impl
+ * actually generate a session upon first request and then clean it up
+ * after the {@link org.hibernate.Transaction} associated with that session
+ * is committed/rolled-back.  In order for ensuring that happens, the sessions
+ * generated here are unusable until after {@link Session#beginTransaction()}
+ * has been called. If <tt>close()</tt> is called on a session managed by
+ * this class, it will be automatically unbound.
+ * <p/>
+ * Additionally, the static {@link #bind} and {@link #unbind} methods are
+ * provided to allow application code to explicitly control opening and
+ * closing of these sessions.  This, with some from of interception,
+ * is the preferred approach.  It also allows easy framework integration
+ * and one possible approach for implementing long-sessions.
+ * <p/>
+ * The {@link #buildOrObtainSession}, {@link #isAutoCloseEnabled},
+ * {@link #isAutoFlushEnabled}, {@link #getConnectionReleaseMode}, and
+ * {@link #buildCleanupSynch} methods are all provided to allow easy
+ * subclassing (for long-running session scenarios, for example).
+ *
+ * @author Steve Ebersole
+ */
+public class ThreadLocalSessionContext implements CurrentSessionContext {
+
+	private static final Logger log = LoggerFactory.getLogger( ThreadLocalSessionContext.class );
+	private static final Class[] SESS_PROXY_INTERFACES = new Class[] {
+			org.hibernate.classic.Session.class,
+	        org.hibernate.engine.SessionImplementor.class,
+	        org.hibernate.jdbc.JDBCContext.Context.class,
+	        org.hibernate.event.EventSource.class
+	};
+
+	/**
+	 * A ThreadLocal maintaining current sessions for the given execution thread.
+	 * The actual ThreadLocal variable is a java.util.Map to account for
+	 * the possibility for multiple SessionFactorys being used during execution
+	 * of the given thread.
+	 */
+	private static final ThreadLocal context = new ThreadLocal();
+
+	protected final SessionFactoryImplementor factory;
+
+	public ThreadLocalSessionContext(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public final Session currentSession() throws HibernateException {
+		Session current = existingSession( factory );
+		if (current == null) {
+			current = buildOrObtainSession();
+			// register a cleanup synch
+			current.getTransaction().registerSynchronization( buildCleanupSynch() );
+			// wrap the session in the transaction-protection proxy
+			if ( needsWrapping( current ) ) {
+				current = wrap( current );
+			}
+			// then bind it
+			doBind( current, factory );
+		}
+		return current;
+	}
+
+	private boolean needsWrapping(Session session) {
+		// try to make sure we don't wrap and already wrapped session
+		return session != null
+		       && ! Proxy.isProxyClass( session.getClass() )
+		       || ( Proxy.getInvocationHandler( session ) != null
+		       && ! ( Proxy.getInvocationHandler( session ) instanceof TransactionProtectionWrapper ) );
+	}
+
+	/**
+	 * Getter for property 'factory'.
+	 *
+	 * @return Value for property 'factory'.
+	 */
+	protected SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	/**
+	 * Strictly provided for subclassing purposes; specifically to allow long-session
+	 * support.
+	 * <p/>
+	 * This implementation always just opens a new session.
+	 *
+	 * @return the built or (re)obtained session.
+	 */
+	protected Session buildOrObtainSession() {
+		return factory.openSession(
+				null,
+		        isAutoFlushEnabled(),
+		        isAutoCloseEnabled(),
+		        getConnectionReleaseMode()
+			);
+	}
+
+	protected CleanupSynch buildCleanupSynch() {
+		return new CleanupSynch( factory );
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns true.
+	 *
+	 * @return Whether or not the the session should be closed by transaction completion.
+	 */
+	protected boolean isAutoCloseEnabled() {
+		return true;
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns true.
+	 *
+	 * @return Whether or not the the session should be flushed prior transaction completion.
+	 */
+	protected boolean isAutoFlushEnabled() {
+		return true;
+	}
+
+	/**
+	 * Mainly for subclass usage.  This impl always returns after_transaction.
+	 *
+	 * @return The connection release mode for any built sessions.
+	 */
+	protected ConnectionReleaseMode getConnectionReleaseMode() {
+		return factory.getSettings().getConnectionReleaseMode();
+	}
+
+	protected Session wrap(Session session) {
+		TransactionProtectionWrapper wrapper = new TransactionProtectionWrapper( session );
+		Session wrapped = ( Session ) Proxy.newProxyInstance(
+				Session.class.getClassLoader(),
+		        SESS_PROXY_INTERFACES,
+		        wrapper
+			);
+		// yick!  need this for proper serialization/deserialization handling...
+		wrapper.setWrapped( wrapped );
+		return wrapped;
+	}
+
+	/**
+	 * Associates the given session with the current thread of execution.
+	 *
+	 * @param session The session to bind.
+	 */
+	public static void bind(org.hibernate.Session session) {
+		SessionFactory factory = session.getSessionFactory();
+		cleanupAnyOrphanedSession( factory );
+		doBind( session, factory );
+	}
+
+	private static void cleanupAnyOrphanedSession(SessionFactory factory) {
+		Session orphan = doUnbind( factory, false );
+		if ( orphan != null ) {
+			log.warn( "Already session bound on call to bind(); make sure you clean up your sessions!" );
+			try {
+				if ( orphan.getTransaction() != null && orphan.getTransaction().isActive() ) {
+					try {
+						orphan.getTransaction().rollback();
+					}
+					catch( Throwable t ) {
+						log.debug( "Unable to rollback transaction for orphaned session", t );
+					}
+				}
+				orphan.close();
+			}
+			catch( Throwable t ) {
+				log.debug( "Unable to close orphaned session", t );
+			}
+		}
+	}
+
+	/**
+	 * Unassociate a previously bound session from the current thread of execution.
+	 *
+	 * @return The session which was unbound.
+	 */
+	public static Session unbind(SessionFactory factory) {
+		return doUnbind( factory, true );
+	}
+
+	private static Session existingSession(SessionFactory factory) {
+		Map sessionMap = sessionMap();
+		if ( sessionMap == null ) {
+			return null;
+		}
+		else {
+			return ( Session ) sessionMap.get( factory );
+		}
+	}
+
+	protected static Map sessionMap() {
+		return ( Map ) context.get();
+	}
+
+	private static void doBind(org.hibernate.Session session, SessionFactory factory) {
+		Map sessionMap = sessionMap();
+		if ( sessionMap == null ) {
+			sessionMap = new HashMap();
+			context.set( sessionMap );
+		}
+		sessionMap.put( factory, session );
+	}
+
+	private static Session doUnbind(SessionFactory factory, boolean releaseMapIfEmpty) {
+		Map sessionMap = sessionMap();
+		Session session = null;
+		if ( sessionMap != null ) {
+			session = ( Session ) sessionMap.remove( factory );
+			if ( releaseMapIfEmpty && sessionMap.isEmpty() ) {
+				context.set( null );
+			}
+		}
+		return session;
+	}
+
+	/**
+	 * JTA transaction synch used for cleanup of the internal session map.
+	 */
+	protected static class CleanupSynch implements Synchronization, Serializable {
+		protected final SessionFactory factory;
+
+		public CleanupSynch(SessionFactory factory) {
+			this.factory = factory;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void beforeCompletion() {
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void afterCompletion(int i) {
+			unbind( factory );
+		}
+	}
+
+	private class TransactionProtectionWrapper implements InvocationHandler, Serializable {
+		private final Session realSession;
+		private Session wrappedSession;
+
+		public TransactionProtectionWrapper(Session realSession) {
+			this.realSession = realSession;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+			try {
+				// If close() is called, guarantee unbind()
+				if ( "close".equals( method.getName()) ) {
+					unbind( realSession.getSessionFactory() );
+				}
+				else if ( "toString".equals( method.getName() )
+					     || "equals".equals( method.getName() )
+					     || "hashCode".equals( method.getName() )
+				         || "getStatistics".equals( method.getName() )
+					     || "isOpen".equals( method.getName() ) ) {
+					// allow these to go through the the real session no matter what
+				}
+				else if ( !realSession.isOpen() ) {
+					// essentially, if the real session is closed allow any
+					// method call to pass through since the real session
+					// will complain by throwing an appropriate exception;
+					// NOTE that allowing close() above has the same basic effect,
+					//   but we capture that there simply to perform the unbind...
+				}
+				else if ( !realSession.getTransaction().isActive() ) {
+					// limit the methods available if no transaction is active
+					if ( "beginTransaction".equals( method.getName() )
+					     || "getTransaction".equals( method.getName() )
+					     || "isTransactionInProgress".equals( method.getName() )
+					     || "setFlushMode".equals( method.getName() )
+					     || "getSessionFactory".equals( method.getName() ) ) {
+						log.trace( "allowing method [" + method.getName() + "] in non-transacted context" );
+					}
+					else if ( "reconnect".equals( method.getName() )
+					          || "disconnect".equals( method.getName() ) ) {
+						// allow these (deprecated) methods to pass through
+					}
+					else {
+						throw new HibernateException( method.getName() + " is not valid without active transaction" );
+					}
+				}
+				log.trace( "allowing proxied method [" + method.getName() + "] to proceed to real session" );
+				return method.invoke( realSession, args );
+			}
+			catch ( InvocationTargetException e ) {
+				if ( e.getTargetException() instanceof RuntimeException ) {
+					throw ( RuntimeException ) e.getTargetException();
+				}
+				else {
+					throw e;
+				}
+			}
+		}
+
+		/**
+		 * Setter for property 'wrapped'.
+		 *
+		 * @param wrapped Value to set for property 'wrapped'.
+		 */
+		public void setWrapped(Session wrapped) {
+			this.wrappedSession = wrapped;
+		}
+
+
+		// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		private void writeObject(ObjectOutputStream oos) throws IOException {
+			// if a ThreadLocalSessionContext-bound session happens to get
+			// serialized, to be completely correct, we need to make sure
+			// that unbinding of that session occurs.
+			oos.defaultWriteObject();
+			if ( existingSession( factory ) == wrappedSession ) {
+				unbind( factory );
+			}
+		}
+
+		private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+			// on the inverse, it makes sense that if a ThreadLocalSessionContext-
+			// bound session then gets deserialized to go ahead and re-bind it to
+			// the ThreadLocalSessionContext session map.
+			ois.defaultReadObject();
+			realSession.getTransaction().registerSynchronization( buildCleanupSynch() );
+			doBind( wrappedSession, factory );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,86 +0,0 @@
-// $Id: AbstractEmptinessExpression.java 6670 2005-05-03 22:19:00Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.sql.ConditionFragment;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-/**
- * Implementation of AbstractEmptinessExpression.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractEmptinessExpression implements Criterion {
-
-	private static final TypedValue[] NO_VALUES = new TypedValue[0];
-
-	protected final String propertyName;
-
-	protected AbstractEmptinessExpression(String propertyName) {
-		this.propertyName = propertyName;
-	}
-
-	protected abstract boolean excludeEmpty();
-
-	public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
-		String entityName = criteriaQuery.getEntityName( criteria, propertyName );
-		String actualPropertyName = criteriaQuery.getPropertyName( propertyName );
-		String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName );
-
-		SessionFactoryImplementor factory = criteriaQuery.getFactory();
-		QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory );
-
-		String[] collectionKeys = collectionPersister.getKeyColumnNames();
-		String[] ownerKeys = ( ( Loadable ) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames();
-
-		String innerSelect = "(select 1 from " + collectionPersister.getTableName()
-		        + " where "
-		        + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString()
-		        + ")";
-
-		return excludeEmpty()
-		        ? "exists " + innerSelect
-		        : "not exists " + innerSelect;
-	}
-
-
-	protected QueryableCollection getQueryableCollection(String entityName, String propertyName, SessionFactoryImplementor factory)
-	        throws HibernateException {
-		PropertyMapping ownerMapping = ( PropertyMapping ) factory.getEntityPersister( entityName );
-		Type type = ownerMapping.toType( propertyName );
-		if ( !type.isCollectionType() ) {
-			throw new MappingException(
-			        "Property path [" + entityName + "." + propertyName + "] does not reference a collection"
-			);
-		}
-
-		String role = ( ( CollectionType ) type ).getRole();
-		try {
-			return ( QueryableCollection ) factory.getCollectionPersister( role );
-		}
-		catch ( ClassCastException cce ) {
-			throw new QueryException( "collection role is not queryable: " + role );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( "collection role not found: " + role );
-		}
-	}
-
-	public final TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	        throws HibernateException {
-		return NO_VALUES;
-	}
-
-	public final String toString() {
-		return propertyName + ( excludeEmpty() ? " is not empty" : " is empty" );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AbstractEmptinessExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,109 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.sql.ConditionFragment;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+/**
+ * Implementation of AbstractEmptinessExpression.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractEmptinessExpression implements Criterion {
+
+	private static final TypedValue[] NO_VALUES = new TypedValue[0];
+
+	protected final String propertyName;
+
+	protected AbstractEmptinessExpression(String propertyName) {
+		this.propertyName = propertyName;
+	}
+
+	protected abstract boolean excludeEmpty();
+
+	public final String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
+		String entityName = criteriaQuery.getEntityName( criteria, propertyName );
+		String actualPropertyName = criteriaQuery.getPropertyName( propertyName );
+		String sqlAlias = criteriaQuery.getSQLAlias( criteria, propertyName );
+
+		SessionFactoryImplementor factory = criteriaQuery.getFactory();
+		QueryableCollection collectionPersister = getQueryableCollection( entityName, actualPropertyName, factory );
+
+		String[] collectionKeys = collectionPersister.getKeyColumnNames();
+		String[] ownerKeys = ( ( Loadable ) factory.getEntityPersister( entityName ) ).getIdentifierColumnNames();
+
+		String innerSelect = "(select 1 from " + collectionPersister.getTableName()
+		        + " where "
+		        + new ConditionFragment().setTableAlias( sqlAlias ).setCondition( ownerKeys, collectionKeys ).toFragmentString()
+		        + ")";
+
+		return excludeEmpty()
+		        ? "exists " + innerSelect
+		        : "not exists " + innerSelect;
+	}
+
+
+	protected QueryableCollection getQueryableCollection(String entityName, String propertyName, SessionFactoryImplementor factory)
+	        throws HibernateException {
+		PropertyMapping ownerMapping = ( PropertyMapping ) factory.getEntityPersister( entityName );
+		Type type = ownerMapping.toType( propertyName );
+		if ( !type.isCollectionType() ) {
+			throw new MappingException(
+			        "Property path [" + entityName + "." + propertyName + "] does not reference a collection"
+			);
+		}
+
+		String role = ( ( CollectionType ) type ).getRole();
+		try {
+			return ( QueryableCollection ) factory.getCollectionPersister( role );
+		}
+		catch ( ClassCastException cce ) {
+			throw new QueryException( "collection role is not queryable: " + role );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( "collection role not found: " + role );
+		}
+	}
+
+	public final TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	        throws HibernateException {
+		return NO_VALUES;
+	}
+
+	public final String toString() {
+		return propertyName + ( excludeEmpty() ? " is not empty" : " is empty" );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/AggregateProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-//$Id: AggregateProjection.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * An aggregation
- * @author max
- */
-public class AggregateProjection extends SimpleProjection {
-
-	protected final String propertyName;
-	private final String aggregate;
-	
-	protected AggregateProjection(String aggregate, String propertyName) {
-		this.aggregate = aggregate;
-		this.propertyName = propertyName;
-	}
-
-	public String toString() {
-		return aggregate + "(" + propertyName + ')';
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new Type[] { criteriaQuery.getType(criteria, propertyName) };
-	}
-
-	public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new StringBuffer()
-			.append(aggregate)
-			.append("(")
-			.append( criteriaQuery.getColumn(criteria, propertyName) )
-			.append(") as y")
-			.append(loc)
-			.append('_')
-			.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/AggregateProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AggregateProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * An aggregation
+ *
+ * @author max
+ */
+public class AggregateProjection extends SimpleProjection {
+
+	protected final String propertyName;
+	private final String aggregate;
+	
+	protected AggregateProjection(String aggregate, String propertyName) {
+		this.aggregate = aggregate;
+		this.propertyName = propertyName;
+	}
+
+	public String toString() {
+		return aggregate + "(" + propertyName + ')';
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new Type[] { criteriaQuery.getType(criteria, propertyName) };
+	}
+
+	public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new StringBuffer()
+			.append(aggregate)
+			.append("(")
+			.append( criteriaQuery.getColumn(criteria, propertyName) )
+			.append(") as y")
+			.append(loc)
+			.append('_')
+			.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/AliasedProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,65 +0,0 @@
-//$Id: AliasedProjection.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class AliasedProjection implements Projection {
-	
-	private final Projection projection;
-	private final String alias;
-	
-	public String toString() {
-		return projection.toString() + " as " + alias;
-	}
-	
-	protected AliasedProjection(Projection projection, String alias) {
-		this.projection = projection;
-		this.alias = alias;
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return projection.toSqlString(criteria, position, criteriaQuery);
-	}
-
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return projection.toGroupSqlString(criteria, criteriaQuery);
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return projection.getTypes(criteria, criteriaQuery);
-	}
-
-	public String[] getColumnAliases(int loc) {
-		return projection.getColumnAliases(loc);
-	}
-
-	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return this.alias.equals(alias) ?
-				getTypes(criteria, criteriaQuery) :
-				null;
-	}
-
-	public String[] getColumnAliases(String alias, int loc) {
-		return this.alias.equals(alias) ? 
-				getColumnAliases(loc) :
-				null;
-	}
-
-	public String[] getAliases() {
-		return new String[]{ alias };
-	}
-
-	public boolean isGrouped() {
-		return projection.isGrouped();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/AliasedProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AliasedProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class AliasedProjection implements Projection {
+	
+	private final Projection projection;
+	private final String alias;
+	
+	public String toString() {
+		return projection.toString() + " as " + alias;
+	}
+	
+	protected AliasedProjection(Projection projection, String alias) {
+		this.projection = projection;
+		this.alias = alias;
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return projection.toSqlString(criteria, position, criteriaQuery);
+	}
+
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return projection.toGroupSqlString(criteria, criteriaQuery);
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return projection.getTypes(criteria, criteriaQuery);
+	}
+
+	public String[] getColumnAliases(int loc) {
+		return projection.getColumnAliases(loc);
+	}
+
+	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return this.alias.equals(alias) ?
+				getTypes(criteria, criteriaQuery) :
+				null;
+	}
+
+	public String[] getColumnAliases(String alias, int loc) {
+		return this.alias.equals(alias) ? 
+				getColumnAliases(loc) :
+				null;
+	}
+
+	public String[] getAliases() {
+		return new String[]{ alias };
+	}
+
+	public boolean isGrouped() {
+		return projection.isGrouped();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/AvgProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: AvgProjection.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class AvgProjection extends AggregateProjection {
-
-	public AvgProjection(String propertyName) {
-		super("avg", propertyName);
-	}
-	
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return new Type[] { Hibernate.DOUBLE };
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/AvgProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/AvgProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * An avg() projection
+ *
+ * @author Gavin King
+ */
+public class AvgProjection extends AggregateProjection {
+
+	public AvgProjection(String propertyName) {
+		super("avg", propertyName);
+	}
+	
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return new Type[] { Hibernate.DOUBLE };
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/BetweenExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-//$Id: BetweenExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * Constrains a property to between two values
- * @author Gavin King
- */
-public class BetweenExpression implements Criterion {
-
-	private final String propertyName;
-	private final Object lo;
-	private final Object hi;
-
-	protected BetweenExpression(String propertyName, Object lo, Object hi) {
-		this.propertyName = propertyName;
-		this.lo = lo;
-		this.hi = hi;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return StringHelper.join(
-			" and ",
-			StringHelper.suffix( criteriaQuery.getColumnsUsingProjection(criteria, propertyName), " between ? and ?" )
-		);
-
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return new TypedValue[] {
-				criteriaQuery.getTypedValue(criteria, propertyName, lo),
-				criteriaQuery.getTypedValue(criteria, propertyName, hi)
-		};
-	}
-
-	public String toString() {
-		return propertyName + " between " + lo + " and " + hi;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/BetweenExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/BetweenExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Constrains a property to between two values
+ * @author Gavin King
+ */
+public class BetweenExpression implements Criterion {
+
+	private final String propertyName;
+	private final Object lo;
+	private final Object hi;
+
+	protected BetweenExpression(String propertyName, Object lo, Object hi) {
+		this.propertyName = propertyName;
+		this.lo = lo;
+		this.hi = hi;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return StringHelper.join(
+			" and ",
+			StringHelper.suffix( criteriaQuery.getColumnsUsingProjection(criteria, propertyName), " between ? and ?" )
+		);
+
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return new TypedValue[] {
+				criteriaQuery.getTypedValue(criteria, propertyName, lo),
+				criteriaQuery.getTypedValue(criteria, propertyName, hi)
+		};
+	}
+
+	public String toString() {
+		return propertyName + " between " + lo + " and " + hi;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Conjunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-package org.hibernate.criterion;
-
-
-/**
- * @author Gavin King
- */
-public class Conjunction extends Junction {
-
-	public Conjunction() {
-		super("and");
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Conjunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Conjunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+/**
+ * @author Gavin King
+ */
+public class Conjunction extends Junction {
+
+	public Conjunction() {
+		super("and");
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-//$Id: CountProjection.java 9913 2006-05-09 07:40:11Z max.andersen at jboss.com $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * A count
- * @author Gavin King
- */
-public class CountProjection extends AggregateProjection {
-
-	private boolean distinct;
-
-	protected CountProjection(String prop) {
-		super("count", prop);
-	}
-
-	public String toString() {
-		if(distinct) {
-			return "distinct " + super.toString();
-		} else {
-			return super.toString();
-		}
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new Type[] { Hibernate.INTEGER };
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		StringBuffer buf = new StringBuffer();
-		buf.append("count(");
-		if (distinct) buf.append("distinct ");
-		return buf.append( criteriaQuery.getColumn(criteria, propertyName) )
-			.append(") as y")
-			.append(position)
-			.append('_')
-			.toString();
-	}
-	
-	public CountProjection setDistinct() {
-		distinct = true;
-		return this;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/CountProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CountProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * A count
+ * @author Gavin King
+ */
+public class CountProjection extends AggregateProjection {
+
+	private boolean distinct;
+
+	protected CountProjection(String prop) {
+		super("count", prop);
+	}
+
+	public String toString() {
+		if(distinct) {
+			return "distinct " + super.toString();
+		} else {
+			return super.toString();
+		}
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new Type[] { Hibernate.INTEGER };
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		StringBuffer buf = new StringBuffer();
+		buf.append("count(");
+		if (distinct) buf.append("distinct ");
+		return buf.append( criteriaQuery.getColumn(criteria, propertyName) )
+			.append(") as y")
+			.append(position)
+			.append('_')
+			.toString();
+	}
+	
+	public CountProjection setDistinct() {
+		distinct = true;
+		return this;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,92 +0,0 @@
-//$Id: CriteriaQuery.java 6970 2005-05-31 20:24:41Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.type.Type;
-
-/**
- * An instance of <tt>CriteriaQuery</tt> is passed to criterion, 
- * order and projection instances when actually compiling and
- * executing the query. This interface is not used by application
- * code.
- * 
- * @author Gavin King
- */
-public interface CriteriaQuery {
-	public SessionFactoryImplementor getFactory();
-	
-	/**
-	 * Get the names of the columns mapped by a property path,
-	 * ignoring projection aliases
-	 */
-	public String getColumn(Criteria criteria, String propertyPath) 
-	throws HibernateException;
-	
-	/**
-	 * Get the type of a property path, ignoring projection aliases
-	 */
-	public Type getType(Criteria criteria, String propertyPath)
-	throws HibernateException;
-
-	/**
-	 * Get the names of the columns mapped by a property path
-	 */
-	public String[] getColumnsUsingProjection(Criteria criteria, String propertyPath) 
-	throws HibernateException;
-	
-	/**
-	 * Get the type of a property path
-	 */
-	public Type getTypeUsingProjection(Criteria criteria, String propertyPath)
-	throws HibernateException;
-
-	/**
-	 * Get the a typed value for the given property value.
-	 */
-	public TypedValue getTypedValue(Criteria criteria, String propertyPath, Object value) 
-	throws HibernateException;
-	
-	/**
-	 * Get the entity name of an entity
-	 */
-	public String getEntityName(Criteria criteria);
-	
-	/**
-	 * Get the entity name of an entity, taking into account
-	 * the qualifier of the property path
-	 */
-	public String getEntityName(Criteria criteria, String propertyPath);
-
-	/**
-	 * Get the root table alias of an entity
-	 */
-	public String getSQLAlias(Criteria subcriteria);
-
-	/**
-	 * Get the root table alias of an entity, taking into account
-	 * the qualifier of the property path
-	 */
-	public String getSQLAlias(Criteria criteria, String propertyPath);
-	
-	/**
-	 * Get the property name, given a possibly qualified property name
-	 */
-	public String getPropertyName(String propertyName);
-	
-	/**
-	 * Get the identifier column names of this entity
-	 */
-	public String[] getIdentifierColumns(Criteria subcriteria);
-	
-	/**
-	 * Get the identifier type of this entity
-	 */
-	public Type getIdentifierType(Criteria subcriteria);
-	
-	public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value);
-	
-	public String generateSQLAlias();
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.type.Type;
+
+/**
+ * An instance of <tt>CriteriaQuery</tt> is passed to criterion, 
+ * order and projection instances when actually compiling and
+ * executing the query. This interface is not used by application
+ * code.
+ * 
+ * @author Gavin King
+ */
+public interface CriteriaQuery {
+	public SessionFactoryImplementor getFactory();
+	
+	/**
+	 * Get the names of the columns mapped by a property path,
+	 * ignoring projection aliases
+	 */
+	public String getColumn(Criteria criteria, String propertyPath) 
+	throws HibernateException;
+	
+	/**
+	 * Get the type of a property path, ignoring projection aliases
+	 */
+	public Type getType(Criteria criteria, String propertyPath)
+	throws HibernateException;
+
+	/**
+	 * Get the names of the columns mapped by a property path
+	 */
+	public String[] getColumnsUsingProjection(Criteria criteria, String propertyPath) 
+	throws HibernateException;
+	
+	/**
+	 * Get the type of a property path
+	 */
+	public Type getTypeUsingProjection(Criteria criteria, String propertyPath)
+	throws HibernateException;
+
+	/**
+	 * Get the a typed value for the given property value.
+	 */
+	public TypedValue getTypedValue(Criteria criteria, String propertyPath, Object value) 
+	throws HibernateException;
+	
+	/**
+	 * Get the entity name of an entity
+	 */
+	public String getEntityName(Criteria criteria);
+	
+	/**
+	 * Get the entity name of an entity, taking into account
+	 * the qualifier of the property path
+	 */
+	public String getEntityName(Criteria criteria, String propertyPath);
+
+	/**
+	 * Get the root table alias of an entity
+	 */
+	public String getSQLAlias(Criteria subcriteria);
+
+	/**
+	 * Get the root table alias of an entity, taking into account
+	 * the qualifier of the property path
+	 */
+	public String getSQLAlias(Criteria criteria, String propertyPath);
+	
+	/**
+	 * Get the property name, given a possibly qualified property name
+	 */
+	public String getPropertyName(String propertyName);
+	
+	/**
+	 * Get the identifier column names of this entity
+	 */
+	public String[] getIdentifierColumns(Criteria subcriteria);
+	
+	/**
+	 * Get the identifier type of this entity
+	 */
+	public Type getIdentifierType(Criteria subcriteria);
+	
+	public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value);
+	
+	public String generateSQLAlias();
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: CriteriaSpecification.java 9116 2006-01-23 21:21:01Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.transform.AliasToEntityMapResultTransformer;
-import org.hibernate.transform.DistinctRootEntityResultTransformer;
-import org.hibernate.transform.PassThroughResultTransformer;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.transform.RootEntityResultTransformer;
-
-/**
- * @author Gavin King
- */
-public interface CriteriaSpecification {
-
-	/**
-	 * The alias that refers to the "root" entity of the criteria query.
-	 */
-	public static final String ROOT_ALIAS = "this";
-
-	/**
-	 * Each row of results is a <tt>Map</tt> from alias to entity instance
-	 */
-	public static final ResultTransformer ALIAS_TO_ENTITY_MAP = new AliasToEntityMapResultTransformer();
-
-	/**
-	 * Each row of results is an instance of the root entity
-	 */
-	public static final ResultTransformer ROOT_ENTITY = new RootEntityResultTransformer();
-
-	/**
-	 * Each row of results is a distinct instance of the root entity
-	 */
-	public static final ResultTransformer DISTINCT_ROOT_ENTITY = new DistinctRootEntityResultTransformer();
-
-	/**
-	 * This result transformer is selected implicitly by calling <tt>setProjection()</tt>
-	 */
-	public static final ResultTransformer PROJECTION = new PassThroughResultTransformer();
-
-	/**
-	 * Specifies joining to an entity based on an inner join.
-	 */
-	public static final int INNER_JOIN = org.hibernate.sql.JoinFragment.INNER_JOIN;
-
-	/**
-	 * Specifies joining to an entity based on a full join.
-	 */
-	public static final int FULL_JOIN = org.hibernate.sql.JoinFragment.FULL_JOIN;
-
-	/**
-	 * Specifies joining to an entity based on a left outer join.
-	 */
-	public static final int LEFT_JOIN = org.hibernate.sql.JoinFragment.LEFT_OUTER_JOIN;
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/CriteriaSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.transform.AliasToEntityMapResultTransformer;
+import org.hibernate.transform.DistinctRootEntityResultTransformer;
+import org.hibernate.transform.PassThroughResultTransformer;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.transform.RootEntityResultTransformer;
+
+/**
+ * @author Gavin King
+ */
+public interface CriteriaSpecification {
+
+	/**
+	 * The alias that refers to the "root" entity of the criteria query.
+	 */
+	public static final String ROOT_ALIAS = "this";
+
+	/**
+	 * Each row of results is a <tt>Map</tt> from alias to entity instance
+	 */
+	public static final ResultTransformer ALIAS_TO_ENTITY_MAP = new AliasToEntityMapResultTransformer();
+
+	/**
+	 * Each row of results is an instance of the root entity
+	 */
+	public static final ResultTransformer ROOT_ENTITY = new RootEntityResultTransformer();
+
+	/**
+	 * Each row of results is a distinct instance of the root entity
+	 */
+	public static final ResultTransformer DISTINCT_ROOT_ENTITY = new DistinctRootEntityResultTransformer();
+
+	/**
+	 * This result transformer is selected implicitly by calling <tt>setProjection()</tt>
+	 */
+	public static final ResultTransformer PROJECTION = new PassThroughResultTransformer();
+
+	/**
+	 * Specifies joining to an entity based on an inner join.
+	 */
+	public static final int INNER_JOIN = org.hibernate.sql.JoinFragment.INNER_JOIN;
+
+	/**
+	 * Specifies joining to an entity based on a full join.
+	 */
+	public static final int FULL_JOIN = org.hibernate.sql.JoinFragment.FULL_JOIN;
+
+	/**
+	 * Specifies joining to an entity based on a left outer join.
+	 */
+	public static final int LEFT_JOIN = org.hibernate.sql.JoinFragment.LEFT_OUTER_JOIN;
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Criterion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-//$Id: Criterion.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import java.io.Serializable;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-
-/**
- * An object-oriented representation of a query criterion that may be used 
- * as a restriction in a <tt>Criteria</tt> query.
- * Built-in criterion types are provided by the <tt>Restrictions</tt> factory 
- * class. This interface might be implemented by application classes that 
- * define custom restriction criteria.
- *
- * @see Restrictions
- * @see org.hibernate.Criteria
- * @author Gavin King
- */
-public interface Criterion extends Serializable {
-
-	/**
-	 * Render the SQL fragment
-	 * @param criteriaQuery
-	 * @param alias
-	 * @return String
-	 * @throws HibernateException
-	 */
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-	
-	/**
-	 * Return typed values for all parameters in the rendered SQL fragment
-	 * @param criteria TODO
-	 * @param criteriaQuery 
-	 * @return TypedValue[]
-	 * @throws HibernateException
-	 */
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Criterion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Criterion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.criterion;
+
+import java.io.Serializable;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * An object-oriented representation of a query criterion that may be used 
+ * as a restriction in a <tt>Criteria</tt> query.
+ * Built-in criterion types are provided by the <tt>Restrictions</tt> factory 
+ * class. This interface might be implemented by application classes that 
+ * define custom restriction criteria.
+ *
+ * @see Restrictions
+ * @see Criteria
+ * @author Gavin King
+ */
+public interface Criterion extends Serializable {
+
+	/**
+	 * Render the SQL fragment
+	 *
+	 * @param criteria The local criteria
+	 * @param criteriaQuery The overal criteria query
+	 *
+	 * @return The generated SQL fragment
+	 * @throws org.hibernate.HibernateException Problem during rendering.
+	 */
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException;
+	
+	/**
+	 * Return typed values for all parameters in the rendered SQL fragment
+	 *
+	 * @param criteria The local criteria
+	 * @param criteriaQuery The overal criteria query
+	 *
+	 * @return The types values (for binding)
+	 * @throws HibernateException Problem determining types.
+	 */
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,153 +0,0 @@
-//$Id: DetachedCriteria.java 8757 2005-12-06 03:35:50Z steveebersole $
-package org.hibernate.criterion;
-
-import java.io.Serializable;
-
-import org.hibernate.Criteria;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.Session;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.transform.ResultTransformer;
-
-/**
- * Some applications need to create criteria queries in "detached
- * mode", where the Hibernate session is not available. This class
- * may be instantiated anywhere, and then a <literal>Criteria</literal>
- * may be obtained by passing a session to 
- * <literal>getExecutableCriteria()</literal>. All methods have the
- * same semantics and behavior as the corresponding methods of the
- * <literal>Criteria</literal> interface.
- * 
- * @see org.hibernate.Criteria
- * @author Gavin King
- */
-public class DetachedCriteria implements CriteriaSpecification, Serializable {
-	
-	private final CriteriaImpl impl;
-	private final Criteria criteria;
-	
-	protected DetachedCriteria(String entityName) {
-		impl = new CriteriaImpl(entityName, null);
-		criteria = impl;
-	}
-	
-	protected DetachedCriteria(String entityName, String alias) {
-		impl = new CriteriaImpl(entityName, alias, null);
-		criteria = impl;
-	}
-	
-	protected DetachedCriteria(CriteriaImpl impl, Criteria criteria) {
-		this.impl = impl;
-		this.criteria = criteria;
-	}
-	
-	/**
-	 * Get an executable instance of <literal>Criteria</literal>,
-	 * to actually run the query.
-	 */
-	public Criteria getExecutableCriteria(Session session) {
-		impl.setSession( ( SessionImplementor ) session );
-		return impl;
-	}
-	
-	public static DetachedCriteria forEntityName(String entityName) {
-		return new DetachedCriteria(entityName);
-	}
-	
-	public static DetachedCriteria forEntityName(String entityName, String alias) {
-		return new DetachedCriteria(entityName, alias);
-	}
-	
-	public static DetachedCriteria forClass(Class clazz) {
-		return new DetachedCriteria( clazz.getName() );
-	}
-	
-	public static DetachedCriteria forClass(Class clazz, String alias) {
-		return new DetachedCriteria( clazz.getName() , alias );
-	}
-	
-	public DetachedCriteria add(Criterion criterion) {
-		criteria.add(criterion);
-		return this;
-	}
-
-	public DetachedCriteria addOrder(Order order) {
-		criteria.addOrder(order);
-		return this;
-	}
-
-	public DetachedCriteria createAlias(String associationPath, String alias)
-	throws HibernateException {
-		criteria.createAlias(associationPath, alias);
-		return this;
-	}
-
-	public DetachedCriteria createCriteria(String associationPath, String alias)
-	throws HibernateException {
-		return new DetachedCriteria( impl, criteria.createCriteria(associationPath, alias) );
-	}
-
-	public DetachedCriteria createCriteria(String associationPath)
-	throws HibernateException {
-		return new DetachedCriteria( impl, criteria.createCriteria(associationPath) );
-	}
-
-	public String getAlias() {
-		return criteria.getAlias();
-	}
-
-	public DetachedCriteria setFetchMode(String associationPath, FetchMode mode)
-	throws HibernateException {
-		criteria.setFetchMode(associationPath, mode);
-		return this;
-	}
-
-	public DetachedCriteria setProjection(Projection projection) {
-		criteria.setProjection(projection);
-		return this;
-	}
-
-	public DetachedCriteria setResultTransformer(ResultTransformer resultTransformer) {
-		criteria.setResultTransformer(resultTransformer);
-		return this;
-	}
-	
-	public String toString() {
-		return "DetachableCriteria(" + criteria.toString() + ')';
-	}
-	
-	CriteriaImpl getCriteriaImpl() {
-		return impl;
-	}
-
-    public DetachedCriteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
-        criteria.createAlias(associationPath, alias, joinType);
-        return this;
-    }
-
-    public DetachedCriteria createCriteria(String associationPath, int joinType) throws HibernateException {
-        return new DetachedCriteria(impl, criteria.createCriteria(associationPath, joinType));
-    }
-
-    public DetachedCriteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
-        return new DetachedCriteria(impl, criteria.createCriteria(associationPath, alias, joinType));
-    }
-
-    public DetachedCriteria setComment(String comment) {
-        criteria.setComment(comment);
-        return this;
-    }
-
-    public DetachedCriteria setLockMode(LockMode lockMode) {
-        criteria.setLockMode(lockMode);
-        return this;
-    }
-
-    public DetachedCriteria setLockMode(String alias, LockMode lockMode) {
-        criteria.setLockMode(alias, lockMode);
-        return this;
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/DetachedCriteria.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,176 @@
+/*
+ * 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.criterion;
+
+import java.io.Serializable;
+
+import org.hibernate.Criteria;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.Session;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.transform.ResultTransformer;
+
+/**
+ * Some applications need to create criteria queries in "detached
+ * mode", where the Hibernate session is not available. This class
+ * may be instantiated anywhere, and then a <literal>Criteria</literal>
+ * may be obtained by passing a session to 
+ * <literal>getExecutableCriteria()</literal>. All methods have the
+ * same semantics and behavior as the corresponding methods of the
+ * <literal>Criteria</literal> interface.
+ * 
+ * @see org.hibernate.Criteria
+ * @author Gavin King
+ */
+public class DetachedCriteria implements CriteriaSpecification, Serializable {
+	
+	private final CriteriaImpl impl;
+	private final Criteria criteria;
+	
+	protected DetachedCriteria(String entityName) {
+		impl = new CriteriaImpl(entityName, null);
+		criteria = impl;
+	}
+	
+	protected DetachedCriteria(String entityName, String alias) {
+		impl = new CriteriaImpl(entityName, alias, null);
+		criteria = impl;
+	}
+	
+	protected DetachedCriteria(CriteriaImpl impl, Criteria criteria) {
+		this.impl = impl;
+		this.criteria = criteria;
+	}
+	
+	/**
+	 * Get an executable instance of <literal>Criteria</literal>,
+	 * to actually run the query.
+	 */
+	public Criteria getExecutableCriteria(Session session) {
+		impl.setSession( ( SessionImplementor ) session );
+		return impl;
+	}
+	
+	public static DetachedCriteria forEntityName(String entityName) {
+		return new DetachedCriteria(entityName);
+	}
+	
+	public static DetachedCriteria forEntityName(String entityName, String alias) {
+		return new DetachedCriteria(entityName, alias);
+	}
+	
+	public static DetachedCriteria forClass(Class clazz) {
+		return new DetachedCriteria( clazz.getName() );
+	}
+	
+	public static DetachedCriteria forClass(Class clazz, String alias) {
+		return new DetachedCriteria( clazz.getName() , alias );
+	}
+	
+	public DetachedCriteria add(Criterion criterion) {
+		criteria.add(criterion);
+		return this;
+	}
+
+	public DetachedCriteria addOrder(Order order) {
+		criteria.addOrder(order);
+		return this;
+	}
+
+	public DetachedCriteria createAlias(String associationPath, String alias)
+	throws HibernateException {
+		criteria.createAlias(associationPath, alias);
+		return this;
+	}
+
+	public DetachedCriteria createCriteria(String associationPath, String alias)
+	throws HibernateException {
+		return new DetachedCriteria( impl, criteria.createCriteria(associationPath, alias) );
+	}
+
+	public DetachedCriteria createCriteria(String associationPath)
+	throws HibernateException {
+		return new DetachedCriteria( impl, criteria.createCriteria(associationPath) );
+	}
+
+	public String getAlias() {
+		return criteria.getAlias();
+	}
+
+	public DetachedCriteria setFetchMode(String associationPath, FetchMode mode)
+	throws HibernateException {
+		criteria.setFetchMode(associationPath, mode);
+		return this;
+	}
+
+	public DetachedCriteria setProjection(Projection projection) {
+		criteria.setProjection(projection);
+		return this;
+	}
+
+	public DetachedCriteria setResultTransformer(ResultTransformer resultTransformer) {
+		criteria.setResultTransformer(resultTransformer);
+		return this;
+	}
+	
+	public String toString() {
+		return "DetachableCriteria(" + criteria.toString() + ')';
+	}
+	
+	CriteriaImpl getCriteriaImpl() {
+		return impl;
+	}
+
+    public DetachedCriteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
+        criteria.createAlias(associationPath, alias, joinType);
+        return this;
+    }
+
+    public DetachedCriteria createCriteria(String associationPath, int joinType) throws HibernateException {
+        return new DetachedCriteria(impl, criteria.createCriteria(associationPath, joinType));
+    }
+
+    public DetachedCriteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
+        return new DetachedCriteria(impl, criteria.createCriteria(associationPath, alias, joinType));
+    }
+
+    public DetachedCriteria setComment(String comment) {
+        criteria.setComment(comment);
+        return this;
+    }
+
+    public DetachedCriteria setLockMode(LockMode lockMode) {
+        criteria.setLockMode(lockMode);
+        return this;
+    }
+
+    public DetachedCriteria setLockMode(String alias, LockMode lockMode) {
+        criteria.setLockMode(alias, lockMode);
+        return this;
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Disjunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-package org.hibernate.criterion;
-
-
-/**
- * @author Gavin King
- */
-public class Disjunction extends Junction {
-
-	protected Disjunction() {
-		super("or");
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Disjunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Disjunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+/**
+ * @author Gavin King
+ */
+public class Disjunction extends Junction {
+
+	protected Disjunction() {
+		super("or");
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Distinct.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: Distinct.java 6452 2005-04-18 17:16:57Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class Distinct implements Projection {
-
-	private final Projection projection;
-	
-	public Distinct(Projection proj) {
-		this.projection = proj;
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery)
-			throws HibernateException {
-		return "distinct " + projection.toSqlString(criteria, position, criteriaQuery);
-	}
-
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-			throws HibernateException {
-		return projection.toGroupSqlString(criteria, criteriaQuery);
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
-			throws HibernateException {
-		return projection.getTypes(criteria, criteriaQuery);
-	}
-
-	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery)
-			throws HibernateException {
-		return projection.getTypes(alias, criteria, criteriaQuery);
-	}
-
-	public String[] getColumnAliases(int loc) {
-		return projection.getColumnAliases(loc);
-	}
-
-	public String[] getColumnAliases(String alias, int loc) {
-		return projection.getColumnAliases(alias, loc);
-	}
-
-	public String[] getAliases() {
-		return projection.getAliases();
-	}
-
-	public boolean isGrouped() {
-		return projection.isGrouped();
-	}
-
-	public String toString() {
-		return "distinct " + projection.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Distinct.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Distinct.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class Distinct implements Projection {
+
+	private final Projection projection;
+	
+	public Distinct(Projection proj) {
+		this.projection = proj;
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery)
+			throws HibernateException {
+		return "distinct " + projection.toSqlString(criteria, position, criteriaQuery);
+	}
+
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+			throws HibernateException {
+		return projection.toGroupSqlString(criteria, criteriaQuery);
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
+			throws HibernateException {
+		return projection.getTypes(criteria, criteriaQuery);
+	}
+
+	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery)
+			throws HibernateException {
+		return projection.getTypes(alias, criteria, criteriaQuery);
+	}
+
+	public String[] getColumnAliases(int loc) {
+		return projection.getColumnAliases(loc);
+	}
+
+	public String[] getColumnAliases(String alias, int loc) {
+		return projection.getColumnAliases(alias, loc);
+	}
+
+	public String[] getAliases() {
+		return projection.getAliases();
+	}
+
+	public boolean isGrouped() {
+		return projection.isGrouped();
+	}
+
+	public String toString() {
+		return "distinct " + projection.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/EmptyExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-//$Id: EmptyExpression.java 6661 2005-05-03 20:12:20Z steveebersole $
-package org.hibernate.criterion;
-
-/**
- * @author Gavin King
- */
-public class EmptyExpression extends AbstractEmptinessExpression implements Criterion {
-
-	protected EmptyExpression(String propertyName) {
-		super( propertyName );
-	}
-
-	protected boolean excludeEmpty() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/EmptyExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/EmptyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.criterion;
+
+/**
+ * @author Gavin King
+ */
+public class EmptyExpression extends AbstractEmptinessExpression implements Criterion {
+
+	protected EmptyExpression(String propertyName) {
+		super( propertyName );
+	}
+
+	protected boolean excludeEmpty() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Example.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,374 +0,0 @@
-//$Id: Example.java 10061 2006-06-28 05:20:51Z steve.ebersole at jboss.com $
-package org.hibernate.criterion;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * Support for query by example.
- * <pre>
- * List results = session.createCriteria(Parent.class)
- *     .add( Example.create(parent).ignoreCase() )
- *     .createCriteria("child")
- *         .add( Example.create( parent.getChild() ) )
- *     .list();
- * </pre>
- * "Examples" may be mixed and matched with "Expressions" in the same <tt>Criteria</tt>.
- * @see org.hibernate.Criteria
- * @author Gavin King
- */
-
-public class Example implements Criterion {
-
-	private final Object entity;
-	private final Set excludedProperties = new HashSet();
-	private PropertySelector selector;
-	private boolean isLikeEnabled;
-	private Character escapeCharacter;
-	private boolean isIgnoreCaseEnabled;
-	private MatchMode matchMode;
-
-	/**
-	 * A strategy for choosing property values for inclusion in the query
-	 * criteria
-	 */
-
-	public static interface PropertySelector extends Serializable {
-		public boolean include(Object propertyValue, String propertyName, Type type);
-	}
-
-	private static final PropertySelector NOT_NULL = new NotNullPropertySelector();
-	private static final PropertySelector ALL = new AllPropertySelector();
-	private static final PropertySelector NOT_NULL_OR_ZERO = new NotNullOrZeroPropertySelector();
-
-	static final class AllPropertySelector implements PropertySelector {
-		public boolean include(Object object, String propertyName, Type type) {
-			return true;
-		}
-		
-		private Object readResolve() {
-			return ALL;
-		}
-	}
-
-	static final class NotNullPropertySelector implements PropertySelector {
-		public boolean include(Object object, String propertyName, Type type) {
-			return object!=null;
-		}
-		
-		private Object readResolve() {
-			return NOT_NULL;
-		}
-	}
-
-	static final class NotNullOrZeroPropertySelector implements PropertySelector {
-		public boolean include(Object object, String propertyName, Type type) {
-			return object!=null && (
-				!(object instanceof Number) || ( (Number) object ).longValue()!=0
-			);
-		}
-		
-		private Object readResolve() {
-			return NOT_NULL_OR_ZERO;
-		}
-	}
-
-	/**
-	 * Set escape character for "like" clause
-	 */
-	public Example setEscapeCharacter(Character escapeCharacter) {
-		this.escapeCharacter = escapeCharacter;
-		return this;
-	}
-
-	/**
-	 * Set the property selector
-	 */
-	public Example setPropertySelector(PropertySelector selector) {
-		this.selector = selector;
-		return this;
-	}
-
-	/**
-	 * Exclude zero-valued properties
-	 */
-	public Example excludeZeroes() {
-		setPropertySelector(NOT_NULL_OR_ZERO);
-		return this;
-	}
-
-	/**
-	 * Don't exclude null or zero-valued properties
-	 */
-	public Example excludeNone() {
-		setPropertySelector(ALL);
-		return this;
-	}
-
-	/**
-	 * Use the "like" operator for all string-valued properties
-	 */
-	public Example enableLike(MatchMode matchMode) {
-		isLikeEnabled = true;
-		this.matchMode = matchMode;
-		return this;
-	}
-
-	/**
-	 * Use the "like" operator for all string-valued properties
-	 */
-	public Example enableLike() {
-		return enableLike(MatchMode.EXACT);
-	}
-
-	/**
-	 * Ignore case for all string-valued properties
-	 */
-	public Example ignoreCase() {
-		isIgnoreCaseEnabled = true;
-		return this;
-	}
-
-	/**
-	 * Exclude a particular named property
-	 */
-	public Example excludeProperty(String name) {
-		excludedProperties.add(name);
-		return this;
-	}
-
-	/**
-	 * Create a new instance, which includes all non-null properties
-	 * by default
-	 * @param entity
-	 * @return a new instance of <tt>Example</tt>
-	 */
-	public static Example create(Object entity) {
-		if (entity==null) throw new NullPointerException("null example");
-		return new Example(entity, NOT_NULL);
-	}
-
-	protected Example(Object entity, PropertySelector selector) {
-		this.entity = entity;
-		this.selector = selector;
-	}
-
-	public String toString() {
-		return "example (" + entity + ')';
-	}
-
-	private boolean isPropertyIncluded(Object value, String name, Type type) {
-		return !excludedProperties.contains(name) &&
-			!type.isAssociationType() &&
-			selector.include(value, name, type);
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-		throws HibernateException {
-
-		StringBuffer buf = new StringBuffer().append('(');
-		EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName(criteria) );
-		String[] propertyNames = meta.getPropertyNames();
-		Type[] propertyTypes = meta.getPropertyTypes();
-		//TODO: get all properties, not just the fetched ones!
-		Object[] propertyValues = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
-		for (int i=0; i<propertyNames.length; i++) {
-			Object propertyValue = propertyValues[i];
-			String propertyName = propertyNames[i];
-
-			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
-				isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] );
-			if (isPropertyIncluded) {
-				if ( propertyTypes[i].isComponentType() ) {
-					appendComponentCondition(
-						propertyName,
-						propertyValue,
-						(AbstractComponentType) propertyTypes[i],
-						criteria,
-						criteriaQuery,
-						buf
-					);
-				}
-				else {
-					appendPropertyCondition(
-						propertyName,
-						propertyValue,
-						criteria,
-						criteriaQuery,
-						buf
-					);
-				}
-			}
-		}
-		if ( buf.length()==1 ) buf.append("1=1"); //yuck!
-		return buf.append(')').toString();
-	}
-
-	private static final Object[] TYPED_VALUES = new TypedValue[0];
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		EntityPersister meta = criteriaQuery.getFactory()
-				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
-		String[] propertyNames = meta.getPropertyNames();
-		Type[] propertyTypes = meta.getPropertyTypes();
-		 //TODO: get all properties, not just the fetched ones!
-		Object[] values = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
-		List list = new ArrayList();
-		for (int i=0; i<propertyNames.length; i++) {
-			Object value = values[i];
-			Type type = propertyTypes[i];
-			String name = propertyNames[i];
-
-			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
-				isPropertyIncluded(value, name, type);
-
-			if (isPropertyIncluded) {
-				if ( propertyTypes[i].isComponentType() ) {
-					addComponentTypedValues(name, value, (AbstractComponentType) type, list, criteria, criteriaQuery);
-				}
-				else {
-					addPropertyTypedValue(value, type, list);
-				}
-			}
-		}
-		return (TypedValue[]) list.toArray(TYPED_VALUES);
-	}
-	
-	private EntityMode getEntityMode(Criteria criteria, CriteriaQuery criteriaQuery) {
-		EntityPersister meta = criteriaQuery.getFactory()
-				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
-		EntityMode result = meta.guessEntityMode(entity);
-		if (result==null) {
-			throw new ClassCastException( entity.getClass().getName() );
-		}
-		return result;
-	}
-
-	protected void addPropertyTypedValue(Object value, Type type, List list) {
-		if ( value!=null ) {
-			if ( value instanceof String ) {
-				String string = (String) value;
-				if (isIgnoreCaseEnabled) string = string.toLowerCase();
-				if (isLikeEnabled) string = matchMode.toMatchString(string);
-				value = string;
-			}
-			list.add( new TypedValue(type, value, null) );
-		}
-	}
-
-	protected void addComponentTypedValues(
-			String path, 
-			Object component, 
-			AbstractComponentType type, 
-			List list, 
-			Criteria criteria, 
-			CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		if (component!=null) {
-			String[] propertyNames = type.getPropertyNames();
-			Type[] subtypes = type.getSubtypes();
-			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
-			for (int i=0; i<propertyNames.length; i++) {
-				Object value = values[i];
-				Type subtype = subtypes[i];
-				String subpath = StringHelper.qualify( path, propertyNames[i] );
-				if ( isPropertyIncluded(value, subpath, subtype) ) {
-					if ( subtype.isComponentType() ) {
-						addComponentTypedValues(subpath, value, (AbstractComponentType) subtype, list, criteria, criteriaQuery);
-					}
-					else {
-						addPropertyTypedValue(value, subtype, list);
-					}
-				}
-			}
-		}
-	}
-
-	protected void appendPropertyCondition(
-		String propertyName,
-		Object propertyValue,
-		Criteria criteria,
-		CriteriaQuery cq,
-		StringBuffer buf)
-	throws HibernateException {
-		Criterion crit;
-		if ( propertyValue!=null ) {
-			boolean isString = propertyValue instanceof String;
-			if ( isLikeEnabled && isString ) {
-				crit = new LikeExpression(
-						propertyName,
-						( String ) propertyValue,
-						matchMode,
-						escapeCharacter,
-						isIgnoreCaseEnabled
-				);
-			}
-			else {
-				crit = new SimpleExpression( propertyName, propertyValue, "=", isIgnoreCaseEnabled && isString );
-			}
-		}
-		else {
-			crit = new NullExpression(propertyName);
-		}
-		String critCondition = crit.toSqlString(criteria, cq);
-		if ( buf.length()>1 && critCondition.trim().length()>0 ) buf.append(" and ");
-		buf.append(critCondition);
-	}
-
-	protected void appendComponentCondition(
-		String path,
-		Object component,
-		AbstractComponentType type,
-		Criteria criteria,
-		CriteriaQuery criteriaQuery,
-		StringBuffer buf)
-	throws HibernateException {
-
-		if (component!=null) {
-			String[] propertyNames = type.getPropertyNames();
-			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
-			Type[] subtypes = type.getSubtypes();
-			for (int i=0; i<propertyNames.length; i++) {
-				String subpath = StringHelper.qualify( path, propertyNames[i] );
-				Object value = values[i];
-				if ( isPropertyIncluded( value, subpath, subtypes[i] ) ) {
-					Type subtype = subtypes[i];
-					if ( subtype.isComponentType() ) {
-						appendComponentCondition(
-							subpath,
-							value,
-							(AbstractComponentType) subtype,
-							criteria,
-							criteriaQuery,
-							buf
-						);
-					}
-					else {
-						appendPropertyCondition(
-							subpath,
-							value,
-							criteria,
-							criteriaQuery,
-							buf
-						);
-					}
-				}
-			}
-		}
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Example.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Example.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,397 @@
+/*
+ * 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.criterion;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Support for query by example.
+ * <pre>
+ * List results = session.createCriteria(Parent.class)
+ *     .add( Example.create(parent).ignoreCase() )
+ *     .createCriteria("child")
+ *         .add( Example.create( parent.getChild() ) )
+ *     .list();
+ * </pre>
+ * "Examples" may be mixed and matched with "Expressions" in the same <tt>Criteria</tt>.
+ * @see org.hibernate.Criteria
+ * @author Gavin King
+ */
+
+public class Example implements Criterion {
+
+	private final Object entity;
+	private final Set excludedProperties = new HashSet();
+	private PropertySelector selector;
+	private boolean isLikeEnabled;
+	private Character escapeCharacter;
+	private boolean isIgnoreCaseEnabled;
+	private MatchMode matchMode;
+
+	/**
+	 * A strategy for choosing property values for inclusion in the query
+	 * criteria
+	 */
+
+	public static interface PropertySelector extends Serializable {
+		public boolean include(Object propertyValue, String propertyName, Type type);
+	}
+
+	private static final PropertySelector NOT_NULL = new NotNullPropertySelector();
+	private static final PropertySelector ALL = new AllPropertySelector();
+	private static final PropertySelector NOT_NULL_OR_ZERO = new NotNullOrZeroPropertySelector();
+
+	static final class AllPropertySelector implements PropertySelector {
+		public boolean include(Object object, String propertyName, Type type) {
+			return true;
+		}
+		
+		private Object readResolve() {
+			return ALL;
+		}
+	}
+
+	static final class NotNullPropertySelector implements PropertySelector {
+		public boolean include(Object object, String propertyName, Type type) {
+			return object!=null;
+		}
+		
+		private Object readResolve() {
+			return NOT_NULL;
+		}
+	}
+
+	static final class NotNullOrZeroPropertySelector implements PropertySelector {
+		public boolean include(Object object, String propertyName, Type type) {
+			return object!=null && (
+				!(object instanceof Number) || ( (Number) object ).longValue()!=0
+			);
+		}
+		
+		private Object readResolve() {
+			return NOT_NULL_OR_ZERO;
+		}
+	}
+
+	/**
+	 * Set escape character for "like" clause
+	 */
+	public Example setEscapeCharacter(Character escapeCharacter) {
+		this.escapeCharacter = escapeCharacter;
+		return this;
+	}
+
+	/**
+	 * Set the property selector
+	 */
+	public Example setPropertySelector(PropertySelector selector) {
+		this.selector = selector;
+		return this;
+	}
+
+	/**
+	 * Exclude zero-valued properties
+	 */
+	public Example excludeZeroes() {
+		setPropertySelector(NOT_NULL_OR_ZERO);
+		return this;
+	}
+
+	/**
+	 * Don't exclude null or zero-valued properties
+	 */
+	public Example excludeNone() {
+		setPropertySelector(ALL);
+		return this;
+	}
+
+	/**
+	 * Use the "like" operator for all string-valued properties
+	 */
+	public Example enableLike(MatchMode matchMode) {
+		isLikeEnabled = true;
+		this.matchMode = matchMode;
+		return this;
+	}
+
+	/**
+	 * Use the "like" operator for all string-valued properties
+	 */
+	public Example enableLike() {
+		return enableLike(MatchMode.EXACT);
+	}
+
+	/**
+	 * Ignore case for all string-valued properties
+	 */
+	public Example ignoreCase() {
+		isIgnoreCaseEnabled = true;
+		return this;
+	}
+
+	/**
+	 * Exclude a particular named property
+	 */
+	public Example excludeProperty(String name) {
+		excludedProperties.add(name);
+		return this;
+	}
+
+	/**
+	 * Create a new instance, which includes all non-null properties
+	 * by default
+	 * @param entity
+	 * @return a new instance of <tt>Example</tt>
+	 */
+	public static Example create(Object entity) {
+		if (entity==null) throw new NullPointerException("null example");
+		return new Example(entity, NOT_NULL);
+	}
+
+	protected Example(Object entity, PropertySelector selector) {
+		this.entity = entity;
+		this.selector = selector;
+	}
+
+	public String toString() {
+		return "example (" + entity + ')';
+	}
+
+	private boolean isPropertyIncluded(Object value, String name, Type type) {
+		return !excludedProperties.contains(name) &&
+			!type.isAssociationType() &&
+			selector.include(value, name, type);
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+		throws HibernateException {
+
+		StringBuffer buf = new StringBuffer().append('(');
+		EntityPersister meta = criteriaQuery.getFactory().getEntityPersister( criteriaQuery.getEntityName(criteria) );
+		String[] propertyNames = meta.getPropertyNames();
+		Type[] propertyTypes = meta.getPropertyTypes();
+		//TODO: get all properties, not just the fetched ones!
+		Object[] propertyValues = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
+		for (int i=0; i<propertyNames.length; i++) {
+			Object propertyValue = propertyValues[i];
+			String propertyName = propertyNames[i];
+
+			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
+				isPropertyIncluded( propertyValue, propertyName, propertyTypes[i] );
+			if (isPropertyIncluded) {
+				if ( propertyTypes[i].isComponentType() ) {
+					appendComponentCondition(
+						propertyName,
+						propertyValue,
+						(AbstractComponentType) propertyTypes[i],
+						criteria,
+						criteriaQuery,
+						buf
+					);
+				}
+				else {
+					appendPropertyCondition(
+						propertyName,
+						propertyValue,
+						criteria,
+						criteriaQuery,
+						buf
+					);
+				}
+			}
+		}
+		if ( buf.length()==1 ) buf.append("1=1"); //yuck!
+		return buf.append(')').toString();
+	}
+
+	private static final Object[] TYPED_VALUES = new TypedValue[0];
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		EntityPersister meta = criteriaQuery.getFactory()
+				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
+		String[] propertyNames = meta.getPropertyNames();
+		Type[] propertyTypes = meta.getPropertyTypes();
+		 //TODO: get all properties, not just the fetched ones!
+		Object[] values = meta.getPropertyValues( entity, getEntityMode(criteria, criteriaQuery) );
+		List list = new ArrayList();
+		for (int i=0; i<propertyNames.length; i++) {
+			Object value = values[i];
+			Type type = propertyTypes[i];
+			String name = propertyNames[i];
+
+			boolean isPropertyIncluded = i!=meta.getVersionProperty() &&
+				isPropertyIncluded(value, name, type);
+
+			if (isPropertyIncluded) {
+				if ( propertyTypes[i].isComponentType() ) {
+					addComponentTypedValues(name, value, (AbstractComponentType) type, list, criteria, criteriaQuery);
+				}
+				else {
+					addPropertyTypedValue(value, type, list);
+				}
+			}
+		}
+		return (TypedValue[]) list.toArray(TYPED_VALUES);
+	}
+	
+	private EntityMode getEntityMode(Criteria criteria, CriteriaQuery criteriaQuery) {
+		EntityPersister meta = criteriaQuery.getFactory()
+				.getEntityPersister( criteriaQuery.getEntityName(criteria) );
+		EntityMode result = meta.guessEntityMode(entity);
+		if (result==null) {
+			throw new ClassCastException( entity.getClass().getName() );
+		}
+		return result;
+	}
+
+	protected void addPropertyTypedValue(Object value, Type type, List list) {
+		if ( value!=null ) {
+			if ( value instanceof String ) {
+				String string = (String) value;
+				if (isIgnoreCaseEnabled) string = string.toLowerCase();
+				if (isLikeEnabled) string = matchMode.toMatchString(string);
+				value = string;
+			}
+			list.add( new TypedValue(type, value, null) );
+		}
+	}
+
+	protected void addComponentTypedValues(
+			String path, 
+			Object component, 
+			AbstractComponentType type, 
+			List list, 
+			Criteria criteria, 
+			CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		if (component!=null) {
+			String[] propertyNames = type.getPropertyNames();
+			Type[] subtypes = type.getSubtypes();
+			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
+			for (int i=0; i<propertyNames.length; i++) {
+				Object value = values[i];
+				Type subtype = subtypes[i];
+				String subpath = StringHelper.qualify( path, propertyNames[i] );
+				if ( isPropertyIncluded(value, subpath, subtype) ) {
+					if ( subtype.isComponentType() ) {
+						addComponentTypedValues(subpath, value, (AbstractComponentType) subtype, list, criteria, criteriaQuery);
+					}
+					else {
+						addPropertyTypedValue(value, subtype, list);
+					}
+				}
+			}
+		}
+	}
+
+	protected void appendPropertyCondition(
+		String propertyName,
+		Object propertyValue,
+		Criteria criteria,
+		CriteriaQuery cq,
+		StringBuffer buf)
+	throws HibernateException {
+		Criterion crit;
+		if ( propertyValue!=null ) {
+			boolean isString = propertyValue instanceof String;
+			if ( isLikeEnabled && isString ) {
+				crit = new LikeExpression(
+						propertyName,
+						( String ) propertyValue,
+						matchMode,
+						escapeCharacter,
+						isIgnoreCaseEnabled
+				);
+			}
+			else {
+				crit = new SimpleExpression( propertyName, propertyValue, "=", isIgnoreCaseEnabled && isString );
+			}
+		}
+		else {
+			crit = new NullExpression(propertyName);
+		}
+		String critCondition = crit.toSqlString(criteria, cq);
+		if ( buf.length()>1 && critCondition.trim().length()>0 ) buf.append(" and ");
+		buf.append(critCondition);
+	}
+
+	protected void appendComponentCondition(
+		String path,
+		Object component,
+		AbstractComponentType type,
+		Criteria criteria,
+		CriteriaQuery criteriaQuery,
+		StringBuffer buf)
+	throws HibernateException {
+
+		if (component!=null) {
+			String[] propertyNames = type.getPropertyNames();
+			Object[] values = type.getPropertyValues( component, getEntityMode(criteria, criteriaQuery) );
+			Type[] subtypes = type.getSubtypes();
+			for (int i=0; i<propertyNames.length; i++) {
+				String subpath = StringHelper.qualify( path, propertyNames[i] );
+				Object value = values[i];
+				if ( isPropertyIncluded( value, subpath, subtypes[i] ) ) {
+					Type subtype = subtypes[i];
+					if ( subtype.isComponentType() ) {
+						appendComponentCondition(
+							subpath,
+							value,
+							(AbstractComponentType) subtype,
+							criteria,
+							criteriaQuery,
+							buf
+						);
+					}
+					else {
+						appendPropertyCondition(
+							subpath,
+							value,
+							criteria,
+							criteriaQuery,
+							buf
+						);
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-//$Id: ExistsSubqueryExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-
-/**
- * @author Gavin King
- */
-public class ExistsSubqueryExpression extends SubqueryExpression {
-
-	protected String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery) {
-		return "";
-	}
-	
-	protected ExistsSubqueryExpression(String quantifier, DetachedCriteria dc) {
-		super(null, quantifier, dc);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ExistsSubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+
+/**
+ * @author Gavin King
+ */
+public class ExistsSubqueryExpression extends SubqueryExpression {
+
+	protected String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery) {
+		return "";
+	}
+	
+	protected ExistsSubqueryExpression(String quantifier, DetachedCriteria dc) {
+		super(null, quantifier, dc);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Expression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: Expression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @deprecated Use <tt>Restrictions</tt>.
- * @see Restrictions
- * @author Gavin King
- */
-public final class Expression extends Restrictions {
-
-	private Expression() {
-		//cannot be instantiated
-	}
-
-	/**
-	 * Apply a constraint expressed in SQL, with the given JDBC
-	 * parameters. Any occurrences of <tt>{alias}</tt> will be
-	 * replaced by the table alias.
-	 *
-	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object[], Type[])}
-	 * @param sql
-	 * @param values
-	 * @param types
-	 * @return Criterion
-	 */
-	public static Criterion sql(String sql, Object[] values, Type[] types) {
-		return new SQLCriterion(sql, values, types);
-	}
-	/**
-	 * Apply a constraint expressed in SQL, with the given JDBC
-	 * parameter. Any occurrences of <tt>{alias}</tt> will be replaced
-	 * by the table alias.
-	 *
-	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object, Type)}
-	 * @param sql
-	 * @param value
-	 * @param type
-	 * @return Criterion
-	 */
-	public static Criterion sql(String sql, Object value, Type type) {
-		return new SQLCriterion(sql, new Object[] { value }, new Type[] { type } );
-	}
-	/**
-	 * Apply a constraint expressed in SQL. Any occurrences of <tt>{alias}</tt>
-	 * will be replaced by the table alias.
-	 *
-	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String)}
-	 * @param sql
-	 * @return Criterion
-	 */
-	public static Criterion sql(String sql) {
-		return new SQLCriterion(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Expression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Expression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @deprecated Use <tt>Restrictions</tt>.
+ * @see Restrictions
+ * @author Gavin King
+ */
+public final class Expression extends Restrictions {
+
+	private Expression() {
+		//cannot be instantiated
+	}
+
+	/**
+	 * Apply a constraint expressed in SQL, with the given JDBC
+	 * parameters. Any occurrences of <tt>{alias}</tt> will be
+	 * replaced by the table alias.
+	 *
+	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object[], Type[])}
+	 * @param sql
+	 * @param values
+	 * @param types
+	 * @return Criterion
+	 */
+	public static Criterion sql(String sql, Object[] values, Type[] types) {
+		return new SQLCriterion(sql, values, types);
+	}
+	/**
+	 * Apply a constraint expressed in SQL, with the given JDBC
+	 * parameter. Any occurrences of <tt>{alias}</tt> will be replaced
+	 * by the table alias.
+	 *
+	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String, Object, Type)}
+	 * @param sql
+	 * @param value
+	 * @param type
+	 * @return Criterion
+	 */
+	public static Criterion sql(String sql, Object value, Type type) {
+		return new SQLCriterion(sql, new Object[] { value }, new Type[] { type } );
+	}
+	/**
+	 * Apply a constraint expressed in SQL. Any occurrences of <tt>{alias}</tt>
+	 * will be replaced by the table alias.
+	 *
+	 * @deprecated use {@link org.hibernate.criterion.Restrictions#sqlRestriction(String)}
+	 * @param sql
+	 * @return Criterion
+	 */
+	public static Criterion sql(String sql) {
+		return new SQLCriterion(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: IdentifierEqExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * An identifier constraint
- * @author Gavin King
- */
-public class IdentifierEqExpression implements Criterion {
-
-	private final Object value;
-
-	protected IdentifierEqExpression(Object value) {
-		this.value = value;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		String[] columns = criteriaQuery.getIdentifierColumns(criteria);
-
-		String result = StringHelper.join(
-			" and ",
-			StringHelper.suffix( columns, " = ?" )
-		);
-		if (columns.length>1) result = '(' + result + ')';
-		return result;
-
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return new TypedValue[] { criteriaQuery.getTypedIdentifierValue(criteria, value) };
-	}
-
-	public String toString() {
-		return "id = " + value;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierEqExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * An identifier constraint
+ * @author Gavin King
+ */
+public class IdentifierEqExpression implements Criterion {
+
+	private final Object value;
+
+	protected IdentifierEqExpression(Object value) {
+		this.value = value;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		String[] columns = criteriaQuery.getIdentifierColumns(criteria);
+
+		String result = StringHelper.join(
+			" and ",
+			StringHelper.suffix( columns, " = ?" )
+		);
+		if (columns.length>1) result = '(' + result + ')';
+		return result;
+
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return new TypedValue[] { criteriaQuery.getTypedIdentifierValue(criteria, value) };
+	}
+
+	public String toString() {
+		return "id = " + value;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-//$Id: IdentifierProjection.java 6970 2005-05-31 20:24:41Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * A property value, or grouped property value
- * @author Gavin King
- */
-public class IdentifierProjection extends SimpleProjection {
-
-	private boolean grouped;
-	
-	protected IdentifierProjection(boolean grouped) {
-		this.grouped = grouped;
-	}
-	
-	protected IdentifierProjection() {
-		this(false);
-	}
-	
-	public String toString() {
-		return "id";
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new Type[] { criteriaQuery.getIdentifierType(criteria) };
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		StringBuffer buf = new StringBuffer();
-		String[] cols = criteriaQuery.getIdentifierColumns(criteria);
-		for ( int i=0; i<cols.length; i++ ) {
-			buf.append( cols[i] )
-				.append(" as y")
-				.append(position + i)
-				.append('_');
-		}
-		return buf.toString();
-	}
-
-	public boolean isGrouped() {
-		return grouped;
-	}
-	
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		if (!grouped) {
-			return super.toGroupSqlString(criteria, criteriaQuery);
-		}
-		else {
-			return StringHelper.join( ", ", criteriaQuery.getIdentifierColumns(criteria) );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IdentifierProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A property value, or grouped property value
+ * @author Gavin King
+ */
+public class IdentifierProjection extends SimpleProjection {
+
+	private boolean grouped;
+	
+	protected IdentifierProjection(boolean grouped) {
+		this.grouped = grouped;
+	}
+	
+	protected IdentifierProjection() {
+		this(false);
+	}
+	
+	public String toString() {
+		return "id";
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new Type[] { criteriaQuery.getIdentifierType(criteria) };
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		StringBuffer buf = new StringBuffer();
+		String[] cols = criteriaQuery.getIdentifierColumns(criteria);
+		for ( int i=0; i<cols.length; i++ ) {
+			buf.append( cols[i] )
+				.append(" as y")
+				.append(position + i)
+				.append('_');
+		}
+		return buf.toString();
+	}
+
+	public boolean isGrouped() {
+		return grouped;
+	}
+	
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		if (!grouped) {
+			return super.toGroupSqlString(criteria, criteriaQuery);
+		}
+		else {
+			return StringHelper.join( ", ", criteriaQuery.getIdentifierColumns(criteria) );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/IlikeExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-//$Id: IlikeExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.PostgreSQLDialect;
-import org.hibernate.engine.TypedValue;
-
-/**
- * A case-insensitive "like"
- * @author Gavin King
- */
-public class IlikeExpression implements Criterion {
-
-	private final String propertyName;
-	private final Object value;
-
-	protected IlikeExpression(String propertyName, Object value) {
-		this.propertyName = propertyName;
-		this.value = value;
-	}
-
-	protected IlikeExpression(String propertyName, String value, MatchMode matchMode) {
-		this( propertyName, matchMode.toMatchString(value) );
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		Dialect dialect = criteriaQuery.getFactory().getDialect();
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		if (columns.length!=1) throw new HibernateException("ilike may only be used with single-column properties");
-		if ( dialect instanceof PostgreSQLDialect ) {
-			return columns[0] + " ilike ?";
-		}
-		else {
-			return dialect.getLowercaseFunction() + '(' + columns[0] + ") like ?";
-		}
-
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, value.toString().toLowerCase() ) };
-	}
-
-	public String toString() {
-		return propertyName + " ilike " + value;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/IlikeExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/IlikeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.PostgreSQLDialect;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * A case-insensitive "like"
+ * @author Gavin King
+ */
+public class IlikeExpression implements Criterion {
+
+	private final String propertyName;
+	private final Object value;
+
+	protected IlikeExpression(String propertyName, Object value) {
+		this.propertyName = propertyName;
+		this.value = value;
+	}
+
+	protected IlikeExpression(String propertyName, String value, MatchMode matchMode) {
+		this( propertyName, matchMode.toMatchString(value) );
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		Dialect dialect = criteriaQuery.getFactory().getDialect();
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		if (columns.length!=1) throw new HibernateException("ilike may only be used with single-column properties");
+		if ( dialect instanceof PostgreSQLDialect ) {
+			return columns[0] + " ilike ?";
+		}
+		else {
+			return dialect.getLowercaseFunction() + '(' + columns[0] + ") like ?";
+		}
+
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return new TypedValue[] { criteriaQuery.getTypedValue( criteria, propertyName, value.toString().toLowerCase() ) };
+	}
+
+	public String toString() {
+		return propertyName + " ilike " + value;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/InExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-//$Id: InExpression.java 7557 2005-07-19 23:25:36Z oneovthafew $
-package org.hibernate.criterion;
-
-import java.util.ArrayList;
-
-
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-
-
-import org.hibernate.engine.TypedValue;
-
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * Constrains the property to a specified list of values
- * @author Gavin King
- */
-public class InExpression implements Criterion {
-
-	private final String propertyName;
-	private final Object[] values;
-
-	protected InExpression(String propertyName, Object[] values) {
-		this.propertyName = propertyName;
-		this.values = values;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		String singleValueParam = StringHelper.repeat( "?, ", columns.length-1 )  + "?";
-		if ( columns.length>1 ) singleValueParam = '(' + singleValueParam + ')';
-		String params = values.length>0 ?
-			StringHelper.repeat( singleValueParam + ", ", values.length-1 ) + singleValueParam :
-			"";
-		String cols = StringHelper.join(", ", columns);
-		if ( columns.length>1 ) cols = '(' + cols + ')';
-		return cols + " in (" + params + ')';
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		ArrayList list = new ArrayList();
-		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
-		if ( type.isComponentType() ) {
-			AbstractComponentType actype = (AbstractComponentType) type;
-			Type[] types = actype.getSubtypes();
-			for ( int i=0; i<types.length; i++ ) {
-				for ( int j=0; j<values.length; j++ ) {
-					Object subval = values[j]==null ? 
-						null : 
-						actype.getPropertyValues( values[j], EntityMode.POJO )[i];
-					list.add( new TypedValue( types[i], subval, EntityMode.POJO ) );
-				}
-			}
-		}
-		else {
-			for ( int j=0; j<values.length; j++ ) {
-				list.add( new TypedValue( type, values[j], EntityMode.POJO ) );
-			}
-		}
-		return (TypedValue[]) list.toArray( new TypedValue[ list.size() ] );
-	}
-
-	public String toString() {
-		return propertyName + " in (" + StringHelper.toString(values) + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/InExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/InExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.criterion;
+
+import java.util.ArrayList;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+
+import org.hibernate.engine.TypedValue;
+
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Constrains the property to a specified list of values
+ * @author Gavin King
+ */
+public class InExpression implements Criterion {
+
+	private final String propertyName;
+	private final Object[] values;
+
+	protected InExpression(String propertyName, Object[] values) {
+		this.propertyName = propertyName;
+		this.values = values;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		String singleValueParam = StringHelper.repeat( "?, ", columns.length-1 )  + "?";
+		if ( columns.length>1 ) singleValueParam = '(' + singleValueParam + ')';
+		String params = values.length>0 ?
+			StringHelper.repeat( singleValueParam + ", ", values.length-1 ) + singleValueParam :
+			"";
+		String cols = StringHelper.join(", ", columns);
+		if ( columns.length>1 ) cols = '(' + cols + ')';
+		return cols + " in (" + params + ')';
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		ArrayList list = new ArrayList();
+		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
+		if ( type.isComponentType() ) {
+			AbstractComponentType actype = (AbstractComponentType) type;
+			Type[] types = actype.getSubtypes();
+			for ( int i=0; i<types.length; i++ ) {
+				for ( int j=0; j<values.length; j++ ) {
+					Object subval = values[j]==null ? 
+						null : 
+						actype.getPropertyValues( values[j], EntityMode.POJO )[i];
+					list.add( new TypedValue( types[i], subval, EntityMode.POJO ) );
+				}
+			}
+		}
+		else {
+			for ( int j=0; j<values.length; j++ ) {
+				list.add( new TypedValue( type, values[j], EntityMode.POJO ) );
+			}
+		}
+		return (TypedValue[]) list.toArray( new TypedValue[ list.size() ] );
+	}
+
+	public String toString() {
+		return propertyName + " in (" + StringHelper.toString(values) + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Junction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-package org.hibernate.criterion;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * A sequence of a logical expressions combined by some
- * associative logical operator
- *
- * @author Gavin King
- */
-public class Junction implements Criterion {
-
-	private final List criteria = new ArrayList();
-	private final String op;
-	
-	protected Junction(String op) {
-		this.op = op;
-	}
-	
-	public Junction add(Criterion criterion) {
-		criteria.add(criterion);
-		return this;
-	}
-
-	public String getOp() {
-		return op;
-	}
-
-	public TypedValue[] getTypedValues(Criteria crit, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		ArrayList typedValues = new ArrayList();
-		Iterator iter = criteria.iterator();
-		while ( iter.hasNext() ) {
-			TypedValue[] subvalues = ( (Criterion) iter.next() ).getTypedValues(crit, criteriaQuery);
-			for ( int i=0; i<subvalues.length; i++ ) {
-				typedValues.add( subvalues[i] );
-			}
-		}
-		return (TypedValue[]) typedValues.toArray( new TypedValue[ typedValues.size() ] );
-	}
-
-	public String toSqlString(Criteria crit, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		if ( criteria.size()==0 ) return "1=1";
-
-		StringBuffer buffer = new StringBuffer()
-			.append('(');
-		Iterator iter = criteria.iterator();
-		while ( iter.hasNext() ) {
-			buffer.append( ( (Criterion) iter.next() ).toSqlString(crit, criteriaQuery) );
-			if ( iter.hasNext() ) buffer.append(' ').append(op).append(' ');
-		}
-		return buffer.append(')').toString();
-	}
-
-	/**
-	 * @see java.lang.Object#toString()
-	 */
-	public String toString() {
-		return '(' + StringHelper.join( ' ' + op + ' ', criteria.iterator() ) + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Junction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Junction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+/*
+ * 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.criterion;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A sequence of a logical expressions combined by some
+ * associative logical operator
+ *
+ * @author Gavin King
+ */
+public class Junction implements Criterion {
+
+	private final List criteria = new ArrayList();
+	private final String op;
+	
+	protected Junction(String op) {
+		this.op = op;
+	}
+	
+	public Junction add(Criterion criterion) {
+		criteria.add(criterion);
+		return this;
+	}
+
+	public String getOp() {
+		return op;
+	}
+
+	public TypedValue[] getTypedValues(Criteria crit, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		ArrayList typedValues = new ArrayList();
+		Iterator iter = criteria.iterator();
+		while ( iter.hasNext() ) {
+			TypedValue[] subvalues = ( (Criterion) iter.next() ).getTypedValues(crit, criteriaQuery);
+			for ( int i=0; i<subvalues.length; i++ ) {
+				typedValues.add( subvalues[i] );
+			}
+		}
+		return (TypedValue[]) typedValues.toArray( new TypedValue[ typedValues.size() ] );
+	}
+
+	public String toSqlString(Criteria crit, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		if ( criteria.size()==0 ) return "1=1";
+
+		StringBuffer buffer = new StringBuffer()
+			.append('(');
+		Iterator iter = criteria.iterator();
+		while ( iter.hasNext() ) {
+			buffer.append( ( (Criterion) iter.next() ).toSqlString(crit, criteriaQuery) );
+			if ( iter.hasNext() ) buffer.append(' ').append(op).append(' ');
+		}
+		return buffer.append(')').toString();
+	}
+
+	/**
+	 * @see java.lang.Object#toString()
+	 */
+	public String toString() {
+		return '(' + StringHelper.join( ' ' + op + ' ', criteria.iterator() ) + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/LikeExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,75 +0,0 @@
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.TypedValue;
-
-/**
- * A criterion representing a "like" expression
- *
- * @author Scott Marlow
- * @author Steve Ebersole
- */
-public class LikeExpression implements Criterion {
-	private final String propertyName;
-	private final Object value;
-	private final Character escapeChar;
-	private final boolean ignoreCase;
-
-	protected LikeExpression(
-			String propertyName,
-			String value,
-			Character escapeChar,
-			boolean ignoreCase) {
-		this.propertyName = propertyName;
-		this.value = value;
-		this.escapeChar = escapeChar;
-		this.ignoreCase = ignoreCase;
-	}
-
-	protected LikeExpression(
-			String propertyName,
-			String value) {
-		this( propertyName, value, null, false );
-	}
-
-	protected LikeExpression(
-			String propertyName,
-			String value,
-			MatchMode matchMode) {
-		this( propertyName, matchMode.toMatchString( value ) );
-	}
-
-	protected LikeExpression(
-			String propertyName,
-			String value,
-			MatchMode matchMode,
-			Character escapeChar,
-			boolean ignoreCase) {
-		this( propertyName, matchMode.toMatchString( value ), escapeChar, ignoreCase );
-	}
-
-	public String toSqlString(
-			Criteria criteria,
-			CriteriaQuery criteriaQuery) throws HibernateException {
-		Dialect dialect = criteriaQuery.getFactory().getDialect();
-		String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
-		if ( columns.length != 1 ) {
-			throw new HibernateException( "Like may only be used with single-column properties" );
-		}
-		String lhs = ignoreCase
-				? dialect.getLowercaseFunction() + '(' + columns[0] + ')'
-	            : columns[0];
-		return lhs + " like ?" + ( escapeChar == null ? "" : " escape \'" + escapeChar + "\'" );
-
-	}
-
-	public TypedValue[] getTypedValues(
-			Criteria criteria,
-			CriteriaQuery criteriaQuery) throws HibernateException {
-		return new TypedValue[] {
-				criteriaQuery.getTypedValue( criteria, propertyName, value.toString().toLowerCase() )
-		};
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/LikeExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LikeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,99 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * A criterion representing a "like" expression
+ *
+ * @author Scott Marlow
+ * @author Steve Ebersole
+ */
+public class LikeExpression implements Criterion {
+	private final String propertyName;
+	private final Object value;
+	private final Character escapeChar;
+	private final boolean ignoreCase;
+
+	protected LikeExpression(
+			String propertyName,
+			String value,
+			Character escapeChar,
+			boolean ignoreCase) {
+		this.propertyName = propertyName;
+		this.value = value;
+		this.escapeChar = escapeChar;
+		this.ignoreCase = ignoreCase;
+	}
+
+	protected LikeExpression(
+			String propertyName,
+			String value) {
+		this( propertyName, value, null, false );
+	}
+
+	protected LikeExpression(
+			String propertyName,
+			String value,
+			MatchMode matchMode) {
+		this( propertyName, matchMode.toMatchString( value ) );
+	}
+
+	protected LikeExpression(
+			String propertyName,
+			String value,
+			MatchMode matchMode,
+			Character escapeChar,
+			boolean ignoreCase) {
+		this( propertyName, matchMode.toMatchString( value ), escapeChar, ignoreCase );
+	}
+
+	public String toSqlString(
+			Criteria criteria,
+			CriteriaQuery criteriaQuery) throws HibernateException {
+		Dialect dialect = criteriaQuery.getFactory().getDialect();
+		String[] columns = criteriaQuery.getColumnsUsingProjection( criteria, propertyName );
+		if ( columns.length != 1 ) {
+			throw new HibernateException( "Like may only be used with single-column properties" );
+		}
+		String lhs = ignoreCase
+				? dialect.getLowercaseFunction() + '(' + columns[0] + ')'
+	            : columns[0];
+		return lhs + " like ?" + ( escapeChar == null ? "" : " escape \'" + escapeChar + "\'" );
+
+	}
+
+	public TypedValue[] getTypedValues(
+			Criteria criteria,
+			CriteriaQuery criteriaQuery) throws HibernateException {
+		return new TypedValue[] {
+				criteriaQuery.getTypedValue( criteria, propertyName, value.toString().toLowerCase() )
+		};
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/LogicalExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: LogicalExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-
-/**
- * Superclass of binary logical expressions
- * @author Gavin King
- */
-public class LogicalExpression implements Criterion {
-
-	private final Criterion lhs;
-	private final Criterion rhs;
-	private final String op;
-
-	protected LogicalExpression(Criterion lhs, Criterion rhs, String op) {
-		this.lhs = lhs;
-		this.rhs = rhs;
-		this.op = op;
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		TypedValue[] lhstv = lhs.getTypedValues(criteria, criteriaQuery);
-		TypedValue[] rhstv = rhs.getTypedValues(criteria, criteriaQuery);
-		TypedValue[] result = new TypedValue[ lhstv.length + rhstv.length ];
-		System.arraycopy(lhstv, 0, result, 0, lhstv.length);
-		System.arraycopy(rhstv, 0, result, lhstv.length, rhstv.length);
-		return result;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		return '(' +
-			lhs.toSqlString(criteria, criteriaQuery) +
-			' ' +
-			getOp() +
-			' ' +
-			rhs.toSqlString(criteria, criteriaQuery) +
-			')';
-	}
-
-	public String getOp() {
-		return op;
-	}
-
-	public String toString() {
-		return lhs.toString() + ' ' + getOp() + ' ' + rhs.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/LogicalExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/LogicalExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * Superclass of binary logical expressions
+ * @author Gavin King
+ */
+public class LogicalExpression implements Criterion {
+
+	private final Criterion lhs;
+	private final Criterion rhs;
+	private final String op;
+
+	protected LogicalExpression(Criterion lhs, Criterion rhs, String op) {
+		this.lhs = lhs;
+		this.rhs = rhs;
+		this.op = op;
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		TypedValue[] lhstv = lhs.getTypedValues(criteria, criteriaQuery);
+		TypedValue[] rhstv = rhs.getTypedValues(criteria, criteriaQuery);
+		TypedValue[] result = new TypedValue[ lhstv.length + rhstv.length ];
+		System.arraycopy(lhstv, 0, result, 0, lhstv.length);
+		System.arraycopy(rhstv, 0, result, lhstv.length, rhstv.length);
+		return result;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		return '(' +
+			lhs.toSqlString(criteria, criteriaQuery) +
+			' ' +
+			getOp() +
+			' ' +
+			rhs.toSqlString(criteria, criteriaQuery) +
+			')';
+	}
+
+	public String getOp() {
+		return op;
+	}
+
+	public String toString() {
+		return lhs.toString() + ' ' + getOp() + ' ' + rhs.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/MatchMode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: MatchMode.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Represents an strategy for matching strings using "like".
- *
- * @see Example#enableLike(MatchMode)
- * @author Gavin King
- */
-public abstract class MatchMode implements Serializable {
-	private final String name;
-	private static final Map INSTANCES = new HashMap();
-
-	protected MatchMode(String name) {
-		this.name=name;
-	}
-	public String toString() {
-		return name;
-	}
-
-	/**
-	 * Match the entire string to the pattern
-	 */
-	public static final MatchMode EXACT = new MatchMode("EXACT") {
-		public String toMatchString(String pattern) {
-			return pattern;
-		}
-	};
-
-	/**
-	 * Match the start of the string to the pattern
-	 */
-	public static final MatchMode START = new MatchMode("START") {
-		public String toMatchString(String pattern) {
-			return pattern + '%';
-		}
-	};
-
-	/**
-	 * Match the end of the string to the pattern
-	 */
-	public static final MatchMode END = new MatchMode("END") {
-		public String toMatchString(String pattern) {
-			return '%' + pattern;
-		}
-	};
-
-	/**
-	 * Match the pattern anywhere in the string
-	 */
-	public static final MatchMode ANYWHERE = new MatchMode("ANYWHERE") {
-		public String toMatchString(String pattern) {
-			return '%' + pattern + '%';
-		}
-	};
-
-	static {
-		INSTANCES.put( EXACT.name, EXACT );
-		INSTANCES.put( END.name, END );
-		INSTANCES.put( START.name, START );
-		INSTANCES.put( ANYWHERE.name, ANYWHERE );
-	}
-
-	private Object readResolve() {
-		return INSTANCES.get(name);
-	}
-
-	/**
-	 * convert the pattern, by appending/prepending "%"
-	 */
-	public abstract String toMatchString(String pattern);
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/MatchMode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/MatchMode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.criterion;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Represents an strategy for matching strings using "like".
+ *
+ * @see Example#enableLike(MatchMode)
+ * @author Gavin King
+ */
+public abstract class MatchMode implements Serializable {
+	private final String name;
+	private static final Map INSTANCES = new HashMap();
+
+	protected MatchMode(String name) {
+		this.name=name;
+	}
+	public String toString() {
+		return name;
+	}
+
+	/**
+	 * Match the entire string to the pattern
+	 */
+	public static final MatchMode EXACT = new MatchMode("EXACT") {
+		public String toMatchString(String pattern) {
+			return pattern;
+		}
+	};
+
+	/**
+	 * Match the start of the string to the pattern
+	 */
+	public static final MatchMode START = new MatchMode("START") {
+		public String toMatchString(String pattern) {
+			return pattern + '%';
+		}
+	};
+
+	/**
+	 * Match the end of the string to the pattern
+	 */
+	public static final MatchMode END = new MatchMode("END") {
+		public String toMatchString(String pattern) {
+			return '%' + pattern;
+		}
+	};
+
+	/**
+	 * Match the pattern anywhere in the string
+	 */
+	public static final MatchMode ANYWHERE = new MatchMode("ANYWHERE") {
+		public String toMatchString(String pattern) {
+			return '%' + pattern + '%';
+		}
+	};
+
+	static {
+		INSTANCES.put( EXACT.name, EXACT );
+		INSTANCES.put( END.name, END );
+		INSTANCES.put( START.name, START );
+		INSTANCES.put( ANYWHERE.name, ANYWHERE );
+	}
+
+	private Object readResolve() {
+		return INSTANCES.get(name);
+	}
+
+	/**
+	 * convert the pattern, by appending/prepending "%"
+	 */
+	public abstract String toMatchString(String pattern);
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: NaturalIdentifier.java 6899 2005-05-25 01:22:07Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-
-/**
- * @author Gavin King
- */
-public class NaturalIdentifier implements Criterion {
-		
-	private Junction conjunction = new Conjunction();
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
-		return conjunction.getTypedValues(criteria, criteriaQuery);
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
-		return conjunction.toSqlString(criteria, criteriaQuery);
-	}
-	
-	public NaturalIdentifier set(String property, Object value) {
-		conjunction.add( Restrictions.eq(property, value) );
-		return this;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NaturalIdentifier.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * @author Gavin King
+ */
+public class NaturalIdentifier implements Criterion {
+		
+	private Junction conjunction = new Conjunction();
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
+		return conjunction.getTypedValues(criteria, criteriaQuery);
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) throws HibernateException {
+		return conjunction.toSqlString(criteria, criteriaQuery);
+	}
+	
+	public NaturalIdentifier set(String property, Object value) {
+		conjunction.add( Restrictions.eq(property, value) );
+		return this;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-//$Id: NotEmptyExpression.java 6661 2005-05-03 20:12:20Z steveebersole $
-package org.hibernate.criterion;
-
-/**
- * @author Gavin King
- */
-public class NotEmptyExpression extends AbstractEmptinessExpression implements Criterion {
-
-	protected NotEmptyExpression(String propertyName) {
-		super( propertyName );
-	}
-
-	protected boolean excludeEmpty() {
-		return true;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotEmptyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.criterion;
+
+/**
+ * @author Gavin King
+ */
+public class NotEmptyExpression extends AbstractEmptinessExpression implements Criterion {
+
+	protected NotEmptyExpression(String propertyName) {
+		super( propertyName );
+	}
+
+	protected boolean excludeEmpty() {
+		return true;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/NotExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: NotExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.MySQLDialect;
-import org.hibernate.engine.TypedValue;
-
-/**
- * Negates another criterion
- * @author Gavin King
- */
-public class NotExpression implements Criterion {
-
-	private Criterion criterion;
-
-	protected NotExpression(Criterion criterion) {
-		this.criterion = criterion;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		if ( criteriaQuery.getFactory().getDialect() instanceof MySQLDialect ) {
-			return "not (" + criterion.toSqlString(criteria, criteriaQuery) + ')';
-		}
-		else {
-			return "not " + criterion.toSqlString(criteria, criteriaQuery);
-		}
-	}
-
-	public TypedValue[] getTypedValues(
-		Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return criterion.getTypedValues(criteria, criteriaQuery);
-	}
-
-	public String toString() {
-		return "not " + criterion.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/NotExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.MySQLDialect;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * Negates another criterion
+ * @author Gavin King
+ */
+public class NotExpression implements Criterion {
+
+	private Criterion criterion;
+
+	protected NotExpression(Criterion criterion) {
+		this.criterion = criterion;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		if ( criteriaQuery.getFactory().getDialect() instanceof MySQLDialect ) {
+			return "not (" + criterion.toSqlString(criteria, criteriaQuery) + ')';
+		}
+		else {
+			return "not " + criterion.toSqlString(criteria, criteriaQuery);
+		}
+	}
+
+	public TypedValue[] getTypedValues(
+		Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return criterion.getTypedValues(criteria, criteriaQuery);
+	}
+
+	public String toString() {
+		return "not " + criterion.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/NotNullExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: NotNullExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * Constrains a property to be non-null
- * @author Gavin King
- */
-public class NotNullExpression implements Criterion {
-
-	private final String propertyName;
-
-	private static final TypedValue[] NO_VALUES = new TypedValue[0];
-
-	protected NotNullExpression(String propertyName) {
-		this.propertyName = propertyName;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		String result = StringHelper.join(
-			" or ",
-			StringHelper.suffix( columns, " is not null" )
-		);
-		if (columns.length>1) result = '(' + result + ')';
-		return result;
-
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return NO_VALUES;
-	}
-
-	public String toString() {
-		return propertyName + " is not null";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/NotNullExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NotNullExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Constrains a property to be non-null
+ * @author Gavin King
+ */
+public class NotNullExpression implements Criterion {
+
+	private final String propertyName;
+
+	private static final TypedValue[] NO_VALUES = new TypedValue[0];
+
+	protected NotNullExpression(String propertyName) {
+		this.propertyName = propertyName;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		String result = StringHelper.join(
+			" or ",
+			StringHelper.suffix( columns, " is not null" )
+		);
+		if (columns.length>1) result = '(' + result + ')';
+		return result;
+
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return NO_VALUES;
+	}
+
+	public String toString() {
+		return propertyName + " is not null";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/NullExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: NullExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * Constrains a property to be null
- * @author Gavin King
- */
-public class NullExpression implements Criterion {
-
-	private final String propertyName;
-
-	private static final TypedValue[] NO_VALUES = new TypedValue[0];
-
-	protected NullExpression(String propertyName) {
-		this.propertyName = propertyName;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		String result = StringHelper.join(
-			" and ",
-			StringHelper.suffix( columns, " is null" )
-		);
-		if (columns.length>1) result = '(' + result + ')';
-		return result;
-
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return NO_VALUES;
-	}
-
-	public String toString() {
-		return propertyName + " is null";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/NullExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/NullExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Constrains a property to be null
+ * @author Gavin King
+ */
+public class NullExpression implements Criterion {
+
+	private final String propertyName;
+
+	private static final TypedValue[] NO_VALUES = new TypedValue[0];
+
+	protected NullExpression(String propertyName) {
+		this.propertyName = propertyName;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		String result = StringHelper.join(
+			" and ",
+			StringHelper.suffix( columns, " is null" )
+		);
+		if (columns.length>1) result = '(' + result + ')';
+		return result;
+
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return NO_VALUES;
+	}
+
+	public String toString() {
+		return propertyName + " is null";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Order.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,83 +0,0 @@
-//$Id: Order.java 7495 2005-07-15 16:52:10Z oneovthafew $
-package org.hibernate.criterion;
-
-import java.io.Serializable;
-import java.sql.Types;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Represents an order imposed upon a <tt>Criteria</tt> result set
- * @author Gavin King
- */
-public class Order implements Serializable {
-
-	private boolean ascending;
-	private boolean ignoreCase;
-	private String propertyName;
-	
-	public String toString() {
-		return propertyName + ' ' + (ascending?"asc":"desc");
-	}
-	
-	public Order ignoreCase() {
-		ignoreCase = true;
-		return this;
-	}
-
-	/**
-	 * Constructor for Order.
-	 */
-	protected Order(String propertyName, boolean ascending) {
-		this.propertyName = propertyName;
-		this.ascending = ascending;
-	}
-
-	/**
-	 * Render the SQL fragment
-	 *
-	 */
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
-		StringBuffer fragment = new StringBuffer();
-		for ( int i=0; i<columns.length; i++ ) {
-			SessionFactoryImplementor factory = criteriaQuery.getFactory();
-			boolean lower = ignoreCase && type.sqlTypes( factory )[i]==Types.VARCHAR;
-			if (lower) {
-				fragment.append( factory.getDialect().getLowercaseFunction() )
-					.append('(');
-			}
-			fragment.append( columns[i] );
-			if (lower) fragment.append(')');
-			fragment.append( ascending ? " asc" : " desc" );
-			if ( i<columns.length-1 ) fragment.append(", ");
-		}
-		return fragment.toString();
-	}
-
-	/**
-	 * Ascending order
-	 *
-	 * @param propertyName
-	 * @return Order
-	 */
-	public static Order asc(String propertyName) {
-		return new Order(propertyName, true);
-	}
-
-	/**
-	 * Descending order
-	 *
-	 * @param propertyName
-	 * @return Order
-	 */
-	public static Order desc(String propertyName) {
-		return new Order(propertyName, false);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Order.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Order.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,106 @@
+/*
+ * 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.criterion;
+
+import java.io.Serializable;
+import java.sql.Types;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Represents an order imposed upon a <tt>Criteria</tt> result set
+ * @author Gavin King
+ */
+public class Order implements Serializable {
+
+	private boolean ascending;
+	private boolean ignoreCase;
+	private String propertyName;
+	
+	public String toString() {
+		return propertyName + ' ' + (ascending?"asc":"desc");
+	}
+	
+	public Order ignoreCase() {
+		ignoreCase = true;
+		return this;
+	}
+
+	/**
+	 * Constructor for Order.
+	 */
+	protected Order(String propertyName, boolean ascending) {
+		this.propertyName = propertyName;
+		this.ascending = ascending;
+	}
+
+	/**
+	 * Render the SQL fragment
+	 *
+	 */
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
+		StringBuffer fragment = new StringBuffer();
+		for ( int i=0; i<columns.length; i++ ) {
+			SessionFactoryImplementor factory = criteriaQuery.getFactory();
+			boolean lower = ignoreCase && type.sqlTypes( factory )[i]==Types.VARCHAR;
+			if (lower) {
+				fragment.append( factory.getDialect().getLowercaseFunction() )
+					.append('(');
+			}
+			fragment.append( columns[i] );
+			if (lower) fragment.append(')');
+			fragment.append( ascending ? " asc" : " desc" );
+			if ( i<columns.length-1 ) fragment.append(", ");
+		}
+		return fragment.toString();
+	}
+
+	/**
+	 * Ascending order
+	 *
+	 * @param propertyName
+	 * @return Order
+	 */
+	public static Order asc(String propertyName) {
+		return new Order(propertyName, true);
+	}
+
+	/**
+	 * Descending order
+	 *
+	 * @param propertyName
+	 * @return Order
+	 */
+	public static Order desc(String propertyName) {
+		return new Order(propertyName, false);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Projection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-//$Id: Projection.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import java.io.Serializable;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * An object-oriented representation of a query result set projection 
- * in a <tt>Criteria</tt> query. Built-in projection types are provided 
- * by the <tt>Projections</tt> factory class.
- * This interface might be implemented by application classes that
- * define custom projections.
- *
- * @see Projections
- * @see org.hibernate.Criteria
- * @author Gavin King
- */
-public interface Projection extends Serializable {
-
-	/**
-	 * Render the SQL fragment
-	 * @param criteriaQuery
-	 * @param columnAlias
-	 * @return String
-	 * @throws HibernateException
-	 */
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-	
-	/**
-	 * Render the SQL fragment to be used in the group by clause
-	 * @param criteriaQuery
-	 * @param columnAlias
-	 * @return String
-	 * @throws HibernateException
-	 */
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-	
-	/**
-	 * Return types returned by the rendered SQL fragment
-	 * @param criteria
-	 * @param criteriaQuery 
-	 * @return Type[]
-	 * @throws HibernateException
-	 */
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-	/**
-	 * Return types for a particular user-visible alias
-	 */
-	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException;
-		
-	/**
-	 * Get the SQL select clause column aliases
-	 */
-	public String[] getColumnAliases(int loc);
-	/**
-	 * Get the SQL select clause column aliases for a particular
-	 * user-visible alias
-	 */
-	public String[] getColumnAliases(String alias, int loc);
-	
-	/**
-	 * Get the user-visible aliases for this projection
-	 * (ie. the ones that will be passed to the 
-	 * <tt>ResultTransformer</tt>)
-	 */
-	public String[] getAliases();
-	
-	/**
-	 * Does this projection specify grouping attributes?
-	 */
-	public boolean isGrouped();
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Projection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+
+import java.io.Serializable;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * An object-oriented representation of a query result set projection 
+ * in a <tt>Criteria</tt> query. Built-in projection types are provided 
+ * by the <tt>Projections</tt> factory class.
+ * This interface might be implemented by application classes that
+ * define custom projections.
+ *
+ * @see Projections
+ * @see org.hibernate.Criteria
+ * @author Gavin King
+ */
+public interface Projection extends Serializable {
+
+	/**
+	 * Render the SQL fragment
+	 * @param criteriaQuery
+	 * @param columnAlias
+	 * @return String
+	 * @throws HibernateException
+	 */
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException;
+	
+	/**
+	 * Render the SQL fragment to be used in the group by clause
+	 * @param criteriaQuery
+	 * @param columnAlias
+	 * @return String
+	 * @throws HibernateException
+	 */
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException;
+	
+	/**
+	 * Return types returned by the rendered SQL fragment
+	 * @param criteria
+	 * @param criteriaQuery 
+	 * @return Type[]
+	 * @throws HibernateException
+	 */
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException;
+	/**
+	 * Return types for a particular user-visible alias
+	 */
+	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException;
+		
+	/**
+	 * Get the SQL select clause column aliases
+	 */
+	public String[] getColumnAliases(int loc);
+	/**
+	 * Get the SQL select clause column aliases for a particular
+	 * user-visible alias
+	 */
+	public String[] getColumnAliases(String alias, int loc);
+	
+	/**
+	 * Get the user-visible aliases for this projection
+	 * (ie. the ones that will be passed to the 
+	 * <tt>ResultTransformer</tt>)
+	 */
+	public String[] getAliases();
+	
+	/**
+	 * Does this projection specify grouping attributes?
+	 */
+	public boolean isGrouped();
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/ProjectionList.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,125 +0,0 @@
-//$Id: ProjectionList.java 6490 2005-04-23 07:09:03Z oneovthafew $
-package org.hibernate.criterion;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @author Gavin King
- */
-public class ProjectionList implements Projection {
-	
-	private List elements = new ArrayList();
-	
-	protected ProjectionList() {}
-	
-	public ProjectionList create() {
-		return new ProjectionList();
-	}
-	
-	public ProjectionList add(Projection proj) {
-		elements.add(proj);
-		return this;
-	}
-
-	public ProjectionList add(Projection projection, String alias) {
-		return add( Projections.alias(projection, alias) );
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		List types = new ArrayList( getLength() );
-		for ( int i=0; i<getLength(); i++ ) {
-			Type[] elemTypes = getProjection(i).getTypes(criteria, criteriaQuery);
-			ArrayHelper.addAll(types, elemTypes);
-		}
-		return ArrayHelper.toTypeArray(types);
-	}
-	
-	public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		StringBuffer buf = new StringBuffer();
-		for ( int i=0; i<getLength(); i++ ) {
-			Projection proj = getProjection(i);
-			buf.append( proj.toSqlString(criteria, loc, criteriaQuery) );
-			loc += proj.getColumnAliases(loc).length;
-			if ( i<elements.size()-1 ) buf.append(", ");
-		}
-		return buf.toString();
-	}
-	
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		StringBuffer buf = new StringBuffer();
-		for ( int i=0; i<getLength(); i++ ) {
-			Projection proj = getProjection(i);
-			if ( proj.isGrouped() ) {
-				buf.append( proj.toGroupSqlString(criteria, criteriaQuery) )
-					.append(", ");
-			}
-		}
-		if ( buf.length()>2 ) buf.setLength( buf.length()-2 ); //pull off the last ", "
-		return buf.toString();
-	}
-	
-	public String[] getColumnAliases(int loc) {
-		List result = new ArrayList( getLength() );
-		for ( int i=0; i<getLength(); i++ ) {
-			String[] colAliases = getProjection(i).getColumnAliases(loc);
-			ArrayHelper.addAll(result, colAliases);
-			loc+=colAliases.length;
-		}
-		return ArrayHelper.toStringArray(result);
-	}
-
-	public String[] getColumnAliases(String alias, int loc) {
-		for ( int i=0; i<getLength(); i++ ) {
-			String[] result = getProjection(i).getColumnAliases(alias, loc);
-			if (result!=null) return result;
-			loc += getProjection(i).getColumnAliases(loc).length;
-		}
-		return null;
-	}
-
-	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) {
-		for ( int i=0; i<getLength(); i++ ) {
-			Type[] result = getProjection(i).getTypes(alias, criteria, criteriaQuery);
-			if (result!=null) return result;
-		}
-		return null;
-	}
-
-	public String[] getAliases() {
-		List result = new ArrayList( getLength() );
-		for ( int i=0; i<getLength(); i++ ) {
-			String[] aliases = getProjection(i).getAliases();
-			ArrayHelper.addAll(result, aliases);
-		}
-		return ArrayHelper.toStringArray(result);
-
-	}
-	
-	public Projection getProjection(int i) {
-		return (Projection) elements.get(i);
-	}
-	
-	public int getLength() {
-		return elements.size();
-	}
-	
-	public String toString() {
-		return elements.toString();
-	}
-
-	public boolean isGrouped() {
-		for ( int i=0; i<getLength(); i++ ) {
-			if ( getProjection(i).isGrouped() ) return true;
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/ProjectionList.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/ProjectionList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @author Gavin King
+ */
+public class ProjectionList implements Projection {
+	
+	private List elements = new ArrayList();
+	
+	protected ProjectionList() {}
+	
+	public ProjectionList create() {
+		return new ProjectionList();
+	}
+	
+	public ProjectionList add(Projection proj) {
+		elements.add(proj);
+		return this;
+	}
+
+	public ProjectionList add(Projection projection, String alias) {
+		return add( Projections.alias(projection, alias) );
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		List types = new ArrayList( getLength() );
+		for ( int i=0; i<getLength(); i++ ) {
+			Type[] elemTypes = getProjection(i).getTypes(criteria, criteriaQuery);
+			ArrayHelper.addAll(types, elemTypes);
+		}
+		return ArrayHelper.toTypeArray(types);
+	}
+	
+	public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		StringBuffer buf = new StringBuffer();
+		for ( int i=0; i<getLength(); i++ ) {
+			Projection proj = getProjection(i);
+			buf.append( proj.toSqlString(criteria, loc, criteriaQuery) );
+			loc += proj.getColumnAliases(loc).length;
+			if ( i<elements.size()-1 ) buf.append(", ");
+		}
+		return buf.toString();
+	}
+	
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		StringBuffer buf = new StringBuffer();
+		for ( int i=0; i<getLength(); i++ ) {
+			Projection proj = getProjection(i);
+			if ( proj.isGrouped() ) {
+				buf.append( proj.toGroupSqlString(criteria, criteriaQuery) )
+					.append(", ");
+			}
+		}
+		if ( buf.length()>2 ) buf.setLength( buf.length()-2 ); //pull off the last ", "
+		return buf.toString();
+	}
+	
+	public String[] getColumnAliases(int loc) {
+		List result = new ArrayList( getLength() );
+		for ( int i=0; i<getLength(); i++ ) {
+			String[] colAliases = getProjection(i).getColumnAliases(loc);
+			ArrayHelper.addAll(result, colAliases);
+			loc+=colAliases.length;
+		}
+		return ArrayHelper.toStringArray(result);
+	}
+
+	public String[] getColumnAliases(String alias, int loc) {
+		for ( int i=0; i<getLength(); i++ ) {
+			String[] result = getProjection(i).getColumnAliases(alias, loc);
+			if (result!=null) return result;
+			loc += getProjection(i).getColumnAliases(loc).length;
+		}
+		return null;
+	}
+
+	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) {
+		for ( int i=0; i<getLength(); i++ ) {
+			Type[] result = getProjection(i).getTypes(alias, criteria, criteriaQuery);
+			if (result!=null) return result;
+		}
+		return null;
+	}
+
+	public String[] getAliases() {
+		List result = new ArrayList( getLength() );
+		for ( int i=0; i<getLength(); i++ ) {
+			String[] aliases = getProjection(i).getAliases();
+			ArrayHelper.addAll(result, aliases);
+		}
+		return ArrayHelper.toStringArray(result);
+
+	}
+	
+	public Projection getProjection(int i) {
+		return (Projection) elements.get(i);
+	}
+	
+	public int getLength() {
+		return elements.size();
+	}
+	
+	public String toString() {
+		return elements.toString();
+	}
+
+	public boolean isGrouped() {
+		for ( int i=0; i<getLength(); i++ ) {
+			if ( getProjection(i).isGrouped() ) return true;
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Projections.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,128 +0,0 @@
-//$Id: Projections.java 6970 2005-05-31 20:24:41Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.type.Type;
-
-/**
- * The <tt>criterion</tt> package may be used by applications as a framework for building
- * new kinds of <tt>Projection</tt>. However, it is intended that most applications will
- * simply use the built-in projection types via the static factory methods of this class.<br/>
- * <br/>
- * The factory methods that take an alias allow the projected value to be referred to by 
- * criterion and order instances.
- *
- * @see org.hibernate.Criteria
- * @see Restrictions factory methods for <tt>Criterion</tt> instances
- * @author Gavin King
- */
-public final class Projections {
-
-	private Projections() {
-		//cannot be instantiated
-	}
-	
-	/**
-	 * Create a distinct projection from a projection
-	 */
-	public static Projection distinct(Projection proj) {
-		return new Distinct(proj);
-	}
-	
-	/**
-	 * Create a new projection list
-	 */
-	public static ProjectionList projectionList() {
-		return new ProjectionList();
-	}
-		
-	/**
-	 * The query row count, ie. <tt>count(*)</tt>
-	 */
-	public static Projection rowCount() {
-		return new RowCountProjection();
-	}
-	
-	/**
-	 * A property value count
-	 */
-	public static CountProjection count(String propertyName) {
-		return new CountProjection(propertyName);
-	}
-	
-	/**
-	 * A distinct property value count
-	 */
-	public static CountProjection countDistinct(String propertyName) {
-		return new CountProjection(propertyName).setDistinct();
-	}
-	
-	/**
-	 * A property maximum value
-	 */
-	public static AggregateProjection max(String propertyName) {
-		return new AggregateProjection("max", propertyName);
-	}
-	
-	/**
-	 * A property minimum value
-	 */
-	public static AggregateProjection min(String propertyName) {
-		return new AggregateProjection("min", propertyName);
-	}
-	
-	/**
-	 * A property average value
-	 */
-	public static AggregateProjection avg(String propertyName) {
-		return new AvgProjection(propertyName);
-	}
-	
-	/**
-	 * A property value sum
-	 */
-	public static AggregateProjection sum(String propertyName) {
-		return new AggregateProjection("sum", propertyName);
-	}
-	
-	/**
-	 * A SQL projection, a typed select clause fragment
-	 */
-	public static Projection sqlProjection(String sql, String[] columnAliases, Type[] types) {
-		return new SQLProjection(sql, columnAliases, types);
-	}
-	
-	/**
-	 * A grouping SQL projection, specifying both select clause and group by clause fragments
-	 */
-	public static Projection sqlGroupProjection(String sql, String groupBy, String[] columnAliases, Type[] types) {
-		return new SQLProjection(sql, groupBy, columnAliases, types);
-	}
-
-	/**
-	 * A grouping property value
-	 */
-	public static PropertyProjection groupProperty(String propertyName) {
-		return new PropertyProjection(propertyName, true);
-	}
-	
-	/**
-	 * A projected property value
-	 */
-	public static PropertyProjection property(String propertyName) {
-		return new PropertyProjection(propertyName);
-	}
-	
-	/**
-	 * A projected identifier value
-	 */
-	public static IdentifierProjection id() {
-		return new IdentifierProjection();
-	}
-	
-	/**
-	 * Assign an alias to a projection, by wrapping it
-	 */
-	public static Projection alias(Projection projection, String alias) {
-		return new AliasedProjection(projection, alias);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Projections.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Projections.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.type.Type;
+
+/**
+ * The <tt>criterion</tt> package may be used by applications as a framework for building
+ * new kinds of <tt>Projection</tt>. However, it is intended that most applications will
+ * simply use the built-in projection types via the static factory methods of this class.<br/>
+ * <br/>
+ * The factory methods that take an alias allow the projected value to be referred to by 
+ * criterion and order instances.
+ *
+ * @see org.hibernate.Criteria
+ * @see Restrictions factory methods for <tt>Criterion</tt> instances
+ * @author Gavin King
+ */
+public final class Projections {
+
+	private Projections() {
+		//cannot be instantiated
+	}
+	
+	/**
+	 * Create a distinct projection from a projection
+	 */
+	public static Projection distinct(Projection proj) {
+		return new Distinct(proj);
+	}
+	
+	/**
+	 * Create a new projection list
+	 */
+	public static ProjectionList projectionList() {
+		return new ProjectionList();
+	}
+		
+	/**
+	 * The query row count, ie. <tt>count(*)</tt>
+	 */
+	public static Projection rowCount() {
+		return new RowCountProjection();
+	}
+	
+	/**
+	 * A property value count
+	 */
+	public static CountProjection count(String propertyName) {
+		return new CountProjection(propertyName);
+	}
+	
+	/**
+	 * A distinct property value count
+	 */
+	public static CountProjection countDistinct(String propertyName) {
+		return new CountProjection(propertyName).setDistinct();
+	}
+	
+	/**
+	 * A property maximum value
+	 */
+	public static AggregateProjection max(String propertyName) {
+		return new AggregateProjection("max", propertyName);
+	}
+	
+	/**
+	 * A property minimum value
+	 */
+	public static AggregateProjection min(String propertyName) {
+		return new AggregateProjection("min", propertyName);
+	}
+	
+	/**
+	 * A property average value
+	 */
+	public static AggregateProjection avg(String propertyName) {
+		return new AvgProjection(propertyName);
+	}
+	
+	/**
+	 * A property value sum
+	 */
+	public static AggregateProjection sum(String propertyName) {
+		return new AggregateProjection("sum", propertyName);
+	}
+	
+	/**
+	 * A SQL projection, a typed select clause fragment
+	 */
+	public static Projection sqlProjection(String sql, String[] columnAliases, Type[] types) {
+		return new SQLProjection(sql, columnAliases, types);
+	}
+	
+	/**
+	 * A grouping SQL projection, specifying both select clause and group by clause fragments
+	 */
+	public static Projection sqlGroupProjection(String sql, String groupBy, String[] columnAliases, Type[] types) {
+		return new SQLProjection(sql, groupBy, columnAliases, types);
+	}
+
+	/**
+	 * A grouping property value
+	 */
+	public static PropertyProjection groupProperty(String propertyName) {
+		return new PropertyProjection(propertyName, true);
+	}
+	
+	/**
+	 * A projected property value
+	 */
+	public static PropertyProjection property(String propertyName) {
+		return new PropertyProjection(propertyName);
+	}
+	
+	/**
+	 * A projected identifier value
+	 */
+	public static IdentifierProjection id() {
+		return new IdentifierProjection();
+	}
+	
+	/**
+	 * Assign an alias to a projection, by wrapping it
+	 */
+	public static Projection alias(Projection projection, String alias) {
+		return new AliasedProjection(projection, alias);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Property.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,235 +0,0 @@
-//$Id: Property.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import java.util.Collection;
-
-/**
- * A factory for property-specific criterion and projection instances
- * @author Gavin King
- */
-public class Property extends PropertyProjection {
-	//private String propertyName;
-	protected Property(String propertyName) {
-		super(propertyName);
-	}
-
-	public Criterion between(Object min, Object max) {
-		return Restrictions.between(getPropertyName(), min, max);
-	}
-
-	public Criterion in(Collection values) {
-		return Restrictions.in(getPropertyName(), values);
-	}
-
-	public Criterion in(Object[] values) {
-		return Restrictions.in(getPropertyName(), values);
-	}
-
-	public SimpleExpression like(Object value) {
-		return Restrictions.like(getPropertyName(), value);
-	}
-
-	public SimpleExpression like(String value, MatchMode matchMode) {
-		return Restrictions.like(getPropertyName(), value, matchMode);
-	}
-
-	public SimpleExpression eq(Object value) {
-		return Restrictions.eq(getPropertyName(), value);
-	}
-
-	public SimpleExpression ne(Object value) {
-		return Restrictions.ne(getPropertyName(), value);
-	}
-
-	public SimpleExpression gt(Object value) {
-		return Restrictions.gt(getPropertyName(), value);
-	}
-
-	public SimpleExpression lt(Object value) {
-		return Restrictions.lt(getPropertyName(), value);
-	}
-
-	public SimpleExpression le(Object value) {
-		return Restrictions.le(getPropertyName(), value);
-	}
-
-	public SimpleExpression ge(Object value) {
-		return Restrictions.ge(getPropertyName(), value);
-	}
-
-	public PropertyExpression eqProperty(Property other) {
-		return Restrictions.eqProperty( getPropertyName(), other.getPropertyName() );
-	}
-
-	public PropertyExpression neProperty(Property other) {
-		return Restrictions.neProperty( getPropertyName(), other.getPropertyName() );
-	}
-	
-	public PropertyExpression leProperty(Property other) {
-		return Restrictions.leProperty( getPropertyName(), other.getPropertyName() );
-	}
-
-	public PropertyExpression geProperty(Property other) {
-		return Restrictions.geProperty( getPropertyName(), other.getPropertyName() );
-	}
-	
-	public PropertyExpression ltProperty(Property other) {
-		return Restrictions.ltProperty( getPropertyName(), other.getPropertyName() );
-	}
-
-	public PropertyExpression gtProperty(Property other) {
-		return Restrictions.gtProperty( getPropertyName(), other.getPropertyName() );
-	}
-	
-	public PropertyExpression eqProperty(String other) {
-		return Restrictions.eqProperty( getPropertyName(), other );
-	}
-
-	public PropertyExpression neProperty(String other) {
-		return Restrictions.neProperty( getPropertyName(), other );
-	}
-	
-	public PropertyExpression leProperty(String other) {
-		return Restrictions.leProperty( getPropertyName(), other );
-	}
-
-	public PropertyExpression geProperty(String other) {
-		return Restrictions.geProperty( getPropertyName(), other );
-	}
-	
-	public PropertyExpression ltProperty(String other) {
-		return Restrictions.ltProperty( getPropertyName(), other );
-	}
-
-	public PropertyExpression gtProperty(String other) {
-		return Restrictions.gtProperty( getPropertyName(), other );
-	}
-	
-	public Criterion isNull() {
-		return Restrictions.isNull(getPropertyName());
-	}
-
-	public Criterion isNotNull() {
-		return Restrictions.isNotNull(getPropertyName());
-	}
-
-	public Criterion isEmpty() {
-		return Restrictions.isEmpty(getPropertyName());
-	}
-
-	public Criterion isNotEmpty() {
-		return Restrictions.isNotEmpty(getPropertyName());
-	}
-	
-	public CountProjection count() {
-		return Projections.count(getPropertyName());
-	}
-	
-	public AggregateProjection max() {
-		return Projections.max(getPropertyName());
-	}
-
-	public AggregateProjection min() {
-		return Projections.min(getPropertyName());
-	}
-
-	public AggregateProjection avg() {
-		return Projections.avg(getPropertyName());
-	}
-	
-	/*public PropertyProjection project() {
-		return Projections.property(getPropertyName());
-	}*/
-
-	public PropertyProjection group() {
-		return Projections.groupProperty(getPropertyName());
-	}
-	
-	public Order asc() {
-		return Order.asc(getPropertyName());
-	}
-
-	public Order desc() {
-		return Order.desc(getPropertyName());
-	}
-
-	public static Property forName(String propertyName) {
-		return new Property(propertyName);
-	}
-	
-	/**
-	 * Get a component attribute of this property
-	 */
-	public Property getProperty(String propertyName) {
-		return forName( getPropertyName() + '.' + propertyName );
-	}
-	
-	public Criterion eq(DetachedCriteria subselect) {
-		return Subqueries.propertyEq( getPropertyName(), subselect );
-	}
-
-	public Criterion ne(DetachedCriteria subselect) {
-		return Subqueries.propertyNe( getPropertyName(), subselect );
-	}
-
-	public Criterion lt(DetachedCriteria subselect) {
-		return Subqueries.propertyLt( getPropertyName(), subselect );
-	}
-
-	public Criterion le(DetachedCriteria subselect) {
-		return Subqueries.propertyLe( getPropertyName(), subselect );
-	}
-
-	public Criterion gt(DetachedCriteria subselect) {
-		return Subqueries.propertyGt( getPropertyName(), subselect );
-	}
-
-	public Criterion ge(DetachedCriteria subselect) {
-		return Subqueries.propertyGe( getPropertyName(), subselect );
-	}
-
-	public Criterion notIn(DetachedCriteria subselect) {
-		return Subqueries.propertyNotIn( getPropertyName(), subselect );
-	}
-
-	public Criterion in(DetachedCriteria subselect) {
-		return Subqueries.propertyIn( getPropertyName(), subselect );
-	}
-
-	public Criterion eqAll(DetachedCriteria subselect) {
-		return Subqueries.propertyEqAll( getPropertyName(), subselect );
-	}
-
-	public Criterion gtAll(DetachedCriteria subselect) {
-		return Subqueries.propertyGtAll( getPropertyName(), subselect );
-	}
-
-	public Criterion ltAll(DetachedCriteria subselect) {
-		return Subqueries.propertyLtAll( getPropertyName(), subselect );
-	}
-
-	public Criterion leAll(DetachedCriteria subselect) {
-		return Subqueries.propertyLeAll( getPropertyName(), subselect );
-	}
-
-	public Criterion geAll(DetachedCriteria subselect) {
-		return Subqueries.propertyGeAll( getPropertyName(), subselect );
-	}
-
-	public Criterion gtSome(DetachedCriteria subselect) {
-		return Subqueries.propertyGtSome( getPropertyName(), subselect );
-	}
-
-	public Criterion ltSome(DetachedCriteria subselect) {
-		return Subqueries.propertyLtSome( getPropertyName(), subselect );
-	}
-
-	public Criterion leSome(DetachedCriteria subselect) {
-		return Subqueries.propertyLeSome( getPropertyName(), subselect );
-	}
-
-	public Criterion geSome(DetachedCriteria subselect) {
-		return Subqueries.propertyGeSome( getPropertyName(), subselect );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Property.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,258 @@
+/*
+ * 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.criterion;
+
+import java.util.Collection;
+
+/**
+ * A factory for property-specific criterion and projection instances
+ * @author Gavin King
+ */
+public class Property extends PropertyProjection {
+	//private String propertyName;
+	protected Property(String propertyName) {
+		super(propertyName);
+	}
+
+	public Criterion between(Object min, Object max) {
+		return Restrictions.between(getPropertyName(), min, max);
+	}
+
+	public Criterion in(Collection values) {
+		return Restrictions.in(getPropertyName(), values);
+	}
+
+	public Criterion in(Object[] values) {
+		return Restrictions.in(getPropertyName(), values);
+	}
+
+	public SimpleExpression like(Object value) {
+		return Restrictions.like(getPropertyName(), value);
+	}
+
+	public SimpleExpression like(String value, MatchMode matchMode) {
+		return Restrictions.like(getPropertyName(), value, matchMode);
+	}
+
+	public SimpleExpression eq(Object value) {
+		return Restrictions.eq(getPropertyName(), value);
+	}
+
+	public SimpleExpression ne(Object value) {
+		return Restrictions.ne(getPropertyName(), value);
+	}
+
+	public SimpleExpression gt(Object value) {
+		return Restrictions.gt(getPropertyName(), value);
+	}
+
+	public SimpleExpression lt(Object value) {
+		return Restrictions.lt(getPropertyName(), value);
+	}
+
+	public SimpleExpression le(Object value) {
+		return Restrictions.le(getPropertyName(), value);
+	}
+
+	public SimpleExpression ge(Object value) {
+		return Restrictions.ge(getPropertyName(), value);
+	}
+
+	public PropertyExpression eqProperty(Property other) {
+		return Restrictions.eqProperty( getPropertyName(), other.getPropertyName() );
+	}
+
+	public PropertyExpression neProperty(Property other) {
+		return Restrictions.neProperty( getPropertyName(), other.getPropertyName() );
+	}
+	
+	public PropertyExpression leProperty(Property other) {
+		return Restrictions.leProperty( getPropertyName(), other.getPropertyName() );
+	}
+
+	public PropertyExpression geProperty(Property other) {
+		return Restrictions.geProperty( getPropertyName(), other.getPropertyName() );
+	}
+	
+	public PropertyExpression ltProperty(Property other) {
+		return Restrictions.ltProperty( getPropertyName(), other.getPropertyName() );
+	}
+
+	public PropertyExpression gtProperty(Property other) {
+		return Restrictions.gtProperty( getPropertyName(), other.getPropertyName() );
+	}
+	
+	public PropertyExpression eqProperty(String other) {
+		return Restrictions.eqProperty( getPropertyName(), other );
+	}
+
+	public PropertyExpression neProperty(String other) {
+		return Restrictions.neProperty( getPropertyName(), other );
+	}
+	
+	public PropertyExpression leProperty(String other) {
+		return Restrictions.leProperty( getPropertyName(), other );
+	}
+
+	public PropertyExpression geProperty(String other) {
+		return Restrictions.geProperty( getPropertyName(), other );
+	}
+	
+	public PropertyExpression ltProperty(String other) {
+		return Restrictions.ltProperty( getPropertyName(), other );
+	}
+
+	public PropertyExpression gtProperty(String other) {
+		return Restrictions.gtProperty( getPropertyName(), other );
+	}
+	
+	public Criterion isNull() {
+		return Restrictions.isNull(getPropertyName());
+	}
+
+	public Criterion isNotNull() {
+		return Restrictions.isNotNull(getPropertyName());
+	}
+
+	public Criterion isEmpty() {
+		return Restrictions.isEmpty(getPropertyName());
+	}
+
+	public Criterion isNotEmpty() {
+		return Restrictions.isNotEmpty(getPropertyName());
+	}
+	
+	public CountProjection count() {
+		return Projections.count(getPropertyName());
+	}
+	
+	public AggregateProjection max() {
+		return Projections.max(getPropertyName());
+	}
+
+	public AggregateProjection min() {
+		return Projections.min(getPropertyName());
+	}
+
+	public AggregateProjection avg() {
+		return Projections.avg(getPropertyName());
+	}
+	
+	/*public PropertyProjection project() {
+		return Projections.property(getPropertyName());
+	}*/
+
+	public PropertyProjection group() {
+		return Projections.groupProperty(getPropertyName());
+	}
+	
+	public Order asc() {
+		return Order.asc(getPropertyName());
+	}
+
+	public Order desc() {
+		return Order.desc(getPropertyName());
+	}
+
+	public static Property forName(String propertyName) {
+		return new Property(propertyName);
+	}
+	
+	/**
+	 * Get a component attribute of this property
+	 */
+	public Property getProperty(String propertyName) {
+		return forName( getPropertyName() + '.' + propertyName );
+	}
+	
+	public Criterion eq(DetachedCriteria subselect) {
+		return Subqueries.propertyEq( getPropertyName(), subselect );
+	}
+
+	public Criterion ne(DetachedCriteria subselect) {
+		return Subqueries.propertyNe( getPropertyName(), subselect );
+	}
+
+	public Criterion lt(DetachedCriteria subselect) {
+		return Subqueries.propertyLt( getPropertyName(), subselect );
+	}
+
+	public Criterion le(DetachedCriteria subselect) {
+		return Subqueries.propertyLe( getPropertyName(), subselect );
+	}
+
+	public Criterion gt(DetachedCriteria subselect) {
+		return Subqueries.propertyGt( getPropertyName(), subselect );
+	}
+
+	public Criterion ge(DetachedCriteria subselect) {
+		return Subqueries.propertyGe( getPropertyName(), subselect );
+	}
+
+	public Criterion notIn(DetachedCriteria subselect) {
+		return Subqueries.propertyNotIn( getPropertyName(), subselect );
+	}
+
+	public Criterion in(DetachedCriteria subselect) {
+		return Subqueries.propertyIn( getPropertyName(), subselect );
+	}
+
+	public Criterion eqAll(DetachedCriteria subselect) {
+		return Subqueries.propertyEqAll( getPropertyName(), subselect );
+	}
+
+	public Criterion gtAll(DetachedCriteria subselect) {
+		return Subqueries.propertyGtAll( getPropertyName(), subselect );
+	}
+
+	public Criterion ltAll(DetachedCriteria subselect) {
+		return Subqueries.propertyLtAll( getPropertyName(), subselect );
+	}
+
+	public Criterion leAll(DetachedCriteria subselect) {
+		return Subqueries.propertyLeAll( getPropertyName(), subselect );
+	}
+
+	public Criterion geAll(DetachedCriteria subselect) {
+		return Subqueries.propertyGeAll( getPropertyName(), subselect );
+	}
+
+	public Criterion gtSome(DetachedCriteria subselect) {
+		return Subqueries.propertyGtSome( getPropertyName(), subselect );
+	}
+
+	public Criterion ltSome(DetachedCriteria subselect) {
+		return Subqueries.propertyLtSome( getPropertyName(), subselect );
+	}
+
+	public Criterion leSome(DetachedCriteria subselect) {
+		return Subqueries.propertyLeSome( getPropertyName(), subselect );
+	}
+
+	public Criterion geSome(DetachedCriteria subselect) {
+		return Subqueries.propertyGeSome( getPropertyName(), subselect );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/PropertyExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: PropertyExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.util.StringHelper;
-
-/**
- * superclass for comparisons between two properties (with SQL binary operators)
- * @author Gavin King
- */
-public class PropertyExpression implements Criterion {
-
-	private final String propertyName;
-	private final String otherPropertyName;
-	private final String op;
-
-	private static final TypedValue[] NO_TYPED_VALUES = new TypedValue[0];
-
-	protected PropertyExpression(String propertyName, String otherPropertyName, String op) {
-		this.propertyName = propertyName;
-		this.otherPropertyName = otherPropertyName;
-		this.op = op;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		String[] xcols = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		String[] ycols = criteriaQuery.getColumnsUsingProjection(criteria, otherPropertyName);
-		String result = StringHelper.join(
-			" and ",
-			StringHelper.add(xcols, getOp(), ycols)
-		);
-		if (xcols.length>1) result = '(' + result + ')';
-		return result;
-		//TODO: get SQL rendering out of this package!
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return NO_TYPED_VALUES;
-	}
-
-	public String toString() {
-		return propertyName + getOp() + otherPropertyName;
-	}
-
-	public String getOp() {
-		return op;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/PropertyExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.util.StringHelper;
+
+/**
+ * superclass for comparisons between two properties (with SQL binary operators)
+ * @author Gavin King
+ */
+public class PropertyExpression implements Criterion {
+
+	private final String propertyName;
+	private final String otherPropertyName;
+	private final String op;
+
+	private static final TypedValue[] NO_TYPED_VALUES = new TypedValue[0];
+
+	protected PropertyExpression(String propertyName, String otherPropertyName, String op) {
+		this.propertyName = propertyName;
+		this.otherPropertyName = otherPropertyName;
+		this.op = op;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		String[] xcols = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		String[] ycols = criteriaQuery.getColumnsUsingProjection(criteria, otherPropertyName);
+		String result = StringHelper.join(
+			" and ",
+			StringHelper.add(xcols, getOp(), ycols)
+		);
+		if (xcols.length>1) result = '(' + result + ')';
+		return result;
+		//TODO: get SQL rendering out of this package!
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return NO_TYPED_VALUES;
+	}
+
+	public String toString() {
+		return propertyName + getOp() + otherPropertyName;
+	}
+
+	public String getOp() {
+		return op;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: PropertyProjection.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * A property value, or grouped property value
- * @author Gavin King
- */
-public class PropertyProjection extends SimpleProjection {
-
-	private String propertyName;
-	private boolean grouped;
-	
-	protected PropertyProjection(String prop, boolean grouped) {
-		this.propertyName = prop;
-		this.grouped = grouped;
-	}
-	
-	protected PropertyProjection(String prop) {
-		this(prop, false);
-	}
-
-	public String getPropertyName() {
-		return propertyName;
-	}
-	
-	public String toString() {
-		return propertyName;
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new Type[] { criteriaQuery.getType(criteria, propertyName) };
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new StringBuffer()
-			.append( criteriaQuery.getColumn(criteria, propertyName) )
-			.append(" as y")
-			.append(position)
-			.append('_')
-			.toString();
-	}
-
-	public boolean isGrouped() {
-		return grouped;
-	}
-	
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		if (!grouped) {
-			return super.toGroupSqlString(criteria, criteriaQuery);
-		}
-		else {
-			return criteriaQuery.getColumn(criteria, propertyName);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/PropertyProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertyProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * A property value, or grouped property value
+ * @author Gavin King
+ */
+public class PropertyProjection extends SimpleProjection {
+
+	private String propertyName;
+	private boolean grouped;
+	
+	protected PropertyProjection(String prop, boolean grouped) {
+		this.propertyName = prop;
+		this.grouped = grouped;
+	}
+	
+	protected PropertyProjection(String prop) {
+		this(prop, false);
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+	
+	public String toString() {
+		return propertyName;
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new Type[] { criteriaQuery.getType(criteria, propertyName) };
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new StringBuffer()
+			.append( criteriaQuery.getColumn(criteria, propertyName) )
+			.append(" as y")
+			.append(position)
+			.append('_')
+			.toString();
+	}
+
+	public boolean isGrouped() {
+		return grouped;
+	}
+	
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		if (!grouped) {
+			return super.toGroupSqlString(criteria, criteriaQuery);
+		}
+		else {
+			return criteriaQuery.getColumn(criteria, propertyName);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: PropertySubqueryExpression.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-
-/**
- * A comparison between a property value in the outer query and the
- * result of a subquery
- * @author Gavin King
- */
-public class PropertySubqueryExpression extends SubqueryExpression {
-	private String propertyName;
-
-	protected PropertySubqueryExpression(String propertyName, String op, String quantifier, DetachedCriteria dc) {
-		super(op, quantifier, dc);
-		this.propertyName = propertyName;
-	}
-
-	protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
-		return criteriaQuery.getColumn(criteria, propertyName);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/PropertySubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+
+/**
+ * A comparison between a property value in the outer query and the
+ * result of a subquery
+ * @author Gavin King
+ */
+public class PropertySubqueryExpression extends SubqueryExpression {
+	private String propertyName;
+
+	protected PropertySubqueryExpression(String propertyName, String op, String quantifier, DetachedCriteria dc) {
+		super(op, quantifier, dc);
+		this.propertyName = propertyName;
+	}
+
+	protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
+		return criteriaQuery.getColumn(criteria, propertyName);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Restrictions.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,368 +0,0 @@
-//$Id: Restrictions.java 7844 2005-08-11 07:26:26Z oneovthafew $
-package org.hibernate.criterion;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * The <tt>criterion</tt> package may be used by applications as a framework for building
- * new kinds of <tt>Criterion</tt>. However, it is intended that most applications will
- * simply use the built-in criterion types via the static factory methods of this class.
- *
- * @see org.hibernate.Criteria
- * @see Projections factory methods for <tt>Projection</tt> instances
- * @author Gavin King
- */
-public class Restrictions {
-
-	Restrictions() {
-		//cannot be instantiated
-	}
-
-	/**
-	 * Apply an "equal" constraint to the identifier property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static Criterion idEq(Object value) {
-		return new IdentifierEqExpression(value);
-	}
-	/**
-	 * Apply an "equal" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression eq(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, "=");
-	}
-	/**
-	 * Apply a "not equal" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression ne(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, "<>");
-	}
-	/**
-	 * Apply a "like" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression like(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, " like ");
-	}
-	/**
-	 * Apply a "like" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression like(String propertyName, String value, MatchMode matchMode) {
-		return new SimpleExpression(propertyName, matchMode.toMatchString(value), " like " );
-	}
-	/**
-	 * A case-insensitive "like", similar to Postgres <tt>ilike</tt>
-	 * operator
-	 *
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static Criterion ilike(String propertyName, String value, MatchMode matchMode) {
-		return new IlikeExpression(propertyName, value, matchMode);
-	}
-	/**
-	 * A case-insensitive "like", similar to Postgres <tt>ilike</tt>
-	 * operator
-	 *
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static Criterion ilike(String propertyName, Object value) {
-		return new IlikeExpression(propertyName, value);
-	}
-	/**
-	 * Apply a "greater than" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression gt(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, ">");
-	}
-	/**
-	 * Apply a "less than" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression lt(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, "<");
-	}
-	/**
-	 * Apply a "less than or equal" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression le(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, "<=");
-	}
-	/**
-	 * Apply a "greater than or equal" constraint to the named property
-	 * @param propertyName
-	 * @param value
-	 * @return Criterion
-	 */
-	public static SimpleExpression ge(String propertyName, Object value) {
-		return new SimpleExpression(propertyName, value, ">=");
-	}
-	/**
-	 * Apply a "between" constraint to the named property
-	 * @param propertyName
-	 * @param lo value
-	 * @param hi value
-	 * @return Criterion
-	 */
-	public static Criterion between(String propertyName, Object lo, Object hi) {
-		return new BetweenExpression(propertyName, lo, hi);
-	}
-	/**
-	 * Apply an "in" constraint to the named property
-	 * @param propertyName
-	 * @param values
-	 * @return Criterion
-	 */
-	public static Criterion in(String propertyName, Object[] values) {
-		return new InExpression(propertyName, values);
-	}
-	/**
-	 * Apply an "in" constraint to the named property
-	 * @param propertyName
-	 * @param values
-	 * @return Criterion
-	 */
-	public static Criterion in(String propertyName, Collection values) {
-		return new InExpression( propertyName, values.toArray() );
-	}
-	/**
-	 * Apply an "is null" constraint to the named property
-	 * @return Criterion
-	 */
-	public static Criterion isNull(String propertyName) {
-		return new NullExpression(propertyName);
-	}
-	/**
-	 * Apply an "equal" constraint to two properties
-	 */
-	public static PropertyExpression eqProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, "=");
-	}
-	/**
-	 * Apply a "not equal" constraint to two properties
-	 */
-	public static PropertyExpression neProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, "<>");
-	}
-	/**
-	 * Apply a "less than" constraint to two properties
-	 */
-	public static PropertyExpression ltProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, "<");
-	}
-	/**
-	 * Apply a "less than or equal" constraint to two properties
-	 */
-	public static PropertyExpression leProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, "<=");
-	}
-	/**
-	 * Apply a "greater than" constraint to two properties
-	 */
-	public static PropertyExpression gtProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, ">");
-	}
-	/**
-	 * Apply a "greater than or equal" constraint to two properties
-	 */
-	public static PropertyExpression geProperty(String propertyName, String otherPropertyName) {
-		return new PropertyExpression(propertyName, otherPropertyName, ">=");
-	}
-	/**
-	 * Apply an "is not null" constraint to the named property
-	 * @return Criterion
-	 */
-	public static Criterion isNotNull(String propertyName) {
-		return new NotNullExpression(propertyName);
-	}
-	/**
-	 * Return the conjuction of two expressions
-	 *
-	 * @param lhs
-	 * @param rhs
-	 * @return Criterion
-	 */
-	public static LogicalExpression and(Criterion lhs, Criterion rhs) {
-		return new LogicalExpression(lhs, rhs, "and");
-	}
-	/**
-	 * Return the disjuction of two expressions
-	 *
-	 * @param lhs
-	 * @param rhs
-	 * @return Criterion
-	 */
-	public static LogicalExpression or(Criterion lhs, Criterion rhs) {
-		return new LogicalExpression(lhs, rhs, "or");
-	}
-	/**
-	 * Return the negation of an expression
-	 *
-	 * @param expression
-	 * @return Criterion
-	 */
-	public static Criterion not(Criterion expression) {
-		return new NotExpression(expression);
-	}
-	/**
-	 * Apply a constraint expressed in SQL, with the given JDBC
-	 * parameters. Any occurrences of <tt>{alias}</tt> will be
-	 * replaced by the table alias.
-	 *
-	 * @param sql
-	 * @param values
-	 * @param types
-	 * @return Criterion
-	 */
-	public static Criterion sqlRestriction(String sql, Object[] values, Type[] types) {
-		return new SQLCriterion(sql, values, types);
-	}
-	/**
-	 * Apply a constraint expressed in SQL, with the given JDBC
-	 * parameter. Any occurrences of <tt>{alias}</tt> will be replaced
-	 * by the table alias.
-	 *
-	 * @param sql
-	 * @param value
-	 * @param type
-	 * @return Criterion
-	 */
-	public static Criterion sqlRestriction(String sql, Object value, Type type) {
-		return new SQLCriterion(sql, new Object[] { value }, new Type[] { type } );
-	}
-	/**
-	 * Apply a constraint expressed in SQL. Any occurrences of <tt>{alias}</tt>
-	 * will be replaced by the table alias.
-	 *
-	 * @param sql
-	 * @return Criterion
-	 */
-	public static Criterion sqlRestriction(String sql) {
-		return new SQLCriterion(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);
-	}
-
-	/**
-	 * Group expressions together in a single conjunction (A and B and C...)
-	 *
-	 * @return Conjunction
-	 */
-	public static Conjunction conjunction() {
-		return new Conjunction();
-	}
-
-	/**
-	 * Group expressions together in a single disjunction (A or B or C...)
-	 *
-	 * @return Conjunction
-	 */
-	public static Disjunction disjunction() {
-		return new Disjunction();
-	}
-
-	/**
-	 * Apply an "equals" constraint to each property in the
-	 * key set of a <tt>Map</tt>
-	 *
-	 * @param propertyNameValues a map from property names to values
-	 * @return Criterion
-	 */
-	public static Criterion allEq(Map propertyNameValues) {
-		Conjunction conj = conjunction();
-		Iterator iter = propertyNameValues.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			conj.add( eq( (String) me.getKey(), me.getValue() ) );
-		}
-		return conj;
-	}
-	
-	/**
-	 * Constrain a collection valued property to be empty
-	 */
-	public static Criterion isEmpty(String propertyName) {
-		return new EmptyExpression(propertyName);
-	}
-
-	/**
-	 * Constrain a collection valued property to be non-empty
-	 */
-	public static Criterion isNotEmpty(String propertyName) {
-		return new NotEmptyExpression(propertyName);
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeEq(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, "=");
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeNe(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, "<>");
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeGt(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, "<");
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeLt(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, ">");
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeGe(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, "<=");
-	}
-	
-	/**
-	 * Constrain a collection valued property by size
-	 */
-	public static Criterion sizeLe(String propertyName, int size) {
-		return new SizeExpression(propertyName, size, ">=");
-	}
-	
-	public static NaturalIdentifier naturalId() {
-		return new NaturalIdentifier();
-	}
-		
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Restrictions.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Restrictions.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,391 @@
+/*
+ * 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.criterion;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * The <tt>criterion</tt> package may be used by applications as a framework for building
+ * new kinds of <tt>Criterion</tt>. However, it is intended that most applications will
+ * simply use the built-in criterion types via the static factory methods of this class.
+ *
+ * @see org.hibernate.Criteria
+ * @see Projections factory methods for <tt>Projection</tt> instances
+ * @author Gavin King
+ */
+public class Restrictions {
+
+	Restrictions() {
+		//cannot be instantiated
+	}
+
+	/**
+	 * Apply an "equal" constraint to the identifier property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static Criterion idEq(Object value) {
+		return new IdentifierEqExpression(value);
+	}
+	/**
+	 * Apply an "equal" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression eq(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, "=");
+	}
+	/**
+	 * Apply a "not equal" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression ne(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, "<>");
+	}
+	/**
+	 * Apply a "like" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression like(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, " like ");
+	}
+	/**
+	 * Apply a "like" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression like(String propertyName, String value, MatchMode matchMode) {
+		return new SimpleExpression(propertyName, matchMode.toMatchString(value), " like " );
+	}
+	/**
+	 * A case-insensitive "like", similar to Postgres <tt>ilike</tt>
+	 * operator
+	 *
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static Criterion ilike(String propertyName, String value, MatchMode matchMode) {
+		return new IlikeExpression(propertyName, value, matchMode);
+	}
+	/**
+	 * A case-insensitive "like", similar to Postgres <tt>ilike</tt>
+	 * operator
+	 *
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static Criterion ilike(String propertyName, Object value) {
+		return new IlikeExpression(propertyName, value);
+	}
+	/**
+	 * Apply a "greater than" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression gt(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, ">");
+	}
+	/**
+	 * Apply a "less than" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression lt(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, "<");
+	}
+	/**
+	 * Apply a "less than or equal" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression le(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, "<=");
+	}
+	/**
+	 * Apply a "greater than or equal" constraint to the named property
+	 * @param propertyName
+	 * @param value
+	 * @return Criterion
+	 */
+	public static SimpleExpression ge(String propertyName, Object value) {
+		return new SimpleExpression(propertyName, value, ">=");
+	}
+	/**
+	 * Apply a "between" constraint to the named property
+	 * @param propertyName
+	 * @param lo value
+	 * @param hi value
+	 * @return Criterion
+	 */
+	public static Criterion between(String propertyName, Object lo, Object hi) {
+		return new BetweenExpression(propertyName, lo, hi);
+	}
+	/**
+	 * Apply an "in" constraint to the named property
+	 * @param propertyName
+	 * @param values
+	 * @return Criterion
+	 */
+	public static Criterion in(String propertyName, Object[] values) {
+		return new InExpression(propertyName, values);
+	}
+	/**
+	 * Apply an "in" constraint to the named property
+	 * @param propertyName
+	 * @param values
+	 * @return Criterion
+	 */
+	public static Criterion in(String propertyName, Collection values) {
+		return new InExpression( propertyName, values.toArray() );
+	}
+	/**
+	 * Apply an "is null" constraint to the named property
+	 * @return Criterion
+	 */
+	public static Criterion isNull(String propertyName) {
+		return new NullExpression(propertyName);
+	}
+	/**
+	 * Apply an "equal" constraint to two properties
+	 */
+	public static PropertyExpression eqProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, "=");
+	}
+	/**
+	 * Apply a "not equal" constraint to two properties
+	 */
+	public static PropertyExpression neProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, "<>");
+	}
+	/**
+	 * Apply a "less than" constraint to two properties
+	 */
+	public static PropertyExpression ltProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, "<");
+	}
+	/**
+	 * Apply a "less than or equal" constraint to two properties
+	 */
+	public static PropertyExpression leProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, "<=");
+	}
+	/**
+	 * Apply a "greater than" constraint to two properties
+	 */
+	public static PropertyExpression gtProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, ">");
+	}
+	/**
+	 * Apply a "greater than or equal" constraint to two properties
+	 */
+	public static PropertyExpression geProperty(String propertyName, String otherPropertyName) {
+		return new PropertyExpression(propertyName, otherPropertyName, ">=");
+	}
+	/**
+	 * Apply an "is not null" constraint to the named property
+	 * @return Criterion
+	 */
+	public static Criterion isNotNull(String propertyName) {
+		return new NotNullExpression(propertyName);
+	}
+	/**
+	 * Return the conjuction of two expressions
+	 *
+	 * @param lhs
+	 * @param rhs
+	 * @return Criterion
+	 */
+	public static LogicalExpression and(Criterion lhs, Criterion rhs) {
+		return new LogicalExpression(lhs, rhs, "and");
+	}
+	/**
+	 * Return the disjuction of two expressions
+	 *
+	 * @param lhs
+	 * @param rhs
+	 * @return Criterion
+	 */
+	public static LogicalExpression or(Criterion lhs, Criterion rhs) {
+		return new LogicalExpression(lhs, rhs, "or");
+	}
+	/**
+	 * Return the negation of an expression
+	 *
+	 * @param expression
+	 * @return Criterion
+	 */
+	public static Criterion not(Criterion expression) {
+		return new NotExpression(expression);
+	}
+	/**
+	 * Apply a constraint expressed in SQL, with the given JDBC
+	 * parameters. Any occurrences of <tt>{alias}</tt> will be
+	 * replaced by the table alias.
+	 *
+	 * @param sql
+	 * @param values
+	 * @param types
+	 * @return Criterion
+	 */
+	public static Criterion sqlRestriction(String sql, Object[] values, Type[] types) {
+		return new SQLCriterion(sql, values, types);
+	}
+	/**
+	 * Apply a constraint expressed in SQL, with the given JDBC
+	 * parameter. Any occurrences of <tt>{alias}</tt> will be replaced
+	 * by the table alias.
+	 *
+	 * @param sql
+	 * @param value
+	 * @param type
+	 * @return Criterion
+	 */
+	public static Criterion sqlRestriction(String sql, Object value, Type type) {
+		return new SQLCriterion(sql, new Object[] { value }, new Type[] { type } );
+	}
+	/**
+	 * Apply a constraint expressed in SQL. Any occurrences of <tt>{alias}</tt>
+	 * will be replaced by the table alias.
+	 *
+	 * @param sql
+	 * @return Criterion
+	 */
+	public static Criterion sqlRestriction(String sql) {
+		return new SQLCriterion(sql, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY);
+	}
+
+	/**
+	 * Group expressions together in a single conjunction (A and B and C...)
+	 *
+	 * @return Conjunction
+	 */
+	public static Conjunction conjunction() {
+		return new Conjunction();
+	}
+
+	/**
+	 * Group expressions together in a single disjunction (A or B or C...)
+	 *
+	 * @return Conjunction
+	 */
+	public static Disjunction disjunction() {
+		return new Disjunction();
+	}
+
+	/**
+	 * Apply an "equals" constraint to each property in the
+	 * key set of a <tt>Map</tt>
+	 *
+	 * @param propertyNameValues a map from property names to values
+	 * @return Criterion
+	 */
+	public static Criterion allEq(Map propertyNameValues) {
+		Conjunction conj = conjunction();
+		Iterator iter = propertyNameValues.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			conj.add( eq( (String) me.getKey(), me.getValue() ) );
+		}
+		return conj;
+	}
+	
+	/**
+	 * Constrain a collection valued property to be empty
+	 */
+	public static Criterion isEmpty(String propertyName) {
+		return new EmptyExpression(propertyName);
+	}
+
+	/**
+	 * Constrain a collection valued property to be non-empty
+	 */
+	public static Criterion isNotEmpty(String propertyName) {
+		return new NotEmptyExpression(propertyName);
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeEq(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, "=");
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeNe(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, "<>");
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeGt(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, "<");
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeLt(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, ">");
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeGe(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, "<=");
+	}
+	
+	/**
+	 * Constrain a collection valued property by size
+	 */
+	public static Criterion sizeLe(String propertyName, int size) {
+		return new SizeExpression(propertyName, size, ">=");
+	}
+	
+	public static NaturalIdentifier naturalId() {
+		return new NaturalIdentifier();
+	}
+		
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/RowCountProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: RowCountProjection.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-/**
- * A row count
- * @author Gavin King
- */
-public class RowCountProjection extends SimpleProjection {
-
-	protected RowCountProjection() {}
-
-	public String toString() {
-		return "count(*)";
-	}
-
-	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new Type[] { Hibernate.INTEGER };
-	}
-
-	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new StringBuffer()
-			.append("count(*) as y")
-			.append(position)
-			.append('_')
-			.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/RowCountProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/RowCountProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+/**
+ * A row count
+ * @author Gavin King
+ */
+public class RowCountProjection extends SimpleProjection {
+
+	protected RowCountProjection() {}
+
+	public String toString() {
+		return "count(*)";
+	}
+
+	public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new Type[] { Hibernate.INTEGER };
+	}
+
+	public String toSqlString(Criteria criteria, int position, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new StringBuffer()
+			.append("count(*) as y")
+			.append(position)
+			.append('_')
+			.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SQLCriterion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: SQLCriterion.java 5757 2005-02-18 03:47:27Z oneovthafew $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * A SQL fragment. The string {alias} will be replaced by the
- * alias of the root entity.
- */
-public class SQLCriterion implements Criterion {
-
-	private final String sql;
-	private final TypedValue[] typedValues;
-
-	public String toSqlString(
-		Criteria criteria,
-		CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return StringHelper.replace( sql, "{alias}", criteriaQuery.getSQLAlias(criteria) );
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return typedValues;
-	}
-
-	public String toString() {
-		return sql;
-	}
-
-	protected SQLCriterion(String sql, Object[] values, Type[] types) {
-		this.sql = sql;
-		typedValues = new TypedValue[values.length];
-		for ( int i=0; i<typedValues.length; i++ ) {
-			typedValues[i] = new TypedValue( types[i], values[i], EntityMode.POJO );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SQLCriterion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLCriterion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A SQL fragment. The string {alias} will be replaced by the
+ * alias of the root entity.
+ */
+public class SQLCriterion implements Criterion {
+
+	private final String sql;
+	private final TypedValue[] typedValues;
+
+	public String toSqlString(
+		Criteria criteria,
+		CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return StringHelper.replace( sql, "{alias}", criteriaQuery.getSQLAlias(criteria) );
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return typedValues;
+	}
+
+	public String toString() {
+		return sql;
+	}
+
+	protected SQLCriterion(String sql, Object[] values, Type[] types) {
+		this.sql = sql;
+		typedValues = new TypedValue[values.length];
+		for ( int i=0; i<typedValues.length; i++ ) {
+			typedValues[i] = new TypedValue( types[i], values[i], EntityMode.POJO );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SQLProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,77 +0,0 @@
-//$Id: SQLProjection.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * A SQL fragment. The string {alias} will be replaced by the
- * alias of the root entity.
- */
-public class SQLProjection implements Projection {
-
-	private final String sql;
-	private final String groupBy;
-	private final Type[] types;
-	private String[] aliases;
-	private String[] columnAliases;
-	private boolean grouped;
-
-	public String toSqlString(
-			Criteria criteria, 
-			int loc, 
-			CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return StringHelper.replace( sql, "{alias}", criteriaQuery.getSQLAlias(criteria) );
-	}
-
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return StringHelper.replace( groupBy, "{alias}", criteriaQuery.getSQLAlias(criteria) );
-	}
-
-	public Type[] getTypes(Criteria crit, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		return types;
-	}
-
-	public String toString() {
-		return sql;
-	}
-
-	protected SQLProjection(String sql, String[] columnAliases, Type[] types) {
-		this(sql, null, columnAliases, types);
-	}
-	
-	protected SQLProjection(String sql, String groupBy, String[] columnAliases, Type[] types) {
-		this.sql = sql;
-		this.types = types;
-		this.aliases = columnAliases;
-		this.columnAliases = columnAliases;
-		this.grouped = groupBy!=null;
-		this.groupBy = groupBy;
-	}
-
-	public String[] getAliases() {
-		return aliases;
-	}
-	
-	public String[] getColumnAliases(int loc) {
-		return columnAliases;
-	}
-	
-	public boolean isGrouped() {
-		return grouped;
-	}
-
-	public Type[] getTypes(String alias, Criteria crit, CriteriaQuery criteriaQuery) {
-		return null; //unsupported
-	}
-
-	public String[] getColumnAliases(String alias, int loc) {
-		return null; //unsupported
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SQLProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SQLProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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.criterion;
+
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A SQL fragment. The string {alias} will be replaced by the
+ * alias of the root entity.
+ */
+public class SQLProjection implements Projection {
+
+	private final String sql;
+	private final String groupBy;
+	private final Type[] types;
+	private String[] aliases;
+	private String[] columnAliases;
+	private boolean grouped;
+
+	public String toSqlString(
+			Criteria criteria, 
+			int loc, 
+			CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return StringHelper.replace( sql, "{alias}", criteriaQuery.getSQLAlias(criteria) );
+	}
+
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return StringHelper.replace( groupBy, "{alias}", criteriaQuery.getSQLAlias(criteria) );
+	}
+
+	public Type[] getTypes(Criteria crit, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		return types;
+	}
+
+	public String toString() {
+		return sql;
+	}
+
+	protected SQLProjection(String sql, String[] columnAliases, Type[] types) {
+		this(sql, null, columnAliases, types);
+	}
+	
+	protected SQLProjection(String sql, String groupBy, String[] columnAliases, Type[] types) {
+		this.sql = sql;
+		this.types = types;
+		this.aliases = columnAliases;
+		this.columnAliases = columnAliases;
+		this.grouped = groupBy!=null;
+		this.groupBy = groupBy;
+	}
+
+	public String[] getAliases() {
+		return aliases;
+	}
+	
+	public String[] getColumnAliases(int loc) {
+		return columnAliases;
+	}
+	
+	public boolean isGrouped() {
+		return grouped;
+	}
+
+	public Type[] getTypes(String alias, Criteria crit, CriteriaQuery criteriaQuery) {
+		return null; //unsupported
+	}
+
+	public String[] getColumnAliases(String alias, int loc) {
+		return null; //unsupported
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SimpleExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: SimpleExpression.java 7641 2005-07-25 04:57:05Z oneovthafew $
-package org.hibernate.criterion;
-
-
-import java.sql.Types;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.type.Type;
-
-/**
- * superclass for "simple" comparisons (with SQL binary operators)
- * @author Gavin King
- */
-public class SimpleExpression implements Criterion {
-
-	private final String propertyName;
-	private final Object value;
-	private boolean ignoreCase;
-	private final String op;
-
-	protected SimpleExpression(String propertyName, Object value, String op) {
-		this.propertyName = propertyName;
-		this.value = value;
-		this.op = op;
-	}
-
-	protected SimpleExpression(String propertyName, Object value, String op, boolean ignoreCase) {
-		this.propertyName = propertyName;
-		this.value = value;
-		this.ignoreCase = ignoreCase;
-		this.op = op;
-	}
-
-	public SimpleExpression ignoreCase() {
-		ignoreCase = true;
-		return this;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
-		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
-		StringBuffer fragment = new StringBuffer();
-		if (columns.length>1) fragment.append('(');
-		SessionFactoryImplementor factory = criteriaQuery.getFactory();
-		int[] sqlTypes = type.sqlTypes( factory );
-		for ( int i=0; i<columns.length; i++ ) {
-			boolean lower = ignoreCase && 
-					( sqlTypes[i]==Types.VARCHAR || sqlTypes[i]==Types.CHAR );
-			if (lower) {
-				fragment.append( factory.getDialect().getLowercaseFunction() )
-					.append('(');
-			}
-			fragment.append( columns[i] );
-			if (lower) fragment.append(')');
-			fragment.append( getOp() ).append("?");
-			if ( i<columns.length-1 ) fragment.append(" and ");
-		}
-		if (columns.length>1) fragment.append(')');
-		return fragment.toString();
-
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		Object icvalue = ignoreCase ? value.toString().toLowerCase() : value;
-		return new TypedValue[] { criteriaQuery.getTypedValue(criteria, propertyName, icvalue) };
-	}
-
-	public String toString() {
-		return propertyName + getOp() + value;
-	}
-
-	protected final String getOp() {
-		return op;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SimpleExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.criterion;
+
+
+import java.sql.Types;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.type.Type;
+
+/**
+ * superclass for "simple" comparisons (with SQL binary operators)
+ * @author Gavin King
+ */
+public class SimpleExpression implements Criterion {
+
+	private final String propertyName;
+	private final Object value;
+	private boolean ignoreCase;
+	private final String op;
+
+	protected SimpleExpression(String propertyName, Object value, String op) {
+		this.propertyName = propertyName;
+		this.value = value;
+		this.op = op;
+	}
+
+	protected SimpleExpression(String propertyName, Object value, String op, boolean ignoreCase) {
+		this.propertyName = propertyName;
+		this.value = value;
+		this.ignoreCase = ignoreCase;
+		this.op = op;
+	}
+
+	public SimpleExpression ignoreCase() {
+		ignoreCase = true;
+		return this;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		String[] columns = criteriaQuery.getColumnsUsingProjection(criteria, propertyName);
+		Type type = criteriaQuery.getTypeUsingProjection(criteria, propertyName);
+		StringBuffer fragment = new StringBuffer();
+		if (columns.length>1) fragment.append('(');
+		SessionFactoryImplementor factory = criteriaQuery.getFactory();
+		int[] sqlTypes = type.sqlTypes( factory );
+		for ( int i=0; i<columns.length; i++ ) {
+			boolean lower = ignoreCase && 
+					( sqlTypes[i]==Types.VARCHAR || sqlTypes[i]==Types.CHAR );
+			if (lower) {
+				fragment.append( factory.getDialect().getLowercaseFunction() )
+					.append('(');
+			}
+			fragment.append( columns[i] );
+			if (lower) fragment.append(')');
+			fragment.append( getOp() ).append("?");
+			if ( i<columns.length-1 ) fragment.append(" and ");
+		}
+		if (columns.length>1) fragment.append(')');
+		return fragment.toString();
+
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		Object icvalue = ignoreCase ? value.toString().toLowerCase() : value;
+		return new TypedValue[] { criteriaQuery.getTypedValue(criteria, propertyName, icvalue) };
+	}
+
+	public String toString() {
+		return propertyName + getOp() + value;
+	}
+
+	protected final String getOp() {
+		return op;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SimpleProjection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: SimpleProjection.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-
-
-/**
- * A single-column projection that may be aliased
- * @author Gavin King
- */
-public abstract class SimpleProjection implements Projection {
-
-	public Projection as(String alias) {
-		return Projections.alias(this, alias);
-	}
-
-	public String[] getColumnAliases(String alias, int loc) {
-		return null;
-	}
-	
-	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return null;
-	}
-
-	public String[] getColumnAliases(int loc) {
-		return new String[] { "y" + loc + "_" };
-	}
-	
-	public String[] getAliases() {
-		return new String[1];
-	}
-
-	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		throw new UnsupportedOperationException("not a grouping projection");
-	}
-
-	public boolean isGrouped() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SimpleProjection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleProjection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+
+
+/**
+ * A single-column projection that may be aliased
+ * @author Gavin King
+ */
+public abstract class SimpleProjection implements Projection {
+
+	public Projection as(String alias) {
+		return Projections.alias(this, alias);
+	}
+
+	public String[] getColumnAliases(String alias, int loc) {
+		return null;
+	}
+	
+	public Type[] getTypes(String alias, Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return null;
+	}
+
+	public String[] getColumnAliases(int loc) {
+		return new String[] { "y" + loc + "_" };
+	}
+	
+	public String[] getAliases() {
+		return new String[1];
+	}
+
+	public String toGroupSqlString(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		throw new UnsupportedOperationException("not a grouping projection");
+	}
+
+	public boolean isGrouped() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: SimpleSubqueryExpression.java 5757 2005-02-18 03:47:27Z oneovthafew $
-package org.hibernate.criterion;
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-
-/**
- * A comparison between a constant value and the the result of a subquery
- * @author Gavin King
- */
-public class SimpleSubqueryExpression extends SubqueryExpression {
-	
-	private Object value;
-	
-	protected SimpleSubqueryExpression(Object value, String op, String quantifier, DetachedCriteria dc) {
-		super(op, quantifier, dc);
-		this.value = value;
-	}
-	
-	
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		TypedValue[] superTv = super.getTypedValues(criteria, criteriaQuery);
-		TypedValue[] result = new TypedValue[superTv.length+1];
-		System.arraycopy(superTv, 0, result, 1, superTv.length);
-		result[0] = new TypedValue( getTypes()[0], value, EntityMode.POJO );
-		return result;
-	}
-	
-	protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
-		return "?";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SimpleSubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+
+/**
+ * A comparison between a constant value and the the result of a subquery
+ * @author Gavin King
+ */
+public class SimpleSubqueryExpression extends SubqueryExpression {
+	
+	private Object value;
+	
+	protected SimpleSubqueryExpression(Object value, String op, String quantifier, DetachedCriteria dc) {
+		super(op, quantifier, dc);
+		this.value = value;
+	}
+	
+	
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		TypedValue[] superTv = super.getTypedValues(criteria, criteriaQuery);
+		TypedValue[] result = new TypedValue[superTv.length+1];
+		System.arraycopy(superTv, 0, result, 1, superTv.length);
+		result[0] = new TypedValue( getTypes()[0], value, EntityMode.POJO );
+		return result;
+	}
+	
+	protected String toLeftSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
+		return "?";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SizeExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: SizeExpression.java 7844 2005-08-11 07:26:26Z oneovthafew $
-package org.hibernate.criterion;
-
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.sql.ConditionFragment;
-
-/**
- * @author Gavin King
- */
-public class SizeExpression implements Criterion {
-	
-	private final String propertyName;
-	private final int size;
-	private final String op;
-	
-	protected SizeExpression(String propertyName, int size, String op) {
-		this.propertyName = propertyName;
-		this.size = size;
-		this.op = op;
-	}
-
-	public String toString() {
-		return propertyName + ".size" + op + size;
-	}
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-		String role = criteriaQuery.getEntityName(criteria, propertyName) + 
-				'.' +  
-				criteriaQuery.getPropertyName(propertyName);
-		QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory()
-				.getCollectionPersister(role);
-		//String[] fk = StringHelper.qualify( "collection_", cp.getKeyColumnNames() );
-		String[] fk = cp.getKeyColumnNames();
-		String[] pk = ( (Loadable) cp.getOwnerEntityPersister() ).getIdentifierColumnNames(); //TODO: handle property-ref
-		return "? " + 
-				op + 
-				" (select count(*) from " +
-				cp.getTableName() +
-				//" collection_ where " +
-				" where " +
-				new ConditionFragment()
-						.setTableAlias( criteriaQuery.getSQLAlias(criteria, propertyName) )
-						.setCondition(pk, fk)
-						.toFragmentString() +
-				")";
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		return new TypedValue[] { 
-			new TypedValue( Hibernate.INTEGER, new Integer(size), EntityMode.POJO ) 
-		};
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SizeExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SizeExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.criterion;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.sql.ConditionFragment;
+
+/**
+ * @author Gavin King
+ */
+public class SizeExpression implements Criterion {
+	
+	private final String propertyName;
+	private final int size;
+	private final String op;
+	
+	protected SizeExpression(String propertyName, int size, String op) {
+		this.propertyName = propertyName;
+		this.size = size;
+		this.op = op;
+	}
+
+	public String toString() {
+		return propertyName + ".size" + op + size;
+	}
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+		String role = criteriaQuery.getEntityName(criteria, propertyName) + 
+				'.' +  
+				criteriaQuery.getPropertyName(propertyName);
+		QueryableCollection cp = (QueryableCollection) criteriaQuery.getFactory()
+				.getCollectionPersister(role);
+		//String[] fk = StringHelper.qualify( "collection_", cp.getKeyColumnNames() );
+		String[] fk = cp.getKeyColumnNames();
+		String[] pk = ( (Loadable) cp.getOwnerEntityPersister() ).getIdentifierColumnNames(); //TODO: handle property-ref
+		return "? " + 
+				op + 
+				" (select count(*) from " +
+				cp.getTableName() +
+				//" collection_ where " +
+				" where " +
+				new ConditionFragment()
+						.setTableAlias( criteriaQuery.getSQLAlias(criteria, propertyName) )
+						.setCondition(pk, fk)
+						.toFragmentString() +
+				")";
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		return new TypedValue[] { 
+			new TypedValue( Hibernate.INTEGER, new Integer(size), EntityMode.POJO ) 
+		};
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/Subqueries.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,160 +0,0 @@
-//$Id: Subqueries.java 8467 2005-10-26 21:20:17Z oneovthafew $
-package org.hibernate.criterion;
-
-/**
- * Factory class for criterion instances that represent expressions
- * involving subqueries.
- * 
- * @see Restriction
- * @see Projection
- * @see org.hibernate.Criteria
- * @author Gavin King
- */
-public class Subqueries {
-		
-	public static Criterion exists(DetachedCriteria dc) {
-		return new ExistsSubqueryExpression("exists", dc);
-	}
-	
-	public static Criterion notExists(DetachedCriteria dc) {
-		return new ExistsSubqueryExpression("not exists", dc);
-	}
-	
-	public static Criterion propertyEqAll(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "=", "all", dc);
-	}
-	
-	public static Criterion propertyIn(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "in", null, dc);
-	}
-	
-	public static Criterion propertyNotIn(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "not in", null, dc);
-	}
-	
-	public static Criterion propertyEq(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "=", null, dc);
-	}
-	
-	public static Criterion propertyNe(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<>", null, dc);
-	}
-	
-	public static Criterion propertyGt(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">", null, dc);
-	}
-	
-	public static Criterion propertyLt(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<", null, dc);
-	}
-	
-	public static Criterion propertyGe(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">=", null, dc);
-	}
-	
-	public static Criterion propertyLe(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<=", null, dc);
-	}
-	
-	public static Criterion propertyGtAll(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">", "all", dc);
-	}
-	
-	public static Criterion propertyLtAll(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<", "all", dc);
-	}
-	
-	public static Criterion propertyGeAll(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">=", "all", dc);
-	}
-	
-	public static Criterion propertyLeAll(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<=", "all", dc);
-	}
-	
-	public static Criterion propertyGtSome(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">", "some", dc);
-	}
-	
-	public static Criterion propertyLtSome(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<", "some", dc);
-	}
-	
-	public static Criterion propertyGeSome(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, ">=", "some", dc);
-	}
-	
-	public static Criterion propertyLeSome(String propertyName, DetachedCriteria dc) {
-		return new PropertySubqueryExpression(propertyName, "<=", "some", dc);
-	}
-	
-	public static Criterion eqAll(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "=", "all", dc);
-	}
-	
-	public static Criterion in(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "in", null, dc);
-	}
-	
-	public static Criterion notIn(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "not in", null, dc);
-	}
-	
-	public static Criterion eq(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "=", null, dc);
-	}
-	
-	public static Criterion gt(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">", null, dc);
-	}
-	
-	public static Criterion lt(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<", null, dc);
-	}
-	
-	public static Criterion ge(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">=", null, dc);
-	}
-	
-	public static Criterion le(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<=", null, dc);
-	}
-	
-	public static Criterion ne(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<>", null, dc);
-	}
-	
-	public static Criterion gtAll(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">", "all", dc);
-	}
-	
-	public static Criterion ltAll(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<", "all", dc);
-	}
-	
-	public static Criterion geAll(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">=", "all", dc);
-	}
-	
-	public static Criterion leAll(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<=", "all", dc);
-	}
-	
-	public static Criterion gtSome(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">", "some", dc);
-	}
-	
-	public static Criterion ltSome(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<", "some", dc);
-	}
-	
-	public static Criterion geSome(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, ">=", "some", dc);
-	}
-	
-	public static Criterion leSome(Object value, DetachedCriteria dc) {
-		return new SimpleSubqueryExpression(value, "<=", "some", dc);
-	}
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/Subqueries.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/Subqueries.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,183 @@
+/*
+ * 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.criterion;
+
+/**
+ * Factory class for criterion instances that represent expressions
+ * involving subqueries.
+ * 
+ * @see Restriction
+ * @see Projection
+ * @see org.hibernate.Criteria
+ * @author Gavin King
+ */
+public class Subqueries {
+		
+	public static Criterion exists(DetachedCriteria dc) {
+		return new ExistsSubqueryExpression("exists", dc);
+	}
+	
+	public static Criterion notExists(DetachedCriteria dc) {
+		return new ExistsSubqueryExpression("not exists", dc);
+	}
+	
+	public static Criterion propertyEqAll(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "=", "all", dc);
+	}
+	
+	public static Criterion propertyIn(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "in", null, dc);
+	}
+	
+	public static Criterion propertyNotIn(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "not in", null, dc);
+	}
+	
+	public static Criterion propertyEq(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "=", null, dc);
+	}
+	
+	public static Criterion propertyNe(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<>", null, dc);
+	}
+	
+	public static Criterion propertyGt(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">", null, dc);
+	}
+	
+	public static Criterion propertyLt(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<", null, dc);
+	}
+	
+	public static Criterion propertyGe(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">=", null, dc);
+	}
+	
+	public static Criterion propertyLe(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<=", null, dc);
+	}
+	
+	public static Criterion propertyGtAll(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">", "all", dc);
+	}
+	
+	public static Criterion propertyLtAll(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<", "all", dc);
+	}
+	
+	public static Criterion propertyGeAll(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">=", "all", dc);
+	}
+	
+	public static Criterion propertyLeAll(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<=", "all", dc);
+	}
+	
+	public static Criterion propertyGtSome(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">", "some", dc);
+	}
+	
+	public static Criterion propertyLtSome(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<", "some", dc);
+	}
+	
+	public static Criterion propertyGeSome(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, ">=", "some", dc);
+	}
+	
+	public static Criterion propertyLeSome(String propertyName, DetachedCriteria dc) {
+		return new PropertySubqueryExpression(propertyName, "<=", "some", dc);
+	}
+	
+	public static Criterion eqAll(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "=", "all", dc);
+	}
+	
+	public static Criterion in(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "in", null, dc);
+	}
+	
+	public static Criterion notIn(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "not in", null, dc);
+	}
+	
+	public static Criterion eq(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "=", null, dc);
+	}
+	
+	public static Criterion gt(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">", null, dc);
+	}
+	
+	public static Criterion lt(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<", null, dc);
+	}
+	
+	public static Criterion ge(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">=", null, dc);
+	}
+	
+	public static Criterion le(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<=", null, dc);
+	}
+	
+	public static Criterion ne(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<>", null, dc);
+	}
+	
+	public static Criterion gtAll(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">", "all", dc);
+	}
+	
+	public static Criterion ltAll(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<", "all", dc);
+	}
+	
+	public static Criterion geAll(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">=", "all", dc);
+	}
+	
+	public static Criterion leAll(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<=", "all", dc);
+	}
+	
+	public static Criterion gtSome(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">", "some", dc);
+	}
+	
+	public static Criterion ltSome(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<", "some", dc);
+	}
+	
+	public static Criterion geSome(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, ">=", "some", dc);
+	}
+	
+	public static Criterion leSome(Object value, DetachedCriteria dc) {
+		return new SimpleSubqueryExpression(value, "<=", "some", dc);
+	}
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,116 +0,0 @@
-//$Id: SubqueryExpression.java 7365 2005-07-04 02:40:29Z oneovthafew $
-package org.hibernate.criterion;
-
-import java.util.HashMap;
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.loader.criteria.CriteriaJoinWalker;
-import org.hibernate.loader.criteria.CriteriaQueryTranslator;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public abstract class SubqueryExpression implements Criterion {
-	
-	private CriteriaImpl criteriaImpl;
-	private String quantifier;
-	private String op;
-	private QueryParameters params;
-	private Type[] types;
-	private CriteriaQueryTranslator innerQuery;
-
-	protected Type[] getTypes() {
-		return types;
-	}
-	
-	protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) {
-		this.criteriaImpl = dc.getCriteriaImpl();
-		this.quantifier = quantifier;
-		this.op = op;
-	}
-	
-	protected abstract String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery);
-
-	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
-	throws HibernateException {
-
-		final SessionFactoryImplementor factory = criteriaQuery.getFactory();
-		final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
-
-		createAndSetInnerQuery( criteriaQuery, factory );
-		
-		CriteriaJoinWalker walker = new CriteriaJoinWalker(
-				persister,
-				innerQuery,
-				factory,
-				criteriaImpl,
-				criteriaImpl.getEntityOrClassName(),
-				new HashMap(),
-				innerQuery.getRootSQLALias());
-
-		String sql = walker.getSQLString();
-
-		final StringBuffer buf = new StringBuffer()
-			.append( toLeftSqlString(criteria, criteriaQuery) );
-		if (op!=null) buf.append(' ').append(op).append(' ');
-		if (quantifier!=null) buf.append(quantifier).append(' ');
-		return buf.append('(').append(sql).append(')')
-			.toString();
-	}
-
-	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
-	throws HibernateException {
-		//the following two lines were added to ensure that this.params is not null, which
-		//can happen with two-deep nested subqueries
-		SessionFactoryImplementor factory = criteriaQuery.getFactory();
-		createAndSetInnerQuery(criteriaQuery, factory);
-		
-		Type[] ppTypes = params.getPositionalParameterTypes();
-		Object[] ppValues = params.getPositionalParameterValues();
-		TypedValue[] tv = new TypedValue[ppTypes.length];
-		for ( int i=0; i<ppTypes.length; i++ ) {
-			tv[i] = new TypedValue( ppTypes[i], ppValues[i], EntityMode.POJO );
-		}
-		return tv;
-	}
-
-	/**
-	 * Creates the inner query used to extract some useful information about
-	 * types, since it is needed in both methods.
-	 * @param criteriaQuery
-	 * @param factory
-	 */
-	private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, final SessionFactoryImplementor factory) {
-		if ( innerQuery == null ) {
-			//with two-deep subqueries, the same alias would get generated for
-			//both using the old method (criteriaQuery.generateSQLAlias()), so
-			//that is now used as a fallback if the main criteria alias isn't set
-			String alias;
-			if ( this.criteriaImpl.getAlias() == null ) {
-				alias = criteriaQuery.generateSQLAlias();
-			}
-			else {
-				alias = this.criteriaImpl.getAlias() + "_";
-			}
-
-			innerQuery = new CriteriaQueryTranslator(
-					factory,
-					criteriaImpl,
-					criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union)
-					alias,
-					criteriaQuery
-				);
-
-			params = innerQuery.getQueryParameters();
-			types = innerQuery.getProjectedTypes();
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/SubqueryExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,139 @@
+/*
+ * 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.criterion;
+
+import java.util.HashMap;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.loader.criteria.CriteriaJoinWalker;
+import org.hibernate.loader.criteria.CriteriaQueryTranslator;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public abstract class SubqueryExpression implements Criterion {
+	
+	private CriteriaImpl criteriaImpl;
+	private String quantifier;
+	private String op;
+	private QueryParameters params;
+	private Type[] types;
+	private CriteriaQueryTranslator innerQuery;
+
+	protected Type[] getTypes() {
+		return types;
+	}
+	
+	protected SubqueryExpression(String op, String quantifier, DetachedCriteria dc) {
+		this.criteriaImpl = dc.getCriteriaImpl();
+		this.quantifier = quantifier;
+		this.op = op;
+	}
+	
+	protected abstract String toLeftSqlString(Criteria criteria, CriteriaQuery outerQuery);
+
+	public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery)
+	throws HibernateException {
+
+		final SessionFactoryImplementor factory = criteriaQuery.getFactory();
+		final OuterJoinLoadable persister = (OuterJoinLoadable) factory.getEntityPersister( criteriaImpl.getEntityOrClassName() );
+
+		createAndSetInnerQuery( criteriaQuery, factory );
+		
+		CriteriaJoinWalker walker = new CriteriaJoinWalker(
+				persister,
+				innerQuery,
+				factory,
+				criteriaImpl,
+				criteriaImpl.getEntityOrClassName(),
+				new HashMap(),
+				innerQuery.getRootSQLALias());
+
+		String sql = walker.getSQLString();
+
+		final StringBuffer buf = new StringBuffer()
+			.append( toLeftSqlString(criteria, criteriaQuery) );
+		if (op!=null) buf.append(' ').append(op).append(' ');
+		if (quantifier!=null) buf.append(quantifier).append(' ');
+		return buf.append('(').append(sql).append(')')
+			.toString();
+	}
+
+	public TypedValue[] getTypedValues(Criteria criteria, CriteriaQuery criteriaQuery) 
+	throws HibernateException {
+		//the following two lines were added to ensure that this.params is not null, which
+		//can happen with two-deep nested subqueries
+		SessionFactoryImplementor factory = criteriaQuery.getFactory();
+		createAndSetInnerQuery(criteriaQuery, factory);
+		
+		Type[] ppTypes = params.getPositionalParameterTypes();
+		Object[] ppValues = params.getPositionalParameterValues();
+		TypedValue[] tv = new TypedValue[ppTypes.length];
+		for ( int i=0; i<ppTypes.length; i++ ) {
+			tv[i] = new TypedValue( ppTypes[i], ppValues[i], EntityMode.POJO );
+		}
+		return tv;
+	}
+
+	/**
+	 * Creates the inner query used to extract some useful information about
+	 * types, since it is needed in both methods.
+	 * @param criteriaQuery
+	 * @param factory
+	 */
+	private void createAndSetInnerQuery(CriteriaQuery criteriaQuery, final SessionFactoryImplementor factory) {
+		if ( innerQuery == null ) {
+			//with two-deep subqueries, the same alias would get generated for
+			//both using the old method (criteriaQuery.generateSQLAlias()), so
+			//that is now used as a fallback if the main criteria alias isn't set
+			String alias;
+			if ( this.criteriaImpl.getAlias() == null ) {
+				alias = criteriaQuery.generateSQLAlias();
+			}
+			else {
+				alias = this.criteriaImpl.getAlias() + "_";
+			}
+
+			innerQuery = new CriteriaQueryTranslator(
+					factory,
+					criteriaImpl,
+					criteriaImpl.getEntityOrClassName(), //implicit polymorphism not supported (would need a union)
+					alias,
+					criteriaQuery
+				);
+
+			params = innerQuery.getQueryParameters();
+			types = innerQuery.getProjectedTypes();
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/criterion/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	A framework for defining restriction criteria and order criteria.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/criterion/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/criterion/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	A framework for defining restriction criteria and order criteria.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,655 +0,0 @@
-//$Id:  $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.NvlFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.function.StandardJDBCEscapeFunction;
-import org.hibernate.dialect.function.ConvertFunction;
-import org.hibernate.dialect.function.ConditionalParenthesisFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.exception.CacheSQLStateConverter;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.id.IdentityGenerator;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.sql.CacheJoinFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.util.StringHelper;
-
-/**
- * Cach&eacute; 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Caché SQL.<br>
- * <br>
- * Compatible with Caché 2007.1.
- * <br>
- * <head>
- * <title>Cach&eacute; and Hibernate</title>
- * </head>
- * <body>
- * <h1>Cach&eacute; and Hibernate</h1>
- * <h2>PREREQUISITES</h2>
- * These setup instructions assume that both Cach&eacute; and Hibernate are installed and operational.
- * <br>
- * <h2>HIBERNATE DIRECTORIES AND FILES</h2>
- * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.1
- * For earlier versions of Hibernate please contact
- * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
- * for the appropriate source files.
- * <br>
- * <h2>CACH&Eacute; DOCUMENTATION</h2>
- * Documentation for Cach&eacute; is available online when Cach&eacute; is running.
- * It can also be obtained from the
- * <a href="http://www.intersystems.com/cache/downloads/documentation.html">InterSystems</A> website.
- * The book, "Object-oriented Application Development Using the Cach&eacute; Post-relational Database:
- * is also available from Springer-Verlag.
- * <br>
- * <h2>HIBERNATE DOCUMENTATION</h2>
- * Hibernate comes with extensive electronic documentation.
- * In addition, several books on Hibernate are available from
- * <a href="http://www.manning.com">Manning Publications Co</a>.
- * Three available titles are "Hibernate Quickly", "Hibernate in Action", and "Java Persistence with Hibernate".
- * <br>
- * <h2>TO SET UP HIBERNATE FOR USE WITH CACH&Eacute;</h2>
- * The following steps assume that the directory where Cach&eacute; was installed is C:\CacheSys.
- * This is the default installation directory for  Cach&eacute;.
- * The default installation directory for Hibernate is assumed to be C:\Hibernate.
- * <p/>
- * If either product is installed in a different location, the pathnames that follow should be modified appropriately.
- * <p/>
- * Cach&eacute; version 2007.1 and above is recommended for use with
- * Hibernate.  The next step depends on the location of your
- * CacheDB.jar depending on your version of Cach&eacute;.
- * <ol>
- * <li>Copy C:\CacheSys\dev\java\lib\JDK15\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
- * <p/>
- * <li>Insert the following files into your Java classpath:
- * <p/>
- * <ul>
- * <li>All jar files in the directory C:\Hibernate\lib</li>
- * <li>The directory (or directories) where hibernate.properties and/or hibernate.cfg.xml are kept.</li>
- * </ul>
- * </li>
- * <p/>
- * <li>In the file, hibernate.properties (or hibernate.cfg.xml),
- * specify the Cach&eacute; dialect and the Cach&eacute; version URL settings.</li>
- * </ol>
- * <p/>
- * For example, in Hibernate 3.2, typical entries in hibernate.properties would have the following
- * "name=value" pairs:
- * <p/>
- * <table cols=3 border cellpadding=5 cellspacing=0>
- * <tr>
- * <th>Property Name</th>
- * <th>Property Value</th>
- * </tr>
- * <tr>
- * <td>hibernate.dialect</td>
- * <td>org.hibernate.dialect.Cache71Dialect</td>
- * </tr>
- * <tr>
- * <td>hibernate.connection.driver_class</td>
- * <td>com.intersys.jdbc.CacheDriver</td>
- * </tr>
- * <tr>
- * <td>hibernate.connection.username</td>
- * <td>(see note 1)</td>
- * </tr>
- * <tr>
- * <td>hibernate.connection.password</td>
- * <td>(see note 1)</td>
- * </tr>
- * <tr>
- * <td>hibernate.connection.url</td>
- * <td>jdbc:Cache://127.0.0.1:1972/USER</td>
- * </tr>
- * </table>
- * <p/>
- * <dl>
- * <dt><b>Note 1</b></dt>
- * <dd>Please contact your administrator for the userid and password you should use when attempting access via JDBC.
- * By default, these are chosen to be "_SYSTEM" and "SYS" respectively as noted in the SQL standard.</dd>
- * </dl>
- * <br>
- * <h2>CACH&Eacute; VERSION URL</h2>
- * This is the standard URL for the JDBC driver.
- * For a JDBC driver on the machine hosting Cach&eacute;, use the IP "loopback" address, 127.0.0.1.
- * For 1972, the default port, specify the super server port of your Cach&eacute; instance.
- * For USER, substitute the NAMESPACE which contains your Cach&eacute; database data.
- * <br>
- * <h2>CACH&Eacute; DIALECTS</h2>
- * Choices for Dialect are:
- * <br>
- * <p/>
- * <ol>
- * <li>org.hibernate.dialect.Cache71Dialect (requires Cach&eacute;
- * 2007.1 or above)</li>
- * <p/>
- * </ol>
- * <br>
- * <h2>SUPPORT FOR IDENTITY COLUMNS</h2>
- * Cach&eacute; 2007.1 or later supports identity columns.  For
- * Hibernate to use identity columns, specify "native" as the
- * generator.
- * <br>
- * <h2>SEQUENCE DIALECTS SUPPORT SEQUENCES</h2>
- * <p/>
- * To use Hibernate sequence support with Cach&eacute; in a namespace, you must FIRST load the following file into that namespace:
- * <pre>
- *     etc\CacheSequences.xml
- * </pre>
- * For example, at the COS terminal prompt in the namespace, run the
- * following command:
- * <p>
- * d LoadFile^%apiOBJ("c:\hibernate\etc\CacheSequences.xml","ck")
- * <p>
- * In your Hibernate mapping you can specify sequence use.
- * <p>
- * For example, the following shows the use of a sequence generator in a Hibernate mapping:
- * <pre>
- *     &lt;id name="id" column="uid" type="long" unsaved-value="null"&gt;
- *         &lt;generator class="sequence"/&gt;
- *     &lt;/id&gt;
- * </pre>
- * <br>
- * <p/>
- * Some versions of Hibernate under some circumstances call
- * getSelectSequenceNextValString() in the dialect.  If this happens
- * you will receive the error message: new MappingException( "Dialect
- * does not support sequences" ).
- * <br>
- * <h2>HIBERNATE FILES ASSOCIATED WITH CACH&Eacute; DIALECT</h2>
- * The following files are associated with Cach&eacute; dialect:
- * <p/>
- * <ol>
- * <li>src\org\hibernate\dialect\Cache71Dialect.java</li>
- * <li>src\org\hibernate\dialect\function\ConditionalParenthesisFunction.java</li>
- * <li>src\org\hibernate\dialect\function\ConvertFunction.java</li>
- * <li>src\org\hibernate\exception\CacheSQLStateConverter.java</li>
- * <li>src\org\hibernate\sql\CacheJoinFragment.java</li>
- * </ol>
- * Cache71Dialect ships with Hibernate 3.2.  All other dialects are distributed by InterSystems and subclass Cache71Dialect.
- *
- * @author Jonathan Levinson
- */
-
-public class Cache71Dialect extends Dialect {
-
-	/**
-	 * Creates new <code>Caché71Dialect</code> instance. Sets up the JDBC /
-	 * Caché type mappings.
-	 */
-	public Cache71Dialect() {
-		super();
-		commonRegistration();
-		register71Functions();
-	}
-
-	protected final void commonRegistration() {
-		// Note: For object <-> SQL datatype mappings see:
-		//	 Configuration Manager | Advanced | SQL | System DDL Datatype Mappings
-		//
-		//	TBD	registerColumnType(Types.BINARY,        "binary($1)");
-		// changed 08-11-2005, jsl
-		registerColumnType( Types.BINARY, "varbinary($1)" );
-		registerColumnType( Types.BIGINT, "BigInt" );
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.DECIMAL, "decimal" );
-		registerColumnType( Types.DOUBLE, "double" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.LONGVARBINARY, "longvarbinary" );	// binary %Stream
-		registerColumnType( Types.LONGVARCHAR, "longvarchar" );		// character %Stream
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-		registerColumnType( Types.REAL, "real" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		// TBD should this be varbinary($1)?
-		//		registerColumnType(Types.VARBINARY,     "binary($1)");
-		registerColumnType( Types.VARBINARY, "longvarbinary" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.BLOB, "longvarbinary" );
-		registerColumnType( Types.CLOB, "longvarchar" );
-
-		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" );
-		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-		//getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-
-		getDefaultProperties().setProperty( Environment.USE_SQL_COMMENTS, "false" );
-
-		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
-		registerFunction( "acos", new StandardJDBCEscapeFunction( "acos", Hibernate.DOUBLE ) );
-		registerFunction( "%alphaup", new StandardSQLFunction( "%alphaup", Hibernate.STRING ) );
-		registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.STRING ) );
-		registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", Hibernate.DOUBLE ) );
-		registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", Hibernate.DOUBLE ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "($length(?1)*8)" ) );
-		// hibernate impelemnts cast in Dialect.java
-		registerFunction( "ceiling", new StandardSQLFunction( "ceiling", Hibernate.INTEGER ) );
-		registerFunction( "char", new StandardJDBCEscapeFunction( "char", Hibernate.CHARACTER ) );
-		registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.INTEGER ) );
-		registerFunction( "char_length", new StandardSQLFunction( "char_length", Hibernate.INTEGER ) );
-		registerFunction( "cos", new StandardJDBCEscapeFunction( "cos", Hibernate.DOUBLE ) );
-		registerFunction( "cot", new StandardJDBCEscapeFunction( "cot", Hibernate.DOUBLE ) );
-		registerFunction( "coalesce", new VarArgsSQLFunction( "coalesce(", ",", ")" ) );
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "", "||", "" ) );
-		registerFunction( "convert", new ConvertFunction() );
-		registerFunction( "curdate", new StandardJDBCEscapeFunction( "curdate", Hibernate.DATE ) );
-		registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
-		registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
-		registerFunction(
-				"current_timestamp", new ConditionalParenthesisFunction( "current_timestamp", Hibernate.TIMESTAMP )
-		);
-		registerFunction( "curtime", new StandardJDBCEscapeFunction( "curtime", Hibernate.TIME ) );
-		registerFunction( "database", new StandardJDBCEscapeFunction( "database", Hibernate.STRING ) );
-		registerFunction( "dateadd", new VarArgsSQLFunction( Hibernate.TIMESTAMP, "dateadd(", ",", ")" ) );
-		registerFunction( "datediff", new VarArgsSQLFunction( Hibernate.INTEGER, "datediff(", ",", ")" ) );
-		registerFunction( "datename", new VarArgsSQLFunction( Hibernate.STRING, "datename(", ",", ")" ) );
-		registerFunction( "datepart", new VarArgsSQLFunction( Hibernate.INTEGER, "datepart(", ",", ")" ) );
-		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
-		registerFunction( "dayname", new StandardJDBCEscapeFunction( "dayname", Hibernate.STRING ) );
-		registerFunction( "dayofmonth", new StandardJDBCEscapeFunction( "dayofmonth", Hibernate.INTEGER ) );
-		registerFunction( "dayofweek", new StandardJDBCEscapeFunction( "dayofweek", Hibernate.INTEGER ) );
-		registerFunction( "dayofyear", new StandardJDBCEscapeFunction( "dayofyear", Hibernate.INTEGER ) );
-		// is it necessary to register %exact since it can only appear in a where clause?
-		registerFunction( "%exact", new StandardSQLFunction( "%exact", Hibernate.STRING ) );
-		registerFunction( "exp", new StandardJDBCEscapeFunction( "exp", Hibernate.DOUBLE ) );
-		registerFunction( "%external", new StandardSQLFunction( "%external", Hibernate.STRING ) );
-		registerFunction( "$extract", new VarArgsSQLFunction( Hibernate.INTEGER, "$extract(", ",", ")" ) );
-		registerFunction( "$find", new VarArgsSQLFunction( Hibernate.INTEGER, "$find(", ",", ")" ) );
-		registerFunction( "floor", new StandardSQLFunction( "floor", Hibernate.INTEGER ) );
-		registerFunction( "getdate", new StandardSQLFunction( "getdate", Hibernate.TIMESTAMP ) );
-		registerFunction( "hour", new StandardJDBCEscapeFunction( "hour", Hibernate.INTEGER ) );
-		registerFunction( "ifnull", new VarArgsSQLFunction( "ifnull(", ",", ")" ) );
-		registerFunction( "%internal", new StandardSQLFunction( "%internal" ) );
-		registerFunction( "isnull", new VarArgsSQLFunction( "isnull(", ",", ")" ) );
-		registerFunction( "isnumeric", new StandardSQLFunction( "isnumeric", Hibernate.INTEGER ) );
-		registerFunction( "lcase", new StandardJDBCEscapeFunction( "lcase", Hibernate.STRING ) );
-		registerFunction( "left", new StandardJDBCEscapeFunction( "left", Hibernate.STRING ) );
-		registerFunction( "len", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
-		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
-		registerFunction( "$length", new VarArgsSQLFunction( "$length(", ",", ")" ) );
-		// aggregate functions shouldn't be registered, right?
-		//registerFunction( "list", new StandardSQLFunction("list",Hibernate.STRING) );
-		// stopped on $list
-		registerFunction( "$list", new VarArgsSQLFunction( "$list(", ",", ")" ) );
-		registerFunction( "$listdata", new VarArgsSQLFunction( "$listdata(", ",", ")" ) );
-		registerFunction( "$listfind", new VarArgsSQLFunction( "$listfind(", ",", ")" ) );
-		registerFunction( "$listget", new VarArgsSQLFunction( "$listget(", ",", ")" ) );
-		registerFunction( "$listlength", new StandardSQLFunction( "$listlength", Hibernate.INTEGER ) );
-		registerFunction( "locate", new StandardSQLFunction( "$FIND", Hibernate.INTEGER ) );
-		registerFunction( "log", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) );
-		registerFunction( "log10", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) );
-		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
-		registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
-		registerFunction( "minute", new StandardJDBCEscapeFunction( "minute", Hibernate.INTEGER ) );
-		registerFunction( "mod", new StandardJDBCEscapeFunction( "mod", Hibernate.DOUBLE ) );
-		registerFunction( "month", new StandardJDBCEscapeFunction( "month", Hibernate.INTEGER ) );
-		registerFunction( "monthname", new StandardJDBCEscapeFunction( "monthname", Hibernate.STRING ) );
-		registerFunction( "now", new StandardJDBCEscapeFunction( "monthname", Hibernate.TIMESTAMP ) );
-		registerFunction( "nullif", new VarArgsSQLFunction( "nullif(", ",", ")" ) );
-		registerFunction( "nvl", new NvlFunction() );
-		registerFunction( "%odbcin", new StandardSQLFunction( "%odbcin" ) );
-		registerFunction( "%odbcout", new StandardSQLFunction( "%odbcin" ) );
-		registerFunction( "%pattern", new VarArgsSQLFunction( Hibernate.STRING, "", "%pattern", "" ) );
-		registerFunction( "pi", new StandardJDBCEscapeFunction( "pi", Hibernate.DOUBLE ) );
-		registerFunction( "$piece", new VarArgsSQLFunction( Hibernate.STRING, "$piece(", ",", ")" ) );
-		registerFunction( "position", new VarArgsSQLFunction( Hibernate.INTEGER, "position(", " in ", ")" ) );
-		registerFunction( "power", new VarArgsSQLFunction( Hibernate.STRING, "power(", ",", ")" ) );
-		registerFunction( "quarter", new StandardJDBCEscapeFunction( "quarter", Hibernate.INTEGER ) );
-		registerFunction( "repeat", new VarArgsSQLFunction( Hibernate.STRING, "repeat(", ",", ")" ) );
-		registerFunction( "replicate", new VarArgsSQLFunction( Hibernate.STRING, "replicate(", ",", ")" ) );
-		registerFunction( "right", new StandardJDBCEscapeFunction( "right", Hibernate.STRING ) );
-		registerFunction( "round", new VarArgsSQLFunction( Hibernate.FLOAT, "round(", ",", ")" ) );
-		registerFunction( "rtrim", new StandardSQLFunction( "rtrim", Hibernate.STRING ) );
-		registerFunction( "second", new StandardJDBCEscapeFunction( "second", Hibernate.INTEGER ) );
-		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
-		registerFunction( "sin", new StandardJDBCEscapeFunction( "sin", Hibernate.DOUBLE ) );
-		registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
-		registerFunction( "%sqlstring", new VarArgsSQLFunction( Hibernate.STRING, "%sqlstring(", ",", ")" ) );
-		registerFunction( "%sqlupper", new VarArgsSQLFunction( Hibernate.STRING, "%sqlupper(", ",", ")" ) );
-		registerFunction( "sqrt", new StandardJDBCEscapeFunction( "SQRT", Hibernate.DOUBLE ) );
-		registerFunction( "%startswith", new VarArgsSQLFunction( Hibernate.STRING, "", "%startswith", "" ) );
-		// below is for Cache' that don't have str in 2007.1 there is str and we register str directly
-		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as char varying)" ) );
-		registerFunction( "string", new VarArgsSQLFunction( Hibernate.STRING, "string(", ",", ")" ) );
-		// note that %string is deprecated
-		registerFunction( "%string", new VarArgsSQLFunction( Hibernate.STRING, "%string(", ",", ")" ) );
-		registerFunction( "substr", new VarArgsSQLFunction( Hibernate.STRING, "substr(", ",", ")" ) );
-		registerFunction( "substring", new VarArgsSQLFunction( Hibernate.STRING, "substring(", ",", ")" ) );
-		registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", Hibernate.TIMESTAMP, false ) );
-		registerFunction( "tan", new StandardJDBCEscapeFunction( "tan", Hibernate.DOUBLE ) );
-		registerFunction( "timestampadd", new StandardJDBCEscapeFunction( "timestampadd", Hibernate.DOUBLE ) );
-		registerFunction( "timestampdiff", new StandardJDBCEscapeFunction( "timestampdiff", Hibernate.DOUBLE ) );
-		registerFunction( "tochar", new VarArgsSQLFunction( Hibernate.STRING, "tochar(", ",", ")" ) );
-		registerFunction( "to_char", new VarArgsSQLFunction( Hibernate.STRING, "to_char(", ",", ")" ) );
-		registerFunction( "todate", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) );
-		registerFunction( "to_date", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) );
-		registerFunction( "tonumber", new StandardSQLFunction( "tonumber" ) );
-		registerFunction( "to_number", new StandardSQLFunction( "tonumber" ) );
-		// TRIM(end_keyword string-expression-1 FROM string-expression-2)
-		// use Hibernate implementation "From" is one of the parameters they pass in position ?3
-		//registerFunction( "trim", new SQLFunctionTemplate(Hibernate.STRING, "trim(?1 ?2 from ?3)") );
-		registerFunction( "truncate", new StandardJDBCEscapeFunction( "truncate", Hibernate.STRING ) );
-		registerFunction( "ucase", new StandardJDBCEscapeFunction( "ucase", Hibernate.STRING ) );
-		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
-		// %upper is deprecated
-		registerFunction( "%upper", new StandardSQLFunction( "%upper" ) );
-		registerFunction( "user", new StandardJDBCEscapeFunction( "user", Hibernate.STRING ) );
-		registerFunction( "week", new StandardJDBCEscapeFunction( "user", Hibernate.INTEGER ) );
-		registerFunction( "xmlconcat", new VarArgsSQLFunction( Hibernate.STRING, "xmlconcat(", ",", ")" ) );
-		registerFunction( "xmlelement", new VarArgsSQLFunction( Hibernate.STRING, "xmlelement(", ",", ")" ) );
-		// xmlforest requires a new kind of function constructor
-		registerFunction( "year", new StandardJDBCEscapeFunction( "year", Hibernate.INTEGER ) );
-	}
-
-	protected final void register71Functions() {
-		this.registerFunction( "str", new VarArgsSQLFunction( Hibernate.STRING, "str(", ",", ")" ) );
-	}
-
-	// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean hasAlterTable() {
-		// Does this dialect support the ALTER TABLE syntax?
-		return true;
-	}
-
-	public boolean qualifyIndexName() {
-		// Do we need to qualify index names with the schema name?
-		return false;
-	}
-
-	public boolean supportsUnique() {
-		// Does this dialect support the UNIQUE column syntax?
-		return true;
-	}
-
-	/**
-	 * The syntax used to add a foreign key constraint to a table.
-	 *
-	 * @return String
-	 */
-	public String getAddForeignKeyConstraintString(
-			String constraintName,
-			String[] foreignKey,
-			String referencedTable,
-			String[] primaryKey,
-			boolean referencesPrimaryKey) {
-		// The syntax used to add a foreign key constraint to a table.
-		return new StringBuffer( 300 )
-				.append( " ADD CONSTRAINT " )
-				.append( constraintName )
-				.append( " FOREIGN KEY " )
-				.append( constraintName )
-				.append( " (" )
-				.append( StringHelper.join( ", ", foreignKey ) )	// identifier-commalist
-				.append( ") REFERENCES " )
-				.append( referencedTable )
-				.append( " (" )
-				.append( StringHelper.join( ", ", primaryKey ) ) // identifier-commalist
-				.append( ") " )
-				.toString();
-	}
-
-	public boolean supportsCheck() {
-		// Does this dialect support check constraints?
-		return false;
-	}
-
-	public String getAddColumnString() {
-		// The syntax used to add a column to a table
-		return " add column";
-	}
-
-	public String getCascadeConstraintsString() {
-		// Completely optional cascading drop clause.
-		return "";
-	}
-
-	public boolean dropConstraints() {
-		// Do we need to drop constraints before dropping tables in this dialect?
-		return true;
-	}
-
-	public boolean supportsCascadeDelete() {
-		return true;
-	}
-
-	public boolean hasSelfReferentialForeignKeyBug() {
-		return true;
-	}
-
-	// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		String name = super.generateTemporaryTableName( baseTableName );
-		return name.length() > 25 ? name.substring( 1, 25 ) : name;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create global temporary table";
-	}
-
-	public Boolean performTemporaryTableDDLInIsolation() {
-		return Boolean.FALSE;
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "";
-	}
-
-	public boolean dropTemporaryTableAfterUse() {
-		return true;
-	}
-
-	// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-
-	public Class getNativeIdentifierGeneratorClass() {
-		return IdentityGenerator.class;
-	}
-
-	public boolean hasDataTypeInIdentityColumn() {
-		// Whether this dialect has an Identity clause added to the data type or a completely seperate identity
-		// data type
-		return true;
-	}
-
-	public String getIdentityColumnString() throws MappingException {
-		// The keyword used to specify an identity column, if identity column key generation is supported.
-		return "identity";
-	}
-
-	public String getIdentitySelectString() {
-		return "SELECT LAST_IDENTITY() FROM %TSQL_sys.snf";
-	}
-
-	// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsSequences() {
-		return false;
-	}
-
-// It really does support sequences, but InterSystems elects to suggest usage of IDENTITY instead :/
-// Anyway, below are the actual support overrides for users wanting to use this combo...
-//
-//	public String getSequenceNextValString(String sequenceName) {
-//		return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
-//	}
-//
-//	public String getSelectSequenceNextValString(String sequenceName) {
-//		return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
-//	}
-//
-//	public String getCreateSequenceString(String sequenceName) {
-//		return "insert into InterSystems.Sequences(Name) values (ucase('" + sequenceName + "'))";
-//	}
-//
-//	public String getDropSequenceString(String sequenceName) {
-//		return "delete from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
-//	}
-//
-//	public String getQuerySequencesString() {
-//		return "select name from InterSystems.Sequences";
-//	}
-
-	// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsForUpdate() {
-		// Does this dialect support the FOR UPDATE syntax?
-		return false;
-	}
-
-	public boolean supportsForUpdateOf() {
-		// Does this dialect support FOR UPDATE OF, allowing particular rows to be locked?
-		return false;
-	}
-
-	public boolean supportsForUpdateNowait() {
-		// Does this dialect support the Oracle-style FOR UPDATE NOWAIT syntax?
-		return false;
-	}
-
-	public boolean supportsOuterJoinForUpdate() {
-		return false;
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// InterSystems Cache' does not current support "SELECT ... FOR UPDATE" syntax...
-		// Set your transaction mode to READ_COMMITTED before using
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-
-	// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public boolean supportsVariableLimit() {
-		return true;
-	}
-
-	public boolean bindLimitParametersFirst() {
-		// Does the LIMIT clause come at the start of the SELECT statement, rather than at the end?
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		// Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows?
-		return true;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		if ( hasOffset ) {
-			throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
-		}
-
-		// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
-		// but this extension is not supported through Hibernate anyway.
-		int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6;
-
-		return new StringBuffer( sql.length() + 8 )
-				.append( sql )
-				.insert( insertionPoint, " TOP ? " )
-				.toString();
-	}
-
-	// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		return col;
-	}
-
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		ps.execute();
-		return ( ResultSet ) ps.getObject( 1 );
-	}
-
-	// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public String getLowercaseFunction() {
-		// The name of the SQL function that transforms a string to lowercase
-		return "lower";
-	}
-
-	public String getNullColumnString() {
-		// The keyword used to specify a nullable column.
-		return " null";
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		// Create an OuterJoinGenerator for this dialect.
-		return new CacheJoinFragment();
-	}
-
-	public String getNoColumnsInsertString() {
-		// The keyword used to insert a row without specifying
-		// any column values
-		return " default values";
-	}
-
-	public SQLExceptionConverter buildSQLExceptionConverter() {
-		return new CacheSQLStateConverter( EXTRACTER );
-	}
-
-	public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-		/**
-		 * Extract the name of the violated constraint from the given SQLException.
-		 *
-		 * @param sqle The exception that was the result of the constraint violation.
-		 * @return The extracted constraint name.
-		 */
-		public String extractConstraintName(SQLException sqle) {
-			return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
-		}
-	};
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean areStringComparisonsCaseInsensitive() {
-		return true;
-	}
-
-	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Cache71Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,678 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.NvlFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.function.StandardJDBCEscapeFunction;
+import org.hibernate.dialect.function.ConvertFunction;
+import org.hibernate.dialect.function.ConditionalParenthesisFunction;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.exception.CacheSQLStateConverter;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.id.IdentityGenerator;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.sql.CacheJoinFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Cach&eacute; 2007.1 dialect. This class is required in order to use Hibernate with Intersystems Cach� SQL.<br>
+ * <br>
+ * Compatible with Cach� 2007.1.
+ * <br>
+ * <head>
+ * <title>Cach&eacute; and Hibernate</title>
+ * </head>
+ * <body>
+ * <h1>Cach&eacute; and Hibernate</h1>
+ * <h2>PREREQUISITES</h2>
+ * These setup instructions assume that both Cach&eacute; and Hibernate are installed and operational.
+ * <br>
+ * <h2>HIBERNATE DIRECTORIES AND FILES</h2>
+ * JBoss distributes the InterSystems Cache' dialect for Hibernate 3.2.1
+ * For earlier versions of Hibernate please contact
+ * <a href="http://www.intersystems.com/support/cache-support.html">InterSystems Worldwide Response Center</A> (WRC)
+ * for the appropriate source files.
+ * <br>
+ * <h2>CACH&Eacute; DOCUMENTATION</h2>
+ * Documentation for Cach&eacute; is available online when Cach&eacute; is running.
+ * It can also be obtained from the
+ * <a href="http://www.intersystems.com/cache/downloads/documentation.html">InterSystems</A> website.
+ * The book, "Object-oriented Application Development Using the Cach&eacute; Post-relational Database:
+ * is also available from Springer-Verlag.
+ * <br>
+ * <h2>HIBERNATE DOCUMENTATION</h2>
+ * Hibernate comes with extensive electronic documentation.
+ * In addition, several books on Hibernate are available from
+ * <a href="http://www.manning.com">Manning Publications Co</a>.
+ * Three available titles are "Hibernate Quickly", "Hibernate in Action", and "Java Persistence with Hibernate".
+ * <br>
+ * <h2>TO SET UP HIBERNATE FOR USE WITH CACH&Eacute;</h2>
+ * The following steps assume that the directory where Cach&eacute; was installed is C:\CacheSys.
+ * This is the default installation directory for  Cach&eacute;.
+ * The default installation directory for Hibernate is assumed to be C:\Hibernate.
+ * <p/>
+ * If either product is installed in a different location, the pathnames that follow should be modified appropriately.
+ * <p/>
+ * Cach&eacute; version 2007.1 and above is recommended for use with
+ * Hibernate.  The next step depends on the location of your
+ * CacheDB.jar depending on your version of Cach&eacute;.
+ * <ol>
+ * <li>Copy C:\CacheSys\dev\java\lib\JDK15\CacheDB.jar to C:\Hibernate\lib\CacheDB.jar.</li>
+ * <p/>
+ * <li>Insert the following files into your Java classpath:
+ * <p/>
+ * <ul>
+ * <li>All jar files in the directory C:\Hibernate\lib</li>
+ * <li>The directory (or directories) where hibernate.properties and/or hibernate.cfg.xml are kept.</li>
+ * </ul>
+ * </li>
+ * <p/>
+ * <li>In the file, hibernate.properties (or hibernate.cfg.xml),
+ * specify the Cach&eacute; dialect and the Cach&eacute; version URL settings.</li>
+ * </ol>
+ * <p/>
+ * For example, in Hibernate 3.2, typical entries in hibernate.properties would have the following
+ * "name=value" pairs:
+ * <p/>
+ * <table cols=3 border cellpadding=5 cellspacing=0>
+ * <tr>
+ * <th>Property Name</th>
+ * <th>Property Value</th>
+ * </tr>
+ * <tr>
+ * <td>hibernate.dialect</td>
+ * <td>org.hibernate.dialect.Cache71Dialect</td>
+ * </tr>
+ * <tr>
+ * <td>hibernate.connection.driver_class</td>
+ * <td>com.intersys.jdbc.CacheDriver</td>
+ * </tr>
+ * <tr>
+ * <td>hibernate.connection.username</td>
+ * <td>(see note 1)</td>
+ * </tr>
+ * <tr>
+ * <td>hibernate.connection.password</td>
+ * <td>(see note 1)</td>
+ * </tr>
+ * <tr>
+ * <td>hibernate.connection.url</td>
+ * <td>jdbc:Cache://127.0.0.1:1972/USER</td>
+ * </tr>
+ * </table>
+ * <p/>
+ * <dl>
+ * <dt><b>Note 1</b></dt>
+ * <dd>Please contact your administrator for the userid and password you should use when attempting access via JDBC.
+ * By default, these are chosen to be "_SYSTEM" and "SYS" respectively as noted in the SQL standard.</dd>
+ * </dl>
+ * <br>
+ * <h2>CACH&Eacute; VERSION URL</h2>
+ * This is the standard URL for the JDBC driver.
+ * For a JDBC driver on the machine hosting Cach&eacute;, use the IP "loopback" address, 127.0.0.1.
+ * For 1972, the default port, specify the super server port of your Cach&eacute; instance.
+ * For USER, substitute the NAMESPACE which contains your Cach&eacute; database data.
+ * <br>
+ * <h2>CACH&Eacute; DIALECTS</h2>
+ * Choices for Dialect are:
+ * <br>
+ * <p/>
+ * <ol>
+ * <li>org.hibernate.dialect.Cache71Dialect (requires Cach&eacute;
+ * 2007.1 or above)</li>
+ * <p/>
+ * </ol>
+ * <br>
+ * <h2>SUPPORT FOR IDENTITY COLUMNS</h2>
+ * Cach&eacute; 2007.1 or later supports identity columns.  For
+ * Hibernate to use identity columns, specify "native" as the
+ * generator.
+ * <br>
+ * <h2>SEQUENCE DIALECTS SUPPORT SEQUENCES</h2>
+ * <p/>
+ * To use Hibernate sequence support with Cach&eacute; in a namespace, you must FIRST load the following file into that namespace:
+ * <pre>
+ *     etc\CacheSequences.xml
+ * </pre>
+ * For example, at the COS terminal prompt in the namespace, run the
+ * following command:
+ * <p>
+ * d LoadFile^%apiOBJ("c:\hibernate\etc\CacheSequences.xml","ck")
+ * <p>
+ * In your Hibernate mapping you can specify sequence use.
+ * <p>
+ * For example, the following shows the use of a sequence generator in a Hibernate mapping:
+ * <pre>
+ *     &lt;id name="id" column="uid" type="long" unsaved-value="null"&gt;
+ *         &lt;generator class="sequence"/&gt;
+ *     &lt;/id&gt;
+ * </pre>
+ * <br>
+ * <p/>
+ * Some versions of Hibernate under some circumstances call
+ * getSelectSequenceNextValString() in the dialect.  If this happens
+ * you will receive the error message: new MappingException( "Dialect
+ * does not support sequences" ).
+ * <br>
+ * <h2>HIBERNATE FILES ASSOCIATED WITH CACH&Eacute; DIALECT</h2>
+ * The following files are associated with Cach&eacute; dialect:
+ * <p/>
+ * <ol>
+ * <li>src\org\hibernate\dialect\Cache71Dialect.java</li>
+ * <li>src\org\hibernate\dialect\function\ConditionalParenthesisFunction.java</li>
+ * <li>src\org\hibernate\dialect\function\ConvertFunction.java</li>
+ * <li>src\org\hibernate\exception\CacheSQLStateConverter.java</li>
+ * <li>src\org\hibernate\sql\CacheJoinFragment.java</li>
+ * </ol>
+ * Cache71Dialect ships with Hibernate 3.2.  All other dialects are distributed by InterSystems and subclass Cache71Dialect.
+ *
+ * @author Jonathan Levinson
+ */
+
+public class Cache71Dialect extends Dialect {
+
+	/**
+	 * Creates new <code>Cach�71Dialect</code> instance. Sets up the JDBC /
+	 * Cach� type mappings.
+	 */
+	public Cache71Dialect() {
+		super();
+		commonRegistration();
+		register71Functions();
+	}
+
+	protected final void commonRegistration() {
+		// Note: For object <-> SQL datatype mappings see:
+		//	 Configuration Manager | Advanced | SQL | System DDL Datatype Mappings
+		//
+		//	TBD	registerColumnType(Types.BINARY,        "binary($1)");
+		// changed 08-11-2005, jsl
+		registerColumnType( Types.BINARY, "varbinary($1)" );
+		registerColumnType( Types.BIGINT, "BigInt" );
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.DECIMAL, "decimal" );
+		registerColumnType( Types.DOUBLE, "double" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.LONGVARBINARY, "longvarbinary" );	// binary %Stream
+		registerColumnType( Types.LONGVARCHAR, "longvarchar" );		// character %Stream
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+		registerColumnType( Types.REAL, "real" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		// TBD should this be varbinary($1)?
+		//		registerColumnType(Types.VARBINARY,     "binary($1)");
+		registerColumnType( Types.VARBINARY, "longvarbinary" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.BLOB, "longvarbinary" );
+		registerColumnType( Types.CLOB, "longvarchar" );
+
+		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" );
+		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
+		//getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+
+		getDefaultProperties().setProperty( Environment.USE_SQL_COMMENTS, "false" );
+
+		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
+		registerFunction( "acos", new StandardJDBCEscapeFunction( "acos", Hibernate.DOUBLE ) );
+		registerFunction( "%alphaup", new StandardSQLFunction( "%alphaup", Hibernate.STRING ) );
+		registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.STRING ) );
+		registerFunction( "asin", new StandardJDBCEscapeFunction( "asin", Hibernate.DOUBLE ) );
+		registerFunction( "atan", new StandardJDBCEscapeFunction( "atan", Hibernate.DOUBLE ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "($length(?1)*8)" ) );
+		// hibernate impelemnts cast in Dialect.java
+		registerFunction( "ceiling", new StandardSQLFunction( "ceiling", Hibernate.INTEGER ) );
+		registerFunction( "char", new StandardJDBCEscapeFunction( "char", Hibernate.CHARACTER ) );
+		registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.INTEGER ) );
+		registerFunction( "char_length", new StandardSQLFunction( "char_length", Hibernate.INTEGER ) );
+		registerFunction( "cos", new StandardJDBCEscapeFunction( "cos", Hibernate.DOUBLE ) );
+		registerFunction( "cot", new StandardJDBCEscapeFunction( "cot", Hibernate.DOUBLE ) );
+		registerFunction( "coalesce", new VarArgsSQLFunction( "coalesce(", ",", ")" ) );
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "", "||", "" ) );
+		registerFunction( "convert", new ConvertFunction() );
+		registerFunction( "curdate", new StandardJDBCEscapeFunction( "curdate", Hibernate.DATE ) );
+		registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
+		registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
+		registerFunction(
+				"current_timestamp", new ConditionalParenthesisFunction( "current_timestamp", Hibernate.TIMESTAMP )
+		);
+		registerFunction( "curtime", new StandardJDBCEscapeFunction( "curtime", Hibernate.TIME ) );
+		registerFunction( "database", new StandardJDBCEscapeFunction( "database", Hibernate.STRING ) );
+		registerFunction( "dateadd", new VarArgsSQLFunction( Hibernate.TIMESTAMP, "dateadd(", ",", ")" ) );
+		registerFunction( "datediff", new VarArgsSQLFunction( Hibernate.INTEGER, "datediff(", ",", ")" ) );
+		registerFunction( "datename", new VarArgsSQLFunction( Hibernate.STRING, "datename(", ",", ")" ) );
+		registerFunction( "datepart", new VarArgsSQLFunction( Hibernate.INTEGER, "datepart(", ",", ")" ) );
+		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
+		registerFunction( "dayname", new StandardJDBCEscapeFunction( "dayname", Hibernate.STRING ) );
+		registerFunction( "dayofmonth", new StandardJDBCEscapeFunction( "dayofmonth", Hibernate.INTEGER ) );
+		registerFunction( "dayofweek", new StandardJDBCEscapeFunction( "dayofweek", Hibernate.INTEGER ) );
+		registerFunction( "dayofyear", new StandardJDBCEscapeFunction( "dayofyear", Hibernate.INTEGER ) );
+		// is it necessary to register %exact since it can only appear in a where clause?
+		registerFunction( "%exact", new StandardSQLFunction( "%exact", Hibernate.STRING ) );
+		registerFunction( "exp", new StandardJDBCEscapeFunction( "exp", Hibernate.DOUBLE ) );
+		registerFunction( "%external", new StandardSQLFunction( "%external", Hibernate.STRING ) );
+		registerFunction( "$extract", new VarArgsSQLFunction( Hibernate.INTEGER, "$extract(", ",", ")" ) );
+		registerFunction( "$find", new VarArgsSQLFunction( Hibernate.INTEGER, "$find(", ",", ")" ) );
+		registerFunction( "floor", new StandardSQLFunction( "floor", Hibernate.INTEGER ) );
+		registerFunction( "getdate", new StandardSQLFunction( "getdate", Hibernate.TIMESTAMP ) );
+		registerFunction( "hour", new StandardJDBCEscapeFunction( "hour", Hibernate.INTEGER ) );
+		registerFunction( "ifnull", new VarArgsSQLFunction( "ifnull(", ",", ")" ) );
+		registerFunction( "%internal", new StandardSQLFunction( "%internal" ) );
+		registerFunction( "isnull", new VarArgsSQLFunction( "isnull(", ",", ")" ) );
+		registerFunction( "isnumeric", new StandardSQLFunction( "isnumeric", Hibernate.INTEGER ) );
+		registerFunction( "lcase", new StandardJDBCEscapeFunction( "lcase", Hibernate.STRING ) );
+		registerFunction( "left", new StandardJDBCEscapeFunction( "left", Hibernate.STRING ) );
+		registerFunction( "len", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
+		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
+		registerFunction( "$length", new VarArgsSQLFunction( "$length(", ",", ")" ) );
+		// aggregate functions shouldn't be registered, right?
+		//registerFunction( "list", new StandardSQLFunction("list",Hibernate.STRING) );
+		// stopped on $list
+		registerFunction( "$list", new VarArgsSQLFunction( "$list(", ",", ")" ) );
+		registerFunction( "$listdata", new VarArgsSQLFunction( "$listdata(", ",", ")" ) );
+		registerFunction( "$listfind", new VarArgsSQLFunction( "$listfind(", ",", ")" ) );
+		registerFunction( "$listget", new VarArgsSQLFunction( "$listget(", ",", ")" ) );
+		registerFunction( "$listlength", new StandardSQLFunction( "$listlength", Hibernate.INTEGER ) );
+		registerFunction( "locate", new StandardSQLFunction( "$FIND", Hibernate.INTEGER ) );
+		registerFunction( "log", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) );
+		registerFunction( "log10", new StandardJDBCEscapeFunction( "log", Hibernate.DOUBLE ) );
+		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
+		registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
+		registerFunction( "minute", new StandardJDBCEscapeFunction( "minute", Hibernate.INTEGER ) );
+		registerFunction( "mod", new StandardJDBCEscapeFunction( "mod", Hibernate.DOUBLE ) );
+		registerFunction( "month", new StandardJDBCEscapeFunction( "month", Hibernate.INTEGER ) );
+		registerFunction( "monthname", new StandardJDBCEscapeFunction( "monthname", Hibernate.STRING ) );
+		registerFunction( "now", new StandardJDBCEscapeFunction( "monthname", Hibernate.TIMESTAMP ) );
+		registerFunction( "nullif", new VarArgsSQLFunction( "nullif(", ",", ")" ) );
+		registerFunction( "nvl", new NvlFunction() );
+		registerFunction( "%odbcin", new StandardSQLFunction( "%odbcin" ) );
+		registerFunction( "%odbcout", new StandardSQLFunction( "%odbcin" ) );
+		registerFunction( "%pattern", new VarArgsSQLFunction( Hibernate.STRING, "", "%pattern", "" ) );
+		registerFunction( "pi", new StandardJDBCEscapeFunction( "pi", Hibernate.DOUBLE ) );
+		registerFunction( "$piece", new VarArgsSQLFunction( Hibernate.STRING, "$piece(", ",", ")" ) );
+		registerFunction( "position", new VarArgsSQLFunction( Hibernate.INTEGER, "position(", " in ", ")" ) );
+		registerFunction( "power", new VarArgsSQLFunction( Hibernate.STRING, "power(", ",", ")" ) );
+		registerFunction( "quarter", new StandardJDBCEscapeFunction( "quarter", Hibernate.INTEGER ) );
+		registerFunction( "repeat", new VarArgsSQLFunction( Hibernate.STRING, "repeat(", ",", ")" ) );
+		registerFunction( "replicate", new VarArgsSQLFunction( Hibernate.STRING, "replicate(", ",", ")" ) );
+		registerFunction( "right", new StandardJDBCEscapeFunction( "right", Hibernate.STRING ) );
+		registerFunction( "round", new VarArgsSQLFunction( Hibernate.FLOAT, "round(", ",", ")" ) );
+		registerFunction( "rtrim", new StandardSQLFunction( "rtrim", Hibernate.STRING ) );
+		registerFunction( "second", new StandardJDBCEscapeFunction( "second", Hibernate.INTEGER ) );
+		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
+		registerFunction( "sin", new StandardJDBCEscapeFunction( "sin", Hibernate.DOUBLE ) );
+		registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
+		registerFunction( "%sqlstring", new VarArgsSQLFunction( Hibernate.STRING, "%sqlstring(", ",", ")" ) );
+		registerFunction( "%sqlupper", new VarArgsSQLFunction( Hibernate.STRING, "%sqlupper(", ",", ")" ) );
+		registerFunction( "sqrt", new StandardJDBCEscapeFunction( "SQRT", Hibernate.DOUBLE ) );
+		registerFunction( "%startswith", new VarArgsSQLFunction( Hibernate.STRING, "", "%startswith", "" ) );
+		// below is for Cache' that don't have str in 2007.1 there is str and we register str directly
+		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as char varying)" ) );
+		registerFunction( "string", new VarArgsSQLFunction( Hibernate.STRING, "string(", ",", ")" ) );
+		// note that %string is deprecated
+		registerFunction( "%string", new VarArgsSQLFunction( Hibernate.STRING, "%string(", ",", ")" ) );
+		registerFunction( "substr", new VarArgsSQLFunction( Hibernate.STRING, "substr(", ",", ")" ) );
+		registerFunction( "substring", new VarArgsSQLFunction( Hibernate.STRING, "substring(", ",", ")" ) );
+		registerFunction( "sysdate", new NoArgSQLFunction( "sysdate", Hibernate.TIMESTAMP, false ) );
+		registerFunction( "tan", new StandardJDBCEscapeFunction( "tan", Hibernate.DOUBLE ) );
+		registerFunction( "timestampadd", new StandardJDBCEscapeFunction( "timestampadd", Hibernate.DOUBLE ) );
+		registerFunction( "timestampdiff", new StandardJDBCEscapeFunction( "timestampdiff", Hibernate.DOUBLE ) );
+		registerFunction( "tochar", new VarArgsSQLFunction( Hibernate.STRING, "tochar(", ",", ")" ) );
+		registerFunction( "to_char", new VarArgsSQLFunction( Hibernate.STRING, "to_char(", ",", ")" ) );
+		registerFunction( "todate", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) );
+		registerFunction( "to_date", new VarArgsSQLFunction( Hibernate.STRING, "todate(", ",", ")" ) );
+		registerFunction( "tonumber", new StandardSQLFunction( "tonumber" ) );
+		registerFunction( "to_number", new StandardSQLFunction( "tonumber" ) );
+		// TRIM(end_keyword string-expression-1 FROM string-expression-2)
+		// use Hibernate implementation "From" is one of the parameters they pass in position ?3
+		//registerFunction( "trim", new SQLFunctionTemplate(Hibernate.STRING, "trim(?1 ?2 from ?3)") );
+		registerFunction( "truncate", new StandardJDBCEscapeFunction( "truncate", Hibernate.STRING ) );
+		registerFunction( "ucase", new StandardJDBCEscapeFunction( "ucase", Hibernate.STRING ) );
+		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
+		// %upper is deprecated
+		registerFunction( "%upper", new StandardSQLFunction( "%upper" ) );
+		registerFunction( "user", new StandardJDBCEscapeFunction( "user", Hibernate.STRING ) );
+		registerFunction( "week", new StandardJDBCEscapeFunction( "user", Hibernate.INTEGER ) );
+		registerFunction( "xmlconcat", new VarArgsSQLFunction( Hibernate.STRING, "xmlconcat(", ",", ")" ) );
+		registerFunction( "xmlelement", new VarArgsSQLFunction( Hibernate.STRING, "xmlelement(", ",", ")" ) );
+		// xmlforest requires a new kind of function constructor
+		registerFunction( "year", new StandardJDBCEscapeFunction( "year", Hibernate.INTEGER ) );
+	}
+
+	protected final void register71Functions() {
+		this.registerFunction( "str", new VarArgsSQLFunction( Hibernate.STRING, "str(", ",", ")" ) );
+	}
+
+	// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean hasAlterTable() {
+		// Does this dialect support the ALTER TABLE syntax?
+		return true;
+	}
+
+	public boolean qualifyIndexName() {
+		// Do we need to qualify index names with the schema name?
+		return false;
+	}
+
+	public boolean supportsUnique() {
+		// Does this dialect support the UNIQUE column syntax?
+		return true;
+	}
+
+	/**
+	 * The syntax used to add a foreign key constraint to a table.
+	 *
+	 * @return String
+	 */
+	public String getAddForeignKeyConstraintString(
+			String constraintName,
+			String[] foreignKey,
+			String referencedTable,
+			String[] primaryKey,
+			boolean referencesPrimaryKey) {
+		// The syntax used to add a foreign key constraint to a table.
+		return new StringBuffer( 300 )
+				.append( " ADD CONSTRAINT " )
+				.append( constraintName )
+				.append( " FOREIGN KEY " )
+				.append( constraintName )
+				.append( " (" )
+				.append( StringHelper.join( ", ", foreignKey ) )	// identifier-commalist
+				.append( ") REFERENCES " )
+				.append( referencedTable )
+				.append( " (" )
+				.append( StringHelper.join( ", ", primaryKey ) ) // identifier-commalist
+				.append( ") " )
+				.toString();
+	}
+
+	public boolean supportsCheck() {
+		// Does this dialect support check constraints?
+		return false;
+	}
+
+	public String getAddColumnString() {
+		// The syntax used to add a column to a table
+		return " add column";
+	}
+
+	public String getCascadeConstraintsString() {
+		// Completely optional cascading drop clause.
+		return "";
+	}
+
+	public boolean dropConstraints() {
+		// Do we need to drop constraints before dropping tables in this dialect?
+		return true;
+	}
+
+	public boolean supportsCascadeDelete() {
+		return true;
+	}
+
+	public boolean hasSelfReferentialForeignKeyBug() {
+		return true;
+	}
+
+	// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		String name = super.generateTemporaryTableName( baseTableName );
+		return name.length() > 25 ? name.substring( 1, 25 ) : name;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create global temporary table";
+	}
+
+	public Boolean performTemporaryTableDDLInIsolation() {
+		return Boolean.FALSE;
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "";
+	}
+
+	public boolean dropTemporaryTableAfterUse() {
+		return true;
+	}
+
+	// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+
+	public Class getNativeIdentifierGeneratorClass() {
+		return IdentityGenerator.class;
+	}
+
+	public boolean hasDataTypeInIdentityColumn() {
+		// Whether this dialect has an Identity clause added to the data type or a completely seperate identity
+		// data type
+		return true;
+	}
+
+	public String getIdentityColumnString() throws MappingException {
+		// The keyword used to specify an identity column, if identity column key generation is supported.
+		return "identity";
+	}
+
+	public String getIdentitySelectString() {
+		return "SELECT LAST_IDENTITY() FROM %TSQL_sys.snf";
+	}
+
+	// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsSequences() {
+		return false;
+	}
+
+// It really does support sequences, but InterSystems elects to suggest usage of IDENTITY instead :/
+// Anyway, below are the actual support overrides for users wanting to use this combo...
+//
+//	public String getSequenceNextValString(String sequenceName) {
+//		return "select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
+//	}
+//
+//	public String getSelectSequenceNextValString(String sequenceName) {
+//		return "(select InterSystems.Sequences_GetNext('" + sequenceName + "') from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "'))";
+//	}
+//
+//	public String getCreateSequenceString(String sequenceName) {
+//		return "insert into InterSystems.Sequences(Name) values (ucase('" + sequenceName + "'))";
+//	}
+//
+//	public String getDropSequenceString(String sequenceName) {
+//		return "delete from InterSystems.Sequences where ucase(name)=ucase('" + sequenceName + "')";
+//	}
+//
+//	public String getQuerySequencesString() {
+//		return "select name from InterSystems.Sequences";
+//	}
+
+	// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsForUpdate() {
+		// Does this dialect support the FOR UPDATE syntax?
+		return false;
+	}
+
+	public boolean supportsForUpdateOf() {
+		// Does this dialect support FOR UPDATE OF, allowing particular rows to be locked?
+		return false;
+	}
+
+	public boolean supportsForUpdateNowait() {
+		// Does this dialect support the Oracle-style FOR UPDATE NOWAIT syntax?
+		return false;
+	}
+
+	public boolean supportsOuterJoinForUpdate() {
+		return false;
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// InterSystems Cache' does not current support "SELECT ... FOR UPDATE" syntax...
+		// Set your transaction mode to READ_COMMITTED before using
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+
+	// LIMIT support (ala TOP) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public boolean supportsVariableLimit() {
+		return true;
+	}
+
+	public boolean bindLimitParametersFirst() {
+		// Does the LIMIT clause come at the start of the SELECT statement, rather than at the end?
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		// Does the LIMIT clause take a "maximum" row number instead of a total number of returned rows?
+		return true;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		if ( hasOffset ) {
+			throw new UnsupportedOperationException( "An offset may not be specified to <TOP n> in Cache SQL" );
+		}
+
+		// This does not support the Cache SQL 'DISTINCT BY (comma-list)' extensions,
+		// but this extension is not supported through Hibernate anyway.
+		int insertionPoint = sql.startsWith( "select distinct" ) ? 15 : 6;
+
+		return new StringBuffer( sql.length() + 8 )
+				.append( sql )
+				.insert( insertionPoint, " TOP ? " )
+				.toString();
+	}
+
+	// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		return col;
+	}
+
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		ps.execute();
+		return ( ResultSet ) ps.getObject( 1 );
+	}
+
+	// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public String getLowercaseFunction() {
+		// The name of the SQL function that transforms a string to lowercase
+		return "lower";
+	}
+
+	public String getNullColumnString() {
+		// The keyword used to specify a nullable column.
+		return " null";
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		// Create an OuterJoinGenerator for this dialect.
+		return new CacheJoinFragment();
+	}
+
+	public String getNoColumnsInsertString() {
+		// The keyword used to insert a row without specifying
+		// any column values
+		return " default values";
+	}
+
+	public SQLExceptionConverter buildSQLExceptionConverter() {
+		return new CacheSQLStateConverter( EXTRACTER );
+	}
+
+	public static final ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+		/**
+		 * Extract the name of the violated constraint from the given SQLException.
+		 *
+		 * @param sqle The exception that was the result of the constraint violation.
+		 * @return The extracted constraint name.
+		 */
+		public String extractConstraintName(SQLException sqle) {
+			return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
+		}
+	};
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean areStringComparisonsCaseInsensitive() {
+		return true;
+	}
+
+	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: DB2390Dialect.java 5712 2005-02-13 13:48:39Z oneovthafew $
-package org.hibernate.dialect;
-
-/**
- * An SQL dialect for DB2/390. This class provides support for
- * DB2 Universal Database for OS/390, also known as DB2/390.
- *
- * @author Kristoffer Dyrkorn
- */
-public class DB2390Dialect extends DB2Dialect {
-
-	public boolean supportsSequences() {
-		return false;
-	}
-
-	public String getIdentitySelectString() {
-		return "select identity_val_local() from sysibm.sysdummy1";
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public String getLimitString(String sql, int offset, int limit) {
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2390Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.dialect;
+
+/**
+ * An SQL dialect for DB2/390. This class provides support for
+ * DB2 Universal Database for OS/390, also known as DB2/390.
+ *
+ * @author Kristoffer Dyrkorn
+ */
+public class DB2390Dialect extends DB2Dialect {
+
+	public boolean supportsSequences() {
+		return false;
+	}
+
+	public String getIdentitySelectString() {
+		return "select identity_val_local() from sysibm.sysdummy1";
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public String getLimitString(String sql, int offset, int limit) {
+		return new StringBuffer(sql.length() + 40)
+			.append(sql)
+			.append(" fetch first ")
+			.append(limit)
+			.append(" rows only ")
+			.toString();
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-package org.hibernate.dialect;
-
-/**
-* An SQL dialect for DB2/400
-* @author Peter DeGregorio (pdegregorio)
-* This class provides support for DB2 Universal Database for iSeries,
-* also known as DB2/400.
-*/
-public class DB2400Dialect extends DB2Dialect {
-
-	public boolean supportsSequences() {
-		return false;
-	}
-
-	public String getIdentitySelectString() {
-		return "select identity_val_local() from sysibm.sysdummy1";
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public String getLimitString(String sql, int offset, int limit) {
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2400Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.dialect;
+
+/**
+* An SQL dialect for DB2/400
+* @author Peter DeGregorio (pdegregorio)
+* This class provides support for DB2 Universal Database for iSeries,
+* also known as DB2/400.
+*/
+public class DB2400Dialect extends DB2Dialect {
+
+	public boolean supportsSequences() {
+		return false;
+	}
+
+	public String getIdentitySelectString() {
+		return "select identity_val_local() from sysibm.sysdummy1";
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public String getLimitString(String sql, int offset, int limit) {
+		return new StringBuffer(sql.length() + 40)
+			.append(sql)
+			.append(" fetch first ")
+			.append(limit)
+			.append(" rows only ")
+			.toString();
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,369 +0,0 @@
-//$Id: DB2Dialect.java 10963 2006-12-08 16:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
-
-/**
- * An SQL dialect for DB2.
- * @author Gavin King
- */
-public class DB2Dialect extends Dialect {
-
-	public DB2Dialect() {
-		super();
-		registerColumnType( Types.BIT, "smallint" );
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "smallint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "varchar($l) for bit data" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-		registerColumnType( Types.BLOB, "blob($l)" );
-		registerColumnType( Types.CLOB, "clob($l)" );
-
-		registerFunction("abs", new StandardSQLFunction("abs") );
-		registerFunction("absval", new StandardSQLFunction("absval") );
-		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction("ceiling", new StandardSQLFunction("ceiling") );
-		registerFunction("ceil", new StandardSQLFunction("ceil") );
-		registerFunction("floor", new StandardSQLFunction("floor") );
-		registerFunction("round", new StandardSQLFunction("round") );
-
-		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
-		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction("float", new StandardSQLFunction("float", Hibernate.DOUBLE) );
-		registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) );
-		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
-		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
-		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
-		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
-		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
-		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction("stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
-		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction("variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
-
-		registerFunction("julian_day", new StandardSQLFunction("julian_day", Hibernate.INTEGER) );
-		registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) );
-		registerFunction("midnight_seconds", new StandardSQLFunction("midnight_seconds", Hibernate.INTEGER) );
-		registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) );
-		registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) );
-		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
-		registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) );
-		registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) );
-		registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) );
-		registerFunction("current_date", new NoArgSQLFunction("current date", Hibernate.DATE, false) );
-		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
-		registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) );
-		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
-		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
-		registerFunction("dayofweek_iso", new StandardSQLFunction("dayofweek_iso", Hibernate.INTEGER) );
-		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
-		registerFunction("days", new StandardSQLFunction("days", Hibernate.LONG) );
-		registerFunction("current_time", new NoArgSQLFunction("current time", Hibernate.TIME, false) );
-		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
-		registerFunction("current_timestamp", new NoArgSQLFunction("current timestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
-		registerFunction("timestamp_iso", new StandardSQLFunction("timestamp_iso", Hibernate.TIMESTAMP) );
-		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
-		registerFunction("week_iso", new StandardSQLFunction("week_iso", Hibernate.INTEGER) );
-		registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) );
-
-		registerFunction("double", new StandardSQLFunction("double", Hibernate.DOUBLE) );
-		registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) );
-		registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) );
-		registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) );
-		registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
-		registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) );
-		registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) );
-
-		registerFunction("digits", new StandardSQLFunction("digits", Hibernate.STRING) );
-		registerFunction("chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
-		registerFunction("upper", new StandardSQLFunction("upper") );
-		registerFunction("lower", new StandardSQLFunction("lower") );
-		registerFunction("ucase", new StandardSQLFunction("ucase") );
-		registerFunction("lcase", new StandardSQLFunction("lcase") );
-		registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) );
-		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction( "substr", new StandardSQLFunction( "substr", Hibernate.STRING ) );
-		registerFunction( "posstr", new StandardSQLFunction( "posstr", Hibernate.INTEGER ) );
-
-		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "length(?1)*8" ) );
-		registerFunction( "trim", new AnsiTrimEmulationFunction() );
-
-		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
-
-		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "rtrim(char(?1))" ) );
-
-		registerKeyword("current");
-		registerKeyword("date");
-		registerKeyword("time");
-		registerKeyword("timestamp");
-		registerKeyword("fetch");
-		registerKeyword("first");
-		registerKeyword("rows");
-		registerKeyword("only");
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-	}
-
-	public String getLowercaseFunction() {
-		return "lcase";
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-	public boolean dropConstraints() {
-		return false;
-	}
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-	public String getIdentitySelectString() {
-		return "values identity_val_local()";
-	}
-	public String getIdentityColumnString() {
-		return "generated by default as identity"; //not null ... (start with 1) is implicit
-	}
-	public String getIdentityInsertString() {
-		return "default";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "values nextval for " + sequenceName;
-	}
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName + " restrict";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public String getQuerySequencesString() {
-		return "select seqname from sysibm.syssequences";
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	/*public String getLimitString(String sql, boolean hasOffset) {
-		StringBuffer rownumber = new StringBuffer(50)
-			.append(" rownumber() over(");
-		int orderByIndex = sql.toLowerCase().indexOf("order by");
-		if (orderByIndex>0) rownumber.append( sql.substring(orderByIndex) );
-		rownumber.append(") as row_,");
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
-			.append("select * from ( ")
-			.append(sql)
-			.insert( getAfterSelectInsertPoint(sql)+16, rownumber.toString() )
-			.append(" ) as temp_ where row_ ");
-		if (hasOffset) {
-			pagingSelect.append("between ?+1 and ?");
-		}
-		else {
-			pagingSelect.append("<= ?");
-		}
-		return pagingSelect.toString();
-	}*/
-
-	/**
-	 * Render the <tt>rownumber() over ( .... ) as rownumber_,</tt> 
-	 * bit, that goes in the select list
-	 */
-	private String getRowNumber(String sql) {
-		StringBuffer rownumber = new StringBuffer(50)
-			.append("rownumber() over(");
-
-		int orderByIndex = sql.toLowerCase().indexOf("order by");
-
-		if ( orderByIndex>0 && !hasDistinct(sql) ) {
-			rownumber.append( sql.substring(orderByIndex) );
-		}
-
-		rownumber.append(") as rownumber_,");
-
-		return rownumber.toString();
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-
-		int startOfSelect = sql.toLowerCase().indexOf("select");
-
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
-					.append( sql.substring(0, startOfSelect) ) //add the comment
-					.append("select * from ( select ") //nest the main query in an outer select
-					.append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
-
-		if ( hasDistinct(sql) ) {
-			pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
-				.append( sql.substring(startOfSelect) ) //add the main query
-				.append(" ) as row_"); //close off the inner nested select
-		}
-		else {
-			pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
-		}
-
-		pagingSelect.append(" ) as temp_ where rownumber_ ");
-
-		//add the restriction to the outer select
-		if (hasOffset) {
-			pagingSelect.append("between ?+1 and ?");
-		}
-		else {
-			pagingSelect.append("<= ?");
-		}
-
-		return pagingSelect.toString();
-	}
-
-	private static boolean hasDistinct(String sql) {
-		return sql.toLowerCase().indexOf("select distinct")>=0;
-	}
-
-	public String getForUpdateString() {
-		return " for read only with rs";
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean supportsOuterJoinForUpdate() {
-		return false;
-	}
-
-	public boolean supportsNotNullUnique() {
-		return false;
-	}
-
-	public String getSelectClauseNullString(int sqlType) {
-		String literal;
-		switch(sqlType) {
-			case Types.VARCHAR:
-			case Types.CHAR:
-				literal = "'x'";
-				break;
-			case Types.DATE:
-				literal = "'2000-1-1'";
-				break;
-			case Types.TIMESTAMP:
-				literal = "'2000-1-1 00:00:00'";
-				break;
-			case Types.TIME:
-				literal = "'00:00:00'";
-				break;
-			default:
-				literal = "0";
-		}
-		return "nullif(" + literal + ',' + literal + ')';
-	}
-
-	public static void main(String[] args) {
-		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos", true) );
-		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos", true) );
-		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos foo order by foo.bar, foo.baz", true) );
-		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos foo order by foo.bar, foo.baz", true) );
-	}
-
-	public boolean supportsUnionAll() {
-		return true;
-	}
-
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		return col;
-	}
-
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		boolean isResultSet = ps.execute();
-		// This assumes you will want to ignore any update counts 
-		while (!isResultSet && ps.getUpdateCount() != -1) {
-		    isResultSet = ps.getMoreResults();
-		}
-		ResultSet rs = ps.getResultSet();
-		// You may still have other ResultSets or update counts left to process here 
-		// but you can't do it now or the ResultSet you just got will be closed 
-		return rs;
-	}
-
-	public boolean supportsCommentOn() {
-		return true;
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "declare global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "not logged";
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		return "session." + super.generateTemporaryTableName(baseTableName);
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "values current timestamp";
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public boolean supportsParametersInInsertSelect() {
-		// DB2 known to not support parameters within the select
-		// clause of an SQL INSERT ... SELECT ... statement
-		return false;
-	}
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsLobValueChangePropogation() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DB2Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DB2Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,392 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
+
+/**
+ * An SQL dialect for DB2.
+ * @author Gavin King
+ */
+public class DB2Dialect extends Dialect {
+
+	public DB2Dialect() {
+		super();
+		registerColumnType( Types.BIT, "smallint" );
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "smallint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "varchar($l) for bit data" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+		registerColumnType( Types.BLOB, "blob($l)" );
+		registerColumnType( Types.CLOB, "clob($l)" );
+
+		registerFunction("abs", new StandardSQLFunction("abs") );
+		registerFunction("absval", new StandardSQLFunction("absval") );
+		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction("ceiling", new StandardSQLFunction("ceiling") );
+		registerFunction("ceil", new StandardSQLFunction("ceil") );
+		registerFunction("floor", new StandardSQLFunction("floor") );
+		registerFunction("round", new StandardSQLFunction("round") );
+
+		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction("float", new StandardSQLFunction("float", Hibernate.DOUBLE) );
+		registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) );
+		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
+		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
+		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
+		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
+		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction("stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
+		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction("variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
+
+		registerFunction("julian_day", new StandardSQLFunction("julian_day", Hibernate.INTEGER) );
+		registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) );
+		registerFunction("midnight_seconds", new StandardSQLFunction("midnight_seconds", Hibernate.INTEGER) );
+		registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) );
+		registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) );
+		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
+		registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) );
+		registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) );
+		registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) );
+		registerFunction("current_date", new NoArgSQLFunction("current date", Hibernate.DATE, false) );
+		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
+		registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) );
+		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
+		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
+		registerFunction("dayofweek_iso", new StandardSQLFunction("dayofweek_iso", Hibernate.INTEGER) );
+		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
+		registerFunction("days", new StandardSQLFunction("days", Hibernate.LONG) );
+		registerFunction("current_time", new NoArgSQLFunction("current time", Hibernate.TIME, false) );
+		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
+		registerFunction("current_timestamp", new NoArgSQLFunction("current timestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
+		registerFunction("timestamp_iso", new StandardSQLFunction("timestamp_iso", Hibernate.TIMESTAMP) );
+		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
+		registerFunction("week_iso", new StandardSQLFunction("week_iso", Hibernate.INTEGER) );
+		registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) );
+
+		registerFunction("double", new StandardSQLFunction("double", Hibernate.DOUBLE) );
+		registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) );
+		registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) );
+		registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) );
+		registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
+		registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) );
+		registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) );
+
+		registerFunction("digits", new StandardSQLFunction("digits", Hibernate.STRING) );
+		registerFunction("chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
+		registerFunction("upper", new StandardSQLFunction("upper") );
+		registerFunction("lower", new StandardSQLFunction("lower") );
+		registerFunction("ucase", new StandardSQLFunction("ucase") );
+		registerFunction("lcase", new StandardSQLFunction("lcase") );
+		registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) );
+		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction( "substr", new StandardSQLFunction( "substr", Hibernate.STRING ) );
+		registerFunction( "posstr", new StandardSQLFunction( "posstr", Hibernate.INTEGER ) );
+
+		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "length(?1)*8" ) );
+		registerFunction( "trim", new AnsiTrimEmulationFunction() );
+
+		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
+
+		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "rtrim(char(?1))" ) );
+
+		registerKeyword("current");
+		registerKeyword("date");
+		registerKeyword("time");
+		registerKeyword("timestamp");
+		registerKeyword("fetch");
+		registerKeyword("first");
+		registerKeyword("rows");
+		registerKeyword("only");
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+	}
+
+	public String getLowercaseFunction() {
+		return "lcase";
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+	public boolean dropConstraints() {
+		return false;
+	}
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+	public String getIdentitySelectString() {
+		return "values identity_val_local()";
+	}
+	public String getIdentityColumnString() {
+		return "generated by default as identity"; //not null ... (start with 1) is implicit
+	}
+	public String getIdentityInsertString() {
+		return "default";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "values nextval for " + sequenceName;
+	}
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName + " restrict";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public String getQuerySequencesString() {
+		return "select seqname from sysibm.syssequences";
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	/*public String getLimitString(String sql, boolean hasOffset) {
+		StringBuffer rownumber = new StringBuffer(50)
+			.append(" rownumber() over(");
+		int orderByIndex = sql.toLowerCase().indexOf("order by");
+		if (orderByIndex>0) rownumber.append( sql.substring(orderByIndex) );
+		rownumber.append(") as row_,");
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
+			.append("select * from ( ")
+			.append(sql)
+			.insert( getAfterSelectInsertPoint(sql)+16, rownumber.toString() )
+			.append(" ) as temp_ where row_ ");
+		if (hasOffset) {
+			pagingSelect.append("between ?+1 and ?");
+		}
+		else {
+			pagingSelect.append("<= ?");
+		}
+		return pagingSelect.toString();
+	}*/
+
+	/**
+	 * Render the <tt>rownumber() over ( .... ) as rownumber_,</tt> 
+	 * bit, that goes in the select list
+	 */
+	private String getRowNumber(String sql) {
+		StringBuffer rownumber = new StringBuffer(50)
+			.append("rownumber() over(");
+
+		int orderByIndex = sql.toLowerCase().indexOf("order by");
+
+		if ( orderByIndex>0 && !hasDistinct(sql) ) {
+			rownumber.append( sql.substring(orderByIndex) );
+		}
+
+		rownumber.append(") as rownumber_,");
+
+		return rownumber.toString();
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+
+		int startOfSelect = sql.toLowerCase().indexOf("select");
+
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 )
+					.append( sql.substring(0, startOfSelect) ) //add the comment
+					.append("select * from ( select ") //nest the main query in an outer select
+					.append( getRowNumber(sql) ); //add the rownnumber bit into the outer query select list
+
+		if ( hasDistinct(sql) ) {
+			pagingSelect.append(" row_.* from ( ") //add another (inner) nested select
+				.append( sql.substring(startOfSelect) ) //add the main query
+				.append(" ) as row_"); //close off the inner nested select
+		}
+		else {
+			pagingSelect.append( sql.substring( startOfSelect + 6 ) ); //add the main query
+		}
+
+		pagingSelect.append(" ) as temp_ where rownumber_ ");
+
+		//add the restriction to the outer select
+		if (hasOffset) {
+			pagingSelect.append("between ?+1 and ?");
+		}
+		else {
+			pagingSelect.append("<= ?");
+		}
+
+		return pagingSelect.toString();
+	}
+
+	private static boolean hasDistinct(String sql) {
+		return sql.toLowerCase().indexOf("select distinct")>=0;
+	}
+
+	public String getForUpdateString() {
+		return " for read only with rs";
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean supportsOuterJoinForUpdate() {
+		return false;
+	}
+
+	public boolean supportsNotNullUnique() {
+		return false;
+	}
+
+	public String getSelectClauseNullString(int sqlType) {
+		String literal;
+		switch(sqlType) {
+			case Types.VARCHAR:
+			case Types.CHAR:
+				literal = "'x'";
+				break;
+			case Types.DATE:
+				literal = "'2000-1-1'";
+				break;
+			case Types.TIMESTAMP:
+				literal = "'2000-1-1 00:00:00'";
+				break;
+			case Types.TIME:
+				literal = "'00:00:00'";
+				break;
+			default:
+				literal = "0";
+		}
+		return "nullif(" + literal + ',' + literal + ')';
+	}
+
+	public static void main(String[] args) {
+		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos", true) );
+		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos", true) );
+		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select * from foos foo order by foo.bar, foo.baz", true) );
+		System.out.println( new DB2Dialect().getLimitString("/*foo*/ select distinct * from foos foo order by foo.bar, foo.baz", true) );
+	}
+
+	public boolean supportsUnionAll() {
+		return true;
+	}
+
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		return col;
+	}
+
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		boolean isResultSet = ps.execute();
+		// This assumes you will want to ignore any update counts 
+		while (!isResultSet && ps.getUpdateCount() != -1) {
+		    isResultSet = ps.getMoreResults();
+		}
+		ResultSet rs = ps.getResultSet();
+		// You may still have other ResultSets or update counts left to process here 
+		// but you can't do it now or the ResultSet you just got will be closed 
+		return rs;
+	}
+
+	public boolean supportsCommentOn() {
+		return true;
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "declare global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "not logged";
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		return "session." + super.generateTemporaryTableName(baseTableName);
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "values current timestamp";
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public boolean supportsParametersInInsertSelect() {
+		// DB2 known to not support parameters within the select
+		// clause of an SQL INSERT ... SELECT ... statement
+		return false;
+	}
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsLobValueChangePropogation() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-public class DataDirectOracle9Dialect extends Oracle9Dialect {
-	
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		return col; // sql server just returns automatically
-	}
-	
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		boolean isResultSet = ps.execute(); 
-//		 This assumes you will want to ignore any update counts 
-		while (!isResultSet && ps.getUpdateCount() != -1) { 
-		    isResultSet = ps.getMoreResults(); 
-		} 
-		ResultSet rs = ps.getResultSet(); 
-//		 You may still have other ResultSets or update counts left to process here 
-//		 but you can't do it now or the ResultSet you just got will be closed 
-		return rs;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DataDirectOracle9Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+public class DataDirectOracle9Dialect extends Oracle9Dialect {
+	
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		return col; // sql server just returns automatically
+	}
+	
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		boolean isResultSet = ps.execute(); 
+//		 This assumes you will want to ignore any update counts 
+		while (!isResultSet && ps.getUpdateCount() != -1) { 
+		    isResultSet = ps.getMoreResults(); 
+		} 
+		ResultSet rs = ps.getResultSet(); 
+//		 You may still have other ResultSets or update counts left to process here 
+//		 but you can't do it now or the ResultSet you just got will be closed 
+		return rs;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,198 +0,0 @@
-//$Id: DerbyDialect.java 10988 2006-12-13 18:37:01Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.id.TableHiLoGenerator;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.DerbyCaseFragment;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * @author Simon Johnston
- *
- * Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an 
- * override for the identity column generator as well as for the case statement
- * issue documented at:
- * http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
- */
-public class DerbyDialect extends DB2Dialect {
-
-	public DerbyDialect() {
-		super();
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
-		registerFunction( "trim", new DerbyTrimFunctionEmulation() );
-	}
-
-	/**
-	 * This is different in Cloudscape to DB2.
-	 */
-	public String getIdentityColumnString() {
-		return "not null generated always as identity"; //$NON-NLS-1
-	}
-
-	/**
-	 * Return the case statement modified for Cloudscape.
-	 */
-	public CaseFragment createCaseFragment() {
-		return new DerbyCaseFragment();
-	}
-
-	public boolean dropConstraints() {
-	      return true;
-	}
-
-	public Class getNativeIdentifierGeneratorClass() {
-		return TableHiLoGenerator.class;
-	}
-
-	public boolean supportsSequences() {
-		return false;
-	}
-
-	public boolean supportsLimit() {
-		return false;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public String getQuerySequencesString() {
-	   return null ;
-	}
-
-	/**
-	 * A specialized function template to emulate the ANSI trim function on Derby DB
-	 * since it does not support the full trim specification.  However, we cannot even
-	 * fully emulate it because there is not standard 'replace' function either. :(
-	 */
-	public static class DerbyTrimFunctionEmulation implements SQLFunction {
-		private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
-		private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
-		private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
-		private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
-
-		public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-			return Hibernate.STRING;
-		}
-
-		public boolean hasArguments() {
-			return true;
-		}
-
-		public boolean hasParenthesesIfNoArguments() {
-			return false;
-		}
-
-		public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-			// according to both the ANSI-SQL and EJB3 specs, trim can either take
-			// exactly one parameter or a variable number of parameters between 1 and 4.
-			// from the SQL spec:
-			//
-			// <trim function> ::=
-			//      TRIM <left paren> <trim operands> <right paren>
-			//
-			// <trim operands> ::=
-			//      [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
-			//
-			// <trim specification> ::=
-			//      LEADING
-			//      | TRAILING
-			//      | BOTH
-			//
-			// If only <trim specification> is omitted, BOTH is assumed;
-			// if <trim character> is omitted, space is assumed
-			if ( args.size() == 1 ) {
-				// we have the form: trim(trimSource)
-				//      so we trim leading and trailing spaces
-				return BOTH_SPACE_TRIM.render( args, factory );
-			}
-			else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
-				// we have the form: trim(from trimSource).
-				//      This is functionally equivalent to trim(trimSource)
-				return BOTH_SPACE_TRIM_FROM.render( args, factory );
-			}
-			else {
-				// otherwise, a trim-specification and/or a trim-character
-				// have been specified;  we need to decide which options
-				// are present and "do the right thing"
-				boolean leading = true;         // should leading trim-characters be trimmed?
-				boolean trailing = true;        // should trailing trim-characters be trimmed?
-				String trimCharacter;    		// the trim-character
-				String trimSource;       		// the trim-source
-
-				// potentialTrimCharacterArgIndex = 1 assumes that a
-				// trim-specification has been specified.  we handle the
-				// exception to that explicitly
-				int potentialTrimCharacterArgIndex = 1;
-				String firstArg = ( String ) args.get( 0 );
-				if ( "leading".equalsIgnoreCase( firstArg ) ) {
-					trailing = false;
-				}
-				else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
-					leading = false;
-				}
-				else if ( "both".equalsIgnoreCase( firstArg ) ) {
-				}
-				else {
-					potentialTrimCharacterArgIndex = 0;
-				}
-
-				String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
-				if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
-					trimCharacter = "' '";
-					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
-				}
-				else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
-					trimCharacter = "' '";
-					trimSource = potentialTrimCharacter;
-				}
-				else {
-					trimCharacter = potentialTrimCharacter;
-					if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
-						trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
-					}
-					else {
-						trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
-					}
-				}
-
-				List argsToUse = new ArrayList();
-				argsToUse.add( trimSource );
-				argsToUse.add( trimCharacter );
-
-				if ( trimCharacter.equals( "' '" ) ) {
-					if ( leading && trailing ) {
-						return BOTH_SPACE_TRIM.render( argsToUse, factory );
-					}
-					else if ( leading ) {
-						return LEADING_SPACE_TRIM.render( argsToUse, factory );
-					}
-					else {
-						return TRAILING_SPACE_TRIM.render( argsToUse, factory );
-					}
-				}
-				else {
-					throw new HibernateException( "cannot specify trim character when using Derby as Derby does not support the ANSI trim function, not does it support a replace function to properly emmulate it" );
-				}
-			}
-		}
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsLobValueChangePropogation() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DerbyDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DerbyDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,221 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.id.TableHiLoGenerator;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.DerbyCaseFragment;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author Simon Johnston
+ *
+ * Hibernate Dialect for Cloudscape 10 - aka Derby. This implements both an 
+ * override for the identity column generator as well as for the case statement
+ * issue documented at:
+ * http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
+ */
+public class DerbyDialect extends DB2Dialect {
+
+	public DerbyDialect() {
+		super();
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+		registerFunction( "trim", new DerbyTrimFunctionEmulation() );
+	}
+
+	/**
+	 * This is different in Cloudscape to DB2.
+	 */
+	public String getIdentityColumnString() {
+		return "not null generated always as identity"; //$NON-NLS-1
+	}
+
+	/**
+	 * Return the case statement modified for Cloudscape.
+	 */
+	public CaseFragment createCaseFragment() {
+		return new DerbyCaseFragment();
+	}
+
+	public boolean dropConstraints() {
+	      return true;
+	}
+
+	public Class getNativeIdentifierGeneratorClass() {
+		return TableHiLoGenerator.class;
+	}
+
+	public boolean supportsSequences() {
+		return false;
+	}
+
+	public boolean supportsLimit() {
+		return false;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public String getQuerySequencesString() {
+	   return null ;
+	}
+
+	/**
+	 * A specialized function template to emulate the ANSI trim function on Derby DB
+	 * since it does not support the full trim specification.  However, we cannot even
+	 * fully emulate it because there is not standard 'replace' function either. :(
+	 */
+	public static class DerbyTrimFunctionEmulation implements SQLFunction {
+		private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
+		private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
+		private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
+		private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
+
+		public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+			return Hibernate.STRING;
+		}
+
+		public boolean hasArguments() {
+			return true;
+		}
+
+		public boolean hasParenthesesIfNoArguments() {
+			return false;
+		}
+
+		public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+			// according to both the ANSI-SQL and EJB3 specs, trim can either take
+			// exactly one parameter or a variable number of parameters between 1 and 4.
+			// from the SQL spec:
+			//
+			// <trim function> ::=
+			//      TRIM <left paren> <trim operands> <right paren>
+			//
+			// <trim operands> ::=
+			//      [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+			//
+			// <trim specification> ::=
+			//      LEADING
+			//      | TRAILING
+			//      | BOTH
+			//
+			// If only <trim specification> is omitted, BOTH is assumed;
+			// if <trim character> is omitted, space is assumed
+			if ( args.size() == 1 ) {
+				// we have the form: trim(trimSource)
+				//      so we trim leading and trailing spaces
+				return BOTH_SPACE_TRIM.render( args, factory );
+			}
+			else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
+				// we have the form: trim(from trimSource).
+				//      This is functionally equivalent to trim(trimSource)
+				return BOTH_SPACE_TRIM_FROM.render( args, factory );
+			}
+			else {
+				// otherwise, a trim-specification and/or a trim-character
+				// have been specified;  we need to decide which options
+				// are present and "do the right thing"
+				boolean leading = true;         // should leading trim-characters be trimmed?
+				boolean trailing = true;        // should trailing trim-characters be trimmed?
+				String trimCharacter;    		// the trim-character
+				String trimSource;       		// the trim-source
+
+				// potentialTrimCharacterArgIndex = 1 assumes that a
+				// trim-specification has been specified.  we handle the
+				// exception to that explicitly
+				int potentialTrimCharacterArgIndex = 1;
+				String firstArg = ( String ) args.get( 0 );
+				if ( "leading".equalsIgnoreCase( firstArg ) ) {
+					trailing = false;
+				}
+				else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
+					leading = false;
+				}
+				else if ( "both".equalsIgnoreCase( firstArg ) ) {
+				}
+				else {
+					potentialTrimCharacterArgIndex = 0;
+				}
+
+				String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
+				if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
+					trimCharacter = "' '";
+					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+				}
+				else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
+					trimCharacter = "' '";
+					trimSource = potentialTrimCharacter;
+				}
+				else {
+					trimCharacter = potentialTrimCharacter;
+					if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
+						trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
+					}
+					else {
+						trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+					}
+				}
+
+				List argsToUse = new ArrayList();
+				argsToUse.add( trimSource );
+				argsToUse.add( trimCharacter );
+
+				if ( trimCharacter.equals( "' '" ) ) {
+					if ( leading && trailing ) {
+						return BOTH_SPACE_TRIM.render( argsToUse, factory );
+					}
+					else if ( leading ) {
+						return LEADING_SPACE_TRIM.render( argsToUse, factory );
+					}
+					else {
+						return TRAILING_SPACE_TRIM.render( argsToUse, factory );
+					}
+				}
+				else {
+					throw new HibernateException( "cannot specify trim character when using Derby as Derby does not support the ANSI trim function, not does it support a replace function to properly emmulate it" );
+				}
+			}
+		}
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsLobValueChangePropogation() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1764 +0,0 @@
-//$Id: Dialect.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.CastFunction;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.engine.Mapping;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.exception.SQLStateConverter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.id.IdentityGenerator;
-import org.hibernate.id.SequenceGenerator;
-import org.hibernate.id.TableHiLoGenerator;
-import org.hibernate.mapping.Column;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.sql.ANSICaseFragment;
-import org.hibernate.sql.ANSIJoinFragment;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.ForUpdateFragment;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Represents a dialect of SQL implemented by a particular RDBMS.
- * Subclasses implement Hibernate compatibility with different systems.<br>
- * <br>
- * Subclasses should provide a public default constructor that <tt>register()</tt>
- * a set of type mappings and default Hibernate properties.<br>
- * <br>
- * Subclasses should be immutable.
- *
- * @author Gavin King, David Channon
- */
-public abstract class Dialect {
-
-	private static final Logger log = LoggerFactory.getLogger( Dialect.class );
-
-	public static final String DEFAULT_BATCH_SIZE = "15";
-	public static final String NO_BATCH = "0";
-
-	/**
-	 * Characters used for quoting SQL identifiers
-	 */
-	public static final String QUOTE = "`\"[";
-	public static final String CLOSED_QUOTE = "`\"]";
-
-
-	// build the map of standard ANSI SQL aggregation functions ~~~~~~~~~~~~~~~
-
-	private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap();
-	static {
-		STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") {
-			public Type getReturnType(Type columnType, Mapping mapping) {
-				return Hibernate.LONG;
-			}
-		} );
-
-		STANDARD_AGGREGATE_FUNCTIONS.put( "avg", new StandardSQLFunction("avg") {
-			public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-				int[] sqlTypes;
-				try {
-					sqlTypes = columnType.sqlTypes( mapping );
-				}
-				catch ( MappingException me ) {
-					throw new QueryException( me );
-				}
-				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
-				return Hibernate.DOUBLE;
-			}
-		} );
-
-		STANDARD_AGGREGATE_FUNCTIONS.put( "max", new StandardSQLFunction("max") );
-		STANDARD_AGGREGATE_FUNCTIONS.put( "min", new StandardSQLFunction("min") );
-		STANDARD_AGGREGATE_FUNCTIONS.put( "sum", new StandardSQLFunction("sum") {
-			public Type getReturnType(Type columnType, Mapping mapping) {
-				//pre H3.2 behavior: super.getReturnType(ct, m);
-				int[] sqlTypes;
-				try {
-					sqlTypes = columnType.sqlTypes( mapping );
-				}
-				catch ( MappingException me ) {
-					throw new QueryException( me );
-				}
-				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in sum()" );
-				int sqlType = sqlTypes[0];
-
-				// First allow the actual type to control the return value. (the actual underlying sqltype could actually be different)
-				if ( columnType == Hibernate.BIG_INTEGER ) {
-					return Hibernate.BIG_INTEGER;
-				}
-				else if ( columnType == Hibernate.BIG_DECIMAL ) {
-					return Hibernate.BIG_DECIMAL;
-				}
-				else if ( columnType == Hibernate.LONG || columnType == Hibernate.SHORT || columnType == Hibernate.INTEGER) {
-					return Hibernate.LONG;
-				}
-				else if ( columnType == Hibernate.FLOAT || columnType == Hibernate.DOUBLE) {
-					return Hibernate.DOUBLE;
-				}
-
-				// finally use the sqltype if == on Hibernate types did not find a match.
-				if ( sqlType == Types.NUMERIC ) {
-					return columnType; //because numeric can be anything
-				}
-				else if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.DECIMAL || sqlType == Types.REAL) {
-					return Hibernate.DOUBLE;
-				}
-				else if ( sqlType == Types.BIGINT || sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) {
-					return Hibernate.LONG;
-				}
-				else {
-					return columnType;
-				}
-			}
-		});
-	}
-
-	private final TypeNames typeNames = new TypeNames();
-	private final TypeNames hibernateTypeNames = new TypeNames();
-
-	private final Properties properties = new Properties();
-	private final Map sqlFunctions = new HashMap();
-	private final Set sqlKeywords = new HashSet();
-
-
-	// constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	protected Dialect() {
-		log.info( "Using dialect: " + this );
-		sqlFunctions.putAll( STANDARD_AGGREGATE_FUNCTIONS );
-
-		// standard sql92 functions (can be overridden by subclasses)
-		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1, ?2, ?3)" ) );
-		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "locate(?1, ?2, ?3)" ) );
-		registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "trim(?1 ?2 ?3 ?4)" ) );
-		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
-		registerFunction( "bit_length", new StandardSQLFunction( "bit_length", Hibernate.INTEGER ) );
-		registerFunction( "coalesce", new StandardSQLFunction( "coalesce" ) );
-		registerFunction( "nullif", new StandardSQLFunction( "nullif" ) );
-		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
-		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER) );
-		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE) );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "cast", new CastFunction() );
-		registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(?1 ?2 ?3)") );
-
-		//map second/minute/hour/day/month/year to ANSI extract(), override on subclasses
-		registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(second from ?1)") );
-		registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(minute from ?1)") );
-		registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(hour from ?1)") );
-		registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(day from ?1)") );
-		registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(month from ?1)") );
-		registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(year from ?1)") );
-
-		registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as char)") );
-
-        // register hibernate types for default use in scalar sqlquery type auto detection
-		registerHibernateType( Types.BIGINT, Hibernate.BIG_INTEGER.getName() );
-		registerHibernateType( Types.BINARY, Hibernate.BINARY.getName() );
-		registerHibernateType( Types.BIT, Hibernate.BOOLEAN.getName() );
-		registerHibernateType( Types.CHAR, Hibernate.CHARACTER.getName() );
-		registerHibernateType( Types.DATE, Hibernate.DATE.getName() );
-		registerHibernateType( Types.DOUBLE, Hibernate.DOUBLE.getName() );
-		registerHibernateType( Types.FLOAT, Hibernate.FLOAT.getName() );
-		registerHibernateType( Types.INTEGER, Hibernate.INTEGER.getName() );
-		registerHibernateType( Types.SMALLINT, Hibernate.SHORT.getName() );
-		registerHibernateType( Types.TINYINT, Hibernate.BYTE.getName() );
-		registerHibernateType( Types.TIME, Hibernate.TIME.getName() );
-		registerHibernateType( Types.TIMESTAMP, Hibernate.TIMESTAMP.getName() );
-		registerHibernateType( Types.VARCHAR, Hibernate.STRING.getName() );
-		registerHibernateType( Types.VARBINARY, Hibernate.BINARY.getName() );
-		registerHibernateType( Types.NUMERIC, Hibernate.BIG_DECIMAL.getName() );
-		registerHibernateType( Types.DECIMAL, Hibernate.BIG_DECIMAL.getName() );
-		registerHibernateType( Types.BLOB, Hibernate.BLOB.getName() );
-		registerHibernateType( Types.CLOB, Hibernate.CLOB.getName() );
-		registerHibernateType( Types.REAL, Hibernate.FLOAT.getName() );
-	}
-
-	/**
-	 * Get an instance of the dialect specified by the current <tt>System</tt> properties.
-	 *
-	 * @return The specified Dialect
-	 * @throws HibernateException If no dialect was specified, or if it could not be instantiated.
-	 */
-	public static Dialect getDialect() throws HibernateException {
-		String dialectName = Environment.getProperties().getProperty( Environment.DIALECT );
-		return instantiateDialect( dialectName );
-	}
-
-
-	/**
-	 * Get an instance of the dialect specified by the given properties or by
-	 * the current <tt>System</tt> properties.
-	 *
-	 * @param props The properties to use for finding the dialect class to use.
-	 * @return The specified Dialect
-	 * @throws HibernateException If no dialect was specified, or if it could not be instantiated.
-	 */
-	public static Dialect getDialect(Properties props) throws HibernateException {
-		String dialectName = props.getProperty( Environment.DIALECT );
-		if ( dialectName == null ) {
-			return getDialect();
-		}
-		return instantiateDialect( dialectName );
-	}
-
-	private static Dialect instantiateDialect(String dialectName) throws HibernateException {
-		if ( dialectName == null ) {
-			throw new HibernateException( "The dialect was not set. Set the property hibernate.dialect." );
-		}
-		try {
-			return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
-		}
-		catch ( ClassNotFoundException cnfe ) {
-			throw new HibernateException( "Dialect class not found: " + dialectName );
-		}
-		catch ( Exception e ) {
-			throw new HibernateException( "Could not instantiate dialect class", e );
-		}
-	}
-
-	/**
-	 * Retrieve a set of default Hibernate properties for this database.
-	 *
-	 * @return a set of Hibernate properties
-	 */
-	public final Properties getDefaultProperties() {
-		return properties;
-	}
-
-	public String toString() {
-		return getClass().getName();
-	}
-
-
-	// database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Get the name of the database type associated with the given
-	 * {@link java.sql.Types} typecode.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @return the database type name
-	 * @throws HibernateException If no mapping was specified for that type.
-	 */
-	public String getTypeName(int code) throws HibernateException {
-		String result = typeNames.get( code );
-		if ( result == null ) {
-			throw new HibernateException( "No default type mapping for (java.sql.Types) " + code );
-		}
-		return result;
-	}
-
-	/**
-	 * Get the name of the database type associated with the given
-	 * {@link java.sql.Types} typecode with the given storage specification
-	 * parameters.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param length The datatype length
-	 * @param precision The datatype precision
-	 * @param scale The datatype scale
-	 * @return the database type name
-	 * @throws HibernateException If no mapping was specified for that type.
-	 */
-	public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
-		String result = typeNames.get( code, length, precision, scale );
-		if ( result == null ) {
-			throw new HibernateException(
-					"No type mapping for java.sql.Types code: " +
-					code +
-					", length: " +
-					length
-			);
-		}
-		return result;
-	}
-
-	/**
-	 * Get the name of the database type appropriate for casting operations
-	 * (via the CAST() SQL function) for the given {@link java.sql.Types} typecode.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @return The database type name
-	 */
-	public String getCastTypeName(int code) {
-		return getTypeName( code, Column.DEFAULT_LENGTH, Column.DEFAULT_PRECISION, Column.DEFAULT_SCALE );
-	}
-
-	/**
-	 * Subclasses register a type name for the given type code and maximum
-	 * column length. <tt>$l</tt> in the type name with be replaced by the
-	 * column length (if appropriate).
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param capacity The maximum length of database type
-	 * @param name The database type name
-	 */
-	protected void registerColumnType(int code, int capacity, String name) {
-		typeNames.put( code, capacity, name );
-	}
-
-	/**
-	 * Subclasses register a type name for the given type code. <tt>$l</tt> in
-	 * the type name with be replaced by the column length (if appropriate).
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param name The database type name
-	 */
-	protected void registerColumnType(int code, String name) {
-		typeNames.put( code, name );
-	}
-
-
-	// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Get the name of the Hibernate {@link org.hibernate.type.Type} associated with th given
-	 * {@link java.sql.Types} typecode.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @return The Hibernate {@link org.hibernate.type.Type} name.
-	 * @throws HibernateException If no mapping was specified for that type.
-	 */
-	public String getHibernateTypeName(int code) throws HibernateException {
-		String result = hibernateTypeNames.get( code );
-		if ( result == null ) {
-			throw new HibernateException( "No Hibernate type mapping for java.sql.Types code: " + code );
-		}
-		return result;
-	}
-
-	/**
-	 * Get the name of the Hibernate {@link org.hibernate.type.Type} associated
-	 * with the given {@link java.sql.Types} typecode with the given storage
-	 * specification parameters.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param length The datatype length
-	 * @param precision The datatype precision
-	 * @param scale The datatype scale
-	 * @return The Hibernate {@link org.hibernate.type.Type} name.
-	 * @throws HibernateException If no mapping was specified for that type.
-	 */
-	public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
-		String result = hibernateTypeNames.get( code, length, precision, scale );
-		if ( result == null ) {
-			throw new HibernateException(
-					"No Hibernate type mapping for java.sql.Types code: " +
-					code +
-					", length: " +
-					length
-			);
-		}
-		return result;
-	}
-
-	/**
-	 * Registers a Hibernate {@link org.hibernate.type.Type} name for the given
-	 * {@link java.sql.Types} type code and maximum column length.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param capacity The maximum length of database type
-	 * @param name The Hibernate {@link org.hibernate.type.Type} name
-	 */
-	protected void registerHibernateType(int code, int capacity, String name) {
-		hibernateTypeNames.put( code, capacity, name);
-	}
-
-	/**
-	 * Registers a Hibernate {@link org.hibernate.type.Type} name for the given
-	 * {@link java.sql.Types} type code.
-	 *
-	 * @param code The {@link java.sql.Types} typecode
-	 * @param name The Hibernate {@link org.hibernate.type.Type} name
-	 */
-	protected void registerHibernateType(int code, String name) {
-		hibernateTypeNames.put( code, name);
-	}
-
-
-	// function support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	protected void registerFunction(String name, SQLFunction function) {
-		sqlFunctions.put( name, function );
-	}
-
-	/**
-	 * Retrieves a map of the dialect's registered fucntions
-	 * (functionName => {@link org.hibernate.dialect.function.SQLFunction}).
-	 *
-	 * @return The map of registered functions.
-	 */
-	public final Map getFunctions() {
-		return sqlFunctions;
-	}
-
-
-	// keyword support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	protected void registerKeyword(String word) {
-		sqlKeywords.add(word);
-	}
-
-	public Set getKeywords() {
-		return sqlKeywords;
-	}
-
-
-	// native identifier generatiion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * The class (which implements {@link org.hibernate.id.IdentifierGenerator})
-	 * which acts as this dialects native generation strategy.
-	 * <p/>
-	 * Comes into play whenever the user specifies the native generator.
-	 *
-	 * @return The native generator class.
-	 */
-	public Class getNativeIdentifierGeneratorClass() {
-		if ( supportsIdentityColumns() ) {
-			return IdentityGenerator.class;
-		}
-		else if ( supportsSequences() ) {
-			return SequenceGenerator.class;
-		}
-		else {
-			return TableHiLoGenerator.class;
-		}
-	}
-
-
-	// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support identity column key generation?
-	 *
-	 * @return True if IDENTITY columns are supported; false otherwise.
-	 */
-	public boolean supportsIdentityColumns() {
-		return false;
-	}
-
-	/**
-	 * Does the dialect support some form of inserting and selecting
-	 * the generated IDENTITY value all in the same statement.
-	 *
-	 * @return True if the dialect supports selecting the just
-	 * generated IDENTITY in the insert statement.
-	 */
-	public boolean supportsInsertSelectIdentity() {
-		return false;
-	}
-
-	/**
-	 * Whether this dialect have an Identity clause added to the data type or a
-	 * completely seperate identity data type
-	 *
-	 * @return boolean
-	 */
-	public boolean hasDataTypeInIdentityColumn() {
-		return true;
-	}
-
-	/**
-	 * Provided we {@link #supportsInsertSelectIdentity}, then attch the
-	 * "select identity" clause to the  insert statement.
-	 *  <p/>
-	 * Note, if {@link #supportsInsertSelectIdentity} == false then
-	 * the insert-string should be returned without modification.
-	 *
-	 * @param insertString The insert command
-	 * @return The insert command with any necessary identity select
-	 * clause attached.
-	 */
-	public String appendIdentitySelectToInsert(String insertString) {
-		return insertString;
-	}
-
-	/**
-	 * Get the select command to use to retrieve the last generated IDENTITY
-	 * value for a particuar table
-	 *
-	 * @param table The table into which the insert was done
-	 * @param column The PK column.
-	 * @param type The {@link java.sql.Types} type code.
-	 * @return The appropriate select command
-	 * @throws MappingException If IDENTITY generation is not supported.
-	 */
-	public String getIdentitySelectString(String table, String column, int type) throws MappingException {
-		return getIdentitySelectString();
-	}
-
-	/**
-	 * Get the select command to use to retrieve the last generated IDENTITY
-	 * value.
-	 *
-	 * @return The appropriate select command
-	 * @throws MappingException If IDENTITY generation is not supported.
-	 */
-	protected String getIdentitySelectString() throws MappingException {
-		throw new MappingException( "Dialect does not support identity key generation" );
-	}
-
-	/**
-	 * The syntax used during DDL to define a column as being an IDENTITY of
-	 * a particular type.
-	 *
-	 * @param type The {@link java.sql.Types} type code.
-	 * @return The appropriate DDL fragment.
-	 * @throws MappingException If IDENTITY generation is not supported.
-	 */
-	public String getIdentityColumnString(int type) throws MappingException {
-		return getIdentityColumnString();
-	}
-
-	/**
-	 * The syntax used during DDL to define a column as being an IDENTITY.
-	 *
-	 * @return The appropriate DDL fragment.
-	 * @throws MappingException If IDENTITY generation is not supported.
-	 */
-	protected String getIdentityColumnString() throws MappingException {
-		throw new MappingException( "Dialect does not support identity key generation" );
-	}
-
-	/**
-	 * The keyword used to insert a generated value into an identity column (or null).
-	 * Need if the dialect does not support inserts that specify no column values.
-	 *
-	 * @return The appropriate keyword.
-	 */
-	public String getIdentityInsertString() {
-		return null;
-	}
-
-
-	// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support sequences?
-	 *
-	 * @return True if sequences supported; false otherwise.
-	 */
-	public boolean supportsSequences() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support "pooled" sequences.  Not aware of a better
-	 * name for this.  Essentially can we specify the initial and increment values?
-	 *
-	 * @return True if such "pooled" sequences are supported; false otherwise.
-	 * @see #getCreateSequenceStrings(String, int, int)
-	 * @see #getCreateSequenceString(String, int, int)
-	 */
-	public boolean supportsPooledSequences() {
-		return false;
-	}
-
-	/**
-	 * Generate the appropriate select statement to to retreive the next value
-	 * of a sequence.
-	 * <p/>
-	 * This should be a "stand alone" select statement.
-	 *
-	 * @param sequenceName the name of the sequence
-	 * @return String The "nextval" select string.
-	 * @throws MappingException If sequences are not supported.
-	 */
-	public String getSequenceNextValString(String sequenceName) throws MappingException {
-		throw new MappingException( "Dialect does not support sequences" );
-	}
-
-	/**
-	 * Generate the select expression fragment that will retreive the next
-	 * value of a sequence as part of another (typically DML) statement.
-	 * <p/>
-	 * This differs from {@link #getSequenceNextValString(String)} in that this
-	 * should return an expression usable within another statement.
-	 *
-	 * @param sequenceName the name of the sequence
-	 * @return The "nextval" fragment.
-	 * @throws MappingException If sequences are not supported.
-	 */
-	public String getSelectSequenceNextValString(String sequenceName) throws MappingException {
-		throw new MappingException( "Dialect does not support sequences" );
-	}
-
-	/**
-	 * The multiline script used to create a sequence.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @return The sequence creation commands
-	 * @throws MappingException If sequences are not supported.
-	 * @deprecated Use {@link #getCreateSequenceString(String, int, int)} instead
-	 */
-	public String[] getCreateSequenceStrings(String sequenceName) throws MappingException {
-		return new String[] { getCreateSequenceString( sequenceName ) };
-	}
-
-	/**
-	 * An optional multi-line form for databases which {@link #supportsPooledSequences()}.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @param initialValue The initial value to apply to 'create sequence' statement
-	 * @param incrementSize The increment value to apply to 'create sequence' statement
-	 * @return The sequence creation commands
-	 * @throws MappingException If sequences are not supported.
-	 */
-	public String[] getCreateSequenceStrings(String sequenceName, int initialValue, int incrementSize) throws MappingException {
-		return new String[] { getCreateSequenceString( sequenceName, initialValue, incrementSize ) };
-	}
-
-	/**
-	 * Typically dialects which support sequences can create a sequence
-	 * with a single command.  This is convenience form of
-	 * {@link #getCreateSequenceStrings} to help facilitate that.
-	 * <p/>
-	 * Dialects which support sequences and can create a sequence in a
-	 * single command need *only* override this method.  Dialects
-	 * which support sequences but require multiple commands to create
-	 * a sequence should instead override {@link #getCreateSequenceStrings}.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @return The sequence creation command
-	 * @throws MappingException If sequences are not supported.
-	 */
-	protected String getCreateSequenceString(String sequenceName) throws MappingException {
-		throw new MappingException( "Dialect does not support sequences" );
-	}
-
-	/**
-	 * Overloaded form of {@link #getCreateSequenceString(String)}, additionally
-	 * taking the initial value and increment size to be applied to the sequence
-	 * definition.
-	 * </p>
-	 * The default definition is to suffix {@link #getCreateSequenceString(String)}
-	 * with the string: " start with {initialValue} increment by {incrementSize}" where
-	 * {initialValue} and {incrementSize} are replacement placeholders.  Generally
-	 * dialects should only need to override this method if different key phrases
-	 * are used to apply the allocation information.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @param initialValue The initial value to apply to 'create sequence' statement
-	 * @param incrementSize The increment value to apply to 'create sequence' statement
-	 * @return The sequence creation command
-	 * @throws MappingException If sequences are not supported.
-	 */
-	protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) throws MappingException {
-		if ( supportsPooledSequences() ) {
-			return getCreateSequenceString( sequenceName ) + " start with " + initialValue + " increment by " + incrementSize;
-		}
-		throw new MappingException( "Dialect does not support pooled sequences" );
-	}
-
-	/**
-	 * The multiline script used to drop a sequence.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @return The sequence drop commands
-	 * @throws MappingException If sequences are not supported.
-	 */
-	public String[] getDropSequenceStrings(String sequenceName) throws MappingException {
-		return new String[]{getDropSequenceString( sequenceName )};
-	}
-
-	/**
-	 * Typically dialects which support sequences can drop a sequence
-	 * with a single command.  This is convenience form of
-	 * {@link #getDropSequenceStrings} to help facilitate that.
-	 * <p/>
-	 * Dialects which support sequences and can drop a sequence in a
-	 * single command need *only* override this method.  Dialects
-	 * which support sequences but require multiple commands to drop
-	 * a sequence should instead override {@link #getDropSequenceStrings}.
-	 *
-	 * @param sequenceName The name of the sequence
-	 * @return The sequence drop commands
-	 * @throws MappingException If sequences are not supported.
-	 */
-	protected String getDropSequenceString(String sequenceName) throws MappingException {
-		throw new MappingException( "Dialect does not support sequences" );
-	}
-
-	/**
-	 * Get the select command used retrieve the names of all sequences.
-	 *
-	 * @return The select command; or null if sequences are not supported.
-	 * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
-	 */
-	public String getQuerySequencesString() {
-		return null;
-	}
-
-
-	// GUID support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Get the command used to select a GUID from the underlying database.
-	 * <p/>
-	 * Optional operation.
-	 *
-	 * @return The appropriate command.
-	 */
-	public String getSelectGUIDString() {
-		throw new UnsupportedOperationException( "dialect does not support GUIDs" );
-	}
-
-
-	// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support some form of limiting query results
-	 * via a SQL clause?
-	 *
-	 * @return True if this dialect supports some form of LIMIT.
-	 */
-	public boolean supportsLimit() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect's LIMIT support (if any) additionally
-	 * support specifying an offset?
-	 *
-	 * @return True if the dialect supports an offset within the limit support.
-	 */
-	public boolean supportsLimitOffset() {
-		return supportsLimit();
-	}
-
-	/**
-	 * Does this dialect support bind variables (i.e., prepared statememnt
-	 * parameters) for its limit/offset?
-	 *
-	 * @return True if bind variables can be used; false otherwise.
-	 */
-	public boolean supportsVariableLimit() {
-		return supportsLimit();
-	}
-
-	/**
-	 * ANSI SQL defines the LIMIT clause to be in the form LIMIT offset, limit.
-	 * Does this dialect require us to bind the parameters in reverse order?
-	 *
-	 * @return true if the correct order is limit, offset
-	 */
-	public boolean bindLimitParametersInReverseOrder() {
-		return false;
-	}
-
-	/**
-	 * Does the <tt>LIMIT</tt> clause come at the start of the
-	 * <tt>SELECT</tt> statement, rather than at the end?
-	 *
-	 * @return true if limit parameters should come before other parameters
-	 */
-	public boolean bindLimitParametersFirst() {
-		return false;
-	}
-
-	/**
-	 * Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
-	 * of a total number of returned rows?
-	 * <p/>
-	 * This is easiest understood via an example.  Consider you have a table
-	 * with 20 rows, but you only want to retrieve rows number 11 through 20.
-	 * Generally, a limit with offset would say that the offset = 11 and the
-	 * limit = 10 (we only want 10 rows at a time); this is specifying the
-	 * total number of returned rows.  Some dialects require that we instead
-	 * specify offset = 11 and limit = 20, where 20 is the "last" row we want
-	 * relative to offset (i.e. total number of rows = 20 - 11 = 9)
-	 * <p/>
-	 * So essentially, is limit relative from offset?  Or is limit absolute?
-	 *
-	 * @return True if limit is relative from offset; false otherwise.
-	 */
-	public boolean useMaxForLimit() {
-		return false;
-	}
-
-	/**
-	 * Given a limit and an offset, apply the limit clause to the query.
-	 *
-	 * @param query The query to which to apply the limit.
-	 * @param offset The offset of the limit
-	 * @param limit The limit of the limit ;)
-	 * @return The modified query statement with the limit applied.
-	 */
-	public String getLimitString(String query, int offset, int limit) {
-		return getLimitString( query, offset > 0 );
-	}
-
-	/**
-	 * Apply s limit clause to the query.
-	 * <p/>
-	 * Typically dialects utilize {@link #supportsVariableLimit() variable}
-	 * limit caluses when they support limits.  Thus, when building the
-	 * select command we do not actually need to know the limit or the offest
-	 * since we will just be using placeholders.
-	 * <p/>
-	 * Here we do still pass along whether or not an offset was specified
-	 * so that dialects not supporting offsets can generate proper exceptions.
-	 * In general, dialects will override one or the other of this method and
-	 * {@link #getLimitString(String, int, int)}.
-	 *
-	 * @param query The query to which to apply the limit.
-	 * @param hasOffset Is the query requesting an offset?
-	 * @return the modified SQL
-	 */
-	protected String getLimitString(String query, boolean hasOffset) {
-		throw new UnsupportedOperationException( "paged queries not supported" );
-	}
-
-
-	// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Get a strategy instance which knows how to acquire a database-level lock
-	 * of the specified mode for this dialect.
-	 *
-	 * @param lockable The persister for the entity to be locked.
-	 * @param lockMode The type of lock to be acquired.
-	 * @return The appropriate locking strategy.
-	 * @since 3.2
-	 */
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		return new SelectLockingStrategy( lockable, lockMode );
-	}
-
-	/**
-	 * Given a lock mode, determine the appropriate for update fragment to use.
-	 *
-	 * @param lockMode The lock mode to apply.
-	 * @return The appropriate for update fragment.
-	 */
-	public String getForUpdateString(LockMode lockMode) {
-		if ( lockMode==LockMode.UPGRADE ) {
-			return getForUpdateString();
-		}
-		else if ( lockMode==LockMode.UPGRADE_NOWAIT ) {
-			return getForUpdateNowaitString();
-		}
-		else if ( lockMode==LockMode.FORCE ) {
-			return getForUpdateNowaitString();
-		}
-		else {
-			return "";
-		}
-	}
-
-	/**
-	 * Get the string to append to SELECT statements to acquire locks
-	 * for this dialect.
-	 *
-	 * @return The appropriate <tt>FOR UPDATE</tt> clause string.
-	 */
-	public String getForUpdateString() {
-		return " for update";
-	}
-
-	/**
-	 * Is <tt>FOR UPDATE OF</tt> syntax supported?
-	 *
-	 * @return True if the database supports <tt>FOR UPDATE OF</tt> syntax;
-	 * false otherwise.
-	 */
-	public boolean forUpdateOfColumns() {
-		// by default we report no support
-		return false;
-	}
-
-	/**
-	 * Does this dialect support <tt>FOR UPDATE</tt> in conjunction with
-	 * outer joined rows?
-	 *
-	 * @return True if outer joined rows can be locked via <tt>FOR UPDATE</tt>.
-	 */
-	public boolean supportsOuterJoinForUpdate() {
-		return true;
-	}
-
-	/**
-	 * Get the <tt>FOR UPDATE OF column_list</tt> fragment appropriate for this
-	 * dialect given the aliases of the columns to be write locked.
-	 *
-	 * @param aliases The columns to be write locked.
-	 * @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string.
-	 */
-	public String getForUpdateString(String aliases) {
-		// by default we simply return the getForUpdateString() result since
-		// the default is to say no support for "FOR UPDATE OF ..."
-		return getForUpdateString();
-	}
-
-	/**
-	 * Retrieves the <tt>FOR UPDATE NOWAIT</tt> syntax specific to this dialect.
-	 *
-	 * @return The appropriate <tt>FOR UPDATE NOWAIT</tt> clause string.
-	 */
-	public String getForUpdateNowaitString() {
-		// by default we report no support for NOWAIT lock semantics
-		return getForUpdateString();
-	}
-
-	/**
-	 * Get the <tt>FOR UPDATE OF column_list NOWAIT</tt> fragment appropriate
-	 * for this dialect given the aliases of the columns to be write locked.
-	 *
-	 * @param aliases The columns to be write locked.
-	 * @return The appropriate <tt>FOR UPDATE colunm_list NOWAIT</tt> clause string.
-	 */
-	public String getForUpdateNowaitString(String aliases) {
-		return getForUpdateString( aliases );
-	}
-
-	/**
-	 * Some dialects support an alternative means to <tt>SELECT FOR UPDATE</tt>,
-	 * whereby a "lock hint" is appends to the table name in the from clause.
-	 * <p/>
-	 * contributed by <a href="http://sourceforge.net/users/heschulz">Helge Schulz</a>
-	 *
-	 * @param mode The lock mode to apply
-	 * @param tableName The name of the table to which to apply the lock hint.
-	 * @return The table with any required lock hints.
-	 */
-	public String appendLockHint(LockMode mode, String tableName) {
-		return tableName;
-	}
-
-	/**
-	 * Modifies the given SQL by applying the appropriate updates for the specified
-	 * lock modes and key columns.
-	 * <p/>
-	 * The behavior here is that of an ANSI SQL <tt>SELECT FOR UPDATE</tt>.  This
-	 * method is really intended to allow dialects which do not support
-	 * <tt>SELECT FOR UPDATE</tt> to achieve this in their own fashion.
-	 *
-	 * @param sql the SQL string to modify
-	 * @param aliasedLockModes a map of lock modes indexed by aliased table names.
-	 * @param keyColumnNames a map of key columns indexed by aliased table names.
-	 * @return the modified SQL string.
-	 */
-	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
-		return sql + new ForUpdateFragment( this, aliasedLockModes, keyColumnNames ).toFragmentString();
-	}
-
-
-	// table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Command used to create a table.
-	 *
-	 * @return The command used to create a table.
-	 */
-	public String getCreateTableString() {
-		return "create table";
-	}
-
-	/**
-	 * Slight variation on {@link #getCreateTableString}.  Here, we have the
-	 * command used to create a table when there is no primary key and
-	 * duplicate rows are expected.
-	 * <p/>
-	 * Most databases do not care about the distinction; originally added for
-	 * Teradata support which does care.
-	 *
-	 * @return The command used to create a multiset table.
-	 */
-	public String getCreateMultisetTableString() {
-		return getCreateTableString();
-	}
-
-
-	// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support temporary tables?
-	 *
-	 * @return True if temp tables are supported; false otherwise.
-	 */
-	public boolean supportsTemporaryTables() {
-		return false;
-	}
-
-	/**
-	 * Generate a temporary table name given the bas table.
-	 *
-	 * @param baseTableName The table name from which to base the temp table name.
-	 * @return The generated temp table name.
-	 */
-	public String generateTemporaryTableName(String baseTableName) {
-		return "HT_" + baseTableName;
-	}
-
-	/**
-	 * Command used to create a temporary table.
-	 *
-	 * @return The command used to create a temporary table.
-	 */
-	public String getCreateTemporaryTableString() {
-		return "create table";
-	}
-
-	/**
-	 * Get any fragments needing to be postfixed to the command for
-	 * temporary table creation.
-	 *
-	 * @return Any required postfix.
-	 */
-	public String getCreateTemporaryTablePostfix() {
-		return "";
-	}
-
-	/**
-	 * Does the dialect require that temporary table DDL statements occur in
-	 * isolation from other statements?  This would be the case if the creation
-	 * would cause any current transaction to get committed implicitly.
-	 * <p/>
-	 * JDBC defines a standard way to query for this information via the
-	 * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}
-	 * method.  However, that does not distinguish between temporary table
-	 * DDL and other forms of DDL; MySQL, for example, reports DDL causing a
-	 * transaction commit via its driver, even though that is not the case for
-	 * temporary table DDL.
-	 * <p/>
-	 * Possible return values and their meanings:<ul>
-	 * <li>{@link Boolean#TRUE} - Unequivocally, perform the temporary table DDL
-	 * in isolation.</li>
-	 * <li>{@link Boolean#FALSE} - Unequivocally, do <b>not</b> perform the
-	 * temporary table DDL in isolation.</li>
-	 * <li><i>null</i> - defer to the JDBC driver response in regards to
-	 * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}</li>
-	 * </ul>
-	 * 
-	 * @return see the result matrix above.
-	 */
-	public Boolean performTemporaryTableDDLInIsolation() {
-		return null;
-	}
-
-	/**
-	 * Do we need to drop the temporary table after use?
-	 *
-	 * @return True if the table should be dropped.
-	 */
-	public boolean dropTemporaryTableAfterUse() {
-		return true;
-	}
-
-
-	// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Registers an OUT parameter which will be returing a
-	 * {@link java.sql.ResultSet}.  How this is accomplished varies greatly
-	 * from DB to DB, hence its inclusion (along with {@link #getResultSet}) here.
-	 *
-	 * @param statement The callable statement.
-	 * @param position The bind position at which to register the OUT param.
-	 * @return The number of (contiguous) bind positions used.
-	 * @throws SQLException Indicates problems registering the OUT param.
-	 */
-	public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {
-		throw new UnsupportedOperationException(
-				getClass().getName() +
-				" does not support resultsets via stored procedures"
-			);
-	}
-
-	/**
-	 * Given a callable statement previously processed by {@link #registerResultSetOutParameter},
-	 * extract the {@link java.sql.ResultSet} from the OUT parameter.
-	 *
-	 * @param statement The callable statement.
-	 * @return The extracted result set.
-	 * @throws SQLException Indicates problems extracting the result set.
-	 */
-	public ResultSet getResultSet(CallableStatement statement) throws SQLException {
-		throw new UnsupportedOperationException(
-				getClass().getName() +
-				" does not support resultsets via stored procedures"
-			);
-	}
-
-	// current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support a way to retrieve the database's current
-	 * timestamp value?
-	 *
-	 * @return True if the current timestamp can be retrieved; false otherwise.
-	 */
-	public boolean supportsCurrentTimestampSelection() {
-		return false;
-	}
-
-	/**
-	 * Should the value returned by {@link #getCurrentTimestampSelectString}
-	 * be treated as callable.  Typically this indicates that JDBC escape
-	 * sytnax is being used...
-	 *
-	 * @return True if the {@link #getCurrentTimestampSelectString} return
-	 * is callable; false otherwise.
-	 */
-	public boolean isCurrentTimestampSelectStringCallable() {
-		throw new UnsupportedOperationException( "Database not known to define a current timestamp function" );
-	}
-
-	/**
-	 * Retrieve the command used to retrieve the current timestammp from the
-	 * database.
-	 *
-	 * @return The command.
-	 */
-	public String getCurrentTimestampSelectString() {
-		throw new UnsupportedOperationException( "Database not known to define a current timestamp function" );
-	}
-
-	/**
-	 * The name of the database-specific SQL function for retrieving the
-	 * current timestamp.
-	 *
-	 * @return The function name.
-	 */
-	public String getCurrentTimestampSQLFunctionName() {
-		// the standard SQL function name is current_timestamp...
-		return "current_timestamp";
-	}
-
-
-	// SQLException support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Build an instance of the SQLExceptionConverter preferred by this dialect for
-	 * converting SQLExceptions into Hibernate's JDBCException hierarchy.  The default
-	 * Dialect implementation simply returns a converter based on X/Open SQLState codes.
-	 * <p/>
-	 * It is strongly recommended that specific Dialect implementations override this
-	 * method, since interpretation of a SQL error is much more accurate when based on
-	 * the ErrorCode rather than the SQLState.  Unfortunately, the ErrorCode is a vendor-
-	 * specific approach.
-	 *
-	 * @return The Dialect's preferred SQLExceptionConverter.
-	 */
-	public SQLExceptionConverter buildSQLExceptionConverter() {
-		// The default SQLExceptionConverter for all dialects is based on SQLState
-		// since SQLErrorCode is extremely vendor-specific.  Specific Dialects
-		// may override to return whatever is most appropriate for that vendor.
-		return new SQLStateConverter( getViolatedConstraintNameExtracter() );
-	}
-
-	private static final ViolatedConstraintNameExtracter EXTRACTER = new ViolatedConstraintNameExtracter() {
-		public String extractConstraintName(SQLException sqle) {
-			return null;
-		}
-	};
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-		return EXTRACTER;
-	}
-
-
-	// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Given a {@link java.sql.Types} type code, determine an appropriate
-	 * null value to use in a select clause.
-	 * <p/>
-	 * One thing to consider here is that certain databases might
-	 * require proper casting for the nulls here since the select here
-	 * will be part of a UNION/UNION ALL.
-	 *
-	 * @param sqlType The {@link java.sql.Types} type code.
-	 * @return The appropriate select clause value fragment.
-	 */
-	public String getSelectClauseNullString(int sqlType) {
-		return "null";
-	}
-
-	/**
-	 * Does this dialect support UNION ALL, which is generally a faster
-	 * variant of UNION?
-	 *
-	 * @return True if UNION ALL is supported; false otherwise.
-	 */
-	public boolean supportsUnionAll() {
-		return false;
-	}
-
-
-	// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-	/**
-	 * Create a {@link org.hibernate.sql.JoinFragment} strategy responsible
-	 * for handling this dialect's variations in how joins are handled.
-	 *
-	 * @return This dialect's {@link org.hibernate.sql.JoinFragment} strategy.
-	 */
-	public JoinFragment createOuterJoinFragment() {
-		return new ANSIJoinFragment();
-	}
-
-	/**
-	 * Create a {@link org.hibernate.sql.CaseFragment} strategy responsible
-	 * for handling this dialect's variations in how CASE statements are
-	 * handled.
-	 *
-	 * @return This dialect's {@link org.hibernate.sql.CaseFragment} strategy.
-	 */
-	public CaseFragment createCaseFragment() {
-		return new ANSICaseFragment();
-	}
-
-	/**
-	 * The fragment used to insert a row without specifying any column values.
-	 * This is not possible on some databases.
-	 *
-	 * @return The appropriate empty values clause.
-	 */
-	public String getNoColumnsInsertString() {
-		return "values ( )";
-	}
-
-	/**
-	 * The name of the SQL function that transforms a string to
-	 * lowercase
-	 *
-	 * @return The dialect-specific lowercase function.
-	 */
-	public String getLowercaseFunction() {
-		return "lower";
-	}
-
-	/**
-	 * Meant as a means for end users to affect the select strings being sent
-	 * to the database and perhaps manipulate them in some fashion.
-	 * <p/>
-	 * The recommend approach is to instead use
-	 * {@link org.hibernate.Interceptor#onPrepareStatement(String)}.
-	 *
-	 * @param select The select command
-	 * @return The mutated select command, or the same as was passed in.
-	 */
-	public String transformSelectString(String select) {
-		return select;
-	}
-
-	/**
-	 * What is the maximum length Hibernate can use for generated aliases?
-	 *
-	 * @return The maximum length.
-	 */
-	public int getMaxAliasLength() {
-		return 10;
-	}
-
-	/**
-	 * The SQL literal value to which this database maps boolean values.
-	 *
-	 * @param bool The boolean value
-	 * @return The appropriate SQL literal.
-	 */
-	public String toBooleanValueString(boolean bool) {
-		return bool ? "1" : "0";
-	}
-
-
-	// identifier quoting support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * The character specific to this dialect used to begin a quoted identifier.
-	 *
-	 * @return The dialect's specific open quote character.
-	 */
-	public char openQuote() {
-		return '"';
-	}
-
-	/**
-	 * The character specific to this dialect used to close a quoted identifier.
-	 *
-	 * @return The dialect's specific close quote character.
-	 */
-	public char closeQuote() {
-		return '"';
-	}
-
-	/**
-	 * Apply dialect-specific quoting.
-	 * <p/>
-	 * By default, the incoming value is checked to see if its first character
-	 * is the back-tick (`).  If so, the dialect specific quoting is applied.
-	 *
-	 * @param column The value to be quoted.
-	 * @return The quoted (or unmodified, if not starting with back-tick) value.
-	 * @see #openQuote()
-	 * @see #closeQuote()
-	 */
-	public final String quote(String column) {
-		if ( column.charAt( 0 ) == '`' ) {
-			return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote();
-		}
-		else {
-			return column;
-		}
-	}
-
-
-	// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support the <tt>ALTER TABLE</tt> syntax?
-	 *
-	 * @return True if we support altering of tables; false otherwise.
-	 */
-	public boolean hasAlterTable() {
-		return true;
-	}
-
-	/**
-	 * Do we need to drop constraints before dropping tables in this dialect?
-	 *
-	 * @return True if constraints must be dropped prior to dropping
-	 * the table; false otherwise.
-	 */
-	public boolean dropConstraints() {
-		return true;
-	}
-
-	/**
-	 * Do we need to qualify index names with the schema name?
-	 *
-	 * @return boolean
-	 */
-	public boolean qualifyIndexName() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support the <tt>UNIQUE</tt> column syntax?
-	 *
-	 * @return boolean
-	 */
-	public boolean supportsUnique() {
-		return true;
-	}
-
-    /**
-     * Does this dialect support adding Unique constraints via create and alter table ?
-     * @return boolean
-     */
-	public boolean supportsUniqueConstraintInCreateAlterTable() {
-	    return true;
-	}
-
-	/**
-	 * The syntax used to add a column to a table (optional).
-	 *
-	 * @return The "add column" fragment.
-	 */
-	public String getAddColumnString() {
-		throw new UnsupportedOperationException( "No add column syntax supported by Dialect" );
-	}
-
-	public String getDropForeignKeyString() {
-		return " drop constraint ";
-	}
-
-	public String getTableTypeString() {
-		// grrr... for differentiation of mysql storage engines
-		return "";
-	}
-
-	/**
-	 * The syntax used to add a foreign key constraint to a table.
-	 *
-	 * @param constraintName The FK constraint name.
-	 * @param foreignKey The names of the columns comprising the FK
-	 * @param referencedTable The table referenced by the FK
-	 * @param primaryKey The explicit columns in the referencedTable referenced
-	 * by this FK.
-	 * @param referencesPrimaryKey if false, constraint should be
-	 * explicit about which column names the constraint refers to
-	 *
-	 * @return the "add FK" fragment
-	 */
-	public String getAddForeignKeyConstraintString(
-			String constraintName,
-			String[] foreignKey,
-			String referencedTable,
-			String[] primaryKey,
-			boolean referencesPrimaryKey) {
-		StringBuffer res = new StringBuffer( 30 );
-
-		res.append( " add constraint " )
-				.append( constraintName )
-				.append( " foreign key (" )
-				.append( StringHelper.join( ", ", foreignKey ) )
-				.append( ") references " )
-				.append( referencedTable );
-
-		if ( !referencesPrimaryKey ) {
-			res.append( " (" )
-					.append( StringHelper.join( ", ", primaryKey ) )
-					.append( ')' );
-		}
-
-		return res.toString();
-	}
-
-	/**
-	 * The syntax used to add a primary key constraint to a table.
-	 *
-	 * @param constraintName The name of the PK constraint.
-	 * @return The "add PK" fragment
-	 */
-	public String getAddPrimaryKeyConstraintString(String constraintName) {
-		return " add constraint " + constraintName + " primary key ";
-	}
-
-	public boolean hasSelfReferentialForeignKeyBug() {
-		return false;
-	}
-
-	/**
-	 * The keyword used to specify a nullable column.
-	 *
-	 * @return String
-	 */
-	public String getNullColumnString() {
-		return "";
-	}
-
-	public boolean supportsCommentOn() {
-		return false;
-	}
-
-	public String getTableComment(String comment) {
-		return "";
-	}
-
-	public String getColumnComment(String comment) {
-		return "";
-	}
-
-	public boolean supportsIfExistsBeforeTableName() {
-		return false;
-	}
-
-	public boolean supportsIfExistsAfterTableName() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support column-level check constraints?
-	 *
-	 * @return True if column-level CHECK constraints are supported; false
-	 * otherwise.
-	 */
-	public boolean supportsColumnCheck() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support table-level check constraints?
-	 *
-	 * @return True if table-level CHECK constraints are supported; false
-	 * otherwise.
-	 */
-	public boolean supportsTableCheck() {
-		return true;
-	}
-
-	public boolean supportsCascadeDelete() {
-		return true;
-	}
-
-	public boolean supportsNotNullUnique() {
-		return true;
-	}
-
-	/**
-	 * Completely optional cascading drop clause
-	 *
-	 * @return String
-	 */
-	public String getCascadeConstraintsString() {
-		return "";
-	}
-
-
-	// Informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Does this dialect support empty IN lists?
-	 * <p/>
-	 * For example, is [where XYZ in ()] a supported construct?
-	 *
-	 * @return True if empty in lists are supported; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsEmptyInList() {
-		return true;
-	}
-
-	/**
-	 * Are string comparisons implicitly case insensitive.
-	 * <p/>
-	 * In other words, does [where 'XYZ' = 'xyz'] resolve to true?
-	 *
-	 * @return True if comparisons are case insensitive.
-	 * @since 3.2
-	 */
-	public boolean areStringComparisonsCaseInsensitive() {
-		return false;
-	}
-
-	/**
-	 * Is this dialect known to support what ANSI-SQL terms "row value
-	 * constructor" syntax; sometimes called tuple syntax.
-	 * <p/>
-	 * Basically, does it support syntax like
-	 * "... where (FIRST_NAME, LAST_NAME) = ('Steve', 'Ebersole') ...".
-	 *
-	 * @return True if this SQL dialect is known to support "row value
-	 * constructor" syntax; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsRowValueConstructorSyntax() {
-		// return false here, as most databases do not properly support this construct...
-		return false;
-	}
-
-	/**
-	 * If the dialect supports {@link #supportsRowValueConstructorSyntax() row values},
-	 * does it offer such support in IN lists as well?
-	 * <p/>
-	 * For example, "... where (FIRST_NAME, LAST_NAME) IN ( (?, ?), (?, ?) ) ..."
-	 *
-	 * @return True if this SQL dialect is known to support "row value
-	 * constructor" syntax in the IN list; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsRowValueConstructorSyntaxInInList() {
-		return false;
-	}
-
-	/**
-	 * Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
-	 * {@link java.sql.PreparedStatement#setBinaryStream}).
-	 *
-	 * @return True if BLOBs and CLOBs should be bound using stream operations.
-	 * @since 3.2
-	 */
-	public boolean useInputStreamToInsertBlob() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support parameters within the select clause of
-	 * INSERT ... SELECT ... statements?
-	 *
-	 * @return True if this is supported; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsParametersInInsertSelect() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support asking the result set its positioning
-	 * information on forward only cursors.  Specifically, in the case of
-	 * scrolling fetches, Hibernate needs to use
-	 * {@link java.sql.ResultSet#isAfterLast} and
-	 * {@link java.sql.ResultSet#isBeforeFirst}.  Certain drivers do not
-	 * allow access to these methods for forward only cursors.
-	 * <p/>
-	 * NOTE : this is highly driver dependent!
-	 *
-	 * @return True if methods like {@link java.sql.ResultSet#isAfterLast} and
-	 * {@link java.sql.ResultSet#isBeforeFirst} are supported for forward
-	 * only cursors; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support definition of cascade delete constraints
-	 * which can cause circular chains?
-	 *
-	 * @return True if circular cascade delete constraints are supported; false
-	 * otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsCircularCascadeDeleteConstraints() {
-		return true;
-	}
-
-	/**
-	 * Are subselects supported as the left-hand-side (LHS) of
-	 * IN-predicates.
-	 * <p/>
-	 * In other words, is syntax like "... <subquery> IN (1, 2, 3) ..." supported?
-	 *
-	 * @return True if subselects can appear as the LHS of an in-predicate;
-	 * false otherwise.
-	 * @since 3.2
-	 */
-	public boolean  supportsSubselectAsInPredicateLHS() {
-		return true;
-	}
-
-	/**
-	 * Expected LOB usage pattern is such that I can perform an insert
-	 * via prepared statement with a parameter binding for a LOB value
-	 * without crazy casting to JDBC driver implementation-specific classes...
-	 * <p/>
-	 * Part of the trickiness here is the fact that this is largely
-	 * driver dependent.  For example, Oracle (which is notoriously bad with
-	 * LOB support in their drivers historically) actually does a pretty good
-	 * job with LOB support as of the 10.2.x versions of their drivers...
-	 *
-	 * @return True if normal LOB usage patterns can be used with this driver;
-	 * false if driver-specific hookiness needs to be applied.
-	 * @since 3.2
-	 */
-	public boolean supportsExpectedLobUsagePattern() {
-		return true;
-	}
-
-	/**
-	 * Does the dialect support propogating changes to LOB
-	 * values back to the database?  Talking about mutating the
-	 * internal value of the locator as opposed to supplying a new
-	 * locator instance...
-	 * <p/>
-	 * For BLOBs, the internal value might be changed by:
-	 * {@link java.sql.Blob#setBinaryStream},
-	 * {@link java.sql.Blob#setBytes(long, byte[])},
-	 * {@link java.sql.Blob#setBytes(long, byte[], int, int)},
-	 * or {@link java.sql.Blob#truncate(long)}.
-	 * <p/>
-	 * For CLOBs, the internal value might be changed by:
-	 * {@link java.sql.Clob#setAsciiStream(long)},
-	 * {@link java.sql.Clob#setCharacterStream(long)},
-	 * {@link java.sql.Clob#setString(long, String)},
-	 * {@link java.sql.Clob#setString(long, String, int, int)},
-	 * or {@link java.sql.Clob#truncate(long)}.
-	 * <p/>
-	 * NOTE : I do not know the correct answer currently for
-	 * databases which (1) are not part of the cruise control process
-	 * or (2) do not {@link #supportsExpectedLobUsagePattern}.
-	 *
-	 * @return True if the changes are propogated back to the
-	 * database; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsLobValueChangePropogation() {
-		return true;
-	}
-
-	/**
-	 * Is it supported to materialize a LOB locator outside the transaction in
-	 * which it was created?
-	 * <p/>
-	 * Again, part of the trickiness here is the fact that this is largely
-	 * driver dependent.
-	 * <p/>
-	 * NOTE: all database I have tested which {@link #supportsExpectedLobUsagePattern()}
-	 * also support the ability to materialize a LOB outside the owning transaction...
-	 *
-	 * @return True if unbounded materialization is supported; false otherwise.
-	 * @since 3.2
-	 */
-	public boolean supportsUnboundedLobLocatorMaterialization() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support referencing the table being mutated in
-	 * a subquery.  The "table being mutated" is the table referenced in
-	 * an UPDATE or a DELETE query.  And so can that table then be
-	 * referenced in a subquery of said UPDATE/DELETE query.
-	 * <p/>
-	 * For example, would the following two syntaxes be supported:<ul>
-	 * <li>delete from TABLE_A where ID not in ( select ID from TABLE_A )</li>
-	 * <li>update TABLE_A set NON_ID = 'something' where ID in ( select ID from TABLE_A)</li>
-	 * </ul>
-	 *
-	 * @return True if this dialect allows references the mutating table from
-	 * a subquery.
-	 */
-	public boolean supportsSubqueryOnMutatingTable() {
-		return true;
-	}
-
-	/**
-	 * Does the dialect support an exists statement in the select clause?
-	 *
-	 * @return True if exists checks are allowed in the select clause; false otherwise.
-	 */
-	public boolean supportsExistsInSelect() {
-		return true;
-	}
-
-	/**
-	 * For the underlying database, is READ_COMMITTED isolation implemented by
-	 * forcing readers to wait for write locks to be released?
-	 *
-	 * @return True if writers block readers to achieve READ_COMMITTED; false otherwise.
-	 */
-	public boolean doesReadCommittedCauseWritersToBlockReaders() {
-		return false;
-	}
-
-	/**
-	 * For the underlying database, is REPEATABLE_READ isolation implemented by
-	 * forcing writers to wait for read locks to be released?
-	 *
-	 * @return True if readers block writers to achieve REPEATABLE_READ; false otherwise.
-	 */
-	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support using a JDBC bind parameter as an argument
-	 * to a function or procedure call?
-	 *
-	 * @return True if the database supports accepting bind params as args; false otherwise.
-	 */
-	public boolean supportsBindAsCallableArgument() {
-		return true;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1787 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.CastFunction;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.engine.Mapping;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.exception.SQLStateConverter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.id.IdentityGenerator;
+import org.hibernate.id.SequenceGenerator;
+import org.hibernate.id.TableHiLoGenerator;
+import org.hibernate.mapping.Column;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.sql.ANSICaseFragment;
+import org.hibernate.sql.ANSIJoinFragment;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.ForUpdateFragment;
+import org.hibernate.type.Type;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Represents a dialect of SQL implemented by a particular RDBMS.
+ * Subclasses implement Hibernate compatibility with different systems.<br>
+ * <br>
+ * Subclasses should provide a public default constructor that <tt>register()</tt>
+ * a set of type mappings and default Hibernate properties.<br>
+ * <br>
+ * Subclasses should be immutable.
+ *
+ * @author Gavin King, David Channon
+ */
+public abstract class Dialect {
+
+	private static final Logger log = LoggerFactory.getLogger( Dialect.class );
+
+	public static final String DEFAULT_BATCH_SIZE = "15";
+	public static final String NO_BATCH = "0";
+
+	/**
+	 * Characters used for quoting SQL identifiers
+	 */
+	public static final String QUOTE = "`\"[";
+	public static final String CLOSED_QUOTE = "`\"]";
+
+
+	// build the map of standard ANSI SQL aggregation functions ~~~~~~~~~~~~~~~
+
+	private static final Map STANDARD_AGGREGATE_FUNCTIONS = new HashMap();
+	static {
+		STANDARD_AGGREGATE_FUNCTIONS.put( "count", new StandardSQLFunction("count") {
+			public Type getReturnType(Type columnType, Mapping mapping) {
+				return Hibernate.LONG;
+			}
+		} );
+
+		STANDARD_AGGREGATE_FUNCTIONS.put( "avg", new StandardSQLFunction("avg") {
+			public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+				int[] sqlTypes;
+				try {
+					sqlTypes = columnType.sqlTypes( mapping );
+				}
+				catch ( MappingException me ) {
+					throw new QueryException( me );
+				}
+				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
+				return Hibernate.DOUBLE;
+			}
+		} );
+
+		STANDARD_AGGREGATE_FUNCTIONS.put( "max", new StandardSQLFunction("max") );
+		STANDARD_AGGREGATE_FUNCTIONS.put( "min", new StandardSQLFunction("min") );
+		STANDARD_AGGREGATE_FUNCTIONS.put( "sum", new StandardSQLFunction("sum") {
+			public Type getReturnType(Type columnType, Mapping mapping) {
+				//pre H3.2 behavior: super.getReturnType(ct, m);
+				int[] sqlTypes;
+				try {
+					sqlTypes = columnType.sqlTypes( mapping );
+				}
+				catch ( MappingException me ) {
+					throw new QueryException( me );
+				}
+				if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in sum()" );
+				int sqlType = sqlTypes[0];
+
+				// First allow the actual type to control the return value. (the actual underlying sqltype could actually be different)
+				if ( columnType == Hibernate.BIG_INTEGER ) {
+					return Hibernate.BIG_INTEGER;
+				}
+				else if ( columnType == Hibernate.BIG_DECIMAL ) {
+					return Hibernate.BIG_DECIMAL;
+				}
+				else if ( columnType == Hibernate.LONG || columnType == Hibernate.SHORT || columnType == Hibernate.INTEGER) {
+					return Hibernate.LONG;
+				}
+				else if ( columnType == Hibernate.FLOAT || columnType == Hibernate.DOUBLE) {
+					return Hibernate.DOUBLE;
+				}
+
+				// finally use the sqltype if == on Hibernate types did not find a match.
+				if ( sqlType == Types.NUMERIC ) {
+					return columnType; //because numeric can be anything
+				}
+				else if ( sqlType == Types.FLOAT || sqlType == Types.DOUBLE || sqlType == Types.DECIMAL || sqlType == Types.REAL) {
+					return Hibernate.DOUBLE;
+				}
+				else if ( sqlType == Types.BIGINT || sqlType == Types.INTEGER || sqlType == Types.SMALLINT || sqlType == Types.TINYINT ) {
+					return Hibernate.LONG;
+				}
+				else {
+					return columnType;
+				}
+			}
+		});
+	}
+
+	private final TypeNames typeNames = new TypeNames();
+	private final TypeNames hibernateTypeNames = new TypeNames();
+
+	private final Properties properties = new Properties();
+	private final Map sqlFunctions = new HashMap();
+	private final Set sqlKeywords = new HashSet();
+
+
+	// constructors and factory methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected Dialect() {
+		log.info( "Using dialect: " + this );
+		sqlFunctions.putAll( STANDARD_AGGREGATE_FUNCTIONS );
+
+		// standard sql92 functions (can be overridden by subclasses)
+		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1, ?2, ?3)" ) );
+		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "locate(?1, ?2, ?3)" ) );
+		registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "trim(?1 ?2 ?3 ?4)" ) );
+		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
+		registerFunction( "bit_length", new StandardSQLFunction( "bit_length", Hibernate.INTEGER ) );
+		registerFunction( "coalesce", new StandardSQLFunction( "coalesce" ) );
+		registerFunction( "nullif", new StandardSQLFunction( "nullif" ) );
+		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
+		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER) );
+		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE) );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "cast", new CastFunction() );
+		registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(?1 ?2 ?3)") );
+
+		//map second/minute/hour/day/month/year to ANSI extract(), override on subclasses
+		registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(second from ?1)") );
+		registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(minute from ?1)") );
+		registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(hour from ?1)") );
+		registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(day from ?1)") );
+		registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(month from ?1)") );
+		registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "extract(year from ?1)") );
+
+		registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as char)") );
+
+        // register hibernate types for default use in scalar sqlquery type auto detection
+		registerHibernateType( Types.BIGINT, Hibernate.BIG_INTEGER.getName() );
+		registerHibernateType( Types.BINARY, Hibernate.BINARY.getName() );
+		registerHibernateType( Types.BIT, Hibernate.BOOLEAN.getName() );
+		registerHibernateType( Types.CHAR, Hibernate.CHARACTER.getName() );
+		registerHibernateType( Types.DATE, Hibernate.DATE.getName() );
+		registerHibernateType( Types.DOUBLE, Hibernate.DOUBLE.getName() );
+		registerHibernateType( Types.FLOAT, Hibernate.FLOAT.getName() );
+		registerHibernateType( Types.INTEGER, Hibernate.INTEGER.getName() );
+		registerHibernateType( Types.SMALLINT, Hibernate.SHORT.getName() );
+		registerHibernateType( Types.TINYINT, Hibernate.BYTE.getName() );
+		registerHibernateType( Types.TIME, Hibernate.TIME.getName() );
+		registerHibernateType( Types.TIMESTAMP, Hibernate.TIMESTAMP.getName() );
+		registerHibernateType( Types.VARCHAR, Hibernate.STRING.getName() );
+		registerHibernateType( Types.VARBINARY, Hibernate.BINARY.getName() );
+		registerHibernateType( Types.NUMERIC, Hibernate.BIG_DECIMAL.getName() );
+		registerHibernateType( Types.DECIMAL, Hibernate.BIG_DECIMAL.getName() );
+		registerHibernateType( Types.BLOB, Hibernate.BLOB.getName() );
+		registerHibernateType( Types.CLOB, Hibernate.CLOB.getName() );
+		registerHibernateType( Types.REAL, Hibernate.FLOAT.getName() );
+	}
+
+	/**
+	 * Get an instance of the dialect specified by the current <tt>System</tt> properties.
+	 *
+	 * @return The specified Dialect
+	 * @throws HibernateException If no dialect was specified, or if it could not be instantiated.
+	 */
+	public static Dialect getDialect() throws HibernateException {
+		String dialectName = Environment.getProperties().getProperty( Environment.DIALECT );
+		return instantiateDialect( dialectName );
+	}
+
+
+	/**
+	 * Get an instance of the dialect specified by the given properties or by
+	 * the current <tt>System</tt> properties.
+	 *
+	 * @param props The properties to use for finding the dialect class to use.
+	 * @return The specified Dialect
+	 * @throws HibernateException If no dialect was specified, or if it could not be instantiated.
+	 */
+	public static Dialect getDialect(Properties props) throws HibernateException {
+		String dialectName = props.getProperty( Environment.DIALECT );
+		if ( dialectName == null ) {
+			return getDialect();
+		}
+		return instantiateDialect( dialectName );
+	}
+
+	private static Dialect instantiateDialect(String dialectName) throws HibernateException {
+		if ( dialectName == null ) {
+			throw new HibernateException( "The dialect was not set. Set the property hibernate.dialect." );
+		}
+		try {
+			return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
+		}
+		catch ( ClassNotFoundException cnfe ) {
+			throw new HibernateException( "Dialect class not found: " + dialectName );
+		}
+		catch ( Exception e ) {
+			throw new HibernateException( "Could not instantiate dialect class", e );
+		}
+	}
+
+	/**
+	 * Retrieve a set of default Hibernate properties for this database.
+	 *
+	 * @return a set of Hibernate properties
+	 */
+	public final Properties getDefaultProperties() {
+		return properties;
+	}
+
+	public String toString() {
+		return getClass().getName();
+	}
+
+
+	// database type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Get the name of the database type associated with the given
+	 * {@link java.sql.Types} typecode.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @return the database type name
+	 * @throws HibernateException If no mapping was specified for that type.
+	 */
+	public String getTypeName(int code) throws HibernateException {
+		String result = typeNames.get( code );
+		if ( result == null ) {
+			throw new HibernateException( "No default type mapping for (java.sql.Types) " + code );
+		}
+		return result;
+	}
+
+	/**
+	 * Get the name of the database type associated with the given
+	 * {@link java.sql.Types} typecode with the given storage specification
+	 * parameters.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param length The datatype length
+	 * @param precision The datatype precision
+	 * @param scale The datatype scale
+	 * @return the database type name
+	 * @throws HibernateException If no mapping was specified for that type.
+	 */
+	public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
+		String result = typeNames.get( code, length, precision, scale );
+		if ( result == null ) {
+			throw new HibernateException(
+					"No type mapping for java.sql.Types code: " +
+					code +
+					", length: " +
+					length
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Get the name of the database type appropriate for casting operations
+	 * (via the CAST() SQL function) for the given {@link java.sql.Types} typecode.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @return The database type name
+	 */
+	public String getCastTypeName(int code) {
+		return getTypeName( code, Column.DEFAULT_LENGTH, Column.DEFAULT_PRECISION, Column.DEFAULT_SCALE );
+	}
+
+	/**
+	 * Subclasses register a type name for the given type code and maximum
+	 * column length. <tt>$l</tt> in the type name with be replaced by the
+	 * column length (if appropriate).
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param capacity The maximum length of database type
+	 * @param name The database type name
+	 */
+	protected void registerColumnType(int code, int capacity, String name) {
+		typeNames.put( code, capacity, name );
+	}
+
+	/**
+	 * Subclasses register a type name for the given type code. <tt>$l</tt> in
+	 * the type name with be replaced by the column length (if appropriate).
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param name The database type name
+	 */
+	protected void registerColumnType(int code, String name) {
+		typeNames.put( code, name );
+	}
+
+
+	// hibernate type mapping support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Get the name of the Hibernate {@link org.hibernate.type.Type} associated with th given
+	 * {@link java.sql.Types} typecode.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @return The Hibernate {@link org.hibernate.type.Type} name.
+	 * @throws HibernateException If no mapping was specified for that type.
+	 */
+	public String getHibernateTypeName(int code) throws HibernateException {
+		String result = hibernateTypeNames.get( code );
+		if ( result == null ) {
+			throw new HibernateException( "No Hibernate type mapping for java.sql.Types code: " + code );
+		}
+		return result;
+	}
+
+	/**
+	 * Get the name of the Hibernate {@link org.hibernate.type.Type} associated
+	 * with the given {@link java.sql.Types} typecode with the given storage
+	 * specification parameters.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param length The datatype length
+	 * @param precision The datatype precision
+	 * @param scale The datatype scale
+	 * @return The Hibernate {@link org.hibernate.type.Type} name.
+	 * @throws HibernateException If no mapping was specified for that type.
+	 */
+	public String getHibernateTypeName(int code, int length, int precision, int scale) throws HibernateException {
+		String result = hibernateTypeNames.get( code, length, precision, scale );
+		if ( result == null ) {
+			throw new HibernateException(
+					"No Hibernate type mapping for java.sql.Types code: " +
+					code +
+					", length: " +
+					length
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Registers a Hibernate {@link org.hibernate.type.Type} name for the given
+	 * {@link java.sql.Types} type code and maximum column length.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param capacity The maximum length of database type
+	 * @param name The Hibernate {@link org.hibernate.type.Type} name
+	 */
+	protected void registerHibernateType(int code, int capacity, String name) {
+		hibernateTypeNames.put( code, capacity, name);
+	}
+
+	/**
+	 * Registers a Hibernate {@link org.hibernate.type.Type} name for the given
+	 * {@link java.sql.Types} type code.
+	 *
+	 * @param code The {@link java.sql.Types} typecode
+	 * @param name The Hibernate {@link org.hibernate.type.Type} name
+	 */
+	protected void registerHibernateType(int code, String name) {
+		hibernateTypeNames.put( code, name);
+	}
+
+
+	// function support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void registerFunction(String name, SQLFunction function) {
+		sqlFunctions.put( name, function );
+	}
+
+	/**
+	 * Retrieves a map of the dialect's registered fucntions
+	 * (functionName => {@link org.hibernate.dialect.function.SQLFunction}).
+	 *
+	 * @return The map of registered functions.
+	 */
+	public final Map getFunctions() {
+		return sqlFunctions;
+	}
+
+
+	// keyword support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected void registerKeyword(String word) {
+		sqlKeywords.add(word);
+	}
+
+	public Set getKeywords() {
+		return sqlKeywords;
+	}
+
+
+	// native identifier generatiion ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * The class (which implements {@link org.hibernate.id.IdentifierGenerator})
+	 * which acts as this dialects native generation strategy.
+	 * <p/>
+	 * Comes into play whenever the user specifies the native generator.
+	 *
+	 * @return The native generator class.
+	 */
+	public Class getNativeIdentifierGeneratorClass() {
+		if ( supportsIdentityColumns() ) {
+			return IdentityGenerator.class;
+		}
+		else if ( supportsSequences() ) {
+			return SequenceGenerator.class;
+		}
+		else {
+			return TableHiLoGenerator.class;
+		}
+	}
+
+
+	// IDENTITY support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support identity column key generation?
+	 *
+	 * @return True if IDENTITY columns are supported; false otherwise.
+	 */
+	public boolean supportsIdentityColumns() {
+		return false;
+	}
+
+	/**
+	 * Does the dialect support some form of inserting and selecting
+	 * the generated IDENTITY value all in the same statement.
+	 *
+	 * @return True if the dialect supports selecting the just
+	 * generated IDENTITY in the insert statement.
+	 */
+	public boolean supportsInsertSelectIdentity() {
+		return false;
+	}
+
+	/**
+	 * Whether this dialect have an Identity clause added to the data type or a
+	 * completely seperate identity data type
+	 *
+	 * @return boolean
+	 */
+	public boolean hasDataTypeInIdentityColumn() {
+		return true;
+	}
+
+	/**
+	 * Provided we {@link #supportsInsertSelectIdentity}, then attch the
+	 * "select identity" clause to the  insert statement.
+	 *  <p/>
+	 * Note, if {@link #supportsInsertSelectIdentity} == false then
+	 * the insert-string should be returned without modification.
+	 *
+	 * @param insertString The insert command
+	 * @return The insert command with any necessary identity select
+	 * clause attached.
+	 */
+	public String appendIdentitySelectToInsert(String insertString) {
+		return insertString;
+	}
+
+	/**
+	 * Get the select command to use to retrieve the last generated IDENTITY
+	 * value for a particuar table
+	 *
+	 * @param table The table into which the insert was done
+	 * @param column The PK column.
+	 * @param type The {@link java.sql.Types} type code.
+	 * @return The appropriate select command
+	 * @throws MappingException If IDENTITY generation is not supported.
+	 */
+	public String getIdentitySelectString(String table, String column, int type) throws MappingException {
+		return getIdentitySelectString();
+	}
+
+	/**
+	 * Get the select command to use to retrieve the last generated IDENTITY
+	 * value.
+	 *
+	 * @return The appropriate select command
+	 * @throws MappingException If IDENTITY generation is not supported.
+	 */
+	protected String getIdentitySelectString() throws MappingException {
+		throw new MappingException( "Dialect does not support identity key generation" );
+	}
+
+	/**
+	 * The syntax used during DDL to define a column as being an IDENTITY of
+	 * a particular type.
+	 *
+	 * @param type The {@link java.sql.Types} type code.
+	 * @return The appropriate DDL fragment.
+	 * @throws MappingException If IDENTITY generation is not supported.
+	 */
+	public String getIdentityColumnString(int type) throws MappingException {
+		return getIdentityColumnString();
+	}
+
+	/**
+	 * The syntax used during DDL to define a column as being an IDENTITY.
+	 *
+	 * @return The appropriate DDL fragment.
+	 * @throws MappingException If IDENTITY generation is not supported.
+	 */
+	protected String getIdentityColumnString() throws MappingException {
+		throw new MappingException( "Dialect does not support identity key generation" );
+	}
+
+	/**
+	 * The keyword used to insert a generated value into an identity column (or null).
+	 * Need if the dialect does not support inserts that specify no column values.
+	 *
+	 * @return The appropriate keyword.
+	 */
+	public String getIdentityInsertString() {
+		return null;
+	}
+
+
+	// SEQUENCE support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support sequences?
+	 *
+	 * @return True if sequences supported; false otherwise.
+	 */
+	public boolean supportsSequences() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support "pooled" sequences.  Not aware of a better
+	 * name for this.  Essentially can we specify the initial and increment values?
+	 *
+	 * @return True if such "pooled" sequences are supported; false otherwise.
+	 * @see #getCreateSequenceStrings(String, int, int)
+	 * @see #getCreateSequenceString(String, int, int)
+	 */
+	public boolean supportsPooledSequences() {
+		return false;
+	}
+
+	/**
+	 * Generate the appropriate select statement to to retreive the next value
+	 * of a sequence.
+	 * <p/>
+	 * This should be a "stand alone" select statement.
+	 *
+	 * @param sequenceName the name of the sequence
+	 * @return String The "nextval" select string.
+	 * @throws MappingException If sequences are not supported.
+	 */
+	public String getSequenceNextValString(String sequenceName) throws MappingException {
+		throw new MappingException( "Dialect does not support sequences" );
+	}
+
+	/**
+	 * Generate the select expression fragment that will retreive the next
+	 * value of a sequence as part of another (typically DML) statement.
+	 * <p/>
+	 * This differs from {@link #getSequenceNextValString(String)} in that this
+	 * should return an expression usable within another statement.
+	 *
+	 * @param sequenceName the name of the sequence
+	 * @return The "nextval" fragment.
+	 * @throws MappingException If sequences are not supported.
+	 */
+	public String getSelectSequenceNextValString(String sequenceName) throws MappingException {
+		throw new MappingException( "Dialect does not support sequences" );
+	}
+
+	/**
+	 * The multiline script used to create a sequence.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @return The sequence creation commands
+	 * @throws MappingException If sequences are not supported.
+	 * @deprecated Use {@link #getCreateSequenceString(String, int, int)} instead
+	 */
+	public String[] getCreateSequenceStrings(String sequenceName) throws MappingException {
+		return new String[] { getCreateSequenceString( sequenceName ) };
+	}
+
+	/**
+	 * An optional multi-line form for databases which {@link #supportsPooledSequences()}.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @param initialValue The initial value to apply to 'create sequence' statement
+	 * @param incrementSize The increment value to apply to 'create sequence' statement
+	 * @return The sequence creation commands
+	 * @throws MappingException If sequences are not supported.
+	 */
+	public String[] getCreateSequenceStrings(String sequenceName, int initialValue, int incrementSize) throws MappingException {
+		return new String[] { getCreateSequenceString( sequenceName, initialValue, incrementSize ) };
+	}
+
+	/**
+	 * Typically dialects which support sequences can create a sequence
+	 * with a single command.  This is convenience form of
+	 * {@link #getCreateSequenceStrings} to help facilitate that.
+	 * <p/>
+	 * Dialects which support sequences and can create a sequence in a
+	 * single command need *only* override this method.  Dialects
+	 * which support sequences but require multiple commands to create
+	 * a sequence should instead override {@link #getCreateSequenceStrings}.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @return The sequence creation command
+	 * @throws MappingException If sequences are not supported.
+	 */
+	protected String getCreateSequenceString(String sequenceName) throws MappingException {
+		throw new MappingException( "Dialect does not support sequences" );
+	}
+
+	/**
+	 * Overloaded form of {@link #getCreateSequenceString(String)}, additionally
+	 * taking the initial value and increment size to be applied to the sequence
+	 * definition.
+	 * </p>
+	 * The default definition is to suffix {@link #getCreateSequenceString(String)}
+	 * with the string: " start with {initialValue} increment by {incrementSize}" where
+	 * {initialValue} and {incrementSize} are replacement placeholders.  Generally
+	 * dialects should only need to override this method if different key phrases
+	 * are used to apply the allocation information.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @param initialValue The initial value to apply to 'create sequence' statement
+	 * @param incrementSize The increment value to apply to 'create sequence' statement
+	 * @return The sequence creation command
+	 * @throws MappingException If sequences are not supported.
+	 */
+	protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) throws MappingException {
+		if ( supportsPooledSequences() ) {
+			return getCreateSequenceString( sequenceName ) + " start with " + initialValue + " increment by " + incrementSize;
+		}
+		throw new MappingException( "Dialect does not support pooled sequences" );
+	}
+
+	/**
+	 * The multiline script used to drop a sequence.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @return The sequence drop commands
+	 * @throws MappingException If sequences are not supported.
+	 */
+	public String[] getDropSequenceStrings(String sequenceName) throws MappingException {
+		return new String[]{getDropSequenceString( sequenceName )};
+	}
+
+	/**
+	 * Typically dialects which support sequences can drop a sequence
+	 * with a single command.  This is convenience form of
+	 * {@link #getDropSequenceStrings} to help facilitate that.
+	 * <p/>
+	 * Dialects which support sequences and can drop a sequence in a
+	 * single command need *only* override this method.  Dialects
+	 * which support sequences but require multiple commands to drop
+	 * a sequence should instead override {@link #getDropSequenceStrings}.
+	 *
+	 * @param sequenceName The name of the sequence
+	 * @return The sequence drop commands
+	 * @throws MappingException If sequences are not supported.
+	 */
+	protected String getDropSequenceString(String sequenceName) throws MappingException {
+		throw new MappingException( "Dialect does not support sequences" );
+	}
+
+	/**
+	 * Get the select command used retrieve the names of all sequences.
+	 *
+	 * @return The select command; or null if sequences are not supported.
+	 * @see org.hibernate.tool.hbm2ddl.SchemaUpdate
+	 */
+	public String getQuerySequencesString() {
+		return null;
+	}
+
+
+	// GUID support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Get the command used to select a GUID from the underlying database.
+	 * <p/>
+	 * Optional operation.
+	 *
+	 * @return The appropriate command.
+	 */
+	public String getSelectGUIDString() {
+		throw new UnsupportedOperationException( "dialect does not support GUIDs" );
+	}
+
+
+	// limit/offset support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support some form of limiting query results
+	 * via a SQL clause?
+	 *
+	 * @return True if this dialect supports some form of LIMIT.
+	 */
+	public boolean supportsLimit() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect's LIMIT support (if any) additionally
+	 * support specifying an offset?
+	 *
+	 * @return True if the dialect supports an offset within the limit support.
+	 */
+	public boolean supportsLimitOffset() {
+		return supportsLimit();
+	}
+
+	/**
+	 * Does this dialect support bind variables (i.e., prepared statememnt
+	 * parameters) for its limit/offset?
+	 *
+	 * @return True if bind variables can be used; false otherwise.
+	 */
+	public boolean supportsVariableLimit() {
+		return supportsLimit();
+	}
+
+	/**
+	 * ANSI SQL defines the LIMIT clause to be in the form LIMIT offset, limit.
+	 * Does this dialect require us to bind the parameters in reverse order?
+	 *
+	 * @return true if the correct order is limit, offset
+	 */
+	public boolean bindLimitParametersInReverseOrder() {
+		return false;
+	}
+
+	/**
+	 * Does the <tt>LIMIT</tt> clause come at the start of the
+	 * <tt>SELECT</tt> statement, rather than at the end?
+	 *
+	 * @return true if limit parameters should come before other parameters
+	 */
+	public boolean bindLimitParametersFirst() {
+		return false;
+	}
+
+	/**
+	 * Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
+	 * of a total number of returned rows?
+	 * <p/>
+	 * This is easiest understood via an example.  Consider you have a table
+	 * with 20 rows, but you only want to retrieve rows number 11 through 20.
+	 * Generally, a limit with offset would say that the offset = 11 and the
+	 * limit = 10 (we only want 10 rows at a time); this is specifying the
+	 * total number of returned rows.  Some dialects require that we instead
+	 * specify offset = 11 and limit = 20, where 20 is the "last" row we want
+	 * relative to offset (i.e. total number of rows = 20 - 11 = 9)
+	 * <p/>
+	 * So essentially, is limit relative from offset?  Or is limit absolute?
+	 *
+	 * @return True if limit is relative from offset; false otherwise.
+	 */
+	public boolean useMaxForLimit() {
+		return false;
+	}
+
+	/**
+	 * Given a limit and an offset, apply the limit clause to the query.
+	 *
+	 * @param query The query to which to apply the limit.
+	 * @param offset The offset of the limit
+	 * @param limit The limit of the limit ;)
+	 * @return The modified query statement with the limit applied.
+	 */
+	public String getLimitString(String query, int offset, int limit) {
+		return getLimitString( query, offset > 0 );
+	}
+
+	/**
+	 * Apply s limit clause to the query.
+	 * <p/>
+	 * Typically dialects utilize {@link #supportsVariableLimit() variable}
+	 * limit caluses when they support limits.  Thus, when building the
+	 * select command we do not actually need to know the limit or the offest
+	 * since we will just be using placeholders.
+	 * <p/>
+	 * Here we do still pass along whether or not an offset was specified
+	 * so that dialects not supporting offsets can generate proper exceptions.
+	 * In general, dialects will override one or the other of this method and
+	 * {@link #getLimitString(String, int, int)}.
+	 *
+	 * @param query The query to which to apply the limit.
+	 * @param hasOffset Is the query requesting an offset?
+	 * @return the modified SQL
+	 */
+	protected String getLimitString(String query, boolean hasOffset) {
+		throw new UnsupportedOperationException( "paged queries not supported" );
+	}
+
+
+	// lock acquisition support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Get a strategy instance which knows how to acquire a database-level lock
+	 * of the specified mode for this dialect.
+	 *
+	 * @param lockable The persister for the entity to be locked.
+	 * @param lockMode The type of lock to be acquired.
+	 * @return The appropriate locking strategy.
+	 * @since 3.2
+	 */
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		return new SelectLockingStrategy( lockable, lockMode );
+	}
+
+	/**
+	 * Given a lock mode, determine the appropriate for update fragment to use.
+	 *
+	 * @param lockMode The lock mode to apply.
+	 * @return The appropriate for update fragment.
+	 */
+	public String getForUpdateString(LockMode lockMode) {
+		if ( lockMode==LockMode.UPGRADE ) {
+			return getForUpdateString();
+		}
+		else if ( lockMode==LockMode.UPGRADE_NOWAIT ) {
+			return getForUpdateNowaitString();
+		}
+		else if ( lockMode==LockMode.FORCE ) {
+			return getForUpdateNowaitString();
+		}
+		else {
+			return "";
+		}
+	}
+
+	/**
+	 * Get the string to append to SELECT statements to acquire locks
+	 * for this dialect.
+	 *
+	 * @return The appropriate <tt>FOR UPDATE</tt> clause string.
+	 */
+	public String getForUpdateString() {
+		return " for update";
+	}
+
+	/**
+	 * Is <tt>FOR UPDATE OF</tt> syntax supported?
+	 *
+	 * @return True if the database supports <tt>FOR UPDATE OF</tt> syntax;
+	 * false otherwise.
+	 */
+	public boolean forUpdateOfColumns() {
+		// by default we report no support
+		return false;
+	}
+
+	/**
+	 * Does this dialect support <tt>FOR UPDATE</tt> in conjunction with
+	 * outer joined rows?
+	 *
+	 * @return True if outer joined rows can be locked via <tt>FOR UPDATE</tt>.
+	 */
+	public boolean supportsOuterJoinForUpdate() {
+		return true;
+	}
+
+	/**
+	 * Get the <tt>FOR UPDATE OF column_list</tt> fragment appropriate for this
+	 * dialect given the aliases of the columns to be write locked.
+	 *
+	 * @param aliases The columns to be write locked.
+	 * @return The appropriate <tt>FOR UPDATE OF column_list</tt> clause string.
+	 */
+	public String getForUpdateString(String aliases) {
+		// by default we simply return the getForUpdateString() result since
+		// the default is to say no support for "FOR UPDATE OF ..."
+		return getForUpdateString();
+	}
+
+	/**
+	 * Retrieves the <tt>FOR UPDATE NOWAIT</tt> syntax specific to this dialect.
+	 *
+	 * @return The appropriate <tt>FOR UPDATE NOWAIT</tt> clause string.
+	 */
+	public String getForUpdateNowaitString() {
+		// by default we report no support for NOWAIT lock semantics
+		return getForUpdateString();
+	}
+
+	/**
+	 * Get the <tt>FOR UPDATE OF column_list NOWAIT</tt> fragment appropriate
+	 * for this dialect given the aliases of the columns to be write locked.
+	 *
+	 * @param aliases The columns to be write locked.
+	 * @return The appropriate <tt>FOR UPDATE colunm_list NOWAIT</tt> clause string.
+	 */
+	public String getForUpdateNowaitString(String aliases) {
+		return getForUpdateString( aliases );
+	}
+
+	/**
+	 * Some dialects support an alternative means to <tt>SELECT FOR UPDATE</tt>,
+	 * whereby a "lock hint" is appends to the table name in the from clause.
+	 * <p/>
+	 * contributed by <a href="http://sourceforge.net/users/heschulz">Helge Schulz</a>
+	 *
+	 * @param mode The lock mode to apply
+	 * @param tableName The name of the table to which to apply the lock hint.
+	 * @return The table with any required lock hints.
+	 */
+	public String appendLockHint(LockMode mode, String tableName) {
+		return tableName;
+	}
+
+	/**
+	 * Modifies the given SQL by applying the appropriate updates for the specified
+	 * lock modes and key columns.
+	 * <p/>
+	 * The behavior here is that of an ANSI SQL <tt>SELECT FOR UPDATE</tt>.  This
+	 * method is really intended to allow dialects which do not support
+	 * <tt>SELECT FOR UPDATE</tt> to achieve this in their own fashion.
+	 *
+	 * @param sql the SQL string to modify
+	 * @param aliasedLockModes a map of lock modes indexed by aliased table names.
+	 * @param keyColumnNames a map of key columns indexed by aliased table names.
+	 * @return the modified SQL string.
+	 */
+	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
+		return sql + new ForUpdateFragment( this, aliasedLockModes, keyColumnNames ).toFragmentString();
+	}
+
+
+	// table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Command used to create a table.
+	 *
+	 * @return The command used to create a table.
+	 */
+	public String getCreateTableString() {
+		return "create table";
+	}
+
+	/**
+	 * Slight variation on {@link #getCreateTableString}.  Here, we have the
+	 * command used to create a table when there is no primary key and
+	 * duplicate rows are expected.
+	 * <p/>
+	 * Most databases do not care about the distinction; originally added for
+	 * Teradata support which does care.
+	 *
+	 * @return The command used to create a multiset table.
+	 */
+	public String getCreateMultisetTableString() {
+		return getCreateTableString();
+	}
+
+
+	// temporary table support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support temporary tables?
+	 *
+	 * @return True if temp tables are supported; false otherwise.
+	 */
+	public boolean supportsTemporaryTables() {
+		return false;
+	}
+
+	/**
+	 * Generate a temporary table name given the bas table.
+	 *
+	 * @param baseTableName The table name from which to base the temp table name.
+	 * @return The generated temp table name.
+	 */
+	public String generateTemporaryTableName(String baseTableName) {
+		return "HT_" + baseTableName;
+	}
+
+	/**
+	 * Command used to create a temporary table.
+	 *
+	 * @return The command used to create a temporary table.
+	 */
+	public String getCreateTemporaryTableString() {
+		return "create table";
+	}
+
+	/**
+	 * Get any fragments needing to be postfixed to the command for
+	 * temporary table creation.
+	 *
+	 * @return Any required postfix.
+	 */
+	public String getCreateTemporaryTablePostfix() {
+		return "";
+	}
+
+	/**
+	 * Does the dialect require that temporary table DDL statements occur in
+	 * isolation from other statements?  This would be the case if the creation
+	 * would cause any current transaction to get committed implicitly.
+	 * <p/>
+	 * JDBC defines a standard way to query for this information via the
+	 * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}
+	 * method.  However, that does not distinguish between temporary table
+	 * DDL and other forms of DDL; MySQL, for example, reports DDL causing a
+	 * transaction commit via its driver, even though that is not the case for
+	 * temporary table DDL.
+	 * <p/>
+	 * Possible return values and their meanings:<ul>
+	 * <li>{@link Boolean#TRUE} - Unequivocally, perform the temporary table DDL
+	 * in isolation.</li>
+	 * <li>{@link Boolean#FALSE} - Unequivocally, do <b>not</b> perform the
+	 * temporary table DDL in isolation.</li>
+	 * <li><i>null</i> - defer to the JDBC driver response in regards to
+	 * {@link java.sql.DatabaseMetaData#dataDefinitionCausesTransactionCommit()}</li>
+	 * </ul>
+	 * 
+	 * @return see the result matrix above.
+	 */
+	public Boolean performTemporaryTableDDLInIsolation() {
+		return null;
+	}
+
+	/**
+	 * Do we need to drop the temporary table after use?
+	 *
+	 * @return True if the table should be dropped.
+	 */
+	public boolean dropTemporaryTableAfterUse() {
+		return true;
+	}
+
+
+	// callable statement support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Registers an OUT parameter which will be returing a
+	 * {@link java.sql.ResultSet}.  How this is accomplished varies greatly
+	 * from DB to DB, hence its inclusion (along with {@link #getResultSet}) here.
+	 *
+	 * @param statement The callable statement.
+	 * @param position The bind position at which to register the OUT param.
+	 * @return The number of (contiguous) bind positions used.
+	 * @throws SQLException Indicates problems registering the OUT param.
+	 */
+	public int registerResultSetOutParameter(CallableStatement statement, int position) throws SQLException {
+		throw new UnsupportedOperationException(
+				getClass().getName() +
+				" does not support resultsets via stored procedures"
+			);
+	}
+
+	/**
+	 * Given a callable statement previously processed by {@link #registerResultSetOutParameter},
+	 * extract the {@link java.sql.ResultSet} from the OUT parameter.
+	 *
+	 * @param statement The callable statement.
+	 * @return The extracted result set.
+	 * @throws SQLException Indicates problems extracting the result set.
+	 */
+	public ResultSet getResultSet(CallableStatement statement) throws SQLException {
+		throw new UnsupportedOperationException(
+				getClass().getName() +
+				" does not support resultsets via stored procedures"
+			);
+	}
+
+	// current timestamp support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support a way to retrieve the database's current
+	 * timestamp value?
+	 *
+	 * @return True if the current timestamp can be retrieved; false otherwise.
+	 */
+	public boolean supportsCurrentTimestampSelection() {
+		return false;
+	}
+
+	/**
+	 * Should the value returned by {@link #getCurrentTimestampSelectString}
+	 * be treated as callable.  Typically this indicates that JDBC escape
+	 * sytnax is being used...
+	 *
+	 * @return True if the {@link #getCurrentTimestampSelectString} return
+	 * is callable; false otherwise.
+	 */
+	public boolean isCurrentTimestampSelectStringCallable() {
+		throw new UnsupportedOperationException( "Database not known to define a current timestamp function" );
+	}
+
+	/**
+	 * Retrieve the command used to retrieve the current timestammp from the
+	 * database.
+	 *
+	 * @return The command.
+	 */
+	public String getCurrentTimestampSelectString() {
+		throw new UnsupportedOperationException( "Database not known to define a current timestamp function" );
+	}
+
+	/**
+	 * The name of the database-specific SQL function for retrieving the
+	 * current timestamp.
+	 *
+	 * @return The function name.
+	 */
+	public String getCurrentTimestampSQLFunctionName() {
+		// the standard SQL function name is current_timestamp...
+		return "current_timestamp";
+	}
+
+
+	// SQLException support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Build an instance of the SQLExceptionConverter preferred by this dialect for
+	 * converting SQLExceptions into Hibernate's JDBCException hierarchy.  The default
+	 * Dialect implementation simply returns a converter based on X/Open SQLState codes.
+	 * <p/>
+	 * It is strongly recommended that specific Dialect implementations override this
+	 * method, since interpretation of a SQL error is much more accurate when based on
+	 * the ErrorCode rather than the SQLState.  Unfortunately, the ErrorCode is a vendor-
+	 * specific approach.
+	 *
+	 * @return The Dialect's preferred SQLExceptionConverter.
+	 */
+	public SQLExceptionConverter buildSQLExceptionConverter() {
+		// The default SQLExceptionConverter for all dialects is based on SQLState
+		// since SQLErrorCode is extremely vendor-specific.  Specific Dialects
+		// may override to return whatever is most appropriate for that vendor.
+		return new SQLStateConverter( getViolatedConstraintNameExtracter() );
+	}
+
+	private static final ViolatedConstraintNameExtracter EXTRACTER = new ViolatedConstraintNameExtracter() {
+		public String extractConstraintName(SQLException sqle) {
+			return null;
+		}
+	};
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+		return EXTRACTER;
+	}
+
+
+	// union subclass support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Given a {@link java.sql.Types} type code, determine an appropriate
+	 * null value to use in a select clause.
+	 * <p/>
+	 * One thing to consider here is that certain databases might
+	 * require proper casting for the nulls here since the select here
+	 * will be part of a UNION/UNION ALL.
+	 *
+	 * @param sqlType The {@link java.sql.Types} type code.
+	 * @return The appropriate select clause value fragment.
+	 */
+	public String getSelectClauseNullString(int sqlType) {
+		return "null";
+	}
+
+	/**
+	 * Does this dialect support UNION ALL, which is generally a faster
+	 * variant of UNION?
+	 *
+	 * @return True if UNION ALL is supported; false otherwise.
+	 */
+	public boolean supportsUnionAll() {
+		return false;
+	}
+
+
+	// miscellaneous support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+	/**
+	 * Create a {@link org.hibernate.sql.JoinFragment} strategy responsible
+	 * for handling this dialect's variations in how joins are handled.
+	 *
+	 * @return This dialect's {@link org.hibernate.sql.JoinFragment} strategy.
+	 */
+	public JoinFragment createOuterJoinFragment() {
+		return new ANSIJoinFragment();
+	}
+
+	/**
+	 * Create a {@link org.hibernate.sql.CaseFragment} strategy responsible
+	 * for handling this dialect's variations in how CASE statements are
+	 * handled.
+	 *
+	 * @return This dialect's {@link org.hibernate.sql.CaseFragment} strategy.
+	 */
+	public CaseFragment createCaseFragment() {
+		return new ANSICaseFragment();
+	}
+
+	/**
+	 * The fragment used to insert a row without specifying any column values.
+	 * This is not possible on some databases.
+	 *
+	 * @return The appropriate empty values clause.
+	 */
+	public String getNoColumnsInsertString() {
+		return "values ( )";
+	}
+
+	/**
+	 * The name of the SQL function that transforms a string to
+	 * lowercase
+	 *
+	 * @return The dialect-specific lowercase function.
+	 */
+	public String getLowercaseFunction() {
+		return "lower";
+	}
+
+	/**
+	 * Meant as a means for end users to affect the select strings being sent
+	 * to the database and perhaps manipulate them in some fashion.
+	 * <p/>
+	 * The recommend approach is to instead use
+	 * {@link org.hibernate.Interceptor#onPrepareStatement(String)}.
+	 *
+	 * @param select The select command
+	 * @return The mutated select command, or the same as was passed in.
+	 */
+	public String transformSelectString(String select) {
+		return select;
+	}
+
+	/**
+	 * What is the maximum length Hibernate can use for generated aliases?
+	 *
+	 * @return The maximum length.
+	 */
+	public int getMaxAliasLength() {
+		return 10;
+	}
+
+	/**
+	 * The SQL literal value to which this database maps boolean values.
+	 *
+	 * @param bool The boolean value
+	 * @return The appropriate SQL literal.
+	 */
+	public String toBooleanValueString(boolean bool) {
+		return bool ? "1" : "0";
+	}
+
+
+	// identifier quoting support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * The character specific to this dialect used to begin a quoted identifier.
+	 *
+	 * @return The dialect's specific open quote character.
+	 */
+	public char openQuote() {
+		return '"';
+	}
+
+	/**
+	 * The character specific to this dialect used to close a quoted identifier.
+	 *
+	 * @return The dialect's specific close quote character.
+	 */
+	public char closeQuote() {
+		return '"';
+	}
+
+	/**
+	 * Apply dialect-specific quoting.
+	 * <p/>
+	 * By default, the incoming value is checked to see if its first character
+	 * is the back-tick (`).  If so, the dialect specific quoting is applied.
+	 *
+	 * @param column The value to be quoted.
+	 * @return The quoted (or unmodified, if not starting with back-tick) value.
+	 * @see #openQuote()
+	 * @see #closeQuote()
+	 */
+	public final String quote(String column) {
+		if ( column.charAt( 0 ) == '`' ) {
+			return openQuote() + column.substring( 1, column.length() - 1 ) + closeQuote();
+		}
+		else {
+			return column;
+		}
+	}
+
+
+	// DDL support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support the <tt>ALTER TABLE</tt> syntax?
+	 *
+	 * @return True if we support altering of tables; false otherwise.
+	 */
+	public boolean hasAlterTable() {
+		return true;
+	}
+
+	/**
+	 * Do we need to drop constraints before dropping tables in this dialect?
+	 *
+	 * @return True if constraints must be dropped prior to dropping
+	 * the table; false otherwise.
+	 */
+	public boolean dropConstraints() {
+		return true;
+	}
+
+	/**
+	 * Do we need to qualify index names with the schema name?
+	 *
+	 * @return boolean
+	 */
+	public boolean qualifyIndexName() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support the <tt>UNIQUE</tt> column syntax?
+	 *
+	 * @return boolean
+	 */
+	public boolean supportsUnique() {
+		return true;
+	}
+
+    /**
+     * Does this dialect support adding Unique constraints via create and alter table ?
+     * @return boolean
+     */
+	public boolean supportsUniqueConstraintInCreateAlterTable() {
+	    return true;
+	}
+
+	/**
+	 * The syntax used to add a column to a table (optional).
+	 *
+	 * @return The "add column" fragment.
+	 */
+	public String getAddColumnString() {
+		throw new UnsupportedOperationException( "No add column syntax supported by Dialect" );
+	}
+
+	public String getDropForeignKeyString() {
+		return " drop constraint ";
+	}
+
+	public String getTableTypeString() {
+		// grrr... for differentiation of mysql storage engines
+		return "";
+	}
+
+	/**
+	 * The syntax used to add a foreign key constraint to a table.
+	 *
+	 * @param constraintName The FK constraint name.
+	 * @param foreignKey The names of the columns comprising the FK
+	 * @param referencedTable The table referenced by the FK
+	 * @param primaryKey The explicit columns in the referencedTable referenced
+	 * by this FK.
+	 * @param referencesPrimaryKey if false, constraint should be
+	 * explicit about which column names the constraint refers to
+	 *
+	 * @return the "add FK" fragment
+	 */
+	public String getAddForeignKeyConstraintString(
+			String constraintName,
+			String[] foreignKey,
+			String referencedTable,
+			String[] primaryKey,
+			boolean referencesPrimaryKey) {
+		StringBuffer res = new StringBuffer( 30 );
+
+		res.append( " add constraint " )
+				.append( constraintName )
+				.append( " foreign key (" )
+				.append( StringHelper.join( ", ", foreignKey ) )
+				.append( ") references " )
+				.append( referencedTable );
+
+		if ( !referencesPrimaryKey ) {
+			res.append( " (" )
+					.append( StringHelper.join( ", ", primaryKey ) )
+					.append( ')' );
+		}
+
+		return res.toString();
+	}
+
+	/**
+	 * The syntax used to add a primary key constraint to a table.
+	 *
+	 * @param constraintName The name of the PK constraint.
+	 * @return The "add PK" fragment
+	 */
+	public String getAddPrimaryKeyConstraintString(String constraintName) {
+		return " add constraint " + constraintName + " primary key ";
+	}
+
+	public boolean hasSelfReferentialForeignKeyBug() {
+		return false;
+	}
+
+	/**
+	 * The keyword used to specify a nullable column.
+	 *
+	 * @return String
+	 */
+	public String getNullColumnString() {
+		return "";
+	}
+
+	public boolean supportsCommentOn() {
+		return false;
+	}
+
+	public String getTableComment(String comment) {
+		return "";
+	}
+
+	public String getColumnComment(String comment) {
+		return "";
+	}
+
+	public boolean supportsIfExistsBeforeTableName() {
+		return false;
+	}
+
+	public boolean supportsIfExistsAfterTableName() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support column-level check constraints?
+	 *
+	 * @return True if column-level CHECK constraints are supported; false
+	 * otherwise.
+	 */
+	public boolean supportsColumnCheck() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support table-level check constraints?
+	 *
+	 * @return True if table-level CHECK constraints are supported; false
+	 * otherwise.
+	 */
+	public boolean supportsTableCheck() {
+		return true;
+	}
+
+	public boolean supportsCascadeDelete() {
+		return true;
+	}
+
+	public boolean supportsNotNullUnique() {
+		return true;
+	}
+
+	/**
+	 * Completely optional cascading drop clause
+	 *
+	 * @return String
+	 */
+	public String getCascadeConstraintsString() {
+		return "";
+	}
+
+
+	// Informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Does this dialect support empty IN lists?
+	 * <p/>
+	 * For example, is [where XYZ in ()] a supported construct?
+	 *
+	 * @return True if empty in lists are supported; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsEmptyInList() {
+		return true;
+	}
+
+	/**
+	 * Are string comparisons implicitly case insensitive.
+	 * <p/>
+	 * In other words, does [where 'XYZ' = 'xyz'] resolve to true?
+	 *
+	 * @return True if comparisons are case insensitive.
+	 * @since 3.2
+	 */
+	public boolean areStringComparisonsCaseInsensitive() {
+		return false;
+	}
+
+	/**
+	 * Is this dialect known to support what ANSI-SQL terms "row value
+	 * constructor" syntax; sometimes called tuple syntax.
+	 * <p/>
+	 * Basically, does it support syntax like
+	 * "... where (FIRST_NAME, LAST_NAME) = ('Steve', 'Ebersole') ...".
+	 *
+	 * @return True if this SQL dialect is known to support "row value
+	 * constructor" syntax; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsRowValueConstructorSyntax() {
+		// return false here, as most databases do not properly support this construct...
+		return false;
+	}
+
+	/**
+	 * If the dialect supports {@link #supportsRowValueConstructorSyntax() row values},
+	 * does it offer such support in IN lists as well?
+	 * <p/>
+	 * For example, "... where (FIRST_NAME, LAST_NAME) IN ( (?, ?), (?, ?) ) ..."
+	 *
+	 * @return True if this SQL dialect is known to support "row value
+	 * constructor" syntax in the IN list; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsRowValueConstructorSyntaxInInList() {
+		return false;
+	}
+
+	/**
+	 * Should LOBs (both BLOB and CLOB) be bound using stream operations (i.e.
+	 * {@link java.sql.PreparedStatement#setBinaryStream}).
+	 *
+	 * @return True if BLOBs and CLOBs should be bound using stream operations.
+	 * @since 3.2
+	 */
+	public boolean useInputStreamToInsertBlob() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support parameters within the select clause of
+	 * INSERT ... SELECT ... statements?
+	 *
+	 * @return True if this is supported; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsParametersInInsertSelect() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support asking the result set its positioning
+	 * information on forward only cursors.  Specifically, in the case of
+	 * scrolling fetches, Hibernate needs to use
+	 * {@link java.sql.ResultSet#isAfterLast} and
+	 * {@link java.sql.ResultSet#isBeforeFirst}.  Certain drivers do not
+	 * allow access to these methods for forward only cursors.
+	 * <p/>
+	 * NOTE : this is highly driver dependent!
+	 *
+	 * @return True if methods like {@link java.sql.ResultSet#isAfterLast} and
+	 * {@link java.sql.ResultSet#isBeforeFirst} are supported for forward
+	 * only cursors; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support definition of cascade delete constraints
+	 * which can cause circular chains?
+	 *
+	 * @return True if circular cascade delete constraints are supported; false
+	 * otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsCircularCascadeDeleteConstraints() {
+		return true;
+	}
+
+	/**
+	 * Are subselects supported as the left-hand-side (LHS) of
+	 * IN-predicates.
+	 * <p/>
+	 * In other words, is syntax like "... <subquery> IN (1, 2, 3) ..." supported?
+	 *
+	 * @return True if subselects can appear as the LHS of an in-predicate;
+	 * false otherwise.
+	 * @since 3.2
+	 */
+	public boolean  supportsSubselectAsInPredicateLHS() {
+		return true;
+	}
+
+	/**
+	 * Expected LOB usage pattern is such that I can perform an insert
+	 * via prepared statement with a parameter binding for a LOB value
+	 * without crazy casting to JDBC driver implementation-specific classes...
+	 * <p/>
+	 * Part of the trickiness here is the fact that this is largely
+	 * driver dependent.  For example, Oracle (which is notoriously bad with
+	 * LOB support in their drivers historically) actually does a pretty good
+	 * job with LOB support as of the 10.2.x versions of their drivers...
+	 *
+	 * @return True if normal LOB usage patterns can be used with this driver;
+	 * false if driver-specific hookiness needs to be applied.
+	 * @since 3.2
+	 */
+	public boolean supportsExpectedLobUsagePattern() {
+		return true;
+	}
+
+	/**
+	 * Does the dialect support propogating changes to LOB
+	 * values back to the database?  Talking about mutating the
+	 * internal value of the locator as opposed to supplying a new
+	 * locator instance...
+	 * <p/>
+	 * For BLOBs, the internal value might be changed by:
+	 * {@link java.sql.Blob#setBinaryStream},
+	 * {@link java.sql.Blob#setBytes(long, byte[])},
+	 * {@link java.sql.Blob#setBytes(long, byte[], int, int)},
+	 * or {@link java.sql.Blob#truncate(long)}.
+	 * <p/>
+	 * For CLOBs, the internal value might be changed by:
+	 * {@link java.sql.Clob#setAsciiStream(long)},
+	 * {@link java.sql.Clob#setCharacterStream(long)},
+	 * {@link java.sql.Clob#setString(long, String)},
+	 * {@link java.sql.Clob#setString(long, String, int, int)},
+	 * or {@link java.sql.Clob#truncate(long)}.
+	 * <p/>
+	 * NOTE : I do not know the correct answer currently for
+	 * databases which (1) are not part of the cruise control process
+	 * or (2) do not {@link #supportsExpectedLobUsagePattern}.
+	 *
+	 * @return True if the changes are propogated back to the
+	 * database; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsLobValueChangePropogation() {
+		return true;
+	}
+
+	/**
+	 * Is it supported to materialize a LOB locator outside the transaction in
+	 * which it was created?
+	 * <p/>
+	 * Again, part of the trickiness here is the fact that this is largely
+	 * driver dependent.
+	 * <p/>
+	 * NOTE: all database I have tested which {@link #supportsExpectedLobUsagePattern()}
+	 * also support the ability to materialize a LOB outside the owning transaction...
+	 *
+	 * @return True if unbounded materialization is supported; false otherwise.
+	 * @since 3.2
+	 */
+	public boolean supportsUnboundedLobLocatorMaterialization() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support referencing the table being mutated in
+	 * a subquery.  The "table being mutated" is the table referenced in
+	 * an UPDATE or a DELETE query.  And so can that table then be
+	 * referenced in a subquery of said UPDATE/DELETE query.
+	 * <p/>
+	 * For example, would the following two syntaxes be supported:<ul>
+	 * <li>delete from TABLE_A where ID not in ( select ID from TABLE_A )</li>
+	 * <li>update TABLE_A set NON_ID = 'something' where ID in ( select ID from TABLE_A)</li>
+	 * </ul>
+	 *
+	 * @return True if this dialect allows references the mutating table from
+	 * a subquery.
+	 */
+	public boolean supportsSubqueryOnMutatingTable() {
+		return true;
+	}
+
+	/**
+	 * Does the dialect support an exists statement in the select clause?
+	 *
+	 * @return True if exists checks are allowed in the select clause; false otherwise.
+	 */
+	public boolean supportsExistsInSelect() {
+		return true;
+	}
+
+	/**
+	 * For the underlying database, is READ_COMMITTED isolation implemented by
+	 * forcing readers to wait for write locks to be released?
+	 *
+	 * @return True if writers block readers to achieve READ_COMMITTED; false otherwise.
+	 */
+	public boolean doesReadCommittedCauseWritersToBlockReaders() {
+		return false;
+	}
+
+	/**
+	 * For the underlying database, is REPEATABLE_READ isolation implemented by
+	 * forcing writers to wait for read locks to be released?
+	 *
+	 * @return True if readers block writers to achieve REPEATABLE_READ; false otherwise.
+	 */
+	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support using a JDBC bind parameter as an argument
+	 * to a function or procedure call?
+	 *
+	 * @return True if the database supports accepting bind params as args; false otherwise.
+	 */
+	public boolean supportsBindAsCallableArgument() {
+		return true;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,156 +0,0 @@
-// $Id: DialectFactory.java 9789 2006-04-25 17:06:55Z epbernard $
-package org.hibernate.dialect;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A factory for generating Dialect instances.
- *
- * @author Steve Ebersole
- */
-public class DialectFactory {
-
-	/**
-	 * Builds an appropriate Dialect instance.
-	 * <p/>
-	 * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, the database name and version
-	 * (obtained from connection metadata) are used to make the dertemination.
-	 * <p/>
-	 * An exception is thrown if a dialect was not explicitly set and the database name is not known.
-	 *
-	 * @param props The configuration properties.
-	 * @param databaseName The name of the database product (obtained from metadata).
-	 * @param databaseMajorVersion The major version of the database product (obtained from metadata).
-	 *
-	 * @return The appropriate dialect.
-	 *
-	 * @throws HibernateException No dialect specified and database name not known.
-	 */
-	public static Dialect buildDialect(Properties props, String databaseName, int databaseMajorVersion)
-	        throws HibernateException {
-		String dialectName = props.getProperty( Environment.DIALECT );
-		if ( dialectName == null ) {
-			return determineDialect( databaseName, databaseMajorVersion );
-		}
-		else {
-			return buildDialect( dialectName );
-		}
-	}
-
-	/**
-	 * Determine the appropriate Dialect to use given the database product name
-	 * and major version.
-	 *
-	 * @param databaseName The name of the database product (obtained from metadata).
-	 * @param databaseMajorVersion The major version of the database product (obtained from metadata).
-	 *
-	 * @return An appropriate dialect instance.
-	 */
-	public static Dialect determineDialect(String databaseName, int databaseMajorVersion) {
-		if ( databaseName == null ) {
-			throw new HibernateException( "Hibernate Dialect must be explicitly set" );
-		}
-
-		DatabaseDialectMapper mapper = ( DatabaseDialectMapper ) MAPPERS.get( databaseName );
-		if ( mapper == null ) {
-			throw new HibernateException( "Hibernate Dialect must be explicitly set for database: " + databaseName );
-		}
-
-		String dialectName = mapper.getDialectClass( databaseMajorVersion );
-		return buildDialect( dialectName );
-	}
-
-	/**
-	 * Returns a dialect instance given the name of the class to use.
-	 *
-	 * @param dialectName The name of the dialect class.
-	 *
-	 * @return The dialect instance.
-	 */
-	public static Dialect buildDialect(String dialectName) {
-		try {
-			return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
-		}
-		catch ( ClassNotFoundException cnfe ) {
-			throw new HibernateException( "Dialect class not found: " + dialectName );
-		}
-		catch ( Exception e ) {
-			throw new HibernateException( "Could not instantiate dialect class", e );
-		}
-	}
-
-	/**
-	 * For a given database product name, instances of
-	 * DatabaseDialectMapper know which Dialect to use for different versions.
-	 */
-	public static interface DatabaseDialectMapper {
-		public String getDialectClass(int majorVersion);
-	}
-
-	/**
-	 * A simple DatabaseDialectMapper for dialects which are independent
-	 * of the underlying database product version.
-	 */
-	public static class VersionInsensitiveMapper implements DatabaseDialectMapper {
-		private String dialectClassName;
-
-		public VersionInsensitiveMapper(String dialectClassName) {
-			this.dialectClassName = dialectClassName;
-		}
-
-		public String getDialectClass(int majorVersion) {
-			return dialectClassName;
-		}
-	}
-
-	// TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
-	private static final Map MAPPERS = new HashMap();
-	static {
-		// detectors...
-		MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
-		MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
-		MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
-		MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
-		MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
-
-		MAPPERS.put( "Ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
-		MAPPERS.put( "ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
-		MAPPERS.put( "INGRES", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
-
-		MAPPERS.put( "Microsoft SQL Server Database", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
-		MAPPERS.put( "Microsoft SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
-		MAPPERS.put( "Sybase SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
-		MAPPERS.put( "Adaptive Server Enterprise", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
-
-		MAPPERS.put( "Informix Dynamic Server", new VersionInsensitiveMapper( "org.hibernate.dialect.InformixDialect" ) );
-
-		// thanks goodness for "universal" databases...
-		MAPPERS.put( "DB2/NT", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/LINUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/6000", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/HPUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/SUN", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/LINUX390", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-		MAPPERS.put( "DB2/AIX64", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
-
-		MAPPERS.put(
-		        "Oracle",
-		        new DatabaseDialectMapper() {
-			        public String getDialectClass(int majorVersion) {
-						switch ( majorVersion ) {
-							case 8: return Oracle8iDialect.class.getName();
-							case 9: return Oracle9iDialect.class.getName();
-							case 10: return Oracle10gDialect.class.getName();
-							default: throw new HibernateException( "unknown Oracle major version [" + majorVersion + "]" );
-						}
-			        }
-		        }
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/DialectFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/DialectFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,179 @@
+/*
+ * 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.dialect;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A factory for generating Dialect instances.
+ *
+ * @author Steve Ebersole
+ */
+public class DialectFactory {
+
+	/**
+	 * Builds an appropriate Dialect instance.
+	 * <p/>
+	 * If a dialect is explicitly named in the incoming properties, it is used. Otherwise, the database name and version
+	 * (obtained from connection metadata) are used to make the dertemination.
+	 * <p/>
+	 * An exception is thrown if a dialect was not explicitly set and the database name is not known.
+	 *
+	 * @param props The configuration properties.
+	 * @param databaseName The name of the database product (obtained from metadata).
+	 * @param databaseMajorVersion The major version of the database product (obtained from metadata).
+	 *
+	 * @return The appropriate dialect.
+	 *
+	 * @throws HibernateException No dialect specified and database name not known.
+	 */
+	public static Dialect buildDialect(Properties props, String databaseName, int databaseMajorVersion)
+	        throws HibernateException {
+		String dialectName = props.getProperty( Environment.DIALECT );
+		if ( dialectName == null ) {
+			return determineDialect( databaseName, databaseMajorVersion );
+		}
+		else {
+			return buildDialect( dialectName );
+		}
+	}
+
+	/**
+	 * Determine the appropriate Dialect to use given the database product name
+	 * and major version.
+	 *
+	 * @param databaseName The name of the database product (obtained from metadata).
+	 * @param databaseMajorVersion The major version of the database product (obtained from metadata).
+	 *
+	 * @return An appropriate dialect instance.
+	 */
+	public static Dialect determineDialect(String databaseName, int databaseMajorVersion) {
+		if ( databaseName == null ) {
+			throw new HibernateException( "Hibernate Dialect must be explicitly set" );
+		}
+
+		DatabaseDialectMapper mapper = ( DatabaseDialectMapper ) MAPPERS.get( databaseName );
+		if ( mapper == null ) {
+			throw new HibernateException( "Hibernate Dialect must be explicitly set for database: " + databaseName );
+		}
+
+		String dialectName = mapper.getDialectClass( databaseMajorVersion );
+		return buildDialect( dialectName );
+	}
+
+	/**
+	 * Returns a dialect instance given the name of the class to use.
+	 *
+	 * @param dialectName The name of the dialect class.
+	 *
+	 * @return The dialect instance.
+	 */
+	public static Dialect buildDialect(String dialectName) {
+		try {
+			return ( Dialect ) ReflectHelper.classForName( dialectName ).newInstance();
+		}
+		catch ( ClassNotFoundException cnfe ) {
+			throw new HibernateException( "Dialect class not found: " + dialectName );
+		}
+		catch ( Exception e ) {
+			throw new HibernateException( "Could not instantiate dialect class", e );
+		}
+	}
+
+	/**
+	 * For a given database product name, instances of
+	 * DatabaseDialectMapper know which Dialect to use for different versions.
+	 */
+	public static interface DatabaseDialectMapper {
+		public String getDialectClass(int majorVersion);
+	}
+
+	/**
+	 * A simple DatabaseDialectMapper for dialects which are independent
+	 * of the underlying database product version.
+	 */
+	public static class VersionInsensitiveMapper implements DatabaseDialectMapper {
+		private String dialectClassName;
+
+		public VersionInsensitiveMapper(String dialectClassName) {
+			this.dialectClassName = dialectClassName;
+		}
+
+		public String getDialectClass(int majorVersion) {
+			return dialectClassName;
+		}
+	}
+
+	// TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
+	private static final Map MAPPERS = new HashMap();
+	static {
+		// detectors...
+		MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
+		MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
+		MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
+		MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
+		MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
+
+		MAPPERS.put( "Ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
+		MAPPERS.put( "ingres", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
+		MAPPERS.put( "INGRES", new VersionInsensitiveMapper( "org.hibernate.dialect.IngresDialect" ) );
+
+		MAPPERS.put( "Microsoft SQL Server Database", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
+		MAPPERS.put( "Microsoft SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SQLServerDialect" ) );
+		MAPPERS.put( "Sybase SQL Server", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
+		MAPPERS.put( "Adaptive Server Enterprise", new VersionInsensitiveMapper( "org.hibernate.dialect.SybaseDialect" ) );
+
+		MAPPERS.put( "Informix Dynamic Server", new VersionInsensitiveMapper( "org.hibernate.dialect.InformixDialect" ) );
+
+		// thanks goodness for "universal" databases...
+		MAPPERS.put( "DB2/NT", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/LINUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/6000", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/HPUX", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/SUN", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/LINUX390", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+		MAPPERS.put( "DB2/AIX64", new VersionInsensitiveMapper( "org.hibernate.dialect.DB2Dialect" ) );
+
+		MAPPERS.put(
+		        "Oracle",
+		        new DatabaseDialectMapper() {
+			        public String getDialectClass(int majorVersion) {
+						switch ( majorVersion ) {
+							case 8: return Oracle8iDialect.class.getName();
+							case 9: return Oracle9iDialect.class.getName();
+							case 10: return Oracle10gDialect.class.getName();
+							default: throw new HibernateException( "unknown Oracle major version [" + majorVersion + "]" );
+						}
+			        }
+		        }
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-//$Id: FirebirdDialect.java 4202 2004-08-09 06:38:52Z oneovthafew $
-package org.hibernate.dialect;
-
-/**
- * An SQL dialect for Firebird.
- * @author Reha CENANI
- */
-public class FirebirdDialect extends InterbaseDialect {
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop generator " + sequenceName;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.insert(6, hasOffset ? " first ? skip ?" : " first ?")
-			.toString();
-	}
-
-	public boolean bindLimitParametersFirst() {
-		return true;
-	}
-
-	public boolean bindLimitParametersInReverseOrder() {
-		return true;
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FirebirdDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+/**
+ * An SQL dialect for Firebird.
+ * @author Reha CENANI
+ */
+public class FirebirdDialect extends InterbaseDialect {
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop generator " + sequenceName;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		return new StringBuffer( sql.length()+20 )
+			.append(sql)
+			.insert(6, hasOffset ? " first ? skip ?" : " first ?")
+			.toString();
+	}
+
+	public boolean bindLimitParametersFirst() {
+		return true;
+	}
+
+	public boolean bindLimitParametersInReverseOrder() {
+		return true;
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,91 +0,0 @@
-//$Id: FrontBaseDialect.java 9328 2006-02-23 17:32:47Z steveebersole $
-package org.hibernate.dialect;
-
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.LockMode;
-
-import java.sql.Types;
-
-/**
- * An SQL Dialect for Frontbase.  Assumes you're using the latest version
- * of the FrontBase JDBC driver, available from <tt>http://frontbase.com/</tt>
- * <p>
- * <b>NOTE</b>: The latest JDBC driver is not always included with the
- * latest release of FrontBase.  Download the driver separately, and enjoy
- * the informative release notes.
- * <p>
- * This dialect was tested with JDBC driver version 2.3.1.  This driver
- * contains a bug that causes batches of updates to fail.  (The bug should be
- * fixed in the next release of the JDBC driver.)  If you are using JDBC driver
- * 2.3.1, you can work-around this problem by setting the following in your
- * <tt>hibernate.properties</tt> file: <tt>hibernate.jdbc.batch_size=15</tt>
- *
- * @author Ron Lussier <tt>rlussier at lenscraft.com</tt>
- */
-public class FrontBaseDialect extends Dialect {
-
-	public FrontBaseDialect() {
-		super();
-
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.BIGINT, "longint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "bit varying($l)" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "clob" );
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	public String getCascadeConstraintsString() {
-		return " cascade";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support the <tt>FOR UPDATE</tt> syntax. No!
-	 *
-	 * @return false always. FrontBase doesn't support this syntax,
-	 * which was dropped with SQL92
-	 */
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public String getCurrentTimestampCallString() {
-		// TODO : not sure this is correct, could not find docs on how to do this.
-		return "{?= call current_timestamp}";
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return true;
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/FrontBaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,114 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.LockMode;
+
+import java.sql.Types;
+
+/**
+ * An SQL Dialect for Frontbase.  Assumes you're using the latest version
+ * of the FrontBase JDBC driver, available from <tt>http://frontbase.com/</tt>
+ * <p>
+ * <b>NOTE</b>: The latest JDBC driver is not always included with the
+ * latest release of FrontBase.  Download the driver separately, and enjoy
+ * the informative release notes.
+ * <p>
+ * This dialect was tested with JDBC driver version 2.3.1.  This driver
+ * contains a bug that causes batches of updates to fail.  (The bug should be
+ * fixed in the next release of the JDBC driver.)  If you are using JDBC driver
+ * 2.3.1, you can work-around this problem by setting the following in your
+ * <tt>hibernate.properties</tt> file: <tt>hibernate.jdbc.batch_size=15</tt>
+ *
+ * @author Ron Lussier <tt>rlussier at lenscraft.com</tt>
+ */
+public class FrontBaseDialect extends Dialect {
+
+	public FrontBaseDialect() {
+		super();
+
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.BIGINT, "longint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "bit varying($l)" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "clob" );
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	public String getCascadeConstraintsString() {
+		return " cascade";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support the <tt>FOR UPDATE</tt> syntax. No!
+	 *
+	 * @return false always. FrontBase doesn't support this syntax,
+	 * which was dropped with SQL92
+	 */
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public String getCurrentTimestampCallString() {
+		// TODO : not sure this is correct, could not find docs on how to do this.
+		return "{?= call current_timestamp}";
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return true;
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// Frontbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/H2Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,298 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A dialect compatible with the H2 database.
- * 
- * @author Thomas Mueller
- *
- */
-public class H2Dialect extends Dialect {
-
-    private String querySequenceString;
-    public H2Dialect() {
-        super();
-               
-        querySequenceString = "select sequence_name from information_schema.sequences";
-        try {
-        	// HHH-2300
-            Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" );
-            Integer build = (Integer)constants.getDeclaredField("BUILD_ID" ).get(null);
-            int buildid = build.intValue();
-            if(buildid < 32) {
-                querySequenceString = "select name from information_schema.sequences";
-            }
-        } catch(Throwable e) {
-            // ignore (probably H2 not in the classpath)
-        }
-        registerColumnType(Types.BOOLEAN, "boolean");
-        registerColumnType(Types.BIGINT, "bigint");
-        registerColumnType(Types.BINARY, "binary");
-        registerColumnType(Types.BIT, "bit");
-        registerColumnType(Types.CHAR, "char($l)");
-        registerColumnType(Types.DATE, "date");
-        registerColumnType(Types.DECIMAL, "decimal($p,$s)");
-        registerColumnType(Types.DOUBLE, "double");
-        registerColumnType(Types.FLOAT, "float");
-        registerColumnType(Types.INTEGER, "integer");
-        registerColumnType(Types.LONGVARBINARY, "longvarbinary");
-        registerColumnType(Types.LONGVARCHAR, "longvarchar");
-        registerColumnType(Types.REAL, "real");        
-        registerColumnType(Types.SMALLINT, "smallint");
-        registerColumnType(Types.TINYINT, "tinyint");
-        registerColumnType(Types.TIME, "time");
-        registerColumnType(Types.TIMESTAMP, "timestamp");
-        registerColumnType(Types.VARCHAR, "varchar($l)");
-        registerColumnType(Types.VARBINARY, "binary($l)");
-        registerColumnType(Types.NUMERIC, "numeric");
-        registerColumnType(Types.BLOB, "blob");
-        registerColumnType(Types.CLOB, "clob");
-        
-        // select topic, syntax from information_schema.help
-        // where section like 'Function%' order by section, topic
-
-//        registerFunction("abs", new StandardSQLFunction("abs"));
-        registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE));
-        registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE));
-        registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE));
-        registerFunction("atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE));
-        registerFunction("bitand", new StandardSQLFunction("bitand", Hibernate.INTEGER));
-        registerFunction("bitor", new StandardSQLFunction("bitor", Hibernate.INTEGER));
-        registerFunction("bitxor", new StandardSQLFunction("bitxor", Hibernate.INTEGER));
-        registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.DOUBLE));
-        registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE));
-        registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE));
-        registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE));
-        registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE));
-        registerFunction("floor", new StandardSQLFunction("floor", Hibernate.DOUBLE));
-        registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE));
-        registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE));
-//        registerFunction("mod", new StandardSQLFunction("mod", Hibernate.INTEGER));
-        registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE));
-        registerFunction("power", new StandardSQLFunction("power", Hibernate.DOUBLE));
-        registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE));
-        registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE));
-        registerFunction("round", new StandardSQLFunction("round", Hibernate.DOUBLE));
-        registerFunction("roundmagic", new StandardSQLFunction("roundmagic", Hibernate.DOUBLE));
-        registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER));
-        registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE));
-//        registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE));
-        registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE));
-        registerFunction("truncate", new StandardSQLFunction("truncate", Hibernate.DOUBLE));
-
-        registerFunction("compress", new StandardSQLFunction("compress", Hibernate.BINARY));
-        registerFunction("expand", new StandardSQLFunction("compress", Hibernate.BINARY));
-        registerFunction("decrypt", new StandardSQLFunction("decrypt", Hibernate.BINARY));
-        registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.BINARY));
-        registerFunction("hash", new StandardSQLFunction("hash", Hibernate.BINARY));
-
-        registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER));
-//        registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.INTEGER));
-        registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER));
-        registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "(", "||", ")"));
-        registerFunction("difference", new StandardSQLFunction("difference", Hibernate.INTEGER));
-        registerFunction("hextoraw", new StandardSQLFunction("hextoraw", Hibernate.STRING));
-        registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING));
-        registerFunction("insert", new StandardSQLFunction("lower", Hibernate.STRING));
-        registerFunction("left", new StandardSQLFunction("left", Hibernate.STRING));
-//        registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER));
-//        registerFunction("locate", new StandardSQLFunction("locate", Hibernate.INTEGER));
-//        registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING));
-        registerFunction("lcase", new StandardSQLFunction("lcase", Hibernate.STRING));
-        registerFunction("ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING));
-        registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.INTEGER));
-        registerFunction("position", new StandardSQLFunction("position", Hibernate.INTEGER));
-        registerFunction("rawtohex", new StandardSQLFunction("rawtohex", Hibernate.STRING));
-        registerFunction("repeat", new StandardSQLFunction("repeat", Hibernate.STRING));
-        registerFunction("replace", new StandardSQLFunction("replace", Hibernate.STRING));
-        registerFunction("right", new StandardSQLFunction("right", Hibernate.STRING));
-        registerFunction("rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING));
-        registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING));
-        registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING));
-        registerFunction("stringencode", new StandardSQLFunction("stringencode", Hibernate.STRING));
-        registerFunction("stringdecode", new StandardSQLFunction("stringdecode", Hibernate.STRING));
-//        registerFunction("substring", new StandardSQLFunction("substring", Hibernate.STRING));
-//        registerFunction("upper", new StandardSQLFunction("upper", Hibernate.STRING));
-        registerFunction("ucase", new StandardSQLFunction("ucase", Hibernate.STRING));
-
-        registerFunction("stringtoutf8", new StandardSQLFunction("stringtoutf8", Hibernate.BINARY));
-        registerFunction("utf8tostring", new StandardSQLFunction("utf8tostring", Hibernate.STRING));
-
-        registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE));
-        registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME));
-        registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP));
-        registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER));
-        registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING));
-        registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER));
-        registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER));
-        registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER));
-//        registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER));
-//        registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER));
-//        registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER));
-        registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING));
-        registerFunction("quater", new StandardSQLFunction("quater", Hibernate.INTEGER));
-//        registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER));
-        registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER));
-//        registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER));
-
-        registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE));
-        registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME));
-        registerFunction("curtimestamp", new NoArgSQLFunction("curtimestamp", Hibernate.TIME));
-        registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP));
-
-        registerFunction("database", new NoArgSQLFunction("database", Hibernate.STRING));
-        registerFunction("user", new NoArgSQLFunction("user", Hibernate.STRING));
-
-        getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-
-    }
-
-    public String getAddColumnString() {
-        return "add column";
-    }
-
-    public boolean supportsIdentityColumns() {
-        return true;
-    }
-
-    public String getIdentityColumnString() {
-        return "generated by default as identity"; // not null is implicit
-    }
-
-    public String getIdentitySelectString() {
-        return "call identity()";
-    }
-
-    public String getIdentityInsertString() {
-        return "null";
-    }
-
-    public String getForUpdateString() {
-        return " for update";
-    }
-
-    public boolean supportsUnique() {
-        return true;
-    }
-
-    public boolean supportsLimit() {
-        return true;
-    }
-
-    public String getLimitString(String sql, boolean hasOffset) {
-        return new StringBuffer(sql.length() + 20).
-            append(sql).
-            append(hasOffset ? " limit ? offset ?" : " limit ?").
-            toString();
-    }
-    
-    public boolean bindLimitParametersInReverseOrder() {
-        return true;
-    }    
-
-    public boolean bindLimitParametersFirst() {
-        return false;
-    }
-
-    public boolean supportsIfExistsAfterTableName() {
-        return true;
-    }
-
-    public boolean supportsSequences() {
-        return true;
-    }
-
-	public boolean supportsPooledSequences() {
-		return true;
-	}
-
-    public String getCreateSequenceString(String sequenceName) {
-        return "create sequence " + sequenceName;
-    }
-
-    public String getDropSequenceString(String sequenceName) {
-        return "drop sequence " + sequenceName;
-    }
-
-    public String getSelectSequenceNextValString(String sequenceName) {
-        return "next value for " + sequenceName;
-    }
-
-    public String getSequenceNextValString(String sequenceName) {
-        return "call next value for " + sequenceName;
-    }
-
-    public String getQuerySequencesString() {
-        return querySequenceString;
-    }
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-        return EXTRACTER;
-    }
-
-    private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-
-        /**
-         * Extract the name of the violated constraint from the given SQLException.
-         *
-         * @param sqle The exception that was the result of the constraint violation.
-         * @return The extracted constraint name.
-         */
-        public String extractConstraintName(SQLException sqle) {
-            String constraintName = null;
-            // 23000: Check constraint violation: {0}
-            // 23001: Unique index or primary key violation: {0}
-            if(sqle.getSQLState().startsWith("23")) {
-                String message = sqle.getMessage();
-                int idx = message.indexOf("violation: ");
-                if(idx > 0) {
-                    constraintName = message.substring(idx + "violation: ".length());
-                }
-            }
-            return constraintName;
-        }
-
-    };
-
-    public boolean supportsTemporaryTables() {
-        return true;
-    }
-    
-    public String getCreateTemporaryTableString() {
-        return "create temporary table if not exists";
-    }
-
-    public boolean supportsCurrentTimestampSelection() {
-        return true;
-    }
-    
-    public boolean isCurrentTimestampSelectStringCallable() {
-        return false;
-    }
-    
-    public String getCurrentTimestampSelectString() {
-        return "call current_timestamp()";
-    }    
-    
-    public boolean supportsUnionAll() {
-        return true;
-    }
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsLobValueChangePropogation() {
-		return false;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/H2Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/H2Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,322 @@
+/*
+ * 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.dialect;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A dialect compatible with the H2 database.
+ * 
+ * @author Thomas Mueller
+ *
+ */
+public class H2Dialect extends Dialect {
+
+    private String querySequenceString;
+    public H2Dialect() {
+        super();
+               
+        querySequenceString = "select sequence_name from information_schema.sequences";
+        try {
+        	// HHH-2300
+            Class constants = ReflectHelper.classForName( "org.h2.engine.Constants" );
+            Integer build = (Integer)constants.getDeclaredField("BUILD_ID" ).get(null);
+            int buildid = build.intValue();
+            if(buildid < 32) {
+                querySequenceString = "select name from information_schema.sequences";
+            }
+        } catch(Throwable e) {
+            // ignore (probably H2 not in the classpath)
+        }
+        registerColumnType(Types.BOOLEAN, "boolean");
+        registerColumnType(Types.BIGINT, "bigint");
+        registerColumnType(Types.BINARY, "binary");
+        registerColumnType(Types.BIT, "bit");
+        registerColumnType(Types.CHAR, "char($l)");
+        registerColumnType(Types.DATE, "date");
+        registerColumnType(Types.DECIMAL, "decimal($p,$s)");
+        registerColumnType(Types.DOUBLE, "double");
+        registerColumnType(Types.FLOAT, "float");
+        registerColumnType(Types.INTEGER, "integer");
+        registerColumnType(Types.LONGVARBINARY, "longvarbinary");
+        registerColumnType(Types.LONGVARCHAR, "longvarchar");
+        registerColumnType(Types.REAL, "real");        
+        registerColumnType(Types.SMALLINT, "smallint");
+        registerColumnType(Types.TINYINT, "tinyint");
+        registerColumnType(Types.TIME, "time");
+        registerColumnType(Types.TIMESTAMP, "timestamp");
+        registerColumnType(Types.VARCHAR, "varchar($l)");
+        registerColumnType(Types.VARBINARY, "binary($l)");
+        registerColumnType(Types.NUMERIC, "numeric");
+        registerColumnType(Types.BLOB, "blob");
+        registerColumnType(Types.CLOB, "clob");
+        
+        // select topic, syntax from information_schema.help
+        // where section like 'Function%' order by section, topic
+
+//        registerFunction("abs", new StandardSQLFunction("abs"));
+        registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE));
+        registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE));
+        registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE));
+        registerFunction("atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE));
+        registerFunction("bitand", new StandardSQLFunction("bitand", Hibernate.INTEGER));
+        registerFunction("bitor", new StandardSQLFunction("bitor", Hibernate.INTEGER));
+        registerFunction("bitxor", new StandardSQLFunction("bitxor", Hibernate.INTEGER));
+        registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.DOUBLE));
+        registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE));
+        registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE));
+        registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE));
+        registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE));
+        registerFunction("floor", new StandardSQLFunction("floor", Hibernate.DOUBLE));
+        registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE));
+        registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE));
+//        registerFunction("mod", new StandardSQLFunction("mod", Hibernate.INTEGER));
+        registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE));
+        registerFunction("power", new StandardSQLFunction("power", Hibernate.DOUBLE));
+        registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE));
+        registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE));
+        registerFunction("round", new StandardSQLFunction("round", Hibernate.DOUBLE));
+        registerFunction("roundmagic", new StandardSQLFunction("roundmagic", Hibernate.DOUBLE));
+        registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER));
+        registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE));
+//        registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE));
+        registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE));
+        registerFunction("truncate", new StandardSQLFunction("truncate", Hibernate.DOUBLE));
+
+        registerFunction("compress", new StandardSQLFunction("compress", Hibernate.BINARY));
+        registerFunction("expand", new StandardSQLFunction("compress", Hibernate.BINARY));
+        registerFunction("decrypt", new StandardSQLFunction("decrypt", Hibernate.BINARY));
+        registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.BINARY));
+        registerFunction("hash", new StandardSQLFunction("hash", Hibernate.BINARY));
+
+        registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER));
+//        registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.INTEGER));
+        registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER));
+        registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "(", "||", ")"));
+        registerFunction("difference", new StandardSQLFunction("difference", Hibernate.INTEGER));
+        registerFunction("hextoraw", new StandardSQLFunction("hextoraw", Hibernate.STRING));
+        registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING));
+        registerFunction("insert", new StandardSQLFunction("lower", Hibernate.STRING));
+        registerFunction("left", new StandardSQLFunction("left", Hibernate.STRING));
+//        registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER));
+//        registerFunction("locate", new StandardSQLFunction("locate", Hibernate.INTEGER));
+//        registerFunction("lower", new StandardSQLFunction("lower", Hibernate.STRING));
+        registerFunction("lcase", new StandardSQLFunction("lcase", Hibernate.STRING));
+        registerFunction("ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING));
+        registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.INTEGER));
+        registerFunction("position", new StandardSQLFunction("position", Hibernate.INTEGER));
+        registerFunction("rawtohex", new StandardSQLFunction("rawtohex", Hibernate.STRING));
+        registerFunction("repeat", new StandardSQLFunction("repeat", Hibernate.STRING));
+        registerFunction("replace", new StandardSQLFunction("replace", Hibernate.STRING));
+        registerFunction("right", new StandardSQLFunction("right", Hibernate.STRING));
+        registerFunction("rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING));
+        registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING));
+        registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING));
+        registerFunction("stringencode", new StandardSQLFunction("stringencode", Hibernate.STRING));
+        registerFunction("stringdecode", new StandardSQLFunction("stringdecode", Hibernate.STRING));
+//        registerFunction("substring", new StandardSQLFunction("substring", Hibernate.STRING));
+//        registerFunction("upper", new StandardSQLFunction("upper", Hibernate.STRING));
+        registerFunction("ucase", new StandardSQLFunction("ucase", Hibernate.STRING));
+
+        registerFunction("stringtoutf8", new StandardSQLFunction("stringtoutf8", Hibernate.BINARY));
+        registerFunction("utf8tostring", new StandardSQLFunction("utf8tostring", Hibernate.STRING));
+
+        registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE));
+        registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME));
+        registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP));
+        registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER));
+        registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING));
+        registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER));
+        registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER));
+        registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER));
+//        registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER));
+//        registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER));
+//        registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER));
+        registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING));
+        registerFunction("quater", new StandardSQLFunction("quater", Hibernate.INTEGER));
+//        registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER));
+        registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER));
+//        registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER));
+
+        registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE));
+        registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME));
+        registerFunction("curtimestamp", new NoArgSQLFunction("curtimestamp", Hibernate.TIME));
+        registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP));
+
+        registerFunction("database", new NoArgSQLFunction("database", Hibernate.STRING));
+        registerFunction("user", new NoArgSQLFunction("user", Hibernate.STRING));
+
+        getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+
+    }
+
+    public String getAddColumnString() {
+        return "add column";
+    }
+
+    public boolean supportsIdentityColumns() {
+        return true;
+    }
+
+    public String getIdentityColumnString() {
+        return "generated by default as identity"; // not null is implicit
+    }
+
+    public String getIdentitySelectString() {
+        return "call identity()";
+    }
+
+    public String getIdentityInsertString() {
+        return "null";
+    }
+
+    public String getForUpdateString() {
+        return " for update";
+    }
+
+    public boolean supportsUnique() {
+        return true;
+    }
+
+    public boolean supportsLimit() {
+        return true;
+    }
+
+    public String getLimitString(String sql, boolean hasOffset) {
+        return new StringBuffer(sql.length() + 20).
+            append(sql).
+            append(hasOffset ? " limit ? offset ?" : " limit ?").
+            toString();
+    }
+    
+    public boolean bindLimitParametersInReverseOrder() {
+        return true;
+    }    
+
+    public boolean bindLimitParametersFirst() {
+        return false;
+    }
+
+    public boolean supportsIfExistsAfterTableName() {
+        return true;
+    }
+
+    public boolean supportsSequences() {
+        return true;
+    }
+
+	public boolean supportsPooledSequences() {
+		return true;
+	}
+
+    public String getCreateSequenceString(String sequenceName) {
+        return "create sequence " + sequenceName;
+    }
+
+    public String getDropSequenceString(String sequenceName) {
+        return "drop sequence " + sequenceName;
+    }
+
+    public String getSelectSequenceNextValString(String sequenceName) {
+        return "next value for " + sequenceName;
+    }
+
+    public String getSequenceNextValString(String sequenceName) {
+        return "call next value for " + sequenceName;
+    }
+
+    public String getQuerySequencesString() {
+        return querySequenceString;
+    }
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+        return EXTRACTER;
+    }
+
+    private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+        /**
+         * Extract the name of the violated constraint from the given SQLException.
+         *
+         * @param sqle The exception that was the result of the constraint violation.
+         * @return The extracted constraint name.
+         */
+        public String extractConstraintName(SQLException sqle) {
+            String constraintName = null;
+            // 23000: Check constraint violation: {0}
+            // 23001: Unique index or primary key violation: {0}
+            if(sqle.getSQLState().startsWith("23")) {
+                String message = sqle.getMessage();
+                int idx = message.indexOf("violation: ");
+                if(idx > 0) {
+                    constraintName = message.substring(idx + "violation: ".length());
+                }
+            }
+            return constraintName;
+        }
+
+    };
+
+    public boolean supportsTemporaryTables() {
+        return true;
+    }
+    
+    public String getCreateTemporaryTableString() {
+        return "create temporary table if not exists";
+    }
+
+    public boolean supportsCurrentTimestampSelection() {
+        return true;
+    }
+    
+    public boolean isCurrentTimestampSelectStringCallable() {
+        return false;
+    }
+    
+    public String getCurrentTimestampSelectString() {
+        return "call current_timestamp()";
+    }    
+    
+    public boolean supportsUnionAll() {
+        return true;
+    }
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsLobValueChangePropogation() {
+		return false;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,297 +0,0 @@
-//$Id: HSQLDialect.java 11259 2007-03-07 22:55:12Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.SQLException;
-import java.sql.Types;
-import java.io.Serializable;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.JDBCException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * An SQL dialect compatible with HSQLDB (Hypersonic SQL).
- * <p/>
- * Note this version supports HSQLDB version 1.8 and higher, only.
- *
- * @author Christoph Sturm
- * @author Phillip Baird
- */
-public class HSQLDialect extends Dialect {
-
-	private static final Logger log = LoggerFactory.getLogger( HSQLDialect.class );
-
-	public HSQLDialect() {
-		super();
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.BINARY, "binary" );
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.DECIMAL, "decimal" );
-		registerColumnType( Types.DOUBLE, "double" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
-		registerColumnType( Types.LONGVARCHAR, "longvarchar" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.VARBINARY, "varbinary($l)" );
-		registerColumnType( Types.NUMERIC, "numeric" );
-		//HSQL has no Blob/Clob support .... but just put these here for now!
-		registerColumnType( Types.BLOB, "longvarbinary" );
-		registerColumnType( Types.CLOB, "longvarchar" );
-
-		registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) );
-		registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) );
-		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) );
-		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
-		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
-		registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
-		registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
-		registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) );
-		registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
-		registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
-		registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
-		registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
-		registerFunction( "rawtohex", new StandardSQLFunction( "rawtohex" ) );
-		registerFunction( "hextoraw", new StandardSQLFunction( "hextoraw" ) );
-
-		registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING ) );
-		registerFunction( "database", new NoArgSQLFunction( "database", Hibernate.STRING ) );
-
-		registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
-		registerFunction( "curdate", new NoArgSQLFunction( "curdate", Hibernate.DATE ) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", Hibernate.TIMESTAMP, false ) );
-		registerFunction( "now", new NoArgSQLFunction( "now", Hibernate.TIMESTAMP ) );
-		registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
-		registerFunction( "curtime", new NoArgSQLFunction( "curtime", Hibernate.TIME ) );
-		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
-		registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", Hibernate.INTEGER ) );
-		registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", Hibernate.INTEGER ) );
-		registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", Hibernate.INTEGER ) );
-		registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
-		registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
-		registerFunction( "week", new StandardSQLFunction( "week", Hibernate.INTEGER ) );
-		registerFunction( "quater", new StandardSQLFunction( "quater", Hibernate.INTEGER ) );
-		registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) );
-		registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) );
-		registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) );
-		registerFunction( "dayname", new StandardSQLFunction( "dayname", Hibernate.STRING ) );
-		registerFunction( "monthname", new StandardSQLFunction( "monthname", Hibernate.STRING ) );
-
-		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
-		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
-
-		registerFunction( "acos", new StandardSQLFunction( "acos", Hibernate.DOUBLE ) );
-		registerFunction( "asin", new StandardSQLFunction( "asin", Hibernate.DOUBLE ) );
-		registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
-		registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
-		registerFunction( "cot", new StandardSQLFunction( "cot", Hibernate.DOUBLE ) );
-		registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
-		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) );
-		registerFunction( "log10", new StandardSQLFunction( "log10", Hibernate.DOUBLE ) );
-		registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
-		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
-		registerFunction( "tan", new StandardSQLFunction( "tan", Hibernate.DOUBLE ) );
-		registerFunction( "pi", new NoArgSQLFunction( "pi", Hibernate.DOUBLE ) );
-		registerFunction( "rand", new StandardSQLFunction( "rand", Hibernate.FLOAT ) );
-
-		registerFunction( "radians", new StandardSQLFunction( "radians", Hibernate.DOUBLE ) );
-		registerFunction( "degrees", new StandardSQLFunction( "degrees", Hibernate.DOUBLE ) );
-		registerFunction( "roundmagic", new StandardSQLFunction( "roundmagic" ) );
-
-		registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) );
-		registerFunction( "floor", new StandardSQLFunction( "floor" ) );
-
-		// Multi-param dialect functions...
-		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) );
-
-		// function templates
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
-
-		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-
-	public String getIdentityColumnString() {
-		return "generated by default as identity (start with 1)"; //not null is implicit
-	}
-
-	public String getIdentitySelectString() {
-		return "call identity()";
-	}
-
-	public String getIdentityInsertString() {
-		return "null";
-	}
-
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public boolean supportsUnique() {
-		return false;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length() + 10 )
-				.append( sql )
-				.insert( sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit ? ?" : " top ?" )
-				.toString();
-	}
-
-	public boolean bindLimitParametersFirst() {
-		return true;
-	}
-
-	public boolean supportsIfExistsAfterTableName() {
-		return true;
-	}
-
-	public boolean supportsColumnCheck() {
-		return false;
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public boolean supportsPooledSequences() {
-		return true;
-	}
-
-	protected String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-
-	protected String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return "next value for " + sequenceName;
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "call next value for " + sequenceName;
-	}
-
-	public String getQuerySequencesString() {
-		// this assumes schema support, which is present in 1.8.0 and later...
-		return "select sequence_name from information_schema.system_sequences";
-	}
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-		return EXTRACTER;
-	}
-
-	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-
-		/**
-		 * Extract the name of the violated constraint from the given SQLException.
-		 *
-		 * @param sqle The exception that was the result of the constraint violation.
-		 * @return The extracted constraint name.
-		 */
-		public String extractConstraintName(SQLException sqle) {
-			String constraintName = null;
-
-			int errorCode = JDBCExceptionHelper.extractErrorCode( sqle );
-
-			if ( errorCode == -8 ) {
-				constraintName = extractUsingTemplate(
-						"Integrity constraint violation ", " table:", sqle.getMessage()
-				);
-			}
-			else if ( errorCode == -9 ) {
-				constraintName = extractUsingTemplate(
-						"Violation of unique index: ", " in statement [", sqle.getMessage()
-				);
-			}
-			else if ( errorCode == -104 ) {
-				constraintName = extractUsingTemplate(
-						"Unique constraint violation: ", " in statement [", sqle.getMessage()
-				);
-			}
-			else if ( errorCode == -177 ) {
-				constraintName = extractUsingTemplate(
-						"Integrity constraint violation - no parent ", " table:", sqle.getMessage()
-				);
-			}
-
-			return constraintName;
-		}
-
-	};
-
-	/**
-	 * HSQL does not really support temp tables; just take advantage of the
-	 * fact that it is a single user db...
-	 */
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return false;
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// HSQLDB only supports READ_UNCOMMITTED transaction isolation
-		return new ReadUncommittedLockingStrategy( lockable, lockMode );
-	}
-
-	public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
-		public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) {
-			super( lockable, lockMode );
-		}
-
-		public void lock(Serializable id, Object version, Object object, SessionImplementor session)
-				throws StaleObjectStateException, JDBCException {
-			if ( getLockMode().greaterThan( LockMode.READ ) ) {
-				log.warn( "HSQLDB supports only READ_UNCOMMITTED isolation" );
-			}
-			super.lock( id, version, object, session );
-		}
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsLobValueChangePropogation() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/HSQLDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/HSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,320 @@
+/*
+ * 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.dialect;
+
+import java.sql.SQLException;
+import java.sql.Types;
+import java.io.Serializable;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An SQL dialect compatible with HSQLDB (Hypersonic SQL).
+ * <p/>
+ * Note this version supports HSQLDB version 1.8 and higher, only.
+ *
+ * @author Christoph Sturm
+ * @author Phillip Baird
+ */
+public class HSQLDialect extends Dialect {
+
+	private static final Logger log = LoggerFactory.getLogger( HSQLDialect.class );
+
+	public HSQLDialect() {
+		super();
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.BINARY, "binary" );
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.DECIMAL, "decimal" );
+		registerColumnType( Types.DOUBLE, "double" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.LONGVARBINARY, "longvarbinary" );
+		registerColumnType( Types.LONGVARCHAR, "longvarchar" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.VARBINARY, "varbinary($l)" );
+		registerColumnType( Types.NUMERIC, "numeric" );
+		//HSQL has no Blob/Clob support .... but just put these here for now!
+		registerColumnType( Types.BLOB, "longvarbinary" );
+		registerColumnType( Types.CLOB, "longvarchar" );
+
+		registerFunction( "ascii", new StandardSQLFunction( "ascii", Hibernate.INTEGER ) );
+		registerFunction( "char", new StandardSQLFunction( "char", Hibernate.CHARACTER ) );
+		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) );
+		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
+		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
+		registerFunction( "lcase", new StandardSQLFunction( "lcase" ) );
+		registerFunction( "ucase", new StandardSQLFunction( "ucase" ) );
+		registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) );
+		registerFunction( "ltrim", new StandardSQLFunction( "ltrim" ) );
+		registerFunction( "rtrim", new StandardSQLFunction( "rtrim" ) );
+		registerFunction( "reverse", new StandardSQLFunction( "reverse" ) );
+		registerFunction( "space", new StandardSQLFunction( "space", Hibernate.STRING ) );
+		registerFunction( "rawtohex", new StandardSQLFunction( "rawtohex" ) );
+		registerFunction( "hextoraw", new StandardSQLFunction( "hextoraw" ) );
+
+		registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING ) );
+		registerFunction( "database", new NoArgSQLFunction( "database", Hibernate.STRING ) );
+
+		registerFunction( "current_date", new NoArgSQLFunction( "current_date", Hibernate.DATE, false ) );
+		registerFunction( "curdate", new NoArgSQLFunction( "curdate", Hibernate.DATE ) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction( "current_timestamp", Hibernate.TIMESTAMP, false ) );
+		registerFunction( "now", new NoArgSQLFunction( "now", Hibernate.TIMESTAMP ) );
+		registerFunction( "current_time", new NoArgSQLFunction( "current_time", Hibernate.TIME, false ) );
+		registerFunction( "curtime", new NoArgSQLFunction( "curtime", Hibernate.TIME ) );
+		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
+		registerFunction( "dayofweek", new StandardSQLFunction( "dayofweek", Hibernate.INTEGER ) );
+		registerFunction( "dayofyear", new StandardSQLFunction( "dayofyear", Hibernate.INTEGER ) );
+		registerFunction( "dayofmonth", new StandardSQLFunction( "dayofmonth", Hibernate.INTEGER ) );
+		registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
+		registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
+		registerFunction( "week", new StandardSQLFunction( "week", Hibernate.INTEGER ) );
+		registerFunction( "quater", new StandardSQLFunction( "quater", Hibernate.INTEGER ) );
+		registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) );
+		registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) );
+		registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) );
+		registerFunction( "dayname", new StandardSQLFunction( "dayname", Hibernate.STRING ) );
+		registerFunction( "monthname", new StandardSQLFunction( "monthname", Hibernate.STRING ) );
+
+		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
+		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
+
+		registerFunction( "acos", new StandardSQLFunction( "acos", Hibernate.DOUBLE ) );
+		registerFunction( "asin", new StandardSQLFunction( "asin", Hibernate.DOUBLE ) );
+		registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
+		registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
+		registerFunction( "cot", new StandardSQLFunction( "cot", Hibernate.DOUBLE ) );
+		registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
+		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) );
+		registerFunction( "log10", new StandardSQLFunction( "log10", Hibernate.DOUBLE ) );
+		registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
+		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
+		registerFunction( "tan", new StandardSQLFunction( "tan", Hibernate.DOUBLE ) );
+		registerFunction( "pi", new NoArgSQLFunction( "pi", Hibernate.DOUBLE ) );
+		registerFunction( "rand", new StandardSQLFunction( "rand", Hibernate.FLOAT ) );
+
+		registerFunction( "radians", new StandardSQLFunction( "radians", Hibernate.DOUBLE ) );
+		registerFunction( "degrees", new StandardSQLFunction( "degrees", Hibernate.DOUBLE ) );
+		registerFunction( "roundmagic", new StandardSQLFunction( "roundmagic" ) );
+
+		registerFunction( "ceiling", new StandardSQLFunction( "ceiling" ) );
+		registerFunction( "floor", new StandardSQLFunction( "floor" ) );
+
+		// Multi-param dialect functions...
+		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) );
+
+		// function templates
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
+
+		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+
+	public String getIdentityColumnString() {
+		return "generated by default as identity (start with 1)"; //not null is implicit
+	}
+
+	public String getIdentitySelectString() {
+		return "call identity()";
+	}
+
+	public String getIdentityInsertString() {
+		return "null";
+	}
+
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public boolean supportsUnique() {
+		return false;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		return new StringBuffer( sql.length() + 10 )
+				.append( sql )
+				.insert( sql.toLowerCase().indexOf( "select" ) + 6, hasOffset ? " limit ? ?" : " top ?" )
+				.toString();
+	}
+
+	public boolean bindLimitParametersFirst() {
+		return true;
+	}
+
+	public boolean supportsIfExistsAfterTableName() {
+		return true;
+	}
+
+	public boolean supportsColumnCheck() {
+		return false;
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public boolean supportsPooledSequences() {
+		return true;
+	}
+
+	protected String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+
+	protected String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return "next value for " + sequenceName;
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "call next value for " + sequenceName;
+	}
+
+	public String getQuerySequencesString() {
+		// this assumes schema support, which is present in 1.8.0 and later...
+		return "select sequence_name from information_schema.system_sequences";
+	}
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+		return EXTRACTER;
+	}
+
+	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+		/**
+		 * Extract the name of the violated constraint from the given SQLException.
+		 *
+		 * @param sqle The exception that was the result of the constraint violation.
+		 * @return The extracted constraint name.
+		 */
+		public String extractConstraintName(SQLException sqle) {
+			String constraintName = null;
+
+			int errorCode = JDBCExceptionHelper.extractErrorCode( sqle );
+
+			if ( errorCode == -8 ) {
+				constraintName = extractUsingTemplate(
+						"Integrity constraint violation ", " table:", sqle.getMessage()
+				);
+			}
+			else if ( errorCode == -9 ) {
+				constraintName = extractUsingTemplate(
+						"Violation of unique index: ", " in statement [", sqle.getMessage()
+				);
+			}
+			else if ( errorCode == -104 ) {
+				constraintName = extractUsingTemplate(
+						"Unique constraint violation: ", " in statement [", sqle.getMessage()
+				);
+			}
+			else if ( errorCode == -177 ) {
+				constraintName = extractUsingTemplate(
+						"Integrity constraint violation - no parent ", " table:", sqle.getMessage()
+				);
+			}
+
+			return constraintName;
+		}
+
+	};
+
+	/**
+	 * HSQL does not really support temp tables; just take advantage of the
+	 * fact that it is a single user db...
+	 */
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return false;
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// HSQLDB only supports READ_UNCOMMITTED transaction isolation
+		return new ReadUncommittedLockingStrategy( lockable, lockMode );
+	}
+
+	public static class ReadUncommittedLockingStrategy extends SelectLockingStrategy {
+		public ReadUncommittedLockingStrategy(Lockable lockable, LockMode lockMode) {
+			super( lockable, lockMode );
+		}
+
+		public void lock(Serializable id, Object version, Object object, SessionImplementor session)
+				throws StaleObjectStateException, JDBCException {
+			if ( getLockMode().greaterThan( LockMode.READ ) ) {
+				log.warn( "HSQLDB supports only READ_UNCOMMITTED isolation" );
+			}
+			super.lock( id, version, object, session );
+		}
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsLobValueChangePropogation() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,213 +0,0 @@
-//$Id: InformixDialect.java 11177 2007-02-09 15:43:04Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.MappingException;
-import org.hibernate.Hibernate;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.util.StringHelper;
-
-/**
- * Informix dialect.<br>
- * <br>
- * Seems to work with Informix Dynamic Server Version 7.31.UD3,
- * Informix JDBC driver version 2.21JC3.
- * @author Steve Molitor
- */
-public class InformixDialect extends Dialect {
-
-	/**
-	 * Creates new <code>InformixDialect</code> instance. Sets up the JDBC /
-	 * Informix type mappings.
-	 */
-	public InformixDialect() {
-		super();
-
-		registerColumnType(Types.BIGINT, "int8");
-		registerColumnType(Types.BINARY, "byte");
-		registerColumnType(Types.BIT, "smallint"); // Informix doesn't have a bit type
-		registerColumnType(Types.CHAR, "char($l)");
-		registerColumnType(Types.DATE, "date");
-		registerColumnType(Types.DECIMAL, "decimal");
-        registerColumnType(Types.DOUBLE, "float");
-        registerColumnType(Types.FLOAT, "smallfloat");
-		registerColumnType(Types.INTEGER, "integer");
-		registerColumnType(Types.LONGVARBINARY, "blob"); // or BYTE
-		registerColumnType(Types.LONGVARCHAR, "clob"); // or TEXT?
-		registerColumnType(Types.NUMERIC, "decimal"); // or MONEY
-		registerColumnType(Types.REAL, "smallfloat");
-		registerColumnType(Types.SMALLINT, "smallint");
-		registerColumnType(Types.TIMESTAMP, "datetime year to fraction(5)");
-		registerColumnType(Types.TIME, "datetime hour to second");
-		registerColumnType(Types.TINYINT, "smallint");
-		registerColumnType(Types.VARBINARY, "byte");
-		registerColumnType(Types.VARCHAR, "varchar($l)");
-		registerColumnType(Types.VARCHAR, 255, "varchar($l)");
-		registerColumnType(Types.VARCHAR, 32739, "lvarchar($l)");
-
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-
-	public String getIdentitySelectString(String table, String column, int type) 
-	throws MappingException {
-		return type==Types.BIGINT ?
-			"select dbinfo('serial8') from systables where tabid=1" :
-			"select dbinfo('sqlca.sqlerrd1') from systables where tabid=1";
-	}
-
-	public String getIdentityColumnString(int type) throws MappingException {
-		return type==Types.BIGINT ?
-			"serial8 not null" :
-			"serial not null";
-	}
-
-	public boolean hasDataTypeInIdentityColumn() {
-		return false;
-	}
-
-	/**
-	 * The syntax used to add a foreign key constraint to a table.
-	 * Informix constraint name must be at the end.
-	 * @return String
-	 */
-	public String getAddForeignKeyConstraintString(
-			String constraintName, 
-			String[] foreignKey, 
-			String referencedTable, 
-			String[] primaryKey, boolean referencesPrimaryKey
-	) {
-		StringBuffer result = new StringBuffer(30);
-		
-		result.append(" add constraint ")
-			.append(" foreign key (")
-			.append( StringHelper.join(", ", foreignKey) )
-			.append(") references ")
-			.append(referencedTable);
-		
-		if(!referencesPrimaryKey) {
-			result.append(" (")
-			   .append( StringHelper.join(", ", primaryKey) )
-			   .append(')');
-		}
-
-		result.append(" constraint ").append(constraintName);
-			
-			return result.toString();
-	}
-
-	/**
-	 * The syntax used to add a primary key constraint to a table.
-	 * Informix constraint name must be at the end.
-	 * @return String
-	 */
-	public String getAddPrimaryKeyConstraintString(String constraintName) {
-		return " add constraint primary key constraint " + constraintName + " ";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName + " restrict";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName ) + " from systables where tabid=1";
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public String getLimitString(String querySelect, int offset, int limit) {
-		if (offset>0) throw new UnsupportedOperationException("informix has no offset");
-		return new StringBuffer( querySelect.length()+8 )
-			.append(querySelect)
-			.insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
-			.toString();
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-        return EXTRACTER;
-	}
-
-	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-
-		/**
-		 * Extract the name of the violated constraint from the given SQLException.
-		 *
-		 * @param sqle The exception that was the result of the constraint violation.
-		 * @return The extracted constraint name.
-		 */
-		public String extractConstraintName(SQLException sqle) {
-			String constraintName = null;
-			
-			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
-			if ( errorCode == -268 ) {
-				constraintName = extractUsingTemplate( "Unique constraint (", ") violated.", sqle.getMessage() );
-			}
-			else if ( errorCode == -691 ) {
-				constraintName = extractUsingTemplate( "Missing key in referenced table for referential constraint (", ").", sqle.getMessage() );
-			}
-			else if ( errorCode == -692 ) {
-				constraintName = extractUsingTemplate( "Key value for constraint (", ") is still being referenced.", sqle.getMessage() );
-			}
-			
-			if (constraintName != null) {
-				// strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>"
-				int i = constraintName.indexOf('.');
-				if (i != -1) {
-					constraintName = constraintName.substring(i + 1);
-				}
-			}
-
-			return constraintName;
-		}
-
-	};
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select distinct current timestamp from informix.systables";
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/InformixDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InformixDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,236 @@
+/*
+ * 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.dialect;
+
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.MappingException;
+import org.hibernate.Hibernate;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Informix dialect.<br>
+ * <br>
+ * Seems to work with Informix Dynamic Server Version 7.31.UD3,
+ * Informix JDBC driver version 2.21JC3.
+ * @author Steve Molitor
+ */
+public class InformixDialect extends Dialect {
+
+	/**
+	 * Creates new <code>InformixDialect</code> instance. Sets up the JDBC /
+	 * Informix type mappings.
+	 */
+	public InformixDialect() {
+		super();
+
+		registerColumnType(Types.BIGINT, "int8");
+		registerColumnType(Types.BINARY, "byte");
+		registerColumnType(Types.BIT, "smallint"); // Informix doesn't have a bit type
+		registerColumnType(Types.CHAR, "char($l)");
+		registerColumnType(Types.DATE, "date");
+		registerColumnType(Types.DECIMAL, "decimal");
+        registerColumnType(Types.DOUBLE, "float");
+        registerColumnType(Types.FLOAT, "smallfloat");
+		registerColumnType(Types.INTEGER, "integer");
+		registerColumnType(Types.LONGVARBINARY, "blob"); // or BYTE
+		registerColumnType(Types.LONGVARCHAR, "clob"); // or TEXT?
+		registerColumnType(Types.NUMERIC, "decimal"); // or MONEY
+		registerColumnType(Types.REAL, "smallfloat");
+		registerColumnType(Types.SMALLINT, "smallint");
+		registerColumnType(Types.TIMESTAMP, "datetime year to fraction(5)");
+		registerColumnType(Types.TIME, "datetime hour to second");
+		registerColumnType(Types.TINYINT, "smallint");
+		registerColumnType(Types.VARBINARY, "byte");
+		registerColumnType(Types.VARCHAR, "varchar($l)");
+		registerColumnType(Types.VARCHAR, 255, "varchar($l)");
+		registerColumnType(Types.VARCHAR, 32739, "lvarchar($l)");
+
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+
+	public String getIdentitySelectString(String table, String column, int type) 
+	throws MappingException {
+		return type==Types.BIGINT ?
+			"select dbinfo('serial8') from systables where tabid=1" :
+			"select dbinfo('sqlca.sqlerrd1') from systables where tabid=1";
+	}
+
+	public String getIdentityColumnString(int type) throws MappingException {
+		return type==Types.BIGINT ?
+			"serial8 not null" :
+			"serial not null";
+	}
+
+	public boolean hasDataTypeInIdentityColumn() {
+		return false;
+	}
+
+	/**
+	 * The syntax used to add a foreign key constraint to a table.
+	 * Informix constraint name must be at the end.
+	 * @return String
+	 */
+	public String getAddForeignKeyConstraintString(
+			String constraintName, 
+			String[] foreignKey, 
+			String referencedTable, 
+			String[] primaryKey, boolean referencesPrimaryKey
+	) {
+		StringBuffer result = new StringBuffer(30);
+		
+		result.append(" add constraint ")
+			.append(" foreign key (")
+			.append( StringHelper.join(", ", foreignKey) )
+			.append(") references ")
+			.append(referencedTable);
+		
+		if(!referencesPrimaryKey) {
+			result.append(" (")
+			   .append( StringHelper.join(", ", primaryKey) )
+			   .append(')');
+		}
+
+		result.append(" constraint ").append(constraintName);
+			
+			return result.toString();
+	}
+
+	/**
+	 * The syntax used to add a primary key constraint to a table.
+	 * Informix constraint name must be at the end.
+	 * @return String
+	 */
+	public String getAddPrimaryKeyConstraintString(String constraintName) {
+		return " add constraint primary key constraint " + constraintName + " ";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName + " restrict";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName ) + " from systables where tabid=1";
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public String getLimitString(String querySelect, int offset, int limit) {
+		if (offset>0) throw new UnsupportedOperationException("informix has no offset");
+		return new StringBuffer( querySelect.length()+8 )
+			.append(querySelect)
+			.insert( querySelect.toLowerCase().indexOf( "select" ) + 6, " first " + limit )
+			.toString();
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+        return EXTRACTER;
+	}
+
+	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+		/**
+		 * Extract the name of the violated constraint from the given SQLException.
+		 *
+		 * @param sqle The exception that was the result of the constraint violation.
+		 * @return The extracted constraint name.
+		 */
+		public String extractConstraintName(SQLException sqle) {
+			String constraintName = null;
+			
+			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
+			if ( errorCode == -268 ) {
+				constraintName = extractUsingTemplate( "Unique constraint (", ") violated.", sqle.getMessage() );
+			}
+			else if ( errorCode == -691 ) {
+				constraintName = extractUsingTemplate( "Missing key in referenced table for referential constraint (", ").", sqle.getMessage() );
+			}
+			else if ( errorCode == -692 ) {
+				constraintName = extractUsingTemplate( "Key value for constraint (", ") is still being referenced.", sqle.getMessage() );
+			}
+			
+			if (constraintName != null) {
+				// strip table-owner because Informix always returns constraint names as "<table-owner>.<constraint-name>"
+				int i = constraintName.indexOf('.');
+				if (i != -1) {
+					constraintName = constraintName.substring(i + 1);
+				}
+			}
+
+			return constraintName;
+		}
+
+	};
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select distinct current timestamp from informix.systables";
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,305 +0,0 @@
-//$Id: IngresDialect.java 10963 2006-12-08 16:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-
-
-/**
- * An Ingres SQL dialect.
- * <p/>
- * Known limitations:
- * - only supports simple constants or columns on the left side of an IN, making (1,2,3) in (...) or (<subselect) in (...) non-supported
- * - supports only 31 digits in decimal
- *
- * @author Ian Booth, Bruce Lunsford, Max Rydahl Andersen
- */
-public class IngresDialect extends Dialect {
-
-	public IngresDialect() {
-		super();
-		registerColumnType( Types.BIT, "tinyint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.REAL, "real" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "float" );
-		registerColumnType( Types.NUMERIC, "decimal($p, $s)" );
-		registerColumnType( Types.DECIMAL, "decimal($p, $s)" );
-		registerColumnType( Types.BINARY, 32000, "byte($l)" );
-		registerColumnType( Types.BINARY, "long byte" );
-		registerColumnType( Types.VARBINARY, 32000, "varbyte($l)" );
-		registerColumnType( Types.VARBINARY, "long byte" );
-		registerColumnType( Types.LONGVARBINARY, "long byte" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, 32000, "varchar($l)" );
-		registerColumnType( Types.VARCHAR, "long varchar" );
-		registerColumnType( Types.LONGVARCHAR, "long varchar" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time with time zone" );
-		registerColumnType( Types.TIMESTAMP, "timestamp with time zone" );
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "clob" );
-
-		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
-		registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
-		registerFunction( "bit_add", new StandardSQLFunction( "bit_add" ) );
-		registerFunction( "bit_and", new StandardSQLFunction( "bit_and" ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(hex(?1))*4" ) );
-		registerFunction( "bit_not", new StandardSQLFunction( "bit_not" ) );
-		registerFunction( "bit_or", new StandardSQLFunction( "bit_or" ) );
-		registerFunction( "bit_xor", new StandardSQLFunction( "bit_xor" ) );
-		registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.LONG ) );
-		registerFunction( "charextract", new StandardSQLFunction( "charextract", Hibernate.STRING ) );
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "+", ")" ) );
-		registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
-		registerFunction( "current_user", new NoArgSQLFunction( "current_user", Hibernate.STRING, false ) );
-		registerFunction( "current_time", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
-		registerFunction( "current_date", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
-		registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) );
-		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
-		registerFunction( "dba", new NoArgSQLFunction( "dba", Hibernate.STRING, true ) );
-		registerFunction( "dow", new StandardSQLFunction( "dow", Hibernate.STRING ) );
-		registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "date_part('?1', ?3)" ) );
-		registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
-		registerFunction( "gmt_timestamp", new StandardSQLFunction( "gmt_timestamp", Hibernate.STRING ) );
-		registerFunction( "hash", new StandardSQLFunction( "hash", Hibernate.INTEGER ) );
-		registerFunction( "hex", new StandardSQLFunction( "hex", Hibernate.STRING ) );
-		registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) );
-		registerFunction( "initial_user", new NoArgSQLFunction( "initial_user", Hibernate.STRING, false ) );
-		registerFunction( "intextract", new StandardSQLFunction( "intextract", Hibernate.INTEGER ) );
-		registerFunction( "left", new StandardSQLFunction( "left", Hibernate.STRING ) );
-		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.LONG, "locate(?1, ?2)" ) );
-		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) );
-		registerFunction( "ln", new StandardSQLFunction( "ln", Hibernate.DOUBLE ) );
-		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) );
-		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
-		registerFunction( "lowercase", new StandardSQLFunction( "lowercase" ) );
-		registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) );
-		registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
-		registerFunction( "octet_length", new StandardSQLFunction( "octet_length", Hibernate.LONG ) );
-		registerFunction( "pad", new StandardSQLFunction( "pad", Hibernate.STRING ) );
-		registerFunction( "position", new StandardSQLFunction( "position", Hibernate.LONG ) );
-		registerFunction( "power", new StandardSQLFunction( "power", Hibernate.DOUBLE ) );
-		registerFunction( "random", new NoArgSQLFunction( "random", Hibernate.LONG, true ) );
-		registerFunction( "randomf", new NoArgSQLFunction( "randomf", Hibernate.DOUBLE, true ) );
-		registerFunction( "right", new StandardSQLFunction( "right", Hibernate.STRING ) );
-		registerFunction( "session_user", new NoArgSQLFunction( "session_user", Hibernate.STRING, false ) );
-		registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) );
-		registerFunction( "size", new NoArgSQLFunction( "size", Hibernate.LONG, true ) );
-		registerFunction( "squeeze", new StandardSQLFunction( "squeeze" ) );
-		registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
-		registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) );
-		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
-		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 FROM ?2 FOR ?3)" ) );
-		registerFunction( "system_user", new NoArgSQLFunction( "system_user", Hibernate.STRING, false ) );
-		//registerFunction( "trim", new StandardSQLFunction( "trim", Hibernate.STRING ) );
-		registerFunction( "unhex", new StandardSQLFunction( "unhex", Hibernate.STRING ) );
-		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
-		registerFunction( "uppercase", new StandardSQLFunction( "uppercase" ) );
-		registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING, false ) );
-		registerFunction( "usercode", new NoArgSQLFunction( "usercode", Hibernate.STRING, true ) );
-		registerFunction( "username", new NoArgSQLFunction( "username", Hibernate.STRING, true ) );
-		registerFunction( "uuid_create", new StandardSQLFunction( "uuid_create", Hibernate.BYTE ) );
-		registerFunction( "uuid_compare", new StandardSQLFunction( "uuid_compare", Hibernate.INTEGER ) );
-		registerFunction( "uuid_from_char", new StandardSQLFunction( "uuid_from_char", Hibernate.BYTE ) );
-		registerFunction( "uuid_to_char", new StandardSQLFunction( "uuid_to_char", Hibernate.STRING ) );
-		registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
-	}
-
-	/**
-	 * Do we need to drop constraints before dropping tables in this dialect?
-	 *
-	 * @return boolean
-	 */
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support <tt>FOR UPDATE OF</tt>, allowing
-	 * particular rows to be locked?
-	 *
-	 * @return True (Ingres does support "for update of" syntax...)
-	 */
-	public boolean supportsForUpdateOf() {
-		return true;
-	}
-
-	/**
-	 * The syntax used to add a column to a table (optional).
-	 */
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	/**
-	 * The keyword used to specify a nullable column.
-	 *
-	 * @return String
-	 */
-	public String getNullColumnString() {
-		return " with null";
-	}
-
-	/**
-	 * Does this dialect support sequences?
-	 *
-	 * @return boolean
-	 */
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	/**
-	 * The syntax that fetches the next value of a sequence, if sequences are supported.
-	 *
-	 * @param sequenceName the name of the sequence
-	 *
-	 * @return String
-	 */
-	public String getSequenceNextValString(String sequenceName) {
-		return "select nextval for " + sequenceName;
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	/**
-	 * The syntax used to create a sequence, if sequences are supported.
-	 *
-	 * @param sequenceName the name of the sequence
-	 *
-	 * @return String
-	 */
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-
-	/**
-	 * The syntax used to drop a sequence, if sequences are supported.
-	 *
-	 * @param sequenceName the name of the sequence
-	 *
-	 * @return String
-	 */
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName + " restrict";
-	}
-
-	/**
-	 * A query used to find all sequences
-	 */
-	public String getQuerySequencesString() {
-		return "select seq_name from iisequence";
-	}
-
-	/**
-	 * The name of the SQL function that transforms a string to
-	 * lowercase
-	 *
-	 * @return String
-	 */
-	public String getLowercaseFunction() {
-		return "lowercase";
-	}
-
-	/**
-	 * Does this <tt>Dialect</tt> have some kind of <tt>LIMIT</tt> syntax?
-	 */
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	/**
-	 * Does this dialect support an offset?
-	 */
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	/**
-	 * Add a <tt>LIMIT</tt> clause to the given SQL <tt>SELECT</tt>
-	 *
-	 * @return the modified SQL
-	 */
-	public String getLimitString(String querySelect, int offset, int limit) {
-		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "offset not supported" );
-		}
-		return new StringBuffer( querySelect.length() + 16 )
-				.append( querySelect )
-				.insert( 6, " first " + limit )
-				.toString();
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-	/**
-	 * Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
-	 * of a total number of returned rows?
-	 */
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	/**
-	 * Ingres explicitly needs "unique not null", because "with null" is default
-	 */
-	public boolean supportsNotNullUnique() {
-		return false;
-	}
-
-	/**
-	 * Does this dialect support temporary tables?
-	 */
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "declare global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "on commit preserve rows with norecovery";
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		return "session." + super.generateTemporaryTableName( baseTableName );
-	}
-
-
-	/**
-	 * Expression for current_timestamp
-	 */
-	public String getCurrentTimestampSQLFunctionName() {
-		return "date(now)";
-	}
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsSubselectAsInPredicateLHS() {
-		return false;
-	}
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsExpectedLobUsagePattern () {
-		return false;
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/IngresDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/IngresDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,327 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * An Ingres SQL dialect.
+ * <p/>
+ * Known limitations:
+ * - only supports simple constants or columns on the left side of an IN, making (1,2,3) in (...) or (<subselect) in (...) non-supported
+ * - supports only 31 digits in decimal
+ *
+ * @author Ian Booth, Bruce Lunsford, Max Rydahl Andersen
+ */
+public class IngresDialect extends Dialect {
+
+	public IngresDialect() {
+		super();
+		registerColumnType( Types.BIT, "tinyint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.REAL, "real" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "float" );
+		registerColumnType( Types.NUMERIC, "decimal($p, $s)" );
+		registerColumnType( Types.DECIMAL, "decimal($p, $s)" );
+		registerColumnType( Types.BINARY, 32000, "byte($l)" );
+		registerColumnType( Types.BINARY, "long byte" );
+		registerColumnType( Types.VARBINARY, 32000, "varbyte($l)" );
+		registerColumnType( Types.VARBINARY, "long byte" );
+		registerColumnType( Types.LONGVARBINARY, "long byte" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, 32000, "varchar($l)" );
+		registerColumnType( Types.VARCHAR, "long varchar" );
+		registerColumnType( Types.LONGVARCHAR, "long varchar" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time with time zone" );
+		registerColumnType( Types.TIMESTAMP, "timestamp with time zone" );
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "clob" );
+
+		registerFunction( "abs", new StandardSQLFunction( "abs" ) );
+		registerFunction( "atan", new StandardSQLFunction( "atan", Hibernate.DOUBLE ) );
+		registerFunction( "bit_add", new StandardSQLFunction( "bit_add" ) );
+		registerFunction( "bit_and", new StandardSQLFunction( "bit_and" ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(hex(?1))*4" ) );
+		registerFunction( "bit_not", new StandardSQLFunction( "bit_not" ) );
+		registerFunction( "bit_or", new StandardSQLFunction( "bit_or" ) );
+		registerFunction( "bit_xor", new StandardSQLFunction( "bit_xor" ) );
+		registerFunction( "character_length", new StandardSQLFunction( "character_length", Hibernate.LONG ) );
+		registerFunction( "charextract", new StandardSQLFunction( "charextract", Hibernate.STRING ) );
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "+", ")" ) );
+		registerFunction( "cos", new StandardSQLFunction( "cos", Hibernate.DOUBLE ) );
+		registerFunction( "current_user", new NoArgSQLFunction( "current_user", Hibernate.STRING, false ) );
+		registerFunction( "current_time", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
+		registerFunction( "current_date", new NoArgSQLFunction( "date('now')", Hibernate.TIMESTAMP, false ) );
+		registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) );
+		registerFunction( "day", new StandardSQLFunction( "day", Hibernate.INTEGER ) );
+		registerFunction( "dba", new NoArgSQLFunction( "dba", Hibernate.STRING, true ) );
+		registerFunction( "dow", new StandardSQLFunction( "dow", Hibernate.STRING ) );
+		registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "date_part('?1', ?3)" ) );
+		registerFunction( "exp", new StandardSQLFunction( "exp", Hibernate.DOUBLE ) );
+		registerFunction( "gmt_timestamp", new StandardSQLFunction( "gmt_timestamp", Hibernate.STRING ) );
+		registerFunction( "hash", new StandardSQLFunction( "hash", Hibernate.INTEGER ) );
+		registerFunction( "hex", new StandardSQLFunction( "hex", Hibernate.STRING ) );
+		registerFunction( "hour", new StandardSQLFunction( "hour", Hibernate.INTEGER ) );
+		registerFunction( "initial_user", new NoArgSQLFunction( "initial_user", Hibernate.STRING, false ) );
+		registerFunction( "intextract", new StandardSQLFunction( "intextract", Hibernate.INTEGER ) );
+		registerFunction( "left", new StandardSQLFunction( "left", Hibernate.STRING ) );
+		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.LONG, "locate(?1, ?2)" ) );
+		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.LONG ) );
+		registerFunction( "ln", new StandardSQLFunction( "ln", Hibernate.DOUBLE ) );
+		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE ) );
+		registerFunction( "lower", new StandardSQLFunction( "lower" ) );
+		registerFunction( "lowercase", new StandardSQLFunction( "lowercase" ) );
+		registerFunction( "minute", new StandardSQLFunction( "minute", Hibernate.INTEGER ) );
+		registerFunction( "month", new StandardSQLFunction( "month", Hibernate.INTEGER ) );
+		registerFunction( "octet_length", new StandardSQLFunction( "octet_length", Hibernate.LONG ) );
+		registerFunction( "pad", new StandardSQLFunction( "pad", Hibernate.STRING ) );
+		registerFunction( "position", new StandardSQLFunction( "position", Hibernate.LONG ) );
+		registerFunction( "power", new StandardSQLFunction( "power", Hibernate.DOUBLE ) );
+		registerFunction( "random", new NoArgSQLFunction( "random", Hibernate.LONG, true ) );
+		registerFunction( "randomf", new NoArgSQLFunction( "randomf", Hibernate.DOUBLE, true ) );
+		registerFunction( "right", new StandardSQLFunction( "right", Hibernate.STRING ) );
+		registerFunction( "session_user", new NoArgSQLFunction( "session_user", Hibernate.STRING, false ) );
+		registerFunction( "second", new StandardSQLFunction( "second", Hibernate.INTEGER ) );
+		registerFunction( "size", new NoArgSQLFunction( "size", Hibernate.LONG, true ) );
+		registerFunction( "squeeze", new StandardSQLFunction( "squeeze" ) );
+		registerFunction( "sin", new StandardSQLFunction( "sin", Hibernate.DOUBLE ) );
+		registerFunction( "soundex", new StandardSQLFunction( "soundex", Hibernate.STRING ) );
+		registerFunction( "sqrt", new StandardSQLFunction( "sqrt", Hibernate.DOUBLE ) );
+		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 FROM ?2 FOR ?3)" ) );
+		registerFunction( "system_user", new NoArgSQLFunction( "system_user", Hibernate.STRING, false ) );
+		//registerFunction( "trim", new StandardSQLFunction( "trim", Hibernate.STRING ) );
+		registerFunction( "unhex", new StandardSQLFunction( "unhex", Hibernate.STRING ) );
+		registerFunction( "upper", new StandardSQLFunction( "upper" ) );
+		registerFunction( "uppercase", new StandardSQLFunction( "uppercase" ) );
+		registerFunction( "user", new NoArgSQLFunction( "user", Hibernate.STRING, false ) );
+		registerFunction( "usercode", new NoArgSQLFunction( "usercode", Hibernate.STRING, true ) );
+		registerFunction( "username", new NoArgSQLFunction( "username", Hibernate.STRING, true ) );
+		registerFunction( "uuid_create", new StandardSQLFunction( "uuid_create", Hibernate.BYTE ) );
+		registerFunction( "uuid_compare", new StandardSQLFunction( "uuid_compare", Hibernate.INTEGER ) );
+		registerFunction( "uuid_from_char", new StandardSQLFunction( "uuid_from_char", Hibernate.BYTE ) );
+		registerFunction( "uuid_to_char", new StandardSQLFunction( "uuid_to_char", Hibernate.STRING ) );
+		registerFunction( "year", new StandardSQLFunction( "year", Hibernate.INTEGER ) );
+	}
+
+	/**
+	 * Do we need to drop constraints before dropping tables in this dialect?
+	 *
+	 * @return boolean
+	 */
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support <tt>FOR UPDATE OF</tt>, allowing
+	 * particular rows to be locked?
+	 *
+	 * @return True (Ingres does support "for update of" syntax...)
+	 */
+	public boolean supportsForUpdateOf() {
+		return true;
+	}
+
+	/**
+	 * The syntax used to add a column to a table (optional).
+	 */
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	/**
+	 * The keyword used to specify a nullable column.
+	 *
+	 * @return String
+	 */
+	public String getNullColumnString() {
+		return " with null";
+	}
+
+	/**
+	 * Does this dialect support sequences?
+	 *
+	 * @return boolean
+	 */
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	/**
+	 * The syntax that fetches the next value of a sequence, if sequences are supported.
+	 *
+	 * @param sequenceName the name of the sequence
+	 *
+	 * @return String
+	 */
+	public String getSequenceNextValString(String sequenceName) {
+		return "select nextval for " + sequenceName;
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	/**
+	 * The syntax used to create a sequence, if sequences are supported.
+	 *
+	 * @param sequenceName the name of the sequence
+	 *
+	 * @return String
+	 */
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+
+	/**
+	 * The syntax used to drop a sequence, if sequences are supported.
+	 *
+	 * @param sequenceName the name of the sequence
+	 *
+	 * @return String
+	 */
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName + " restrict";
+	}
+
+	/**
+	 * A query used to find all sequences
+	 */
+	public String getQuerySequencesString() {
+		return "select seq_name from iisequence";
+	}
+
+	/**
+	 * The name of the SQL function that transforms a string to
+	 * lowercase
+	 *
+	 * @return String
+	 */
+	public String getLowercaseFunction() {
+		return "lowercase";
+	}
+
+	/**
+	 * Does this <tt>Dialect</tt> have some kind of <tt>LIMIT</tt> syntax?
+	 */
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	/**
+	 * Does this dialect support an offset?
+	 */
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	/**
+	 * Add a <tt>LIMIT</tt> clause to the given SQL <tt>SELECT</tt>
+	 *
+	 * @return the modified SQL
+	 */
+	public String getLimitString(String querySelect, int offset, int limit) {
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "offset not supported" );
+		}
+		return new StringBuffer( querySelect.length() + 16 )
+				.append( querySelect )
+				.insert( 6, " first " + limit )
+				.toString();
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+	/**
+	 * Does the <tt>LIMIT</tt> clause take a "maximum" row number instead
+	 * of a total number of returned rows?
+	 */
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	/**
+	 * Ingres explicitly needs "unique not null", because "with null" is default
+	 */
+	public boolean supportsNotNullUnique() {
+		return false;
+	}
+
+	/**
+	 * Does this dialect support temporary tables?
+	 */
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "declare global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "on commit preserve rows with norecovery";
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		return "session." + super.generateTemporaryTableName( baseTableName );
+	}
+
+
+	/**
+	 * Expression for current_timestamp
+	 */
+	public String getCurrentTimestampSQLFunctionName() {
+		return "date(now)";
+	}
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsSubselectAsInPredicateLHS() {
+		return false;
+	}
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsExpectedLobUsagePattern () {
+		return false;
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,105 +0,0 @@
-//$Id: InterbaseDialect.java 7746 2005-08-03 23:29:32Z oneovthafew $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-
-/**
- * An SQL dialect for Interbase.
- * @author Gavin King
- */
-public class InterbaseDialect extends Dialect {
-
-	public InterbaseDialect() {
-		super();
-		registerColumnType( Types.BIT, "smallint" );
-		registerColumnType( Types.BIGINT, "numeric(18,0)" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "smallint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "blob" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "blob sub_type 1" );
-		
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName ) + " from RDB$DATABASE";
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return "gen_id( " + sequenceName + ", 1 )";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create generator " + sequenceName;
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "delete from RDB$GENERATORS where RDB$GENERATOR_NAME = '" + sequenceName.toUpperCase() + "'";
-	}
-
-	public String getQuerySequencesString() {
-		return "select RDB$GENERATOR_NAME from RDB$GENERATORS";
-	}
-	
-	public String getForUpdateString() {
-		return " with lock";
-	}
-	public String getForUpdateString(String aliases) {
-		return " for update of " + aliases + " with lock";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+15 )
-			.append(sql)
-			.append(hasOffset ? " rows ? to ?" : " rows ?")
-			.toString();
-	}
-
-	public boolean bindLimitParametersFirst() {
-		return false;
-	}
-
-	public boolean bindLimitParametersInReverseOrder() {
-		return false;
-	}
-
-	public String getCurrentTimestampCallString() {
-		// TODO : not sure which (either?) is correct, could not find docs on how to do this.
-		// did find various blogs and forums mentioning that select CURRENT_TIMESTAMP
-		// does not work...
-		return "{?= call CURRENT_TIMESTAMP }";
-//		return "select CURRENT_TIMESTAMP from RDB$DATABASE";
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return true;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/InterbaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * An SQL dialect for Interbase.
+ * @author Gavin King
+ */
+public class InterbaseDialect extends Dialect {
+
+	public InterbaseDialect() {
+		super();
+		registerColumnType( Types.BIT, "smallint" );
+		registerColumnType( Types.BIGINT, "numeric(18,0)" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "smallint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "blob" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "blob sub_type 1" );
+		
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName ) + " from RDB$DATABASE";
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return "gen_id( " + sequenceName + ", 1 )";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create generator " + sequenceName;
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "delete from RDB$GENERATORS where RDB$GENERATOR_NAME = '" + sequenceName.toUpperCase() + "'";
+	}
+
+	public String getQuerySequencesString() {
+		return "select RDB$GENERATOR_NAME from RDB$GENERATORS";
+	}
+	
+	public String getForUpdateString() {
+		return " with lock";
+	}
+	public String getForUpdateString(String aliases) {
+		return " for update of " + aliases + " with lock";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		return new StringBuffer( sql.length()+15 )
+			.append(sql)
+			.append(hasOffset ? " rows ? to ?" : " rows ?")
+			.toString();
+	}
+
+	public boolean bindLimitParametersFirst() {
+		return false;
+	}
+
+	public boolean bindLimitParametersInReverseOrder() {
+		return false;
+	}
+
+	public String getCurrentTimestampCallString() {
+		// TODO : not sure which (either?) is correct, could not find docs on how to do this.
+		// did find various blogs and forums mentioning that select CURRENT_TIMESTAMP
+		// does not work...
+		return "{?= call CURRENT_TIMESTAMP }";
+//		return "select CURRENT_TIMESTAMP from RDB$DATABASE";
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return true;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-// $Id: JDataStoreDialect.java 7075 2005-06-08 07:06:50Z oneovthafew $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.cfg.Environment;
-
-/**
- * A <tt>Dialect</tt> for JDataStore.
- * 
- * @author Vishy Kasar
- */
-public class JDataStoreDialect extends Dialect {
-
-	/**
-	 * Creates new JDataStoreDialect
-	 */
-	public JDataStoreDialect() {
-		super();
-
-		registerColumnType( Types.BIT, "tinyint" );
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "varbinary($l)" );
-		registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
-
-		registerColumnType( Types.BLOB, "varbinary" );
-		registerColumnType( Types.CLOB, "varchar" );
-
-		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public String getCascadeConstraintsString() {
-		return " cascade";
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-
-	public String getIdentitySelectString() {
-		return null; // NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method
-	}
-
-	public String getIdentityColumnString() {
-		return "autoincrement";
-	}
-
-	public String getNoColumnsInsertString() {
-		return "default values";
-	}
-
-	public boolean supportsColumnCheck() {
-		return false;
-	}
-
-	public boolean supportsTableCheck() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/JDataStoreDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.cfg.Environment;
+
+/**
+ * A <tt>Dialect</tt> for JDataStore.
+ * 
+ * @author Vishy Kasar
+ */
+public class JDataStoreDialect extends Dialect {
+
+	/**
+	 * Creates new JDataStoreDialect
+	 */
+	public JDataStoreDialect() {
+		super();
+
+		registerColumnType( Types.BIT, "tinyint" );
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "varbinary($l)" );
+		registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
+
+		registerColumnType( Types.BLOB, "varbinary" );
+		registerColumnType( Types.CLOB, "varchar" );
+
+		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public String getCascadeConstraintsString() {
+		return " cascade";
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+
+	public String getIdentitySelectString() {
+		return null; // NOT_SUPPORTED_SHOULD_USE_JDBC3_PreparedStatement.getGeneratedKeys_method
+	}
+
+	public String getIdentityColumnString() {
+		return "autoincrement";
+	}
+
+	public String getNoColumnsInsertString() {
+		return "default values";
+	}
+
+	public boolean supportsColumnCheck() {
+		return false;
+	}
+
+	public boolean supportsTableCheck() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,98 +0,0 @@
-//$Id: MckoiDialect.java 9328 2006-02-23 17:32:47Z steveebersole $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.MckoiCaseFragment;
-
-/**
- * An SQL dialect compatible with McKoi SQL
- * @author Doug Currie, Gabe Hicks
- */
-public class MckoiDialect extends Dialect {
-	public MckoiDialect() {
-		super();
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "varbinary" );
-		registerColumnType( Types.NUMERIC, "numeric" );
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "clob" );
-
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
-		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
-		registerFunction( "round", new StandardSQLFunction( "round", Hibernate.INTEGER ) );
-		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) );
-		registerFunction( "least", new StandardSQLFunction("least") );
-		registerFunction( "greatest", new StandardSQLFunction("greatest") );
-		registerFunction( "user", new StandardSQLFunction( "user", Hibernate.STRING ) );
-		registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) );
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName );
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return "nextval('" + sequenceName + "')";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public CaseFragment createCaseFragment() {
-		return new MckoiCaseFragment();
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax...
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MckoiDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MckoiDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.MckoiCaseFragment;
+
+/**
+ * An SQL dialect compatible with McKoi SQL
+ * @author Doug Currie, Gabe Hicks
+ */
+public class MckoiDialect extends Dialect {
+	public MckoiDialect() {
+		super();
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "varbinary" );
+		registerColumnType( Types.NUMERIC, "numeric" );
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "clob" );
+
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction( "sign", Hibernate.INTEGER ) );
+		registerFunction( "length", new StandardSQLFunction( "length", Hibernate.INTEGER ) );
+		registerFunction( "round", new StandardSQLFunction( "round", Hibernate.INTEGER ) );
+		registerFunction( "mod", new StandardSQLFunction( "mod", Hibernate.INTEGER ) );
+		registerFunction( "least", new StandardSQLFunction("least") );
+		registerFunction( "greatest", new StandardSQLFunction("greatest") );
+		registerFunction( "user", new StandardSQLFunction( "user", Hibernate.STRING ) );
+		registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) );
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName );
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return "nextval('" + sequenceName + "')";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public CaseFragment createCaseFragment() {
+		return new MckoiCaseFragment();
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// Mckoi has no known variation of a "SELECT ... FOR UPDATE" syntax...
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,221 +0,0 @@
-//$Id: MimerSQLDialect.java 7822 2005-08-10 19:49:36Z oneovthafew $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.*;
-
-/**
- * An Hibernate 3 SQL dialect for Mimer SQL. This dialect requires Mimer SQL 9.2.1 or later
- * because of the mappings to NCLOB, BINARY, and BINARY VARYING.
- * @author Fredrik Ålund <fredrik.alund at mimer.se>
- */
-public class MimerSQLDialect extends Dialect {
-
-	private static final int NATIONAL_CHAR_LENGTH = 2000;
-	private static final int BINARY_MAX_LENGTH = 2000;
-
-	/**
-	 * Even thoug Mimer SQL supports character and binary columns up to 15 000 in lenght,
-	 * this is also the maximum width of the table (exluding LOBs). To avoid breaking the limit all the
-	 * time we limit the length of the character columns to CHAR_MAX_LENTH, NATIONAL_CHAR_LENGTH for national
-	 * characters, and BINARY_MAX_LENGTH for binary types.
-	 *
-	 */
-	public MimerSQLDialect() {
-		super();
-		registerColumnType( Types.BIT, "ODBC.BIT" );
-		registerColumnType( Types.BIGINT, "BIGINT" );
-		registerColumnType( Types.SMALLINT, "SMALLINT" );
-		registerColumnType( Types.TINYINT, "ODBC.TINYINT" );
-		registerColumnType( Types.INTEGER, "INTEGER" );
-		registerColumnType( Types.CHAR, "NCHAR(1)" );
-		registerColumnType( Types.VARCHAR, NATIONAL_CHAR_LENGTH, "NATIONAL CHARACTER VARYING($l)" );
-		registerColumnType( Types.VARCHAR, "NCLOB($l)" );
-		registerColumnType( Types.LONGVARCHAR, "CLOB($1)");
-		registerColumnType( Types.FLOAT, "FLOAT" );
-		registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" );
-		registerColumnType( Types.DATE, "DATE" );
-		registerColumnType( Types.TIME, "TIME" );
-		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
-		registerColumnType( Types.VARBINARY, BINARY_MAX_LENGTH, "BINARY VARYING($l)" );
-		registerColumnType( Types.VARBINARY, "BLOB($1)" );
-		registerColumnType( Types.LONGVARBINARY, "BLOB($1)");
-		registerColumnType( Types.BINARY, BINARY_MAX_LENGTH, "BINARY" );
-		registerColumnType( Types.BINARY, "BLOB($1)" );
-		registerColumnType( Types.NUMERIC, "NUMERIC(19, $l)" );
-		registerColumnType( Types.BLOB, "BLOB($l)" );
-		registerColumnType( Types.CLOB, "NCLOB($l)" );
-
-		registerFunction("abs", new StandardSQLFunction("abs") );
-		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-		registerFunction("ceiling", new StandardSQLFunction("ceiling") );
-		registerFunction("floor", new StandardSQLFunction("floor") );
-		registerFunction("round", new StandardSQLFunction("round") );
-
-		registerFunction("dacos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) );
-		registerFunction("acos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) );
-		registerFunction("dasin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) );
-		registerFunction("asin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) );
-		registerFunction("datan", new StandardSQLFunction("datan", Hibernate.DOUBLE) );
-		registerFunction("atan", new StandardSQLFunction("datan", Hibernate.DOUBLE) );
-		registerFunction("datan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) );
-		registerFunction("atan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) );
-		registerFunction("dcos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) );
-		registerFunction("cos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) );
-		registerFunction("dcot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) );
-		registerFunction("cot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) );
-		registerFunction("ddegrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) );
-		registerFunction("degrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) );
-		registerFunction("dexp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) );
-		registerFunction("exp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) );
-		registerFunction("dlog", new StandardSQLFunction("dlog", Hibernate.DOUBLE) );
-		registerFunction("log", new StandardSQLFunction("dlog", Hibernate.DOUBLE) );
-		registerFunction("dlog10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) );
-		registerFunction("log10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) );
-		registerFunction("dradian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) );
-		registerFunction("radian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) );
-		registerFunction("dsin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) );
-		registerFunction("sin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) );
-		registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
-		registerFunction("dsqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) );
-		registerFunction("sqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) );
-		registerFunction("dtan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) );
-		registerFunction("tan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) );
-		registerFunction("dpower", new StandardSQLFunction("dpower") );
-		registerFunction("power", new StandardSQLFunction("dpower") );
-
-		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
-		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
-		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
-		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
-		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
-		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
-
-
-		registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) );
-		registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) );
-		registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) );
-		registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
-		registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) );
-		registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) );
-
-		registerFunction("ascii_char", new StandardSQLFunction("ascii_char", Hibernate.CHARACTER) );
-		registerFunction("ascii_code", new StandardSQLFunction("ascii_code", Hibernate.STRING));
-		registerFunction("unicode_char", new StandardSQLFunction("unicode_char", Hibernate.LONG));
-		registerFunction("unicode_code", new StandardSQLFunction("unicode_code", Hibernate.STRING));
-		registerFunction("upper", new StandardSQLFunction("upper") );
-		registerFunction("lower", new StandardSQLFunction("lower") );
-		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
-		registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.STRING));
-
-		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, "50");
-	}
-
-	/**
-	 * The syntax used to add a column to a table
-	 */
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	/**
-	 * We do not have to drop constraints before we drop the table
-	 */
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	/**
-	 * TODO: Check if Mimer SQL cannot handle the way DB2 does
-	 */
-	public boolean supportsIdentityColumns() {
-		return false;
-	}
-
-	/**
-	 * Mimer SQL supports sequences
-	 * @return boolean
-	 */
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	/**
-	 * The syntax used to get the next value of a sequence in Mimer SQL
-	 */
-	public String getSequenceNextValString(String sequenceName) {
-		return "select next_value of " + sequenceName + " from system.onerow";
-	}
-
-	/**
-	 * The syntax used to create a sequence. Since we presume the sequences will be used as keys,
-	 * we make them unique.
-	 */
-	public String getCreateSequenceString(String sequenceName) {
-		return "create unique sequence " + sequenceName;
-	}
-
-	/**
-	* The syntax used to drop sequences
-	*/
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName + " restrict";
-	}
-
-	/**
-	* Mimer SQL does not support limit
-	*/
-	public boolean supportsLimit() {
-		return false;
-	}
-
-	/**
-	* The syntax for using cascade on constraints
-	*/
-	public String getCascadeConstraintsString() {
-		return " cascade";
-	}
-
-	/**
-	* The syntax for fetching all sequnces avialable in the current schema.
-	*/
-	public String getQuerySequencesString() {
-		return "select sequence_schema || '.' || sequence_name from information_schema.ext_sequences";
-	}
-
-	/**
-	 * Does the <tt>FOR UPDATE OF</tt> syntax specify particular
-	 * columns?
-	 */
-	public boolean forUpdateOfColumns() {
-		return false;
-	}
-
-	/**
-	 * Support the FOR UPDATE syntax? For now, returns false since
-	 * the current version of the Mimer SQL JDBC Driver does not support
-	 * updatable resultsets. Otherwise, Mimer SQL actually supports the for update syntax.
-	 * @return boolean
-	 */
-	public boolean supportsForUpdate() {
-		return false;
-	}
-
-
-	/**
-	 * For now, simply return false since we don't updatable result sets.
-	 */
-	public boolean supportsOuterJoinForUpdate() {
-		return false;
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MimerSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,244 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.*;
+
+/**
+ * An Hibernate 3 SQL dialect for Mimer SQL. This dialect requires Mimer SQL 9.2.1 or later
+ * because of the mappings to NCLOB, BINARY, and BINARY VARYING.
+ * @author Fredrik �lund <fredrik.alund at mimer.se>
+ */
+public class MimerSQLDialect extends Dialect {
+
+	private static final int NATIONAL_CHAR_LENGTH = 2000;
+	private static final int BINARY_MAX_LENGTH = 2000;
+
+	/**
+	 * Even thoug Mimer SQL supports character and binary columns up to 15 000 in lenght,
+	 * this is also the maximum width of the table (exluding LOBs). To avoid breaking the limit all the
+	 * time we limit the length of the character columns to CHAR_MAX_LENTH, NATIONAL_CHAR_LENGTH for national
+	 * characters, and BINARY_MAX_LENGTH for binary types.
+	 *
+	 */
+	public MimerSQLDialect() {
+		super();
+		registerColumnType( Types.BIT, "ODBC.BIT" );
+		registerColumnType( Types.BIGINT, "BIGINT" );
+		registerColumnType( Types.SMALLINT, "SMALLINT" );
+		registerColumnType( Types.TINYINT, "ODBC.TINYINT" );
+		registerColumnType( Types.INTEGER, "INTEGER" );
+		registerColumnType( Types.CHAR, "NCHAR(1)" );
+		registerColumnType( Types.VARCHAR, NATIONAL_CHAR_LENGTH, "NATIONAL CHARACTER VARYING($l)" );
+		registerColumnType( Types.VARCHAR, "NCLOB($l)" );
+		registerColumnType( Types.LONGVARCHAR, "CLOB($1)");
+		registerColumnType( Types.FLOAT, "FLOAT" );
+		registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" );
+		registerColumnType( Types.DATE, "DATE" );
+		registerColumnType( Types.TIME, "TIME" );
+		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
+		registerColumnType( Types.VARBINARY, BINARY_MAX_LENGTH, "BINARY VARYING($l)" );
+		registerColumnType( Types.VARBINARY, "BLOB($1)" );
+		registerColumnType( Types.LONGVARBINARY, "BLOB($1)");
+		registerColumnType( Types.BINARY, BINARY_MAX_LENGTH, "BINARY" );
+		registerColumnType( Types.BINARY, "BLOB($1)" );
+		registerColumnType( Types.NUMERIC, "NUMERIC(19, $l)" );
+		registerColumnType( Types.BLOB, "BLOB($l)" );
+		registerColumnType( Types.CLOB, "NCLOB($l)" );
+
+		registerFunction("abs", new StandardSQLFunction("abs") );
+		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+		registerFunction("ceiling", new StandardSQLFunction("ceiling") );
+		registerFunction("floor", new StandardSQLFunction("floor") );
+		registerFunction("round", new StandardSQLFunction("round") );
+
+		registerFunction("dacos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) );
+		registerFunction("acos", new StandardSQLFunction("dacos", Hibernate.DOUBLE) );
+		registerFunction("dasin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) );
+		registerFunction("asin", new StandardSQLFunction("dasin", Hibernate.DOUBLE) );
+		registerFunction("datan", new StandardSQLFunction("datan", Hibernate.DOUBLE) );
+		registerFunction("atan", new StandardSQLFunction("datan", Hibernate.DOUBLE) );
+		registerFunction("datan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) );
+		registerFunction("atan2", new StandardSQLFunction("datan2", Hibernate.DOUBLE) );
+		registerFunction("dcos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) );
+		registerFunction("cos", new StandardSQLFunction("dcos", Hibernate.DOUBLE) );
+		registerFunction("dcot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) );
+		registerFunction("cot", new StandardSQLFunction("dcot", Hibernate.DOUBLE) );
+		registerFunction("ddegrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) );
+		registerFunction("degrees", new StandardSQLFunction("ddegrees", Hibernate.DOUBLE) );
+		registerFunction("dexp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) );
+		registerFunction("exp", new StandardSQLFunction("dexp", Hibernate.DOUBLE) );
+		registerFunction("dlog", new StandardSQLFunction("dlog", Hibernate.DOUBLE) );
+		registerFunction("log", new StandardSQLFunction("dlog", Hibernate.DOUBLE) );
+		registerFunction("dlog10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) );
+		registerFunction("log10", new StandardSQLFunction("dlog10", Hibernate.DOUBLE) );
+		registerFunction("dradian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) );
+		registerFunction("radian", new StandardSQLFunction("dradian", Hibernate.DOUBLE) );
+		registerFunction("dsin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) );
+		registerFunction("sin", new StandardSQLFunction("dsin", Hibernate.DOUBLE) );
+		registerFunction("soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
+		registerFunction("dsqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) );
+		registerFunction("sqrt", new StandardSQLFunction("dsqrt", Hibernate.DOUBLE) );
+		registerFunction("dtan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) );
+		registerFunction("tan", new StandardSQLFunction("dtan", Hibernate.DOUBLE) );
+		registerFunction("dpower", new StandardSQLFunction("dpower") );
+		registerFunction("power", new StandardSQLFunction("dpower") );
+
+		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
+		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
+		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
+		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
+		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
+		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
+
+
+		registerFunction("varchar", new StandardSQLFunction("varchar", Hibernate.STRING) );
+		registerFunction("real", new StandardSQLFunction("real", Hibernate.FLOAT) );
+		registerFunction("bigint", new StandardSQLFunction("bigint", Hibernate.LONG) );
+		registerFunction("char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
+		registerFunction("integer", new StandardSQLFunction("integer", Hibernate.INTEGER) );
+		registerFunction("smallint", new StandardSQLFunction("smallint", Hibernate.SHORT) );
+
+		registerFunction("ascii_char", new StandardSQLFunction("ascii_char", Hibernate.CHARACTER) );
+		registerFunction("ascii_code", new StandardSQLFunction("ascii_code", Hibernate.STRING));
+		registerFunction("unicode_char", new StandardSQLFunction("unicode_char", Hibernate.LONG));
+		registerFunction("unicode_code", new StandardSQLFunction("unicode_code", Hibernate.STRING));
+		registerFunction("upper", new StandardSQLFunction("upper") );
+		registerFunction("lower", new StandardSQLFunction("lower") );
+		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
+		registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.STRING));
+
+		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, "50");
+	}
+
+	/**
+	 * The syntax used to add a column to a table
+	 */
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	/**
+	 * We do not have to drop constraints before we drop the table
+	 */
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	/**
+	 * TODO: Check if Mimer SQL cannot handle the way DB2 does
+	 */
+	public boolean supportsIdentityColumns() {
+		return false;
+	}
+
+	/**
+	 * Mimer SQL supports sequences
+	 * @return boolean
+	 */
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	/**
+	 * The syntax used to get the next value of a sequence in Mimer SQL
+	 */
+	public String getSequenceNextValString(String sequenceName) {
+		return "select next_value of " + sequenceName + " from system.onerow";
+	}
+
+	/**
+	 * The syntax used to create a sequence. Since we presume the sequences will be used as keys,
+	 * we make them unique.
+	 */
+	public String getCreateSequenceString(String sequenceName) {
+		return "create unique sequence " + sequenceName;
+	}
+
+	/**
+	* The syntax used to drop sequences
+	*/
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName + " restrict";
+	}
+
+	/**
+	* Mimer SQL does not support limit
+	*/
+	public boolean supportsLimit() {
+		return false;
+	}
+
+	/**
+	* The syntax for using cascade on constraints
+	*/
+	public String getCascadeConstraintsString() {
+		return " cascade";
+	}
+
+	/**
+	* The syntax for fetching all sequnces avialable in the current schema.
+	*/
+	public String getQuerySequencesString() {
+		return "select sequence_schema || '.' || sequence_name from information_schema.ext_sequences";
+	}
+
+	/**
+	 * Does the <tt>FOR UPDATE OF</tt> syntax specify particular
+	 * columns?
+	 */
+	public boolean forUpdateOfColumns() {
+		return false;
+	}
+
+	/**
+	 * Support the FOR UPDATE syntax? For now, returns false since
+	 * the current version of the Mimer SQL JDBC Driver does not support
+	 * updatable resultsets. Otherwise, Mimer SQL actually supports the for update syntax.
+	 * @return boolean
+	 */
+	public boolean supportsForUpdate() {
+		return false;
+	}
+
+
+	/**
+	 * For now, simply return false since we don't updatable result sets.
+	 */
+	public boolean supportsOuterJoinForUpdate() {
+		return false;
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-/**
- * An SQL dialect for MySQL 5.x specific features.
- *
- * @author Steve Ebersole
- */
-public class MySQL5Dialect extends MySQLDialect {
-	protected void registerVarcharTypes() {
-		registerColumnType( Types.VARCHAR, "longtext" );
-//		registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
-		registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+/**
+ * An SQL dialect for MySQL 5.x specific features.
+ *
+ * @author Steve Ebersole
+ */
+public class MySQL5Dialect extends MySQLDialect {
+	protected void registerVarcharTypes() {
+		registerColumnType( Types.VARCHAR, "longtext" );
+//		registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
+		registerColumnType( Types.VARCHAR, 65535, "varchar($l)" );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id:  $
-package org.hibernate.dialect;
-
-/**
- * @author Gavin King, Scott Marlow
- */
-public class MySQL5InnoDBDialect extends MySQL5Dialect {
-
-	public boolean supportsCascadeDelete() {
-		return true;
-	}
-	
-	public String getTableTypeString() {
-		return " ENGINE=InnoDB";
-	}
-
-	public boolean hasSelfReferentialForeignKeyBug() {
-		return true;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQL5InnoDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.dialect;
+
+/**
+ * @author Gavin King, Scott Marlow
+ */
+public class MySQL5InnoDBDialect extends MySQL5Dialect {
+
+	public boolean supportsCascadeDelete() {
+		return true;
+	}
+	
+	public String getTableTypeString() {
+		return " ENGINE=InnoDB";
+	}
+
+	public boolean hasSelfReferentialForeignKeyBug() {
+		return true;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,350 +0,0 @@
-//$Id: MySQLDialect.java 10963 2006-12-08 16:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.util.StringHelper;
-
-/**
- * An SQL dialect for MySQL (prior to 5.x).
- *
- * @author Gavin King
- */
-public class MySQLDialect extends Dialect {
-
-	public MySQLDialect() {
-		super();
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "datetime" );
-		registerColumnType( Types.VARBINARY, "longblob" );
-		registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
-		registerColumnType( Types.VARBINARY, 65535, "blob" );
-		registerColumnType( Types.VARBINARY, 255, "tinyblob" );
-		registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
-		registerColumnType( Types.BLOB, "longblob" );
-//		registerColumnType( Types.BLOB, 16777215, "mediumblob" );
-//		registerColumnType( Types.BLOB, 65535, "blob" );
-		registerColumnType( Types.CLOB, "longtext" );
-//		registerColumnType( Types.CLOB, 16777215, "mediumtext" );
-//		registerColumnType( Types.CLOB, 65535, "text" );
-		registerVarcharTypes();
-
-		registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction("bin", new StandardSQLFunction("bin", Hibernate.STRING) );
-		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
-		registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.LONG) );
-		registerFunction("lcase", new StandardSQLFunction("lcase") );
-		registerFunction("lower", new StandardSQLFunction("lower") );
-		registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) );
-		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction("ord", new StandardSQLFunction("ord", Hibernate.INTEGER) );
-		registerFunction("quote", new StandardSQLFunction("quote") );
-		registerFunction("reverse", new StandardSQLFunction("reverse") );
-		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction("soundex", new StandardSQLFunction("soundex") );
-		registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) );
-		registerFunction("ucase", new StandardSQLFunction("ucase") );
-		registerFunction("upper", new StandardSQLFunction("upper") );
-		registerFunction("unhex", new StandardSQLFunction("unhex", Hibernate.STRING) );
-
-		registerFunction("abs", new StandardSQLFunction("abs") );
-		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
-		registerFunction("crc32", new StandardSQLFunction("crc32", Hibernate.LONG) );
-		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
-		registerFunction("log2", new StandardSQLFunction("log2", Hibernate.DOUBLE) );
-		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
-		registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
-		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
-		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-
-		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
-		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-
-		registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.INTEGER) );
-		registerFunction("ceil", new StandardSQLFunction("ceil", Hibernate.INTEGER) );
-		registerFunction("floor", new StandardSQLFunction("floor", Hibernate.INTEGER) );
-		registerFunction("round", new StandardSQLFunction("round", Hibernate.INTEGER) );
-
-		registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER) );
-		registerFunction("timediff", new StandardSQLFunction("timediff", Hibernate.TIME) );
-		registerFunction("date_format", new StandardSQLFunction("date_format", Hibernate.STRING) );
-
-		registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE) );
-		registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME) );
-		registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
-		registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) );
-		registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
-		registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) );
-		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) );
-		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
-		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
-		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
-		registerFunction("from_days", new StandardSQLFunction("from_days", Hibernate.DATE) );
-		registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", Hibernate.TIMESTAMP) );
-		registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) );
-		registerFunction("last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
-		registerFunction("localtime", new NoArgSQLFunction("localtime", Hibernate.TIMESTAMP) );
-		registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP) );
-		registerFunction("microseconds", new StandardSQLFunction("microseconds", Hibernate.INTEGER) );
-		registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) );
-		registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) );
-		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
-		registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) );
-		registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) );
-		registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) );
-		registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", Hibernate.TIME) );
-		registerFunction("sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP) );
-		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
-		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
-		registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", Hibernate.INTEGER) );
-		registerFunction("to_days", new StandardSQLFunction("to_days", Hibernate.LONG) );
-		registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", Hibernate.LONG) );
-		registerFunction("utc_date", new NoArgSQLFunction("utc_date", Hibernate.STRING) );
-		registerFunction("utc_time", new NoArgSQLFunction("utc_time", Hibernate.STRING) );
-		registerFunction("utc_timestamp", new NoArgSQLFunction("utc_timestamp", Hibernate.STRING) );
-		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
-		registerFunction("weekday", new StandardSQLFunction("weekday", Hibernate.INTEGER) );
-		registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) );
-		registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) );
-		registerFunction("yearweek", new StandardSQLFunction("yearweek", Hibernate.INTEGER) );
-
-		registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) );
-		registerFunction("oct", new StandardSQLFunction("oct", Hibernate.STRING) );
-
-		registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
-		registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) );
-
-		registerFunction("bit_count", new StandardSQLFunction("bit_count", Hibernate.LONG) );
-		registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.STRING) );
-		registerFunction("md5", new StandardSQLFunction("md5", Hibernate.STRING) );
-		registerFunction("sha1", new StandardSQLFunction("sha1", Hibernate.STRING) );
-		registerFunction("sha", new StandardSQLFunction("sha", Hibernate.STRING) );
-
-		registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) );
-
-		getDefaultProperties().setProperty(Environment.MAX_FETCH_DEPTH, "2");
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-	}
-
-	protected void registerVarcharTypes() {
-		registerColumnType( Types.VARCHAR, "longtext" );
-//		registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
-//		registerColumnType( Types.VARCHAR, 65535, "text" );
-		registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-	
-	public boolean qualifyIndexName() {
-		return false;
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-	
-	public String getIdentitySelectString() {
-		return "select last_insert_id()";
-	}
-
-	public String getIdentityColumnString() {
-		return "not null auto_increment"; //starts with 1, implicitly
-	}
-
-	public String getAddForeignKeyConstraintString(
-			String constraintName, 
-			String[] foreignKey, 
-			String referencedTable, 
-			String[] primaryKey, boolean referencesPrimaryKey
-	) {
-		String cols = StringHelper.join(", ", foreignKey);
-		return new StringBuffer(30)
-			.append(" add index ")
-			.append(constraintName)
-			.append(" (")
-			.append(cols)
-			.append("), add constraint ")
-			.append(constraintName)
-			.append(" foreign key (")
-			.append(cols)
-			.append(") references ")
-			.append(referencedTable)
-			.append(" (")
-			.append( StringHelper.join(", ", primaryKey) )
-			.append(')')
-			.toString();
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-	
-	public String getDropForeignKeyString() {
-		return " drop foreign key ";
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.append( hasOffset ? " limit ?, ?" : " limit ?")
-			.toString();
-	}
-	
-	/*
-	 * Temporary, until MySQL fix Connector/J bug
-	 */
-	/*public String getLimitString(String sql, int offset, int limit) {
-		StringBuffer buf = new StringBuffer( sql.length()+20 )
-			.append(sql);
-		if (offset>0) {
-			buf.append(" limit ")
-				.append(offset)
-				.append(", ")
-				.append(limit);
-		}
-		else {
-			buf.append(" limit ")
-				.append(limit);
-		}
-		return buf.toString();
-	}*/
-
-	/*
-	 * Temporary, until MySQL fix Connector/J bug
-	 */
-	/*public boolean supportsVariableLimit() {
-		return false;
-	}*/
-
-	public char closeQuote() {
-		return '`';
-	}
-
-	public char openQuote() {
-		return '`';
-	}
-
-	public boolean supportsIfExistsBeforeTableName() {
-		return true;
-	}
-
-	public String getSelectGUIDString() {
-		return "select uuid()";
-	}
-
-	public boolean supportsCascadeDelete() {
-		return false;
-	}
-	
-	public String getTableComment(String comment) {
-		return " comment='" + comment + "'";
-	}
-
-	public String getColumnComment(String comment) {
-		return " comment '" + comment + "'";
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create temporary table if not exists";
-	}
-
-	public String getCastTypeName(int code) {
-		if ( code==Types.INTEGER ) {
-			return "signed";
-		}
-		else if ( code==Types.VARCHAR ) {
-			return "char";
-		}
-		else if ( code==Types.VARBINARY ) {
-			return "binary";
-		}
-		else {
-			return super.getCastTypeName( code );
-		}
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select now()";
-	}
-
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		return col;
-	} 
-	
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		boolean isResultSet = ps.execute(); 
-		while (!isResultSet && ps.getUpdateCount() != -1) { 
-			isResultSet = ps.getMoreResults(); 
-		} 
-		return ps.getResultSet();
-	}
-
-	public boolean supportsRowValueConstructorSyntax() {
-		return true;
-	}
-
-	public Boolean performTemporaryTableDDLInIsolation() {
-		return Boolean.FALSE;
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean areStringComparisonsCaseInsensitive() {
-		return true;
-	}
-
-	public boolean supportsLobValueChangePropogation() {
-		// note: at least my local MySQL 5.1 install shows this not working...
-		return false;
-	}
-
-	public boolean supportsSubqueryOnMutatingTable() {
-		return false;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MySQLDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,373 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.util.StringHelper;
+
+/**
+ * An SQL dialect for MySQL (prior to 5.x).
+ *
+ * @author Gavin King
+ */
+public class MySQLDialect extends Dialect {
+
+	public MySQLDialect() {
+		super();
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "datetime" );
+		registerColumnType( Types.VARBINARY, "longblob" );
+		registerColumnType( Types.VARBINARY, 16777215, "mediumblob" );
+		registerColumnType( Types.VARBINARY, 65535, "blob" );
+		registerColumnType( Types.VARBINARY, 255, "tinyblob" );
+		registerColumnType( Types.NUMERIC, "decimal($p,$s)" );
+		registerColumnType( Types.BLOB, "longblob" );
+//		registerColumnType( Types.BLOB, 16777215, "mediumblob" );
+//		registerColumnType( Types.BLOB, 65535, "blob" );
+		registerColumnType( Types.CLOB, "longtext" );
+//		registerColumnType( Types.CLOB, 16777215, "mediumtext" );
+//		registerColumnType( Types.CLOB, 65535, "text" );
+		registerVarcharTypes();
+
+		registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction("bin", new StandardSQLFunction("bin", Hibernate.STRING) );
+		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
+		registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.LONG) );
+		registerFunction("lcase", new StandardSQLFunction("lcase") );
+		registerFunction("lower", new StandardSQLFunction("lower") );
+		registerFunction("length", new StandardSQLFunction("length", Hibernate.LONG) );
+		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction("ord", new StandardSQLFunction("ord", Hibernate.INTEGER) );
+		registerFunction("quote", new StandardSQLFunction("quote") );
+		registerFunction("reverse", new StandardSQLFunction("reverse") );
+		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction("soundex", new StandardSQLFunction("soundex") );
+		registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) );
+		registerFunction("ucase", new StandardSQLFunction("ucase") );
+		registerFunction("upper", new StandardSQLFunction("upper") );
+		registerFunction("unhex", new StandardSQLFunction("unhex", Hibernate.STRING) );
+
+		registerFunction("abs", new StandardSQLFunction("abs") );
+		registerFunction("sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+		registerFunction("crc32", new StandardSQLFunction("crc32", Hibernate.LONG) );
+		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
+		registerFunction("log2", new StandardSQLFunction("log2", Hibernate.DOUBLE) );
+		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
+		registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
+		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
+		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+
+		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+
+		registerFunction("ceiling", new StandardSQLFunction("ceiling", Hibernate.INTEGER) );
+		registerFunction("ceil", new StandardSQLFunction("ceil", Hibernate.INTEGER) );
+		registerFunction("floor", new StandardSQLFunction("floor", Hibernate.INTEGER) );
+		registerFunction("round", new StandardSQLFunction("round", Hibernate.INTEGER) );
+
+		registerFunction("datediff", new StandardSQLFunction("datediff", Hibernate.INTEGER) );
+		registerFunction("timediff", new StandardSQLFunction("timediff", Hibernate.TIME) );
+		registerFunction("date_format", new StandardSQLFunction("date_format", Hibernate.STRING) );
+
+		registerFunction("curdate", new NoArgSQLFunction("curdate", Hibernate.DATE) );
+		registerFunction("curtime", new NoArgSQLFunction("curtime", Hibernate.TIME) );
+		registerFunction("current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
+		registerFunction("current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) );
+		registerFunction("current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
+		registerFunction("day", new StandardSQLFunction("day", Hibernate.INTEGER) );
+		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) );
+		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
+		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
+		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
+		registerFunction("from_days", new StandardSQLFunction("from_days", Hibernate.DATE) );
+		registerFunction("from_unixtime", new StandardSQLFunction("from_unixtime", Hibernate.TIMESTAMP) );
+		registerFunction("hour", new StandardSQLFunction("hour", Hibernate.INTEGER) );
+		registerFunction("last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
+		registerFunction("localtime", new NoArgSQLFunction("localtime", Hibernate.TIMESTAMP) );
+		registerFunction("localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP) );
+		registerFunction("microseconds", new StandardSQLFunction("microseconds", Hibernate.INTEGER) );
+		registerFunction("minute", new StandardSQLFunction("minute", Hibernate.INTEGER) );
+		registerFunction("month", new StandardSQLFunction("month", Hibernate.INTEGER) );
+		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
+		registerFunction("now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) );
+		registerFunction("quarter", new StandardSQLFunction("quarter", Hibernate.INTEGER) );
+		registerFunction("second", new StandardSQLFunction("second", Hibernate.INTEGER) );
+		registerFunction("sec_to_time", new StandardSQLFunction("sec_to_time", Hibernate.TIME) );
+		registerFunction("sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP) );
+		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
+		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
+		registerFunction("time_to_sec", new StandardSQLFunction("time_to_sec", Hibernate.INTEGER) );
+		registerFunction("to_days", new StandardSQLFunction("to_days", Hibernate.LONG) );
+		registerFunction("unix_timestamp", new StandardSQLFunction("unix_timestamp", Hibernate.LONG) );
+		registerFunction("utc_date", new NoArgSQLFunction("utc_date", Hibernate.STRING) );
+		registerFunction("utc_time", new NoArgSQLFunction("utc_time", Hibernate.STRING) );
+		registerFunction("utc_timestamp", new NoArgSQLFunction("utc_timestamp", Hibernate.STRING) );
+		registerFunction("week", new StandardSQLFunction("week", Hibernate.INTEGER) );
+		registerFunction("weekday", new StandardSQLFunction("weekday", Hibernate.INTEGER) );
+		registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) );
+		registerFunction("year", new StandardSQLFunction("year", Hibernate.INTEGER) );
+		registerFunction("yearweek", new StandardSQLFunction("yearweek", Hibernate.INTEGER) );
+
+		registerFunction("hex", new StandardSQLFunction("hex", Hibernate.STRING) );
+		registerFunction("oct", new StandardSQLFunction("oct", Hibernate.STRING) );
+
+		registerFunction("octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
+		registerFunction("bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) );
+
+		registerFunction("bit_count", new StandardSQLFunction("bit_count", Hibernate.LONG) );
+		registerFunction("encrypt", new StandardSQLFunction("encrypt", Hibernate.STRING) );
+		registerFunction("md5", new StandardSQLFunction("md5", Hibernate.STRING) );
+		registerFunction("sha1", new StandardSQLFunction("sha1", Hibernate.STRING) );
+		registerFunction("sha", new StandardSQLFunction("sha", Hibernate.STRING) );
+
+		registerFunction( "concat", new StandardSQLFunction( "concat", Hibernate.STRING ) );
+
+		getDefaultProperties().setProperty(Environment.MAX_FETCH_DEPTH, "2");
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+	}
+
+	protected void registerVarcharTypes() {
+		registerColumnType( Types.VARCHAR, "longtext" );
+//		registerColumnType( Types.VARCHAR, 16777215, "mediumtext" );
+//		registerColumnType( Types.VARCHAR, 65535, "text" );
+		registerColumnType( Types.VARCHAR, 255, "varchar($l)" );
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+	
+	public boolean qualifyIndexName() {
+		return false;
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+	
+	public String getIdentitySelectString() {
+		return "select last_insert_id()";
+	}
+
+	public String getIdentityColumnString() {
+		return "not null auto_increment"; //starts with 1, implicitly
+	}
+
+	public String getAddForeignKeyConstraintString(
+			String constraintName, 
+			String[] foreignKey, 
+			String referencedTable, 
+			String[] primaryKey, boolean referencesPrimaryKey
+	) {
+		String cols = StringHelper.join(", ", foreignKey);
+		return new StringBuffer(30)
+			.append(" add index ")
+			.append(constraintName)
+			.append(" (")
+			.append(cols)
+			.append("), add constraint ")
+			.append(constraintName)
+			.append(" foreign key (")
+			.append(cols)
+			.append(") references ")
+			.append(referencedTable)
+			.append(" (")
+			.append( StringHelper.join(", ", primaryKey) )
+			.append(')')
+			.toString();
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+	
+	public String getDropForeignKeyString() {
+		return " drop foreign key ";
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		return new StringBuffer( sql.length()+20 )
+			.append(sql)
+			.append( hasOffset ? " limit ?, ?" : " limit ?")
+			.toString();
+	}
+	
+	/*
+	 * Temporary, until MySQL fix Connector/J bug
+	 */
+	/*public String getLimitString(String sql, int offset, int limit) {
+		StringBuffer buf = new StringBuffer( sql.length()+20 )
+			.append(sql);
+		if (offset>0) {
+			buf.append(" limit ")
+				.append(offset)
+				.append(", ")
+				.append(limit);
+		}
+		else {
+			buf.append(" limit ")
+				.append(limit);
+		}
+		return buf.toString();
+	}*/
+
+	/*
+	 * Temporary, until MySQL fix Connector/J bug
+	 */
+	/*public boolean supportsVariableLimit() {
+		return false;
+	}*/
+
+	public char closeQuote() {
+		return '`';
+	}
+
+	public char openQuote() {
+		return '`';
+	}
+
+	public boolean supportsIfExistsBeforeTableName() {
+		return true;
+	}
+
+	public String getSelectGUIDString() {
+		return "select uuid()";
+	}
+
+	public boolean supportsCascadeDelete() {
+		return false;
+	}
+	
+	public String getTableComment(String comment) {
+		return " comment='" + comment + "'";
+	}
+
+	public String getColumnComment(String comment) {
+		return " comment '" + comment + "'";
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create temporary table if not exists";
+	}
+
+	public String getCastTypeName(int code) {
+		if ( code==Types.INTEGER ) {
+			return "signed";
+		}
+		else if ( code==Types.VARCHAR ) {
+			return "char";
+		}
+		else if ( code==Types.VARBINARY ) {
+			return "binary";
+		}
+		else {
+			return super.getCastTypeName( code );
+		}
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select now()";
+	}
+
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		return col;
+	} 
+	
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		boolean isResultSet = ps.execute(); 
+		while (!isResultSet && ps.getUpdateCount() != -1) { 
+			isResultSet = ps.getMoreResults(); 
+		} 
+		return ps.getResultSet();
+	}
+
+	public boolean supportsRowValueConstructorSyntax() {
+		return true;
+	}
+
+	public Boolean performTemporaryTableDDLInIsolation() {
+		return Boolean.FALSE;
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean areStringComparisonsCaseInsensitive() {
+		return true;
+	}
+
+	public boolean supportsLobValueChangePropogation() {
+		// note: at least my local MySQL 5.1 install shows this not working...
+		return false;
+	}
+
+	public boolean supportsSubqueryOnMutatingTable() {
+		return false;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: MySQLInnoDBDialect.java 7118 2005-06-12 21:55:12Z oneovthafew $
-package org.hibernate.dialect;
-
-/**
- * @author Gavin King
- */
-public class MySQLInnoDBDialect extends MySQLDialect {
-
-	public boolean supportsCascadeDelete() {
-		return true;
-	}
-	
-	public String getTableTypeString() {
-		return " type=InnoDB";
-	}
-
-	public boolean hasSelfReferentialForeignKeyBug() {
-		return true;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLInnoDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.dialect;
+
+/**
+ * @author Gavin King
+ */
+public class MySQLInnoDBDialect extends MySQLDialect {
+
+	public boolean supportsCascadeDelete() {
+		return true;
+	}
+	
+	public String getTableTypeString() {
+		return " type=InnoDB";
+	}
+
+	public boolean hasSelfReferentialForeignKeyBug() {
+		return true;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-//$Id: MySQLMyISAMDialect.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.dialect;
-
-/**
- * @author Gavin King
- */
-public class MySQLMyISAMDialect extends MySQLDialect {
-
-	public String getTableTypeString() {
-		return " type=MyISAM";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/MySQLMyISAMDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.dialect;
+
+/**
+ * @author Gavin King
+ */
+public class MySQLMyISAMDialect extends MySQLDialect {
+
+	public String getTableTypeString() {
+		return " type=MyISAM";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: Oracle9Dialect.java 11286 2007-03-15 10:33:16Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.ANSIJoinFragment;
-
-
-/**
- * A dialect specifically for use with Oracle 10g.
- * <p/>
- * The main difference between this dialect and {@link Oracle9iDialect}
- * is the use of "ANSI join syntax" here...
- *
- * @author Steve Ebersole
- */
-public class Oracle10gDialect extends Oracle9iDialect {
-
-	public Oracle10gDialect() {
-		super();
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		return new ANSIJoinFragment();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle10gDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.ANSIJoinFragment;
+
+
+/**
+ * A dialect specifically for use with Oracle 10g.
+ * <p/>
+ * The main difference between this dialect and {@link Oracle9iDialect}
+ * is the use of "ANSI join syntax" here...
+ *
+ * @author Steve Ebersole
+ */
+public class Oracle10gDialect extends Oracle9iDialect {
+
+	public Oracle10gDialect() {
+		super();
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		return new ANSIJoinFragment();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,438 +0,0 @@
-//$Id: OracleDialect.java 8610 2005-11-18 18:30:27Z steveebersole $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-import java.sql.SQLException;
-import java.sql.ResultSet;
-import java.sql.CallableStatement;
-
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.DecodeCaseFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.OracleJoinFragment;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.NvlFunction;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-/**
- * A dialect for Oracle 8i.
- *
- * @author Steve Ebersole
- */
-public class Oracle8iDialect extends Dialect {
-
-	public Oracle8iDialect() {
-		super();
-		registerCharacterTypeMappings();
-		registerNumericTypeMappings();
-		registerDateTimeTypeMappings();
-		registerLargeObjectTypeMappings();
-
-		registerReverseHibernateTypeMappings();
-
-		registerFunctions();
-
-		registerDefaultProperties();
-	}
-
-	protected void registerCharacterTypeMappings() {
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
-		registerColumnType( Types.VARCHAR, "long" );
-	}
-
-	protected void registerNumericTypeMappings() {
-		registerColumnType( Types.BIT, "number(1,0)" );
-		registerColumnType( Types.BIGINT, "number(19,0)" );
-		registerColumnType( Types.SMALLINT, "number(5,0)" );
-		registerColumnType( Types.TINYINT, "number(3,0)" );
-		registerColumnType( Types.INTEGER, "number(10,0)" );
-
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.NUMERIC, "number($p,$s)" );
-		registerColumnType( Types.DECIMAL, "number($p,$s)" );
-	}
-
-	protected void registerDateTimeTypeMappings() {
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "date" );
-		registerColumnType( Types.TIMESTAMP, "date" );
-	}
-
-	protected void registerLargeObjectTypeMappings() {
-		registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
-		registerColumnType( Types.VARBINARY, "long raw" );
-
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "clob" );
-	}
-
-	protected void registerReverseHibernateTypeMappings() {
-	}
-
-	protected void registerFunctions() {
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
-		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
-		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
-		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
-		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "trunc", new StandardSQLFunction("trunc") );
-		registerFunction( "ceil", new StandardSQLFunction("ceil") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-
-		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
-		registerFunction( "initcap", new StandardSQLFunction("initcap") );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction( "soundex", new StandardSQLFunction("soundex") );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
-
-		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
-		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );
-
-		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
-		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
-
-		registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
-		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
-		registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
-		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
-
-		registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
-		registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) );
-
-		// Multi-param string dialect functions...
-		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
-		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) );
-		registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) );
-		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
-		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
-		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
-		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
-		registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) );
-		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
-
-		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
-		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) );
-		registerFunction( "coalesce", new NvlFunction() );
-
-		// Multi-param numeric dialect functions...
-		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) );
-		registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) );
-		registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) );
-		registerFunction( "nvl", new StandardSQLFunction("nvl") );
-		registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
-		registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) );
-
-		// Multi-param date dialect functions...
-		registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) );
-		registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) );
-		registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) );
-
-		registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) );
-	}
-
-	protected void registerDefaultProperties() {
-		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
-		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
-		// Oracle driver reports to support getGeneratedKeys(), but they only
-		// support the version taking an array of the names of the columns to
-		// be returned (via its RETURNING clause).  No other driver seems to
-		// support this overloaded version.
-		getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
-	}
-
-
-	// features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Support for the oracle proprietary join syntax...
-	 *
-	 * @return The orqacle join fragment
-	 */
-	public JoinFragment createOuterJoinFragment() {
-		return new OracleJoinFragment();
-	}
-
-	/**
-	 * Map case support to the Oracle DECODE function.  Oracle did not
-	 * add support for CASE until 9i.
-	 *
-	 * @return The oracle CASE -> DECODE fragment
-	 */
-	public CaseFragment createCaseFragment() {
-		return new DecodeCaseFragment();
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		sql = sql.trim();
-		boolean isForUpdate = false;
-		if ( sql.toLowerCase().endsWith(" for update") ) {
-			sql = sql.substring( 0, sql.length()-11 );
-			isForUpdate = true;
-		}
-
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
-		if (hasOffset) {
-			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
-		}
-		else {
-			pagingSelect.append("select * from ( ");
-		}
-		pagingSelect.append(sql);
-		if (hasOffset) {
-			pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
-		}
-		else {
-			pagingSelect.append(" ) where rownum <= ?");
-		}
-
-		if ( isForUpdate ) {
-			pagingSelect.append( " for update" );
-		}
-
-		return pagingSelect.toString();
-	}
-
-	/**
-	 * Allows access to the basic {@link Dialect#getSelectClauseNullString}
-	 * implementation...
-	 *
-	 * @param sqlType The {@link java.sql.Types} mapping type code
-	 * @return The appropriate select cluse fragment
-	 */
-	public String getBasicSelectClauseNullString(int sqlType) {
-		return super.getSelectClauseNullString( sqlType );
-	}
-
-	public String getSelectClauseNullString(int sqlType) {
-		switch(sqlType) {
-			case Types.VARCHAR:
-			case Types.CHAR:
-				return "to_char(null)";
-			case Types.DATE:
-			case Types.TIMESTAMP:
-			case Types.TIME:
-				return "to_date(null)";
-			default:
-				return "to_number(null)";
-		}
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select sysdate from dual";
-	}
-
-	public String getCurrentTimestampSQLFunctionName() {
-		return "sysdate";
-	}
-
-
-	// features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName; //starts with 1, implicitly
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getCascadeConstraintsString() {
-		return " cascade constraints";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public String getForUpdateNowaitString() {
-		return " for update nowait";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public boolean supportsPooledSequences() {
-		return true;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public String getForUpdateString(String aliases) {
-		return getForUpdateString() + " of " + aliases;
-	}
-
-	public String getForUpdateNowaitString(String aliases) {
-		return getForUpdateString() + " of " + aliases + " nowait";
-	}
-
-	public boolean bindLimitParametersInReverseOrder() {
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean forUpdateOfColumns() {
-		return true;
-	}
-
-	public String getQuerySequencesString() {
-		return    " select sequence_name from all_sequences"
-				+ "  union"
-				+ " select synonym_name"
-				+ "   from all_synonyms us, all_sequences asq"
-				+ "  where asq.sequence_name = us.table_name"
-				+ "    and asq.sequence_owner = us.table_owner";
-	}
-
-	public String getSelectGUIDString() {
-		return "select rawtohex(sys_guid()) from dual";
-	}
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-        return EXTRACTER;
-	}
-
-	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-
-		/**
-		 * Extract the name of the violated constraint from the given SQLException.
-		 *
-		 * @param sqle The exception that was the result of the constraint violation.
-		 * @return The extracted constraint name.
-		 */
-		public String extractConstraintName(SQLException sqle) {
-			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
-			if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
-				return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
-			}
-			else if ( errorCode == 1400 ) {
-				// simple nullability constraint
-				return null;
-			}
-			else {
-				return null;
-			}
-		}
-
-	};
-
-	// not final-static to avoid possible classcast exceptions if using different oracle drivers.
-	int oracletypes_cursor_value = 0;
-	public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
-		if(oracletypes_cursor_value==0) {
-			try {
-				Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
-				oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
-			} catch (Exception se) {
-				throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
-			}
-		}
-		//	register the type of the out param - an Oracle specific type
-		statement.registerOutParameter(col, oracletypes_cursor_value);
-		col++;
-		return col;
-	}
-
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		ps.execute();
-		return ( ResultSet ) ps.getObject( 1 );
-	}
-
-	public boolean supportsUnionAll() {
-		return true;
-	}
-
-	public boolean supportsCommentOn() {
-		return true;
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		String name = super.generateTemporaryTableName(baseTableName);
-		return name.length() > 30 ? name.substring( 1, 30 ) : name;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "on commit delete rows";
-	}
-
-	public boolean dropTemporaryTableAfterUse() {
-		return false;
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsExistsInSelect() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,461 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.sql.CallableStatement;
+
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.DecodeCaseFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.OracleJoinFragment;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.NvlFunction;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+/**
+ * A dialect for Oracle 8i.
+ *
+ * @author Steve Ebersole
+ */
+public class Oracle8iDialect extends Dialect {
+
+	public Oracle8iDialect() {
+		super();
+		registerCharacterTypeMappings();
+		registerNumericTypeMappings();
+		registerDateTimeTypeMappings();
+		registerLargeObjectTypeMappings();
+
+		registerReverseHibernateTypeMappings();
+
+		registerFunctions();
+
+		registerDefaultProperties();
+	}
+
+	protected void registerCharacterTypeMappings() {
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
+		registerColumnType( Types.VARCHAR, "long" );
+	}
+
+	protected void registerNumericTypeMappings() {
+		registerColumnType( Types.BIT, "number(1,0)" );
+		registerColumnType( Types.BIGINT, "number(19,0)" );
+		registerColumnType( Types.SMALLINT, "number(5,0)" );
+		registerColumnType( Types.TINYINT, "number(3,0)" );
+		registerColumnType( Types.INTEGER, "number(10,0)" );
+
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.NUMERIC, "number($p,$s)" );
+		registerColumnType( Types.DECIMAL, "number($p,$s)" );
+	}
+
+	protected void registerDateTimeTypeMappings() {
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "date" );
+		registerColumnType( Types.TIMESTAMP, "date" );
+	}
+
+	protected void registerLargeObjectTypeMappings() {
+		registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
+		registerColumnType( Types.VARBINARY, "long raw" );
+
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "clob" );
+	}
+
+	protected void registerReverseHibernateTypeMappings() {
+	}
+
+	protected void registerFunctions() {
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
+		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
+		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
+		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
+		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "trunc", new StandardSQLFunction("trunc") );
+		registerFunction( "ceil", new StandardSQLFunction("ceil") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+
+		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
+		registerFunction( "initcap", new StandardSQLFunction("initcap") );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction( "soundex", new StandardSQLFunction("soundex") );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
+
+		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
+		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );
+
+		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
+		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
+
+		registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
+		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
+		registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
+		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
+
+		registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
+		registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) );
+
+		// Multi-param string dialect functions...
+		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
+		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) );
+		registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) );
+		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
+		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
+		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
+		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
+		registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) );
+		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
+
+		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
+		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) );
+		registerFunction( "coalesce", new NvlFunction() );
+
+		// Multi-param numeric dialect functions...
+		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) );
+		registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) );
+		registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) );
+		registerFunction( "nvl", new StandardSQLFunction("nvl") );
+		registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
+		registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) );
+
+		// Multi-param date dialect functions...
+		registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) );
+		registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) );
+		registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) );
+
+		registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) );
+	}
+
+	protected void registerDefaultProperties() {
+		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "true" );
+		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE );
+		// Oracle driver reports to support getGeneratedKeys(), but they only
+		// support the version taking an array of the names of the columns to
+		// be returned (via its RETURNING clause).  No other driver seems to
+		// support this overloaded version.
+		getDefaultProperties().setProperty( Environment.USE_GET_GENERATED_KEYS, "false" );
+	}
+
+
+	// features which change between 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Support for the oracle proprietary join syntax...
+	 *
+	 * @return The orqacle join fragment
+	 */
+	public JoinFragment createOuterJoinFragment() {
+		return new OracleJoinFragment();
+	}
+
+	/**
+	 * Map case support to the Oracle DECODE function.  Oracle did not
+	 * add support for CASE until 9i.
+	 *
+	 * @return The oracle CASE -> DECODE fragment
+	 */
+	public CaseFragment createCaseFragment() {
+		return new DecodeCaseFragment();
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		sql = sql.trim();
+		boolean isForUpdate = false;
+		if ( sql.toLowerCase().endsWith(" for update") ) {
+			sql = sql.substring( 0, sql.length()-11 );
+			isForUpdate = true;
+		}
+
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
+		if (hasOffset) {
+			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
+		}
+		else {
+			pagingSelect.append("select * from ( ");
+		}
+		pagingSelect.append(sql);
+		if (hasOffset) {
+			pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
+		}
+		else {
+			pagingSelect.append(" ) where rownum <= ?");
+		}
+
+		if ( isForUpdate ) {
+			pagingSelect.append( " for update" );
+		}
+
+		return pagingSelect.toString();
+	}
+
+	/**
+	 * Allows access to the basic {@link Dialect#getSelectClauseNullString}
+	 * implementation...
+	 *
+	 * @param sqlType The {@link java.sql.Types} mapping type code
+	 * @return The appropriate select cluse fragment
+	 */
+	public String getBasicSelectClauseNullString(int sqlType) {
+		return super.getSelectClauseNullString( sqlType );
+	}
+
+	public String getSelectClauseNullString(int sqlType) {
+		switch(sqlType) {
+			case Types.VARCHAR:
+			case Types.CHAR:
+				return "to_char(null)";
+			case Types.DATE:
+			case Types.TIMESTAMP:
+			case Types.TIME:
+				return "to_date(null)";
+			default:
+				return "to_number(null)";
+		}
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select sysdate from dual";
+	}
+
+	public String getCurrentTimestampSQLFunctionName() {
+		return "sysdate";
+	}
+
+
+	// features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName; //starts with 1, implicitly
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getCascadeConstraintsString() {
+		return " cascade constraints";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public String getForUpdateNowaitString() {
+		return " for update nowait";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public boolean supportsPooledSequences() {
+		return true;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public String getForUpdateString(String aliases) {
+		return getForUpdateString() + " of " + aliases;
+	}
+
+	public String getForUpdateNowaitString(String aliases) {
+		return getForUpdateString() + " of " + aliases + " nowait";
+	}
+
+	public boolean bindLimitParametersInReverseOrder() {
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean forUpdateOfColumns() {
+		return true;
+	}
+
+	public String getQuerySequencesString() {
+		return    " select sequence_name from all_sequences"
+				+ "  union"
+				+ " select synonym_name"
+				+ "   from all_synonyms us, all_sequences asq"
+				+ "  where asq.sequence_name = us.table_name"
+				+ "    and asq.sequence_owner = us.table_owner";
+	}
+
+	public String getSelectGUIDString() {
+		return "select rawtohex(sys_guid()) from dual";
+	}
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+        return EXTRACTER;
+	}
+
+	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+		/**
+		 * Extract the name of the violated constraint from the given SQLException.
+		 *
+		 * @param sqle The exception that was the result of the constraint violation.
+		 * @return The extracted constraint name.
+		 */
+		public String extractConstraintName(SQLException sqle) {
+			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
+			if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
+				return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
+			}
+			else if ( errorCode == 1400 ) {
+				// simple nullability constraint
+				return null;
+			}
+			else {
+				return null;
+			}
+		}
+
+	};
+
+	// not final-static to avoid possible classcast exceptions if using different oracle drivers.
+	int oracletypes_cursor_value = 0;
+	public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
+		if(oracletypes_cursor_value==0) {
+			try {
+				Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
+				oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
+			} catch (Exception se) {
+				throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
+			}
+		}
+		//	register the type of the out param - an Oracle specific type
+		statement.registerOutParameter(col, oracletypes_cursor_value);
+		col++;
+		return col;
+	}
+
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		ps.execute();
+		return ( ResultSet ) ps.getObject( 1 );
+	}
+
+	public boolean supportsUnionAll() {
+		return true;
+	}
+
+	public boolean supportsCommentOn() {
+		return true;
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		String name = super.generateTemporaryTableName(baseTableName);
+		return name.length() > 30 ? name.substring( 1, 30 ) : name;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "on commit delete rows";
+	}
+
+	public boolean dropTemporaryTableAfterUse() {
+		return false;
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsExistsInSelect() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,351 +0,0 @@
-//$Id: Oracle9Dialect.java 11259 2007-03-07 22:55:12Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.NvlFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
- *
- * @deprecated Use either Oracle9iDialect or Oracle10gDialect instead
- * @author Gavin King, David Channon
- */
-public class Oracle9Dialect extends Dialect {
-
-	private static final Logger log = LoggerFactory.getLogger( Oracle9Dialect.class );
-
-	public Oracle9Dialect() {
-		super();
-		log.warn( "The Oracle9Dialect dialect has been deprecated; use either Oracle9iDialect or Oracle10gDialect instead" );
-		registerColumnType( Types.BIT, "number(1,0)" );
-		registerColumnType( Types.BIGINT, "number(19,0)" );
-		registerColumnType( Types.SMALLINT, "number(5,0)" );
-		registerColumnType( Types.TINYINT, "number(3,0)" );
-		registerColumnType( Types.INTEGER, "number(10,0)" );
-		registerColumnType( Types.CHAR, "char(1 char)" );
-		registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
-		registerColumnType( Types.VARCHAR, "long" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "date" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
-		registerColumnType( Types.VARBINARY, "long raw" );
-		registerColumnType( Types.NUMERIC, "number($p,$s)" );
-		registerColumnType( Types.DECIMAL, "number($p,$s)" );
-		registerColumnType( Types.BLOB, "blob" );
-		registerColumnType( Types.CLOB, "clob" );
-
-		// Oracle driver reports to support getGeneratedKeys(), but they only
-		// support the version taking an array of the names of the columns to
-		// be returned (via its RETURNING clause).  No other driver seems to
-		// support this overloaded version.
-		getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
-		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
-		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
-		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
-		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
-		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "trunc", new StandardSQLFunction("trunc") );
-		registerFunction( "ceil", new StandardSQLFunction("ceil") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-
-		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
-		registerFunction( "initcap", new StandardSQLFunction("initcap") );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction( "soundex", new StandardSQLFunction("soundex") );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
-
-		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
-		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );
-
-		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
-		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
-		
-		registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
-		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
-		registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
-		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
-
-		registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
-		registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) );
-
-		// Multi-param string dialect functions...
-		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
-		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) );
-		registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) );
-		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
-		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
-		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
-		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
-		registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) );
-		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
-
-		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
-		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) );
-		registerFunction( "coalesce", new NvlFunction() );
-
-		// Multi-param numeric dialect functions...
-		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) );
-		registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) );
-		registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) );
-		registerFunction( "nvl", new StandardSQLFunction("nvl") );
-		registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
-		registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) );
-
-		// Multi-param date dialect functions...
-		registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) );
-		registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) );
-		registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) );
-
-		registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) );
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName; //starts with 1, implicitly
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getCascadeConstraintsString() {
-		return " cascade constraints";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public String getForUpdateNowaitString() {
-		return " for update nowait";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public boolean supportsPooledSequences() {
-		return true;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		
-		sql = sql.trim();
-		boolean isForUpdate = false;
-		if ( sql.toLowerCase().endsWith(" for update") ) {
-			sql = sql.substring( 0, sql.length()-11 );
-			isForUpdate = true;
-		}
-		
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
-		if (hasOffset) {
-			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
-		}
-		else {
-			pagingSelect.append("select * from ( ");
-		}
-		pagingSelect.append(sql);
-		if (hasOffset) {
-			pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
-		}
-		else {
-			pagingSelect.append(" ) where rownum <= ?");
-		}
-
-		if ( isForUpdate ) {
-			pagingSelect.append( " for update" );
-		}
-		
-		return pagingSelect.toString();
-	}
-
-	public String getForUpdateString(String aliases) {
-		return getForUpdateString() + " of " + aliases;
-	}
-
-	public String getForUpdateNowaitString(String aliases) {
-		return getForUpdateString() + " of " + aliases + " nowait";
-	}
-
-	public boolean bindLimitParametersInReverseOrder() {
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-	
-	public boolean forUpdateOfColumns() {
-		return true;
-	}
-
-	public String getQuerySequencesString() {
-		return "select sequence_name from user_sequences";
-	}
-
-	public String getSelectGUIDString() {
-		return "select rawtohex(sys_guid()) from dual";
-	}
-	
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-        return EXTRACTER;
-	}
-
-	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-
-		/**
-		 * Extract the name of the violated constraint from the given SQLException.
-		 *
-		 * @param sqle The exception that was the result of the constraint violation.
-		 * @return The extracted constraint name.
-		 */
-		public String extractConstraintName(SQLException sqle) {
-			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
-			if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
-				return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
-			}
-			else if ( errorCode == 1400 ) {
-				// simple nullability constraint
-				return null;
-			}
-			else {
-				return null;
-			}
-		}
-
-	};
-
-	// not final-static to avoid possible classcast exceptions if using different oracle drivers.
-	int oracletypes_cursor_value = 0; 
-	public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
-		if(oracletypes_cursor_value==0) {
-			try {
-				Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
-				oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
-			} catch (Exception se) {
-				throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
-			} 
-		}
-		//	register the type of the out param - an Oracle specific type
-		statement.registerOutParameter(col, oracletypes_cursor_value);
-		col++;
-		return col;
-	}
-	
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		ps.execute();
-		return ( ResultSet ) ps.getObject( 1 );
-	}
-
-	public boolean supportsUnionAll() {
-		return true;
-	}
-	
-	public boolean supportsCommentOn() {
-		return true;
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		String name = super.generateTemporaryTableName(baseTableName);
-		return name.length() > 30 ? name.substring( 1, 30 ) : name;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "on commit delete rows";
-	}
-
-	public boolean dropTemporaryTableAfterUse() {
-		return false;
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select systimestamp from dual";
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsExistsInSelect() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.NvlFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * An SQL dialect for Oracle 9 (uses ANSI-style syntax where possible).
+ *
+ * @deprecated Use either Oracle9iDialect or Oracle10gDialect instead
+ * @author Gavin King, David Channon
+ */
+public class Oracle9Dialect extends Dialect {
+
+	private static final Logger log = LoggerFactory.getLogger( Oracle9Dialect.class );
+
+	public Oracle9Dialect() {
+		super();
+		log.warn( "The Oracle9Dialect dialect has been deprecated; use either Oracle9iDialect or Oracle10gDialect instead" );
+		registerColumnType( Types.BIT, "number(1,0)" );
+		registerColumnType( Types.BIGINT, "number(19,0)" );
+		registerColumnType( Types.SMALLINT, "number(5,0)" );
+		registerColumnType( Types.TINYINT, "number(3,0)" );
+		registerColumnType( Types.INTEGER, "number(10,0)" );
+		registerColumnType( Types.CHAR, "char(1 char)" );
+		registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
+		registerColumnType( Types.VARCHAR, "long" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "date" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, 2000, "raw($l)" );
+		registerColumnType( Types.VARBINARY, "long raw" );
+		registerColumnType( Types.NUMERIC, "number($p,$s)" );
+		registerColumnType( Types.DECIMAL, "number($p,$s)" );
+		registerColumnType( Types.BLOB, "blob" );
+		registerColumnType( Types.CLOB, "clob" );
+
+		// Oracle driver reports to support getGeneratedKeys(), but they only
+		// support the version taking an array of the names of the columns to
+		// be returned (via its RETURNING clause).  No other driver seems to
+		// support this overloaded version.
+		getDefaultProperties().setProperty(Environment.USE_GET_GENERATED_KEYS, "false");
+		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
+		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
+		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
+		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
+		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "trunc", new StandardSQLFunction("trunc") );
+		registerFunction( "ceil", new StandardSQLFunction("ceil") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+
+		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
+		registerFunction( "initcap", new StandardSQLFunction("initcap") );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction( "soundex", new StandardSQLFunction("soundex") );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
+
+		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
+		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.TIMESTAMP) );
+
+		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
+		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
+		
+		registerFunction( "last_day", new StandardSQLFunction("last_day", Hibernate.DATE) );
+		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.DATE, false) );
+		registerFunction( "systimestamp", new NoArgSQLFunction("systimestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction( "uid", new NoArgSQLFunction("uid", Hibernate.INTEGER, false) );
+		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
+
+		registerFunction( "rowid", new NoArgSQLFunction("rowid", Hibernate.LONG, false) );
+		registerFunction( "rownum", new NoArgSQLFunction("rownum", Hibernate.LONG, false) );
+
+		// Multi-param string dialect functions...
+		registerFunction( "concat", new VarArgsSQLFunction(Hibernate.STRING, "", "||", "") );
+		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.INTEGER) );
+		registerFunction( "instrb", new StandardSQLFunction("instrb", Hibernate.INTEGER) );
+		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
+		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
+		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
+		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
+		registerFunction( "substrb", new StandardSQLFunction("substrb", Hibernate.STRING) );
+		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
+
+		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
+		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.INTEGER, "instr(?2,?1)" ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "vsize(?1)*8" ) );
+		registerFunction( "coalesce", new NvlFunction() );
+
+		// Multi-param numeric dialect functions...
+		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.FLOAT) );
+		registerFunction( "log", new StandardSQLFunction("log", Hibernate.INTEGER) );
+		registerFunction( "mod", new StandardSQLFunction("mod", Hibernate.INTEGER) );
+		registerFunction( "nvl", new StandardSQLFunction("nvl") );
+		registerFunction( "nvl2", new StandardSQLFunction("nvl2") );
+		registerFunction( "power", new StandardSQLFunction("power", Hibernate.FLOAT) );
+
+		// Multi-param date dialect functions...
+		registerFunction( "add_months", new StandardSQLFunction("add_months", Hibernate.DATE) );
+		registerFunction( "months_between", new StandardSQLFunction("months_between", Hibernate.FLOAT) );
+		registerFunction( "next_day", new StandardSQLFunction("next_day", Hibernate.DATE) );
+
+		registerFunction( "str", new StandardSQLFunction("to_char", Hibernate.STRING) );
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName; //starts with 1, implicitly
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getCascadeConstraintsString() {
+		return " cascade constraints";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public String getForUpdateNowaitString() {
+		return " for update nowait";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public boolean supportsPooledSequences() {
+		return true;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		
+		sql = sql.trim();
+		boolean isForUpdate = false;
+		if ( sql.toLowerCase().endsWith(" for update") ) {
+			sql = sql.substring( 0, sql.length()-11 );
+			isForUpdate = true;
+		}
+		
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
+		if (hasOffset) {
+			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
+		}
+		else {
+			pagingSelect.append("select * from ( ");
+		}
+		pagingSelect.append(sql);
+		if (hasOffset) {
+			pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
+		}
+		else {
+			pagingSelect.append(" ) where rownum <= ?");
+		}
+
+		if ( isForUpdate ) {
+			pagingSelect.append( " for update" );
+		}
+		
+		return pagingSelect.toString();
+	}
+
+	public String getForUpdateString(String aliases) {
+		return getForUpdateString() + " of " + aliases;
+	}
+
+	public String getForUpdateNowaitString(String aliases) {
+		return getForUpdateString() + " of " + aliases + " nowait";
+	}
+
+	public boolean bindLimitParametersInReverseOrder() {
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+	
+	public boolean forUpdateOfColumns() {
+		return true;
+	}
+
+	public String getQuerySequencesString() {
+		return "select sequence_name from user_sequences";
+	}
+
+	public String getSelectGUIDString() {
+		return "select rawtohex(sys_guid()) from dual";
+	}
+	
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+        return EXTRACTER;
+	}
+
+	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+
+		/**
+		 * Extract the name of the violated constraint from the given SQLException.
+		 *
+		 * @param sqle The exception that was the result of the constraint violation.
+		 * @return The extracted constraint name.
+		 */
+		public String extractConstraintName(SQLException sqle) {
+			int errorCode = JDBCExceptionHelper.extractErrorCode(sqle);
+			if ( errorCode == 1 || errorCode == 2291 || errorCode == 2292 ) {
+				return extractUsingTemplate( "constraint (", ") violated", sqle.getMessage() );
+			}
+			else if ( errorCode == 1400 ) {
+				// simple nullability constraint
+				return null;
+			}
+			else {
+				return null;
+			}
+		}
+
+	};
+
+	// not final-static to avoid possible classcast exceptions if using different oracle drivers.
+	int oracletypes_cursor_value = 0; 
+	public int registerResultSetOutParameter(java.sql.CallableStatement statement,int col) throws SQLException {
+		if(oracletypes_cursor_value==0) {
+			try {
+				Class types = ReflectHelper.classForName("oracle.jdbc.driver.OracleTypes");
+				oracletypes_cursor_value = types.getField("CURSOR").getInt(types.newInstance());
+			} catch (Exception se) {
+				throw new HibernateException("Problem while trying to load or access OracleTypes.CURSOR value",se);
+			} 
+		}
+		//	register the type of the out param - an Oracle specific type
+		statement.registerOutParameter(col, oracletypes_cursor_value);
+		col++;
+		return col;
+	}
+	
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		ps.execute();
+		return ( ResultSet ) ps.getObject( 1 );
+	}
+
+	public boolean supportsUnionAll() {
+		return true;
+	}
+	
+	public boolean supportsCommentOn() {
+		return true;
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		String name = super.generateTemporaryTableName(baseTableName);
+		return name.length() > 30 ? name.substring( 1, 30 ) : name;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "on commit delete rows";
+	}
+
+	public boolean dropTemporaryTableAfterUse() {
+		return false;
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select systimestamp from dual";
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsExistsInSelect() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,77 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.ANSICaseFragment;
-
-/**
- * A dialect for Oracle 9i databases.
- * <p/>
- * Unlike the older (deprecated) {@Link Oracl9Dialect), this version specifies
- * to not use "ANSI join syntax" because 9i does not seem to properly
- * handle it in all cases.
- *
- * @author Steve Ebersole
- */
-public class Oracle9iDialect extends Oracle8iDialect {
-	protected void registerCharacterTypeMappings() {
-		registerColumnType( Types.CHAR, "char(1 char)" );
-		registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
-		registerColumnType( Types.VARCHAR, "long" );
-	}
-
-	protected void registerDateTimeTypeMappings() {
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "date" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-	}
-
-	public CaseFragment createCaseFragment() {
-		// Oracle did add support for ANSI CASE statements in 9i
-		return new ANSICaseFragment();
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		sql = sql.trim();
-		boolean isForUpdate = false;
-		if ( sql.toLowerCase().endsWith(" for update") ) {
-			sql = sql.substring( 0, sql.length()-11 );
-			isForUpdate = true;
-		}
-
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
-		if (hasOffset) {
-			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
-		}
-		else {
-			pagingSelect.append("select * from ( ");
-		}
-		pagingSelect.append(sql);
-		if (hasOffset) {
-			pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
-		}
-		else {
-			pagingSelect.append(" ) where rownum <= ?");
-		}
-
-		if ( isForUpdate ) {
-			pagingSelect.append( " for update" );
-		}
-
-		return pagingSelect.toString();
-	}
-
-	public String getSelectClauseNullString(int sqlType) {
-		return getBasicSelectClauseNullString( sqlType );
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select systimestamp from dual";
-	}
-
-	public String getCurrentTimestampSQLFunctionName() {
-		// the standard SQL function name is current_timestamp...
-		return "current_timestamp";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Oracle9iDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.ANSICaseFragment;
+
+/**
+ * A dialect for Oracle 9i databases.
+ * <p/>
+ * Unlike the older (deprecated) {@Link Oracl9Dialect), this version specifies
+ * to not use "ANSI join syntax" because 9i does not seem to properly
+ * handle it in all cases.
+ *
+ * @author Steve Ebersole
+ */
+public class Oracle9iDialect extends Oracle8iDialect {
+	protected void registerCharacterTypeMappings() {
+		registerColumnType( Types.CHAR, "char(1 char)" );
+		registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
+		registerColumnType( Types.VARCHAR, "long" );
+	}
+
+	protected void registerDateTimeTypeMappings() {
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "date" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+	}
+
+	public CaseFragment createCaseFragment() {
+		// Oracle did add support for ANSI CASE statements in 9i
+		return new ANSICaseFragment();
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		sql = sql.trim();
+		boolean isForUpdate = false;
+		if ( sql.toLowerCase().endsWith(" for update") ) {
+			sql = sql.substring( 0, sql.length()-11 );
+			isForUpdate = true;
+		}
+
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
+		if (hasOffset) {
+			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
+		}
+		else {
+			pagingSelect.append("select * from ( ");
+		}
+		pagingSelect.append(sql);
+		if (hasOffset) {
+			pagingSelect.append(" ) row_ where rownum <= ?) where rownum_ > ?");
+		}
+		else {
+			pagingSelect.append(" ) where rownum <= ?");
+		}
+
+		if ( isForUpdate ) {
+			pagingSelect.append( " for update" );
+		}
+
+		return pagingSelect.toString();
+	}
+
+	public String getSelectClauseNullString(int sqlType) {
+		return getBasicSelectClauseNullString( sqlType );
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select systimestamp from dual";
+	}
+
+	public String getCurrentTimestampSQLFunctionName() {
+		// the standard SQL function name is current_timestamp...
+		return "current_timestamp";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/OracleDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-//$Id: OracleDialect.java 8610 2005-11-18 18:30:27Z steveebersole $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.DecodeCaseFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.OracleJoinFragment;
-
-/**
- * An SQL dialect for Oracle, compatible with Oracle 8.
- *
- * @deprecated Use Oracle8iDialect instead.
- * @author Gavin King
- */
-public class OracleDialect extends Oracle9Dialect {
-
-	private static final Logger log = LoggerFactory.getLogger( OracleDialect.class );
-
-	public OracleDialect() {
-		super();
-		log.warn( "The OracleDialect dialect has been deprecated; use Oracle8iDialect instead" );
-		// Oracle8 and previous define only a "DATE" type which
-		//      is used to represent all aspects of date/time
-		registerColumnType( Types.TIMESTAMP, "date" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		return new OracleJoinFragment();
-	}
-	public CaseFragment createCaseFragment() {
-		return new DecodeCaseFragment();
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-
-		sql = sql.trim();
-		boolean isForUpdate = false;
-		if ( sql.toLowerCase().endsWith(" for update") ) {
-			sql = sql.substring( 0, sql.length()-11 );
-			isForUpdate = true;
-		}
-		
-		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
-		if (hasOffset) {
-			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
-		}
-		else {
-			pagingSelect.append("select * from ( ");
-		}
-		pagingSelect.append(sql);
-		if (hasOffset) {
-			pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
-		}
-		else {
-			pagingSelect.append(" ) where rownum <= ?");
-		}
-
-		if ( isForUpdate ) {
-			pagingSelect.append( " for update" );
-		}
-		
-		return pagingSelect.toString();
-	}
-
-	public String getSelectClauseNullString(int sqlType) {
-		switch(sqlType) {
-			case Types.VARCHAR:
-			case Types.CHAR:
-				return "to_char(null)";
-			case Types.DATE:
-			case Types.TIMESTAMP:
-			case Types.TIME:
-				return "to_date(null)";
-			default:
-				return "to_number(null)";
-		}
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select sysdate from dual";
-	}
-
-	public String getCurrentTimestampSQLFunctionName() {
-		return "sysdate";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/OracleDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/OracleDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.DecodeCaseFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.OracleJoinFragment;
+
+/**
+ * An SQL dialect for Oracle, compatible with Oracle 8.
+ *
+ * @deprecated Use Oracle8iDialect instead.
+ * @author Gavin King
+ */
+public class OracleDialect extends Oracle9Dialect {
+
+	private static final Logger log = LoggerFactory.getLogger( OracleDialect.class );
+
+	public OracleDialect() {
+		super();
+		log.warn( "The OracleDialect dialect has been deprecated; use Oracle8iDialect instead" );
+		// Oracle8 and previous define only a "DATE" type which
+		//      is used to represent all aspects of date/time
+		registerColumnType( Types.TIMESTAMP, "date" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, 4000, "varchar2($l)" );
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		return new OracleJoinFragment();
+	}
+	public CaseFragment createCaseFragment() {
+		return new DecodeCaseFragment();
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+
+		sql = sql.trim();
+		boolean isForUpdate = false;
+		if ( sql.toLowerCase().endsWith(" for update") ) {
+			sql = sql.substring( 0, sql.length()-11 );
+			isForUpdate = true;
+		}
+		
+		StringBuffer pagingSelect = new StringBuffer( sql.length()+100 );
+		if (hasOffset) {
+			pagingSelect.append("select * from ( select row_.*, rownum rownum_ from ( ");
+		}
+		else {
+			pagingSelect.append("select * from ( ");
+		}
+		pagingSelect.append(sql);
+		if (hasOffset) {
+			pagingSelect.append(" ) row_ ) where rownum_ <= ? and rownum_ > ?");
+		}
+		else {
+			pagingSelect.append(" ) where rownum <= ?");
+		}
+
+		if ( isForUpdate ) {
+			pagingSelect.append( " for update" );
+		}
+		
+		return pagingSelect.toString();
+	}
+
+	public String getSelectClauseNullString(int sqlType) {
+		switch(sqlType) {
+			case Types.VARCHAR:
+			case Types.CHAR:
+				return "to_char(null)";
+			case Types.DATE:
+			case Types.TIMESTAMP:
+			case Types.TIME:
+				return "to_date(null)";
+			default:
+				return "to_number(null)";
+		}
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select sysdate from dual";
+	}
+
+	public String getCurrentTimestampSQLFunctionName() {
+		return "sysdate";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-//$Id: PointbaseDialect.java 9328 2006-02-23 17:32:47Z steveebersole $
-//Created on 04 February 2002, 17:35
-package org.hibernate.dialect;
-
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.LockMode;
-
-import java.sql.Types;
-
-/**
- * A <tt>Dialect</tt> for Pointbase.
- * @author  Ed Mackenzie
- */
-public class PointbaseDialect extends org.hibernate.dialect.Dialect {
-
-	/**
-	 * Creates new PointbaseDialect
-	 */
-	public PointbaseDialect() {
-		super();
-		registerColumnType( Types.BIT, "smallint" ); //no pointbase BIT
-		registerColumnType( Types.BIGINT, "bigint" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "smallint" ); //no pointbase TINYINT
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		//the BLOB type requires a size arguement - this defaults to
-		//bytes - no arg defaults to 1 whole byte!
-		//other argument mods include K - kilobyte, M - megabyte, G - gigabyte.
-		//refer to the PBdevelopers guide for more info.
-		registerColumnType( Types.VARBINARY, "blob($l)" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public String getCascadeConstraintsString() {
-		return " cascade";
-	}
-
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PointbaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.LockMode;
+
+import java.sql.Types;
+
+/**
+ * A <tt>Dialect</tt> for Pointbase.
+ * @author  Ed Mackenzie
+ */
+public class PointbaseDialect extends org.hibernate.dialect.Dialect {
+
+	/**
+	 * Creates new PointbaseDialect
+	 */
+	public PointbaseDialect() {
+		super();
+		registerColumnType( Types.BIT, "smallint" ); //no pointbase BIT
+		registerColumnType( Types.BIGINT, "bigint" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "smallint" ); //no pointbase TINYINT
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		//the BLOB type requires a size arguement - this defaults to
+		//bytes - no arg defaults to 1 whole byte!
+		//other argument mods include K - kilobyte, M - megabyte, G - gigabyte.
+		//refer to the PBdevelopers guide for more info.
+		registerColumnType( Types.VARBINARY, "blob($l)" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public String getCascadeConstraintsString() {
+		return " cascade";
+	}
+
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// Pointbase has no known variation of a "SELECT ... FOR UPDATE" syntax...
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,337 +0,0 @@
-//$Id: PostgreSQLDialect.java 11367 2007-03-29 13:26:40Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.PositionSubstringFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
-import org.hibernate.exception.ViolatedConstraintNameExtracter;
-import org.hibernate.id.SequenceGenerator;
-
-/**
- * An SQL dialect for Postgres
- * @author Gavin King
- */
-public class PostgreSQLDialect extends Dialect {
-
-	public PostgreSQLDialect() {
-		super();
-		registerColumnType( Types.BIT, "bool" );
-		registerColumnType( Types.BIGINT, "int8" );
-		registerColumnType( Types.SMALLINT, "int2" );
-		registerColumnType( Types.TINYINT, "int2" );
-		registerColumnType( Types.INTEGER, "int4" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float4" );
-		registerColumnType( Types.DOUBLE, "float8" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "bytea" );
-		registerColumnType( Types.CLOB, "text" );
-		registerColumnType( Types.BLOB, "oid" );
-		registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
-
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
-		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction( "log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
-		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction( "cbrt", new StandardSQLFunction("cbrt", Hibernate.DOUBLE) );
-		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
-		registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-
-		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
-		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
-
-		registerFunction( "random", new NoArgSQLFunction("random", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "trunc", new StandardSQLFunction("trunc") );
-		registerFunction( "ceil", new StandardSQLFunction("ceil") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-
-		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
-		registerFunction( "initcap", new StandardSQLFunction("initcap") );
-		registerFunction( "to_ascii", new StandardSQLFunction("to_ascii") );
-		registerFunction( "quote_ident", new StandardSQLFunction("quote_ident", Hibernate.STRING) );
-		registerFunction( "quote_literal", new StandardSQLFunction("quote_literal", Hibernate.STRING) );
-		registerFunction( "md5", new StandardSQLFunction("md5") );
-		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
-		registerFunction( "char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
-		registerFunction( "bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) );
-		registerFunction( "octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
-
-		registerFunction( "age", new StandardSQLFunction("age") );
-		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
-		registerFunction( "current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) );
-		registerFunction( "localtime", new NoArgSQLFunction("localtime", Hibernate.TIME, false) );
-		registerFunction( "localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction( "now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) );
-		registerFunction( "timeofday", new NoArgSQLFunction("timeofday", Hibernate.STRING) );
-
-		registerFunction( "current_user", new NoArgSQLFunction("current_user", Hibernate.STRING, false) );
-		registerFunction( "session_user", new NoArgSQLFunction("session_user", Hibernate.STRING, false) );
-		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
-		registerFunction( "current_database", new NoArgSQLFunction("current_database", Hibernate.STRING, true) );
-		registerFunction( "current_schema", new NoArgSQLFunction("current_schema", Hibernate.STRING, true) );
-		
-		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
-		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.DATE) );
-		registerFunction( "to_timestamp", new StandardSQLFunction("to_timestamp", Hibernate.TIMESTAMP) );
-		registerFunction( "to_number", new StandardSQLFunction("to_number", Hibernate.BIG_DECIMAL) );
-
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
-
-		registerFunction( "locate", new PositionSubstringFunction() );
-
-		registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as varchar)") );
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName );
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return "nextval ('" + sequenceName + "')";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName; //starts with 1, implicitly
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getCascadeConstraintsString() {
-		return "";//" cascade";
-	}
-	public boolean dropConstraints() {
-		return true;
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public String getQuerySequencesString() {
-		return "select relname from pg_class where relkind='S'";
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public String getLimitString(String sql, boolean hasOffset) {
-		return new StringBuffer( sql.length()+20 )
-			.append(sql)
-			.append(hasOffset ? " limit ? offset ?" : " limit ?")
-			.toString();
-	}
-
-	public boolean bindLimitParametersInReverseOrder() {
-		return true;
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-
-	public String getForUpdateString(String aliases) {
-		return getForUpdateString() + " of " + aliases;
-	}
-
-	public String getIdentitySelectString(String table, String column, int type) {
-		return new StringBuffer().append("select currval('")
-			.append(table)
-			.append('_')
-			.append(column)
-			.append("_seq')")
-			.toString();
-	}
-
-	public String getIdentityColumnString(int type) {
-		return type==Types.BIGINT ?
-			"bigserial not null" :
-			"serial not null";
-	}
-
-	public boolean hasDataTypeInIdentityColumn() {
-		return false;
-	}
-
-	public String getNoColumnsInsertString() {
-		return "default values";
-	}
-
-	public Class getNativeIdentifierGeneratorClass() {
-		return SequenceGenerator.class;
-	}
-
-	public boolean supportsOuterJoinForUpdate() {
-		return false;
-	}
-	
-	public boolean useInputStreamToInsertBlob() {
-		return false;
-	}
-
-	public boolean supportsUnionAll() {
-		return true;
-	}
-
-	/**
-	 * Workaround for postgres bug #1453
-	 */
-	public String getSelectClauseNullString(int sqlType) {
-		String typeName = getTypeName(sqlType, 1, 1, 0);
-		//trim off the length/precision/scale
-		int loc = typeName.indexOf('(');
-		if (loc>-1) {
-			typeName = typeName.substring(0, loc);
-		}
-		return "null::" + typeName;
-	}
-
-	public boolean supportsCommentOn() {
-		return true;
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "on commit drop";
-	}
-
-	/*public boolean dropTemporaryTableAfterUse() {
-		//we have to, because postgres sets current tx
-		//to rollback only after a failed create table
-		return true;
-	}*/
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select now()";
-	}
-
-	public String toBooleanValueString(boolean bool) {
-		return bool ? "true" : "false";
-	}
-
-	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
-		return EXTRACTER;
-	}
-
-	/**
-	 * Constraint-name extractor for Postgres contraint violation exceptions.
-	 * Orginally contributed by Denny Bartelt.
-	 */
-	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
-		public String extractConstraintName(SQLException sqle) {
-			try {
-				int sqlState = Integer.valueOf( JDBCExceptionHelper.extractSqlState(sqle)).intValue();
-				switch (sqlState) {
-					// CHECK VIOLATION
-					case 23514: return extractUsingTemplate("violates check constraint \"","\"", sqle.getMessage());
-					// UNIQUE VIOLATION
-					case 23505: return extractUsingTemplate("violates unique constraint \"","\"", sqle.getMessage());
-					// FOREIGN KEY VIOLATION
-					case 23503: return extractUsingTemplate("violates foreign key constraint \"","\"", sqle.getMessage());
-					// NOT NULL VIOLATION
-					case 23502: return extractUsingTemplate("null value in column \"","\" violates not-null constraint", sqle.getMessage());
-					// TODO: RESTRICT VIOLATION
-					case 23001: return null;
-					// ALL OTHER
-					default: return null;
-				}
-			} catch (NumberFormatException nfe) {
-				return null;
-			}
-		}
-	};
-	
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		// Register the type of the out param - PostgreSQL uses Types.OTHER
-		statement.registerOutParameter(col, Types.OTHER);
-		col++;
-		return col;
-	}
-
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		ps.execute();
-		ResultSet rs = (ResultSet) ps.getObject(1);
-		return rs;
-	}
-
-	public boolean supportsPooledSequences() {
-		return true;
-	}
-
-	//only necessary for postgre < 7.4
-	//http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ref/create_sequence.sgml
-	protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
-		return getCreateSequenceString( sequenceName ) + " start " + initialValue + " increment " + incrementSize;
-	}
-	
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-// seems to not really...
-//	public boolean supportsRowValueConstructorSyntax() {
-//		return true;
-//	}
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsExpectedLobUsagePattern() {
-		// seems to have spotty LOB suppport
-		return false;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,360 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.PositionSubstringFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.TemplatedViolatedConstraintNameExtracter;
+import org.hibernate.exception.ViolatedConstraintNameExtracter;
+import org.hibernate.id.SequenceGenerator;
+
+/**
+ * An SQL dialect for Postgres
+ * @author Gavin King
+ */
+public class PostgreSQLDialect extends Dialect {
+
+	public PostgreSQLDialect() {
+		super();
+		registerColumnType( Types.BIT, "bool" );
+		registerColumnType( Types.BIGINT, "int8" );
+		registerColumnType( Types.SMALLINT, "int2" );
+		registerColumnType( Types.TINYINT, "int2" );
+		registerColumnType( Types.INTEGER, "int4" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float4" );
+		registerColumnType( Types.DOUBLE, "float8" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "bytea" );
+		registerColumnType( Types.CLOB, "text" );
+		registerColumnType( Types.BLOB, "oid" );
+		registerColumnType( Types.NUMERIC, "numeric($p, $s)" );
+
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction( "log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
+		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction( "cbrt", new StandardSQLFunction("cbrt", Hibernate.DOUBLE) );
+		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+		registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+
+		registerFunction( "stddev", new StandardSQLFunction("stddev", Hibernate.DOUBLE) );
+		registerFunction( "variance", new StandardSQLFunction("variance", Hibernate.DOUBLE) );
+
+		registerFunction( "random", new NoArgSQLFunction("random", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "trunc", new StandardSQLFunction("trunc") );
+		registerFunction( "ceil", new StandardSQLFunction("ceil") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+
+		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
+		registerFunction( "initcap", new StandardSQLFunction("initcap") );
+		registerFunction( "to_ascii", new StandardSQLFunction("to_ascii") );
+		registerFunction( "quote_ident", new StandardSQLFunction("quote_ident", Hibernate.STRING) );
+		registerFunction( "quote_literal", new StandardSQLFunction("quote_literal", Hibernate.STRING) );
+		registerFunction( "md5", new StandardSQLFunction("md5") );
+		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction( "length", new StandardSQLFunction("length", Hibernate.LONG) );
+		registerFunction( "char_length", new StandardSQLFunction("char_length", Hibernate.LONG) );
+		registerFunction( "bit_length", new StandardSQLFunction("bit_length", Hibernate.LONG) );
+		registerFunction( "octet_length", new StandardSQLFunction("octet_length", Hibernate.LONG) );
+
+		registerFunction( "age", new StandardSQLFunction("age") );
+		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
+		registerFunction( "current_time", new NoArgSQLFunction("current_time", Hibernate.TIME, false) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction( "date_trunc", new StandardSQLFunction( "date_trunc", Hibernate.TIMESTAMP ) );
+		registerFunction( "localtime", new NoArgSQLFunction("localtime", Hibernate.TIME, false) );
+		registerFunction( "localtimestamp", new NoArgSQLFunction("localtimestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction( "now", new NoArgSQLFunction("now", Hibernate.TIMESTAMP) );
+		registerFunction( "timeofday", new NoArgSQLFunction("timeofday", Hibernate.STRING) );
+
+		registerFunction( "current_user", new NoArgSQLFunction("current_user", Hibernate.STRING, false) );
+		registerFunction( "session_user", new NoArgSQLFunction("session_user", Hibernate.STRING, false) );
+		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
+		registerFunction( "current_database", new NoArgSQLFunction("current_database", Hibernate.STRING, true) );
+		registerFunction( "current_schema", new NoArgSQLFunction("current_schema", Hibernate.STRING, true) );
+		
+		registerFunction( "to_char", new StandardSQLFunction("to_char", Hibernate.STRING) );
+		registerFunction( "to_date", new StandardSQLFunction("to_date", Hibernate.DATE) );
+		registerFunction( "to_timestamp", new StandardSQLFunction("to_timestamp", Hibernate.TIMESTAMP) );
+		registerFunction( "to_number", new StandardSQLFunction("to_number", Hibernate.BIG_DECIMAL) );
+
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","||",")" ) );
+
+		registerFunction( "locate", new PositionSubstringFunction() );
+
+		registerFunction( "str", new SQLFunctionTemplate(Hibernate.STRING, "cast(?1 as varchar)") );
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName );
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return "nextval ('" + sequenceName + "')";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName; //starts with 1, implicitly
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getCascadeConstraintsString() {
+		return "";//" cascade";
+	}
+	public boolean dropConstraints() {
+		return true;
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public String getQuerySequencesString() {
+		return "select relname from pg_class where relkind='S'";
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public String getLimitString(String sql, boolean hasOffset) {
+		return new StringBuffer( sql.length()+20 )
+			.append(sql)
+			.append(hasOffset ? " limit ? offset ?" : " limit ?")
+			.toString();
+	}
+
+	public boolean bindLimitParametersInReverseOrder() {
+		return true;
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+
+	public String getForUpdateString(String aliases) {
+		return getForUpdateString() + " of " + aliases;
+	}
+
+	public String getIdentitySelectString(String table, String column, int type) {
+		return new StringBuffer().append("select currval('")
+			.append(table)
+			.append('_')
+			.append(column)
+			.append("_seq')")
+			.toString();
+	}
+
+	public String getIdentityColumnString(int type) {
+		return type==Types.BIGINT ?
+			"bigserial not null" :
+			"serial not null";
+	}
+
+	public boolean hasDataTypeInIdentityColumn() {
+		return false;
+	}
+
+	public String getNoColumnsInsertString() {
+		return "default values";
+	}
+
+	public Class getNativeIdentifierGeneratorClass() {
+		return SequenceGenerator.class;
+	}
+
+	public boolean supportsOuterJoinForUpdate() {
+		return false;
+	}
+	
+	public boolean useInputStreamToInsertBlob() {
+		return false;
+	}
+
+	public boolean supportsUnionAll() {
+		return true;
+	}
+
+	/**
+	 * Workaround for postgres bug #1453
+	 */
+	public String getSelectClauseNullString(int sqlType) {
+		String typeName = getTypeName(sqlType, 1, 1, 0);
+		//trim off the length/precision/scale
+		int loc = typeName.indexOf('(');
+		if (loc>-1) {
+			typeName = typeName.substring(0, loc);
+		}
+		return "null::" + typeName;
+	}
+
+	public boolean supportsCommentOn() {
+		return true;
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "on commit drop";
+	}
+
+	/*public boolean dropTemporaryTableAfterUse() {
+		//we have to, because postgres sets current tx
+		//to rollback only after a failed create table
+		return true;
+	}*/
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select now()";
+	}
+
+	public String toBooleanValueString(boolean bool) {
+		return bool ? "true" : "false";
+	}
+
+	public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
+		return EXTRACTER;
+	}
+
+	/**
+	 * Constraint-name extractor for Postgres contraint violation exceptions.
+	 * Orginally contributed by Denny Bartelt.
+	 */
+	private static ViolatedConstraintNameExtracter EXTRACTER = new TemplatedViolatedConstraintNameExtracter() {
+		public String extractConstraintName(SQLException sqle) {
+			try {
+				int sqlState = Integer.valueOf( JDBCExceptionHelper.extractSqlState(sqle)).intValue();
+				switch (sqlState) {
+					// CHECK VIOLATION
+					case 23514: return extractUsingTemplate("violates check constraint \"","\"", sqle.getMessage());
+					// UNIQUE VIOLATION
+					case 23505: return extractUsingTemplate("violates unique constraint \"","\"", sqle.getMessage());
+					// FOREIGN KEY VIOLATION
+					case 23503: return extractUsingTemplate("violates foreign key constraint \"","\"", sqle.getMessage());
+					// NOT NULL VIOLATION
+					case 23502: return extractUsingTemplate("null value in column \"","\" violates not-null constraint", sqle.getMessage());
+					// TODO: RESTRICT VIOLATION
+					case 23001: return null;
+					// ALL OTHER
+					default: return null;
+				}
+			} catch (NumberFormatException nfe) {
+				return null;
+			}
+		}
+	};
+	
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		// Register the type of the out param - PostgreSQL uses Types.OTHER
+		statement.registerOutParameter(col, Types.OTHER);
+		col++;
+		return col;
+	}
+
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		ps.execute();
+		ResultSet rs = (ResultSet) ps.getObject(1);
+		return rs;
+	}
+
+	public boolean supportsPooledSequences() {
+		return true;
+	}
+
+	//only necessary for postgre < 7.4
+	//http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/doc/src/sgml/ref/create_sequence.sgml
+	protected String getCreateSequenceString(String sequenceName, int initialValue, int incrementSize) {
+		return getCreateSequenceString( sequenceName ) + " start " + initialValue + " increment " + incrementSize;
+	}
+	
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+// seems to not really...
+//	public boolean supportsRowValueConstructorSyntax() {
+//		return true;
+//	}
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsExpectedLobUsagePattern() {
+		// seems to have spotty LOB suppport
+		return false;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/ProgressDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-//$Id: ProgressDialect.java 4609 2004-09-27 03:17:46Z oneovthafew $
-// contributed by Phillip Baird
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-/**
- * An SQL dialect compatible with Progress 9.1C<br>
- *<br>
- * Connection Parameters required:
- *<ul>
- * <li>hibernate.dialect org.hibernate.sql.ProgressDialect
- * <li>hibernate.driver com.progress.sql.jdbc.JdbcProgressDriver
- * <li>hibernate.url jdbc:JdbcProgress:T:host:port:dbname;WorkArounds=536870912
- * <li>hibernate.username username
- * <li>hibernate.password password
- *</ul>
- * The WorkArounds parameter in the URL is required to avoid an error
- * in the Progress 9.1C JDBC driver related to PreparedStatements.
- * @author Phillip Baird
- *
- */
-public class ProgressDialect extends Dialect {
-	public ProgressDialect() {
-		super();
-		registerColumnType( Types.BIT, "bit" );
-		registerColumnType( Types.BIGINT, "numeric" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "integer" );
-		registerColumnType( Types.CHAR, "character(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "real" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "varbinary($l)" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-	}
-
-	public boolean hasAlterTable(){
-		return false;
-	}
-
-	public String getAddColumnString() {
-		return "add column";
-	}
-
-	public boolean qualifyIndexName() {
-		return false;
-	}
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/ProgressDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ProgressDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+import java.sql.Types;
+
+/**
+ * An SQL dialect compatible with Progress 9.1C<br>
+ *<br>
+ * Connection Parameters required:
+ *<ul>
+ * <li>hibernate.dialect org.hibernate.sql.ProgressDialect
+ * <li>hibernate.driver com.progress.sql.jdbc.JdbcProgressDriver
+ * <li>hibernate.url jdbc:JdbcProgress:T:host:port:dbname;WorkArounds=536870912
+ * <li>hibernate.username username
+ * <li>hibernate.password password
+ *</ul>
+ * The WorkArounds parameter in the URL is required to avoid an error
+ * in the Progress 9.1C JDBC driver related to PreparedStatements.
+ * @author Phillip Baird
+ *
+ */
+public class ProgressDialect extends Dialect {
+	public ProgressDialect() {
+		super();
+		registerColumnType( Types.BIT, "bit" );
+		registerColumnType( Types.BIGINT, "numeric" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "integer" );
+		registerColumnType( Types.CHAR, "character(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "real" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "varbinary($l)" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+	}
+
+	public boolean hasAlterTable(){
+		return false;
+	}
+
+	public String getAddColumnString() {
+		return "add column";
+	}
+
+	public boolean qualifyIndexName() {
+		return false;
+	}
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,322 +0,0 @@
-/*
- * Created on Aug 24, 2005
- * This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS).
- * This dialect was developed for use with Hibernate 3.0.5. Other versions may
- * require modifications to the dialect.
- *
- * Version History:
- * Also change the version displayed below in the constructor
- * 1.1
- * 1.0  2005-10-24  CDH - First dated version for use with CP 11
- */
-package org.hibernate.dialect;
-
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-
-import java.sql.Types;
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.DecodeCaseFragment;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author Ploski and Hanson
- */
-public class RDMSOS2200Dialect extends Dialect {
-	private static Logger log = LoggerFactory.getLogger(RDMSOS2200Dialect.class);
-
-	public RDMSOS2200Dialect() {
-		super();
-        // Display the dialect version.
-		log.info("RDMSOS2200Dialect version: 1.0");
-
-        /**
-         * This section registers RDMS Biult-in Functions (BIFs) with Hibernate.
-         * The first parameter is the 'register' function name with Hibernate.
-         * The second parameter is the defined RDMS SQL Function and it's
-         * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF
-         * name and the return type (if any) is specified.  If
-         * SQLFunctionTemplate(...) is used, the return type and a template
-         * string is provided, plus an optional hasParenthesesIfNoArgs flag.
-         */
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.INTEGER) );
-		registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.INTEGER) );
-		registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER) );
-
-		// The RDMS concat() function only supports 2 parameters
-		registerFunction( "concat", new SQLFunctionTemplate(Hibernate.STRING, "concat(?1, ?2)") );
-		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.STRING) );
-		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
-		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
-		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
-		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
-
-		registerFunction("lcase", new StandardSQLFunction("lcase") );
-		registerFunction("lower", new StandardSQLFunction("lower") );
-		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction("reverse", new StandardSQLFunction("reverse") );
-		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
-
-		// RDMS does not directly support the trim() function, we use rtrim() and ltrim()
-		registerFunction("trim", new SQLFunctionTemplate(Hibernate.INTEGER, "ltrim(rtrim(?1))" ) );
-		registerFunction("soundex", new StandardSQLFunction("soundex") );
-		registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) );
-		registerFunction("ucase", new StandardSQLFunction("ucase") );
-		registerFunction("upper", new StandardSQLFunction("upper") );
-
-		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction("cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
-		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
-		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
-		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
-		registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
-		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
-		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction("sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
-		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction("tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "trunc", new StandardSQLFunction("trunc") );
-		registerFunction( "ceil", new StandardSQLFunction("ceil") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-
-		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
-		registerFunction( "initcap", new StandardSQLFunction("initcap") );
-
-		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
-
-		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
-		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
-		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
-		registerFunction("curdate", new NoArgSQLFunction("curdate",Hibernate.DATE) );
-		registerFunction("curtime", new NoArgSQLFunction("curtime",Hibernate.TIME) );
-		registerFunction("days", new StandardSQLFunction("days",Hibernate.INTEGER) );
-		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",Hibernate.INTEGER) );
-		registerFunction("dayname", new StandardSQLFunction("dayname",Hibernate.STRING) );
-		registerFunction("dayofweek", new StandardSQLFunction("dayofweek",Hibernate.INTEGER) );
-		registerFunction("dayofyear", new StandardSQLFunction("dayofyear",Hibernate.INTEGER) );
-		registerFunction("hour", new StandardSQLFunction("hour",Hibernate.INTEGER) );
-		registerFunction("last_day", new StandardSQLFunction("last_day",Hibernate.DATE) );
-		registerFunction("microsecond", new StandardSQLFunction("microsecond",Hibernate.INTEGER) );
-		registerFunction("minute", new StandardSQLFunction("minute",Hibernate.INTEGER) );
-		registerFunction("month", new StandardSQLFunction("month",Hibernate.INTEGER) );
-		registerFunction("monthname", new StandardSQLFunction("monthname",Hibernate.STRING) );
-		registerFunction("now", new NoArgSQLFunction("now",Hibernate.TIMESTAMP) );
-		registerFunction("quarter", new StandardSQLFunction("quarter",Hibernate.INTEGER) );
-		registerFunction("second", new StandardSQLFunction("second",Hibernate.INTEGER) );
-		registerFunction("time", new StandardSQLFunction("time",Hibernate.TIME) );
-		registerFunction("timestamp", new StandardSQLFunction("timestamp",Hibernate.TIMESTAMP) );
-		registerFunction("week", new StandardSQLFunction("week",Hibernate.INTEGER) );
-		registerFunction("year", new StandardSQLFunction("year",Hibernate.INTEGER) );
-
-		registerFunction("atan2", new StandardSQLFunction("atan2",Hibernate.DOUBLE) );
-		registerFunction( "mod", new StandardSQLFunction("mod",Hibernate.INTEGER) );
-		registerFunction( "nvl", new StandardSQLFunction("nvl") );
-		registerFunction( "power", new StandardSQLFunction("power", Hibernate.DOUBLE) );
-
-		/**
-		 * For a list of column types to register, see section A-1
-		 * in 7862 7395, the Unisys JDBC manual.
-		 *
-		 * Here are column sizes as documented in Table A-1 of
-		 * 7831 0760, "Enterprise Relational Database Server
-		 * for ClearPath OS2200 Administration Guide"
-		 * Numeric - 21
-		 * Decimal - 22 (21 digits plus one for sign)
-		 * Float   - 60 bits
-		 * Char    - 28000
-		 * NChar   - 14000
-		 * BLOB+   - 4294967296 (4 Gb)
-		 * + RDMS JDBC driver does not support BLOBs
-		 *
-		 * DATE, TIME and TIMESTAMP literal formats are
-		 * are all described in section 2.3.4 DATE Literal Format
-		 * in 7830 8160.
-		 * The DATE literal format is: YYYY-MM-DD
-		 * The TIME literal format is: HH:MM:SS[.[FFFFFF]]
-		 * The TIMESTAMP literal format is: YYYY-MM-DD HH:MM:SS[.[FFFFFF]]
-		 *
-		 * Note that $l (dollar-L) will use the length value if provided.
-		 * Also new for Hibernate3 is the $p percision and $s (scale) parameters
-		 */
-		registerColumnType(Types.BIT, "SMALLINT");
-		registerColumnType(Types.TINYINT, "SMALLINT");
-		registerColumnType(Types.BIGINT, "NUMERIC(21,0)");
-		registerColumnType(Types.SMALLINT, "SMALLINT");
-		registerColumnType(Types.CHAR, "CHARACTER(1)");
-		registerColumnType(Types.DOUBLE, "DOUBLE PRECISION");
-		registerColumnType(Types.FLOAT, "FLOAT");
-		registerColumnType(Types.REAL, "REAL");
-		registerColumnType(Types.INTEGER, "INTEGER");
-		registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)");
-		registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)");
-		registerColumnType(Types.DATE, "DATE");
-		registerColumnType(Types.TIME, "TIME");
-		registerColumnType(Types.TIMESTAMP, "TIMESTAMP");
-		registerColumnType(Types.VARCHAR, "CHARACTER($l)");
-        registerColumnType(Types.BLOB, "BLOB($l)" );
-        /*
-         * The following types are not supported in RDMS/JDBC and therefore commented out.
-         * However, in some cases, mapping them to CHARACTER columns works
-         * for many applications, but does not work for all cases.
-         */
-        // registerColumnType(Types.VARBINARY, "CHARACTER($l)");
-        // registerColumnType(Types.BLOB, "CHARACTER($l)" );  // For use prior to CP 11.0
-        // registerColumnType(Types.CLOB, "CHARACTER($l)" );
-	}
-
-
-	// Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-    /**
-     * RDMS does not support qualifing index names with the schema name.
-     */
-	public boolean qualifyIndexName() {
-		return false;
-	}
-
-	/**
-	 * The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC
-     * driver does not support this feature, so a false is return.
-     * The base dialect also returns a false, but we will leave this over-ride
-     * in to make sure it stays false.
-	 */
-	public boolean forUpdateOfColumns() {
-		return false;
-	}
-
-	/**
-	 * Since the RDMS-JDBC driver does not support for updates, this string is
-     * set to an empty string. Whenever, the driver does support this feature,
-     * the returned string should be " FOR UPDATE OF". Note that RDMS does not
-     * support the string 'FOR UPDATE' string.
-	 */
-	public String getForUpdateString() {
-		return ""; // Original Dialect.java returns " for update";
-	}
-
-    /**
-     * RDMS does not support adding Unique constraints via create and alter table.
-     */
-	public boolean supportsUniqueConstraintInCreateAlterTable() {
-	    return true;
-	}
-
-	// Verify the state of this new method in Hibernate 3.0 Dialect.java
-    /**
-     * RDMS does not support Cascade Deletes.
-     * Need to review this in the future when support is provided.
-     */
-	public boolean supportsCascadeDelete() {
-		return false; // Origial Dialect.java returns true;
-	}
-
-	/**
-     * Currently, RDMS-JDBC does not support ForUpdate.
-     * Need to review this in the future when support is provided.
-	 */
-    public boolean supportsOuterJoinForUpdate() {
-		return false;
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public String getNullColumnString() {
-		// The keyword used to specify a nullable column.
-		return " null";
-	}
-
-    // *** Sequence methods - start. The RDMS dialect needs these
-
-    // methods to make it possible to use the Native Id generator
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-	    // The where clause was added to eliminate this statement from Brute Force Searches.
-        return  "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 ";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-        // We must return a valid RDMS/RSA command from this method to
-        // prevent RDMS/RSA from issuing *ERROR 400
-        return "";
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-        // We must return a valid RDMS/RSA command from this method to
-        // prevent RDMS/RSA from issuing *ERROR 400
-        return "";
-	}
-
-	// *** Sequence methods - end
-
-    public String getCascadeConstraintsString() {
-        // Used with DROP TABLE to delete all records in the table.
-        return " including contents";
-    }
-
-	public CaseFragment createCaseFragment() {
-		return new DecodeCaseFragment();
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-    public String getLimitString(String sql, int offset, int limit) {
-        if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
-		return new StringBuffer(sql.length() + 40)
-			.append(sql)
-			.append(" fetch first ")
-			.append(limit)
-			.append(" rows only ")
-			.toString();
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-	public boolean supportsUnionAll() {
-		// RDMS supports the UNION ALL clause.
-          return true;
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax...
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/RDMSOS2200Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,344 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+
+import java.sql.Types;
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.DecodeCaseFragment;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This is the Hibernate dialect for the Unisys 2200 Relational Database (RDMS).
+ * This dialect was developed for use with Hibernate 3.0.5. Other versions may
+ * require modifications to the dialect.
+ *
+ * Version History:
+ * Also change the version displayed below in the constructor
+ * 1.1
+ * 1.0  2005-10-24  CDH - First dated version for use with CP 11
+ *
+ * @author Ploski and Hanson
+ */
+public class RDMSOS2200Dialect extends Dialect {
+	private static Logger log = LoggerFactory.getLogger(RDMSOS2200Dialect.class);
+
+	public RDMSOS2200Dialect() {
+		super();
+        // Display the dialect version.
+		log.info("RDMSOS2200Dialect version: 1.0");
+
+        /**
+         * This section registers RDMS Biult-in Functions (BIFs) with Hibernate.
+         * The first parameter is the 'register' function name with Hibernate.
+         * The second parameter is the defined RDMS SQL Function and it's
+         * characteristics. If StandardSQLFunction(...) is used, the RDMS BIF
+         * name and the return type (if any) is specified.  If
+         * SQLFunctionTemplate(...) is used, the return type and a template
+         * string is provided, plus an optional hasParenthesesIfNoArgs flag.
+         */
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction("ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction("char_length", new StandardSQLFunction("char_length", Hibernate.INTEGER) );
+		registerFunction("character_length", new StandardSQLFunction("character_length", Hibernate.INTEGER) );
+		registerFunction("length", new StandardSQLFunction("length", Hibernate.INTEGER) );
+
+		// The RDMS concat() function only supports 2 parameters
+		registerFunction( "concat", new SQLFunctionTemplate(Hibernate.STRING, "concat(?1, ?2)") );
+		registerFunction( "instr", new StandardSQLFunction("instr", Hibernate.STRING) );
+		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
+		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
+		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
+		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
+
+		registerFunction("lcase", new StandardSQLFunction("lcase") );
+		registerFunction("lower", new StandardSQLFunction("lower") );
+		registerFunction("ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction("reverse", new StandardSQLFunction("reverse") );
+		registerFunction("rtrim", new StandardSQLFunction("rtrim") );
+
+		// RDMS does not directly support the trim() function, we use rtrim() and ltrim()
+		registerFunction("trim", new SQLFunctionTemplate(Hibernate.INTEGER, "ltrim(rtrim(?1))" ) );
+		registerFunction("soundex", new StandardSQLFunction("soundex") );
+		registerFunction("space", new StandardSQLFunction("space", Hibernate.STRING) );
+		registerFunction("ucase", new StandardSQLFunction("ucase") );
+		registerFunction("upper", new StandardSQLFunction("upper") );
+
+		registerFunction("acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction("asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction("atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction("cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction("cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
+		registerFunction("cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+		registerFunction("exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction("ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction("log", new StandardSQLFunction("log", Hibernate.DOUBLE) );
+		registerFunction("log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
+		registerFunction("pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
+		registerFunction("rand", new NoArgSQLFunction("rand", Hibernate.DOUBLE) );
+		registerFunction("sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction("sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
+		registerFunction("sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction("tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction("tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "trunc", new StandardSQLFunction("trunc") );
+		registerFunction( "ceil", new StandardSQLFunction("ceil") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+
+		registerFunction( "chr", new StandardSQLFunction("chr", Hibernate.CHARACTER) );
+		registerFunction( "initcap", new StandardSQLFunction("initcap") );
+
+		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING, false) );
+
+		registerFunction( "current_date", new NoArgSQLFunction("current_date", Hibernate.DATE, false) );
+		registerFunction( "current_time", new NoArgSQLFunction("current_timestamp", Hibernate.TIME, false) );
+		registerFunction( "current_timestamp", new NoArgSQLFunction("current_timestamp", Hibernate.TIMESTAMP, false) );
+		registerFunction("curdate", new NoArgSQLFunction("curdate",Hibernate.DATE) );
+		registerFunction("curtime", new NoArgSQLFunction("curtime",Hibernate.TIME) );
+		registerFunction("days", new StandardSQLFunction("days",Hibernate.INTEGER) );
+		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth",Hibernate.INTEGER) );
+		registerFunction("dayname", new StandardSQLFunction("dayname",Hibernate.STRING) );
+		registerFunction("dayofweek", new StandardSQLFunction("dayofweek",Hibernate.INTEGER) );
+		registerFunction("dayofyear", new StandardSQLFunction("dayofyear",Hibernate.INTEGER) );
+		registerFunction("hour", new StandardSQLFunction("hour",Hibernate.INTEGER) );
+		registerFunction("last_day", new StandardSQLFunction("last_day",Hibernate.DATE) );
+		registerFunction("microsecond", new StandardSQLFunction("microsecond",Hibernate.INTEGER) );
+		registerFunction("minute", new StandardSQLFunction("minute",Hibernate.INTEGER) );
+		registerFunction("month", new StandardSQLFunction("month",Hibernate.INTEGER) );
+		registerFunction("monthname", new StandardSQLFunction("monthname",Hibernate.STRING) );
+		registerFunction("now", new NoArgSQLFunction("now",Hibernate.TIMESTAMP) );
+		registerFunction("quarter", new StandardSQLFunction("quarter",Hibernate.INTEGER) );
+		registerFunction("second", new StandardSQLFunction("second",Hibernate.INTEGER) );
+		registerFunction("time", new StandardSQLFunction("time",Hibernate.TIME) );
+		registerFunction("timestamp", new StandardSQLFunction("timestamp",Hibernate.TIMESTAMP) );
+		registerFunction("week", new StandardSQLFunction("week",Hibernate.INTEGER) );
+		registerFunction("year", new StandardSQLFunction("year",Hibernate.INTEGER) );
+
+		registerFunction("atan2", new StandardSQLFunction("atan2",Hibernate.DOUBLE) );
+		registerFunction( "mod", new StandardSQLFunction("mod",Hibernate.INTEGER) );
+		registerFunction( "nvl", new StandardSQLFunction("nvl") );
+		registerFunction( "power", new StandardSQLFunction("power", Hibernate.DOUBLE) );
+
+		/**
+		 * For a list of column types to register, see section A-1
+		 * in 7862 7395, the Unisys JDBC manual.
+		 *
+		 * Here are column sizes as documented in Table A-1 of
+		 * 7831 0760, "Enterprise Relational Database Server
+		 * for ClearPath OS2200 Administration Guide"
+		 * Numeric - 21
+		 * Decimal - 22 (21 digits plus one for sign)
+		 * Float   - 60 bits
+		 * Char    - 28000
+		 * NChar   - 14000
+		 * BLOB+   - 4294967296 (4 Gb)
+		 * + RDMS JDBC driver does not support BLOBs
+		 *
+		 * DATE, TIME and TIMESTAMP literal formats are
+		 * are all described in section 2.3.4 DATE Literal Format
+		 * in 7830 8160.
+		 * The DATE literal format is: YYYY-MM-DD
+		 * The TIME literal format is: HH:MM:SS[.[FFFFFF]]
+		 * The TIMESTAMP literal format is: YYYY-MM-DD HH:MM:SS[.[FFFFFF]]
+		 *
+		 * Note that $l (dollar-L) will use the length value if provided.
+		 * Also new for Hibernate3 is the $p percision and $s (scale) parameters
+		 */
+		registerColumnType(Types.BIT, "SMALLINT");
+		registerColumnType(Types.TINYINT, "SMALLINT");
+		registerColumnType(Types.BIGINT, "NUMERIC(21,0)");
+		registerColumnType(Types.SMALLINT, "SMALLINT");
+		registerColumnType(Types.CHAR, "CHARACTER(1)");
+		registerColumnType(Types.DOUBLE, "DOUBLE PRECISION");
+		registerColumnType(Types.FLOAT, "FLOAT");
+		registerColumnType(Types.REAL, "REAL");
+		registerColumnType(Types.INTEGER, "INTEGER");
+		registerColumnType(Types.NUMERIC, "NUMERIC(21,$l)");
+		registerColumnType(Types.DECIMAL, "NUMERIC(21,$l)");
+		registerColumnType(Types.DATE, "DATE");
+		registerColumnType(Types.TIME, "TIME");
+		registerColumnType(Types.TIMESTAMP, "TIMESTAMP");
+		registerColumnType(Types.VARCHAR, "CHARACTER($l)");
+        registerColumnType(Types.BLOB, "BLOB($l)" );
+        /*
+         * The following types are not supported in RDMS/JDBC and therefore commented out.
+         * However, in some cases, mapping them to CHARACTER columns works
+         * for many applications, but does not work for all cases.
+         */
+        // registerColumnType(Types.VARBINARY, "CHARACTER($l)");
+        // registerColumnType(Types.BLOB, "CHARACTER($l)" );  // For use prior to CP 11.0
+        // registerColumnType(Types.CLOB, "CHARACTER($l)" );
+	}
+
+
+	// Dialect method overrides ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    /**
+     * RDMS does not support qualifing index names with the schema name.
+     */
+	public boolean qualifyIndexName() {
+		return false;
+	}
+
+	/**
+	 * The RDMS DB supports the 'FOR UPDATE OF' clause. However, the RDMS-JDBC
+     * driver does not support this feature, so a false is return.
+     * The base dialect also returns a false, but we will leave this over-ride
+     * in to make sure it stays false.
+	 */
+	public boolean forUpdateOfColumns() {
+		return false;
+	}
+
+	/**
+	 * Since the RDMS-JDBC driver does not support for updates, this string is
+     * set to an empty string. Whenever, the driver does support this feature,
+     * the returned string should be " FOR UPDATE OF". Note that RDMS does not
+     * support the string 'FOR UPDATE' string.
+	 */
+	public String getForUpdateString() {
+		return ""; // Original Dialect.java returns " for update";
+	}
+
+    /**
+     * RDMS does not support adding Unique constraints via create and alter table.
+     */
+	public boolean supportsUniqueConstraintInCreateAlterTable() {
+	    return true;
+	}
+
+	// Verify the state of this new method in Hibernate 3.0 Dialect.java
+    /**
+     * RDMS does not support Cascade Deletes.
+     * Need to review this in the future when support is provided.
+     */
+	public boolean supportsCascadeDelete() {
+		return false; // Origial Dialect.java returns true;
+	}
+
+	/**
+     * Currently, RDMS-JDBC does not support ForUpdate.
+     * Need to review this in the future when support is provided.
+	 */
+    public boolean supportsOuterJoinForUpdate() {
+		return false;
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public String getNullColumnString() {
+		// The keyword used to specify a nullable column.
+		return " null";
+	}
+
+    // *** Sequence methods - start. The RDMS dialect needs these
+
+    // methods to make it possible to use the Native Id generator
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+	    // The where clause was added to eliminate this statement from Brute Force Searches.
+        return  "select permuted_id('NEXT',31) from rdms.rdms_dummy where key_col = 1 ";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+        // We must return a valid RDMS/RSA command from this method to
+        // prevent RDMS/RSA from issuing *ERROR 400
+        return "";
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+        // We must return a valid RDMS/RSA command from this method to
+        // prevent RDMS/RSA from issuing *ERROR 400
+        return "";
+	}
+
+	// *** Sequence methods - end
+
+    public String getCascadeConstraintsString() {
+        // Used with DROP TABLE to delete all records in the table.
+        return " including contents";
+    }
+
+	public CaseFragment createCaseFragment() {
+		return new DecodeCaseFragment();
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+    public String getLimitString(String sql, int offset, int limit) {
+        if (offset>0) throw new UnsupportedOperationException("RDMS does not support paged queries");
+		return new StringBuffer(sql.length() + 40)
+			.append(sql)
+			.append(" fetch first ")
+			.append(limit)
+			.append(" rows only ")
+			.toString();
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+	public boolean supportsUnionAll() {
+		// RDMS supports the UNION ALL clause.
+          return true;
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// RDMS has no known variation of a "SELECT ... FOR UPDATE" syntax...
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,67 +0,0 @@
-package org.hibernate.dialect;
-
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Defines how we need to reference columns in the group-by, having, and order-by
- * clauses.
- *
- * @author Steve Ebersole
- */
-public class ResultColumnReferenceStrategy implements Serializable {
-
-	private static final Map INSTANCES = new HashMap();
-
-	/**
-	 * This strategy says to reference the result columns by the qualified column name
-	 * found in the result source.  This strategy is not strictly allowed by ANSI SQL
-	 * but is Hibernate's legacy behavior and is also the fastest of the strategies; thus
-	 * it should be used if supported by the underlying database.
-	 */
-	public static final ResultColumnReferenceStrategy SOURCE = new ResultColumnReferenceStrategy( "source");
-
-	/**
-	 * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
-	 * approaches.  One is to reference the result column by the alias it is given in the
-	 * result source (if it is given an alias).  This strategy says to use this approach.
-	 * <p/>
-	 * The other QNSI SQL compliant approach is {@link #ORDINAL}.
-	 */
-	public static final ResultColumnReferenceStrategy ALIAS = new ResultColumnReferenceStrategy( "alias" );
-
-	/**
-	 * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
-	 * approaches.  One is to reference the result column by the ordinal position at which
-	 * it appears in the result source.  This strategy says to use this approach.
-	 * <p/>
-	 * The other QNSI SQL compliant approach is {@link #ALIAS}.
-	 */
-	public static final ResultColumnReferenceStrategy ORDINAL = new ResultColumnReferenceStrategy( "ordinal" );
-
-	static {
-		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.SOURCE.name, ResultColumnReferenceStrategy.SOURCE );
-		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ALIAS.name, ResultColumnReferenceStrategy.ALIAS );
-		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ORDINAL.name, ResultColumnReferenceStrategy.ORDINAL );
-	}
-
-	private final String name;
-
-	public ResultColumnReferenceStrategy(String name) {
-		this.name = name;
-	}
-
-	public String toString() {
-		return name;
-	}
-
-	private Object readResolve() throws ObjectStreamException {
-		return parse( name );
-	}
-
-	public static ResultColumnReferenceStrategy parse(String name) {
-		return ( ResultColumnReferenceStrategy ) ResultColumnReferenceStrategy.INSTANCES.get( name );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/ResultColumnReferenceStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.dialect;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Defines how we need to reference columns in the group-by, having, and order-by
+ * clauses.
+ *
+ * @author Steve Ebersole
+ */
+public class ResultColumnReferenceStrategy implements Serializable {
+
+	private static final Map INSTANCES = new HashMap();
+
+	/**
+	 * This strategy says to reference the result columns by the qualified column name
+	 * found in the result source.  This strategy is not strictly allowed by ANSI SQL
+	 * but is Hibernate's legacy behavior and is also the fastest of the strategies; thus
+	 * it should be used if supported by the underlying database.
+	 */
+	public static final ResultColumnReferenceStrategy SOURCE = new ResultColumnReferenceStrategy( "source");
+
+	/**
+	 * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
+	 * approaches.  One is to reference the result column by the alias it is given in the
+	 * result source (if it is given an alias).  This strategy says to use this approach.
+	 * <p/>
+	 * The other QNSI SQL compliant approach is {@link #ORDINAL}.
+	 */
+	public static final ResultColumnReferenceStrategy ALIAS = new ResultColumnReferenceStrategy( "alias" );
+
+	/**
+	 * For databases which do not support {@link #SOURCE}, ANSI SQL defines two allowable
+	 * approaches.  One is to reference the result column by the ordinal position at which
+	 * it appears in the result source.  This strategy says to use this approach.
+	 * <p/>
+	 * The other QNSI SQL compliant approach is {@link #ALIAS}.
+	 */
+	public static final ResultColumnReferenceStrategy ORDINAL = new ResultColumnReferenceStrategy( "ordinal" );
+
+	static {
+		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.SOURCE.name, ResultColumnReferenceStrategy.SOURCE );
+		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ALIAS.name, ResultColumnReferenceStrategy.ALIAS );
+		ResultColumnReferenceStrategy.INSTANCES.put( ResultColumnReferenceStrategy.ORDINAL.name, ResultColumnReferenceStrategy.ORDINAL );
+	}
+
+	private final String name;
+
+	public ResultColumnReferenceStrategy(String name) {
+		this.name = name;
+	}
+
+	public String toString() {
+		return name;
+	}
+
+	private Object readResolve() throws ObjectStreamException {
+		return parse( name );
+	}
+
+	public static ResultColumnReferenceStrategy parse(String name) {
+		return ( ResultColumnReferenceStrategy ) ResultColumnReferenceStrategy.INSTANCES.get( name );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,205 +0,0 @@
-//$Id: SAPDBDialect.java 8749 2005-12-04 17:32:04Z oneovthafew $
-// contributed by Brad Clow
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.DecodeCaseFragment;
-import org.hibernate.sql.OracleJoinFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.util.StringHelper;
-
-/**
- * An SQL dialect compatible with SAP DB.
- * @author Brad Clow
- */
-public class SAPDBDialect extends Dialect {
-
-	public SAPDBDialect() {
-		super();
-		registerColumnType( Types.BIT, "boolean" );
-		registerColumnType( Types.BIGINT, "fixed(19,0)" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "fixed(3,0)" );
-		registerColumnType( Types.INTEGER, "int" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "date" );
-		registerColumnType( Types.TIME, "time" );
-		registerColumnType( Types.TIMESTAMP, "timestamp" );
-		registerColumnType( Types.VARBINARY, "long byte" );
-		registerColumnType( Types.NUMERIC, "fixed($p,$s)" );
-		registerColumnType( Types.CLOB, "long varchar" );
-		registerColumnType( Types.BLOB, "long byte" );
-		
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction( "log", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
-		registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
-		registerFunction( "power", new StandardSQLFunction("power") );
-		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
-		registerFunction( "cot", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
-		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
-		registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
-		registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "trunc", new StandardSQLFunction("trunc") );
-		registerFunction( "ceil", new StandardSQLFunction("ceil") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-		registerFunction( "greatest", new StandardSQLFunction("greatest") );
-		registerFunction( "least", new StandardSQLFunction("least") );
-
-		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
-		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
-		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
-		registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) );
-
-		registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "second(?1)") );
-		registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "minute(?1)") );
-		registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "hour(?1)") );
-		registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "day(?1)") );
-		registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "month(?1)") );
-		registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "year(?1)") );
-
-		registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "?1(?3)") );
-
-		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
-		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
-		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) );
-		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
-		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
-		registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) );
-
-		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
-		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
-		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
-		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
-		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
-		registerFunction( "initcap", new StandardSQLFunction("initcap", Hibernate.STRING) );
-		registerFunction( "lower", new StandardSQLFunction("lower", Hibernate.STRING) );
-		registerFunction( "ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING) );
-		registerFunction( "rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING) );
-		registerFunction( "lfill", new StandardSQLFunction("ltrim", Hibernate.STRING) );
-		registerFunction( "rfill", new StandardSQLFunction("rtrim", Hibernate.STRING) );
-		registerFunction( "soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
-		registerFunction( "upper", new StandardSQLFunction("upper", Hibernate.STRING) );
-		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.STRING) );
-		registerFunction( "index", new StandardSQLFunction("index", Hibernate.INTEGER) );
-
-		registerFunction( "value", new StandardSQLFunction( "value" ) );
-		
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
-		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
-		registerFunction( "locate", new StandardSQLFunction("index", Hibernate.INTEGER) );
-		registerFunction( "coalesce", new StandardSQLFunction( "value" ) );
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-
-	}
-
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-
-	public String getAddForeignKeyConstraintString(
-			String constraintName, 
-			String[] foreignKey, 
-			String referencedTable, 
-			String[] primaryKey, boolean referencesPrimaryKey
-	) {
-		StringBuffer res = new StringBuffer(30)
-			.append(" foreign key ")
-			.append(constraintName)
-			.append(" (")
-			.append( StringHelper.join(", ", foreignKey) )
-			.append(") references ")
-			.append(referencedTable);
-		
-		if(!referencesPrimaryKey) {
-			res.append(" (")
-			   .append( StringHelper.join(", ", primaryKey) )
-			   .append(')');
-		}
-			
-		return res.toString();
-	}
-
-	public String getAddPrimaryKeyConstraintString(String constraintName) {
-		return " primary key ";
-	}
-
-	public String getNullColumnString() {
-		return " null";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getQuerySequencesString() {
-		return "select sequence_name from domain.sequences";
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		return new OracleJoinFragment();
-	}
-
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public CaseFragment createCaseFragment() {
-		return new DecodeCaseFragment();
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "ignore rollback";
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		return "temp." + super.generateTemporaryTableName(baseTableName);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SAPDBDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,227 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.DecodeCaseFragment;
+import org.hibernate.sql.OracleJoinFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.util.StringHelper;
+
+/**
+ * An SQL dialect compatible with SAP DB.
+ * @author Brad Clow
+ */
+public class SAPDBDialect extends Dialect {
+
+	public SAPDBDialect() {
+		super();
+		registerColumnType( Types.BIT, "boolean" );
+		registerColumnType( Types.BIGINT, "fixed(19,0)" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "fixed(3,0)" );
+		registerColumnType( Types.INTEGER, "int" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "date" );
+		registerColumnType( Types.TIME, "time" );
+		registerColumnType( Types.TIMESTAMP, "timestamp" );
+		registerColumnType( Types.VARBINARY, "long byte" );
+		registerColumnType( Types.NUMERIC, "fixed($p,$s)" );
+		registerColumnType( Types.CLOB, "long varchar" );
+		registerColumnType( Types.BLOB, "long byte" );
+		
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction( "ln", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction( "log", new StandardSQLFunction("ln", Hibernate.DOUBLE) );
+		registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
+		registerFunction( "power", new StandardSQLFunction("power") );
+		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "cosh", new StandardSQLFunction("cosh", Hibernate.DOUBLE) );
+		registerFunction( "cot", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction( "sinh", new StandardSQLFunction("sinh", Hibernate.DOUBLE) );
+		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction( "tanh", new StandardSQLFunction("tanh", Hibernate.DOUBLE) );
+		registerFunction( "radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+		registerFunction( "degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+		registerFunction( "atan2", new StandardSQLFunction("atan2", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "trunc", new StandardSQLFunction("trunc") );
+		registerFunction( "ceil", new StandardSQLFunction("ceil") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+		registerFunction( "greatest", new StandardSQLFunction("greatest") );
+		registerFunction( "least", new StandardSQLFunction("least") );
+
+		registerFunction("time", new StandardSQLFunction("time", Hibernate.TIME) );
+		registerFunction("timestamp", new StandardSQLFunction("timestamp", Hibernate.TIMESTAMP) );
+		registerFunction("date", new StandardSQLFunction("date", Hibernate.DATE) );
+		registerFunction("microsecond", new StandardSQLFunction("microsecond", Hibernate.INTEGER) );
+
+		registerFunction( "second", new SQLFunctionTemplate(Hibernate.INTEGER, "second(?1)") );
+		registerFunction( "minute", new SQLFunctionTemplate(Hibernate.INTEGER, "minute(?1)") );
+		registerFunction( "hour", new SQLFunctionTemplate(Hibernate.INTEGER, "hour(?1)") );
+		registerFunction( "day", new SQLFunctionTemplate(Hibernate.INTEGER, "day(?1)") );
+		registerFunction( "month", new SQLFunctionTemplate(Hibernate.INTEGER, "month(?1)") );
+		registerFunction( "year", new SQLFunctionTemplate(Hibernate.INTEGER, "year(?1)") );
+
+		registerFunction( "extract", new SQLFunctionTemplate(Hibernate.INTEGER, "?1(?3)") );
+
+		registerFunction("dayname", new StandardSQLFunction("dayname", Hibernate.STRING) );
+		registerFunction("monthname", new StandardSQLFunction("monthname", Hibernate.STRING) );
+		registerFunction("dayofmonth", new StandardSQLFunction("dayofmonth", Hibernate.INTEGER) );
+		registerFunction("dayofweek", new StandardSQLFunction("dayofweek", Hibernate.INTEGER) );
+		registerFunction("dayofyear", new StandardSQLFunction("dayofyear", Hibernate.INTEGER) );
+		registerFunction("weekofyear", new StandardSQLFunction("weekofyear", Hibernate.INTEGER) );
+
+		registerFunction( "replace", new StandardSQLFunction("replace", Hibernate.STRING) );
+		registerFunction( "translate", new StandardSQLFunction("translate", Hibernate.STRING) );
+		registerFunction( "lpad", new StandardSQLFunction("lpad", Hibernate.STRING) );
+		registerFunction( "rpad", new StandardSQLFunction("rpad", Hibernate.STRING) );
+		registerFunction( "substr", new StandardSQLFunction("substr", Hibernate.STRING) );
+		registerFunction( "initcap", new StandardSQLFunction("initcap", Hibernate.STRING) );
+		registerFunction( "lower", new StandardSQLFunction("lower", Hibernate.STRING) );
+		registerFunction( "ltrim", new StandardSQLFunction("ltrim", Hibernate.STRING) );
+		registerFunction( "rtrim", new StandardSQLFunction("rtrim", Hibernate.STRING) );
+		registerFunction( "lfill", new StandardSQLFunction("ltrim", Hibernate.STRING) );
+		registerFunction( "rfill", new StandardSQLFunction("rtrim", Hibernate.STRING) );
+		registerFunction( "soundex", new StandardSQLFunction("soundex", Hibernate.STRING) );
+		registerFunction( "upper", new StandardSQLFunction("upper", Hibernate.STRING) );
+		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.STRING) );
+		registerFunction( "index", new StandardSQLFunction("index", Hibernate.INTEGER) );
+
+		registerFunction( "value", new StandardSQLFunction( "value" ) );
+		
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
+		registerFunction( "substring", new StandardSQLFunction( "substr", Hibernate.STRING ) );
+		registerFunction( "locate", new StandardSQLFunction("index", Hibernate.INTEGER) );
+		registerFunction( "coalesce", new StandardSQLFunction( "value" ) );
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+
+	}
+
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+
+	public String getAddForeignKeyConstraintString(
+			String constraintName, 
+			String[] foreignKey, 
+			String referencedTable, 
+			String[] primaryKey, boolean referencesPrimaryKey
+	) {
+		StringBuffer res = new StringBuffer(30)
+			.append(" foreign key ")
+			.append(constraintName)
+			.append(" (")
+			.append( StringHelper.join(", ", foreignKey) )
+			.append(") references ")
+			.append(referencedTable);
+		
+		if(!referencesPrimaryKey) {
+			res.append(" (")
+			   .append( StringHelper.join(", ", primaryKey) )
+			   .append(')');
+		}
+			
+		return res.toString();
+	}
+
+	public String getAddPrimaryKeyConstraintString(String constraintName) {
+		return " primary key ";
+	}
+
+	public String getNullColumnString() {
+		return " null";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getQuerySequencesString() {
+		return "select sequence_name from domain.sequences";
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		return new OracleJoinFragment();
+	}
+
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public CaseFragment createCaseFragment() {
+		return new DecodeCaseFragment();
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "ignore rollback";
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		return "temp." + super.generateTemporaryTableName(baseTableName);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,140 +0,0 @@
-//$Id: SQLServerDialect.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.Types;
-import java.util.Map;
-import java.util.Iterator;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.util.StringHelper;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
-
-/**
- * A dialect for Microsoft SQL Server 2000 and 2005
- *
- * @author Gavin King
- */
-public class SQLServerDialect extends SybaseDialect {
-
-	public SQLServerDialect() {
-		registerColumnType( Types.VARBINARY, "image" );
-		registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
-
-		registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) );
-		registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) );
-		registerFunction( "hour", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(hour, ?1)" ) );
-		registerFunction( "locate", new StandardSQLFunction( "charindex", Hibernate.INTEGER ) );
-
-		registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
-		registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
-		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
-
-		registerFunction( "trim", new AnsiTrimEmulationFunction() );
-
-		registerKeyword( "top" );
-	}
-
-	public String getNoColumnsInsertString() {
-		return "default values";
-	}
-
-	static int getAfterSelectInsertPoint(String sql) {
-		int selectIndex = sql.toLowerCase().indexOf( "select" );
-		final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
-		return selectIndex + ( selectDistinctIndex == selectIndex ? 15 : 6 );
-	}
-
-	public String getLimitString(String querySelect, int offset, int limit) {
-		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "sql server has no offset" );
-		}
-		return new StringBuffer( querySelect.length() + 8 )
-				.append( querySelect )
-				.insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )
-				.toString();
-	}
-
-	/**
-	 * Use <tt>insert table(...) values(...) select SCOPE_IDENTITY()</tt>
-	 */
-	public String appendIdentitySelectToInsert(String insertSQL) {
-		return insertSQL + " select scope_identity()";
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-	public char closeQuote() {
-		return ']';
-	}
-
-	public char openQuote() {
-		return '[';
-	}
-
-	public String appendLockHint(LockMode mode, String tableName) {
-		if ( mode.greaterThan( LockMode.READ ) ) {
-			// does this need holdlock also? : return tableName + " with (updlock, rowlock, holdlock)";
-			return tableName + " with (updlock, rowlock)";
-		}
-		else {
-			return tableName;
-		}
-	}
-
-	public String getSelectGUIDString() {
-		return "select newid()";
-	}
-
-	// The current_timestamp is more accurate, but only known to be supported
-	// in SQL Server 7.0 and later (i.e., Sybase not known to support it at all)
-	public String getCurrentTimestampSelectString() {
-		return "select current_timestamp";
-	}
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean areStringComparisonsCaseInsensitive() {
-		return true;
-	}
-
-	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
-		return false;
-	}
-
-	public boolean supportsCircularCascadeDeleteConstraints() {
-		// SQL Server (at least up through 2005) does not support defining
-		// cascade delete constraints which can circel back to the mutating
-		// table
-		return false;
-	}
-
-	public boolean supportsLobValueChangePropogation() {
-		// note: at least my local SQL Server 2005 Express shows this not working...
-		return false;
-	}
-
-	public boolean doesReadCommittedCauseWritersToBlockReaders() {
-		return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
-	}
-
-	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
-		return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SQLServerDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,160 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.AnsiTrimEmulationFunction;
+
+/**
+ * A dialect for Microsoft SQL Server 2000 and 2005
+ *
+ * @author Gavin King
+ */
+public class SQLServerDialect extends SybaseDialect {
+
+	public SQLServerDialect() {
+		registerColumnType( Types.VARBINARY, "image" );
+		registerColumnType( Types.VARBINARY, 8000, "varbinary($l)" );
+
+		registerFunction( "second", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(second, ?1)" ) );
+		registerFunction( "minute", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(minute, ?1)" ) );
+		registerFunction( "hour", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(hour, ?1)" ) );
+		registerFunction( "locate", new StandardSQLFunction( "charindex", Hibernate.INTEGER ) );
+
+		registerFunction( "extract", new SQLFunctionTemplate( Hibernate.INTEGER, "datepart(?1, ?3)" ) );
+		registerFunction( "mod", new SQLFunctionTemplate( Hibernate.INTEGER, "?1 % ?2" ) );
+		registerFunction( "bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "datalength(?1) * 8" ) );
+
+		registerFunction( "trim", new AnsiTrimEmulationFunction() );
+
+		registerKeyword( "top" );
+	}
+
+	public String getNoColumnsInsertString() {
+		return "default values";
+	}
+
+	static int getAfterSelectInsertPoint(String sql) {
+		int selectIndex = sql.toLowerCase().indexOf( "select" );
+		final int selectDistinctIndex = sql.toLowerCase().indexOf( "select distinct" );
+		return selectIndex + ( selectDistinctIndex == selectIndex ? 15 : 6 );
+	}
+
+	public String getLimitString(String querySelect, int offset, int limit) {
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "sql server has no offset" );
+		}
+		return new StringBuffer( querySelect.length() + 8 )
+				.append( querySelect )
+				.insert( getAfterSelectInsertPoint( querySelect ), " top " + limit )
+				.toString();
+	}
+
+	/**
+	 * Use <tt>insert table(...) values(...) select SCOPE_IDENTITY()</tt>
+	 */
+	public String appendIdentitySelectToInsert(String insertSQL) {
+		return insertSQL + " select scope_identity()";
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+	public char closeQuote() {
+		return ']';
+	}
+
+	public char openQuote() {
+		return '[';
+	}
+
+	public String appendLockHint(LockMode mode, String tableName) {
+		if ( mode.greaterThan( LockMode.READ ) ) {
+			// does this need holdlock also? : return tableName + " with (updlock, rowlock, holdlock)";
+			return tableName + " with (updlock, rowlock)";
+		}
+		else {
+			return tableName;
+		}
+	}
+
+	public String getSelectGUIDString() {
+		return "select newid()";
+	}
+
+	// The current_timestamp is more accurate, but only known to be supported
+	// in SQL Server 7.0 and later (i.e., Sybase not known to support it at all)
+	public String getCurrentTimestampSelectString() {
+		return "select current_timestamp";
+	}
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean areStringComparisonsCaseInsensitive() {
+		return true;
+	}
+
+	public boolean supportsResultSetPositionQueryMethodsOnForwardOnlyCursor() {
+		return false;
+	}
+
+	public boolean supportsCircularCascadeDeleteConstraints() {
+		// SQL Server (at least up through 2005) does not support defining
+		// cascade delete constraints which can circel back to the mutating
+		// table
+		return false;
+	}
+
+	public boolean supportsLobValueChangePropogation() {
+		// note: at least my local SQL Server 2005 Express shows this not working...
+		return false;
+	}
+
+	public boolean doesReadCommittedCauseWritersToBlockReaders() {
+		return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
+	}
+
+	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
+		return false; // here assume SQLServer2005 using snapshot isolation, which does not have this problem
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-//$Id: Sybase11Dialect.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.dialect;
-
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.Sybase11JoinFragment;
-
-/**
- * A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax)
- * @author Colm O' Flaherty
- */
-public class Sybase11Dialect extends SybaseDialect  {
-	public Sybase11Dialect() {
-		super();
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		return new Sybase11JoinFragment();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/Sybase11Dialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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.dialect;
+
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.Sybase11JoinFragment;
+
+/**
+ * A SQL dialect suitable for use with Sybase 11.9.2 (specifically: avoids ANSI JOIN syntax)
+ * @author Colm O' Flaherty
+ */
+public class Sybase11Dialect extends SybaseDialect  {
+	public Sybase11Dialect() {
+		super();
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		return new Sybase11JoinFragment();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.dialect;
-
-/**
- * SQL Dialect for Sybase Anywhere
- * extending Sybase (Enterprise) Dialect
- * (Tested on ASA 8.x)
- * @author ?
- */
-public class SybaseAnywhereDialect extends SybaseDialect {
-
-	/**
-	 * Sybase Anywhere syntax would require a "DEFAULT" for each column specified,
-	 * but I suppose Hibernate use this syntax only with tables with just 1 column
-	 */
-	public String getNoColumnsInsertString() {
-		return "values (default)";
-	}
-
-
-	/**
-	 * ASA does not require to drop constraint before dropping tables, and DROP statement
-	 * syntax used by Hibernate to drop constraint is not compatible with ASA, so disable it
-	 */
-	public boolean dropConstraints() {
-		return false;
-	}
-
-	public boolean supportsInsertSelectIdentity() {
-		return false;
-	}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseAnywhereDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect;
+
+/**
+ * SQL Dialect for Sybase Anywhere
+ * extending Sybase (Enterprise) Dialect
+ * (Tested on ASA 8.x)
+ * @author ?
+ */
+public class SybaseAnywhereDialect extends SybaseDialect {
+
+	/**
+	 * Sybase Anywhere syntax would require a "DEFAULT" for each column specified,
+	 * but I suppose Hibernate use this syntax only with tables with just 1 column
+	 */
+	public String getNoColumnsInsertString() {
+		return "values (default)";
+	}
+
+
+	/**
+	 * ASA does not require to drop constraint before dropping tables, and DROP statement
+	 * syntax used by Hibernate to drop constraint is not compatible with ASA, so disable it
+	 */
+	public boolean dropConstraints() {
+		return false;
+	}
+
+	public boolean supportsInsertSelectIdentity() {
+		return false;
+	}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/SybaseDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,238 +0,0 @@
-//$Id: SybaseDialect.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.dialect;
-
-import java.sql.CallableStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Map;
-import java.util.Iterator;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.CharIndexFunction;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-
-/**
- * An SQL dialect compatible with Sybase and MS SQL Server.
- * @author Gavin King
- */
-
-public class SybaseDialect extends Dialect {
-	public SybaseDialect() {
-		super();
-		registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
-		registerColumnType( Types.BIGINT, "numeric(19,0)" );
-		registerColumnType( Types.SMALLINT, "smallint" );
-		registerColumnType( Types.TINYINT, "tinyint" );
-		registerColumnType( Types.INTEGER, "int" );
-		registerColumnType( Types.CHAR, "char(1)" );
-		registerColumnType( Types.VARCHAR, "varchar($l)" );
-		registerColumnType( Types.FLOAT, "float" );
-		registerColumnType( Types.DOUBLE, "double precision" );
-		registerColumnType( Types.DATE, "datetime" );
-		registerColumnType( Types.TIME, "datetime" );
-		registerColumnType( Types.TIMESTAMP, "datetime" );
-		registerColumnType( Types.VARBINARY, "varbinary($l)" );
-		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
-		registerColumnType( Types.BLOB, "image" );
-		registerColumnType( Types.CLOB, "text" );
-
-		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
-		registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
-		registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
-		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
-		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction( "reverse", new StandardSQLFunction("reverse") );
-		registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
-
-		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
-
-		registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
-		registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
-		registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
-		
-		registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
-		registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
-		registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
-		registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
-		registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
-		registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
-
-		registerFunction( "abs", new StandardSQLFunction("abs") );
-		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
-
-		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
-		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
-		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
-		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
-		registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
-		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
-		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
-		registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
-		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
-		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
-		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
-		registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
-		registerFunction( "square", new StandardSQLFunction("square") );
-		registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
-
-		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
-		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
-
-		registerFunction( "round", new StandardSQLFunction("round") );
-		registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
-		registerFunction( "floor", new StandardSQLFunction("floor") );
-
-		registerFunction( "isnull", new StandardSQLFunction("isnull") );
-
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
-		
-		registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
-		registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
-		registerFunction( "locate", new CharIndexFunction() );
-
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
-	}
-
-	public String getAddColumnString() {
-		return "add";
-	}
-	public String getNullColumnString() {
-		return " null";
-	}
-	public boolean qualifyIndexName() {
-		return false;
-	}
-
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public boolean supportsIdentityColumns() {
-		return true;
-	}
-	public String getIdentitySelectString() {
-		return "select @@identity";
-	}
-	public String getIdentityColumnString() {
-		return "identity not null"; //starts with 1, implicitly
-	}
-
-	public boolean supportsInsertSelectIdentity() {
-		return true;
-	}
-
-	public String appendIdentitySelectToInsert(String insertSQL) {
-		return insertSQL + "\nselect @@identity";
-	}
-
-	public String appendLockHint(LockMode mode, String tableName) {
-		if ( mode.greaterThan( LockMode.READ ) ) {
-			return tableName + " holdlock";
-		}
-		else {
-			return tableName;
-		}
-	}
-
-	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
-		Iterator itr = aliasedLockModes.entrySet().iterator();
-		StringBuffer buffer = new StringBuffer( sql );
-		int correction = 0;
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final LockMode lockMode = ( LockMode ) entry.getValue();
-			if ( lockMode.greaterThan( LockMode.READ ) ) {
-				final String alias = ( String ) entry.getKey();
-				int start = -1, end = -1;
-				if ( sql.endsWith( " " + alias ) ) {
-					start = ( sql.length() - alias.length() ) + correction;
-					end = start + alias.length();
-				}
-				else {
-					int position = sql.indexOf( " " + alias + " " );
-					if ( position <= -1 ) {
-						position = sql.indexOf( " " + alias + "," );
-					}
-					if ( position > -1 ) {
-						start = position + correction + 1;
-						end = start + alias.length();
-					}
-				}
-
-				if ( start > -1 ) {
-					final String lockHint = appendLockHint( lockMode, alias );
-					buffer.replace( start, end, lockHint );
-					correction += ( lockHint.length() - alias.length() );
-				}
-			}
-		}
-		return buffer.toString();
-	}
-	
-	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
-		return col; // sql server just returns automatically
-	}
-
-	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
-		boolean isResultSet = ps.execute();
-//		 This assumes you will want to ignore any update counts 
-		while ( !isResultSet && ps.getUpdateCount() != -1 ) {
-			isResultSet = ps.getMoreResults();
-		}
-//		 You may still have other ResultSets or update counts left to process here
-//		 but you can't do it now or the ResultSet you just got will be closed
-		return ps.getResultSet();
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select getdate()";
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		return "#" + baseTableName;
-	}
-
-	public boolean dropTemporaryTableAfterUse() {
-		return true;  // sql-server, at least needed this dropped after use; strange!
-	}
-
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public boolean supportsExistsInSelect() {
-		return false;
-	}
-
-	public boolean doesReadCommittedCauseWritersToBlockReaders() {
-		return true;
-	}
-
-	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
-		return true;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/SybaseDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/SybaseDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,261 @@
+/*
+ * 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.dialect;
+
+import java.sql.CallableStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+import java.util.Iterator;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.CharIndexFunction;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * An SQL dialect compatible with Sybase and MS SQL Server.
+ * @author Gavin King
+ */
+
+public class SybaseDialect extends Dialect {
+	public SybaseDialect() {
+		super();
+		registerColumnType( Types.BIT, "tinyint" ); //Sybase BIT type does not support null values
+		registerColumnType( Types.BIGINT, "numeric(19,0)" );
+		registerColumnType( Types.SMALLINT, "smallint" );
+		registerColumnType( Types.TINYINT, "tinyint" );
+		registerColumnType( Types.INTEGER, "int" );
+		registerColumnType( Types.CHAR, "char(1)" );
+		registerColumnType( Types.VARCHAR, "varchar($l)" );
+		registerColumnType( Types.FLOAT, "float" );
+		registerColumnType( Types.DOUBLE, "double precision" );
+		registerColumnType( Types.DATE, "datetime" );
+		registerColumnType( Types.TIME, "datetime" );
+		registerColumnType( Types.TIMESTAMP, "datetime" );
+		registerColumnType( Types.VARBINARY, "varbinary($l)" );
+		registerColumnType( Types.NUMERIC, "numeric($p,$s)" );
+		registerColumnType( Types.BLOB, "image" );
+		registerColumnType( Types.CLOB, "text" );
+
+		registerFunction( "ascii", new StandardSQLFunction("ascii", Hibernate.INTEGER) );
+		registerFunction( "char", new StandardSQLFunction("char", Hibernate.CHARACTER) );
+		registerFunction( "len", new StandardSQLFunction("len", Hibernate.LONG) );
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "str", new StandardSQLFunction("str", Hibernate.STRING) );
+		registerFunction( "ltrim", new StandardSQLFunction("ltrim") );
+		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction( "reverse", new StandardSQLFunction("reverse") );
+		registerFunction( "space", new StandardSQLFunction("space", Hibernate.STRING) );
+
+		registerFunction( "user", new NoArgSQLFunction("user", Hibernate.STRING) );
+
+		registerFunction( "current_timestamp", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
+		registerFunction( "current_time", new NoArgSQLFunction("getdate", Hibernate.TIME) );
+		registerFunction( "current_date", new NoArgSQLFunction("getdate", Hibernate.DATE) );
+		
+		registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP) );
+		registerFunction( "getutcdate", new NoArgSQLFunction("getutcdate", Hibernate.TIMESTAMP) );
+		registerFunction( "day", new StandardSQLFunction("day", Hibernate.INTEGER) );
+		registerFunction( "month", new StandardSQLFunction("month", Hibernate.INTEGER) );
+		registerFunction( "year", new StandardSQLFunction("year", Hibernate.INTEGER) );
+		registerFunction( "datename", new StandardSQLFunction("datename", Hibernate.STRING) );
+
+		registerFunction( "abs", new StandardSQLFunction("abs") );
+		registerFunction( "sign", new StandardSQLFunction("sign", Hibernate.INTEGER) );
+
+		registerFunction( "acos", new StandardSQLFunction("acos", Hibernate.DOUBLE) );
+		registerFunction( "asin", new StandardSQLFunction("asin", Hibernate.DOUBLE) );
+		registerFunction( "atan", new StandardSQLFunction("atan", Hibernate.DOUBLE) );
+		registerFunction( "cos", new StandardSQLFunction("cos", Hibernate.DOUBLE) );
+		registerFunction( "cot", new StandardSQLFunction("cot", Hibernate.DOUBLE) );
+		registerFunction( "exp", new StandardSQLFunction("exp", Hibernate.DOUBLE) );
+		registerFunction( "log", new StandardSQLFunction( "log", Hibernate.DOUBLE) );
+		registerFunction( "log10", new StandardSQLFunction("log10", Hibernate.DOUBLE) );
+		registerFunction( "sin", new StandardSQLFunction("sin", Hibernate.DOUBLE) );
+		registerFunction( "sqrt", new StandardSQLFunction("sqrt", Hibernate.DOUBLE) );
+		registerFunction( "tan", new StandardSQLFunction("tan", Hibernate.DOUBLE) );
+		registerFunction( "pi", new NoArgSQLFunction("pi", Hibernate.DOUBLE) );
+		registerFunction( "square", new StandardSQLFunction("square") );
+		registerFunction( "rand", new StandardSQLFunction("rand", Hibernate.FLOAT) );
+
+		registerFunction("radians", new StandardSQLFunction("radians", Hibernate.DOUBLE) );
+		registerFunction("degrees", new StandardSQLFunction("degrees", Hibernate.DOUBLE) );
+
+		registerFunction( "round", new StandardSQLFunction("round") );
+		registerFunction( "ceiling", new StandardSQLFunction("ceiling") );
+		registerFunction( "floor", new StandardSQLFunction("floor") );
+
+		registerFunction( "isnull", new StandardSQLFunction("isnull") );
+
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(","+",")" ) );
+		
+		registerFunction( "length", new StandardSQLFunction( "len", Hibernate.INTEGER ) );
+		registerFunction( "trim", new SQLFunctionTemplate( Hibernate.STRING, "ltrim(rtrim(?1))") );
+		registerFunction( "locate", new CharIndexFunction() );
+
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, NO_BATCH);
+	}
+
+	public String getAddColumnString() {
+		return "add";
+	}
+	public String getNullColumnString() {
+		return " null";
+	}
+	public boolean qualifyIndexName() {
+		return false;
+	}
+
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public boolean supportsIdentityColumns() {
+		return true;
+	}
+	public String getIdentitySelectString() {
+		return "select @@identity";
+	}
+	public String getIdentityColumnString() {
+		return "identity not null"; //starts with 1, implicitly
+	}
+
+	public boolean supportsInsertSelectIdentity() {
+		return true;
+	}
+
+	public String appendIdentitySelectToInsert(String insertSQL) {
+		return insertSQL + "\nselect @@identity";
+	}
+
+	public String appendLockHint(LockMode mode, String tableName) {
+		if ( mode.greaterThan( LockMode.READ ) ) {
+			return tableName + " holdlock";
+		}
+		else {
+			return tableName;
+		}
+	}
+
+	public String applyLocksToSql(String sql, Map aliasedLockModes, Map keyColumnNames) {
+		Iterator itr = aliasedLockModes.entrySet().iterator();
+		StringBuffer buffer = new StringBuffer( sql );
+		int correction = 0;
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final LockMode lockMode = ( LockMode ) entry.getValue();
+			if ( lockMode.greaterThan( LockMode.READ ) ) {
+				final String alias = ( String ) entry.getKey();
+				int start = -1, end = -1;
+				if ( sql.endsWith( " " + alias ) ) {
+					start = ( sql.length() - alias.length() ) + correction;
+					end = start + alias.length();
+				}
+				else {
+					int position = sql.indexOf( " " + alias + " " );
+					if ( position <= -1 ) {
+						position = sql.indexOf( " " + alias + "," );
+					}
+					if ( position > -1 ) {
+						start = position + correction + 1;
+						end = start + alias.length();
+					}
+				}
+
+				if ( start > -1 ) {
+					final String lockHint = appendLockHint( lockMode, alias );
+					buffer.replace( start, end, lockHint );
+					correction += ( lockHint.length() - alias.length() );
+				}
+			}
+		}
+		return buffer.toString();
+	}
+	
+	public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
+		return col; // sql server just returns automatically
+	}
+
+	public ResultSet getResultSet(CallableStatement ps) throws SQLException {
+		boolean isResultSet = ps.execute();
+//		 This assumes you will want to ignore any update counts 
+		while ( !isResultSet && ps.getUpdateCount() != -1 ) {
+			isResultSet = ps.getMoreResults();
+		}
+//		 You may still have other ResultSets or update counts left to process here
+//		 but you can't do it now or the ResultSet you just got will be closed
+		return ps.getResultSet();
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select getdate()";
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		return "#" + baseTableName;
+	}
+
+	public boolean dropTemporaryTableAfterUse() {
+		return true;  // sql-server, at least needed this dropped after use; strange!
+	}
+
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public boolean supportsExistsInSelect() {
+		return false;
+	}
+
+	public boolean doesReadCommittedCauseWritersToBlockReaders() {
+		return true;
+	}
+
+	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
+		return true;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/TeradataDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,237 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.SQLFunctionTemplate;
-import org.hibernate.dialect.function.VarArgsSQLFunction;
-
-/**
- * A dialect for the Teradata database created by MCR as part of the
- * dialect certification process.
- *
- * @author Jay Nance
- */
-public class TeradataDialect extends Dialect {
-
-	/**
-	 * Constructor
-	 */
-	public TeradataDialect() {
-		super();
-		//registerColumnType data types
-		registerColumnType( Types.NUMERIC, "NUMERIC($p,$s)" );
-		registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" );
-		registerColumnType( Types.BIGINT, "NUMERIC(18,0)" );
-		registerColumnType( Types.BIT, "BYTEINT" );
-		registerColumnType( Types.TINYINT, "BYTEINT" );
-		registerColumnType( Types.VARBINARY, "VARBYTE($l)" );
-		registerColumnType( Types.BINARY, "BYTEINT" );
-		registerColumnType( Types.LONGVARCHAR, "LONG VARCHAR" );
-		registerColumnType( Types.CHAR, "CHAR(1)" );
-		registerColumnType( Types.DECIMAL, "DECIMAL" );
-		registerColumnType( Types.INTEGER, "INTEGER" );
-		registerColumnType( Types.SMALLINT, "SMALLINT" );
-		registerColumnType( Types.FLOAT, "FLOAT" );
-		registerColumnType( Types.VARCHAR, "VARCHAR($l)" );
-		registerColumnType( Types.DATE, "DATE" );
-		registerColumnType( Types.TIME, "TIME" );
-		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
-		registerColumnType( Types.BOOLEAN, "BYTEINT" );  // hibernate seems to ignore this type...
-		registerColumnType( Types.BLOB, "BLOB" );
-		registerColumnType( Types.CLOB, "CLOB" );
-
-		registerFunction( "year", new SQLFunctionTemplate( Hibernate.INTEGER, "extract(year from ?1)" ) );
-		registerFunction( "length", new SQLFunctionTemplate( Hibernate.INTEGER, "character_length(?1)" ) );
-		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
-		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 from ?2 for ?3)" ) );
-		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.STRING, "position(?1 in ?2)" ) );
-		registerFunction( "mod", new SQLFunctionTemplate( Hibernate.STRING, "?1 mod ?2" ) );
-		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as varchar(255))" ) );
-
-		// bit_length feels a bit broken to me. We have to cast to char in order to
-		// pass when a numeric value is supplied. But of course the answers given will
-		// be wildly different for these two datatypes. 1234.5678 will be 9 bytes as
-		// a char string but will be 8 or 16 bytes as a true numeric.
-		// Jay Nance 2006-09-22
-		registerFunction(
-				"bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(cast(?1 as char))*4" )
-		);
-
-		// The preference here would be
-		//   SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)", false)
-		// but this appears not to work.
-		// Jay Nance 2006-09-22
-		registerFunction( "current_timestamp", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp" ) );
-		registerFunction( "current_time", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_time" ) );
-		registerFunction( "current_date", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_date" ) );
-		// IBID for current_time and current_date
-
-		registerKeyword( "password" );
-		registerKeyword( "type" );
-		registerKeyword( "title" );
-		registerKeyword( "year" );
-		registerKeyword( "month" );
-		registerKeyword( "summary" );
-		registerKeyword( "alias" );
-		registerKeyword( "value" );
-		registerKeyword( "first" );
-		registerKeyword( "role" );
-		registerKeyword( "account" );
-		registerKeyword( "class" );
-
-		// Tell hibernate to use getBytes instead of getBinaryStream
-		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" );
-		// No batch statements
-		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
-	}
-
-	/**
-	 * Does this dialect support the <tt>FOR UPDATE</tt> syntax?
-	 *
-	 * @return empty string ... Teradata does not support <tt>FOR UPDATE<tt> syntax
-	 */
-	public String getForUpdateString() {
-		return "";
-	}
-
-	public boolean supportsIdentityColumns() {
-		return false;
-	}
-
-	public boolean supportsSequences() {
-		return false;
-	}
-
-	public String getAddColumnString() {
-		return "Add Column";
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return " on commit preserve rows";
-	}
-
-	public Boolean performTemporaryTableDDLInIsolation() {
-		return Boolean.TRUE;
-	}
-
-	public boolean dropTemporaryTableAfterUse() {
-		return false;
-	}
-
-	/**
-	 * Get the name of the database type associated with the given
-	 * <tt>java.sql.Types</tt> typecode.
-	 *
-	 * @param code <tt>java.sql.Types</tt> typecode
-	 * @param length the length or precision of the column
-	 * @param precision the precision of the column
-	 * @param scale the scale of the column
-	 *
-	 * @return the database type name
-	 *
-	 * @throws HibernateException
-	 */
-	public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
-		/*
-		 * We might want a special case for 19,2. This is very common for money types
-		 * and here it is converted to 18,1
-		 */
-		float f = precision > 0 ? ( float ) scale / ( float ) precision : 0;
-		int p = ( precision > 18 ? 18 : precision );
-		int s = ( precision > 18 ? ( int ) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) );
-
-		return super.getTypeName( code, length, p, s );
-	}
-
-	public boolean supportsCascadeDelete() {
-		return false;
-	}
-
-	public boolean supportsCircularCascadeDeleteConstraints() {
-		return false;
-	}
-
-	public boolean areStringComparisonsCaseInsensitive() {
-		return true;
-	}
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-
-	public String getSelectClauseNullString(int sqlType) {
-		String v = "null";
-
-		switch ( sqlType ) {
-			case Types.BIT:
-			case Types.TINYINT:
-			case Types.SMALLINT:
-			case Types.INTEGER:
-			case Types.BIGINT:
-			case Types.FLOAT:
-			case Types.REAL:
-			case Types.DOUBLE:
-			case Types.NUMERIC:
-			case Types.DECIMAL:
-				v = "cast(null as decimal)";
-				break;
-			case Types.CHAR:
-			case Types.VARCHAR:
-			case Types.LONGVARCHAR:
-				v = "cast(null as varchar(255))";
-				break;
-			case Types.DATE:
-			case Types.TIME:
-			case Types.TIMESTAMP:
-				v = "cast(null as timestamp)";
-				break;
-			case Types.BINARY:
-			case Types.VARBINARY:
-			case Types.LONGVARBINARY:
-			case Types.NULL:
-			case Types.OTHER:
-			case Types.JAVA_OBJECT:
-			case Types.DISTINCT:
-			case Types.STRUCT:
-			case Types.ARRAY:
-			case Types.BLOB:
-			case Types.CLOB:
-			case Types.REF:
-			case Types.DATALINK:
-			case Types.BOOLEAN:
-				break;
-		}
-		return v;
-	}
-
-	public String getCreateMultisetTableString() {
-		return "create multiset table ";
-	}
-
-	public boolean supportsLobValueChangePropogation() {
-		return false;
-	}
-
-	public boolean doesReadCommittedCauseWritersToBlockReaders() {
-		return true;
-	}
-
-	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
-		return true;
-	}
-
-	public boolean supportsBindAsCallableArgument() {
-		return false;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/TeradataDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TeradataDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,261 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.SQLFunctionTemplate;
+import org.hibernate.dialect.function.VarArgsSQLFunction;
+
+/**
+ * A dialect for the Teradata database created by MCR as part of the
+ * dialect certification process.
+ *
+ * @author Jay Nance
+ */
+public class TeradataDialect extends Dialect {
+
+	/**
+	 * Constructor
+	 */
+	public TeradataDialect() {
+		super();
+		//registerColumnType data types
+		registerColumnType( Types.NUMERIC, "NUMERIC($p,$s)" );
+		registerColumnType( Types.DOUBLE, "DOUBLE PRECISION" );
+		registerColumnType( Types.BIGINT, "NUMERIC(18,0)" );
+		registerColumnType( Types.BIT, "BYTEINT" );
+		registerColumnType( Types.TINYINT, "BYTEINT" );
+		registerColumnType( Types.VARBINARY, "VARBYTE($l)" );
+		registerColumnType( Types.BINARY, "BYTEINT" );
+		registerColumnType( Types.LONGVARCHAR, "LONG VARCHAR" );
+		registerColumnType( Types.CHAR, "CHAR(1)" );
+		registerColumnType( Types.DECIMAL, "DECIMAL" );
+		registerColumnType( Types.INTEGER, "INTEGER" );
+		registerColumnType( Types.SMALLINT, "SMALLINT" );
+		registerColumnType( Types.FLOAT, "FLOAT" );
+		registerColumnType( Types.VARCHAR, "VARCHAR($l)" );
+		registerColumnType( Types.DATE, "DATE" );
+		registerColumnType( Types.TIME, "TIME" );
+		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
+		registerColumnType( Types.BOOLEAN, "BYTEINT" );  // hibernate seems to ignore this type...
+		registerColumnType( Types.BLOB, "BLOB" );
+		registerColumnType( Types.CLOB, "CLOB" );
+
+		registerFunction( "year", new SQLFunctionTemplate( Hibernate.INTEGER, "extract(year from ?1)" ) );
+		registerFunction( "length", new SQLFunctionTemplate( Hibernate.INTEGER, "character_length(?1)" ) );
+		registerFunction( "concat", new VarArgsSQLFunction( Hibernate.STRING, "(", "||", ")" ) );
+		registerFunction( "substring", new SQLFunctionTemplate( Hibernate.STRING, "substring(?1 from ?2 for ?3)" ) );
+		registerFunction( "locate", new SQLFunctionTemplate( Hibernate.STRING, "position(?1 in ?2)" ) );
+		registerFunction( "mod", new SQLFunctionTemplate( Hibernate.STRING, "?1 mod ?2" ) );
+		registerFunction( "str", new SQLFunctionTemplate( Hibernate.STRING, "cast(?1 as varchar(255))" ) );
+
+		// bit_length feels a bit broken to me. We have to cast to char in order to
+		// pass when a numeric value is supplied. But of course the answers given will
+		// be wildly different for these two datatypes. 1234.5678 will be 9 bytes as
+		// a char string but will be 8 or 16 bytes as a true numeric.
+		// Jay Nance 2006-09-22
+		registerFunction(
+				"bit_length", new SQLFunctionTemplate( Hibernate.INTEGER, "octet_length(cast(?1 as char))*4" )
+		);
+
+		// The preference here would be
+		//   SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp(?1)", false)
+		// but this appears not to work.
+		// Jay Nance 2006-09-22
+		registerFunction( "current_timestamp", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_timestamp" ) );
+		registerFunction( "current_time", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_time" ) );
+		registerFunction( "current_date", new SQLFunctionTemplate( Hibernate.TIMESTAMP, "current_date" ) );
+		// IBID for current_time and current_date
+
+		registerKeyword( "password" );
+		registerKeyword( "type" );
+		registerKeyword( "title" );
+		registerKeyword( "year" );
+		registerKeyword( "month" );
+		registerKeyword( "summary" );
+		registerKeyword( "alias" );
+		registerKeyword( "value" );
+		registerKeyword( "first" );
+		registerKeyword( "role" );
+		registerKeyword( "account" );
+		registerKeyword( "class" );
+
+		// Tell hibernate to use getBytes instead of getBinaryStream
+		getDefaultProperties().setProperty( Environment.USE_STREAMS_FOR_BINARY, "false" );
+		// No batch statements
+		getDefaultProperties().setProperty( Environment.STATEMENT_BATCH_SIZE, NO_BATCH );
+	}
+
+	/**
+	 * Does this dialect support the <tt>FOR UPDATE</tt> syntax?
+	 *
+	 * @return empty string ... Teradata does not support <tt>FOR UPDATE<tt> syntax
+	 */
+	public String getForUpdateString() {
+		return "";
+	}
+
+	public boolean supportsIdentityColumns() {
+		return false;
+	}
+
+	public boolean supportsSequences() {
+		return false;
+	}
+
+	public String getAddColumnString() {
+		return "Add Column";
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return " on commit preserve rows";
+	}
+
+	public Boolean performTemporaryTableDDLInIsolation() {
+		return Boolean.TRUE;
+	}
+
+	public boolean dropTemporaryTableAfterUse() {
+		return false;
+	}
+
+	/**
+	 * Get the name of the database type associated with the given
+	 * <tt>java.sql.Types</tt> typecode.
+	 *
+	 * @param code <tt>java.sql.Types</tt> typecode
+	 * @param length the length or precision of the column
+	 * @param precision the precision of the column
+	 * @param scale the scale of the column
+	 *
+	 * @return the database type name
+	 *
+	 * @throws HibernateException
+	 */
+	public String getTypeName(int code, int length, int precision, int scale) throws HibernateException {
+		/*
+		 * We might want a special case for 19,2. This is very common for money types
+		 * and here it is converted to 18,1
+		 */
+		float f = precision > 0 ? ( float ) scale / ( float ) precision : 0;
+		int p = ( precision > 18 ? 18 : precision );
+		int s = ( precision > 18 ? ( int ) ( 18.0 * f ) : ( scale > 18 ? 18 : scale ) );
+
+		return super.getTypeName( code, length, p, s );
+	}
+
+	public boolean supportsCascadeDelete() {
+		return false;
+	}
+
+	public boolean supportsCircularCascadeDeleteConstraints() {
+		return false;
+	}
+
+	public boolean areStringComparisonsCaseInsensitive() {
+		return true;
+	}
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+
+	public String getSelectClauseNullString(int sqlType) {
+		String v = "null";
+
+		switch ( sqlType ) {
+			case Types.BIT:
+			case Types.TINYINT:
+			case Types.SMALLINT:
+			case Types.INTEGER:
+			case Types.BIGINT:
+			case Types.FLOAT:
+			case Types.REAL:
+			case Types.DOUBLE:
+			case Types.NUMERIC:
+			case Types.DECIMAL:
+				v = "cast(null as decimal)";
+				break;
+			case Types.CHAR:
+			case Types.VARCHAR:
+			case Types.LONGVARCHAR:
+				v = "cast(null as varchar(255))";
+				break;
+			case Types.DATE:
+			case Types.TIME:
+			case Types.TIMESTAMP:
+				v = "cast(null as timestamp)";
+				break;
+			case Types.BINARY:
+			case Types.VARBINARY:
+			case Types.LONGVARBINARY:
+			case Types.NULL:
+			case Types.OTHER:
+			case Types.JAVA_OBJECT:
+			case Types.DISTINCT:
+			case Types.STRUCT:
+			case Types.ARRAY:
+			case Types.BLOB:
+			case Types.CLOB:
+			case Types.REF:
+			case Types.DATALINK:
+			case Types.BOOLEAN:
+				break;
+		}
+		return v;
+	}
+
+	public String getCreateMultisetTableString() {
+		return "create multiset table ";
+	}
+
+	public boolean supportsLobValueChangePropogation() {
+		return false;
+	}
+
+	public boolean doesReadCommittedCauseWritersToBlockReaders() {
+		return true;
+	}
+
+	public boolean doesRepeatableReadCauseReadersToBlockWriters() {
+		return true;
+	}
+
+	public boolean supportsBindAsCallableArgument() {
+		return false;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,205 +0,0 @@
-package org.hibernate.dialect;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.LockMode;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.function.NoArgSQLFunction;
-import org.hibernate.dialect.function.StandardSQLFunction;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.dialect.lock.UpdateLockingStrategy;
-import org.hibernate.dialect.lock.SelectLockingStrategy;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.OracleJoinFragment;
-
-/**
- * A SQL dialect for TimesTen 5.1.
- * 
- * Known limitations:
- * joined-subclass support because of no CASE support in TimesTen
- * No support for subqueries that includes aggregation
- *  - size() in HQL not supported
- *  - user queries that does subqueries with aggregation
- * No CLOB/BLOB support 
- * No cascade delete support.
- * No Calendar support
- * No support for updating primary keys.
- * 
- * @author Sherry Listgarten and Max Andersen
- */
-public class TimesTenDialect extends Dialect {
-	
-	public TimesTenDialect() {
-		super();
-		registerColumnType( Types.BIT, "TINYINT" );
-		registerColumnType( Types.BIGINT, "BIGINT" );
-		registerColumnType( Types.SMALLINT, "SMALLINT" );
-		registerColumnType( Types.TINYINT, "TINYINT" );
-		registerColumnType( Types.INTEGER, "INTEGER" );
-		registerColumnType( Types.CHAR, "CHAR(1)" );
-		registerColumnType( Types.VARCHAR, "VARCHAR($l)" );
-		registerColumnType( Types.FLOAT, "FLOAT" );
-		registerColumnType( Types.DOUBLE, "DOUBLE" );
-		registerColumnType( Types.DATE, "DATE" );
-		registerColumnType( Types.TIME, "TIME" );
-		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
-		registerColumnType( Types.VARBINARY, "VARBINARY($l)" );
-		registerColumnType( Types.NUMERIC, "DECIMAL($p, $s)" );
-		// TimesTen has no BLOB/CLOB support, but these types may be suitable 
-		// for some applications. The length is limited to 4 million bytes.
-        registerColumnType( Types.BLOB, "VARBINARY(4000000)" ); 
-        registerColumnType( Types.CLOB, "VARCHAR(4000000)" );
-	
-		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
-		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
-		registerFunction( "lower", new StandardSQLFunction("lower") );
-		registerFunction( "upper", new StandardSQLFunction("upper") );
-		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
-		registerFunction( "concat", new StandardSQLFunction("concat", Hibernate.STRING) );
-		registerFunction( "mod", new StandardSQLFunction("mod") );
-		registerFunction( "to_char", new StandardSQLFunction("to_char",Hibernate.STRING) );
-		registerFunction( "to_date", new StandardSQLFunction("to_date",Hibernate.TIMESTAMP) );
-		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP, false) );
-		registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP, false) );
-		registerFunction( "nvl", new StandardSQLFunction("nvl") );
-
-	}
-	
-	public boolean dropConstraints() {
-            return true;
-	}
-	
-	public boolean qualifyIndexName() {
-            return false;
-	}
-
-	public boolean supportsUnique() {
-		return false;
-	}
-    
-	public boolean supportsUniqueConstraintInCreateAlterTable() {
-		return false;
-	}
-	
-    public String getAddColumnString() {
-            return "add";
-	}
-
-	public boolean supportsSequences() {
-		return true;
-	}
-
-	public String getSelectSequenceNextValString(String sequenceName) {
-		return sequenceName + ".nextval";
-	}
-
-	public String getSequenceNextValString(String sequenceName) {
-		return "select first 1 " + sequenceName + ".nextval from sys.tables";
-	}
-
-	public String getCreateSequenceString(String sequenceName) {
-		return "create sequence " + sequenceName;
-	}
-
-	public String getDropSequenceString(String sequenceName) {
-		return "drop sequence " + sequenceName;
-	}
-
-	public String getQuerySequencesString() {
-		return "select NAME from sys.sequences";
-	}
-
-	public JoinFragment createOuterJoinFragment() {
-		return new OracleJoinFragment();
-	}
-
-	// new methods in dialect3
-	/*public boolean supportsForUpdateNowait() {
-		return false;
-	}*/
-	
-	public String getForUpdateString() {
-		return "";
-	}
-	
-	public boolean supportsColumnCheck() {
-		return false;
-	}
-
-	public boolean supportsTableCheck() {
-		return false;
-	}
-	
-	public boolean supportsLimitOffset() {
-		return false;
-	}
-
-	public boolean supportsVariableLimit() {
-		return false;
-	}
-
-	public boolean supportsLimit() {
-		return true;
-	}
-
-	public boolean useMaxForLimit() {
-		return true;
-	}
-
-	public String getLimitString(String querySelect, int offset, int limit) {
-		if ( offset > 0 ) {
-			throw new UnsupportedOperationException( "TimesTen does not support offset" );
-		}
-		return new StringBuffer( querySelect.length()+8 )
-			.append(querySelect)
-			.insert( 6, " first " + limit )
-			.toString();
-	}
-
-	public boolean supportsCurrentTimestampSelection() {
-		return true;
-	}
-
-	public String getCurrentTimestampSelectString() {
-		return "select first 1 sysdate from sys.tables";
-	}
-
-	public boolean isCurrentTimestampSelectStringCallable() {
-		return false;
-	}
-
-	public boolean supportsTemporaryTables() {
-		return true;
-	}
-
-	public String generateTemporaryTableName(String baseTableName) {
-		String name = super.generateTemporaryTableName(baseTableName);
-		return name.length() > 30 ? name.substring( 1, 30 ) : name;
-	}
-
-	public String getCreateTemporaryTableString() {
-		return "create global temporary table";
-	}
-
-	public String getCreateTemporaryTablePostfix() {
-		return "on commit delete rows";
-	}
-
-	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
-		// TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax...
-		if ( lockMode.greaterThan( LockMode.READ ) ) {
-			return new UpdateLockingStrategy( lockable, lockMode );
-		}
-		else {
-			return new SelectLockingStrategy( lockable, lockMode );
-		}
-	}
-
-	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean supportsEmptyInList() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TimesTenDialect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,229 @@
+/*
+ * 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.dialect;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.LockMode;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.function.NoArgSQLFunction;
+import org.hibernate.dialect.function.StandardSQLFunction;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.dialect.lock.UpdateLockingStrategy;
+import org.hibernate.dialect.lock.SelectLockingStrategy;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.OracleJoinFragment;
+
+/**
+ * A SQL dialect for TimesTen 5.1.
+ * 
+ * Known limitations:
+ * joined-subclass support because of no CASE support in TimesTen
+ * No support for subqueries that includes aggregation
+ *  - size() in HQL not supported
+ *  - user queries that does subqueries with aggregation
+ * No CLOB/BLOB support 
+ * No cascade delete support.
+ * No Calendar support
+ * No support for updating primary keys.
+ * 
+ * @author Sherry Listgarten and Max Andersen
+ */
+public class TimesTenDialect extends Dialect {
+	
+	public TimesTenDialect() {
+		super();
+		registerColumnType( Types.BIT, "TINYINT" );
+		registerColumnType( Types.BIGINT, "BIGINT" );
+		registerColumnType( Types.SMALLINT, "SMALLINT" );
+		registerColumnType( Types.TINYINT, "TINYINT" );
+		registerColumnType( Types.INTEGER, "INTEGER" );
+		registerColumnType( Types.CHAR, "CHAR(1)" );
+		registerColumnType( Types.VARCHAR, "VARCHAR($l)" );
+		registerColumnType( Types.FLOAT, "FLOAT" );
+		registerColumnType( Types.DOUBLE, "DOUBLE" );
+		registerColumnType( Types.DATE, "DATE" );
+		registerColumnType( Types.TIME, "TIME" );
+		registerColumnType( Types.TIMESTAMP, "TIMESTAMP" );
+		registerColumnType( Types.VARBINARY, "VARBINARY($l)" );
+		registerColumnType( Types.NUMERIC, "DECIMAL($p, $s)" );
+		// TimesTen has no BLOB/CLOB support, but these types may be suitable 
+		// for some applications. The length is limited to 4 million bytes.
+        registerColumnType( Types.BLOB, "VARBINARY(4000000)" ); 
+        registerColumnType( Types.CLOB, "VARCHAR(4000000)" );
+	
+		getDefaultProperties().setProperty(Environment.USE_STREAMS_FOR_BINARY, "true");
+		getDefaultProperties().setProperty(Environment.STATEMENT_BATCH_SIZE, DEFAULT_BATCH_SIZE);
+		registerFunction( "lower", new StandardSQLFunction("lower") );
+		registerFunction( "upper", new StandardSQLFunction("upper") );
+		registerFunction( "rtrim", new StandardSQLFunction("rtrim") );
+		registerFunction( "concat", new StandardSQLFunction("concat", Hibernate.STRING) );
+		registerFunction( "mod", new StandardSQLFunction("mod") );
+		registerFunction( "to_char", new StandardSQLFunction("to_char",Hibernate.STRING) );
+		registerFunction( "to_date", new StandardSQLFunction("to_date",Hibernate.TIMESTAMP) );
+		registerFunction( "sysdate", new NoArgSQLFunction("sysdate", Hibernate.TIMESTAMP, false) );
+		registerFunction( "getdate", new NoArgSQLFunction("getdate", Hibernate.TIMESTAMP, false) );
+		registerFunction( "nvl", new StandardSQLFunction("nvl") );
+
+	}
+	
+	public boolean dropConstraints() {
+            return true;
+	}
+	
+	public boolean qualifyIndexName() {
+            return false;
+	}
+
+	public boolean supportsUnique() {
+		return false;
+	}
+    
+	public boolean supportsUniqueConstraintInCreateAlterTable() {
+		return false;
+	}
+	
+    public String getAddColumnString() {
+            return "add";
+	}
+
+	public boolean supportsSequences() {
+		return true;
+	}
+
+	public String getSelectSequenceNextValString(String sequenceName) {
+		return sequenceName + ".nextval";
+	}
+
+	public String getSequenceNextValString(String sequenceName) {
+		return "select first 1 " + sequenceName + ".nextval from sys.tables";
+	}
+
+	public String getCreateSequenceString(String sequenceName) {
+		return "create sequence " + sequenceName;
+	}
+
+	public String getDropSequenceString(String sequenceName) {
+		return "drop sequence " + sequenceName;
+	}
+
+	public String getQuerySequencesString() {
+		return "select NAME from sys.sequences";
+	}
+
+	public JoinFragment createOuterJoinFragment() {
+		return new OracleJoinFragment();
+	}
+
+	// new methods in dialect3
+	/*public boolean supportsForUpdateNowait() {
+		return false;
+	}*/
+	
+	public String getForUpdateString() {
+		return "";
+	}
+	
+	public boolean supportsColumnCheck() {
+		return false;
+	}
+
+	public boolean supportsTableCheck() {
+		return false;
+	}
+	
+	public boolean supportsLimitOffset() {
+		return false;
+	}
+
+	public boolean supportsVariableLimit() {
+		return false;
+	}
+
+	public boolean supportsLimit() {
+		return true;
+	}
+
+	public boolean useMaxForLimit() {
+		return true;
+	}
+
+	public String getLimitString(String querySelect, int offset, int limit) {
+		if ( offset > 0 ) {
+			throw new UnsupportedOperationException( "TimesTen does not support offset" );
+		}
+		return new StringBuffer( querySelect.length()+8 )
+			.append(querySelect)
+			.insert( 6, " first " + limit )
+			.toString();
+	}
+
+	public boolean supportsCurrentTimestampSelection() {
+		return true;
+	}
+
+	public String getCurrentTimestampSelectString() {
+		return "select first 1 sysdate from sys.tables";
+	}
+
+	public boolean isCurrentTimestampSelectStringCallable() {
+		return false;
+	}
+
+	public boolean supportsTemporaryTables() {
+		return true;
+	}
+
+	public String generateTemporaryTableName(String baseTableName) {
+		String name = super.generateTemporaryTableName(baseTableName);
+		return name.length() > 30 ? name.substring( 1, 30 ) : name;
+	}
+
+	public String getCreateTemporaryTableString() {
+		return "create global temporary table";
+	}
+
+	public String getCreateTemporaryTablePostfix() {
+		return "on commit delete rows";
+	}
+
+	public LockingStrategy getLockingStrategy(Lockable lockable, LockMode lockMode) {
+		// TimesTen has no known variation of a "SELECT ... FOR UPDATE" syntax...
+		if ( lockMode.greaterThan( LockMode.READ ) ) {
+			return new UpdateLockingStrategy( lockable, lockMode );
+		}
+		else {
+			return new SelectLockingStrategy( lockable, lockMode );
+		}
+	}
+
+	// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean supportsEmptyInList() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/TypeNames.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,116 +0,0 @@
-//$Id: TypeNames.java 6254 2005-03-30 18:01:41Z oneovthafew $
-package org.hibernate.dialect;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.TreeMap;
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.util.StringHelper;
-
-/**
- * This class maps a type to names. Associations
- * may be marked with a capacity. Calling the get()
- * method with a type and actual size n will return
- * the associated name with smallest capacity >= n,
- * if available and an unmarked default type otherwise.
- * Eg, setting
- * <pre>
- *	names.put(type,        "TEXT" );
- *	names.put(type,   255, "VARCHAR($l)" );
- *	names.put(type, 65534, "LONGVARCHAR($l)" );
- * </pre>
- * will give you back the following:
- * <pre>
- *  names.get(type)         // --> "TEXT" (default)
- *  names.get(type,    100) // --> "VARCHAR(100)" (100 is in [0:255])
- *  names.get(type,   1000) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
- *  names.get(type, 100000) // --> "TEXT" (default)
- * </pre>
- * On the other hand, simply putting
- * <pre>
- *	names.put(type, "VARCHAR($l)" );
- * </pre>
- * would result in
- * <pre>
- *  names.get(type)        // --> "VARCHAR($l)" (will cause trouble)
- *  names.get(type, 100)   // --> "VARCHAR(100)"
- *  names.get(type, 10000) // --> "VARCHAR(10000)"
- * </pre>
- *
- * @author Christoph Beck
- */
-public class TypeNames {
-
-	private HashMap weighted = new HashMap();
-	private HashMap defaults = new HashMap();
-
-	/**
-	 * get default type name for specified type
-	 * @param typecode the type key
-	 * @return the default type name associated with specified key
-	 */
-	public String get(int typecode) throws MappingException {
-		String result = (String) defaults.get( new Integer(typecode) );
-		if (result==null) throw new MappingException("No Dialect mapping for JDBC type: " + typecode);
-		return result;
-	}
-
-	/**
-	 * get type name for specified type and size
-	 * @param typecode the type key
-	 * @param size the SQL length
-	 * @param scale the SQL scale
-	 * @param precision the SQL precision
-	 * @return the associated name with smallest capacity >= size,
-	 * if available and the default type name otherwise
-	 */
-	public String get(int typecode, int size, int precision, int scale) throws MappingException {
-		Map map = (Map) weighted.get( new Integer(typecode) );
-		if ( map!=null && map.size()>0 ) {
-			// iterate entries ordered by capacity to find first fit
-			Iterator entries = map.entrySet().iterator();
-			while ( entries.hasNext() ) {
-				Map.Entry entry = (Map.Entry)entries.next();
-				if ( size <= ( (Integer) entry.getKey() ).intValue() ) {
-					return replace( (String) entry.getValue(), size, precision, scale );
-				}
-			}
-		}
-		return replace( get(typecode), size, precision, scale );
-	}
-	
-	private static String replace(String type, int size, int precision, int scale) {
-		type = StringHelper.replaceOnce(type, "$s", Integer.toString(scale) );
-		type = StringHelper.replaceOnce(type, "$l", Integer.toString(size) );
-		return StringHelper.replaceOnce(type, "$p", Integer.toString(precision) );
-	}
-
-	/**
-	 * set a type name for specified type key and capacity
-	 * @param typecode the type key
-	 */
-	public void put(int typecode, int capacity, String value) {
-		TreeMap map = (TreeMap)weighted.get( new Integer(typecode) );
-		if (map == null) {// add new ordered map
-			map = new TreeMap();
-			weighted.put( new Integer(typecode), map );
-		}
-		map.put(new Integer(capacity), value);
-	}
-
-	/**
-	 * set a default type name for specified type key
-	 * @param typecode the type key
-	 */
-	public void put(int typecode, String value) {
-		defaults.put( new Integer(typecode), value );
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/TypeNames.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/TypeNames.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,139 @@
+/*
+ * 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.dialect;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.util.StringHelper;
+
+/**
+ * This class maps a type to names. Associations
+ * may be marked with a capacity. Calling the get()
+ * method with a type and actual size n will return
+ * the associated name with smallest capacity >= n,
+ * if available and an unmarked default type otherwise.
+ * Eg, setting
+ * <pre>
+ *	names.put(type,        "TEXT" );
+ *	names.put(type,   255, "VARCHAR($l)" );
+ *	names.put(type, 65534, "LONGVARCHAR($l)" );
+ * </pre>
+ * will give you back the following:
+ * <pre>
+ *  names.get(type)         // --> "TEXT" (default)
+ *  names.get(type,    100) // --> "VARCHAR(100)" (100 is in [0:255])
+ *  names.get(type,   1000) // --> "LONGVARCHAR(1000)" (1000 is in [256:65534])
+ *  names.get(type, 100000) // --> "TEXT" (default)
+ * </pre>
+ * On the other hand, simply putting
+ * <pre>
+ *	names.put(type, "VARCHAR($l)" );
+ * </pre>
+ * would result in
+ * <pre>
+ *  names.get(type)        // --> "VARCHAR($l)" (will cause trouble)
+ *  names.get(type, 100)   // --> "VARCHAR(100)"
+ *  names.get(type, 10000) // --> "VARCHAR(10000)"
+ * </pre>
+ *
+ * @author Christoph Beck
+ */
+public class TypeNames {
+
+	private HashMap weighted = new HashMap();
+	private HashMap defaults = new HashMap();
+
+	/**
+	 * get default type name for specified type
+	 * @param typecode the type key
+	 * @return the default type name associated with specified key
+	 */
+	public String get(int typecode) throws MappingException {
+		String result = (String) defaults.get( new Integer(typecode) );
+		if (result==null) throw new MappingException("No Dialect mapping for JDBC type: " + typecode);
+		return result;
+	}
+
+	/**
+	 * get type name for specified type and size
+	 * @param typecode the type key
+	 * @param size the SQL length
+	 * @param scale the SQL scale
+	 * @param precision the SQL precision
+	 * @return the associated name with smallest capacity >= size,
+	 * if available and the default type name otherwise
+	 */
+	public String get(int typecode, int size, int precision, int scale) throws MappingException {
+		Map map = (Map) weighted.get( new Integer(typecode) );
+		if ( map!=null && map.size()>0 ) {
+			// iterate entries ordered by capacity to find first fit
+			Iterator entries = map.entrySet().iterator();
+			while ( entries.hasNext() ) {
+				Map.Entry entry = (Map.Entry)entries.next();
+				if ( size <= ( (Integer) entry.getKey() ).intValue() ) {
+					return replace( (String) entry.getValue(), size, precision, scale );
+				}
+			}
+		}
+		return replace( get(typecode), size, precision, scale );
+	}
+	
+	private static String replace(String type, int size, int precision, int scale) {
+		type = StringHelper.replaceOnce(type, "$s", Integer.toString(scale) );
+		type = StringHelper.replaceOnce(type, "$l", Integer.toString(size) );
+		return StringHelper.replaceOnce(type, "$p", Integer.toString(precision) );
+	}
+
+	/**
+	 * set a type name for specified type key and capacity
+	 * @param typecode the type key
+	 */
+	public void put(int typecode, int capacity, String value) {
+		TreeMap map = (TreeMap)weighted.get( new Integer(typecode) );
+		if (map == null) {// add new ordered map
+			map = new TreeMap();
+			weighted.put( new Integer(typecode), map );
+		}
+		map.put(new Integer(capacity), value);
+	}
+
+	/**
+	 * set a default type name for specified type key
+	 * @param typecode the type key
+	 */
+	public void put(int typecode, String value) {
+		defaults.put( new Integer(typecode), value );
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,146 +0,0 @@
-package org.hibernate.dialect.function;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * A {@link SQLFunction} implementation that emulates the ANSI SQL trim function
- * on dialects which do not support the full definition.  However, this function
- * definition does assume the availability of ltrim, rtrim, and replace functions
- * which it uses in various combinations to emulate the desired ANSI trim()
- * functionality.
- *
- * @author Steve Ebersole
- */
-public class AnsiTrimEmulationFunction implements SQLFunction {
-
-	private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
-	private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
-	private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
-	private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
-
-	private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
-	private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
-	private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" );
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return Hibernate.STRING;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return false;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		// according to both the ANSI-SQL and EJB3 specs, trim can either take
-		// exactly one parameter or a variable number of parameters between 1 and 4.
-		// from the SQL spec:
-		//
-		// <trim function> ::=
-		//      TRIM <left paren> <trim operands> <right paren>
-		//
-		// <trim operands> ::=
-		//      [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
-		//
-		// <trim specification> ::=
-		//      LEADING
-		//      | TRAILING
-		//      | BOTH
-		//
-		// If only <trim specification> is omitted, BOTH is assumed;
-		// if <trim character> is omitted, space is assumed
-		if ( args.size() == 1 ) {
-			// we have the form: trim(trimSource)
-			//      so we trim leading and trailing spaces
-			return BOTH_SPACE_TRIM.render( args, factory );
-		}
-		else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
-			// we have the form: trim(from trimSource).
-			//      This is functionally equivalent to trim(trimSource)
-			return BOTH_SPACE_TRIM_FROM.render( args, factory );
-		}
-		else {
-			// otherwise, a trim-specification and/or a trim-character
-			// have been specified;  we need to decide which options
-			// are present and "do the right thing"
-			boolean leading = true;         // should leading trim-characters be trimmed?
-			boolean trailing = true;        // should trailing trim-characters be trimmed?
-			String trimCharacter = null;    // the trim-character
-			String trimSource = null;       // the trim-source
-
-			// potentialTrimCharacterArgIndex = 1 assumes that a
-			// trim-specification has been specified.  we handle the
-			// exception to that explicitly
-			int potentialTrimCharacterArgIndex = 1;
-			String firstArg = ( String ) args.get( 0 );
-			if ( "leading".equalsIgnoreCase( firstArg ) ) {
-				trailing = false;
-			}
-			else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
-				leading = false;
-			}
-			else if ( "both".equalsIgnoreCase( firstArg ) ) {
-			}
-			else {
-				potentialTrimCharacterArgIndex = 0;
-			}
-
-			String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
-			if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
-				trimCharacter = "' '";
-				trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
-			}
-			else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
-				trimCharacter = "' '";
-				trimSource = potentialTrimCharacter;
-			}
-			else {
-				trimCharacter = potentialTrimCharacter;
-				if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
-					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
-				}
-				else {
-					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
-				}
-			}
-
-			List argsToUse = null;
-			argsToUse = new ArrayList();
-			argsToUse.add( trimSource );
-			argsToUse.add( trimCharacter );
-
-			if ( trimCharacter.equals( "' '" ) ) {
-				if ( leading && trailing ) {
-					return BOTH_SPACE_TRIM.render( argsToUse, factory );
-				}
-				else if ( leading ) {
-					return LEADING_SPACE_TRIM.render( argsToUse, factory );
-				}
-				else {
-					return TRAILING_SPACE_TRIM.render( argsToUse, factory );
-				}
-			}
-			else {
-				if ( leading && trailing ) {
-					return BOTH_TRIM.render( argsToUse, factory );
-				}
-				else if ( leading ) {
-					return LEADING_TRIM.render( argsToUse, factory );
-				}
-				else {
-					return TRAILING_TRIM.render( argsToUse, factory );
-				}
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/AnsiTrimEmulationFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,170 @@
+/*
+ * 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.dialect.function;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * A {@link SQLFunction} implementation that emulates the ANSI SQL trim function
+ * on dialects which do not support the full definition.  However, this function
+ * definition does assume the availability of ltrim, rtrim, and replace functions
+ * which it uses in various combinations to emulate the desired ANSI trim()
+ * functionality.
+ *
+ * @author Steve Ebersole
+ */
+public class AnsiTrimEmulationFunction implements SQLFunction {
+
+	private static final SQLFunction LEADING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( ?1 )");
+	private static final SQLFunction TRAILING_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "rtrim( ?1 )");
+	private static final SQLFunction BOTH_SPACE_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?1 ) )");
+	private static final SQLFunction BOTH_SPACE_TRIM_FROM = new SQLFunctionTemplate( Hibernate.STRING, "ltrim( rtrim( ?2 ) )");
+
+	private static final SQLFunction LEADING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
+	private static final SQLFunction TRAILING_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ), ' ', ?2 ), '${space}$', ' ' )" );
+	private static final SQLFunction BOTH_TRIM = new SQLFunctionTemplate( Hibernate.STRING, "replace( replace( ltrim( rtrim( replace( replace( ?1, ' ', '${space}$' ), ?2, ' ' ) ) ), ' ', ?2 ), '${space}$', ' ' )" );
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return Hibernate.STRING;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return false;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		// according to both the ANSI-SQL and EJB3 specs, trim can either take
+		// exactly one parameter or a variable number of parameters between 1 and 4.
+		// from the SQL spec:
+		//
+		// <trim function> ::=
+		//      TRIM <left paren> <trim operands> <right paren>
+		//
+		// <trim operands> ::=
+		//      [ [ <trim specification> ] [ <trim character> ] FROM ] <trim source>
+		//
+		// <trim specification> ::=
+		//      LEADING
+		//      | TRAILING
+		//      | BOTH
+		//
+		// If only <trim specification> is omitted, BOTH is assumed;
+		// if <trim character> is omitted, space is assumed
+		if ( args.size() == 1 ) {
+			// we have the form: trim(trimSource)
+			//      so we trim leading and trailing spaces
+			return BOTH_SPACE_TRIM.render( args, factory );
+		}
+		else if ( "from".equalsIgnoreCase( ( String ) args.get( 0 ) ) ) {
+			// we have the form: trim(from trimSource).
+			//      This is functionally equivalent to trim(trimSource)
+			return BOTH_SPACE_TRIM_FROM.render( args, factory );
+		}
+		else {
+			// otherwise, a trim-specification and/or a trim-character
+			// have been specified;  we need to decide which options
+			// are present and "do the right thing"
+			boolean leading = true;         // should leading trim-characters be trimmed?
+			boolean trailing = true;        // should trailing trim-characters be trimmed?
+			String trimCharacter = null;    // the trim-character
+			String trimSource = null;       // the trim-source
+
+			// potentialTrimCharacterArgIndex = 1 assumes that a
+			// trim-specification has been specified.  we handle the
+			// exception to that explicitly
+			int potentialTrimCharacterArgIndex = 1;
+			String firstArg = ( String ) args.get( 0 );
+			if ( "leading".equalsIgnoreCase( firstArg ) ) {
+				trailing = false;
+			}
+			else if ( "trailing".equalsIgnoreCase( firstArg ) ) {
+				leading = false;
+			}
+			else if ( "both".equalsIgnoreCase( firstArg ) ) {
+			}
+			else {
+				potentialTrimCharacterArgIndex = 0;
+			}
+
+			String potentialTrimCharacter = ( String ) args.get( potentialTrimCharacterArgIndex );
+			if ( "from".equalsIgnoreCase( potentialTrimCharacter ) ) {
+				trimCharacter = "' '";
+				trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+			}
+			else if ( potentialTrimCharacterArgIndex + 1 >= args.size() ) {
+				trimCharacter = "' '";
+				trimSource = potentialTrimCharacter;
+			}
+			else {
+				trimCharacter = potentialTrimCharacter;
+				if ( "from".equalsIgnoreCase( ( String ) args.get( potentialTrimCharacterArgIndex + 1 ) ) ) {
+					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 2 );
+				}
+				else {
+					trimSource = ( String ) args.get( potentialTrimCharacterArgIndex + 1 );
+				}
+			}
+
+			List argsToUse = null;
+			argsToUse = new ArrayList();
+			argsToUse.add( trimSource );
+			argsToUse.add( trimCharacter );
+
+			if ( trimCharacter.equals( "' '" ) ) {
+				if ( leading && trailing ) {
+					return BOTH_SPACE_TRIM.render( argsToUse, factory );
+				}
+				else if ( leading ) {
+					return LEADING_SPACE_TRIM.render( argsToUse, factory );
+				}
+				else {
+					return TRAILING_SPACE_TRIM.render( argsToUse, factory );
+				}
+			}
+			else {
+				if ( leading && trailing ) {
+					return BOTH_TRIM.render( argsToUse, factory );
+				}
+				else if ( leading ) {
+					return LEADING_TRIM.render( argsToUse, factory );
+				}
+				else {
+					return TRAILING_TRIM.render( argsToUse, factory );
+				}
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/CastFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: CastFunction.java 7368 2005-07-04 02:54:27Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * ANSI-SQL style <tt>cast(foo as type)</tt> where the type is
- * a Hibernate type
- * @author Gavin King
- */
-public class CastFunction implements SQLFunction {
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return columnType; //note there is a wierd implementation in the client side
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		if ( args.size()!=2 ) {
-			throw new QueryException("cast() requires two arguments");
-		}
-		String type = (String) args.get(1);
-		int[] sqlTypeCodes = TypeFactory.heuristicType(type).sqlTypes(factory);
-		if ( sqlTypeCodes.length!=1 ) {
-			throw new QueryException("invalid Hibernate type for cast()");
-		}
-		String sqlType = factory.getDialect().getCastTypeName( sqlTypeCodes[0] );
-		if (sqlType==null) {
-			//TODO: never reached, since getTypeName() actually throws an exception!
-			sqlType = type;
-		}
-		/*else {
-			//trim off the length/precision/scale
-			int loc = sqlType.indexOf('(');
-			if (loc>-1) {
-				sqlType = sqlType.substring(0, loc);
-			}
-		}*/
-		return "cast(" + args.get(0) + " as " + sqlType + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/CastFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CastFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * ANSI-SQL style <tt>cast(foo as type)</tt> where the type is
+ * a Hibernate type
+ * @author Gavin King
+ */
+public class CastFunction implements SQLFunction {
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return columnType; //note there is a wierd implementation in the client side
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		if ( args.size()!=2 ) {
+			throw new QueryException("cast() requires two arguments");
+		}
+		String type = (String) args.get(1);
+		int[] sqlTypeCodes = TypeFactory.heuristicType(type).sqlTypes(factory);
+		if ( sqlTypeCodes.length!=1 ) {
+			throw new QueryException("invalid Hibernate type for cast()");
+		}
+		String sqlType = factory.getDialect().getCastTypeName( sqlTypeCodes[0] );
+		if (sqlType==null) {
+			//TODO: never reached, since getTypeName() actually throws an exception!
+			sqlType = type;
+		}
+		/*else {
+			//trim off the length/precision/scale
+			int loc = sqlType.indexOf('(');
+			if (loc>-1) {
+				sqlType = sqlType.substring(0, loc);
+			}
+		}*/
+		return "cast(" + args.get(0) + " as " + sqlType + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: CharIndexFunction.java 8470 2005-10-26 22:12:27Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Emulation of <tt>locate()</tt> on Sybase
- * @author Nathan Moon
- */
-public class CharIndexFunction implements SQLFunction {
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return Hibernate.INTEGER;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		boolean threeArgs = args.size() > 2;
-		Object pattern = args.get(0);
-		Object string = args.get(1);
-		Object start = threeArgs ? args.get(2) : null;
-
-		StringBuffer buf = new StringBuffer();
-		buf.append("charindex(").append( pattern ).append(", ");
-		if (threeArgs) buf.append( "right(");
-		buf.append( string );
-		if (threeArgs) buf.append( ", char_length(" ).append( string ).append(")-(").append( start ).append("-1))");
-		buf.append(')');
-		return buf.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/CharIndexFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Emulation of <tt>locate()</tt> on Sybase
+ * @author Nathan Moon
+ */
+public class CharIndexFunction implements SQLFunction {
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return Hibernate.INTEGER;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		boolean threeArgs = args.size() > 2;
+		Object pattern = args.get(0);
+		Object string = args.get(1);
+		Object start = threeArgs ? args.get(2) : null;
+
+		StringBuffer buf = new StringBuffer();
+		buf.append("charindex(").append( pattern ).append(", ");
+		if (threeArgs) buf.append( "right(");
+		buf.append( string );
+		if (threeArgs) buf.append( ", char_length(" ).append( string ).append(")-(").append( start ).append("-1))");
+		buf.append(')');
+		return buf.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-/**
- * 
- */
-package org.hibernate.dialect.function;
-
-import java.sql.Types;
-
-import org.hibernate.Hibernate;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.Type;
-
-/**
- * Classic AVG sqlfunction that return types as it was done in Hibernate 3.1 
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class ClassicAvgFunction extends StandardSQLFunction {
-	public ClassicAvgFunction() {
-		super( "avg" );
-	}
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		int[] sqlTypes;
-		try {
-			sqlTypes = columnType.sqlTypes( mapping );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-		if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
-		int sqlType = sqlTypes[0];
-		if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) {
-			return Hibernate.FLOAT;
-		}
-		else {
-			return columnType;
-		}
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicAvgFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.dialect.function;
+
+import java.sql.Types;
+
+import org.hibernate.Hibernate;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.Type;
+
+/**
+ * Classic AVG sqlfunction that return types as it was done in Hibernate 3.1 
+ * 
+ * @author Max Rydahl Andersen
+ *
+ */
+public class ClassicAvgFunction extends StandardSQLFunction {
+	public ClassicAvgFunction() {
+		super( "avg" );
+	}
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		int[] sqlTypes;
+		try {
+			sqlTypes = columnType.sqlTypes( mapping );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+		if ( sqlTypes.length != 1 ) throw new QueryException( "multi-column type in avg()" );
+		int sqlType = sqlTypes[0];
+		if ( sqlType == Types.INTEGER || sqlType == Types.BIGINT || sqlType == Types.TINYINT ) {
+			return Hibernate.FLOAT;
+		}
+		else {
+			return columnType;
+		}
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-/**
- * 
- */
-package org.hibernate.dialect.function;
-
-import org.hibernate.Hibernate;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.Type;
-
-
-/**
- * Classic COUNT sqlfunction that return types as it was done in Hibernate 3.1 
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class ClassicCountFunction extends StandardSQLFunction {
-	public ClassicCountFunction() {
-		super( "count" );
-	}
-
-	public Type getReturnType(Type columnType, Mapping mapping) {
-		return Hibernate.INTEGER;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicCountFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import org.hibernate.Hibernate;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.Type;
+
+
+/**
+ * Classic COUNT sqlfunction that return types as it was done in Hibernate 3.1 
+ * 
+ * @author Max Rydahl Andersen
+ *
+ */
+public class ClassicCountFunction extends StandardSQLFunction {
+	public ClassicCountFunction() {
+		super( "count" );
+	}
+
+	public Type getReturnType(Type columnType, Mapping mapping) {
+		return Hibernate.INTEGER;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-/**
- * 
- */
-package org.hibernate.dialect.function;
-
-
-/**
- * Classic SUM sqlfunction that return types as it was done in Hibernate 3.1 
- * 
- * @author Max Rydahl Andersen
- *
- */
-public class ClassicSumFunction extends StandardSQLFunction {
-	public ClassicSumFunction() {
-		super( "sum" );
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ClassicSumFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+
+/**
+ * Classic SUM sqlfunction that return types as it was done in Hibernate 3.1 
+ * 
+ * @author Max Rydahl Andersen
+ *
+ */
+public class ClassicSumFunction extends StandardSQLFunction {
+	public ClassicSumFunction() {
+		super( "sum" );
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: ConditionalParenthesisFunction.java,v 1.4 2005/04/26 18:08:01 oneovthafew Exp $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Essentially the same as {@link org.hibernate.dialect.function.StandardSQLFunction},
- * except that here the parentheses are not included when no arguments are given.
- *
- * @author Jonathan Levinson
- */
-public class ConditionalParenthesisFunction extends StandardSQLFunction {
-
-	public ConditionalParenthesisFunction(String name) {
-		super( name );
-	}
-
-	public ConditionalParenthesisFunction(String name, Type type) {
-		super( name, type );
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return false;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) {
-		final boolean hasArgs = !args.isEmpty();
-		StringBuffer buf = new StringBuffer();
-		buf.append( getName() );
-		if ( hasArgs ) {
-			buf.append( "(" );
-			for ( int i = 0; i < args.size(); i++ ) {
-				buf.append( args.get( i ) );
-				if ( i < args.size() - 1 ) {
-					buf.append( ", " );
-				}
-			}
-			buf.append( ")" );
-		}
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConditionalParenthesisFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Essentially the same as {@link org.hibernate.dialect.function.StandardSQLFunction},
+ * except that here the parentheses are not included when no arguments are given.
+ *
+ * @author Jonathan Levinson
+ */
+public class ConditionalParenthesisFunction extends StandardSQLFunction {
+
+	public ConditionalParenthesisFunction(String name) {
+		super( name );
+	}
+
+	public ConditionalParenthesisFunction(String name, Type type) {
+		super( name, type );
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return false;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) {
+		final boolean hasArgs = !args.isEmpty();
+		StringBuffer buf = new StringBuffer();
+		buf.append( getName() );
+		if ( hasArgs ) {
+			buf.append( "(" );
+			for ( int i = 0; i < args.size(); i++ ) {
+				buf.append( args.get( i ) );
+				if ( i < args.size() - 1 ) {
+					buf.append( ", " );
+				}
+			}
+			buf.append( ")" );
+		}
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: CastFunction.java 7368 2005-07-04 02:54:27Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.Hibernate;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * A Cach&eacute; defintion of a convert function.
- *
- * @author Jonathan Levinson
- */
-public class ConvertFunction implements SQLFunction {
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return Hibernate.STRING;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		if ( args.size() != 2 && args.size() != 3 ) {
-			throw new QueryException( "convert() requires two or three arguments" );
-		}
-		String type = ( String ) args.get( 1 );
-
-		if ( args.size() == 2 ) {
-			return "{fn convert(" + args.get( 0 ) + " , " + type + ")}";
-		}
-		else {
-			return "convert(" + args.get( 0 ) + " , " + type + "," + args.get( 2 ) + ")";
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/ConvertFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.Hibernate;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A Cach&eacute; defintion of a convert function.
+ *
+ * @author Jonathan Levinson
+ */
+public class ConvertFunction implements SQLFunction {
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return Hibernate.STRING;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		if ( args.size() != 2 && args.size() != 3 ) {
+			throw new QueryException( "convert() requires two or three arguments" );
+		}
+		String type = ( String ) args.get( 1 );
+
+		if ( args.size() == 2 ) {
+			return "{fn convert(" + args.get( 0 ) + " , " + type + ")}";
+		}
+		else {
+			return "convert(" + args.get( 0 ) + " , " + type + "," + args.get( 2 ) + ")";
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: NoArgSQLFunction.java 6608 2005-04-29 15:32:30Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-
-/**
- * A function which takes no arguments
- * @author Michi
- */
-public class NoArgSQLFunction implements SQLFunction {
-    private Type returnType;
-    private boolean hasParenthesesIfNoArguments;
-    private String name;
-
-    public NoArgSQLFunction(String name, Type returnType) {
-        this(name, returnType, true);
-    }
-
-    public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) {
-        this.returnType = returnType;
-        this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments;
-        this.name = name;
-    }
-
-    public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-        return returnType;
-    }
-
-    public boolean hasArguments() {
-        return false;
-    }
-
-    public boolean hasParenthesesIfNoArguments() {
-        return hasParenthesesIfNoArguments;
-    }
-    
-    public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-    	if ( args.size()>0 ) {
-    		throw new QueryException("function takes no arguments: " + name);
-    	}
-    	return hasParenthesesIfNoArguments ? name + "()" : name;
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NoArgSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+
+/**
+ * A function which takes no arguments
+ * @author Michi
+ */
+public class NoArgSQLFunction implements SQLFunction {
+    private Type returnType;
+    private boolean hasParenthesesIfNoArguments;
+    private String name;
+
+    public NoArgSQLFunction(String name, Type returnType) {
+        this(name, returnType, true);
+    }
+
+    public NoArgSQLFunction(String name, Type returnType, boolean hasParenthesesIfNoArguments) {
+        this.returnType = returnType;
+        this.hasParenthesesIfNoArguments = hasParenthesesIfNoArguments;
+        this.name = name;
+    }
+
+    public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+        return returnType;
+    }
+
+    public boolean hasArguments() {
+        return false;
+    }
+
+    public boolean hasParenthesesIfNoArguments() {
+        return hasParenthesesIfNoArguments;
+    }
+    
+    public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+    	if ( args.size()>0 ) {
+    		throw new QueryException("function takes no arguments: " + name);
+    	}
+    	return hasParenthesesIfNoArguments ? name + "()" : name;
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: NvlFunction.java 6608 2005-04-29 15:32:30Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Emulation of <tt>coalesce()</tt> on Oracle, using multiple
- * <tt>nvl()</tt> calls
- * @author Gavin King
- */
-public class NvlFunction implements SQLFunction {
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return columnType;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		int lastIndex = args.size()-1;
-		Object last = args.remove(lastIndex);
-		if ( lastIndex==0 ) return last.toString();
-		Object secondLast = args.get(lastIndex-1);
-		String nvl = "nvl(" + secondLast + ", " + last + ")";
-		args.set(lastIndex-1, nvl);
-		return render(args, factory);
-	}
-
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/NvlFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Emulation of <tt>coalesce()</tt> on Oracle, using multiple
+ * <tt>nvl()</tt> calls
+ * @author Gavin King
+ */
+public class NvlFunction implements SQLFunction {
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return columnType;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		int lastIndex = args.size()-1;
+		Object last = args.remove(lastIndex);
+		if ( lastIndex==0 ) return last.toString();
+		Object secondLast = args.get(lastIndex-1);
+		String nvl = "nvl(" + secondLast + ", " + last + ")";
+		args.set(lastIndex-1, nvl);
+		return render(args, factory);
+	}
+
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-//$Id: PositionSubstringFunction.java 6608 2005-04-29 15:32:30Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Emulation of <tt>locate()</tt> on PostgreSQL
- * @author Gavin King
- */
-public class PositionSubstringFunction implements SQLFunction {
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return Hibernate.INTEGER;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		boolean threeArgs = args.size() > 2;
-		Object pattern = args.get(0);
-		Object string = args.get(1);
-		Object start = threeArgs ? args.get(2) : null;
-
-		StringBuffer buf = new StringBuffer();
-		if (threeArgs) buf.append('(');
-		buf.append("position(").append( pattern ).append(" in ");
-		if (threeArgs) buf.append( "substring(");
-		buf.append( string );
-		if (threeArgs) buf.append( ", " ).append( start ).append(')');
-		buf.append(')');
-		if (threeArgs) buf.append('+').append( start ).append("-1)");
-		return buf.toString();
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/PositionSubstringFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Emulation of <tt>locate()</tt> on PostgreSQL
+ * @author Gavin King
+ */
+public class PositionSubstringFunction implements SQLFunction {
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return Hibernate.INTEGER;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		boolean threeArgs = args.size() > 2;
+		Object pattern = args.get(0);
+		Object string = args.get(1);
+		Object start = threeArgs ? args.get(2) : null;
+
+		StringBuffer buf = new StringBuffer();
+		if (threeArgs) buf.append('(');
+		buf.append("position(").append( pattern ).append(" in ");
+		if (threeArgs) buf.append( "substring(");
+		buf.append( string );
+		if (threeArgs) buf.append( ", " ).append( start ).append(')');
+		buf.append(')');
+		if (threeArgs) buf.append('+').append( start ).append("-1)");
+		return buf.toString();
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: SQLFunction.java 10774 2006-11-08 16:54:55Z steve.ebersole at jboss.com $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Provides support routines for the HQL functions as used
- * in the various SQL Dialects
- *
- * Provides an interface for supporting various HQL functions that are
- * translated to SQL. The Dialect and its sub-classes use this interface to
- * provide details required for processing of the function.
- *
- * @author David Channon
- */
-public interface SQLFunction {
-	/**
-	 * The return type of the function.  May be either a concrete type which
-	 * is preset, or variable depending upon the type of the first function
-	 * argument.
-	 *
-	 * @param columnType the type of the first argument
-	 * @param mapping The mapping source.
-	 * @return The type to be expected as a return.
-	 * @throws org.hibernate.QueryException Indicates an issue resolving the return type.
-	 */
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException;
-
-	/**
-	 * Does this function have any arguments?
-	 *
-	 * @return True if the function expects to have parameters; false otherwise.
-	 */
-	public boolean hasArguments();
-
-	/**
-	 * If there are no arguments, are parens required?
-	 *
-	 * @return True if a no-arg call of this function requires parentheses.
-	 */
-	public boolean hasParenthesesIfNoArguments();
-
-	/**
-	 * Render the function call as SQL fragment.
-	 *
-	 * @param args The function arguments
-	 * @param factory The SessionFactory
-	 * @return The rendered function call
-	 * @throws org.hibernate.QueryException Indicates a problem rendering the
-	 * function call.
-	 */
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Provides support routines for the HQL functions as used
+ * in the various SQL Dialects
+ *
+ * Provides an interface for supporting various HQL functions that are
+ * translated to SQL. The Dialect and its sub-classes use this interface to
+ * provide details required for processing of the function.
+ *
+ * @author David Channon
+ */
+public interface SQLFunction {
+	/**
+	 * The return type of the function.  May be either a concrete type which
+	 * is preset, or variable depending upon the type of the first function
+	 * argument.
+	 *
+	 * @param columnType the type of the first argument
+	 * @param mapping The mapping source.
+	 * @return The type to be expected as a return.
+	 * @throws org.hibernate.QueryException Indicates an issue resolving the return type.
+	 */
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException;
+
+	/**
+	 * Does this function have any arguments?
+	 *
+	 * @return True if the function expects to have parameters; false otherwise.
+	 */
+	public boolean hasArguments();
+
+	/**
+	 * If there are no arguments, are parens required?
+	 *
+	 * @return True if a no-arg call of this function requires parentheses.
+	 */
+	public boolean hasParenthesesIfNoArguments();
+
+	/**
+	 * Render the function call as SQL fragment.
+	 *
+	 * @param args The function arguments
+	 * @param factory The SessionFactory
+	 * @return The rendered function call
+	 * @throws org.hibernate.QueryException Indicates a problem rendering the
+	 * function call.
+	 */
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-package org.hibernate.dialect.function;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.dialect.Dialect;
-
-public class SQLFunctionRegistry {
-
-	private final Dialect dialect;
-	private final Map userFunctions;
-	
-	public SQLFunctionRegistry(Dialect dialect, Map userFunctions) {
-		this.dialect = dialect;
-		this.userFunctions = new HashMap();
-		this.userFunctions.putAll( userFunctions );
-	}
-	
-	public SQLFunction findSQLFunction(String functionName) {
-		String name = functionName.toLowerCase();
-		SQLFunction userFunction = (SQLFunction) userFunctions.get( name );
-		
-		return userFunction!=null?userFunction:(SQLFunction) dialect.getFunctions().get(name); // TODO: lowercasing done here. Was done "at random" before; maybe not needed at all ?
-	}
-
-	public boolean hasFunction(String functionName) {
-		String name = functionName.toLowerCase();
-		boolean hasUserFunction = userFunctions.containsKey ( name );
-		
-		return hasUserFunction || dialect.getFunctions().containsKey ( name ); // TODO: toLowerCase was not done before. Only used in Template.
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionRegistry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.dialect.function;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.dialect.Dialect;
+
+public class SQLFunctionRegistry {
+
+	private final Dialect dialect;
+	private final Map userFunctions;
+	
+	public SQLFunctionRegistry(Dialect dialect, Map userFunctions) {
+		this.dialect = dialect;
+		this.userFunctions = new HashMap();
+		this.userFunctions.putAll( userFunctions );
+	}
+	
+	public SQLFunction findSQLFunction(String functionName) {
+		String name = functionName.toLowerCase();
+		SQLFunction userFunction = (SQLFunction) userFunctions.get( name );
+		
+		return userFunction!=null?userFunction:(SQLFunction) dialect.getFunctions().get(name); // TODO: lowercasing done here. Was done "at random" before; maybe not needed at all ?
+	}
+
+	public boolean hasFunction(String functionName) {
+		String name = functionName.toLowerCase();
+		boolean hasUserFunction = userFunctions.containsKey ( name );
+		
+		return hasUserFunction || dialect.getFunctions().containsKey ( name ); // TODO: toLowerCase was not done before. Only used in Template.
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +0,0 @@
-//$Id: SQLFunctionTemplate.java 6608 2005-04-29 15:32:30Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Represents HQL functions that can have different representations in different SQL dialects.
- * E.g. in HQL we can define function <code>concat(?1, ?2)</code> to concatenate two strings 
- * p1 and p2. Target SQL function will be dialect-specific, e.g. <code>(?1 || ?2)</code> for 
- * Oracle, <code>concat(?1, ?2)</code> for MySql, <code>(?1 + ?2)</code> for MS SQL.
- * Each dialect will define a template as a string (exactly like above) marking function 
- * parameters with '?' followed by parameter's index (first index is 1).
- *
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @version <tt>$Revision: 6608 $</tt>
- */
-public class SQLFunctionTemplate implements SQLFunction {
-	private final Type type;
-	private final boolean hasArguments;
-	private final boolean hasParenthesesIfNoArgs;
-
-	private final String template;
-	private final String[] chunks;
-	private final int[] paramIndexes;
-
-	public SQLFunctionTemplate(Type type, String template) {
-		this( type, template, true );
-	}
-
-	public SQLFunctionTemplate(Type type, String template, boolean hasParenthesesIfNoArgs) {
-		this.type = type;
-		this.template = template;
-
-		List chunkList = new ArrayList();
-		List paramList = new ArrayList();
-		StringBuffer chunk = new StringBuffer( 10 );
-		StringBuffer index = new StringBuffer( 2 );
-
-		for ( int i = 0; i < template.length(); ++i ) {
-			char c = template.charAt( i );
-			if ( c == '?' ) {
-				chunkList.add( chunk.toString() );
-				chunk.delete( 0, chunk.length() );
-
-				while ( ++i < template.length() ) {
-					c = template.charAt( i );
-					if ( Character.isDigit( c ) ) {
-						index.append( c );
-					}
-					else {
-						chunk.append( c );
-						break;
-					}
-				}
-
-				paramList.add( new Integer( Integer.parseInt( index.toString() ) - 1 ) );
-				index.delete( 0, index.length() );
-			}
-			else {
-				chunk.append( c );
-			}
-		}
-
-		if ( chunk.length() > 0 ) {
-			chunkList.add( chunk.toString() );
-		}
-
-		chunks = ( String[] ) chunkList.toArray( new String[chunkList.size()] );
-		paramIndexes = new int[paramList.size()];
-		for ( int i = 0; i < paramIndexes.length; ++i ) {
-			paramIndexes[i] = ( ( Integer ) paramList.get( i ) ).intValue();
-		}
-
-		hasArguments = paramIndexes.length > 0;
-		this.hasParenthesesIfNoArgs = hasParenthesesIfNoArgs;
-	}
-
-	/**
-	 * Applies the template to passed in arguments.
-	 * @param args function arguments
-	 *
-	 * @return generated SQL function call
-	 */
-	public String render(List args, SessionFactoryImplementor factory) {
-		StringBuffer buf = new StringBuffer();
-		for ( int i = 0; i < chunks.length; ++i ) {
-			if ( i < paramIndexes.length ) {
-				Object arg = paramIndexes[i] < args.size() ? args.get( paramIndexes[i] ) : null;
-				if ( arg != null ) {
-					buf.append( chunks[i] ).append( arg );
-				}
-			}
-			else {
-				buf.append( chunks[i] );
-			}
-		}
-		return buf.toString();
-	}
-
-	// SQLFunction implementation
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return type;
-	}
-
-	public boolean hasArguments() {
-		return hasArguments;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return hasParenthesesIfNoArgs;
-	}
-	
-	public String toString() {
-		return template;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/SQLFunctionTemplate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Represents HQL functions that can have different representations in different SQL dialects.
+ * E.g. in HQL we can define function <code>concat(?1, ?2)</code> to concatenate two strings 
+ * p1 and p2. Target SQL function will be dialect-specific, e.g. <code>(?1 || ?2)</code> for 
+ * Oracle, <code>concat(?1, ?2)</code> for MySql, <code>(?1 + ?2)</code> for MS SQL.
+ * Each dialect will define a template as a string (exactly like above) marking function 
+ * parameters with '?' followed by parameter's index (first index is 1).
+ *
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @version <tt>$Revision: 6608 $</tt>
+ */
+public class SQLFunctionTemplate implements SQLFunction {
+	private final Type type;
+	private final boolean hasArguments;
+	private final boolean hasParenthesesIfNoArgs;
+
+	private final String template;
+	private final String[] chunks;
+	private final int[] paramIndexes;
+
+	public SQLFunctionTemplate(Type type, String template) {
+		this( type, template, true );
+	}
+
+	public SQLFunctionTemplate(Type type, String template, boolean hasParenthesesIfNoArgs) {
+		this.type = type;
+		this.template = template;
+
+		List chunkList = new ArrayList();
+		List paramList = new ArrayList();
+		StringBuffer chunk = new StringBuffer( 10 );
+		StringBuffer index = new StringBuffer( 2 );
+
+		for ( int i = 0; i < template.length(); ++i ) {
+			char c = template.charAt( i );
+			if ( c == '?' ) {
+				chunkList.add( chunk.toString() );
+				chunk.delete( 0, chunk.length() );
+
+				while ( ++i < template.length() ) {
+					c = template.charAt( i );
+					if ( Character.isDigit( c ) ) {
+						index.append( c );
+					}
+					else {
+						chunk.append( c );
+						break;
+					}
+				}
+
+				paramList.add( new Integer( Integer.parseInt( index.toString() ) - 1 ) );
+				index.delete( 0, index.length() );
+			}
+			else {
+				chunk.append( c );
+			}
+		}
+
+		if ( chunk.length() > 0 ) {
+			chunkList.add( chunk.toString() );
+		}
+
+		chunks = ( String[] ) chunkList.toArray( new String[chunkList.size()] );
+		paramIndexes = new int[paramList.size()];
+		for ( int i = 0; i < paramIndexes.length; ++i ) {
+			paramIndexes[i] = ( ( Integer ) paramList.get( i ) ).intValue();
+		}
+
+		hasArguments = paramIndexes.length > 0;
+		this.hasParenthesesIfNoArgs = hasParenthesesIfNoArgs;
+	}
+
+	/**
+	 * Applies the template to passed in arguments.
+	 * @param args function arguments
+	 *
+	 * @return generated SQL function call
+	 */
+	public String render(List args, SessionFactoryImplementor factory) {
+		StringBuffer buf = new StringBuffer();
+		for ( int i = 0; i < chunks.length; ++i ) {
+			if ( i < paramIndexes.length ) {
+				Object arg = paramIndexes[i] < args.size() ? args.get( paramIndexes[i] ) : null;
+				if ( arg != null ) {
+					buf.append( chunks[i] ).append( arg );
+				}
+			}
+			else {
+				buf.append( chunks[i] );
+			}
+		}
+		return buf.toString();
+	}
+
+	// SQLFunction implementation
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return type;
+	}
+
+	public boolean hasArguments() {
+		return hasArguments;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return hasParenthesesIfNoArgs;
+	}
+	
+	public String toString() {
+		return template;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Analogous to {@link org.hibernate.dialect.function.StandardSQLFunction}
- * except that standard JDBC escape sequences (i.e. {fn blah}) are used when
- * rendering the SQL.
- *
- * @author Steve Ebersole
- */
-public class StandardJDBCEscapeFunction extends StandardSQLFunction {
-	public StandardJDBCEscapeFunction(String name) {
-		super( name );
-	}
-
-	public StandardJDBCEscapeFunction(String name, Type typeValue) {
-		super( name, typeValue );
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) {
-		return "{fn " + super.render( args, factory ) + "}";
-	}
-
-	public String toString() {
-		return "{fn " + getName() + "...}";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardJDBCEscapeFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Analogous to {@link org.hibernate.dialect.function.StandardSQLFunction}
+ * except that standard JDBC escape sequences (i.e. {fn blah}) are used when
+ * rendering the SQL.
+ *
+ * @author Steve Ebersole
+ */
+public class StandardJDBCEscapeFunction extends StandardSQLFunction {
+	public StandardJDBCEscapeFunction(String name) {
+		super( name );
+	}
+
+	public StandardJDBCEscapeFunction(String name, Type typeValue) {
+		super( name, typeValue );
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) {
+		return "{fn " + super.render( args, factory ) + "}";
+	}
+
+	public String toString() {
+		return "{fn " + getName() + "...}";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: StandardSQLFunction.java 10774 2006-11-08 16:54:55Z steve.ebersole at jboss.com $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Provides a standard implementation that supports the majority of the HQL
- * functions that are translated to SQL. The Dialect and its sub-classes use
- * this class to provide details required for processing of the associated
- * function.
- *
- * @author David Channon
- */
-public class StandardSQLFunction implements SQLFunction {
-	private final String name;
-	private final Type type;
-
-	/**
-	 * Construct a standard SQL function definition with a variable return type;
-	 * the actual return type will depend on the types to which the function
-	 * is applied.
-	 * <p/>
-	 * Using this form, the return type is considered non-static and assumed
-	 * to be the type of the first argument.
-	 *
-	 * @param name The name of the function.
-	 */
-	public StandardSQLFunction(String name) {
-		this( name, null );
-	}
-
-	/**
-	 * Construct a standard SQL function definition with a static return type.
-	 *
-	 * @param name The name of the function.
-	 * @param type The static return type.
-	 */
-	public StandardSQLFunction(String name, Type type) {
-		this.name = name;
-		this.type = type;
-	}
-
-	/**
-	 * Function name accessor
-	 *
-	 * @return The function name.
-	 */
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * Function static return type accessor.
-	 *
-	 * @return The static function return type; or null if return type is
-	 * not static.
-	 */
-	public Type getType() {
-		return type;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Type getReturnType(Type columnType, Mapping mapping) {
-		// return the concrete type, or the underlying type if a concrete type
-		// was not specified
-		return type == null ? columnType : type;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean hasArguments() {
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String render(List args, SessionFactoryImplementor factory) {
-		StringBuffer buf = new StringBuffer();
-		buf.append( name ).append( '(' );
-		for ( int i = 0; i < args.size(); i++ ) {
-			buf.append( args.get( i ) );
-			if ( i < args.size() - 1 ) {
-				buf.append( ", " );
-			}
-		}
-		return buf.append( ')' ).toString();
-	}
-
-	public String toString() {
-		return name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/StandardSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Provides a standard implementation that supports the majority of the HQL
+ * functions that are translated to SQL. The Dialect and its sub-classes use
+ * this class to provide details required for processing of the associated
+ * function.
+ *
+ * @author David Channon
+ */
+public class StandardSQLFunction implements SQLFunction {
+	private final String name;
+	private final Type type;
+
+	/**
+	 * Construct a standard SQL function definition with a variable return type;
+	 * the actual return type will depend on the types to which the function
+	 * is applied.
+	 * <p/>
+	 * Using this form, the return type is considered non-static and assumed
+	 * to be the type of the first argument.
+	 *
+	 * @param name The name of the function.
+	 */
+	public StandardSQLFunction(String name) {
+		this( name, null );
+	}
+
+	/**
+	 * Construct a standard SQL function definition with a static return type.
+	 *
+	 * @param name The name of the function.
+	 * @param type The static return type.
+	 */
+	public StandardSQLFunction(String name, Type type) {
+		this.name = name;
+		this.type = type;
+	}
+
+	/**
+	 * Function name accessor
+	 *
+	 * @return The function name.
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * Function static return type accessor.
+	 *
+	 * @return The static function return type; or null if return type is
+	 * not static.
+	 */
+	public Type getType() {
+		return type;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Type getReturnType(Type columnType, Mapping mapping) {
+		// return the concrete type, or the underlying type if a concrete type
+		// was not specified
+		return type == null ? columnType : type;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasArguments() {
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String render(List args, SessionFactoryImplementor factory) {
+		StringBuffer buf = new StringBuffer();
+		buf.append( name ).append( '(' );
+		for ( int i = 0; i < args.size(); i++ ) {
+			buf.append( args.get( i ) );
+			if ( i < args.size() - 1 ) {
+				buf.append( ", " );
+			}
+		}
+		return buf.append( ')' ).toString();
+	}
+
+	public String toString() {
+		return name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: VarArgsSQLFunction.java 6608 2005-04-29 15:32:30Z oneovthafew $
-package org.hibernate.dialect.function;
-
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Support for slightly more general templating than <tt>StandardSQLFunction</tt>,
- * with an unlimited number of arguments.
- * @author Gavin King
- */
-public class VarArgsSQLFunction implements SQLFunction {
-
-	private final String begin;
-	private final String sep;
-	private final String end;
-	private final Type type;
-	
-	public VarArgsSQLFunction(Type type, String begin, String sep, String end) {
-		this.begin = begin;
-		this.sep = sep;
-		this.end = end;
-		this.type = type;
-	}
-
-	public VarArgsSQLFunction(String begin, String sep, String end) {
-		this.begin = begin;
-		this.sep = sep;
-		this.end = end;
-		this.type = null;
-	}
-
-	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
-		return type==null ? columnType : type;
-	}
-
-	public boolean hasArguments() {
-		return true;
-	}
-
-	public boolean hasParenthesesIfNoArguments() {
-		return true;
-	}
-
-	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
-		StringBuffer buf = new StringBuffer().append(begin);
-		for ( int i=0; i<args.size(); i++ ) {
-			buf.append( args.get(i) );
-			if (i<args.size()-1) buf.append(sep);
-		}
-		return buf.append(end).toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/VarArgsSQLFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.function;
+
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Support for slightly more general templating than <tt>StandardSQLFunction</tt>,
+ * with an unlimited number of arguments.
+ * @author Gavin King
+ */
+public class VarArgsSQLFunction implements SQLFunction {
+
+	private final String begin;
+	private final String sep;
+	private final String end;
+	private final Type type;
+	
+	public VarArgsSQLFunction(Type type, String begin, String sep, String end) {
+		this.begin = begin;
+		this.sep = sep;
+		this.end = end;
+		this.type = type;
+	}
+
+	public VarArgsSQLFunction(String begin, String sep, String end) {
+		this.begin = begin;
+		this.sep = sep;
+		this.end = end;
+		this.type = null;
+	}
+
+	public Type getReturnType(Type columnType, Mapping mapping) throws QueryException {
+		return type==null ? columnType : type;
+	}
+
+	public boolean hasArguments() {
+		return true;
+	}
+
+	public boolean hasParenthesesIfNoArguments() {
+		return true;
+	}
+
+	public String render(List args, SessionFactoryImplementor factory) throws QueryException {
+		StringBuffer buf = new StringBuffer().append(begin);
+		for ( int i=0; i<args.size(); i++ ) {
+			buf.append( args.get(i) );
+			if (i<args.size()-1) buf.append(sep);
+		}
+		return buf.append(end).toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/function/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	A framework for defining database-specific SQL functions
-	that are available via the dialect.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/function/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/function/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	A framework for defining database-specific SQL functions
+	that are available via the dialect.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-package org.hibernate.dialect.lock;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.JDBCException;
-
-import java.io.Serializable;
-
-/**
- * A strategy abstraction for how locks are obtained in the underlying database.
- * <p/>
- * All locking provided implemenations assume the underlying database supports
- * (and that the connection is in) at least read-committed transaction isolation.
- * The most glaring exclusion to this is HSQLDB which only offers support for
- * READ_UNCOMMITTED isolation.
- *
- * @see org.hibernate.dialect.Dialect#getLockingStrategy
- * @since 3.2
- *
- * @author Steve Ebersole
- */
-public interface LockingStrategy {
-	/**
-	 * Acquire an appropriate type of lock on the underlying data that will
-	 * endure until the end of the current transaction.
-	 *
-	 * @param id The id of the row to be locked
-	 * @param version The current version (or null if not versioned)
-	 * @param object The object logically being locked (currently not used)
-	 * @param session The session from which the lock request originated
-	 * @throws StaleObjectStateException Indicates an optimisitic lock failure
-	 * as part of acquiring the requested database lock.
-	 * @throws JDBCException
-	 */
-	public void lock(Serializable id, Object version, Object object, SessionImplementor session)
-	throws StaleObjectStateException, JDBCException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/LockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.lock;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+
+import java.io.Serializable;
+
+/**
+ * A strategy abstraction for how locks are obtained in the underlying database.
+ * <p/>
+ * All locking provided implemenations assume the underlying database supports
+ * (and that the connection is in) at least read-committed transaction isolation.
+ * The most glaring exclusion to this is HSQLDB which only offers support for
+ * READ_UNCOMMITTED isolation.
+ *
+ * @see org.hibernate.dialect.Dialect#getLockingStrategy
+ * @since 3.2
+ *
+ * @author Steve Ebersole
+ */
+public interface LockingStrategy {
+	/**
+	 * Acquire an appropriate type of lock on the underlying data that will
+	 * endure until the end of the current transaction.
+	 *
+	 * @param id The id of the row to be locked
+	 * @param version The current version (or null if not versioned)
+	 * @param object The object logically being locked (currently not used)
+	 * @param session The session from which the lock request originated
+	 * @throws StaleObjectStateException Indicates an optimisitic lock failure
+	 * as part of acquiring the requested database lock.
+	 * @throws JDBCException
+	 */
+	public void lock(Serializable id, Object version, Object object, SessionImplementor session)
+	throws StaleObjectStateException, JDBCException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,119 +0,0 @@
-package org.hibernate.dialect.lock;
-
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.JDBCException;
-import org.hibernate.LockMode;
-import org.hibernate.sql.SimpleSelect;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * A locking strategy where the locks are obtained through select statements.
- * <p/>
- * For non-read locks, this is achieved through the Dialect's specific
- * SELECT ... FOR UPDATE syntax.
- *
- * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
- * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
- * @since 3.2
- *
- * @author Steve Ebersole
- */
-public class SelectLockingStrategy implements LockingStrategy {
-
-	private final Lockable lockable;
-	private final LockMode lockMode;
-	private final String sql;
-
-	/**
-	 * Construct a locking strategy based on SQL SELECT statements.
-	 *
-	 * @param lockable The metadata for the entity to be locked.
-	 * @param lockMode Indictates the type of lock to be acquired.
-	 */
-	public SelectLockingStrategy(Lockable lockable, LockMode lockMode) {
-		this.lockable = lockable;
-		this.lockMode = lockMode;
-		this.sql = generateLockString();
-	}
-
-	/**
-	 * @see LockingStrategy#lock
-	 */
-	public void lock(
-	        Serializable id,
-	        Object version,
-	        Object object,
-	        SessionImplementor session) throws StaleObjectStateException, JDBCException {
-
-		SessionFactoryImplementor factory = session.getFactory();
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
-			try {
-				lockable.getIdentifierType().nullSafeSet( st, id, 1, session );
-				if ( lockable.isVersioned() ) {
-					lockable.getVersionType().nullSafeSet(
-							st,
-							version,
-							lockable.getIdentifierType().getColumnSpan( factory ) + 1,
-							session
-					);
-				}
-
-				ResultSet rs = st.executeQuery();
-				try {
-					if ( !rs.next() ) {
-						if ( factory.getStatistics().isStatisticsEnabled() ) {
-							factory.getStatisticsImplementor()
-									.optimisticFailure( lockable.getEntityName() );
-						}
-						throw new StaleObjectStateException( lockable.getEntityName(), id );
-					}
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
-					sql
-				);
-		}
-	}
-
-	protected LockMode getLockMode() {
-		return lockMode;
-	}
-
-	protected String generateLockString() {
-		SessionFactoryImplementor factory = lockable.getFactory();
-		SimpleSelect select = new SimpleSelect( factory.getDialect() )
-				.setLockMode( lockMode )
-				.setTableName( lockable.getRootTableName() )
-				.addColumn( lockable.getRootTableIdentifierColumnNames()[0] )
-				.addCondition( lockable.getRootTableIdentifierColumnNames(), "=?" );
-		if ( lockable.isVersioned() ) {
-			select.addCondition( lockable.getVersionColumnName(), "=?" );
-		}
-		if ( factory.getSettings().isCommentsEnabled() ) {
-			select.setComment( lockMode + " lock " + lockable.getEntityName() );
-		}
-		return select.toStatementString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,143 @@
+/*
+ * 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.dialect.lock;
+
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.LockMode;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * A locking strategy where the locks are obtained through select statements.
+ * <p/>
+ * For non-read locks, this is achieved through the Dialect's specific
+ * SELECT ... FOR UPDATE syntax.
+ *
+ * @see org.hibernate.dialect.Dialect#getForUpdateString(org.hibernate.LockMode)
+ * @see org.hibernate.dialect.Dialect#appendLockHint(org.hibernate.LockMode, String)
+ * @since 3.2
+ *
+ * @author Steve Ebersole
+ */
+public class SelectLockingStrategy implements LockingStrategy {
+
+	private final Lockable lockable;
+	private final LockMode lockMode;
+	private final String sql;
+
+	/**
+	 * Construct a locking strategy based on SQL SELECT statements.
+	 *
+	 * @param lockable The metadata for the entity to be locked.
+	 * @param lockMode Indictates the type of lock to be acquired.
+	 */
+	public SelectLockingStrategy(Lockable lockable, LockMode lockMode) {
+		this.lockable = lockable;
+		this.lockMode = lockMode;
+		this.sql = generateLockString();
+	}
+
+	/**
+	 * @see LockingStrategy#lock
+	 */
+	public void lock(
+	        Serializable id,
+	        Object version,
+	        Object object,
+	        SessionImplementor session) throws StaleObjectStateException, JDBCException {
+
+		SessionFactoryImplementor factory = session.getFactory();
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
+			try {
+				lockable.getIdentifierType().nullSafeSet( st, id, 1, session );
+				if ( lockable.isVersioned() ) {
+					lockable.getVersionType().nullSafeSet(
+							st,
+							version,
+							lockable.getIdentifierType().getColumnSpan( factory ) + 1,
+							session
+					);
+				}
+
+				ResultSet rs = st.executeQuery();
+				try {
+					if ( !rs.next() ) {
+						if ( factory.getStatistics().isStatisticsEnabled() ) {
+							factory.getStatisticsImplementor()
+									.optimisticFailure( lockable.getEntityName() );
+						}
+						throw new StaleObjectStateException( lockable.getEntityName(), id );
+					}
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
+					sql
+				);
+		}
+	}
+
+	protected LockMode getLockMode() {
+		return lockMode;
+	}
+
+	protected String generateLockString() {
+		SessionFactoryImplementor factory = lockable.getFactory();
+		SimpleSelect select = new SimpleSelect( factory.getDialect() )
+				.setLockMode( lockMode )
+				.setTableName( lockable.getRootTableName() )
+				.addColumn( lockable.getRootTableIdentifierColumnNames()[0] )
+				.addCondition( lockable.getRootTableIdentifierColumnNames(), "=?" );
+		if ( lockable.isVersioned() ) {
+			select.addCondition( lockable.getVersionColumnName(), "=?" );
+		}
+		if ( factory.getSettings().isCommentsEnabled() ) {
+			select.setComment( lockMode + " lock " + lockable.getEntityName() );
+		}
+		return select.toStatementString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,122 +0,0 @@
-package org.hibernate.dialect.lock;
-
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.LockMode;
-import org.hibernate.HibernateException;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.JDBCException;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.sql.Update;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * A locking strategy where the locks are obtained through update statements.
- * <p/>
- * This strategy is not valid for read style locks.
- *
- * @since 3.2
- *
- * @author Steve Ebersole
- */
-public class UpdateLockingStrategy implements LockingStrategy {
-	private static final Logger log = LoggerFactory.getLogger( UpdateLockingStrategy.class );
-
-	private final Lockable lockable;
-	private final LockMode lockMode;
-	private final String sql;
-
-	/**
-	 * Construct a locking strategy based on SQL UPDATE statements.
-	 *
-	 * @param lockable The metadata for the entity to be locked.
-	 * @param lockMode Indictates the type of lock to be acquired.  Note that
-	 * read-locks are not valid for this strategy.
-	 */
-	public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
-		this.lockable = lockable;
-		this.lockMode = lockMode;
-		if ( lockMode.lessThan( LockMode.UPGRADE ) ) {
-			throw new HibernateException( "[" + lockMode + "] not valid for update statement" );
-		}
-		if ( !lockable.isVersioned() ) {
-			log.warn( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
-			this.sql = null;
-		}
-		else {
-			this.sql = generateLockString();
-		}
-	}
-
-	/**
-	 * @see LockingStrategy#lock
-	 */
-	public void lock(
-			Serializable id,
-	        Object version,
-	        Object object,
-	        SessionImplementor session) throws StaleObjectStateException, JDBCException {
-		if ( !lockable.isVersioned() ) {
-			throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
-		}
-		// todo : should we additionally check the current isolation mode explicitly?
-		SessionFactoryImplementor factory = session.getFactory();
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
-			try {
-				lockable.getVersionType().nullSafeSet( st, version, 1, session );
-				int offset = 2;
-
-				lockable.getIdentifierType().nullSafeSet( st, id, offset, session );
-				offset += lockable.getIdentifierType().getColumnSpan( factory );
-
-				if ( lockable.isVersioned() ) {
-					lockable.getVersionType().nullSafeSet( st, version, offset, session );
-				}
-
-				int affected = st.executeUpdate();
-				if ( affected < 0 ) {
-					factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
-					throw new StaleObjectStateException( lockable.getEntityName(), id );
-				}
-
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
-			        sql
-			);
-		}
-	}
-
-	protected String generateLockString() {
-		SessionFactoryImplementor factory = lockable.getFactory();
-		Update update = new Update( factory.getDialect() );
-		update.setTableName( lockable.getRootTableName() );
-		update.setPrimaryKeyColumnNames( lockable.getRootTableIdentifierColumnNames() );
-		update.setVersionColumnName( lockable.getVersionColumnName() );
-		update.addColumn( lockable.getVersionColumnName() );
-		if ( factory.getSettings().isCommentsEnabled() ) {
-			update.setComment( lockMode + " lock " + lockable.getEntityName() );
-		}
-		return update.toStatementString();
-	}
-
-	protected LockMode getLockMode() {
-		return lockMode;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.dialect.lock;
+
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.LockMode;
+import org.hibernate.HibernateException;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.JDBCException;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.sql.Update;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * A locking strategy where the locks are obtained through update statements.
+ * <p/>
+ * This strategy is not valid for read style locks.
+ *
+ * @since 3.2
+ *
+ * @author Steve Ebersole
+ */
+public class UpdateLockingStrategy implements LockingStrategy {
+	private static final Logger log = LoggerFactory.getLogger( UpdateLockingStrategy.class );
+
+	private final Lockable lockable;
+	private final LockMode lockMode;
+	private final String sql;
+
+	/**
+	 * Construct a locking strategy based on SQL UPDATE statements.
+	 *
+	 * @param lockable The metadata for the entity to be locked.
+	 * @param lockMode Indictates the type of lock to be acquired.  Note that
+	 * read-locks are not valid for this strategy.
+	 */
+	public UpdateLockingStrategy(Lockable lockable, LockMode lockMode) {
+		this.lockable = lockable;
+		this.lockMode = lockMode;
+		if ( lockMode.lessThan( LockMode.UPGRADE ) ) {
+			throw new HibernateException( "[" + lockMode + "] not valid for update statement" );
+		}
+		if ( !lockable.isVersioned() ) {
+			log.warn( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
+			this.sql = null;
+		}
+		else {
+			this.sql = generateLockString();
+		}
+	}
+
+	/**
+	 * @see LockingStrategy#lock
+	 */
+	public void lock(
+			Serializable id,
+	        Object version,
+	        Object object,
+	        SessionImplementor session) throws StaleObjectStateException, JDBCException {
+		if ( !lockable.isVersioned() ) {
+			throw new HibernateException( "write locks via update not supported for non-versioned entities [" + lockable.getEntityName() + "]" );
+		}
+		// todo : should we additionally check the current isolation mode explicitly?
+		SessionFactoryImplementor factory = session.getFactory();
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
+			try {
+				lockable.getVersionType().nullSafeSet( st, version, 1, session );
+				int offset = 2;
+
+				lockable.getIdentifierType().nullSafeSet( st, id, offset, session );
+				offset += lockable.getIdentifierType().getColumnSpan( factory );
+
+				if ( lockable.isVersioned() ) {
+					lockable.getVersionType().nullSafeSet( st, version, offset, session );
+				}
+
+				int affected = st.executeUpdate();
+				if ( affected < 0 ) {
+					factory.getStatisticsImplementor().optimisticFailure( lockable.getEntityName() );
+					throw new StaleObjectStateException( lockable.getEntityName(), id );
+				}
+
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not lock: " + MessageHelper.infoString( lockable, id, session.getFactory() ),
+			        sql
+			);
+		}
+	}
+
+	protected String generateLockString() {
+		SessionFactoryImplementor factory = lockable.getFactory();
+		Update update = new Update( factory.getDialect() );
+		update.setTableName( lockable.getRootTableName() );
+		update.setPrimaryKeyColumnNames( lockable.getRootTableIdentifierColumnNames() );
+		update.setVersionColumnName( lockable.getVersionColumnName() );
+		update.addColumn( lockable.getVersionColumnName() );
+		if ( factory.getSettings().isCommentsEnabled() ) {
+			update.setComment( lockMode + " lock " + lockable.getEntityName() );
+		}
+		return update.toStatementString();
+	}
+
+	protected LockMode getLockMode() {
+		return lockMode;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/dialect/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,11 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the SQL dialect of the underlying database.
-</p>
-<p>
-	A concrete <tt>Dialect</tt> may be specifed using <tt>hibernate.dialect</tt>.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/dialect/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/dialect/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the SQL dialect of the underlying database.
+</p>
+<p>
+	A concrete <tt>Dialect</tt> may be specifed using <tt>hibernate.dialect</tt>.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ActionQueue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,619 +0,0 @@
-/*
- * Hibernate, Relational Persistence for Idiomatic Java
- *
- * Copyright (c) 2007, 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.engine;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.action.BulkOperationCleanupAction;
-import org.hibernate.action.CollectionRecreateAction;
-import org.hibernate.action.CollectionRemoveAction;
-import org.hibernate.action.CollectionUpdateAction;
-import org.hibernate.action.EntityDeleteAction;
-import org.hibernate.action.EntityIdentityInsertAction;
-import org.hibernate.action.EntityInsertAction;
-import org.hibernate.action.EntityUpdateAction;
-import org.hibernate.action.Executable;
-import org.hibernate.cache.CacheException;
-import org.hibernate.type.Type;
-
-/**
- * Responsible for maintaining the queue of actions related to events.
- * </p>
- * The ActionQueue holds the DML operations queued as part of a session's
- * transactional-write-behind semantics.  DML operations are queued here
- * until a flush forces them to be executed against the database.
- *
- * @author Steve Ebersole
- */
-public class ActionQueue {
-
-	private static final Logger log = LoggerFactory.getLogger( ActionQueue.class );
-	private static final int INIT_QUEUE_LIST_SIZE = 5;
-
-	private SessionImplementor session;
-
-	// Object insertions, updates, and deletions have list semantics because
-	// they must happen in the right order so as to respect referential
-	// integrity
-	private ArrayList insertions;
-	private ArrayList deletions;
-	private ArrayList updates;
-	// Actually the semantics of the next three are really "Bag"
-	// Note that, unlike objects, collection insertions, updates,
-	// deletions are not really remembered between flushes. We
-	// just re-use the same Lists for convenience.
-	private ArrayList collectionCreations;
-	private ArrayList collectionUpdates;
-	private ArrayList collectionRemovals;
-
-	private ArrayList executions;
-
-	/**
-	 * Constructs an action queue bound to the given session.
-	 *
-	 * @param session The session "owning" this queue.
-	 */
-	public ActionQueue(SessionImplementor session) {
-		this.session = session;
-		init();
-	}
-
-	private void init() {
-		insertions = new ArrayList( INIT_QUEUE_LIST_SIZE );
-		deletions = new ArrayList( INIT_QUEUE_LIST_SIZE );
-		updates = new ArrayList( INIT_QUEUE_LIST_SIZE );
-
-		collectionCreations = new ArrayList( INIT_QUEUE_LIST_SIZE );
-		collectionRemovals = new ArrayList( INIT_QUEUE_LIST_SIZE );
-		collectionUpdates = new ArrayList( INIT_QUEUE_LIST_SIZE );
-
-		executions = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 );
-	}
-
-	public void clear() {
-		updates.clear();
-		insertions.clear();
-		deletions.clear();
-
-		collectionCreations.clear();
-		collectionRemovals.clear();
-		collectionUpdates.clear();
-	}
-
-	public void addAction(EntityInsertAction action) {
-		insertions.add( action );
-	}
-
-	public void addAction(EntityDeleteAction action) {
-		deletions.add( action );
-	}
-
-	public void addAction(EntityUpdateAction action) {
-		updates.add( action );
-	}
-
-	public void addAction(CollectionRecreateAction action) {
-		collectionCreations.add( action );
-	}
-
-	public void addAction(CollectionRemoveAction action) {
-		collectionRemovals.add( action );
-	}
-
-	public void addAction(CollectionUpdateAction action) {
-		collectionUpdates.add( action );
-	}
-
-	public void addAction(EntityIdentityInsertAction insert) {
-		insertions.add( insert );
-	}
-
-	public void addAction(BulkOperationCleanupAction cleanupAction) {
-		// Add these directly to the executions queue
-		executions.add( cleanupAction );
-	}
-
-	/**
-	 * Perform all currently queued entity-insertion actions.
-	 *
-	 * @throws HibernateException error executing queued insertion actions.
-	 */
-	public void executeInserts() throws HibernateException {
-		executeActions( insertions );
-	}
-
-	/**
-	 * Perform all currently queued actions.
-	 *
-	 * @throws HibernateException error executing queued actions.
-	 */
-	public void executeActions() throws HibernateException {
-		executeActions( insertions );
-		executeActions( updates );
-		executeActions( collectionRemovals );
-		executeActions( collectionUpdates );
-		executeActions( collectionCreations );
-		executeActions( deletions );
-	}
-
-	/**
-	 * Prepares the internal action queues for execution.
-	 *
-	 * @throws HibernateException error preparing actions.
-	 */
-	public void prepareActions() throws HibernateException {
-		prepareActions( collectionRemovals );
-		prepareActions( collectionUpdates );
-		prepareActions( collectionCreations );
-	}
-
-	/**
-	 * Performs cleanup of any held cache softlocks.
-	 *
-	 * @param success Was the transaction successful.
-	 */
-	public void afterTransactionCompletion(boolean success) {
-		int size = executions.size();
-		final boolean invalidateQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
-		for ( int i = 0; i < size; i++ ) {
-			try {
-				Executable exec = ( Executable ) executions.get( i );
-				try {
-					exec.afterTransactionCompletion( success );
-				}
-				finally {
-					if ( invalidateQueryCache ) {
-						session.getFactory().getUpdateTimestampsCache().invalidate( exec.getPropertySpaces() );
-					}
-				}
-			}
-			catch ( CacheException ce ) {
-				log.error( "could not release a cache lock", ce );
-				// continue loop
-			}
-			catch ( Exception e ) {
-				throw new AssertionFailure( "Exception releasing cache locks", e );
-			}
-		}
-		executions.clear();
-	}
-
-	/**
-	 * Check whether the given tables/query-spaces are to be executed against
-	 * given the currently queued actions.
-	 *
-	 * @param tables The table/query-spaces to check.
-	 *
-	 * @return True if we contain pending actions against any of the given
-	 *         tables; false otherwise.
-	 */
-	public boolean areTablesToBeUpdated(Set tables) {
-		return areTablesToUpdated( updates, tables ) ||
-				areTablesToUpdated( insertions, tables ) ||
-				areTablesToUpdated( deletions, tables ) ||
-				areTablesToUpdated( collectionUpdates, tables ) ||
-				areTablesToUpdated( collectionCreations, tables ) ||
-				areTablesToUpdated( collectionRemovals, tables );
-	}
-
-	/**
-	 * Check whether any insertion or deletion actions are currently queued.
-	 *
-	 * @return True if insertions or deletions are currently queued; false otherwise.
-	 */
-	public boolean areInsertionsOrDeletionsQueued() {
-		return ( insertions.size() > 0 || deletions.size() > 0 );
-	}
-
-	private static boolean areTablesToUpdated(List executables, Set tablespaces) {
-		int size = executables.size();
-		for ( int j = 0; j < size; j++ ) {
-			Serializable[] spaces = ( ( Executable ) executables.get( j ) ).getPropertySpaces();
-			for ( int i = 0; i < spaces.length; i++ ) {
-				if ( tablespaces.contains( spaces[i] ) ) {
-					if ( log.isDebugEnabled() ) {
-						log.debug( "changes must be flushed to space: " + spaces[i] );
-					}
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private void executeActions(List list) throws HibernateException {
-		int size = list.size();
-		for ( int i = 0; i < size; i++ ) {
-			execute( ( Executable ) list.get( i ) );
-		}
-		list.clear();
-		session.getBatcher().executeBatch();
-	}
-
-	public void execute(Executable executable) {
-		final boolean lockQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
-		if ( executable.hasAfterTransactionCompletion() || lockQueryCache ) {
-			executions.add( executable );
-		}
-		if ( lockQueryCache ) {
-			session.getFactory()
-					.getUpdateTimestampsCache()
-					.preinvalidate( executable.getPropertySpaces() );
-		}
-		executable.execute();
-	}
-
-	private void prepareActions(List queue) throws HibernateException {
-		int size = queue.size();
-		for ( int i = 0; i < size; i++ ) {
-			Executable executable = ( Executable ) queue.get( i );
-			executable.beforeExecutions();
-		}
-	}
-
-	/**
-	 * Returns a string representation of the object.
-	 *
-	 * @return a string representation of the object.
-	 */
-	public String toString() {
-		return new StringBuffer()
-				.append( "ActionQueue[insertions=" ).append( insertions )
-				.append( " updates=" ).append( updates )
-				.append( " deletions=" ).append( deletions )
-				.append( " collectionCreations=" ).append( collectionCreations )
-				.append( " collectionRemovals=" ).append( collectionRemovals )
-				.append( " collectionUpdates=" ).append( collectionUpdates )
-				.append( "]" )
-				.toString();
-	}
-
-	public int numberOfCollectionRemovals() {
-		return collectionRemovals.size();
-	}
-
-	public int numberOfCollectionUpdates() {
-		return collectionUpdates.size();
-	}
-
-	public int numberOfCollectionCreations() {
-		return collectionCreations.size();
-	}
-
-	public int numberOfDeletions() {
-		return deletions.size();
-	}
-
-	public int numberOfUpdates() {
-		return updates.size();
-	}
-
-	public int numberOfInsertions() {
-		return insertions.size();
-	}
-
-	public void sortCollectionActions() {
-		if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
-			//sort the updates by fk
-			java.util.Collections.sort( collectionCreations );
-			java.util.Collections.sort( collectionUpdates );
-			java.util.Collections.sort( collectionRemovals );
-		}
-	}
-
-	public void sortActions() {
-		if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
-			//sort the updates by pk
-			java.util.Collections.sort( updates );
-		}
-		if ( session.getFactory().getSettings().isOrderInsertsEnabled() ) {
-			sortInsertActions();
-		}
-	}
-
-	/**
-	 * Order the {@link #insertions} queue such that we group inserts
-	 * against the same entity together (without violating constraints).  The
-	 * original order is generated by cascade order, which in turn is based on
-	 * the directionality of foreign-keys.  So even though we will be changing
-	 * the ordering here, we need to make absolutely certain that we do not
-	 * circumvent this FK ordering to the extent of causing constraint
-	 * violations
-	 */
-	private void sortInsertActions() {
-		new InsertActionSorter().sort();
-	}
-
-	public ArrayList cloneDeletions() {
-		return ( ArrayList ) deletions.clone();
-	}
-
-	public void clearFromFlushNeededCheck(int previousCollectionRemovalSize) {
-		collectionCreations.clear();
-		collectionUpdates.clear();
-		updates.clear();
-		// collection deletions are a special case since update() can add
-		// deletions of collections not loaded by the session.
-		for ( int i = collectionRemovals.size() - 1; i >= previousCollectionRemovalSize; i-- ) {
-			collectionRemovals.remove( i );
-		}
-	}
-
-	public boolean hasAfterTransactionActions() {
-		return executions.size() > 0;
-	}
-
-	public boolean hasAnyQueuedActions() {
-		return updates.size() > 0 ||
-				insertions.size() > 0 ||
-				deletions.size() > 0 ||
-				collectionUpdates.size() > 0 ||
-				collectionRemovals.size() > 0 ||
-				collectionCreations.size() > 0;
-	}
-
-	/**
-	 * Used by the owning session to explicitly control serialization of the
-	 * action queue
-	 *
-	 * @param oos The stream to which the action queue should get written
-	 *
-	 * @throws IOException
-	 */
-	public void serialize(ObjectOutputStream oos) throws IOException {
-		log.trace( "serializing action-queue" );
-
-		int queueSize = insertions.size();
-		log.trace( "starting serialization of [" + queueSize + "] insertions entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( insertions.get( i ) );
-		}
-
-		queueSize = deletions.size();
-		log.trace( "starting serialization of [" + queueSize + "] deletions entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( deletions.get( i ) );
-		}
-
-		queueSize = updates.size();
-		log.trace( "starting serialization of [" + queueSize + "] updates entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( updates.get( i ) );
-		}
-
-		queueSize = collectionUpdates.size();
-		log.trace( "starting serialization of [" + queueSize + "] collectionUpdates entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( collectionUpdates.get( i ) );
-		}
-
-		queueSize = collectionRemovals.size();
-		log.trace( "starting serialization of [" + queueSize + "] collectionRemovals entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( collectionRemovals.get( i ) );
-		}
-
-		queueSize = collectionCreations.size();
-		log.trace( "starting serialization of [" + queueSize + "] collectionCreations entries" );
-		oos.writeInt( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			oos.writeObject( collectionCreations.get( i ) );
-		}
-	}
-
-	/**
-	 * Used by the owning session to explicitly control deserialization of the
-	 * action queue
-	 *
-	 * @param ois The stream from which to read the action queue
-	 *
-	 * @throws IOException
-	 */
-	public static ActionQueue deserialize(
-			ObjectInputStream ois,
-			SessionImplementor session) throws IOException, ClassNotFoundException {
-		log.trace( "deserializing action-queue" );
-		ActionQueue rtn = new ActionQueue( session );
-
-		int queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] insertions entries" );
-		rtn.insertions = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.insertions.add( ois.readObject() );
-		}
-
-		queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] deletions entries" );
-		rtn.deletions = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.deletions.add( ois.readObject() );
-		}
-
-		queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] updates entries" );
-		rtn.updates = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.updates.add( ois.readObject() );
-		}
-
-		queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] collectionUpdates entries" );
-		rtn.collectionUpdates = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.collectionUpdates.add( ois.readObject() );
-		}
-
-		queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] collectionRemovals entries" );
-		rtn.collectionRemovals = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.collectionRemovals.add( ois.readObject() );
-		}
-
-		queueSize = ois.readInt();
-		log.trace( "starting deserialization of [" + queueSize + "] collectionCreations entries" );
-		rtn.collectionCreations = new ArrayList( queueSize );
-		for ( int i = 0; i < queueSize; i++ ) {
-			rtn.collectionCreations.add( ois.readObject() );
-		}
-		return rtn;
-	}
-
-
-	/**
-	 * Sorts the insert actions using more hashes.
-	 *
-	 * @author Jay Erb
-	 */
-	private class InsertActionSorter {
-
-		// the mapping of entity names to their latest batch numbers.
-		private HashMap latestBatches = new HashMap();
-		private HashMap entityBatchNumber;
-
-		// the map of batch numbers to EntityInsertAction lists
-		private HashMap actionBatches = new HashMap();
-
-		public InsertActionSorter() {
-			//optimize the hash size to eliminate a rehash.
-			entityBatchNumber = new HashMap( insertions.size() + 1, 1.0f );
-		}
-
-		/**
-		 * Sort the insert actions.
-		 */
-		public void sort() {
-
-			// the list of entity names that indicate the batch number
-			for ( Iterator actionItr = insertions.iterator(); actionItr.hasNext(); ) {
-				EntityInsertAction action = ( EntityInsertAction ) actionItr.next();
-				// remove the current element from insertions. It will be added back later.
-				String entityName = action.getEntityName();
-
-				// the entity associated with the current action.
-				Object currentEntity = action.getInstance();
-
-				Integer batchNumber;
-				if ( latestBatches.containsKey( entityName ) ) {
-					// There is already an existing batch for this type of entity.
-					// Check to see if the latest batch is acceptable.
-					batchNumber = findBatchNumber( action, entityName );
-				}
-				else {
-					// add an entry for this type of entity.
-					// we can be assured that all referenced entities have already
-					// been processed,
-					// so specify that this entity is with the latest batch.
-					// doing the batch number before adding the name to the list is
-					// a faster way to get an accurate number.
-
-					batchNumber = new Integer( actionBatches.size() );
-					latestBatches.put( entityName, batchNumber );
-				}
-				entityBatchNumber.put( currentEntity, batchNumber );
-				addToBatch( batchNumber, action );
-			}
-			insertions.clear();
-
-			// now rebuild the insertions list. There is a batch for each entry in the name list.
-			for ( int i = 0; i < actionBatches.size(); i++ ) {
-				List batch = ( List ) actionBatches.get( new Integer( i ) );
-				for ( Iterator batchItr = batch.iterator(); batchItr.hasNext(); ) {
-					EntityInsertAction action = ( EntityInsertAction ) batchItr.next();
-					insertions.add( action );
-				}
-			}
-		}
-
-		/**
-		 * Finds an acceptable batch for this entity to be a member.
-		 */
-		private Integer findBatchNumber(EntityInsertAction action,
-										String entityName) {
-			// loop through all the associated entities and make sure they have been
-			// processed before the latest
-			// batch associated with this entity type.
-
-			// the current batch number is the latest batch for this entity type.
-			Integer latestBatchNumberForType = ( Integer ) latestBatches.get( entityName );
-
-			// loop through all the associations of the current entity and make sure that they are processed
-			// before the current batch number
-			Object[] propertyValues = action.getState();
-			Type[] propertyTypes = action.getPersister().getClassMetadata()
-					.getPropertyTypes();
-
-			for ( int i = 0; i < propertyValues.length; i++ ) {
-				Object value = propertyValues[i];
-				Type type = propertyTypes[i];
-				if ( type.isEntityType() && value != null ) {
-					// find the batch number associated with the current association, if any.
-					Integer associationBatchNumber = ( Integer ) entityBatchNumber.get( value );
-					if ( associationBatchNumber != null && associationBatchNumber.compareTo( latestBatchNumberForType ) > 0 ) {
-						// create a new batch for this type. The batch number is the number of current batches.
-						latestBatchNumberForType = new Integer( actionBatches.size() );
-						latestBatches.put( entityName, latestBatchNumberForType );
-						// since this entity will now be processed in the latest possible batch,
-						// we can be assured that it will come after all other associations,
-						// there's not need to continue checking.
-						break;
-					}
-				}
-			}
-			return latestBatchNumberForType;
-		}
-
-		private void addToBatch(Integer batchNumber, EntityInsertAction action) {
-			List actions = ( List ) actionBatches.get( batchNumber );
-
-			if ( actions == null ) {
-				actions = new LinkedList();
-				actionBatches.put( batchNumber, actions );
-			}
-			actions.add( action );
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ActionQueue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ActionQueue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,619 @@
+/*
+ * 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.engine;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.action.BulkOperationCleanupAction;
+import org.hibernate.action.CollectionRecreateAction;
+import org.hibernate.action.CollectionRemoveAction;
+import org.hibernate.action.CollectionUpdateAction;
+import org.hibernate.action.EntityDeleteAction;
+import org.hibernate.action.EntityIdentityInsertAction;
+import org.hibernate.action.EntityInsertAction;
+import org.hibernate.action.EntityUpdateAction;
+import org.hibernate.action.Executable;
+import org.hibernate.cache.CacheException;
+import org.hibernate.type.Type;
+
+/**
+ * Responsible for maintaining the queue of actions related to events.
+ * </p>
+ * The ActionQueue holds the DML operations queued as part of a session's
+ * transactional-write-behind semantics.  DML operations are queued here
+ * until a flush forces them to be executed against the database.
+ *
+ * @author Steve Ebersole
+ */
+public class ActionQueue {
+
+	private static final Logger log = LoggerFactory.getLogger( ActionQueue.class );
+	private static final int INIT_QUEUE_LIST_SIZE = 5;
+
+	private SessionImplementor session;
+
+	// Object insertions, updates, and deletions have list semantics because
+	// they must happen in the right order so as to respect referential
+	// integrity
+	private ArrayList insertions;
+	private ArrayList deletions;
+	private ArrayList updates;
+	// Actually the semantics of the next three are really "Bag"
+	// Note that, unlike objects, collection insertions, updates,
+	// deletions are not really remembered between flushes. We
+	// just re-use the same Lists for convenience.
+	private ArrayList collectionCreations;
+	private ArrayList collectionUpdates;
+	private ArrayList collectionRemovals;
+
+	private ArrayList executions;
+
+	/**
+	 * Constructs an action queue bound to the given session.
+	 *
+	 * @param session The session "owning" this queue.
+	 */
+	public ActionQueue(SessionImplementor session) {
+		this.session = session;
+		init();
+	}
+
+	private void init() {
+		insertions = new ArrayList( INIT_QUEUE_LIST_SIZE );
+		deletions = new ArrayList( INIT_QUEUE_LIST_SIZE );
+		updates = new ArrayList( INIT_QUEUE_LIST_SIZE );
+
+		collectionCreations = new ArrayList( INIT_QUEUE_LIST_SIZE );
+		collectionRemovals = new ArrayList( INIT_QUEUE_LIST_SIZE );
+		collectionUpdates = new ArrayList( INIT_QUEUE_LIST_SIZE );
+
+		executions = new ArrayList( INIT_QUEUE_LIST_SIZE * 3 );
+	}
+
+	public void clear() {
+		updates.clear();
+		insertions.clear();
+		deletions.clear();
+
+		collectionCreations.clear();
+		collectionRemovals.clear();
+		collectionUpdates.clear();
+	}
+
+	public void addAction(EntityInsertAction action) {
+		insertions.add( action );
+	}
+
+	public void addAction(EntityDeleteAction action) {
+		deletions.add( action );
+	}
+
+	public void addAction(EntityUpdateAction action) {
+		updates.add( action );
+	}
+
+	public void addAction(CollectionRecreateAction action) {
+		collectionCreations.add( action );
+	}
+
+	public void addAction(CollectionRemoveAction action) {
+		collectionRemovals.add( action );
+	}
+
+	public void addAction(CollectionUpdateAction action) {
+		collectionUpdates.add( action );
+	}
+
+	public void addAction(EntityIdentityInsertAction insert) {
+		insertions.add( insert );
+	}
+
+	public void addAction(BulkOperationCleanupAction cleanupAction) {
+		// Add these directly to the executions queue
+		executions.add( cleanupAction );
+	}
+
+	/**
+	 * Perform all currently queued entity-insertion actions.
+	 *
+	 * @throws HibernateException error executing queued insertion actions.
+	 */
+	public void executeInserts() throws HibernateException {
+		executeActions( insertions );
+	}
+
+	/**
+	 * Perform all currently queued actions.
+	 *
+	 * @throws HibernateException error executing queued actions.
+	 */
+	public void executeActions() throws HibernateException {
+		executeActions( insertions );
+		executeActions( updates );
+		executeActions( collectionRemovals );
+		executeActions( collectionUpdates );
+		executeActions( collectionCreations );
+		executeActions( deletions );
+	}
+
+	/**
+	 * Prepares the internal action queues for execution.
+	 *
+	 * @throws HibernateException error preparing actions.
+	 */
+	public void prepareActions() throws HibernateException {
+		prepareActions( collectionRemovals );
+		prepareActions( collectionUpdates );
+		prepareActions( collectionCreations );
+	}
+
+	/**
+	 * Performs cleanup of any held cache softlocks.
+	 *
+	 * @param success Was the transaction successful.
+	 */
+	public void afterTransactionCompletion(boolean success) {
+		int size = executions.size();
+		final boolean invalidateQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
+		for ( int i = 0; i < size; i++ ) {
+			try {
+				Executable exec = ( Executable ) executions.get( i );
+				try {
+					exec.afterTransactionCompletion( success );
+				}
+				finally {
+					if ( invalidateQueryCache ) {
+						session.getFactory().getUpdateTimestampsCache().invalidate( exec.getPropertySpaces() );
+					}
+				}
+			}
+			catch ( CacheException ce ) {
+				log.error( "could not release a cache lock", ce );
+				// continue loop
+			}
+			catch ( Exception e ) {
+				throw new AssertionFailure( "Exception releasing cache locks", e );
+			}
+		}
+		executions.clear();
+	}
+
+	/**
+	 * Check whether the given tables/query-spaces are to be executed against
+	 * given the currently queued actions.
+	 *
+	 * @param tables The table/query-spaces to check.
+	 *
+	 * @return True if we contain pending actions against any of the given
+	 *         tables; false otherwise.
+	 */
+	public boolean areTablesToBeUpdated(Set tables) {
+		return areTablesToUpdated( updates, tables ) ||
+				areTablesToUpdated( insertions, tables ) ||
+				areTablesToUpdated( deletions, tables ) ||
+				areTablesToUpdated( collectionUpdates, tables ) ||
+				areTablesToUpdated( collectionCreations, tables ) ||
+				areTablesToUpdated( collectionRemovals, tables );
+	}
+
+	/**
+	 * Check whether any insertion or deletion actions are currently queued.
+	 *
+	 * @return True if insertions or deletions are currently queued; false otherwise.
+	 */
+	public boolean areInsertionsOrDeletionsQueued() {
+		return ( insertions.size() > 0 || deletions.size() > 0 );
+	}
+
+	private static boolean areTablesToUpdated(List executables, Set tablespaces) {
+		int size = executables.size();
+		for ( int j = 0; j < size; j++ ) {
+			Serializable[] spaces = ( ( Executable ) executables.get( j ) ).getPropertySpaces();
+			for ( int i = 0; i < spaces.length; i++ ) {
+				if ( tablespaces.contains( spaces[i] ) ) {
+					if ( log.isDebugEnabled() ) {
+						log.debug( "changes must be flushed to space: " + spaces[i] );
+					}
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private void executeActions(List list) throws HibernateException {
+		int size = list.size();
+		for ( int i = 0; i < size; i++ ) {
+			execute( ( Executable ) list.get( i ) );
+		}
+		list.clear();
+		session.getBatcher().executeBatch();
+	}
+
+	public void execute(Executable executable) {
+		final boolean lockQueryCache = session.getFactory().getSettings().isQueryCacheEnabled();
+		if ( executable.hasAfterTransactionCompletion() || lockQueryCache ) {
+			executions.add( executable );
+		}
+		if ( lockQueryCache ) {
+			session.getFactory()
+					.getUpdateTimestampsCache()
+					.preinvalidate( executable.getPropertySpaces() );
+		}
+		executable.execute();
+	}
+
+	private void prepareActions(List queue) throws HibernateException {
+		int size = queue.size();
+		for ( int i = 0; i < size; i++ ) {
+			Executable executable = ( Executable ) queue.get( i );
+			executable.beforeExecutions();
+		}
+	}
+
+	/**
+	 * Returns a string representation of the object.
+	 *
+	 * @return a string representation of the object.
+	 */
+	public String toString() {
+		return new StringBuffer()
+				.append( "ActionQueue[insertions=" ).append( insertions )
+				.append( " updates=" ).append( updates )
+				.append( " deletions=" ).append( deletions )
+				.append( " collectionCreations=" ).append( collectionCreations )
+				.append( " collectionRemovals=" ).append( collectionRemovals )
+				.append( " collectionUpdates=" ).append( collectionUpdates )
+				.append( "]" )
+				.toString();
+	}
+
+	public int numberOfCollectionRemovals() {
+		return collectionRemovals.size();
+	}
+
+	public int numberOfCollectionUpdates() {
+		return collectionUpdates.size();
+	}
+
+	public int numberOfCollectionCreations() {
+		return collectionCreations.size();
+	}
+
+	public int numberOfDeletions() {
+		return deletions.size();
+	}
+
+	public int numberOfUpdates() {
+		return updates.size();
+	}
+
+	public int numberOfInsertions() {
+		return insertions.size();
+	}
+
+	public void sortCollectionActions() {
+		if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
+			//sort the updates by fk
+			java.util.Collections.sort( collectionCreations );
+			java.util.Collections.sort( collectionUpdates );
+			java.util.Collections.sort( collectionRemovals );
+		}
+	}
+
+	public void sortActions() {
+		if ( session.getFactory().getSettings().isOrderUpdatesEnabled() ) {
+			//sort the updates by pk
+			java.util.Collections.sort( updates );
+		}
+		if ( session.getFactory().getSettings().isOrderInsertsEnabled() ) {
+			sortInsertActions();
+		}
+	}
+
+	/**
+	 * Order the {@link #insertions} queue such that we group inserts
+	 * against the same entity together (without violating constraints).  The
+	 * original order is generated by cascade order, which in turn is based on
+	 * the directionality of foreign-keys.  So even though we will be changing
+	 * the ordering here, we need to make absolutely certain that we do not
+	 * circumvent this FK ordering to the extent of causing constraint
+	 * violations
+	 */
+	private void sortInsertActions() {
+		new InsertActionSorter().sort();
+	}
+
+	public ArrayList cloneDeletions() {
+		return ( ArrayList ) deletions.clone();
+	}
+
+	public void clearFromFlushNeededCheck(int previousCollectionRemovalSize) {
+		collectionCreations.clear();
+		collectionUpdates.clear();
+		updates.clear();
+		// collection deletions are a special case since update() can add
+		// deletions of collections not loaded by the session.
+		for ( int i = collectionRemovals.size() - 1; i >= previousCollectionRemovalSize; i-- ) {
+			collectionRemovals.remove( i );
+		}
+	}
+
+	public boolean hasAfterTransactionActions() {
+		return executions.size() > 0;
+	}
+
+	public boolean hasAnyQueuedActions() {
+		return updates.size() > 0 ||
+				insertions.size() > 0 ||
+				deletions.size() > 0 ||
+				collectionUpdates.size() > 0 ||
+				collectionRemovals.size() > 0 ||
+				collectionCreations.size() > 0;
+	}
+
+	/**
+	 * Used by the owning session to explicitly control serialization of the
+	 * action queue
+	 *
+	 * @param oos The stream to which the action queue should get written
+	 *
+	 * @throws IOException
+	 */
+	public void serialize(ObjectOutputStream oos) throws IOException {
+		log.trace( "serializing action-queue" );
+
+		int queueSize = insertions.size();
+		log.trace( "starting serialization of [" + queueSize + "] insertions entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( insertions.get( i ) );
+		}
+
+		queueSize = deletions.size();
+		log.trace( "starting serialization of [" + queueSize + "] deletions entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( deletions.get( i ) );
+		}
+
+		queueSize = updates.size();
+		log.trace( "starting serialization of [" + queueSize + "] updates entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( updates.get( i ) );
+		}
+
+		queueSize = collectionUpdates.size();
+		log.trace( "starting serialization of [" + queueSize + "] collectionUpdates entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( collectionUpdates.get( i ) );
+		}
+
+		queueSize = collectionRemovals.size();
+		log.trace( "starting serialization of [" + queueSize + "] collectionRemovals entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( collectionRemovals.get( i ) );
+		}
+
+		queueSize = collectionCreations.size();
+		log.trace( "starting serialization of [" + queueSize + "] collectionCreations entries" );
+		oos.writeInt( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			oos.writeObject( collectionCreations.get( i ) );
+		}
+	}
+
+	/**
+	 * Used by the owning session to explicitly control deserialization of the
+	 * action queue
+	 *
+	 * @param ois The stream from which to read the action queue
+	 *
+	 * @throws IOException
+	 */
+	public static ActionQueue deserialize(
+			ObjectInputStream ois,
+			SessionImplementor session) throws IOException, ClassNotFoundException {
+		log.trace( "deserializing action-queue" );
+		ActionQueue rtn = new ActionQueue( session );
+
+		int queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] insertions entries" );
+		rtn.insertions = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.insertions.add( ois.readObject() );
+		}
+
+		queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] deletions entries" );
+		rtn.deletions = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.deletions.add( ois.readObject() );
+		}
+
+		queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] updates entries" );
+		rtn.updates = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.updates.add( ois.readObject() );
+		}
+
+		queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] collectionUpdates entries" );
+		rtn.collectionUpdates = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.collectionUpdates.add( ois.readObject() );
+		}
+
+		queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] collectionRemovals entries" );
+		rtn.collectionRemovals = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.collectionRemovals.add( ois.readObject() );
+		}
+
+		queueSize = ois.readInt();
+		log.trace( "starting deserialization of [" + queueSize + "] collectionCreations entries" );
+		rtn.collectionCreations = new ArrayList( queueSize );
+		for ( int i = 0; i < queueSize; i++ ) {
+			rtn.collectionCreations.add( ois.readObject() );
+		}
+		return rtn;
+	}
+
+
+	/**
+	 * Sorts the insert actions using more hashes.
+	 *
+	 * @author Jay Erb
+	 */
+	private class InsertActionSorter {
+
+		// the mapping of entity names to their latest batch numbers.
+		private HashMap latestBatches = new HashMap();
+		private HashMap entityBatchNumber;
+
+		// the map of batch numbers to EntityInsertAction lists
+		private HashMap actionBatches = new HashMap();
+
+		public InsertActionSorter() {
+			//optimize the hash size to eliminate a rehash.
+			entityBatchNumber = new HashMap( insertions.size() + 1, 1.0f );
+		}
+
+		/**
+		 * Sort the insert actions.
+		 */
+		public void sort() {
+
+			// the list of entity names that indicate the batch number
+			for ( Iterator actionItr = insertions.iterator(); actionItr.hasNext(); ) {
+				EntityInsertAction action = ( EntityInsertAction ) actionItr.next();
+				// remove the current element from insertions. It will be added back later.
+				String entityName = action.getEntityName();
+
+				// the entity associated with the current action.
+				Object currentEntity = action.getInstance();
+
+				Integer batchNumber;
+				if ( latestBatches.containsKey( entityName ) ) {
+					// There is already an existing batch for this type of entity.
+					// Check to see if the latest batch is acceptable.
+					batchNumber = findBatchNumber( action, entityName );
+				}
+				else {
+					// add an entry for this type of entity.
+					// we can be assured that all referenced entities have already
+					// been processed,
+					// so specify that this entity is with the latest batch.
+					// doing the batch number before adding the name to the list is
+					// a faster way to get an accurate number.
+
+					batchNumber = new Integer( actionBatches.size() );
+					latestBatches.put( entityName, batchNumber );
+				}
+				entityBatchNumber.put( currentEntity, batchNumber );
+				addToBatch( batchNumber, action );
+			}
+			insertions.clear();
+
+			// now rebuild the insertions list. There is a batch for each entry in the name list.
+			for ( int i = 0; i < actionBatches.size(); i++ ) {
+				List batch = ( List ) actionBatches.get( new Integer( i ) );
+				for ( Iterator batchItr = batch.iterator(); batchItr.hasNext(); ) {
+					EntityInsertAction action = ( EntityInsertAction ) batchItr.next();
+					insertions.add( action );
+				}
+			}
+		}
+
+		/**
+		 * Finds an acceptable batch for this entity to be a member.
+		 */
+		private Integer findBatchNumber(EntityInsertAction action,
+										String entityName) {
+			// loop through all the associated entities and make sure they have been
+			// processed before the latest
+			// batch associated with this entity type.
+
+			// the current batch number is the latest batch for this entity type.
+			Integer latestBatchNumberForType = ( Integer ) latestBatches.get( entityName );
+
+			// loop through all the associations of the current entity and make sure that they are processed
+			// before the current batch number
+			Object[] propertyValues = action.getState();
+			Type[] propertyTypes = action.getPersister().getClassMetadata()
+					.getPropertyTypes();
+
+			for ( int i = 0; i < propertyValues.length; i++ ) {
+				Object value = propertyValues[i];
+				Type type = propertyTypes[i];
+				if ( type.isEntityType() && value != null ) {
+					// find the batch number associated with the current association, if any.
+					Integer associationBatchNumber = ( Integer ) entityBatchNumber.get( value );
+					if ( associationBatchNumber != null && associationBatchNumber.compareTo( latestBatchNumberForType ) > 0 ) {
+						// create a new batch for this type. The batch number is the number of current batches.
+						latestBatchNumberForType = new Integer( actionBatches.size() );
+						latestBatches.put( entityName, latestBatchNumberForType );
+						// since this entity will now be processed in the latest possible batch,
+						// we can be assured that it will come after all other associations,
+						// there's not need to continue checking.
+						break;
+					}
+				}
+			}
+			return latestBatchNumberForType;
+		}
+
+		private void addToBatch(Integer batchNumber, EntityInsertAction action) {
+			List actions = ( List ) actionBatches.get( batchNumber );
+
+			if ( actions == null ) {
+				actions = new LinkedList();
+				actionBatches.put( batchNumber, actions );
+			}
+			actions.add( action );
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/AssociationKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-//$Id: AssociationKey.java 7458 2005-07-12 20:12:57Z oneovthafew $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-
-/**
- * Identifies a named association belonging to a particular
- * entity instance. Used to record the fact that an association
- * is null during loading.
- * 
- * @author Gavin King
- */
-final class AssociationKey implements Serializable {
-	private EntityKey ownerKey;
-	private String propertyName;
-	
-	public AssociationKey(EntityKey ownerKey, String propertyName) {
-		this.ownerKey = ownerKey;
-		this.propertyName = propertyName;
-	}
-	
-	public boolean equals(Object that) {
-		AssociationKey key = (AssociationKey) that;
-		return key.propertyName.equals(propertyName) && 
-			key.ownerKey.equals(ownerKey);
-	}
-	
-	public int hashCode() {
-		return ownerKey.hashCode() + propertyName.hashCode();
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/AssociationKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/AssociationKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+
+/**
+ * Identifies a named association belonging to a particular
+ * entity instance. Used to record the fact that an association
+ * is null during loading.
+ * 
+ * @author Gavin King
+ */
+final class AssociationKey implements Serializable {
+	private EntityKey ownerKey;
+	private String propertyName;
+	
+	public AssociationKey(EntityKey ownerKey, String propertyName) {
+		this.ownerKey = ownerKey;
+		this.propertyName = propertyName;
+	}
+	
+	public boolean equals(Object that) {
+		AssociationKey key = (AssociationKey) that;
+		return key.propertyName.equals(propertyName) && 
+			key.ownerKey.equals(ownerKey);
+	}
+	
+	public int hashCode() {
+		return ownerKey.hashCode() + propertyName.hashCode();
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,276 +0,0 @@
-//$Id: BatchFetchQueue.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.util.MarkerObject;
-
-/**
- * Tracks entity and collection keys that are available for batch
- * fetching, and the queries which were used to load entities, which
- * can be re-used as a subquery for loading owned collections.
- *
- * @author Gavin King
- */
-public class BatchFetchQueue {
-
-	public static final Object MARKER = new MarkerObject( "MARKER" );
-
-	/**
-	 * Defines a sequence of {@link EntityKey} elements that are currently
-	 * elegible for batch-fetching.
-	 * <p/>
-	 * Even though this is a map, we only use the keys.  A map was chosen in
-	 * order to utilize a {@link LinkedHashMap} to maintain sequencing
-	 * as well as uniqueness.
-	 * <p/>
-	 * TODO : this would be better as a SequencedReferenceSet, but no such beast exists!
-	 */
-	private final Map batchLoadableEntityKeys = new LinkedHashMap(8);
-
-	/**
-	 * A map of {@link SubselectFetch subselect-fetch descriptors} keyed by the
-	 * {@link EntityKey) against which the descriptor is registered.
-	 */
-	private final Map subselectsByEntityKey = new HashMap(8);
-
-	/**
-	 * The owning persistence context.
-	 */
-	private final PersistenceContext context;
-
-	/**
-	 * Constructs a queue for the given context.
-	 *
-	 * @param context The owning context.
-	 */
-	public BatchFetchQueue(PersistenceContext context) {
-		this.context = context;
-	}
-
-	/**
-	 * Clears all entries from this fetch queue.
-	 */
-	public void clear() {
-		batchLoadableEntityKeys.clear();
-		subselectsByEntityKey.clear();
-	}
-
-	/**
-	 * Retrieve the fetch descriptor associated with the given entity key.
-	 *
-	 * @param key The entity key for which to locate any defined subselect fetch.
-	 * @return The fetch descriptor; may return null if no subselect fetch queued for
-	 * this entity key.
-	 */
-	public SubselectFetch getSubselect(EntityKey key) {
-		return (SubselectFetch) subselectsByEntityKey.get(key);
-	}
-
-	/**
-	 * Adds a subselect fetch decriptor for the given entity key.
-	 *
-	 * @param key The entity for which to register the subselect fetch.
-	 * @param subquery The fetch descriptor.
-	 */
-	public void addSubselect(EntityKey key, SubselectFetch subquery) {
-		subselectsByEntityKey.put(key, subquery);
-	}
-
-	/**
-	 * After evicting or deleting an entity, we don't need to
-	 * know the query that was used to load it anymore (don't
-	 * call this after loading the entity, since we might still
-	 * need to load its collections)
-	 */
-	public void removeSubselect(EntityKey key) {
-		subselectsByEntityKey.remove(key);
-	}
-
-	/**
-	 * Clears all pending subselect fetches from the queue.
-	 * <p/>
-	 * Called after flushing.
-	 */
-	public void clearSubselects() {
-		subselectsByEntityKey.clear();
-	}
-
-	/**
-	 * If an EntityKey represents a batch loadable entity, add
-	 * it to the queue.
-	 * <p/>
-	 * Note that the contract here is such that any key passed in should
-	 * previously have been been checked for existence within the
-	 * {@link PersistenceContext}; failure to do so may cause the
-	 * referenced entity to be included in a batch even though it is
-	 * already associated with the {@link PersistenceContext}.
-	 */
-	public void addBatchLoadableEntityKey(EntityKey key) {
-		if ( key.isBatchLoadable() ) {
-			batchLoadableEntityKeys.put( key, MARKER );
-		}
-	}
-
-	/**
-	 * After evicting or deleting or loading an entity, we don't
-	 * need to batch fetch it anymore, remove it from the queue
-	 * if necessary
-	 */
-	public void removeBatchLoadableEntityKey(EntityKey key) {
-		if ( key.isBatchLoadable() ) batchLoadableEntityKeys.remove(key);
-	}
-
-	/**
-	 * Get a batch of uninitialized collection keys for a given role
-	 *
-	 * @param collectionPersister The persister for the collection role.
-	 * @param id A key that must be included in the batch fetch
-	 * @param batchSize the maximum number of keys to return
-	 * @return an array of collection keys, of length batchSize (padded with nulls)
-	 */
-	public Serializable[] getCollectionBatch(
-			final CollectionPersister collectionPersister,
-			final Serializable id,
-			final int batchSize,
-			final EntityMode entityMode) {
-		Serializable[] keys = new Serializable[batchSize];
-		keys[0] = id;
-		int i = 1;
-		//int count = 0;
-		int end = -1;
-		boolean checkForEnd = false;
-		// this only works because collection entries are kept in a sequenced
-		// map by persistence context (maybe we should do like entities and
-		// keep a separate sequences set...)
-		Iterator iter = context.getCollectionEntries().entrySet().iterator(); //TODO: calling entrySet on an IdentityMap is SLOW!!
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-
-			CollectionEntry ce = (CollectionEntry) me.getValue();
-			PersistentCollection collection = (PersistentCollection) me.getKey();
-			if ( !collection.wasInitialized() && ce.getLoadedPersister() == collectionPersister ) {
-
-				if ( checkForEnd && i == end ) {
-					return keys; //the first key found after the given key
-				}
-
-				//if ( end == -1 && count > batchSize*10 ) return keys; //try out ten batches, max
-
-				final boolean isEqual = collectionPersister.getKeyType().isEqual(
-						id,
-						ce.getLoadedKey(),
-						entityMode,
-						collectionPersister.getFactory()
-				);
-
-				if ( isEqual ) {
-					end = i;
-					//checkForEnd = false;
-				}
-				else if ( !isCached( ce.getLoadedKey(), collectionPersister, entityMode ) ) {
-					keys[i++] = ce.getLoadedKey();
-					//count++;
-				}
-
-				if ( i == batchSize ) {
-					i = 1; //end of array, start filling again from start
-					if ( end != -1 ) {
-						checkForEnd = true;
-					}
-				}
-			}
-
-		}
-		return keys; //we ran out of keys to try
-	}
-
-	/**
-	 * Get a batch of unloaded identifiers for this class, using a slightly
-	 * complex algorithm that tries to grab keys registered immediately after
-	 * the given key.
-	 *
-	 * @param persister The persister for the entities being loaded.
-	 * @param id The identifier of the entity currently demanding load.
-	 * @param batchSize The maximum number of keys to return
-	 * @return an array of identifiers, of length batchSize (possibly padded with nulls)
-	 */
-	public Serializable[] getEntityBatch(
-			final EntityPersister persister,
-			final Serializable id,
-			final int batchSize,
-			final EntityMode entityMode) {
-		Serializable[] ids = new Serializable[batchSize];
-		ids[0] = id; //first element of array is reserved for the actual instance we are loading!
-		int i = 1;
-		int end = -1;
-		boolean checkForEnd = false;
-
-		Iterator iter = batchLoadableEntityKeys.keySet().iterator();
-		while ( iter.hasNext() ) {
-			EntityKey key = (EntityKey) iter.next();
-			if ( key.getEntityName().equals( persister.getEntityName() ) ) { //TODO: this needn't exclude subclasses...
-				if ( checkForEnd && i == end ) {
-					//the first id found after the given id
-					return ids;
-				}
-				if ( persister.getIdentifierType().isEqual( id, key.getIdentifier(), entityMode ) ) {
-					end = i;
-				}
-				else {
-					if ( !isCached( key, persister, entityMode ) ) {
-						ids[i++] = key.getIdentifier();
-					}
-				}
-				if ( i == batchSize ) {
-					i = 1; //end of array, start filling again from start
-					if (end!=-1) checkForEnd = true;
-				}
-			}
-		}
-		return ids; //we ran out of ids to try
-	}
-
-	private boolean isCached(
-			EntityKey entityKey,
-			EntityPersister persister,
-			EntityMode entityMode) {
-		if ( persister.hasCache() ) {
-			CacheKey key = new CacheKey(
-					entityKey.getIdentifier(),
-					persister.getIdentifierType(),
-					entityKey.getEntityName(),
-					entityMode,
-					context.getSession().getFactory()
-			);
-			return persister.getCacheAccessStrategy().get( key, context.getSession().getTimestamp() ) != null;
-		}
-		return false;
-	}
-
-	private boolean isCached(
-			Serializable collectionKey,
-			CollectionPersister persister,
-			EntityMode entityMode) {
-		if ( persister.hasCache() ) {
-			CacheKey cacheKey = new CacheKey(
-					collectionKey,
-			        persister.getKeyType(),
-			        persister.getRole(),
-			        entityMode,
-			        context.getSession().getFactory()
-			);
-			return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null;
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/BatchFetchQueue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,299 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.util.MarkerObject;
+
+/**
+ * Tracks entity and collection keys that are available for batch
+ * fetching, and the queries which were used to load entities, which
+ * can be re-used as a subquery for loading owned collections.
+ *
+ * @author Gavin King
+ */
+public class BatchFetchQueue {
+
+	public static final Object MARKER = new MarkerObject( "MARKER" );
+
+	/**
+	 * Defines a sequence of {@link EntityKey} elements that are currently
+	 * elegible for batch-fetching.
+	 * <p/>
+	 * Even though this is a map, we only use the keys.  A map was chosen in
+	 * order to utilize a {@link LinkedHashMap} to maintain sequencing
+	 * as well as uniqueness.
+	 * <p/>
+	 * TODO : this would be better as a SequencedReferenceSet, but no such beast exists!
+	 */
+	private final Map batchLoadableEntityKeys = new LinkedHashMap(8);
+
+	/**
+	 * A map of {@link SubselectFetch subselect-fetch descriptors} keyed by the
+	 * {@link EntityKey) against which the descriptor is registered.
+	 */
+	private final Map subselectsByEntityKey = new HashMap(8);
+
+	/**
+	 * The owning persistence context.
+	 */
+	private final PersistenceContext context;
+
+	/**
+	 * Constructs a queue for the given context.
+	 *
+	 * @param context The owning context.
+	 */
+	public BatchFetchQueue(PersistenceContext context) {
+		this.context = context;
+	}
+
+	/**
+	 * Clears all entries from this fetch queue.
+	 */
+	public void clear() {
+		batchLoadableEntityKeys.clear();
+		subselectsByEntityKey.clear();
+	}
+
+	/**
+	 * Retrieve the fetch descriptor associated with the given entity key.
+	 *
+	 * @param key The entity key for which to locate any defined subselect fetch.
+	 * @return The fetch descriptor; may return null if no subselect fetch queued for
+	 * this entity key.
+	 */
+	public SubselectFetch getSubselect(EntityKey key) {
+		return (SubselectFetch) subselectsByEntityKey.get(key);
+	}
+
+	/**
+	 * Adds a subselect fetch decriptor for the given entity key.
+	 *
+	 * @param key The entity for which to register the subselect fetch.
+	 * @param subquery The fetch descriptor.
+	 */
+	public void addSubselect(EntityKey key, SubselectFetch subquery) {
+		subselectsByEntityKey.put(key, subquery);
+	}
+
+	/**
+	 * After evicting or deleting an entity, we don't need to
+	 * know the query that was used to load it anymore (don't
+	 * call this after loading the entity, since we might still
+	 * need to load its collections)
+	 */
+	public void removeSubselect(EntityKey key) {
+		subselectsByEntityKey.remove(key);
+	}
+
+	/**
+	 * Clears all pending subselect fetches from the queue.
+	 * <p/>
+	 * Called after flushing.
+	 */
+	public void clearSubselects() {
+		subselectsByEntityKey.clear();
+	}
+
+	/**
+	 * If an EntityKey represents a batch loadable entity, add
+	 * it to the queue.
+	 * <p/>
+	 * Note that the contract here is such that any key passed in should
+	 * previously have been been checked for existence within the
+	 * {@link PersistenceContext}; failure to do so may cause the
+	 * referenced entity to be included in a batch even though it is
+	 * already associated with the {@link PersistenceContext}.
+	 */
+	public void addBatchLoadableEntityKey(EntityKey key) {
+		if ( key.isBatchLoadable() ) {
+			batchLoadableEntityKeys.put( key, MARKER );
+		}
+	}
+
+	/**
+	 * After evicting or deleting or loading an entity, we don't
+	 * need to batch fetch it anymore, remove it from the queue
+	 * if necessary
+	 */
+	public void removeBatchLoadableEntityKey(EntityKey key) {
+		if ( key.isBatchLoadable() ) batchLoadableEntityKeys.remove(key);
+	}
+
+	/**
+	 * Get a batch of uninitialized collection keys for a given role
+	 *
+	 * @param collectionPersister The persister for the collection role.
+	 * @param id A key that must be included in the batch fetch
+	 * @param batchSize the maximum number of keys to return
+	 * @return an array of collection keys, of length batchSize (padded with nulls)
+	 */
+	public Serializable[] getCollectionBatch(
+			final CollectionPersister collectionPersister,
+			final Serializable id,
+			final int batchSize,
+			final EntityMode entityMode) {
+		Serializable[] keys = new Serializable[batchSize];
+		keys[0] = id;
+		int i = 1;
+		//int count = 0;
+		int end = -1;
+		boolean checkForEnd = false;
+		// this only works because collection entries are kept in a sequenced
+		// map by persistence context (maybe we should do like entities and
+		// keep a separate sequences set...)
+		Iterator iter = context.getCollectionEntries().entrySet().iterator(); //TODO: calling entrySet on an IdentityMap is SLOW!!
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+
+			CollectionEntry ce = (CollectionEntry) me.getValue();
+			PersistentCollection collection = (PersistentCollection) me.getKey();
+			if ( !collection.wasInitialized() && ce.getLoadedPersister() == collectionPersister ) {
+
+				if ( checkForEnd && i == end ) {
+					return keys; //the first key found after the given key
+				}
+
+				//if ( end == -1 && count > batchSize*10 ) return keys; //try out ten batches, max
+
+				final boolean isEqual = collectionPersister.getKeyType().isEqual(
+						id,
+						ce.getLoadedKey(),
+						entityMode,
+						collectionPersister.getFactory()
+				);
+
+				if ( isEqual ) {
+					end = i;
+					//checkForEnd = false;
+				}
+				else if ( !isCached( ce.getLoadedKey(), collectionPersister, entityMode ) ) {
+					keys[i++] = ce.getLoadedKey();
+					//count++;
+				}
+
+				if ( i == batchSize ) {
+					i = 1; //end of array, start filling again from start
+					if ( end != -1 ) {
+						checkForEnd = true;
+					}
+				}
+			}
+
+		}
+		return keys; //we ran out of keys to try
+	}
+
+	/**
+	 * Get a batch of unloaded identifiers for this class, using a slightly
+	 * complex algorithm that tries to grab keys registered immediately after
+	 * the given key.
+	 *
+	 * @param persister The persister for the entities being loaded.
+	 * @param id The identifier of the entity currently demanding load.
+	 * @param batchSize The maximum number of keys to return
+	 * @return an array of identifiers, of length batchSize (possibly padded with nulls)
+	 */
+	public Serializable[] getEntityBatch(
+			final EntityPersister persister,
+			final Serializable id,
+			final int batchSize,
+			final EntityMode entityMode) {
+		Serializable[] ids = new Serializable[batchSize];
+		ids[0] = id; //first element of array is reserved for the actual instance we are loading!
+		int i = 1;
+		int end = -1;
+		boolean checkForEnd = false;
+
+		Iterator iter = batchLoadableEntityKeys.keySet().iterator();
+		while ( iter.hasNext() ) {
+			EntityKey key = (EntityKey) iter.next();
+			if ( key.getEntityName().equals( persister.getEntityName() ) ) { //TODO: this needn't exclude subclasses...
+				if ( checkForEnd && i == end ) {
+					//the first id found after the given id
+					return ids;
+				}
+				if ( persister.getIdentifierType().isEqual( id, key.getIdentifier(), entityMode ) ) {
+					end = i;
+				}
+				else {
+					if ( !isCached( key, persister, entityMode ) ) {
+						ids[i++] = key.getIdentifier();
+					}
+				}
+				if ( i == batchSize ) {
+					i = 1; //end of array, start filling again from start
+					if (end!=-1) checkForEnd = true;
+				}
+			}
+		}
+		return ids; //we ran out of ids to try
+	}
+
+	private boolean isCached(
+			EntityKey entityKey,
+			EntityPersister persister,
+			EntityMode entityMode) {
+		if ( persister.hasCache() ) {
+			CacheKey key = new CacheKey(
+					entityKey.getIdentifier(),
+					persister.getIdentifierType(),
+					entityKey.getEntityName(),
+					entityMode,
+					context.getSession().getFactory()
+			);
+			return persister.getCacheAccessStrategy().get( key, context.getSession().getTimestamp() ) != null;
+		}
+		return false;
+	}
+
+	private boolean isCached(
+			Serializable collectionKey,
+			CollectionPersister persister,
+			EntityMode entityMode) {
+		if ( persister.hasCache() ) {
+			CacheKey cacheKey = new CacheKey(
+					collectionKey,
+			        persister.getKeyType(),
+			        persister.getRole(),
+			        entityMode,
+			        context.getSession().getFactory()
+			);
+			return persister.getCacheAccessStrategy().get( cacheKey, context.getSession().getTimestamp() ) != null;
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Cascade.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,360 +0,0 @@
-//$Id: Cascade.java 10720 2006-11-06 11:35:40Z max.andersen at jboss.com $
-package org.hibernate.engine;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * Delegate responsible for, in conjunction with the various
- * {@link CascadingAction actions}, implementing cascade processing.
- *
- * @author Gavin King
- * @see CascadingAction
- */
-public final class Cascade {
-
-	/**
-	 * A cascade point that occurs just after the insertion of the parent entity and
-	 * just before deletion
-	 */
-	public static final int AFTER_INSERT_BEFORE_DELETE = 1;
-	/**
-	 * A cascade point that occurs just before the insertion of the parent entity and
-	 * just after deletion
-	 */
-	public static final int BEFORE_INSERT_AFTER_DELETE = 2;
-	/**
-	 * A cascade point that occurs just after the insertion of the parent entity and
-	 * just before deletion, inside a collection
-	 */
-	public static final int AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION = 3;
-	/**
-	 * A cascade point that occurs just after update of the parent entity
-	 */
-	public static final int AFTER_UPDATE = 0;
-	/**
-	 * A cascade point that occurs just before the session is flushed
-	 */
-	public static final int BEFORE_FLUSH = 0;
-	/**
-	 * A cascade point that occurs just after eviction of the parent entity from the
-	 * session cache
-	 */
-	public static final int AFTER_EVICT = 0;
-	/**
-	 * A cascade point that occurs just after locking a transient parent entity into the
-	 * session cache
-	 */
-	public static final int BEFORE_REFRESH = 0;
-	/**
-	 * A cascade point that occurs just after refreshing a parent entity
-	 */
-	public static final int AFTER_LOCK = 0;
-	/**
-	 * A cascade point that occurs just before merging from a transient parent entity into
-	 * the object in the session cache
-	 */
-	public static final int BEFORE_MERGE = 0;
-
-
-	private static final Logger log = LoggerFactory.getLogger( Cascade.class );
-
-
-	private int cascadeTo;
-	private EventSource eventSource;
-	private CascadingAction action;
-
-	public Cascade(final CascadingAction action, final int cascadeTo, final EventSource eventSource) {
-		this.cascadeTo = cascadeTo;
-		this.eventSource = eventSource;
-		this.action = action;
-	}
-
-	/**
-	 * Cascade an action from the parent entity instance to all its children.
-	 *
-	 * @param persister The parent's entity persister
-	 * @param parent The parent reference.
-	 * @throws HibernateException
-	 */
-	public void cascade(final EntityPersister persister, final Object parent)
-	throws HibernateException {
-		cascade( persister, parent, null );
-	}
-
-	/**
-	 * Cascade an action from the parent entity instance to all its children.  This
-	 * form is typicaly called from within cascade actions.
-	 *
-	 * @param persister The parent's entity persister
-	 * @param parent The parent reference.
-	 * @param anything Anything ;)   Typically some form of cascade-local cache
-	 * which is specific to each CascadingAction type
-	 * @throws HibernateException
-	 */
-	public void cascade(final EntityPersister persister, final Object parent, final Object anything)
-			throws HibernateException {
-
-		if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
-			if ( log.isTraceEnabled() ) {
-				log.trace( "processing cascade " + action + " for: " + persister.getEntityName() );
-			}
-
-			Type[] types = persister.getPropertyTypes();
-			CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
-			EntityMode entityMode = eventSource.getEntityMode();
-			boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent, entityMode );
-			for ( int i=0; i<types.length; i++) {
-				CascadeStyle style = cascadeStyles[i];
-				if ( hasUninitializedLazyProperties && persister.getPropertyLaziness()[i] && ! action.performOnLazyProperty() ) {
-					//do nothing to avoid a lazy property initialization
-					continue;
-				}
-
-				if ( style.doCascade( action ) ) {
-					cascadeProperty(
-					        persister.getPropertyValue( parent, i, entityMode ),
-					        types[i],
-					        style,
-					        anything,
-					        false
-					);
-				}
-				else if ( action.requiresNoCascadeChecking() ) {
-					action.noCascade(
-							eventSource,
-							persister.getPropertyValue( parent, i, entityMode ),
-							parent,
-							persister,
-							i
-					);
-				}
-			}
-
-			if ( log.isTraceEnabled() ) {
-				log.trace( "done processing cascade " + action + " for: " + persister.getEntityName() );
-			}
-		}
-	}
-
-	/**
-	 * Cascade an action to the child or children
-	 */
-	private void cascadeProperty(
-			final Object child,
-			final Type type,
-			final CascadeStyle style,
-			final Object anything,
-			final boolean isCascadeDeleteEnabled) throws HibernateException {
-
-		if (child!=null) {
-			if ( type.isAssociationType() ) {
-				AssociationType associationType = (AssociationType) type;
-				if ( cascadeAssociationNow( associationType ) ) {
-					cascadeAssociation(
-							child,
-							type,
-							style,
-							anything,
-							isCascadeDeleteEnabled
-						);
-				}
-			}
-			else if ( type.isComponentType() ) {
-				cascadeComponent( child, (AbstractComponentType) type, anything );
-			}
-		}
-	}
-
-	private boolean cascadeAssociationNow(AssociationType associationType) {
-		return associationType.getForeignKeyDirection().cascadeNow(cascadeTo) &&
-			( eventSource.getEntityMode()!=EntityMode.DOM4J || associationType.isEmbeddedInXML() );
-	}
-
-	private void cascadeComponent(
-			final Object child,
-			final AbstractComponentType componentType,
-			final Object anything) {
-		Object[] children = componentType.getPropertyValues(child, eventSource);
-		Type[] types = componentType.getSubtypes();
-		for ( int i=0; i<types.length; i++ ) {
-			CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
-			if ( componentPropertyStyle.doCascade(action) ) {
-				cascadeProperty(
-						children[i],
-						types[i],
-						componentPropertyStyle,
-						anything,
-						false
-					);
-			}
-		}
-	}
-
-	private void cascadeAssociation(
-			final Object child,
-			final Type type,
-			final CascadeStyle style,
-			final Object anything,
-			final boolean isCascadeDeleteEnabled) {
-		if ( type.isEntityType() || type.isAnyType() ) {
-			cascadeToOne( child, type, style, anything, isCascadeDeleteEnabled );
-		}
-		else if ( type.isCollectionType() ) {
-			cascadeCollection( child, style, anything, (CollectionType) type );
-		}
-	}
-
-	/**
-	 * Cascade an action to a collection
-	 */
-	private void cascadeCollection(
-			final Object child,
-			final CascadeStyle style,
-			final Object anything,
-			final CollectionType type) {
-		CollectionPersister persister = eventSource.getFactory()
-				.getCollectionPersister( type.getRole() );
-		Type elemType = persister.getElementType();
-
-		final int oldCascadeTo = cascadeTo;
-		if ( cascadeTo==AFTER_INSERT_BEFORE_DELETE) {
-			cascadeTo = AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION;
-		}
-
-		//cascade to current collection elements
-		if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) {
-			cascadeCollectionElements(
-				child,
-				type,
-				style,
-				elemType,
-				anything,
-				persister.isCascadeDeleteEnabled()
-			);
-		}
-
-		cascadeTo = oldCascadeTo;
-	}
-
-	/**
-	 * Cascade an action to a to-one association or any type
-	 */
-	private void cascadeToOne(
-			final Object child,
-			final Type type,
-			final CascadeStyle style,
-			final Object anything,
-			final boolean isCascadeDeleteEnabled) {
-		final String entityName = type.isEntityType()
-				? ( (EntityType) type ).getAssociatedEntityName()
-				: null;
-		if ( style.reallyDoCascade(action) ) { //not really necessary, but good for consistency...
-			action.cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
-		}
-	}
-
-	/**
-	 * Cascade to the collection elements
-	 */
-	private void cascadeCollectionElements(
-			final Object child,
-			final CollectionType collectionType,
-			final CascadeStyle style,
-			final Type elemType,
-			final Object anything,
-			final boolean isCascadeDeleteEnabled) throws HibernateException {
-		// we can't cascade to non-embedded elements
-		boolean embeddedElements = eventSource.getEntityMode()!=EntityMode.DOM4J ||
-				( (EntityType) collectionType.getElementType( eventSource.getFactory() ) ).isEmbeddedInXML();
-		
-		boolean reallyDoCascade = style.reallyDoCascade(action) && 
-			embeddedElements && child!=CollectionType.UNFETCHED_COLLECTION;
-		
-		if ( reallyDoCascade ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascade " + action + " for collection: " + collectionType.getRole() );
-			}
-			
-			Iterator iter = action.getCascadableChildrenIterator(eventSource, collectionType, child);
-			while ( iter.hasNext() ) {
-				cascadeProperty(
-						iter.next(), 
-						elemType,
-						style, 
-						anything, 
-						isCascadeDeleteEnabled 
-					);
-			}
-			
-			if ( log.isTraceEnabled() ) {
-				log.trace( "done cascade " + action + " for collection: " + collectionType.getRole() );
-			}
-		}
-		
-		final boolean deleteOrphans = style.hasOrphanDelete() && 
-				action.deleteOrphans() && 
-				elemType.isEntityType() && 
-				child instanceof PersistentCollection; //a newly instantiated collection can't have orphans
-		
-		if ( deleteOrphans ) { // handle orphaned entities!!
-			if ( log.isTraceEnabled() ) {
-				log.trace( "deleting orphans for collection: " + collectionType.getRole() );
-			}
-			
-			// we can do the cast since orphan-delete does not apply to:
-			// 1. newly instantiated collections
-			// 2. arrays (we can't track orphans for detached arrays)
-			final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() );
-			deleteOrphans( entityName, (PersistentCollection) child );
-			
-			if ( log.isTraceEnabled() ) {
-				log.trace( "done deleting orphans for collection: " + collectionType.getRole() );
-			}
-		}
-	}
-
-	/**
-	 * Delete any entities that were removed from the collection
-	 */
-	private void deleteOrphans(String entityName, PersistentCollection pc) throws HibernateException {
-		//TODO: suck this logic into the collection!
-		final Collection orphans;
-		if ( pc.wasInitialized() ) {
-			CollectionEntry ce = eventSource.getPersistenceContext().getCollectionEntry(pc);
-			orphans = ce==null ? 
-					CollectionHelper.EMPTY_COLLECTION :
-					ce.getOrphans(entityName, pc);
-		}
-		else {
-			orphans = pc.getQueuedOrphans(entityName);
-		}
-		
-		final Iterator orphanIter = orphans.iterator();
-		while ( orphanIter.hasNext() ) {
-			Object orphan = orphanIter.next();
-			if (orphan!=null) {
-				if ( log.isTraceEnabled() ) {
-					log.trace("deleting orphaned entity instance: " + entityName);
-				}
-				eventSource.delete( entityName, orphan, false, null );
-			}
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Cascade.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Cascade.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,383 @@
+/*
+ * 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.engine;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * Delegate responsible for, in conjunction with the various
+ * {@link CascadingAction actions}, implementing cascade processing.
+ *
+ * @author Gavin King
+ * @see CascadingAction
+ */
+public final class Cascade {
+
+	/**
+	 * A cascade point that occurs just after the insertion of the parent entity and
+	 * just before deletion
+	 */
+	public static final int AFTER_INSERT_BEFORE_DELETE = 1;
+	/**
+	 * A cascade point that occurs just before the insertion of the parent entity and
+	 * just after deletion
+	 */
+	public static final int BEFORE_INSERT_AFTER_DELETE = 2;
+	/**
+	 * A cascade point that occurs just after the insertion of the parent entity and
+	 * just before deletion, inside a collection
+	 */
+	public static final int AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION = 3;
+	/**
+	 * A cascade point that occurs just after update of the parent entity
+	 */
+	public static final int AFTER_UPDATE = 0;
+	/**
+	 * A cascade point that occurs just before the session is flushed
+	 */
+	public static final int BEFORE_FLUSH = 0;
+	/**
+	 * A cascade point that occurs just after eviction of the parent entity from the
+	 * session cache
+	 */
+	public static final int AFTER_EVICT = 0;
+	/**
+	 * A cascade point that occurs just after locking a transient parent entity into the
+	 * session cache
+	 */
+	public static final int BEFORE_REFRESH = 0;
+	/**
+	 * A cascade point that occurs just after refreshing a parent entity
+	 */
+	public static final int AFTER_LOCK = 0;
+	/**
+	 * A cascade point that occurs just before merging from a transient parent entity into
+	 * the object in the session cache
+	 */
+	public static final int BEFORE_MERGE = 0;
+
+
+	private static final Logger log = LoggerFactory.getLogger( Cascade.class );
+
+
+	private int cascadeTo;
+	private EventSource eventSource;
+	private CascadingAction action;
+
+	public Cascade(final CascadingAction action, final int cascadeTo, final EventSource eventSource) {
+		this.cascadeTo = cascadeTo;
+		this.eventSource = eventSource;
+		this.action = action;
+	}
+
+	/**
+	 * Cascade an action from the parent entity instance to all its children.
+	 *
+	 * @param persister The parent's entity persister
+	 * @param parent The parent reference.
+	 * @throws HibernateException
+	 */
+	public void cascade(final EntityPersister persister, final Object parent)
+	throws HibernateException {
+		cascade( persister, parent, null );
+	}
+
+	/**
+	 * Cascade an action from the parent entity instance to all its children.  This
+	 * form is typicaly called from within cascade actions.
+	 *
+	 * @param persister The parent's entity persister
+	 * @param parent The parent reference.
+	 * @param anything Anything ;)   Typically some form of cascade-local cache
+	 * which is specific to each CascadingAction type
+	 * @throws HibernateException
+	 */
+	public void cascade(final EntityPersister persister, final Object parent, final Object anything)
+			throws HibernateException {
+
+		if ( persister.hasCascades() || action.requiresNoCascadeChecking() ) { // performance opt
+			if ( log.isTraceEnabled() ) {
+				log.trace( "processing cascade " + action + " for: " + persister.getEntityName() );
+			}
+
+			Type[] types = persister.getPropertyTypes();
+			CascadeStyle[] cascadeStyles = persister.getPropertyCascadeStyles();
+			EntityMode entityMode = eventSource.getEntityMode();
+			boolean hasUninitializedLazyProperties = persister.hasUninitializedLazyProperties( parent, entityMode );
+			for ( int i=0; i<types.length; i++) {
+				CascadeStyle style = cascadeStyles[i];
+				if ( hasUninitializedLazyProperties && persister.getPropertyLaziness()[i] && ! action.performOnLazyProperty() ) {
+					//do nothing to avoid a lazy property initialization
+					continue;
+				}
+
+				if ( style.doCascade( action ) ) {
+					cascadeProperty(
+					        persister.getPropertyValue( parent, i, entityMode ),
+					        types[i],
+					        style,
+					        anything,
+					        false
+					);
+				}
+				else if ( action.requiresNoCascadeChecking() ) {
+					action.noCascade(
+							eventSource,
+							persister.getPropertyValue( parent, i, entityMode ),
+							parent,
+							persister,
+							i
+					);
+				}
+			}
+
+			if ( log.isTraceEnabled() ) {
+				log.trace( "done processing cascade " + action + " for: " + persister.getEntityName() );
+			}
+		}
+	}
+
+	/**
+	 * Cascade an action to the child or children
+	 */
+	private void cascadeProperty(
+			final Object child,
+			final Type type,
+			final CascadeStyle style,
+			final Object anything,
+			final boolean isCascadeDeleteEnabled) throws HibernateException {
+
+		if (child!=null) {
+			if ( type.isAssociationType() ) {
+				AssociationType associationType = (AssociationType) type;
+				if ( cascadeAssociationNow( associationType ) ) {
+					cascadeAssociation(
+							child,
+							type,
+							style,
+							anything,
+							isCascadeDeleteEnabled
+						);
+				}
+			}
+			else if ( type.isComponentType() ) {
+				cascadeComponent( child, (AbstractComponentType) type, anything );
+			}
+		}
+	}
+
+	private boolean cascadeAssociationNow(AssociationType associationType) {
+		return associationType.getForeignKeyDirection().cascadeNow(cascadeTo) &&
+			( eventSource.getEntityMode()!=EntityMode.DOM4J || associationType.isEmbeddedInXML() );
+	}
+
+	private void cascadeComponent(
+			final Object child,
+			final AbstractComponentType componentType,
+			final Object anything) {
+		Object[] children = componentType.getPropertyValues(child, eventSource);
+		Type[] types = componentType.getSubtypes();
+		for ( int i=0; i<types.length; i++ ) {
+			CascadeStyle componentPropertyStyle = componentType.getCascadeStyle(i);
+			if ( componentPropertyStyle.doCascade(action) ) {
+				cascadeProperty(
+						children[i],
+						types[i],
+						componentPropertyStyle,
+						anything,
+						false
+					);
+			}
+		}
+	}
+
+	private void cascadeAssociation(
+			final Object child,
+			final Type type,
+			final CascadeStyle style,
+			final Object anything,
+			final boolean isCascadeDeleteEnabled) {
+		if ( type.isEntityType() || type.isAnyType() ) {
+			cascadeToOne( child, type, style, anything, isCascadeDeleteEnabled );
+		}
+		else if ( type.isCollectionType() ) {
+			cascadeCollection( child, style, anything, (CollectionType) type );
+		}
+	}
+
+	/**
+	 * Cascade an action to a collection
+	 */
+	private void cascadeCollection(
+			final Object child,
+			final CascadeStyle style,
+			final Object anything,
+			final CollectionType type) {
+		CollectionPersister persister = eventSource.getFactory()
+				.getCollectionPersister( type.getRole() );
+		Type elemType = persister.getElementType();
+
+		final int oldCascadeTo = cascadeTo;
+		if ( cascadeTo==AFTER_INSERT_BEFORE_DELETE) {
+			cascadeTo = AFTER_INSERT_BEFORE_DELETE_VIA_COLLECTION;
+		}
+
+		//cascade to current collection elements
+		if ( elemType.isEntityType() || elemType.isAnyType() || elemType.isComponentType() ) {
+			cascadeCollectionElements(
+				child,
+				type,
+				style,
+				elemType,
+				anything,
+				persister.isCascadeDeleteEnabled()
+			);
+		}
+
+		cascadeTo = oldCascadeTo;
+	}
+
+	/**
+	 * Cascade an action to a to-one association or any type
+	 */
+	private void cascadeToOne(
+			final Object child,
+			final Type type,
+			final CascadeStyle style,
+			final Object anything,
+			final boolean isCascadeDeleteEnabled) {
+		final String entityName = type.isEntityType()
+				? ( (EntityType) type ).getAssociatedEntityName()
+				: null;
+		if ( style.reallyDoCascade(action) ) { //not really necessary, but good for consistency...
+			action.cascade(eventSource, child, entityName, anything, isCascadeDeleteEnabled);
+		}
+	}
+
+	/**
+	 * Cascade to the collection elements
+	 */
+	private void cascadeCollectionElements(
+			final Object child,
+			final CollectionType collectionType,
+			final CascadeStyle style,
+			final Type elemType,
+			final Object anything,
+			final boolean isCascadeDeleteEnabled) throws HibernateException {
+		// we can't cascade to non-embedded elements
+		boolean embeddedElements = eventSource.getEntityMode()!=EntityMode.DOM4J ||
+				( (EntityType) collectionType.getElementType( eventSource.getFactory() ) ).isEmbeddedInXML();
+		
+		boolean reallyDoCascade = style.reallyDoCascade(action) && 
+			embeddedElements && child!=CollectionType.UNFETCHED_COLLECTION;
+		
+		if ( reallyDoCascade ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascade " + action + " for collection: " + collectionType.getRole() );
+			}
+			
+			Iterator iter = action.getCascadableChildrenIterator(eventSource, collectionType, child);
+			while ( iter.hasNext() ) {
+				cascadeProperty(
+						iter.next(), 
+						elemType,
+						style, 
+						anything, 
+						isCascadeDeleteEnabled 
+					);
+			}
+			
+			if ( log.isTraceEnabled() ) {
+				log.trace( "done cascade " + action + " for collection: " + collectionType.getRole() );
+			}
+		}
+		
+		final boolean deleteOrphans = style.hasOrphanDelete() && 
+				action.deleteOrphans() && 
+				elemType.isEntityType() && 
+				child instanceof PersistentCollection; //a newly instantiated collection can't have orphans
+		
+		if ( deleteOrphans ) { // handle orphaned entities!!
+			if ( log.isTraceEnabled() ) {
+				log.trace( "deleting orphans for collection: " + collectionType.getRole() );
+			}
+			
+			// we can do the cast since orphan-delete does not apply to:
+			// 1. newly instantiated collections
+			// 2. arrays (we can't track orphans for detached arrays)
+			final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() );
+			deleteOrphans( entityName, (PersistentCollection) child );
+			
+			if ( log.isTraceEnabled() ) {
+				log.trace( "done deleting orphans for collection: " + collectionType.getRole() );
+			}
+		}
+	}
+
+	/**
+	 * Delete any entities that were removed from the collection
+	 */
+	private void deleteOrphans(String entityName, PersistentCollection pc) throws HibernateException {
+		//TODO: suck this logic into the collection!
+		final Collection orphans;
+		if ( pc.wasInitialized() ) {
+			CollectionEntry ce = eventSource.getPersistenceContext().getCollectionEntry(pc);
+			orphans = ce==null ? 
+					CollectionHelper.EMPTY_COLLECTION :
+					ce.getOrphans(entityName, pc);
+		}
+		else {
+			orphans = pc.getQueuedOrphans(entityName);
+		}
+		
+		final Iterator orphanIter = orphans.iterator();
+		while ( orphanIter.hasNext() ) {
+			Object orphan = orphanIter.next();
+			if (orphan!=null) {
+				if ( log.isTraceEnabled() ) {
+					log.trace("deleting orphaned entity instance: " + entityName);
+				}
+				eventSource.delete( entityName, orphan, false, null );
+			}
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CascadeStyle.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,275 +0,0 @@
-//$Id: CascadeStyle.java 10799 2006-11-13 19:34:33Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * A contract for defining the aspects of cascading various persistence actions.
- *
- * @see CascadingAction
- *
- * @author Gavin King
- */
-public abstract class CascadeStyle implements Serializable {
-
-	/**
-	 * For this style, should the given action be cascaded?
-	 *
-	 * @param action The action to be checked for cascade-ability.
-	 * @return True if the action should be cascaded under this style; false otherwise.
-	 */
-	public abstract boolean doCascade(CascadingAction action);
-
-	/**
-	 * Probably more aptly named something like doCascadeToCollectionElements(); it is
-	 * however used from both the collection and to-one logic branches...
-	 * <p/>
-	 * For this style, should the given action really be cascaded?  The default
-	 * implementation is simply to return {@link #doCascade}; for certain
-	 * styles (currently only delete-orphan), however, we need to be able to
-	 * control this seperately.
-	 *
-	 * @param action The action to be checked for cascade-ability.
-	 * @return True if the action should be really cascaded under this style;
-	 * false otherwise.
-	 */
-	public boolean reallyDoCascade(CascadingAction action) {
-		return doCascade(action);
-	}
-
-	/**
-	 * Do we need to delete orphaned collection elements?
-	 *
-	 * @return True if this style need to account for orphan delete
-	 * operations; false othwerwise.
-	 */
-	public boolean hasOrphanDelete() {
-		return false;
-	}
-
-	public static final class MultipleCascadeStyle extends CascadeStyle {
-		private final CascadeStyle[] styles;
-		public MultipleCascadeStyle(CascadeStyle[] styles) {
-			this.styles = styles;
-		}
-		public boolean doCascade(CascadingAction action) {
-			for (int i=0; i<styles.length; i++) {
-				if ( styles[i].doCascade(action) ) return true;
-			}
-			return false;
-		}
-		public boolean reallyDoCascade(CascadingAction action) {
-			for (int i=0; i<styles.length; i++) {
-				if ( styles[i].reallyDoCascade(action) ) return true;
-			}
-			return false;
-		}
-		public boolean hasOrphanDelete() {
-			for (int i=0; i<styles.length; i++) {
-				if ( styles[i].hasOrphanDelete() ) return true;
-			}
-			return false;
-		}
-		public String toString() {
-			return ArrayHelper.toString(styles);
-		}
-	}
-
-	/**
-	 * save / delete / update / evict / lock / replicate / merge / persist + delete orphans
-	 */
-	public static final CascadeStyle ALL_DELETE_ORPHAN = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return true;
-		}
-		public boolean hasOrphanDelete() {
-			return true;
-		}
-		public String toString() {
-			return "STYLE_ALL_DELETE_ORPHAN";
-		}
-	};
-
-	/**
-	 * save / delete / update / evict / lock / replicate / merge / persist
-	 */
-	public static final CascadeStyle ALL = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return true;
-		}
-		public String toString() {
-			return "STYLE_ALL";
-		}
-	};
-
-	/**
-	 * save / update
-	 */
-	public static final CascadeStyle UPDATE = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.SAVE_UPDATE || action==CascadingAction.SAVE_UPDATE_COPY;
-		}
-		public String toString() {
-			return "STYLE_SAVE_UPDATE";
-		}
-	};
-
-	/**
-	 * lock
-	 */
-	public static final CascadeStyle LOCK = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.LOCK;
-		}
-		public String toString() {
-			return "STYLE_LOCK";
-		}
-	};
-
-	/**
-	 * refresh
-	 */
-	public static final CascadeStyle REFRESH = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.REFRESH;
-		}
-		public String toString() {
-			return "STYLE_REFRESH";
-		}
-	};
-
-	/**
-	 * evict
-	 */
-	public static final CascadeStyle EVICT = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.EVICT;
-		}
-		public String toString() {
-			return "STYLE_EVICT";
-		}
-	};
-
-	/**
-	 * replicate
-	 */
-	public static final CascadeStyle REPLICATE = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.REPLICATE;
-		}
-		public String toString() {
-			return "STYLE_REPLICATE";
-		}
-	};
-	/**
-	 * merge
-	 */
-	public static final CascadeStyle MERGE = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.MERGE;
-		}
-		public String toString() {
-			return "STYLE_MERGE";
-		}
-	};
-
-	/**
-	 * create
-	 */
-	public static final CascadeStyle PERSIST = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.PERSIST
-				|| action==CascadingAction.PERSIST_ON_FLUSH;
-		}
-		public String toString() {
-			return "STYLE_PERSIST";
-		}
-	};
-
-	/**
-	 * delete
-	 */
-	public static final CascadeStyle DELETE = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.DELETE;
-		}
-		public String toString() {
-			return "STYLE_DELETE";
-		}
-	};
-
-	/**
-	 * delete + delete orphans
-	 */
-	public static final CascadeStyle DELETE_ORPHAN = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return action==CascadingAction.DELETE || action==CascadingAction.SAVE_UPDATE;
-		}
-		public boolean reallyDoCascade(CascadingAction action) {
-			return action==CascadingAction.DELETE;
-		}
-		public boolean hasOrphanDelete() {
-			return true;
-		}
-		public String toString() {
-			return "STYLE_DELETE_ORPHAN";
-		}
-	};
-
-	/**
-	 * no cascades
-	 */
-	public static final CascadeStyle NONE = new CascadeStyle() {
-		public boolean doCascade(CascadingAction action) {
-			return false;
-		}
-		public String toString() {
-			return "STYLE_NONE";
-		}
-	};
-
-	/**
-	 * package-protected constructor
-	 */
-	CascadeStyle() {
-	}
-
-	static final Map STYLES = new HashMap();
-
-	static {
-		STYLES.put( "all", ALL );
-		STYLES.put( "all-delete-orphan", ALL_DELETE_ORPHAN );
-		STYLES.put( "save-update", UPDATE );
-		STYLES.put( "persist", PERSIST );
-		STYLES.put( "merge", MERGE );
-		STYLES.put( "lock", LOCK );
-		STYLES.put( "refresh", REFRESH );
-		STYLES.put( "replicate", REPLICATE );
-		STYLES.put( "evict", EVICT );
-		STYLES.put( "delete", DELETE );
-		STYLES.put( "remove", DELETE ); // adds remove as a sort-of alias for delete...
-		STYLES.put( "delete-orphan", DELETE_ORPHAN );
-		STYLES.put( "none", NONE );
-	}
-
-	/**
-	 * Factory method for obtaining named cascade styles
-	 *
-	 * @param cascade The named cascade style name.
-	 * @return The appropriate CascadeStyle
-	 */
-	public static CascadeStyle getCascadeStyle(String cascade) {
-		CascadeStyle style = (CascadeStyle) STYLES.get(cascade);
-		if (style==null) {
-			throw new MappingException("Unsupported cascade style: " + cascade);
-		}
-		else {
-			return style;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/CascadeStyle.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadeStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,298 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * A contract for defining the aspects of cascading various persistence actions.
+ *
+ * @see CascadingAction
+ *
+ * @author Gavin King
+ */
+public abstract class CascadeStyle implements Serializable {
+
+	/**
+	 * For this style, should the given action be cascaded?
+	 *
+	 * @param action The action to be checked for cascade-ability.
+	 * @return True if the action should be cascaded under this style; false otherwise.
+	 */
+	public abstract boolean doCascade(CascadingAction action);
+
+	/**
+	 * Probably more aptly named something like doCascadeToCollectionElements(); it is
+	 * however used from both the collection and to-one logic branches...
+	 * <p/>
+	 * For this style, should the given action really be cascaded?  The default
+	 * implementation is simply to return {@link #doCascade}; for certain
+	 * styles (currently only delete-orphan), however, we need to be able to
+	 * control this seperately.
+	 *
+	 * @param action The action to be checked for cascade-ability.
+	 * @return True if the action should be really cascaded under this style;
+	 * false otherwise.
+	 */
+	public boolean reallyDoCascade(CascadingAction action) {
+		return doCascade(action);
+	}
+
+	/**
+	 * Do we need to delete orphaned collection elements?
+	 *
+	 * @return True if this style need to account for orphan delete
+	 * operations; false othwerwise.
+	 */
+	public boolean hasOrphanDelete() {
+		return false;
+	}
+
+	public static final class MultipleCascadeStyle extends CascadeStyle {
+		private final CascadeStyle[] styles;
+		public MultipleCascadeStyle(CascadeStyle[] styles) {
+			this.styles = styles;
+		}
+		public boolean doCascade(CascadingAction action) {
+			for (int i=0; i<styles.length; i++) {
+				if ( styles[i].doCascade(action) ) return true;
+			}
+			return false;
+		}
+		public boolean reallyDoCascade(CascadingAction action) {
+			for (int i=0; i<styles.length; i++) {
+				if ( styles[i].reallyDoCascade(action) ) return true;
+			}
+			return false;
+		}
+		public boolean hasOrphanDelete() {
+			for (int i=0; i<styles.length; i++) {
+				if ( styles[i].hasOrphanDelete() ) return true;
+			}
+			return false;
+		}
+		public String toString() {
+			return ArrayHelper.toString(styles);
+		}
+	}
+
+	/**
+	 * save / delete / update / evict / lock / replicate / merge / persist + delete orphans
+	 */
+	public static final CascadeStyle ALL_DELETE_ORPHAN = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return true;
+		}
+		public boolean hasOrphanDelete() {
+			return true;
+		}
+		public String toString() {
+			return "STYLE_ALL_DELETE_ORPHAN";
+		}
+	};
+
+	/**
+	 * save / delete / update / evict / lock / replicate / merge / persist
+	 */
+	public static final CascadeStyle ALL = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return true;
+		}
+		public String toString() {
+			return "STYLE_ALL";
+		}
+	};
+
+	/**
+	 * save / update
+	 */
+	public static final CascadeStyle UPDATE = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.SAVE_UPDATE || action==CascadingAction.SAVE_UPDATE_COPY;
+		}
+		public String toString() {
+			return "STYLE_SAVE_UPDATE";
+		}
+	};
+
+	/**
+	 * lock
+	 */
+	public static final CascadeStyle LOCK = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.LOCK;
+		}
+		public String toString() {
+			return "STYLE_LOCK";
+		}
+	};
+
+	/**
+	 * refresh
+	 */
+	public static final CascadeStyle REFRESH = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.REFRESH;
+		}
+		public String toString() {
+			return "STYLE_REFRESH";
+		}
+	};
+
+	/**
+	 * evict
+	 */
+	public static final CascadeStyle EVICT = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.EVICT;
+		}
+		public String toString() {
+			return "STYLE_EVICT";
+		}
+	};
+
+	/**
+	 * replicate
+	 */
+	public static final CascadeStyle REPLICATE = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.REPLICATE;
+		}
+		public String toString() {
+			return "STYLE_REPLICATE";
+		}
+	};
+	/**
+	 * merge
+	 */
+	public static final CascadeStyle MERGE = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.MERGE;
+		}
+		public String toString() {
+			return "STYLE_MERGE";
+		}
+	};
+
+	/**
+	 * create
+	 */
+	public static final CascadeStyle PERSIST = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.PERSIST
+				|| action==CascadingAction.PERSIST_ON_FLUSH;
+		}
+		public String toString() {
+			return "STYLE_PERSIST";
+		}
+	};
+
+	/**
+	 * delete
+	 */
+	public static final CascadeStyle DELETE = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.DELETE;
+		}
+		public String toString() {
+			return "STYLE_DELETE";
+		}
+	};
+
+	/**
+	 * delete + delete orphans
+	 */
+	public static final CascadeStyle DELETE_ORPHAN = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return action==CascadingAction.DELETE || action==CascadingAction.SAVE_UPDATE;
+		}
+		public boolean reallyDoCascade(CascadingAction action) {
+			return action==CascadingAction.DELETE;
+		}
+		public boolean hasOrphanDelete() {
+			return true;
+		}
+		public String toString() {
+			return "STYLE_DELETE_ORPHAN";
+		}
+	};
+
+	/**
+	 * no cascades
+	 */
+	public static final CascadeStyle NONE = new CascadeStyle() {
+		public boolean doCascade(CascadingAction action) {
+			return false;
+		}
+		public String toString() {
+			return "STYLE_NONE";
+		}
+	};
+
+	/**
+	 * package-protected constructor
+	 */
+	CascadeStyle() {
+	}
+
+	static final Map STYLES = new HashMap();
+
+	static {
+		STYLES.put( "all", ALL );
+		STYLES.put( "all-delete-orphan", ALL_DELETE_ORPHAN );
+		STYLES.put( "save-update", UPDATE );
+		STYLES.put( "persist", PERSIST );
+		STYLES.put( "merge", MERGE );
+		STYLES.put( "lock", LOCK );
+		STYLES.put( "refresh", REFRESH );
+		STYLES.put( "replicate", REPLICATE );
+		STYLES.put( "evict", EVICT );
+		STYLES.put( "delete", DELETE );
+		STYLES.put( "remove", DELETE ); // adds remove as a sort-of alias for delete...
+		STYLES.put( "delete-orphan", DELETE_ORPHAN );
+		STYLES.put( "none", NONE );
+	}
+
+	/**
+	 * Factory method for obtaining named cascade styles
+	 *
+	 * @param cascade The named cascade style name.
+	 * @return The appropriate CascadeStyle
+	 */
+	public static CascadeStyle getCascadeStyle(String cascade) {
+		CascadeStyle style = (CascadeStyle) STYLES.get(cascade);
+		if (style==null) {
+			throw new MappingException("Unsupported cascade style: " + cascade);
+		}
+		else {
+			return style;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CascadingAction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,438 +0,0 @@
-//$Id: CascadingAction.java 10451 2006-09-05 06:53:46Z epbernard $
-package org.hibernate.engine;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.ReplicationMode;
-import org.hibernate.TransientObjectException;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventSource;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-import org.hibernate.type.EntityType;
-
-/**
- * A session action that may be cascaded from parent entity to its children
- *
- * @author Gavin King
- */
-public abstract class CascadingAction {
-
-	private static final Logger log = LoggerFactory.getLogger( CascadingAction.class );
-
-
-	// the CascadingAction contract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * protected constructor
-	 */
-	CascadingAction() {
-	}
-
-	/**
-	 * Cascade the action to the child object.
-	 *
-	 * @param session The session within which the cascade is occuring.
-	 * @param child The child to which cascading should be performed.
-	 * @param entityName The child's entity name
-	 * @param anything Anything ;)  Typically some form of cascade-local cache
-	 * which is specific to each CascadingAction type
-	 * @param isCascadeDeleteEnabled Are cascading deletes enabled.
-	 * @throws HibernateException
-	 */
-	public abstract void cascade(
-			EventSource session,
-			Object child,
-			String entityName,
-			Object anything,
-			boolean isCascadeDeleteEnabled) throws HibernateException;
-
-	/**
-	 * Given a collection, get an iterator of the children upon which the
-	 * current cascading action should be visited.
-	 *
-	 * @param session The session within which the cascade is occuring.
-	 * @param collectionType The mapping type of the collection.
-	 * @param collection The collection instance.
-	 * @return The children iterator.
-	 */
-	public abstract Iterator getCascadableChildrenIterator(
-			EventSource session,
-			CollectionType collectionType,
-			Object collection);
-
-	/**
-	 * Does this action potentially extrapolate to orphan deletes?
-	 *
-	 * @return True if this action can lead to deletions of orphans.
-	 */
-	public abstract boolean deleteOrphans();
-
-
-	/**
-	 * Does the specified cascading action require verification of no cascade validity?
-	 *
-	 * @return True if this action requires no-cascade verification; false otherwise.
-	 */
-	public boolean requiresNoCascadeChecking() {
-		return false;
-	}
-
-	/**
-	 * Called (in the case of {@link #requiresNoCascadeChecking} returning true) to validate
-	 * that no cascade on the given property is considered a valid semantic.
-	 *
-	 * @param session The session witin which the cascade is occurring.
-	 * @param child The property value
-	 * @param parent The property value owner
-	 * @param persister The entity persister for the owner
-	 * @param propertyIndex The index of the property within the owner.
-	 */
-	public void noCascade(EventSource session, Object child, Object parent, EntityPersister persister, int propertyIndex) {
-	}
-
-	/**
-	 * Should this action be performed (or noCascade consulted) in the case of lazy properties.
-	 */
-	public boolean performOnLazyProperty() {
-		return true;
-	}
-
-
-	// the CascadingAction implementations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * @see org.hibernate.Session#delete(Object)
-	 */
-	public static final CascadingAction DELETE = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace("cascading to delete: " + entityName);
-			}
-			session.delete( entityName, child, isCascadeDeleteEnabled, ( Set ) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// delete does cascade to uninitialized collections
-			return CascadingAction.getAllElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			// orphans should be deleted during delete
-			return true;
-		}
-		public String toString() {
-			return "ACTION_DELETE";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#lock(Object, LockMode)
-	 */
-	public static final CascadingAction LOCK = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to lock: " + entityName );
-			}
-			session.lock( entityName, child, LockMode.NONE/*(LockMode) anything*/ );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// lock doesn't cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			//TODO: should orphans really be deleted during lock???
-			return false;
-		}
-		public String toString() {
-			return "ACTION_LOCK";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#refresh(Object)
-	 */
-	public static final CascadingAction REFRESH = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to refresh: " + entityName );
-			}
-			session.refresh( child, (Map) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// refresh doesn't cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			return false;
-		}
-		public String toString() {
-			return "ACTION_REFRESH";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#evict(Object)
-	 */
-	public static final CascadingAction EVICT = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to evict: " + entityName );
-			}
-			session.evict(child);
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// evicts don't cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			return false;
-		}
-		public boolean performOnLazyProperty() {
-			return false;
-		}
-		public String toString() {
-			return "ACTION_EVICT";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#saveOrUpdate(Object)
-	 */
-	public static final CascadingAction SAVE_UPDATE = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to saveOrUpdate: " + entityName );
-			}
-			session.saveOrUpdate(entityName, child);
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// saves / updates don't cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			// orphans should be deleted during save/update
-			return true;
-		}
-		public boolean performOnLazyProperty() {
-			return false;
-		}
-		public String toString() {
-			return "ACTION_SAVE_UPDATE";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#merge(Object)
-	 */
-	public static final CascadingAction MERGE = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to merge: " + entityName );
-			}
-			session.merge( entityName, child, (Map) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// merges don't cascade to uninitialized collections
-//			//TODO: perhaps this does need to cascade after all....
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			// orphans should not be deleted during merge??
-			return false;
-		}
-		public String toString() {
-			return "ACTION_MERGE";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.classic.Session#saveOrUpdateCopy(Object)
-	 */
-	public static final CascadingAction SAVE_UPDATE_COPY = new CascadingAction() {
-		// for deprecated saveOrUpdateCopy()
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to saveOrUpdateCopy: " + entityName );
-			}
-			session.saveOrUpdateCopy( entityName, child, (Map) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// saves / updates don't cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			// orphans should not be deleted during copy??
-			return false;
-		}
-		public String toString() {
-			return "ACTION_SAVE_UPDATE_COPY";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#persist(Object)
-	 */
-	public static final CascadingAction PERSIST = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to persist: " + entityName );
-			}
-			session.persist( entityName, child, (Map) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// persists don't cascade to uninitialized collections
-			return CascadingAction.getAllElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			return false;
-		}
-		public boolean performOnLazyProperty() {
-			return false;
-		}
-		public String toString() {
-			return "ACTION_PERSIST";
-		}
-	};
-
-	/**
-	 * Execute persist during flush time
-	 *
-	 * @see org.hibernate.Session#persist(Object)
-	 */
-	public static final CascadingAction PERSIST_ON_FLUSH = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to persistOnFlush: " + entityName );
-			}
-			session.persistOnFlush( entityName, child, (Map) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// persists don't cascade to uninitialized collections
-			return CascadingAction.getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			return true;
-		}
-		public boolean requiresNoCascadeChecking() {
-			return true;
-		}
-		public void noCascade(
-				EventSource session,
-				Object child,
-				Object parent,
-				EntityPersister persister,
-				int propertyIndex) {
-			if ( child == null ) {
-				return;
-			}
-			Type type = persister.getPropertyTypes()[propertyIndex];
-			if ( type.isEntityType() ) {
-				String childEntityName = ( ( EntityType ) type ).getAssociatedEntityName( session.getFactory() );
-
-				if ( ! isInManagedState( child, session )
-						&& ! ( child instanceof HibernateProxy ) //a proxy cannot be transient and it breaks ForeignKeys.isTransient
-						&& ForeignKeys.isTransient( childEntityName, child, null, session ) ) {
-					String parentEntiytName = persister.getEntityName();
-					String propertyName = persister.getPropertyNames()[propertyIndex];
-					throw new TransientObjectException(
-							"object references an unsaved transient instance - " +
-							"save the transient instance before flushing: " +
-							parentEntiytName + "." + propertyName + " -> " + childEntityName
-					);
-
-				}
-			}
-		}
-		public boolean performOnLazyProperty() {
-			return false;
-		}
-
-		private boolean isInManagedState(Object child, EventSource session) {
-			EntityEntry entry = session.getPersistenceContext().getEntry( child );
-			return entry != null && (entry.getStatus() == Status.MANAGED || entry.getStatus() == Status.READ_ONLY);
-		}
-
-		public String toString() {
-			return "ACTION_PERSIST_ON_FLUSH";
-		}
-	};
-
-	/**
-	 * @see org.hibernate.Session#replicate(Object, org.hibernate.ReplicationMode)
-	 */
-	public static final CascadingAction REPLICATE = new CascadingAction() {
-		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
-		throws HibernateException {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "cascading to replicate: " + entityName );
-			}
-			session.replicate( entityName, child, (ReplicationMode) anything );
-		}
-		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
-			// replicate does cascade to uninitialized collections
-			return getLoadedElementsIterator(session, collectionType, collection);
-		}
-		public boolean deleteOrphans() {
-			return false; //I suppose?
-		}
-		public String toString() {
-			return "ACTION_REPLICATE";
-		}
-	};
-
-
-	// static helper methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Given a collection, get an iterator of all its children, loading them
-	 * from the database if necessary.
-	 *
-	 * @param session The session within which the cascade is occuring.
-	 * @param collectionType The mapping type of the collection.
-	 * @param collection The collection instance.
-	 * @return The children iterator.
-	 */
-	private static Iterator getAllElementsIterator(
-			EventSource session,
-			CollectionType collectionType,
-			Object collection) {
-		return collectionType.getElementsIterator( collection, session );
-	}
-
-	/**
-	 * Iterate just the elements of the collection that are already there. Don't load
-	 * any new elements from the database.
-	 */
-	public static Iterator getLoadedElementsIterator(SessionImplementor session, CollectionType collectionType, Object collection) {
-		if ( collectionIsInitialized(collection) ) {
-			// handles arrays and newly instantiated collections
-			return collectionType.getElementsIterator(collection, session);
-		}
-		else {
-			// does not handle arrays (thats ok, cos they can't be lazy)
-			// or newly instantiated collections, so we can do the cast
-			return ( (PersistentCollection) collection ).queuedAdditionIterator();
-		}
-	}
-
-	private static boolean collectionIsInitialized(Object collection) {
-		return !(collection instanceof PersistentCollection) || ( (PersistentCollection) collection ).wasInitialized();
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/CascadingAction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CascadingAction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,461 @@
+/*
+ * 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.engine;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.ReplicationMode;
+import org.hibernate.TransientObjectException;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventSource;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+import org.hibernate.type.EntityType;
+
+/**
+ * A session action that may be cascaded from parent entity to its children
+ *
+ * @author Gavin King
+ */
+public abstract class CascadingAction {
+
+	private static final Logger log = LoggerFactory.getLogger( CascadingAction.class );
+
+
+	// the CascadingAction contract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * protected constructor
+	 */
+	CascadingAction() {
+	}
+
+	/**
+	 * Cascade the action to the child object.
+	 *
+	 * @param session The session within which the cascade is occuring.
+	 * @param child The child to which cascading should be performed.
+	 * @param entityName The child's entity name
+	 * @param anything Anything ;)  Typically some form of cascade-local cache
+	 * which is specific to each CascadingAction type
+	 * @param isCascadeDeleteEnabled Are cascading deletes enabled.
+	 * @throws HibernateException
+	 */
+	public abstract void cascade(
+			EventSource session,
+			Object child,
+			String entityName,
+			Object anything,
+			boolean isCascadeDeleteEnabled) throws HibernateException;
+
+	/**
+	 * Given a collection, get an iterator of the children upon which the
+	 * current cascading action should be visited.
+	 *
+	 * @param session The session within which the cascade is occuring.
+	 * @param collectionType The mapping type of the collection.
+	 * @param collection The collection instance.
+	 * @return The children iterator.
+	 */
+	public abstract Iterator getCascadableChildrenIterator(
+			EventSource session,
+			CollectionType collectionType,
+			Object collection);
+
+	/**
+	 * Does this action potentially extrapolate to orphan deletes?
+	 *
+	 * @return True if this action can lead to deletions of orphans.
+	 */
+	public abstract boolean deleteOrphans();
+
+
+	/**
+	 * Does the specified cascading action require verification of no cascade validity?
+	 *
+	 * @return True if this action requires no-cascade verification; false otherwise.
+	 */
+	public boolean requiresNoCascadeChecking() {
+		return false;
+	}
+
+	/**
+	 * Called (in the case of {@link #requiresNoCascadeChecking} returning true) to validate
+	 * that no cascade on the given property is considered a valid semantic.
+	 *
+	 * @param session The session witin which the cascade is occurring.
+	 * @param child The property value
+	 * @param parent The property value owner
+	 * @param persister The entity persister for the owner
+	 * @param propertyIndex The index of the property within the owner.
+	 */
+	public void noCascade(EventSource session, Object child, Object parent, EntityPersister persister, int propertyIndex) {
+	}
+
+	/**
+	 * Should this action be performed (or noCascade consulted) in the case of lazy properties.
+	 */
+	public boolean performOnLazyProperty() {
+		return true;
+	}
+
+
+	// the CascadingAction implementations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * @see org.hibernate.Session#delete(Object)
+	 */
+	public static final CascadingAction DELETE = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace("cascading to delete: " + entityName);
+			}
+			session.delete( entityName, child, isCascadeDeleteEnabled, ( Set ) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// delete does cascade to uninitialized collections
+			return CascadingAction.getAllElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			// orphans should be deleted during delete
+			return true;
+		}
+		public String toString() {
+			return "ACTION_DELETE";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#lock(Object, LockMode)
+	 */
+	public static final CascadingAction LOCK = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to lock: " + entityName );
+			}
+			session.lock( entityName, child, LockMode.NONE/*(LockMode) anything*/ );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// lock doesn't cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			//TODO: should orphans really be deleted during lock???
+			return false;
+		}
+		public String toString() {
+			return "ACTION_LOCK";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#refresh(Object)
+	 */
+	public static final CascadingAction REFRESH = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to refresh: " + entityName );
+			}
+			session.refresh( child, (Map) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// refresh doesn't cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			return false;
+		}
+		public String toString() {
+			return "ACTION_REFRESH";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#evict(Object)
+	 */
+	public static final CascadingAction EVICT = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to evict: " + entityName );
+			}
+			session.evict(child);
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// evicts don't cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			return false;
+		}
+		public boolean performOnLazyProperty() {
+			return false;
+		}
+		public String toString() {
+			return "ACTION_EVICT";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#saveOrUpdate(Object)
+	 */
+	public static final CascadingAction SAVE_UPDATE = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to saveOrUpdate: " + entityName );
+			}
+			session.saveOrUpdate(entityName, child);
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// saves / updates don't cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			// orphans should be deleted during save/update
+			return true;
+		}
+		public boolean performOnLazyProperty() {
+			return false;
+		}
+		public String toString() {
+			return "ACTION_SAVE_UPDATE";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#merge(Object)
+	 */
+	public static final CascadingAction MERGE = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to merge: " + entityName );
+			}
+			session.merge( entityName, child, (Map) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// merges don't cascade to uninitialized collections
+//			//TODO: perhaps this does need to cascade after all....
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			// orphans should not be deleted during merge??
+			return false;
+		}
+		public String toString() {
+			return "ACTION_MERGE";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.classic.Session#saveOrUpdateCopy(Object)
+	 */
+	public static final CascadingAction SAVE_UPDATE_COPY = new CascadingAction() {
+		// for deprecated saveOrUpdateCopy()
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to saveOrUpdateCopy: " + entityName );
+			}
+			session.saveOrUpdateCopy( entityName, child, (Map) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// saves / updates don't cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			// orphans should not be deleted during copy??
+			return false;
+		}
+		public String toString() {
+			return "ACTION_SAVE_UPDATE_COPY";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#persist(Object)
+	 */
+	public static final CascadingAction PERSIST = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to persist: " + entityName );
+			}
+			session.persist( entityName, child, (Map) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// persists don't cascade to uninitialized collections
+			return CascadingAction.getAllElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			return false;
+		}
+		public boolean performOnLazyProperty() {
+			return false;
+		}
+		public String toString() {
+			return "ACTION_PERSIST";
+		}
+	};
+
+	/**
+	 * Execute persist during flush time
+	 *
+	 * @see org.hibernate.Session#persist(Object)
+	 */
+	public static final CascadingAction PERSIST_ON_FLUSH = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to persistOnFlush: " + entityName );
+			}
+			session.persistOnFlush( entityName, child, (Map) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// persists don't cascade to uninitialized collections
+			return CascadingAction.getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			return true;
+		}
+		public boolean requiresNoCascadeChecking() {
+			return true;
+		}
+		public void noCascade(
+				EventSource session,
+				Object child,
+				Object parent,
+				EntityPersister persister,
+				int propertyIndex) {
+			if ( child == null ) {
+				return;
+			}
+			Type type = persister.getPropertyTypes()[propertyIndex];
+			if ( type.isEntityType() ) {
+				String childEntityName = ( ( EntityType ) type ).getAssociatedEntityName( session.getFactory() );
+
+				if ( ! isInManagedState( child, session )
+						&& ! ( child instanceof HibernateProxy ) //a proxy cannot be transient and it breaks ForeignKeys.isTransient
+						&& ForeignKeys.isTransient( childEntityName, child, null, session ) ) {
+					String parentEntiytName = persister.getEntityName();
+					String propertyName = persister.getPropertyNames()[propertyIndex];
+					throw new TransientObjectException(
+							"object references an unsaved transient instance - " +
+							"save the transient instance before flushing: " +
+							parentEntiytName + "." + propertyName + " -> " + childEntityName
+					);
+
+				}
+			}
+		}
+		public boolean performOnLazyProperty() {
+			return false;
+		}
+
+		private boolean isInManagedState(Object child, EventSource session) {
+			EntityEntry entry = session.getPersistenceContext().getEntry( child );
+			return entry != null && (entry.getStatus() == Status.MANAGED || entry.getStatus() == Status.READ_ONLY);
+		}
+
+		public String toString() {
+			return "ACTION_PERSIST_ON_FLUSH";
+		}
+	};
+
+	/**
+	 * @see org.hibernate.Session#replicate(Object, org.hibernate.ReplicationMode)
+	 */
+	public static final CascadingAction REPLICATE = new CascadingAction() {
+		public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
+		throws HibernateException {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "cascading to replicate: " + entityName );
+			}
+			session.replicate( entityName, child, (ReplicationMode) anything );
+		}
+		public Iterator getCascadableChildrenIterator(EventSource session, CollectionType collectionType, Object collection) {
+			// replicate does cascade to uninitialized collections
+			return getLoadedElementsIterator(session, collectionType, collection);
+		}
+		public boolean deleteOrphans() {
+			return false; //I suppose?
+		}
+		public String toString() {
+			return "ACTION_REPLICATE";
+		}
+	};
+
+
+	// static helper methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Given a collection, get an iterator of all its children, loading them
+	 * from the database if necessary.
+	 *
+	 * @param session The session within which the cascade is occuring.
+	 * @param collectionType The mapping type of the collection.
+	 * @param collection The collection instance.
+	 * @return The children iterator.
+	 */
+	private static Iterator getAllElementsIterator(
+			EventSource session,
+			CollectionType collectionType,
+			Object collection) {
+		return collectionType.getElementsIterator( collection, session );
+	}
+
+	/**
+	 * Iterate just the elements of the collection that are already there. Don't load
+	 * any new elements from the database.
+	 */
+	public static Iterator getLoadedElementsIterator(SessionImplementor session, CollectionType collectionType, Object collection) {
+		if ( collectionIsInitialized(collection) ) {
+			// handles arrays and newly instantiated collections
+			return collectionType.getElementsIterator(collection, session);
+		}
+		else {
+			// does not handle arrays (thats ok, cos they can't be lazy)
+			// or newly instantiated collections, so we can do the cast
+			return ( (PersistentCollection) collection ).queuedAdditionIterator();
+		}
+	}
+
+	private static boolean collectionIsInitialized(Object collection) {
+		return !(collection instanceof PersistentCollection) || ( (PersistentCollection) collection ).wasInitialized();
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,397 +0,0 @@
-//$Id: CollectionEntry.java 9551 2006-03-04 03:49:55Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.util.Collection;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * We need an entry to tell us all about the current state
- * of a collection with respect to its persistent state
- * 
- * @author Gavin King
- */
-public final class CollectionEntry implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger(CollectionEntry.class);
-	
-	//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
-	
-	// session-start/post-flush persistent state
-	private Serializable snapshot;
-	// allow the CollectionSnapshot to be serialized
-	private String role;
-	
-	// "loaded" means the reference that is consistent 
-	// with the current database state
-	private transient CollectionPersister loadedPersister;
-	private Serializable loadedKey;
-
-	// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
-	
-	// during flush, we navigate the object graph to
-	// collections and decide what to do with them
-	private transient boolean reached;
-	private transient boolean processed;
-	private transient boolean doupdate;
-	private transient boolean doremove;
-	private transient boolean dorecreate;
-	// if we instantiate a collection during the flush() process,
-	// we must ignore it for the rest of the flush()
-	private transient boolean ignore;
-	
-	// "current" means the reference that was found during flush() 
-	private transient CollectionPersister currentPersister;
-	private transient Serializable currentKey;
-
-	/**
-	 * For newly wrapped collections, or dereferenced collection wrappers
-	 */
-	public CollectionEntry(CollectionPersister persister, PersistentCollection collection) {
-		// new collections that get found + wrapped
-		// during flush shouldn't be ignored
-		ignore = false;
-
-		collection.clearDirty(); //a newly wrapped collection is NOT dirty (or we get unnecessary version updates)
-		
-		snapshot = persister.isMutable() ?
-				collection.getSnapshot(persister) :
-				null;
-		collection.setSnapshot(loadedKey, role, snapshot);
-	}
-
-	/**
-	 * For collections just loaded from the database
-	 */
-	public CollectionEntry(
-			final PersistentCollection collection, 
-			final CollectionPersister loadedPersister, 
-			final Serializable loadedKey, 
-			final boolean ignore
-	) {
-		this.ignore=ignore;
-
-		//collection.clearDirty()
-		
-		this.loadedKey = loadedKey;
-		setLoadedPersister(loadedPersister);
-
-		collection.setSnapshot(loadedKey, role, null);
-
-		//postInitialize() will be called after initialization
-	}
-
-	/**
-	 * For uninitialized detached collections
-	 */
-	public CollectionEntry(CollectionPersister loadedPersister, Serializable loadedKey) {
-		// detached collection wrappers that get found + reattached
-		// during flush shouldn't be ignored
-		ignore = false;
-
-		//collection.clearDirty()
-		
-		this.loadedKey = loadedKey;
-		setLoadedPersister(loadedPersister);
-	}
-	
-	/**
-	 * For initialized detached collections
-	 */
-	CollectionEntry(PersistentCollection collection, SessionFactoryImplementor factory)
-	throws MappingException {
-		// detached collections that get found + reattached
-		// during flush shouldn't be ignored
-		ignore = false;
-
-		loadedKey = collection.getKey();
-		setLoadedPersister( factory.getCollectionPersister( collection.getRole() ) );
-
-		snapshot = collection.getStoredSnapshot();		
-	}
-
-	/**
-	 * Used from custom serialization.
-	 *
-	 * @see #serialize
-	 * @see #deserialize
-	 */
-	private CollectionEntry(
-			String role,
-	        Serializable snapshot,
-	        Serializable loadedKey,
-	        SessionFactoryImplementor factory) {
-		this.role = role;
-		this.snapshot = snapshot;
-		this.loadedKey = loadedKey;
-		if ( role != null ) {
-			afterDeserialize( factory );
-		}
-	}
-
-	/**
-	 * Determine if the collection is "really" dirty, by checking dirtiness
-	 * of the collection elements, if necessary
-	 */
-	private void dirty(PersistentCollection collection) throws HibernateException {
-		
-		boolean forceDirty = collection.wasInitialized() &&
-				!collection.isDirty() && //optimization
-				getLoadedPersister() != null &&
-				getLoadedPersister().isMutable() && //optimization
-				( collection.isDirectlyAccessible() || getLoadedPersister().getElementType().isMutable() ) && //optimization
-				!collection.equalsSnapshot( getLoadedPersister() );
-		
-		if ( forceDirty ) {
-			collection.dirty();
-		}
-		
-	}
-
-	public void preFlush(PersistentCollection collection) throws HibernateException {
-		
-		boolean nonMutableChange = collection.isDirty() && 
-				getLoadedPersister()!=null && 
-				!getLoadedPersister().isMutable();
-		if (nonMutableChange) {
-			throw new HibernateException(
-					"changed an immutable collection instance: " + 
-					MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
-				);
-		}
-		
-		dirty(collection);
-		
-		if ( log.isDebugEnabled() && collection.isDirty() && getLoadedPersister() != null ) {
-			log.debug(
-					"Collection dirty: " +
-					MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
-				);
-		}
-
-		setDoupdate(false);
-		setDoremove(false);
-		setDorecreate(false);
-		setReached(false);
-		setProcessed(false);
-	}
-
-	public void postInitialize(PersistentCollection collection) throws HibernateException {
-		snapshot = getLoadedPersister().isMutable() ?
-				collection.getSnapshot( getLoadedPersister() ) :
-				null;
-		collection.setSnapshot(loadedKey, role, snapshot);
-	}
-
-	/**
-	 * Called after a successful flush
-	 */
-	public void postFlush(PersistentCollection collection) throws HibernateException {
-		if ( isIgnore() ) {
-			ignore = false;
-		}
-		else if ( !isProcessed() ) {
-			throw new AssertionFailure( "collection [" + collection.getRole() + "] was not processed by flush()" );
-		}
-		collection.setSnapshot(loadedKey, role, snapshot);
-	}
-	
-	/**
-	 * Called after execution of an action
-	 */
-	public void afterAction(PersistentCollection collection) {
-		loadedKey = getCurrentKey();
-		setLoadedPersister( getCurrentPersister() );
-		
-		boolean resnapshot = collection.wasInitialized() && 
-				( isDoremove() || isDorecreate() || isDoupdate() );
-		if ( resnapshot ) {
-			snapshot = loadedPersister==null || !loadedPersister.isMutable() ? 
-					null : 
-					collection.getSnapshot(loadedPersister); //re-snapshot
-		}
-		
-		collection.postAction();
-	}
-
-	public Serializable getKey() {
-		return getLoadedKey();
-	}
-
-	public String getRole() {
-		return role;
-	}
-
-	public Serializable getSnapshot() {
-		return snapshot;
-	}
-
-	private void setLoadedPersister(CollectionPersister persister) {
-		loadedPersister = persister;
-		setRole( persister == null ? null : persister.getRole() );
-	}
-	
-	void afterDeserialize(SessionFactoryImplementor factory) {
-		loadedPersister = factory.getCollectionPersister(role);
-	}
-
-	public boolean wasDereferenced() {
-		return getLoadedKey() == null;
-	}
-
-	public boolean isReached() {
-		return reached;
-	}
-
-	public void setReached(boolean reached) {
-		this.reached = reached;
-	}
-
-	public boolean isProcessed() {
-		return processed;
-	}
-
-	public void setProcessed(boolean processed) {
-		this.processed = processed;
-	}
-
-	public boolean isDoupdate() {
-		return doupdate;
-	}
-
-	public void setDoupdate(boolean doupdate) {
-		this.doupdate = doupdate;
-	}
-
-	public boolean isDoremove() {
-		return doremove;
-	}
-
-	public void setDoremove(boolean doremove) {
-		this.doremove = doremove;
-	}
-
-	public boolean isDorecreate() {
-		return dorecreate;
-	}
-
-	public void setDorecreate(boolean dorecreate) {
-		this.dorecreate = dorecreate;
-	}
-
-	public boolean isIgnore() {
-		return ignore;
-	}
-
-	public CollectionPersister getCurrentPersister() {
-		return currentPersister;
-	}
-
-	public void setCurrentPersister(CollectionPersister currentPersister) {
-		this.currentPersister = currentPersister;
-	}
-
-	/**
-	 * This is only available late during the flush
-	 * cycle
-	 */
-	public Serializable getCurrentKey() {
-		return currentKey;
-	}
-
-	public void setCurrentKey(Serializable currentKey) {
-		this.currentKey = currentKey;
-	}
-	
-	/**
-	 * This is only available late during the flush cycle
-	 */
-	public CollectionPersister getLoadedPersister() {
-		return loadedPersister;
-	}
-
-	public Serializable getLoadedKey() {
-		return loadedKey;
-	}
-
-	public void setRole(String role) {
-		this.role = role;
-	}
-
-	public String toString() {
-		String result = "CollectionEntry" + 
-				MessageHelper.collectionInfoString( loadedPersister.getRole(), loadedKey );
-		if (currentPersister!=null) {
-			result += "->" + 
-					MessageHelper.collectionInfoString( currentPersister.getRole(), currentKey );
-		}
-		return result;
-	}
-
-	/**
-	 * Get the collection orphans (entities which were removed from the collection)
-	 */
-	public Collection getOrphans(String entityName, PersistentCollection collection) 
-	throws HibernateException {
-		if (snapshot==null) {
-			throw new AssertionFailure("no collection snapshot for orphan delete");
-		}
-		return collection.getOrphans( snapshot, entityName );
-	}
-
-	public boolean isSnapshotEmpty(PersistentCollection collection) {
-		//TODO: does this really need to be here?
-		//      does the collection already have
-		//      it's own up-to-date snapshot?
-		return collection.wasInitialized() && 
-			( getLoadedPersister()==null || getLoadedPersister().isMutable() ) &&
-			collection.isSnapshotEmpty( getSnapshot() );
-	}
-
-
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws java.io.IOException
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeObject( role );
-		oos.writeObject( snapshot );
-		oos.writeObject( loadedKey );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @param session The session being deserialized.
-	 * @return The deserialized CollectionEntry
-	 * @throws IOException
-	 * @throws ClassNotFoundException
-	 */
-	static CollectionEntry deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		return new CollectionEntry(
-				( String ) ois.readObject(),
-		        ( Serializable ) ois.readObject(),
-		        ( Serializable ) ois.readObject(),
-		        session.getFactory()
-		);
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/CollectionEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,420 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.util.Collection;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * We need an entry to tell us all about the current state
+ * of a collection with respect to its persistent state
+ * 
+ * @author Gavin King
+ */
+public final class CollectionEntry implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(CollectionEntry.class);
+	
+	//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
+	
+	// session-start/post-flush persistent state
+	private Serializable snapshot;
+	// allow the CollectionSnapshot to be serialized
+	private String role;
+	
+	// "loaded" means the reference that is consistent 
+	// with the current database state
+	private transient CollectionPersister loadedPersister;
+	private Serializable loadedKey;
+
+	// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
+	
+	// during flush, we navigate the object graph to
+	// collections and decide what to do with them
+	private transient boolean reached;
+	private transient boolean processed;
+	private transient boolean doupdate;
+	private transient boolean doremove;
+	private transient boolean dorecreate;
+	// if we instantiate a collection during the flush() process,
+	// we must ignore it for the rest of the flush()
+	private transient boolean ignore;
+	
+	// "current" means the reference that was found during flush() 
+	private transient CollectionPersister currentPersister;
+	private transient Serializable currentKey;
+
+	/**
+	 * For newly wrapped collections, or dereferenced collection wrappers
+	 */
+	public CollectionEntry(CollectionPersister persister, PersistentCollection collection) {
+		// new collections that get found + wrapped
+		// during flush shouldn't be ignored
+		ignore = false;
+
+		collection.clearDirty(); //a newly wrapped collection is NOT dirty (or we get unnecessary version updates)
+		
+		snapshot = persister.isMutable() ?
+				collection.getSnapshot(persister) :
+				null;
+		collection.setSnapshot(loadedKey, role, snapshot);
+	}
+
+	/**
+	 * For collections just loaded from the database
+	 */
+	public CollectionEntry(
+			final PersistentCollection collection, 
+			final CollectionPersister loadedPersister, 
+			final Serializable loadedKey, 
+			final boolean ignore
+	) {
+		this.ignore=ignore;
+
+		//collection.clearDirty()
+		
+		this.loadedKey = loadedKey;
+		setLoadedPersister(loadedPersister);
+
+		collection.setSnapshot(loadedKey, role, null);
+
+		//postInitialize() will be called after initialization
+	}
+
+	/**
+	 * For uninitialized detached collections
+	 */
+	public CollectionEntry(CollectionPersister loadedPersister, Serializable loadedKey) {
+		// detached collection wrappers that get found + reattached
+		// during flush shouldn't be ignored
+		ignore = false;
+
+		//collection.clearDirty()
+		
+		this.loadedKey = loadedKey;
+		setLoadedPersister(loadedPersister);
+	}
+	
+	/**
+	 * For initialized detached collections
+	 */
+	CollectionEntry(PersistentCollection collection, SessionFactoryImplementor factory)
+	throws MappingException {
+		// detached collections that get found + reattached
+		// during flush shouldn't be ignored
+		ignore = false;
+
+		loadedKey = collection.getKey();
+		setLoadedPersister( factory.getCollectionPersister( collection.getRole() ) );
+
+		snapshot = collection.getStoredSnapshot();		
+	}
+
+	/**
+	 * Used from custom serialization.
+	 *
+	 * @see #serialize
+	 * @see #deserialize
+	 */
+	private CollectionEntry(
+			String role,
+	        Serializable snapshot,
+	        Serializable loadedKey,
+	        SessionFactoryImplementor factory) {
+		this.role = role;
+		this.snapshot = snapshot;
+		this.loadedKey = loadedKey;
+		if ( role != null ) {
+			afterDeserialize( factory );
+		}
+	}
+
+	/**
+	 * Determine if the collection is "really" dirty, by checking dirtiness
+	 * of the collection elements, if necessary
+	 */
+	private void dirty(PersistentCollection collection) throws HibernateException {
+		
+		boolean forceDirty = collection.wasInitialized() &&
+				!collection.isDirty() && //optimization
+				getLoadedPersister() != null &&
+				getLoadedPersister().isMutable() && //optimization
+				( collection.isDirectlyAccessible() || getLoadedPersister().getElementType().isMutable() ) && //optimization
+				!collection.equalsSnapshot( getLoadedPersister() );
+		
+		if ( forceDirty ) {
+			collection.dirty();
+		}
+		
+	}
+
+	public void preFlush(PersistentCollection collection) throws HibernateException {
+		
+		boolean nonMutableChange = collection.isDirty() && 
+				getLoadedPersister()!=null && 
+				!getLoadedPersister().isMutable();
+		if (nonMutableChange) {
+			throw new HibernateException(
+					"changed an immutable collection instance: " + 
+					MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
+				);
+		}
+		
+		dirty(collection);
+		
+		if ( log.isDebugEnabled() && collection.isDirty() && getLoadedPersister() != null ) {
+			log.debug(
+					"Collection dirty: " +
+					MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
+				);
+		}
+
+		setDoupdate(false);
+		setDoremove(false);
+		setDorecreate(false);
+		setReached(false);
+		setProcessed(false);
+	}
+
+	public void postInitialize(PersistentCollection collection) throws HibernateException {
+		snapshot = getLoadedPersister().isMutable() ?
+				collection.getSnapshot( getLoadedPersister() ) :
+				null;
+		collection.setSnapshot(loadedKey, role, snapshot);
+	}
+
+	/**
+	 * Called after a successful flush
+	 */
+	public void postFlush(PersistentCollection collection) throws HibernateException {
+		if ( isIgnore() ) {
+			ignore = false;
+		}
+		else if ( !isProcessed() ) {
+			throw new AssertionFailure( "collection [" + collection.getRole() + "] was not processed by flush()" );
+		}
+		collection.setSnapshot(loadedKey, role, snapshot);
+	}
+	
+	/**
+	 * Called after execution of an action
+	 */
+	public void afterAction(PersistentCollection collection) {
+		loadedKey = getCurrentKey();
+		setLoadedPersister( getCurrentPersister() );
+		
+		boolean resnapshot = collection.wasInitialized() && 
+				( isDoremove() || isDorecreate() || isDoupdate() );
+		if ( resnapshot ) {
+			snapshot = loadedPersister==null || !loadedPersister.isMutable() ? 
+					null : 
+					collection.getSnapshot(loadedPersister); //re-snapshot
+		}
+		
+		collection.postAction();
+	}
+
+	public Serializable getKey() {
+		return getLoadedKey();
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public Serializable getSnapshot() {
+		return snapshot;
+	}
+
+	private void setLoadedPersister(CollectionPersister persister) {
+		loadedPersister = persister;
+		setRole( persister == null ? null : persister.getRole() );
+	}
+	
+	void afterDeserialize(SessionFactoryImplementor factory) {
+		loadedPersister = factory.getCollectionPersister(role);
+	}
+
+	public boolean wasDereferenced() {
+		return getLoadedKey() == null;
+	}
+
+	public boolean isReached() {
+		return reached;
+	}
+
+	public void setReached(boolean reached) {
+		this.reached = reached;
+	}
+
+	public boolean isProcessed() {
+		return processed;
+	}
+
+	public void setProcessed(boolean processed) {
+		this.processed = processed;
+	}
+
+	public boolean isDoupdate() {
+		return doupdate;
+	}
+
+	public void setDoupdate(boolean doupdate) {
+		this.doupdate = doupdate;
+	}
+
+	public boolean isDoremove() {
+		return doremove;
+	}
+
+	public void setDoremove(boolean doremove) {
+		this.doremove = doremove;
+	}
+
+	public boolean isDorecreate() {
+		return dorecreate;
+	}
+
+	public void setDorecreate(boolean dorecreate) {
+		this.dorecreate = dorecreate;
+	}
+
+	public boolean isIgnore() {
+		return ignore;
+	}
+
+	public CollectionPersister getCurrentPersister() {
+		return currentPersister;
+	}
+
+	public void setCurrentPersister(CollectionPersister currentPersister) {
+		this.currentPersister = currentPersister;
+	}
+
+	/**
+	 * This is only available late during the flush
+	 * cycle
+	 */
+	public Serializable getCurrentKey() {
+		return currentKey;
+	}
+
+	public void setCurrentKey(Serializable currentKey) {
+		this.currentKey = currentKey;
+	}
+	
+	/**
+	 * This is only available late during the flush cycle
+	 */
+	public CollectionPersister getLoadedPersister() {
+		return loadedPersister;
+	}
+
+	public Serializable getLoadedKey() {
+		return loadedKey;
+	}
+
+	public void setRole(String role) {
+		this.role = role;
+	}
+
+	public String toString() {
+		String result = "CollectionEntry" + 
+				MessageHelper.collectionInfoString( loadedPersister.getRole(), loadedKey );
+		if (currentPersister!=null) {
+			result += "->" + 
+					MessageHelper.collectionInfoString( currentPersister.getRole(), currentKey );
+		}
+		return result;
+	}
+
+	/**
+	 * Get the collection orphans (entities which were removed from the collection)
+	 */
+	public Collection getOrphans(String entityName, PersistentCollection collection) 
+	throws HibernateException {
+		if (snapshot==null) {
+			throw new AssertionFailure("no collection snapshot for orphan delete");
+		}
+		return collection.getOrphans( snapshot, entityName );
+	}
+
+	public boolean isSnapshotEmpty(PersistentCollection collection) {
+		//TODO: does this really need to be here?
+		//      does the collection already have
+		//      it's own up-to-date snapshot?
+		return collection.wasInitialized() && 
+			( getLoadedPersister()==null || getLoadedPersister().isMutable() ) &&
+			collection.isSnapshotEmpty( getSnapshot() );
+	}
+
+
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws java.io.IOException
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeObject( role );
+		oos.writeObject( snapshot );
+		oos.writeObject( loadedKey );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @param session The session being deserialized.
+	 * @return The deserialized CollectionEntry
+	 * @throws IOException
+	 * @throws ClassNotFoundException
+	 */
+	static CollectionEntry deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		return new CollectionEntry(
+				( String ) ois.readObject(),
+		        ( Serializable ) ois.readObject(),
+		        ( Serializable ) ois.readObject(),
+		        session.getFactory()
+		);
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,113 +0,0 @@
-//$Id: CollectionKey.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate.engine;
-
-import org.hibernate.EntityMode;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-
-
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * Uniquely identifies a collection instance in a particular session.
- *
- * @author Gavin King
- */
-public final class CollectionKey implements Serializable {
-
-	private final String role;
-	private final Serializable key;
-	private final Type keyType;
-	private final SessionFactoryImplementor factory;
-	private final int hashCode;
-	private EntityMode entityMode;
-
-	public CollectionKey(CollectionPersister persister, Serializable key, EntityMode em) {
-		this( persister.getRole(), key, persister.getKeyType(), em, persister.getFactory() );
-	}
-
-	private CollectionKey(
-			String role,
-	        Serializable key,
-	        Type keyType,
-	        EntityMode entityMode,
-	        SessionFactoryImplementor factory) {
-		this.role = role;
-		this.key = key;
-		this.keyType = keyType;
-		this.entityMode = entityMode;
-		this.factory = factory;
-		this.hashCode = generateHashCode(); //cache the hashcode
-	}
-
-	public boolean equals(Object other) {
-		CollectionKey that = (CollectionKey) other;
-		return that.role.equals(role) &&
-		       keyType.isEqual(that.key, key, entityMode, factory);
-	}
-
-	public int generateHashCode() {
-		int result = 17;
-		result = 37 * result + role.hashCode();
-		result = 37 * result + keyType.getHashCode(key, entityMode, factory);
-		return result;
-	}
-
-	public int hashCode() {
-		return hashCode;
-	}
-
-	public String getRole() {
-		return role;
-	}
-
-	public Serializable getKey() {
-		return key;
-	}
-
-	public String toString() {
-		return "CollectionKey" +
-		       MessageHelper.collectionInfoString( factory.getCollectionPersister(role), key, factory );
-	}
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws java.io.IOException
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeObject( role );
-		oos.writeObject( key );
-		oos.writeObject( keyType );
-		oos.writeObject( entityMode.toString() );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @param session The session being deserialized.
-	 * @return The deserialized CollectionKey
-	 * @throws IOException
-	 * @throws ClassNotFoundException
-	 */
-	static CollectionKey deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		return new CollectionKey(
-				( String ) ois.readObject(),
-		        ( Serializable ) ois.readObject(),
-		        ( Type ) ois.readObject(),
-		        EntityMode.parse( ( String ) ois.readObject() ),
-		        session.getFactory()
-		);
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/CollectionKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/CollectionKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.engine;
+
+import org.hibernate.EntityMode;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Uniquely identifies a collection instance in a particular session.
+ *
+ * @author Gavin King
+ */
+public final class CollectionKey implements Serializable {
+
+	private final String role;
+	private final Serializable key;
+	private final Type keyType;
+	private final SessionFactoryImplementor factory;
+	private final int hashCode;
+	private EntityMode entityMode;
+
+	public CollectionKey(CollectionPersister persister, Serializable key, EntityMode em) {
+		this( persister.getRole(), key, persister.getKeyType(), em, persister.getFactory() );
+	}
+
+	private CollectionKey(
+			String role,
+	        Serializable key,
+	        Type keyType,
+	        EntityMode entityMode,
+	        SessionFactoryImplementor factory) {
+		this.role = role;
+		this.key = key;
+		this.keyType = keyType;
+		this.entityMode = entityMode;
+		this.factory = factory;
+		this.hashCode = generateHashCode(); //cache the hashcode
+	}
+
+	public boolean equals(Object other) {
+		CollectionKey that = (CollectionKey) other;
+		return that.role.equals(role) &&
+		       keyType.isEqual(that.key, key, entityMode, factory);
+	}
+
+	public int generateHashCode() {
+		int result = 17;
+		result = 37 * result + role.hashCode();
+		result = 37 * result + keyType.getHashCode(key, entityMode, factory);
+		return result;
+	}
+
+	public int hashCode() {
+		return hashCode;
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public Serializable getKey() {
+		return key;
+	}
+
+	public String toString() {
+		return "CollectionKey" +
+		       MessageHelper.collectionInfoString( factory.getCollectionPersister(role), key, factory );
+	}
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws java.io.IOException
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeObject( role );
+		oos.writeObject( key );
+		oos.writeObject( keyType );
+		oos.writeObject( entityMode.toString() );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @param session The session being deserialized.
+	 * @return The deserialized CollectionKey
+	 * @throws IOException
+	 * @throws ClassNotFoundException
+	 */
+	static CollectionKey deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		return new CollectionKey(
+				( String ) ois.readObject(),
+		        ( Serializable ) ois.readObject(),
+		        ( Type ) ois.readObject(),
+		        EntityMode.parse( ( String ) ois.readObject() ),
+		        session.getFactory()
+		);
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Collections.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,254 +0,0 @@
-//$Id: Collections.java 8694 2005-11-28 19:28:17Z steveebersole $
-package org.hibernate.engine;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.CollectionType;
-
-import java.io.Serializable;
-
-/**
- * Implements book-keeping for the collection persistence by reachability algorithm
- * @author Gavin King
- */
-public final class Collections {
-
-	private Collections() {}
-
-	private static final Logger log = LoggerFactory.getLogger(Collections.class);
-
-	/**
-	 * record the fact that this collection was dereferenced
-	 *
-	 * @param coll The collection to be updated by unreachability.
-	 * @throws HibernateException
-	 */
-	public static void processUnreachableCollection(PersistentCollection coll, SessionImplementor session)
-	throws HibernateException {
-
-		if ( coll.getOwner()==null ) {
-			processNeverReferencedCollection(coll, session);
-		}
-		else {
-			processDereferencedCollection(coll, session);
-		}
-
-	}
-
-	private static void processDereferencedCollection(PersistentCollection coll, SessionImplementor session)
-	throws HibernateException {
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
-		final CollectionPersister loadedPersister = entry.getLoadedPersister();
-
-		if ( log.isDebugEnabled() && loadedPersister != null )
-			log.debug(
-					"Collection dereferenced: " +
-					MessageHelper.collectionInfoString(
-							loadedPersister,
-					        entry.getLoadedKey(),
-					        session.getFactory()
-						)
-				);
-
-		// do a check
-		boolean hasOrphanDelete = loadedPersister != null &&
-		                          loadedPersister.hasOrphanDelete();
-		if (hasOrphanDelete) {
-			Serializable ownerId = loadedPersister.getOwnerEntityPersister()
-					.getIdentifier( coll.getOwner(), session.getEntityMode() );
-			if ( ownerId == null ) {
-				// the owning entity may have been deleted and its identifier unset due to
-				// identifier-rollback; in which case, try to look up its identifier from
-				// the persistence context
-				if ( session.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
-					EntityEntry ownerEntry = persistenceContext.getEntry( coll.getOwner() );
-					if ( ownerEntry != null ) {
-						ownerId = ownerEntry.getId();
-					}
-				}
-				if ( ownerId == null ) {
-					throw new AssertionFailure( "Unable to determine collection owner identifier for orphan-delete processing" );
-				}
-			}
-			EntityKey key = new EntityKey(
-					ownerId,
-			        loadedPersister.getOwnerEntityPersister(),
-			        session.getEntityMode()
-			);
-			Object owner = persistenceContext.getEntity(key);
-			if ( owner == null ) {
-				throw new AssertionFailure(
-						"collection owner not associated with session: " +
-						loadedPersister.getRole()
-				);
-			}
-			EntityEntry e = persistenceContext.getEntry(owner);
-			//only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
-			if ( e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE ) {
-				throw new HibernateException(
-						"A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " +
-						loadedPersister.getRole()
-				);
-			}
-		}
-
-		// do the work
-		entry.setCurrentPersister(null);
-		entry.setCurrentKey(null);
-		prepareCollectionForUpdate( coll, entry, session.getEntityMode(), session.getFactory() );
-
-	}
-
-	private static void processNeverReferencedCollection(PersistentCollection coll, SessionImplementor session)
-	throws HibernateException {
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
-
-		log.debug(
-				"Found collection with unloaded owner: " +
-				MessageHelper.collectionInfoString(
-						entry.getLoadedPersister(),
-				        entry.getLoadedKey(),
-				        session.getFactory()
-				)
-		);
-
-		entry.setCurrentPersister( entry.getLoadedPersister() );
-		entry.setCurrentKey( entry.getLoadedKey() );
-
-		prepareCollectionForUpdate( coll, entry, session.getEntityMode(), session.getFactory() );
-
-	}
-
-	/**
-	 * Initialize the role of the collection.
-	 *
-	 * @param collection The collection to be updated by reachibility.
-	 * @param type The type of the collection.
-	 * @param entity The owner of the collection.
-	 * @throws HibernateException
-	 */
-	public static void processReachableCollection(
-			PersistentCollection collection,
-	        CollectionType type,
-	        Object entity,
-	        SessionImplementor session)
-	throws HibernateException {
-
-		collection.setOwner(entity);
-
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(collection);
-
-		if ( ce == null ) {
-			// refer to comment in StatefulPersistenceContext.addCollection()
-			throw new HibernateException(
-					"Found two representations of same collection: " +
-					type.getRole()
-			);
-		}
-
-		// The CollectionEntry.isReached() stuff is just to detect any silly users  
-		// who set up circular or shared references between/to collections.
-		if ( ce.isReached() ) {
-			// We've been here before
-			throw new HibernateException(
-					"Found shared references to a collection: " +
-					type.getRole()
-			);
-		}
-		ce.setReached(true);
-
-		SessionFactoryImplementor factory = session.getFactory();
-		CollectionPersister persister = factory.getCollectionPersister( type.getRole() );
-		ce.setCurrentPersister(persister);
-		ce.setCurrentKey( type.getKeyOfOwner(entity, session) ); //TODO: better to pass the id in as an argument?
-
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"Collection found: " +
-					MessageHelper.collectionInfoString( persister, ce.getCurrentKey(), factory ) +
-					", was: " +
-					MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), factory ) +
-					( collection.wasInitialized() ? " (initialized)" : " (uninitialized)" )
-			);
-		}
-
-		prepareCollectionForUpdate( collection, ce, session.getEntityMode(), factory );
-
-	}
-
-	/**
-	 * 1. record the collection role that this collection is referenced by
-	 * 2. decide if the collection needs deleting/creating/updating (but
-	 *	don't actually schedule the action yet)
-	 */
-	private static void prepareCollectionForUpdate(
-			PersistentCollection collection,
-	        CollectionEntry entry,
-	        EntityMode entityMode,
-	        SessionFactoryImplementor factory)
-	throws HibernateException {
-
-		if ( entry.isProcessed() ) {
-			throw new AssertionFailure( "collection was processed twice by flush()" );
-		}
-		entry.setProcessed(true);
-
-		final CollectionPersister loadedPersister = entry.getLoadedPersister();
-		final CollectionPersister currentPersister = entry.getCurrentPersister();
-		if ( loadedPersister != null || currentPersister != null ) {					// it is or was referenced _somewhere_
-
-			boolean ownerChanged = loadedPersister != currentPersister ||				// if either its role changed,
-			                       !currentPersister
-					                       .getKeyType().isEqual(                       // or its key changed
-													entry.getLoadedKey(),
-			                                        entry.getCurrentKey(),
-			                                        entityMode, factory
-			                       );
-
-			if (ownerChanged) {
-
-				// do a check
-				final boolean orphanDeleteAndRoleChanged = loadedPersister != null &&
-				                                           currentPersister != null &&
-				                                           loadedPersister.hasOrphanDelete();
-
-				if (orphanDeleteAndRoleChanged) {
-					throw new HibernateException(
-							"Don't change the reference to a collection with cascade=\"all-delete-orphan\": " +
-							loadedPersister.getRole()
-						);
-				}
-
-				// do the work
-				if ( currentPersister != null ) {
-					entry.setDorecreate(true);											// we will need to create new entries
-				}
-
-				if ( loadedPersister != null ) {
-					entry.setDoremove(true);											// we will need to remove ye olde entries
-					if ( entry.isDorecreate() ) {
-						log.trace( "Forcing collection initialization" );
-						collection.forceInitialization();								// force initialize!
-					}
-				}
-
-			}
-			else if ( collection.isDirty() ) {											// else if it's elements changed
-				entry.setDoupdate(true);
-			}
-
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Collections.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Collections.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,277 @@
+/*
+ * 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.engine;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.CollectionType;
+
+import java.io.Serializable;
+
+/**
+ * Implements book-keeping for the collection persistence by reachability algorithm
+ * @author Gavin King
+ */
+public final class Collections {
+
+	private Collections() {}
+
+	private static final Logger log = LoggerFactory.getLogger(Collections.class);
+
+	/**
+	 * record the fact that this collection was dereferenced
+	 *
+	 * @param coll The collection to be updated by unreachability.
+	 * @throws HibernateException
+	 */
+	public static void processUnreachableCollection(PersistentCollection coll, SessionImplementor session)
+	throws HibernateException {
+
+		if ( coll.getOwner()==null ) {
+			processNeverReferencedCollection(coll, session);
+		}
+		else {
+			processDereferencedCollection(coll, session);
+		}
+
+	}
+
+	private static void processDereferencedCollection(PersistentCollection coll, SessionImplementor session)
+	throws HibernateException {
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
+		final CollectionPersister loadedPersister = entry.getLoadedPersister();
+
+		if ( log.isDebugEnabled() && loadedPersister != null )
+			log.debug(
+					"Collection dereferenced: " +
+					MessageHelper.collectionInfoString(
+							loadedPersister,
+					        entry.getLoadedKey(),
+					        session.getFactory()
+						)
+				);
+
+		// do a check
+		boolean hasOrphanDelete = loadedPersister != null &&
+		                          loadedPersister.hasOrphanDelete();
+		if (hasOrphanDelete) {
+			Serializable ownerId = loadedPersister.getOwnerEntityPersister()
+					.getIdentifier( coll.getOwner(), session.getEntityMode() );
+			if ( ownerId == null ) {
+				// the owning entity may have been deleted and its identifier unset due to
+				// identifier-rollback; in which case, try to look up its identifier from
+				// the persistence context
+				if ( session.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
+					EntityEntry ownerEntry = persistenceContext.getEntry( coll.getOwner() );
+					if ( ownerEntry != null ) {
+						ownerId = ownerEntry.getId();
+					}
+				}
+				if ( ownerId == null ) {
+					throw new AssertionFailure( "Unable to determine collection owner identifier for orphan-delete processing" );
+				}
+			}
+			EntityKey key = new EntityKey(
+					ownerId,
+			        loadedPersister.getOwnerEntityPersister(),
+			        session.getEntityMode()
+			);
+			Object owner = persistenceContext.getEntity(key);
+			if ( owner == null ) {
+				throw new AssertionFailure(
+						"collection owner not associated with session: " +
+						loadedPersister.getRole()
+				);
+			}
+			EntityEntry e = persistenceContext.getEntry(owner);
+			//only collections belonging to deleted entities are allowed to be dereferenced in the case of orphan delete
+			if ( e != null && e.getStatus() != Status.DELETED && e.getStatus() != Status.GONE ) {
+				throw new HibernateException(
+						"A collection with cascade=\"all-delete-orphan\" was no longer referenced by the owning entity instance: " +
+						loadedPersister.getRole()
+				);
+			}
+		}
+
+		// do the work
+		entry.setCurrentPersister(null);
+		entry.setCurrentKey(null);
+		prepareCollectionForUpdate( coll, entry, session.getEntityMode(), session.getFactory() );
+
+	}
+
+	private static void processNeverReferencedCollection(PersistentCollection coll, SessionImplementor session)
+	throws HibernateException {
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		CollectionEntry entry = persistenceContext.getCollectionEntry(coll);
+
+		log.debug(
+				"Found collection with unloaded owner: " +
+				MessageHelper.collectionInfoString(
+						entry.getLoadedPersister(),
+				        entry.getLoadedKey(),
+				        session.getFactory()
+				)
+		);
+
+		entry.setCurrentPersister( entry.getLoadedPersister() );
+		entry.setCurrentKey( entry.getLoadedKey() );
+
+		prepareCollectionForUpdate( coll, entry, session.getEntityMode(), session.getFactory() );
+
+	}
+
+	/**
+	 * Initialize the role of the collection.
+	 *
+	 * @param collection The collection to be updated by reachibility.
+	 * @param type The type of the collection.
+	 * @param entity The owner of the collection.
+	 * @throws HibernateException
+	 */
+	public static void processReachableCollection(
+			PersistentCollection collection,
+	        CollectionType type,
+	        Object entity,
+	        SessionImplementor session)
+	throws HibernateException {
+
+		collection.setOwner(entity);
+
+		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(collection);
+
+		if ( ce == null ) {
+			// refer to comment in StatefulPersistenceContext.addCollection()
+			throw new HibernateException(
+					"Found two representations of same collection: " +
+					type.getRole()
+			);
+		}
+
+		// The CollectionEntry.isReached() stuff is just to detect any silly users  
+		// who set up circular or shared references between/to collections.
+		if ( ce.isReached() ) {
+			// We've been here before
+			throw new HibernateException(
+					"Found shared references to a collection: " +
+					type.getRole()
+			);
+		}
+		ce.setReached(true);
+
+		SessionFactoryImplementor factory = session.getFactory();
+		CollectionPersister persister = factory.getCollectionPersister( type.getRole() );
+		ce.setCurrentPersister(persister);
+		ce.setCurrentKey( type.getKeyOfOwner(entity, session) ); //TODO: better to pass the id in as an argument?
+
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"Collection found: " +
+					MessageHelper.collectionInfoString( persister, ce.getCurrentKey(), factory ) +
+					", was: " +
+					MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), factory ) +
+					( collection.wasInitialized() ? " (initialized)" : " (uninitialized)" )
+			);
+		}
+
+		prepareCollectionForUpdate( collection, ce, session.getEntityMode(), factory );
+
+	}
+
+	/**
+	 * 1. record the collection role that this collection is referenced by
+	 * 2. decide if the collection needs deleting/creating/updating (but
+	 *	don't actually schedule the action yet)
+	 */
+	private static void prepareCollectionForUpdate(
+			PersistentCollection collection,
+	        CollectionEntry entry,
+	        EntityMode entityMode,
+	        SessionFactoryImplementor factory)
+	throws HibernateException {
+
+		if ( entry.isProcessed() ) {
+			throw new AssertionFailure( "collection was processed twice by flush()" );
+		}
+		entry.setProcessed(true);
+
+		final CollectionPersister loadedPersister = entry.getLoadedPersister();
+		final CollectionPersister currentPersister = entry.getCurrentPersister();
+		if ( loadedPersister != null || currentPersister != null ) {					// it is or was referenced _somewhere_
+
+			boolean ownerChanged = loadedPersister != currentPersister ||				// if either its role changed,
+			                       !currentPersister
+					                       .getKeyType().isEqual(                       // or its key changed
+													entry.getLoadedKey(),
+			                                        entry.getCurrentKey(),
+			                                        entityMode, factory
+			                       );
+
+			if (ownerChanged) {
+
+				// do a check
+				final boolean orphanDeleteAndRoleChanged = loadedPersister != null &&
+				                                           currentPersister != null &&
+				                                           loadedPersister.hasOrphanDelete();
+
+				if (orphanDeleteAndRoleChanged) {
+					throw new HibernateException(
+							"Don't change the reference to a collection with cascade=\"all-delete-orphan\": " +
+							loadedPersister.getRole()
+						);
+				}
+
+				// do the work
+				if ( currentPersister != null ) {
+					entry.setDorecreate(true);											// we will need to create new entries
+				}
+
+				if ( loadedPersister != null ) {
+					entry.setDoremove(true);											// we will need to remove ye olde entries
+					if ( entry.isDorecreate() ) {
+						log.trace( "Forcing collection initialization" );
+						collection.forceInitialization();								// force initialize!
+					}
+				}
+
+			}
+			else if ( collection.isDirty() ) {											// else if it's elements changed
+				entry.setDoupdate(true);
+			}
+
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,316 +0,0 @@
-//$Id: EntityEntry.java 9283 2006-02-14 03:24:18Z steveebersole $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.UniqueKeyLoadable;
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * We need an entry to tell us all about the current state
- * of an object with respect to its persistent state
- * 
- * @author Gavin King
- */
-public final class EntityEntry implements Serializable {
-
-	private LockMode lockMode;
-	private Status status;
-	private final Serializable id;
-	private Object[] loadedState;
-	private Object[] deletedState;
-	private boolean existsInDatabase;
-	private Object version;
-	private transient EntityPersister persister; // for convenience to save some lookups
-	private final EntityMode entityMode;
-	private final String entityName;
-	private boolean isBeingReplicated;
-	private boolean loadedWithLazyPropertiesUnfetched; //NOTE: this is not updated when properties are fetched lazily!
-	private final transient Object rowId;
-
-	EntityEntry(
-			final Status status,
-			final Object[] loadedState,
-			final Object rowId,
-			final Serializable id,
-			final Object version,
-			final LockMode lockMode,
-			final boolean existsInDatabase,
-			final EntityPersister persister,
-			final EntityMode entityMode,
-			final boolean disableVersionIncrement,
-			final boolean lazyPropertiesAreUnfetched) {
-		this.status=status;
-		this.loadedState=loadedState;
-		this.id=id;
-		this.rowId=rowId;
-		this.existsInDatabase=existsInDatabase;
-		this.version=version;
-		this.lockMode=lockMode;
-		this.isBeingReplicated=disableVersionIncrement;
-		this.loadedWithLazyPropertiesUnfetched = lazyPropertiesAreUnfetched;
-		this.persister=persister;
-		this.entityMode = entityMode;
-		this.entityName = persister == null ?
-				null : persister.getEntityName();
-	}
-
-	/**
-	 * Used during custom deserialization
-	 */
-	private EntityEntry(
-			final SessionFactoryImplementor factory,
-			final String entityName,
-			final Serializable id,
-			final EntityMode entityMode,
-			final Status status,
-			final Object[] loadedState,
-	        final Object[] deletedState,
-			final Object version,
-			final LockMode lockMode,
-			final boolean existsInDatabase,
-			final boolean isBeingReplicated,
-			final boolean loadedWithLazyPropertiesUnfetched) {
-		this.entityName = entityName;
-		this.persister = factory.getEntityPersister( entityName );
-		this.id = id;
-		this.entityMode = entityMode;
-		this.status = status;
-		this.loadedState = loadedState;
-		this.deletedState = deletedState;
-		this.version = version;
-		this.lockMode = lockMode;
-		this.existsInDatabase = existsInDatabase;
-		this.isBeingReplicated = isBeingReplicated;
-		this.loadedWithLazyPropertiesUnfetched = loadedWithLazyPropertiesUnfetched;
-		this.rowId = null; // this is equivalent to the old behavior...
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-
-	public void setLockMode(LockMode lockMode) {
-		this.lockMode = lockMode;
-	}
-
-	public Status getStatus() {
-		return status;
-	}
-
-	public void setStatus(Status status) {
-		if (status==Status.READ_ONLY) {
-			loadedState = null; //memory optimization
-		}
-		this.status = status;
-	}
-
-	public Serializable getId() {
-		return id;
-	}
-
-	public Object[] getLoadedState() {
-		return loadedState;
-	}
-
-	public Object[] getDeletedState() {
-		return deletedState;
-	}
-
-	public void setDeletedState(Object[] deletedState) {
-		this.deletedState = deletedState;
-	}
-
-	public boolean isExistsInDatabase() {
-		return existsInDatabase;
-	}
-
-	public Object getVersion() {
-		return version;
-	}
-
-	public EntityPersister getPersister() {
-		return persister;
-	}
-
-	void afterDeserialize(SessionFactoryImplementor factory) {
-		persister = factory.getEntityPersister( entityName );
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public boolean isBeingReplicated() {
-		return isBeingReplicated;
-	}
-	
-	public Object getRowId() {
-		return rowId;
-	}
-	
-	/**
-	 * After actually updating the database, update the snapshot information,
-	 * and escalate the lock mode
-	 */
-	public void postUpdate(Object entity, Object[] updatedState, Object nextVersion) {
-		this.loadedState = updatedState;
-		
-		setLockMode(LockMode.WRITE);
-		
-		if ( getPersister().isVersioned() ) {
-			this.version = nextVersion;
-			getPersister().setPropertyValue( 
-					entity, 
-					getPersister().getVersionProperty(), 
-					nextVersion, 
-					entityMode 
-				);
-		}
-		
-		FieldInterceptionHelper.clearDirty( entity );
-	}
-
-	/**
-	 * After actually deleting a row, record the fact that the instance no longer
-	 * exists in the database
-	 */
-	public void postDelete() {
-		status = Status.GONE;
-		existsInDatabase = false;
-	}
-	
-	/**
-	 * After actually inserting a row, record the fact that the instance exists on the 
-	 * database (needed for identity-column key generation)
-	 */
-	public void postInsert() {
-		existsInDatabase = true;
-	}
-	
-	public boolean isNullifiable(boolean earlyInsert, SessionImplementor session) {
-		return getStatus() == Status.SAVING || (
-				earlyInsert ?
-						!isExistsInDatabase() :
-						session.getPersistenceContext().getNullifiableEntityKeys()
-							.contains( new EntityKey( getId(), getPersister(), entityMode ) )
-				);
-	}
-	
-	public Object getLoadedValue(String propertyName) {
-		int propertyIndex = ( (UniqueKeyLoadable) persister ).getPropertyIndex(propertyName);
-		return loadedState[propertyIndex];
-	}
-	
-	
-	public boolean requiresDirtyCheck(Object entity) {
-		
-		boolean isMutableInstance = 
-				status != Status.READ_ONLY && 
-				persister.isMutable();
-		
-		return isMutableInstance && (
-				getPersister().hasMutableProperties() ||
-				!FieldInterceptionHelper.isInstrumented( entity ) ||
-				FieldInterceptionHelper.extractFieldInterceptor( entity).isDirty()
-			);
-		
-	}
-
-	public void forceLocked(Object entity, Object nextVersion) {
-		version = nextVersion;
-		loadedState[ persister.getVersionProperty() ] = version;
-		setLockMode( LockMode.FORCE );
-		persister.setPropertyValue(
-				entity,
-		        getPersister().getVersionProperty(),
-		        nextVersion,
-		        entityMode
-		);
-	}
-
-	public void setReadOnly(boolean readOnly, Object entity) {
-		if (status!=Status.MANAGED && status!=Status.READ_ONLY) {
-			throw new HibernateException("instance was not in a valid state");
-		}
-		if (readOnly) {
-			setStatus(Status.READ_ONLY);
-			loadedState = null;
-		}
-		else {
-			setStatus(Status.MANAGED);
-			loadedState = getPersister().getPropertyValues(entity, entityMode);
-		}
-	}
-	
-	public String toString() {
-		return "EntityEntry" + 
-				MessageHelper.infoString(entityName, id) + 
-				'(' + status + ')';
-	}
-
-	public boolean isLoadedWithLazyPropertiesUnfetched() {
-		return loadedWithLazyPropertiesUnfetched;
-	}
-
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws java.io.IOException
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeObject( entityName );
-		oos.writeObject( id );
-		oos.writeObject( entityMode.toString() );
-		oos.writeObject( status.toString() );
-		// todo : potentially look at optimizing these two arrays
-		oos.writeObject( loadedState );
-		oos.writeObject( deletedState );
-		oos.writeObject( version );
-		oos.writeObject( lockMode.toString() );
-		oos.writeBoolean( existsInDatabase );
-		oos.writeBoolean( isBeingReplicated );
-		oos.writeBoolean( loadedWithLazyPropertiesUnfetched );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @param session The session being deserialized.
-	 * @return The deserialized EntityEntry
-	 * @throws IOException
-	 * @throws ClassNotFoundException
-	 */
-	static EntityEntry deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		return new EntityEntry(
-				session.getFactory(),
-		        ( String ) ois.readObject(),
-				( Serializable ) ois.readObject(),
-	            EntityMode.parse( ( String ) ois.readObject() ),
-				Status.parse( ( String ) ois.readObject() ),
-	            ( Object[] ) ois.readObject(),
-	            ( Object[] ) ois.readObject(),
-	            ( Object ) ois.readObject(),
-	            LockMode.parse( ( String ) ois.readObject() ),
-	            ois.readBoolean(),
-	            ois.readBoolean(),
-	            ois.readBoolean()
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/EntityEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,339 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.UniqueKeyLoadable;
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * We need an entry to tell us all about the current state
+ * of an object with respect to its persistent state
+ * 
+ * @author Gavin King
+ */
+public final class EntityEntry implements Serializable {
+
+	private LockMode lockMode;
+	private Status status;
+	private final Serializable id;
+	private Object[] loadedState;
+	private Object[] deletedState;
+	private boolean existsInDatabase;
+	private Object version;
+	private transient EntityPersister persister; // for convenience to save some lookups
+	private final EntityMode entityMode;
+	private final String entityName;
+	private boolean isBeingReplicated;
+	private boolean loadedWithLazyPropertiesUnfetched; //NOTE: this is not updated when properties are fetched lazily!
+	private final transient Object rowId;
+
+	EntityEntry(
+			final Status status,
+			final Object[] loadedState,
+			final Object rowId,
+			final Serializable id,
+			final Object version,
+			final LockMode lockMode,
+			final boolean existsInDatabase,
+			final EntityPersister persister,
+			final EntityMode entityMode,
+			final boolean disableVersionIncrement,
+			final boolean lazyPropertiesAreUnfetched) {
+		this.status=status;
+		this.loadedState=loadedState;
+		this.id=id;
+		this.rowId=rowId;
+		this.existsInDatabase=existsInDatabase;
+		this.version=version;
+		this.lockMode=lockMode;
+		this.isBeingReplicated=disableVersionIncrement;
+		this.loadedWithLazyPropertiesUnfetched = lazyPropertiesAreUnfetched;
+		this.persister=persister;
+		this.entityMode = entityMode;
+		this.entityName = persister == null ?
+				null : persister.getEntityName();
+	}
+
+	/**
+	 * Used during custom deserialization
+	 */
+	private EntityEntry(
+			final SessionFactoryImplementor factory,
+			final String entityName,
+			final Serializable id,
+			final EntityMode entityMode,
+			final Status status,
+			final Object[] loadedState,
+	        final Object[] deletedState,
+			final Object version,
+			final LockMode lockMode,
+			final boolean existsInDatabase,
+			final boolean isBeingReplicated,
+			final boolean loadedWithLazyPropertiesUnfetched) {
+		this.entityName = entityName;
+		this.persister = factory.getEntityPersister( entityName );
+		this.id = id;
+		this.entityMode = entityMode;
+		this.status = status;
+		this.loadedState = loadedState;
+		this.deletedState = deletedState;
+		this.version = version;
+		this.lockMode = lockMode;
+		this.existsInDatabase = existsInDatabase;
+		this.isBeingReplicated = isBeingReplicated;
+		this.loadedWithLazyPropertiesUnfetched = loadedWithLazyPropertiesUnfetched;
+		this.rowId = null; // this is equivalent to the old behavior...
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+
+	public void setLockMode(LockMode lockMode) {
+		this.lockMode = lockMode;
+	}
+
+	public Status getStatus() {
+		return status;
+	}
+
+	public void setStatus(Status status) {
+		if (status==Status.READ_ONLY) {
+			loadedState = null; //memory optimization
+		}
+		this.status = status;
+	}
+
+	public Serializable getId() {
+		return id;
+	}
+
+	public Object[] getLoadedState() {
+		return loadedState;
+	}
+
+	public Object[] getDeletedState() {
+		return deletedState;
+	}
+
+	public void setDeletedState(Object[] deletedState) {
+		this.deletedState = deletedState;
+	}
+
+	public boolean isExistsInDatabase() {
+		return existsInDatabase;
+	}
+
+	public Object getVersion() {
+		return version;
+	}
+
+	public EntityPersister getPersister() {
+		return persister;
+	}
+
+	void afterDeserialize(SessionFactoryImplementor factory) {
+		persister = factory.getEntityPersister( entityName );
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public boolean isBeingReplicated() {
+		return isBeingReplicated;
+	}
+	
+	public Object getRowId() {
+		return rowId;
+	}
+	
+	/**
+	 * After actually updating the database, update the snapshot information,
+	 * and escalate the lock mode
+	 */
+	public void postUpdate(Object entity, Object[] updatedState, Object nextVersion) {
+		this.loadedState = updatedState;
+		
+		setLockMode(LockMode.WRITE);
+		
+		if ( getPersister().isVersioned() ) {
+			this.version = nextVersion;
+			getPersister().setPropertyValue( 
+					entity, 
+					getPersister().getVersionProperty(), 
+					nextVersion, 
+					entityMode 
+				);
+		}
+		
+		FieldInterceptionHelper.clearDirty( entity );
+	}
+
+	/**
+	 * After actually deleting a row, record the fact that the instance no longer
+	 * exists in the database
+	 */
+	public void postDelete() {
+		status = Status.GONE;
+		existsInDatabase = false;
+	}
+	
+	/**
+	 * After actually inserting a row, record the fact that the instance exists on the 
+	 * database (needed for identity-column key generation)
+	 */
+	public void postInsert() {
+		existsInDatabase = true;
+	}
+	
+	public boolean isNullifiable(boolean earlyInsert, SessionImplementor session) {
+		return getStatus() == Status.SAVING || (
+				earlyInsert ?
+						!isExistsInDatabase() :
+						session.getPersistenceContext().getNullifiableEntityKeys()
+							.contains( new EntityKey( getId(), getPersister(), entityMode ) )
+				);
+	}
+	
+	public Object getLoadedValue(String propertyName) {
+		int propertyIndex = ( (UniqueKeyLoadable) persister ).getPropertyIndex(propertyName);
+		return loadedState[propertyIndex];
+	}
+	
+	
+	public boolean requiresDirtyCheck(Object entity) {
+		
+		boolean isMutableInstance = 
+				status != Status.READ_ONLY && 
+				persister.isMutable();
+		
+		return isMutableInstance && (
+				getPersister().hasMutableProperties() ||
+				!FieldInterceptionHelper.isInstrumented( entity ) ||
+				FieldInterceptionHelper.extractFieldInterceptor( entity).isDirty()
+			);
+		
+	}
+
+	public void forceLocked(Object entity, Object nextVersion) {
+		version = nextVersion;
+		loadedState[ persister.getVersionProperty() ] = version;
+		setLockMode( LockMode.FORCE );
+		persister.setPropertyValue(
+				entity,
+		        getPersister().getVersionProperty(),
+		        nextVersion,
+		        entityMode
+		);
+	}
+
+	public void setReadOnly(boolean readOnly, Object entity) {
+		if (status!=Status.MANAGED && status!=Status.READ_ONLY) {
+			throw new HibernateException("instance was not in a valid state");
+		}
+		if (readOnly) {
+			setStatus(Status.READ_ONLY);
+			loadedState = null;
+		}
+		else {
+			setStatus(Status.MANAGED);
+			loadedState = getPersister().getPropertyValues(entity, entityMode);
+		}
+	}
+	
+	public String toString() {
+		return "EntityEntry" + 
+				MessageHelper.infoString(entityName, id) + 
+				'(' + status + ')';
+	}
+
+	public boolean isLoadedWithLazyPropertiesUnfetched() {
+		return loadedWithLazyPropertiesUnfetched;
+	}
+
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws java.io.IOException
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeObject( entityName );
+		oos.writeObject( id );
+		oos.writeObject( entityMode.toString() );
+		oos.writeObject( status.toString() );
+		// todo : potentially look at optimizing these two arrays
+		oos.writeObject( loadedState );
+		oos.writeObject( deletedState );
+		oos.writeObject( version );
+		oos.writeObject( lockMode.toString() );
+		oos.writeBoolean( existsInDatabase );
+		oos.writeBoolean( isBeingReplicated );
+		oos.writeBoolean( loadedWithLazyPropertiesUnfetched );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @param session The session being deserialized.
+	 * @return The deserialized EntityEntry
+	 * @throws IOException
+	 * @throws ClassNotFoundException
+	 */
+	static EntityEntry deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		return new EntityEntry(
+				session.getFactory(),
+		        ( String ) ois.readObject(),
+				( Serializable ) ois.readObject(),
+	            EntityMode.parse( ( String ) ois.readObject() ),
+				Status.parse( ( String ) ois.readObject() ),
+	            ( Object[] ) ois.readObject(),
+	            ( Object[] ) ois.readObject(),
+	            ( Object ) ois.readObject(),
+	            LockMode.parse( ( String ) ois.readObject() ),
+	            ois.readBoolean(),
+	            ois.readBoolean(),
+	            ois.readBoolean()
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,156 +0,0 @@
-//$Id: EntityKey.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.util.SerializationHelper;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-
-/**
- * Uniquely identifies of an entity instance in a particular session by identifier.
- * <p/>
- * Uniqueing information consists of the entity-name and the identifier value.
- *
- * @see EntityUniqueKey
- * @author Gavin King
- */
-public final class EntityKey implements Serializable {
-	private final Serializable identifier;
-	private final String rootEntityName;
-	private final String entityName;
-	private final Type identifierType;
-	private final boolean isBatchLoadable;
-	private final SessionFactoryImplementor factory;
-	private final int hashCode;
-	private final EntityMode entityMode;
-
-	/**
-	 * Construct a unique identifier for an entity class instance
-	 */
-	public EntityKey(Serializable id, EntityPersister persister, EntityMode entityMode) {
-		if ( id == null ) {
-			throw new AssertionFailure( "null identifier" );
-		}
-		this.identifier = id; 
-		this.entityMode = entityMode;
-		this.rootEntityName = persister.getRootEntityName();
-		this.entityName = persister.getEntityName();
-		this.identifierType = persister.getIdentifierType();
-		this.isBatchLoadable = persister.isBatchLoadable();
-		this.factory = persister.getFactory();
-		hashCode = generateHashCode(); //cache the hashcode
-	}
-
-	/**
-	 * Used to reconstruct an EntityKey during deserialization.
-	 *
-	 * @param identifier The identifier value
-	 * @param rootEntityName The root entity name
-	 * @param entityName The specific entity name
-	 * @param identifierType The type of the identifier value
-	 * @param batchLoadable Whether represented entity is eligible for batch loading
-	 * @param factory The session factory
-	 * @param entityMode The entity's entity mode
-	 */
-	private EntityKey(
-			Serializable identifier,
-	        String rootEntityName,
-	        String entityName,
-	        Type identifierType,
-	        boolean batchLoadable,
-	        SessionFactoryImplementor factory,
-	        EntityMode entityMode) {
-		this.identifier = identifier;
-		this.rootEntityName = rootEntityName;
-		this.entityName = entityName;
-		this.identifierType = identifierType;
-		this.isBatchLoadable = batchLoadable;
-		this.factory = factory;
-		this.entityMode = entityMode;
-		this.hashCode = generateHashCode();
-	}
-
-	public boolean isBatchLoadable() {
-		return isBatchLoadable;
-	}
-
-	/**
-	 * Get the user-visible identifier
-	 */
-	public Serializable getIdentifier() {
-		return identifier;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public boolean equals(Object other) {
-		EntityKey otherKey = (EntityKey) other;
-		return otherKey.rootEntityName.equals(this.rootEntityName) && 
-			identifierType.isEqual(otherKey.identifier, this.identifier, entityMode, factory);
-	}
-	
-	private int generateHashCode() {
-		int result = 17;
-		result = 37 * result + rootEntityName.hashCode();
-		result = 37 * result + identifierType.getHashCode( identifier, entityMode, factory );
-		return result;
-	}
-
-	public int hashCode() {
-		return hashCode;
-	}
-
-	public String toString() {
-		return "EntityKey" + 
-			MessageHelper.infoString( factory.getEntityPersister( entityName ), identifier, factory );
-	}
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws IOException
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeObject( identifier );
-		oos.writeObject( rootEntityName );
-		oos.writeObject( entityName );
-		oos.writeObject( identifierType );
-		oos.writeBoolean( isBatchLoadable );
-		oos.writeObject( entityMode.toString() );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @param session The session being deserialized.
-	 * @return The deserialized EntityEntry
-	 * @throws IOException
-	 * @throws ClassNotFoundException
-	 */
-	static EntityKey deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		return new EntityKey(
-				( Serializable ) ois.readObject(),
-		        ( String ) ois.readObject(),
-		        ( String ) ois.readObject(),
-		        ( Type ) ois.readObject(),
-		        ois.readBoolean(),
-		        session.getFactory(),
-		        EntityMode.parse( ( String ) ois.readObject() )
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/EntityKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,178 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+
+/**
+ * Uniquely identifies of an entity instance in a particular session by identifier.
+ * <p/>
+ * Uniqueing information consists of the entity-name and the identifier value.
+ *
+ * @see EntityUniqueKey
+ * @author Gavin King
+ */
+public final class EntityKey implements Serializable {
+	private final Serializable identifier;
+	private final String rootEntityName;
+	private final String entityName;
+	private final Type identifierType;
+	private final boolean isBatchLoadable;
+	private final SessionFactoryImplementor factory;
+	private final int hashCode;
+	private final EntityMode entityMode;
+
+	/**
+	 * Construct a unique identifier for an entity class instance
+	 */
+	public EntityKey(Serializable id, EntityPersister persister, EntityMode entityMode) {
+		if ( id == null ) {
+			throw new AssertionFailure( "null identifier" );
+		}
+		this.identifier = id; 
+		this.entityMode = entityMode;
+		this.rootEntityName = persister.getRootEntityName();
+		this.entityName = persister.getEntityName();
+		this.identifierType = persister.getIdentifierType();
+		this.isBatchLoadable = persister.isBatchLoadable();
+		this.factory = persister.getFactory();
+		hashCode = generateHashCode(); //cache the hashcode
+	}
+
+	/**
+	 * Used to reconstruct an EntityKey during deserialization.
+	 *
+	 * @param identifier The identifier value
+	 * @param rootEntityName The root entity name
+	 * @param entityName The specific entity name
+	 * @param identifierType The type of the identifier value
+	 * @param batchLoadable Whether represented entity is eligible for batch loading
+	 * @param factory The session factory
+	 * @param entityMode The entity's entity mode
+	 */
+	private EntityKey(
+			Serializable identifier,
+	        String rootEntityName,
+	        String entityName,
+	        Type identifierType,
+	        boolean batchLoadable,
+	        SessionFactoryImplementor factory,
+	        EntityMode entityMode) {
+		this.identifier = identifier;
+		this.rootEntityName = rootEntityName;
+		this.entityName = entityName;
+		this.identifierType = identifierType;
+		this.isBatchLoadable = batchLoadable;
+		this.factory = factory;
+		this.entityMode = entityMode;
+		this.hashCode = generateHashCode();
+	}
+
+	public boolean isBatchLoadable() {
+		return isBatchLoadable;
+	}
+
+	/**
+	 * Get the user-visible identifier
+	 */
+	public Serializable getIdentifier() {
+		return identifier;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public boolean equals(Object other) {
+		EntityKey otherKey = (EntityKey) other;
+		return otherKey.rootEntityName.equals(this.rootEntityName) && 
+			identifierType.isEqual(otherKey.identifier, this.identifier, entityMode, factory);
+	}
+	
+	private int generateHashCode() {
+		int result = 17;
+		result = 37 * result + rootEntityName.hashCode();
+		result = 37 * result + identifierType.getHashCode( identifier, entityMode, factory );
+		return result;
+	}
+
+	public int hashCode() {
+		return hashCode;
+	}
+
+	public String toString() {
+		return "EntityKey" + 
+			MessageHelper.infoString( factory.getEntityPersister( entityName ), identifier, factory );
+	}
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws IOException
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeObject( identifier );
+		oos.writeObject( rootEntityName );
+		oos.writeObject( entityName );
+		oos.writeObject( identifierType );
+		oos.writeBoolean( isBatchLoadable );
+		oos.writeObject( entityMode.toString() );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @param session The session being deserialized.
+	 * @return The deserialized EntityEntry
+	 * @throws IOException
+	 * @throws ClassNotFoundException
+	 */
+	static EntityKey deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		return new EntityKey(
+				( Serializable ) ois.readObject(),
+		        ( String ) ois.readObject(),
+		        ( String ) ois.readObject(),
+		        ( Type ) ois.readObject(),
+		        ois.readBoolean(),
+		        session.getFactory(),
+		        EntityMode.parse( ( String ) ois.readObject() )
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,137 +0,0 @@
-//$Id: EntityUniqueKey.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate.engine;
-
-import org.hibernate.EntityMode;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-/**
- * Used to uniquely key an entity instance in relation to a particular session
- * by some unique property reference, as opposed to identifier.
- * <p/>
- * Uniqueing information consists of the entity-name, the referenced
- * property name, and the referenced property value.
- *
- * @see EntityKey
- * @author Gavin King
- */
-public class EntityUniqueKey implements Serializable {
-	private final String uniqueKeyName;
-	private final String entityName;
-	private final Object key;
-	private final Type keyType;
-	private final EntityMode entityMode;
-	private final int hashCode;
-
-	public EntityUniqueKey(
-			final String entityName,
-	        final String uniqueKeyName,
-	        final Object semiResolvedKey,
-	        final Type keyType,
-	        final EntityMode entityMode,
-	        final SessionFactoryImplementor factory
-	) {
-		this.uniqueKeyName = uniqueKeyName;
-		this.entityName = entityName;
-		this.key = semiResolvedKey;
-		this.keyType = keyType.getSemiResolvedType(factory);
-		this.entityMode = entityMode;
-		this.hashCode = generateHashCode(factory);
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public Object getKey() {
-		return key;
-	}
-
-	public String getUniqueKeyName() {
-		return uniqueKeyName;
-	}
-
-	public int generateHashCode(SessionFactoryImplementor factory) {
-		int result = 17;
-		result = 37 * result + entityName.hashCode();
-		result = 37 * result + uniqueKeyName.hashCode();
-		result = 37 * result + keyType.getHashCode(key, entityMode, factory);
-		return result;
-	}
-
-	public int hashCode() {
-		return hashCode;
-	}
-
-	public boolean equals(Object other) {
-		EntityUniqueKey that = (EntityUniqueKey) other;
-		return that.entityName.equals(entityName) &&
-		       that.uniqueKeyName.equals(uniqueKeyName) &&
-		       keyType.isEqual(that.key, key, entityMode);
-	}
-
-	public String toString() {
-		return "EntityUniqueKey" + MessageHelper.infoString(entityName, uniqueKeyName, key);
-	}
-
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		checkAbilityToSerialize();
-		oos.defaultWriteObject();
-	}
-
-	private void checkAbilityToSerialize() {
-		// The unique property value represented here may or may not be
-		// serializable, so we do an explicit check here in order to generate
-		// a better error message
-		if ( key != null && ! Serializable.class.isAssignableFrom( key.getClass() ) ) {
-			throw new IllegalStateException(
-					"Cannot serialize an EntityUniqueKey which represents a non " +
-					"serializable property value [" + entityName + "." + uniqueKeyName + "]"
-			);
-		}
-	}
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws IOException
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		checkAbilityToSerialize();
-		oos.writeObject( uniqueKeyName );
-		oos.writeObject( entityName );
-		oos.writeObject( key );
-		oos.writeObject( keyType );
-		oos.writeObject( entityMode );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @param session The session being deserialized.
-	 * @return The deserialized EntityEntry
-	 * @throws IOException
-	 * @throws ClassNotFoundException
-	 */
-	static EntityUniqueKey deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		return new EntityUniqueKey(
-				( String ) ois.readObject(),
-		        ( String ) ois.readObject(),
-		        ois.readObject(),
-		        ( Type ) ois.readObject(),
-		        ( EntityMode ) ois.readObject(),
-		        session.getFactory()
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/EntityUniqueKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,160 @@
+/*
+ * 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.engine;
+
+import org.hibernate.EntityMode;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
+/**
+ * Used to uniquely key an entity instance in relation to a particular session
+ * by some unique property reference, as opposed to identifier.
+ * <p/>
+ * Uniqueing information consists of the entity-name, the referenced
+ * property name, and the referenced property value.
+ *
+ * @see EntityKey
+ * @author Gavin King
+ */
+public class EntityUniqueKey implements Serializable {
+	private final String uniqueKeyName;
+	private final String entityName;
+	private final Object key;
+	private final Type keyType;
+	private final EntityMode entityMode;
+	private final int hashCode;
+
+	public EntityUniqueKey(
+			final String entityName,
+	        final String uniqueKeyName,
+	        final Object semiResolvedKey,
+	        final Type keyType,
+	        final EntityMode entityMode,
+	        final SessionFactoryImplementor factory
+	) {
+		this.uniqueKeyName = uniqueKeyName;
+		this.entityName = entityName;
+		this.key = semiResolvedKey;
+		this.keyType = keyType.getSemiResolvedType(factory);
+		this.entityMode = entityMode;
+		this.hashCode = generateHashCode(factory);
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public Object getKey() {
+		return key;
+	}
+
+	public String getUniqueKeyName() {
+		return uniqueKeyName;
+	}
+
+	public int generateHashCode(SessionFactoryImplementor factory) {
+		int result = 17;
+		result = 37 * result + entityName.hashCode();
+		result = 37 * result + uniqueKeyName.hashCode();
+		result = 37 * result + keyType.getHashCode(key, entityMode, factory);
+		return result;
+	}
+
+	public int hashCode() {
+		return hashCode;
+	}
+
+	public boolean equals(Object other) {
+		EntityUniqueKey that = (EntityUniqueKey) other;
+		return that.entityName.equals(entityName) &&
+		       that.uniqueKeyName.equals(uniqueKeyName) &&
+		       keyType.isEqual(that.key, key, entityMode);
+	}
+
+	public String toString() {
+		return "EntityUniqueKey" + MessageHelper.infoString(entityName, uniqueKeyName, key);
+	}
+
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		checkAbilityToSerialize();
+		oos.defaultWriteObject();
+	}
+
+	private void checkAbilityToSerialize() {
+		// The unique property value represented here may or may not be
+		// serializable, so we do an explicit check here in order to generate
+		// a better error message
+		if ( key != null && ! Serializable.class.isAssignableFrom( key.getClass() ) ) {
+			throw new IllegalStateException(
+					"Cannot serialize an EntityUniqueKey which represents a non " +
+					"serializable property value [" + entityName + "." + uniqueKeyName + "]"
+			);
+		}
+	}
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws IOException
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		checkAbilityToSerialize();
+		oos.writeObject( uniqueKeyName );
+		oos.writeObject( entityName );
+		oos.writeObject( key );
+		oos.writeObject( keyType );
+		oos.writeObject( entityMode );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @param session The session being deserialized.
+	 * @return The deserialized EntityEntry
+	 * @throws IOException
+	 * @throws ClassNotFoundException
+	 */
+	static EntityUniqueKey deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		return new EntityUniqueKey(
+				( String ) ois.readObject(),
+		        ( String ) ois.readObject(),
+		        ois.readObject(),
+		        ( Type ) ois.readObject(),
+		        ( EntityMode ) ois.readObject(),
+		        session.getFactory()
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,73 +0,0 @@
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.io.InvalidObjectException;
-
-/**
- * For persistence operations (INSERT, UPDATE, DELETE) what style of determining
- * results (success/failure) is to be used.
- *
- * @author Steve Ebersole
- */
-public class ExecuteUpdateResultCheckStyle implements Serializable {
-	/**
-	 * Do not perform checking.  Either user simply does not want checking, or is
-	 * indicating a {@link java.sql.CallableStatement} execution in which the
-	 * checks are being performed explicitly and failures are handled through
-	 * propogation of {@link java.sql.SQLException}s.
-	 */
-	public static final ExecuteUpdateResultCheckStyle NONE = new ExecuteUpdateResultCheckStyle( "none" );
-	/**
-	 * Perform row-count checking.  Row counts are the int values returned by both
-	 * {@link java.sql.PreparedStatement#executeUpdate()} and
-	 * {@link java.sql.Statement#executeBatch()}.  These values are checked
-	 * against some expected count.
-	 */
-	public static final ExecuteUpdateResultCheckStyle COUNT = new ExecuteUpdateResultCheckStyle( "rowcount" );
-	/**
-	 * Essentially the same as {@link #COUNT} except that the row count actually
-	 * comes from an output parameter registered as part of a
-	 * {@link java.sql.CallableStatement}.  This style explicitly prohibits
-	 * statement batching from being used...
-	 */
-	public static final ExecuteUpdateResultCheckStyle PARAM = new ExecuteUpdateResultCheckStyle( "param" );
-
-	private final String name;
-
-	private ExecuteUpdateResultCheckStyle(String name) {
-		this.name = name;
-	}
-
-	private Object readResolve() throws ObjectStreamException {
-		Object resolved = parse( name );
-		if ( resolved == null ) {
-			throw new InvalidObjectException( "unknown result style [" + name + "]" );
-		}
-		return resolved;
-	}
-
-	public static ExecuteUpdateResultCheckStyle parse(String name) {
-		if ( name.equals( NONE.name ) ) {
-			return NONE;
-		}
-		else if ( name.equals( COUNT.name ) ) {
-			return COUNT;
-		}
-		else if ( name.equals( PARAM.name ) ) {
-			return PARAM;
-		}
-		else {
-			return null;
-		}
-	}
-
-	public static ExecuteUpdateResultCheckStyle determineDefault(String customSql, boolean callable) {
-		if ( customSql == null ) {
-			return COUNT;
-		}
-		else {
-			return callable ? PARAM : COUNT;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ExecuteUpdateResultCheckStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.io.InvalidObjectException;
+
+/**
+ * For persistence operations (INSERT, UPDATE, DELETE) what style of determining
+ * results (success/failure) is to be used.
+ *
+ * @author Steve Ebersole
+ */
+public class ExecuteUpdateResultCheckStyle implements Serializable {
+	/**
+	 * Do not perform checking.  Either user simply does not want checking, or is
+	 * indicating a {@link java.sql.CallableStatement} execution in which the
+	 * checks are being performed explicitly and failures are handled through
+	 * propogation of {@link java.sql.SQLException}s.
+	 */
+	public static final ExecuteUpdateResultCheckStyle NONE = new ExecuteUpdateResultCheckStyle( "none" );
+	/**
+	 * Perform row-count checking.  Row counts are the int values returned by both
+	 * {@link java.sql.PreparedStatement#executeUpdate()} and
+	 * {@link java.sql.Statement#executeBatch()}.  These values are checked
+	 * against some expected count.
+	 */
+	public static final ExecuteUpdateResultCheckStyle COUNT = new ExecuteUpdateResultCheckStyle( "rowcount" );
+	/**
+	 * Essentially the same as {@link #COUNT} except that the row count actually
+	 * comes from an output parameter registered as part of a
+	 * {@link java.sql.CallableStatement}.  This style explicitly prohibits
+	 * statement batching from being used...
+	 */
+	public static final ExecuteUpdateResultCheckStyle PARAM = new ExecuteUpdateResultCheckStyle( "param" );
+
+	private final String name;
+
+	private ExecuteUpdateResultCheckStyle(String name) {
+		this.name = name;
+	}
+
+	private Object readResolve() throws ObjectStreamException {
+		Object resolved = parse( name );
+		if ( resolved == null ) {
+			throw new InvalidObjectException( "unknown result style [" + name + "]" );
+		}
+		return resolved;
+	}
+
+	public static ExecuteUpdateResultCheckStyle parse(String name) {
+		if ( name.equals( NONE.name ) ) {
+			return NONE;
+		}
+		else if ( name.equals( COUNT.name ) ) {
+			return COUNT;
+		}
+		else if ( name.equals( PARAM.name ) ) {
+			return PARAM;
+		}
+		else {
+			return null;
+		}
+	}
+
+	public static ExecuteUpdateResultCheckStyle determineDefault(String customSql, boolean callable) {
+		if ( customSql == null ) {
+			return COUNT;
+		}
+		else {
+			return callable ? PARAM : COUNT;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/FilterDefinition.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-// $Id: FilterDefinition.java 9765 2006-04-19 01:45:07Z max.andersen at jboss.com $
-package org.hibernate.engine;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Set;
-
-/**
- * A FilterDefinition defines the global attributes of a dynamic filter.  This
- * information includes its name as well as its defined parameters (name and type).
- * 
- * @author Steve Ebersole
- */
-public class FilterDefinition implements Serializable {
-	private final String filterName;
-	private final String defaultFilterCondition;
-	private final Map parameterTypes = new HashMap();
-
-	/**
-	 * Construct a new FilterDefinition instance.
-	 *
-	 * @param name The name of the filter for which this configuration is in effect.
-	 */
-	public FilterDefinition(String name, String defaultCondition, Map parameterTypes) {
-		this.filterName = name;
-		this.defaultFilterCondition = defaultCondition;
-		this.parameterTypes.putAll( parameterTypes );
-	}
-
-	/**
-	 * Get the name of the filter this configuration defines.
-	 *
-	 * @return The filter name for this configuration.
-	 */
-	public String getFilterName() {
-		return filterName;
-	}
-
-	/**
-	 * Get a set of the parameters defined by this configuration.
-	 *
-	 * @return The parameters named by this configuration.
-	 */
-	public Set getParameterNames() {
-		return parameterTypes.keySet();
-	}
-
-	/**
-	 * Retreive the type of the named parameter defined for this filter.
-	 *
-	 * @param parameterName The name of the filter parameter for which to return the type.
-	 * @return The type of the named parameter.
-	 */
-    public Type getParameterType(String parameterName) {
-	    return (Type) parameterTypes.get(parameterName);
-    }
-
-	public String getDefaultFilterCondition() {
-		return defaultFilterCondition;
-	}
-
-	public Map getParameterTypes() {
-		return parameterTypes;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/FilterDefinition.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/FilterDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.engine;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+
+/**
+ * A FilterDefinition defines the global attributes of a dynamic filter.  This
+ * information includes its name as well as its defined parameters (name and type).
+ * 
+ * @author Steve Ebersole
+ */
+public class FilterDefinition implements Serializable {
+	private final String filterName;
+	private final String defaultFilterCondition;
+	private final Map parameterTypes = new HashMap();
+
+	/**
+	 * Construct a new FilterDefinition instance.
+	 *
+	 * @param name The name of the filter for which this configuration is in effect.
+	 */
+	public FilterDefinition(String name, String defaultCondition, Map parameterTypes) {
+		this.filterName = name;
+		this.defaultFilterCondition = defaultCondition;
+		this.parameterTypes.putAll( parameterTypes );
+	}
+
+	/**
+	 * Get the name of the filter this configuration defines.
+	 *
+	 * @return The filter name for this configuration.
+	 */
+	public String getFilterName() {
+		return filterName;
+	}
+
+	/**
+	 * Get a set of the parameters defined by this configuration.
+	 *
+	 * @return The parameters named by this configuration.
+	 */
+	public Set getParameterNames() {
+		return parameterTypes.keySet();
+	}
+
+	/**
+	 * Retreive the type of the named parameter defined for this filter.
+	 *
+	 * @param parameterName The name of the filter parameter for which to return the type.
+	 * @return The type of the named parameter.
+	 */
+    public Type getParameterType(String parameterName) {
+	    return (Type) parameterTypes.get(parameterName);
+    }
+
+	public String getDefaultFilterCondition() {
+		return defaultFilterCondition;
+	}
+
+	public Map getParameterTypes() {
+		return parameterTypes;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ForeignKeys.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,230 +0,0 @@
-//$Id: ForeignKeys.java 10133 2006-07-24 10:35:25Z max.andersen at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-
-/**
- * Algorithms related to foreign key constraint transparency
- * 
- * @author Gavin King
- */
-public final class ForeignKeys {
-	
-	private ForeignKeys() {}
-	
-	public static class Nullifier {
-	
-		private final boolean isDelete;
-		private final boolean isEarlyInsert;
-		private final SessionImplementor session;
-		private final Object self;
-		
-		public Nullifier(Object self, boolean isDelete, boolean isEarlyInsert, SessionImplementor session) {
-			this.isDelete = isDelete;
-			this.isEarlyInsert = isEarlyInsert;
-			this.session = session;
-			this.self = self;
-		}
-		
-		/**
-		 * Nullify all references to entities that have not yet 
-		 * been inserted in the database, where the foreign key
-		 * points toward that entity
-		 */
-		public void nullifyTransientReferences(final Object[] values, final Type[] types) 
-		throws HibernateException {
-			for ( int i = 0; i < types.length; i++ ) {
-				values[i] = nullifyTransientReferences( values[i], types[i] );
-			}
-		}
-	
-		/**
-		 * Return null if the argument is an "unsaved" entity (ie. 
-		 * one with no existing database row), or the input argument 
-		 * otherwise. This is how Hibernate avoids foreign key constraint
-		 * violations.
-		 */
-		private Object nullifyTransientReferences(final Object value, final Type type) 
-		throws HibernateException {
-			if ( value == null ) {
-				return null;
-			}
-			else if ( type.isEntityType() ) {
-				EntityType entityType = (EntityType) type;
-				if ( entityType.isOneToOne() ) {
-					return value;
-				}
-				else {
-					String entityName = entityType.getAssociatedEntityName();
-					return isNullifiable(entityName, value) ? null : value;
-				}
-			}
-			else if ( type.isAnyType() ) {
-				return isNullifiable(null, value) ? null : value;
-			}
-			else if ( type.isComponentType() ) {
-				AbstractComponentType actype = (AbstractComponentType) type;
-				Object[] subvalues = actype.getPropertyValues(value, session);
-				Type[] subtypes = actype.getSubtypes();
-				boolean substitute = false;
-				for ( int i = 0; i < subvalues.length; i++ ) {
-					Object replacement = nullifyTransientReferences( subvalues[i], subtypes[i] );
-					if ( replacement != subvalues[i] ) {
-						substitute = true;
-						subvalues[i] = replacement;
-					}
-				}
-				if (substitute) actype.setPropertyValues( value, subvalues, session.getEntityMode() );
-				return value;
-			}
-			else {
-				return value;
-			}
-		}
-	
-		/**
-		 * Determine if the object already exists in the database, 
-		 * using a "best guess"
-		 */
-		private boolean isNullifiable(final String entityName, Object object) 
-		throws HibernateException {
-			
-			if (object==LazyPropertyInitializer.UNFETCHED_PROPERTY) return false; //this is kinda the best we can do...
-			
-			if ( object instanceof HibernateProxy ) {
-				// if its an uninitialized proxy it can't be transient
-				LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
-				if ( li.getImplementation(session) == null ) {
-					return false;
-					// ie. we never have to null out a reference to
-					// an uninitialized proxy
-				}
-				else {
-					//unwrap it
-					object = li.getImplementation();
-				}
-			}
-	
-			// if it was a reference to self, don't need to nullify
-			// unless we are using native id generation, in which
-			// case we definitely need to nullify
-			if ( object == self ) {
-				return isEarlyInsert || (
-					isDelete &&
-					session.getFactory()
-						.getDialect()
-						.hasSelfReferentialForeignKeyBug()
-				);
-			}
-	
-			// See if the entity is already bound to this session, if not look at the
-			// entity identifier and assume that the entity is persistent if the
-			// id is not "unsaved" (that is, we rely on foreign keys to keep
-			// database integrity)
-	
-			EntityEntry entityEntry = session.getPersistenceContext().getEntry(object);
-			if ( entityEntry==null ) {
-				return isTransient(entityName, object, null, session);
-			}
-			else {
-				return entityEntry.isNullifiable(isEarlyInsert, session);
-			}
-	
-		}
-		
-	}
-	
-	/**
-	 * Is this instance persistent or detached?
-	 * If <tt>assumed</tt> is non-null, don't hit the database to make the 
-	 * determination, instead assume that value; the client code must be 
-	 * prepared to "recover" in the case that this assumed result is incorrect.
-	 */
-	public static boolean isNotTransient(String entityName, Object entity, Boolean assumed, SessionImplementor session) 
-	throws HibernateException {
-		if (entity instanceof HibernateProxy) return true;
-		if ( session.getPersistenceContext().isEntryFor(entity) ) return true;
-		return !isTransient(entityName, entity, assumed, session);
-	}
-	
-	/**
-	 * Is this instance, which we know is not persistent, actually transient?
-	 * If <tt>assumed</tt> is non-null, don't hit the database to make the 
-	 * determination, instead assume that value; the client code must be 
-	 * prepared to "recover" in the case that this assumed result is incorrect.
-	 */
-	public static boolean isTransient(String entityName, Object entity, Boolean assumed, SessionImplementor session) 
-	throws HibernateException {
-		
-		if (entity==LazyPropertyInitializer.UNFETCHED_PROPERTY) {
-			// an unfetched association can only point to
-			// an entity that already exists in the db
-			return false;
-		}
-		
-		// let the interceptor inspect the instance to decide
-		Boolean isUnsaved = session.getInterceptor().isTransient(entity);
-		if (isUnsaved!=null) return isUnsaved.booleanValue();
-		
-		// let the persister inspect the instance to decide
-		EntityPersister persister = session.getEntityPersister(entityName, entity);
-		isUnsaved = persister.isTransient(entity, session);
-		if (isUnsaved!=null) return isUnsaved.booleanValue();
-
-		// we use the assumed value, if there is one, to avoid hitting
-		// the database
-		if (assumed!=null) return assumed.booleanValue();
-		
-		// hit the database, after checking the session cache for a snapshot
-		Object[] snapshot = session.getPersistenceContext()
-		        .getDatabaseSnapshot( persister.getIdentifier( entity, session.getEntityMode() ), persister );
-		return snapshot==null;
-
-	}
-
-	/**
-	 * Return the identifier of the persistent or transient object, or throw
-	 * an exception if the instance is "unsaved"
-	 *
-	 * Used by OneToOneType and ManyToOneType to determine what id value should 
-	 * be used for an object that may or may not be associated with the session. 
-	 * This does a "best guess" using any/all info available to use (not just the 
-	 * EntityEntry).
-	 */
-	public static Serializable getEntityIdentifierIfNotUnsaved(
-			final String entityName, 
-			final Object object, 
-			final SessionImplementor session) 
-	throws HibernateException {
-		if ( object == null ) {
-			return null;
-		}
-		else {
-			Serializable id = session.getContextEntityIdentifier( object );
-			if ( id == null ) {
-				// context-entity-identifier returns null explicitly if the entity
-				// is not associated with the persistence context; so make some
-				// deeper checks...
-				if ( isTransient(entityName, object, Boolean.FALSE, session) ) {
-					throw new TransientObjectException(
-							"object references an unsaved transient instance - save the transient instance before flushing: " +
-							(entityName == null ? session.guessEntityName( object ) : entityName)
-					);
-				}
-				id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() );
-			}
-			return id;
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ForeignKeys.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ForeignKeys.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,253 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * Algorithms related to foreign key constraint transparency
+ * 
+ * @author Gavin King
+ */
+public final class ForeignKeys {
+	
+	private ForeignKeys() {}
+	
+	public static class Nullifier {
+	
+		private final boolean isDelete;
+		private final boolean isEarlyInsert;
+		private final SessionImplementor session;
+		private final Object self;
+		
+		public Nullifier(Object self, boolean isDelete, boolean isEarlyInsert, SessionImplementor session) {
+			this.isDelete = isDelete;
+			this.isEarlyInsert = isEarlyInsert;
+			this.session = session;
+			this.self = self;
+		}
+		
+		/**
+		 * Nullify all references to entities that have not yet 
+		 * been inserted in the database, where the foreign key
+		 * points toward that entity
+		 */
+		public void nullifyTransientReferences(final Object[] values, final Type[] types) 
+		throws HibernateException {
+			for ( int i = 0; i < types.length; i++ ) {
+				values[i] = nullifyTransientReferences( values[i], types[i] );
+			}
+		}
+	
+		/**
+		 * Return null if the argument is an "unsaved" entity (ie. 
+		 * one with no existing database row), or the input argument 
+		 * otherwise. This is how Hibernate avoids foreign key constraint
+		 * violations.
+		 */
+		private Object nullifyTransientReferences(final Object value, final Type type) 
+		throws HibernateException {
+			if ( value == null ) {
+				return null;
+			}
+			else if ( type.isEntityType() ) {
+				EntityType entityType = (EntityType) type;
+				if ( entityType.isOneToOne() ) {
+					return value;
+				}
+				else {
+					String entityName = entityType.getAssociatedEntityName();
+					return isNullifiable(entityName, value) ? null : value;
+				}
+			}
+			else if ( type.isAnyType() ) {
+				return isNullifiable(null, value) ? null : value;
+			}
+			else if ( type.isComponentType() ) {
+				AbstractComponentType actype = (AbstractComponentType) type;
+				Object[] subvalues = actype.getPropertyValues(value, session);
+				Type[] subtypes = actype.getSubtypes();
+				boolean substitute = false;
+				for ( int i = 0; i < subvalues.length; i++ ) {
+					Object replacement = nullifyTransientReferences( subvalues[i], subtypes[i] );
+					if ( replacement != subvalues[i] ) {
+						substitute = true;
+						subvalues[i] = replacement;
+					}
+				}
+				if (substitute) actype.setPropertyValues( value, subvalues, session.getEntityMode() );
+				return value;
+			}
+			else {
+				return value;
+			}
+		}
+	
+		/**
+		 * Determine if the object already exists in the database, 
+		 * using a "best guess"
+		 */
+		private boolean isNullifiable(final String entityName, Object object) 
+		throws HibernateException {
+			
+			if (object==LazyPropertyInitializer.UNFETCHED_PROPERTY) return false; //this is kinda the best we can do...
+			
+			if ( object instanceof HibernateProxy ) {
+				// if its an uninitialized proxy it can't be transient
+				LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
+				if ( li.getImplementation(session) == null ) {
+					return false;
+					// ie. we never have to null out a reference to
+					// an uninitialized proxy
+				}
+				else {
+					//unwrap it
+					object = li.getImplementation();
+				}
+			}
+	
+			// if it was a reference to self, don't need to nullify
+			// unless we are using native id generation, in which
+			// case we definitely need to nullify
+			if ( object == self ) {
+				return isEarlyInsert || (
+					isDelete &&
+					session.getFactory()
+						.getDialect()
+						.hasSelfReferentialForeignKeyBug()
+				);
+			}
+	
+			// See if the entity is already bound to this session, if not look at the
+			// entity identifier and assume that the entity is persistent if the
+			// id is not "unsaved" (that is, we rely on foreign keys to keep
+			// database integrity)
+	
+			EntityEntry entityEntry = session.getPersistenceContext().getEntry(object);
+			if ( entityEntry==null ) {
+				return isTransient(entityName, object, null, session);
+			}
+			else {
+				return entityEntry.isNullifiable(isEarlyInsert, session);
+			}
+	
+		}
+		
+	}
+	
+	/**
+	 * Is this instance persistent or detached?
+	 * If <tt>assumed</tt> is non-null, don't hit the database to make the 
+	 * determination, instead assume that value; the client code must be 
+	 * prepared to "recover" in the case that this assumed result is incorrect.
+	 */
+	public static boolean isNotTransient(String entityName, Object entity, Boolean assumed, SessionImplementor session) 
+	throws HibernateException {
+		if (entity instanceof HibernateProxy) return true;
+		if ( session.getPersistenceContext().isEntryFor(entity) ) return true;
+		return !isTransient(entityName, entity, assumed, session);
+	}
+	
+	/**
+	 * Is this instance, which we know is not persistent, actually transient?
+	 * If <tt>assumed</tt> is non-null, don't hit the database to make the 
+	 * determination, instead assume that value; the client code must be 
+	 * prepared to "recover" in the case that this assumed result is incorrect.
+	 */
+	public static boolean isTransient(String entityName, Object entity, Boolean assumed, SessionImplementor session) 
+	throws HibernateException {
+		
+		if (entity==LazyPropertyInitializer.UNFETCHED_PROPERTY) {
+			// an unfetched association can only point to
+			// an entity that already exists in the db
+			return false;
+		}
+		
+		// let the interceptor inspect the instance to decide
+		Boolean isUnsaved = session.getInterceptor().isTransient(entity);
+		if (isUnsaved!=null) return isUnsaved.booleanValue();
+		
+		// let the persister inspect the instance to decide
+		EntityPersister persister = session.getEntityPersister(entityName, entity);
+		isUnsaved = persister.isTransient(entity, session);
+		if (isUnsaved!=null) return isUnsaved.booleanValue();
+
+		// we use the assumed value, if there is one, to avoid hitting
+		// the database
+		if (assumed!=null) return assumed.booleanValue();
+		
+		// hit the database, after checking the session cache for a snapshot
+		Object[] snapshot = session.getPersistenceContext()
+		        .getDatabaseSnapshot( persister.getIdentifier( entity, session.getEntityMode() ), persister );
+		return snapshot==null;
+
+	}
+
+	/**
+	 * Return the identifier of the persistent or transient object, or throw
+	 * an exception if the instance is "unsaved"
+	 *
+	 * Used by OneToOneType and ManyToOneType to determine what id value should 
+	 * be used for an object that may or may not be associated with the session. 
+	 * This does a "best guess" using any/all info available to use (not just the 
+	 * EntityEntry).
+	 */
+	public static Serializable getEntityIdentifierIfNotUnsaved(
+			final String entityName, 
+			final Object object, 
+			final SessionImplementor session) 
+	throws HibernateException {
+		if ( object == null ) {
+			return null;
+		}
+		else {
+			Serializable id = session.getContextEntityIdentifier( object );
+			if ( id == null ) {
+				// context-entity-identifier returns null explicitly if the entity
+				// is not associated with the persistence context; so make some
+				// deeper checks...
+				if ( isTransient(entityName, object, Boolean.FALSE, session) ) {
+					throw new TransientObjectException(
+							"object references an unsaved transient instance - save the transient instance before flushing: " +
+							(entityName == null ? session.guessEntityName( object ) : entityName)
+					);
+				}
+				id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() );
+			}
+			return id;
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/HibernateIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: HibernateIterator.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.engine;
-
-import org.hibernate.JDBCException;
-
-import java.util.Iterator;
-
-/**
- * An iterator that may be "closed"
- * @see org.hibernate.Hibernate#close(java.util.Iterator)
- * @author Gavin King
- */
-public interface HibernateIterator extends Iterator {
-	public void close() throws JDBCException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/HibernateIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/HibernateIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import org.hibernate.JDBCException;
+
+import java.util.Iterator;
+
+/**
+ * An iterator that may be "closed"
+ * @see org.hibernate.Hibernate#close(java.util.Iterator)
+ * @author Gavin King
+ */
+public interface HibernateIterator extends Iterator {
+	public void close() throws JDBCException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/IdentifierValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,115 +0,0 @@
-//$Id: IdentifierValue.java 7017 2005-06-05 04:31:34Z oneovthafew $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A strategy for determining if an identifier value is an identifier of
- * a new transient instance or a previously persistent transient instance.
- * The strategy is determined by the <tt>unsaved-value</tt> attribute in
- * the mapping file.
- * 
- * @author Gavin King
- */
-public class IdentifierValue {
-
-	private static final Logger log = LoggerFactory.getLogger(IdentifierValue.class);
-	
-	private final Serializable value;
-	
-	/**
-	 * Always assume the transient instance is newly instantiated
-	 */
-	public static final IdentifierValue ANY = new IdentifierValue() {
-		public final Boolean isUnsaved(Serializable id) {
-			log.trace("id unsaved-value strategy ANY");
-			return Boolean.TRUE;
-		}
-		public Serializable getDefaultValue(Serializable currentValue) {
-			return currentValue;
-		}
-		public String toString() {
-			return "SAVE_ANY";
-		}
-	};
-	
-	/**
-	 * Never assume the transient instance is newly instantiated
-	 */
-	public static final IdentifierValue NONE = new IdentifierValue() {
-		public final Boolean isUnsaved(Serializable id) {
-			log.trace("id unsaved-value strategy NONE");
-			return Boolean.FALSE;
-		}
-		public Serializable getDefaultValue(Serializable currentValue) {
-			return currentValue;
-		}
-		public String toString() {
-			return "SAVE_NONE";
-		}
-	};
-	
-	/**
-	 * Assume the transient instance is newly instantiated if the identifier
-	 * is null.
-	 */
-	public static final IdentifierValue NULL = new IdentifierValue() {
-		public final Boolean isUnsaved(Serializable id) {
-			log.trace("id unsaved-value strategy NULL");
-			return id==null ? Boolean.TRUE : Boolean.FALSE;
-		}
-		public Serializable getDefaultValue(Serializable currentValue) {
-			return null;
-		}
-		public String toString() {
-			return "SAVE_NULL";
-		}
-	};
-	
-	/**
-	 * Assume nothing.
-	 */
-	public static final IdentifierValue UNDEFINED = new IdentifierValue() {
-		public final Boolean isUnsaved(Serializable id) {
-			log.trace("id unsaved-value strategy UNDEFINED");
-			return null;
-		}
-		public Serializable getDefaultValue(Serializable currentValue) {
-			return null;
-		}
-		public String toString() {
-			return "UNDEFINED";
-		}
-	};
-	
-	protected IdentifierValue() {
-		this.value = null;
-	}
-	
-	/**
-	 * Assume the transient instance is newly instantiated if
-	 * its identifier is null or equal to <tt>value</tt>
-	 */
-	public IdentifierValue(Serializable value) {
-		this.value = value;
-	}
-	
-	/**
-	 * Does the given identifier belong to a new instance?
-	 */
-	public Boolean isUnsaved(Serializable id) {
-		if ( log.isTraceEnabled() ) log.trace("id unsaved-value: " + value);
-		return id==null || id.equals(value) ? Boolean.TRUE : Boolean.FALSE;
-	}
-	
-	public Serializable getDefaultValue(Serializable currentValue) {
-		return value;
-	}
-	
-	public String toString() {
-		return "identifier unsaved-value: " + value;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/IdentifierValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/IdentifierValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,138 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A strategy for determining if an identifier value is an identifier of
+ * a new transient instance or a previously persistent transient instance.
+ * The strategy is determined by the <tt>unsaved-value</tt> attribute in
+ * the mapping file.
+ * 
+ * @author Gavin King
+ */
+public class IdentifierValue {
+
+	private static final Logger log = LoggerFactory.getLogger(IdentifierValue.class);
+	
+	private final Serializable value;
+	
+	/**
+	 * Always assume the transient instance is newly instantiated
+	 */
+	public static final IdentifierValue ANY = new IdentifierValue() {
+		public final Boolean isUnsaved(Serializable id) {
+			log.trace("id unsaved-value strategy ANY");
+			return Boolean.TRUE;
+		}
+		public Serializable getDefaultValue(Serializable currentValue) {
+			return currentValue;
+		}
+		public String toString() {
+			return "SAVE_ANY";
+		}
+	};
+	
+	/**
+	 * Never assume the transient instance is newly instantiated
+	 */
+	public static final IdentifierValue NONE = new IdentifierValue() {
+		public final Boolean isUnsaved(Serializable id) {
+			log.trace("id unsaved-value strategy NONE");
+			return Boolean.FALSE;
+		}
+		public Serializable getDefaultValue(Serializable currentValue) {
+			return currentValue;
+		}
+		public String toString() {
+			return "SAVE_NONE";
+		}
+	};
+	
+	/**
+	 * Assume the transient instance is newly instantiated if the identifier
+	 * is null.
+	 */
+	public static final IdentifierValue NULL = new IdentifierValue() {
+		public final Boolean isUnsaved(Serializable id) {
+			log.trace("id unsaved-value strategy NULL");
+			return id==null ? Boolean.TRUE : Boolean.FALSE;
+		}
+		public Serializable getDefaultValue(Serializable currentValue) {
+			return null;
+		}
+		public String toString() {
+			return "SAVE_NULL";
+		}
+	};
+	
+	/**
+	 * Assume nothing.
+	 */
+	public static final IdentifierValue UNDEFINED = new IdentifierValue() {
+		public final Boolean isUnsaved(Serializable id) {
+			log.trace("id unsaved-value strategy UNDEFINED");
+			return null;
+		}
+		public Serializable getDefaultValue(Serializable currentValue) {
+			return null;
+		}
+		public String toString() {
+			return "UNDEFINED";
+		}
+	};
+	
+	protected IdentifierValue() {
+		this.value = null;
+	}
+	
+	/**
+	 * Assume the transient instance is newly instantiated if
+	 * its identifier is null or equal to <tt>value</tt>
+	 */
+	public IdentifierValue(Serializable value) {
+		this.value = value;
+	}
+	
+	/**
+	 * Does the given identifier belong to a new instance?
+	 */
+	public Boolean isUnsaved(Serializable id) {
+		if ( log.isTraceEnabled() ) log.trace("id unsaved-value: " + value);
+		return id==null || id.equals(value) ? Boolean.TRUE : Boolean.FALSE;
+	}
+	
+	public Serializable getDefaultValue(Serializable currentValue) {
+		return value;
+	}
+	
+	public String toString() {
+		return "identifier unsaved-value: " + value;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/JoinHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,157 +0,0 @@
-//$Id: JoinHelper.java 7586 2005-07-21 01:11:52Z oneovthafew $
-package org.hibernate.engine;
-
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.type.AssociationType;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Gavin King
- */
-public final class JoinHelper {
-	
-	private JoinHelper() {}
-	
-	/**
-	 * Get the aliased columns of the owning entity which are to 
-	 * be used in the join
-	 */
-	public static String[] getAliasedLHSColumnNames(
-			AssociationType type, 
-			String alias, 
-			int property, 
-			OuterJoinLoadable lhsPersister,
-			Mapping mapping
-	) {
-		return getAliasedLHSColumnNames(type, alias, property, 0, lhsPersister, mapping);
-	}
-	
-	/**
-	 * Get the columns of the owning entity which are to 
-	 * be used in the join
-	 */
-	public static String[] getLHSColumnNames(
-			AssociationType type, 
-			int property, 
-			OuterJoinLoadable lhsPersister,
-			Mapping mapping
-	) {
-		return getLHSColumnNames(type, property, 0, lhsPersister, mapping);
-	}
-	
-	/**
-	 * Get the aliased columns of the owning entity which are to 
-	 * be used in the join
-	 */
-	public static String[] getAliasedLHSColumnNames(
-			AssociationType type, 
-			String alias, 
-			int property, 
-			int begin, 
-			OuterJoinLoadable lhsPersister,
-			Mapping mapping
-	) {
-		if ( type.useLHSPrimaryKey() ) {
-			return StringHelper.qualify( alias, lhsPersister.getIdentifierColumnNames() );
-		}
-		else {
-			String propertyName = type.getLHSPropertyName();
-			if (propertyName==null) {
-				return ArrayHelper.slice( 
-						lhsPersister.toColumns(alias, property), 
-						begin, 
-						type.getColumnSpan(mapping) 
-					);
-			}
-			else {
-				return ( (PropertyMapping) lhsPersister ).toColumns(alias, propertyName); //bad cast
-			}
-		}
-	}
-	
-	/**
-	 * Get the columns of the owning entity which are to 
-	 * be used in the join
-	 */
-	public static String[] getLHSColumnNames(
-			AssociationType type, 
-			int property, 
-			int begin, 
-			OuterJoinLoadable lhsPersister,
-			Mapping mapping
-	) {
-		if ( type.useLHSPrimaryKey() ) {
-			//return lhsPersister.getSubclassPropertyColumnNames(property);
-			return lhsPersister.getIdentifierColumnNames();
-		}
-		else {
-			String propertyName = type.getLHSPropertyName();
-			if (propertyName==null) {
-				//slice, to get the columns for this component
-				//property
-				return ArrayHelper.slice( 
-						lhsPersister.getSubclassPropertyColumnNames(property),
-						begin, 
-						type.getColumnSpan(mapping) 
-					);
-			}
-			else {
-				//property-refs for associations defined on a
-				//component are not supported, so no need to slice
-				return lhsPersister.getPropertyColumnNames(propertyName);
-			}
-		}
-	}
-	
-	public static String getLHSTableName(
-		AssociationType type, 
-		int property, 
-		OuterJoinLoadable lhsPersister
-	) {
-		if ( type.useLHSPrimaryKey() ) {
-			return lhsPersister.getTableName();
-		}
-		else {
-			String propertyName = type.getLHSPropertyName();
-			if (propertyName==null) {
-				//if there is no property-ref, assume the join
-				//is to the subclass table (ie. the table of the
-				//subclass that the association belongs to)
-				return lhsPersister.getSubclassPropertyTableName(property);
-			}
-			else {
-				//handle a property-ref
-				String propertyRefTable = lhsPersister.getPropertyTableName(propertyName);
-				if (propertyRefTable==null) {
-					//it is possible that the tree-walking in OuterJoinLoader can get to
-					//an association defined by a subclass, in which case the property-ref
-					//might refer to a property defined on a subclass of the current class
-					//in this case, the table name is not known - this temporary solution 
-					//assumes that the property-ref refers to a property of the subclass
-					//table that the association belongs to (a reasonable guess)
-					//TODO: fix this, add: OuterJoinLoadable.getSubclassPropertyTableName(String propertyName)
-					propertyRefTable = lhsPersister.getSubclassPropertyTableName(property);
-				}
-				return propertyRefTable;
-			}
-		}
-	}
-	
-	/**
-	 * Get the columns of the associated table which are to 
-	 * be used in the join
-	 */
-	public static String[] getRHSColumnNames(AssociationType type, SessionFactoryImplementor factory) {
-		String uniqueKeyPropertyName = type.getRHSUniqueKeyPropertyName();
-		Joinable joinable = type.getAssociatedJoinable(factory);
-		if (uniqueKeyPropertyName==null) {
-			return joinable.getKeyColumnNames();
-		}
-		else {
-			return ( (OuterJoinLoadable) joinable ).getPropertyColumnNames(uniqueKeyPropertyName);
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/JoinHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,180 @@
+/*
+ * 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.engine;
+
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.type.AssociationType;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Gavin King
+ */
+public final class JoinHelper {
+	
+	private JoinHelper() {}
+	
+	/**
+	 * Get the aliased columns of the owning entity which are to 
+	 * be used in the join
+	 */
+	public static String[] getAliasedLHSColumnNames(
+			AssociationType type, 
+			String alias, 
+			int property, 
+			OuterJoinLoadable lhsPersister,
+			Mapping mapping
+	) {
+		return getAliasedLHSColumnNames(type, alias, property, 0, lhsPersister, mapping);
+	}
+	
+	/**
+	 * Get the columns of the owning entity which are to 
+	 * be used in the join
+	 */
+	public static String[] getLHSColumnNames(
+			AssociationType type, 
+			int property, 
+			OuterJoinLoadable lhsPersister,
+			Mapping mapping
+	) {
+		return getLHSColumnNames(type, property, 0, lhsPersister, mapping);
+	}
+	
+	/**
+	 * Get the aliased columns of the owning entity which are to 
+	 * be used in the join
+	 */
+	public static String[] getAliasedLHSColumnNames(
+			AssociationType type, 
+			String alias, 
+			int property, 
+			int begin, 
+			OuterJoinLoadable lhsPersister,
+			Mapping mapping
+	) {
+		if ( type.useLHSPrimaryKey() ) {
+			return StringHelper.qualify( alias, lhsPersister.getIdentifierColumnNames() );
+		}
+		else {
+			String propertyName = type.getLHSPropertyName();
+			if (propertyName==null) {
+				return ArrayHelper.slice( 
+						lhsPersister.toColumns(alias, property), 
+						begin, 
+						type.getColumnSpan(mapping) 
+					);
+			}
+			else {
+				return ( (PropertyMapping) lhsPersister ).toColumns(alias, propertyName); //bad cast
+			}
+		}
+	}
+	
+	/**
+	 * Get the columns of the owning entity which are to 
+	 * be used in the join
+	 */
+	public static String[] getLHSColumnNames(
+			AssociationType type, 
+			int property, 
+			int begin, 
+			OuterJoinLoadable lhsPersister,
+			Mapping mapping
+	) {
+		if ( type.useLHSPrimaryKey() ) {
+			//return lhsPersister.getSubclassPropertyColumnNames(property);
+			return lhsPersister.getIdentifierColumnNames();
+		}
+		else {
+			String propertyName = type.getLHSPropertyName();
+			if (propertyName==null) {
+				//slice, to get the columns for this component
+				//property
+				return ArrayHelper.slice( 
+						lhsPersister.getSubclassPropertyColumnNames(property),
+						begin, 
+						type.getColumnSpan(mapping) 
+					);
+			}
+			else {
+				//property-refs for associations defined on a
+				//component are not supported, so no need to slice
+				return lhsPersister.getPropertyColumnNames(propertyName);
+			}
+		}
+	}
+	
+	public static String getLHSTableName(
+		AssociationType type, 
+		int property, 
+		OuterJoinLoadable lhsPersister
+	) {
+		if ( type.useLHSPrimaryKey() ) {
+			return lhsPersister.getTableName();
+		}
+		else {
+			String propertyName = type.getLHSPropertyName();
+			if (propertyName==null) {
+				//if there is no property-ref, assume the join
+				//is to the subclass table (ie. the table of the
+				//subclass that the association belongs to)
+				return lhsPersister.getSubclassPropertyTableName(property);
+			}
+			else {
+				//handle a property-ref
+				String propertyRefTable = lhsPersister.getPropertyTableName(propertyName);
+				if (propertyRefTable==null) {
+					//it is possible that the tree-walking in OuterJoinLoader can get to
+					//an association defined by a subclass, in which case the property-ref
+					//might refer to a property defined on a subclass of the current class
+					//in this case, the table name is not known - this temporary solution 
+					//assumes that the property-ref refers to a property of the subclass
+					//table that the association belongs to (a reasonable guess)
+					//TODO: fix this, add: OuterJoinLoadable.getSubclassPropertyTableName(String propertyName)
+					propertyRefTable = lhsPersister.getSubclassPropertyTableName(property);
+				}
+				return propertyRefTable;
+			}
+		}
+	}
+	
+	/**
+	 * Get the columns of the associated table which are to 
+	 * be used in the join
+	 */
+	public static String[] getRHSColumnNames(AssociationType type, SessionFactoryImplementor factory) {
+		String uniqueKeyPropertyName = type.getRHSUniqueKeyPropertyName();
+		Joinable joinable = type.getAssociatedJoinable(factory);
+		if (uniqueKeyPropertyName==null) {
+			return joinable.getKeyColumnNames();
+		}
+		else {
+			return ( (OuterJoinLoadable) joinable ).getPropertyColumnNames(uniqueKeyPropertyName);
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/JoinSequence.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,267 +0,0 @@
-//$Id: JoinSequence.java 9336 2006-02-24 22:12:13Z steveebersole $
-package org.hibernate.engine;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.QueryJoinFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * @author Gavin King
- */
-public class JoinSequence {
-
-	private final SessionFactoryImplementor factory;
-	private final List joins = new ArrayList();
-	private boolean useThetaStyle = false;
-	private final StringBuffer conditions = new StringBuffer();
-	private String rootAlias;
-	private Joinable rootJoinable;
-	private Selector selector;
-	private JoinSequence next;
-	private boolean isFromPart = false;
-
-	public String toString() {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "JoinSequence{" );
-		if ( rootJoinable != null ) {
-			buf.append( rootJoinable )
-					.append( '[' )
-					.append( rootAlias )
-					.append( ']' );
-		}
-		for ( int i = 0; i < joins.size(); i++ ) {
-			buf.append( "->" ).append( joins.get( i ) );
-		}
-		return buf.append( '}' ).toString();
-	}
-
-	final class Join {
-
-		private final AssociationType associationType;
-		private final Joinable joinable;
-		private final int joinType;
-		private final String alias;
-		private final String[] lhsColumns;
-
-		Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
-				throws MappingException {
-			this.associationType = associationType;
-			this.joinable = associationType.getAssociatedJoinable( factory );
-			this.alias = alias;
-			this.joinType = joinType;
-			this.lhsColumns = lhsColumns;
-		}
-
-		String getAlias() {
-			return alias;
-		}
-
-		AssociationType getAssociationType() {
-			return associationType;
-		}
-
-		Joinable getJoinable() {
-			return joinable;
-		}
-
-		int getJoinType() {
-			return joinType;
-		}
-
-		String[] getLHSColumns() {
-			return lhsColumns;
-		}
-
-		public String toString() {
-			return joinable.toString() + '[' + alias + ']';
-		}
-	}
-
-	public JoinSequence(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	public JoinSequence getFromPart() {
-		JoinSequence fromPart = new JoinSequence( factory );
-		fromPart.joins.addAll( this.joins );
-		fromPart.useThetaStyle = this.useThetaStyle;
-		fromPart.rootAlias = this.rootAlias;
-		fromPart.rootJoinable = this.rootJoinable;
-		fromPart.selector = this.selector;
-		fromPart.next = this.next == null ? null : this.next.getFromPart();
-		fromPart.isFromPart = true;
-		return fromPart;
-	}
-
-	public JoinSequence copy() {
-		JoinSequence copy = new JoinSequence( factory );
-		copy.joins.addAll( this.joins );
-		copy.useThetaStyle = this.useThetaStyle;
-		copy.rootAlias = this.rootAlias;
-		copy.rootJoinable = this.rootJoinable;
-		copy.selector = this.selector;
-		copy.next = this.next == null ? null : this.next.copy();
-		copy.isFromPart = this.isFromPart;
-		copy.conditions.append( this.conditions.toString() );
-		return copy;
-	}
-
-	public JoinSequence addJoin(AssociationType associationType, String alias, int joinType, String[] referencingKey)
-			throws MappingException {
-		joins.add( new Join( associationType, alias, joinType, referencingKey ) );
-		return this;
-	}
-
-	public JoinFragment toJoinFragment() throws MappingException {
-		return toJoinFragment( CollectionHelper.EMPTY_MAP, true );
-	}
-
-	public JoinFragment toJoinFragment(Map enabledFilters, boolean includeExtraJoins) throws MappingException {
-		return toJoinFragment( enabledFilters, includeExtraJoins, null, null );
-	}
-
-	public JoinFragment toJoinFragment(
-			Map enabledFilters,
-	        boolean includeExtraJoins,
-	        String withClauseFragment,
-	        String withClauseJoinAlias) throws MappingException {
-		QueryJoinFragment joinFragment = new QueryJoinFragment( factory.getDialect(), useThetaStyle );
-		if ( rootJoinable != null ) {
-			joinFragment.addCrossJoin( rootJoinable.getTableName(), rootAlias );
-			String filterCondition = rootJoinable.filterFragment( rootAlias, enabledFilters );
-			// JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
-			// can put the where clause fragment in the right place in the SQL AST.   'hasFilterCondition' keeps track
-			// of that fact.
-			joinFragment.setHasFilterCondition( joinFragment.addCondition( filterCondition ) );
-			if (includeExtraJoins) { //TODO: not quite sure about the full implications of this!
-				addExtraJoins( joinFragment, rootAlias, rootJoinable, true );
-			}
-		}
-
-		Joinable last = rootJoinable;
-
-		for ( int i = 0; i < joins.size(); i++ ) {
-			Join join = ( Join ) joins.get( i );
-			String on = join.getAssociationType().getOnCondition( join.getAlias(), factory, enabledFilters );
-			String condition = null;
-			if ( last != null &&
-			        isManyToManyRoot( last ) &&
-			        ( ( QueryableCollection ) last ).getElementType() == join.getAssociationType() ) {
-				// the current join represents the join between a many-to-many association table
-				// and its "target" table.  Here we need to apply any additional filters
-				// defined specifically on the many-to-many
-				String manyToManyFilter = ( ( QueryableCollection ) last )
-				        .getManyToManyFilterFragment( join.getAlias(), enabledFilters );
-				condition = "".equals( manyToManyFilter )
-						? on
-						: "".equals( on )
-								? manyToManyFilter
-								: on + " and " + manyToManyFilter;
-			}
-			else {
-				condition = on;
-			}
-			if ( withClauseFragment != null ) {
-				if ( join.getAlias().equals( withClauseJoinAlias ) ) {
-					condition += " and " + withClauseFragment;
-				}
-			}
-			joinFragment.addJoin(
-			        join.getJoinable().getTableName(),
-					join.getAlias(),
-					join.getLHSColumns(),
-					JoinHelper.getRHSColumnNames( join.getAssociationType(), factory ),
-					join.joinType,
-					condition
-			);
-			if (includeExtraJoins) { //TODO: not quite sure about the full implications of this!
-				addExtraJoins( joinFragment, join.getAlias(), join.getJoinable(), join.joinType == JoinFragment.INNER_JOIN );
-			}
-			last = join.getJoinable();
-		}
-		if ( next != null ) {
-			joinFragment.addFragment( next.toJoinFragment( enabledFilters, includeExtraJoins ) );
-		}
-		joinFragment.addCondition( conditions.toString() );
-		if ( isFromPart ) joinFragment.clearWherePart();
-		return joinFragment;
-	}
-
-	private boolean isManyToManyRoot(Joinable joinable) {
-		if ( joinable != null && joinable.isCollection() ) {
-			QueryableCollection persister = ( QueryableCollection ) joinable;
-			return persister.isManyToMany();
-		}
-		return false;
-	}
-
-	private boolean isIncluded(String alias) {
-		return selector != null && selector.includeSubclasses( alias );
-	}
-
-	private void addExtraJoins(JoinFragment joinFragment, String alias, Joinable joinable, boolean innerJoin) {
-		boolean include = isIncluded( alias );
-		joinFragment.addJoins( joinable.fromJoinFragment( alias, innerJoin, include ),
-				joinable.whereJoinFragment( alias, innerJoin, include ) );
-	}
-
-	public JoinSequence addCondition(String condition) {
-		if ( condition.trim().length() != 0 ) {
-			if ( !condition.startsWith( " and " ) ) conditions.append( " and " );
-			conditions.append( condition );
-		}
-		return this;
-	}
-
-	public JoinSequence addCondition(String alias, String[] columns, String condition) {
-		for ( int i = 0; i < columns.length; i++ ) {
-			conditions.append( " and " )
-					.append( alias )
-					.append( '.' )
-					.append( columns[i] )
-					.append( condition );
-		}
-		return this;
-	}
-
-	public JoinSequence setRoot(Joinable joinable, String alias) {
-		this.rootAlias = alias;
-		this.rootJoinable = joinable;
-		return this;
-	}
-
-	public JoinSequence setNext(JoinSequence next) {
-		this.next = next;
-		return this;
-	}
-
-	public JoinSequence setSelector(Selector s) {
-		this.selector = s;
-		return this;
-	}
-
-	public JoinSequence setUseThetaStyle(boolean useThetaStyle) {
-		this.useThetaStyle = useThetaStyle;
-		return this;
-	}
-
-	public boolean isThetaStyle() {
-		return useThetaStyle;
-	}
-
-	public int getJoinCount() {
-		return joins.size();
-	}
-	
-	public static interface Selector {
-		public boolean includeSubclasses(String alias);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/JoinSequence.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/JoinSequence.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,290 @@
+/*
+ * 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.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.QueryJoinFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * @author Gavin King
+ */
+public class JoinSequence {
+
+	private final SessionFactoryImplementor factory;
+	private final List joins = new ArrayList();
+	private boolean useThetaStyle = false;
+	private final StringBuffer conditions = new StringBuffer();
+	private String rootAlias;
+	private Joinable rootJoinable;
+	private Selector selector;
+	private JoinSequence next;
+	private boolean isFromPart = false;
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "JoinSequence{" );
+		if ( rootJoinable != null ) {
+			buf.append( rootJoinable )
+					.append( '[' )
+					.append( rootAlias )
+					.append( ']' );
+		}
+		for ( int i = 0; i < joins.size(); i++ ) {
+			buf.append( "->" ).append( joins.get( i ) );
+		}
+		return buf.append( '}' ).toString();
+	}
+
+	final class Join {
+
+		private final AssociationType associationType;
+		private final Joinable joinable;
+		private final int joinType;
+		private final String alias;
+		private final String[] lhsColumns;
+
+		Join(AssociationType associationType, String alias, int joinType, String[] lhsColumns)
+				throws MappingException {
+			this.associationType = associationType;
+			this.joinable = associationType.getAssociatedJoinable( factory );
+			this.alias = alias;
+			this.joinType = joinType;
+			this.lhsColumns = lhsColumns;
+		}
+
+		String getAlias() {
+			return alias;
+		}
+
+		AssociationType getAssociationType() {
+			return associationType;
+		}
+
+		Joinable getJoinable() {
+			return joinable;
+		}
+
+		int getJoinType() {
+			return joinType;
+		}
+
+		String[] getLHSColumns() {
+			return lhsColumns;
+		}
+
+		public String toString() {
+			return joinable.toString() + '[' + alias + ']';
+		}
+	}
+
+	public JoinSequence(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	public JoinSequence getFromPart() {
+		JoinSequence fromPart = new JoinSequence( factory );
+		fromPart.joins.addAll( this.joins );
+		fromPart.useThetaStyle = this.useThetaStyle;
+		fromPart.rootAlias = this.rootAlias;
+		fromPart.rootJoinable = this.rootJoinable;
+		fromPart.selector = this.selector;
+		fromPart.next = this.next == null ? null : this.next.getFromPart();
+		fromPart.isFromPart = true;
+		return fromPart;
+	}
+
+	public JoinSequence copy() {
+		JoinSequence copy = new JoinSequence( factory );
+		copy.joins.addAll( this.joins );
+		copy.useThetaStyle = this.useThetaStyle;
+		copy.rootAlias = this.rootAlias;
+		copy.rootJoinable = this.rootJoinable;
+		copy.selector = this.selector;
+		copy.next = this.next == null ? null : this.next.copy();
+		copy.isFromPart = this.isFromPart;
+		copy.conditions.append( this.conditions.toString() );
+		return copy;
+	}
+
+	public JoinSequence addJoin(AssociationType associationType, String alias, int joinType, String[] referencingKey)
+			throws MappingException {
+		joins.add( new Join( associationType, alias, joinType, referencingKey ) );
+		return this;
+	}
+
+	public JoinFragment toJoinFragment() throws MappingException {
+		return toJoinFragment( CollectionHelper.EMPTY_MAP, true );
+	}
+
+	public JoinFragment toJoinFragment(Map enabledFilters, boolean includeExtraJoins) throws MappingException {
+		return toJoinFragment( enabledFilters, includeExtraJoins, null, null );
+	}
+
+	public JoinFragment toJoinFragment(
+			Map enabledFilters,
+	        boolean includeExtraJoins,
+	        String withClauseFragment,
+	        String withClauseJoinAlias) throws MappingException {
+		QueryJoinFragment joinFragment = new QueryJoinFragment( factory.getDialect(), useThetaStyle );
+		if ( rootJoinable != null ) {
+			joinFragment.addCrossJoin( rootJoinable.getTableName(), rootAlias );
+			String filterCondition = rootJoinable.filterFragment( rootAlias, enabledFilters );
+			// JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it
+			// can put the where clause fragment in the right place in the SQL AST.   'hasFilterCondition' keeps track
+			// of that fact.
+			joinFragment.setHasFilterCondition( joinFragment.addCondition( filterCondition ) );
+			if (includeExtraJoins) { //TODO: not quite sure about the full implications of this!
+				addExtraJoins( joinFragment, rootAlias, rootJoinable, true );
+			}
+		}
+
+		Joinable last = rootJoinable;
+
+		for ( int i = 0; i < joins.size(); i++ ) {
+			Join join = ( Join ) joins.get( i );
+			String on = join.getAssociationType().getOnCondition( join.getAlias(), factory, enabledFilters );
+			String condition = null;
+			if ( last != null &&
+			        isManyToManyRoot( last ) &&
+			        ( ( QueryableCollection ) last ).getElementType() == join.getAssociationType() ) {
+				// the current join represents the join between a many-to-many association table
+				// and its "target" table.  Here we need to apply any additional filters
+				// defined specifically on the many-to-many
+				String manyToManyFilter = ( ( QueryableCollection ) last )
+				        .getManyToManyFilterFragment( join.getAlias(), enabledFilters );
+				condition = "".equals( manyToManyFilter )
+						? on
+						: "".equals( on )
+								? manyToManyFilter
+								: on + " and " + manyToManyFilter;
+			}
+			else {
+				condition = on;
+			}
+			if ( withClauseFragment != null ) {
+				if ( join.getAlias().equals( withClauseJoinAlias ) ) {
+					condition += " and " + withClauseFragment;
+				}
+			}
+			joinFragment.addJoin(
+			        join.getJoinable().getTableName(),
+					join.getAlias(),
+					join.getLHSColumns(),
+					JoinHelper.getRHSColumnNames( join.getAssociationType(), factory ),
+					join.joinType,
+					condition
+			);
+			if (includeExtraJoins) { //TODO: not quite sure about the full implications of this!
+				addExtraJoins( joinFragment, join.getAlias(), join.getJoinable(), join.joinType == JoinFragment.INNER_JOIN );
+			}
+			last = join.getJoinable();
+		}
+		if ( next != null ) {
+			joinFragment.addFragment( next.toJoinFragment( enabledFilters, includeExtraJoins ) );
+		}
+		joinFragment.addCondition( conditions.toString() );
+		if ( isFromPart ) joinFragment.clearWherePart();
+		return joinFragment;
+	}
+
+	private boolean isManyToManyRoot(Joinable joinable) {
+		if ( joinable != null && joinable.isCollection() ) {
+			QueryableCollection persister = ( QueryableCollection ) joinable;
+			return persister.isManyToMany();
+		}
+		return false;
+	}
+
+	private boolean isIncluded(String alias) {
+		return selector != null && selector.includeSubclasses( alias );
+	}
+
+	private void addExtraJoins(JoinFragment joinFragment, String alias, Joinable joinable, boolean innerJoin) {
+		boolean include = isIncluded( alias );
+		joinFragment.addJoins( joinable.fromJoinFragment( alias, innerJoin, include ),
+				joinable.whereJoinFragment( alias, innerJoin, include ) );
+	}
+
+	public JoinSequence addCondition(String condition) {
+		if ( condition.trim().length() != 0 ) {
+			if ( !condition.startsWith( " and " ) ) conditions.append( " and " );
+			conditions.append( condition );
+		}
+		return this;
+	}
+
+	public JoinSequence addCondition(String alias, String[] columns, String condition) {
+		for ( int i = 0; i < columns.length; i++ ) {
+			conditions.append( " and " )
+					.append( alias )
+					.append( '.' )
+					.append( columns[i] )
+					.append( condition );
+		}
+		return this;
+	}
+
+	public JoinSequence setRoot(Joinable joinable, String alias) {
+		this.rootAlias = alias;
+		this.rootJoinable = joinable;
+		return this;
+	}
+
+	public JoinSequence setNext(JoinSequence next) {
+		this.next = next;
+		return this;
+	}
+
+	public JoinSequence setSelector(Selector s) {
+		this.selector = s;
+		return this;
+	}
+
+	public JoinSequence setUseThetaStyle(boolean useThetaStyle) {
+		this.useThetaStyle = useThetaStyle;
+		return this;
+	}
+
+	public boolean isThetaStyle() {
+		return useThetaStyle;
+	}
+
+	public int getJoinCount() {
+		return joins.size();
+	}
+	
+	public static interface Selector {
+		public boolean includeSubclasses(String alias);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: Mapping.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.Type;
-
-/**
- * Defines operations common to "compiled" mappings (ie. <tt>SessionFactory</tt>)
- * and "uncompiled" mappings (ie. <tt>Configuration</tt>) that are used by
- * implementors of <tt>Type</tt>.
- *
- * @see org.hibernate.type.Type
- * @see org.hibernate.impl.SessionFactoryImpl
- * @see org.hibernate.cfg.Configuration
- * @author Gavin King
- */
-public interface Mapping {
-	public Type getIdentifierType(String className) throws MappingException;
-	public String getIdentifierPropertyName(String className) throws MappingException;
-	public Type getReferencedPropertyType(String className, String propertyName) throws MappingException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Mapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Mapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.engine;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.Type;
+
+/**
+ * Defines operations common to "compiled" mappings (ie. <tt>SessionFactory</tt>)
+ * and "uncompiled" mappings (ie. <tt>Configuration</tt>) that are used by
+ * implementors of <tt>Type</tt>.
+ *
+ * @see org.hibernate.type.Type
+ * @see org.hibernate.impl.SessionFactoryImpl
+ * @see org.hibernate.cfg.Configuration
+ * @author Gavin King
+ */
+public interface Mapping {
+	public Type getIdentifierType(String className) throws MappingException;
+	public String getIdentifierPropertyName(String className) throws MappingException;
+	public Type getReferencedPropertyType(String className, String propertyName) throws MappingException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +0,0 @@
-//$Id: NamedQueryDefinition.java 7966 2005-08-19 23:40:24Z epbernard $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.CacheMode;
-import org.hibernate.FlushMode;
-
-
-/**
- * Definition of a named query, defined in the mapping metadata.
- *
- * @author Gavin King
- */
-public class NamedQueryDefinition implements Serializable {
-	private final String query;
-	private final boolean cacheable;
-	private final String cacheRegion;
-	private final Integer timeout;
-	private final Integer fetchSize;
-	private final FlushMode flushMode;
-	private final Map parameterTypes;
-	private CacheMode cacheMode;
-	private boolean readOnly;
-	private String comment;
-
-	// kept for backward compatibility until after the 3.1beta5 release of HA
-	public NamedQueryDefinition(
-			String query,
-			boolean cacheable,
-			String cacheRegion,
-			Integer timeout,
-			Integer fetchSize,
-			FlushMode flushMode,
-			Map parameterTypes
-	) {
-		this(
-				query,
-				cacheable,
-				cacheRegion,
-				timeout,
-				fetchSize,
-				flushMode,
-				null,
-				false,
-				null,
-				parameterTypes
-		);
-	}
-
-	public NamedQueryDefinition(
-			String query,
-			boolean cacheable,
-			String cacheRegion,
-			Integer timeout,
-			Integer fetchSize,
-			FlushMode flushMode,
-			CacheMode cacheMode,
-			boolean readOnly,
-			String comment,
-			Map parameterTypes
-	) {
-		this.query = query;
-		this.cacheable = cacheable;
-		this.cacheRegion = cacheRegion;
-		this.timeout = timeout;
-		this.fetchSize = fetchSize;
-		this.flushMode = flushMode;
-		this.parameterTypes = parameterTypes;
-		this.cacheMode = cacheMode;
-		this.readOnly = readOnly;
-		this.comment = comment;
-	}
-
-	public String getQueryString() {
-		return query;
-	}
-
-	public boolean isCacheable() {
-		return cacheable;
-	}
-
-	public String getCacheRegion() {
-		return cacheRegion;
-	}
-
-	public Integer getFetchSize() {
-		return fetchSize;
-	}
-
-	public Integer getTimeout() {
-		return timeout;
-	}
-
-	public FlushMode getFlushMode() {
-		return flushMode;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + query + ')';
-	}
-
-	public Map getParameterTypes() {
-		return parameterTypes;
-	}
-
-	public String getQuery() {
-		return query;
-	}
-
-	public CacheMode getCacheMode() {
-		return cacheMode;
-	}
-
-	public boolean isReadOnly() {
-		return readOnly;
-	}
-
-	public String getComment() {
-		return comment;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedQueryDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+
+
+/**
+ * Definition of a named query, defined in the mapping metadata.
+ *
+ * @author Gavin King
+ */
+public class NamedQueryDefinition implements Serializable {
+	private final String query;
+	private final boolean cacheable;
+	private final String cacheRegion;
+	private final Integer timeout;
+	private final Integer fetchSize;
+	private final FlushMode flushMode;
+	private final Map parameterTypes;
+	private CacheMode cacheMode;
+	private boolean readOnly;
+	private String comment;
+
+	// kept for backward compatibility until after the 3.1beta5 release of HA
+	public NamedQueryDefinition(
+			String query,
+			boolean cacheable,
+			String cacheRegion,
+			Integer timeout,
+			Integer fetchSize,
+			FlushMode flushMode,
+			Map parameterTypes
+	) {
+		this(
+				query,
+				cacheable,
+				cacheRegion,
+				timeout,
+				fetchSize,
+				flushMode,
+				null,
+				false,
+				null,
+				parameterTypes
+		);
+	}
+
+	public NamedQueryDefinition(
+			String query,
+			boolean cacheable,
+			String cacheRegion,
+			Integer timeout,
+			Integer fetchSize,
+			FlushMode flushMode,
+			CacheMode cacheMode,
+			boolean readOnly,
+			String comment,
+			Map parameterTypes
+	) {
+		this.query = query;
+		this.cacheable = cacheable;
+		this.cacheRegion = cacheRegion;
+		this.timeout = timeout;
+		this.fetchSize = fetchSize;
+		this.flushMode = flushMode;
+		this.parameterTypes = parameterTypes;
+		this.cacheMode = cacheMode;
+		this.readOnly = readOnly;
+		this.comment = comment;
+	}
+
+	public String getQueryString() {
+		return query;
+	}
+
+	public boolean isCacheable() {
+		return cacheable;
+	}
+
+	public String getCacheRegion() {
+		return cacheRegion;
+	}
+
+	public Integer getFetchSize() {
+		return fetchSize;
+	}
+
+	public Integer getTimeout() {
+		return timeout;
+	}
+
+	public FlushMode getFlushMode() {
+		return flushMode;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + query + ')';
+	}
+
+	public Map getParameterTypes() {
+		return parameterTypes;
+	}
+
+	public String getQuery() {
+		return query;
+	}
+
+	public CacheMode getCacheMode() {
+		return cacheMode;
+	}
+
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,185 +0,0 @@
-//$Id: NamedSQLQueryDefinition.java 11198 2007-02-13 21:04:10Z epbernard $
-package org.hibernate.engine;
-
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.FlushMode;
-import org.hibernate.CacheMode;
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-
-/**
- * Definition of a named native SQL query, defined
- * in the mapping metadata.
- * 
- * @author Max Andersen
- */
-public class NamedSQLQueryDefinition extends NamedQueryDefinition {
-
-	private NativeSQLQueryReturn[] queryReturns;
-	private final List querySpaces;
-	private final boolean callable;
-	private String resultSetRef;
-
-	/**
-	 * This form used to construct a NamedSQLQueryDefinition from the binder
-	 * code when a the result-set mapping information is explicitly
-	 * provided in the query definition (i.e., no resultset-mapping used)
-	 *
-	 * @param query The sql query string
-	 * @param queryReturns The in-lined query return definitions
-	 * @param querySpaces Any specified query spaces (used for auto-flushing)
-	 * @param cacheable Whether the query results are cacheable
-	 * @param cacheRegion If cacheable, the region into which to store the results
-	 * @param timeout A JDBC-level timeout to be applied
-	 * @param fetchSize A JDBC-level fetch-size to be applied
-	 * @param flushMode The flush mode to use for this query
-	 * @param cacheMode The cache mode to use during execution and subsequent result loading
-	 * @param readOnly Whether returned entities should be marked as read-only in the session
-	 * @param comment Any sql comment to be applied to the query
-	 * @param parameterTypes parameter type map
-	 * @param callable Does the query string represent a callable object (i.e., proc)
-	 */
-	public NamedSQLQueryDefinition(
-			String query,
-			NativeSQLQueryReturn[] queryReturns,
-			List querySpaces,
-			boolean cacheable,
-			String cacheRegion,
-			Integer timeout,
-			Integer fetchSize,
-			FlushMode flushMode,
-			CacheMode cacheMode,
-			boolean readOnly,
-			String comment,
-			Map parameterTypes,
-			boolean callable) {
-		super(
-				query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
-				cacheable,
-				cacheRegion,
-				timeout,
-				fetchSize,
-				flushMode,
-				cacheMode,
-				readOnly,
-				comment,
-				parameterTypes
-		);
-		this.queryReturns = queryReturns;
-		this.querySpaces = querySpaces;
-		this.callable = callable;
-	}
-
-	/**
-	 * This form used to construct a NamedSQLQueryDefinition from the binder
-	 * code when a resultset-mapping reference is used.
-	 *
-	 * @param query The sql query string
-	 * @param resultSetRef The resultset-mapping name
-	 * @param querySpaces Any specified query spaces (used for auto-flushing)
-	 * @param cacheable Whether the query results are cacheable
-	 * @param cacheRegion If cacheable, the region into which to store the results
-	 * @param timeout A JDBC-level timeout to be applied
-	 * @param fetchSize A JDBC-level fetch-size to be applied
-	 * @param flushMode The flush mode to use for this query
-	 * @param cacheMode The cache mode to use during execution and subsequent result loading
-	 * @param readOnly Whether returned entities should be marked as read-only in the session
-	 * @param comment Any sql comment to be applied to the query
-	 * @param parameterTypes parameter type map
-	 * @param callable Does the query string represent a callable object (i.e., proc)
-	 */
-	public NamedSQLQueryDefinition(
-			String query,
-			String resultSetRef,
-			List querySpaces,
-			boolean cacheable,
-			String cacheRegion,
-			Integer timeout,
-			Integer fetchSize,
-			FlushMode flushMode,
-			CacheMode cacheMode,
-			boolean readOnly,
-			String comment,
-			Map parameterTypes,
-			boolean callable) {
-		super(
-				query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
-				cacheable,
-				cacheRegion,
-				timeout,
-				fetchSize,
-				flushMode,
-				cacheMode,
-				readOnly,
-				comment,
-				parameterTypes
-		);
-		this.resultSetRef = resultSetRef;
-		this.querySpaces = querySpaces;
-		this.callable = callable;
-	}
-
-	/**
-	 * This form used from annotations (?).  Essentially the same as the above using a
-	 * resultset-mapping reference, but without cacheMode, readOnly, and comment.
-	 *
-	 * FIXME: annotations do not use it, so it can be remove from my POV
-	 * @deprecated
-	 *
-	 *
-	 * @param query The sql query string
-	 * @param resultSetRef The result-set-mapping name
-	 * @param querySpaces Any specified query spaces (used for auto-flushing)
-	 * @param cacheable Whether the query results are cacheable
-	 * @param cacheRegion If cacheable, the region into which to store the results
-	 * @param timeout A JDBC-level timeout to be applied
-	 * @param fetchSize A JDBC-level fetch-size to be applied
-	 * @param flushMode The flush mode to use for this query
-	 * @param parameterTypes parameter type map
-	 * @param callable Does the query string represent a callable object (i.e., proc)
-	 */
-	public NamedSQLQueryDefinition(
-			String query,
-			String resultSetRef,
-			List querySpaces,
-			boolean cacheable,
-			String cacheRegion,
-			Integer timeout,
-			Integer fetchSize,
-			FlushMode flushMode,
-			Map parameterTypes,
-			boolean callable) {
-		this(
-				query,
-				resultSetRef,
-				querySpaces,
-				cacheable,
-				cacheRegion,
-				timeout,
-				fetchSize,
-				flushMode,
-				null,
-				false,
-				null,
-				parameterTypes,
-				callable
-		);
-	}
-
-	public NativeSQLQueryReturn[] getQueryReturns() {
-		return queryReturns;
-	}
-
-	public List getQuerySpaces() {
-		return querySpaces;
-	}
-
-	public boolean isCallable() {
-		return callable;
-	}
-
-	public String getResultSetRef() {
-		return resultSetRef;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/NamedSQLQueryDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,208 @@
+/*
+ * 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.engine;
+
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.FlushMode;
+import org.hibernate.CacheMode;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+
+/**
+ * Definition of a named native SQL query, defined
+ * in the mapping metadata.
+ * 
+ * @author Max Andersen
+ */
+public class NamedSQLQueryDefinition extends NamedQueryDefinition {
+
+	private NativeSQLQueryReturn[] queryReturns;
+	private final List querySpaces;
+	private final boolean callable;
+	private String resultSetRef;
+
+	/**
+	 * This form used to construct a NamedSQLQueryDefinition from the binder
+	 * code when a the result-set mapping information is explicitly
+	 * provided in the query definition (i.e., no resultset-mapping used)
+	 *
+	 * @param query The sql query string
+	 * @param queryReturns The in-lined query return definitions
+	 * @param querySpaces Any specified query spaces (used for auto-flushing)
+	 * @param cacheable Whether the query results are cacheable
+	 * @param cacheRegion If cacheable, the region into which to store the results
+	 * @param timeout A JDBC-level timeout to be applied
+	 * @param fetchSize A JDBC-level fetch-size to be applied
+	 * @param flushMode The flush mode to use for this query
+	 * @param cacheMode The cache mode to use during execution and subsequent result loading
+	 * @param readOnly Whether returned entities should be marked as read-only in the session
+	 * @param comment Any sql comment to be applied to the query
+	 * @param parameterTypes parameter type map
+	 * @param callable Does the query string represent a callable object (i.e., proc)
+	 */
+	public NamedSQLQueryDefinition(
+			String query,
+			NativeSQLQueryReturn[] queryReturns,
+			List querySpaces,
+			boolean cacheable,
+			String cacheRegion,
+			Integer timeout,
+			Integer fetchSize,
+			FlushMode flushMode,
+			CacheMode cacheMode,
+			boolean readOnly,
+			String comment,
+			Map parameterTypes,
+			boolean callable) {
+		super(
+				query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
+				cacheable,
+				cacheRegion,
+				timeout,
+				fetchSize,
+				flushMode,
+				cacheMode,
+				readOnly,
+				comment,
+				parameterTypes
+		);
+		this.queryReturns = queryReturns;
+		this.querySpaces = querySpaces;
+		this.callable = callable;
+	}
+
+	/**
+	 * This form used to construct a NamedSQLQueryDefinition from the binder
+	 * code when a resultset-mapping reference is used.
+	 *
+	 * @param query The sql query string
+	 * @param resultSetRef The resultset-mapping name
+	 * @param querySpaces Any specified query spaces (used for auto-flushing)
+	 * @param cacheable Whether the query results are cacheable
+	 * @param cacheRegion If cacheable, the region into which to store the results
+	 * @param timeout A JDBC-level timeout to be applied
+	 * @param fetchSize A JDBC-level fetch-size to be applied
+	 * @param flushMode The flush mode to use for this query
+	 * @param cacheMode The cache mode to use during execution and subsequent result loading
+	 * @param readOnly Whether returned entities should be marked as read-only in the session
+	 * @param comment Any sql comment to be applied to the query
+	 * @param parameterTypes parameter type map
+	 * @param callable Does the query string represent a callable object (i.e., proc)
+	 */
+	public NamedSQLQueryDefinition(
+			String query,
+			String resultSetRef,
+			List querySpaces,
+			boolean cacheable,
+			String cacheRegion,
+			Integer timeout,
+			Integer fetchSize,
+			FlushMode flushMode,
+			CacheMode cacheMode,
+			boolean readOnly,
+			String comment,
+			Map parameterTypes,
+			boolean callable) {
+		super(
+				query.trim(), /* trim done to workaround stupid oracle bug that cant handle whitespaces before a { in a sp */
+				cacheable,
+				cacheRegion,
+				timeout,
+				fetchSize,
+				flushMode,
+				cacheMode,
+				readOnly,
+				comment,
+				parameterTypes
+		);
+		this.resultSetRef = resultSetRef;
+		this.querySpaces = querySpaces;
+		this.callable = callable;
+	}
+
+	/**
+	 * This form used from annotations (?).  Essentially the same as the above using a
+	 * resultset-mapping reference, but without cacheMode, readOnly, and comment.
+	 *
+	 * FIXME: annotations do not use it, so it can be remove from my POV
+	 * @deprecated
+	 *
+	 *
+	 * @param query The sql query string
+	 * @param resultSetRef The result-set-mapping name
+	 * @param querySpaces Any specified query spaces (used for auto-flushing)
+	 * @param cacheable Whether the query results are cacheable
+	 * @param cacheRegion If cacheable, the region into which to store the results
+	 * @param timeout A JDBC-level timeout to be applied
+	 * @param fetchSize A JDBC-level fetch-size to be applied
+	 * @param flushMode The flush mode to use for this query
+	 * @param parameterTypes parameter type map
+	 * @param callable Does the query string represent a callable object (i.e., proc)
+	 */
+	public NamedSQLQueryDefinition(
+			String query,
+			String resultSetRef,
+			List querySpaces,
+			boolean cacheable,
+			String cacheRegion,
+			Integer timeout,
+			Integer fetchSize,
+			FlushMode flushMode,
+			Map parameterTypes,
+			boolean callable) {
+		this(
+				query,
+				resultSetRef,
+				querySpaces,
+				cacheable,
+				cacheRegion,
+				timeout,
+				fetchSize,
+				flushMode,
+				null,
+				false,
+				null,
+				parameterTypes,
+				callable
+		);
+	}
+
+	public NativeSQLQueryReturn[] getQueryReturns() {
+		return queryReturns;
+	}
+
+	public List getQuerySpaces() {
+		return querySpaces;
+	}
+
+	public boolean isCallable() {
+		return callable;
+	}
+
+	public String getResultSetRef() {
+		return resultSetRef;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Nullability.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,183 +0,0 @@
-//$Id: Nullability.java 7566 2005-07-20 07:16:33Z oneovthafew $
-package org.hibernate.engine;
-
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyValueException;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-/**
- * Implements the algorithm for validating property values
- * for illegal null values
- * @author Gavin King
- */
-public final class Nullability {
-	
-	private final SessionImplementor session;
-	
-	public Nullability(SessionImplementor session) {
-		this.session = session;
-	}
-	/**
-	 * Check nullability of the class persister properties
-	 *
-	 * @param values entity properties
-	 * @param persister class persister
-	 * @param isUpdate wether it is intended to be updated or saved
-	 * @throws org.hibernate.PropertyValueException Break the nullability of one property
-	 * @throws HibernateException error while getting Component values
-	 */
-	public void checkNullability(
-			final Object[] values,
-			final EntityPersister persister,
-			final boolean isUpdate) 
-	throws PropertyValueException, HibernateException {
-
-		/*
-		  * Algorithm
-		  * Check for any level one nullability breaks
-		  * Look at non null components to
-		  *   recursively check next level of nullability breaks
-		  * Look at Collections contraining component to
-		  *   recursively check next level of nullability breaks
-		  *
-		  *
-		  * In the previous implementation, not-null stuffs where checked
-		  * filtering by level one only updateable
-		  * or insertable columns. So setting a sub component as update="false"
-		  * has no effect on not-null check if the main component had good checkeability
-		  * In this implementation, we keep this feature.
-		  * However, I never see any documentation mentioning that, but it's for
-		  * sure a limitation.
-		  */
-
-		final boolean[] nullability = persister.getPropertyNullability();
-		final boolean[] checkability = isUpdate ?
-			persister.getPropertyUpdateability() :
-			persister.getPropertyInsertability();
-		final Type[] propertyTypes = persister.getPropertyTypes();
-
-		for ( int i = 0; i < values.length; i++ ) {
-			
-			if ( checkability[i] && values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
-				final Object value = values[i];
-				if ( !nullability[i] && value == null ) {
-					
-					//check basic level one nullablilty
-					throw new PropertyValueException(
-							"not-null property references a null or transient value",
-							persister.getEntityName(),
-							persister.getPropertyNames()[i]
-						);
-					
-				}
-				else if ( value != null ) {
-					
-					//values is not null and is checkable, we'll look deeper
-					String breakProperties = checkSubElementsNullability( propertyTypes[i], value );
-					if ( breakProperties != null ) {
-						throw new PropertyValueException(
-							"not-null property references a null or transient value",
-							persister.getEntityName(),
-							buildPropertyPath( persister.getPropertyNames()[i], breakProperties )
-						);
-					}
-					
-				}
-			}
-			
-		}
-	}
-
-	/**
-	 * check sub elements-nullability. Returns property path that break
-	 * nullability or null if none
-	 *
-	 * @param propertyType type to check
-	 * @param value value to check
-	 *
-	 * @return property path
-	 * @throws HibernateException error while getting subcomponent values
-	 */
-	private String checkSubElementsNullability(final Type propertyType, final Object value) 
-	throws HibernateException {
-		//for non null args, check for components and elements containing components
-		if ( propertyType.isComponentType() ) {
-			return checkComponentNullability( value, (AbstractComponentType) propertyType );
-		}
-		else if ( propertyType.isCollectionType() ) {
-
-			//persistent collections may have components
-			CollectionType collectionType = (CollectionType) propertyType;
-			Type collectionElementType = collectionType.getElementType( session.getFactory() );
-			if ( collectionElementType.isComponentType() ) {
-				//check for all components values in the collection
-
-				AbstractComponentType componentType = (AbstractComponentType) collectionElementType;
-				Iterator iter = CascadingAction.getLoadedElementsIterator(session, collectionType, value);
-				while ( iter.hasNext() ) {
-					Object compValue = iter.next();
-					if (compValue != null) {
-						return checkComponentNullability(compValue, componentType);
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * check component nullability. Returns property path that break
-	 * nullability or null if none
-	 *
-	 * @param value component properties
-	 * @param compType component not-nullable type
-	 *
-	 * @return property path
-	 * @throws HibernateException error while getting subcomponent values
-	 */
-	private String checkComponentNullability(final Object value, final AbstractComponentType compType) 
-	throws HibernateException {
-		/* will check current level if some of them are not null
-		 * or sublevels if they exist
-		 */
-		boolean[] nullability = compType.getPropertyNullability();
-		if ( nullability!=null ) {
-			//do the test
-			final Object[] values = compType.getPropertyValues( value, session.getEntityMode() );
-			final Type[] propertyTypes = compType.getSubtypes();
-			for ( int i=0; i<values.length; i++ ) {
-				final Object subvalue = values[i];
-				if ( !nullability[i] && subvalue==null ) {
-					return compType.getPropertyNames()[i];
-				}
-				else if ( subvalue != null ) {
-					String breakProperties = checkSubElementsNullability( propertyTypes[i], subvalue );
-					if ( breakProperties != null ) {
-						return buildPropertyPath( compType.getPropertyNames()[i], breakProperties );
-					}
-	 			}
-	 		}
-		}
-		return null;
-	}
-
-	/**
-	 * Return a well formed property path.
-	 * Basicaly, it will return parent.child
-	 *
-	 * @param parent parent in path
-	 * @param child child in path
-	 * @return parent-child path
-	 */
-	private static String buildPropertyPath(String parent, String child) {
-		return new StringBuffer( parent.length() + child.length() + 1 )
-			.append(parent).append('.').append(child).toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Nullability.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Nullability.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,206 @@
+/*
+ * 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.engine;
+
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyValueException;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+/**
+ * Implements the algorithm for validating property values
+ * for illegal null values
+ * @author Gavin King
+ */
+public final class Nullability {
+	
+	private final SessionImplementor session;
+	
+	public Nullability(SessionImplementor session) {
+		this.session = session;
+	}
+	/**
+	 * Check nullability of the class persister properties
+	 *
+	 * @param values entity properties
+	 * @param persister class persister
+	 * @param isUpdate wether it is intended to be updated or saved
+	 * @throws org.hibernate.PropertyValueException Break the nullability of one property
+	 * @throws HibernateException error while getting Component values
+	 */
+	public void checkNullability(
+			final Object[] values,
+			final EntityPersister persister,
+			final boolean isUpdate) 
+	throws PropertyValueException, HibernateException {
+
+		/*
+		  * Algorithm
+		  * Check for any level one nullability breaks
+		  * Look at non null components to
+		  *   recursively check next level of nullability breaks
+		  * Look at Collections contraining component to
+		  *   recursively check next level of nullability breaks
+		  *
+		  *
+		  * In the previous implementation, not-null stuffs where checked
+		  * filtering by level one only updateable
+		  * or insertable columns. So setting a sub component as update="false"
+		  * has no effect on not-null check if the main component had good checkeability
+		  * In this implementation, we keep this feature.
+		  * However, I never see any documentation mentioning that, but it's for
+		  * sure a limitation.
+		  */
+
+		final boolean[] nullability = persister.getPropertyNullability();
+		final boolean[] checkability = isUpdate ?
+			persister.getPropertyUpdateability() :
+			persister.getPropertyInsertability();
+		final Type[] propertyTypes = persister.getPropertyTypes();
+
+		for ( int i = 0; i < values.length; i++ ) {
+			
+			if ( checkability[i] && values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
+				final Object value = values[i];
+				if ( !nullability[i] && value == null ) {
+					
+					//check basic level one nullablilty
+					throw new PropertyValueException(
+							"not-null property references a null or transient value",
+							persister.getEntityName(),
+							persister.getPropertyNames()[i]
+						);
+					
+				}
+				else if ( value != null ) {
+					
+					//values is not null and is checkable, we'll look deeper
+					String breakProperties = checkSubElementsNullability( propertyTypes[i], value );
+					if ( breakProperties != null ) {
+						throw new PropertyValueException(
+							"not-null property references a null or transient value",
+							persister.getEntityName(),
+							buildPropertyPath( persister.getPropertyNames()[i], breakProperties )
+						);
+					}
+					
+				}
+			}
+			
+		}
+	}
+
+	/**
+	 * check sub elements-nullability. Returns property path that break
+	 * nullability or null if none
+	 *
+	 * @param propertyType type to check
+	 * @param value value to check
+	 *
+	 * @return property path
+	 * @throws HibernateException error while getting subcomponent values
+	 */
+	private String checkSubElementsNullability(final Type propertyType, final Object value) 
+	throws HibernateException {
+		//for non null args, check for components and elements containing components
+		if ( propertyType.isComponentType() ) {
+			return checkComponentNullability( value, (AbstractComponentType) propertyType );
+		}
+		else if ( propertyType.isCollectionType() ) {
+
+			//persistent collections may have components
+			CollectionType collectionType = (CollectionType) propertyType;
+			Type collectionElementType = collectionType.getElementType( session.getFactory() );
+			if ( collectionElementType.isComponentType() ) {
+				//check for all components values in the collection
+
+				AbstractComponentType componentType = (AbstractComponentType) collectionElementType;
+				Iterator iter = CascadingAction.getLoadedElementsIterator(session, collectionType, value);
+				while ( iter.hasNext() ) {
+					Object compValue = iter.next();
+					if (compValue != null) {
+						return checkComponentNullability(compValue, componentType);
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * check component nullability. Returns property path that break
+	 * nullability or null if none
+	 *
+	 * @param value component properties
+	 * @param compType component not-nullable type
+	 *
+	 * @return property path
+	 * @throws HibernateException error while getting subcomponent values
+	 */
+	private String checkComponentNullability(final Object value, final AbstractComponentType compType) 
+	throws HibernateException {
+		/* will check current level if some of them are not null
+		 * or sublevels if they exist
+		 */
+		boolean[] nullability = compType.getPropertyNullability();
+		if ( nullability!=null ) {
+			//do the test
+			final Object[] values = compType.getPropertyValues( value, session.getEntityMode() );
+			final Type[] propertyTypes = compType.getSubtypes();
+			for ( int i=0; i<values.length; i++ ) {
+				final Object subvalue = values[i];
+				if ( !nullability[i] && subvalue==null ) {
+					return compType.getPropertyNames()[i];
+				}
+				else if ( subvalue != null ) {
+					String breakProperties = checkSubElementsNullability( propertyTypes[i], subvalue );
+					if ( breakProperties != null ) {
+						return buildPropertyPath( compType.getPropertyNames()[i], breakProperties );
+					}
+	 			}
+	 		}
+		}
+		return null;
+	}
+
+	/**
+	 * Return a well formed property path.
+	 * Basicaly, it will return parent.child
+	 *
+	 * @param parent parent in path
+	 * @param child child in path
+	 * @return parent-child path
+	 */
+	private static String buildPropertyPath(String parent, String child) {
+		return new StringBuffer( parent.length() + child.length() + 1 )
+			.append(parent).append('.').append(child).toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ParameterBinder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,114 +0,0 @@
-// $Id: ParameterBinder.java 7385 2005-07-06 17:13:15Z steveebersole $
-package org.hibernate.engine;
-
-import org.hibernate.HibernateException;
-import org.hibernate.type.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Map;
-import java.util.Iterator;
-
-/**
- * Centralizes the commonality regarding binding of parameter values into
- * PreparedStatements as this logic is used in many places.
- * <p/>
- * Ideally would like to move to the parameter handling as it is done in
- * the hql.ast package.
- * 
- * @author Steve Ebersole
- */
-public class ParameterBinder {
-
-	private static final Logger log = LoggerFactory.getLogger( ParameterBinder.class );
-
-	public static interface NamedParameterSource {
-		public int[] getNamedParameterLocations(String name);
-	}
-
-	private ParameterBinder() {
-	}
-
-	public static int bindQueryParameters(
-	        final PreparedStatement st,
-	        final QueryParameters queryParameters,
-	        final int start,
-	        final NamedParameterSource source,
-	        SessionImplementor session) throws SQLException, HibernateException {
-		int col = start;
-		col += bindPositionalParameters( st, queryParameters, col, session );
-		col += bindNamedParameters( st, queryParameters, col, source, session );
-		return col;
-	}
-
-	public static int bindPositionalParameters(
-	        final PreparedStatement st,
-	        final QueryParameters queryParameters,
-	        final int start,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-		return bindPositionalParameters(
-		        st,
-		        queryParameters.getPositionalParameterValues(),
-		        queryParameters.getPositionalParameterTypes(),
-		        start,
-		        session
-		);
-	}
-
-	public static int bindPositionalParameters(
-	        final PreparedStatement st,
-	        final Object[] values,
-	        final Type[] types,
-	        final int start,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-		int span = 0;
-		for ( int i = 0; i < values.length; i++ ) {
-			types[i].nullSafeSet( st, values[i], start + span, session );
-			span += types[i].getColumnSpan( session.getFactory() );
-		}
-		return span;
-	}
-
-	public static int bindNamedParameters(
-	        final PreparedStatement ps,
-	        final QueryParameters queryParameters,
-	        final int start,
-	        final NamedParameterSource source,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-		return bindNamedParameters( ps, queryParameters.getNamedParameters(), start, source, session );
-	}
-
-	public static int bindNamedParameters(
-	        final PreparedStatement ps,
-	        final Map namedParams,
-	        final int start,
-	        final NamedParameterSource source,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-		if ( namedParams != null ) {
-			// assumes that types are all of span 1
-			Iterator iter = namedParams.entrySet().iterator();
-			int result = 0;
-			while ( iter.hasNext() ) {
-				Map.Entry e = ( Map.Entry ) iter.next();
-				String name = ( String ) e.getKey();
-				TypedValue typedval = ( TypedValue ) e.getValue();
-				int[] locations = source.getNamedParameterLocations( name );
-				for ( int i = 0; i < locations.length; i++ ) {
-					if ( log.isDebugEnabled() ) {
-						log.debug( "bindNamedParameters() " +
-								typedval.getValue() + " -> " + name +
-								" [" + ( locations[i] + start ) + "]" );
-					}
-					typedval.getType().nullSafeSet( ps, typedval.getValue(), locations[i] + start, session );
-				}
-				result += locations.length;
-			}
-			return result;
-		}
-		else {
-			return 0;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ParameterBinder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ParameterBinder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,137 @@
+/*
+ * 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.engine;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Iterator;
+
+/**
+ * Centralizes the commonality regarding binding of parameter values into
+ * PreparedStatements as this logic is used in many places.
+ * <p/>
+ * Ideally would like to move to the parameter handling as it is done in
+ * the hql.ast package.
+ * 
+ * @author Steve Ebersole
+ */
+public class ParameterBinder {
+
+	private static final Logger log = LoggerFactory.getLogger( ParameterBinder.class );
+
+	public static interface NamedParameterSource {
+		public int[] getNamedParameterLocations(String name);
+	}
+
+	private ParameterBinder() {
+	}
+
+	public static int bindQueryParameters(
+	        final PreparedStatement st,
+	        final QueryParameters queryParameters,
+	        final int start,
+	        final NamedParameterSource source,
+	        SessionImplementor session) throws SQLException, HibernateException {
+		int col = start;
+		col += bindPositionalParameters( st, queryParameters, col, session );
+		col += bindNamedParameters( st, queryParameters, col, source, session );
+		return col;
+	}
+
+	public static int bindPositionalParameters(
+	        final PreparedStatement st,
+	        final QueryParameters queryParameters,
+	        final int start,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+		return bindPositionalParameters(
+		        st,
+		        queryParameters.getPositionalParameterValues(),
+		        queryParameters.getPositionalParameterTypes(),
+		        start,
+		        session
+		);
+	}
+
+	public static int bindPositionalParameters(
+	        final PreparedStatement st,
+	        final Object[] values,
+	        final Type[] types,
+	        final int start,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+		int span = 0;
+		for ( int i = 0; i < values.length; i++ ) {
+			types[i].nullSafeSet( st, values[i], start + span, session );
+			span += types[i].getColumnSpan( session.getFactory() );
+		}
+		return span;
+	}
+
+	public static int bindNamedParameters(
+	        final PreparedStatement ps,
+	        final QueryParameters queryParameters,
+	        final int start,
+	        final NamedParameterSource source,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+		return bindNamedParameters( ps, queryParameters.getNamedParameters(), start, source, session );
+	}
+
+	public static int bindNamedParameters(
+	        final PreparedStatement ps,
+	        final Map namedParams,
+	        final int start,
+	        final NamedParameterSource source,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+		if ( namedParams != null ) {
+			// assumes that types are all of span 1
+			Iterator iter = namedParams.entrySet().iterator();
+			int result = 0;
+			while ( iter.hasNext() ) {
+				Map.Entry e = ( Map.Entry ) iter.next();
+				String name = ( String ) e.getKey();
+				TypedValue typedval = ( TypedValue ) e.getValue();
+				int[] locations = source.getNamedParameterLocations( name );
+				for ( int i = 0; i < locations.length; i++ ) {
+					if ( log.isDebugEnabled() ) {
+						log.debug( "bindNamedParameters() " +
+								typedval.getValue() + " -> " + name +
+								" [" + ( locations[i] + start ) + "]" );
+					}
+					typedval.getType().nullSafeSet( ps, typedval.getValue(), locations[i] + start, session );
+				}
+				result += locations.length;
+			}
+			return result;
+		}
+		else {
+			return 0;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,462 +0,0 @@
-//$Id: PersistenceContext.java 14312 2008-02-05 23:55:35Z gbadner $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.loading.LoadContexts;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Holds the state of the persistence context, including the 
- * first-level cache, entries, snapshots, proxies, etc.
- * 
- * @author Gavin King
- */
-public interface PersistenceContext {
-	
-	public boolean isStateless();
-
-	/**
-	 * Get the session to which this persistence context is bound.
-	 *
-	 * @return The session.
-	 */
-	public SessionImplementor getSession();
-
-	/**
-	 * Retrieve this persistence context's managed load context.
-	 *
-	 * @return The load context
-	 */
-	public LoadContexts getLoadContexts();
-
-	/**
-	 * Add a collection which has no owner loaded
-	 */
-	public void addUnownedCollection(CollectionKey key, PersistentCollection collection);
-
-	/**
-	 * Get and remove a collection whose owner is not yet loaded,
-	 * when its owner is being loaded
-	 */
-	public PersistentCollection useUnownedCollection(CollectionKey key);
-
-	/**
-	 * Get the <tt>BatchFetchQueue</tt>, instantiating one if
-	 * necessary.
-	 */
-	public BatchFetchQueue getBatchFetchQueue();
-	
-	/**
-	 * Clear the state of the persistence context
-	 */
-	public void clear();
-
-	/**
-	 * @return false if we know for certain that all the entities are read-only
-	 */
-	public boolean hasNonReadOnlyEntities();
-
-	/**
-	 * Set the status of an entry
-	 */
-	public void setEntryStatus(EntityEntry entry, Status status);
-
-	/**
-	 * Called after transactions end
-	 */
-	public void afterTransactionCompletion();
-
-	/**
-	 * Get the current state of the entity as known to the underlying
-	 * database, or null if there is no corresponding row 
-	 */
-	public Object[] getDatabaseSnapshot(Serializable id, EntityPersister persister)
-			throws HibernateException;
-
-	public Object[] getCachedDatabaseSnapshot(EntityKey key);
-
-	/**
-	 * Get the values of the natural id fields as known to the underlying 
-	 * database, or null if the entity has no natural id or there is no 
-	 * corresponding row.
-	 */
-	public Object[] getNaturalIdSnapshot(Serializable id, EntityPersister persister)
-	throws HibernateException;
-
-	/**
-	 * Add a canonical mapping from entity key to entity instance
-	 */
-	public void addEntity(EntityKey key, Object entity);
-
-	/**
-	 * Get the entity instance associated with the given 
-	 * <tt>EntityKey</tt>
-	 */
-	public Object getEntity(EntityKey key);
-
-	/**
-	 * Is there an entity with the given key in the persistence context
-	 */
-	public boolean containsEntity(EntityKey key);
-
-	/**
-	 * Remove an entity from the session cache, also clear
-	 * up other state associated with the entity, all except
-	 * for the <tt>EntityEntry</tt>
-	 */
-	public Object removeEntity(EntityKey key);
-
-	/**
-	 * Get an entity cached by unique key
-	 */
-	public Object getEntity(EntityUniqueKey euk);
-
-	/**
-	 * Add an entity to the cache by unique key
-	 */
-	public void addEntity(EntityUniqueKey euk, Object entity);
-
-	/**
-	 * Retreive the EntityEntry representation of the given entity.
-	 *
-	 * @param entity The entity for which to locate the EntityEntry.
-	 * @return The EntityEntry for the given entity.
-	 */
-	public EntityEntry getEntry(Object entity);
-
-	/**
-	 * Remove an entity entry from the session cache
-	 */
-	public EntityEntry removeEntry(Object entity);
-
-	/**
-	 * Is there an EntityEntry for this instance?
-	 */
-	public boolean isEntryFor(Object entity);
-
-	/**
-	 * Get the collection entry for a persistent collection
-	 */
-	public CollectionEntry getCollectionEntry(PersistentCollection coll);
-
-	/**
-	 * Adds an entity to the internal caches.
-	 */
-	public EntityEntry addEntity(final Object entity, final Status status,
-			final Object[] loadedState, final EntityKey entityKey, final Object version,
-			final LockMode lockMode, final boolean existsInDatabase,
-			final EntityPersister persister, final boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched);
-
-	/**
-	 * Generates an appropriate EntityEntry instance and adds it 
-	 * to the event source's internal caches.
-	 */
-	public EntityEntry addEntry(final Object entity, final Status status,
-			final Object[] loadedState, final Object rowId, final Serializable id,
-			final Object version, final LockMode lockMode, final boolean existsInDatabase,
-			final EntityPersister persister, final boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched);
-
-	/**
-	 * Is the given collection associated with this persistence context?
-	 */
-	public boolean containsCollection(PersistentCollection collection);
-	
-	/**
-	 * Is the given proxy associated with this persistence context?
-	 */
-	public boolean containsProxy(Object proxy);
-
-	/**
-	 * Takes the given object and, if it represents a proxy, reassociates it with this event source.
-	 *
-	 * @param value The possible proxy to be reassociated.
-	 * @return Whether the passed value represented an actual proxy which got initialized.
-	 * @throws MappingException
-	 */
-	public boolean reassociateIfUninitializedProxy(Object value) throws MappingException;
-
-	/**
-	 * If a deleted entity instance is re-saved, and it has a proxy, we need to
-	 * reset the identifier of the proxy 
-	 */
-	public void reassociateProxy(Object value, Serializable id) throws MappingException;
-
-	/**
-	 * Get the entity instance underlying the given proxy, throwing
-	 * an exception if the proxy is uninitialized. If the given object
-	 * is not a proxy, simply return the argument.
-	 */
-	public Object unproxy(Object maybeProxy) throws HibernateException;
-
-	/**
-	 * Possibly unproxy the given reference and reassociate it with the current session.
-	 *
-	 * @param maybeProxy The reference to be unproxied if it currently represents a proxy.
-	 * @return The unproxied instance.
-	 * @throws HibernateException
-	 */
-	public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException;
-
-	/**
-	 * Attempts to check whether the given key represents an entity already loaded within the
-	 * current session.
-	 * @param object The entity reference against which to perform the uniqueness check.
-	 * @throws HibernateException
-	 */
-	public void checkUniqueness(EntityKey key, Object object) throws HibernateException;
-
-	/**
-	 * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
-	 * and overwrite the registration of the old one. This breaks == and occurs only for
-	 * "class" proxies rather than "interface" proxies. Also init the proxy to point to
-	 * the given target implementation if necessary.
-	 *
-	 * @param proxy The proxy instance to be narrowed.
-	 * @param persister The persister for the proxied entity.
-	 * @param key The internal cache key for the proxied entity.
-	 * @param object (optional) the actual proxied entity instance.
-	 * @return An appropriately narrowed instance.
-	 * @throws HibernateException
-	 */
-	public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
-			throws HibernateException;
-
-	/**
-	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
-	 * third argument (the entity associated with the key) if no proxy exists. Init
-	 * the proxy to the target implementation, if necessary.
-	 */
-	public Object proxyFor(EntityPersister persister, EntityKey key, Object impl)
-			throws HibernateException;
-
-	/**
-	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
-	 * argument (the entity associated with the key) if no proxy exists.
-	 * (slower than the form above)
-	 */
-	public Object proxyFor(Object impl) throws HibernateException;
-
-	/**
-	 * Get the entity that owns this persistent collection
-	 */
-	public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister)
-			throws MappingException;
-
-	/**
-	 * Get the entity that owned this persistent collection when it was loaded
-	 *
-	 * @param collection The persistent collection
-	 * @return the owner if its entity ID is available from the collection's loaded key
-	 * and the owner entity is in the persistence context; otherwise, returns null
-	 */
-	Object getLoadedCollectionOwnerOrNull(PersistentCollection collection);
-
-	/**
-	 * Get the ID for the entity that owned this persistent collection when it was loaded
-	 *
-	 * @param collection The persistent collection
-	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
-	 */
-	public Serializable getLoadedCollectionOwnerIdOrNull(PersistentCollection collection);
-
-	/**
-	 * add a collection we just loaded up (still needs initializing)
-	 */
-	public void addUninitializedCollection(CollectionPersister persister,
-			PersistentCollection collection, Serializable id);
-
-	/**
-	 * add a detached uninitialized collection
-	 */
-	public void addUninitializedDetachedCollection(CollectionPersister persister,
-			PersistentCollection collection);
-
-	/**
-	 * Add a new collection (ie. a newly created one, just instantiated by the
-	 * application, with no database state or snapshot)
-	 * @param collection The collection to be associated with the persistence context
-	 */
-	public void addNewCollection(CollectionPersister persister, PersistentCollection collection)
-			throws HibernateException;
-
-	/**
-	 * add an (initialized) collection that was created by another session and passed
-	 * into update() (ie. one with a snapshot and existing state on the database)
-	 */
-	public void addInitializedDetachedCollection(CollectionPersister collectionPersister,
-			PersistentCollection collection) throws HibernateException;
-
-	/**
-	 * add a collection we just pulled out of the cache (does not need initializing)
-	 */
-	public CollectionEntry addInitializedCollection(CollectionPersister persister,
-			PersistentCollection collection, Serializable id) throws HibernateException;
-
-	/**
-	 * Get the collection instance associated with the <tt>CollectionKey</tt>
-	 */
-	public PersistentCollection getCollection(CollectionKey collectionKey);
-
-	/**
-	 * Register a collection for non-lazy loading at the end of the
-	 * two-phase load
-	 */
-	public void addNonLazyCollection(PersistentCollection collection);
-
-	/**
-	 * Force initialization of all non-lazy collections encountered during
-	 * the current two-phase load (actually, this is a no-op, unless this
-	 * is the "outermost" load)
-	 */
-	public void initializeNonLazyCollections() throws HibernateException;
-
-	/**
-	 * Get the <tt>PersistentCollection</tt> object for an array
-	 */
-	public PersistentCollection getCollectionHolder(Object array);
-
-	/**
-	 * Register a <tt>PersistentCollection</tt> object for an array.
-	 * Associates a holder with an array - MUST be called after loading 
-	 * array, since the array instance is not created until endLoad().
-	 */
-	public void addCollectionHolder(PersistentCollection holder);
-	
-	/**
-	 * Remove the mapping of collection to holder during eviction
-	 * of the owning entity
-	 */
-	public PersistentCollection removeCollectionHolder(Object array);
-
-	/**
-	 * Get the snapshot of the pre-flush collection state
-	 */
-	public Serializable getSnapshot(PersistentCollection coll);
-
-	/**
-	 * Get the collection entry for a collection passed to filter,
-	 * which might be a collection wrapper, an array, or an unwrapped
-	 * collection. Return null if there is no entry.
-	 */
-	public CollectionEntry getCollectionEntryOrNull(Object collection);
-
-	/**
-	 * Get an existing proxy by key
-	 */
-	public Object getProxy(EntityKey key);
-
-	/**
-	 * Add a proxy to the session cache
-	 */
-	public void addProxy(EntityKey key, Object proxy);
-
-	/**
-	 * Remove a proxy from the session cache
-	 */
-	public Object removeProxy(EntityKey key);
-
-	/** 
-	 * Retrieve the set of EntityKeys representing nullifiable references
-	 */
-	public HashSet getNullifiableEntityKeys();
-
-	/**
-	 * Get the mapping from key value to entity instance
-	 */
-	public Map getEntitiesByKey();
-	
-	/**
-	 * Get the mapping from entity instance to entity entry
-	 */
-	public Map getEntityEntries();
-
-	/**
-	 * Get the mapping from collection instance to collection entry
-	 */
-	public Map getCollectionEntries();
-
-	/**
-	 * Get the mapping from collection key to collection instance
-	 */
-	public Map getCollectionsByKey();
-
-	/**
-	 * How deep are we cascaded?
-	 */
-	public int getCascadeLevel();
-	
-	/**
-	 * Called before cascading
-	 */
-	public int incrementCascadeLevel();
-
-	/**
-	 * Called after cascading
-	 */
-	public int decrementCascadeLevel();
-
-	/**
-	 * Is a flush cycle currently in process?
-	 */
-	public boolean isFlushing();
-	
-	/**
-	 * Called before and after the flushcycle
-	 */
-	public void setFlushing(boolean flushing);
-
-	/**
-	 * Call this before begining a two-phase load
-	 */
-	public void beforeLoad();
-
-	/**
-	 * Call this after finishing a two-phase load
-	 */
-	public void afterLoad();
-
-	/**
-	 * Returns a string representation of the object.
-	 *
-	 * @return a string representation of the object.
-	 */
-	public String toString();
-
-	/**
-	 * Search the persistence context for an owner for the child object,
-	 * given a collection role
-	 */
-	public Serializable getOwnerId(String entity, String property, Object childObject, Map mergeMap);
-
-	/**
-	 * Search the persistence context for an index of the child object,
-	 * given a collection role
-	 */
-	public Object getIndexInOwner(String entity, String property, Object childObject, Map mergeMap);
-
-	/**
-	 * Record the fact that the association belonging to the keyed
-	 * entity is null.
-	 */
-	public void addNullProperty(EntityKey ownerKey, String propertyName);
-
-	/**
-	 * Is the association property belonging to the keyed entity null?
-	 */
-	public boolean isPropertyNull(EntityKey ownerKey, String propertyName);
-	
-	/**
-	 * Set the object to read only and discard it's snapshot
-	 */
-	public void setReadOnly(Object entity, boolean readOnly);
-
-	void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/PersistenceContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/PersistenceContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,485 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.loading.LoadContexts;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Holds the state of the persistence context, including the 
+ * first-level cache, entries, snapshots, proxies, etc.
+ * 
+ * @author Gavin King
+ */
+public interface PersistenceContext {
+	
+	public boolean isStateless();
+
+	/**
+	 * Get the session to which this persistence context is bound.
+	 *
+	 * @return The session.
+	 */
+	public SessionImplementor getSession();
+
+	/**
+	 * Retrieve this persistence context's managed load context.
+	 *
+	 * @return The load context
+	 */
+	public LoadContexts getLoadContexts();
+
+	/**
+	 * Add a collection which has no owner loaded
+	 */
+	public void addUnownedCollection(CollectionKey key, PersistentCollection collection);
+
+	/**
+	 * Get and remove a collection whose owner is not yet loaded,
+	 * when its owner is being loaded
+	 */
+	public PersistentCollection useUnownedCollection(CollectionKey key);
+
+	/**
+	 * Get the <tt>BatchFetchQueue</tt>, instantiating one if
+	 * necessary.
+	 */
+	public BatchFetchQueue getBatchFetchQueue();
+	
+	/**
+	 * Clear the state of the persistence context
+	 */
+	public void clear();
+
+	/**
+	 * @return false if we know for certain that all the entities are read-only
+	 */
+	public boolean hasNonReadOnlyEntities();
+
+	/**
+	 * Set the status of an entry
+	 */
+	public void setEntryStatus(EntityEntry entry, Status status);
+
+	/**
+	 * Called after transactions end
+	 */
+	public void afterTransactionCompletion();
+
+	/**
+	 * Get the current state of the entity as known to the underlying
+	 * database, or null if there is no corresponding row 
+	 */
+	public Object[] getDatabaseSnapshot(Serializable id, EntityPersister persister)
+			throws HibernateException;
+
+	public Object[] getCachedDatabaseSnapshot(EntityKey key);
+
+	/**
+	 * Get the values of the natural id fields as known to the underlying 
+	 * database, or null if the entity has no natural id or there is no 
+	 * corresponding row.
+	 */
+	public Object[] getNaturalIdSnapshot(Serializable id, EntityPersister persister)
+	throws HibernateException;
+
+	/**
+	 * Add a canonical mapping from entity key to entity instance
+	 */
+	public void addEntity(EntityKey key, Object entity);
+
+	/**
+	 * Get the entity instance associated with the given 
+	 * <tt>EntityKey</tt>
+	 */
+	public Object getEntity(EntityKey key);
+
+	/**
+	 * Is there an entity with the given key in the persistence context
+	 */
+	public boolean containsEntity(EntityKey key);
+
+	/**
+	 * Remove an entity from the session cache, also clear
+	 * up other state associated with the entity, all except
+	 * for the <tt>EntityEntry</tt>
+	 */
+	public Object removeEntity(EntityKey key);
+
+	/**
+	 * Get an entity cached by unique key
+	 */
+	public Object getEntity(EntityUniqueKey euk);
+
+	/**
+	 * Add an entity to the cache by unique key
+	 */
+	public void addEntity(EntityUniqueKey euk, Object entity);
+
+	/**
+	 * Retreive the EntityEntry representation of the given entity.
+	 *
+	 * @param entity The entity for which to locate the EntityEntry.
+	 * @return The EntityEntry for the given entity.
+	 */
+	public EntityEntry getEntry(Object entity);
+
+	/**
+	 * Remove an entity entry from the session cache
+	 */
+	public EntityEntry removeEntry(Object entity);
+
+	/**
+	 * Is there an EntityEntry for this instance?
+	 */
+	public boolean isEntryFor(Object entity);
+
+	/**
+	 * Get the collection entry for a persistent collection
+	 */
+	public CollectionEntry getCollectionEntry(PersistentCollection coll);
+
+	/**
+	 * Adds an entity to the internal caches.
+	 */
+	public EntityEntry addEntity(final Object entity, final Status status,
+			final Object[] loadedState, final EntityKey entityKey, final Object version,
+			final LockMode lockMode, final boolean existsInDatabase,
+			final EntityPersister persister, final boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched);
+
+	/**
+	 * Generates an appropriate EntityEntry instance and adds it 
+	 * to the event source's internal caches.
+	 */
+	public EntityEntry addEntry(final Object entity, final Status status,
+			final Object[] loadedState, final Object rowId, final Serializable id,
+			final Object version, final LockMode lockMode, final boolean existsInDatabase,
+			final EntityPersister persister, final boolean disableVersionIncrement, boolean lazyPropertiesAreUnfetched);
+
+	/**
+	 * Is the given collection associated with this persistence context?
+	 */
+	public boolean containsCollection(PersistentCollection collection);
+	
+	/**
+	 * Is the given proxy associated with this persistence context?
+	 */
+	public boolean containsProxy(Object proxy);
+
+	/**
+	 * Takes the given object and, if it represents a proxy, reassociates it with this event source.
+	 *
+	 * @param value The possible proxy to be reassociated.
+	 * @return Whether the passed value represented an actual proxy which got initialized.
+	 * @throws MappingException
+	 */
+	public boolean reassociateIfUninitializedProxy(Object value) throws MappingException;
+
+	/**
+	 * If a deleted entity instance is re-saved, and it has a proxy, we need to
+	 * reset the identifier of the proxy 
+	 */
+	public void reassociateProxy(Object value, Serializable id) throws MappingException;
+
+	/**
+	 * Get the entity instance underlying the given proxy, throwing
+	 * an exception if the proxy is uninitialized. If the given object
+	 * is not a proxy, simply return the argument.
+	 */
+	public Object unproxy(Object maybeProxy) throws HibernateException;
+
+	/**
+	 * Possibly unproxy the given reference and reassociate it with the current session.
+	 *
+	 * @param maybeProxy The reference to be unproxied if it currently represents a proxy.
+	 * @return The unproxied instance.
+	 * @throws HibernateException
+	 */
+	public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException;
+
+	/**
+	 * Attempts to check whether the given key represents an entity already loaded within the
+	 * current session.
+	 * @param object The entity reference against which to perform the uniqueness check.
+	 * @throws HibernateException
+	 */
+	public void checkUniqueness(EntityKey key, Object object) throws HibernateException;
+
+	/**
+	 * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
+	 * and overwrite the registration of the old one. This breaks == and occurs only for
+	 * "class" proxies rather than "interface" proxies. Also init the proxy to point to
+	 * the given target implementation if necessary.
+	 *
+	 * @param proxy The proxy instance to be narrowed.
+	 * @param persister The persister for the proxied entity.
+	 * @param key The internal cache key for the proxied entity.
+	 * @param object (optional) the actual proxied entity instance.
+	 * @return An appropriately narrowed instance.
+	 * @throws HibernateException
+	 */
+	public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
+			throws HibernateException;
+
+	/**
+	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
+	 * third argument (the entity associated with the key) if no proxy exists. Init
+	 * the proxy to the target implementation, if necessary.
+	 */
+	public Object proxyFor(EntityPersister persister, EntityKey key, Object impl)
+			throws HibernateException;
+
+	/**
+	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
+	 * argument (the entity associated with the key) if no proxy exists.
+	 * (slower than the form above)
+	 */
+	public Object proxyFor(Object impl) throws HibernateException;
+
+	/**
+	 * Get the entity that owns this persistent collection
+	 */
+	public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister)
+			throws MappingException;
+
+	/**
+	 * Get the entity that owned this persistent collection when it was loaded
+	 *
+	 * @param collection The persistent collection
+	 * @return the owner if its entity ID is available from the collection's loaded key
+	 * and the owner entity is in the persistence context; otherwise, returns null
+	 */
+	Object getLoadedCollectionOwnerOrNull(PersistentCollection collection);
+
+	/**
+	 * Get the ID for the entity that owned this persistent collection when it was loaded
+	 *
+	 * @param collection The persistent collection
+	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
+	 */
+	public Serializable getLoadedCollectionOwnerIdOrNull(PersistentCollection collection);
+
+	/**
+	 * add a collection we just loaded up (still needs initializing)
+	 */
+	public void addUninitializedCollection(CollectionPersister persister,
+			PersistentCollection collection, Serializable id);
+
+	/**
+	 * add a detached uninitialized collection
+	 */
+	public void addUninitializedDetachedCollection(CollectionPersister persister,
+			PersistentCollection collection);
+
+	/**
+	 * Add a new collection (ie. a newly created one, just instantiated by the
+	 * application, with no database state or snapshot)
+	 * @param collection The collection to be associated with the persistence context
+	 */
+	public void addNewCollection(CollectionPersister persister, PersistentCollection collection)
+			throws HibernateException;
+
+	/**
+	 * add an (initialized) collection that was created by another session and passed
+	 * into update() (ie. one with a snapshot and existing state on the database)
+	 */
+	public void addInitializedDetachedCollection(CollectionPersister collectionPersister,
+			PersistentCollection collection) throws HibernateException;
+
+	/**
+	 * add a collection we just pulled out of the cache (does not need initializing)
+	 */
+	public CollectionEntry addInitializedCollection(CollectionPersister persister,
+			PersistentCollection collection, Serializable id) throws HibernateException;
+
+	/**
+	 * Get the collection instance associated with the <tt>CollectionKey</tt>
+	 */
+	public PersistentCollection getCollection(CollectionKey collectionKey);
+
+	/**
+	 * Register a collection for non-lazy loading at the end of the
+	 * two-phase load
+	 */
+	public void addNonLazyCollection(PersistentCollection collection);
+
+	/**
+	 * Force initialization of all non-lazy collections encountered during
+	 * the current two-phase load (actually, this is a no-op, unless this
+	 * is the "outermost" load)
+	 */
+	public void initializeNonLazyCollections() throws HibernateException;
+
+	/**
+	 * Get the <tt>PersistentCollection</tt> object for an array
+	 */
+	public PersistentCollection getCollectionHolder(Object array);
+
+	/**
+	 * Register a <tt>PersistentCollection</tt> object for an array.
+	 * Associates a holder with an array - MUST be called after loading 
+	 * array, since the array instance is not created until endLoad().
+	 */
+	public void addCollectionHolder(PersistentCollection holder);
+	
+	/**
+	 * Remove the mapping of collection to holder during eviction
+	 * of the owning entity
+	 */
+	public PersistentCollection removeCollectionHolder(Object array);
+
+	/**
+	 * Get the snapshot of the pre-flush collection state
+	 */
+	public Serializable getSnapshot(PersistentCollection coll);
+
+	/**
+	 * Get the collection entry for a collection passed to filter,
+	 * which might be a collection wrapper, an array, or an unwrapped
+	 * collection. Return null if there is no entry.
+	 */
+	public CollectionEntry getCollectionEntryOrNull(Object collection);
+
+	/**
+	 * Get an existing proxy by key
+	 */
+	public Object getProxy(EntityKey key);
+
+	/**
+	 * Add a proxy to the session cache
+	 */
+	public void addProxy(EntityKey key, Object proxy);
+
+	/**
+	 * Remove a proxy from the session cache
+	 */
+	public Object removeProxy(EntityKey key);
+
+	/** 
+	 * Retrieve the set of EntityKeys representing nullifiable references
+	 */
+	public HashSet getNullifiableEntityKeys();
+
+	/**
+	 * Get the mapping from key value to entity instance
+	 */
+	public Map getEntitiesByKey();
+	
+	/**
+	 * Get the mapping from entity instance to entity entry
+	 */
+	public Map getEntityEntries();
+
+	/**
+	 * Get the mapping from collection instance to collection entry
+	 */
+	public Map getCollectionEntries();
+
+	/**
+	 * Get the mapping from collection key to collection instance
+	 */
+	public Map getCollectionsByKey();
+
+	/**
+	 * How deep are we cascaded?
+	 */
+	public int getCascadeLevel();
+	
+	/**
+	 * Called before cascading
+	 */
+	public int incrementCascadeLevel();
+
+	/**
+	 * Called after cascading
+	 */
+	public int decrementCascadeLevel();
+
+	/**
+	 * Is a flush cycle currently in process?
+	 */
+	public boolean isFlushing();
+	
+	/**
+	 * Called before and after the flushcycle
+	 */
+	public void setFlushing(boolean flushing);
+
+	/**
+	 * Call this before begining a two-phase load
+	 */
+	public void beforeLoad();
+
+	/**
+	 * Call this after finishing a two-phase load
+	 */
+	public void afterLoad();
+
+	/**
+	 * Returns a string representation of the object.
+	 *
+	 * @return a string representation of the object.
+	 */
+	public String toString();
+
+	/**
+	 * Search the persistence context for an owner for the child object,
+	 * given a collection role
+	 */
+	public Serializable getOwnerId(String entity, String property, Object childObject, Map mergeMap);
+
+	/**
+	 * Search the persistence context for an index of the child object,
+	 * given a collection role
+	 */
+	public Object getIndexInOwner(String entity, String property, Object childObject, Map mergeMap);
+
+	/**
+	 * Record the fact that the association belonging to the keyed
+	 * entity is null.
+	 */
+	public void addNullProperty(EntityKey ownerKey, String propertyName);
+
+	/**
+	 * Is the association property belonging to the keyed entity null?
+	 */
+	public boolean isPropertyNull(EntityKey ownerKey, String propertyName);
+	
+	/**
+	 * Set the object to read only and discard it's snapshot
+	 */
+	public void setReadOnly(Object entity, boolean readOnly);
+
+	void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/QueryParameters.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,482 +0,0 @@
-//$Id: QueryParameters.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.hql.classic.ParserHelper;
-import org.hibernate.pretty.Printer;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @author Gavin King
- */
-public final class QueryParameters {
-	private static final Logger log = LoggerFactory.getLogger(QueryParameters.class);
-
-	private Type[] positionalParameterTypes;
-	private Object[] positionalParameterValues;
-	private Map namedParameters;
-	private Map lockModes;
-	private RowSelection rowSelection;
-	private boolean cacheable;
-	private String cacheRegion;
-	private String comment;
-	private ScrollMode scrollMode;
-	private Serializable[] collectionKeys;
-	private Object optionalObject;
-	private String optionalEntityName;
-	private Serializable optionalId;
-	private boolean readOnly;
-	private boolean callable = false;
-	private boolean autodiscovertypes = false;
-	private boolean isNaturalKeyLookup;
-	
-	private final ResultTransformer resultTransformer; // why is all others non final ?
-	
-	private String processedSQL;
-	private Type[] processedPositionalParameterTypes;
-	private Object[] processedPositionalParameterValues;
-	
-	public QueryParameters() {
-		this( ArrayHelper.EMPTY_TYPE_ARRAY, ArrayHelper.EMPTY_OBJECT_ARRAY );
-	}
-
-	public QueryParameters(Type type, Object value) {
-		this( new Type[] {type}, new Object[] {value} );
-	}
-
-	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues,
-		final Object optionalObject,
-		final String optionalEntityName,
-		final Serializable optionalObjectId
-	) {
-		this(positionalParameterTypes, postionalParameterValues);
-		this.optionalObject = optionalObject;
-		this.optionalId = optionalObjectId;
-		this.optionalEntityName = optionalEntityName;
-
-	}
-
-	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues
-	) {
-		this(
-			positionalParameterTypes,
-			postionalParameterValues, 
-			null, 
-			null, 
-			false, 
-			null, 
-			null,
-			false,
-			null
-		);
-	}
-
-	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] postionalParameterValues,
-		final Serializable[] collectionKeys
-	) {
-		this(
-			positionalParameterTypes,
-			postionalParameterValues,
-			null,
-			collectionKeys
-		);
-	}
-
-	public QueryParameters(
-			final Type[] positionalParameterTypes,
-			final Object[] postionalParameterValues,
-			final Map namedParameters,
-			final Serializable[] collectionKeys
-		) {
-			this(
-				positionalParameterTypes,
-				postionalParameterValues,
-				namedParameters,
-				null,
-				null,
-				false,
-				false,
-				null, 
-				null,
-				collectionKeys,
-				null
-			);
-		}
-
-	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] positionalParameterValues,
-		final Map lockModes,
-		final RowSelection rowSelection,
-		final boolean cacheable,
-		final String cacheRegion,
-		//final boolean forceCacheRefresh,
-		final String comment,
-		final boolean isLookupByNaturalKey,
-		final ResultTransformer transformer
-	) {
-		this(
-			positionalParameterTypes,
-			positionalParameterValues,
-			null,
-			lockModes,
-			rowSelection,
-			false,
-			cacheable,
-			cacheRegion, 
-			comment,
-			null,
-			transformer
-		);
-		isNaturalKeyLookup = isLookupByNaturalKey;
-	}
-
-	public QueryParameters(
-			final Type[] positionalParameterTypes,
-			final Object[] positionalParameterValues,
-			final Map namedParameters,
-			final Map lockModes,
-			final RowSelection rowSelection,
-			final boolean readOnly,
-			final boolean cacheable,
-			final String cacheRegion,
-			//final boolean forceCacheRefresh,
-			final String comment,
-			final Serializable[] collectionKeys,
-			ResultTransformer transformer			
-	) {
-		this.positionalParameterTypes = positionalParameterTypes;
-		this.positionalParameterValues = positionalParameterValues;
-		this.namedParameters = namedParameters;
-		this.lockModes = lockModes;
-		this.rowSelection = rowSelection;
-		this.cacheable = cacheable;
-		this.cacheRegion = cacheRegion;
-		//this.forceCacheRefresh = forceCacheRefresh;
-		this.comment = comment;
-		this.collectionKeys = collectionKeys;
-		this.readOnly = readOnly;
-		this.resultTransformer = transformer;
-	}
-	
-	public QueryParameters(
-		final Type[] positionalParameterTypes,
-		final Object[] positionalParameterValues,
-		final Map namedParameters,
-		final Map lockModes,
-		final RowSelection rowSelection,
-		final boolean readOnly,
-		final boolean cacheable,
-		final String cacheRegion,
-		//final boolean forceCacheRefresh,
-		final String comment,
-		final Serializable[] collectionKeys,
-		final Object optionalObject,
-		final String optionalEntityName,
-		final Serializable optionalId,
-		final ResultTransformer transformer
-	) {
-		this(
-			positionalParameterTypes, 
-			positionalParameterValues, 
-			namedParameters, 
-			lockModes, 
-			rowSelection, 
-			readOnly, 
-			cacheable, 
-			cacheRegion,
-			comment,
-			collectionKeys,
-			transformer
-		);
-		this.optionalEntityName = optionalEntityName;
-		this.optionalId = optionalId;
-		this.optionalObject = optionalObject;
-	}
-
-	public boolean hasRowSelection() {
-		return rowSelection!=null;
-	}
-
-	public Map getNamedParameters() {
-		return namedParameters;
-	}
-
-	public Type[] getPositionalParameterTypes() {
-		return positionalParameterTypes;
-	}
-
-	public Object[] getPositionalParameterValues() {
-		return positionalParameterValues;
-	}
-
-	public RowSelection getRowSelection() {
-		return rowSelection;
-	}
-	
-	public ResultTransformer getResultTransformer() {
-		return resultTransformer;
-	}
-
-	public void setNamedParameters(Map map) {
-		namedParameters = map;
-	}
-
-	public void setPositionalParameterTypes(Type[] types) {
-		positionalParameterTypes = types;
-	}
-
-	public void setPositionalParameterValues(Object[] objects) {
-		positionalParameterValues = objects;
-	}
-
-	public void setRowSelection(RowSelection selection) {
-		rowSelection = selection;
-	}
-
-	public Map getLockModes() {
-		return lockModes;
-	}
-
-	public void setLockModes(Map map) {
-		lockModes = map;
-	}
-
-	public void traceParameters(SessionFactoryImplementor factory) throws HibernateException {
-		Printer print = new Printer(factory);
-		if (positionalParameterValues.length!=0) {
-			log.trace(
-					"parameters: " + 
-					print.toString(positionalParameterTypes, positionalParameterValues) 
-				);
-		}
-		if (namedParameters!=null) {
-			log.trace( "named parameters: " + print.toString(namedParameters) );
-		}
-	}
-
-	public boolean isCacheable() {
-		return cacheable;
-	}
-
-	public void setCacheable(boolean b) {
-		cacheable = b;
-	}
-
-	public String getCacheRegion() {
-		return cacheRegion;
-	}
-
-	public void setCacheRegion(String cacheRegion) {
-		this.cacheRegion = cacheRegion;
-	}
-
-	public void validateParameters() throws QueryException {
-		int types = positionalParameterTypes==null ? 0 : positionalParameterTypes.length;
-		int values = positionalParameterValues==null ? 0 : positionalParameterValues.length;
-		if (types!=values) {
-			throw new QueryException(
-					"Number of positional parameter types:" + types + 
-					" does not match number of positional parameters: " + values
-				);
-		}
-	}
-
-	public String getComment() {
-		return comment;
-	}
-
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-
-	public ScrollMode getScrollMode() {
-		return scrollMode;
-	}
-
-	public void setScrollMode(ScrollMode scrollMode) {
-		this.scrollMode = scrollMode;
-	}
-
-	public Serializable[] getCollectionKeys() {
-		return collectionKeys;
-	}
-
-	public void setCollectionKeys(Serializable[] collectionKeys) {
-		this.collectionKeys = collectionKeys;
-	}
-
-	public String getOptionalEntityName() {
-		return optionalEntityName;
-	}
-
-	public void setOptionalEntityName(String optionalEntityName) {
-		this.optionalEntityName = optionalEntityName;
-	}
-
-	public Serializable getOptionalId() {
-		return optionalId;
-	}
-
-	public void setOptionalId(Serializable optionalId) {
-		this.optionalId = optionalId;
-	}
-
-	public Object getOptionalObject() {
-		return optionalObject;
-	}
-
-	public void setOptionalObject(Object optionalObject) {
-		this.optionalObject = optionalObject;
-	}
-
-	public boolean isReadOnly() {
-		return readOnly;
-	}
-
-	public void setReadOnly(boolean readOnly) {
-		this.readOnly = readOnly;
-	}
-
-	public void setCallable(boolean callable) {
-		this.callable = callable;		
-	}
-
-	public boolean isCallable() {
-		return callable;
-	}
-	
-	public boolean hasAutoDiscoverScalarTypes() {
-		return autodiscovertypes;
-	}
-
-	public void processFilters(String sql, SessionImplementor session) {
-		
-		if ( session.getEnabledFilters().size()==0 || sql.indexOf(ParserHelper.HQL_VARIABLE_PREFIX)<0 ) {
-			// HELLA IMPORTANT OPTIMIZATION!!!
-			processedPositionalParameterValues = getPositionalParameterValues();
-			processedPositionalParameterTypes = getPositionalParameterTypes();
-			processedSQL = sql;
-		}
-		else {
-			
-			Dialect dialect = session.getFactory().getDialect();
-			String symbols = new StringBuffer().append( ParserHelper.HQL_SEPARATORS )
-					.append( dialect.openQuote() )
-					.append( dialect.closeQuote() )
-					.toString();
-			StringTokenizer tokens = new StringTokenizer( sql, symbols, true );
-			StringBuffer result = new StringBuffer();
-		
-			List parameters = new ArrayList();
-			List parameterTypes = new ArrayList();
-		
-			while ( tokens.hasMoreTokens() ) {
-				final String token = tokens.nextToken();
-				if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) {
-					String filterParameterName = token.substring( 1 );
-					Object value = session.getFilterParameterValue( filterParameterName );
-					Type type = session.getFilterParameterType( filterParameterName );
-					if ( value != null && Collection.class.isAssignableFrom( value.getClass() ) ) {
-						Iterator itr = ( ( Collection ) value ).iterator();
-						while ( itr.hasNext() ) {
-							Object elementValue = itr.next();
-							result.append( '?' );
-							parameters.add( elementValue );
-							parameterTypes.add( type );
-							if ( itr.hasNext() ) {
-								result.append( ", " );
-							}
-						}
-					}
-					else {
-						result.append( '?' );
-						parameters.add( value );
-						parameterTypes.add( type );
-					}
-				}
-				else {
-					result.append( token );
-				}
-			}
-			parameters.addAll( Arrays.asList( getPositionalParameterValues() ) );
-			parameterTypes.addAll( Arrays.asList( getPositionalParameterTypes() ) );
-			processedPositionalParameterValues = parameters.toArray();
-			processedPositionalParameterTypes = ( Type[] ) parameterTypes.toArray( new Type[0] );
-			processedSQL = result.toString();
-			
-		}
-	}
-
-	public String getFilteredSQL() {
-		return processedSQL;
-	}
-
-	public Object[] getFilteredPositionalParameterValues() {
-		return processedPositionalParameterValues;
-	}
-
-	public Type[] getFilteredPositionalParameterTypes() {
-		return processedPositionalParameterTypes;
-	}
-
-	public boolean isNaturalKeyLookup() {
-		return isNaturalKeyLookup;
-	}
-
-	public void setNaturalKeyLookup(boolean isNaturalKeyLookup) {
-		this.isNaturalKeyLookup = isNaturalKeyLookup;
-	}
-
-	public void setAutoDiscoverScalarTypes(boolean autodiscovertypes) {
-		this.autodiscovertypes = autodiscovertypes;
-	}
-
-	public QueryParameters createCopyUsing(RowSelection selection) {
-		QueryParameters copy = new QueryParameters(
-				this.positionalParameterTypes,
-		        this.positionalParameterValues,
-		        this.namedParameters,
-		        this.lockModes,
-	            selection,
-		        this.readOnly,
-		        this.cacheable,
-	            this.cacheRegion,
-		        this.comment,
-		        this.collectionKeys,
-		        this.optionalObject,
-				this.optionalEntityName,
-				this.optionalId,
-				this.resultTransformer
-		);
-		copy.processedSQL = this.processedSQL;
-		copy.processedPositionalParameterTypes = this.processedPositionalParameterTypes;
-		copy.processedPositionalParameterValues = this.processedPositionalParameterValues;
-		return copy;
-	}
-
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/QueryParameters.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/QueryParameters.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,505 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.hql.classic.ParserHelper;
+import org.hibernate.pretty.Printer;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @author Gavin King
+ */
+public final class QueryParameters {
+	private static final Logger log = LoggerFactory.getLogger(QueryParameters.class);
+
+	private Type[] positionalParameterTypes;
+	private Object[] positionalParameterValues;
+	private Map namedParameters;
+	private Map lockModes;
+	private RowSelection rowSelection;
+	private boolean cacheable;
+	private String cacheRegion;
+	private String comment;
+	private ScrollMode scrollMode;
+	private Serializable[] collectionKeys;
+	private Object optionalObject;
+	private String optionalEntityName;
+	private Serializable optionalId;
+	private boolean readOnly;
+	private boolean callable = false;
+	private boolean autodiscovertypes = false;
+	private boolean isNaturalKeyLookup;
+	
+	private final ResultTransformer resultTransformer; // why is all others non final ?
+	
+	private String processedSQL;
+	private Type[] processedPositionalParameterTypes;
+	private Object[] processedPositionalParameterValues;
+	
+	public QueryParameters() {
+		this( ArrayHelper.EMPTY_TYPE_ARRAY, ArrayHelper.EMPTY_OBJECT_ARRAY );
+	}
+
+	public QueryParameters(Type type, Object value) {
+		this( new Type[] {type}, new Object[] {value} );
+	}
+
+	public QueryParameters(
+		final Type[] positionalParameterTypes,
+		final Object[] postionalParameterValues,
+		final Object optionalObject,
+		final String optionalEntityName,
+		final Serializable optionalObjectId
+	) {
+		this(positionalParameterTypes, postionalParameterValues);
+		this.optionalObject = optionalObject;
+		this.optionalId = optionalObjectId;
+		this.optionalEntityName = optionalEntityName;
+
+	}
+
+	public QueryParameters(
+		final Type[] positionalParameterTypes,
+		final Object[] postionalParameterValues
+	) {
+		this(
+			positionalParameterTypes,
+			postionalParameterValues, 
+			null, 
+			null, 
+			false, 
+			null, 
+			null,
+			false,
+			null
+		);
+	}
+
+	public QueryParameters(
+		final Type[] positionalParameterTypes,
+		final Object[] postionalParameterValues,
+		final Serializable[] collectionKeys
+	) {
+		this(
+			positionalParameterTypes,
+			postionalParameterValues,
+			null,
+			collectionKeys
+		);
+	}
+
+	public QueryParameters(
+			final Type[] positionalParameterTypes,
+			final Object[] postionalParameterValues,
+			final Map namedParameters,
+			final Serializable[] collectionKeys
+		) {
+			this(
+				positionalParameterTypes,
+				postionalParameterValues,
+				namedParameters,
+				null,
+				null,
+				false,
+				false,
+				null, 
+				null,
+				collectionKeys,
+				null
+			);
+		}
+
+	public QueryParameters(
+		final Type[] positionalParameterTypes,
+		final Object[] positionalParameterValues,
+		final Map lockModes,
+		final RowSelection rowSelection,
+		final boolean cacheable,
+		final String cacheRegion,
+		//final boolean forceCacheRefresh,
+		final String comment,
+		final boolean isLookupByNaturalKey,
+		final ResultTransformer transformer
+	) {
+		this(
+			positionalParameterTypes,
+			positionalParameterValues,
+			null,
+			lockModes,
+			rowSelection,
+			false,
+			cacheable,
+			cacheRegion, 
+			comment,
+			null,
+			transformer
+		);
+		isNaturalKeyLookup = isLookupByNaturalKey;
+	}
+
+	public QueryParameters(
+			final Type[] positionalParameterTypes,
+			final Object[] positionalParameterValues,
+			final Map namedParameters,
+			final Map lockModes,
+			final RowSelection rowSelection,
+			final boolean readOnly,
+			final boolean cacheable,
+			final String cacheRegion,
+			//final boolean forceCacheRefresh,
+			final String comment,
+			final Serializable[] collectionKeys,
+			ResultTransformer transformer			
+	) {
+		this.positionalParameterTypes = positionalParameterTypes;
+		this.positionalParameterValues = positionalParameterValues;
+		this.namedParameters = namedParameters;
+		this.lockModes = lockModes;
+		this.rowSelection = rowSelection;
+		this.cacheable = cacheable;
+		this.cacheRegion = cacheRegion;
+		//this.forceCacheRefresh = forceCacheRefresh;
+		this.comment = comment;
+		this.collectionKeys = collectionKeys;
+		this.readOnly = readOnly;
+		this.resultTransformer = transformer;
+	}
+	
+	public QueryParameters(
+		final Type[] positionalParameterTypes,
+		final Object[] positionalParameterValues,
+		final Map namedParameters,
+		final Map lockModes,
+		final RowSelection rowSelection,
+		final boolean readOnly,
+		final boolean cacheable,
+		final String cacheRegion,
+		//final boolean forceCacheRefresh,
+		final String comment,
+		final Serializable[] collectionKeys,
+		final Object optionalObject,
+		final String optionalEntityName,
+		final Serializable optionalId,
+		final ResultTransformer transformer
+	) {
+		this(
+			positionalParameterTypes, 
+			positionalParameterValues, 
+			namedParameters, 
+			lockModes, 
+			rowSelection, 
+			readOnly, 
+			cacheable, 
+			cacheRegion,
+			comment,
+			collectionKeys,
+			transformer
+		);
+		this.optionalEntityName = optionalEntityName;
+		this.optionalId = optionalId;
+		this.optionalObject = optionalObject;
+	}
+
+	public boolean hasRowSelection() {
+		return rowSelection!=null;
+	}
+
+	public Map getNamedParameters() {
+		return namedParameters;
+	}
+
+	public Type[] getPositionalParameterTypes() {
+		return positionalParameterTypes;
+	}
+
+	public Object[] getPositionalParameterValues() {
+		return positionalParameterValues;
+	}
+
+	public RowSelection getRowSelection() {
+		return rowSelection;
+	}
+	
+	public ResultTransformer getResultTransformer() {
+		return resultTransformer;
+	}
+
+	public void setNamedParameters(Map map) {
+		namedParameters = map;
+	}
+
+	public void setPositionalParameterTypes(Type[] types) {
+		positionalParameterTypes = types;
+	}
+
+	public void setPositionalParameterValues(Object[] objects) {
+		positionalParameterValues = objects;
+	}
+
+	public void setRowSelection(RowSelection selection) {
+		rowSelection = selection;
+	}
+
+	public Map getLockModes() {
+		return lockModes;
+	}
+
+	public void setLockModes(Map map) {
+		lockModes = map;
+	}
+
+	public void traceParameters(SessionFactoryImplementor factory) throws HibernateException {
+		Printer print = new Printer(factory);
+		if (positionalParameterValues.length!=0) {
+			log.trace(
+					"parameters: " + 
+					print.toString(positionalParameterTypes, positionalParameterValues) 
+				);
+		}
+		if (namedParameters!=null) {
+			log.trace( "named parameters: " + print.toString(namedParameters) );
+		}
+	}
+
+	public boolean isCacheable() {
+		return cacheable;
+	}
+
+	public void setCacheable(boolean b) {
+		cacheable = b;
+	}
+
+	public String getCacheRegion() {
+		return cacheRegion;
+	}
+
+	public void setCacheRegion(String cacheRegion) {
+		this.cacheRegion = cacheRegion;
+	}
+
+	public void validateParameters() throws QueryException {
+		int types = positionalParameterTypes==null ? 0 : positionalParameterTypes.length;
+		int values = positionalParameterValues==null ? 0 : positionalParameterValues.length;
+		if (types!=values) {
+			throw new QueryException(
+					"Number of positional parameter types:" + types + 
+					" does not match number of positional parameters: " + values
+				);
+		}
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public ScrollMode getScrollMode() {
+		return scrollMode;
+	}
+
+	public void setScrollMode(ScrollMode scrollMode) {
+		this.scrollMode = scrollMode;
+	}
+
+	public Serializable[] getCollectionKeys() {
+		return collectionKeys;
+	}
+
+	public void setCollectionKeys(Serializable[] collectionKeys) {
+		this.collectionKeys = collectionKeys;
+	}
+
+	public String getOptionalEntityName() {
+		return optionalEntityName;
+	}
+
+	public void setOptionalEntityName(String optionalEntityName) {
+		this.optionalEntityName = optionalEntityName;
+	}
+
+	public Serializable getOptionalId() {
+		return optionalId;
+	}
+
+	public void setOptionalId(Serializable optionalId) {
+		this.optionalId = optionalId;
+	}
+
+	public Object getOptionalObject() {
+		return optionalObject;
+	}
+
+	public void setOptionalObject(Object optionalObject) {
+		this.optionalObject = optionalObject;
+	}
+
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+
+	public void setReadOnly(boolean readOnly) {
+		this.readOnly = readOnly;
+	}
+
+	public void setCallable(boolean callable) {
+		this.callable = callable;		
+	}
+
+	public boolean isCallable() {
+		return callable;
+	}
+	
+	public boolean hasAutoDiscoverScalarTypes() {
+		return autodiscovertypes;
+	}
+
+	public void processFilters(String sql, SessionImplementor session) {
+		
+		if ( session.getEnabledFilters().size()==0 || sql.indexOf(ParserHelper.HQL_VARIABLE_PREFIX)<0 ) {
+			// HELLA IMPORTANT OPTIMIZATION!!!
+			processedPositionalParameterValues = getPositionalParameterValues();
+			processedPositionalParameterTypes = getPositionalParameterTypes();
+			processedSQL = sql;
+		}
+		else {
+			
+			Dialect dialect = session.getFactory().getDialect();
+			String symbols = new StringBuffer().append( ParserHelper.HQL_SEPARATORS )
+					.append( dialect.openQuote() )
+					.append( dialect.closeQuote() )
+					.toString();
+			StringTokenizer tokens = new StringTokenizer( sql, symbols, true );
+			StringBuffer result = new StringBuffer();
+		
+			List parameters = new ArrayList();
+			List parameterTypes = new ArrayList();
+		
+			while ( tokens.hasMoreTokens() ) {
+				final String token = tokens.nextToken();
+				if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) {
+					String filterParameterName = token.substring( 1 );
+					Object value = session.getFilterParameterValue( filterParameterName );
+					Type type = session.getFilterParameterType( filterParameterName );
+					if ( value != null && Collection.class.isAssignableFrom( value.getClass() ) ) {
+						Iterator itr = ( ( Collection ) value ).iterator();
+						while ( itr.hasNext() ) {
+							Object elementValue = itr.next();
+							result.append( '?' );
+							parameters.add( elementValue );
+							parameterTypes.add( type );
+							if ( itr.hasNext() ) {
+								result.append( ", " );
+							}
+						}
+					}
+					else {
+						result.append( '?' );
+						parameters.add( value );
+						parameterTypes.add( type );
+					}
+				}
+				else {
+					result.append( token );
+				}
+			}
+			parameters.addAll( Arrays.asList( getPositionalParameterValues() ) );
+			parameterTypes.addAll( Arrays.asList( getPositionalParameterTypes() ) );
+			processedPositionalParameterValues = parameters.toArray();
+			processedPositionalParameterTypes = ( Type[] ) parameterTypes.toArray( new Type[0] );
+			processedSQL = result.toString();
+			
+		}
+	}
+
+	public String getFilteredSQL() {
+		return processedSQL;
+	}
+
+	public Object[] getFilteredPositionalParameterValues() {
+		return processedPositionalParameterValues;
+	}
+
+	public Type[] getFilteredPositionalParameterTypes() {
+		return processedPositionalParameterTypes;
+	}
+
+	public boolean isNaturalKeyLookup() {
+		return isNaturalKeyLookup;
+	}
+
+	public void setNaturalKeyLookup(boolean isNaturalKeyLookup) {
+		this.isNaturalKeyLookup = isNaturalKeyLookup;
+	}
+
+	public void setAutoDiscoverScalarTypes(boolean autodiscovertypes) {
+		this.autodiscovertypes = autodiscovertypes;
+	}
+
+	public QueryParameters createCopyUsing(RowSelection selection) {
+		QueryParameters copy = new QueryParameters(
+				this.positionalParameterTypes,
+		        this.positionalParameterValues,
+		        this.namedParameters,
+		        this.lockModes,
+	            selection,
+		        this.readOnly,
+		        this.cacheable,
+	            this.cacheRegion,
+		        this.comment,
+		        this.collectionKeys,
+		        this.optionalObject,
+				this.optionalEntityName,
+				this.optionalId,
+				this.resultTransformer
+		);
+		copy.processedSQL = this.processedSQL;
+		copy.processedPositionalParameterTypes = this.processedPositionalParameterTypes;
+		copy.processedPositionalParameterValues = this.processedPositionalParameterValues;
+		return copy;
+	}
+
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: ResultSetMappingDefinition.java 10018 2006-06-15 05:21:06Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.io.Serializable;
-
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-
-/**
- * Keep a description of the resultset mapping
- *
- * @author Emmanuel Bernard
- */
-public class ResultSetMappingDefinition implements Serializable {
-
-	private final String name;
-	private final List /*NativeSQLQueryReturn*/ queryReturns = new ArrayList();
-
-	public ResultSetMappingDefinition(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void addQueryReturn(NativeSQLQueryReturn queryReturn) {
-		queryReturns.add( queryReturn );
-	}
-
-// We could also keep these if needed for binary compatibility with annotations, provided
-// it only uses the addXXX() methods...
-//	public void addEntityQueryReturn(NativeSQLQueryNonScalarReturn entityQueryReturn) {
-//		entityQueryReturns.add(entityQueryReturn);
-//	}
-//
-//	public void addScalarQueryReturn(NativeSQLQueryScalarReturn scalarQueryReturn) {
-//		scalarQueryReturns.add(scalarQueryReturn);
-//	}
-
-	public NativeSQLQueryReturn[] getQueryReturns() {
-		return ( NativeSQLQueryReturn[] ) queryReturns.toArray( new NativeSQLQueryReturn[0] );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ResultSetMappingDefinition.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.Serializable;
+
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+
+/**
+ * Keep a description of the resultset mapping
+ *
+ * @author Emmanuel Bernard
+ */
+public class ResultSetMappingDefinition implements Serializable {
+
+	private final String name;
+	private final List /*NativeSQLQueryReturn*/ queryReturns = new ArrayList();
+
+	public ResultSetMappingDefinition(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void addQueryReturn(NativeSQLQueryReturn queryReturn) {
+		queryReturns.add( queryReturn );
+	}
+
+// We could also keep these if needed for binary compatibility with annotations, provided
+// it only uses the addXXX() methods...
+//	public void addEntityQueryReturn(NativeSQLQueryNonScalarReturn entityQueryReturn) {
+//		entityQueryReturns.add(entityQueryReturn);
+//	}
+//
+//	public void addScalarQueryReturn(NativeSQLQueryScalarReturn scalarQueryReturn) {
+//		scalarQueryReturns.add(scalarQueryReturn);
+//	}
+
+	public NativeSQLQueryReturn[] getQueryReturns() {
+		return ( NativeSQLQueryReturn[] ) queryReturns.toArray( new NativeSQLQueryReturn[0] );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/RowSelection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: RowSelection.java 9299 2006-02-16 22:51:00Z steveebersole $
-package org.hibernate.engine;
-
-/**
- * Represents a selection of rows in a JDBC <tt>ResultSet</tt>
- * @author Gavin King
- */
-public final class RowSelection {
-	private Integer firstRow;
-	private Integer maxRows;
-	private Integer timeout;
-	private Integer fetchSize;
-
-	public void setFirstRow(Integer firstRow) {
-		this.firstRow = firstRow;
-	}
-
-	public Integer getFirstRow() {
-		return firstRow;
-	}
-
-	public void setMaxRows(Integer maxRows) {
-		this.maxRows = maxRows;
-	}
-
-	public Integer getMaxRows() {
-		return maxRows;
-	}
-
-	public void setTimeout(Integer timeout) {
-		this.timeout = timeout;
-	}
-
-	public Integer getTimeout() {
-		return timeout;
-	}
-
-	public Integer getFetchSize() {
-		return fetchSize;
-	}
-
-	public void setFetchSize(Integer fetchSize) {
-		this.fetchSize = fetchSize;
-	}
-
-	public boolean definesLimits() {
-		return maxRows != null ||
-	           ( firstRow != null && firstRow.intValue() <= 0 );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/RowSelection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/RowSelection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.engine;
+
+/**
+ * Represents a selection of rows in a JDBC <tt>ResultSet</tt>
+ * @author Gavin King
+ */
+public final class RowSelection {
+	private Integer firstRow;
+	private Integer maxRows;
+	private Integer timeout;
+	private Integer fetchSize;
+
+	public void setFirstRow(Integer firstRow) {
+		this.firstRow = firstRow;
+	}
+
+	public Integer getFirstRow() {
+		return firstRow;
+	}
+
+	public void setMaxRows(Integer maxRows) {
+		this.maxRows = maxRows;
+	}
+
+	public Integer getMaxRows() {
+		return maxRows;
+	}
+
+	public void setTimeout(Integer timeout) {
+		this.timeout = timeout;
+	}
+
+	public Integer getTimeout() {
+		return timeout;
+	}
+
+	public Integer getFetchSize() {
+		return fetchSize;
+	}
+
+	public void setFetchSize(Integer fetchSize) {
+		this.fetchSize = fetchSize;
+	}
+
+	public boolean definesLimits() {
+		return maxRows != null ||
+	           ( firstRow != null && firstRow.intValue() <= 0 );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,200 +0,0 @@
-//$Id: SessionFactoryImplementor.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.util.Map;
-import java.util.Set;
-import java.sql.Connection;
-
-import javax.transaction.TransactionManager;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.MappingException;
-import org.hibernate.SessionFactory;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.proxy.EntityNotFoundDelegate;
-import org.hibernate.engine.query.QueryPlanCache;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.cache.QueryCache;
-import org.hibernate.cache.UpdateTimestampsCache;
-import org.hibernate.cache.Region;
-import org.hibernate.cfg.Settings;
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.stat.StatisticsImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Defines the internal contract between the <tt>SessionFactory</tt> and other parts of
- * Hibernate such as implementors of <tt>Type</tt>.
- *
- * @see org.hibernate.SessionFactory
- * @see org.hibernate.impl.SessionFactoryImpl
- * @author Gavin King
- */
-public interface SessionFactoryImplementor extends Mapping, SessionFactory {
-
-	/**
-	 * Get the persister for the named entity
-	 *
-	 * @param entityName The name of the entity for which to retrieve the persister.
-	 * @return The persister
-	 * @throws MappingException Indicates persister could not be found with that name.
-	 */
-	public EntityPersister getEntityPersister(String entityName) throws MappingException;
-
-	/**
-	 * Get the persister object for a collection role.
-	 *
-	 * @param role The role (name) of the collection for which to retrieve the
-	 * persister.
-	 * @return The persister
-	 * @throws MappingException Indicates persister could not be found with that role.
-	 */
-	public CollectionPersister getCollectionPersister(String role) throws MappingException;
-
-	/**
-	 * Get the SQL dialect.
-	 * <p/>
-	 * Shorthand for {@link #getSettings()}.{@link Settings#getDialect()}
-	 *
-	 * @return The dialect
-	 */
-	public Dialect getDialect();
-
-	/**
-	 * Get the factory scoped interceptor for this factory.
-	 *
-	 * @return The factory scope interceptor, or null if none.
-	 */
-	public Interceptor getInterceptor();
-
-	public QueryPlanCache getQueryPlanCache();
-
-	/**
-	 * Get the return types of a query
-	 */
-	public Type[] getReturnTypes(String queryString) throws HibernateException;
-
-	/**
-	 * Get the return aliases of a query
-	 */
-	public String[] getReturnAliases(String queryString) throws HibernateException;
-
-	/**
-	 * Get the connection provider
-	 */
-	public ConnectionProvider getConnectionProvider();
-	/**
-	 * Get the names of all persistent classes that implement/extend the given interface/class
-	 */
-	public String[] getImplementors(String className) throws MappingException;
-	/**
-	 * Get a class name, using query language imports
-	 */
-	public String getImportedClassName(String name);
-
-
-	/**
-	 * Get the JTA transaction manager
-	 */
-	public TransactionManager getTransactionManager();
-
-
-	/**
-	 * Get the default query cache
-	 */
-	public QueryCache getQueryCache();
-	/**
-	 * Get a particular named query cache, or the default cache
-	 * @param regionName the name of the cache region, or null for the default query cache
-	 * @return the existing cache, or a newly created cache if none by that region name
-	 */
-	public QueryCache getQueryCache(String regionName) throws HibernateException;
-	
-	/**
-	 * Get the cache of table update timestamps
-	 */
-	public UpdateTimestampsCache getUpdateTimestampsCache();
-	/**
-	 * Statistics SPI
-	 */
-	public StatisticsImplementor getStatisticsImplementor();
-	
-	public NamedQueryDefinition getNamedQuery(String queryName);
-	public NamedSQLQueryDefinition getNamedSQLQuery(String queryName);
-	public ResultSetMappingDefinition getResultSetMapping(String name);
-
-	/**
-	 * Get the identifier generator for the hierarchy
-	 */
-	public IdentifierGenerator getIdentifierGenerator(String rootEntityName);
-	
-	/**
-	 * Get a named second-level cache region
-	 *
-	 * @param regionName The name of the region to retrieve.
-	 * @return The region
-	 */
-	public Region getSecondLevelCacheRegion(String regionName);
-
-	/**
-	 * Get a map of all the second level cache regions currently maintained in
-	 * this session factory.  The map is structured with the region name as the
-	 * key and the {@link Region} instances as the values.
-	 *
-	 * @return The map of regions
-	 */
-	public Map getAllSecondLevelCacheRegions();
-	
-	/**
-	 * Retrieves the SQLExceptionConverter in effect for this SessionFactory.
-	 *
-	 * @return The SQLExceptionConverter for this SessionFactory.
-	 */
-	public SQLExceptionConverter getSQLExceptionConverter();
-
-	public Settings getSettings();
-
-	/**
-	 * Get a nontransactional "current" session for Hibernate EntityManager
-	 */
-	public org.hibernate.classic.Session openTemporarySession() throws HibernateException;
-
-	/**
-	 * Open a session conforming to the given parameters.  Used mainly by
-	 * {@link org.hibernate.context.JTASessionContext} for current session processing.
-	 *
-	 * @param connection The external jdbc connection to use, if one (i.e., optional).
-	 * @param flushBeforeCompletionEnabled Should the session be auto-flushed
-	 * prior to transaction completion?
-	 * @param autoCloseSessionEnabled Should the session be auto-closed after
-	 * transaction completion?
-	 * @param connectionReleaseMode The release mode for managed jdbc connections.
-	 * @return An appropriate session.
-	 * @throws HibernateException
-	 */
-	public org.hibernate.classic.Session openSession(
-			final Connection connection,
-			final boolean flushBeforeCompletionEnabled,
-			final boolean autoCloseSessionEnabled,
-			final ConnectionReleaseMode connectionReleaseMode) throws HibernateException;
-
-	/**
-	 * Retrieves a set of all the collection roles in which the given entity
-	 * is a participant, as either an index or an element.
-	 *
-	 * @param entityName The entity name for which to get the collection roles.
-	 * @return set of all the collection roles in which the given entityName participates.
-	 */
-	public Set getCollectionRolesByEntityParticipant(String entityName);
-
-	public EntityNotFoundDelegate getEntityNotFoundDelegate();
-
-	public SQLFunctionRegistry getSqlFunctionRegistry();
-		
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionFactoryImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,223 @@
+/*
+ * 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.engine;
+
+import java.util.Map;
+import java.util.Set;
+import java.sql.Connection;
+
+import javax.transaction.TransactionManager;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.MappingException;
+import org.hibernate.SessionFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.engine.query.QueryPlanCache;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.cache.QueryCache;
+import org.hibernate.cache.UpdateTimestampsCache;
+import org.hibernate.cache.Region;
+import org.hibernate.cfg.Settings;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.stat.StatisticsImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Defines the internal contract between the <tt>SessionFactory</tt> and other parts of
+ * Hibernate such as implementors of <tt>Type</tt>.
+ *
+ * @see org.hibernate.SessionFactory
+ * @see org.hibernate.impl.SessionFactoryImpl
+ * @author Gavin King
+ */
+public interface SessionFactoryImplementor extends Mapping, SessionFactory {
+
+	/**
+	 * Get the persister for the named entity
+	 *
+	 * @param entityName The name of the entity for which to retrieve the persister.
+	 * @return The persister
+	 * @throws MappingException Indicates persister could not be found with that name.
+	 */
+	public EntityPersister getEntityPersister(String entityName) throws MappingException;
+
+	/**
+	 * Get the persister object for a collection role.
+	 *
+	 * @param role The role (name) of the collection for which to retrieve the
+	 * persister.
+	 * @return The persister
+	 * @throws MappingException Indicates persister could not be found with that role.
+	 */
+	public CollectionPersister getCollectionPersister(String role) throws MappingException;
+
+	/**
+	 * Get the SQL dialect.
+	 * <p/>
+	 * Shorthand for {@link #getSettings()}.{@link Settings#getDialect()}
+	 *
+	 * @return The dialect
+	 */
+	public Dialect getDialect();
+
+	/**
+	 * Get the factory scoped interceptor for this factory.
+	 *
+	 * @return The factory scope interceptor, or null if none.
+	 */
+	public Interceptor getInterceptor();
+
+	public QueryPlanCache getQueryPlanCache();
+
+	/**
+	 * Get the return types of a query
+	 */
+	public Type[] getReturnTypes(String queryString) throws HibernateException;
+
+	/**
+	 * Get the return aliases of a query
+	 */
+	public String[] getReturnAliases(String queryString) throws HibernateException;
+
+	/**
+	 * Get the connection provider
+	 */
+	public ConnectionProvider getConnectionProvider();
+	/**
+	 * Get the names of all persistent classes that implement/extend the given interface/class
+	 */
+	public String[] getImplementors(String className) throws MappingException;
+	/**
+	 * Get a class name, using query language imports
+	 */
+	public String getImportedClassName(String name);
+
+
+	/**
+	 * Get the JTA transaction manager
+	 */
+	public TransactionManager getTransactionManager();
+
+
+	/**
+	 * Get the default query cache
+	 */
+	public QueryCache getQueryCache();
+	/**
+	 * Get a particular named query cache, or the default cache
+	 * @param regionName the name of the cache region, or null for the default query cache
+	 * @return the existing cache, or a newly created cache if none by that region name
+	 */
+	public QueryCache getQueryCache(String regionName) throws HibernateException;
+	
+	/**
+	 * Get the cache of table update timestamps
+	 */
+	public UpdateTimestampsCache getUpdateTimestampsCache();
+	/**
+	 * Statistics SPI
+	 */
+	public StatisticsImplementor getStatisticsImplementor();
+	
+	public NamedQueryDefinition getNamedQuery(String queryName);
+	public NamedSQLQueryDefinition getNamedSQLQuery(String queryName);
+	public ResultSetMappingDefinition getResultSetMapping(String name);
+
+	/**
+	 * Get the identifier generator for the hierarchy
+	 */
+	public IdentifierGenerator getIdentifierGenerator(String rootEntityName);
+	
+	/**
+	 * Get a named second-level cache region
+	 *
+	 * @param regionName The name of the region to retrieve.
+	 * @return The region
+	 */
+	public Region getSecondLevelCacheRegion(String regionName);
+
+	/**
+	 * Get a map of all the second level cache regions currently maintained in
+	 * this session factory.  The map is structured with the region name as the
+	 * key and the {@link Region} instances as the values.
+	 *
+	 * @return The map of regions
+	 */
+	public Map getAllSecondLevelCacheRegions();
+	
+	/**
+	 * Retrieves the SQLExceptionConverter in effect for this SessionFactory.
+	 *
+	 * @return The SQLExceptionConverter for this SessionFactory.
+	 */
+	public SQLExceptionConverter getSQLExceptionConverter();
+
+	public Settings getSettings();
+
+	/**
+	 * Get a nontransactional "current" session for Hibernate EntityManager
+	 */
+	public org.hibernate.classic.Session openTemporarySession() throws HibernateException;
+
+	/**
+	 * Open a session conforming to the given parameters.  Used mainly by
+	 * {@link org.hibernate.context.JTASessionContext} for current session processing.
+	 *
+	 * @param connection The external jdbc connection to use, if one (i.e., optional).
+	 * @param flushBeforeCompletionEnabled Should the session be auto-flushed
+	 * prior to transaction completion?
+	 * @param autoCloseSessionEnabled Should the session be auto-closed after
+	 * transaction completion?
+	 * @param connectionReleaseMode The release mode for managed jdbc connections.
+	 * @return An appropriate session.
+	 * @throws HibernateException
+	 */
+	public org.hibernate.classic.Session openSession(
+			final Connection connection,
+			final boolean flushBeforeCompletionEnabled,
+			final boolean autoCloseSessionEnabled,
+			final ConnectionReleaseMode connectionReleaseMode) throws HibernateException;
+
+	/**
+	 * Retrieves a set of all the collection roles in which the given entity
+	 * is a participant, as either an index or an element.
+	 *
+	 * @param entityName The entity name for which to get the collection roles.
+	 * @return set of all the collection roles in which the given entityName participates.
+	 */
+	public Set getCollectionRolesByEntityParticipant(String entityName);
+
+	public EntityNotFoundDelegate getEntityNotFoundDelegate();
+
+	public SQLFunctionRegistry getSqlFunctionRegistry();
+		
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,302 +0,0 @@
-//$Id: SessionImplementor.java 10018 2006-06-15 05:21:06Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.CacheMode;
-import org.hibernate.EntityMode;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.Query;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.Transaction;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventListeners;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.jdbc.Batcher;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.loader.custom.CustomQuery;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.Type;
-
-
-/**
- * Defines the internal contract between the <tt>Session</tt> and other parts of
- * Hibernate such as implementors of <tt>Type</tt> or <tt>EntityPersister</tt>.
- *
- * @see org.hibernate.Session the interface to the application
- * @see org.hibernate.impl.SessionImpl the actual implementation
- * @author Gavin King
- */
-public interface SessionImplementor extends Serializable {
-
-	/**
-	 * Retrieves the interceptor currently in use by this event source.
-	 *
-	 * @return The interceptor.
-	 */
-	public Interceptor getInterceptor();
-	
-	/**
-	 * Enable/disable automatic cache clearing from after transaction
-	 * completion (for EJB3)
-	 */
-	public void setAutoClear(boolean enabled);
-		
-	/**
-	 * Does this <tt>Session</tt> have an active Hibernate transaction
-	 * or is there a JTA transaction in progress?
-	 */
-	public boolean isTransactionInProgress();
-
-	/**
-	 * Initialize the collection (if not already initialized)
-	 */
-	public void initializeCollection(PersistentCollection collection, boolean writing) 
-	throws HibernateException;
-	
-	/**
-	 * Load an instance without checking if it was deleted. 
-	 * 
-	 * When <tt>nullable</tt> is disabled this method may create a new proxy or 
-	 * return an existing proxy; if it does not exist, throw an exception.
-	 * 
-	 * When <tt>nullable</tt> is enabled, the method does not create new proxies 
-	 * (but might return an existing proxy); if it does not exist, return 
-	 * <tt>null</tt>.
-	 * 
-	 * When <tt>eager</tt> is enabled, the object is eagerly fetched
-	 */
-	public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) 
-	throws HibernateException;
-
-	/**
-	 * Load an instance immediately. This method is only called when lazily initializing a proxy.
-	 * Do not return the proxy.
-	 */
-	public Object immediateLoad(String entityName, Serializable id) throws HibernateException;
-
-	/**
-	 * System time before the start of the transaction
-	 */
-	public long getTimestamp();
-	/**
-	 * Get the creating <tt>SessionFactoryImplementor</tt>
-	 */
-	public SessionFactoryImplementor getFactory();
-	/**
-	 * Get the prepared statement <tt>Batcher</tt> for this session
-	 */
-	public Batcher getBatcher();
-	
-	/**
-	 * Execute a <tt>find()</tt> query
-	 */
-	public List list(String query, QueryParameters queryParameters) throws HibernateException;
-	/**
-	 * Execute an <tt>iterate()</tt> query
-	 */
-	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException;
-	/**
-	 * Execute a <tt>scroll()</tt> query
-	 */
-	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException;
-	/**
-	 * Execute a criteria query
-	 */
-	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode);
-	/**
-	 * Execute a criteria query
-	 */
-	public List list(CriteriaImpl criteria);
-	
-	/**
-	 * Execute a filter
-	 */
-	public List listFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException;
-	/**
-	 * Iterate a filter
-	 */
-	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException;
-	
-	/**
-	 * Get the <tt>EntityPersister</tt> for any instance
-	 * @param entityName optional entity name
-	 * @param object the entity instance
-	 */
-	public EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException;
-	
-	/**
-	 * Get the entity instance associated with the given <tt>Key</tt>,
-	 * calling the Interceptor if necessary
-	 */
-	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException;
-
-	/**
-	 * Notify the session that the transaction completed, so we no longer
-	 * own the old locks. (Also we should release cache softlocks.) May
-	 * be called multiple times during the transaction completion process.
-	 * Also called after an autocommit, in which case the second argument
-	 * is null.
-	 */
-	public void afterTransactionCompletion(boolean successful, Transaction tx);
-	
-	/**
-	 * Notify the session that the transaction is about to complete
-	 */
-	public void beforeTransactionCompletion(Transaction tx);
-
-	/**
-	 * Return the identifier of the persistent object, or null if 
-	 * not associated with the session
-	 */
-	public Serializable getContextEntityIdentifier(Object object);
-
-	/**
-	 * The best guess entity name for an entity not in an association
-	 */
-	public String bestGuessEntityName(Object object);
-	
-	/**
-	 * The guessed entity name for an entity not in an association
-	 */
-	public String guessEntityName(Object entity) throws HibernateException;
-	
-	/** 
-	 * Instantiate the entity class, initializing with the given identifier
-	 */
-	public Object instantiate(String entityName, Serializable id) throws HibernateException;
-	
-	/**
-	 * Execute an SQL Query
-	 */
-	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
-	throws HibernateException;
-	
-	/**
-	 * Execute an SQL Query
-	 */
-	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
-	throws HibernateException;
-
-	/**
-	 * Execute a native SQL query, and return the results as a fully built list.
-	 *
-	 * @param spec The specification of the native SQL query to execute.
-	 * @param queryParameters The parameters by which to perform the execution.
-	 * @return The result list.
-	 * @throws HibernateException
-	 */
-	public List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
-	throws HibernateException;
-
-	/**
-	 * Execute a native SQL query, and return the results as a scrollable result.
-	 *
-	 * @param spec The specification of the native SQL query to execute.
-	 * @param queryParameters The parameters by which to perform the execution.
-	 * @return The resulting scrollable result.
-	 * @throws HibernateException
-	 */
-	public ScrollableResults scroll(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
-	throws HibernateException;
-
-	/**
-	 * Retreive the currently set value for a filter parameter.
-	 *
-	 * @param filterParameterName The filter parameter name in the format
-	 * {FILTER_NAME.PARAMETER_NAME}.
-	 * @return The filter parameter value.
-	 */
-	public Object getFilterParameterValue(String filterParameterName);
-
-	/**
-	 * Retreive the type for a given filter parrameter.
-	 *
-	 * @param filterParameterName The filter parameter name in the format
-	 * {FILTER_NAME.PARAMETER_NAME}.
-	 */
-	public Type getFilterParameterType(String filterParameterName);
-
-	/**
-	 * Return the currently enabled filters.  The filter map is keyed by filter
-	 * name, with values corresponding to the {@link org.hibernate.impl.FilterImpl}
-	 * instance.
-	 * @return The currently enabled filters.
-	 */
-	public Map getEnabledFilters();
-	
-	public int getDontFlushFromFind();
-	
-	/**
-	 * Retrieves the configured event listeners from this event source.
-	 *
-	 * @return The configured event listeners.
-	 */
-	public EventListeners getListeners();
-	
-	//TODO: temporary
-	
-	/**
-	 * Get the persistence context for this session
-	 */
-	public PersistenceContext getPersistenceContext();
-	
-	/**
-	 * Execute a HQL update or delete query
-	 */
-	int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException;
-	
-	/**
-	 * Execute a native SQL update or delete query
-	 */
-	int executeNativeUpdate(NativeSQLQuerySpecification specification, QueryParameters queryParameters) throws HibernateException;
-
-	// copied from Session:
-	
-	public EntityMode getEntityMode();
-	public CacheMode getCacheMode();
-	public void setCacheMode(CacheMode cm);
-	public boolean isOpen();
-	public boolean isConnected();
-	public FlushMode getFlushMode();
-	public void setFlushMode(FlushMode fm);
-	public Connection connection();
-	public void flush();
-	
-	/**
-	 * Get a Query instance for a named query or named native SQL query
-	 */
-	public Query getNamedQuery(String name);
-	/**
-	 * Get a Query instance for a named native SQL query
-	 */
-	public Query getNamedSQLQuery(String name);
-	
-	public boolean isEventSource();
-
-	public void afterScrollOperation();
-
-	public void setFetchProfile(String name);
-
-	public String getFetchProfile();
-
-	public JDBCContext getJDBCContext();
-
-	/**
-	 * Determine whether the session is closed.  Provided seperately from
-	 * {@link #isOpen()} as this method does not attempt any JTA synch
-	 * registration, where as {@link #isOpen()} does; which makes this one
-	 * nicer to use for most internal purposes.
-	 *
-	 * @return True if the session is closed; false otherwise.
-	 */
-	public boolean isClosed();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/SessionImplementor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SessionImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,325 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.CacheMode;
+import org.hibernate.EntityMode;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Transaction;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventListeners;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.jdbc.Batcher;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.loader.custom.CustomQuery;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.Type;
+
+
+/**
+ * Defines the internal contract between the <tt>Session</tt> and other parts of
+ * Hibernate such as implementors of <tt>Type</tt> or <tt>EntityPersister</tt>.
+ *
+ * @see org.hibernate.Session the interface to the application
+ * @see org.hibernate.impl.SessionImpl the actual implementation
+ * @author Gavin King
+ */
+public interface SessionImplementor extends Serializable {
+
+	/**
+	 * Retrieves the interceptor currently in use by this event source.
+	 *
+	 * @return The interceptor.
+	 */
+	public Interceptor getInterceptor();
+	
+	/**
+	 * Enable/disable automatic cache clearing from after transaction
+	 * completion (for EJB3)
+	 */
+	public void setAutoClear(boolean enabled);
+		
+	/**
+	 * Does this <tt>Session</tt> have an active Hibernate transaction
+	 * or is there a JTA transaction in progress?
+	 */
+	public boolean isTransactionInProgress();
+
+	/**
+	 * Initialize the collection (if not already initialized)
+	 */
+	public void initializeCollection(PersistentCollection collection, boolean writing) 
+	throws HibernateException;
+	
+	/**
+	 * Load an instance without checking if it was deleted. 
+	 * 
+	 * When <tt>nullable</tt> is disabled this method may create a new proxy or 
+	 * return an existing proxy; if it does not exist, throw an exception.
+	 * 
+	 * When <tt>nullable</tt> is enabled, the method does not create new proxies 
+	 * (but might return an existing proxy); if it does not exist, return 
+	 * <tt>null</tt>.
+	 * 
+	 * When <tt>eager</tt> is enabled, the object is eagerly fetched
+	 */
+	public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) 
+	throws HibernateException;
+
+	/**
+	 * Load an instance immediately. This method is only called when lazily initializing a proxy.
+	 * Do not return the proxy.
+	 */
+	public Object immediateLoad(String entityName, Serializable id) throws HibernateException;
+
+	/**
+	 * System time before the start of the transaction
+	 */
+	public long getTimestamp();
+	/**
+	 * Get the creating <tt>SessionFactoryImplementor</tt>
+	 */
+	public SessionFactoryImplementor getFactory();
+	/**
+	 * Get the prepared statement <tt>Batcher</tt> for this session
+	 */
+	public Batcher getBatcher();
+	
+	/**
+	 * Execute a <tt>find()</tt> query
+	 */
+	public List list(String query, QueryParameters queryParameters) throws HibernateException;
+	/**
+	 * Execute an <tt>iterate()</tt> query
+	 */
+	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException;
+	/**
+	 * Execute a <tt>scroll()</tt> query
+	 */
+	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException;
+	/**
+	 * Execute a criteria query
+	 */
+	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode);
+	/**
+	 * Execute a criteria query
+	 */
+	public List list(CriteriaImpl criteria);
+	
+	/**
+	 * Execute a filter
+	 */
+	public List listFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException;
+	/**
+	 * Iterate a filter
+	 */
+	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) throws HibernateException;
+	
+	/**
+	 * Get the <tt>EntityPersister</tt> for any instance
+	 * @param entityName optional entity name
+	 * @param object the entity instance
+	 */
+	public EntityPersister getEntityPersister(String entityName, Object object) throws HibernateException;
+	
+	/**
+	 * Get the entity instance associated with the given <tt>Key</tt>,
+	 * calling the Interceptor if necessary
+	 */
+	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException;
+
+	/**
+	 * Notify the session that the transaction completed, so we no longer
+	 * own the old locks. (Also we should release cache softlocks.) May
+	 * be called multiple times during the transaction completion process.
+	 * Also called after an autocommit, in which case the second argument
+	 * is null.
+	 */
+	public void afterTransactionCompletion(boolean successful, Transaction tx);
+	
+	/**
+	 * Notify the session that the transaction is about to complete
+	 */
+	public void beforeTransactionCompletion(Transaction tx);
+
+	/**
+	 * Return the identifier of the persistent object, or null if 
+	 * not associated with the session
+	 */
+	public Serializable getContextEntityIdentifier(Object object);
+
+	/**
+	 * The best guess entity name for an entity not in an association
+	 */
+	public String bestGuessEntityName(Object object);
+	
+	/**
+	 * The guessed entity name for an entity not in an association
+	 */
+	public String guessEntityName(Object entity) throws HibernateException;
+	
+	/** 
+	 * Instantiate the entity class, initializing with the given identifier
+	 */
+	public Object instantiate(String entityName, Serializable id) throws HibernateException;
+	
+	/**
+	 * Execute an SQL Query
+	 */
+	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
+	throws HibernateException;
+	
+	/**
+	 * Execute an SQL Query
+	 */
+	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
+	throws HibernateException;
+
+	/**
+	 * Execute a native SQL query, and return the results as a fully built list.
+	 *
+	 * @param spec The specification of the native SQL query to execute.
+	 * @param queryParameters The parameters by which to perform the execution.
+	 * @return The result list.
+	 * @throws HibernateException
+	 */
+	public List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
+	throws HibernateException;
+
+	/**
+	 * Execute a native SQL query, and return the results as a scrollable result.
+	 *
+	 * @param spec The specification of the native SQL query to execute.
+	 * @param queryParameters The parameters by which to perform the execution.
+	 * @return The resulting scrollable result.
+	 * @throws HibernateException
+	 */
+	public ScrollableResults scroll(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
+	throws HibernateException;
+
+	/**
+	 * Retreive the currently set value for a filter parameter.
+	 *
+	 * @param filterParameterName The filter parameter name in the format
+	 * {FILTER_NAME.PARAMETER_NAME}.
+	 * @return The filter parameter value.
+	 */
+	public Object getFilterParameterValue(String filterParameterName);
+
+	/**
+	 * Retreive the type for a given filter parrameter.
+	 *
+	 * @param filterParameterName The filter parameter name in the format
+	 * {FILTER_NAME.PARAMETER_NAME}.
+	 */
+	public Type getFilterParameterType(String filterParameterName);
+
+	/**
+	 * Return the currently enabled filters.  The filter map is keyed by filter
+	 * name, with values corresponding to the {@link org.hibernate.impl.FilterImpl}
+	 * instance.
+	 * @return The currently enabled filters.
+	 */
+	public Map getEnabledFilters();
+	
+	public int getDontFlushFromFind();
+	
+	/**
+	 * Retrieves the configured event listeners from this event source.
+	 *
+	 * @return The configured event listeners.
+	 */
+	public EventListeners getListeners();
+	
+	//TODO: temporary
+	
+	/**
+	 * Get the persistence context for this session
+	 */
+	public PersistenceContext getPersistenceContext();
+	
+	/**
+	 * Execute a HQL update or delete query
+	 */
+	int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException;
+	
+	/**
+	 * Execute a native SQL update or delete query
+	 */
+	int executeNativeUpdate(NativeSQLQuerySpecification specification, QueryParameters queryParameters) throws HibernateException;
+
+	// copied from Session:
+	
+	public EntityMode getEntityMode();
+	public CacheMode getCacheMode();
+	public void setCacheMode(CacheMode cm);
+	public boolean isOpen();
+	public boolean isConnected();
+	public FlushMode getFlushMode();
+	public void setFlushMode(FlushMode fm);
+	public Connection connection();
+	public void flush();
+	
+	/**
+	 * Get a Query instance for a named query or named native SQL query
+	 */
+	public Query getNamedQuery(String name);
+	/**
+	 * Get a Query instance for a named native SQL query
+	 */
+	public Query getNamedSQLQuery(String name);
+	
+	public boolean isEventSource();
+
+	public void afterScrollOperation();
+
+	public void setFetchProfile(String name);
+
+	public String getFetchProfile();
+
+	public JDBCContext getJDBCContext();
+
+	/**
+	 * Determine whether the session is closed.  Provided seperately from
+	 * {@link #isOpen()} as this method does not attempt any JTA synch
+	 * registration, where as {@link #isOpen()} does; which makes this one
+	 * nicer to use for most internal purposes.
+	 *
+	 * @return True if the session is closed; false otherwise.
+	 */
+	public boolean isClosed();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1463 +0,0 @@
-// $Id: StatefulPersistenceContext.java 11490 2007-05-09 01:43:11Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.collections.map.ReferenceMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.NonUniqueObjectException;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.engine.loading.LoadContexts;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.tuple.ElementWrapper;
-import org.hibernate.util.IdentityMap;
-import org.hibernate.util.MarkerObject;
-
-/**
- * A <tt>PersistenceContext</tt> represents the state of persistent "stuff" which
- * Hibernate is tracking.  This includes persistent entities, collections,
- * as well as proxies generated.
- * </p>
- * There is meant to be a one-to-one correspondence between a SessionImpl and
- * a PersistentContext.  The SessionImpl uses the PersistentContext to track
- * the current state of its context.  Event-listeners then use the
- * PersistentContext to drive their processing.
- *
- * @author Steve Ebersole
- */
-public class StatefulPersistenceContext implements PersistenceContext {
-
-	public static final Object NO_ROW = new MarkerObject( "NO_ROW" );
-
-	private static final Logger log = LoggerFactory.getLogger( StatefulPersistenceContext.class );
-	private static final Logger PROXY_WARN_LOG = LoggerFactory.getLogger( StatefulPersistenceContext.class.getName() + ".ProxyWarnLog" );
-	private static final int INIT_COLL_SIZE = 8;
-
-	private SessionImplementor session;
-	
-	// Loaded entity instances, by EntityKey
-	private Map entitiesByKey;
-
-	// Loaded entity instances, by EntityUniqueKey
-	private Map entitiesByUniqueKey;
-	
-	// Identity map of EntityEntry instances, by the entity instance
-	private Map entityEntries;
-	
-	// Entity proxies, by EntityKey
-	private Map proxiesByKey;
-	
-	// Snapshots of current database state for entities
-	// that have *not* been loaded
-	private Map entitySnapshotsByKey;
-	
-	// Identity map of array holder ArrayHolder instances, by the array instance
-	private Map arrayHolders;
-	
-	// Identity map of CollectionEntry instances, by the collection wrapper
-	private Map collectionEntries;
-	
-	// Collection wrappers, by the CollectionKey
-	private Map collectionsByKey; //key=CollectionKey, value=PersistentCollection
-	
-	// Set of EntityKeys of deleted objects
-	private HashSet nullifiableEntityKeys;
-	
-	// properties that we have tried to load, and not found in the database
-	private HashSet nullAssociations;
-	
-	// A list of collection wrappers that were instantiating during result set
-	// processing, that we will need to initialize at the end of the query
-	private List nonlazyCollections;
-	
-	// A container for collections we load up when the owning entity is not
-	// yet loaded ... for now, this is purely transient!
-	private Map unownedCollections;
-	
-	private int cascading = 0;
-	private int loadCounter = 0;
-	private boolean flushing = false;
-	
-	private boolean hasNonReadOnlyEntities = false;
-
-	private LoadContexts loadContexts;
-	private BatchFetchQueue batchFetchQueue;
-
-
-
-	/**
-	 * Constructs a PersistentContext, bound to the given session.
-	 *
-	 * @param session The session "owning" this context.
-	 */
-	public StatefulPersistenceContext(SessionImplementor session) {
-		this.session = session;
-
-		entitiesByKey = new HashMap( INIT_COLL_SIZE );
-		entitiesByUniqueKey = new HashMap( INIT_COLL_SIZE );
-		proxiesByKey = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.WEAK );
-		entitySnapshotsByKey = new HashMap( INIT_COLL_SIZE );
-
-		entityEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
-		collectionEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
-		collectionsByKey = new HashMap( INIT_COLL_SIZE );
-		arrayHolders = IdentityMap.instantiate( INIT_COLL_SIZE );
-
-		nullifiableEntityKeys = new HashSet();
-
-		initTransientState();
-	}
-
-	private void initTransientState() {
-		nullAssociations = new HashSet( INIT_COLL_SIZE );
-		nonlazyCollections = new ArrayList( INIT_COLL_SIZE );
-	}
-
-	public boolean isStateless() {
-		return false;
-	}
-	
-	public SessionImplementor getSession() {
-		return session;
-	}
-
-	public LoadContexts getLoadContexts() {
-		if ( loadContexts == null ) {
-			loadContexts = new LoadContexts( this );
-		}
-		return loadContexts;
-	}
-
-	public void addUnownedCollection(CollectionKey key, PersistentCollection collection) {
-		if (unownedCollections==null) {
-			unownedCollections = new HashMap(8);
-		}
-		unownedCollections.put(key, collection);
-	}
-	
-	public PersistentCollection useUnownedCollection(CollectionKey key) {
-		if (unownedCollections==null) {
-			return null;
-		}
-		else {
-			return (PersistentCollection) unownedCollections.remove(key);
-		}
-	}
-	
-	/**
-	 * Get the <tt>BatchFetchQueue</tt>, instantiating one if
-	 * necessary.
-	 */
-	public BatchFetchQueue getBatchFetchQueue() {
-		if (batchFetchQueue==null) {
-			batchFetchQueue = new BatchFetchQueue(this);
-		}
-		return batchFetchQueue;
-	}
-
-	public void clear() {
-		Iterator itr = proxiesByKey.values().iterator();
-		while ( itr.hasNext() ) {
-			final LazyInitializer li = ( ( HibernateProxy ) itr.next() ).getHibernateLazyInitializer();
-			li.setSession( null );
-		}
-		Map.Entry[] collectionEntryArray = IdentityMap.concurrentEntries( collectionEntries );
-		for ( int i = 0; i < collectionEntryArray.length; i++ ) {
-			( ( PersistentCollection ) collectionEntryArray[i].getKey() ).unsetSession( getSession() );
-		}
-		arrayHolders.clear();
-		entitiesByKey.clear();
-		entitiesByUniqueKey.clear();
-		entityEntries.clear();
-		entitySnapshotsByKey.clear();
-		collectionsByKey.clear();
-		collectionEntries.clear();
-		if ( unownedCollections != null ) {
-			unownedCollections.clear();
-		}
-		proxiesByKey.clear();
-		nullifiableEntityKeys.clear();
-		if ( batchFetchQueue != null ) {
-			batchFetchQueue.clear();
-		}
-		hasNonReadOnlyEntities = false;
-		if ( loadContexts != null ) {
-			loadContexts.cleanup();
-		}
-	}
-	
-	public boolean hasNonReadOnlyEntities() {
-		return hasNonReadOnlyEntities;
-	}
-	
-	public void setEntryStatus(EntityEntry entry, Status status) {
-		entry.setStatus(status);
-		setHasNonReadOnlyEnties(status);
-	}
-	
-	private void setHasNonReadOnlyEnties(Status status) {
-		if ( status==Status.DELETED || status==Status.MANAGED || status==Status.SAVING ) {
-			hasNonReadOnlyEntities = true;
-		}
-	}
-
-	public void afterTransactionCompletion() {
-		// Downgrade locks
-		Iterator iter = entityEntries.values().iterator();
-		while ( iter.hasNext() ) {
-			( (EntityEntry) iter.next() ).setLockMode(LockMode.NONE);
-		}
-	}
-
-	/**
-	 * Get the current state of the entity as known to the underlying
-	 * database, or null if there is no corresponding row 
-	 */
-	public Object[] getDatabaseSnapshot(Serializable id, EntityPersister persister)
-	throws HibernateException {
-		EntityKey key = new EntityKey( id, persister, session.getEntityMode() );
-		Object cached = entitySnapshotsByKey.get(key);
-		if (cached!=null) {
-			return cached==NO_ROW ? null : (Object[]) cached;
-		}
-		else {
-			Object[] snapshot = persister.getDatabaseSnapshot( id, session );
-			entitySnapshotsByKey.put( key, snapshot==null ? NO_ROW : snapshot );
-			return snapshot;
-		}
-	}
-
-	public Object[] getNaturalIdSnapshot(Serializable id, EntityPersister persister)
-	throws HibernateException {
-		if ( !persister.hasNaturalIdentifier() ) {
-			return null;
-		}
-
-		// if the natural-id is marked as non-mutable, it is not retrieved during a
-		// normal database-snapshot operation...
-		int[] props = persister.getNaturalIdentifierProperties();
-		boolean[] updateable = persister.getPropertyUpdateability();
-		boolean allNatualIdPropsAreUpdateable = true;
-		for ( int i = 0; i < props.length; i++ ) {
-			if ( !updateable[ props[i] ] ) {
-				allNatualIdPropsAreUpdateable = false;
-				break;
-			}
-		}
-
-		if ( allNatualIdPropsAreUpdateable ) {
-			// do this when all the properties are updateable since there is
-			// a certain likelihood that the information will already be
-			// snapshot-cached.
-			Object[] entitySnapshot = getDatabaseSnapshot( id, persister );
-			if ( entitySnapshot == NO_ROW ) {
-				return null;
-			}
-			Object[] naturalIdSnapshot = new Object[ props.length ];
-			for ( int i = 0; i < props.length; i++ ) {
-				naturalIdSnapshot[i] = entitySnapshot[ props[i] ];
-			}
-			return naturalIdSnapshot;
-		}
-		else {
-			return persister.getNaturalIdentifierSnapshot( id, session );
-		}
-	}
-
-	/**
-	 * Retrieve the cached database snapshot for the requested entity key.
-	 * <p/>
-	 * This differs from {@link #getDatabaseSnapshot} is two important respects:<ol>
-	 * <li>no snapshot is obtained from the database if not already cached</li>
-	 * <li>an entry of {@link #NO_ROW} here is interpretet as an exception</li>
-	 * </ol>
-	 * @param key The entity key for which to retrieve the cached snapshot
-	 * @return The cached snapshot
-	 * @throws IllegalStateException if the cached snapshot was == {@link #NO_ROW}.
-	 */
-	public Object[] getCachedDatabaseSnapshot(EntityKey key) {
-		Object snapshot = entitySnapshotsByKey.get( key );
-		if ( snapshot == NO_ROW ) {
-			throw new IllegalStateException( "persistence context reported no row snapshot for " + MessageHelper.infoString( key.getEntityName(), key.getIdentifier() ) );
-		}
-		return ( Object[] ) snapshot;
-	}
-
-	/*public void removeDatabaseSnapshot(EntityKey key) {
-		entitySnapshotsByKey.remove(key);
-	}*/
-
-	public void addEntity(EntityKey key, Object entity) {
-		entitiesByKey.put(key, entity);
-		getBatchFetchQueue().removeBatchLoadableEntityKey(key);
-	}
-
-	/**
-	 * Get the entity instance associated with the given 
-	 * <tt>EntityKey</tt>
-	 */
-	public Object getEntity(EntityKey key) {
-		return entitiesByKey.get(key);
-	}
-
-	public boolean containsEntity(EntityKey key) {
-		return entitiesByKey.containsKey(key);
-	}
-
-	/**
-	 * Remove an entity from the session cache, also clear
-	 * up other state associated with the entity, all except
-	 * for the <tt>EntityEntry</tt>
-	 */
-	public Object removeEntity(EntityKey key) {
-		Object entity = entitiesByKey.remove(key);
-		Iterator iter = entitiesByUniqueKey.values().iterator();
-		while ( iter.hasNext() ) {
-			if ( iter.next()==entity ) iter.remove();
-		}
-		entitySnapshotsByKey.remove(key);
-		nullifiableEntityKeys.remove(key);
-		getBatchFetchQueue().removeBatchLoadableEntityKey(key);
-		getBatchFetchQueue().removeSubselect(key);
-		return entity;
-	}
-
-	/**
-	 * Get an entity cached by unique key
-	 */
-	public Object getEntity(EntityUniqueKey euk) {
-		return entitiesByUniqueKey.get(euk);
-	}
-
-	/**
-	 * Add an entity to the cache by unique key
-	 */
-	public void addEntity(EntityUniqueKey euk, Object entity) {
-		entitiesByUniqueKey.put(euk, entity);
-	}
-
-	/**
-	 * Retreive the EntityEntry representation of the given entity.
-	 *
-	 * @param entity The entity for which to locate the EntityEntry.
-	 * @return The EntityEntry for the given entity.
-	 */
-	public EntityEntry getEntry(Object entity) {
-		return (EntityEntry) entityEntries.get(entity);
-	}
-
-	/**
-	 * Remove an entity entry from the session cache
-	 */
-	public EntityEntry removeEntry(Object entity) {
-		return (EntityEntry) entityEntries.remove(entity);
-	}
-
-	/**
-	 * Is there an EntityEntry for this instance?
-	 */
-	public boolean isEntryFor(Object entity) {
-		return entityEntries.containsKey(entity);
-	}
-
-	/**
-	 * Get the collection entry for a persistent collection
-	 */
-	public CollectionEntry getCollectionEntry(PersistentCollection coll) {
-		return (CollectionEntry) collectionEntries.get(coll);
-	}
-
-	/**
-	 * Adds an entity to the internal caches.
-	 */
-	public EntityEntry addEntity(
-			final Object entity,
-			final Status status,
-			final Object[] loadedState,
-			final EntityKey entityKey,
-			final Object version,
-			final LockMode lockMode,
-			final boolean existsInDatabase,
-			final EntityPersister persister,
-			final boolean disableVersionIncrement, 
-			boolean lazyPropertiesAreUnfetched
-	) {
-		
-		addEntity( entityKey, entity );
-		
-		return addEntry(
-				entity,
-				status,
-				loadedState,
-				null,
-				entityKey.getIdentifier(),
-				version,
-				lockMode,
-				existsInDatabase,
-				persister,
-				disableVersionIncrement, 
-				lazyPropertiesAreUnfetched
-			);
-	}
-
-
-	/**
-	 * Generates an appropriate EntityEntry instance and adds it 
-	 * to the event source's internal caches.
-	 */
-	public EntityEntry addEntry(
-			final Object entity,
-			final Status status,
-			final Object[] loadedState,
-			final Object rowId,
-			final Serializable id,
-			final Object version,
-			final LockMode lockMode,
-			final boolean existsInDatabase,
-			final EntityPersister persister,
-			final boolean disableVersionIncrement, 
-			boolean lazyPropertiesAreUnfetched) {
-		
-		EntityEntry e = new EntityEntry(
-				status,
-				loadedState,
-				rowId,
-				id,
-				version,
-				lockMode,
-				existsInDatabase,
-				persister,
-				session.getEntityMode(),
-				disableVersionIncrement,
-				lazyPropertiesAreUnfetched
-			);
-		entityEntries.put(entity, e);
-		
-		setHasNonReadOnlyEnties(status);
-		return e;
-	}
-
-	public boolean containsCollection(PersistentCollection collection) {
-		return collectionEntries.containsKey(collection);
-	}
-
-	public boolean containsProxy(Object entity) {
-		return proxiesByKey.containsValue( entity );
-	}
-	
-	/**
-	 * Takes the given object and, if it represents a proxy, reassociates it with this event source.
-	 *
-	 * @param value The possible proxy to be reassociated.
-	 * @return Whether the passed value represented an actual proxy which got initialized.
-	 * @throws MappingException
-	 */
-	public boolean reassociateIfUninitializedProxy(Object value) throws MappingException {
-		if ( value instanceof ElementWrapper ) {
-			value = ( (ElementWrapper) value ).getElement();
-		}
-		
-		if ( !Hibernate.isInitialized(value) ) {
-			HibernateProxy proxy = (HibernateProxy) value;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			reassociateProxy(li, proxy);
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * If a deleted entity instance is re-saved, and it has a proxy, we need to
-	 * reset the identifier of the proxy 
-	 */
-	public void reassociateProxy(Object value, Serializable id) throws MappingException {
-		if ( value instanceof ElementWrapper ) {
-			value = ( (ElementWrapper) value ).getElement();
-		}
-		
-		if ( value instanceof HibernateProxy ) {
-			if ( log.isDebugEnabled() ) log.debug("setting proxy identifier: " + id);
-			HibernateProxy proxy = (HibernateProxy) value;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			li.setIdentifier(id);
-			reassociateProxy(li, proxy);
-		}
-	}
-
-	/**
-	 * Associate a proxy that was instantiated by another session with this session
-	 *
-	 * @param li The proxy initializer.
-	 * @param proxy The proxy to reassociate.
-	 */
-	private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
-		if ( li.getSession() != this.getSession() ) {
-			EntityPersister persister = session.getFactory().getEntityPersister( li.getEntityName() );
-			EntityKey key = new EntityKey( li.getIdentifier(), persister, session.getEntityMode() );
-		  	// any earlier proxy takes precedence
-			if ( !proxiesByKey.containsKey( key ) ) {
-				proxiesByKey.put( key, proxy );
-			}
-			proxy.getHibernateLazyInitializer().setSession( session );
-		}
-	}
-
-	/**
-	 * Get the entity instance underlying the given proxy, throwing
-	 * an exception if the proxy is uninitialized. If the given object
-	 * is not a proxy, simply return the argument.
-	 */
-	public Object unproxy(Object maybeProxy) throws HibernateException {
-		if ( maybeProxy instanceof ElementWrapper ) {
-			maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
-		}
-		
-		if ( maybeProxy instanceof HibernateProxy ) {
-			HibernateProxy proxy = (HibernateProxy) maybeProxy;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			if ( li.isUninitialized() ) {
-				throw new PersistentObjectException(
-						"object was an uninitialized proxy for " +
-						li.getEntityName()
-				);
-			}
-			return li.getImplementation(); //unwrap the object
-		}
-		else {
-			return maybeProxy;
-		}
-	}
-
-	/**
-	 * Possibly unproxy the given reference and reassociate it with the current session.
-	 *
-	 * @param maybeProxy The reference to be unproxied if it currently represents a proxy.
-	 * @return The unproxied instance.
-	 * @throws HibernateException
-	 */
-	public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException {
-		if ( maybeProxy instanceof ElementWrapper ) {
-			maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
-		}
-		
-		if ( maybeProxy instanceof HibernateProxy ) {
-			HibernateProxy proxy = (HibernateProxy) maybeProxy;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			reassociateProxy(li, proxy);
-			return li.getImplementation(); //initialize + unwrap the object
-		}
-		else {
-			return maybeProxy;
-		}
-	}
-
-	/**
-	 * Attempts to check whether the given key represents an entity already loaded within the
-	 * current session.
-	 * @param object The entity reference against which to perform the uniqueness check.
-	 * @throws HibernateException
-	 */
-	public void checkUniqueness(EntityKey key, Object object) throws HibernateException {
-		Object entity = getEntity(key);
-		if ( entity == object ) {
-			throw new AssertionFailure( "object already associated, but no entry was found" );
-		}
-		if ( entity != null ) {
-			throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() );
-		}
-	}
-
-	/**
-	 * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
-	 * and overwrite the registration of the old one. This breaks == and occurs only for
-	 * "class" proxies rather than "interface" proxies. Also init the proxy to point to
-	 * the given target implementation if necessary.
-	 *
-	 * @param proxy The proxy instance to be narrowed.
-	 * @param persister The persister for the proxied entity.
-	 * @param key The internal cache key for the proxied entity.
-	 * @param object (optional) the actual proxied entity instance.
-	 * @return An appropriately narrowed instance.
-	 * @throws HibernateException
-	 */
-	public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
-	throws HibernateException {
-		
-		boolean alreadyNarrow = persister.getConcreteProxyClass( session.getEntityMode() )
-				.isAssignableFrom( proxy.getClass() );
-		
-		if ( !alreadyNarrow ) {
-			if ( PROXY_WARN_LOG.isWarnEnabled() ) {
-				PROXY_WARN_LOG.warn(
-						"Narrowing proxy to " +
-						persister.getConcreteProxyClass( session.getEntityMode() ) +
-						" - this operation breaks =="
-				);
-			}
-
-			if ( object != null ) {
-				proxiesByKey.remove(key);
-				return object; //return the proxied object
-			}
-			else {
-				proxy = persister.createProxy( key.getIdentifier(), session );
-				proxiesByKey.put(key, proxy); //overwrite old proxy
-				return proxy;
-			}
-			
-		}
-		else {
-			
-			if ( object != null ) {
-				LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
-				li.setImplementation(object);
-			}
-			
-			return proxy;
-			
-		}
-		
-	}
-
-	/**
-	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
-	 * third argument (the entity associated with the key) if no proxy exists. Init
-	 * the proxy to the target implementation, if necessary.
-	 */
-	public Object proxyFor(EntityPersister persister, EntityKey key, Object impl) 
-	throws HibernateException {
-		if ( !persister.hasProxy() ) return impl;
-		Object proxy = proxiesByKey.get(key);
-		if ( proxy != null ) {
-			return narrowProxy(proxy, persister, key, impl);
-		}
-		else {
-			return impl;
-		}
-	}
-
-	/**
-	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
-	 * argument (the entity associated with the key) if no proxy exists.
-	 * (slower than the form above)
-	 */
-	public Object proxyFor(Object impl) throws HibernateException {
-		EntityEntry e = getEntry(impl);
-		EntityPersister p = e.getPersister();
-		return proxyFor( p, new EntityKey( e.getId(), p, session.getEntityMode() ), impl );
-	}
-
-	/**
-	 * Get the entity that owns this persistent collection
-	 */
-	public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException {
-		return getEntity( new EntityKey( key, collectionPersister.getOwnerEntityPersister(), session.getEntityMode() ) );
-	}
-
-	/**
-	 * Get the entity that owned this persistent collection when it was loaded
-	 *
-	 * @param collection The persistent collection
-	 * @return the owner, if its entity ID is available from the collection's loaded key
-	 * and the owner entity is in the persistence context; otherwise, returns null
-	 */
-	public Object getLoadedCollectionOwnerOrNull(PersistentCollection collection) {
-		CollectionEntry ce = getCollectionEntry( collection );
-		if ( ce.getLoadedPersister() == null ) {
-			return null; // early exit...
-		}
-		Object loadedOwner = null;
-		// TODO: an alternative is to check if the owner has changed; if it hasn't then
-		// return collection.getOwner()
-		Serializable entityId = getLoadedCollectionOwnerIdOrNull( ce );
-		if ( entityId != null ) {
-			loadedOwner = getCollectionOwner( entityId, ce.getLoadedPersister() );
-		}
-		return loadedOwner;
-	}
-
-	/**
-	 * Get the ID for the entity that owned this persistent collection when it was loaded
-	 *
-	 * @param collection The persistent collection
-	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
-	 */
-	public Serializable getLoadedCollectionOwnerIdOrNull(PersistentCollection collection) {
-		return getLoadedCollectionOwnerIdOrNull( getCollectionEntry( collection ) );
-	}
-
-	/**
-	 * Get the ID for the entity that owned this persistent collection when it was loaded
-	 *
-	 * @param ce The collection entry
-	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
-	 */
-	private Serializable getLoadedCollectionOwnerIdOrNull(CollectionEntry ce) {
-		if ( ce == null || ce.getLoadedKey() == null || ce.getLoadedPersister() == null ) {
-			return null;
-		}
-		// TODO: an alternative is to check if the owner has changed; if it hasn't then
-		// get the ID from collection.getOwner()
-		return ce.getLoadedPersister().getCollectionType().getIdOfOwnerOrNull( ce.getLoadedKey(), session );
-	}
-
-	/**
-	 * add a collection we just loaded up (still needs initializing)
-	 */
-	public void addUninitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) {
-		CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
-		addCollection(collection, ce, id);
-	}
-
-	/**
-	 * add a detached uninitialized collection
-	 */
-	public void addUninitializedDetachedCollection(CollectionPersister persister, PersistentCollection collection) {
-		CollectionEntry ce = new CollectionEntry( persister, collection.getKey() );
-		addCollection( collection, ce, collection.getKey() );
-	}
-
-	/**
-	 * Add a new collection (ie. a newly created one, just instantiated by the
-	 * application, with no database state or snapshot)
-	 * @param collection The collection to be associated with the persistence context
-	 */
-	public void addNewCollection(CollectionPersister persister, PersistentCollection collection)
-	throws HibernateException {
-		addCollection(collection, persister);
-	}
-
-	/**
-	 * Add an collection to the cache, with a given collection entry.
-	 *
-	 * @param coll The collection for which we are adding an entry.
-	 * @param entry The entry representing the collection.
-	 * @param key The key of the collection's entry.
-	 */
-	private void addCollection(PersistentCollection coll, CollectionEntry entry, Serializable key) {
-		collectionEntries.put( coll, entry );
-		CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key, session.getEntityMode() );
-		PersistentCollection old = ( PersistentCollection ) collectionsByKey.put( collectionKey, coll );
-		if ( old != null ) {
-			if ( old == coll ) {
-				throw new AssertionFailure("bug adding collection twice");
-			}
-			// or should it actually throw an exception?
-			old.unsetSession( session );
-			collectionEntries.remove( old );
-			// watch out for a case where old is still referenced
-			// somewhere in the object graph! (which is a user error)
-		}
-	}
-
-	/**
-	 * Add a collection to the cache, creating a new collection entry for it
-	 *
-	 * @param collection The collection for which we are adding an entry.
-	 * @param persister The collection persister
-	 */
-	private void addCollection(PersistentCollection collection, CollectionPersister persister) {
-		CollectionEntry ce = new CollectionEntry( persister, collection );
-		collectionEntries.put( collection, ce );
-	}
-
-	/**
-	 * add an (initialized) collection that was created by another session and passed
-	 * into update() (ie. one with a snapshot and existing state on the database)
-	 */
-	public void addInitializedDetachedCollection(CollectionPersister collectionPersister, PersistentCollection collection) 
-	throws HibernateException {
-		if ( collection.isUnreferenced() ) {
-			//treat it just like a new collection
-			addCollection( collection, collectionPersister );
-		}
-		else {
-			CollectionEntry ce = new CollectionEntry( collection, session.getFactory() );
-			addCollection( collection, ce, collection.getKey() );
-		}
-	}
-
-	/**
-	 * add a collection we just pulled out of the cache (does not need initializing)
-	 */
-	public CollectionEntry addInitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id)
-	throws HibernateException {
-		CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
-		ce.postInitialize(collection);
-		addCollection(collection, ce, id);
-		return ce;
-	}
-	
-	/**
-	 * Get the collection instance associated with the <tt>CollectionKey</tt>
-	 */
-	public PersistentCollection getCollection(CollectionKey collectionKey) {
-		return (PersistentCollection) collectionsByKey.get(collectionKey);
-	}
-	
-	/**
-	 * Register a collection for non-lazy loading at the end of the
-	 * two-phase load
-	 */
-	public void addNonLazyCollection(PersistentCollection collection) {
-		nonlazyCollections.add(collection);
-	}
-
-	/**
-	 * Force initialization of all non-lazy collections encountered during
-	 * the current two-phase load (actually, this is a no-op, unless this
-	 * is the "outermost" load)
-	 */
-	public void initializeNonLazyCollections() throws HibernateException {
-		if ( loadCounter == 0 ) {
-			log.debug( "initializing non-lazy collections" );
-			//do this work only at the very highest level of the load
-			loadCounter++; //don't let this method be called recursively
-			try {
-				int size;
-				while ( ( size = nonlazyCollections.size() ) > 0 ) {
-					//note that each iteration of the loop may add new elements
-					( (PersistentCollection) nonlazyCollections.remove( size - 1 ) ).forceInitialization();
-				}
-			}
-			finally {
-				loadCounter--;
-				clearNullProperties();
-			}
-		}
-	}
-
-
-	/**
-	 * Get the <tt>PersistentCollection</tt> object for an array
-	 */
-	public PersistentCollection getCollectionHolder(Object array) {
-		return (PersistentCollection) arrayHolders.get(array);
-	}
-
-	/**
-	 * Register a <tt>PersistentCollection</tt> object for an array.
-	 * Associates a holder with an array - MUST be called after loading 
-	 * array, since the array instance is not created until endLoad().
-	 */
-	public void addCollectionHolder(PersistentCollection holder) {
-		//TODO:refactor + make this method private
-		arrayHolders.put( holder.getValue(), holder );
-	}
-
-	public PersistentCollection removeCollectionHolder(Object array) {
-		return (PersistentCollection) arrayHolders.remove(array);
-	}
-
-	/**
-	 * Get the snapshot of the pre-flush collection state
-	 */
-	public Serializable getSnapshot(PersistentCollection coll) {
-		return getCollectionEntry(coll).getSnapshot();
-	}
-
-	/**
-	 * Get the collection entry for a collection passed to filter,
-	 * which might be a collection wrapper, an array, or an unwrapped
-	 * collection. Return null if there is no entry.
-	 */
-	public CollectionEntry getCollectionEntryOrNull(Object collection) {
-		PersistentCollection coll;
-		if ( collection instanceof PersistentCollection ) {
-			coll = (PersistentCollection) collection;
-			//if (collection==null) throw new TransientObjectException("Collection was not yet persistent");
-		}
-		else {
-			coll = getCollectionHolder(collection);
-			if ( coll == null ) {
-				//it might be an unwrapped collection reference!
-				//try to find a wrapper (slowish)
-				Iterator wrappers = IdentityMap.keyIterator(collectionEntries);
-				while ( wrappers.hasNext() ) {
-					PersistentCollection pc = (PersistentCollection) wrappers.next();
-					if ( pc.isWrapper(collection) ) {
-						coll = pc;
-						break;
-					}
-				}
-			}
-		}
-
-		return (coll == null) ? null : getCollectionEntry(coll);
-	}
-
-	/**
-	 * Get an existing proxy by key
-	 */
-	public Object getProxy(EntityKey key) {
-		return proxiesByKey.get(key);
-	}
-
-	/**
-	 * Add a proxy to the session cache
-	 */
-	public void addProxy(EntityKey key, Object proxy) {
-		proxiesByKey.put(key, proxy);
-	}
-
-	/**
-	 * Remove a proxy from the session cache.
-	 * <p/>
-	 * Additionally, ensure that any load optimization references
-	 * such as batch or subselect loading get cleaned up as well.
-	 *
-	 * @param key The key of the entity proxy to be removed
-	 * @return The proxy reference.
-	 */
-	public Object removeProxy(EntityKey key) {
-		if ( batchFetchQueue != null ) {
-			batchFetchQueue.removeBatchLoadableEntityKey( key );
-			batchFetchQueue.removeSubselect( key );
-		}
-		return proxiesByKey.remove( key );
-	}
-
-	/**
-	 * Record the fact that an entity does not exist in the database
-	 * 
-	 * @param key the primary key of the entity
-	 */
-	/*public void addNonExistantEntityKey(EntityKey key) {
-		nonExistantEntityKeys.add(key);
-	}*/
-
-	/**
-	 * Record the fact that an entity does not exist in the database
-	 * 
-	 * @param key a unique key of the entity
-	 */
-	/*public void addNonExistantEntityUniqueKey(EntityUniqueKey key) {
-		nonExistentEntityUniqueKeys.add(key);
-	}*/
-
-	/*public void removeNonExist(EntityKey key) {
-		nonExistantEntityKeys.remove(key);
-	}*/
-
-	/** 
-	 * Retrieve the set of EntityKeys representing nullifiable references
-	 */
-	public HashSet getNullifiableEntityKeys() {
-		return nullifiableEntityKeys;
-	}
-
-	public Map getEntitiesByKey() {
-		return entitiesByKey;
-	}
-
-	public Map getEntityEntries() {
-		return entityEntries;
-	}
-
-	public Map getCollectionEntries() {
-		return collectionEntries;
-	}
-
-	public Map getCollectionsByKey() {
-		return collectionsByKey;
-	}
-
-	/**
-	 * Do we already know that the entity does not exist in the
-	 * database?
-	 */
-	/*public boolean isNonExistant(EntityKey key) {
-		return nonExistantEntityKeys.contains(key);
-	}*/
-
-	/**
-	 * Do we already know that the entity does not exist in the
-	 * database?
-	 */
-	/*public boolean isNonExistant(EntityUniqueKey key) {
-		return nonExistentEntityUniqueKeys.contains(key);
-	}*/
-
-	public int getCascadeLevel() {
-		return cascading;
-	}
-
-	public int incrementCascadeLevel() {
-		return ++cascading;
-	}
-
-	public int decrementCascadeLevel() {
-		return --cascading;
-	}
-
-	public boolean isFlushing() {
-		return flushing;
-	}
-
-	public void setFlushing(boolean flushing) {
-		this.flushing = flushing;
-	}
-
-	/**
-	 * Call this before begining a two-phase load
-	 */
-	public void beforeLoad() {
-		loadCounter++;
-	}
-
-	/**
-	 * Call this after finishing a two-phase load
-	 */
-	public void afterLoad() {
-		loadCounter--;
-	}
-
-	/**
-	 * Returns a string representation of the object.
-	 *
-	 * @return a string representation of the object.
-	 */
-	public String toString() {
-		return new StringBuffer()
-				.append("PersistenceContext[entityKeys=")
-				.append(entitiesByKey.keySet())
-				.append(",collectionKeys=")
-				.append(collectionsByKey.keySet())
-				.append("]")
-				.toString();
-	}
-
-	/**
-	 * Search <tt>this</tt> persistence context for an associated entity instance which is considered the "owner" of
-	 * the given <tt>childEntity</tt>, and return that owner's id value.  This is performed in the scenario of a
-	 * uni-directional, non-inverse one-to-many collection (which means that the collection elements do not maintain
-	 * a direct reference to the owner).
-	 * <p/>
-	 * As such, the processing here is basically to loop over every entity currently associated with this persistence
-	 * context and for those of the correct entity (sub) type to extract its collection role property value and see
-	 * if the child is contained within that collection.  If so, we have found the owner; if not, we go on.
-	 * <p/>
-	 * Also need to account for <tt>mergeMap</tt> which acts as a local copy cache managed for the duration of a merge
-	 * operation.  It represents a map of the detached entity instances pointing to the corresponding managed instance.
-	 *
-	 * @param entityName The entity name for the entity type which would own the child
-	 * @param propertyName The name of the property on the owning entity type which would name this child association.
-	 * @param childEntity The child entity instance for which to locate the owner instance id.
-	 * @param mergeMap A map of non-persistent instances from an on-going merge operation (possibly null).
-	 *
-	 * @return The id of the entityName instance which is said to own the child; null if an appropriate owner not
-	 * located.
-	 */
-	public Serializable getOwnerId(String entityName, String propertyName, Object childEntity, Map mergeMap) {
-		final String collectionRole = entityName + '.' + propertyName;
-		final EntityPersister persister = session.getFactory().getEntityPersister( entityName );
-		final CollectionPersister collectionPersister = session.getFactory().getCollectionPersister( collectionRole );
-
-		// iterate all the entities currently associated with the persistence context.
-		Iterator entities = entityEntries.entrySet().iterator();
-		while ( entities.hasNext() ) {
-			final Map.Entry me = ( Map.Entry ) entities.next();
-			final EntityEntry entityEntry = ( EntityEntry ) me.getValue();
-			// does this entity entry pertain to the entity persister in which we are interested (owner)?
-			if ( persister.isSubclassEntityName( entityEntry.getEntityName() ) ) {
-				final Object entityEntryInstance = me.getKey();
-
-				//check if the managed object is the parent
-				boolean found = isFoundInParent(
-						propertyName,
-						childEntity,
-						persister,
-						collectionPersister,
-						entityEntryInstance
-				);
-
-				if ( !found && mergeMap != null ) {
-					//check if the detached object being merged is the parent
-					Object unmergedInstance = mergeMap.get( entityEntryInstance );
-					Object unmergedChild = mergeMap.get( childEntity );
-					if ( unmergedInstance != null && unmergedChild != null ) {
-						found = isFoundInParent(
-								propertyName,
-								unmergedChild,
-								persister,
-								collectionPersister,
-								unmergedInstance
-						);
-					}
-				}
-
-				if ( found ) {
-					return entityEntry.getId();
-				}
-
-			}
-		}
-
-		// if we get here, it is possible that we have a proxy 'in the way' of the merge map resolution...
-		// 		NOTE: decided to put this here rather than in the above loop as I was nervous about the performance
-		//		of the loop-in-loop especially considering this is far more likely the 'edge case'
-		if ( mergeMap != null ) {
-			Iterator mergeMapItr = mergeMap.entrySet().iterator();
-			while ( mergeMapItr.hasNext() ) {
-				final Map.Entry mergeMapEntry = ( Map.Entry ) mergeMapItr.next();
-				if ( mergeMapEntry.getKey() instanceof HibernateProxy ) {
-					final HibernateProxy proxy = ( HibernateProxy ) mergeMapEntry.getKey();
-					if ( persister.isSubclassEntityName( proxy.getHibernateLazyInitializer().getEntityName() ) ) {
-						boolean found = isFoundInParent(
-								propertyName,
-								childEntity,
-								persister,
-								collectionPersister,
-								mergeMap.get( proxy )
-						);
-						if ( !found ) {
-							found = isFoundInParent(
-									propertyName,
-									mergeMap.get( childEntity ),
-									persister,
-									collectionPersister,
-									mergeMap.get( proxy )
-							);
-						}
-						if ( found ) {
-							return proxy.getHibernateLazyInitializer().getIdentifier();
-						}
-					}
-				}
-			}
-		}
-
-		return null;
-	}
-
-	private boolean isFoundInParent(
-			String property,
-			Object childEntity,
-			EntityPersister persister,
-			CollectionPersister collectionPersister,
-			Object potentialParent) {
-		Object collection = persister.getPropertyValue(
-				potentialParent,
-				property,
-				session.getEntityMode()
-		);
-		return collection != null
-				&& Hibernate.isInitialized( collection )
-				&& collectionPersister.getCollectionType().contains( collection, childEntity, session );
-	}
-
-	/**
-	 * Search the persistence context for an index of the child object,
-	 * given a collection role
-	 */
-	public Object getIndexInOwner(String entity, String property, Object childEntity, Map mergeMap) {
-
-		EntityPersister persister = session.getFactory()
-				.getEntityPersister(entity);
-		CollectionPersister cp = session.getFactory()
-				.getCollectionPersister(entity + '.' + property);
-		Iterator entities = entityEntries.entrySet().iterator();
-		while ( entities.hasNext() ) {
-			Map.Entry me = (Map.Entry) entities.next();
-			EntityEntry ee = (EntityEntry) me.getValue();
-			if ( persister.isSubclassEntityName( ee.getEntityName() ) ) {
-				Object instance = me.getKey();
-				
-				Object index = getIndexInParent(property, childEntity, persister, cp, instance);
-				
-				if (index==null && mergeMap!=null) {
-					Object unmergedInstance = mergeMap.get(instance);
-					Object unmergedChild = mergeMap.get(childEntity);
-					if ( unmergedInstance!=null && unmergedChild!=null ) {
-						index = getIndexInParent(property, unmergedChild, persister, cp, unmergedInstance);
-					}
-				}
-				
-				if (index!=null) return index;
-			}
-		}
-		return null;
-	}
-	
-	private Object getIndexInParent(
-			String property, 
-			Object childEntity, 
-			EntityPersister persister, 
-			CollectionPersister collectionPersister,
-			Object potentialParent
-	){	
-		Object collection = persister.getPropertyValue( potentialParent, property, session.getEntityMode() );
-		if ( collection!=null && Hibernate.isInitialized(collection) ) {
-			return collectionPersister.getCollectionType().indexOf(collection, childEntity);
-		}
-		else {
-			return null;
-		}
-	}
-	
-	/**
-	 * Record the fact that the association belonging to the keyed
-	 * entity is null.
-	 */
-	public void addNullProperty(EntityKey ownerKey, String propertyName) {
-		nullAssociations.add( new AssociationKey(ownerKey, propertyName) );
-	}
-	
-	/**
-	 * Is the association property belonging to the keyed entity null?
-	 */
-	public boolean isPropertyNull(EntityKey ownerKey, String propertyName) {
-		return nullAssociations.contains( new AssociationKey(ownerKey, propertyName) );
-	}
-	
-	private void clearNullProperties() {
-		nullAssociations.clear();
-	}
-
-	public void setReadOnly(Object entity, boolean readOnly) {
-		EntityEntry entry = getEntry(entity);
-		if (entry==null) {
-			throw new TransientObjectException("Instance was not associated with the session");
-		}
-		entry.setReadOnly(readOnly, entity);
-		hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
-	}
-
-	public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId) {
-		Object entity = entitiesByKey.remove( oldKey );
-		EntityEntry oldEntry = ( EntityEntry ) entityEntries.remove( entity );
-
-		EntityKey newKey = new EntityKey( generatedId, oldEntry.getPersister(), getSession().getEntityMode() );
-		addEntity( newKey, entity );
-		addEntry(
-				entity,
-		        oldEntry.getStatus(),
-		        oldEntry.getLoadedState(),
-		        oldEntry.getRowId(),
-		        generatedId,
-		        oldEntry.getVersion(),
-		        oldEntry.getLockMode(),
-		        oldEntry.isExistsInDatabase(),
-		        oldEntry.getPersister(),
-		        oldEntry.isBeingReplicated(),
-		        oldEntry.isLoadedWithLazyPropertiesUnfetched()
-		);
-	}
-
-	/**
-	 * Used by the owning session to explicitly control serialization of the
-	 * persistence context.
-	 *
-	 * @param oos The stream to which the persistence context should get written
-	 * @throws IOException serialization errors.
-	 */
-	public void serialize(ObjectOutputStream oos) throws IOException {
-		log.trace( "serializing persistent-context" );
-
-		oos.writeBoolean( hasNonReadOnlyEntities );
-
-		oos.writeInt( entitiesByKey.size() );
-		log.trace( "starting serialization of [" + entitiesByKey.size() + "] entitiesByKey entries" );
-		Iterator itr = entitiesByKey.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			( ( EntityKey ) entry.getKey() ).serialize( oos );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( entitiesByUniqueKey.size() );
-		log.trace( "starting serialization of [" + entitiesByUniqueKey.size() + "] entitiesByUniqueKey entries" );
-		itr = entitiesByUniqueKey.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			( ( EntityUniqueKey ) entry.getKey() ).serialize( oos );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( proxiesByKey.size() );
-		log.trace( "starting serialization of [" + proxiesByKey.size() + "] proxiesByKey entries" );
-		itr = proxiesByKey.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			( ( EntityKey ) entry.getKey() ).serialize( oos );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( entitySnapshotsByKey.size() );
-		log.trace( "starting serialization of [" + entitySnapshotsByKey.size() + "] entitySnapshotsByKey entries" );
-		itr = entitySnapshotsByKey.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			( ( EntityKey ) entry.getKey() ).serialize( oos );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( entityEntries.size() );
-		log.trace( "starting serialization of [" + entityEntries.size() + "] entityEntries entries" );
-		itr = entityEntries.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			oos.writeObject( entry.getKey() );
-			( ( EntityEntry ) entry.getValue() ).serialize( oos );
-		}
-
-		oos.writeInt( collectionsByKey.size() );
-		log.trace( "starting serialization of [" + collectionsByKey.size() + "] collectionsByKey entries" );
-		itr = collectionsByKey.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			( ( CollectionKey ) entry.getKey() ).serialize( oos );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( collectionEntries.size() );
-		log.trace( "starting serialization of [" + collectionEntries.size() + "] collectionEntries entries" );
-		itr = collectionEntries.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			oos.writeObject( entry.getKey() );
-			( ( CollectionEntry ) entry.getValue() ).serialize( oos );
-		}
-
-		oos.writeInt( arrayHolders.size() );
-		log.trace( "starting serialization of [" + arrayHolders.size() + "] arrayHolders entries" );
-		itr = arrayHolders.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			oos.writeObject( entry.getKey() );
-			oos.writeObject( entry.getValue() );
-		}
-
-		oos.writeInt( nullifiableEntityKeys.size() );
-		log.trace( "starting serialization of [" + nullifiableEntityKeys.size() + "] nullifiableEntityKeys entries" );
-		itr = nullifiableEntityKeys.iterator();
-		while ( itr.hasNext() ) {
-			EntityKey entry = ( EntityKey ) itr.next();
-			entry.serialize( oos );
-		}
-	}
-
-	public static StatefulPersistenceContext deserialize(
-			ObjectInputStream ois,
-	        SessionImplementor session) throws IOException, ClassNotFoundException {
-		log.trace( "deserializing persistent-context" );
-		StatefulPersistenceContext rtn = new StatefulPersistenceContext( session );
-
-		// during deserialization, we need to reconnect all proxies and
-		// collections to this session, as well as the EntityEntry and
-		// CollectionEntry instances; these associations are transient
-		// because serialization is used for different things.
-
-		try {
-			// todo : we can actually just determine this from the incoming EntityEntry-s
-			rtn.hasNonReadOnlyEntities = ois.readBoolean();
-
-			int count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] entitiesByKey entries" );
-			rtn.entitiesByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				rtn.entitiesByKey.put( EntityKey.deserialize( ois, session ), ois.readObject() );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] entitiesByUniqueKey entries" );
-			rtn.entitiesByUniqueKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				rtn.entitiesByUniqueKey.put( EntityUniqueKey.deserialize( ois, session ), ois.readObject() );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] proxiesByKey entries" );
-			rtn.proxiesByKey = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.WEAK, count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count, .75f );
-			for ( int i = 0; i < count; i++ ) {
-				EntityKey ek = EntityKey.deserialize( ois, session );
-				Object proxy = ois.readObject();
-				if ( proxy instanceof HibernateProxy ) {
-					( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().setSession( session );
-					rtn.proxiesByKey.put( ek, proxy );
-				}
-				else {
-					log.trace( "encountered prunded proxy" );
-				}
-				// otherwise, the proxy was pruned during the serialization process
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] entitySnapshotsByKey entries" );
-			rtn.entitySnapshotsByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				rtn.entitySnapshotsByKey.put( EntityKey.deserialize( ois, session ), ois.readObject() );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] entityEntries entries" );
-			rtn.entityEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				Object entity = ois.readObject();
-				EntityEntry entry = EntityEntry.deserialize( ois, session );
-				rtn.entityEntries.put( entity, entry );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] collectionsByKey entries" );
-			rtn.collectionsByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				rtn.collectionsByKey.put( CollectionKey.deserialize( ois, session ), ois.readObject() );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] collectionEntries entries" );
-			rtn.collectionEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				final PersistentCollection pc = ( PersistentCollection ) ois.readObject();
-				final CollectionEntry ce = CollectionEntry.deserialize( ois, session );
-				pc.setCurrentSession( session );
-				rtn.collectionEntries.put( pc, ce );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] arrayHolders entries" );
-			rtn.arrayHolders = IdentityMap.instantiate( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
-			for ( int i = 0; i < count; i++ ) {
-				rtn.arrayHolders.put( ois.readObject(), ois.readObject() );
-			}
-
-			count = ois.readInt();
-			log.trace( "staring deserialization of [" + count + "] nullifiableEntityKeys entries" );
-			rtn.nullifiableEntityKeys = new HashSet();
-			for ( int i = 0; i < count; i++ ) {
-				rtn.nullifiableEntityKeys.add( EntityKey.deserialize( ois, session ) );
-			}
-
-		}
-		catch ( HibernateException he ) {
-			throw new InvalidObjectException( he.getMessage() );
-		}
-
-		return rtn;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/StatefulPersistenceContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1486 @@
+/*
+ * 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.engine;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections.map.ReferenceMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.NonUniqueObjectException;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.engine.loading.LoadContexts;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.tuple.ElementWrapper;
+import org.hibernate.util.IdentityMap;
+import org.hibernate.util.MarkerObject;
+
+/**
+ * A <tt>PersistenceContext</tt> represents the state of persistent "stuff" which
+ * Hibernate is tracking.  This includes persistent entities, collections,
+ * as well as proxies generated.
+ * </p>
+ * There is meant to be a one-to-one correspondence between a SessionImpl and
+ * a PersistentContext.  The SessionImpl uses the PersistentContext to track
+ * the current state of its context.  Event-listeners then use the
+ * PersistentContext to drive their processing.
+ *
+ * @author Steve Ebersole
+ */
+public class StatefulPersistenceContext implements PersistenceContext {
+
+	public static final Object NO_ROW = new MarkerObject( "NO_ROW" );
+
+	private static final Logger log = LoggerFactory.getLogger( StatefulPersistenceContext.class );
+	private static final Logger PROXY_WARN_LOG = LoggerFactory.getLogger( StatefulPersistenceContext.class.getName() + ".ProxyWarnLog" );
+	private static final int INIT_COLL_SIZE = 8;
+
+	private SessionImplementor session;
+	
+	// Loaded entity instances, by EntityKey
+	private Map entitiesByKey;
+
+	// Loaded entity instances, by EntityUniqueKey
+	private Map entitiesByUniqueKey;
+	
+	// Identity map of EntityEntry instances, by the entity instance
+	private Map entityEntries;
+	
+	// Entity proxies, by EntityKey
+	private Map proxiesByKey;
+	
+	// Snapshots of current database state for entities
+	// that have *not* been loaded
+	private Map entitySnapshotsByKey;
+	
+	// Identity map of array holder ArrayHolder instances, by the array instance
+	private Map arrayHolders;
+	
+	// Identity map of CollectionEntry instances, by the collection wrapper
+	private Map collectionEntries;
+	
+	// Collection wrappers, by the CollectionKey
+	private Map collectionsByKey; //key=CollectionKey, value=PersistentCollection
+	
+	// Set of EntityKeys of deleted objects
+	private HashSet nullifiableEntityKeys;
+	
+	// properties that we have tried to load, and not found in the database
+	private HashSet nullAssociations;
+	
+	// A list of collection wrappers that were instantiating during result set
+	// processing, that we will need to initialize at the end of the query
+	private List nonlazyCollections;
+	
+	// A container for collections we load up when the owning entity is not
+	// yet loaded ... for now, this is purely transient!
+	private Map unownedCollections;
+	
+	private int cascading = 0;
+	private int loadCounter = 0;
+	private boolean flushing = false;
+	
+	private boolean hasNonReadOnlyEntities = false;
+
+	private LoadContexts loadContexts;
+	private BatchFetchQueue batchFetchQueue;
+
+
+
+	/**
+	 * Constructs a PersistentContext, bound to the given session.
+	 *
+	 * @param session The session "owning" this context.
+	 */
+	public StatefulPersistenceContext(SessionImplementor session) {
+		this.session = session;
+
+		entitiesByKey = new HashMap( INIT_COLL_SIZE );
+		entitiesByUniqueKey = new HashMap( INIT_COLL_SIZE );
+		proxiesByKey = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.WEAK );
+		entitySnapshotsByKey = new HashMap( INIT_COLL_SIZE );
+
+		entityEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
+		collectionEntries = IdentityMap.instantiateSequenced( INIT_COLL_SIZE );
+		collectionsByKey = new HashMap( INIT_COLL_SIZE );
+		arrayHolders = IdentityMap.instantiate( INIT_COLL_SIZE );
+
+		nullifiableEntityKeys = new HashSet();
+
+		initTransientState();
+	}
+
+	private void initTransientState() {
+		nullAssociations = new HashSet( INIT_COLL_SIZE );
+		nonlazyCollections = new ArrayList( INIT_COLL_SIZE );
+	}
+
+	public boolean isStateless() {
+		return false;
+	}
+	
+	public SessionImplementor getSession() {
+		return session;
+	}
+
+	public LoadContexts getLoadContexts() {
+		if ( loadContexts == null ) {
+			loadContexts = new LoadContexts( this );
+		}
+		return loadContexts;
+	}
+
+	public void addUnownedCollection(CollectionKey key, PersistentCollection collection) {
+		if (unownedCollections==null) {
+			unownedCollections = new HashMap(8);
+		}
+		unownedCollections.put(key, collection);
+	}
+	
+	public PersistentCollection useUnownedCollection(CollectionKey key) {
+		if (unownedCollections==null) {
+			return null;
+		}
+		else {
+			return (PersistentCollection) unownedCollections.remove(key);
+		}
+	}
+	
+	/**
+	 * Get the <tt>BatchFetchQueue</tt>, instantiating one if
+	 * necessary.
+	 */
+	public BatchFetchQueue getBatchFetchQueue() {
+		if (batchFetchQueue==null) {
+			batchFetchQueue = new BatchFetchQueue(this);
+		}
+		return batchFetchQueue;
+	}
+
+	public void clear() {
+		Iterator itr = proxiesByKey.values().iterator();
+		while ( itr.hasNext() ) {
+			final LazyInitializer li = ( ( HibernateProxy ) itr.next() ).getHibernateLazyInitializer();
+			li.setSession( null );
+		}
+		Map.Entry[] collectionEntryArray = IdentityMap.concurrentEntries( collectionEntries );
+		for ( int i = 0; i < collectionEntryArray.length; i++ ) {
+			( ( PersistentCollection ) collectionEntryArray[i].getKey() ).unsetSession( getSession() );
+		}
+		arrayHolders.clear();
+		entitiesByKey.clear();
+		entitiesByUniqueKey.clear();
+		entityEntries.clear();
+		entitySnapshotsByKey.clear();
+		collectionsByKey.clear();
+		collectionEntries.clear();
+		if ( unownedCollections != null ) {
+			unownedCollections.clear();
+		}
+		proxiesByKey.clear();
+		nullifiableEntityKeys.clear();
+		if ( batchFetchQueue != null ) {
+			batchFetchQueue.clear();
+		}
+		hasNonReadOnlyEntities = false;
+		if ( loadContexts != null ) {
+			loadContexts.cleanup();
+		}
+	}
+	
+	public boolean hasNonReadOnlyEntities() {
+		return hasNonReadOnlyEntities;
+	}
+	
+	public void setEntryStatus(EntityEntry entry, Status status) {
+		entry.setStatus(status);
+		setHasNonReadOnlyEnties(status);
+	}
+	
+	private void setHasNonReadOnlyEnties(Status status) {
+		if ( status==Status.DELETED || status==Status.MANAGED || status==Status.SAVING ) {
+			hasNonReadOnlyEntities = true;
+		}
+	}
+
+	public void afterTransactionCompletion() {
+		// Downgrade locks
+		Iterator iter = entityEntries.values().iterator();
+		while ( iter.hasNext() ) {
+			( (EntityEntry) iter.next() ).setLockMode(LockMode.NONE);
+		}
+	}
+
+	/**
+	 * Get the current state of the entity as known to the underlying
+	 * database, or null if there is no corresponding row 
+	 */
+	public Object[] getDatabaseSnapshot(Serializable id, EntityPersister persister)
+	throws HibernateException {
+		EntityKey key = new EntityKey( id, persister, session.getEntityMode() );
+		Object cached = entitySnapshotsByKey.get(key);
+		if (cached!=null) {
+			return cached==NO_ROW ? null : (Object[]) cached;
+		}
+		else {
+			Object[] snapshot = persister.getDatabaseSnapshot( id, session );
+			entitySnapshotsByKey.put( key, snapshot==null ? NO_ROW : snapshot );
+			return snapshot;
+		}
+	}
+
+	public Object[] getNaturalIdSnapshot(Serializable id, EntityPersister persister)
+	throws HibernateException {
+		if ( !persister.hasNaturalIdentifier() ) {
+			return null;
+		}
+
+		// if the natural-id is marked as non-mutable, it is not retrieved during a
+		// normal database-snapshot operation...
+		int[] props = persister.getNaturalIdentifierProperties();
+		boolean[] updateable = persister.getPropertyUpdateability();
+		boolean allNatualIdPropsAreUpdateable = true;
+		for ( int i = 0; i < props.length; i++ ) {
+			if ( !updateable[ props[i] ] ) {
+				allNatualIdPropsAreUpdateable = false;
+				break;
+			}
+		}
+
+		if ( allNatualIdPropsAreUpdateable ) {
+			// do this when all the properties are updateable since there is
+			// a certain likelihood that the information will already be
+			// snapshot-cached.
+			Object[] entitySnapshot = getDatabaseSnapshot( id, persister );
+			if ( entitySnapshot == NO_ROW ) {
+				return null;
+			}
+			Object[] naturalIdSnapshot = new Object[ props.length ];
+			for ( int i = 0; i < props.length; i++ ) {
+				naturalIdSnapshot[i] = entitySnapshot[ props[i] ];
+			}
+			return naturalIdSnapshot;
+		}
+		else {
+			return persister.getNaturalIdentifierSnapshot( id, session );
+		}
+	}
+
+	/**
+	 * Retrieve the cached database snapshot for the requested entity key.
+	 * <p/>
+	 * This differs from {@link #getDatabaseSnapshot} is two important respects:<ol>
+	 * <li>no snapshot is obtained from the database if not already cached</li>
+	 * <li>an entry of {@link #NO_ROW} here is interpretet as an exception</li>
+	 * </ol>
+	 * @param key The entity key for which to retrieve the cached snapshot
+	 * @return The cached snapshot
+	 * @throws IllegalStateException if the cached snapshot was == {@link #NO_ROW}.
+	 */
+	public Object[] getCachedDatabaseSnapshot(EntityKey key) {
+		Object snapshot = entitySnapshotsByKey.get( key );
+		if ( snapshot == NO_ROW ) {
+			throw new IllegalStateException( "persistence context reported no row snapshot for " + MessageHelper.infoString( key.getEntityName(), key.getIdentifier() ) );
+		}
+		return ( Object[] ) snapshot;
+	}
+
+	/*public void removeDatabaseSnapshot(EntityKey key) {
+		entitySnapshotsByKey.remove(key);
+	}*/
+
+	public void addEntity(EntityKey key, Object entity) {
+		entitiesByKey.put(key, entity);
+		getBatchFetchQueue().removeBatchLoadableEntityKey(key);
+	}
+
+	/**
+	 * Get the entity instance associated with the given 
+	 * <tt>EntityKey</tt>
+	 */
+	public Object getEntity(EntityKey key) {
+		return entitiesByKey.get(key);
+	}
+
+	public boolean containsEntity(EntityKey key) {
+		return entitiesByKey.containsKey(key);
+	}
+
+	/**
+	 * Remove an entity from the session cache, also clear
+	 * up other state associated with the entity, all except
+	 * for the <tt>EntityEntry</tt>
+	 */
+	public Object removeEntity(EntityKey key) {
+		Object entity = entitiesByKey.remove(key);
+		Iterator iter = entitiesByUniqueKey.values().iterator();
+		while ( iter.hasNext() ) {
+			if ( iter.next()==entity ) iter.remove();
+		}
+		entitySnapshotsByKey.remove(key);
+		nullifiableEntityKeys.remove(key);
+		getBatchFetchQueue().removeBatchLoadableEntityKey(key);
+		getBatchFetchQueue().removeSubselect(key);
+		return entity;
+	}
+
+	/**
+	 * Get an entity cached by unique key
+	 */
+	public Object getEntity(EntityUniqueKey euk) {
+		return entitiesByUniqueKey.get(euk);
+	}
+
+	/**
+	 * Add an entity to the cache by unique key
+	 */
+	public void addEntity(EntityUniqueKey euk, Object entity) {
+		entitiesByUniqueKey.put(euk, entity);
+	}
+
+	/**
+	 * Retreive the EntityEntry representation of the given entity.
+	 *
+	 * @param entity The entity for which to locate the EntityEntry.
+	 * @return The EntityEntry for the given entity.
+	 */
+	public EntityEntry getEntry(Object entity) {
+		return (EntityEntry) entityEntries.get(entity);
+	}
+
+	/**
+	 * Remove an entity entry from the session cache
+	 */
+	public EntityEntry removeEntry(Object entity) {
+		return (EntityEntry) entityEntries.remove(entity);
+	}
+
+	/**
+	 * Is there an EntityEntry for this instance?
+	 */
+	public boolean isEntryFor(Object entity) {
+		return entityEntries.containsKey(entity);
+	}
+
+	/**
+	 * Get the collection entry for a persistent collection
+	 */
+	public CollectionEntry getCollectionEntry(PersistentCollection coll) {
+		return (CollectionEntry) collectionEntries.get(coll);
+	}
+
+	/**
+	 * Adds an entity to the internal caches.
+	 */
+	public EntityEntry addEntity(
+			final Object entity,
+			final Status status,
+			final Object[] loadedState,
+			final EntityKey entityKey,
+			final Object version,
+			final LockMode lockMode,
+			final boolean existsInDatabase,
+			final EntityPersister persister,
+			final boolean disableVersionIncrement, 
+			boolean lazyPropertiesAreUnfetched
+	) {
+		
+		addEntity( entityKey, entity );
+		
+		return addEntry(
+				entity,
+				status,
+				loadedState,
+				null,
+				entityKey.getIdentifier(),
+				version,
+				lockMode,
+				existsInDatabase,
+				persister,
+				disableVersionIncrement, 
+				lazyPropertiesAreUnfetched
+			);
+	}
+
+
+	/**
+	 * Generates an appropriate EntityEntry instance and adds it 
+	 * to the event source's internal caches.
+	 */
+	public EntityEntry addEntry(
+			final Object entity,
+			final Status status,
+			final Object[] loadedState,
+			final Object rowId,
+			final Serializable id,
+			final Object version,
+			final LockMode lockMode,
+			final boolean existsInDatabase,
+			final EntityPersister persister,
+			final boolean disableVersionIncrement, 
+			boolean lazyPropertiesAreUnfetched) {
+		
+		EntityEntry e = new EntityEntry(
+				status,
+				loadedState,
+				rowId,
+				id,
+				version,
+				lockMode,
+				existsInDatabase,
+				persister,
+				session.getEntityMode(),
+				disableVersionIncrement,
+				lazyPropertiesAreUnfetched
+			);
+		entityEntries.put(entity, e);
+		
+		setHasNonReadOnlyEnties(status);
+		return e;
+	}
+
+	public boolean containsCollection(PersistentCollection collection) {
+		return collectionEntries.containsKey(collection);
+	}
+
+	public boolean containsProxy(Object entity) {
+		return proxiesByKey.containsValue( entity );
+	}
+	
+	/**
+	 * Takes the given object and, if it represents a proxy, reassociates it with this event source.
+	 *
+	 * @param value The possible proxy to be reassociated.
+	 * @return Whether the passed value represented an actual proxy which got initialized.
+	 * @throws MappingException
+	 */
+	public boolean reassociateIfUninitializedProxy(Object value) throws MappingException {
+		if ( value instanceof ElementWrapper ) {
+			value = ( (ElementWrapper) value ).getElement();
+		}
+		
+		if ( !Hibernate.isInitialized(value) ) {
+			HibernateProxy proxy = (HibernateProxy) value;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			reassociateProxy(li, proxy);
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * If a deleted entity instance is re-saved, and it has a proxy, we need to
+	 * reset the identifier of the proxy 
+	 */
+	public void reassociateProxy(Object value, Serializable id) throws MappingException {
+		if ( value instanceof ElementWrapper ) {
+			value = ( (ElementWrapper) value ).getElement();
+		}
+		
+		if ( value instanceof HibernateProxy ) {
+			if ( log.isDebugEnabled() ) log.debug("setting proxy identifier: " + id);
+			HibernateProxy proxy = (HibernateProxy) value;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			li.setIdentifier(id);
+			reassociateProxy(li, proxy);
+		}
+	}
+
+	/**
+	 * Associate a proxy that was instantiated by another session with this session
+	 *
+	 * @param li The proxy initializer.
+	 * @param proxy The proxy to reassociate.
+	 */
+	private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) {
+		if ( li.getSession() != this.getSession() ) {
+			EntityPersister persister = session.getFactory().getEntityPersister( li.getEntityName() );
+			EntityKey key = new EntityKey( li.getIdentifier(), persister, session.getEntityMode() );
+		  	// any earlier proxy takes precedence
+			if ( !proxiesByKey.containsKey( key ) ) {
+				proxiesByKey.put( key, proxy );
+			}
+			proxy.getHibernateLazyInitializer().setSession( session );
+		}
+	}
+
+	/**
+	 * Get the entity instance underlying the given proxy, throwing
+	 * an exception if the proxy is uninitialized. If the given object
+	 * is not a proxy, simply return the argument.
+	 */
+	public Object unproxy(Object maybeProxy) throws HibernateException {
+		if ( maybeProxy instanceof ElementWrapper ) {
+			maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
+		}
+		
+		if ( maybeProxy instanceof HibernateProxy ) {
+			HibernateProxy proxy = (HibernateProxy) maybeProxy;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			if ( li.isUninitialized() ) {
+				throw new PersistentObjectException(
+						"object was an uninitialized proxy for " +
+						li.getEntityName()
+				);
+			}
+			return li.getImplementation(); //unwrap the object
+		}
+		else {
+			return maybeProxy;
+		}
+	}
+
+	/**
+	 * Possibly unproxy the given reference and reassociate it with the current session.
+	 *
+	 * @param maybeProxy The reference to be unproxied if it currently represents a proxy.
+	 * @return The unproxied instance.
+	 * @throws HibernateException
+	 */
+	public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException {
+		if ( maybeProxy instanceof ElementWrapper ) {
+			maybeProxy = ( (ElementWrapper) maybeProxy ).getElement();
+		}
+		
+		if ( maybeProxy instanceof HibernateProxy ) {
+			HibernateProxy proxy = (HibernateProxy) maybeProxy;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			reassociateProxy(li, proxy);
+			return li.getImplementation(); //initialize + unwrap the object
+		}
+		else {
+			return maybeProxy;
+		}
+	}
+
+	/**
+	 * Attempts to check whether the given key represents an entity already loaded within the
+	 * current session.
+	 * @param object The entity reference against which to perform the uniqueness check.
+	 * @throws HibernateException
+	 */
+	public void checkUniqueness(EntityKey key, Object object) throws HibernateException {
+		Object entity = getEntity(key);
+		if ( entity == object ) {
+			throw new AssertionFailure( "object already associated, but no entry was found" );
+		}
+		if ( entity != null ) {
+			throw new NonUniqueObjectException( key.getIdentifier(), key.getEntityName() );
+		}
+	}
+
+	/**
+	 * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy
+	 * and overwrite the registration of the old one. This breaks == and occurs only for
+	 * "class" proxies rather than "interface" proxies. Also init the proxy to point to
+	 * the given target implementation if necessary.
+	 *
+	 * @param proxy The proxy instance to be narrowed.
+	 * @param persister The persister for the proxied entity.
+	 * @param key The internal cache key for the proxied entity.
+	 * @param object (optional) the actual proxied entity instance.
+	 * @return An appropriately narrowed instance.
+	 * @throws HibernateException
+	 */
+	public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object)
+	throws HibernateException {
+		
+		boolean alreadyNarrow = persister.getConcreteProxyClass( session.getEntityMode() )
+				.isAssignableFrom( proxy.getClass() );
+		
+		if ( !alreadyNarrow ) {
+			if ( PROXY_WARN_LOG.isWarnEnabled() ) {
+				PROXY_WARN_LOG.warn(
+						"Narrowing proxy to " +
+						persister.getConcreteProxyClass( session.getEntityMode() ) +
+						" - this operation breaks =="
+				);
+			}
+
+			if ( object != null ) {
+				proxiesByKey.remove(key);
+				return object; //return the proxied object
+			}
+			else {
+				proxy = persister.createProxy( key.getIdentifier(), session );
+				proxiesByKey.put(key, proxy); //overwrite old proxy
+				return proxy;
+			}
+			
+		}
+		else {
+			
+			if ( object != null ) {
+				LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
+				li.setImplementation(object);
+			}
+			
+			return proxy;
+			
+		}
+		
+	}
+
+	/**
+	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
+	 * third argument (the entity associated with the key) if no proxy exists. Init
+	 * the proxy to the target implementation, if necessary.
+	 */
+	public Object proxyFor(EntityPersister persister, EntityKey key, Object impl) 
+	throws HibernateException {
+		if ( !persister.hasProxy() ) return impl;
+		Object proxy = proxiesByKey.get(key);
+		if ( proxy != null ) {
+			return narrowProxy(proxy, persister, key, impl);
+		}
+		else {
+			return impl;
+		}
+	}
+
+	/**
+	 * Return the existing proxy associated with the given <tt>EntityKey</tt>, or the
+	 * argument (the entity associated with the key) if no proxy exists.
+	 * (slower than the form above)
+	 */
+	public Object proxyFor(Object impl) throws HibernateException {
+		EntityEntry e = getEntry(impl);
+		EntityPersister p = e.getPersister();
+		return proxyFor( p, new EntityKey( e.getId(), p, session.getEntityMode() ), impl );
+	}
+
+	/**
+	 * Get the entity that owns this persistent collection
+	 */
+	public Object getCollectionOwner(Serializable key, CollectionPersister collectionPersister) throws MappingException {
+		return getEntity( new EntityKey( key, collectionPersister.getOwnerEntityPersister(), session.getEntityMode() ) );
+	}
+
+	/**
+	 * Get the entity that owned this persistent collection when it was loaded
+	 *
+	 * @param collection The persistent collection
+	 * @return the owner, if its entity ID is available from the collection's loaded key
+	 * and the owner entity is in the persistence context; otherwise, returns null
+	 */
+	public Object getLoadedCollectionOwnerOrNull(PersistentCollection collection) {
+		CollectionEntry ce = getCollectionEntry( collection );
+		if ( ce.getLoadedPersister() == null ) {
+			return null; // early exit...
+		}
+		Object loadedOwner = null;
+		// TODO: an alternative is to check if the owner has changed; if it hasn't then
+		// return collection.getOwner()
+		Serializable entityId = getLoadedCollectionOwnerIdOrNull( ce );
+		if ( entityId != null ) {
+			loadedOwner = getCollectionOwner( entityId, ce.getLoadedPersister() );
+		}
+		return loadedOwner;
+	}
+
+	/**
+	 * Get the ID for the entity that owned this persistent collection when it was loaded
+	 *
+	 * @param collection The persistent collection
+	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
+	 */
+	public Serializable getLoadedCollectionOwnerIdOrNull(PersistentCollection collection) {
+		return getLoadedCollectionOwnerIdOrNull( getCollectionEntry( collection ) );
+	}
+
+	/**
+	 * Get the ID for the entity that owned this persistent collection when it was loaded
+	 *
+	 * @param ce The collection entry
+	 * @return the owner ID if available from the collection's loaded key; otherwise, returns null
+	 */
+	private Serializable getLoadedCollectionOwnerIdOrNull(CollectionEntry ce) {
+		if ( ce == null || ce.getLoadedKey() == null || ce.getLoadedPersister() == null ) {
+			return null;
+		}
+		// TODO: an alternative is to check if the owner has changed; if it hasn't then
+		// get the ID from collection.getOwner()
+		return ce.getLoadedPersister().getCollectionType().getIdOfOwnerOrNull( ce.getLoadedKey(), session );
+	}
+
+	/**
+	 * add a collection we just loaded up (still needs initializing)
+	 */
+	public void addUninitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id) {
+		CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
+		addCollection(collection, ce, id);
+	}
+
+	/**
+	 * add a detached uninitialized collection
+	 */
+	public void addUninitializedDetachedCollection(CollectionPersister persister, PersistentCollection collection) {
+		CollectionEntry ce = new CollectionEntry( persister, collection.getKey() );
+		addCollection( collection, ce, collection.getKey() );
+	}
+
+	/**
+	 * Add a new collection (ie. a newly created one, just instantiated by the
+	 * application, with no database state or snapshot)
+	 * @param collection The collection to be associated with the persistence context
+	 */
+	public void addNewCollection(CollectionPersister persister, PersistentCollection collection)
+	throws HibernateException {
+		addCollection(collection, persister);
+	}
+
+	/**
+	 * Add an collection to the cache, with a given collection entry.
+	 *
+	 * @param coll The collection for which we are adding an entry.
+	 * @param entry The entry representing the collection.
+	 * @param key The key of the collection's entry.
+	 */
+	private void addCollection(PersistentCollection coll, CollectionEntry entry, Serializable key) {
+		collectionEntries.put( coll, entry );
+		CollectionKey collectionKey = new CollectionKey( entry.getLoadedPersister(), key, session.getEntityMode() );
+		PersistentCollection old = ( PersistentCollection ) collectionsByKey.put( collectionKey, coll );
+		if ( old != null ) {
+			if ( old == coll ) {
+				throw new AssertionFailure("bug adding collection twice");
+			}
+			// or should it actually throw an exception?
+			old.unsetSession( session );
+			collectionEntries.remove( old );
+			// watch out for a case where old is still referenced
+			// somewhere in the object graph! (which is a user error)
+		}
+	}
+
+	/**
+	 * Add a collection to the cache, creating a new collection entry for it
+	 *
+	 * @param collection The collection for which we are adding an entry.
+	 * @param persister The collection persister
+	 */
+	private void addCollection(PersistentCollection collection, CollectionPersister persister) {
+		CollectionEntry ce = new CollectionEntry( persister, collection );
+		collectionEntries.put( collection, ce );
+	}
+
+	/**
+	 * add an (initialized) collection that was created by another session and passed
+	 * into update() (ie. one with a snapshot and existing state on the database)
+	 */
+	public void addInitializedDetachedCollection(CollectionPersister collectionPersister, PersistentCollection collection) 
+	throws HibernateException {
+		if ( collection.isUnreferenced() ) {
+			//treat it just like a new collection
+			addCollection( collection, collectionPersister );
+		}
+		else {
+			CollectionEntry ce = new CollectionEntry( collection, session.getFactory() );
+			addCollection( collection, ce, collection.getKey() );
+		}
+	}
+
+	/**
+	 * add a collection we just pulled out of the cache (does not need initializing)
+	 */
+	public CollectionEntry addInitializedCollection(CollectionPersister persister, PersistentCollection collection, Serializable id)
+	throws HibernateException {
+		CollectionEntry ce = new CollectionEntry(collection, persister, id, flushing);
+		ce.postInitialize(collection);
+		addCollection(collection, ce, id);
+		return ce;
+	}
+	
+	/**
+	 * Get the collection instance associated with the <tt>CollectionKey</tt>
+	 */
+	public PersistentCollection getCollection(CollectionKey collectionKey) {
+		return (PersistentCollection) collectionsByKey.get(collectionKey);
+	}
+	
+	/**
+	 * Register a collection for non-lazy loading at the end of the
+	 * two-phase load
+	 */
+	public void addNonLazyCollection(PersistentCollection collection) {
+		nonlazyCollections.add(collection);
+	}
+
+	/**
+	 * Force initialization of all non-lazy collections encountered during
+	 * the current two-phase load (actually, this is a no-op, unless this
+	 * is the "outermost" load)
+	 */
+	public void initializeNonLazyCollections() throws HibernateException {
+		if ( loadCounter == 0 ) {
+			log.debug( "initializing non-lazy collections" );
+			//do this work only at the very highest level of the load
+			loadCounter++; //don't let this method be called recursively
+			try {
+				int size;
+				while ( ( size = nonlazyCollections.size() ) > 0 ) {
+					//note that each iteration of the loop may add new elements
+					( (PersistentCollection) nonlazyCollections.remove( size - 1 ) ).forceInitialization();
+				}
+			}
+			finally {
+				loadCounter--;
+				clearNullProperties();
+			}
+		}
+	}
+
+
+	/**
+	 * Get the <tt>PersistentCollection</tt> object for an array
+	 */
+	public PersistentCollection getCollectionHolder(Object array) {
+		return (PersistentCollection) arrayHolders.get(array);
+	}
+
+	/**
+	 * Register a <tt>PersistentCollection</tt> object for an array.
+	 * Associates a holder with an array - MUST be called after loading 
+	 * array, since the array instance is not created until endLoad().
+	 */
+	public void addCollectionHolder(PersistentCollection holder) {
+		//TODO:refactor + make this method private
+		arrayHolders.put( holder.getValue(), holder );
+	}
+
+	public PersistentCollection removeCollectionHolder(Object array) {
+		return (PersistentCollection) arrayHolders.remove(array);
+	}
+
+	/**
+	 * Get the snapshot of the pre-flush collection state
+	 */
+	public Serializable getSnapshot(PersistentCollection coll) {
+		return getCollectionEntry(coll).getSnapshot();
+	}
+
+	/**
+	 * Get the collection entry for a collection passed to filter,
+	 * which might be a collection wrapper, an array, or an unwrapped
+	 * collection. Return null if there is no entry.
+	 */
+	public CollectionEntry getCollectionEntryOrNull(Object collection) {
+		PersistentCollection coll;
+		if ( collection instanceof PersistentCollection ) {
+			coll = (PersistentCollection) collection;
+			//if (collection==null) throw new TransientObjectException("Collection was not yet persistent");
+		}
+		else {
+			coll = getCollectionHolder(collection);
+			if ( coll == null ) {
+				//it might be an unwrapped collection reference!
+				//try to find a wrapper (slowish)
+				Iterator wrappers = IdentityMap.keyIterator(collectionEntries);
+				while ( wrappers.hasNext() ) {
+					PersistentCollection pc = (PersistentCollection) wrappers.next();
+					if ( pc.isWrapper(collection) ) {
+						coll = pc;
+						break;
+					}
+				}
+			}
+		}
+
+		return (coll == null) ? null : getCollectionEntry(coll);
+	}
+
+	/**
+	 * Get an existing proxy by key
+	 */
+	public Object getProxy(EntityKey key) {
+		return proxiesByKey.get(key);
+	}
+
+	/**
+	 * Add a proxy to the session cache
+	 */
+	public void addProxy(EntityKey key, Object proxy) {
+		proxiesByKey.put(key, proxy);
+	}
+
+	/**
+	 * Remove a proxy from the session cache.
+	 * <p/>
+	 * Additionally, ensure that any load optimization references
+	 * such as batch or subselect loading get cleaned up as well.
+	 *
+	 * @param key The key of the entity proxy to be removed
+	 * @return The proxy reference.
+	 */
+	public Object removeProxy(EntityKey key) {
+		if ( batchFetchQueue != null ) {
+			batchFetchQueue.removeBatchLoadableEntityKey( key );
+			batchFetchQueue.removeSubselect( key );
+		}
+		return proxiesByKey.remove( key );
+	}
+
+	/**
+	 * Record the fact that an entity does not exist in the database
+	 * 
+	 * @param key the primary key of the entity
+	 */
+	/*public void addNonExistantEntityKey(EntityKey key) {
+		nonExistantEntityKeys.add(key);
+	}*/
+
+	/**
+	 * Record the fact that an entity does not exist in the database
+	 * 
+	 * @param key a unique key of the entity
+	 */
+	/*public void addNonExistantEntityUniqueKey(EntityUniqueKey key) {
+		nonExistentEntityUniqueKeys.add(key);
+	}*/
+
+	/*public void removeNonExist(EntityKey key) {
+		nonExistantEntityKeys.remove(key);
+	}*/
+
+	/** 
+	 * Retrieve the set of EntityKeys representing nullifiable references
+	 */
+	public HashSet getNullifiableEntityKeys() {
+		return nullifiableEntityKeys;
+	}
+
+	public Map getEntitiesByKey() {
+		return entitiesByKey;
+	}
+
+	public Map getEntityEntries() {
+		return entityEntries;
+	}
+
+	public Map getCollectionEntries() {
+		return collectionEntries;
+	}
+
+	public Map getCollectionsByKey() {
+		return collectionsByKey;
+	}
+
+	/**
+	 * Do we already know that the entity does not exist in the
+	 * database?
+	 */
+	/*public boolean isNonExistant(EntityKey key) {
+		return nonExistantEntityKeys.contains(key);
+	}*/
+
+	/**
+	 * Do we already know that the entity does not exist in the
+	 * database?
+	 */
+	/*public boolean isNonExistant(EntityUniqueKey key) {
+		return nonExistentEntityUniqueKeys.contains(key);
+	}*/
+
+	public int getCascadeLevel() {
+		return cascading;
+	}
+
+	public int incrementCascadeLevel() {
+		return ++cascading;
+	}
+
+	public int decrementCascadeLevel() {
+		return --cascading;
+	}
+
+	public boolean isFlushing() {
+		return flushing;
+	}
+
+	public void setFlushing(boolean flushing) {
+		this.flushing = flushing;
+	}
+
+	/**
+	 * Call this before begining a two-phase load
+	 */
+	public void beforeLoad() {
+		loadCounter++;
+	}
+
+	/**
+	 * Call this after finishing a two-phase load
+	 */
+	public void afterLoad() {
+		loadCounter--;
+	}
+
+	/**
+	 * Returns a string representation of the object.
+	 *
+	 * @return a string representation of the object.
+	 */
+	public String toString() {
+		return new StringBuffer()
+				.append("PersistenceContext[entityKeys=")
+				.append(entitiesByKey.keySet())
+				.append(",collectionKeys=")
+				.append(collectionsByKey.keySet())
+				.append("]")
+				.toString();
+	}
+
+	/**
+	 * Search <tt>this</tt> persistence context for an associated entity instance which is considered the "owner" of
+	 * the given <tt>childEntity</tt>, and return that owner's id value.  This is performed in the scenario of a
+	 * uni-directional, non-inverse one-to-many collection (which means that the collection elements do not maintain
+	 * a direct reference to the owner).
+	 * <p/>
+	 * As such, the processing here is basically to loop over every entity currently associated with this persistence
+	 * context and for those of the correct entity (sub) type to extract its collection role property value and see
+	 * if the child is contained within that collection.  If so, we have found the owner; if not, we go on.
+	 * <p/>
+	 * Also need to account for <tt>mergeMap</tt> which acts as a local copy cache managed for the duration of a merge
+	 * operation.  It represents a map of the detached entity instances pointing to the corresponding managed instance.
+	 *
+	 * @param entityName The entity name for the entity type which would own the child
+	 * @param propertyName The name of the property on the owning entity type which would name this child association.
+	 * @param childEntity The child entity instance for which to locate the owner instance id.
+	 * @param mergeMap A map of non-persistent instances from an on-going merge operation (possibly null).
+	 *
+	 * @return The id of the entityName instance which is said to own the child; null if an appropriate owner not
+	 * located.
+	 */
+	public Serializable getOwnerId(String entityName, String propertyName, Object childEntity, Map mergeMap) {
+		final String collectionRole = entityName + '.' + propertyName;
+		final EntityPersister persister = session.getFactory().getEntityPersister( entityName );
+		final CollectionPersister collectionPersister = session.getFactory().getCollectionPersister( collectionRole );
+
+		// iterate all the entities currently associated with the persistence context.
+		Iterator entities = entityEntries.entrySet().iterator();
+		while ( entities.hasNext() ) {
+			final Map.Entry me = ( Map.Entry ) entities.next();
+			final EntityEntry entityEntry = ( EntityEntry ) me.getValue();
+			// does this entity entry pertain to the entity persister in which we are interested (owner)?
+			if ( persister.isSubclassEntityName( entityEntry.getEntityName() ) ) {
+				final Object entityEntryInstance = me.getKey();
+
+				//check if the managed object is the parent
+				boolean found = isFoundInParent(
+						propertyName,
+						childEntity,
+						persister,
+						collectionPersister,
+						entityEntryInstance
+				);
+
+				if ( !found && mergeMap != null ) {
+					//check if the detached object being merged is the parent
+					Object unmergedInstance = mergeMap.get( entityEntryInstance );
+					Object unmergedChild = mergeMap.get( childEntity );
+					if ( unmergedInstance != null && unmergedChild != null ) {
+						found = isFoundInParent(
+								propertyName,
+								unmergedChild,
+								persister,
+								collectionPersister,
+								unmergedInstance
+						);
+					}
+				}
+
+				if ( found ) {
+					return entityEntry.getId();
+				}
+
+			}
+		}
+
+		// if we get here, it is possible that we have a proxy 'in the way' of the merge map resolution...
+		// 		NOTE: decided to put this here rather than in the above loop as I was nervous about the performance
+		//		of the loop-in-loop especially considering this is far more likely the 'edge case'
+		if ( mergeMap != null ) {
+			Iterator mergeMapItr = mergeMap.entrySet().iterator();
+			while ( mergeMapItr.hasNext() ) {
+				final Map.Entry mergeMapEntry = ( Map.Entry ) mergeMapItr.next();
+				if ( mergeMapEntry.getKey() instanceof HibernateProxy ) {
+					final HibernateProxy proxy = ( HibernateProxy ) mergeMapEntry.getKey();
+					if ( persister.isSubclassEntityName( proxy.getHibernateLazyInitializer().getEntityName() ) ) {
+						boolean found = isFoundInParent(
+								propertyName,
+								childEntity,
+								persister,
+								collectionPersister,
+								mergeMap.get( proxy )
+						);
+						if ( !found ) {
+							found = isFoundInParent(
+									propertyName,
+									mergeMap.get( childEntity ),
+									persister,
+									collectionPersister,
+									mergeMap.get( proxy )
+							);
+						}
+						if ( found ) {
+							return proxy.getHibernateLazyInitializer().getIdentifier();
+						}
+					}
+				}
+			}
+		}
+
+		return null;
+	}
+
+	private boolean isFoundInParent(
+			String property,
+			Object childEntity,
+			EntityPersister persister,
+			CollectionPersister collectionPersister,
+			Object potentialParent) {
+		Object collection = persister.getPropertyValue(
+				potentialParent,
+				property,
+				session.getEntityMode()
+		);
+		return collection != null
+				&& Hibernate.isInitialized( collection )
+				&& collectionPersister.getCollectionType().contains( collection, childEntity, session );
+	}
+
+	/**
+	 * Search the persistence context for an index of the child object,
+	 * given a collection role
+	 */
+	public Object getIndexInOwner(String entity, String property, Object childEntity, Map mergeMap) {
+
+		EntityPersister persister = session.getFactory()
+				.getEntityPersister(entity);
+		CollectionPersister cp = session.getFactory()
+				.getCollectionPersister(entity + '.' + property);
+		Iterator entities = entityEntries.entrySet().iterator();
+		while ( entities.hasNext() ) {
+			Map.Entry me = (Map.Entry) entities.next();
+			EntityEntry ee = (EntityEntry) me.getValue();
+			if ( persister.isSubclassEntityName( ee.getEntityName() ) ) {
+				Object instance = me.getKey();
+				
+				Object index = getIndexInParent(property, childEntity, persister, cp, instance);
+				
+				if (index==null && mergeMap!=null) {
+					Object unmergedInstance = mergeMap.get(instance);
+					Object unmergedChild = mergeMap.get(childEntity);
+					if ( unmergedInstance!=null && unmergedChild!=null ) {
+						index = getIndexInParent(property, unmergedChild, persister, cp, unmergedInstance);
+					}
+				}
+				
+				if (index!=null) return index;
+			}
+		}
+		return null;
+	}
+	
+	private Object getIndexInParent(
+			String property, 
+			Object childEntity, 
+			EntityPersister persister, 
+			CollectionPersister collectionPersister,
+			Object potentialParent
+	){	
+		Object collection = persister.getPropertyValue( potentialParent, property, session.getEntityMode() );
+		if ( collection!=null && Hibernate.isInitialized(collection) ) {
+			return collectionPersister.getCollectionType().indexOf(collection, childEntity);
+		}
+		else {
+			return null;
+		}
+	}
+	
+	/**
+	 * Record the fact that the association belonging to the keyed
+	 * entity is null.
+	 */
+	public void addNullProperty(EntityKey ownerKey, String propertyName) {
+		nullAssociations.add( new AssociationKey(ownerKey, propertyName) );
+	}
+	
+	/**
+	 * Is the association property belonging to the keyed entity null?
+	 */
+	public boolean isPropertyNull(EntityKey ownerKey, String propertyName) {
+		return nullAssociations.contains( new AssociationKey(ownerKey, propertyName) );
+	}
+	
+	private void clearNullProperties() {
+		nullAssociations.clear();
+	}
+
+	public void setReadOnly(Object entity, boolean readOnly) {
+		EntityEntry entry = getEntry(entity);
+		if (entry==null) {
+			throw new TransientObjectException("Instance was not associated with the session");
+		}
+		entry.setReadOnly(readOnly, entity);
+		hasNonReadOnlyEntities = hasNonReadOnlyEntities || !readOnly;
+	}
+
+	public void replaceDelayedEntityIdentityInsertKeys(EntityKey oldKey, Serializable generatedId) {
+		Object entity = entitiesByKey.remove( oldKey );
+		EntityEntry oldEntry = ( EntityEntry ) entityEntries.remove( entity );
+
+		EntityKey newKey = new EntityKey( generatedId, oldEntry.getPersister(), getSession().getEntityMode() );
+		addEntity( newKey, entity );
+		addEntry(
+				entity,
+		        oldEntry.getStatus(),
+		        oldEntry.getLoadedState(),
+		        oldEntry.getRowId(),
+		        generatedId,
+		        oldEntry.getVersion(),
+		        oldEntry.getLockMode(),
+		        oldEntry.isExistsInDatabase(),
+		        oldEntry.getPersister(),
+		        oldEntry.isBeingReplicated(),
+		        oldEntry.isLoadedWithLazyPropertiesUnfetched()
+		);
+	}
+
+	/**
+	 * Used by the owning session to explicitly control serialization of the
+	 * persistence context.
+	 *
+	 * @param oos The stream to which the persistence context should get written
+	 * @throws IOException serialization errors.
+	 */
+	public void serialize(ObjectOutputStream oos) throws IOException {
+		log.trace( "serializing persistent-context" );
+
+		oos.writeBoolean( hasNonReadOnlyEntities );
+
+		oos.writeInt( entitiesByKey.size() );
+		log.trace( "starting serialization of [" + entitiesByKey.size() + "] entitiesByKey entries" );
+		Iterator itr = entitiesByKey.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			( ( EntityKey ) entry.getKey() ).serialize( oos );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( entitiesByUniqueKey.size() );
+		log.trace( "starting serialization of [" + entitiesByUniqueKey.size() + "] entitiesByUniqueKey entries" );
+		itr = entitiesByUniqueKey.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			( ( EntityUniqueKey ) entry.getKey() ).serialize( oos );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( proxiesByKey.size() );
+		log.trace( "starting serialization of [" + proxiesByKey.size() + "] proxiesByKey entries" );
+		itr = proxiesByKey.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			( ( EntityKey ) entry.getKey() ).serialize( oos );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( entitySnapshotsByKey.size() );
+		log.trace( "starting serialization of [" + entitySnapshotsByKey.size() + "] entitySnapshotsByKey entries" );
+		itr = entitySnapshotsByKey.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			( ( EntityKey ) entry.getKey() ).serialize( oos );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( entityEntries.size() );
+		log.trace( "starting serialization of [" + entityEntries.size() + "] entityEntries entries" );
+		itr = entityEntries.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			oos.writeObject( entry.getKey() );
+			( ( EntityEntry ) entry.getValue() ).serialize( oos );
+		}
+
+		oos.writeInt( collectionsByKey.size() );
+		log.trace( "starting serialization of [" + collectionsByKey.size() + "] collectionsByKey entries" );
+		itr = collectionsByKey.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			( ( CollectionKey ) entry.getKey() ).serialize( oos );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( collectionEntries.size() );
+		log.trace( "starting serialization of [" + collectionEntries.size() + "] collectionEntries entries" );
+		itr = collectionEntries.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			oos.writeObject( entry.getKey() );
+			( ( CollectionEntry ) entry.getValue() ).serialize( oos );
+		}
+
+		oos.writeInt( arrayHolders.size() );
+		log.trace( "starting serialization of [" + arrayHolders.size() + "] arrayHolders entries" );
+		itr = arrayHolders.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			oos.writeObject( entry.getKey() );
+			oos.writeObject( entry.getValue() );
+		}
+
+		oos.writeInt( nullifiableEntityKeys.size() );
+		log.trace( "starting serialization of [" + nullifiableEntityKeys.size() + "] nullifiableEntityKeys entries" );
+		itr = nullifiableEntityKeys.iterator();
+		while ( itr.hasNext() ) {
+			EntityKey entry = ( EntityKey ) itr.next();
+			entry.serialize( oos );
+		}
+	}
+
+	public static StatefulPersistenceContext deserialize(
+			ObjectInputStream ois,
+	        SessionImplementor session) throws IOException, ClassNotFoundException {
+		log.trace( "deserializing persistent-context" );
+		StatefulPersistenceContext rtn = new StatefulPersistenceContext( session );
+
+		// during deserialization, we need to reconnect all proxies and
+		// collections to this session, as well as the EntityEntry and
+		// CollectionEntry instances; these associations are transient
+		// because serialization is used for different things.
+
+		try {
+			// todo : we can actually just determine this from the incoming EntityEntry-s
+			rtn.hasNonReadOnlyEntities = ois.readBoolean();
+
+			int count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] entitiesByKey entries" );
+			rtn.entitiesByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				rtn.entitiesByKey.put( EntityKey.deserialize( ois, session ), ois.readObject() );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] entitiesByUniqueKey entries" );
+			rtn.entitiesByUniqueKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				rtn.entitiesByUniqueKey.put( EntityUniqueKey.deserialize( ois, session ), ois.readObject() );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] proxiesByKey entries" );
+			rtn.proxiesByKey = new ReferenceMap( ReferenceMap.HARD, ReferenceMap.WEAK, count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count, .75f );
+			for ( int i = 0; i < count; i++ ) {
+				EntityKey ek = EntityKey.deserialize( ois, session );
+				Object proxy = ois.readObject();
+				if ( proxy instanceof HibernateProxy ) {
+					( ( HibernateProxy ) proxy ).getHibernateLazyInitializer().setSession( session );
+					rtn.proxiesByKey.put( ek, proxy );
+				}
+				else {
+					log.trace( "encountered prunded proxy" );
+				}
+				// otherwise, the proxy was pruned during the serialization process
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] entitySnapshotsByKey entries" );
+			rtn.entitySnapshotsByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				rtn.entitySnapshotsByKey.put( EntityKey.deserialize( ois, session ), ois.readObject() );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] entityEntries entries" );
+			rtn.entityEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				Object entity = ois.readObject();
+				EntityEntry entry = EntityEntry.deserialize( ois, session );
+				rtn.entityEntries.put( entity, entry );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] collectionsByKey entries" );
+			rtn.collectionsByKey = new HashMap( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				rtn.collectionsByKey.put( CollectionKey.deserialize( ois, session ), ois.readObject() );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] collectionEntries entries" );
+			rtn.collectionEntries = IdentityMap.instantiateSequenced( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				final PersistentCollection pc = ( PersistentCollection ) ois.readObject();
+				final CollectionEntry ce = CollectionEntry.deserialize( ois, session );
+				pc.setCurrentSession( session );
+				rtn.collectionEntries.put( pc, ce );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] arrayHolders entries" );
+			rtn.arrayHolders = IdentityMap.instantiate( count < INIT_COLL_SIZE ? INIT_COLL_SIZE : count );
+			for ( int i = 0; i < count; i++ ) {
+				rtn.arrayHolders.put( ois.readObject(), ois.readObject() );
+			}
+
+			count = ois.readInt();
+			log.trace( "staring deserialization of [" + count + "] nullifiableEntityKeys entries" );
+			rtn.nullifiableEntityKeys = new HashSet();
+			for ( int i = 0; i < count; i++ ) {
+				rtn.nullifiableEntityKeys.add( EntityKey.deserialize( ois, session ) );
+			}
+
+		}
+		catch ( HibernateException he ) {
+			throw new InvalidObjectException( he.getMessage() );
+		}
+
+		return rtn;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Status.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: Status.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.io.InvalidObjectException;
-
-/**
- * Represents the status of an entity with respect to
- * this session. These statuses are for internal
- * book-keeping only and are not intended to represent
- * any notion that is visible to the _application_.
- */
-public final class Status implements Serializable {
-
-	public static final Status MANAGED = new Status( "MANAGED" );
-	public static final Status READ_ONLY = new Status( "READ_ONLY" );
-	public static final Status DELETED = new Status( "DELETED" );
-	public static final Status GONE = new Status( "GONE" );
-	public static final Status LOADING = new Status( "LOADING" );
-	public static final Status SAVING = new Status( "SAVING" );
-
-	private String name;
-
-	private Status(String name) {
-		this.name = name;
-	}
-
-	public String toString() {
-		return name;
-	}
-
-	private Object readResolve() throws ObjectStreamException {
-		return parse( name );
-	}
-
-	public static Status parse(String name) throws InvalidObjectException {
-		if ( name.equals(MANAGED.name) ) return MANAGED;
-		if ( name.equals(READ_ONLY.name) ) return READ_ONLY;
-		if ( name.equals(DELETED.name) ) return DELETED;
-		if ( name.equals(GONE.name) ) return GONE;
-		if ( name.equals(LOADING.name) ) return LOADING;
-		if ( name.equals(SAVING.name) ) return SAVING;
-		throw new InvalidObjectException( "invalid Status" );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Status.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Status.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.io.InvalidObjectException;
+
+/**
+ * Represents the status of an entity with respect to
+ * this session. These statuses are for internal
+ * book-keeping only and are not intended to represent
+ * any notion that is visible to the _application_.
+ */
+public final class Status implements Serializable {
+
+	public static final Status MANAGED = new Status( "MANAGED" );
+	public static final Status READ_ONLY = new Status( "READ_ONLY" );
+	public static final Status DELETED = new Status( "DELETED" );
+	public static final Status GONE = new Status( "GONE" );
+	public static final Status LOADING = new Status( "LOADING" );
+	public static final Status SAVING = new Status( "SAVING" );
+
+	private String name;
+
+	private Status(String name) {
+		this.name = name;
+	}
+
+	public String toString() {
+		return name;
+	}
+
+	private Object readResolve() throws ObjectStreamException {
+		return parse( name );
+	}
+
+	public static Status parse(String name) throws InvalidObjectException {
+		if ( name.equals(MANAGED.name) ) return MANAGED;
+		if ( name.equals(READ_ONLY.name) ) return READ_ONLY;
+		if ( name.equals(DELETED.name) ) return DELETED;
+		if ( name.equals(GONE.name) ) return GONE;
+		if ( name.equals(LOADING.name) ) return LOADING;
+		if ( name.equals(SAVING.name) ) return SAVING;
+		throw new InvalidObjectException( "invalid Status" );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/SubselectFetch.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: SubselectFetch.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.engine;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Gavin King
- */
-public class SubselectFetch {
-	private final Set resultingEntityKeys;
-	private final String queryString;
-	private final String alias;
-	private final Loadable loadable;
-	private final QueryParameters queryParameters;
-	private final Map namedParameterLocMap;
-	
-	public SubselectFetch(
-		//final String queryString, 
-		final String alias, 
-		final Loadable loadable,
-		final QueryParameters queryParameters, 
-		final Set resultingEntityKeys,
-		final Map namedParameterLocMap
-	) {
-		this.resultingEntityKeys = resultingEntityKeys;
-		this.queryParameters = queryParameters;
-		this.namedParameterLocMap = namedParameterLocMap;
-		this.loadable = loadable;
-		this.alias = alias;
-		
-		//TODO: ugly here:
-		final String queryString = queryParameters.getFilteredSQL();
-		int fromIndex = queryString.indexOf(" from ");
-		int orderByIndex = queryString.lastIndexOf("order by");
-		this.queryString = orderByIndex>0 ? 
-				queryString.substring(fromIndex, orderByIndex) : 
-				queryString.substring(fromIndex);
-			
-	}
-
-	public QueryParameters getQueryParameters() {
-		return queryParameters;
-	}
-	
-	/**
-	 * Get the Set of EntityKeys
-	 */
-	public Set getResult() {
-		return resultingEntityKeys;
-	}
-	
-	public String toSubselectString(String ukname) {
-		
-		String[] joinColumns = ukname==null ?
-			StringHelper.qualify( alias, loadable.getIdentifierColumnNames() ) :
-			( (PropertyMapping) loadable ).toColumns(alias, ukname);
-		
-		return new StringBuffer()
-			.append("select ")
-			.append( StringHelper.join(", ", joinColumns) )
-			.append(queryString)
-			.toString();
-	}
-	
-	public String toString() {
-		return "SubselectFetch(" + queryString + ')';
-	}
-	
-	public Map getNamedParameterLocMap() {
-		return namedParameterLocMap;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/SubselectFetch.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/SubselectFetch.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Gavin King
+ */
+public class SubselectFetch {
+	private final Set resultingEntityKeys;
+	private final String queryString;
+	private final String alias;
+	private final Loadable loadable;
+	private final QueryParameters queryParameters;
+	private final Map namedParameterLocMap;
+	
+	public SubselectFetch(
+		//final String queryString, 
+		final String alias, 
+		final Loadable loadable,
+		final QueryParameters queryParameters, 
+		final Set resultingEntityKeys,
+		final Map namedParameterLocMap
+	) {
+		this.resultingEntityKeys = resultingEntityKeys;
+		this.queryParameters = queryParameters;
+		this.namedParameterLocMap = namedParameterLocMap;
+		this.loadable = loadable;
+		this.alias = alias;
+		
+		//TODO: ugly here:
+		final String queryString = queryParameters.getFilteredSQL();
+		int fromIndex = queryString.indexOf(" from ");
+		int orderByIndex = queryString.lastIndexOf("order by");
+		this.queryString = orderByIndex>0 ? 
+				queryString.substring(fromIndex, orderByIndex) : 
+				queryString.substring(fromIndex);
+			
+	}
+
+	public QueryParameters getQueryParameters() {
+		return queryParameters;
+	}
+	
+	/**
+	 * Get the Set of EntityKeys
+	 */
+	public Set getResult() {
+		return resultingEntityKeys;
+	}
+	
+	public String toSubselectString(String ukname) {
+		
+		String[] joinColumns = ukname==null ?
+			StringHelper.qualify( alias, loadable.getIdentifierColumnNames() ) :
+			( (PropertyMapping) loadable ).toColumns(alias, ukname);
+		
+		return new StringBuffer()
+			.append("select ")
+			.append( StringHelper.join(", ", joinColumns) )
+			.append(queryString)
+			.toString();
+	}
+	
+	public String toString() {
+		return "SubselectFetch(" + queryString + ')';
+	}
+	
+	public Map getNamedParameterLocMap() {
+		return namedParameterLocMap;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/TransactionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: TransactionHelper.java 9056 2006-01-13 19:40:15Z steveebersole $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.transaction.IsolatedWork;
-import org.hibernate.engine.transaction.Isolater;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-/**
- * Allows work to be done outside the current transaction, by suspending it,
- * and performing work in a new transaction
- * 
- * @author Emmanuel Bernard
- */
-public abstract class TransactionHelper {
-
-	// todo : remove this and just have subclasses use Isolater/IsolatedWork directly...
-
-	/**
-	 * The work to be done
-	 */
-	protected abstract Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException;
-
-	/**
-	 * Suspend the current transaction and perform work in a new transaction
-	 */
-	public Serializable doWorkInNewTransaction(final SessionImplementor session)
-	throws HibernateException {
-		class Work implements IsolatedWork {
-			Serializable generatedValue;
-			public void doWork(Connection connection) throws HibernateException {
-				String sql = null;
-				try {
-					generatedValue = doWorkInCurrentTransaction( connection, sql );
-				}
-				catch( SQLException sqle ) {
-					throw JDBCExceptionHelper.convert(
-							session.getFactory().getSQLExceptionConverter(),
-							sqle,
-							"could not get or update next value",
-							sql
-						);
-				}
-			}
-		}
-		Work work = new Work();
-		Isolater.doIsolatedWork( work, session );
-		return work.generatedValue;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/TransactionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TransactionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.transaction.IsolatedWork;
+import org.hibernate.engine.transaction.Isolater;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+/**
+ * Allows work to be done outside the current transaction, by suspending it,
+ * and performing work in a new transaction
+ * 
+ * @author Emmanuel Bernard
+ */
+public abstract class TransactionHelper {
+
+	// todo : remove this and just have subclasses use Isolater/IsolatedWork directly...
+
+	/**
+	 * The work to be done
+	 */
+	protected abstract Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException;
+
+	/**
+	 * Suspend the current transaction and perform work in a new transaction
+	 */
+	public Serializable doWorkInNewTransaction(final SessionImplementor session)
+	throws HibernateException {
+		class Work implements IsolatedWork {
+			Serializable generatedValue;
+			public void doWork(Connection connection) throws HibernateException {
+				String sql = null;
+				try {
+					generatedValue = doWorkInCurrentTransaction( connection, sql );
+				}
+				catch( SQLException sqle ) {
+					throw JDBCExceptionHelper.convert(
+							session.getFactory().getSQLExceptionConverter(),
+							sqle,
+							"could not get or update next value",
+							sql
+						);
+				}
+			}
+		}
+		Work work = new Work();
+		Isolater.doIsolatedWork( work, session );
+		return work.generatedValue;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,273 +0,0 @@
-//$Id: TwoPhaseLoad.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.CacheMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.entry.CacheEntry;
-import org.hibernate.event.PostLoadEvent;
-import org.hibernate.event.PostLoadEventListener;
-import org.hibernate.event.PreLoadEvent;
-import org.hibernate.event.PreLoadEventListener;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.property.BackrefPropertyAccessor;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * Functionality relating to Hibernate's two-phase loading process,
- * that may be reused by persisters that do not use the Loader
- * framework
- * 
- * @author Gavin King
- */
-public final class TwoPhaseLoad {
-
-	private static final Logger log = LoggerFactory.getLogger(TwoPhaseLoad.class);
-	
-	private TwoPhaseLoad() {}
-
-	/**
-	 * Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
-	 * 
-	 * Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
-	 * to resolve any associations yet, because there might be other entities waiting to be
-	 * read from the JDBC result set we are currently processing
-	 */
-	public static void postHydrate(
-		final EntityPersister persister, 
-		final Serializable id, 
-		final Object[] values, 
-		final Object rowId,
-		final Object object, 
-		final LockMode lockMode,
-		final boolean lazyPropertiesAreUnfetched, 
-		final SessionImplementor session) 
-	throws HibernateException {
-		
-		Object version = Versioning.getVersion(values, persister);
-		session.getPersistenceContext().addEntry( 
-				object, 
-				Status.LOADING,
-				values, 
-				rowId, 
-				id, 
-				version, 
-				lockMode, 
-				true, 
-				persister, 
-				false, 
-				lazyPropertiesAreUnfetched 
-			);
-	
-		if ( log.isTraceEnabled() && version!=null ) {
-			String versionStr = persister.isVersioned()
-					? persister.getVersionType().toLoggableString( version, session.getFactory() )
-			        : "null";
-			log.trace( "Version: " + versionStr );
-		}
-	
-	}
-
-	/**
-	 * Perform the second step of 2-phase load. Fully initialize the entity 
-	 * instance.
-	 *
-	 * After processing a JDBC result set, we "resolve" all the associations
-	 * between the entities which were instantiated and had their state
-	 * "hydrated" into an array
-	 */
-	public static void initializeEntity(
-			final Object entity, 
-			final boolean readOnly,
-			final SessionImplementor session,
-			final PreLoadEvent preLoadEvent,
-			final PostLoadEvent postLoadEvent) throws HibernateException {
-		
-		//TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)
-	
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		EntityEntry entityEntry = persistenceContext.getEntry(entity);
-		if ( entityEntry == null ) {
-			throw new AssertionFailure( "possible non-threadsafe access to the session" );
-		}
-		EntityPersister persister = entityEntry.getPersister();
-		Serializable id = entityEntry.getId();
-		Object[] hydratedState = entityEntry.getLoadedState();
-	
-		if ( log.isDebugEnabled() )
-			log.debug(
-					"resolving associations for " +
-					MessageHelper.infoString(persister, id, session.getFactory())
-				);
-	
-		Type[] types = persister.getPropertyTypes();
-		for ( int i = 0; i < hydratedState.length; i++ ) {
-			final Object value = hydratedState[i];
-			if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
-				hydratedState[i] = types[i].resolve( value, session, entity );
-			}
-		}
-	
-		//Must occur after resolving identifiers!
-		if ( session.isEventSource() ) {
-			preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
-			PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
-			for ( int i = 0; i < listeners.length; i++ ) {
-				listeners[i].onPreLoad(preLoadEvent);
-			}
-		}
-	
-		persister.setPropertyValues( entity, hydratedState, session.getEntityMode() );
-	
-		final SessionFactoryImplementor factory = session.getFactory();
-		if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
-			
-			if ( log.isDebugEnabled() )
-				log.debug(
-						"adding entity to second-level cache: " +
-						MessageHelper.infoString( persister, id, session.getFactory() )
-					);
-
-			Object version = Versioning.getVersion(hydratedState, persister);
-			CacheEntry entry = new CacheEntry(
-					hydratedState, 
-					persister, 
-					entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
-					version, 
-					session, 
-					entity
-			);
-			CacheKey cacheKey = new CacheKey( 
-					id, 
-					persister.getIdentifierType(), 
-					persister.getRootEntityName(), 
-					session.getEntityMode(), 
-					session.getFactory() 
-			);
-			boolean put = persister.getCacheAccessStrategy().putFromLoad(
-					cacheKey,
-					persister.getCacheEntryStructure().structure( entry ),
-					session.getTimestamp(),
-					version,
-					useMinimalPuts( session, entityEntry )
-			);
-
-			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
-				factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
-			}
-		}
-	
-		if ( readOnly || !persister.isMutable() ) {
-			//no need to take a snapshot - this is a 
-			//performance optimization, but not really
-			//important, except for entities with huge 
-			//mutable property values
-			persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
-		}
-		else {
-			//take a snapshot
-			TypeFactory.deepCopy( 
-					hydratedState, 
-					persister.getPropertyTypes(), 
-					persister.getPropertyUpdateability(), 
-					hydratedState,  //after setting values to object, entityMode
-					session
-				);
-			persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
-		}
-		
-		persister.afterInitialize(
-				entity, 
-				entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
-				session
-			);
-		
-		if ( session.isEventSource() ) {
-			postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
-			PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
-			for ( int i = 0; i < listeners.length; i++ ) {
-				listeners[i].onPostLoad(postLoadEvent);
-			}
-		}
-		
-		if ( log.isDebugEnabled() )
-			log.debug(
-					"done materializing entity " +
-					MessageHelper.infoString( persister, id, session.getFactory() )
-				);
-		
-		if ( factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().loadEntity( persister.getEntityName() );
-		}
-	
-	}
-
-	private static boolean useMinimalPuts(SessionImplementor session, EntityEntry entityEntry) {
-		return ( session.getFactory().getSettings().isMinimalPutsEnabled() && 
-						session.getCacheMode()!=CacheMode.REFRESH ) ||
-				( entityEntry.getPersister().hasLazyProperties() && 
-						entityEntry.isLoadedWithLazyPropertiesUnfetched() && 
-						entityEntry.getPersister().isLazyPropertiesCacheable() );
-	}
-
-	/**
-	 * Add an uninitialized instance of an entity class, as a placeholder to ensure object 
-	 * identity. Must be called before <tt>postHydrate()</tt>.
-	 *
-	 * Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized,
-	 * but we need the mapping from id to instance in order to guarantee uniqueness.
-	 */
-	public static void addUninitializedEntity(
-			final EntityKey key, 
-			final Object object, 
-			final EntityPersister persister, 
-			final LockMode lockMode,
-			final boolean lazyPropertiesAreUnfetched, 
-			final SessionImplementor session
-	) {
-		session.getPersistenceContext().addEntity(
-				object, 
-				Status.LOADING, 
-				null, 
-				key, 
-				null, 
-				lockMode, 
-				true, 
-				persister, 
-				false, 
-				lazyPropertiesAreUnfetched
-			);
-	}
-
-	public static void addUninitializedCachedEntity(
-			final EntityKey key, 
-			final Object object, 
-			final EntityPersister persister, 
-			final LockMode lockMode,
-			final boolean lazyPropertiesAreUnfetched,
-			final Object version,
-			final SessionImplementor session
-	) {
-		session.getPersistenceContext().addEntity(
-				object, 
-				Status.LOADING, 
-				null, 
-				key, 
-				version, 
-				lockMode, 
-				true, 
-				persister, 
-				false, 
-				lazyPropertiesAreUnfetched
-			);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TwoPhaseLoad.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,296 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.CacheMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.event.PostLoadEvent;
+import org.hibernate.event.PostLoadEventListener;
+import org.hibernate.event.PreLoadEvent;
+import org.hibernate.event.PreLoadEventListener;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.property.BackrefPropertyAccessor;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * Functionality relating to Hibernate's two-phase loading process,
+ * that may be reused by persisters that do not use the Loader
+ * framework
+ * 
+ * @author Gavin King
+ */
+public final class TwoPhaseLoad {
+
+	private static final Logger log = LoggerFactory.getLogger(TwoPhaseLoad.class);
+	
+	private TwoPhaseLoad() {}
+
+	/**
+	 * Register the "hydrated" state of an entity instance, after the first step of 2-phase loading.
+	 * 
+	 * Add the "hydrated state" (an array) of an uninitialized entity to the session. We don't try
+	 * to resolve any associations yet, because there might be other entities waiting to be
+	 * read from the JDBC result set we are currently processing
+	 */
+	public static void postHydrate(
+		final EntityPersister persister, 
+		final Serializable id, 
+		final Object[] values, 
+		final Object rowId,
+		final Object object, 
+		final LockMode lockMode,
+		final boolean lazyPropertiesAreUnfetched, 
+		final SessionImplementor session) 
+	throws HibernateException {
+		
+		Object version = Versioning.getVersion(values, persister);
+		session.getPersistenceContext().addEntry( 
+				object, 
+				Status.LOADING,
+				values, 
+				rowId, 
+				id, 
+				version, 
+				lockMode, 
+				true, 
+				persister, 
+				false, 
+				lazyPropertiesAreUnfetched 
+			);
+	
+		if ( log.isTraceEnabled() && version!=null ) {
+			String versionStr = persister.isVersioned()
+					? persister.getVersionType().toLoggableString( version, session.getFactory() )
+			        : "null";
+			log.trace( "Version: " + versionStr );
+		}
+	
+	}
+
+	/**
+	 * Perform the second step of 2-phase load. Fully initialize the entity 
+	 * instance.
+	 *
+	 * After processing a JDBC result set, we "resolve" all the associations
+	 * between the entities which were instantiated and had their state
+	 * "hydrated" into an array
+	 */
+	public static void initializeEntity(
+			final Object entity, 
+			final boolean readOnly,
+			final SessionImplementor session,
+			final PreLoadEvent preLoadEvent,
+			final PostLoadEvent postLoadEvent) throws HibernateException {
+		
+		//TODO: Should this be an InitializeEntityEventListener??? (watch out for performance!)
+	
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		EntityEntry entityEntry = persistenceContext.getEntry(entity);
+		if ( entityEntry == null ) {
+			throw new AssertionFailure( "possible non-threadsafe access to the session" );
+		}
+		EntityPersister persister = entityEntry.getPersister();
+		Serializable id = entityEntry.getId();
+		Object[] hydratedState = entityEntry.getLoadedState();
+	
+		if ( log.isDebugEnabled() )
+			log.debug(
+					"resolving associations for " +
+					MessageHelper.infoString(persister, id, session.getFactory())
+				);
+	
+		Type[] types = persister.getPropertyTypes();
+		for ( int i = 0; i < hydratedState.length; i++ ) {
+			final Object value = hydratedState[i];
+			if ( value!=LazyPropertyInitializer.UNFETCHED_PROPERTY && value!=BackrefPropertyAccessor.UNKNOWN ) {
+				hydratedState[i] = types[i].resolve( value, session, entity );
+			}
+		}
+	
+		//Must occur after resolving identifiers!
+		if ( session.isEventSource() ) {
+			preLoadEvent.setEntity(entity).setState(hydratedState).setId(id).setPersister(persister);
+			PreLoadEventListener[] listeners = session.getListeners().getPreLoadEventListeners();
+			for ( int i = 0; i < listeners.length; i++ ) {
+				listeners[i].onPreLoad(preLoadEvent);
+			}
+		}
+	
+		persister.setPropertyValues( entity, hydratedState, session.getEntityMode() );
+	
+		final SessionFactoryImplementor factory = session.getFactory();
+		if ( persister.hasCache() && session.getCacheMode().isPutEnabled() ) {
+			
+			if ( log.isDebugEnabled() )
+				log.debug(
+						"adding entity to second-level cache: " +
+						MessageHelper.infoString( persister, id, session.getFactory() )
+					);
+
+			Object version = Versioning.getVersion(hydratedState, persister);
+			CacheEntry entry = new CacheEntry(
+					hydratedState, 
+					persister, 
+					entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
+					version, 
+					session, 
+					entity
+			);
+			CacheKey cacheKey = new CacheKey( 
+					id, 
+					persister.getIdentifierType(), 
+					persister.getRootEntityName(), 
+					session.getEntityMode(), 
+					session.getFactory() 
+			);
+			boolean put = persister.getCacheAccessStrategy().putFromLoad(
+					cacheKey,
+					persister.getCacheEntryStructure().structure( entry ),
+					session.getTimestamp(),
+					version,
+					useMinimalPuts( session, entityEntry )
+			);
+
+			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
+				factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
+			}
+		}
+	
+		if ( readOnly || !persister.isMutable() ) {
+			//no need to take a snapshot - this is a 
+			//performance optimization, but not really
+			//important, except for entities with huge 
+			//mutable property values
+			persistenceContext.setEntryStatus(entityEntry, Status.READ_ONLY);
+		}
+		else {
+			//take a snapshot
+			TypeFactory.deepCopy( 
+					hydratedState, 
+					persister.getPropertyTypes(), 
+					persister.getPropertyUpdateability(), 
+					hydratedState,  //after setting values to object, entityMode
+					session
+				);
+			persistenceContext.setEntryStatus(entityEntry, Status.MANAGED);
+		}
+		
+		persister.afterInitialize(
+				entity, 
+				entityEntry.isLoadedWithLazyPropertiesUnfetched(), 
+				session
+			);
+		
+		if ( session.isEventSource() ) {
+			postLoadEvent.setEntity(entity).setId(id).setPersister(persister);
+			PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
+			for ( int i = 0; i < listeners.length; i++ ) {
+				listeners[i].onPostLoad(postLoadEvent);
+			}
+		}
+		
+		if ( log.isDebugEnabled() )
+			log.debug(
+					"done materializing entity " +
+					MessageHelper.infoString( persister, id, session.getFactory() )
+				);
+		
+		if ( factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().loadEntity( persister.getEntityName() );
+		}
+	
+	}
+
+	private static boolean useMinimalPuts(SessionImplementor session, EntityEntry entityEntry) {
+		return ( session.getFactory().getSettings().isMinimalPutsEnabled() && 
+						session.getCacheMode()!=CacheMode.REFRESH ) ||
+				( entityEntry.getPersister().hasLazyProperties() && 
+						entityEntry.isLoadedWithLazyPropertiesUnfetched() && 
+						entityEntry.getPersister().isLazyPropertiesCacheable() );
+	}
+
+	/**
+	 * Add an uninitialized instance of an entity class, as a placeholder to ensure object 
+	 * identity. Must be called before <tt>postHydrate()</tt>.
+	 *
+	 * Create a "temporary" entry for a newly instantiated entity. The entity is uninitialized,
+	 * but we need the mapping from id to instance in order to guarantee uniqueness.
+	 */
+	public static void addUninitializedEntity(
+			final EntityKey key, 
+			final Object object, 
+			final EntityPersister persister, 
+			final LockMode lockMode,
+			final boolean lazyPropertiesAreUnfetched, 
+			final SessionImplementor session
+	) {
+		session.getPersistenceContext().addEntity(
+				object, 
+				Status.LOADING, 
+				null, 
+				key, 
+				null, 
+				lockMode, 
+				true, 
+				persister, 
+				false, 
+				lazyPropertiesAreUnfetched
+			);
+	}
+
+	public static void addUninitializedCachedEntity(
+			final EntityKey key, 
+			final Object object, 
+			final EntityPersister persister, 
+			final LockMode lockMode,
+			final boolean lazyPropertiesAreUnfetched,
+			final Object version,
+			final SessionImplementor session
+	) {
+		session.getPersistenceContext().addEntity(
+				object, 
+				Status.LOADING, 
+				null, 
+				key, 
+				version, 
+				lockMode, 
+				true, 
+				persister, 
+				false, 
+				lazyPropertiesAreUnfetched
+			);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/TypedValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-//$Id: TypedValue.java 6638 2005-05-02 14:34:17Z oneovthafew $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-
-import org.hibernate.EntityMode;
-import org.hibernate.type.Type;
-
-/**
- * An ordered pair of a value and its Hibernate type.
- * 
- * @see org.hibernate.type.Type
- * @author Gavin King
- */
-public final class TypedValue implements Serializable {
-	private final Type type;
-	private final Object value;
-	private final EntityMode entityMode;
-
-	public TypedValue(Type type, Object value, EntityMode entityMode) {
-		this.type = type;
-		this.value=value;
-		this.entityMode = entityMode;
-	}
-
-	public Object getValue() {
-		return value;
-	}
-
-	public Type getType() {
-		return type;
-	}
-
-	public String toString() {
-		return value==null ? "null" : value.toString();
-	}
-
-	public int hashCode() {
-		//int result = 17;
-		//result = 37 * result + type.hashCode();
-		//result = 37 * result + ( value==null ? 0 : value.hashCode() );
-		//return result;
-		return value==null ? 0 : type.getHashCode(value, entityMode);
-	}
-
-	public boolean equals(Object other) {
-		if ( !(other instanceof TypedValue) ) return false;
-		TypedValue that = (TypedValue) other;
-		/*return that.type.equals(type) && 
-			EqualsHelper.equals(that.value, value);*/
-		return type.getReturnedClass() == that.type.getReturnedClass() &&
-			type.isEqual(that.value, value, entityMode);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/TypedValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/TypedValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+
+import org.hibernate.EntityMode;
+import org.hibernate.type.Type;
+
+/**
+ * An ordered pair of a value and its Hibernate type.
+ * 
+ * @see org.hibernate.type.Type
+ * @author Gavin King
+ */
+public final class TypedValue implements Serializable {
+	private final Type type;
+	private final Object value;
+	private final EntityMode entityMode;
+
+	public TypedValue(Type type, Object value, EntityMode entityMode) {
+		this.type = type;
+		this.value=value;
+		this.entityMode = entityMode;
+	}
+
+	public Object getValue() {
+		return value;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public String toString() {
+		return value==null ? "null" : value.toString();
+	}
+
+	public int hashCode() {
+		//int result = 17;
+		//result = 37 * result + type.hashCode();
+		//result = 37 * result + ( value==null ? 0 : value.hashCode() );
+		//return result;
+		return value==null ? 0 : type.getHashCode(value, entityMode);
+	}
+
+	public boolean equals(Object other) {
+		if ( !(other instanceof TypedValue) ) return false;
+		TypedValue that = (TypedValue) other;
+		/*return that.type.equals(type) && 
+			EqualsHelper.equals(that.value, value);*/
+		return type.getReturnedClass() == that.type.getReturnedClass() &&
+			type.isEqual(that.value, value, entityMode);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,115 +0,0 @@
-//$Id: UnsavedValueFactory.java 7736 2005-08-03 20:03:34Z steveebersole $
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-
-import org.hibernate.InstantiationException;
-import org.hibernate.MappingException;
-import org.hibernate.property.Getter;
-import org.hibernate.type.IdentifierType;
-import org.hibernate.type.PrimitiveType;
-import org.hibernate.type.Type;
-import org.hibernate.type.VersionType;
-
-/**
- * @author Gavin King
- */
-public class UnsavedValueFactory {
-	
-	private static Object instantiate(Constructor constructor) {
-		try {
-			return constructor.newInstance(null);
-		}
-		catch (Exception e) {
-			throw new InstantiationException( "could not instantiate test object", constructor.getDeclaringClass(), e );
-		}
-	}
-	
-	/**
-	 * Return an IdentifierValue for the specified unsaved-value. If none is specified, 
-	 * guess the unsaved value by instantiating a test instance of the class and
-	 * reading it's id property, or if that is not possible, using the java default
-	 * value for the type 
-	 */
-	public static IdentifierValue getUnsavedIdentifierValue(
-			String unsavedValue, 
-			Getter identifierGetter,
-			Type identifierType,
-			Constructor constructor) {
-		
-		if ( unsavedValue == null ) {
-			if ( identifierGetter!=null && constructor!=null ) {
-				// use the id value of a newly instantiated instance as the unsaved-value
-				Serializable defaultValue = (Serializable) identifierGetter.get( instantiate(constructor) );
-				return new IdentifierValue( defaultValue );
-			}
-			else if ( identifierGetter != null && (identifierType instanceof PrimitiveType) ) {
-				Serializable defaultValue = ( ( PrimitiveType ) identifierType ).getDefaultValue();
-				return new IdentifierValue( defaultValue );
-			}
-			else {
-				return IdentifierValue.NULL;
-			}
-		}
-		else if ( "null".equals( unsavedValue ) ) {
-			return IdentifierValue.NULL;
-		}
-		else if ( "undefined".equals( unsavedValue ) ) {
-			return IdentifierValue.UNDEFINED;
-		}
-		else if ( "none".equals( unsavedValue ) ) {
-			return IdentifierValue.NONE;
-		}
-		else if ( "any".equals( unsavedValue ) ) {
-			return IdentifierValue.ANY;
-		}
-		else {
-			try {
-				return new IdentifierValue( ( Serializable ) ( ( IdentifierType ) identifierType ).stringToObject( unsavedValue ) );
-			}
-			catch ( ClassCastException cce ) {
-				throw new MappingException( "Bad identifier type: " + identifierType.getName() );
-			}
-			catch ( Exception e ) {
-				throw new MappingException( "Could not parse identifier unsaved-value: " + unsavedValue );
-			}
-		}
-	}
-
-	public static VersionValue getUnsavedVersionValue(
-			String versionUnsavedValue, 
-			Getter versionGetter,
-			VersionType versionType,
-			Constructor constructor) {
-		
-		if ( versionUnsavedValue == null ) {
-			if ( constructor!=null ) {
-				Object defaultValue = versionGetter.get( instantiate(constructor) );
-				// if the version of a newly instantiated object is not the same
-				// as the version seed value, use that as the unsaved-value
-				return versionType.isEqual( versionType.seed( null ), defaultValue ) ?
-						VersionValue.UNDEFINED :
-						new VersionValue( defaultValue );
-			}
-			else {
-				return VersionValue.UNDEFINED;
-			}
-		}
-		else if ( "undefined".equals( versionUnsavedValue ) ) {
-			return VersionValue.UNDEFINED;
-		}
-		else if ( "null".equals( versionUnsavedValue ) ) {
-			return VersionValue.NULL;
-		}
-		else if ( "negative".equals( versionUnsavedValue ) ) {
-			return VersionValue.NEGATIVE;
-		}
-		else {
-			// this should not happen since the DTD prevents it
-			throw new MappingException( "Could not parse version unsaved-value: " + versionUnsavedValue );
-		}
-		
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/UnsavedValueFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,138 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+
+import org.hibernate.InstantiationException;
+import org.hibernate.MappingException;
+import org.hibernate.property.Getter;
+import org.hibernate.type.IdentifierType;
+import org.hibernate.type.PrimitiveType;
+import org.hibernate.type.Type;
+import org.hibernate.type.VersionType;
+
+/**
+ * @author Gavin King
+ */
+public class UnsavedValueFactory {
+	
+	private static Object instantiate(Constructor constructor) {
+		try {
+			return constructor.newInstance(null);
+		}
+		catch (Exception e) {
+			throw new InstantiationException( "could not instantiate test object", constructor.getDeclaringClass(), e );
+		}
+	}
+	
+	/**
+	 * Return an IdentifierValue for the specified unsaved-value. If none is specified, 
+	 * guess the unsaved value by instantiating a test instance of the class and
+	 * reading it's id property, or if that is not possible, using the java default
+	 * value for the type 
+	 */
+	public static IdentifierValue getUnsavedIdentifierValue(
+			String unsavedValue, 
+			Getter identifierGetter,
+			Type identifierType,
+			Constructor constructor) {
+		
+		if ( unsavedValue == null ) {
+			if ( identifierGetter!=null && constructor!=null ) {
+				// use the id value of a newly instantiated instance as the unsaved-value
+				Serializable defaultValue = (Serializable) identifierGetter.get( instantiate(constructor) );
+				return new IdentifierValue( defaultValue );
+			}
+			else if ( identifierGetter != null && (identifierType instanceof PrimitiveType) ) {
+				Serializable defaultValue = ( ( PrimitiveType ) identifierType ).getDefaultValue();
+				return new IdentifierValue( defaultValue );
+			}
+			else {
+				return IdentifierValue.NULL;
+			}
+		}
+		else if ( "null".equals( unsavedValue ) ) {
+			return IdentifierValue.NULL;
+		}
+		else if ( "undefined".equals( unsavedValue ) ) {
+			return IdentifierValue.UNDEFINED;
+		}
+		else if ( "none".equals( unsavedValue ) ) {
+			return IdentifierValue.NONE;
+		}
+		else if ( "any".equals( unsavedValue ) ) {
+			return IdentifierValue.ANY;
+		}
+		else {
+			try {
+				return new IdentifierValue( ( Serializable ) ( ( IdentifierType ) identifierType ).stringToObject( unsavedValue ) );
+			}
+			catch ( ClassCastException cce ) {
+				throw new MappingException( "Bad identifier type: " + identifierType.getName() );
+			}
+			catch ( Exception e ) {
+				throw new MappingException( "Could not parse identifier unsaved-value: " + unsavedValue );
+			}
+		}
+	}
+
+	public static VersionValue getUnsavedVersionValue(
+			String versionUnsavedValue, 
+			Getter versionGetter,
+			VersionType versionType,
+			Constructor constructor) {
+		
+		if ( versionUnsavedValue == null ) {
+			if ( constructor!=null ) {
+				Object defaultValue = versionGetter.get( instantiate(constructor) );
+				// if the version of a newly instantiated object is not the same
+				// as the version seed value, use that as the unsaved-value
+				return versionType.isEqual( versionType.seed( null ), defaultValue ) ?
+						VersionValue.UNDEFINED :
+						new VersionValue( defaultValue );
+			}
+			else {
+				return VersionValue.UNDEFINED;
+			}
+		}
+		else if ( "undefined".equals( versionUnsavedValue ) ) {
+			return VersionValue.UNDEFINED;
+		}
+		else if ( "null".equals( versionUnsavedValue ) ) {
+			return VersionValue.NULL;
+		}
+		else if ( "negative".equals( versionUnsavedValue ) ) {
+			return VersionValue.NEGATIVE;
+		}
+		else {
+			// this should not happen since the DTD prevents it
+			throw new MappingException( "Could not parse version unsaved-value: " + versionUnsavedValue );
+		}
+		
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/ValueInclusion.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-package org.hibernate.engine;
-
-import java.io.Serializable;
-import java.io.ObjectStreamException;
-import java.io.StreamCorruptedException;
-
-/**
- * An enum of the different ways a value might be "included".
- * <p/>
- * This is really an expanded true/false notion with "PARTIAL" being the
- * expansion.  PARTIAL deals with components in the cases where
- * parts of the referenced component might define inclusion, but the
- * component overall does not.
- *
- * @author Steve Ebersole
- */
-public class ValueInclusion implements Serializable {
-
-	public static final ValueInclusion NONE = new ValueInclusion( "none" );
-	public static final ValueInclusion FULL = new ValueInclusion( "full" );
-	public static final ValueInclusion PARTIAL = new ValueInclusion( "partial" );
-
-	private final String name;
-
-	public ValueInclusion(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String toString() {
-		return "ValueInclusion[" + name + "]";
-	}
-
-	private Object readResolve() throws ObjectStreamException {
-		if ( name.equals( NONE.name ) ) {
-			return NONE;
-		}
-		else if ( name.equals( FULL.name ) ) {
-			return FULL;
-		}
-		else if ( name.equals( PARTIAL.name ) ) {
-			return PARTIAL;
-		}
-		else {
-			throw new StreamCorruptedException( "unrecognized value inclusion [" + name + "]" );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/ValueInclusion.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/ValueInclusion.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.engine;
+
+import java.io.Serializable;
+import java.io.ObjectStreamException;
+import java.io.StreamCorruptedException;
+
+/**
+ * An enum of the different ways a value might be "included".
+ * <p/>
+ * This is really an expanded true/false notion with "PARTIAL" being the
+ * expansion.  PARTIAL deals with components in the cases where
+ * parts of the referenced component might define inclusion, but the
+ * component overall does not.
+ *
+ * @author Steve Ebersole
+ */
+public class ValueInclusion implements Serializable {
+
+	public static final ValueInclusion NONE = new ValueInclusion( "none" );
+	public static final ValueInclusion FULL = new ValueInclusion( "full" );
+	public static final ValueInclusion PARTIAL = new ValueInclusion( "partial" );
+
+	private final String name;
+
+	public ValueInclusion(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String toString() {
+		return "ValueInclusion[" + name + "]";
+	}
+
+	private Object readResolve() throws ObjectStreamException {
+		if ( name.equals( NONE.name ) ) {
+			return NONE;
+		}
+		else if ( name.equals( FULL.name ) ) {
+			return FULL;
+		}
+		else if ( name.equals( PARTIAL.name ) ) {
+			return PARTIAL;
+		}
+		else {
+			throw new StreamCorruptedException( "unrecognized value inclusion [" + name + "]" );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,109 +0,0 @@
-//$Id: VersionValue.java 7017 2005-06-05 04:31:34Z oneovthafew $
-package org.hibernate.engine;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.id.IdentifierGeneratorFactory;
-
-/**
- * A strategy for determining if a version value is an version of
- * a new transient instance or a previously persistent transient instance.
- * The strategy is determined by the <tt>unsaved-value</tt> attribute in
- * the mapping file.
- * 
- * @author Gavin King
- */
-public class VersionValue {
-
-	private static final Logger log = LoggerFactory.getLogger(VersionValue.class);
-
-	private final Object value;
-	/**
-	 * Assume the transient instance is newly instantiated if the version
-	 * is null, otherwise assume it is a detached instance.
-	 */
-	public static final VersionValue NULL = new VersionValue() {
-		public final Boolean isUnsaved(Object version) {
-			log.trace("version unsaved-value strategy NULL");
-			return version==null ? Boolean.TRUE : Boolean.FALSE;
-		}
-		public Object getDefaultValue(Object currentValue) {
-			return null;
-		}
-		public String toString() {
-			return "VERSION_SAVE_NULL";
-		}
-	};
-	/**
-	 * Assume the transient instance is newly instantiated if the version
-	 * is null, otherwise defer to the identifier unsaved-value.
-	 */
-	public static final VersionValue UNDEFINED = new VersionValue() {
-		public final Boolean isUnsaved(Object version) {
-			log.trace("version unsaved-value strategy UNDEFINED");
-			return version==null ? Boolean.TRUE : null;
-		}
-		public Object getDefaultValue(Object currentValue) {
-			return currentValue;
-		}
-		public String toString() {
-			return "VERSION_UNDEFINED";
-		}
-	};
-	/**
-	 * Assume the transient instance is newly instantiated if the version
-	 * is negative, otherwise assume it is a detached instance.
-	 */
-	public static final VersionValue NEGATIVE = new VersionValue() {
-	
-		public final Boolean isUnsaved(Object version) throws MappingException {
-			log.trace("version unsaved-value strategy NEGATIVE");
-			if (version==null) return Boolean.TRUE;
-			if (version instanceof Number) {
-				return ( (Number) version ).longValue() < 0l ? Boolean.TRUE : Boolean.FALSE;
-			}
-			else {
-				throw new MappingException("unsaved-value NEGATIVE may only be used with short, int and long types");
-			}
-		}
-		public Object getDefaultValue(Object currentValue) {
-			return IdentifierGeneratorFactory.createNumber( -1l, currentValue.getClass() );
-		}
-		public String toString() {
-			return "VERSION_NEGATIVE";
-		}
-	};
-	
-	protected VersionValue() {
-		this.value = null;
-	}
-
-	/**
-	 * Assume the transient instance is newly instantiated if
-	 * its version is null or equal to <tt>value</tt>
-	 * @param value value to compare to
-	 */
-	public VersionValue(Object value) {
-		this.value = value;
-	}
-	
-	/**
-	 * Does the given version belong to a new instance?
-	 *
-	 * @param version version to check
-	 * @return true is unsaved, false is saved, null is undefined
-	 */
-	public Boolean isUnsaved(Object version) throws MappingException  {
-		if ( log.isTraceEnabled() ) log.trace("version unsaved-value: " + value);
-		return version==null || version.equals(value) ? Boolean.TRUE : Boolean.FALSE;
-	}
-	
-	public Object getDefaultValue(Object currentValue) {
-		return value;
-	}
-	
-	public String toString() {
-		return "version unsaved-value: " + value;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/VersionValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/VersionValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,132 @@
+/*
+ * 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.engine;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.id.IdentifierGeneratorFactory;
+
+/**
+ * A strategy for determining if a version value is an version of
+ * a new transient instance or a previously persistent transient instance.
+ * The strategy is determined by the <tt>unsaved-value</tt> attribute in
+ * the mapping file.
+ * 
+ * @author Gavin King
+ */
+public class VersionValue {
+
+	private static final Logger log = LoggerFactory.getLogger(VersionValue.class);
+
+	private final Object value;
+	/**
+	 * Assume the transient instance is newly instantiated if the version
+	 * is null, otherwise assume it is a detached instance.
+	 */
+	public static final VersionValue NULL = new VersionValue() {
+		public final Boolean isUnsaved(Object version) {
+			log.trace("version unsaved-value strategy NULL");
+			return version==null ? Boolean.TRUE : Boolean.FALSE;
+		}
+		public Object getDefaultValue(Object currentValue) {
+			return null;
+		}
+		public String toString() {
+			return "VERSION_SAVE_NULL";
+		}
+	};
+	/**
+	 * Assume the transient instance is newly instantiated if the version
+	 * is null, otherwise defer to the identifier unsaved-value.
+	 */
+	public static final VersionValue UNDEFINED = new VersionValue() {
+		public final Boolean isUnsaved(Object version) {
+			log.trace("version unsaved-value strategy UNDEFINED");
+			return version==null ? Boolean.TRUE : null;
+		}
+		public Object getDefaultValue(Object currentValue) {
+			return currentValue;
+		}
+		public String toString() {
+			return "VERSION_UNDEFINED";
+		}
+	};
+	/**
+	 * Assume the transient instance is newly instantiated if the version
+	 * is negative, otherwise assume it is a detached instance.
+	 */
+	public static final VersionValue NEGATIVE = new VersionValue() {
+	
+		public final Boolean isUnsaved(Object version) throws MappingException {
+			log.trace("version unsaved-value strategy NEGATIVE");
+			if (version==null) return Boolean.TRUE;
+			if (version instanceof Number) {
+				return ( (Number) version ).longValue() < 0l ? Boolean.TRUE : Boolean.FALSE;
+			}
+			else {
+				throw new MappingException("unsaved-value NEGATIVE may only be used with short, int and long types");
+			}
+		}
+		public Object getDefaultValue(Object currentValue) {
+			return IdentifierGeneratorFactory.createNumber( -1l, currentValue.getClass() );
+		}
+		public String toString() {
+			return "VERSION_NEGATIVE";
+		}
+	};
+	
+	protected VersionValue() {
+		this.value = null;
+	}
+
+	/**
+	 * Assume the transient instance is newly instantiated if
+	 * its version is null or equal to <tt>value</tt>
+	 * @param value value to compare to
+	 */
+	public VersionValue(Object value) {
+		this.value = value;
+	}
+	
+	/**
+	 * Does the given version belong to a new instance?
+	 *
+	 * @param version version to check
+	 * @return true is unsaved, false is saved, null is undefined
+	 */
+	public Boolean isUnsaved(Object version) throws MappingException  {
+		if ( log.isTraceEnabled() ) log.trace("version unsaved-value: " + value);
+		return version==null || version.equals(value) ? Boolean.TRUE : Boolean.FALSE;
+	}
+	
+	public Object getDefaultValue(Object currentValue) {
+		return value;
+	}
+	
+	public String toString() {
+		return "version unsaved-value: " + value;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/Versioning.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,172 +0,0 @@
-//$Id: Versioning.java 10857 2006-11-21 23:28:07Z steve.ebersole at jboss.com $
-package org.hibernate.engine;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.VersionType;
-
-/**
- * Utilities for dealing with optimisitic locking values.
- *
- * @author Gavin King
- */
-public final class Versioning {
-	/**
-	 * Apply no optimistic locking
-	 */
-	public static final int OPTIMISTIC_LOCK_NONE = -1;
-
-	/**
-	 * Apply optimisitc locking based on the defined version or timestamp
-	 * property.
-	 */
-	public static final int OPTIMISTIC_LOCK_VERSION = 0;
-
-	/**
-	 * Apply optimisitc locking based on the a current vs. snapshot comparison
-	 * of <b>all</b> properties.
-	 */
-	public static final int OPTIMISTIC_LOCK_ALL = 2;
-
-	/**
-	 * Apply optimisitc locking based on the a current vs. snapshot comparison
-	 * of <b>dirty</b> properties.
-	 */
-	public static final int OPTIMISTIC_LOCK_DIRTY = 1;
-
-	private static final Logger log = LoggerFactory.getLogger( Versioning.class );
-
-	/**
-	 * Private constructor disallowing instantiation.
-	 */
-	private Versioning() {}
-
-	/**
-	 * Create an initial optimisitc locking value according the {@link VersionType}
-	 * contract for the version property.
-	 *
-	 * @param versionType The version type.
-	 * @param session The originating session
-	 * @return The initial optimisitc locking value
-	 */
-	private static Object seed(VersionType versionType, SessionImplementor session) {
-		Object seed = versionType.seed( session );
-		if ( log.isTraceEnabled() ) log.trace("Seeding: " + seed);
-		return seed;
-	}
-
-	/**
-	 * Create an initial optimisitc locking value according the {@link VersionType}
-	 * contract for the version property <b>if required</b> and inject it into
-	 * the snapshot state.
-	 *
-	 * @param fields The current snapshot state
-	 * @param versionProperty The index of the version property
-	 * @param versionType The version type
-	 * @param session The orginating session
-	 * @return True if we injected a new version value into the fields array; false
-	 * otherwise.
-	 */
-	public static boolean seedVersion(
-	        Object[] fields,
-	        int versionProperty,
-	        VersionType versionType,
-	        SessionImplementor session) {
-		Object initialVersion = fields[versionProperty];
-		if (
-			initialVersion==null ||
-			// This next bit is to allow for both unsaved-value="negative"
-			// and for "older" behavior where version number did not get
-			// seeded if it was already set in the object
-			// TODO: shift it into unsaved-value strategy
-			( (initialVersion instanceof Number) && ( (Number) initialVersion ).longValue()<0 )
-		) {
-			fields[versionProperty] = seed( versionType, session );
-			return true;
-		}
-		else {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "using initial version: " + initialVersion );
-			}
-			return false;
-		}
-	}
-
-
-	/**
-	 * Generate the next increment in the optimisitc locking value according
-	 * the {@link VersionType} contract for the version property.
-	 *
-	 * @param version The current version
-	 * @param versionType The version type
-	 * @param session The originating session
-	 * @return The incremented optimistic locking value.
-	 */
-	public static Object increment(Object version, VersionType versionType, SessionImplementor session) {
-		Object next = versionType.next( version, session );
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"Incrementing: " +
-					versionType.toLoggableString( version, session.getFactory() ) +
-					" to " +
-					versionType.toLoggableString( next, session.getFactory() )
-			);
-		}
-		return next;
-	}
-
-	/**
-	 * Inject the optimisitc locking value into the entity state snapshot.
-	 *
-	 * @param fields The state snapshot
-	 * @param version The optimisitc locking value
-	 * @param persister The entity persister
-	 */
-	public static void setVersion(Object[] fields, Object version, EntityPersister persister) {
-		if ( !persister.isVersioned() ) {
-			return;
-		}
-		fields[ persister.getVersionProperty() ] = version;
-	}
-
-	/**
-	 * Extract the optimisitc locking value out of the entity state snapshot.
-	 *
-	 * @param fields The state snapshot
-	 * @param persister The entity persister
-	 * @return The extracted optimisitc locking value
-	 */
-	public static Object getVersion(Object[] fields, EntityPersister persister) {
-		if ( !persister.isVersioned() ) {
-			return null;
-		}
-		return fields[ persister.getVersionProperty() ];
-	}
-
-	/**
-	 * Do we need to increment the version number, given the dirty properties?
-	 *
-	 * @param dirtyProperties The array of property indexes which were deemed dirty
-	 * @param hasDirtyCollections Were any collections found to be dirty (structurally changed)
-	 * @param propertyVersionability An array indicating versionability of each property.
-	 * @return True if a version increment is required; false otherwise.
-	 */
-	public static boolean isVersionIncrementRequired(
-			final int[] dirtyProperties,
-			final boolean hasDirtyCollections,
-			final boolean[] propertyVersionability) {
-		if ( hasDirtyCollections ) {
-			return true;
-		}
-		for ( int i = 0; i < dirtyProperties.length; i++ ) {
-			if ( propertyVersionability[ dirtyProperties[i] ] ) {
-				return true;
-			}
-		}
-	    return false;
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/Versioning.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/Versioning.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,195 @@
+/*
+ * 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.engine;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.VersionType;
+
+/**
+ * Utilities for dealing with optimisitic locking values.
+ *
+ * @author Gavin King
+ */
+public final class Versioning {
+	/**
+	 * Apply no optimistic locking
+	 */
+	public static final int OPTIMISTIC_LOCK_NONE = -1;
+
+	/**
+	 * Apply optimisitc locking based on the defined version or timestamp
+	 * property.
+	 */
+	public static final int OPTIMISTIC_LOCK_VERSION = 0;
+
+	/**
+	 * Apply optimisitc locking based on the a current vs. snapshot comparison
+	 * of <b>all</b> properties.
+	 */
+	public static final int OPTIMISTIC_LOCK_ALL = 2;
+
+	/**
+	 * Apply optimisitc locking based on the a current vs. snapshot comparison
+	 * of <b>dirty</b> properties.
+	 */
+	public static final int OPTIMISTIC_LOCK_DIRTY = 1;
+
+	private static final Logger log = LoggerFactory.getLogger( Versioning.class );
+
+	/**
+	 * Private constructor disallowing instantiation.
+	 */
+	private Versioning() {}
+
+	/**
+	 * Create an initial optimisitc locking value according the {@link VersionType}
+	 * contract for the version property.
+	 *
+	 * @param versionType The version type.
+	 * @param session The originating session
+	 * @return The initial optimisitc locking value
+	 */
+	private static Object seed(VersionType versionType, SessionImplementor session) {
+		Object seed = versionType.seed( session );
+		if ( log.isTraceEnabled() ) log.trace("Seeding: " + seed);
+		return seed;
+	}
+
+	/**
+	 * Create an initial optimisitc locking value according the {@link VersionType}
+	 * contract for the version property <b>if required</b> and inject it into
+	 * the snapshot state.
+	 *
+	 * @param fields The current snapshot state
+	 * @param versionProperty The index of the version property
+	 * @param versionType The version type
+	 * @param session The orginating session
+	 * @return True if we injected a new version value into the fields array; false
+	 * otherwise.
+	 */
+	public static boolean seedVersion(
+	        Object[] fields,
+	        int versionProperty,
+	        VersionType versionType,
+	        SessionImplementor session) {
+		Object initialVersion = fields[versionProperty];
+		if (
+			initialVersion==null ||
+			// This next bit is to allow for both unsaved-value="negative"
+			// and for "older" behavior where version number did not get
+			// seeded if it was already set in the object
+			// TODO: shift it into unsaved-value strategy
+			( (initialVersion instanceof Number) && ( (Number) initialVersion ).longValue()<0 )
+		) {
+			fields[versionProperty] = seed( versionType, session );
+			return true;
+		}
+		else {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "using initial version: " + initialVersion );
+			}
+			return false;
+		}
+	}
+
+
+	/**
+	 * Generate the next increment in the optimisitc locking value according
+	 * the {@link VersionType} contract for the version property.
+	 *
+	 * @param version The current version
+	 * @param versionType The version type
+	 * @param session The originating session
+	 * @return The incremented optimistic locking value.
+	 */
+	public static Object increment(Object version, VersionType versionType, SessionImplementor session) {
+		Object next = versionType.next( version, session );
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"Incrementing: " +
+					versionType.toLoggableString( version, session.getFactory() ) +
+					" to " +
+					versionType.toLoggableString( next, session.getFactory() )
+			);
+		}
+		return next;
+	}
+
+	/**
+	 * Inject the optimisitc locking value into the entity state snapshot.
+	 *
+	 * @param fields The state snapshot
+	 * @param version The optimisitc locking value
+	 * @param persister The entity persister
+	 */
+	public static void setVersion(Object[] fields, Object version, EntityPersister persister) {
+		if ( !persister.isVersioned() ) {
+			return;
+		}
+		fields[ persister.getVersionProperty() ] = version;
+	}
+
+	/**
+	 * Extract the optimisitc locking value out of the entity state snapshot.
+	 *
+	 * @param fields The state snapshot
+	 * @param persister The entity persister
+	 * @return The extracted optimisitc locking value
+	 */
+	public static Object getVersion(Object[] fields, EntityPersister persister) {
+		if ( !persister.isVersioned() ) {
+			return null;
+		}
+		return fields[ persister.getVersionProperty() ];
+	}
+
+	/**
+	 * Do we need to increment the version number, given the dirty properties?
+	 *
+	 * @param dirtyProperties The array of property indexes which were deemed dirty
+	 * @param hasDirtyCollections Were any collections found to be dirty (structurally changed)
+	 * @param propertyVersionability An array indicating versionability of each property.
+	 * @return True if a version increment is required; false otherwise.
+	 */
+	public static boolean isVersionIncrementRequired(
+			final int[] dirtyProperties,
+			final boolean hasDirtyCollections,
+			final boolean[] propertyVersionability) {
+		if ( hasDirtyCollections ) {
+			return true;
+		}
+		for ( int i = 0; i < dirtyProperties.length; i++ ) {
+			if ( propertyVersionability[ dirtyProperties[i] ] ) {
+				return true;
+			}
+		}
+	    return false;
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,334 +0,0 @@
-package org.hibernate.engine.loading;
-
-import java.sql.ResultSet;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Iterator;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.HashSet;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.EntityMode;
-import org.hibernate.CacheMode;
-import org.hibernate.cache.entry.CollectionCacheEntry;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.engine.CollectionKey;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Represents state associated with the processing of a given {@link ResultSet}
- * in regards to loading collections.
- * <p/>
- * Another implementation option to consider is to not expose {@link ResultSet}s
- * directly (in the JDBC redesign) but to always "wrap" them and apply a
- * [series of] context[s] to that wrapper.
- *
- * @author Steve Ebersole
- */
-public class CollectionLoadContext {
-	private static final Logger log = LoggerFactory.getLogger( CollectionLoadContext.class );
-
-	private final LoadContexts loadContexts;
-	private final ResultSet resultSet;
-	private Set localLoadingCollectionKeys = new HashSet();
-
-	/**
-	 * Creates a collection load context for the given result set.
-	 *
-	 * @param loadContexts Callback to other collection load contexts.
-	 * @param resultSet The result set this is "wrapping".
-	 */
-	public CollectionLoadContext(LoadContexts loadContexts, ResultSet resultSet) {
-		this.loadContexts = loadContexts;
-		this.resultSet = resultSet;
-	}
-
-	public ResultSet getResultSet() {
-		return resultSet;
-	}
-
-	public LoadContexts getLoadContext() {
-		return loadContexts;
-	}
-
-	/**
-	 * Retrieve the collection that is being loaded as part of processing this
-	 * result set.
-	 * <p/>
-	 * Basically, there are two valid return values from this method:<ul>
-	 * <li>an instance of {@link PersistentCollection} which indicates to
-	 * continue loading the result set row data into that returned collection
-	 * instance; this may be either an instance already associated and in the
-	 * midst of being loaded, or a newly instantiated instance as a matching
-	 * associated collection was not found.</li>
-	 * <li><i>null</i> indicates to ignore the corresponding result set row
-	 * data relating to the requested collection; this indicates that either
-	 * the collection was found to already be associated with the persistence
-	 * context in a fully loaded state, or it was found in a loading state
-	 * associated with another result set processing context.</li>
-	 * </ul>
-	 *
-	 * @param persister The persister for the collection being requested.
-	 * @param key The key of the collection being requested.
-	 *
-	 * @return The loading collection (see discussion above).
-	 */
-	public PersistentCollection getLoadingCollection(final CollectionPersister persister, final Serializable key) {
-		final EntityMode em = loadContexts.getPersistenceContext().getSession().getEntityMode();
-		final CollectionKey collectionKey = new CollectionKey( persister, key, em );
-		if ( log.isTraceEnabled() ) {
-			log.trace( "starting attempt to find loading collection [" + MessageHelper.collectionInfoString( persister.getRole(), key ) + "]" );
-		}
-		final LoadingCollectionEntry loadingCollectionEntry = loadContexts.locateLoadingCollectionEntry( collectionKey );
-		if ( loadingCollectionEntry == null ) {
-			// look for existing collection as part of the persistence context
-			PersistentCollection collection = loadContexts.getPersistenceContext().getCollection( collectionKey );
-			if ( collection != null ) {
-				if ( collection.wasInitialized() ) {
-					log.trace( "collection already initialized; ignoring" );
-					return null; // ignore this row of results! Note the early exit
-				}
-				else {
-					// initialize this collection
-					log.trace( "collection not yet initialized; initializing" );
-				}
-			}
-			else {
-				Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister );
-				final boolean newlySavedEntity = owner != null
-						&& loadContexts.getPersistenceContext().getEntry( owner ).getStatus() != Status.LOADING
-						&& em != EntityMode.DOM4J;
-				if ( newlySavedEntity ) {
-					// important, to account for newly saved entities in query
-					// todo : some kind of check for new status...
-					log.trace( "owning entity already loaded; ignoring" );
-					return null;
-				}
-				else {
-					// create one
-					if ( log.isTraceEnabled() ) {
-						log.trace( "instantiating new collection [key=" + key + ", rs=" + resultSet + "]" );
-					}
-					collection = persister.getCollectionType()
-							.instantiate( loadContexts.getPersistenceContext().getSession(), persister, key );
-				}
-			}
-			collection.beforeInitialize( persister, -1 );
-			collection.beginRead();
-			localLoadingCollectionKeys.add( collectionKey );
-			loadContexts.registerLoadingCollectionXRef( collectionKey, new LoadingCollectionEntry( resultSet, persister, key, collection ) );
-			return collection;
-		}
-		else {
-			if ( loadingCollectionEntry.getResultSet() == resultSet ) {
-				log.trace( "found loading collection bound to current result set processing; reading row" );
-				return loadingCollectionEntry.getCollection();
-			}
-			else {
-				// ignore this row, the collection is in process of
-				// being loaded somewhere further "up" the stack
-				log.trace( "collection is already being initialized; ignoring row" );
-				return null;
-			}
-		}
-	}
-
-	/**
-	 * Finish the process of collection-loading for this bound result set.  Mainly this
-	 * involves cleaning up resources and notifying the collections that loading is
-	 * complete.
-	 *
-	 * @param persister The persister for which to complete loading.
-	 */
-	public void endLoadingCollections(CollectionPersister persister) {
-		SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
-		if ( !loadContexts.hasLoadingCollectionEntries()
-				&& localLoadingCollectionKeys.isEmpty() ) {
-			return;
-		}
-
-		// in an effort to avoid concurrent-modification-exceptions (from
-		// potential recursive calls back through here as a result of the
-		// eventual call to PersistentCollection#endRead), we scan the
-		// internal loadingCollections map for matches and store those matches
-		// in a temp collection.  the temp collection is then used to "drive"
-		// the #endRead processing.
-		List matches = null;
-		Iterator iter = localLoadingCollectionKeys.iterator();
-		while ( iter.hasNext() ) {
-			final CollectionKey collectionKey = (CollectionKey) iter.next();
-			final LoadingCollectionEntry lce = loadContexts.locateLoadingCollectionEntry( collectionKey );
-			if ( lce == null) {
-				log.warn( "In CollectionLoadContext#endLoadingCollections, localLoadingCollectionKeys contained [" + collectionKey + "], but no LoadingCollectionEntry was found in loadContexts" );
-			}
-			else if ( lce.getResultSet() == resultSet && lce.getPersister() == persister ) {
-				if ( matches == null ) {
-					matches = new ArrayList();
-				}
-				matches.add( lce );
-				if ( lce.getCollection().getOwner() == null ) {
-					session.getPersistenceContext().addUnownedCollection(
-							new CollectionKey( persister, lce.getKey(), session.getEntityMode() ),
-							lce.getCollection()
-					);
-				}
-				if ( log.isTraceEnabled() ) {
-					log.trace( "removing collection load entry [" + lce + "]" );
-				}
-
-				// todo : i'd much rather have this done from #endLoadingCollection(CollectionPersister,LoadingCollectionEntry)...
-				loadContexts.unregisterLoadingCollectionXRef( collectionKey );
-				iter.remove();
-			}
-		}
-
-		endLoadingCollections( persister, matches );
-		if ( localLoadingCollectionKeys.isEmpty() ) {
-			// todo : hack!!!
-			// NOTE : here we cleanup the load context when we have no more local
-			// LCE entries.  This "works" for the time being because really
-			// only the collection load contexts are implemented.  Long term,
-			// this cleanup should become part of the "close result set"
-			// processing from the (sandbox/jdbc) jdbc-container code.
-			loadContexts.cleanup( resultSet );
-		}
-	}
-
-	private void endLoadingCollections(CollectionPersister persister, List matchedCollectionEntries) {
-		if ( matchedCollectionEntries == null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "no collections were found in result set for role: " + persister.getRole() );
-			}
-			return;
-		}
-
-		final int count = matchedCollectionEntries.size();
-		if ( log.isDebugEnabled() ) {
-			log.debug( count + " collections were found in result set for role: " + persister.getRole() );
-		}
-
-		for ( int i = 0; i < count; i++ ) {
-			LoadingCollectionEntry lce = ( LoadingCollectionEntry ) matchedCollectionEntries.get( i );
-			endLoadingCollection( lce, persister );
-		}
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( count + " collections initialized for role: " + persister.getRole() );
-		}
-	}
-
-	private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) {
-		if ( log.isTraceEnabled() ) {
-			log.debug( "ending loading collection [" + lce + "]" );
-		}
-		final SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
-		final EntityMode em = session.getEntityMode();
-
-		boolean hasNoQueuedAdds = lce.getCollection().endRead(); // warning: can cause a recursive calls! (proxy initialization)
-
-		if ( persister.getCollectionType().hasHolder( em ) ) {
-			getLoadContext().getPersistenceContext().addCollectionHolder( lce.getCollection() );
-		}
-
-		CollectionEntry ce = getLoadContext().getPersistenceContext().getCollectionEntry( lce.getCollection() );
-		if ( ce == null ) {
-			ce = getLoadContext().getPersistenceContext().addInitializedCollection( persister, lce.getCollection(), lce.getKey() );
-		}
-		else {
-			ce.postInitialize( lce.getCollection() );
-		}
-
-		boolean addToCache = hasNoQueuedAdds && // there were no queued additions
-				persister.hasCache() &&             // and the role has a cache
-				session.getCacheMode().isPutEnabled() &&
-				!ce.isDoremove();                   // and this is not a forced initialization during flush
-		if ( addToCache ) {
-			addCollectionToCache( lce, persister );
-		}
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "collection fully initialized: " + MessageHelper.collectionInfoString(persister, lce.getKey(), session.getFactory() ) );
-		}
-
-		if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
-			session.getFactory().getStatisticsImplementor().loadCollection( persister.getRole() );
-		}
-	}
-
-	/**
-	 * Add the collection to the second-level cache
-	 *
-	 * @param lce The entry representing the collection to add
-	 * @param persister The persister
-	 */
-	private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersister persister) {
-		final SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
-		final SessionFactoryImplementor factory = session.getFactory();
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Caching collection: " + MessageHelper.collectionInfoString( persister, lce.getKey(), factory ) );
-		}
-
-		if ( !session.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( session ) ) {
-			// some filters affecting the collection are enabled on the session, so do not do the put into the cache.
-			log.debug( "Refusing to add to cache due to enabled filters" );
-			// todo : add the notion of enabled filters to the CacheKey to differentiate filtered collections from non-filtered;
-			//      but CacheKey is currently used for both collections and entities; would ideally need to define two seperate ones;
-			//      currently this works in conjuction with the check on
-			//      DefaultInitializeCollectionEventHandler.initializeCollectionFromCache() (which makes sure to not read from
-			//      cache with enabled filters).
-			return; // EARLY EXIT!!!!!
-		}
-
-		final Object version;
-		if ( persister.isVersioned() ) {
-			final Object collectionOwner = getLoadContext().getPersistenceContext().getCollectionOwner( lce.getKey(), persister );
-			version = getLoadContext().getPersistenceContext().getEntry( collectionOwner ).getVersion();
-		}
-		else {
-			version = null;
-		}
-
-		CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister );
-		CacheKey cacheKey = new CacheKey(
-				lce.getKey(),
-				persister.getKeyType(),
-				persister.getRole(),
-				session.getEntityMode(),
-				session.getFactory()
-		);
-		boolean put = persister.getCacheAccessStrategy().putFromLoad(
-				cacheKey,
-				persister.getCacheEntryStructure().structure(entry),
-				session.getTimestamp(),
-				version,
-				factory.getSettings().isMinimalPutsEnabled() && session.getCacheMode()!= CacheMode.REFRESH
-		);
-
-		if ( put && factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
-		}
-	}
-
-	void cleanup() {
-		if ( !localLoadingCollectionKeys.isEmpty() ) {
-			log.warn( "On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [" + localLoadingCollectionKeys.size() + "] entries" );
-		}
-		loadContexts.cleanupCollectionXRefs( localLoadingCollectionKeys );
-		localLoadingCollectionKeys.clear();
-	}
-
-
-	public String toString() {
-		return super.toString() + "<rs=" + resultSet + ">";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/CollectionLoadContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,358 @@
+/*
+ * 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.engine.loading;
+
+import java.sql.ResultSet;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.EntityMode;
+import org.hibernate.CacheMode;
+import org.hibernate.cache.entry.CollectionCacheEntry;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.engine.CollectionKey;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Represents state associated with the processing of a given {@link ResultSet}
+ * in regards to loading collections.
+ * <p/>
+ * Another implementation option to consider is to not expose {@link ResultSet}s
+ * directly (in the JDBC redesign) but to always "wrap" them and apply a
+ * [series of] context[s] to that wrapper.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionLoadContext {
+	private static final Logger log = LoggerFactory.getLogger( CollectionLoadContext.class );
+
+	private final LoadContexts loadContexts;
+	private final ResultSet resultSet;
+	private Set localLoadingCollectionKeys = new HashSet();
+
+	/**
+	 * Creates a collection load context for the given result set.
+	 *
+	 * @param loadContexts Callback to other collection load contexts.
+	 * @param resultSet The result set this is "wrapping".
+	 */
+	public CollectionLoadContext(LoadContexts loadContexts, ResultSet resultSet) {
+		this.loadContexts = loadContexts;
+		this.resultSet = resultSet;
+	}
+
+	public ResultSet getResultSet() {
+		return resultSet;
+	}
+
+	public LoadContexts getLoadContext() {
+		return loadContexts;
+	}
+
+	/**
+	 * Retrieve the collection that is being loaded as part of processing this
+	 * result set.
+	 * <p/>
+	 * Basically, there are two valid return values from this method:<ul>
+	 * <li>an instance of {@link PersistentCollection} which indicates to
+	 * continue loading the result set row data into that returned collection
+	 * instance; this may be either an instance already associated and in the
+	 * midst of being loaded, or a newly instantiated instance as a matching
+	 * associated collection was not found.</li>
+	 * <li><i>null</i> indicates to ignore the corresponding result set row
+	 * data relating to the requested collection; this indicates that either
+	 * the collection was found to already be associated with the persistence
+	 * context in a fully loaded state, or it was found in a loading state
+	 * associated with another result set processing context.</li>
+	 * </ul>
+	 *
+	 * @param persister The persister for the collection being requested.
+	 * @param key The key of the collection being requested.
+	 *
+	 * @return The loading collection (see discussion above).
+	 */
+	public PersistentCollection getLoadingCollection(final CollectionPersister persister, final Serializable key) {
+		final EntityMode em = loadContexts.getPersistenceContext().getSession().getEntityMode();
+		final CollectionKey collectionKey = new CollectionKey( persister, key, em );
+		if ( log.isTraceEnabled() ) {
+			log.trace( "starting attempt to find loading collection [" + MessageHelper.collectionInfoString( persister.getRole(), key ) + "]" );
+		}
+		final LoadingCollectionEntry loadingCollectionEntry = loadContexts.locateLoadingCollectionEntry( collectionKey );
+		if ( loadingCollectionEntry == null ) {
+			// look for existing collection as part of the persistence context
+			PersistentCollection collection = loadContexts.getPersistenceContext().getCollection( collectionKey );
+			if ( collection != null ) {
+				if ( collection.wasInitialized() ) {
+					log.trace( "collection already initialized; ignoring" );
+					return null; // ignore this row of results! Note the early exit
+				}
+				else {
+					// initialize this collection
+					log.trace( "collection not yet initialized; initializing" );
+				}
+			}
+			else {
+				Object owner = loadContexts.getPersistenceContext().getCollectionOwner( key, persister );
+				final boolean newlySavedEntity = owner != null
+						&& loadContexts.getPersistenceContext().getEntry( owner ).getStatus() != Status.LOADING
+						&& em != EntityMode.DOM4J;
+				if ( newlySavedEntity ) {
+					// important, to account for newly saved entities in query
+					// todo : some kind of check for new status...
+					log.trace( "owning entity already loaded; ignoring" );
+					return null;
+				}
+				else {
+					// create one
+					if ( log.isTraceEnabled() ) {
+						log.trace( "instantiating new collection [key=" + key + ", rs=" + resultSet + "]" );
+					}
+					collection = persister.getCollectionType()
+							.instantiate( loadContexts.getPersistenceContext().getSession(), persister, key );
+				}
+			}
+			collection.beforeInitialize( persister, -1 );
+			collection.beginRead();
+			localLoadingCollectionKeys.add( collectionKey );
+			loadContexts.registerLoadingCollectionXRef( collectionKey, new LoadingCollectionEntry( resultSet, persister, key, collection ) );
+			return collection;
+		}
+		else {
+			if ( loadingCollectionEntry.getResultSet() == resultSet ) {
+				log.trace( "found loading collection bound to current result set processing; reading row" );
+				return loadingCollectionEntry.getCollection();
+			}
+			else {
+				// ignore this row, the collection is in process of
+				// being loaded somewhere further "up" the stack
+				log.trace( "collection is already being initialized; ignoring row" );
+				return null;
+			}
+		}
+	}
+
+	/**
+	 * Finish the process of collection-loading for this bound result set.  Mainly this
+	 * involves cleaning up resources and notifying the collections that loading is
+	 * complete.
+	 *
+	 * @param persister The persister for which to complete loading.
+	 */
+	public void endLoadingCollections(CollectionPersister persister) {
+		SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
+		if ( !loadContexts.hasLoadingCollectionEntries()
+				&& localLoadingCollectionKeys.isEmpty() ) {
+			return;
+		}
+
+		// in an effort to avoid concurrent-modification-exceptions (from
+		// potential recursive calls back through here as a result of the
+		// eventual call to PersistentCollection#endRead), we scan the
+		// internal loadingCollections map for matches and store those matches
+		// in a temp collection.  the temp collection is then used to "drive"
+		// the #endRead processing.
+		List matches = null;
+		Iterator iter = localLoadingCollectionKeys.iterator();
+		while ( iter.hasNext() ) {
+			final CollectionKey collectionKey = (CollectionKey) iter.next();
+			final LoadingCollectionEntry lce = loadContexts.locateLoadingCollectionEntry( collectionKey );
+			if ( lce == null) {
+				log.warn( "In CollectionLoadContext#endLoadingCollections, localLoadingCollectionKeys contained [" + collectionKey + "], but no LoadingCollectionEntry was found in loadContexts" );
+			}
+			else if ( lce.getResultSet() == resultSet && lce.getPersister() == persister ) {
+				if ( matches == null ) {
+					matches = new ArrayList();
+				}
+				matches.add( lce );
+				if ( lce.getCollection().getOwner() == null ) {
+					session.getPersistenceContext().addUnownedCollection(
+							new CollectionKey( persister, lce.getKey(), session.getEntityMode() ),
+							lce.getCollection()
+					);
+				}
+				if ( log.isTraceEnabled() ) {
+					log.trace( "removing collection load entry [" + lce + "]" );
+				}
+
+				// todo : i'd much rather have this done from #endLoadingCollection(CollectionPersister,LoadingCollectionEntry)...
+				loadContexts.unregisterLoadingCollectionXRef( collectionKey );
+				iter.remove();
+			}
+		}
+
+		endLoadingCollections( persister, matches );
+		if ( localLoadingCollectionKeys.isEmpty() ) {
+			// todo : hack!!!
+			// NOTE : here we cleanup the load context when we have no more local
+			// LCE entries.  This "works" for the time being because really
+			// only the collection load contexts are implemented.  Long term,
+			// this cleanup should become part of the "close result set"
+			// processing from the (sandbox/jdbc) jdbc-container code.
+			loadContexts.cleanup( resultSet );
+		}
+	}
+
+	private void endLoadingCollections(CollectionPersister persister, List matchedCollectionEntries) {
+		if ( matchedCollectionEntries == null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "no collections were found in result set for role: " + persister.getRole() );
+			}
+			return;
+		}
+
+		final int count = matchedCollectionEntries.size();
+		if ( log.isDebugEnabled() ) {
+			log.debug( count + " collections were found in result set for role: " + persister.getRole() );
+		}
+
+		for ( int i = 0; i < count; i++ ) {
+			LoadingCollectionEntry lce = ( LoadingCollectionEntry ) matchedCollectionEntries.get( i );
+			endLoadingCollection( lce, persister );
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( count + " collections initialized for role: " + persister.getRole() );
+		}
+	}
+
+	private void endLoadingCollection(LoadingCollectionEntry lce, CollectionPersister persister) {
+		if ( log.isTraceEnabled() ) {
+			log.debug( "ending loading collection [" + lce + "]" );
+		}
+		final SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
+		final EntityMode em = session.getEntityMode();
+
+		boolean hasNoQueuedAdds = lce.getCollection().endRead(); // warning: can cause a recursive calls! (proxy initialization)
+
+		if ( persister.getCollectionType().hasHolder( em ) ) {
+			getLoadContext().getPersistenceContext().addCollectionHolder( lce.getCollection() );
+		}
+
+		CollectionEntry ce = getLoadContext().getPersistenceContext().getCollectionEntry( lce.getCollection() );
+		if ( ce == null ) {
+			ce = getLoadContext().getPersistenceContext().addInitializedCollection( persister, lce.getCollection(), lce.getKey() );
+		}
+		else {
+			ce.postInitialize( lce.getCollection() );
+		}
+
+		boolean addToCache = hasNoQueuedAdds && // there were no queued additions
+				persister.hasCache() &&             // and the role has a cache
+				session.getCacheMode().isPutEnabled() &&
+				!ce.isDoremove();                   // and this is not a forced initialization during flush
+		if ( addToCache ) {
+			addCollectionToCache( lce, persister );
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "collection fully initialized: " + MessageHelper.collectionInfoString(persister, lce.getKey(), session.getFactory() ) );
+		}
+
+		if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
+			session.getFactory().getStatisticsImplementor().loadCollection( persister.getRole() );
+		}
+	}
+
+	/**
+	 * Add the collection to the second-level cache
+	 *
+	 * @param lce The entry representing the collection to add
+	 * @param persister The persister
+	 */
+	private void addCollectionToCache(LoadingCollectionEntry lce, CollectionPersister persister) {
+		final SessionImplementor session = getLoadContext().getPersistenceContext().getSession();
+		final SessionFactoryImplementor factory = session.getFactory();
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Caching collection: " + MessageHelper.collectionInfoString( persister, lce.getKey(), factory ) );
+		}
+
+		if ( !session.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( session ) ) {
+			// some filters affecting the collection are enabled on the session, so do not do the put into the cache.
+			log.debug( "Refusing to add to cache due to enabled filters" );
+			// todo : add the notion of enabled filters to the CacheKey to differentiate filtered collections from non-filtered;
+			//      but CacheKey is currently used for both collections and entities; would ideally need to define two seperate ones;
+			//      currently this works in conjuction with the check on
+			//      DefaultInitializeCollectionEventHandler.initializeCollectionFromCache() (which makes sure to not read from
+			//      cache with enabled filters).
+			return; // EARLY EXIT!!!!!
+		}
+
+		final Object version;
+		if ( persister.isVersioned() ) {
+			final Object collectionOwner = getLoadContext().getPersistenceContext().getCollectionOwner( lce.getKey(), persister );
+			version = getLoadContext().getPersistenceContext().getEntry( collectionOwner ).getVersion();
+		}
+		else {
+			version = null;
+		}
+
+		CollectionCacheEntry entry = new CollectionCacheEntry( lce.getCollection(), persister );
+		CacheKey cacheKey = new CacheKey(
+				lce.getKey(),
+				persister.getKeyType(),
+				persister.getRole(),
+				session.getEntityMode(),
+				session.getFactory()
+		);
+		boolean put = persister.getCacheAccessStrategy().putFromLoad(
+				cacheKey,
+				persister.getCacheEntryStructure().structure(entry),
+				session.getTimestamp(),
+				version,
+				factory.getSettings().isMinimalPutsEnabled() && session.getCacheMode()!= CacheMode.REFRESH
+		);
+
+		if ( put && factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().secondLevelCachePut( persister.getCacheAccessStrategy().getRegion().getName() );
+		}
+	}
+
+	void cleanup() {
+		if ( !localLoadingCollectionKeys.isEmpty() ) {
+			log.warn( "On CollectionLoadContext#cleanup, localLoadingCollectionKeys contained [" + localLoadingCollectionKeys.size() + "] entries" );
+		}
+		loadContexts.cleanupCollectionXRefs( localLoadingCollectionKeys );
+		localLoadingCollectionKeys.clear();
+	}
+
+
+	public String toString() {
+		return super.toString() + "<rs=" + resultSet + ">";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-package org.hibernate.engine.loading;
-
-import java.sql.ResultSet;
-import java.util.List;
-import java.util.ArrayList;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class EntityLoadContext {
-	private static final Logger log = LoggerFactory.getLogger( EntityLoadContext.class );
-
-	private final LoadContexts loadContexts;
-	private final ResultSet resultSet;
-	private final List hydratingEntities = new ArrayList( 20 ); // todo : need map? the prob is a proper key, right?
-
-	public EntityLoadContext(LoadContexts loadContexts, ResultSet resultSet) {
-		this.loadContexts = loadContexts;
-		this.resultSet = resultSet;
-	}
-
-	void cleanup() {
-		if ( !hydratingEntities.isEmpty() ) {
-			log.warn( "On EntityLoadContext#clear, hydratingEntities contained [" + hydratingEntities.size() + "] entries" );
-		}
-		hydratingEntities.clear();
-	}
-
-
-	public String toString() {
-		return super.toString() + "<rs=" + resultSet + ">";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/EntityLoadContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.engine.loading;
+
+import java.sql.ResultSet;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class EntityLoadContext {
+	private static final Logger log = LoggerFactory.getLogger( EntityLoadContext.class );
+
+	private final LoadContexts loadContexts;
+	private final ResultSet resultSet;
+	private final List hydratingEntities = new ArrayList( 20 ); // todo : need map? the prob is a proper key, right?
+
+	public EntityLoadContext(LoadContexts loadContexts, ResultSet resultSet) {
+		this.loadContexts = loadContexts;
+		this.resultSet = resultSet;
+	}
+
+	void cleanup() {
+		if ( !hydratingEntities.isEmpty() ) {
+			log.warn( "On EntityLoadContext#clear, hydratingEntities contained [" + hydratingEntities.size() + "] entries" );
+		}
+		hydratingEntities.clear();
+	}
+
+
+	public String toString() {
+		return super.toString() + "<rs=" + resultSet + ">";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,307 +0,0 @@
-package org.hibernate.engine.loading;
-
-import java.sql.ResultSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
-import java.util.HashMap;
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.util.IdentityMap;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.CollectionKey;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.EntityMode;
-
-/**
- * Maps {@link ResultSet result-sets} to specific contextual data
- * related to processing that {@link ResultSet result-sets}.
- * <p/>
- * Implementation note: internally an {@link IdentityMap} is used to maintain
- * the mappings; {@link IdentityMap} was chosen because I'd rather not be
- * dependent upon potentially bad {@link ResultSet#equals} and {ResultSet#hashCode}
- * implementations.
- * <p/>
- * Considering the JDBC-redesign work, would further like this contextual info
- * not mapped seperately, but available based on the result set being processed.
- * This would also allow maintaining a single mapping as we could reliably get
- * notification of the result-set closing...
- *
- * @author Steve Ebersole
- */
-public class LoadContexts {
-	private static final Logger log = LoggerFactory.getLogger( LoadContexts.class );
-
-	private final PersistenceContext persistenceContext;
-	private Map collectionLoadContexts;
-	private Map entityLoadContexts;
-
-	private Map xrefLoadingCollectionEntries;
-
-	/**
-	 * Creates and binds this to the given persistence context.
-	 *
-	 * @param persistenceContext The persistence context to which this
-	 * will be bound.
-	 */
-	public LoadContexts(PersistenceContext persistenceContext) {
-		this.persistenceContext = persistenceContext;
-	}
-
-	/**
-	 * Retrieves the persistence context to which this is bound.
-	 *
-	 * @return The persistence context to which this is bound.
-	 */
-	public PersistenceContext getPersistenceContext() {
-		return persistenceContext;
-	}
-
-	private SessionImplementor getSession() {
-		return getPersistenceContext().getSession();
-	}
-
-	private EntityMode getEntityMode() {
-		return getSession().getEntityMode();
-	}
-
-
-	// cleanup code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
- 	/**
-	 * Release internal state associated with the given result set.
-	 * <p/>
-	 * This should be called when we are done with processing said result set,
-	 * ideally as the result set is being closed.
-	 *
-	 * @param resultSet The result set for which it is ok to release
-	 * associated resources.
-	 */
-	public void cleanup(ResultSet resultSet) {
-		if ( collectionLoadContexts != null ) {
-			CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) collectionLoadContexts.remove( resultSet );
-			collectionLoadContext.cleanup();
-		}
-		if ( entityLoadContexts != null ) {
-			EntityLoadContext entityLoadContext = ( EntityLoadContext ) entityLoadContexts.remove( resultSet );
-			entityLoadContext.cleanup();
-		}
-	}
-
-	/**
-	 * Release internal state associated with *all* result sets.
-	 * <p/>
-	 * This is intended as a "failsafe" process to make sure we get everything
-	 * cleaned up and released.
-	 */
-	public void cleanup() {
-		if ( collectionLoadContexts != null ) {
-			Iterator itr = collectionLoadContexts.values().iterator();
-			while ( itr.hasNext() ) {
-				CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) itr.next();
-				log.warn( "fail-safe cleanup (collections) : " + collectionLoadContext );
-				collectionLoadContext.cleanup();
-			}
-			collectionLoadContexts.clear();
-		}
-		if ( entityLoadContexts != null ) {
-			Iterator itr = entityLoadContexts.values().iterator();
-			while ( itr.hasNext() ) {
-				EntityLoadContext entityLoadContext = ( EntityLoadContext ) itr.next();
-				log.warn( "fail-safe cleanup (entities) : " + entityLoadContext );
-				entityLoadContext.cleanup();
-			}
-			entityLoadContexts.clear();
-		}
-	}
-
-
-	// Collection load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Do we currently have any internal entries corresponding to loading
-	 * collections?
-	 *
-	 * @return True if we currently hold state pertaining to loading collections;
-	 * false otherwise.
-	 */
-	public boolean hasLoadingCollectionEntries() {
-		return ( collectionLoadContexts != null && !collectionLoadContexts.isEmpty() );
-	}
-
-	/**
-	 * Do we currently have any registered internal entries corresponding to loading
-	 * collections?
-	 *
-	 * @return True if we currently hold state pertaining to a registered loading collections;
-	 * false otherwise.
-	 */
-	public boolean hasRegisteredLoadingCollectionEntries() {
-		return ( xrefLoadingCollectionEntries != null && !xrefLoadingCollectionEntries.isEmpty() );
-	}
-
-
-	/**
-	 * Get the {@link CollectionLoadContext} associated with the given
-	 * {@link ResultSet}, creating one if needed.
-	 *
-	 * @param resultSet The result set for which to retrieve the context.
-	 * @return The processing context.
-	 */
-	public CollectionLoadContext getCollectionLoadContext(ResultSet resultSet) {
-		CollectionLoadContext context = null;
-		if ( collectionLoadContexts == null ) {
-			collectionLoadContexts = IdentityMap.instantiate( 8 );
-		}
-		else {
-			context = ( CollectionLoadContext ) collectionLoadContexts.get( resultSet );
-		}
-		if ( context == null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "constructing collection load context for result set [" + resultSet + "]" );
-			}
-			context = new CollectionLoadContext( this, resultSet );
-			collectionLoadContexts.put( resultSet, context );
-		}
-		return context;
-	}
-
-	/**
-	 * Attempt to locate the loading collection given the owner's key.  The lookup here
-	 * occurs against all result-set contexts...
-	 *
-	 * @param persister The collection persister
-	 * @param ownerKey The owner key
-	 * @return The loading collection, or null if not found.
-	 */
-	public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) {
-		LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey, getEntityMode() ) );
-		if ( lce != null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "returning loading collection:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
-			}
-			return lce.getCollection();
-		}
-		else {
-			// todo : should really move this log statement to CollectionType, where this is used from...
-			if ( log.isTraceEnabled() ) {
-				log.trace( "creating collection wrapper:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
-			}
-			return null;
-		}
-	}
-
-	// loading collection xrefs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Register a loading collection xref.
-	 * <p/>
-	 * This xref map is used because sometimes a collection is in process of
-	 * being loaded from one result set, but needs to be accessed from the
-	 * context of another "nested" result set processing.
-	 * <p/>
-	 * Implementation note: package protected, as this is meant solely for use
-	 * by {@link CollectionLoadContext} to be able to locate collections
-	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
-	 *
-	 * @param entryKey The xref collection key
-	 * @param entry The corresponding loading collection entry
-	 */
-	void registerLoadingCollectionXRef(CollectionKey entryKey, LoadingCollectionEntry entry) {
-		if ( xrefLoadingCollectionEntries == null ) {
-			xrefLoadingCollectionEntries = new HashMap();
-		}
-		xrefLoadingCollectionEntries.put( entryKey, entry );
-	}
-
-	/**
-	 * The inverse of {@link #registerLoadingCollectionXRef}.  Here, we are done
-	 * processing the said collection entry, so we remove it from the
-	 * load context.
-	 * <p/>
-	 * The idea here is that other loading collections can now reference said
-	 * collection directly from the {@link PersistenceContext} because it
-	 * has completed its load cycle.
-	 * <p/>
-	 * Implementation note: package protected, as this is meant solely for use
-	 * by {@link CollectionLoadContext} to be able to locate collections
-	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
-	 *
-	 * @param key The key of the collection we are done processing.
-	 */
-	void unregisterLoadingCollectionXRef(CollectionKey key) {
-		if ( !hasRegisteredLoadingCollectionEntries() ) {
-			return;
-		}
-		xrefLoadingCollectionEntries.remove(key);
-	 }
-
-	/*package*/Map getLoadingCollectionXRefs() {
- 		return xrefLoadingCollectionEntries;
- 	}
-
-
-	/**
-	 * Locate the LoadingCollectionEntry within *any* of the tracked
-	 * {@link CollectionLoadContext}s.
-	 * <p/>
-	 * Implementation note: package protected, as this is meant solely for use
-	 * by {@link CollectionLoadContext} to be able to locate collections
-	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
-	 *
-	 * @param key The collection key.
-	 * @return The located entry; or null.
-	 */
-	LoadingCollectionEntry locateLoadingCollectionEntry(CollectionKey key) {
-		if ( xrefLoadingCollectionEntries == null ) {
-			return null;
-		}
-		if ( log.isTraceEnabled() ) {
-			log.trace( "attempting to locate loading collection entry [" + key + "] in any result-set context" );
-		}
-		LoadingCollectionEntry rtn = ( LoadingCollectionEntry ) xrefLoadingCollectionEntries.get( key );
-		if ( log.isTraceEnabled() ) {
-			if ( rtn == null ) {
-				log.trace( "collection [" + key + "] not located in load context" );
-			}
-			else {
-				log.trace( "collection [" + key + "] located in load context" );
-			}
-		}
-		return rtn;
-	}
-
-	/*package*/void cleanupCollectionXRefs(Set entryKeys) {
-		Iterator itr = entryKeys.iterator();
-		while ( itr.hasNext() ) {
-			final CollectionKey entryKey = ( CollectionKey ) itr.next();
-			xrefLoadingCollectionEntries.remove( entryKey );
-		}
-	}
-
-
-	// Entity load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// 	* currently, not yet used...
-
-	public EntityLoadContext getEntityLoadContext(ResultSet resultSet) {
-		EntityLoadContext context = null;
-		if ( entityLoadContexts == null ) {
-			entityLoadContexts = IdentityMap.instantiate( 8 );
-		}
-		else {
-			context = ( EntityLoadContext ) entityLoadContexts.get( resultSet );
-		}
-		if ( context == null ) {
-			context = new EntityLoadContext( this, resultSet );
-			entityLoadContexts.put( resultSet, context );
-		}
-		return context;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadContexts.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,331 @@
+/*
+ * 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.engine.loading;
+
+import java.sql.ResultSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.util.IdentityMap;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.CollectionKey;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.EntityMode;
+
+/**
+ * Maps {@link ResultSet result-sets} to specific contextual data
+ * related to processing that {@link ResultSet result-sets}.
+ * <p/>
+ * Implementation note: internally an {@link IdentityMap} is used to maintain
+ * the mappings; {@link IdentityMap} was chosen because I'd rather not be
+ * dependent upon potentially bad {@link ResultSet#equals} and {ResultSet#hashCode}
+ * implementations.
+ * <p/>
+ * Considering the JDBC-redesign work, would further like this contextual info
+ * not mapped seperately, but available based on the result set being processed.
+ * This would also allow maintaining a single mapping as we could reliably get
+ * notification of the result-set closing...
+ *
+ * @author Steve Ebersole
+ */
+public class LoadContexts {
+	private static final Logger log = LoggerFactory.getLogger( LoadContexts.class );
+
+	private final PersistenceContext persistenceContext;
+	private Map collectionLoadContexts;
+	private Map entityLoadContexts;
+
+	private Map xrefLoadingCollectionEntries;
+
+	/**
+	 * Creates and binds this to the given persistence context.
+	 *
+	 * @param persistenceContext The persistence context to which this
+	 * will be bound.
+	 */
+	public LoadContexts(PersistenceContext persistenceContext) {
+		this.persistenceContext = persistenceContext;
+	}
+
+	/**
+	 * Retrieves the persistence context to which this is bound.
+	 *
+	 * @return The persistence context to which this is bound.
+	 */
+	public PersistenceContext getPersistenceContext() {
+		return persistenceContext;
+	}
+
+	private SessionImplementor getSession() {
+		return getPersistenceContext().getSession();
+	}
+
+	private EntityMode getEntityMode() {
+		return getSession().getEntityMode();
+	}
+
+
+	// cleanup code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ 	/**
+	 * Release internal state associated with the given result set.
+	 * <p/>
+	 * This should be called when we are done with processing said result set,
+	 * ideally as the result set is being closed.
+	 *
+	 * @param resultSet The result set for which it is ok to release
+	 * associated resources.
+	 */
+	public void cleanup(ResultSet resultSet) {
+		if ( collectionLoadContexts != null ) {
+			CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) collectionLoadContexts.remove( resultSet );
+			collectionLoadContext.cleanup();
+		}
+		if ( entityLoadContexts != null ) {
+			EntityLoadContext entityLoadContext = ( EntityLoadContext ) entityLoadContexts.remove( resultSet );
+			entityLoadContext.cleanup();
+		}
+	}
+
+	/**
+	 * Release internal state associated with *all* result sets.
+	 * <p/>
+	 * This is intended as a "failsafe" process to make sure we get everything
+	 * cleaned up and released.
+	 */
+	public void cleanup() {
+		if ( collectionLoadContexts != null ) {
+			Iterator itr = collectionLoadContexts.values().iterator();
+			while ( itr.hasNext() ) {
+				CollectionLoadContext collectionLoadContext = ( CollectionLoadContext ) itr.next();
+				log.warn( "fail-safe cleanup (collections) : " + collectionLoadContext );
+				collectionLoadContext.cleanup();
+			}
+			collectionLoadContexts.clear();
+		}
+		if ( entityLoadContexts != null ) {
+			Iterator itr = entityLoadContexts.values().iterator();
+			while ( itr.hasNext() ) {
+				EntityLoadContext entityLoadContext = ( EntityLoadContext ) itr.next();
+				log.warn( "fail-safe cleanup (entities) : " + entityLoadContext );
+				entityLoadContext.cleanup();
+			}
+			entityLoadContexts.clear();
+		}
+	}
+
+
+	// Collection load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Do we currently have any internal entries corresponding to loading
+	 * collections?
+	 *
+	 * @return True if we currently hold state pertaining to loading collections;
+	 * false otherwise.
+	 */
+	public boolean hasLoadingCollectionEntries() {
+		return ( collectionLoadContexts != null && !collectionLoadContexts.isEmpty() );
+	}
+
+	/**
+	 * Do we currently have any registered internal entries corresponding to loading
+	 * collections?
+	 *
+	 * @return True if we currently hold state pertaining to a registered loading collections;
+	 * false otherwise.
+	 */
+	public boolean hasRegisteredLoadingCollectionEntries() {
+		return ( xrefLoadingCollectionEntries != null && !xrefLoadingCollectionEntries.isEmpty() );
+	}
+
+
+	/**
+	 * Get the {@link CollectionLoadContext} associated with the given
+	 * {@link ResultSet}, creating one if needed.
+	 *
+	 * @param resultSet The result set for which to retrieve the context.
+	 * @return The processing context.
+	 */
+	public CollectionLoadContext getCollectionLoadContext(ResultSet resultSet) {
+		CollectionLoadContext context = null;
+		if ( collectionLoadContexts == null ) {
+			collectionLoadContexts = IdentityMap.instantiate( 8 );
+		}
+		else {
+			context = ( CollectionLoadContext ) collectionLoadContexts.get( resultSet );
+		}
+		if ( context == null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "constructing collection load context for result set [" + resultSet + "]" );
+			}
+			context = new CollectionLoadContext( this, resultSet );
+			collectionLoadContexts.put( resultSet, context );
+		}
+		return context;
+	}
+
+	/**
+	 * Attempt to locate the loading collection given the owner's key.  The lookup here
+	 * occurs against all result-set contexts...
+	 *
+	 * @param persister The collection persister
+	 * @param ownerKey The owner key
+	 * @return The loading collection, or null if not found.
+	 */
+	public PersistentCollection locateLoadingCollection(CollectionPersister persister, Serializable ownerKey) {
+		LoadingCollectionEntry lce = locateLoadingCollectionEntry( new CollectionKey( persister, ownerKey, getEntityMode() ) );
+		if ( lce != null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "returning loading collection:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
+			}
+			return lce.getCollection();
+		}
+		else {
+			// todo : should really move this log statement to CollectionType, where this is used from...
+			if ( log.isTraceEnabled() ) {
+				log.trace( "creating collection wrapper:" + MessageHelper.collectionInfoString( persister, ownerKey, getSession().getFactory() ) );
+			}
+			return null;
+		}
+	}
+
+	// loading collection xrefs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Register a loading collection xref.
+	 * <p/>
+	 * This xref map is used because sometimes a collection is in process of
+	 * being loaded from one result set, but needs to be accessed from the
+	 * context of another "nested" result set processing.
+	 * <p/>
+	 * Implementation note: package protected, as this is meant solely for use
+	 * by {@link CollectionLoadContext} to be able to locate collections
+	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
+	 *
+	 * @param entryKey The xref collection key
+	 * @param entry The corresponding loading collection entry
+	 */
+	void registerLoadingCollectionXRef(CollectionKey entryKey, LoadingCollectionEntry entry) {
+		if ( xrefLoadingCollectionEntries == null ) {
+			xrefLoadingCollectionEntries = new HashMap();
+		}
+		xrefLoadingCollectionEntries.put( entryKey, entry );
+	}
+
+	/**
+	 * The inverse of {@link #registerLoadingCollectionXRef}.  Here, we are done
+	 * processing the said collection entry, so we remove it from the
+	 * load context.
+	 * <p/>
+	 * The idea here is that other loading collections can now reference said
+	 * collection directly from the {@link PersistenceContext} because it
+	 * has completed its load cycle.
+	 * <p/>
+	 * Implementation note: package protected, as this is meant solely for use
+	 * by {@link CollectionLoadContext} to be able to locate collections
+	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
+	 *
+	 * @param key The key of the collection we are done processing.
+	 */
+	void unregisterLoadingCollectionXRef(CollectionKey key) {
+		if ( !hasRegisteredLoadingCollectionEntries() ) {
+			return;
+		}
+		xrefLoadingCollectionEntries.remove(key);
+	 }
+
+	/*package*/Map getLoadingCollectionXRefs() {
+ 		return xrefLoadingCollectionEntries;
+ 	}
+
+
+	/**
+	 * Locate the LoadingCollectionEntry within *any* of the tracked
+	 * {@link CollectionLoadContext}s.
+	 * <p/>
+	 * Implementation note: package protected, as this is meant solely for use
+	 * by {@link CollectionLoadContext} to be able to locate collections
+	 * being loaded by other {@link CollectionLoadContext}s/{@link ResultSet}s.
+	 *
+	 * @param key The collection key.
+	 * @return The located entry; or null.
+	 */
+	LoadingCollectionEntry locateLoadingCollectionEntry(CollectionKey key) {
+		if ( xrefLoadingCollectionEntries == null ) {
+			return null;
+		}
+		if ( log.isTraceEnabled() ) {
+			log.trace( "attempting to locate loading collection entry [" + key + "] in any result-set context" );
+		}
+		LoadingCollectionEntry rtn = ( LoadingCollectionEntry ) xrefLoadingCollectionEntries.get( key );
+		if ( log.isTraceEnabled() ) {
+			if ( rtn == null ) {
+				log.trace( "collection [" + key + "] not located in load context" );
+			}
+			else {
+				log.trace( "collection [" + key + "] located in load context" );
+			}
+		}
+		return rtn;
+	}
+
+	/*package*/void cleanupCollectionXRefs(Set entryKeys) {
+		Iterator itr = entryKeys.iterator();
+		while ( itr.hasNext() ) {
+			final CollectionKey entryKey = ( CollectionKey ) itr.next();
+			xrefLoadingCollectionEntries.remove( entryKey );
+		}
+	}
+
+
+	// Entity load contexts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// 	* currently, not yet used...
+
+	public EntityLoadContext getEntityLoadContext(ResultSet resultSet) {
+		EntityLoadContext context = null;
+		if ( entityLoadContexts == null ) {
+			entityLoadContexts = IdentityMap.instantiate( 8 );
+		}
+		else {
+			context = ( EntityLoadContext ) entityLoadContexts.get( resultSet );
+		}
+		if ( context == null ) {
+			context = new EntityLoadContext( this, resultSet );
+			entityLoadContexts.put( resultSet, context );
+		}
+		return context;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-package org.hibernate.engine.loading;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * Represents a collection currently being loaded.
- *
- * @author Steve Ebersole
- */
-public class LoadingCollectionEntry {
-	private final ResultSet resultSet;
-	private final CollectionPersister persister;
-	private final Serializable key;
-	private final PersistentCollection collection;
-
-	public LoadingCollectionEntry(
-			ResultSet resultSet,
-			CollectionPersister persister,
-			Serializable key,
-			PersistentCollection collection) {
-		this.resultSet = resultSet;
-		this.persister = persister;
-		this.key = key;
-		this.collection = collection;
-	}
-
-	public ResultSet getResultSet() {
-		return resultSet;
-	}
-
-	public CollectionPersister getPersister() {
-		return persister;
-	}
-
-	public Serializable getKey() {
-		return key;
-	}
-
-	public PersistentCollection getCollection() {
-		return collection;
-	}
-
-	public String toString() {
-		return getClass().getName() + "<rs=" + resultSet + ", coll=" + MessageHelper.collectionInfoString( persister.getRole(), key ) + ">@" + Integer.toHexString( hashCode() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/loading/LoadingCollectionEntry.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.engine.loading;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * Represents a collection currently being loaded.
+ *
+ * @author Steve Ebersole
+ */
+public class LoadingCollectionEntry {
+	private final ResultSet resultSet;
+	private final CollectionPersister persister;
+	private final Serializable key;
+	private final PersistentCollection collection;
+
+	public LoadingCollectionEntry(
+			ResultSet resultSet,
+			CollectionPersister persister,
+			Serializable key,
+			PersistentCollection collection) {
+		this.resultSet = resultSet;
+		this.persister = persister;
+		this.key = key;
+		this.collection = collection;
+	}
+
+	public ResultSet getResultSet() {
+		return resultSet;
+	}
+
+	public CollectionPersister getPersister() {
+		return persister;
+	}
+
+	public Serializable getKey() {
+		return key;
+	}
+
+	public PersistentCollection getCollection() {
+		return collection;
+	}
+
+	public String toString() {
+		return getClass().getName() + "<rs=" + resultSet + ", coll=" + MessageHelper.collectionInfoString( persister.getRole(), key ) + ">@" + Integer.toHexString( hashCode() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package contains classes that are "shared" by other packages, 
-	and implementations of some key algorithms.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package contains classes that are "shared" by other packages, 
+	and implementations of some key algorithms.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-import java.io.Serializable;
-import java.util.Map;
-
-/**
- * Extends an HQLQueryPlan to maintain a reference to the collection-role name
- * being filtered.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class FilterQueryPlan extends HQLQueryPlan implements Serializable {
-
-	private final String collectionRole;
-
-	public FilterQueryPlan(
-			String hql,
-	        String collectionRole,
-	        boolean shallow,
-	        Map enabledFilters,
-	        SessionFactoryImplementor factory) {
-		super( hql, collectionRole, shallow, enabledFilters, factory );
-		this.collectionRole = collectionRole;
-	}
-
-	public String getCollectionRole() {
-		return collectionRole;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/FilterQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Extends an HQLQueryPlan to maintain a reference to the collection-role name
+ * being filtered.
+ *
+ * @author Steve Ebersole
+ */
+public class FilterQueryPlan extends HQLQueryPlan implements Serializable {
+
+	private final String collectionRole;
+
+	public FilterQueryPlan(
+			String hql,
+	        String collectionRole,
+	        boolean shallow,
+	        Map enabledFilters,
+	        SessionFactoryImplementor factory) {
+		super( hql, collectionRole, shallow, enabledFilters, factory );
+		this.collectionRole = collectionRole;
+	}
+
+	public String getCollectionRole() {
+		return collectionRole;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,315 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.hql.QuerySplitter;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.ParameterTranslations;
-import org.hibernate.hql.FilterTranslator;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.EmptyIterator;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.IdentitySet;
-import org.hibernate.HibernateException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.event.EventSource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.HashMap;
-
-/**
- * Defines a query execution plan for an HQL query (or filter).
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class HQLQueryPlan implements Serializable {
-
-	// TODO : keep seperate notions of QT[] here for shallow/non-shallow queries...
-
-	private static final Logger log = LoggerFactory.getLogger( HQLQueryPlan.class );
-
-	private final String sourceQuery;
-	private final QueryTranslator[] translators;
-	private final String[] sqlStrings;
-
-	private final ParameterMetadata parameterMetadata;
-	private final ReturnMetadata returnMetadata;
-	private final Set querySpaces;
-
-	private final Set enabledFilterNames;
-	private final boolean shallow;
-
-
-	public HQLQueryPlan(String hql, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) {
-		this( hql, null, shallow, enabledFilters, factory );
-	}
-
-	protected HQLQueryPlan(String hql, String collectionRole, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) {
-		this.sourceQuery = hql;
-		this.shallow = shallow;
-
-		Set copy = new HashSet();
-		copy.addAll( enabledFilters.keySet() );
-		this.enabledFilterNames = java.util.Collections.unmodifiableSet( copy );
-
-		Set combinedQuerySpaces = new HashSet();
-		String[] concreteQueryStrings = QuerySplitter.concreteQueries( hql, factory );
-		final int length = concreteQueryStrings.length;
-		translators = new QueryTranslator[length];
-		List sqlStringList = new ArrayList();
-		for ( int i=0; i<length; i++ ) {
-			if ( collectionRole == null ) {
-				translators[i] = factory.getSettings()
-						.getQueryTranslatorFactory()
-						.createQueryTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
-				translators[i].compile( factory.getSettings().getQuerySubstitutions(), shallow );
-			}
-			else {
-				translators[i] = factory.getSettings()
-						.getQueryTranslatorFactory()
-						.createFilterTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
-				( ( FilterTranslator ) translators[i] ).compile( collectionRole, factory.getSettings().getQuerySubstitutions(), shallow );
-			}
-			combinedQuerySpaces.addAll( translators[i].getQuerySpaces() );
-			sqlStringList.addAll( translators[i].collectSqlStrings() );
-		}
-
-		this.sqlStrings = ArrayHelper.toStringArray( sqlStringList );
-		this.querySpaces = combinedQuerySpaces;
-
-		if ( length == 0 ) {
-			parameterMetadata = new ParameterMetadata( null, null );
-			returnMetadata = null;
-		}
-		else {
-			this.parameterMetadata = buildParameterMetadata( translators[0].getParameterTranslations(), hql );
-			if ( translators[0].isManipulationStatement() ) {
-				returnMetadata = null;
-			}
-			else {
-				if ( length > 1 ) {
-					final int returns = translators[0].getReturnTypes().length;
-					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), new Type[returns] );
-				}
-				else {
-					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), translators[0].getReturnTypes() );
-				}
-			}
-		}
-	}
-
-	public String getSourceQuery() {
-		return sourceQuery;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	public ParameterMetadata getParameterMetadata() {
-		return parameterMetadata;
-	}
-
-	public ReturnMetadata getReturnMetadata() {
-		return returnMetadata;
-	}
-
-	public Set getEnabledFilterNames() {
-		return enabledFilterNames;
-	}
-
-	public String[] getSqlStrings() {
-		return sqlStrings;
-	}
-
-	public Set getUtilizedFilterNames() {
-		// TODO : add this info to the translator and aggregate it here...
-		return null;
-	}
-
-	public boolean isShallow() {
-		return shallow;
-	}
-
-	public List performList(
-			QueryParameters queryParameters,
-	        SessionImplementor session) throws HibernateException {
-		if ( log.isTraceEnabled() ) {
-			log.trace( "find: " + getSourceQuery() );
-			queryParameters.traceParameters( session.getFactory() );
-		}
-		boolean hasLimit = queryParameters.getRowSelection() != null &&
-		                   queryParameters.getRowSelection().definesLimits();
-		boolean needsLimit = hasLimit && translators.length > 1;
-		QueryParameters queryParametersToUse;
-		if ( needsLimit ) {
-			log.warn( "firstResult/maxResults specified on polymorphic query; applying in memory!" );
-			RowSelection selection = new RowSelection();
-			selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
-			selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
-			queryParametersToUse = queryParameters.createCopyUsing( selection );
-		}
-		else {
-			queryParametersToUse = queryParameters;
-		}
-
-		List combinedResults = new ArrayList();
-		IdentitySet distinction = new IdentitySet();
-		int includedCount = -1;
-		translator_loop: for ( int i = 0; i < translators.length; i++ ) {
-			List tmp = translators[i].list( session, queryParametersToUse );
-			if ( needsLimit ) {
-				// NOTE : firstRow is zero-based
-				int first = queryParameters.getRowSelection().getFirstRow() == null
-				            ? 0
-			                : queryParameters.getRowSelection().getFirstRow().intValue();
-				int max = queryParameters.getRowSelection().getMaxRows() == null
-				            ? -1
-			                : queryParameters.getRowSelection().getMaxRows().intValue();
-				final int size = tmp.size();
-				for ( int x = 0; x < size; x++ ) {
-					final Object result = tmp.get( x );
-					if ( distinction.add( result ) ) {
-						continue;
-					}
-					includedCount++;
-					if ( includedCount < first ) {
-						continue;
-					}
-					combinedResults.add( result );
-					if ( max >= 0 && includedCount > max ) {
-						// break the outer loop !!!
-						break translator_loop;
-					}
-				}
-			}
-			else {
-				combinedResults.addAll( tmp );
-			}
-		}
-		return combinedResults;
-	}
-
-	public Iterator performIterate(
-			QueryParameters queryParameters,
-	        EventSource session) throws HibernateException {
-		if ( log.isTraceEnabled() ) {
-			log.trace( "iterate: " + getSourceQuery() );
-			queryParameters.traceParameters( session.getFactory() );
-		}
-		if ( translators.length == 0 ) {
-			return EmptyIterator.INSTANCE;
-		}
-
-		Iterator[] results = null;
-		boolean many = translators.length > 1;
-		if (many) {
-			results = new Iterator[translators.length];
-		}
-
-		Iterator result = null;
-		for ( int i = 0; i < translators.length; i++ ) {
-			result = translators[i].iterate( queryParameters, session );
-			if (many) results[i] = result;
-		}
-
-		return many ? new JoinedIterator(results) : result;
-	}
-
-	public ScrollableResults performScroll(
-			QueryParameters queryParameters,
-	        SessionImplementor session) throws HibernateException {
-		if ( log.isTraceEnabled() ) {
-			log.trace( "iterate: " + getSourceQuery() );
-			queryParameters.traceParameters( session.getFactory() );
-		}
-		if ( translators.length != 1 ) {
-			throw new QueryException( "implicit polymorphism not supported for scroll() queries" );
-		}
-		if ( queryParameters.getRowSelection().definesLimits() && translators[0].containsCollectionFetches() ) {
-			throw new QueryException( "firstResult/maxResults not supported in conjunction with scroll() of a query containing collection fetches" );
-		}
-
-		return translators[0].scroll( queryParameters, session );
-	}
-
-	public int performExecuteUpdate(QueryParameters queryParameters, SessionImplementor session)
-			throws HibernateException {
-		if ( log.isTraceEnabled() ) {
-			log.trace( "executeUpdate: " + getSourceQuery() );
-			queryParameters.traceParameters( session.getFactory() );
-		}
-		if ( translators.length != 1 ) {
-			log.warn( "manipulation query [" + getSourceQuery() + "] resulted in [" + translators.length + "] split queries" );
-		}
-		int result = 0;
-		for ( int i = 0; i < translators.length; i++ ) {
-			result += translators[i].executeUpdate( queryParameters, session );
-		}
-		return result;
-	}
-
-	private ParameterMetadata buildParameterMetadata(ParameterTranslations parameterTranslations, String hql) {
-		long start = System.currentTimeMillis();
-		ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql );
-		long end = System.currentTimeMillis();
-		if ( log.isTraceEnabled() ) {
-			log.trace( "HQL param location recognition took " + (end - start) + " mills (" + hql + ")" );
-		}
-
-		int ordinalParamCount = parameterTranslations.getOrdinalParameterCount();
-		int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() );
-		if ( parameterTranslations.supportsOrdinalParameterMetadata() && locations.length != ordinalParamCount ) {
-			throw new HibernateException( "ordinal parameter mismatch" );
-		}
-		ordinalParamCount = locations.length;
-		OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount];
-		for ( int i = 1; i <= ordinalParamCount; i++ ) {
-			ordinalParamDescriptors[ i - 1 ] = new OrdinalParameterDescriptor(
-					i,
-			        parameterTranslations.supportsOrdinalParameterMetadata()
-		                    ? parameterTranslations.getOrdinalParameterExpectedType( i )
-		                    : null,
-			        locations[ i - 1 ]
-			);
-		}
-
-		Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator();
-		Map namedParamDescriptorMap = new HashMap();
-		while( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final String name = ( String ) entry.getKey();
-			final ParamLocationRecognizer.NamedParameterDescription description =
-					( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue();
-			namedParamDescriptorMap.put(
-					name,
-					new NamedParameterDescriptor(
-							name,
-					        parameterTranslations.getNamedParameterExpectedType( name ),
-					        description.buildPositionsArray(),
-					        description.isJpaStyle()
-					)
-			);
-		}
-
-		return new ParameterMetadata( ordinalParamDescriptors, namedParamDescriptorMap );
-	}
-
-	public QueryTranslator[] getTranslators() {
-		QueryTranslator[] copy = new QueryTranslator[translators.length];
-		System.arraycopy(translators, 0, copy, 0, copy.length);
-		return copy;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/HQLQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,339 @@
+/*
+ * 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.engine.query;
+
+import org.hibernate.hql.QuerySplitter;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.ParameterTranslations;
+import org.hibernate.hql.FilterTranslator;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.IdentitySet;
+import org.hibernate.HibernateException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.QueryException;
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.event.EventSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.HashMap;
+
+/**
+ * Defines a query execution plan for an HQL query (or filter).
+ *
+ * @author Steve Ebersole
+ */
+public class HQLQueryPlan implements Serializable {
+
+	// TODO : keep seperate notions of QT[] here for shallow/non-shallow queries...
+
+	private static final Logger log = LoggerFactory.getLogger( HQLQueryPlan.class );
+
+	private final String sourceQuery;
+	private final QueryTranslator[] translators;
+	private final String[] sqlStrings;
+
+	private final ParameterMetadata parameterMetadata;
+	private final ReturnMetadata returnMetadata;
+	private final Set querySpaces;
+
+	private final Set enabledFilterNames;
+	private final boolean shallow;
+
+
+	public HQLQueryPlan(String hql, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) {
+		this( hql, null, shallow, enabledFilters, factory );
+	}
+
+	protected HQLQueryPlan(String hql, String collectionRole, boolean shallow, Map enabledFilters, SessionFactoryImplementor factory) {
+		this.sourceQuery = hql;
+		this.shallow = shallow;
+
+		Set copy = new HashSet();
+		copy.addAll( enabledFilters.keySet() );
+		this.enabledFilterNames = java.util.Collections.unmodifiableSet( copy );
+
+		Set combinedQuerySpaces = new HashSet();
+		String[] concreteQueryStrings = QuerySplitter.concreteQueries( hql, factory );
+		final int length = concreteQueryStrings.length;
+		translators = new QueryTranslator[length];
+		List sqlStringList = new ArrayList();
+		for ( int i=0; i<length; i++ ) {
+			if ( collectionRole == null ) {
+				translators[i] = factory.getSettings()
+						.getQueryTranslatorFactory()
+						.createQueryTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
+				translators[i].compile( factory.getSettings().getQuerySubstitutions(), shallow );
+			}
+			else {
+				translators[i] = factory.getSettings()
+						.getQueryTranslatorFactory()
+						.createFilterTranslator( hql, concreteQueryStrings[i], enabledFilters, factory );
+				( ( FilterTranslator ) translators[i] ).compile( collectionRole, factory.getSettings().getQuerySubstitutions(), shallow );
+			}
+			combinedQuerySpaces.addAll( translators[i].getQuerySpaces() );
+			sqlStringList.addAll( translators[i].collectSqlStrings() );
+		}
+
+		this.sqlStrings = ArrayHelper.toStringArray( sqlStringList );
+		this.querySpaces = combinedQuerySpaces;
+
+		if ( length == 0 ) {
+			parameterMetadata = new ParameterMetadata( null, null );
+			returnMetadata = null;
+		}
+		else {
+			this.parameterMetadata = buildParameterMetadata( translators[0].getParameterTranslations(), hql );
+			if ( translators[0].isManipulationStatement() ) {
+				returnMetadata = null;
+			}
+			else {
+				if ( length > 1 ) {
+					final int returns = translators[0].getReturnTypes().length;
+					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), new Type[returns] );
+				}
+				else {
+					returnMetadata = new ReturnMetadata( translators[0].getReturnAliases(), translators[0].getReturnTypes() );
+				}
+			}
+		}
+	}
+
+	public String getSourceQuery() {
+		return sourceQuery;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	public ParameterMetadata getParameterMetadata() {
+		return parameterMetadata;
+	}
+
+	public ReturnMetadata getReturnMetadata() {
+		return returnMetadata;
+	}
+
+	public Set getEnabledFilterNames() {
+		return enabledFilterNames;
+	}
+
+	public String[] getSqlStrings() {
+		return sqlStrings;
+	}
+
+	public Set getUtilizedFilterNames() {
+		// TODO : add this info to the translator and aggregate it here...
+		return null;
+	}
+
+	public boolean isShallow() {
+		return shallow;
+	}
+
+	public List performList(
+			QueryParameters queryParameters,
+	        SessionImplementor session) throws HibernateException {
+		if ( log.isTraceEnabled() ) {
+			log.trace( "find: " + getSourceQuery() );
+			queryParameters.traceParameters( session.getFactory() );
+		}
+		boolean hasLimit = queryParameters.getRowSelection() != null &&
+		                   queryParameters.getRowSelection().definesLimits();
+		boolean needsLimit = hasLimit && translators.length > 1;
+		QueryParameters queryParametersToUse;
+		if ( needsLimit ) {
+			log.warn( "firstResult/maxResults specified on polymorphic query; applying in memory!" );
+			RowSelection selection = new RowSelection();
+			selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
+			selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
+			queryParametersToUse = queryParameters.createCopyUsing( selection );
+		}
+		else {
+			queryParametersToUse = queryParameters;
+		}
+
+		List combinedResults = new ArrayList();
+		IdentitySet distinction = new IdentitySet();
+		int includedCount = -1;
+		translator_loop: for ( int i = 0; i < translators.length; i++ ) {
+			List tmp = translators[i].list( session, queryParametersToUse );
+			if ( needsLimit ) {
+				// NOTE : firstRow is zero-based
+				int first = queryParameters.getRowSelection().getFirstRow() == null
+				            ? 0
+			                : queryParameters.getRowSelection().getFirstRow().intValue();
+				int max = queryParameters.getRowSelection().getMaxRows() == null
+				            ? -1
+			                : queryParameters.getRowSelection().getMaxRows().intValue();
+				final int size = tmp.size();
+				for ( int x = 0; x < size; x++ ) {
+					final Object result = tmp.get( x );
+					if ( distinction.add( result ) ) {
+						continue;
+					}
+					includedCount++;
+					if ( includedCount < first ) {
+						continue;
+					}
+					combinedResults.add( result );
+					if ( max >= 0 && includedCount > max ) {
+						// break the outer loop !!!
+						break translator_loop;
+					}
+				}
+			}
+			else {
+				combinedResults.addAll( tmp );
+			}
+		}
+		return combinedResults;
+	}
+
+	public Iterator performIterate(
+			QueryParameters queryParameters,
+	        EventSource session) throws HibernateException {
+		if ( log.isTraceEnabled() ) {
+			log.trace( "iterate: " + getSourceQuery() );
+			queryParameters.traceParameters( session.getFactory() );
+		}
+		if ( translators.length == 0 ) {
+			return EmptyIterator.INSTANCE;
+		}
+
+		Iterator[] results = null;
+		boolean many = translators.length > 1;
+		if (many) {
+			results = new Iterator[translators.length];
+		}
+
+		Iterator result = null;
+		for ( int i = 0; i < translators.length; i++ ) {
+			result = translators[i].iterate( queryParameters, session );
+			if (many) results[i] = result;
+		}
+
+		return many ? new JoinedIterator(results) : result;
+	}
+
+	public ScrollableResults performScroll(
+			QueryParameters queryParameters,
+	        SessionImplementor session) throws HibernateException {
+		if ( log.isTraceEnabled() ) {
+			log.trace( "iterate: " + getSourceQuery() );
+			queryParameters.traceParameters( session.getFactory() );
+		}
+		if ( translators.length != 1 ) {
+			throw new QueryException( "implicit polymorphism not supported for scroll() queries" );
+		}
+		if ( queryParameters.getRowSelection().definesLimits() && translators[0].containsCollectionFetches() ) {
+			throw new QueryException( "firstResult/maxResults not supported in conjunction with scroll() of a query containing collection fetches" );
+		}
+
+		return translators[0].scroll( queryParameters, session );
+	}
+
+	public int performExecuteUpdate(QueryParameters queryParameters, SessionImplementor session)
+			throws HibernateException {
+		if ( log.isTraceEnabled() ) {
+			log.trace( "executeUpdate: " + getSourceQuery() );
+			queryParameters.traceParameters( session.getFactory() );
+		}
+		if ( translators.length != 1 ) {
+			log.warn( "manipulation query [" + getSourceQuery() + "] resulted in [" + translators.length + "] split queries" );
+		}
+		int result = 0;
+		for ( int i = 0; i < translators.length; i++ ) {
+			result += translators[i].executeUpdate( queryParameters, session );
+		}
+		return result;
+	}
+
+	private ParameterMetadata buildParameterMetadata(ParameterTranslations parameterTranslations, String hql) {
+		long start = System.currentTimeMillis();
+		ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( hql );
+		long end = System.currentTimeMillis();
+		if ( log.isTraceEnabled() ) {
+			log.trace( "HQL param location recognition took " + (end - start) + " mills (" + hql + ")" );
+		}
+
+		int ordinalParamCount = parameterTranslations.getOrdinalParameterCount();
+		int[] locations = ArrayHelper.toIntArray( recognizer.getOrdinalParameterLocationList() );
+		if ( parameterTranslations.supportsOrdinalParameterMetadata() && locations.length != ordinalParamCount ) {
+			throw new HibernateException( "ordinal parameter mismatch" );
+		}
+		ordinalParamCount = locations.length;
+		OrdinalParameterDescriptor[] ordinalParamDescriptors = new OrdinalParameterDescriptor[ordinalParamCount];
+		for ( int i = 1; i <= ordinalParamCount; i++ ) {
+			ordinalParamDescriptors[ i - 1 ] = new OrdinalParameterDescriptor(
+					i,
+			        parameterTranslations.supportsOrdinalParameterMetadata()
+		                    ? parameterTranslations.getOrdinalParameterExpectedType( i )
+		                    : null,
+			        locations[ i - 1 ]
+			);
+		}
+
+		Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator();
+		Map namedParamDescriptorMap = new HashMap();
+		while( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final String name = ( String ) entry.getKey();
+			final ParamLocationRecognizer.NamedParameterDescription description =
+					( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue();
+			namedParamDescriptorMap.put(
+					name,
+					new NamedParameterDescriptor(
+							name,
+					        parameterTranslations.getNamedParameterExpectedType( name ),
+					        description.buildPositionsArray(),
+					        description.isJpaStyle()
+					)
+			);
+		}
+
+		return new ParameterMetadata( ordinalParamDescriptors, namedParamDescriptorMap );
+	}
+
+	public QueryTranslator[] getTranslators() {
+		QueryTranslator[] copy = new QueryTranslator[translators.length];
+		System.arraycopy(translators, 0, copy, 0, copy.length);
+		return copy;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-
-/**
- * Descriptor regarding a named parameter.
- *
- * @author Steve Ebersole
- */
-public class NamedParameterDescriptor implements Serializable {
-	private final String name;
-	private final Type expectedType;
-	private final int[] sourceLocations;
-	private final boolean jpaStyle;
-
-	public NamedParameterDescriptor(String name, Type expectedType, int[] sourceLocations, boolean jpaStyle) {
-		this.name = name;
-		this.expectedType = expectedType;
-		this.sourceLocations = sourceLocations;
-		this.jpaStyle = jpaStyle;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Type getExpectedType() {
-		return expectedType;
-	}
-
-	public int[] getSourceLocations() {
-		return sourceLocations;
-	}
-
-	public boolean isJpaStyle() {
-		return jpaStyle;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NamedParameterDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+
+/**
+ * Descriptor regarding a named parameter.
+ *
+ * @author Steve Ebersole
+ */
+public class NamedParameterDescriptor implements Serializable {
+	private final String name;
+	private final Type expectedType;
+	private final int[] sourceLocations;
+	private final boolean jpaStyle;
+
+	public NamedParameterDescriptor(String name, Type expectedType, int[] sourceLocations, boolean jpaStyle) {
+		this.name = name;
+		this.expectedType = expectedType;
+		this.sourceLocations = sourceLocations;
+		this.jpaStyle = jpaStyle;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Type getExpectedType() {
+		return expectedType;
+	}
+
+	public int[] getSourceLocations() {
+		return sourceLocations;
+	}
+
+	public boolean isJpaStyle() {
+		return jpaStyle;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,182 +0,0 @@
-package org.hibernate.engine.query;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.action.BulkOperationCleanupAction;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.event.EventSource;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.loader.custom.sql.SQLCustomQuery;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Defines a query execution plan for a native-SQL query.
- * 
- * @author Steve Ebersole
- */
-public class NativeSQLQueryPlan implements Serializable {
-	private final String sourceQuery;
-
-	private final SQLCustomQuery customQuery;
-
-	private static final Logger log = LoggerFactory.getLogger(NativeSQLQueryPlan.class);
-
-	public NativeSQLQueryPlan(
-			NativeSQLQuerySpecification specification,
-			SessionFactoryImplementor factory) {
-		this.sourceQuery = specification.getQueryString();
-
-		customQuery = new SQLCustomQuery(
-				specification.getQueryString(),
-				specification.getQueryReturns(),
-				specification.getQuerySpaces(),
-				factory );
-	}
-
-	public String getSourceQuery() {
-		return sourceQuery;
-	}
-
-	public SQLCustomQuery getCustomQuery() {
-		return customQuery;
-	}
-
-	private int[] getNamedParameterLocs(String name) throws QueryException {
-		Object loc = customQuery.getNamedParameterBindPoints().get( name );
-		if ( loc == null ) {
-			throw new QueryException(
-					"Named parameter does not appear in Query: " + name,
-					customQuery.getSQL() );
-		}
-		if ( loc instanceof Integer ) {
-			return new int[] { ((Integer) loc ).intValue() };
-		}
-		else {
-			return ArrayHelper.toIntArray( (List) loc );
-		}
-	}
-
-	/**
-	 * Bind positional parameter values to the <tt>PreparedStatement</tt>
-	 * (these are parameters specified by a JDBC-style ?).
-	 */
-	private int bindPositionalParameters(final PreparedStatement st,
-			final QueryParameters queryParameters, final int start,
-			final SessionImplementor session) throws SQLException,
-			HibernateException {
-
-		final Object[] values = queryParameters
-				.getFilteredPositionalParameterValues();
-		final Type[] types = queryParameters
-				.getFilteredPositionalParameterTypes();
-		int span = 0;
-		for (int i = 0; i < values.length; i++) {
-			types[i].nullSafeSet( st, values[i], start + span, session );
-			span += types[i].getColumnSpan( session.getFactory() );
-		}
-		return span;
-	}
-
-	/**
-	 * Bind named parameters to the <tt>PreparedStatement</tt>. This has an
-	 * empty implementation on this superclass and should be implemented by
-	 * subclasses (queries) which allow named parameters.
-	 */
-	private int bindNamedParameters(final PreparedStatement ps,
-			final Map namedParams, final int start,
-			final SessionImplementor session) throws SQLException,
-			HibernateException {
-
-		if ( namedParams != null ) {
-			// assumes that types are all of span 1
-			Iterator iter = namedParams.entrySet().iterator();
-			int result = 0;
-			while ( iter.hasNext() ) {
-				Map.Entry e = (Map.Entry) iter.next();
-				String name = (String) e.getKey();
-				TypedValue typedval = (TypedValue) e.getValue();
-				int[] locs = getNamedParameterLocs( name );
-				for (int i = 0; i < locs.length; i++) {
-					if ( log.isDebugEnabled() ) {
-						log.debug( "bindNamedParameters() "
-								+ typedval.getValue() + " -> " + name + " ["
-								+ (locs[i] + start ) + "]" );
-					}
-					typedval.getType().nullSafeSet( ps, typedval.getValue(),
-							locs[i] + start, session );
-				}
-				result += locs.length;
-			}
-			return result;
-		}
-		else {
-			return 0;
-		}
-	}
-
-	protected void coordinateSharedCacheCleanup(SessionImplementor session) {
-		BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getCustomQuery().getQuerySpaces() );
-
-		action.init();
-
-		if ( session.isEventSource() ) {
-			( ( EventSource ) session ).getActionQueue().addAction( action );
-		}
-	}
-
-	public int performExecuteUpdate(QueryParameters queryParameters,
-			SessionImplementor session) throws HibernateException {
-		
-		coordinateSharedCacheCleanup( session );
-		
-		if(queryParameters.isCallable()) {
-			throw new IllegalArgumentException("callable not yet supported for native queries");
-		}
-		
-		int result = 0;
-		PreparedStatement ps;
-		try {
-			queryParameters.processFilters( this.customQuery.getSQL(),
-					session );
-			String sql = queryParameters.getFilteredSQL();
-
-			ps = session.getBatcher().prepareStatement( sql );
-
-			try {
-				int col = 1;
-				col += bindPositionalParameters( ps, queryParameters, col,
-						session );
-				col += bindNamedParameters( ps, queryParameters
-						.getNamedParameters(), col, session );
-				result = ps.executeUpdate();
-			}
-			finally {
-				if ( ps != null ) {
-					session.getBatcher().closeStatement( ps );
-				}				
-			}			
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert( session.getFactory()
-					.getSQLExceptionConverter(), sqle,
-					"could not execute native bulk manipulation query", this.sourceQuery );
-		}
-
-		return result;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/NativeSQLQueryPlan.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,206 @@
+/*
+ * 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.engine.query;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.action.BulkOperationCleanupAction;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.event.EventSource;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.loader.custom.sql.SQLCustomQuery;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Defines a query execution plan for a native-SQL query.
+ * 
+ * @author Steve Ebersole
+ */
+public class NativeSQLQueryPlan implements Serializable {
+	private final String sourceQuery;
+
+	private final SQLCustomQuery customQuery;
+
+	private static final Logger log = LoggerFactory.getLogger(NativeSQLQueryPlan.class);
+
+	public NativeSQLQueryPlan(
+			NativeSQLQuerySpecification specification,
+			SessionFactoryImplementor factory) {
+		this.sourceQuery = specification.getQueryString();
+
+		customQuery = new SQLCustomQuery(
+				specification.getQueryString(),
+				specification.getQueryReturns(),
+				specification.getQuerySpaces(),
+				factory );
+	}
+
+	public String getSourceQuery() {
+		return sourceQuery;
+	}
+
+	public SQLCustomQuery getCustomQuery() {
+		return customQuery;
+	}
+
+	private int[] getNamedParameterLocs(String name) throws QueryException {
+		Object loc = customQuery.getNamedParameterBindPoints().get( name );
+		if ( loc == null ) {
+			throw new QueryException(
+					"Named parameter does not appear in Query: " + name,
+					customQuery.getSQL() );
+		}
+		if ( loc instanceof Integer ) {
+			return new int[] { ((Integer) loc ).intValue() };
+		}
+		else {
+			return ArrayHelper.toIntArray( (List) loc );
+		}
+	}
+
+	/**
+	 * Bind positional parameter values to the <tt>PreparedStatement</tt>
+	 * (these are parameters specified by a JDBC-style ?).
+	 */
+	private int bindPositionalParameters(final PreparedStatement st,
+			final QueryParameters queryParameters, final int start,
+			final SessionImplementor session) throws SQLException,
+			HibernateException {
+
+		final Object[] values = queryParameters
+				.getFilteredPositionalParameterValues();
+		final Type[] types = queryParameters
+				.getFilteredPositionalParameterTypes();
+		int span = 0;
+		for (int i = 0; i < values.length; i++) {
+			types[i].nullSafeSet( st, values[i], start + span, session );
+			span += types[i].getColumnSpan( session.getFactory() );
+		}
+		return span;
+	}
+
+	/**
+	 * Bind named parameters to the <tt>PreparedStatement</tt>. This has an
+	 * empty implementation on this superclass and should be implemented by
+	 * subclasses (queries) which allow named parameters.
+	 */
+	private int bindNamedParameters(final PreparedStatement ps,
+			final Map namedParams, final int start,
+			final SessionImplementor session) throws SQLException,
+			HibernateException {
+
+		if ( namedParams != null ) {
+			// assumes that types are all of span 1
+			Iterator iter = namedParams.entrySet().iterator();
+			int result = 0;
+			while ( iter.hasNext() ) {
+				Map.Entry e = (Map.Entry) iter.next();
+				String name = (String) e.getKey();
+				TypedValue typedval = (TypedValue) e.getValue();
+				int[] locs = getNamedParameterLocs( name );
+				for (int i = 0; i < locs.length; i++) {
+					if ( log.isDebugEnabled() ) {
+						log.debug( "bindNamedParameters() "
+								+ typedval.getValue() + " -> " + name + " ["
+								+ (locs[i] + start ) + "]" );
+					}
+					typedval.getType().nullSafeSet( ps, typedval.getValue(),
+							locs[i] + start, session );
+				}
+				result += locs.length;
+			}
+			return result;
+		}
+		else {
+			return 0;
+		}
+	}
+
+	protected void coordinateSharedCacheCleanup(SessionImplementor session) {
+		BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getCustomQuery().getQuerySpaces() );
+
+		action.init();
+
+		if ( session.isEventSource() ) {
+			( ( EventSource ) session ).getActionQueue().addAction( action );
+		}
+	}
+
+	public int performExecuteUpdate(QueryParameters queryParameters,
+			SessionImplementor session) throws HibernateException {
+		
+		coordinateSharedCacheCleanup( session );
+		
+		if(queryParameters.isCallable()) {
+			throw new IllegalArgumentException("callable not yet supported for native queries");
+		}
+		
+		int result = 0;
+		PreparedStatement ps;
+		try {
+			queryParameters.processFilters( this.customQuery.getSQL(),
+					session );
+			String sql = queryParameters.getFilteredSQL();
+
+			ps = session.getBatcher().prepareStatement( sql );
+
+			try {
+				int col = 1;
+				col += bindPositionalParameters( ps, queryParameters, col,
+						session );
+				col += bindNamedParameters( ps, queryParameters
+						.getNamedParameters(), col, session );
+				result = ps.executeUpdate();
+			}
+			finally {
+				if ( ps != null ) {
+					session.getBatcher().closeStatement( ps );
+				}				
+			}			
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert( session.getFactory()
+					.getSQLExceptionConverter(), sqle,
+					"could not execute native bulk manipulation query", this.sourceQuery );
+		}
+
+		return result;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-
-/**
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class OrdinalParameterDescriptor implements Serializable {
-	private final int ordinalPosition;
-	private final Type expectedType;
-	private final int sourceLocation;
-
-	public OrdinalParameterDescriptor(int ordinalPosition, Type expectedType, int sourceLocation) {
-		this.ordinalPosition = ordinalPosition;
-		this.expectedType = expectedType;
-		this.sourceLocation = sourceLocation;
-	}
-
-	public int getOrdinalPosition() {
-		return ordinalPosition;
-	}
-
-	public Type getExpectedType() {
-		return expectedType;
-	}
-
-	public int getSourceLocation() {
-		return sourceLocation;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/OrdinalParameterDescriptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+
+/**
+ * @author Steve Ebersole
+ */
+public class OrdinalParameterDescriptor implements Serializable {
+	private final int ordinalPosition;
+	private final Type expectedType;
+	private final int sourceLocation;
+
+	public OrdinalParameterDescriptor(int ordinalPosition, Type expectedType, int sourceLocation) {
+		this.ordinalPosition = ordinalPosition;
+		this.expectedType = expectedType;
+		this.sourceLocation = sourceLocation;
+	}
+
+	public int getOrdinalPosition() {
+		return ordinalPosition;
+	}
+
+	public Type getExpectedType() {
+		return expectedType;
+	}
+
+	public int getSourceLocation() {
+		return sourceLocation;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.util.ArrayHelper;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.ArrayList;
-
-/**
- * Implements a parameter parser recognizer specifically for the purpose
- * of journaling parameter locations.
- *
- * @author Steve Ebersole
- */
-public class ParamLocationRecognizer implements ParameterParser.Recognizer {
-
-	public static class NamedParameterDescription {
-		private final boolean jpaStyle;
-		private final List positions = new ArrayList();
-
-		public NamedParameterDescription(boolean jpaStyle) {
-			this.jpaStyle = jpaStyle;
-		}
-
-		public boolean isJpaStyle() {
-			return jpaStyle;
-		}
-
-		private void add(int position) {
-			positions.add( new Integer( position ) );
-		}
-
-		public int[] buildPositionsArray() {
-			return ArrayHelper.toIntArray( positions );
-		}
-	}
-
-	private Map namedParameterDescriptions = new HashMap();
-	private List ordinalParameterLocationList = new ArrayList();
-
-	/**
-	 * Convenience method for creating a param location recognizer and
-	 * initiating the parse.
-	 *
-	 * @param query The query to be parsed for parameter locations.
-	 * @return The generated recognizer, with journaled location info.
-	 */
-	public static ParamLocationRecognizer parseLocations(String query) {
-		ParamLocationRecognizer recognizer = new ParamLocationRecognizer();
-		ParameterParser.parse( query, recognizer );
-		return recognizer;
-	}
-
-	/**
-	 * Returns the map of named parameter locations.  The map is keyed by
-	 * parameter name; the corresponding value is a (@link NamedParameterDescription}.
-	 *
-	 * @return The map of named parameter locations.
-	 */
-	public Map getNamedParameterDescriptionMap() {
-		return namedParameterDescriptions;
-	}
-
-	/**
-	 * Returns the list of ordinal parameter locations.  The list elements
-	 * are Integers, representing the location for that given ordinal.  Thus
-	 * {@link #getOrdinalParameterLocationList()}.elementAt(n) represents the
-	 * location for the nth parameter.
-	 *
-	 * @return The list of ordinal parameter locations.
-	 */
-	public List getOrdinalParameterLocationList() {
-		return ordinalParameterLocationList;
-	}
-
-
-	// Recognition code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void ordinalParameter(int position) {
-		ordinalParameterLocationList.add( new Integer( position ) );
-	}
-
-	public void namedParameter(String name, int position) {
-		getOrBuildNamedParameterDescription( name, false ).add( position );
-	}
-
-	public void jpaPositionalParameter(String name, int position) {
-		getOrBuildNamedParameterDescription( name, true ).add( position );
-	}
-
-	private NamedParameterDescription getOrBuildNamedParameterDescription(String name, boolean jpa) {
-		NamedParameterDescription desc = ( NamedParameterDescription ) namedParameterDescriptions.get( name );
-		if ( desc == null ) {
-			desc = new NamedParameterDescription( jpa );
-			namedParameterDescriptions.put( name, desc );
-		}
-		return desc;
-	}
-
-	public void other(char character) {
-		// don't care...
-	}
-
-	public void outParameter(int position) {
-		// don't care...
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParamLocationRecognizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,132 @@
+/*
+ * 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.engine.query;
+
+import org.hibernate.util.ArrayHelper;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * Implements a parameter parser recognizer specifically for the purpose
+ * of journaling parameter locations.
+ *
+ * @author Steve Ebersole
+ */
+public class ParamLocationRecognizer implements ParameterParser.Recognizer {
+
+	public static class NamedParameterDescription {
+		private final boolean jpaStyle;
+		private final List positions = new ArrayList();
+
+		public NamedParameterDescription(boolean jpaStyle) {
+			this.jpaStyle = jpaStyle;
+		}
+
+		public boolean isJpaStyle() {
+			return jpaStyle;
+		}
+
+		private void add(int position) {
+			positions.add( new Integer( position ) );
+		}
+
+		public int[] buildPositionsArray() {
+			return ArrayHelper.toIntArray( positions );
+		}
+	}
+
+	private Map namedParameterDescriptions = new HashMap();
+	private List ordinalParameterLocationList = new ArrayList();
+
+	/**
+	 * Convenience method for creating a param location recognizer and
+	 * initiating the parse.
+	 *
+	 * @param query The query to be parsed for parameter locations.
+	 * @return The generated recognizer, with journaled location info.
+	 */
+	public static ParamLocationRecognizer parseLocations(String query) {
+		ParamLocationRecognizer recognizer = new ParamLocationRecognizer();
+		ParameterParser.parse( query, recognizer );
+		return recognizer;
+	}
+
+	/**
+	 * Returns the map of named parameter locations.  The map is keyed by
+	 * parameter name; the corresponding value is a (@link NamedParameterDescription}.
+	 *
+	 * @return The map of named parameter locations.
+	 */
+	public Map getNamedParameterDescriptionMap() {
+		return namedParameterDescriptions;
+	}
+
+	/**
+	 * Returns the list of ordinal parameter locations.  The list elements
+	 * are Integers, representing the location for that given ordinal.  Thus
+	 * {@link #getOrdinalParameterLocationList()}.elementAt(n) represents the
+	 * location for the nth parameter.
+	 *
+	 * @return The list of ordinal parameter locations.
+	 */
+	public List getOrdinalParameterLocationList() {
+		return ordinalParameterLocationList;
+	}
+
+
+	// Recognition code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void ordinalParameter(int position) {
+		ordinalParameterLocationList.add( new Integer( position ) );
+	}
+
+	public void namedParameter(String name, int position) {
+		getOrBuildNamedParameterDescription( name, false ).add( position );
+	}
+
+	public void jpaPositionalParameter(String name, int position) {
+		getOrBuildNamedParameterDescription( name, true ).add( position );
+	}
+
+	private NamedParameterDescription getOrBuildNamedParameterDescription(String name, boolean jpa) {
+		NamedParameterDescription desc = ( NamedParameterDescription ) namedParameterDescriptions.get( name );
+		if ( desc == null ) {
+			desc = new NamedParameterDescription( jpa );
+			namedParameterDescriptions.put( name, desc );
+		}
+		return desc;
+	}
+
+	public void other(char character) {
+		// don't care...
+	}
+
+	public void outParameter(int position) {
+		// don't care...
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,88 +0,0 @@
-package org.hibernate.engine.query;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.QueryParameterException;
-import org.hibernate.type.Type;
-
-/**
- * Encapsulates metadata about parameters encountered within a query.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class ParameterMetadata implements Serializable {
-
-	private static final OrdinalParameterDescriptor[] EMPTY_ORDINALS = new OrdinalParameterDescriptor[0];
-
-	private final OrdinalParameterDescriptor[] ordinalDescriptors;
-	private final Map namedDescriptorMap;
-
-	/**
-	 * Instantiates a ParameterMetadata container.
-	 *
-	 * @param ordinalDescriptors
-	 * @param namedDescriptorMap
-	 */
-	public ParameterMetadata(OrdinalParameterDescriptor[] ordinalDescriptors, Map namedDescriptorMap) {
-		if ( ordinalDescriptors == null ) {
-			this.ordinalDescriptors = EMPTY_ORDINALS;
-		}
-		else {
-			OrdinalParameterDescriptor[] copy = new OrdinalParameterDescriptor[ ordinalDescriptors.length ];
-			System.arraycopy( ordinalDescriptors, 0, copy, 0, ordinalDescriptors.length );
-			this.ordinalDescriptors = copy;
-		}
-		if ( namedDescriptorMap == null ) {
-			this.namedDescriptorMap = java.util.Collections.EMPTY_MAP;
-		}
-		else {
-			int size = ( int ) ( ( namedDescriptorMap.size() / .75 ) + 1 );
-			Map copy = new HashMap( size );
-			copy.putAll( namedDescriptorMap );
-			this.namedDescriptorMap = java.util.Collections.unmodifiableMap( copy );
-		}
-	}
-
-	public int getOrdinalParameterCount() {
-		return ordinalDescriptors.length;
-	}
-
-	public OrdinalParameterDescriptor getOrdinalParameterDescriptor(int position) {
-		if ( position < 1 || position > ordinalDescriptors.length ) {
-			throw new IndexOutOfBoundsException( "Remember that ordinal parameters are 1-based!" );
-		}
-		return ordinalDescriptors[position - 1];
-	}
-
-	public Type getOrdinalParameterExpectedType(int position) {
-		return getOrdinalParameterDescriptor( position ).getExpectedType();
-	}
-
-	public int getOrdinalParameterSourceLocation(int position) {
-		return getOrdinalParameterDescriptor( position ).getSourceLocation();
-	}
-
-	public Set getNamedParameterNames() {
-		return namedDescriptorMap.keySet();
-	}
-
-	public NamedParameterDescriptor getNamedParameterDescriptor(String name) {
-		NamedParameterDescriptor meta = ( NamedParameterDescriptor ) namedDescriptorMap.get( name );
-		if ( meta == null ) {
-			throw new QueryParameterException( "could not locate named parameter [" + name + "]" );
-		}
-		return meta;
-	}
-
-	public Type getNamedParameterExpectedType(String name) {
-		return getNamedParameterDescriptor( name ).getExpectedType();
-	}
-
-	public int[] getNamedParameterSourceLocations(String name) {
-		return getNamedParameterDescriptor( name ).getSourceLocations();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,112 @@
+/*
+ * 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.engine.query;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.QueryParameterException;
+import org.hibernate.type.Type;
+
+/**
+ * Encapsulates metadata about parameters encountered within a query.
+ *
+ * @author Steve Ebersole
+ */
+public class ParameterMetadata implements Serializable {
+
+	private static final OrdinalParameterDescriptor[] EMPTY_ORDINALS = new OrdinalParameterDescriptor[0];
+
+	private final OrdinalParameterDescriptor[] ordinalDescriptors;
+	private final Map namedDescriptorMap;
+
+	/**
+	 * Instantiates a ParameterMetadata container.
+	 *
+	 * @param ordinalDescriptors
+	 * @param namedDescriptorMap
+	 */
+	public ParameterMetadata(OrdinalParameterDescriptor[] ordinalDescriptors, Map namedDescriptorMap) {
+		if ( ordinalDescriptors == null ) {
+			this.ordinalDescriptors = EMPTY_ORDINALS;
+		}
+		else {
+			OrdinalParameterDescriptor[] copy = new OrdinalParameterDescriptor[ ordinalDescriptors.length ];
+			System.arraycopy( ordinalDescriptors, 0, copy, 0, ordinalDescriptors.length );
+			this.ordinalDescriptors = copy;
+		}
+		if ( namedDescriptorMap == null ) {
+			this.namedDescriptorMap = java.util.Collections.EMPTY_MAP;
+		}
+		else {
+			int size = ( int ) ( ( namedDescriptorMap.size() / .75 ) + 1 );
+			Map copy = new HashMap( size );
+			copy.putAll( namedDescriptorMap );
+			this.namedDescriptorMap = java.util.Collections.unmodifiableMap( copy );
+		}
+	}
+
+	public int getOrdinalParameterCount() {
+		return ordinalDescriptors.length;
+	}
+
+	public OrdinalParameterDescriptor getOrdinalParameterDescriptor(int position) {
+		if ( position < 1 || position > ordinalDescriptors.length ) {
+			throw new IndexOutOfBoundsException( "Remember that ordinal parameters are 1-based!" );
+		}
+		return ordinalDescriptors[position - 1];
+	}
+
+	public Type getOrdinalParameterExpectedType(int position) {
+		return getOrdinalParameterDescriptor( position ).getExpectedType();
+	}
+
+	public int getOrdinalParameterSourceLocation(int position) {
+		return getOrdinalParameterDescriptor( position ).getSourceLocation();
+	}
+
+	public Set getNamedParameterNames() {
+		return namedDescriptorMap.keySet();
+	}
+
+	public NamedParameterDescriptor getNamedParameterDescriptor(String name) {
+		NamedParameterDescriptor meta = ( NamedParameterDescriptor ) namedDescriptorMap.get( name );
+		if ( meta == null ) {
+			throw new QueryParameterException( "could not locate named parameter [" + name + "]" );
+		}
+		return meta;
+	}
+
+	public Type getNamedParameterExpectedType(String name) {
+		return getNamedParameterDescriptor( name ).getExpectedType();
+	}
+
+	public int[] getNamedParameterSourceLocations(String name) {
+		return getNamedParameterDescriptor( name ).getSourceLocations();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/ParameterParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.QueryException;
-import org.hibernate.hql.classic.ParserHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * The single available method {@link #parse} is responsible for parsing a
- * query string and recognizing tokens in relation to parameters (either
- * named, JPA-style, or ordinal) and providing callbacks about such
- * recognitions.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class ParameterParser {
-
-	public static interface Recognizer {
-		public void outParameter(int position);
-		public void ordinalParameter(int position);
-		public void namedParameter(String name, int position);
-		public void jpaPositionalParameter(String name, int position);
-		public void other(char character);
-	}
-
-	private ParameterParser() {
-		// disallow instantiation
-	}
-
-	/**
-	 * Performs the actual parsing and tokenizing of the query string making appropriate
-	 * callbacks to the given recognizer upon recognition of the various tokens.
-	 * <p/>
-	 * Note that currently, this only knows how to deal with a single output
-	 * parameter (for callable statements).  If we later add support for
-	 * multiple output params, this, obviously, needs to change.
-	 *
-	 * @param sqlString The string to be parsed/tokenized.
-	 * @param recognizer The thing which handles recognition events.
-	 * @throws QueryException
-	 */
-	public static void parse(String sqlString, Recognizer recognizer) throws QueryException {
-		boolean hasMainOutputParameter = sqlString.indexOf( "call" ) > 0 &&
-		                                 sqlString.indexOf( "?" ) < sqlString.indexOf( "call" ) &&
-		                                 sqlString.indexOf( "=" ) < sqlString.indexOf( "call" );
-		boolean foundMainOutputParam = false;
-
-		int stringLength = sqlString.length();
-		boolean inQuote = false;
-		for ( int indx = 0; indx < stringLength; indx++ ) {
-			char c = sqlString.charAt( indx );
-			if ( inQuote ) {
-				if ( '\'' == c ) {
-					inQuote = false;
-				}
-				recognizer.other( c );
-			}
-			else if ( '\'' == c ) {
-				inQuote = true;
-				recognizer.other( c );
-			}
-			else {
-				if ( c == ':' ) {
-					// named parameter
-					int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
-					int chopLocation = right < 0 ? sqlString.length() : right;
-					String param = sqlString.substring( indx + 1, chopLocation );
-					if ( StringHelper.isEmpty( param ) ) {
-						throw new QueryException("Space is not allowed after parameter prefix ':' '"
-								+ sqlString + "'");
-					}
-					recognizer.namedParameter( param, indx );
-					indx = chopLocation - 1;
-				}
-				else if ( c == '?' ) {
-					// could be either an ordinal or JPA-positional parameter
-					if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) {
-						// a peek ahead showed this as an JPA-positional parameter
-						int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
-						int chopLocation = right < 0 ? sqlString.length() : right;
-						String param = sqlString.substring( indx + 1, chopLocation );
-						// make sure this "name" is an integral
-						try {
-							new Integer( param );
-						}
-						catch( NumberFormatException e ) {
-							throw new QueryException( "JPA-style positional param was not an integral ordinal" );
-						}
-						recognizer.jpaPositionalParameter( param, indx );
-						indx = chopLocation - 1;
-					}
-					else {
-						if ( hasMainOutputParameter && !foundMainOutputParam ) {
-							foundMainOutputParam = true;
-							recognizer.outParameter( indx );
-						}
-						else {
-							recognizer.ordinalParameter( indx );
-						}
-					}
-				}
-				else {
-					recognizer.other( c );
-				}
-			}
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/ParameterParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ParameterParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,132 @@
+/*
+ * 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.engine.query;
+
+import org.hibernate.QueryException;
+import org.hibernate.hql.classic.ParserHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * The single available method {@link #parse} is responsible for parsing a
+ * query string and recognizing tokens in relation to parameters (either
+ * named, JPA-style, or ordinal) and providing callbacks about such
+ * recognitions.
+ *
+ * @author Steve Ebersole
+ */
+public class ParameterParser {
+
+	public static interface Recognizer {
+		public void outParameter(int position);
+		public void ordinalParameter(int position);
+		public void namedParameter(String name, int position);
+		public void jpaPositionalParameter(String name, int position);
+		public void other(char character);
+	}
+
+	private ParameterParser() {
+		// disallow instantiation
+	}
+
+	/**
+	 * Performs the actual parsing and tokenizing of the query string making appropriate
+	 * callbacks to the given recognizer upon recognition of the various tokens.
+	 * <p/>
+	 * Note that currently, this only knows how to deal with a single output
+	 * parameter (for callable statements).  If we later add support for
+	 * multiple output params, this, obviously, needs to change.
+	 *
+	 * @param sqlString The string to be parsed/tokenized.
+	 * @param recognizer The thing which handles recognition events.
+	 * @throws QueryException
+	 */
+	public static void parse(String sqlString, Recognizer recognizer) throws QueryException {
+		boolean hasMainOutputParameter = sqlString.indexOf( "call" ) > 0 &&
+		                                 sqlString.indexOf( "?" ) < sqlString.indexOf( "call" ) &&
+		                                 sqlString.indexOf( "=" ) < sqlString.indexOf( "call" );
+		boolean foundMainOutputParam = false;
+
+		int stringLength = sqlString.length();
+		boolean inQuote = false;
+		for ( int indx = 0; indx < stringLength; indx++ ) {
+			char c = sqlString.charAt( indx );
+			if ( inQuote ) {
+				if ( '\'' == c ) {
+					inQuote = false;
+				}
+				recognizer.other( c );
+			}
+			else if ( '\'' == c ) {
+				inQuote = true;
+				recognizer.other( c );
+			}
+			else {
+				if ( c == ':' ) {
+					// named parameter
+					int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
+					int chopLocation = right < 0 ? sqlString.length() : right;
+					String param = sqlString.substring( indx + 1, chopLocation );
+					if ( StringHelper.isEmpty( param ) ) {
+						throw new QueryException("Space is not allowed after parameter prefix ':' '"
+								+ sqlString + "'");
+					}
+					recognizer.namedParameter( param, indx );
+					indx = chopLocation - 1;
+				}
+				else if ( c == '?' ) {
+					// could be either an ordinal or JPA-positional parameter
+					if ( indx < stringLength - 1 && Character.isDigit( sqlString.charAt( indx + 1 ) ) ) {
+						// a peek ahead showed this as an JPA-positional parameter
+						int right = StringHelper.firstIndexOfChar( sqlString, ParserHelper.HQL_SEPARATORS, indx + 1 );
+						int chopLocation = right < 0 ? sqlString.length() : right;
+						String param = sqlString.substring( indx + 1, chopLocation );
+						// make sure this "name" is an integral
+						try {
+							new Integer( param );
+						}
+						catch( NumberFormatException e ) {
+							throw new QueryException( "JPA-style positional param was not an integral ordinal" );
+						}
+						recognizer.jpaPositionalParameter( param, indx );
+						indx = chopLocation - 1;
+					}
+					else {
+						if ( hasMainOutputParameter && !foundMainOutputParam ) {
+							foundMainOutputParam = true;
+							recognizer.outParameter( indx );
+						}
+						else {
+							recognizer.ordinalParameter( indx );
+						}
+					}
+				}
+				else {
+					recognizer.other( c );
+				}
+			}
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-import java.util.Set;
-
-/**
- * Defines metadata regarding a translated HQL or native-SQL query.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class QueryMetadata implements Serializable {
-	private final String sourceQuery;
-	private final ParameterMetadata parameterMetadata;
-	private final String[] returnAliases;
-	private final Type[] returnTypes;
-	private final Set querySpaces;
-
-	public QueryMetadata(
-			String sourceQuery,
-	        ParameterMetadata parameterMetadata,
-	        String[] returnAliases,
-	        Type[] returnTypes,
-	        Set querySpaces) {
-		this.sourceQuery = sourceQuery;
-		this.parameterMetadata = parameterMetadata;
-		this.returnAliases = returnAliases;
-		this.returnTypes = returnTypes;
-		this.querySpaces = querySpaces;
-	}
-
-	/**
-	 * Get the source HQL or native-SQL query.
-	 *
-	 * @return The source query.
-	 */
-	public String getSourceQuery() {
-		return sourceQuery;
-	}
-
-	public ParameterMetadata getParameterMetadata() {
-		return parameterMetadata;
-	}
-
-	/**
-	 * Return source query select clause aliases (if any)
-	 *
-	 * @return an array of aliases as strings.
-	 */
-	public String[] getReturnAliases() {
-		return returnAliases;
-	}
-
-	/**
-	 * An array of types describing the returns of the source query.
-	 *
-	 * @return The return type array.
-	 */
-	public Type[] getReturnTypes() {
-		return returnTypes;
-	}
-
-	/**
-	 * The set of query spaces affected by this source query.
-	 *
-	 * @return The set of query spaces.
-	 */
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Defines metadata regarding a translated HQL or native-SQL query.
+ *
+ * @author Steve Ebersole
+ */
+public class QueryMetadata implements Serializable {
+	private final String sourceQuery;
+	private final ParameterMetadata parameterMetadata;
+	private final String[] returnAliases;
+	private final Type[] returnTypes;
+	private final Set querySpaces;
+
+	public QueryMetadata(
+			String sourceQuery,
+	        ParameterMetadata parameterMetadata,
+	        String[] returnAliases,
+	        Type[] returnTypes,
+	        Set querySpaces) {
+		this.sourceQuery = sourceQuery;
+		this.parameterMetadata = parameterMetadata;
+		this.returnAliases = returnAliases;
+		this.returnTypes = returnTypes;
+		this.querySpaces = querySpaces;
+	}
+
+	/**
+	 * Get the source HQL or native-SQL query.
+	 *
+	 * @return The source query.
+	 */
+	public String getSourceQuery() {
+		return sourceQuery;
+	}
+
+	public ParameterMetadata getParameterMetadata() {
+		return parameterMetadata;
+	}
+
+	/**
+	 * Return source query select clause aliases (if any)
+	 *
+	 * @return an array of aliases as strings.
+	 */
+	public String[] getReturnAliases() {
+		return returnAliases;
+	}
+
+	/**
+	 * An array of types describing the returns of the source query.
+	 *
+	 * @return The return type array.
+	 */
+	public Type[] getReturnTypes() {
+		return returnTypes;
+	}
+
+	/**
+	 * The set of query spaces affected by this source query.
+	 *
+	 * @return The set of query spaces.
+	 */
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,263 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.SimpleMRUCache;
-import org.hibernate.util.SoftLimitMRUCache;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.QueryException;
-import org.hibernate.MappingException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
-
-/**
- * Acts as a cache for compiled query plans, as well as query-parameter metadata.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class QueryPlanCache implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger( QueryPlanCache.class );
-
-	private SessionFactoryImplementor factory;
-
-	public QueryPlanCache(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	// simple cache of param metadata based on query string.  Ideally, the
-	// original "user-supplied query" string should be used to retreive this
-	// metadata (i.e., not the para-list-expanded query string) to avoid
-	// unnecessary cache entries.
-	// Used solely for caching param metadata for native-sql queries, see
-	// getSQLParameterMetadata() for a discussion as to why...
-	private final SimpleMRUCache sqlParamMetadataCache = new SimpleMRUCache();
-
-	// the cache of the actual plans...
-	private final SoftLimitMRUCache planCache = new SoftLimitMRUCache( 128 );
-
-
-	public ParameterMetadata getSQLParameterMetadata(String query) {
-		ParameterMetadata metadata = ( ParameterMetadata ) sqlParamMetadataCache.get( query );
-		if ( metadata == null ) {
-			// for native-sql queries, the param metadata is determined outside
-			// any relation to a query plan, because query plan creation and/or
-			// retreival for a native-sql query depends on all of the return
-			// types having been set, which might not be the case up-front when
-			// param metadata would be most useful
-			metadata = buildNativeSQLParameterMetadata( query );
-			sqlParamMetadataCache.put( query, metadata );
-		}
-		return metadata;
-	}
-
-	public HQLQueryPlan getHQLQueryPlan(String queryString, boolean shallow, Map enabledFilters)
-			throws QueryException, MappingException {
-		HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters );
-		HQLQueryPlan plan = ( HQLQueryPlan ) planCache.get ( key );
-
-		if ( plan == null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "unable to locate HQL query plan in cache; generating (" + queryString + ")" );
-			}
-			plan = new HQLQueryPlan(queryString, shallow, enabledFilters, factory );
-		}
-		else {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "located HQL query plan in cache (" + queryString + ")" );
-			}
-		}
-
-		planCache.put( key, plan );
-
-		return plan;
-	}
-
-	public FilterQueryPlan getFilterQueryPlan(String filterString, String collectionRole, boolean shallow, Map enabledFilters)
-			throws QueryException, MappingException {
-		FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters );
-		FilterQueryPlan plan = ( FilterQueryPlan ) planCache.get ( key );
-
-		if ( plan == null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "unable to locate collection-filter query plan in cache; generating (" + collectionRole + " : " + filterString + ")" );
-			}
-			plan = new FilterQueryPlan( filterString, collectionRole, shallow, enabledFilters, factory );
-		}
-		else {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "located collection-filter query plan in cache (" + collectionRole + " : " + filterString + ")" );
-			}
-		}
-
-		planCache.put( key, plan );
-
-		return plan;
-	}
-
-	public NativeSQLQueryPlan getNativeSQLQueryPlan(NativeSQLQuerySpecification spec) {
-		NativeSQLQueryPlan plan = ( NativeSQLQueryPlan ) planCache.get( spec );
-
-		if ( plan == null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "unable to locate native-sql query plan in cache; generating (" + spec.getQueryString() + ")" );
-			}
-			plan = new NativeSQLQueryPlan( spec, factory );
-		}
-		else {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "located native-sql query plan in cache (" + spec.getQueryString() + ")" );
-			}
-		}
-
-		planCache.put( spec, plan );
-		return plan;
-	}
-
-	private ParameterMetadata buildNativeSQLParameterMetadata(String sqlString) {
-		ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( sqlString );
-
-		OrdinalParameterDescriptor[] ordinalDescriptors =
-				new OrdinalParameterDescriptor[ recognizer.getOrdinalParameterLocationList().size() ];
-		for ( int i = 0; i < recognizer.getOrdinalParameterLocationList().size(); i++ ) {
-			final Integer position = ( Integer ) recognizer.getOrdinalParameterLocationList().get( i );
-			ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position.intValue() );
-		}
-
-		Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator();
-		Map namedParamDescriptorMap = new HashMap();
-		while( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final String name = ( String ) entry.getKey();
-			final ParamLocationRecognizer.NamedParameterDescription description =
-					( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue();
-			namedParamDescriptorMap.put(
-					name ,
-			        new NamedParameterDescriptor( name, null, description.buildPositionsArray(), description.isJpaStyle() )
-			);
-		}
-
-		return new ParameterMetadata( ordinalDescriptors, namedParamDescriptorMap );
-	}
-
-	private static class HQLQueryPlanKey implements Serializable {
-		private final String query;
-		private final boolean shallow;
-		private final Set filterNames;
-		private final int hashCode;
-
-		public HQLQueryPlanKey(String query, boolean shallow, Map enabledFilters) {
-			this.query = query;
-			this.shallow = shallow;
-
-			if ( enabledFilters == null || enabledFilters.isEmpty() ) {
-				filterNames = Collections.EMPTY_SET;
-			}
-			else {
-				Set tmp = new HashSet();
-				tmp.addAll( enabledFilters.keySet() );
-				this.filterNames = Collections.unmodifiableSet( tmp );
-			}
-
-			int hash = query.hashCode();
-			hash = 29 * hash + ( shallow ? 1 : 0 );
-			hash = 29 * hash + filterNames.hashCode();
-			this.hashCode = hash;
-		}
-
-		public boolean equals(Object o) {
-			if ( this == o ) {
-				return true;
-			}
-			if ( o == null || getClass() != o.getClass() ) {
-				return false;
-			}
-
-			final HQLQueryPlanKey that = ( HQLQueryPlanKey ) o;
-
-			if ( shallow != that.shallow ) {
-				return false;
-			}
-			if ( !filterNames.equals( that.filterNames ) ) {
-				return false;
-			}
-			if ( !query.equals( that.query ) ) {
-				return false;
-			}
-
-			return true;
-		}
-
-		public int hashCode() {
-			return hashCode;
-		}
-	}
-
-	private static class FilterQueryPlanKey implements Serializable {
-		private final String query;
-		private final String collectionRole;
-		private final boolean shallow;
-		private final Set filterNames;
-		private final int hashCode;
-
-		public FilterQueryPlanKey(String query, String collectionRole, boolean shallow, Map enabledFilters) {
-			this.query = query;
-			this.collectionRole = collectionRole;
-			this.shallow = shallow;
-
-			if ( enabledFilters == null || enabledFilters.isEmpty() ) {
-				filterNames = Collections.EMPTY_SET;
-			}
-			else {
-				Set tmp = new HashSet();
-				tmp.addAll( enabledFilters.keySet() );
-				this.filterNames = Collections.unmodifiableSet( tmp );
-			}
-
-			int hash = query.hashCode();
-			hash = 29 * hash + collectionRole.hashCode();
-			hash = 29 * hash + ( shallow ? 1 : 0 );
-			hash = 29 * hash + filterNames.hashCode();
-			this.hashCode = hash;
-		}
-
-		public boolean equals(Object o) {
-			if ( this == o ) {
-				return true;
-			}
-			if ( o == null || getClass() != o.getClass() ) {
-				return false;
-			}
-
-			final FilterQueryPlanKey that = ( FilterQueryPlanKey ) o;
-
-			if ( shallow != that.shallow ) {
-				return false;
-			}
-			if ( !filterNames.equals( that.filterNames ) ) {
-				return false;
-			}
-			if ( !query.equals( that.query ) ) {
-				return false;
-			}
-			if ( !collectionRole.equals( that.collectionRole ) ) {
-				return false;
-			}
-
-			return true;
-		}
-
-		public int hashCode() {
-			return hashCode;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/QueryPlanCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,285 @@
+/*
+ * 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.engine.query;
+
+import org.hibernate.util.SimpleMRUCache;
+import org.hibernate.util.SoftLimitMRUCache;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.QueryException;
+import org.hibernate.MappingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+/**
+ * Acts as a cache for compiled query plans, as well as query-parameter metadata.
+ *
+ * @author Steve Ebersole
+ */
+public class QueryPlanCache implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger( QueryPlanCache.class );
+
+	private SessionFactoryImplementor factory;
+
+	public QueryPlanCache(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	// simple cache of param metadata based on query string.  Ideally, the
+	// original "user-supplied query" string should be used to retreive this
+	// metadata (i.e., not the para-list-expanded query string) to avoid
+	// unnecessary cache entries.
+	// Used solely for caching param metadata for native-sql queries, see
+	// getSQLParameterMetadata() for a discussion as to why...
+	private final SimpleMRUCache sqlParamMetadataCache = new SimpleMRUCache();
+
+	// the cache of the actual plans...
+	private final SoftLimitMRUCache planCache = new SoftLimitMRUCache( 128 );
+
+
+	public ParameterMetadata getSQLParameterMetadata(String query) {
+		ParameterMetadata metadata = ( ParameterMetadata ) sqlParamMetadataCache.get( query );
+		if ( metadata == null ) {
+			// for native-sql queries, the param metadata is determined outside
+			// any relation to a query plan, because query plan creation and/or
+			// retreival for a native-sql query depends on all of the return
+			// types having been set, which might not be the case up-front when
+			// param metadata would be most useful
+			metadata = buildNativeSQLParameterMetadata( query );
+			sqlParamMetadataCache.put( query, metadata );
+		}
+		return metadata;
+	}
+
+	public HQLQueryPlan getHQLQueryPlan(String queryString, boolean shallow, Map enabledFilters)
+			throws QueryException, MappingException {
+		HQLQueryPlanKey key = new HQLQueryPlanKey( queryString, shallow, enabledFilters );
+		HQLQueryPlan plan = ( HQLQueryPlan ) planCache.get ( key );
+
+		if ( plan == null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "unable to locate HQL query plan in cache; generating (" + queryString + ")" );
+			}
+			plan = new HQLQueryPlan(queryString, shallow, enabledFilters, factory );
+		}
+		else {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "located HQL query plan in cache (" + queryString + ")" );
+			}
+		}
+
+		planCache.put( key, plan );
+
+		return plan;
+	}
+
+	public FilterQueryPlan getFilterQueryPlan(String filterString, String collectionRole, boolean shallow, Map enabledFilters)
+			throws QueryException, MappingException {
+		FilterQueryPlanKey key = new FilterQueryPlanKey( filterString, collectionRole, shallow, enabledFilters );
+		FilterQueryPlan plan = ( FilterQueryPlan ) planCache.get ( key );
+
+		if ( plan == null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "unable to locate collection-filter query plan in cache; generating (" + collectionRole + " : " + filterString + ")" );
+			}
+			plan = new FilterQueryPlan( filterString, collectionRole, shallow, enabledFilters, factory );
+		}
+		else {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "located collection-filter query plan in cache (" + collectionRole + " : " + filterString + ")" );
+			}
+		}
+
+		planCache.put( key, plan );
+
+		return plan;
+	}
+
+	public NativeSQLQueryPlan getNativeSQLQueryPlan(NativeSQLQuerySpecification spec) {
+		NativeSQLQueryPlan plan = ( NativeSQLQueryPlan ) planCache.get( spec );
+
+		if ( plan == null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "unable to locate native-sql query plan in cache; generating (" + spec.getQueryString() + ")" );
+			}
+			plan = new NativeSQLQueryPlan( spec, factory );
+		}
+		else {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "located native-sql query plan in cache (" + spec.getQueryString() + ")" );
+			}
+		}
+
+		planCache.put( spec, plan );
+		return plan;
+	}
+
+	private ParameterMetadata buildNativeSQLParameterMetadata(String sqlString) {
+		ParamLocationRecognizer recognizer = ParamLocationRecognizer.parseLocations( sqlString );
+
+		OrdinalParameterDescriptor[] ordinalDescriptors =
+				new OrdinalParameterDescriptor[ recognizer.getOrdinalParameterLocationList().size() ];
+		for ( int i = 0; i < recognizer.getOrdinalParameterLocationList().size(); i++ ) {
+			final Integer position = ( Integer ) recognizer.getOrdinalParameterLocationList().get( i );
+			ordinalDescriptors[i] = new OrdinalParameterDescriptor( i, null, position.intValue() );
+		}
+
+		Iterator itr = recognizer.getNamedParameterDescriptionMap().entrySet().iterator();
+		Map namedParamDescriptorMap = new HashMap();
+		while( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final String name = ( String ) entry.getKey();
+			final ParamLocationRecognizer.NamedParameterDescription description =
+					( ParamLocationRecognizer.NamedParameterDescription ) entry.getValue();
+			namedParamDescriptorMap.put(
+					name ,
+			        new NamedParameterDescriptor( name, null, description.buildPositionsArray(), description.isJpaStyle() )
+			);
+		}
+
+		return new ParameterMetadata( ordinalDescriptors, namedParamDescriptorMap );
+	}
+
+	private static class HQLQueryPlanKey implements Serializable {
+		private final String query;
+		private final boolean shallow;
+		private final Set filterNames;
+		private final int hashCode;
+
+		public HQLQueryPlanKey(String query, boolean shallow, Map enabledFilters) {
+			this.query = query;
+			this.shallow = shallow;
+
+			if ( enabledFilters == null || enabledFilters.isEmpty() ) {
+				filterNames = Collections.EMPTY_SET;
+			}
+			else {
+				Set tmp = new HashSet();
+				tmp.addAll( enabledFilters.keySet() );
+				this.filterNames = Collections.unmodifiableSet( tmp );
+			}
+
+			int hash = query.hashCode();
+			hash = 29 * hash + ( shallow ? 1 : 0 );
+			hash = 29 * hash + filterNames.hashCode();
+			this.hashCode = hash;
+		}
+
+		public boolean equals(Object o) {
+			if ( this == o ) {
+				return true;
+			}
+			if ( o == null || getClass() != o.getClass() ) {
+				return false;
+			}
+
+			final HQLQueryPlanKey that = ( HQLQueryPlanKey ) o;
+
+			if ( shallow != that.shallow ) {
+				return false;
+			}
+			if ( !filterNames.equals( that.filterNames ) ) {
+				return false;
+			}
+			if ( !query.equals( that.query ) ) {
+				return false;
+			}
+
+			return true;
+		}
+
+		public int hashCode() {
+			return hashCode;
+		}
+	}
+
+	private static class FilterQueryPlanKey implements Serializable {
+		private final String query;
+		private final String collectionRole;
+		private final boolean shallow;
+		private final Set filterNames;
+		private final int hashCode;
+
+		public FilterQueryPlanKey(String query, String collectionRole, boolean shallow, Map enabledFilters) {
+			this.query = query;
+			this.collectionRole = collectionRole;
+			this.shallow = shallow;
+
+			if ( enabledFilters == null || enabledFilters.isEmpty() ) {
+				filterNames = Collections.EMPTY_SET;
+			}
+			else {
+				Set tmp = new HashSet();
+				tmp.addAll( enabledFilters.keySet() );
+				this.filterNames = Collections.unmodifiableSet( tmp );
+			}
+
+			int hash = query.hashCode();
+			hash = 29 * hash + collectionRole.hashCode();
+			hash = 29 * hash + ( shallow ? 1 : 0 );
+			hash = 29 * hash + filterNames.hashCode();
+			this.hashCode = hash;
+		}
+
+		public boolean equals(Object o) {
+			if ( this == o ) {
+				return true;
+			}
+			if ( o == null || getClass() != o.getClass() ) {
+				return false;
+			}
+
+			final FilterQueryPlanKey that = ( FilterQueryPlanKey ) o;
+
+			if ( shallow != that.shallow ) {
+				return false;
+			}
+			if ( !filterNames.equals( that.filterNames ) ) {
+				return false;
+			}
+			if ( !query.equals( that.query ) ) {
+				return false;
+			}
+			if ( !collectionRole.equals( that.collectionRole ) ) {
+				return false;
+			}
+
+			return true;
+		}
+
+		public int hashCode() {
+			return hashCode;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-package org.hibernate.engine.query;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-
-/**
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class ReturnMetadata implements Serializable {
-	private final String[] returnAliases;
-	private final Type[] returnTypes;
-
-	public ReturnMetadata(String[] returnAliases, Type[] returnTypes) {
-		this.returnAliases = returnAliases;
-		this.returnTypes = returnTypes;
-	}
-
-	public String[] getReturnAliases() {
-		return returnAliases;
-	}
-
-	public Type[] getReturnTypes() {
-		return returnTypes;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/ReturnMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.engine.query;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+
+/**
+ * @author Steve Ebersole
+ */
+public class ReturnMetadata implements Serializable {
+	private final String[] returnAliases;
+	private final Type[] returnTypes;
+
+	public ReturnMetadata(String[] returnAliases, Type[] returnTypes) {
+		this.returnAliases = returnAliases;
+		this.returnTypes = returnTypes;
+	}
+
+	public String[] getReturnAliases() {
+		return returnAliases;
+	}
+
+	public Type[] getReturnTypes() {
+		return returnTypes;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-// $Id: NativeSQLQueryCollectionReturn.java 7232 2005-06-19 17:16:40 -0500 (Sun, 19 Jun 2005) maxcsaucdk $
-package org.hibernate.engine.query.sql;
-
-import java.util.Map;
-
-import org.hibernate.LockMode;
-
-/**
- * Represents a return defined as part of a native sql query which
- * names a collection role in the form {classname}.{collectionrole}; it
- * is used in defining a custom sql query for loading an entity's
- * collection in non-fetching scenarios (i.e., loading the collection
- * itself as the "root" of the result).
- *
- * @author Steve Ebersole
- */
-public class NativeSQLQueryCollectionReturn extends NativeSQLQueryNonScalarReturn {
-	private String ownerEntityName;
-	private String ownerProperty;
-
-	/**
-	 * Construct a native-sql return representing a collection initializer
-	 *
-	 * @param alias The result alias
-	 * @param ownerEntityName The entity-name of the entity owning the collection
-	 * to be initialized.
-	 * @param ownerProperty The property name (on the owner) which represents
-	 * the collection to be initialized.
-	 * @param propertyResults Any user-supplied column->property mappings
-	 * @param lockMode The lock mode to apply to the collection.
-	 */
-	public NativeSQLQueryCollectionReturn(
-			String alias,
-			String ownerEntityName,
-			String ownerProperty,
-			Map propertyResults,
-			LockMode lockMode) {
-		super( alias, propertyResults, lockMode );
-		this.ownerEntityName = ownerEntityName;
-		this.ownerProperty = ownerProperty;
-	}
-
-	/**
-	 * Returns the class owning the collection.
-	 *
-	 * @return The class owning the collection.
-	 */
-	public String getOwnerEntityName() {
-		return ownerEntityName;
-	}
-
-	/**
-	 * Returns the name of the property representing the collection from the {@link #getOwnerEntityName}.
-	 *
-	 * @return The name of the property representing the collection on the owner class.
-	 */
-	public String getOwnerProperty() {
-		return ownerProperty;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryCollectionReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.engine.query.sql;
+
+import java.util.Map;
+
+import org.hibernate.LockMode;
+
+/**
+ * Represents a return defined as part of a native sql query which
+ * names a collection role in the form {classname}.{collectionrole}; it
+ * is used in defining a custom sql query for loading an entity's
+ * collection in non-fetching scenarios (i.e., loading the collection
+ * itself as the "root" of the result).
+ *
+ * @author Steve Ebersole
+ */
+public class NativeSQLQueryCollectionReturn extends NativeSQLQueryNonScalarReturn {
+	private String ownerEntityName;
+	private String ownerProperty;
+
+	/**
+	 * Construct a native-sql return representing a collection initializer
+	 *
+	 * @param alias The result alias
+	 * @param ownerEntityName The entity-name of the entity owning the collection
+	 * to be initialized.
+	 * @param ownerProperty The property name (on the owner) which represents
+	 * the collection to be initialized.
+	 * @param propertyResults Any user-supplied column->property mappings
+	 * @param lockMode The lock mode to apply to the collection.
+	 */
+	public NativeSQLQueryCollectionReturn(
+			String alias,
+			String ownerEntityName,
+			String ownerProperty,
+			Map propertyResults,
+			LockMode lockMode) {
+		super( alias, propertyResults, lockMode );
+		this.ownerEntityName = ownerEntityName;
+		this.ownerProperty = ownerProperty;
+	}
+
+	/**
+	 * Returns the class owning the collection.
+	 *
+	 * @return The class owning the collection.
+	 */
+	public String getOwnerEntityName() {
+		return ownerEntityName;
+	}
+
+	/**
+	 * Returns the name of the property representing the collection from the {@link #getOwnerEntityName}.
+	 *
+	 * @return The name of the property representing the collection on the owner class.
+	 */
+	public String getOwnerProperty() {
+		return ownerProperty;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,56 +0,0 @@
-// $Id: NativeSQLQueryJoinReturn.java 7232 2005-06-19 17:16:40 -0500 (Sun, 19 Jun 2005) maxcsaucdk $
-package org.hibernate.engine.query.sql;
-
-import java.util.Map;
-
-import org.hibernate.LockMode;
-
-/**
- * Represents a return defined as part of a native sql query which
- * names a fetched role.
- *
- * @author Steve Ebersole
- */
-public class NativeSQLQueryJoinReturn extends NativeSQLQueryNonScalarReturn {
-	private String ownerAlias;
-	private String ownerProperty;
-
-	/**
-	 * Construct a return descriptor representing some form of fetch.
-	 *
-	 * @param alias The result alias
-	 * @param ownerAlias The owner's result alias
-	 * @param ownerProperty The owner's property representing the thing to be fetched
-	 * @param propertyResults Any user-supplied column->property mappings
-	 * @param lockMode The lock mode to apply
-	 */
-	public NativeSQLQueryJoinReturn(
-			String alias,
-			String ownerAlias,
-			String ownerProperty,
-			Map propertyResults,
-			LockMode lockMode) {
-		super( alias, propertyResults, lockMode );
-		this.ownerAlias = ownerAlias;
-		this.ownerProperty = ownerProperty;
-	}
-
-	/**
-	 * Retrieve the alias of the owner of this fetched association.
-	 *
-	 * @return The owner's alias.
-	 */
-	public String getOwnerAlias() {
-		return ownerAlias;
-	}
-
-	/**
-	 * Retrieve the property name (relative to the owner) which maps to
-	 * the association to be fetched.
-	 *
-	 * @return The property name.
-	 */
-	public String getOwnerProperty() {
-		return ownerProperty;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryJoinReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query.sql;
+
+import java.util.Map;
+
+import org.hibernate.LockMode;
+
+/**
+ * Represents a return defined as part of a native sql query which
+ * names a fetched role.
+ *
+ * @author Steve Ebersole
+ */
+public class NativeSQLQueryJoinReturn extends NativeSQLQueryNonScalarReturn {
+	private String ownerAlias;
+	private String ownerProperty;
+
+	/**
+	 * Construct a return descriptor representing some form of fetch.
+	 *
+	 * @param alias The result alias
+	 * @param ownerAlias The owner's result alias
+	 * @param ownerProperty The owner's property representing the thing to be fetched
+	 * @param propertyResults Any user-supplied column->property mappings
+	 * @param lockMode The lock mode to apply
+	 */
+	public NativeSQLQueryJoinReturn(
+			String alias,
+			String ownerAlias,
+			String ownerProperty,
+			Map propertyResults,
+			LockMode lockMode) {
+		super( alias, propertyResults, lockMode );
+		this.ownerAlias = ownerAlias;
+		this.ownerProperty = ownerProperty;
+	}
+
+	/**
+	 * Retrieve the alias of the owner of this fetched association.
+	 *
+	 * @return The owner's alias.
+	 */
+	public String getOwnerAlias() {
+		return ownerAlias;
+	}
+
+	/**
+	 * Retrieve the property name (relative to the owner) which maps to
+	 * the association to be fetched.
+	 *
+	 * @return The property name.
+	 */
+	public String getOwnerProperty() {
+		return ownerProperty;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,67 +0,0 @@
-// $Id: NativeSQLQueryNonScalarReturn.java 7232 2005-06-19 17:16:40 -0500 (Sun, 19 Jun 2005) maxcsaucdk $
-package org.hibernate.engine.query.sql;
-
-import java.io.Serializable;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-
-/**
- * Represents the base information for a non-scalar return defined as part of
- * a native sql query.
- *
- * @author Steve Ebersole
- */
-public abstract class NativeSQLQueryNonScalarReturn implements NativeSQLQueryReturn, Serializable {
-	private final String alias;
-	private final LockMode lockMode;
-	private final Map propertyResults = new HashMap();
-
-	/**
-	 * Constructs some form of non-scalar return descriptor
-	 *
-	 * @param alias The result alias
-	 * @param propertyResults Any user-supplied column->property mappings
-	 * @param lockMode The lock mode to apply to the return.
-	 */
-	protected NativeSQLQueryNonScalarReturn(String alias, Map propertyResults, LockMode lockMode) {
-		this.alias = alias;
-		if ( alias == null ) {
-			throw new HibernateException("alias must be specified");
-		}
-		this.lockMode = lockMode;
-		if ( propertyResults != null ) {
-			this.propertyResults.putAll( propertyResults );
-		}
-	}
-
-	/**
-	 * Retrieve the defined result alias
-	 *
-	 * @return The result alias.
-	 */
-	public String getAlias() {
-		return alias;
-	}
-
-	/**
-	 * Retrieve the lock-mode to apply to this return
-	 *
-	 * @return The lock mode
-	 */
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-
-	/**
-	 * Retrieve the user-supplied column->property mappings.
-	 *
-	 * @return The property mappings.
-	 */
-	public Map getPropertyResultsMap() {
-		return Collections.unmodifiableMap( propertyResults );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryNonScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,90 @@
+/*
+ * 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.engine.query.sql;
+
+import java.io.Serializable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+
+/**
+ * Represents the base information for a non-scalar return defined as part of
+ * a native sql query.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class NativeSQLQueryNonScalarReturn implements NativeSQLQueryReturn, Serializable {
+	private final String alias;
+	private final LockMode lockMode;
+	private final Map propertyResults = new HashMap();
+
+	/**
+	 * Constructs some form of non-scalar return descriptor
+	 *
+	 * @param alias The result alias
+	 * @param propertyResults Any user-supplied column->property mappings
+	 * @param lockMode The lock mode to apply to the return.
+	 */
+	protected NativeSQLQueryNonScalarReturn(String alias, Map propertyResults, LockMode lockMode) {
+		this.alias = alias;
+		if ( alias == null ) {
+			throw new HibernateException("alias must be specified");
+		}
+		this.lockMode = lockMode;
+		if ( propertyResults != null ) {
+			this.propertyResults.putAll( propertyResults );
+		}
+	}
+
+	/**
+	 * Retrieve the defined result alias
+	 *
+	 * @return The result alias.
+	 */
+	public String getAlias() {
+		return alias;
+	}
+
+	/**
+	 * Retrieve the lock-mode to apply to this return
+	 *
+	 * @return The lock mode
+	 */
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+
+	/**
+	 * Retrieve the user-supplied column->property mappings.
+	 *
+	 * @return The property mappings.
+	 */
+	public Map getPropertyResultsMap() {
+		return Collections.unmodifiableMap( propertyResults );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-package org.hibernate.engine.query.sql;
-
-/**
- * Describes a return in a native SQL query.
- *
- * @author Steve Ebersole
- */
-public interface NativeSQLQueryReturn {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+/*
+ * 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.engine.query.sql;
+
+/**
+ * Describes a return in a native SQL query.
+ *
+ * @author Steve Ebersole
+ */
+public interface NativeSQLQueryReturn {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-// $Id: NativeSQLQueryRootReturn.java 7232 2005-06-19 17:16:40 -0500 (Sun, 19 Jun 2005) maxcsaucdk $
-package org.hibernate.engine.query.sql;
-
-import java.util.Map;
-
-import org.hibernate.LockMode;
-
-/**
- * Represents a return defined as part of a native sql query which
- * names a "root" entity.  A root entity means it is explicitly a
- * "column" in the result, as opposed to a fetched relationship or role.
- *
- * @author Steve Ebersole
- */
-public class NativeSQLQueryRootReturn extends NativeSQLQueryNonScalarReturn {
-	private String returnEntityName;
-
-	/**
-	 * Construct a return representing an entity returned at the root
-	 * of the result.
-	 *
-	 * @param alias The result alias
-	 * @param entityName The entity name.
-	 * @param lockMode The lock mode to apply
-	 */
-	public NativeSQLQueryRootReturn(String alias, String entityName, LockMode lockMode) {
-		this(alias, entityName, null, lockMode);
-	}
-
-	/**
-	 *
-	 * @param alias The result alias
-	 * @param entityName The entity name.
-	 * @param propertyResults Any user-supplied column->property mappings
-	 * @param lockMode The lock mode to apply
-	 */
-	public NativeSQLQueryRootReturn(String alias, String entityName, Map propertyResults, LockMode lockMode) {
-		super( alias, propertyResults, lockMode );
-		this.returnEntityName = entityName;
-
-	}
-
-	/**
-	 * The name of the entity to be returned.
-	 *
-	 * @return The entity name
-	 */
-	public String getReturnEntityName() {
-		return returnEntityName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryRootReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.engine.query.sql;
+
+import java.util.Map;
+
+import org.hibernate.LockMode;
+
+/**
+ * Represents a return defined as part of a native sql query which
+ * names a "root" entity.  A root entity means it is explicitly a
+ * "column" in the result, as opposed to a fetched relationship or role.
+ *
+ * @author Steve Ebersole
+ */
+public class NativeSQLQueryRootReturn extends NativeSQLQueryNonScalarReturn {
+	private String returnEntityName;
+
+	/**
+	 * Construct a return representing an entity returned at the root
+	 * of the result.
+	 *
+	 * @param alias The result alias
+	 * @param entityName The entity name.
+	 * @param lockMode The lock mode to apply
+	 */
+	public NativeSQLQueryRootReturn(String alias, String entityName, LockMode lockMode) {
+		this(alias, entityName, null, lockMode);
+	}
+
+	/**
+	 *
+	 * @param alias The result alias
+	 * @param entityName The entity name.
+	 * @param propertyResults Any user-supplied column->property mappings
+	 * @param lockMode The lock mode to apply
+	 */
+	public NativeSQLQueryRootReturn(String alias, String entityName, Map propertyResults, LockMode lockMode) {
+		super( alias, propertyResults, lockMode );
+		this.returnEntityName = entityName;
+
+	}
+
+	/**
+	 * The name of the entity to be returned.
+	 *
+	 * @return The entity name
+	 */
+	public String getReturnEntityName() {
+		return returnEntityName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-package org.hibernate.engine.query.sql;
-
-import org.hibernate.type.Type;
-
-/**
- * Describes a scalar return in a native SQL query.
- *
- * @author gloegl
- */
-public class NativeSQLQueryScalarReturn implements NativeSQLQueryReturn {
-	private Type type;
-	private String columnAlias;
-
-	public NativeSQLQueryScalarReturn(String alias, Type type) {
-		this.type = type;
-		this.columnAlias = alias;
-	}
-
-	public String getColumnAlias() {
-		return columnAlias;
-	}
-
-	public Type getType() {
-		return type;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQueryScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.engine.query.sql;
+
+import org.hibernate.type.Type;
+
+/**
+ * Describes a scalar return in a native SQL query.
+ *
+ * @author gloegl
+ */
+public class NativeSQLQueryScalarReturn implements NativeSQLQueryReturn {
+	private Type type;
+	private String columnAlias;
+
+	public NativeSQLQueryScalarReturn(String alias, Type type) {
+		this.type = type;
+		this.columnAlias = alias;
+	}
+
+	public String getColumnAlias() {
+		return columnAlias;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,80 +0,0 @@
-package org.hibernate.engine.query.sql;
-
-import org.hibernate.util.ArrayHelper;
-
-import java.util.Set;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Arrays;
-import java.util.Collections;
-
-/**
- * Defines the specification or blue-print for a native-sql query.
- * Essentially a simple struct containing the information needed to "translate"
- * a native-sql query and cache that translated representation.  Also used as
- * the key by which the native-sql query plans are cached.
- *
- * @author Steve Ebersole
- */
-public class NativeSQLQuerySpecification {
-	private final String queryString;
-	private final NativeSQLQueryReturn[] queryReturns;
-	private final Set querySpaces;
-	private final int hashCode;
-
-	public NativeSQLQuerySpecification(
-			String queryString,
-	        NativeSQLQueryReturn[] queryReturns,
-	        Collection querySpaces) {
-		this.queryString = queryString;
-		this.queryReturns = queryReturns;
-		if ( querySpaces == null ) {
-			this.querySpaces = Collections.EMPTY_SET;
-		}
-		else {
-			Set tmp = new HashSet();
-			tmp.addAll( querySpaces );
-			this.querySpaces = Collections.unmodifiableSet( tmp );
-		}
-
-		// pre-determine and cache the hashcode
-		int hashCode = queryString.hashCode();
-		hashCode = 29 * hashCode + this.querySpaces.hashCode();
-		if ( this.queryReturns != null ) {
-			hashCode = 29 * hashCode + ArrayHelper.toList( this.queryReturns ).hashCode();
-		}
-		this.hashCode = hashCode;
-	}
-
-	public String getQueryString() {
-		return queryString;
-	}
-
-	public NativeSQLQueryReturn[] getQueryReturns() {
-		return queryReturns;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	public boolean equals(Object o) {
-		if ( this == o ) {
-			return true;
-		}
-		if ( o == null || getClass() != o.getClass() ) {
-			return false;
-		}
-
-		final NativeSQLQuerySpecification that = ( NativeSQLQuerySpecification ) o;
-
-		return querySpaces.equals( that.querySpaces ) &&
-		       queryString.equals( that.queryString ) &&
-		       Arrays.equals( queryReturns, that.queryReturns );
-	}
-
-
-	public int hashCode() {
-		return hashCode;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/query/sql/NativeSQLQuerySpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.query.sql;
+
+import org.hibernate.util.ArrayHelper;
+
+import java.util.Set;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * Defines the specification or blue-print for a native-sql query.
+ * Essentially a simple struct containing the information needed to "translate"
+ * a native-sql query and cache that translated representation.  Also used as
+ * the key by which the native-sql query plans are cached.
+ *
+ * @author Steve Ebersole
+ */
+public class NativeSQLQuerySpecification {
+	private final String queryString;
+	private final NativeSQLQueryReturn[] queryReturns;
+	private final Set querySpaces;
+	private final int hashCode;
+
+	public NativeSQLQuerySpecification(
+			String queryString,
+	        NativeSQLQueryReturn[] queryReturns,
+	        Collection querySpaces) {
+		this.queryString = queryString;
+		this.queryReturns = queryReturns;
+		if ( querySpaces == null ) {
+			this.querySpaces = Collections.EMPTY_SET;
+		}
+		else {
+			Set tmp = new HashSet();
+			tmp.addAll( querySpaces );
+			this.querySpaces = Collections.unmodifiableSet( tmp );
+		}
+
+		// pre-determine and cache the hashcode
+		int hashCode = queryString.hashCode();
+		hashCode = 29 * hashCode + this.querySpaces.hashCode();
+		if ( this.queryReturns != null ) {
+			hashCode = 29 * hashCode + ArrayHelper.toList( this.queryReturns ).hashCode();
+		}
+		this.hashCode = hashCode;
+	}
+
+	public String getQueryString() {
+		return queryString;
+	}
+
+	public NativeSQLQueryReturn[] getQueryReturns() {
+		return queryReturns;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+
+		final NativeSQLQuerySpecification that = ( NativeSQLQuerySpecification ) o;
+
+		return querySpaces.equals( that.querySpaces ) &&
+		       queryString.equals( that.queryString ) &&
+		       Arrays.equals( queryReturns, that.queryReturns );
+	}
+
+
+	public int hashCode() {
+		return hashCode;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-package org.hibernate.engine.transaction;
-
-import org.hibernate.HibernateException;
-
-import java.sql.Connection;
-
-/**
- * Represents work that needs to be performed in a manner
- * which isolates it from any current application unit of
- * work transaction.
- *
- * @author Steve Ebersole
- */
-public interface IsolatedWork {
-	/**
-	 * Perform the actual work to be done.
-	 *
-	 * @param connection The JDBC connection to use.
-	 * @throws HibernateException
-	 */
-	public void doWork(Connection connection) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/IsolatedWork.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.engine.transaction;
+
+import org.hibernate.HibernateException;
+
+import java.sql.Connection;
+
+/**
+ * Represents work that needs to be performed in a manner
+ * which isolates it from any current application unit of
+ * work transaction.
+ *
+ * @author Steve Ebersole
+ */
+public interface IsolatedWork {
+	/**
+	 * Perform the actual work to be done.
+	 *
+	 * @param connection The JDBC connection to use.
+	 * @throws HibernateException
+	 */
+	public void doWork(Connection connection) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/engine/transaction/Isolater.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,230 +0,0 @@
-package org.hibernate.engine.transaction;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-/**
- * Class which provides the isolation semantics required by
- * an {@link IsolatedWork}.  Processing comes in two flavors:<ul>
- * <li>{@link #doIsolatedWork} : makes sure the work to be done is
- * performed in a seperate, distinct transaction</li>
- * <li>{@link #doNonTransactedWork} : makes sure the work to be
- * done is performed outside the scope of any transaction</li>
- * </ul>
- *
- * @author Steve Ebersole
- */
-public class Isolater {
-
-	private static final Logger log = LoggerFactory.getLogger( Isolater.class );
-
-	/**
-	 * Ensures that all processing actually performed by the given work will
-	 * occur on a seperate transaction.
-	 *
-	 * @param work The work to be performed.
-	 * @param session The session from which this request is originating.
-	 * @throws HibernateException
-	 */
-	public static void doIsolatedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
-		boolean isJta = session.getFactory().getTransactionManager() != null;
-		if ( isJta ) {
-			new JtaDelegate( session ).delegateWork( work, true );
-		}
-		else {
-			new JdbcDelegate( session ).delegateWork( work, true );
-		}
-	}
-
-	/**
-	 * Ensures that all processing actually performed by the given work will
-	 * occur outside of a transaction.
-	 *
-	 * @param work The work to be performed.
-	 * @param session The session from which this request is originating.
-	 * @throws HibernateException
-	 */
-	public static void doNonTransactedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
-		boolean isJta = session.getFactory().getTransactionManager() != null;
-		if ( isJta ) {
-			new JtaDelegate( session ).delegateWork( work, false );
-		}
-		else {
-			new JdbcDelegate( session ).delegateWork( work, false );
-		}
-	}
-
-	// should be ok performance-wise to generate new delegate instances for each
-	// request since these are locally stack-scoped.  Besides, it makes the code
-	// much easier to read than the old TransactionHelper stuff...
-
-	private static interface Delegate {
-		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException;
-	}
-
-	/**
-	 * An isolation delegate for JTA-based transactions.  Essentially susepnds
-	 * any current transaction, does the work in a new transaction, and then
-	 * resumes the initial transaction (if there was one).
-	 */
-	public static class JtaDelegate implements Delegate {
-		private final SessionImplementor session;
-
-		public JtaDelegate(SessionImplementor session) {
-			this.session = session;
-		}
-
-		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
-			TransactionManager transactionManager = session.getFactory().getTransactionManager();
-			Transaction surroundingTransaction = null;
-			Connection connection = null;
-			boolean caughtException = false;
-
-			try {
-				// First we need to suspend any current JTA transaction and obtain
-				// a JDBC connection
-				surroundingTransaction = transactionManager.suspend();
-				if ( log.isDebugEnabled() ) {
-					log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
-				}
-
-				if ( transacted ) {
-					transactionManager.begin();
-				}
-
-				connection = session.getBatcher().openConnection();
-
-				// perform the actual work
-				work.doWork( connection );
-
-				// if everything went ok, commit the transaction and close the obtained
-				// connection handle...
-				session.getBatcher().closeConnection( connection );
-
-				if ( transacted ) {
-					transactionManager.commit();
-				}
-			}
-			catch( Throwable t ) {
-				// at some point the processing went bad, so we need to:
-				//      1) make sure the connection handle gets released
-				//      2) try to cleanup the JTA context as much as possible
-				caughtException = true;
-				try {
-					if ( connection != null && !connection.isClosed() ) {
-						session.getBatcher().closeConnection( connection );
-					}
-				}
-				catch( Throwable ignore ) {
-					log.trace( "unable to release connection on exception [" + ignore + "]" );
-				}
-				if ( transacted ) {
-					try {
-						transactionManager.rollback();
-					}
-					catch( Throwable ignore ) {
-						log.trace( "unable to rollback new transaction on exception [" + ignore + "]" );
-					}
-				}
-				// finally handle the exception
-				if ( t instanceof HibernateException ) {
-					throw ( HibernateException ) t;
-				}
-				else {
-					throw new HibernateException( "error performing isolated work", t );
-				}
-			}
-			finally {
-				if ( surroundingTransaction != null ) {
-					try {
-						transactionManager.resume( surroundingTransaction );
-						if ( log.isDebugEnabled() ) {
-							log.debug( "surrounding JTA transaction resumed [" + surroundingTransaction + "]" );
-						}
-					}
-					catch( Throwable t ) {
-						if ( !caughtException ) {
-							throw new HibernateException( "unable to resume previously suspended transaction", t );
-						}
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * An isolation delegate for JDBC-based transactions.  Basically just
-	 * grabs a new connection and does the work on that.
-	 */
-	public static class JdbcDelegate implements Delegate {
-		private final SessionImplementor session;
-
-		public JdbcDelegate(SessionImplementor session) {
-			this.session = session;
-		}
-
-		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
-			Connection connection = null;
-			boolean wasAutoCommit = false;
-			try {
-				connection = session.getBatcher().openConnection();
-
-				if ( transacted ) {
-					if ( connection.getAutoCommit() ) {
-						wasAutoCommit = true;
-						connection.setAutoCommit( false );
-					}
-				}
-
-				work.doWork( connection );
-
-				if ( transacted ) {
-					connection.commit();
-				}
-			}
-			catch( Throwable t ) {
-				try {
-					if ( transacted && connection != null && !connection.isClosed() ) {
-						connection.rollback();
-					}
-				}
-				catch( Throwable ignore ) {
-					log.trace( "unable to release connection on exception [" + ignore + "]" );
-				}
-
-				if ( t instanceof HibernateException ) {
-					throw ( HibernateException ) t;
-				}
-				else if ( t instanceof SQLException ) {
-					throw JDBCExceptionHelper.convert(
-							session.getFactory().getSQLExceptionConverter(),
-					        ( SQLException ) t,
-					        "error performing isolated work"
-					);
-				}
-				else {
-					throw new HibernateException( "error performing isolated work", t );
-				}
-			}
-			finally {
-				if ( transacted && wasAutoCommit ) {
-					try {
-						connection.setAutoCommit( true );
-					}
-					catch( Throwable ignore ) {
-						log.trace( "was unable to reset connection back to auto-commit" );
-					}
-				}
-				session.getBatcher().closeConnection( connection );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java (from rev 14998, core/trunk/core/src/main/java/org/hibernate/engine/transaction/Isolater.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/engine/transaction/Isolater.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,256 @@
+/*
+ * 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.engine.transaction;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+/**
+ * Class which provides the isolation semantics required by
+ * an {@link IsolatedWork}.  Processing comes in two flavors:<ul>
+ * <li>{@link #doIsolatedWork} : makes sure the work to be done is
+ * performed in a seperate, distinct transaction</li>
+ * <li>{@link #doNonTransactedWork} : makes sure the work to be
+ * done is performed outside the scope of any transaction</li>
+ * </ul>
+ *
+ * @author Steve Ebersole
+ */
+public class Isolater {
+
+	private static final Logger log = LoggerFactory.getLogger( Isolater.class );
+
+	/**
+	 * Ensures that all processing actually performed by the given work will
+	 * occur on a seperate transaction.
+	 *
+	 * @param work The work to be performed.
+	 * @param session The session from which this request is originating.
+	 * @throws HibernateException
+	 */
+	public static void doIsolatedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
+		boolean isJta = session.getFactory().getTransactionManager() != null;
+		if ( isJta ) {
+			new JtaDelegate( session ).delegateWork( work, true );
+		}
+		else {
+			new JdbcDelegate( session ).delegateWork( work, true );
+		}
+	}
+
+	/**
+	 * Ensures that all processing actually performed by the given work will
+	 * occur outside of a transaction.
+	 *
+	 * @param work The work to be performed.
+	 * @param session The session from which this request is originating.
+	 * @throws HibernateException
+	 */
+	public static void doNonTransactedWork(IsolatedWork work, SessionImplementor session) throws HibernateException {
+		boolean isJta = session.getFactory().getTransactionManager() != null;
+		if ( isJta ) {
+			new JtaDelegate( session ).delegateWork( work, false );
+		}
+		else {
+			new JdbcDelegate( session ).delegateWork( work, false );
+		}
+	}
+
+	// should be ok performance-wise to generate new delegate instances for each
+	// request since these are locally stack-scoped.  Besides, it makes the code
+	// much easier to read than the old TransactionHelper stuff...
+
+	private static interface Delegate {
+		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException;
+	}
+
+	/**
+	 * An isolation delegate for JTA-based transactions.  Essentially susepnds
+	 * any current transaction, does the work in a new transaction, and then
+	 * resumes the initial transaction (if there was one).
+	 */
+	public static class JtaDelegate implements Delegate {
+		private final SessionImplementor session;
+
+		public JtaDelegate(SessionImplementor session) {
+			this.session = session;
+		}
+
+		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
+			TransactionManager transactionManager = session.getFactory().getTransactionManager();
+			Transaction surroundingTransaction = null;
+			Connection connection = null;
+			boolean caughtException = false;
+
+			try {
+				// First we need to suspend any current JTA transaction and obtain
+				// a JDBC connection
+				surroundingTransaction = transactionManager.suspend();
+				if ( log.isDebugEnabled() ) {
+					log.debug( "surrounding JTA transaction suspended [" + surroundingTransaction + "]" );
+				}
+
+				if ( transacted ) {
+					transactionManager.begin();
+				}
+
+				connection = session.getBatcher().openConnection();
+
+				// perform the actual work
+				work.doWork( connection );
+
+				// if everything went ok, commit the transaction and close the obtained
+				// connection handle...
+				session.getBatcher().closeConnection( connection );
+
+				if ( transacted ) {
+					transactionManager.commit();
+				}
+			}
+			catch( Throwable t ) {
+				// at some point the processing went bad, so we need to:
+				//      1) make sure the connection handle gets released
+				//      2) try to cleanup the JTA context as much as possible
+				caughtException = true;
+				try {
+					if ( connection != null && !connection.isClosed() ) {
+						session.getBatcher().closeConnection( connection );
+					}
+				}
+				catch( Throwable ignore ) {
+					log.trace( "unable to release connection on exception [" + ignore + "]" );
+				}
+				if ( transacted ) {
+					try {
+						transactionManager.rollback();
+					}
+					catch( Throwable ignore ) {
+						log.trace( "unable to rollback new transaction on exception [" + ignore + "]" );
+					}
+				}
+				// finally handle the exception
+				if ( t instanceof HibernateException ) {
+					throw ( HibernateException ) t;
+				}
+				else {
+					throw new HibernateException( "error performing isolated work", t );
+				}
+			}
+			finally {
+				if ( surroundingTransaction != null ) {
+					try {
+						transactionManager.resume( surroundingTransaction );
+						if ( log.isDebugEnabled() ) {
+							log.debug( "surrounding JTA transaction resumed [" + surroundingTransaction + "]" );
+						}
+					}
+					catch( Throwable t ) {
+						if ( !caughtException ) {
+							throw new HibernateException( "unable to resume previously suspended transaction", t );
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * An isolation delegate for JDBC-based transactions.  Basically just
+	 * grabs a new connection and does the work on that.
+	 */
+	public static class JdbcDelegate implements Delegate {
+		private final SessionImplementor session;
+
+		public JdbcDelegate(SessionImplementor session) {
+			this.session = session;
+		}
+
+		public void delegateWork(IsolatedWork work, boolean transacted) throws HibernateException {
+			Connection connection = null;
+			boolean wasAutoCommit = false;
+			try {
+				connection = session.getBatcher().openConnection();
+
+				if ( transacted ) {
+					if ( connection.getAutoCommit() ) {
+						wasAutoCommit = true;
+						connection.setAutoCommit( false );
+					}
+				}
+
+				work.doWork( connection );
+
+				if ( transacted ) {
+					connection.commit();
+				}
+			}
+			catch( Throwable t ) {
+				try {
+					if ( transacted && connection != null && !connection.isClosed() ) {
+						connection.rollback();
+					}
+				}
+				catch( Throwable ignore ) {
+					log.trace( "unable to release connection on exception [" + ignore + "]" );
+				}
+
+				if ( t instanceof HibernateException ) {
+					throw ( HibernateException ) t;
+				}
+				else if ( t instanceof SQLException ) {
+					throw JDBCExceptionHelper.convert(
+							session.getFactory().getSQLExceptionConverter(),
+					        ( SQLException ) t,
+					        "error performing isolated work"
+					);
+				}
+				else {
+					throw new HibernateException( "error performing isolated work", t );
+				}
+			}
+			finally {
+				if ( connection != null ) {
+					if ( transacted && wasAutoCommit ) {
+						try {
+							connection.setAutoCommit( true );
+						}
+						catch( Throwable ignore ) {
+							log.trace( "was unable to reset connection back to auto-commit" );
+						}
+					}
+					session.getBatcher().closeConnection( connection );
+				}
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,115 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * Defines a base class for events involving collections.
- *
- * @author Gail Badner
- */
-public abstract class AbstractCollectionEvent extends AbstractEvent {
-
-	private final PersistentCollection collection;
-	private final Object affectedOwner;
-	private final Serializable affectedOwnerId;
-	private final String affectedOwnerEntityName;
-
-	/**
-	 * Constructs an AbstractCollectionEvent object.
-	 *
-	 * @param collection - the collection
-	 * @param source - the Session source
-	 * @param affectedOwner - the owner that is affected by this event;
-	 * can be null if unavailable
-	 * @param affectedOwnerId - the ID for the owner that is affected
-	 * by this event; can be null if unavailable
-	 * that is affected by this event; can be null if unavailable
-	 */
-	public AbstractCollectionEvent( CollectionPersister collectionPersister,
-					PersistentCollection collection,
-					EventSource source,
-					Object affectedOwner,
-					Serializable affectedOwnerId) {
-		super(source);
-		this.collection = collection;
-		this.affectedOwner = affectedOwner;
-		this.affectedOwnerId = affectedOwnerId;
-		this.affectedOwnerEntityName =
-				getAffectedOwnerEntityName( collectionPersister, affectedOwner, source );
-	}
-
-	protected static CollectionPersister getLoadedCollectionPersister( PersistentCollection collection, EventSource source ) {
-		CollectionEntry ce = source.getPersistenceContext().getCollectionEntry( collection );
-		return ( ce == null ? null : ce.getLoadedPersister() );		
-	}
-
-	protected static Object getLoadedOwnerOrNull( PersistentCollection collection, EventSource source ) {
-		return source.getPersistenceContext().getLoadedCollectionOwnerOrNull( collection );
-	}
-
-	protected static Serializable getLoadedOwnerIdOrNull( PersistentCollection collection, EventSource source ) {
-		return source.getPersistenceContext().getLoadedCollectionOwnerIdOrNull( collection );
-	}
-
-	protected static Serializable getOwnerIdOrNull( Object owner, EventSource source ) {
-		EntityEntry ownerEntry = source.getPersistenceContext().getEntry( owner );
-		return ( ownerEntry == null ? null : ownerEntry.getId() );
-	}
-
-	protected static String getAffectedOwnerEntityName(CollectionPersister collectionPersister, Object affectedOwner, EventSource source ) {
-
-		// collectionPersister should not be null, but we don't want to throw
-		// an exception if it is null
-		String entityName =
-				( collectionPersister == null ? null : collectionPersister.getOwnerEntityPersister().getEntityName() );
-		if ( affectedOwner != null ) {
-			EntityEntry ee = source.getPersistenceContext().getEntry( affectedOwner );
-			if ( ee != null && ee.getEntityName() != null) {
-				entityName = ee.getEntityName();
-			}
-		}	
-		return entityName;
-	}
-
-	public PersistentCollection getCollection() {
-		return collection;
-	}
-
-	/**
-	 * Get the collection owner entity that is affected by this event.
-	 *
-	 * @return the affected owner; returns null if the entity is not in the persistence context
-	 * (e.g., because the collection from a detached entity was moved to a new owner)
-	 */
-	public Object getAffectedOwnerOrNull() {
-		return affectedOwner;
-	}
-
-	/**
-	 * Get the ID for the collection owner entity that is affected by this event.
-	 *
-	 * @return the affected owner ID; returns null if the ID cannot be obtained
-	 * from the collection's loaded key (e.g., a property-ref is used for the
-	 * collection and does not include the entity's ID)
-	 */
-	public Serializable getAffectedOwnerIdOrNull() {
-		return affectedOwnerId;
-	}
-
-	/**
-	 * Get the entity name for the collection owner entity that is affected by this event.
-	 *
-	 * @return the entity name; if the owner is not in the PersistenceContext, the
-	 * returned value may be a superclass name, instead of the actual class name
-	 */
-	public String getAffectedOwnerEntityName() {
-		return affectedOwnerEntityName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractCollectionEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,138 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * Defines a base class for events involving collections.
+ *
+ * @author Gail Badner
+ */
+public abstract class AbstractCollectionEvent extends AbstractEvent {
+
+	private final PersistentCollection collection;
+	private final Object affectedOwner;
+	private final Serializable affectedOwnerId;
+	private final String affectedOwnerEntityName;
+
+	/**
+	 * Constructs an AbstractCollectionEvent object.
+	 *
+	 * @param collection - the collection
+	 * @param source - the Session source
+	 * @param affectedOwner - the owner that is affected by this event;
+	 * can be null if unavailable
+	 * @param affectedOwnerId - the ID for the owner that is affected
+	 * by this event; can be null if unavailable
+	 * that is affected by this event; can be null if unavailable
+	 */
+	public AbstractCollectionEvent( CollectionPersister collectionPersister,
+					PersistentCollection collection,
+					EventSource source,
+					Object affectedOwner,
+					Serializable affectedOwnerId) {
+		super(source);
+		this.collection = collection;
+		this.affectedOwner = affectedOwner;
+		this.affectedOwnerId = affectedOwnerId;
+		this.affectedOwnerEntityName =
+				getAffectedOwnerEntityName( collectionPersister, affectedOwner, source );
+	}
+
+	protected static CollectionPersister getLoadedCollectionPersister( PersistentCollection collection, EventSource source ) {
+		CollectionEntry ce = source.getPersistenceContext().getCollectionEntry( collection );
+		return ( ce == null ? null : ce.getLoadedPersister() );		
+	}
+
+	protected static Object getLoadedOwnerOrNull( PersistentCollection collection, EventSource source ) {
+		return source.getPersistenceContext().getLoadedCollectionOwnerOrNull( collection );
+	}
+
+	protected static Serializable getLoadedOwnerIdOrNull( PersistentCollection collection, EventSource source ) {
+		return source.getPersistenceContext().getLoadedCollectionOwnerIdOrNull( collection );
+	}
+
+	protected static Serializable getOwnerIdOrNull( Object owner, EventSource source ) {
+		EntityEntry ownerEntry = source.getPersistenceContext().getEntry( owner );
+		return ( ownerEntry == null ? null : ownerEntry.getId() );
+	}
+
+	protected static String getAffectedOwnerEntityName(CollectionPersister collectionPersister, Object affectedOwner, EventSource source ) {
+
+		// collectionPersister should not be null, but we don't want to throw
+		// an exception if it is null
+		String entityName =
+				( collectionPersister == null ? null : collectionPersister.getOwnerEntityPersister().getEntityName() );
+		if ( affectedOwner != null ) {
+			EntityEntry ee = source.getPersistenceContext().getEntry( affectedOwner );
+			if ( ee != null && ee.getEntityName() != null) {
+				entityName = ee.getEntityName();
+			}
+		}	
+		return entityName;
+	}
+
+	public PersistentCollection getCollection() {
+		return collection;
+	}
+
+	/**
+	 * Get the collection owner entity that is affected by this event.
+	 *
+	 * @return the affected owner; returns null if the entity is not in the persistence context
+	 * (e.g., because the collection from a detached entity was moved to a new owner)
+	 */
+	public Object getAffectedOwnerOrNull() {
+		return affectedOwner;
+	}
+
+	/**
+	 * Get the ID for the collection owner entity that is affected by this event.
+	 *
+	 * @return the affected owner ID; returns null if the ID cannot be obtained
+	 * from the collection's loaded key (e.g., a property-ref is used for the
+	 * collection and does not include the entity's ID)
+	 */
+	public Serializable getAffectedOwnerIdOrNull() {
+		return affectedOwnerId;
+	}
+
+	/**
+	 * Get the entity name for the collection owner entity that is affected by this event.
+	 *
+	 * @return the entity name; if the owner is not in the PersistenceContext, the
+	 * returned value may be a superclass name, instead of the actual class name
+	 */
+	public String getAffectedOwnerEntityName() {
+		return affectedOwnerEntityName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/AbstractEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: AbstractEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-
-/**
- * Defines a base class for Session generated events.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractEvent implements Serializable {
-
-	private final EventSource session;
-
-    /**
-     * Constructs an event from the given event session.
-     *
-     * @param source The session event source.
-     */
-	public AbstractEvent(EventSource source) {
-		this.session = source;
-	}
-
-    /**
-     * Returns the session event source for this event.  This is the underlying
-     * session from which this event was generated.
-     *
-     * @return The session event source.
-     */
-	public final EventSource getSession() {
-		return session;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/AbstractEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AbstractEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+
+/**
+ * Defines a base class for Session generated events.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractEvent implements Serializable {
+
+	private final EventSource session;
+
+    /**
+     * Constructs an event from the given event session.
+     *
+     * @param source The session event source.
+     */
+	public AbstractEvent(EventSource source) {
+		this.session = source;
+	}
+
+    /**
+     * Returns the session event source for this event.  This is the underlying
+     * session from which this event was generated.
+     *
+     * @return The session event source.
+     */
+	public final EventSource getSession() {
+		return session;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/AutoFlushEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-///$Id: AutoFlushEvent.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.util.Set;
-
-
-/** Defines an event class for the auto-flushing of a session.
- *
- * @author Steve Ebersole
- */
-public class AutoFlushEvent extends FlushEvent {
-
-	private Set querySpaces;
-	private boolean flushRequired;
-
-	public AutoFlushEvent(Set querySpaces, EventSource source) {
-		super(source);
-		this.querySpaces = querySpaces;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	public void setQuerySpaces(Set querySpaces) {
-		this.querySpaces = querySpaces;
-	}
-
-	public boolean isFlushRequired() {
-		return flushRequired;
-	}
-
-	public void setFlushRequired(boolean dirty) {
-		this.flushRequired = dirty;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/AutoFlushEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.util.Set;
+
+
+/** Defines an event class for the auto-flushing of a session.
+ *
+ * @author Steve Ebersole
+ */
+public class AutoFlushEvent extends FlushEvent {
+
+	private Set querySpaces;
+	private boolean flushRequired;
+
+	public AutoFlushEvent(Set querySpaces, EventSource source) {
+		super(source);
+		this.querySpaces = querySpaces;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	public void setQuerySpaces(Set querySpaces) {
+		this.querySpaces = querySpaces;
+	}
+
+	public boolean isFlushRequired() {
+		return flushRequired;
+	}
+
+	public void setFlushRequired(boolean dirty) {
+		this.flushRequired = dirty;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: AutoFlushEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of session auto-flush events.
- *
- * @author Steve Ebersole
- */
-public interface AutoFlushEventListener extends Serializable {
-
-    /** Handle the given auto-flush event.
-     *
-     * @param event The auto-flush event to be handled.
-     * @throws HibernateException
-     */
-	public void onAutoFlush(AutoFlushEvent event) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/AutoFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of session auto-flush events.
+ *
+ * @author Steve Ebersole
+ */
+public interface AutoFlushEventListener extends Serializable {
+
+    /** Handle the given auto-flush event.
+     *
+     * @param event The auto-flush event to be handled.
+     * @throws HibernateException
+     */
+	public void onAutoFlush(AutoFlushEvent event) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/DeleteEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-//$Id: DeleteEvent.java 7450 2005-07-11 20:33:59Z steveebersole $
-package org.hibernate.event;
-
-
-/** Defines an event class for the deletion of an entity.
- *
- * @author Steve Ebersole
- */
-public class DeleteEvent extends AbstractEvent {
-
-	private Object object;
-	private String entityName;
-	private boolean cascadeDeleteEnabled;
-
-	/**
-	 * Constructs a new DeleteEvent instance.
-	 *
-	 * @param object The entity to be deleted.
-	 * @param source The session from which the delete event was generated.
-	 */
-	public DeleteEvent(Object object, EventSource source) {
-		super(source);
-		if (object == null) {
-			throw new IllegalArgumentException(
-					"attempt to create delete event with null entity"
-				);
-		}
-		this.object = object;
-	}
-
-	public DeleteEvent(String entityName, Object object, EventSource source) {
-		this(object, source);
-		this.entityName = entityName;
-	}
-
-	public DeleteEvent(String entityName, Object object, boolean isCascadeDeleteEnabled, EventSource source) {
-		this(object, source);
-		this.entityName = entityName;
-		cascadeDeleteEnabled = isCascadeDeleteEnabled;
-	}
-
-	/**
-     * Returns the encapsulated entity to be deleed.
-     *
-     * @return The entity to be deleted.
-     */
-	public Object getObject() {
-		return object;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-	
-	public boolean isCascadeDeleteEnabled() {
-		return cascadeDeleteEnabled;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/DeleteEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+
+/** Defines an event class for the deletion of an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteEvent extends AbstractEvent {
+
+	private Object object;
+	private String entityName;
+	private boolean cascadeDeleteEnabled;
+
+	/**
+	 * Constructs a new DeleteEvent instance.
+	 *
+	 * @param object The entity to be deleted.
+	 * @param source The session from which the delete event was generated.
+	 */
+	public DeleteEvent(Object object, EventSource source) {
+		super(source);
+		if (object == null) {
+			throw new IllegalArgumentException(
+					"attempt to create delete event with null entity"
+				);
+		}
+		this.object = object;
+	}
+
+	public DeleteEvent(String entityName, Object object, EventSource source) {
+		this(object, source);
+		this.entityName = entityName;
+	}
+
+	public DeleteEvent(String entityName, Object object, boolean isCascadeDeleteEnabled, EventSource source) {
+		this(object, source);
+		this.entityName = entityName;
+		cascadeDeleteEnabled = isCascadeDeleteEnabled;
+	}
+
+	/**
+     * Returns the encapsulated entity to be deleed.
+     *
+     * @return The entity to be deleted.
+     */
+	public Object getObject() {
+		return object;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+	
+	public boolean isCascadeDeleteEnabled() {
+		return cascadeDeleteEnabled;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/DeleteEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: DeleteEventListener.java 9944 2006-05-24 21:14:56Z steve.ebersole at jboss.com $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-import java.util.Set;
-
-/**
- * Defines the contract for handling of deletion events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface DeleteEventListener extends Serializable {
-
-    /** Handle the given delete event.
-     *
-     * @param event The delete event to be handled.
-     * @throws HibernateException
-     */
-	public void onDelete(DeleteEvent event) throws HibernateException;
-
-	public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/DeleteEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+import java.util.Set;
+
+/**
+ * Defines the contract for handling of deletion events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface DeleteEventListener extends Serializable {
+
+    /** Handle the given delete event.
+     *
+     * @param event The delete event to be handled.
+     * @throws HibernateException
+     */
+	public void onDelete(DeleteEvent event) throws HibernateException;
+
+	public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/Destructible.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +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.event;
-
-/**
- * Contract for listeners which require notification of SessionFactory closing,
- * presumably to destroy internal state.
- *
- * @author Steve Ebersole
- */
-public interface Destructible {
-	/**
-	 * Notification of {@link org.hibernate.SessionFactory} shutdown.
-	 */
-	public void cleanup();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/Destructible.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Destructible.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+/**
+ * Contract for listeners which require notification of SessionFactory closing,
+ * presumably to destroy internal state.
+ *
+ * @author Steve Ebersole
+ */
+public interface Destructible {
+	/**
+	 * Notification of {@link org.hibernate.SessionFactory} shutdown.
+	 */
+	public void cleanup();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: DirtyCheckEvent.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-
-/** Defines an event class for the dirty-checking of a session.
- *
- * @author Steve Ebersole
- */
-public class DirtyCheckEvent extends FlushEvent {
-	
-	private boolean dirty;
-
-	public DirtyCheckEvent(EventSource source) {
-		super(source);
-	}
-
-	public boolean isDirty() {
-		return dirty;
-	}
-
-	public void setDirty(boolean dirty) {
-		this.dirty = dirty;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.event;
+
+
+/** Defines an event class for the dirty-checking of a session.
+ *
+ * @author Steve Ebersole
+ */
+public class DirtyCheckEvent extends FlushEvent {
+	
+	private boolean dirty;
+
+	public DirtyCheckEvent(EventSource source) {
+		super(source);
+	}
+
+	public boolean isDirty() {
+		return dirty;
+	}
+
+	public void setDirty(boolean dirty) {
+		this.dirty = dirty;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: DirtyCheckEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of session dirty-check events.
- *
- * @author Steve Ebersole
- */
-public interface DirtyCheckEventListener extends Serializable {
-
-    /** Handle the given dirty-check event.
-     *
-     * @param event The dirty-check event to be handled.
-     * @throws HibernateException
-     */
-	public void onDirtyCheck(DirtyCheckEvent event) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/DirtyCheckEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of session dirty-check events.
+ *
+ * @author Steve Ebersole
+ */
+public interface DirtyCheckEventListener extends Serializable {
+
+    /** Handle the given dirty-check event.
+     *
+     * @param event The dirty-check event to be handled.
+     * @throws HibernateException
+     */
+	public void onDirtyCheck(DirtyCheckEvent event) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/EventListeners.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,512 +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.event;
-
-import java.io.Serializable;
-import java.lang.reflect.Field;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.event.def.DefaultAutoFlushEventListener;
-import org.hibernate.event.def.DefaultDeleteEventListener;
-import org.hibernate.event.def.DefaultDirtyCheckEventListener;
-import org.hibernate.event.def.DefaultEvictEventListener;
-import org.hibernate.event.def.DefaultFlushEntityEventListener;
-import org.hibernate.event.def.DefaultFlushEventListener;
-import org.hibernate.event.def.DefaultInitializeCollectionEventListener;
-import org.hibernate.event.def.DefaultLoadEventListener;
-import org.hibernate.event.def.DefaultLockEventListener;
-import org.hibernate.event.def.DefaultMergeEventListener;
-import org.hibernate.event.def.DefaultPersistEventListener;
-import org.hibernate.event.def.DefaultPostLoadEventListener;
-import org.hibernate.event.def.DefaultPreLoadEventListener;
-import org.hibernate.event.def.DefaultRefreshEventListener;
-import org.hibernate.event.def.DefaultReplicateEventListener;
-import org.hibernate.event.def.DefaultSaveEventListener;
-import org.hibernate.event.def.DefaultSaveOrUpdateCopyEventListener;
-import org.hibernate.event.def.DefaultSaveOrUpdateEventListener;
-import org.hibernate.event.def.DefaultUpdateEventListener;
-import org.hibernate.event.def.DefaultPersistOnFlushEventListener;
-import org.hibernate.util.Cloneable;
-
-/**
- * A convience holder for all defined session event listeners.
- *
- * @author Steve Ebersole
- */
-public class EventListeners extends Cloneable implements Serializable {
-
-	private LoadEventListener[] loadEventListeners = { new DefaultLoadEventListener() };
-	private SaveOrUpdateEventListener[] saveOrUpdateEventListeners = { new DefaultSaveOrUpdateEventListener() };
-	private MergeEventListener[] mergeEventListeners = { new DefaultMergeEventListener() };
-	private PersistEventListener[] persistEventListeners = { new DefaultPersistEventListener() };
-	private PersistEventListener[] persistOnFlushEventListeners = { new DefaultPersistOnFlushEventListener() };
-	private ReplicateEventListener[] replicateEventListeners = { new DefaultReplicateEventListener() };
-	private DeleteEventListener[] deleteEventListeners = { new DefaultDeleteEventListener() };
-	private AutoFlushEventListener[] autoFlushEventListeners = { new DefaultAutoFlushEventListener() };
-	private DirtyCheckEventListener[] dirtyCheckEventListeners = { new DefaultDirtyCheckEventListener() };
-	private FlushEventListener[] flushEventListeners = { new DefaultFlushEventListener() };
-	private EvictEventListener[] evictEventListeners = { new DefaultEvictEventListener() };
-	private LockEventListener[] lockEventListeners = { new DefaultLockEventListener() };
-	private RefreshEventListener[] refreshEventListeners = { new DefaultRefreshEventListener() };
-	private FlushEntityEventListener[] flushEntityEventListeners = { new DefaultFlushEntityEventListener() };
-	private InitializeCollectionEventListener[] initializeCollectionEventListeners = 
-			{ new DefaultInitializeCollectionEventListener() };
-
-	private PostLoadEventListener[] postLoadEventListeners = { new DefaultPostLoadEventListener() };
-	private PreLoadEventListener[] preLoadEventListeners = { new DefaultPreLoadEventListener() };
-	
-	private PreDeleteEventListener[] preDeleteEventListeners = {};
-	private PreUpdateEventListener[] preUpdateEventListeners = {};
-	private PreInsertEventListener[] preInsertEventListeners = {};
-	private PostDeleteEventListener[] postDeleteEventListeners = {};
-	private PostUpdateEventListener[] postUpdateEventListeners = {};
-	private PostInsertEventListener[] postInsertEventListeners = {};
-	private PostDeleteEventListener[] postCommitDeleteEventListeners = {};
-	private PostUpdateEventListener[] postCommitUpdateEventListeners = {};
-	private PostInsertEventListener[] postCommitInsertEventListeners = {};
-
-	private PreCollectionRecreateEventListener[] preCollectionRecreateEventListeners = {};
-	private PostCollectionRecreateEventListener[] postCollectionRecreateEventListeners = {};
-	private PreCollectionRemoveEventListener[] preCollectionRemoveEventListeners = {};
-	private PostCollectionRemoveEventListener[] postCollectionRemoveEventListeners = {};
-	private PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners = {};
-	private PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners = {};	
-
-	private SaveOrUpdateEventListener[] saveEventListeners = { new DefaultSaveEventListener() };
-	private SaveOrUpdateEventListener[] updateEventListeners = { new DefaultUpdateEventListener() };
-	private MergeEventListener[] saveOrUpdateCopyEventListeners = { new DefaultSaveOrUpdateCopyEventListener() };//saveOrUpdateCopy() is deprecated!
-
-	private static Map eventInterfaceFromType;
-
-	static {
-		eventInterfaceFromType = new HashMap();
-
-		eventInterfaceFromType.put("auto-flush", AutoFlushEventListener.class);
-		eventInterfaceFromType.put("merge", MergeEventListener.class);
-		eventInterfaceFromType.put("create", PersistEventListener.class);
-		eventInterfaceFromType.put("create-onflush", PersistEventListener.class);
-		eventInterfaceFromType.put("delete", DeleteEventListener.class);
-		eventInterfaceFromType.put("dirty-check", DirtyCheckEventListener.class);
-		eventInterfaceFromType.put("evict", EvictEventListener.class);
-		eventInterfaceFromType.put("flush", FlushEventListener.class);
-		eventInterfaceFromType.put("flush-entity", FlushEntityEventListener.class);
-		eventInterfaceFromType.put("load", LoadEventListener.class);
-		eventInterfaceFromType.put("load-collection", InitializeCollectionEventListener.class);
-		eventInterfaceFromType.put("lock", LockEventListener.class);
-		eventInterfaceFromType.put("refresh", RefreshEventListener.class);
-		eventInterfaceFromType.put("replicate", ReplicateEventListener.class);
-		eventInterfaceFromType.put("save-update", SaveOrUpdateEventListener.class);
-		eventInterfaceFromType.put("save", SaveOrUpdateEventListener.class);
-		eventInterfaceFromType.put("update", SaveOrUpdateEventListener.class);
-		eventInterfaceFromType.put("pre-load", PreLoadEventListener.class);
-		eventInterfaceFromType.put("pre-update", PreUpdateEventListener.class);
-		eventInterfaceFromType.put("pre-delete", PreDeleteEventListener.class);
-		eventInterfaceFromType.put("pre-insert", PreInsertEventListener.class);
-		eventInterfaceFromType.put("pre-collection-recreate", PreCollectionRecreateEventListener.class);
-		eventInterfaceFromType.put("pre-collection-remove", PreCollectionRemoveEventListener.class);
-		eventInterfaceFromType.put("pre-collection-update", PreCollectionUpdateEventListener.class);
-		eventInterfaceFromType.put("post-load", PostLoadEventListener.class);
-		eventInterfaceFromType.put("post-update", PostUpdateEventListener.class);
-		eventInterfaceFromType.put("post-delete", PostDeleteEventListener.class);
-		eventInterfaceFromType.put("post-insert", PostInsertEventListener.class);
-		eventInterfaceFromType.put("post-commit-update", PostUpdateEventListener.class);
-		eventInterfaceFromType.put("post-commit-delete", PostDeleteEventListener.class);
-		eventInterfaceFromType.put("post-commit-insert", PostInsertEventListener.class);
-		eventInterfaceFromType.put("post-collection-recreate", PostCollectionRecreateEventListener.class);
-		eventInterfaceFromType.put("post-collection-remove", PostCollectionRemoveEventListener.class);
-		eventInterfaceFromType.put("post-collection-update", PostCollectionUpdateEventListener.class);
-		eventInterfaceFromType = Collections.unmodifiableMap( eventInterfaceFromType );
-	}
-
-	public Class getListenerClassFor(String type) {
-		Class clazz = (Class) eventInterfaceFromType.get(type);
-		
-		if (clazz == null) {
-			throw new MappingException("Unrecognized listener type [" + type + "]");
-		}
-
-		return clazz;
-	}
-
-	private static interface ListenerProcesser {
-		public void processListener(Object listener);
-	}
-
-	private void processListeners(ListenerProcesser processer) {
-		Field[] fields = getClass().getDeclaredFields();
-		for ( int i = 0; i < fields.length; i++ ) {
-			final Object[] listeners;
-			try {
-				Object fieldValue = fields[i].get(this);
-				if ( fieldValue instanceof Object[] ) {
-					listeners = ( Object[] ) fieldValue;
-				}
-				else {
-					continue;
-				}
-			}
-			catch ( Throwable t ) {
-				throw new HibernateException( "could not init listeners", t );
-			}
-
-			int length = listeners.length;
-			for ( int index = 0 ; index < length ; index++ ) {
-				processer.processListener( listeners[index ] );
-			}
-		}
-	}
-
-	/**
-	 * Call {@link Initializable#initialize} on any listeners that implement the
-	 * {@link Initializable} interface.
-	 *
-	 * @param cfg The configuration.
-	 */
-	public void initializeListeners(final Configuration cfg) {
-		try {
-			processListeners(
-					new ListenerProcesser() {
-						public void processListener(Object listener) {
-							if ( listener instanceof Initializable ) {
-								( ( Initializable ) listener ).initialize( cfg );
-							}
-						}
-					}
-			);
-		}
-		catch ( Exception e ) {
-			throw new HibernateException("could not init listeners", e);
-		}
-	}
-
-	/**
-	 * Call {@link Destructible#cleanup} on any listeners that implement the
-	 * {@link Destructible} interface.
-	 */
-	public void destroyListeners() {
-		try {
-			processListeners(
-					new ListenerProcesser() {
-						public void processListener(Object listener) {
-							if ( listener instanceof Destructible ) {
-								( ( Destructible ) listener ).cleanup();
-							}
-						}
-					}
-			);
-		}
-		catch ( Exception e ) {
-			throw new HibernateException("could not destruct listeners", e);
-		}
-	}
-
-	public LoadEventListener[] getLoadEventListeners() {
-        return loadEventListeners;
-    }
-
-    public void setLoadEventListeners(LoadEventListener[] loadEventListener) {
-        this.loadEventListeners = loadEventListener;
-    }
-
-	public ReplicateEventListener[] getReplicateEventListeners() {
-		return replicateEventListeners;
-	}
-
-	public void setReplicateEventListeners(ReplicateEventListener[] replicateEventListener) {
-		this.replicateEventListeners = replicateEventListener;
-	}
-
-	public DeleteEventListener[] getDeleteEventListeners() {
-		return deleteEventListeners;
-	}
-
-	public void setDeleteEventListeners(DeleteEventListener[] deleteEventListener) {
-		this.deleteEventListeners = deleteEventListener;
-	}
-
-	public AutoFlushEventListener[] getAutoFlushEventListeners() {
-		return autoFlushEventListeners;
-	}
-
-	public void setAutoFlushEventListeners(AutoFlushEventListener[] autoFlushEventListener) {
-		this.autoFlushEventListeners = autoFlushEventListener;
-	}
-
-	public DirtyCheckEventListener[] getDirtyCheckEventListeners() {
-		return dirtyCheckEventListeners;
-	}
-
-	public void setDirtyCheckEventListeners(DirtyCheckEventListener[] dirtyCheckEventListener) {
-		this.dirtyCheckEventListeners = dirtyCheckEventListener;
-	}
-
-	public FlushEventListener[] getFlushEventListeners() {
-		return flushEventListeners;
-	}
-
-	public void setFlushEventListeners(FlushEventListener[] flushEventListener) {
-		this.flushEventListeners = flushEventListener;
-	}
-
-	public EvictEventListener[] getEvictEventListeners() {
-		return evictEventListeners;
-	}
-
-	public void setEvictEventListeners(EvictEventListener[] evictEventListener) {
-		this.evictEventListeners = evictEventListener;
-	}
-
-	public LockEventListener[] getLockEventListeners() {
-		return lockEventListeners;
-	}
-
-	public void setLockEventListeners(LockEventListener[] lockEventListener) {
-		this.lockEventListeners = lockEventListener;
-	}
-
-	public RefreshEventListener[] getRefreshEventListeners() {
-		return refreshEventListeners;
-	}
-
-	public void setRefreshEventListeners(RefreshEventListener[] refreshEventListener) {
-		this.refreshEventListeners = refreshEventListener;
-	}
-
-	public InitializeCollectionEventListener[] getInitializeCollectionEventListeners() {
-		return initializeCollectionEventListeners;
-	}
-
-	public void setInitializeCollectionEventListeners(InitializeCollectionEventListener[] initializeCollectionEventListener) {
-		this.initializeCollectionEventListeners = initializeCollectionEventListener;
-	}
-	
-	public FlushEntityEventListener[] getFlushEntityEventListeners() {
-		return flushEntityEventListeners;
-	}
-	
-	public void setFlushEntityEventListeners(FlushEntityEventListener[] flushEntityEventListener) {
-		this.flushEntityEventListeners = flushEntityEventListener;
-	}
-	
-	public SaveOrUpdateEventListener[] getSaveOrUpdateEventListeners() {
-		return saveOrUpdateEventListeners;
-	}
-	
-	public void setSaveOrUpdateEventListeners(SaveOrUpdateEventListener[] saveOrUpdateEventListener) {
-		this.saveOrUpdateEventListeners = saveOrUpdateEventListener;
-	}
-	
-	public MergeEventListener[] getMergeEventListeners() {
-		return mergeEventListeners;
-	}
-	
-	public void setMergeEventListeners(MergeEventListener[] mergeEventListener) {
-		this.mergeEventListeners = mergeEventListener;
-	}
-	
-	public PersistEventListener[] getPersistEventListeners() {
-		return persistEventListeners;
-	}
-	
-	public void setPersistEventListeners(PersistEventListener[] createEventListener) {
-		this.persistEventListeners = createEventListener;
-	}
-
-	public PersistEventListener[] getPersistOnFlushEventListeners() {
-		return persistOnFlushEventListeners;
-	}
-
-	public void setPersistOnFlushEventListeners(PersistEventListener[] createEventListener) {
-		this.persistOnFlushEventListeners = createEventListener;
-	}
-	
-	public MergeEventListener[] getSaveOrUpdateCopyEventListeners() {
-		return saveOrUpdateCopyEventListeners;
-	}
-	
-	public void setSaveOrUpdateCopyEventListeners(MergeEventListener[] saveOrUpdateCopyEventListener) {
-		this.saveOrUpdateCopyEventListeners = saveOrUpdateCopyEventListener;
-	}
-	
-	public SaveOrUpdateEventListener[] getSaveEventListeners() {
-		return saveEventListeners;
-	}
-	
-	public void setSaveEventListeners(SaveOrUpdateEventListener[] saveEventListener) {
-		this.saveEventListeners = saveEventListener;
-	}
-	
-	public SaveOrUpdateEventListener[] getUpdateEventListeners() {
-		return updateEventListeners;
-	}
-	
-	public void setUpdateEventListeners(SaveOrUpdateEventListener[] updateEventListener) {
-		this.updateEventListeners = updateEventListener;
-	}
-
-	public PostLoadEventListener[] getPostLoadEventListeners() {
-		return postLoadEventListeners;
-	}
-
-	public void setPostLoadEventListeners(PostLoadEventListener[] postLoadEventListener) {
-		this.postLoadEventListeners = postLoadEventListener;
-	}
-
-	public PreLoadEventListener[] getPreLoadEventListeners() {
-		return preLoadEventListeners;
-	}
-
-	public void setPreLoadEventListeners(PreLoadEventListener[] preLoadEventListener) {
-		this.preLoadEventListeners = preLoadEventListener;
-	}
-
-	public PreCollectionRecreateEventListener[] getPreCollectionRecreateEventListeners() {
-		return preCollectionRecreateEventListeners;
-	}
-
-	public void setPreCollectionRecreateEventListeners(PreCollectionRecreateEventListener[] preCollectionRecreateEventListener) {
-		this.preCollectionRecreateEventListeners = preCollectionRecreateEventListener;
-	}
-
-	public PreCollectionRemoveEventListener[] getPreCollectionRemoveEventListeners() {
-		return preCollectionRemoveEventListeners;
-	}
-
-	public void setPreCollectionRemoveEventListeners(PreCollectionRemoveEventListener[] preCollectionRemoveEventListener) {
-		this.preCollectionRemoveEventListeners = preCollectionRemoveEventListener;
-	}
-
-	public PreCollectionUpdateEventListener[] getPreCollectionUpdateEventListeners() {
-		return preCollectionUpdateEventListeners;
-	}
-
-	public void setPreCollectionUpdateEventListeners(PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners) {
-		this.preCollectionUpdateEventListeners = preCollectionUpdateEventListeners;
-	}
-
-	public PostDeleteEventListener[] getPostDeleteEventListeners() {
-		return postDeleteEventListeners;
-	}
-	
-	public PostInsertEventListener[] getPostInsertEventListeners() {
-		return postInsertEventListeners;
-	}
-	
-	public PostUpdateEventListener[] getPostUpdateEventListeners() {
-		return postUpdateEventListeners;
-	}
-	
-	public void setPostDeleteEventListeners(PostDeleteEventListener[] postDeleteEventListener) {
-		this.postDeleteEventListeners = postDeleteEventListener;
-	}
-	
-	public void setPostInsertEventListeners(PostInsertEventListener[] postInsertEventListener) {
-		this.postInsertEventListeners = postInsertEventListener;
-	}
-	
-	public void setPostUpdateEventListeners(PostUpdateEventListener[] postUpdateEventListener) {
-		this.postUpdateEventListeners = postUpdateEventListener;
-	}
-	
-	public PostCollectionRecreateEventListener[] getPostCollectionRecreateEventListeners() {
-		return postCollectionRecreateEventListeners;
-	}
-
-	public void setPostCollectionRecreateEventListeners(PostCollectionRecreateEventListener[] postCollectionRecreateEventListener) {
-		this.postCollectionRecreateEventListeners = postCollectionRecreateEventListener;
-	}
-
-	public PostCollectionRemoveEventListener[] getPostCollectionRemoveEventListeners() {
-		return postCollectionRemoveEventListeners;
-	}
-
-	public void setPostCollectionRemoveEventListeners(PostCollectionRemoveEventListener[] postCollectionRemoveEventListener) {
-		this.postCollectionRemoveEventListeners = postCollectionRemoveEventListener;
-	}	        
-
-	public PostCollectionUpdateEventListener[] getPostCollectionUpdateEventListeners() {
-		return postCollectionUpdateEventListeners;
-	}
-
-	public void setPostCollectionUpdateEventListeners(PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners) {
-		this.postCollectionUpdateEventListeners = postCollectionUpdateEventListeners;
-	}
-
-	public PreDeleteEventListener[] getPreDeleteEventListeners() {
-		return preDeleteEventListeners;
-	}
-	
-	public void setPreDeleteEventListeners(PreDeleteEventListener[] preDeleteEventListener) {
-		this.preDeleteEventListeners = preDeleteEventListener;
-	}
-	
-	public PreInsertEventListener[] getPreInsertEventListeners() {
-		return preInsertEventListeners;
-	}
-	
-	public void setPreInsertEventListeners(PreInsertEventListener[] preInsertEventListener) {
-		this.preInsertEventListeners = preInsertEventListener;
-	}
-	
-	public PreUpdateEventListener[] getPreUpdateEventListeners() {
-		return preUpdateEventListeners;
-	}
-	
-	public void setPreUpdateEventListeners(PreUpdateEventListener[] preUpdateEventListener) {
-		this.preUpdateEventListeners = preUpdateEventListener;
-	}
-
-	public PostDeleteEventListener[] getPostCommitDeleteEventListeners() {
-		return postCommitDeleteEventListeners;
-	}
-
-	public void setPostCommitDeleteEventListeners(
-			PostDeleteEventListener[] postCommitDeleteEventListeners) {
-		this.postCommitDeleteEventListeners = postCommitDeleteEventListeners;
-	}
-
-	public PostInsertEventListener[] getPostCommitInsertEventListeners() {
-		return postCommitInsertEventListeners;
-	}
-
-	public void setPostCommitInsertEventListeners(
-			PostInsertEventListener[] postCommitInsertEventListeners) {
-		this.postCommitInsertEventListeners = postCommitInsertEventListeners;
-	}
-
-	public PostUpdateEventListener[] getPostCommitUpdateEventListeners() {
-		return postCommitUpdateEventListeners;
-	}
-
-	public void setPostCommitUpdateEventListeners(
-			PostUpdateEventListener[] postCommitUpdateEventListeners) {
-		this.postCommitUpdateEventListeners = postCommitUpdateEventListeners;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/EventListeners.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventListeners.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,513 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+import java.lang.reflect.Field;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.event.def.DefaultAutoFlushEventListener;
+import org.hibernate.event.def.DefaultDeleteEventListener;
+import org.hibernate.event.def.DefaultDirtyCheckEventListener;
+import org.hibernate.event.def.DefaultEvictEventListener;
+import org.hibernate.event.def.DefaultFlushEntityEventListener;
+import org.hibernate.event.def.DefaultFlushEventListener;
+import org.hibernate.event.def.DefaultInitializeCollectionEventListener;
+import org.hibernate.event.def.DefaultLoadEventListener;
+import org.hibernate.event.def.DefaultLockEventListener;
+import org.hibernate.event.def.DefaultMergeEventListener;
+import org.hibernate.event.def.DefaultPersistEventListener;
+import org.hibernate.event.def.DefaultPostLoadEventListener;
+import org.hibernate.event.def.DefaultPreLoadEventListener;
+import org.hibernate.event.def.DefaultRefreshEventListener;
+import org.hibernate.event.def.DefaultReplicateEventListener;
+import org.hibernate.event.def.DefaultSaveEventListener;
+import org.hibernate.event.def.DefaultSaveOrUpdateCopyEventListener;
+import org.hibernate.event.def.DefaultSaveOrUpdateEventListener;
+import org.hibernate.event.def.DefaultUpdateEventListener;
+import org.hibernate.event.def.DefaultPersistOnFlushEventListener;
+import org.hibernate.util.Cloneable;
+
+/**
+ * A convience holder for all defined session event listeners.
+ *
+ * @author Steve Ebersole
+ */
+public class EventListeners extends Cloneable implements Serializable {
+
+	private LoadEventListener[] loadEventListeners = { new DefaultLoadEventListener() };
+	private SaveOrUpdateEventListener[] saveOrUpdateEventListeners = { new DefaultSaveOrUpdateEventListener() };
+	private MergeEventListener[] mergeEventListeners = { new DefaultMergeEventListener() };
+	private PersistEventListener[] persistEventListeners = { new DefaultPersistEventListener() };
+	private PersistEventListener[] persistOnFlushEventListeners = { new DefaultPersistOnFlushEventListener() };
+	private ReplicateEventListener[] replicateEventListeners = { new DefaultReplicateEventListener() };
+	private DeleteEventListener[] deleteEventListeners = { new DefaultDeleteEventListener() };
+	private AutoFlushEventListener[] autoFlushEventListeners = { new DefaultAutoFlushEventListener() };
+	private DirtyCheckEventListener[] dirtyCheckEventListeners = { new DefaultDirtyCheckEventListener() };
+	private FlushEventListener[] flushEventListeners = { new DefaultFlushEventListener() };
+	private EvictEventListener[] evictEventListeners = { new DefaultEvictEventListener() };
+	private LockEventListener[] lockEventListeners = { new DefaultLockEventListener() };
+	private RefreshEventListener[] refreshEventListeners = { new DefaultRefreshEventListener() };
+	private FlushEntityEventListener[] flushEntityEventListeners = { new DefaultFlushEntityEventListener() };
+	private InitializeCollectionEventListener[] initializeCollectionEventListeners = 
+			{ new DefaultInitializeCollectionEventListener() };
+
+	private PostLoadEventListener[] postLoadEventListeners = { new DefaultPostLoadEventListener() };
+	private PreLoadEventListener[] preLoadEventListeners = { new DefaultPreLoadEventListener() };
+	
+	private PreDeleteEventListener[] preDeleteEventListeners = {};
+	private PreUpdateEventListener[] preUpdateEventListeners = {};
+	private PreInsertEventListener[] preInsertEventListeners = {};
+	private PostDeleteEventListener[] postDeleteEventListeners = {};
+	private PostUpdateEventListener[] postUpdateEventListeners = {};
+	private PostInsertEventListener[] postInsertEventListeners = {};
+	private PostDeleteEventListener[] postCommitDeleteEventListeners = {};
+	private PostUpdateEventListener[] postCommitUpdateEventListeners = {};
+	private PostInsertEventListener[] postCommitInsertEventListeners = {};
+
+	private PreCollectionRecreateEventListener[] preCollectionRecreateEventListeners = {};
+	private PostCollectionRecreateEventListener[] postCollectionRecreateEventListeners = {};
+	private PreCollectionRemoveEventListener[] preCollectionRemoveEventListeners = {};
+	private PostCollectionRemoveEventListener[] postCollectionRemoveEventListeners = {};
+	private PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners = {};
+	private PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners = {};	
+
+	private SaveOrUpdateEventListener[] saveEventListeners = { new DefaultSaveEventListener() };
+	private SaveOrUpdateEventListener[] updateEventListeners = { new DefaultUpdateEventListener() };
+	private MergeEventListener[] saveOrUpdateCopyEventListeners = { new DefaultSaveOrUpdateCopyEventListener() };//saveOrUpdateCopy() is deprecated!
+
+	private static Map eventInterfaceFromType;
+
+	static {
+		eventInterfaceFromType = new HashMap();
+
+		eventInterfaceFromType.put("auto-flush", AutoFlushEventListener.class);
+		eventInterfaceFromType.put("merge", MergeEventListener.class);
+		eventInterfaceFromType.put("create", PersistEventListener.class);
+		eventInterfaceFromType.put("create-onflush", PersistEventListener.class);
+		eventInterfaceFromType.put("delete", DeleteEventListener.class);
+		eventInterfaceFromType.put("dirty-check", DirtyCheckEventListener.class);
+		eventInterfaceFromType.put("evict", EvictEventListener.class);
+		eventInterfaceFromType.put("flush", FlushEventListener.class);
+		eventInterfaceFromType.put("flush-entity", FlushEntityEventListener.class);
+		eventInterfaceFromType.put("load", LoadEventListener.class);
+		eventInterfaceFromType.put("load-collection", InitializeCollectionEventListener.class);
+		eventInterfaceFromType.put("lock", LockEventListener.class);
+		eventInterfaceFromType.put("refresh", RefreshEventListener.class);
+		eventInterfaceFromType.put("replicate", ReplicateEventListener.class);
+		eventInterfaceFromType.put("save-update", SaveOrUpdateEventListener.class);
+		eventInterfaceFromType.put("save", SaveOrUpdateEventListener.class);
+		eventInterfaceFromType.put("update", SaveOrUpdateEventListener.class);
+		eventInterfaceFromType.put("pre-load", PreLoadEventListener.class);
+		eventInterfaceFromType.put("pre-update", PreUpdateEventListener.class);
+		eventInterfaceFromType.put("pre-delete", PreDeleteEventListener.class);
+		eventInterfaceFromType.put("pre-insert", PreInsertEventListener.class);
+		eventInterfaceFromType.put("pre-collection-recreate", PreCollectionRecreateEventListener.class);
+		eventInterfaceFromType.put("pre-collection-remove", PreCollectionRemoveEventListener.class);
+		eventInterfaceFromType.put("pre-collection-update", PreCollectionUpdateEventListener.class);
+		eventInterfaceFromType.put("post-load", PostLoadEventListener.class);
+		eventInterfaceFromType.put("post-update", PostUpdateEventListener.class);
+		eventInterfaceFromType.put("post-delete", PostDeleteEventListener.class);
+		eventInterfaceFromType.put("post-insert", PostInsertEventListener.class);
+		eventInterfaceFromType.put("post-commit-update", PostUpdateEventListener.class);
+		eventInterfaceFromType.put("post-commit-delete", PostDeleteEventListener.class);
+		eventInterfaceFromType.put("post-commit-insert", PostInsertEventListener.class);
+		eventInterfaceFromType.put("post-collection-recreate", PostCollectionRecreateEventListener.class);
+		eventInterfaceFromType.put("post-collection-remove", PostCollectionRemoveEventListener.class);
+		eventInterfaceFromType.put("post-collection-update", PostCollectionUpdateEventListener.class);
+		eventInterfaceFromType = Collections.unmodifiableMap( eventInterfaceFromType );
+	}
+
+	public Class getListenerClassFor(String type) {
+		Class clazz = (Class) eventInterfaceFromType.get(type);
+		
+		if (clazz == null) {
+			throw new MappingException("Unrecognized listener type [" + type + "]");
+		}
+
+		return clazz;
+	}
+
+	private static interface ListenerProcesser {
+		public void processListener(Object listener);
+	}
+
+	private void processListeners(ListenerProcesser processer) {
+		Field[] fields = getClass().getDeclaredFields();
+		for ( int i = 0; i < fields.length; i++ ) {
+			final Object[] listeners;
+			try {
+				Object fieldValue = fields[i].get(this);
+				if ( fieldValue instanceof Object[] ) {
+					listeners = ( Object[] ) fieldValue;
+				}
+				else {
+					continue;
+				}
+			}
+			catch ( Throwable t ) {
+				throw new HibernateException( "could not init listeners", t );
+			}
+
+			int length = listeners.length;
+			for ( int index = 0 ; index < length ; index++ ) {
+				processer.processListener( listeners[index ] );
+			}
+		}
+	}
+
+	/**
+	 * Call {@link Initializable#initialize} on any listeners that implement the
+	 * {@link Initializable} interface.
+	 *
+	 * @param cfg The configuration.
+	 */
+	public void initializeListeners(final Configuration cfg) {
+		try {
+			processListeners(
+					new ListenerProcesser() {
+						public void processListener(Object listener) {
+							if ( listener instanceof Initializable ) {
+								( ( Initializable ) listener ).initialize( cfg );
+							}
+						}
+					}
+			);
+		}
+		catch ( Exception e ) {
+			throw new HibernateException("could not init listeners", e);
+		}
+	}
+
+	/**
+	 * Call {@link Destructible#cleanup} on any listeners that implement the
+	 * {@link Destructible} interface.
+	 */
+	public void destroyListeners() {
+		try {
+			processListeners(
+					new ListenerProcesser() {
+						public void processListener(Object listener) {
+							if ( listener instanceof Destructible ) {
+								( ( Destructible ) listener ).cleanup();
+							}
+						}
+					}
+			);
+		}
+		catch ( Exception e ) {
+			throw new HibernateException("could not destruct listeners", e);
+		}
+	}
+
+	public LoadEventListener[] getLoadEventListeners() {
+        return loadEventListeners;
+    }
+
+    public void setLoadEventListeners(LoadEventListener[] loadEventListener) {
+        this.loadEventListeners = loadEventListener;
+    }
+
+	public ReplicateEventListener[] getReplicateEventListeners() {
+		return replicateEventListeners;
+	}
+
+	public void setReplicateEventListeners(ReplicateEventListener[] replicateEventListener) {
+		this.replicateEventListeners = replicateEventListener;
+	}
+
+	public DeleteEventListener[] getDeleteEventListeners() {
+		return deleteEventListeners;
+	}
+
+	public void setDeleteEventListeners(DeleteEventListener[] deleteEventListener) {
+		this.deleteEventListeners = deleteEventListener;
+	}
+
+	public AutoFlushEventListener[] getAutoFlushEventListeners() {
+		return autoFlushEventListeners;
+	}
+
+	public void setAutoFlushEventListeners(AutoFlushEventListener[] autoFlushEventListener) {
+		this.autoFlushEventListeners = autoFlushEventListener;
+	}
+
+	public DirtyCheckEventListener[] getDirtyCheckEventListeners() {
+		return dirtyCheckEventListeners;
+	}
+
+	public void setDirtyCheckEventListeners(DirtyCheckEventListener[] dirtyCheckEventListener) {
+		this.dirtyCheckEventListeners = dirtyCheckEventListener;
+	}
+
+	public FlushEventListener[] getFlushEventListeners() {
+		return flushEventListeners;
+	}
+
+	public void setFlushEventListeners(FlushEventListener[] flushEventListener) {
+		this.flushEventListeners = flushEventListener;
+	}
+
+	public EvictEventListener[] getEvictEventListeners() {
+		return evictEventListeners;
+	}
+
+	public void setEvictEventListeners(EvictEventListener[] evictEventListener) {
+		this.evictEventListeners = evictEventListener;
+	}
+
+	public LockEventListener[] getLockEventListeners() {
+		return lockEventListeners;
+	}
+
+	public void setLockEventListeners(LockEventListener[] lockEventListener) {
+		this.lockEventListeners = lockEventListener;
+	}
+
+	public RefreshEventListener[] getRefreshEventListeners() {
+		return refreshEventListeners;
+	}
+
+	public void setRefreshEventListeners(RefreshEventListener[] refreshEventListener) {
+		this.refreshEventListeners = refreshEventListener;
+	}
+
+	public InitializeCollectionEventListener[] getInitializeCollectionEventListeners() {
+		return initializeCollectionEventListeners;
+	}
+
+	public void setInitializeCollectionEventListeners(InitializeCollectionEventListener[] initializeCollectionEventListener) {
+		this.initializeCollectionEventListeners = initializeCollectionEventListener;
+	}
+	
+	public FlushEntityEventListener[] getFlushEntityEventListeners() {
+		return flushEntityEventListeners;
+	}
+	
+	public void setFlushEntityEventListeners(FlushEntityEventListener[] flushEntityEventListener) {
+		this.flushEntityEventListeners = flushEntityEventListener;
+	}
+	
+	public SaveOrUpdateEventListener[] getSaveOrUpdateEventListeners() {
+		return saveOrUpdateEventListeners;
+	}
+	
+	public void setSaveOrUpdateEventListeners(SaveOrUpdateEventListener[] saveOrUpdateEventListener) {
+		this.saveOrUpdateEventListeners = saveOrUpdateEventListener;
+	}
+	
+	public MergeEventListener[] getMergeEventListeners() {
+		return mergeEventListeners;
+	}
+	
+	public void setMergeEventListeners(MergeEventListener[] mergeEventListener) {
+		this.mergeEventListeners = mergeEventListener;
+	}
+	
+	public PersistEventListener[] getPersistEventListeners() {
+		return persistEventListeners;
+	}
+	
+	public void setPersistEventListeners(PersistEventListener[] createEventListener) {
+		this.persistEventListeners = createEventListener;
+	}
+
+	public PersistEventListener[] getPersistOnFlushEventListeners() {
+		return persistOnFlushEventListeners;
+	}
+
+	public void setPersistOnFlushEventListeners(PersistEventListener[] createEventListener) {
+		this.persistOnFlushEventListeners = createEventListener;
+	}
+	
+	public MergeEventListener[] getSaveOrUpdateCopyEventListeners() {
+		return saveOrUpdateCopyEventListeners;
+	}
+	
+	public void setSaveOrUpdateCopyEventListeners(MergeEventListener[] saveOrUpdateCopyEventListener) {
+		this.saveOrUpdateCopyEventListeners = saveOrUpdateCopyEventListener;
+	}
+	
+	public SaveOrUpdateEventListener[] getSaveEventListeners() {
+		return saveEventListeners;
+	}
+	
+	public void setSaveEventListeners(SaveOrUpdateEventListener[] saveEventListener) {
+		this.saveEventListeners = saveEventListener;
+	}
+	
+	public SaveOrUpdateEventListener[] getUpdateEventListeners() {
+		return updateEventListeners;
+	}
+	
+	public void setUpdateEventListeners(SaveOrUpdateEventListener[] updateEventListener) {
+		this.updateEventListeners = updateEventListener;
+	}
+
+	public PostLoadEventListener[] getPostLoadEventListeners() {
+		return postLoadEventListeners;
+	}
+
+	public void setPostLoadEventListeners(PostLoadEventListener[] postLoadEventListener) {
+		this.postLoadEventListeners = postLoadEventListener;
+	}
+
+	public PreLoadEventListener[] getPreLoadEventListeners() {
+		return preLoadEventListeners;
+	}
+
+	public void setPreLoadEventListeners(PreLoadEventListener[] preLoadEventListener) {
+		this.preLoadEventListeners = preLoadEventListener;
+	}
+
+	public PreCollectionRecreateEventListener[] getPreCollectionRecreateEventListeners() {
+		return preCollectionRecreateEventListeners;
+	}
+
+	public void setPreCollectionRecreateEventListeners(PreCollectionRecreateEventListener[] preCollectionRecreateEventListener) {
+		this.preCollectionRecreateEventListeners = preCollectionRecreateEventListener;
+	}
+
+	public PreCollectionRemoveEventListener[] getPreCollectionRemoveEventListeners() {
+		return preCollectionRemoveEventListeners;
+	}
+
+	public void setPreCollectionRemoveEventListeners(PreCollectionRemoveEventListener[] preCollectionRemoveEventListener) {
+		this.preCollectionRemoveEventListeners = preCollectionRemoveEventListener;
+	}
+
+	public PreCollectionUpdateEventListener[] getPreCollectionUpdateEventListeners() {
+		return preCollectionUpdateEventListeners;
+	}
+
+	public void setPreCollectionUpdateEventListeners(PreCollectionUpdateEventListener[] preCollectionUpdateEventListeners) {
+		this.preCollectionUpdateEventListeners = preCollectionUpdateEventListeners;
+	}
+
+	public PostDeleteEventListener[] getPostDeleteEventListeners() {
+		return postDeleteEventListeners;
+	}
+	
+	public PostInsertEventListener[] getPostInsertEventListeners() {
+		return postInsertEventListeners;
+	}
+	
+	public PostUpdateEventListener[] getPostUpdateEventListeners() {
+		return postUpdateEventListeners;
+	}
+	
+	public void setPostDeleteEventListeners(PostDeleteEventListener[] postDeleteEventListener) {
+		this.postDeleteEventListeners = postDeleteEventListener;
+	}
+	
+	public void setPostInsertEventListeners(PostInsertEventListener[] postInsertEventListener) {
+		this.postInsertEventListeners = postInsertEventListener;
+	}
+	
+	public void setPostUpdateEventListeners(PostUpdateEventListener[] postUpdateEventListener) {
+		this.postUpdateEventListeners = postUpdateEventListener;
+	}
+	
+	public PostCollectionRecreateEventListener[] getPostCollectionRecreateEventListeners() {
+		return postCollectionRecreateEventListeners;
+	}
+
+	public void setPostCollectionRecreateEventListeners(PostCollectionRecreateEventListener[] postCollectionRecreateEventListener) {
+		this.postCollectionRecreateEventListeners = postCollectionRecreateEventListener;
+	}
+
+	public PostCollectionRemoveEventListener[] getPostCollectionRemoveEventListeners() {
+		return postCollectionRemoveEventListeners;
+	}
+
+	public void setPostCollectionRemoveEventListeners(PostCollectionRemoveEventListener[] postCollectionRemoveEventListener) {
+		this.postCollectionRemoveEventListeners = postCollectionRemoveEventListener;
+	}	        
+
+	public PostCollectionUpdateEventListener[] getPostCollectionUpdateEventListeners() {
+		return postCollectionUpdateEventListeners;
+	}
+
+	public void setPostCollectionUpdateEventListeners(PostCollectionUpdateEventListener[] postCollectionUpdateEventListeners) {
+		this.postCollectionUpdateEventListeners = postCollectionUpdateEventListeners;
+	}
+
+	public PreDeleteEventListener[] getPreDeleteEventListeners() {
+		return preDeleteEventListeners;
+	}
+	
+	public void setPreDeleteEventListeners(PreDeleteEventListener[] preDeleteEventListener) {
+		this.preDeleteEventListeners = preDeleteEventListener;
+	}
+	
+	public PreInsertEventListener[] getPreInsertEventListeners() {
+		return preInsertEventListeners;
+	}
+	
+	public void setPreInsertEventListeners(PreInsertEventListener[] preInsertEventListener) {
+		this.preInsertEventListeners = preInsertEventListener;
+	}
+	
+	public PreUpdateEventListener[] getPreUpdateEventListeners() {
+		return preUpdateEventListeners;
+	}
+	
+	public void setPreUpdateEventListeners(PreUpdateEventListener[] preUpdateEventListener) {
+		this.preUpdateEventListeners = preUpdateEventListener;
+	}
+
+	public PostDeleteEventListener[] getPostCommitDeleteEventListeners() {
+		return postCommitDeleteEventListeners;
+	}
+
+	public void setPostCommitDeleteEventListeners(
+			PostDeleteEventListener[] postCommitDeleteEventListeners) {
+		this.postCommitDeleteEventListeners = postCommitDeleteEventListeners;
+	}
+
+	public PostInsertEventListener[] getPostCommitInsertEventListeners() {
+		return postCommitInsertEventListeners;
+	}
+
+	public void setPostCommitInsertEventListeners(
+			PostInsertEventListener[] postCommitInsertEventListeners) {
+		this.postCommitInsertEventListeners = postCommitInsertEventListeners;
+	}
+
+	public PostUpdateEventListener[] getPostCommitUpdateEventListeners() {
+		return postCommitUpdateEventListeners;
+	}
+
+	public void setPostCommitUpdateEventListeners(
+			PostUpdateEventListener[] postCommitUpdateEventListeners) {
+		this.postCommitUpdateEventListeners = postCommitUpdateEventListeners;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/EventSource.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: EventSource.java 9944 2006-05-24 21:14:56Z steve.ebersole at jboss.com $
-package org.hibernate.event;
-
-import java.io.Serializable;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Session;
-import org.hibernate.engine.ActionQueue;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * @author Gavin King
- */
-public interface EventSource extends SessionImplementor, Session {
-	
-	/**
-	 * Get the ActionQueue for this session
-	 */
-	public ActionQueue getActionQueue();
-
-	/**
-	 * Instantiate an entity instance, using either an interceptor,
-	 * or the given persister
-	 */
-	public Object instantiate(EntityPersister persister, Serializable id) throws HibernateException;
-
-	/**
-	 * Force an immediate flush
-	 */
-	public void forceFlush(EntityEntry e) throws HibernateException;
-
-	/**
-	 * Cascade merge an entity instance
-	 */
-	public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException;
-	/**
-	 * Cascade persist an entity instance
-	 */
-	public void persist(String entityName, Object object, Map createdAlready) throws HibernateException;
-
-	/**
-	 * Cascade persist an entity instance during the flush process
-	 */
-	public void persistOnFlush(String entityName, Object object, Map copiedAlready);
-	/**
-	 * Cascade refesh an entity instance
-	 */
-	public void refresh(Object object, Map refreshedAlready) throws HibernateException;
-	/**
-	 * Cascade copy an entity instance
-	 */
-	public void saveOrUpdateCopy(String entityName, Object object, Map copiedAlready) throws HibernateException;
-	
-	/**
-	 * Cascade delete an entity instance
-	 */
-	public void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/EventSource.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EventSource.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.engine.ActionQueue;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * @author Gavin King
+ */
+public interface EventSource extends SessionImplementor, Session {
+	
+	/**
+	 * Get the ActionQueue for this session
+	 */
+	public ActionQueue getActionQueue();
+
+	/**
+	 * Instantiate an entity instance, using either an interceptor,
+	 * or the given persister
+	 */
+	public Object instantiate(EntityPersister persister, Serializable id) throws HibernateException;
+
+	/**
+	 * Force an immediate flush
+	 */
+	public void forceFlush(EntityEntry e) throws HibernateException;
+
+	/**
+	 * Cascade merge an entity instance
+	 */
+	public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException;
+	/**
+	 * Cascade persist an entity instance
+	 */
+	public void persist(String entityName, Object object, Map createdAlready) throws HibernateException;
+
+	/**
+	 * Cascade persist an entity instance during the flush process
+	 */
+	public void persistOnFlush(String entityName, Object object, Map copiedAlready);
+	/**
+	 * Cascade refesh an entity instance
+	 */
+	public void refresh(Object object, Map refreshedAlready) throws HibernateException;
+	/**
+	 * Cascade copy an entity instance
+	 */
+	public void saveOrUpdateCopy(String entityName, Object object, Map copiedAlready) throws HibernateException;
+	
+	/**
+	 * Cascade delete an entity instance
+	 */
+	public void delete(String entityName, Object child, boolean isCascadeDeleteEnabled, Set transientEntities);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/EvictEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: EvictEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-
-/**
- *  Defines an event class for the evicting of an entity.
- *
- * @author Steve Ebersole
- */
-public class EvictEvent extends AbstractEvent {
-
-	private Object object;
-
-	public EvictEvent(Object object, EventSource source) {
-		super(source);
-		this.object = object;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public void setObject(Object object) {
-		this.object = object;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/EvictEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.event;
+
+
+/**
+ *  Defines an event class for the evicting of an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class EvictEvent extends AbstractEvent {
+
+	private Object object;
+
+	public EvictEvent(Object object, EventSource source) {
+		super(source);
+		this.object = object;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/EvictEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: EvictEventListener.java 4533 2004-09-12 03:02:54Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of evict events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface EvictEventListener extends Serializable {
-
-    /** 
-     * Handle the given evict event.
-     *
-     * @param event The evict event to be handled.
-     * @throws HibernateException
-     */
-	public void onEvict(EvictEvent event) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/EvictEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/EvictEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of evict events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface EvictEventListener extends Serializable {
+
+    /** 
+     * Handle the given evict event.
+     *
+     * @param event The evict event to be handled.
+     * @throws HibernateException
+     */
+	public void onEvict(EvictEvent event) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/FlushEntityEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-//$Id: FlushEntityEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.engine.EntityEntry;
-
-/**
- * @author Gavin King
- */
-public class FlushEntityEvent extends AbstractEvent {
-	
-	private Object entity;
-	private Object[] propertyValues;
-	private Object[] databaseSnapshot;
-	private int[] dirtyProperties;
-	private boolean hasDirtyCollection;
-	private boolean dirtyCheckPossible;
-	private boolean dirtyCheckHandledByInterceptor;
-	private EntityEntry entityEntry;
-	
-	public FlushEntityEvent(EventSource source, Object entity, EntityEntry entry) {
-		super(source);
-		this.entity = entity;
-		this.entityEntry = entry;
-	}
-
-	public EntityEntry getEntityEntry() {
-		return entityEntry;
-	}
-	public Object[] getDatabaseSnapshot() {
-		return databaseSnapshot;
-	}
-	public void setDatabaseSnapshot(Object[] databaseSnapshot) {
-		this.databaseSnapshot = databaseSnapshot;
-	}
-	public boolean hasDatabaseSnapshot() {
-		return databaseSnapshot!=null;
-	}
-	public boolean isDirtyCheckHandledByInterceptor() {
-		return dirtyCheckHandledByInterceptor;
-	}
-	public void setDirtyCheckHandledByInterceptor(boolean dirtyCheckHandledByInterceptor) {
-		this.dirtyCheckHandledByInterceptor = dirtyCheckHandledByInterceptor;
-	}
-	public boolean isDirtyCheckPossible() {
-		return dirtyCheckPossible;
-	}
-	public void setDirtyCheckPossible(boolean dirtyCheckPossible) {
-		this.dirtyCheckPossible = dirtyCheckPossible;
-	}
-	public int[] getDirtyProperties() {
-		return dirtyProperties;
-	}
-	public void setDirtyProperties(int[] dirtyProperties) {
-		this.dirtyProperties = dirtyProperties;
-	}
-	public boolean hasDirtyCollection() {
-		return hasDirtyCollection;
-	}
-	public void setHasDirtyCollection(boolean hasDirtyCollection) {
-		this.hasDirtyCollection = hasDirtyCollection;
-	}
-	public Object[] getPropertyValues() {
-		return propertyValues;
-	}
-	public void setPropertyValues(Object[] propertyValues) {
-		this.propertyValues = propertyValues;
-	}
-	public Object getEntity() {
-		return entity;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/FlushEntityEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.event;
+
+import org.hibernate.engine.EntityEntry;
+
+/**
+ * @author Gavin King
+ */
+public class FlushEntityEvent extends AbstractEvent {
+	
+	private Object entity;
+	private Object[] propertyValues;
+	private Object[] databaseSnapshot;
+	private int[] dirtyProperties;
+	private boolean hasDirtyCollection;
+	private boolean dirtyCheckPossible;
+	private boolean dirtyCheckHandledByInterceptor;
+	private EntityEntry entityEntry;
+	
+	public FlushEntityEvent(EventSource source, Object entity, EntityEntry entry) {
+		super(source);
+		this.entity = entity;
+		this.entityEntry = entry;
+	}
+
+	public EntityEntry getEntityEntry() {
+		return entityEntry;
+	}
+	public Object[] getDatabaseSnapshot() {
+		return databaseSnapshot;
+	}
+	public void setDatabaseSnapshot(Object[] databaseSnapshot) {
+		this.databaseSnapshot = databaseSnapshot;
+	}
+	public boolean hasDatabaseSnapshot() {
+		return databaseSnapshot!=null;
+	}
+	public boolean isDirtyCheckHandledByInterceptor() {
+		return dirtyCheckHandledByInterceptor;
+	}
+	public void setDirtyCheckHandledByInterceptor(boolean dirtyCheckHandledByInterceptor) {
+		this.dirtyCheckHandledByInterceptor = dirtyCheckHandledByInterceptor;
+	}
+	public boolean isDirtyCheckPossible() {
+		return dirtyCheckPossible;
+	}
+	public void setDirtyCheckPossible(boolean dirtyCheckPossible) {
+		this.dirtyCheckPossible = dirtyCheckPossible;
+	}
+	public int[] getDirtyProperties() {
+		return dirtyProperties;
+	}
+	public void setDirtyProperties(int[] dirtyProperties) {
+		this.dirtyProperties = dirtyProperties;
+	}
+	public boolean hasDirtyCollection() {
+		return hasDirtyCollection;
+	}
+	public void setHasDirtyCollection(boolean hasDirtyCollection) {
+		this.hasDirtyCollection = hasDirtyCollection;
+	}
+	public Object[] getPropertyValues() {
+		return propertyValues;
+	}
+	public void setPropertyValues(Object[] propertyValues) {
+		this.propertyValues = propertyValues;
+	}
+	public Object getEntity() {
+		return entity;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: FlushEntityEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-
-/**
- * @author Gavin King
- */
-public interface FlushEntityEventListener extends Serializable {
-	public void onFlushEntity(FlushEntityEvent event) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEntityEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * @author Gavin King
+ */
+public interface FlushEntityEventListener extends Serializable {
+	public void onFlushEntity(FlushEntityEvent event) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/FlushEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: FlushEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-
-/** 
- * Defines an event class for the flushing of a session.
- *
- * @author Steve Ebersole
- */
-public class FlushEvent extends AbstractEvent {
-	
-	public FlushEvent(EventSource source) {
-		super(source);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/FlushEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+
+/** 
+ * Defines an event class for the flushing of a session.
+ *
+ * @author Steve Ebersole
+ */
+public class FlushEvent extends AbstractEvent {
+	
+	public FlushEvent(EventSource source) {
+		super(source);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/FlushEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: FlushEventListener.java 4185 2004-08-08 11:24:56Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of session flush events.
- *
- * @author Steve Ebersole
- */
-public interface FlushEventListener extends Serializable {
-
-    /** Handle the given flush event.
-     *
-     * @param event The flush event to be handled.
-     * @throws HibernateException
-     */
-	public void onFlush(FlushEvent event) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/FlushEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/FlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of session flush events.
+ *
+ * @author Steve Ebersole
+ */
+public interface FlushEventListener extends Serializable {
+
+    /** Handle the given flush event.
+     *
+     * @param event The flush event to be handled.
+     * @throws HibernateException
+     */
+	public void onFlush(FlushEvent event) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/Initializable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +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.event;
-
-import org.hibernate.cfg.Configuration;
-
-/**
- * An event listener that requires access to mappings to initialize state at 
- * initialization time.
- *
- * @author Gavin King
- */
-public interface Initializable {
-	public void initialize(Configuration cfg);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/Initializable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/Initializable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.cfg.Configuration;
+
+/**
+ * An event listener that requires access to mappings to initialize state at 
+ * initialization time.
+ *
+ * @author Gavin King
+ */
+public interface Initializable {
+	public void initialize(Configuration cfg);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: InitializeCollectionEvent.java 14313 2008-02-06 07:46:52Z gbadner $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-
-/**
- * An event that occurs when a collection wants to be
- * initialized
- * 
- * @author Gavin King
- */
-public class InitializeCollectionEvent extends AbstractCollectionEvent {
-
-	public InitializeCollectionEvent(PersistentCollection collection, EventSource source ) {
-		super( getLoadedCollectionPersister( collection, source ),
-				collection,
-				source,
-				getLoadedOwnerOrNull( collection, source ),
-				getLoadedOwnerIdOrNull( collection, source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.collection.PersistentCollection;
+
+/**
+ * An event that occurs when a collection wants to be
+ * initialized
+ * 
+ * @author Gavin King
+ */
+public class InitializeCollectionEvent extends AbstractCollectionEvent {
+
+	public InitializeCollectionEvent(PersistentCollection collection, EventSource source ) {
+		super( getLoadedCollectionPersister( collection, source ),
+				collection,
+				source,
+				getLoadedOwnerOrNull( collection, source ),
+				getLoadedOwnerIdOrNull( collection, source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-//$Id: InitializeCollectionEventListener.java 4345 2004-08-16 12:12:12Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of collection initialization events 
- * generated by a session.
- *
- * @author Gavin King
- */
-public interface InitializeCollectionEventListener extends Serializable {
-
-	public void onInitializeCollection(InitializeCollectionEvent event) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/InitializeCollectionEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of collection initialization events 
+ * generated by a session.
+ *
+ * @author Gavin King
+ */
+public interface InitializeCollectionEventListener extends Serializable {
+
+	public void onInitializeCollection(InitializeCollectionEvent event) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/LoadEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: LoadEvent.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.LockMode;
-
-/**
- *  Defines an event class for the loading of an entity.
- *
- * @author Steve Ebersole
- */
-public class LoadEvent extends AbstractEvent {
-
-	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
-
-	private Serializable entityId;
-	private String entityClassName;
-	private Object instanceToLoad;
-	private LockMode lockMode;
-	private boolean isAssociationFetch;
-	private Object result;
-
-	public LoadEvent(Serializable entityId, Object instanceToLoad, EventSource source) {
-		this(entityId, null, instanceToLoad, null, false, source);
-	}
-
-	public LoadEvent(Serializable entityId, String entityClassName, LockMode lockMode, EventSource source) {
-		this(entityId, entityClassName, null, lockMode, false, source);
-	}
-	
-	public LoadEvent(Serializable entityId, String entityClassName, boolean isAssociationFetch, EventSource source) {
-		this(entityId, entityClassName, null, null, isAssociationFetch, source);
-	}
-	
-	public boolean isAssociationFetch() {
-		return isAssociationFetch;
-	}
-
-	private LoadEvent(
-			Serializable entityId,
-			String entityClassName,
-			Object instanceToLoad,
-			LockMode lockMode,
-			boolean isAssociationFetch,
-			EventSource source) {
-
-		super(source);
-
-		if ( entityId == null ) {
-			throw new IllegalArgumentException("id to load is required for loading");
-		}
-
-		if ( lockMode == LockMode.WRITE ) {
-			throw new IllegalArgumentException("Invalid lock mode for loading");
-		}
-		else if ( lockMode == null ) {
-			lockMode = DEFAULT_LOCK_MODE;
-		}
-
-		this.entityId = entityId;
-		this.entityClassName = entityClassName;
-		this.instanceToLoad = instanceToLoad;
-		this.lockMode = lockMode;
-		this.isAssociationFetch = isAssociationFetch;
-	}
-
-	public Serializable getEntityId() {
-		return entityId;
-	}
-
-	public void setEntityId(Serializable entityId) {
-		this.entityId = entityId;
-	}
-
-	public String getEntityClassName() {
-		return entityClassName;
-	}
-
-	public void setEntityClassName(String entityClassName) {
-		this.entityClassName = entityClassName;
-	}
-
-	public Object getInstanceToLoad() {
-		return instanceToLoad;
-	}
-
-	public void setInstanceToLoad(Object instanceToLoad) {
-		this.instanceToLoad = instanceToLoad;
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-
-	public void setLockMode(LockMode lockMode) {
-		this.lockMode = lockMode;
-	}
-
-	public Object getResult() {
-		return result;
-	}
-
-	public void setResult(Object result) {
-		this.result = result;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/LoadEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.LockMode;
+
+/**
+ *  Defines an event class for the loading of an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class LoadEvent extends AbstractEvent {
+
+	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
+
+	private Serializable entityId;
+	private String entityClassName;
+	private Object instanceToLoad;
+	private LockMode lockMode;
+	private boolean isAssociationFetch;
+	private Object result;
+
+	public LoadEvent(Serializable entityId, Object instanceToLoad, EventSource source) {
+		this(entityId, null, instanceToLoad, null, false, source);
+	}
+
+	public LoadEvent(Serializable entityId, String entityClassName, LockMode lockMode, EventSource source) {
+		this(entityId, entityClassName, null, lockMode, false, source);
+	}
+	
+	public LoadEvent(Serializable entityId, String entityClassName, boolean isAssociationFetch, EventSource source) {
+		this(entityId, entityClassName, null, null, isAssociationFetch, source);
+	}
+	
+	public boolean isAssociationFetch() {
+		return isAssociationFetch;
+	}
+
+	private LoadEvent(
+			Serializable entityId,
+			String entityClassName,
+			Object instanceToLoad,
+			LockMode lockMode,
+			boolean isAssociationFetch,
+			EventSource source) {
+
+		super(source);
+
+		if ( entityId == null ) {
+			throw new IllegalArgumentException("id to load is required for loading");
+		}
+
+		if ( lockMode == LockMode.WRITE ) {
+			throw new IllegalArgumentException("Invalid lock mode for loading");
+		}
+		else if ( lockMode == null ) {
+			lockMode = DEFAULT_LOCK_MODE;
+		}
+
+		this.entityId = entityId;
+		this.entityClassName = entityClassName;
+		this.instanceToLoad = instanceToLoad;
+		this.lockMode = lockMode;
+		this.isAssociationFetch = isAssociationFetch;
+	}
+
+	public Serializable getEntityId() {
+		return entityId;
+	}
+
+	public void setEntityId(Serializable entityId) {
+		this.entityId = entityId;
+	}
+
+	public String getEntityClassName() {
+		return entityClassName;
+	}
+
+	public void setEntityClassName(String entityClassName) {
+		this.entityClassName = entityClassName;
+	}
+
+	public Object getInstanceToLoad() {
+		return instanceToLoad;
+	}
+
+	public void setInstanceToLoad(Object instanceToLoad) {
+		this.instanceToLoad = instanceToLoad;
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+
+	public void setLockMode(LockMode lockMode) {
+		this.lockMode = lockMode;
+	}
+
+	public Object getResult() {
+		return result;
+	}
+
+	public void setResult(Object result) {
+		this.result = result;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/LoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,122 +0,0 @@
-//$Id: LoadEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of load events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface LoadEventListener extends Serializable {
-
-	/** 
-	 * Handle the given load event.
-     *
-     * @param event The load event to be handled.
-     * @return The result (i.e., the loaded entity).
-     * @throws HibernateException
-     */
-	public void onLoad(LoadEvent event, LoadType loadType) throws HibernateException;
-
-	public static final LoadType RELOAD = new LoadType("GET")
-			.setAllowNulls(false)
-			.setAllowProxyCreation(false)
-			.setCheckDeleted(true)
-			.setNakedEntityReturned(false);
-
-	public static final LoadType GET = new LoadType("GET")
-			.setAllowNulls(true)
-			.setAllowProxyCreation(false)
-			.setCheckDeleted(true)
-			.setNakedEntityReturned(false);
-	
-	public static final LoadType LOAD = new LoadType("LOAD")
-			.setAllowNulls(false)
-			.setAllowProxyCreation(true)
-			.setCheckDeleted(true)
-			.setNakedEntityReturned(false);
-	
-	public static final LoadType IMMEDIATE_LOAD = new LoadType("IMMEDIATE_LOAD")
-			.setAllowNulls(true)
-			.setAllowProxyCreation(false)
-			.setCheckDeleted(false)
-			.setNakedEntityReturned(true);
-	
-	public static final LoadType INTERNAL_LOAD_EAGER = new LoadType("INTERNAL_LOAD_EAGER")
-			.setAllowNulls(false)
-			.setAllowProxyCreation(false)
-			.setCheckDeleted(false)
-			.setNakedEntityReturned(false);
-	
-	public static final LoadType INTERNAL_LOAD_LAZY = new LoadType("INTERNAL_LOAD_LAZY")
-			.setAllowNulls(false)
-			.setAllowProxyCreation(true)
-			.setCheckDeleted(false)
-			.setNakedEntityReturned(false);
-	
-	public static final LoadType INTERNAL_LOAD_NULLABLE = new LoadType("INTERNAL_LOAD_NULLABLE")
-			.setAllowNulls(true)
-			.setAllowProxyCreation(false)
-			.setCheckDeleted(false)
-			.setNakedEntityReturned(false);
-
-	public static final class LoadType {
-		private String name;
-
-		private boolean nakedEntityReturned;
-		private boolean allowNulls;
-		private boolean checkDeleted;
-		private boolean allowProxyCreation;
-
-        private LoadType(String name) {
-	        this.name = name;
-        }
-
-		public boolean isAllowNulls() {
-			return allowNulls;
-		}
-
-		private LoadType setAllowNulls(boolean allowNulls) {
-			this.allowNulls = allowNulls;
-			return this;
-		}
-
-		public boolean isNakedEntityReturned() {
-			return nakedEntityReturned;
-		}
-
-		private LoadType setNakedEntityReturned(boolean immediateLoad) {
-			this.nakedEntityReturned = immediateLoad;
-			return this;
-		}
-
-		public boolean isCheckDeleted() {
-			return checkDeleted;
-		}
-
-		private LoadType setCheckDeleted(boolean checkDeleted) {
-			this.checkDeleted = checkDeleted;
-			return this;
-		}
-
-		public boolean isAllowProxyCreation() {
-			return allowProxyCreation;
-		}
-
-		private LoadType setAllowProxyCreation(boolean allowProxyCreation) {
-			this.allowProxyCreation = allowProxyCreation;
-			return this;
-		}
-
-		public String getName() {
-			return name;
-		}
-		
-		public String toString() {
-			return name;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/LoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,145 @@
+/*
+ * 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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of load events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface LoadEventListener extends Serializable {
+
+	/** 
+	 * Handle the given load event.
+     *
+     * @param event The load event to be handled.
+     * @return The result (i.e., the loaded entity).
+     * @throws HibernateException
+     */
+	public void onLoad(LoadEvent event, LoadType loadType) throws HibernateException;
+
+	public static final LoadType RELOAD = new LoadType("GET")
+			.setAllowNulls(false)
+			.setAllowProxyCreation(false)
+			.setCheckDeleted(true)
+			.setNakedEntityReturned(false);
+
+	public static final LoadType GET = new LoadType("GET")
+			.setAllowNulls(true)
+			.setAllowProxyCreation(false)
+			.setCheckDeleted(true)
+			.setNakedEntityReturned(false);
+	
+	public static final LoadType LOAD = new LoadType("LOAD")
+			.setAllowNulls(false)
+			.setAllowProxyCreation(true)
+			.setCheckDeleted(true)
+			.setNakedEntityReturned(false);
+	
+	public static final LoadType IMMEDIATE_LOAD = new LoadType("IMMEDIATE_LOAD")
+			.setAllowNulls(true)
+			.setAllowProxyCreation(false)
+			.setCheckDeleted(false)
+			.setNakedEntityReturned(true);
+	
+	public static final LoadType INTERNAL_LOAD_EAGER = new LoadType("INTERNAL_LOAD_EAGER")
+			.setAllowNulls(false)
+			.setAllowProxyCreation(false)
+			.setCheckDeleted(false)
+			.setNakedEntityReturned(false);
+	
+	public static final LoadType INTERNAL_LOAD_LAZY = new LoadType("INTERNAL_LOAD_LAZY")
+			.setAllowNulls(false)
+			.setAllowProxyCreation(true)
+			.setCheckDeleted(false)
+			.setNakedEntityReturned(false);
+	
+	public static final LoadType INTERNAL_LOAD_NULLABLE = new LoadType("INTERNAL_LOAD_NULLABLE")
+			.setAllowNulls(true)
+			.setAllowProxyCreation(false)
+			.setCheckDeleted(false)
+			.setNakedEntityReturned(false);
+
+	public static final class LoadType {
+		private String name;
+
+		private boolean nakedEntityReturned;
+		private boolean allowNulls;
+		private boolean checkDeleted;
+		private boolean allowProxyCreation;
+
+        private LoadType(String name) {
+	        this.name = name;
+        }
+
+		public boolean isAllowNulls() {
+			return allowNulls;
+		}
+
+		private LoadType setAllowNulls(boolean allowNulls) {
+			this.allowNulls = allowNulls;
+			return this;
+		}
+
+		public boolean isNakedEntityReturned() {
+			return nakedEntityReturned;
+		}
+
+		private LoadType setNakedEntityReturned(boolean immediateLoad) {
+			this.nakedEntityReturned = immediateLoad;
+			return this;
+		}
+
+		public boolean isCheckDeleted() {
+			return checkDeleted;
+		}
+
+		private LoadType setCheckDeleted(boolean checkDeleted) {
+			this.checkDeleted = checkDeleted;
+			return this;
+		}
+
+		public boolean isAllowProxyCreation() {
+			return allowProxyCreation;
+		}
+
+		private LoadType setAllowProxyCreation(boolean allowProxyCreation) {
+			this.allowProxyCreation = allowProxyCreation;
+			return this;
+		}
+
+		public String getName() {
+			return name;
+		}
+		
+		public String toString() {
+			return name;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/LockEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-//$Id: LockEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.LockMode;
-
-/**
- *  Defines an event class for the locking of an entity.
- *
- * @author Steve Ebersole
- */
-public class LockEvent extends AbstractEvent {
-
-	private Object object;
-	private LockMode lockMode;
-	private String entityName;
-
-	public LockEvent(String entityName, Object original, LockMode lockMode, EventSource source) {
-		this(original, lockMode, source);
-		this.entityName = entityName;
-	}
-
-	public LockEvent(Object object, LockMode lockMode, EventSource source) {
-		super(source);
-		this.object = object;
-		this.lockMode = lockMode;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public void setObject(Object object) {
-		this.object = object;
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-
-	public void setLockMode(LockMode lockMode) {
-		this.lockMode = lockMode;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/LockEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.event;
+
+import org.hibernate.LockMode;
+
+/**
+ *  Defines an event class for the locking of an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class LockEvent extends AbstractEvent {
+
+	private Object object;
+	private LockMode lockMode;
+	private String entityName;
+
+	public LockEvent(String entityName, Object original, LockMode lockMode, EventSource source) {
+		this(original, lockMode, source);
+		this.entityName = entityName;
+	}
+
+	public LockEvent(Object object, LockMode lockMode, EventSource source) {
+		super(source);
+		this.object = object;
+		this.lockMode = lockMode;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+
+	public void setLockMode(LockMode lockMode) {
+		this.lockMode = lockMode;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/LockEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: LockEventListener.java 4185 2004-08-08 11:24:56Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of lock events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface LockEventListener extends Serializable {
-
-    /** Handle the given lock event.
-     *
-     * @param event The lock event to be handled.
-     * @throws HibernateException
-     */
-	public void onLock(LockEvent event) throws HibernateException;
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/LockEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/LockEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of lock events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface LockEventListener extends Serializable {
+
+    /** Handle the given lock event.
+     *
+     * @param event The lock event to be handled.
+     * @throws HibernateException
+     */
+	public void onLock(LockEvent event) throws HibernateException;
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/MergeEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: MergeEvent.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/** 
- * An event class for merge() and saveOrUpdateCopy()
- *
- * @author Gavin King
- */
-public class MergeEvent extends AbstractEvent {
-
-	private Object original;
-	private Serializable requestedId;
-	private String entityName;
-	private Object entity;
-	private Object result;
-
-	public MergeEvent(String entityName, Object original, EventSource source) {
-		this(original, source);
-		this.entityName = entityName;
-	}
-
-	public MergeEvent(String entityName, Object original, Serializable id, EventSource source) {
-		this(entityName, original, source);
-		this.requestedId = id;
-		if ( requestedId == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create merge event with null identifier"
-				);
-		}
-	}
-
-	public MergeEvent(Object object, EventSource source) {
-		super(source);
-		if ( object == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create merge event with null entity"
-				);
-		}
-		this.original = object;
-	}
-
-	public Object getOriginal() {
-		return original;
-	}
-
-	public void setOriginal(Object object) {
-		this.original = object;
-	}
-
-	public Serializable getRequestedId() {
-		return requestedId;
-	}
-
-	public void setRequestedId(Serializable requestedId) {
-		this.requestedId = requestedId;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	public void setEntity(Object entity) {
-		this.entity = entity;
-	}
-
-	public Object getResult() {
-		return result;
-	}
-
-	public void setResult(Object result) {
-		this.result = result;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/MergeEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+/** 
+ * An event class for merge() and saveOrUpdateCopy()
+ *
+ * @author Gavin King
+ */
+public class MergeEvent extends AbstractEvent {
+
+	private Object original;
+	private Serializable requestedId;
+	private String entityName;
+	private Object entity;
+	private Object result;
+
+	public MergeEvent(String entityName, Object original, EventSource source) {
+		this(original, source);
+		this.entityName = entityName;
+	}
+
+	public MergeEvent(String entityName, Object original, Serializable id, EventSource source) {
+		this(entityName, original, source);
+		this.requestedId = id;
+		if ( requestedId == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create merge event with null identifier"
+				);
+		}
+	}
+
+	public MergeEvent(Object object, EventSource source) {
+		super(source);
+		if ( object == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create merge event with null entity"
+				);
+		}
+		this.original = object;
+	}
+
+	public Object getOriginal() {
+		return original;
+	}
+
+	public void setOriginal(Object object) {
+		this.original = object;
+	}
+
+	public Serializable getRequestedId() {
+		return requestedId;
+	}
+
+	public void setRequestedId(Serializable requestedId) {
+		this.requestedId = requestedId;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	public void setEntity(Object entity) {
+		this.entity = entity;
+	}
+
+	public Object getResult() {
+		return result;
+	}
+
+	public void setResult(Object result) {
+		this.result = result;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/MergeEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: MergeEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-
-/**
- * Defines the contract for handling of merge events generated from a session.
- *
- * @author Gavin King
- */
-public interface MergeEventListener extends Serializable {
-
-    /** 
-     * Handle the given merge event.
-     *
-     * @param event The merge event to be handled.
-     * @throws HibernateException
-     */
-	public void onMerge(MergeEvent event) throws HibernateException;
-
-    /** 
-     * Handle the given merge event.
-     *
-     * @param event The merge event to be handled.
-     * @throws HibernateException
-     */
-	public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/MergeEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/MergeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Defines the contract for handling of merge events generated from a session.
+ *
+ * @author Gavin King
+ */
+public interface MergeEventListener extends Serializable {
+
+    /** 
+     * Handle the given merge event.
+     *
+     * @param event The merge event to be handled.
+     * @throws HibernateException
+     */
+	public void onMerge(MergeEvent event) throws HibernateException;
+
+    /** 
+     * Handle the given merge event.
+     *
+     * @param event The merge event to be handled.
+     * @throws HibernateException
+     */
+	public void onMerge(MergeEvent event, Map copiedAlready) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PersistEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +0,0 @@
-//$Id: PersistEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-
-
-/** 
- * An event class for persist()
- *
- * @author Gavin King
- */
-public class PersistEvent extends AbstractEvent {
-
-	private Object object;
-	private String entityName;
-
-	public PersistEvent(String entityName, Object original, EventSource source) {
-		this(original, source);
-		this.entityName = entityName;
-	}
-
-	public PersistEvent(Object object, EventSource source) {
-		super(source);
-		if ( object == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create create event with null entity"
-			);
-		}
-		this.object = object;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public void setObject(Object object) {
-		this.object = object;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PersistEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.event;
+
+/** 
+ * An event class for persist()
+ *
+ * @author Gavin King
+ */
+public class PersistEvent extends AbstractEvent {
+
+	private Object object;
+	private String entityName;
+
+	public PersistEvent(String entityName, Object original, EventSource source) {
+		this(original, source);
+		this.entityName = entityName;
+	}
+
+	public PersistEvent(Object object, EventSource source) {
+		super(source);
+		if ( object == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create create event with null entity"
+			);
+		}
+		this.object = object;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PersistEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: PersistEventListener.java 5835 2005-02-21 14:39:02Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-
-/**
- * Defines the contract for handling of create events generated from a session.
- *
- * @author Gavin King
- */
-public interface PersistEventListener extends Serializable {
-
-    /** 
-     * Handle the given create event.
-     *
-     * @param event The create event to be handled.
-     * @throws HibernateException
-     */
-	public void onPersist(PersistEvent event) throws HibernateException;
-
-    /** 
-     * Handle the given create event.
-     *
-     * @param event The create event to be handled.
-     * @throws HibernateException
-     */
-	public void onPersist(PersistEvent event, Map createdAlready) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PersistEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PersistEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Defines the contract for handling of create events generated from a session.
+ *
+ * @author Gavin King
+ */
+public interface PersistEventListener extends Serializable {
+
+    /** 
+     * Handle the given create event.
+     *
+     * @param event The create event to be handled.
+     * @throws HibernateException
+     */
+	public void onPersist(PersistEvent event) throws HibernateException;
+
+    /** 
+     * Handle the given create event.
+     *
+     * @param event The create event to be handled.
+     * @throws HibernateException
+     */
+	public void onPersist(PersistEvent event, Map createdAlready) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs after a collection is recreated
- *
- * @author Gail Badner
- */
-public class PostCollectionRecreateEvent extends AbstractCollectionEvent {
-
-	public PostCollectionRecreateEvent( CollectionPersister collectionPersister,
-										PersistentCollection collection,
-										EventSource source ) {
-		super( collectionPersister, collection, source,
-				collection.getOwner(),
-				getOwnerIdOrNull( collection.getOwner(), source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs after a collection is recreated
+ *
+ * @author Gail Badner
+ */
+public class PostCollectionRecreateEvent extends AbstractCollectionEvent {
+
+	public PostCollectionRecreateEvent( CollectionPersister collectionPersister,
+										PersistentCollection collection,
+										EventSource source ) {
+		super( collectionPersister, collection, source,
+				collection.getOwner(),
+				getOwnerIdOrNull( collection.getOwner(), source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after recreating a collection
- *
- * @author Gail Badner
- */
-public interface PostCollectionRecreateEventListener extends Serializable {
-	public void onPostRecreateCollection(PostCollectionRecreateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRecreateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after recreating a collection
+ *
+ * @author Gail Badner
+ */
+public interface PostCollectionRecreateEventListener extends Serializable {
+	public void onPostRecreateCollection(PostCollectionRecreateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs after a collection is removed
- *
- * @author Gail Badner
- */
-public class PostCollectionRemoveEvent extends AbstractCollectionEvent {
-
-	public PostCollectionRemoveEvent(CollectionPersister collectionPersister,
-									 PersistentCollection collection,
-									 EventSource source,
-									 Object loadedOwner ) {
-		super( collectionPersister, collection, source,
-				loadedOwner,
-				getOwnerIdOrNull( loadedOwner, source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs after a collection is removed
+ *
+ * @author Gail Badner
+ */
+public class PostCollectionRemoveEvent extends AbstractCollectionEvent {
+
+	public PostCollectionRemoveEvent(CollectionPersister collectionPersister,
+									 PersistentCollection collection,
+									 EventSource source,
+									 Object loadedOwner ) {
+		super( collectionPersister, collection, source,
+				loadedOwner,
+				getOwnerIdOrNull( loadedOwner, source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after removing a collection
- *
- * @author Gail Badner
- */
-public interface PostCollectionRemoveEventListener extends Serializable {
-	public void onPostRemoveCollection(PostCollectionRemoveEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionRemoveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after removing a collection
+ *
+ * @author Gail Badner
+ */
+public interface PostCollectionRemoveEventListener extends Serializable {
+	public void onPostRemoveCollection(PostCollectionRemoveEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs after a collection is updated
- *
- * @author Gail Badner
- */
-public class PostCollectionUpdateEvent extends AbstractCollectionEvent {
-
-	public PostCollectionUpdateEvent(CollectionPersister collectionPersister,
-									 PersistentCollection collection,
-									 EventSource source) {
-		super( collectionPersister, collection, source,
-				getLoadedOwnerOrNull( collection, source ),
-				getLoadedOwnerIdOrNull( collection, source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs after a collection is updated
+ *
+ * @author Gail Badner
+ */
+public class PostCollectionUpdateEvent extends AbstractCollectionEvent {
+
+	public PostCollectionUpdateEvent(CollectionPersister collectionPersister,
+									 PersistentCollection collection,
+									 EventSource source) {
+		super( collectionPersister, collection, source,
+				getLoadedOwnerOrNull( collection, source ),
+				getLoadedOwnerIdOrNull( collection, source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after updating a collection
- *
- * @author Gail Badner
- */
-public interface PostCollectionUpdateEventListener extends Serializable {
-	public void onPostUpdateCollection(PostCollectionUpdateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostCollectionUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after updating a collection
+ *
+ * @author Gail Badner
+ */
+public interface PostCollectionUpdateEventListener extends Serializable {
+	public void onPostUpdateCollection(PostCollectionUpdateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostDeleteEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: PostDeleteEvent.java 10680 2006-11-01 22:53:30Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Occurs after deleting an item from the datastore
- * 
- * @author Gavin King
- */
-public class PostDeleteEvent extends AbstractEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Serializable id;
-	private Object[] deletedState;
-	
-	public PostDeleteEvent(
-			Object entity, 
-			Serializable id,
-			Object[] deletedState,
-			EntityPersister persister,
-			EventSource source
-	) {
-		super(source);
-		this.entity = entity;
-		this.id = id;
-		this.persister = persister;
-		this.deletedState = deletedState;
-	}
-	
-	public Serializable getId() {
-		return id;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object getEntity() {
-		return entity;
-	}
-	public Object[] getDeletedState() {
-		return deletedState;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostDeleteEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Occurs after deleting an item from the datastore
+ * 
+ * @author Gavin King
+ */
+public class PostDeleteEvent extends AbstractEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Serializable id;
+	private Object[] deletedState;
+	
+	public PostDeleteEvent(
+			Object entity, 
+			Serializable id,
+			Object[] deletedState,
+			EntityPersister persister,
+			EventSource source
+	) {
+		super(source);
+		this.entity = entity;
+		this.id = id;
+		this.persister = persister;
+		this.deletedState = deletedState;
+	}
+	
+	public Serializable getId() {
+		return id;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object getEntity() {
+		return entity;
+	}
+	public Object[] getDeletedState() {
+		return deletedState;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: PostDeleteEventListener.java 7581 2005-07-20 22:48:22Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after deleting an item from the datastore
- * 
- * @author Gavin King
- */
-public interface PostDeleteEventListener extends Serializable {
-	public void onPostDelete(PostDeleteEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after deleting an item from the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PostDeleteEventListener extends Serializable {
+	public void onPostDelete(PostDeleteEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostInsertEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: PostInsertEvent.java 10680 2006-11-01 22:53:30Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Occurs after inserting an item in the datastore
- * 
- * @author Gavin King
- */
-public class PostInsertEvent extends AbstractEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Object[] state;
-	private Serializable id;
-	
-	public PostInsertEvent(
-			Object entity, 
-			Serializable id,
-			Object[] state,
-			EntityPersister persister,
-			EventSource source
-	) {
-		super(source);
-		this.entity = entity;
-		this.id = id;
-		this.state = state;
-		this.persister = persister;
-	}
-	
-	public Object getEntity() {
-		return entity;
-	}
-	public Serializable getId() {
-		return id;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object[] getState() {
-		return state;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostInsertEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Occurs after inserting an item in the datastore
+ * 
+ * @author Gavin King
+ */
+public class PostInsertEvent extends AbstractEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Object[] state;
+	private Serializable id;
+	
+	public PostInsertEvent(
+			Object entity, 
+			Serializable id,
+			Object[] state,
+			EntityPersister persister,
+			EventSource source
+	) {
+		super(source);
+		this.entity = entity;
+		this.id = id;
+		this.state = state;
+		this.persister = persister;
+	}
+	
+	public Object getEntity() {
+		return entity;
+	}
+	public Serializable getId() {
+		return id;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object[] getState() {
+		return state;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostInsertEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: PostInsertEventListener.java 7581 2005-07-20 22:48:22Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after insterting an item in the datastore
- * 
- * @author Gavin King
- */
-public interface PostInsertEventListener extends Serializable {
-	public void onPostInsert(PostInsertEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostInsertEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after insterting an item in the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PostInsertEventListener extends Serializable {
+	public void onPostInsert(PostInsertEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostLoadEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: PostLoadEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Occurs after an an entity instance is fully loaded.
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>, Gavin King
- */
-public class PostLoadEvent extends AbstractEvent {
-	private Object entity;
-	private Serializable id;
-	private EntityPersister persister;
-
-	public PostLoadEvent(EventSource session) {
-		super(session);
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	
-	public Serializable getId() {
-		return id;
-	}
-
-	public PostLoadEvent setEntity(Object entity) {
-		this.entity = entity;
-		return this;
-	}
-	
-	public PostLoadEvent setId(Serializable id) {
-		this.id = id;
-		return this;
-	}
-
-	public PostLoadEvent setPersister(EntityPersister persister) {
-		this.persister = persister;
-		return this;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostLoadEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Occurs after an an entity instance is fully loaded.
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>, Gavin King
+ */
+public class PostLoadEvent extends AbstractEvent {
+	private Object entity;
+	private Serializable id;
+	private EntityPersister persister;
+
+	public PostLoadEvent(EventSource session) {
+		super(session);
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	
+	public Serializable getId() {
+		return id;
+	}
+
+	public PostLoadEvent setEntity(Object entity) {
+		this.entity = entity;
+		return this;
+	}
+	
+	public PostLoadEvent setId(Serializable id) {
+		this.id = id;
+		return this;
+	}
+
+	public PostLoadEvent setPersister(EntityPersister persister) {
+		this.persister = persister;
+		return this;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: PostLoadEventListener.java 5006 2004-12-19 20:15:13Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Occurs after an an entity instance is fully loaded.
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- */
-public interface PostLoadEventListener extends Serializable {
-	public void onPostLoad(PostLoadEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Occurs after an an entity instance is fully loaded.
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ */
+public interface PostLoadEventListener extends Serializable {
+	public void onPostLoad(PostLoadEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostUpdateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-//$Id: PostUpdateEvent.java 9964 2006-05-30 15:40:54Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Occurs after the datastore is updated
- * 
- * @author Gavin King
- */
-public class PostUpdateEvent extends AbstractEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Object[] state;
-	private Object[] oldState;
-	private Serializable id;
-	
-	public PostUpdateEvent(
-			Object entity, 
-			Serializable id,
-			Object[] state,
-			Object[] oldState,
-			EntityPersister persister,
-			EventSource source
-	) {
-		super(source);
-		this.entity = entity;
-		this.id = id;
-		this.state = state;
-		this.oldState = oldState;
-		this.persister = persister;
-	}
-	
-	public Object getEntity() {
-		return entity;
-	}
-	public Serializable getId() {
-		return id;
-	}
-	public Object[] getOldState() {
-		return oldState;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object[] getState() {
-		return state;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostUpdateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Occurs after the datastore is updated
+ * 
+ * @author Gavin King
+ */
+public class PostUpdateEvent extends AbstractEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Object[] state;
+	private Object[] oldState;
+	private Serializable id;
+	
+	public PostUpdateEvent(
+			Object entity, 
+			Serializable id,
+			Object[] state,
+			Object[] oldState,
+			EntityPersister persister,
+			EventSource source
+	) {
+		super(source);
+		this.entity = entity;
+		this.id = id;
+		this.state = state;
+		this.oldState = oldState;
+		this.persister = persister;
+	}
+	
+	public Object getEntity() {
+		return entity;
+	}
+	public Serializable getId() {
+		return id;
+	}
+	public Object[] getOldState() {
+		return oldState;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object[] getState() {
+		return state;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: PostUpdateEventListener.java 7581 2005-07-20 22:48:22Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called after updating the datastore
- * 
- * @author Gavin King
- */
-public interface PostUpdateEventListener extends Serializable {
-	public void onPostUpdate(PostUpdateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PostUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called after updating the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PostUpdateEventListener extends Serializable {
+	public void onPostUpdate(PostUpdateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs before a collection is recreated
- *
- * @author Gail Badner
- */
-public class PreCollectionRecreateEvent extends AbstractCollectionEvent {
-
-	public PreCollectionRecreateEvent(CollectionPersister collectionPersister,
-									  PersistentCollection collection,
-									  EventSource source) {
-		super( collectionPersister, collection, source,
-				collection.getOwner(),
-				getOwnerIdOrNull( collection.getOwner(), source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs before a collection is recreated
+ *
+ * @author Gail Badner
+ */
+public class PreCollectionRecreateEvent extends AbstractCollectionEvent {
+
+	public PreCollectionRecreateEvent(CollectionPersister collectionPersister,
+									  PersistentCollection collection,
+									  EventSource source) {
+		super( collectionPersister, collection, source,
+				collection.getOwner(),
+				getOwnerIdOrNull( collection.getOwner(), source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before recreating a collection
- *
- * @author Gail Badner
- */
-public interface PreCollectionRecreateEventListener extends Serializable {
-	public void onPreRecreateCollection(PreCollectionRecreateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRecreateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before recreating a collection
+ *
+ * @author Gail Badner
+ */
+public interface PreCollectionRecreateEventListener extends Serializable {
+	public void onPreRecreateCollection(PreCollectionRecreateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs before a collection is removed
- *
- * @author Gail Badner
- */
-public class PreCollectionRemoveEvent extends AbstractCollectionEvent {
-
-	public PreCollectionRemoveEvent(CollectionPersister collectionPersister,
-									PersistentCollection collection,
-									EventSource source,
-									Object loadedOwner) {
-		super( collectionPersister, collection, source,
-				loadedOwner,
-				getOwnerIdOrNull( loadedOwner, source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs before a collection is removed
+ *
+ * @author Gail Badner
+ */
+public class PreCollectionRemoveEvent extends AbstractCollectionEvent {
+
+	public PreCollectionRemoveEvent(CollectionPersister collectionPersister,
+									PersistentCollection collection,
+									EventSource source,
+									Object loadedOwner) {
+		super( collectionPersister, collection, source,
+				loadedOwner,
+				getOwnerIdOrNull( loadedOwner, source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before removing a collection
- *
- * @author Gail Badner
- */
-public interface PreCollectionRemoveEventListener extends Serializable {
-	public void onPreRemoveCollection(PreCollectionRemoveEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionRemoveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before removing a collection
+ *
+ * @author Gail Badner
+ */
+public interface PreCollectionRemoveEventListener extends Serializable {
+	public void onPreRemoveCollection(PreCollectionRemoveEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: $
-package org.hibernate.event;
-
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * An event that occurs before a collection is updated
- *
- * @author Gail Badner
- */
-public class PreCollectionUpdateEvent extends AbstractCollectionEvent {
-
-	public PreCollectionUpdateEvent(CollectionPersister collectionPersister,
-									PersistentCollection collection,
-									EventSource source) {
-		super( collectionPersister, collection, source,
-				getLoadedOwnerOrNull( collection, source ),
-				getLoadedOwnerIdOrNull( collection, source ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.event;
+
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * An event that occurs before a collection is updated
+ *
+ * @author Gail Badner
+ */
+public class PreCollectionUpdateEvent extends AbstractCollectionEvent {
+
+	public PreCollectionUpdateEvent(CollectionPersister collectionPersister,
+									PersistentCollection collection,
+									EventSource source) {
+		super( collectionPersister, collection, source,
+				getLoadedOwnerOrNull( collection, source ),
+				getLoadedOwnerIdOrNull( collection, source ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,12 +0,0 @@
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before updating a collection
- *
- * @author Gail Badner
- */
-public interface PreCollectionUpdateEventListener extends Serializable {
-	public void onPreUpdateCollection(PreCollectionUpdateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreCollectionUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before updating a collection
+ *
+ * @author Gail Badner
+ */
+public interface PreCollectionUpdateEventListener extends Serializable {
+	public void onPreUpdateCollection(PreCollectionUpdateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreDeleteEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-//$Id: PreDeleteEvent.java 7581 2005-07-20 22:48:22Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Occurs before deleting an item from the datastore
- * 
- * @author Gavin King
- */
-public class PreDeleteEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Serializable id;
-	private Object[] deletedState;
-	
-	public Object getEntity() {
-		return entity;
-	}
-	public Serializable getId() {
-		return id;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object[] getDeletedState() {
-		return deletedState;
-	}
-	
-	public PreDeleteEvent(
-			Object entity, 
-			Serializable id,
-			Object[] deletedState,
-			EntityPersister persister
-	) {
-		this.entity = entity;
-		this.persister = persister;
-		this.id = id;
-		this.deletedState = deletedState;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreDeleteEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Occurs before deleting an item from the datastore
+ * 
+ * @author Gavin King
+ */
+public class PreDeleteEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Serializable id;
+	private Object[] deletedState;
+	
+	public Object getEntity() {
+		return entity;
+	}
+	public Serializable getId() {
+		return id;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object[] getDeletedState() {
+		return deletedState;
+	}
+	
+	public PreDeleteEvent(
+			Object entity, 
+			Serializable id,
+			Object[] deletedState,
+			EntityPersister persister
+	) {
+		this.entity = entity;
+		this.persister = persister;
+		this.id = id;
+		this.deletedState = deletedState;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: PreDeleteEventListener.java 11272 2007-03-12 00:17:45Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before deleting an item from the datastore
- * 
- * @author Gavin King
- */
-public interface PreDeleteEventListener extends Serializable {
-	/**
-	 * Return true if the operation should be vetoed
-	 */
-	public boolean onPreDelete(PreDeleteEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before deleting an item from the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PreDeleteEventListener extends Serializable {
+	/**
+	 * Return true if the operation should be vetoed
+	 */
+	public boolean onPreDelete(PreDeleteEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreInsertEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: PreInsertEvent.java 7850 2005-08-11 19:37:08Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Occurs before inserting an item in the datastore
- * 
- * @author Gavin King
- */
-public class PreInsertEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Object[] state;
-	private Serializable id;
-	private SessionImplementor source;
-
-	public PreInsertEvent(
-			Object entity,
-			Serializable id,
-			Object[] state,
-			EntityPersister persister,
-			SessionImplementor source
-	) {
-		this.source = source;
-		this.entity = entity;
-		this.id = id;
-		this.state = state;
-		this.persister = persister;
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	public Serializable getId() {
-		return id;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object[] getState() {
-		return state;
-	}
-	public SessionImplementor getSource() {
-		return source;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreInsertEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Occurs before inserting an item in the datastore
+ * 
+ * @author Gavin King
+ */
+public class PreInsertEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Object[] state;
+	private Serializable id;
+	private SessionImplementor source;
+
+	public PreInsertEvent(
+			Object entity,
+			Serializable id,
+			Object[] state,
+			EntityPersister persister,
+			SessionImplementor source
+	) {
+		this.source = source;
+		this.entity = entity;
+		this.id = id;
+		this.state = state;
+		this.persister = persister;
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	public Serializable getId() {
+		return id;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object[] getState() {
+		return state;
+	}
+	public SessionImplementor getSource() {
+		return source;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreInsertEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: PreInsertEventListener.java 11272 2007-03-12 00:17:45Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before inserting an item in the datastore
- * 
- * @author Gavin King
- */
-public interface PreInsertEventListener extends Serializable {
-	/**
-	 * Return true if the operation should be vetoed
-	 */
-	public boolean onPreInsert(PreInsertEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreInsertEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before inserting an item in the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PreInsertEventListener extends Serializable {
+	/**
+	 * Return true if the operation should be vetoed
+	 */
+	public boolean onPreInsert(PreInsertEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreLoadEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-//$Id: PreLoadEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Called before injecting property values into a newly 
- * loaded entity instance.
- *
- * @author Gavin King
- */
-public class PreLoadEvent extends AbstractEvent {
-	private Object entity;
-	private Object[] state;
-	private Serializable id;
-	private EntityPersister persister;
-
-	public PreLoadEvent(EventSource session) {
-		super(session);
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	
-	public Serializable getId() {
-		return id;
-	}
-	
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	
-	public Object[] getState() {
-		return state;
-	}
-
-	public PreLoadEvent setEntity(Object entity) {
-		this.entity = entity;
-		return this;
-	}
-	
-	public PreLoadEvent setId(Serializable id) {
-		this.id = id;
-		return this;
-	}
-	
-	public PreLoadEvent setPersister(EntityPersister persister) {
-		this.persister = persister;
-		return this;
-	}
-	
-	public PreLoadEvent setState(Object[] state) {
-		this.state = state;
-		return this;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreLoadEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Called before injecting property values into a newly 
+ * loaded entity instance.
+ *
+ * @author Gavin King
+ */
+public class PreLoadEvent extends AbstractEvent {
+	private Object entity;
+	private Object[] state;
+	private Serializable id;
+	private EntityPersister persister;
+
+	public PreLoadEvent(EventSource session) {
+		super(session);
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	
+	public Serializable getId() {
+		return id;
+	}
+	
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	
+	public Object[] getState() {
+		return state;
+	}
+
+	public PreLoadEvent setEntity(Object entity) {
+		this.entity = entity;
+		return this;
+	}
+	
+	public PreLoadEvent setId(Serializable id) {
+		this.id = id;
+		return this;
+	}
+	
+	public PreLoadEvent setPersister(EntityPersister persister) {
+		this.persister = persister;
+		return this;
+	}
+	
+	public PreLoadEvent setState(Object[] state) {
+		this.state = state;
+		return this;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-//$Id: PreLoadEventListener.java 5006 2004-12-19 20:15:13Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before injecting property values into a newly 
- * loaded entity instance.
- *
- * @author Gavin King
- */
-public interface PreLoadEventListener extends Serializable {
-	public void onPreLoad(PreLoadEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before injecting property values into a newly 
+ * loaded entity instance.
+ *
+ * @author Gavin King
+ */
+public interface PreLoadEventListener extends Serializable {
+	public void onPreLoad(PreLoadEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreUpdateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,56 +0,0 @@
-//$Id: PreUpdateEvent.java 7850 2005-08-11 19:37:08Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Occurs before updating the datastore
- * 
- * @author Gavin King
- */
-public class PreUpdateEvent {
-	private Object entity;
-	private EntityPersister persister;
-	private Object[] state;
-	private Object[] oldState;
-	private Serializable id;
-	private SessionImplementor source;
-
-	public PreUpdateEvent(
-			Object entity,
-			Serializable id,
-			Object[] state,
-			Object[] oldState,
-			EntityPersister persister,
-			SessionImplementor source
-	) {
-		this.source = source;
-		this.entity = entity;
-		this.id = id;
-		this.state = state;
-		this.oldState = oldState;
-		this.persister = persister;
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	public Serializable getId() {
-		return id;
-	}
-	public Object[] getOldState() {
-		return oldState;
-	}
-	public EntityPersister getPersister() {
-		return persister;
-	}
-	public Object[] getState() {
-		return state;
-	}
-	public SessionImplementor getSource() {
-		return source;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreUpdateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Occurs before updating the datastore
+ * 
+ * @author Gavin King
+ */
+public class PreUpdateEvent {
+	private Object entity;
+	private EntityPersister persister;
+	private Object[] state;
+	private Object[] oldState;
+	private Serializable id;
+	private SessionImplementor source;
+
+	public PreUpdateEvent(
+			Object entity,
+			Serializable id,
+			Object[] state,
+			Object[] oldState,
+			EntityPersister persister,
+			SessionImplementor source
+	) {
+		this.source = source;
+		this.entity = entity;
+		this.id = id;
+		this.state = state;
+		this.oldState = oldState;
+		this.persister = persister;
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	public Serializable getId() {
+		return id;
+	}
+	public Object[] getOldState() {
+		return oldState;
+	}
+	public EntityPersister getPersister() {
+		return persister;
+	}
+	public Object[] getState() {
+		return state;
+	}
+	public SessionImplementor getSource() {
+		return source;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: PreUpdateEventListener.java 11272 2007-03-12 00:17:45Z epbernard $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-/**
- * Called before updating the datastore
- * 
- * @author Gavin King
- */
-public interface PreUpdateEventListener extends Serializable {
-	/**
-	 * Return true if the operation should be vetoed
-	 */
-	public boolean onPreUpdate(PreUpdateEvent event);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/PreUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+/**
+ * Called before updating the datastore
+ * 
+ * @author Gavin King
+ */
+public interface PreUpdateEventListener extends Serializable {
+	/**
+	 * Return true if the operation should be vetoed
+	 */
+	public boolean onPreUpdate(PreUpdateEvent event);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/RefreshEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: RefreshEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.LockMode;
-
-/**
- *  Defines an event class for the refreshing of an object.
- *
- * @author Steve Ebersole
- */
-public class RefreshEvent extends AbstractEvent {
-
-	private Object object;
-	private LockMode lockMode = LockMode.READ;
-
-	public RefreshEvent(Object object, EventSource source) {
-		super(source);
-		if (object == null) {
-			throw new IllegalArgumentException("Attempt to generate refresh event with null object");
-		}
-		this.object = object;
-	}
-
-	public RefreshEvent(Object object, LockMode lockMode, EventSource source) {
-		this(object, source);
-		if (lockMode == null) {
-			throw new IllegalArgumentException("Attempt to generate refresh event with null lock mode");
-		}
-		this.lockMode = lockMode;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/RefreshEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.event;
+
+import org.hibernate.LockMode;
+
+/**
+ *  Defines an event class for the refreshing of an object.
+ *
+ * @author Steve Ebersole
+ */
+public class RefreshEvent extends AbstractEvent {
+
+	private Object object;
+	private LockMode lockMode = LockMode.READ;
+
+	public RefreshEvent(Object object, EventSource source) {
+		super(source);
+		if (object == null) {
+			throw new IllegalArgumentException("Attempt to generate refresh event with null object");
+		}
+		this.object = object;
+	}
+
+	public RefreshEvent(Object object, LockMode lockMode, EventSource source) {
+		this(object, source);
+		if (lockMode == null) {
+			throw new IllegalArgumentException("Attempt to generate refresh event with null lock mode");
+		}
+		this.lockMode = lockMode;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/RefreshEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: RefreshEventListener.java 7485 2005-07-15 03:35:18Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-import java.util.Map;
-
-/**
- * Defines the contract for handling of refresh events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface RefreshEventListener extends Serializable {
-
-    /** 
-     * Handle the given refresh event.
-     *
-     * @param event The refresh event to be handled.
-     * @throws HibernateException
-     */
-	public void onRefresh(RefreshEvent event) throws HibernateException;
-	
-	public void onRefresh(RefreshEvent event, Map refreshedAlready) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/RefreshEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/RefreshEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * Defines the contract for handling of refresh events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface RefreshEventListener extends Serializable {
+
+    /** 
+     * Handle the given refresh event.
+     *
+     * @param event The refresh event to be handled.
+     * @throws HibernateException
+     */
+	public void onRefresh(RefreshEvent event) throws HibernateException;
+	
+	public void onRefresh(RefreshEvent event, Map refreshedAlready) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/ReplicateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-//$Id: ReplicateEvent.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.ReplicationMode;
-
-/**
- *  Defines an event class for the replication of an entity.
- *
- * @author Steve Ebersole
- */
-public class ReplicateEvent extends AbstractEvent {
-
-	private Object object;
-	private ReplicationMode replicationMode;
-	private String entityName;
-
-	public ReplicateEvent(Object object, ReplicationMode replicationMode, EventSource source) {
-		this(null, object, replicationMode, source);
-	}
-	
-	public ReplicateEvent(String entityName, Object object, ReplicationMode replicationMode, EventSource source) {
-		super(source);
-		this.entityName = entityName;
-
-		if ( object == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create replication strategy with null entity"
-			);
-		}
-		if ( replicationMode == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create replication strategy with null replication mode"
-			);
-		}
-
-		this.object = object;
-		this.replicationMode = replicationMode;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public void setObject(Object object) {
-		this.object = object;
-	}
-
-	public ReplicationMode getReplicationMode() {
-		return replicationMode;
-	}
-
-	public void setReplicationMode(ReplicationMode replicationMode) {
-		this.replicationMode = replicationMode;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/ReplicateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.event;
+
+import org.hibernate.ReplicationMode;
+
+/**
+ *  Defines an event class for the replication of an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class ReplicateEvent extends AbstractEvent {
+
+	private Object object;
+	private ReplicationMode replicationMode;
+	private String entityName;
+
+	public ReplicateEvent(Object object, ReplicationMode replicationMode, EventSource source) {
+		this(null, object, replicationMode, source);
+	}
+	
+	public ReplicateEvent(String entityName, Object object, ReplicationMode replicationMode, EventSource source) {
+		super(source);
+		this.entityName = entityName;
+
+		if ( object == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create replication strategy with null entity"
+			);
+		}
+		if ( replicationMode == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create replication strategy with null replication mode"
+			);
+		}
+
+		this.object = object;
+		this.replicationMode = replicationMode;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+
+	public ReplicationMode getReplicationMode() {
+		return replicationMode;
+	}
+
+	public void setReplicationMode(ReplicationMode replicationMode) {
+		this.replicationMode = replicationMode;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/ReplicateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: ReplicateEventListener.java 4185 2004-08-08 11:24:56Z oneovthafew $
-package org.hibernate.event;
-
-import org.hibernate.HibernateException;
-
-import java.io.Serializable;
-
-/**
- * Defines the contract for handling of replicate events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface ReplicateEventListener extends Serializable {
-
-    /** Handle the given replicate event.
-     *
-     * @param event The replicate event to be handled.
-     * @throws HibernateException
-     */
-	public void onReplicate(ReplicateEvent event) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/ReplicateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/ReplicateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import org.hibernate.HibernateException;
+
+import java.io.Serializable;
+
+/**
+ * Defines the contract for handling of replicate events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface ReplicateEventListener extends Serializable {
+
+    /** Handle the given replicate event.
+     *
+     * @param event The replicate event to be handled.
+     * @throws HibernateException
+     */
+	public void onReplicate(ReplicateEvent event) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-//$Id: SaveOrUpdateEvent.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.engine.EntityEntry;
-
-/** 
- * An event class for saveOrUpdate()
- *
- * @author Steve Ebersole
- */
-public class SaveOrUpdateEvent extends AbstractEvent {
-
-	private Object object;
-	private Serializable requestedId;
-	private String entityName;
-	private Object entity;
-	private EntityEntry entry;
-	private Serializable resultId;
-
-	public SaveOrUpdateEvent(String entityName, Object original, EventSource source) {
-		this(original, source);
-		this.entityName = entityName;
-	}
-
-	public SaveOrUpdateEvent(String entityName, Object original, Serializable id, EventSource source) {
-		this(entityName, original, source);
-		this.requestedId = id;
-		if ( requestedId == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create saveOrUpdate event with null identifier"
-				);
-		}
-	}
-
-	public SaveOrUpdateEvent(Object object, EventSource source) {
-		super(source);
-		if ( object == null ) {
-			throw new IllegalArgumentException(
-					"attempt to create saveOrUpdate event with null entity"
-				);
-		}
-		this.object = object;
-	}
-
-	public Object getObject() {
-		return object;
-	}
-
-	public void setObject(Object object) {
-		this.object = object;
-	}
-
-	public Serializable getRequestedId() {
-		return requestedId;
-	}
-
-	public void setRequestedId(Serializable requestedId) {
-		this.requestedId = requestedId;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-
-	public Object getEntity() {
-		return entity;
-	}
-	
-	public void setEntity(Object entity) {
-		this.entity = entity;
-	}
-	
-	public EntityEntry getEntry() {
-		return entry;
-	}
-	
-	public void setEntry(EntityEntry entry) {
-		this.entry = entry;
-	}
-
-	public Serializable getResultId() {
-		return resultId;
-	}
-
-	public void setResultId(Serializable resultId) {
-		this.resultId = resultId;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEvent.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.engine.EntityEntry;
+
+/** 
+ * An event class for saveOrUpdate()
+ *
+ * @author Steve Ebersole
+ */
+public class SaveOrUpdateEvent extends AbstractEvent {
+
+	private Object object;
+	private Serializable requestedId;
+	private String entityName;
+	private Object entity;
+	private EntityEntry entry;
+	private Serializable resultId;
+
+	public SaveOrUpdateEvent(String entityName, Object original, EventSource source) {
+		this(original, source);
+		this.entityName = entityName;
+	}
+
+	public SaveOrUpdateEvent(String entityName, Object original, Serializable id, EventSource source) {
+		this(entityName, original, source);
+		this.requestedId = id;
+		if ( requestedId == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create saveOrUpdate event with null identifier"
+				);
+		}
+	}
+
+	public SaveOrUpdateEvent(Object object, EventSource source) {
+		super(source);
+		if ( object == null ) {
+			throw new IllegalArgumentException(
+					"attempt to create saveOrUpdate event with null entity"
+				);
+		}
+		this.object = object;
+	}
+
+	public Object getObject() {
+		return object;
+	}
+
+	public void setObject(Object object) {
+		this.object = object;
+	}
+
+	public Serializable getRequestedId() {
+		return requestedId;
+	}
+
+	public void setRequestedId(Serializable requestedId) {
+		this.requestedId = requestedId;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+
+	public Object getEntity() {
+		return entity;
+	}
+	
+	public void setEntity(Object entity) {
+		this.entity = entity;
+	}
+	
+	public EntityEntry getEntry() {
+		return entry;
+	}
+	
+	public void setEntry(EntityEntry entry) {
+		this.entry = entry;
+	}
+
+	public Serializable getResultId() {
+		return resultId;
+	}
+
+	public void setResultId(Serializable resultId) {
+		this.resultId = resultId;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: SaveOrUpdateEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-
-/**
- * Defines the contract for handling of update events generated from a session.
- *
- * @author Steve Ebersole
- */
-public interface SaveOrUpdateEventListener extends Serializable {
-
-    /** 
-     * Handle the given update event.
-     *
-     * @param event The update event to be handled.
-     * @throws HibernateException
-     */
-	public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/SaveOrUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Defines the contract for handling of update events generated from a session.
+ *
+ * @author Steve Ebersole
+ */
+public interface SaveOrUpdateEventListener extends Serializable {
+
+    /** 
+     * Handle the given update event.
+     *
+     * @param event The update event to be handled.
+     * @throws HibernateException
+     */
+	public void onSaveOrUpdate(SaveOrUpdateEvent event) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,356 +0,0 @@
-//$Id: AbstractFlushingEventListener.java 11402 2007-04-11 14:24:35Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.action.CollectionRecreateAction;
-import org.hibernate.action.CollectionRemoveAction;
-import org.hibernate.action.CollectionUpdateAction;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.ActionQueue;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.CollectionKey;
-import org.hibernate.engine.Collections;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.Status;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.FlushEntityEvent;
-import org.hibernate.event.FlushEntityEventListener;
-import org.hibernate.event.FlushEvent;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.Printer;
-import org.hibernate.util.IdentityMap;
-import org.hibernate.util.LazyIterator;
-
-/**
- * A convenience base class for listeners whose functionality results in flushing.
- *
- * @author Steve Eberole
- */
-public abstract class AbstractFlushingEventListener implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger(AbstractFlushingEventListener.class);
-	
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// Pre-flushing section
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/** 
-	 * Coordinates the processing necessary to get things ready for executions
-	 * as db calls by preping the session caches and moving the appropriate
-	 * entities and collections to their respective execution queues.
-	 *
-	 * @param event The flush event.
-	 * @throws HibernateException Error flushing caches to execution queues.
-	 */
-	protected void flushEverythingToExecutions(FlushEvent event) throws HibernateException {
-
-		log.trace("flushing session");
-		
-		EventSource session = event.getSession();
-		
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		session.getInterceptor().preFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) );
-
-		prepareEntityFlushes(session);
-		// we could move this inside if we wanted to
-		// tolerate collection initializations during
-		// collection dirty checking:
-		prepareCollectionFlushes(session);
-		// now, any collections that are initialized
-		// inside this block do not get updated - they
-		// are ignored until the next flush
-				
-		persistenceContext.setFlushing(true);
-		try {
-			flushEntities(event);
-			flushCollections(session);
-		}
-		finally {
-			persistenceContext.setFlushing(false);
-		}
-
-		//some statistics
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Flushed: " +
-					session.getActionQueue().numberOfInsertions() + " insertions, " +
-					session.getActionQueue().numberOfUpdates() + " updates, " +
-					session.getActionQueue().numberOfDeletions() + " deletions to " +
-					persistenceContext.getEntityEntries().size() + " objects"
-				);
-			log.debug( "Flushed: " +
-					session.getActionQueue().numberOfCollectionCreations() + " (re)creations, " +
-					session.getActionQueue().numberOfCollectionUpdates() + " updates, " +
-					session.getActionQueue().numberOfCollectionRemovals() + " removals to " +
-					persistenceContext.getCollectionEntries().size() + " collections"
-				);
-			new Printer( session.getFactory() ).toString( 
-					persistenceContext.getEntitiesByKey().values().iterator(), 
-					session.getEntityMode() 
-				);
-		}
-	}
-
-	/**
-	 * process cascade save/update at the start of a flush to discover
-	 * any newly referenced entity that must be passed to saveOrUpdate(),
-	 * and also apply orphan delete
-	 */
-	private void prepareEntityFlushes(EventSource session) throws HibernateException {
-		
-		log.debug("processing flush-time cascades");
-
-		final Map.Entry[] list = IdentityMap.concurrentEntries( session.getPersistenceContext().getEntityEntries() );
-		//safe from concurrent modification because of how entryList() is implemented on IdentityMap
-		final int size = list.length;
-		final Object anything = getAnything();
-		for ( int i=0; i<size; i++ ) {
-			Map.Entry me = list[i];
-			EntityEntry entry = (EntityEntry) me.getValue();
-			Status status = entry.getStatus();
-			if ( status == Status.MANAGED || status == Status.SAVING ) {
-				cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
-			}
-		}
-	}
-	
-	private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything) 
-	throws HibernateException {
-		session.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( getCascadingAction(), Cascade.BEFORE_FLUSH, session )
-			.cascade( persister, object, anything );
-		}
-		finally {
-			session.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-	
-	protected Object getAnything() { return null; }
-	
-	protected CascadingAction getCascadingAction() {
-		return CascadingAction.SAVE_UPDATE;
-	}
-
-	/**
-	 * Initialize the flags of the CollectionEntry, including the
-	 * dirty check.
-	 */
-	private void prepareCollectionFlushes(SessionImplementor session) throws HibernateException {
-
-		// Initialize dirty flags for arrays + collections with composite elements
-		// and reset reached, doupdate, etc.
-		
-		log.debug("dirty checking collections");
-
-		final List list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
-		final int size = list.size();
-		for ( int i = 0; i < size; i++ ) {
-			Map.Entry e = ( Map.Entry ) list.get( i );
-			( (CollectionEntry) e.getValue() ).preFlush( (PersistentCollection) e.getKey() );
-		}
-	}
-
-	/**
-	 * 1. detect any dirty entities
-	 * 2. schedule any entity updates
-	 * 3. search out any reachable collections
-	 */
-	private void flushEntities(FlushEvent event) throws HibernateException {
-
-		log.trace("Flushing entities and processing referenced collections");
-
-		// Among other things, updateReachables() will recursively load all
-		// collections that are moving roles. This might cause entities to
-		// be loaded.
-
-		// So this needs to be safe from concurrent modification problems.
-		// It is safe because of how IdentityMap implements entrySet()
-
-		final EventSource source = event.getSession();
-		
-		final Map.Entry[] list = IdentityMap.concurrentEntries( source.getPersistenceContext().getEntityEntries() );
-		final int size = list.length;
-		for ( int i = 0; i < size; i++ ) {
-
-			// Update the status of the object and if necessary, schedule an update
-
-			Map.Entry me = list[i];
-			EntityEntry entry = (EntityEntry) me.getValue();
-			Status status = entry.getStatus();
-
-			if ( status != Status.LOADING && status != Status.GONE ) {
-				FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
-				FlushEntityEventListener[] listeners = source.getListeners().getFlushEntityEventListeners();
-				for ( int j = 0; j < listeners.length; j++ ) {
-					listeners[j].onFlushEntity(entityEvent);
-				}
-			}
-		}
-
-		source.getActionQueue().sortActions();
-	}
-
-	/**
-	 * process any unreferenced collections and then inspect all known collections,
-	 * scheduling creates/removes/updates
-	 */
-	private void flushCollections(EventSource session) throws HibernateException {
-
-		log.trace("Processing unreferenced collections");
-
-		List list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
-		int size = list.size();
-		for ( int i = 0; i < size; i++ ) {
-			Map.Entry me = ( Map.Entry ) list.get( i );
-			CollectionEntry ce = (CollectionEntry) me.getValue();
-			if ( !ce.isReached() && !ce.isIgnore() ) {
-				Collections.processUnreachableCollection( (PersistentCollection) me.getKey(), session );
-			}
-		}
-
-		// Schedule updates to collections:
-
-		log.trace( "Scheduling collection removes/(re)creates/updates" );
-
-		list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
-		size = list.size();
-		ActionQueue actionQueue = session.getActionQueue();
-		for ( int i = 0; i < size; i++ ) {
-			Map.Entry me = (Map.Entry) list.get(i);
-			PersistentCollection coll = (PersistentCollection) me.getKey();
-			CollectionEntry ce = (CollectionEntry) me.getValue();
-
-			if ( ce.isDorecreate() ) {
-				session.getInterceptor().onCollectionRecreate( coll, ce.getCurrentKey() );
-				actionQueue.addAction(
-						new CollectionRecreateAction( 
-								coll, 
-								ce.getCurrentPersister(), 
-								ce.getCurrentKey(), 
-								session 
-							)
-					);
-			}
-			if ( ce.isDoremove() ) {
-				session.getInterceptor().onCollectionRemove( coll, ce.getLoadedKey() );
-				actionQueue.addAction(
-						new CollectionRemoveAction( 
-								coll, 
-								ce.getLoadedPersister(), 
-								ce.getLoadedKey(), 
-								ce.isSnapshotEmpty(coll), 
-								session 
-							)
-					);
-			}
-			if ( ce.isDoupdate() ) {
-				session.getInterceptor().onCollectionUpdate( coll, ce.getLoadedKey() );
-				actionQueue.addAction(
-						new CollectionUpdateAction( 
-								coll, 
-								ce.getLoadedPersister(), 
-								ce.getLoadedKey(), 
-								ce.isSnapshotEmpty(coll), 
-								session 
-							)
-					);
-			}
-
-		}
-
-		actionQueue.sortCollectionActions();
-		
-	}
-
-	/**
-	 * Execute all SQL and second-level cache updates, in a
-	 * special order so that foreign-key constraints cannot
-	 * be violated:
-	 * <ol>
-	 * <li> Inserts, in the order they were performed
-	 * <li> Updates
-	 * <li> Deletion of collection elements
-	 * <li> Insertion of collection elements
-	 * <li> Deletes, in the order they were performed
-	 * </ol>
-	 */
-	protected void performExecutions(EventSource session) throws HibernateException {
-
-		log.trace("executing flush");
-
-		try {
-			session.getJDBCContext().getConnectionManager().flushBeginning();
-			// we need to lock the collection caches before
-			// executing entity inserts/updates in order to
-			// account for bidi associations
-			session.getActionQueue().prepareActions();
-			session.getActionQueue().executeActions();
-		}
-		catch (HibernateException he) {
-			log.error("Could not synchronize database state with session", he);
-			throw he;
-		}
-		finally {
-			session.getJDBCContext().getConnectionManager().flushEnding();
-		}
-	}
-
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// Post-flushing section
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * 1. Recreate the collection key -> collection map
-	 * 2. rebuild the collection entries
-	 * 3. call Interceptor.postFlush()
-	 */
-	protected void postFlush(SessionImplementor session) throws HibernateException {
-
-		log.trace( "post flush" );
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		persistenceContext.getCollectionsByKey().clear();
-		persistenceContext.getBatchFetchQueue()
-				.clearSubselects(); //the database has changed now, so the subselect results need to be invalidated
-
-		Iterator iter = persistenceContext.getCollectionEntries().entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			CollectionEntry collectionEntry = (CollectionEntry) me.getValue();
-			PersistentCollection persistentCollection = (PersistentCollection) me.getKey();
-			collectionEntry.postFlush(persistentCollection);
-			if ( collectionEntry.getLoadedPersister() == null ) {
-				//if the collection is dereferenced, remove from the session cache
-				//iter.remove(); //does not work, since the entrySet is not backed by the set
-				persistenceContext.getCollectionEntries()
-						.remove(persistentCollection);
-			}
-			else {
-				//otherwise recreate the mapping between the collection and its key
-				CollectionKey collectionKey = new CollectionKey( 
-						collectionEntry.getLoadedPersister(), 
-						collectionEntry.getLoadedKey(), 
-						session.getEntityMode() 
-					);
-				persistenceContext.getCollectionsByKey()
-						.put(collectionKey, persistentCollection);
-			}
-		}
-		
-		session.getInterceptor().postFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) );
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,379 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.action.CollectionRecreateAction;
+import org.hibernate.action.CollectionRemoveAction;
+import org.hibernate.action.CollectionUpdateAction;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.ActionQueue;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.CollectionKey;
+import org.hibernate.engine.Collections;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.Status;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.FlushEntityEvent;
+import org.hibernate.event.FlushEntityEventListener;
+import org.hibernate.event.FlushEvent;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.Printer;
+import org.hibernate.util.IdentityMap;
+import org.hibernate.util.LazyIterator;
+
+/**
+ * A convenience base class for listeners whose functionality results in flushing.
+ *
+ * @author Steve Eberole
+ */
+public abstract class AbstractFlushingEventListener implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(AbstractFlushingEventListener.class);
+	
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// Pre-flushing section
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/** 
+	 * Coordinates the processing necessary to get things ready for executions
+	 * as db calls by preping the session caches and moving the appropriate
+	 * entities and collections to their respective execution queues.
+	 *
+	 * @param event The flush event.
+	 * @throws HibernateException Error flushing caches to execution queues.
+	 */
+	protected void flushEverythingToExecutions(FlushEvent event) throws HibernateException {
+
+		log.trace("flushing session");
+		
+		EventSource session = event.getSession();
+		
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		session.getInterceptor().preFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) );
+
+		prepareEntityFlushes(session);
+		// we could move this inside if we wanted to
+		// tolerate collection initializations during
+		// collection dirty checking:
+		prepareCollectionFlushes(session);
+		// now, any collections that are initialized
+		// inside this block do not get updated - they
+		// are ignored until the next flush
+				
+		persistenceContext.setFlushing(true);
+		try {
+			flushEntities(event);
+			flushCollections(session);
+		}
+		finally {
+			persistenceContext.setFlushing(false);
+		}
+
+		//some statistics
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Flushed: " +
+					session.getActionQueue().numberOfInsertions() + " insertions, " +
+					session.getActionQueue().numberOfUpdates() + " updates, " +
+					session.getActionQueue().numberOfDeletions() + " deletions to " +
+					persistenceContext.getEntityEntries().size() + " objects"
+				);
+			log.debug( "Flushed: " +
+					session.getActionQueue().numberOfCollectionCreations() + " (re)creations, " +
+					session.getActionQueue().numberOfCollectionUpdates() + " updates, " +
+					session.getActionQueue().numberOfCollectionRemovals() + " removals to " +
+					persistenceContext.getCollectionEntries().size() + " collections"
+				);
+			new Printer( session.getFactory() ).toString( 
+					persistenceContext.getEntitiesByKey().values().iterator(), 
+					session.getEntityMode() 
+				);
+		}
+	}
+
+	/**
+	 * process cascade save/update at the start of a flush to discover
+	 * any newly referenced entity that must be passed to saveOrUpdate(),
+	 * and also apply orphan delete
+	 */
+	private void prepareEntityFlushes(EventSource session) throws HibernateException {
+		
+		log.debug("processing flush-time cascades");
+
+		final Map.Entry[] list = IdentityMap.concurrentEntries( session.getPersistenceContext().getEntityEntries() );
+		//safe from concurrent modification because of how entryList() is implemented on IdentityMap
+		final int size = list.length;
+		final Object anything = getAnything();
+		for ( int i=0; i<size; i++ ) {
+			Map.Entry me = list[i];
+			EntityEntry entry = (EntityEntry) me.getValue();
+			Status status = entry.getStatus();
+			if ( status == Status.MANAGED || status == Status.SAVING ) {
+				cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
+			}
+		}
+	}
+	
+	private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything) 
+	throws HibernateException {
+		session.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( getCascadingAction(), Cascade.BEFORE_FLUSH, session )
+			.cascade( persister, object, anything );
+		}
+		finally {
+			session.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+	
+	protected Object getAnything() { return null; }
+	
+	protected CascadingAction getCascadingAction() {
+		return CascadingAction.SAVE_UPDATE;
+	}
+
+	/**
+	 * Initialize the flags of the CollectionEntry, including the
+	 * dirty check.
+	 */
+	private void prepareCollectionFlushes(SessionImplementor session) throws HibernateException {
+
+		// Initialize dirty flags for arrays + collections with composite elements
+		// and reset reached, doupdate, etc.
+		
+		log.debug("dirty checking collections");
+
+		final List list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
+		final int size = list.size();
+		for ( int i = 0; i < size; i++ ) {
+			Map.Entry e = ( Map.Entry ) list.get( i );
+			( (CollectionEntry) e.getValue() ).preFlush( (PersistentCollection) e.getKey() );
+		}
+	}
+
+	/**
+	 * 1. detect any dirty entities
+	 * 2. schedule any entity updates
+	 * 3. search out any reachable collections
+	 */
+	private void flushEntities(FlushEvent event) throws HibernateException {
+
+		log.trace("Flushing entities and processing referenced collections");
+
+		// Among other things, updateReachables() will recursively load all
+		// collections that are moving roles. This might cause entities to
+		// be loaded.
+
+		// So this needs to be safe from concurrent modification problems.
+		// It is safe because of how IdentityMap implements entrySet()
+
+		final EventSource source = event.getSession();
+		
+		final Map.Entry[] list = IdentityMap.concurrentEntries( source.getPersistenceContext().getEntityEntries() );
+		final int size = list.length;
+		for ( int i = 0; i < size; i++ ) {
+
+			// Update the status of the object and if necessary, schedule an update
+
+			Map.Entry me = list[i];
+			EntityEntry entry = (EntityEntry) me.getValue();
+			Status status = entry.getStatus();
+
+			if ( status != Status.LOADING && status != Status.GONE ) {
+				FlushEntityEvent entityEvent = new FlushEntityEvent( source, me.getKey(), entry );
+				FlushEntityEventListener[] listeners = source.getListeners().getFlushEntityEventListeners();
+				for ( int j = 0; j < listeners.length; j++ ) {
+					listeners[j].onFlushEntity(entityEvent);
+				}
+			}
+		}
+
+		source.getActionQueue().sortActions();
+	}
+
+	/**
+	 * process any unreferenced collections and then inspect all known collections,
+	 * scheduling creates/removes/updates
+	 */
+	private void flushCollections(EventSource session) throws HibernateException {
+
+		log.trace("Processing unreferenced collections");
+
+		List list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
+		int size = list.size();
+		for ( int i = 0; i < size; i++ ) {
+			Map.Entry me = ( Map.Entry ) list.get( i );
+			CollectionEntry ce = (CollectionEntry) me.getValue();
+			if ( !ce.isReached() && !ce.isIgnore() ) {
+				Collections.processUnreachableCollection( (PersistentCollection) me.getKey(), session );
+			}
+		}
+
+		// Schedule updates to collections:
+
+		log.trace( "Scheduling collection removes/(re)creates/updates" );
+
+		list = IdentityMap.entries( session.getPersistenceContext().getCollectionEntries() );
+		size = list.size();
+		ActionQueue actionQueue = session.getActionQueue();
+		for ( int i = 0; i < size; i++ ) {
+			Map.Entry me = (Map.Entry) list.get(i);
+			PersistentCollection coll = (PersistentCollection) me.getKey();
+			CollectionEntry ce = (CollectionEntry) me.getValue();
+
+			if ( ce.isDorecreate() ) {
+				session.getInterceptor().onCollectionRecreate( coll, ce.getCurrentKey() );
+				actionQueue.addAction(
+						new CollectionRecreateAction( 
+								coll, 
+								ce.getCurrentPersister(), 
+								ce.getCurrentKey(), 
+								session 
+							)
+					);
+			}
+			if ( ce.isDoremove() ) {
+				session.getInterceptor().onCollectionRemove( coll, ce.getLoadedKey() );
+				actionQueue.addAction(
+						new CollectionRemoveAction( 
+								coll, 
+								ce.getLoadedPersister(), 
+								ce.getLoadedKey(), 
+								ce.isSnapshotEmpty(coll), 
+								session 
+							)
+					);
+			}
+			if ( ce.isDoupdate() ) {
+				session.getInterceptor().onCollectionUpdate( coll, ce.getLoadedKey() );
+				actionQueue.addAction(
+						new CollectionUpdateAction( 
+								coll, 
+								ce.getLoadedPersister(), 
+								ce.getLoadedKey(), 
+								ce.isSnapshotEmpty(coll), 
+								session 
+							)
+					);
+			}
+
+		}
+
+		actionQueue.sortCollectionActions();
+		
+	}
+
+	/**
+	 * Execute all SQL and second-level cache updates, in a
+	 * special order so that foreign-key constraints cannot
+	 * be violated:
+	 * <ol>
+	 * <li> Inserts, in the order they were performed
+	 * <li> Updates
+	 * <li> Deletion of collection elements
+	 * <li> Insertion of collection elements
+	 * <li> Deletes, in the order they were performed
+	 * </ol>
+	 */
+	protected void performExecutions(EventSource session) throws HibernateException {
+
+		log.trace("executing flush");
+
+		try {
+			session.getJDBCContext().getConnectionManager().flushBeginning();
+			// we need to lock the collection caches before
+			// executing entity inserts/updates in order to
+			// account for bidi associations
+			session.getActionQueue().prepareActions();
+			session.getActionQueue().executeActions();
+		}
+		catch (HibernateException he) {
+			log.error("Could not synchronize database state with session", he);
+			throw he;
+		}
+		finally {
+			session.getJDBCContext().getConnectionManager().flushEnding();
+		}
+	}
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// Post-flushing section
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * 1. Recreate the collection key -> collection map
+	 * 2. rebuild the collection entries
+	 * 3. call Interceptor.postFlush()
+	 */
+	protected void postFlush(SessionImplementor session) throws HibernateException {
+
+		log.trace( "post flush" );
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		persistenceContext.getCollectionsByKey().clear();
+		persistenceContext.getBatchFetchQueue()
+				.clearSubselects(); //the database has changed now, so the subselect results need to be invalidated
+
+		Iterator iter = persistenceContext.getCollectionEntries().entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			CollectionEntry collectionEntry = (CollectionEntry) me.getValue();
+			PersistentCollection persistentCollection = (PersistentCollection) me.getKey();
+			collectionEntry.postFlush(persistentCollection);
+			if ( collectionEntry.getLoadedPersister() == null ) {
+				//if the collection is dereferenced, remove from the session cache
+				//iter.remove(); //does not work, since the entrySet is not backed by the set
+				persistenceContext.getCollectionEntries()
+						.remove(persistentCollection);
+			}
+			else {
+				//otherwise recreate the mapping between the collection and its key
+				CollectionKey collectionKey = new CollectionKey( 
+						collectionEntry.getLoadedPersister(), 
+						collectionEntry.getLoadedKey(), 
+						session.getEntityMode() 
+					);
+				persistenceContext.getCollectionsByKey()
+						.put(collectionKey, persistentCollection);
+			}
+		}
+		
+		session.getInterceptor().postFlush( new LazyIterator( persistenceContext.getEntitiesByKey() ) );
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-//$Id: AbstractLockUpgradeEventListener.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.LockMode;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * A convenience base class for listeners that respond to requests to perform a
- * pessimistic lock upgrade on an entity.
- *
- * @author Gavin King
- */
-public class AbstractLockUpgradeEventListener extends AbstractReassociateEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(AbstractLockUpgradeEventListener.class);
-
-	/**
-	 * Performs a pessimistic lock upgrade on a given entity, if needed.
-	 *
-	 * @param object The entity for which to upgrade the lock.
-	 * @param entry The entity's EntityEntry instance.
-	 * @param requestedLockMode The lock mode being requested for locking.
-	 * @param source The session which is the source of the event being processed.
-	 */
-	protected void upgradeLock(Object object, EntityEntry entry, LockMode requestedLockMode, SessionImplementor source) {
-
-		if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
-			// The user requested a "greater" (i.e. more restrictive) form of
-			// pessimistic lock
-
-			if ( entry.getStatus() != Status.MANAGED ) {
-				throw new ObjectDeletedException(
-						"attempted to lock a deleted instance",
-						entry.getId(),
-						entry.getPersister().getEntityName()
-				);
-			}
-
-			final EntityPersister persister = entry.getPersister();
-
-			if ( log.isTraceEnabled() )
-				log.trace(
-						"locking " +
-						MessageHelper.infoString( persister, entry.getId(), source.getFactory() ) +
-						" in mode: " +
-						requestedLockMode
-				);
-
-			final SoftLock lock;
-			final CacheKey ck;
-			if ( persister.hasCache() ) {
-				ck = new CacheKey( 
-						entry.getId(), 
-						persister.getIdentifierType(), 
-						persister.getRootEntityName(), 
-						source.getEntityMode(), 
-						source.getFactory() 
-				);
-				lock = persister.getCacheAccessStrategy().lockItem( ck, entry.getVersion() );
-			}
-			else {
-				ck = null;
-				lock = null;
-			}
-			
-			try {
-				if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) {
-					// todo : should we check the current isolation mode explicitly?
-					Object nextVersion = persister.forceVersionIncrement(
-							entry.getId(), entry.getVersion(), source
-					);
-					entry.forceLocked( object, nextVersion );
-				}
-				else {
-					persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source );
-				}
-				entry.setLockMode(requestedLockMode);
-			}
-			finally {
-				// the database now holds a lock + the object is flushed from the cache,
-				// so release the soft lock
-				if ( persister.hasCache() ) {
-					persister.getCacheAccessStrategy().unlockItem( ck, lock );
-				}
-			}
-
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractLockUpgradeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,123 @@
+/*
+ * 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.event.def;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.LockMode;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * A convenience base class for listeners that respond to requests to perform a
+ * pessimistic lock upgrade on an entity.
+ *
+ * @author Gavin King
+ */
+public class AbstractLockUpgradeEventListener extends AbstractReassociateEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(AbstractLockUpgradeEventListener.class);
+
+	/**
+	 * Performs a pessimistic lock upgrade on a given entity, if needed.
+	 *
+	 * @param object The entity for which to upgrade the lock.
+	 * @param entry The entity's EntityEntry instance.
+	 * @param requestedLockMode The lock mode being requested for locking.
+	 * @param source The session which is the source of the event being processed.
+	 */
+	protected void upgradeLock(Object object, EntityEntry entry, LockMode requestedLockMode, SessionImplementor source) {
+
+		if ( requestedLockMode.greaterThan( entry.getLockMode() ) ) {
+			// The user requested a "greater" (i.e. more restrictive) form of
+			// pessimistic lock
+
+			if ( entry.getStatus() != Status.MANAGED ) {
+				throw new ObjectDeletedException(
+						"attempted to lock a deleted instance",
+						entry.getId(),
+						entry.getPersister().getEntityName()
+				);
+			}
+
+			final EntityPersister persister = entry.getPersister();
+
+			if ( log.isTraceEnabled() )
+				log.trace(
+						"locking " +
+						MessageHelper.infoString( persister, entry.getId(), source.getFactory() ) +
+						" in mode: " +
+						requestedLockMode
+				);
+
+			final SoftLock lock;
+			final CacheKey ck;
+			if ( persister.hasCache() ) {
+				ck = new CacheKey( 
+						entry.getId(), 
+						persister.getIdentifierType(), 
+						persister.getRootEntityName(), 
+						source.getEntityMode(), 
+						source.getFactory() 
+				);
+				lock = persister.getCacheAccessStrategy().lockItem( ck, entry.getVersion() );
+			}
+			else {
+				ck = null;
+				lock = null;
+			}
+			
+			try {
+				if ( persister.isVersioned() && requestedLockMode == LockMode.FORCE ) {
+					// todo : should we check the current isolation mode explicitly?
+					Object nextVersion = persister.forceVersionIncrement(
+							entry.getId(), entry.getVersion(), source
+					);
+					entry.forceLocked( object, nextVersion );
+				}
+				else {
+					persister.lock( entry.getId(), entry.getVersion(), object, requestedLockMode, source );
+				}
+				entry.setLockMode(requestedLockMode);
+			}
+			finally {
+				// the database now holds a lock + the object is flushed from the cache,
+				// so release the soft lock
+				if ( persister.hasCache() ) {
+					persister.getCacheAccessStrategy().unlockItem( ck, lock );
+				}
+			}
+
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,87 +0,0 @@
-//$Id: AbstractReassociateEventListener.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.LockMode;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.AbstractEvent;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A convenience base class for listeners that respond to requests to reassociate an entity
- * to a session ( such as through lock() or update() ).
- *
- * @author Gavin King
- */
-public class AbstractReassociateEventListener implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractReassociateEventListener.class );
-
-	/**
-	 * Associates a given entity (either transient or associated with another session) to
-	 * the given session.
-	 *
-	 * @param event The event triggering the re-association
-	 * @param object The entity to be associated
-	 * @param id The id of the entity.
-	 * @param persister The entity's persister instance.
-	 *
-	 * @return An EntityEntry representing the entity within this session.
-	 */
-	protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"reassociating transient instance: " +
-							MessageHelper.infoString( persister, id, event.getSession().getFactory() )
-			);
-		}
-
-		EventSource source = event.getSession();
-		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-
-		source.getPersistenceContext().checkUniqueness( key, object );
-
-		//get a snapshot
-		Object[] values = persister.getPropertyValues( object, source.getEntityMode() );
-		TypeFactory.deepCopy(
-				values,
-				persister.getPropertyTypes(),
-				persister.getPropertyUpdateability(),
-				values,
-				source
-		);
-		Object version = Versioning.getVersion( values, persister );
-
-		EntityEntry newEntry = source.getPersistenceContext().addEntity(
-				object,
-				Status.MANAGED,
-				values,
-				key,
-				version,
-				LockMode.NONE,
-				true,
-				persister,
-				false,
-				true //will be ignored, using the existing Entry instead
-		);
-
-		new OnLockVisitor( source, id, object ).process( object, persister );
-
-		persister.afterReassociate( object, source );
-
-		return newEntry;
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractReassociateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,110 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.LockMode;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.AbstractEvent;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A convenience base class for listeners that respond to requests to reassociate an entity
+ * to a session ( such as through lock() or update() ).
+ *
+ * @author Gavin King
+ */
+public class AbstractReassociateEventListener implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractReassociateEventListener.class );
+
+	/**
+	 * Associates a given entity (either transient or associated with another session) to
+	 * the given session.
+	 *
+	 * @param event The event triggering the re-association
+	 * @param object The entity to be associated
+	 * @param id The id of the entity.
+	 * @param persister The entity's persister instance.
+	 *
+	 * @return An EntityEntry representing the entity within this session.
+	 */
+	protected final EntityEntry reassociate(AbstractEvent event, Object object, Serializable id, EntityPersister persister) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"reassociating transient instance: " +
+							MessageHelper.infoString( persister, id, event.getSession().getFactory() )
+			);
+		}
+
+		EventSource source = event.getSession();
+		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+
+		source.getPersistenceContext().checkUniqueness( key, object );
+
+		//get a snapshot
+		Object[] values = persister.getPropertyValues( object, source.getEntityMode() );
+		TypeFactory.deepCopy(
+				values,
+				persister.getPropertyTypes(),
+				persister.getPropertyUpdateability(),
+				values,
+				source
+		);
+		Object version = Versioning.getVersion( values, persister );
+
+		EntityEntry newEntry = source.getPersistenceContext().addEntity(
+				object,
+				Status.MANAGED,
+				values,
+				key,
+				version,
+				LockMode.NONE,
+				true,
+				persister,
+				false,
+				true //will be ignored, using the existing Entry instead
+		);
+
+		new OnLockVisitor( source, id, object ).process( object, persister );
+
+		persister.afterReassociate( object, source );
+
+		return newEntry;
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,542 +0,0 @@
-//$Id: AbstractSaveEventListener.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.LockMode;
-import org.hibernate.NonUniqueObjectException;
-import org.hibernate.action.EntityIdentityInsertAction;
-import org.hibernate.action.EntityInsertAction;
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.classic.Validatable;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Nullability;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.EventSource;
-import org.hibernate.id.IdentifierGenerationException;
-import org.hibernate.id.IdentifierGeneratorFactory;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A convenience bas class for listeners responding to save events.
- *
- * @author Steve Ebersole.
- */
-public abstract class AbstractSaveEventListener extends AbstractReassociateEventListener {
-
-	protected static final int PERSISTENT = 0;
-	protected static final int TRANSIENT = 1;
-	protected static final int DETACHED = 2;
-	protected static final int DELETED = 3;
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractSaveEventListener.class );
-
-	/**
-	 * Prepares the save call using the given requested id.
-	 *
-	 * @param entity The entity to be saved.
-	 * @param requestedId The id to which to associate the entity.
-	 * @param entityName The name of the entity being saved.
-	 * @param anything Generally cascade-specific information.
-	 * @param source The session which is the source of this save event.
-	 *
-	 * @return The id used to save the entity.
-	 */
-	protected Serializable saveWithRequestedId(
-			Object entity,
-			Serializable requestedId,
-			String entityName,
-			Object anything,
-			EventSource source) {
-		return performSave(
-				entity,
-				requestedId,
-				source.getEntityPersister( entityName, entity ),
-				false,
-				anything,
-				source,
-				true
-		);
-	}
-
-	/**
-	 * Prepares the save call using a newly generated id.
-	 *
-	 * @param entity The entity to be saved
-	 * @param entityName The entity-name for the entity to be saved
-	 * @param anything Generally cascade-specific information.
-	 * @param source The session which is the source of this save event.
-	 * @param requiresImmediateIdAccess does the event context require
-	 * access to the identifier immediately after execution of this method (if
-	 * not, post-insert style id generators may be postponed if we are outside
-	 * a transaction).
-	 *
-	 * @return The id used to save the entity; may be null depending on the
-	 *         type of id generator used and the requiresImmediateIdAccess value
-	 */
-	protected Serializable saveWithGeneratedId(
-			Object entity,
-			String entityName,
-			Object anything,
-			EventSource source,
-			boolean requiresImmediateIdAccess) {
-		EntityPersister persister = source.getEntityPersister( entityName, entity );
-		Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
-		if ( generatedId == null ) {
-			throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
-		}
-		else if ( generatedId == IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR ) {
-			return source.getIdentifier( entity );
-		}
-		else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
-			return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
-		}
-		else {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug(
-						"generated identifier: " +
-								persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ) +
-								", using strategy: " +
-								persister.getIdentifierGenerator().getClass().getName()
-						//TODO: define toString()s for generators
-				);
-			}
-
-			return performSave( entity, generatedId, persister, false, anything, source, true );
-		}
-	}
-
-	/**
-	 * Ppepares the save call by checking the session caches for a pre-existing
-	 * entity and performing any lifecycle callbacks.
-	 *
-	 * @param entity The entity to be saved.
-	 * @param id The id by which to save the entity.
-	 * @param persister The entity's persister instance.
-	 * @param useIdentityColumn Is an identity column being used?
-	 * @param anything Generally cascade-specific information.
-	 * @param source The session from which the event originated.
-	 * @param requiresImmediateIdAccess does the event context require
-	 * access to the identifier immediately after execution of this method (if
-	 * not, post-insert style id generators may be postponed if we are outside
-	 * a transaction).
-	 *
-	 * @return The id used to save the entity; may be null depending on the
-	 *         type of id generator used and the requiresImmediateIdAccess value
-	 */
-	protected Serializable performSave(
-			Object entity,
-			Serializable id,
-			EntityPersister persister,
-			boolean useIdentityColumn,
-			Object anything,
-			EventSource source,
-			boolean requiresImmediateIdAccess) {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"saving " +
-							MessageHelper.infoString( persister, id, source.getFactory() )
-			);
-		}
-
-		EntityKey key;
-		if ( !useIdentityColumn ) {
-			key = new EntityKey( id, persister, source.getEntityMode() );
-			Object old = source.getPersistenceContext().getEntity( key );
-			if ( old != null ) {
-				if ( source.getPersistenceContext().getEntry( old ).getStatus() == Status.DELETED ) {
-					source.forceFlush( source.getPersistenceContext().getEntry( old ) );
-				}
-				else {
-					throw new NonUniqueObjectException( id, persister.getEntityName() );
-				}
-			}
-			persister.setIdentifier( entity, id, source.getEntityMode() );
-		}
-		else {
-			key = null;
-		}
-
-		if ( invokeSaveLifecycle( entity, persister, source ) ) {
-			return id; //EARLY EXIT
-		}
-
-		return performSaveOrReplicate(
-				entity,
-				key,
-				persister,
-				useIdentityColumn,
-				anything,
-				source,
-				requiresImmediateIdAccess
-		);
-	}
-
-	protected boolean invokeSaveLifecycle(Object entity, EntityPersister persister, EventSource source) {
-		// Sub-insertions should occur before containing insertion so
-		// Try to do the callback now
-		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
-			log.debug( "calling onSave()" );
-			if ( ( ( Lifecycle ) entity ).onSave( source ) ) {
-				log.debug( "insertion vetoed by onSave()" );
-				return true;
-			}
-		}
-		return false;
-	}
-
-	protected void validate(Object entity, EntityPersister persister, EventSource source) {
-		if ( persister.implementsValidatable( source.getEntityMode() ) ) {
-			( ( Validatable ) entity ).validate();
-		}
-	}
-
-	/**
-	 * Performs all the actual work needed to save an entity (well to get the save moved to
-	 * the execution queue).
-	 *
-	 * @param entity The entity to be saved
-	 * @param key The id to be used for saving the entity (or null, in the case of identity columns)
-	 * @param persister The entity's persister instance.
-	 * @param useIdentityColumn Should an identity column be used for id generation?
-	 * @param anything Generally cascade-specific information.
-	 * @param source The session which is the source of the current event.
-	 * @param requiresImmediateIdAccess Is access to the identifier required immediately
-	 * after the completion of the save?  persist(), for example, does not require this...
-	 *
-	 * @return The id used to save the entity; may be null depending on the
-	 *         type of id generator used and the requiresImmediateIdAccess value
-	 */
-	protected Serializable performSaveOrReplicate(
-			Object entity,
-			EntityKey key,
-			EntityPersister persister,
-			boolean useIdentityColumn,
-			Object anything,
-			EventSource source,
-			boolean requiresImmediateIdAccess) {
-
-		validate( entity, persister, source );
-
-		Serializable id = key == null ? null : key.getIdentifier();
-
-		boolean inTxn = source.getJDBCContext().isTransactionInProgress();
-		boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
-
-		if ( useIdentityColumn && !shouldDelayIdentityInserts ) {
-			log.trace( "executing insertions" );
-			source.getActionQueue().executeInserts();
-		}
-
-		// Put a placeholder in entries, so we don't recurse back and try to save() the
-		// same object again. QUESTION: should this be done before onSave() is called?
-		// likewise, should it be done before onUpdate()?
-		source.getPersistenceContext().addEntry(
-				entity,
-				Status.SAVING,
-				null,
-				null,
-				id,
-				null,
-				LockMode.WRITE,
-				useIdentityColumn,
-				persister,
-				false,
-				false
-		);
-
-		cascadeBeforeSave( source, persister, entity, anything );
-
-		Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( anything ), source );
-		Type[] types = persister.getPropertyTypes();
-
-		boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
-
-		if ( persister.hasCollections() ) {
-			substitute = substitute || visitCollectionsBeforeSave( entity, id, values, types, source );
-		}
-
-		if ( substitute ) {
-			persister.setPropertyValues( entity, values, source.getEntityMode() );
-		}
-
-		TypeFactory.deepCopy(
-				values,
-				types,
-				persister.getPropertyUpdateability(),
-				values,
-				source
-		);
-
-		new ForeignKeys.Nullifier( entity, false, useIdentityColumn, source )
-				.nullifyTransientReferences( values, types );
-		new Nullability( source ).checkNullability( values, persister, false );
-
-		if ( useIdentityColumn ) {
-			EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
-					values, entity, persister, source, shouldDelayIdentityInserts
-			);
-			if ( !shouldDelayIdentityInserts ) {
-				log.debug( "executing identity-insert immediately" );
-				source.getActionQueue().execute( insert );
-				id = insert.getGeneratedId();
-				//now done in EntityIdentityInsertAction
-				//persister.setIdentifier( entity, id, source.getEntityMode() );
-				key = new EntityKey( id, persister, source.getEntityMode() );
-				source.getPersistenceContext().checkUniqueness( key, entity );
-				//source.getBatcher().executeBatch(); //found another way to ensure that all batched joined inserts have been executed
-			}
-			else {
-				log.debug( "delaying identity-insert due to no transaction in progress" );
-				source.getActionQueue().addAction( insert );
-				key = insert.getDelayedEntityKey();
-			}
-		}
-
-		Object version = Versioning.getVersion( values, persister );
-		source.getPersistenceContext().addEntity(
-				entity,
-				Status.MANAGED,
-				values,
-				key,
-				version,
-				LockMode.WRITE,
-				useIdentityColumn,
-				persister,
-				isVersionIncrementDisabled(),
-				false
-		);
-		//source.getPersistenceContext().removeNonExist( new EntityKey( id, persister, source.getEntityMode() ) );
-
-		if ( !useIdentityColumn ) {
-			source.getActionQueue().addAction(
-					new EntityInsertAction( id, values, entity, version, persister, source )
-			);
-		}
-
-		cascadeAfterSave( source, persister, entity, anything );
-
-		markInterceptorDirty( entity, persister, source );
-
-		return id;
-	}
-
-	private void markInterceptorDirty(Object entity, EntityPersister persister, EventSource source) {
-		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
-			FieldInterceptor interceptor = FieldInterceptionHelper.injectFieldInterceptor(
-					entity,
-					persister.getEntityName(),
-					null,
-					source
-			);
-			interceptor.dirty();
-		}
-	}
-
-	protected Map getMergeMap(Object anything) {
-		return null;
-	}
-
-	/**
-	 * After the save, will te version number be incremented
-	 * if the instance is modified?
-	 *
-	 * @return True if the version will be incremented on an entity change after save;
-	 *         false otherwise.
-	 */
-	protected boolean isVersionIncrementDisabled() {
-		return false;
-	}
-
-	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
-		WrapVisitor visitor = new WrapVisitor( source );
-		// substitutes into values by side-effect
-		visitor.processEntityPropertyValues( values, types );
-		return visitor.isSubstitutionRequired();
-	}
-
-	/**
-	 * Perform any property value substitution that is necessary
-	 * (interceptor callback, version initialization...)
-	 *
-	 * @param entity The entity
-	 * @param id The entity identifier
-	 * @param values The snapshot entity state
-	 * @param persister The entity persister
-	 * @param source The originating session
-	 *
-	 * @return True if the snapshot state changed such that
-	 * reinjection of the values into the entity is required.
-	 */
-	protected boolean substituteValuesIfNecessary(
-			Object entity,
-			Serializable id,
-			Object[] values,
-			EntityPersister persister,
-			SessionImplementor source) {
-		boolean substitute = source.getInterceptor().onSave(
-				entity,
-				id,
-				values,
-				persister.getPropertyNames(),
-				persister.getPropertyTypes()
-		);
-
-		//keep the existing version number in the case of replicate!
-		if ( persister.isVersioned() ) {
-			substitute = Versioning.seedVersion(
-					values,
-					persister.getVersionProperty(),
-					persister.getVersionType(),
-					source
-			) || substitute;
-		}
-		return substitute;
-	}
-
-	/**
-	 * Handles the calls needed to perform pre-save cascades for the given entity.
-	 *
-	 * @param source The session from whcih the save event originated.
-	 * @param persister The entity's persister instance.
-	 * @param entity The entity to be saved.
-	 * @param anything Generally cascade-specific data
-	 */
-	protected void cascadeBeforeSave(
-			EventSource source,
-			EntityPersister persister,
-			Object entity,
-			Object anything) {
-
-		// cascade-save to many-to-one BEFORE the parent is saved
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( getCascadeAction(), Cascade.BEFORE_INSERT_AFTER_DELETE, source )
-					.cascade( persister, entity, anything );
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-	/**
-	 * Handles to calls needed to perform post-save cascades.
-	 *
-	 * @param source The session from which the event originated.
-	 * @param persister The entity's persister instance.
-	 * @param entity The entity beng saved.
-	 * @param anything Generally cascade-specific data
-	 */
-	protected void cascadeAfterSave(
-			EventSource source,
-			EntityPersister persister,
-			Object entity,
-			Object anything) {
-
-		// cascade-save to collections AFTER the collection owner was saved
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( getCascadeAction(), Cascade.AFTER_INSERT_BEFORE_DELETE, source )
-					.cascade( persister, entity, anything );
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-	protected abstract CascadingAction getCascadeAction();
-
-	/**
-	 * Determine whether the entity is persistent, detached, or transient
-	 *
-	 * @param entity The entity to check
-	 * @param entityName The name of the entity
-	 * @param entry The entity's entry in the persistence context
-	 * @param source The originating session.
-	 *
-	 * @return The state.
-	 */
-	protected int getEntityState(
-			Object entity,
-			String entityName,
-			EntityEntry entry, //pass this as an argument only to avoid double looking
-			SessionImplementor source) {
-
-		if ( entry != null ) { // the object is persistent
-
-			//the entity is associated with the session, so check its status
-			if ( entry.getStatus() != Status.DELETED ) {
-				// do nothing for persistent instances
-				if ( log.isTraceEnabled() ) {
-					log.trace(
-							"persistent instance of: " +
-									getLoggableName( entityName, entity )
-					);
-				}
-				return PERSISTENT;
-			}
-			else {
-				//ie. e.status==DELETED
-				if ( log.isTraceEnabled() ) {
-					log.trace(
-							"deleted instance of: " +
-									getLoggableName( entityName, entity )
-					);
-				}
-				return DELETED;
-			}
-
-		}
-		else { // the object is transient or detached
-
-			//the entity is not associated with the session, so
-			//try interceptor and unsaved-value
-
-			if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
-				if ( log.isTraceEnabled() ) {
-					log.trace(
-							"transient instance of: " +
-									getLoggableName( entityName, entity )
-					);
-				}
-				return TRANSIENT;
-			}
-			else {
-				if ( log.isTraceEnabled() ) {
-					log.trace(
-							"detached instance of: " +
-									getLoggableName( entityName, entity )
-					);
-				}
-				return DETACHED;
-			}
-
-		}
-	}
-
-	protected String getLoggableName(String entityName, Object entity) {
-		return entityName == null ? entity.getClass().getName() : entityName;
-	}
-
-	protected Boolean getAssumedUnsaved() {
-		return null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractSaveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,565 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.LockMode;
+import org.hibernate.NonUniqueObjectException;
+import org.hibernate.action.EntityIdentityInsertAction;
+import org.hibernate.action.EntityInsertAction;
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.classic.Validatable;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Nullability;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.EventSource;
+import org.hibernate.id.IdentifierGenerationException;
+import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A convenience bas class for listeners responding to save events.
+ *
+ * @author Steve Ebersole.
+ */
+public abstract class AbstractSaveEventListener extends AbstractReassociateEventListener {
+
+	protected static final int PERSISTENT = 0;
+	protected static final int TRANSIENT = 1;
+	protected static final int DETACHED = 2;
+	protected static final int DELETED = 3;
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractSaveEventListener.class );
+
+	/**
+	 * Prepares the save call using the given requested id.
+	 *
+	 * @param entity The entity to be saved.
+	 * @param requestedId The id to which to associate the entity.
+	 * @param entityName The name of the entity being saved.
+	 * @param anything Generally cascade-specific information.
+	 * @param source The session which is the source of this save event.
+	 *
+	 * @return The id used to save the entity.
+	 */
+	protected Serializable saveWithRequestedId(
+			Object entity,
+			Serializable requestedId,
+			String entityName,
+			Object anything,
+			EventSource source) {
+		return performSave(
+				entity,
+				requestedId,
+				source.getEntityPersister( entityName, entity ),
+				false,
+				anything,
+				source,
+				true
+		);
+	}
+
+	/**
+	 * Prepares the save call using a newly generated id.
+	 *
+	 * @param entity The entity to be saved
+	 * @param entityName The entity-name for the entity to be saved
+	 * @param anything Generally cascade-specific information.
+	 * @param source The session which is the source of this save event.
+	 * @param requiresImmediateIdAccess does the event context require
+	 * access to the identifier immediately after execution of this method (if
+	 * not, post-insert style id generators may be postponed if we are outside
+	 * a transaction).
+	 *
+	 * @return The id used to save the entity; may be null depending on the
+	 *         type of id generator used and the requiresImmediateIdAccess value
+	 */
+	protected Serializable saveWithGeneratedId(
+			Object entity,
+			String entityName,
+			Object anything,
+			EventSource source,
+			boolean requiresImmediateIdAccess) {
+		EntityPersister persister = source.getEntityPersister( entityName, entity );
+		Serializable generatedId = persister.getIdentifierGenerator().generate( source, entity );
+		if ( generatedId == null ) {
+			throw new IdentifierGenerationException( "null id generated for:" + entity.getClass() );
+		}
+		else if ( generatedId == IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR ) {
+			return source.getIdentifier( entity );
+		}
+		else if ( generatedId == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
+			return performSave( entity, null, persister, true, anything, source, requiresImmediateIdAccess );
+		}
+		else {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug(
+						"generated identifier: " +
+								persister.getIdentifierType().toLoggableString( generatedId, source.getFactory() ) +
+								", using strategy: " +
+								persister.getIdentifierGenerator().getClass().getName()
+						//TODO: define toString()s for generators
+				);
+			}
+
+			return performSave( entity, generatedId, persister, false, anything, source, true );
+		}
+	}
+
+	/**
+	 * Ppepares the save call by checking the session caches for a pre-existing
+	 * entity and performing any lifecycle callbacks.
+	 *
+	 * @param entity The entity to be saved.
+	 * @param id The id by which to save the entity.
+	 * @param persister The entity's persister instance.
+	 * @param useIdentityColumn Is an identity column being used?
+	 * @param anything Generally cascade-specific information.
+	 * @param source The session from which the event originated.
+	 * @param requiresImmediateIdAccess does the event context require
+	 * access to the identifier immediately after execution of this method (if
+	 * not, post-insert style id generators may be postponed if we are outside
+	 * a transaction).
+	 *
+	 * @return The id used to save the entity; may be null depending on the
+	 *         type of id generator used and the requiresImmediateIdAccess value
+	 */
+	protected Serializable performSave(
+			Object entity,
+			Serializable id,
+			EntityPersister persister,
+			boolean useIdentityColumn,
+			Object anything,
+			EventSource source,
+			boolean requiresImmediateIdAccess) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"saving " +
+							MessageHelper.infoString( persister, id, source.getFactory() )
+			);
+		}
+
+		EntityKey key;
+		if ( !useIdentityColumn ) {
+			key = new EntityKey( id, persister, source.getEntityMode() );
+			Object old = source.getPersistenceContext().getEntity( key );
+			if ( old != null ) {
+				if ( source.getPersistenceContext().getEntry( old ).getStatus() == Status.DELETED ) {
+					source.forceFlush( source.getPersistenceContext().getEntry( old ) );
+				}
+				else {
+					throw new NonUniqueObjectException( id, persister.getEntityName() );
+				}
+			}
+			persister.setIdentifier( entity, id, source.getEntityMode() );
+		}
+		else {
+			key = null;
+		}
+
+		if ( invokeSaveLifecycle( entity, persister, source ) ) {
+			return id; //EARLY EXIT
+		}
+
+		return performSaveOrReplicate(
+				entity,
+				key,
+				persister,
+				useIdentityColumn,
+				anything,
+				source,
+				requiresImmediateIdAccess
+		);
+	}
+
+	protected boolean invokeSaveLifecycle(Object entity, EntityPersister persister, EventSource source) {
+		// Sub-insertions should occur before containing insertion so
+		// Try to do the callback now
+		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
+			log.debug( "calling onSave()" );
+			if ( ( ( Lifecycle ) entity ).onSave( source ) ) {
+				log.debug( "insertion vetoed by onSave()" );
+				return true;
+			}
+		}
+		return false;
+	}
+
+	protected void validate(Object entity, EntityPersister persister, EventSource source) {
+		if ( persister.implementsValidatable( source.getEntityMode() ) ) {
+			( ( Validatable ) entity ).validate();
+		}
+	}
+
+	/**
+	 * Performs all the actual work needed to save an entity (well to get the save moved to
+	 * the execution queue).
+	 *
+	 * @param entity The entity to be saved
+	 * @param key The id to be used for saving the entity (or null, in the case of identity columns)
+	 * @param persister The entity's persister instance.
+	 * @param useIdentityColumn Should an identity column be used for id generation?
+	 * @param anything Generally cascade-specific information.
+	 * @param source The session which is the source of the current event.
+	 * @param requiresImmediateIdAccess Is access to the identifier required immediately
+	 * after the completion of the save?  persist(), for example, does not require this...
+	 *
+	 * @return The id used to save the entity; may be null depending on the
+	 *         type of id generator used and the requiresImmediateIdAccess value
+	 */
+	protected Serializable performSaveOrReplicate(
+			Object entity,
+			EntityKey key,
+			EntityPersister persister,
+			boolean useIdentityColumn,
+			Object anything,
+			EventSource source,
+			boolean requiresImmediateIdAccess) {
+
+		validate( entity, persister, source );
+
+		Serializable id = key == null ? null : key.getIdentifier();
+
+		boolean inTxn = source.getJDBCContext().isTransactionInProgress();
+		boolean shouldDelayIdentityInserts = !inTxn && !requiresImmediateIdAccess;
+
+		if ( useIdentityColumn && !shouldDelayIdentityInserts ) {
+			log.trace( "executing insertions" );
+			source.getActionQueue().executeInserts();
+		}
+
+		// Put a placeholder in entries, so we don't recurse back and try to save() the
+		// same object again. QUESTION: should this be done before onSave() is called?
+		// likewise, should it be done before onUpdate()?
+		source.getPersistenceContext().addEntry(
+				entity,
+				Status.SAVING,
+				null,
+				null,
+				id,
+				null,
+				LockMode.WRITE,
+				useIdentityColumn,
+				persister,
+				false,
+				false
+		);
+
+		cascadeBeforeSave( source, persister, entity, anything );
+
+		Object[] values = persister.getPropertyValuesToInsert( entity, getMergeMap( anything ), source );
+		Type[] types = persister.getPropertyTypes();
+
+		boolean substitute = substituteValuesIfNecessary( entity, id, values, persister, source );
+
+		if ( persister.hasCollections() ) {
+			substitute = substitute || visitCollectionsBeforeSave( entity, id, values, types, source );
+		}
+
+		if ( substitute ) {
+			persister.setPropertyValues( entity, values, source.getEntityMode() );
+		}
+
+		TypeFactory.deepCopy(
+				values,
+				types,
+				persister.getPropertyUpdateability(),
+				values,
+				source
+		);
+
+		new ForeignKeys.Nullifier( entity, false, useIdentityColumn, source )
+				.nullifyTransientReferences( values, types );
+		new Nullability( source ).checkNullability( values, persister, false );
+
+		if ( useIdentityColumn ) {
+			EntityIdentityInsertAction insert = new EntityIdentityInsertAction(
+					values, entity, persister, source, shouldDelayIdentityInserts
+			);
+			if ( !shouldDelayIdentityInserts ) {
+				log.debug( "executing identity-insert immediately" );
+				source.getActionQueue().execute( insert );
+				id = insert.getGeneratedId();
+				//now done in EntityIdentityInsertAction
+				//persister.setIdentifier( entity, id, source.getEntityMode() );
+				key = new EntityKey( id, persister, source.getEntityMode() );
+				source.getPersistenceContext().checkUniqueness( key, entity );
+				//source.getBatcher().executeBatch(); //found another way to ensure that all batched joined inserts have been executed
+			}
+			else {
+				log.debug( "delaying identity-insert due to no transaction in progress" );
+				source.getActionQueue().addAction( insert );
+				key = insert.getDelayedEntityKey();
+			}
+		}
+
+		Object version = Versioning.getVersion( values, persister );
+		source.getPersistenceContext().addEntity(
+				entity,
+				Status.MANAGED,
+				values,
+				key,
+				version,
+				LockMode.WRITE,
+				useIdentityColumn,
+				persister,
+				isVersionIncrementDisabled(),
+				false
+		);
+		//source.getPersistenceContext().removeNonExist( new EntityKey( id, persister, source.getEntityMode() ) );
+
+		if ( !useIdentityColumn ) {
+			source.getActionQueue().addAction(
+					new EntityInsertAction( id, values, entity, version, persister, source )
+			);
+		}
+
+		cascadeAfterSave( source, persister, entity, anything );
+
+		markInterceptorDirty( entity, persister, source );
+
+		return id;
+	}
+
+	private void markInterceptorDirty(Object entity, EntityPersister persister, EventSource source) {
+		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
+			FieldInterceptor interceptor = FieldInterceptionHelper.injectFieldInterceptor(
+					entity,
+					persister.getEntityName(),
+					null,
+					source
+			);
+			interceptor.dirty();
+		}
+	}
+
+	protected Map getMergeMap(Object anything) {
+		return null;
+	}
+
+	/**
+	 * After the save, will te version number be incremented
+	 * if the instance is modified?
+	 *
+	 * @return True if the version will be incremented on an entity change after save;
+	 *         false otherwise.
+	 */
+	protected boolean isVersionIncrementDisabled() {
+		return false;
+	}
+
+	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
+		WrapVisitor visitor = new WrapVisitor( source );
+		// substitutes into values by side-effect
+		visitor.processEntityPropertyValues( values, types );
+		return visitor.isSubstitutionRequired();
+	}
+
+	/**
+	 * Perform any property value substitution that is necessary
+	 * (interceptor callback, version initialization...)
+	 *
+	 * @param entity The entity
+	 * @param id The entity identifier
+	 * @param values The snapshot entity state
+	 * @param persister The entity persister
+	 * @param source The originating session
+	 *
+	 * @return True if the snapshot state changed such that
+	 * reinjection of the values into the entity is required.
+	 */
+	protected boolean substituteValuesIfNecessary(
+			Object entity,
+			Serializable id,
+			Object[] values,
+			EntityPersister persister,
+			SessionImplementor source) {
+		boolean substitute = source.getInterceptor().onSave(
+				entity,
+				id,
+				values,
+				persister.getPropertyNames(),
+				persister.getPropertyTypes()
+		);
+
+		//keep the existing version number in the case of replicate!
+		if ( persister.isVersioned() ) {
+			substitute = Versioning.seedVersion(
+					values,
+					persister.getVersionProperty(),
+					persister.getVersionType(),
+					source
+			) || substitute;
+		}
+		return substitute;
+	}
+
+	/**
+	 * Handles the calls needed to perform pre-save cascades for the given entity.
+	 *
+	 * @param source The session from whcih the save event originated.
+	 * @param persister The entity's persister instance.
+	 * @param entity The entity to be saved.
+	 * @param anything Generally cascade-specific data
+	 */
+	protected void cascadeBeforeSave(
+			EventSource source,
+			EntityPersister persister,
+			Object entity,
+			Object anything) {
+
+		// cascade-save to many-to-one BEFORE the parent is saved
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( getCascadeAction(), Cascade.BEFORE_INSERT_AFTER_DELETE, source )
+					.cascade( persister, entity, anything );
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+	/**
+	 * Handles to calls needed to perform post-save cascades.
+	 *
+	 * @param source The session from which the event originated.
+	 * @param persister The entity's persister instance.
+	 * @param entity The entity beng saved.
+	 * @param anything Generally cascade-specific data
+	 */
+	protected void cascadeAfterSave(
+			EventSource source,
+			EntityPersister persister,
+			Object entity,
+			Object anything) {
+
+		// cascade-save to collections AFTER the collection owner was saved
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( getCascadeAction(), Cascade.AFTER_INSERT_BEFORE_DELETE, source )
+					.cascade( persister, entity, anything );
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+	protected abstract CascadingAction getCascadeAction();
+
+	/**
+	 * Determine whether the entity is persistent, detached, or transient
+	 *
+	 * @param entity The entity to check
+	 * @param entityName The name of the entity
+	 * @param entry The entity's entry in the persistence context
+	 * @param source The originating session.
+	 *
+	 * @return The state.
+	 */
+	protected int getEntityState(
+			Object entity,
+			String entityName,
+			EntityEntry entry, //pass this as an argument only to avoid double looking
+			SessionImplementor source) {
+
+		if ( entry != null ) { // the object is persistent
+
+			//the entity is associated with the session, so check its status
+			if ( entry.getStatus() != Status.DELETED ) {
+				// do nothing for persistent instances
+				if ( log.isTraceEnabled() ) {
+					log.trace(
+							"persistent instance of: " +
+									getLoggableName( entityName, entity )
+					);
+				}
+				return PERSISTENT;
+			}
+			else {
+				//ie. e.status==DELETED
+				if ( log.isTraceEnabled() ) {
+					log.trace(
+							"deleted instance of: " +
+									getLoggableName( entityName, entity )
+					);
+				}
+				return DELETED;
+			}
+
+		}
+		else { // the object is transient or detached
+
+			//the entity is not associated with the session, so
+			//try interceptor and unsaved-value
+
+			if ( ForeignKeys.isTransient( entityName, entity, getAssumedUnsaved(), source ) ) {
+				if ( log.isTraceEnabled() ) {
+					log.trace(
+							"transient instance of: " +
+									getLoggableName( entityName, entity )
+					);
+				}
+				return TRANSIENT;
+			}
+			else {
+				if ( log.isTraceEnabled() ) {
+					log.trace(
+							"detached instance of: " +
+									getLoggableName( entityName, entity )
+					);
+				}
+				return DETACHED;
+			}
+
+		}
+	}
+
+	protected String getLoggableName(String entityName, Object entity) {
+		return entityName == null ? entity.getClass().getName() : entityName;
+	}
+
+	protected Boolean getAssumedUnsaved() {
+		return null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,157 +0,0 @@
-//$Id: AbstractVisitor.java 7546 2005-07-19 18:17:15Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.event.EventSource;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-
-
-/**
- * Abstract superclass of algorithms that walk
- * a tree of property values of an entity, and
- * perform specific functionality for collections,
- * components and associated entities.
- *
- * @author Gavin King
- */
-public abstract class AbstractVisitor {
-
-	private final EventSource session;
-
-	AbstractVisitor(EventSource session) {
-		this.session = session;
-	}
-
-	/**
-	 * Dispatch each property value to processValue().
-	 *
-	 * @param values
-	 * @param types
-	 * @throws HibernateException
-	 */
-	void processValues(Object[] values, Type[] types) throws HibernateException {
-		for ( int i=0; i<types.length; i++ ) {
-			if ( includeProperty(values, i) ) {
-				processValue( i, values, types );
-			}
-		}
-	}
-	
-	/**
-	 * Dispatch each property value to processValue().
-	 *
-	 * @param values
-	 * @param types
-	 * @throws HibernateException
-	 */
-	public void processEntityPropertyValues(Object[] values, Type[] types) throws HibernateException {
-		for ( int i=0; i<types.length; i++ ) {
-			if ( includeEntityProperty(values, i) ) {
-				processValue( i, values, types );
-			}
-		}
-	}
-	
-	void processValue(int i, Object[] values, Type[] types) {
-		processValue( values[i], types[i] );
-	}
-	
-	boolean includeEntityProperty(Object[] values, int i) {
-		return includeProperty(values, i);
-	}
-	
-	boolean includeProperty(Object[] values, int i) {
-		return values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY;
-	}
-
-	/**
-	 * Visit a component. Dispatch each property
-	 * to processValue().
-	 * @param component
-	 * @param componentType
-	 * @throws HibernateException
-	 */
-	Object processComponent(Object component, AbstractComponentType componentType)
-	throws HibernateException {
-		if (component!=null) {
-			processValues(
-				componentType.getPropertyValues(component, session),
-				componentType.getSubtypes()
-			);
-		}
-		return null;
-	}
-
-	/**
-	 * Visit a property value. Dispatch to the
-	 * correct handler for the property type.
-	 * @param value
-	 * @param type
-	 * @throws HibernateException
-	 */
-	final Object processValue(Object value, Type type) throws HibernateException {
-
-		if ( type.isCollectionType() ) {
-			//even process null collections
-			return processCollection( value, (CollectionType) type );
-		}
-		else if ( type.isEntityType() ) {
-			return processEntity( value, (EntityType) type );
-		}
-		else if ( type.isComponentType() ) {
-			return processComponent( value, (AbstractComponentType) type );
-		}
-		else {
-			return null;
-		}
-	}
-
-	/**
-	 * Walk the tree starting from the given entity.
-	 *
-	 * @param object
-	 * @param persister
-	 * @throws HibernateException
-	 */
-	void process(Object object, EntityPersister persister)
-	throws HibernateException {
-		processEntityPropertyValues(
-			persister.getPropertyValues( object, getSession().getEntityMode() ),
-			persister.getPropertyTypes()
-		);
-	}
-
-	/**
-	 * Visit a collection. Default superclass
-	 * implementation is a no-op.
-	 * @param collection
-	 * @param type
-	 * @throws HibernateException
-	 */
-	Object processCollection(Object collection, CollectionType type)
-	throws HibernateException {
-		return null;
-	}
-
-	/**
-	 * Visit a many-to-one or one-to-one associated
-	 * entity. Default superclass implementation is
-	 * a no-op.
-	 * @param value
-	 * @param entityType
-	 * @throws HibernateException
-	 */
-	Object processEntity(Object value, EntityType entityType)
-	throws HibernateException {
-		return null;
-	}
-
-	final EventSource getSession() {
-		return session;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/AbstractVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,180 @@
+/*
+ * 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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.event.EventSource;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+
+/**
+ * Abstract superclass of algorithms that walk
+ * a tree of property values of an entity, and
+ * perform specific functionality for collections,
+ * components and associated entities.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractVisitor {
+
+	private final EventSource session;
+
+	AbstractVisitor(EventSource session) {
+		this.session = session;
+	}
+
+	/**
+	 * Dispatch each property value to processValue().
+	 *
+	 * @param values
+	 * @param types
+	 * @throws HibernateException
+	 */
+	void processValues(Object[] values, Type[] types) throws HibernateException {
+		for ( int i=0; i<types.length; i++ ) {
+			if ( includeProperty(values, i) ) {
+				processValue( i, values, types );
+			}
+		}
+	}
+	
+	/**
+	 * Dispatch each property value to processValue().
+	 *
+	 * @param values
+	 * @param types
+	 * @throws HibernateException
+	 */
+	public void processEntityPropertyValues(Object[] values, Type[] types) throws HibernateException {
+		for ( int i=0; i<types.length; i++ ) {
+			if ( includeEntityProperty(values, i) ) {
+				processValue( i, values, types );
+			}
+		}
+	}
+	
+	void processValue(int i, Object[] values, Type[] types) {
+		processValue( values[i], types[i] );
+	}
+	
+	boolean includeEntityProperty(Object[] values, int i) {
+		return includeProperty(values, i);
+	}
+	
+	boolean includeProperty(Object[] values, int i) {
+		return values[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY;
+	}
+
+	/**
+	 * Visit a component. Dispatch each property
+	 * to processValue().
+	 * @param component
+	 * @param componentType
+	 * @throws HibernateException
+	 */
+	Object processComponent(Object component, AbstractComponentType componentType)
+	throws HibernateException {
+		if (component!=null) {
+			processValues(
+				componentType.getPropertyValues(component, session),
+				componentType.getSubtypes()
+			);
+		}
+		return null;
+	}
+
+	/**
+	 * Visit a property value. Dispatch to the
+	 * correct handler for the property type.
+	 * @param value
+	 * @param type
+	 * @throws HibernateException
+	 */
+	final Object processValue(Object value, Type type) throws HibernateException {
+
+		if ( type.isCollectionType() ) {
+			//even process null collections
+			return processCollection( value, (CollectionType) type );
+		}
+		else if ( type.isEntityType() ) {
+			return processEntity( value, (EntityType) type );
+		}
+		else if ( type.isComponentType() ) {
+			return processComponent( value, (AbstractComponentType) type );
+		}
+		else {
+			return null;
+		}
+	}
+
+	/**
+	 * Walk the tree starting from the given entity.
+	 *
+	 * @param object
+	 * @param persister
+	 * @throws HibernateException
+	 */
+	void process(Object object, EntityPersister persister)
+	throws HibernateException {
+		processEntityPropertyValues(
+			persister.getPropertyValues( object, getSession().getEntityMode() ),
+			persister.getPropertyTypes()
+		);
+	}
+
+	/**
+	 * Visit a collection. Default superclass
+	 * implementation is a no-op.
+	 * @param collection
+	 * @param type
+	 * @throws HibernateException
+	 */
+	Object processCollection(Object collection, CollectionType type)
+	throws HibernateException {
+		return null;
+	}
+
+	/**
+	 * Visit a many-to-one or one-to-one associated
+	 * entity. Default superclass implementation is
+	 * a no-op.
+	 * @param value
+	 * @param entityType
+	 * @throws HibernateException
+	 */
+	Object processEntity(Object value, EntityType entityType)
+	throws HibernateException {
+		return null;
+	}
+
+	final EventSource getSession() {
+		return session;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,75 +0,0 @@
-//$Id: DefaultAutoFlushEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.event.AutoFlushEvent;
-import org.hibernate.event.AutoFlushEventListener;
-import org.hibernate.event.EventSource;
-
-/**
- * Defines the default flush event listeners used by hibernate for 
- * flushing session state in response to generated auto-flush events.
- *
- * @author Steve Ebersole
- */
-public class DefaultAutoFlushEventListener extends AbstractFlushingEventListener implements AutoFlushEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultAutoFlushEventListener.class);
-
-    /** Handle the given auto-flush event.
-     *
-     * @param event The auto-flush event to be handled.
-     * @throws HibernateException
-     */
-	public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
-
-		final EventSource source = event.getSession();
-		
-		if ( flushMightBeNeeded(source) ) {
-
-			final int oldSize = source.getActionQueue().numberOfCollectionRemovals();
-
-			flushEverythingToExecutions(event);
-			
-			if ( flushIsReallyNeeded(event, source) ) {
-
-				log.trace("Need to execute flush");
-
-				performExecutions(source);
-				postFlush(source);
-				// note: performExecutions() clears all collectionXxxxtion 
-				// collections (the collection actions) in the session
-
-				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
-					source.getFactory().getStatisticsImplementor().flush();
-				}
-				
-			}
-			else {
-
-				log.trace("Dont need to execute flush");
-				source.getActionQueue().clearFromFlushNeededCheck( oldSize );
-			}
-			
-			event.setFlushRequired( flushIsReallyNeeded( event, source ) );
-
-		}
-
-	}
-
-	private boolean flushIsReallyNeeded(AutoFlushEvent event, final EventSource source) {
-		return source.getActionQueue()
-				.areTablesToBeUpdated( event.getQuerySpaces() ) || 
-						source.getFlushMode()==FlushMode.ALWAYS;
-	}
-
-	private boolean flushMightBeNeeded(final EventSource source) {
-		return !source.getFlushMode().lessThan(FlushMode.AUTO) && 
-				source.getDontFlushFromFind() == 0 &&
-				source.getPersistenceContext().hasNonReadOnlyEntities();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultAutoFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.event.AutoFlushEvent;
+import org.hibernate.event.AutoFlushEventListener;
+import org.hibernate.event.EventSource;
+
+/**
+ * Defines the default flush event listeners used by hibernate for 
+ * flushing session state in response to generated auto-flush events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultAutoFlushEventListener extends AbstractFlushingEventListener implements AutoFlushEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultAutoFlushEventListener.class);
+
+    /** Handle the given auto-flush event.
+     *
+     * @param event The auto-flush event to be handled.
+     * @throws HibernateException
+     */
+	public void onAutoFlush(AutoFlushEvent event) throws HibernateException {
+
+		final EventSource source = event.getSession();
+		
+		if ( flushMightBeNeeded(source) ) {
+
+			final int oldSize = source.getActionQueue().numberOfCollectionRemovals();
+
+			flushEverythingToExecutions(event);
+			
+			if ( flushIsReallyNeeded(event, source) ) {
+
+				log.trace("Need to execute flush");
+
+				performExecutions(source);
+				postFlush(source);
+				// note: performExecutions() clears all collectionXxxxtion 
+				// collections (the collection actions) in the session
+
+				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
+					source.getFactory().getStatisticsImplementor().flush();
+				}
+				
+			}
+			else {
+
+				log.trace("Dont need to execute flush");
+				source.getActionQueue().clearFromFlushNeededCheck( oldSize );
+			}
+			
+			event.setFlushRequired( flushIsReallyNeeded( event, source ) );
+
+		}
+
+	}
+
+	private boolean flushIsReallyNeeded(AutoFlushEvent event, final EventSource source) {
+		return source.getActionQueue()
+				.areTablesToBeUpdated( event.getQuerySpaces() ) || 
+						source.getFlushMode()==FlushMode.ALWAYS;
+	}
+
+	private boolean flushMightBeNeeded(final EventSource source) {
+		return !source.getFlushMode().lessThan(FlushMode.AUTO) && 
+				source.getDontFlushFromFind() == 0 &&
+				source.getPersistenceContext().hasNonReadOnlyEntities();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,336 +0,0 @@
-//$Id: DefaultDeleteEventListener.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.CacheMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.TransientObjectException;
-import org.hibernate.util.IdentitySet;
-import org.hibernate.action.EntityDeleteAction;
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Nullability;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.Status;
-import org.hibernate.event.DeleteEvent;
-import org.hibernate.event.DeleteEventListener;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-
-/**
- * Defines the default delete event listener used by hibernate for deleting entities
- * from the datastore in response to generated delete events.
- *
- * @author Steve Ebersole
- */
-public class DefaultDeleteEventListener implements DeleteEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger( DefaultDeleteEventListener.class );
-
-	/**
-	 * Handle the given delete event.
-	 *
-	 * @param event The delete event to be handled.
-	 *
-	 * @throws HibernateException
-	 */
-	public void onDelete(DeleteEvent event) throws HibernateException {
-		onDelete( event, new IdentitySet() );
-	}
-
-	/**
-	 * Handle the given delete event.  This is the cascaded form.
-	 *
-	 * @param event The delete event.
-	 * @param transientEntities The cache of entities already deleted
-	 *
-	 * @throws HibernateException
-	 */
-	public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
-
-		final EventSource source = event.getSession();
-
-		final PersistenceContext persistenceContext = source.getPersistenceContext();
-		Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
-
-		EntityEntry entityEntry = persistenceContext.getEntry( entity );
-		final EntityPersister persister;
-		final Serializable id;
-		final Object version;
-
-		if ( entityEntry == null ) {
-			log.trace( "entity was not persistent in delete processing" );
-
-			persister = source.getEntityPersister( event.getEntityName(), entity );
-
-			if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
-				deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
-				// EARLY EXIT!!!
-				return;
-			}
-			else {
-				performDetachedEntityDeletionCheck( event );
-			}
-
-			id = persister.getIdentifier( entity, source.getEntityMode() );
-
-			if ( id == null ) {
-				throw new TransientObjectException(
-						"the detached instance passed to delete() had a null identifier"
-				);
-			}
-
-			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-
-			persistenceContext.checkUniqueness( key, entity );
-
-			new OnUpdateVisitor( source, id, entity ).process( entity, persister );
-
-			version = persister.getVersion( entity, source.getEntityMode() );
-
-			entityEntry = persistenceContext.addEntity(
-					entity,
-					Status.MANAGED,
-					persister.getPropertyValues( entity, source.getEntityMode() ),
-					key,
-					version,
-					LockMode.NONE,
-					true,
-					persister,
-					false,
-					false
-			);
-		}
-		else {
-			log.trace( "deleting a persistent instance" );
-
-			if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
-				log.trace( "object was already deleted" );
-				return;
-			}
-			persister = entityEntry.getPersister();
-			id = entityEntry.getId();
-			version = entityEntry.getVersion();
-		}
-
-		/*if ( !persister.isMutable() ) {
-			throw new HibernateException(
-					"attempted to delete an object of immutable class: " +
-					MessageHelper.infoString(persister)
-				);
-		}*/
-
-		if ( invokeDeleteLifecycle( source, entity, persister ) ) {
-			return;
-		}
-
-		deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), persister, transientEntities );
-
-		if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
-			persister.resetIdentifier( entity, id, version, source.getEntityMode() );
-		}
-	}
-
-	/**
-	 * Called when we have recognized an attempt to delete a detached entity.
-	 * <p/>
-	 * This is perfectly valid in Hibernate usage; JPA, however, forbids this.
-	 * Thus, this is a hook for HEM to affect this behavior.
-	 *
-	 * @param event The event.
-	 */
-	protected void performDetachedEntityDeletionCheck(DeleteEvent event) {
-		// ok in normal Hibernate usage to delete a detached entity; JPA however
-		// forbids it, thus this is a hook for HEM to affect this behavior
-	}
-
-	/**
-	 * We encountered a delete request on a transient instance.
-	 * <p/>
-	 * This is a deviation from historical Hibernate (pre-3.2) behavior to
-	 * align with the JPA spec, which states that transient entities can be
-	 * passed to remove operation in which case cascades still need to be
-	 * performed.
-	 *
-	 * @param session The session which is the source of the event
-	 * @param entity The entity being delete processed
-	 * @param cascadeDeleteEnabled Is cascading of deletes enabled
-	 * @param persister The entity persister
-	 * @param transientEntities A cache of already visited transient entities
-	 * (to avoid infinite recursion).
-	 */
-	protected void deleteTransientEntity(
-			EventSource session,
-			Object entity,
-			boolean cascadeDeleteEnabled,
-			EntityPersister persister,
-			Set transientEntities) {
-		log.info( "handling transient entity in delete processing" );
-		if ( transientEntities.contains( entity ) ) {
-			log.trace( "already handled transient entity; skipping" );
-			return;
-		}
-		transientEntities.add( entity );
-		cascadeBeforeDelete( session, persister, entity, null, transientEntities );
-		cascadeAfterDelete( session, persister, entity, transientEntities );
-	}
-
-	/**
-	 * Perform the entity deletion.  Well, as with most operations, does not
-	 * really perform it; just schedules an action/execution with the
-	 * {@link org.hibernate.engine.ActionQueue} for execution during flush.
-	 *
-	 * @param session The originating session
-	 * @param entity The entity to delete
-	 * @param entityEntry The entity's entry in the {@link PersistenceContext}
-	 * @param isCascadeDeleteEnabled Is delete cascading enabled?
-	 * @param persister The entity persister.
-	 * @param transientEntities A cache of already deleted entities.
-	 */
-	protected final void deleteEntity(
-			final EventSource session,
-			final Object entity,
-			final EntityEntry entityEntry,
-			final boolean isCascadeDeleteEnabled,
-			final EntityPersister persister,
-			final Set transientEntities) {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"deleting " +
-							MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
-			);
-		}
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		final Type[] propTypes = persister.getPropertyTypes();
-		final Object version = entityEntry.getVersion();
-
-		final Object[] currentState;
-		if ( entityEntry.getLoadedState() == null ) { //ie. the entity came in from update()
-			currentState = persister.getPropertyValues( entity, session.getEntityMode() );
-		}
-		else {
-			currentState = entityEntry.getLoadedState();
-		}
-
-		final Object[] deletedState = createDeletedState( persister, currentState, session );
-		entityEntry.setDeletedState( deletedState );
-
-		session.getInterceptor().onDelete(
-				entity,
-				entityEntry.getId(),
-				deletedState,
-				persister.getPropertyNames(),
-				propTypes
-		);
-
-		// before any callbacks, etc, so subdeletions see that this deletion happened first
-		persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
-		EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() );
-
-		cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );
-
-		new ForeignKeys.Nullifier( entity, true, false, session )
-				.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
-		new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true );
-		persistenceContext.getNullifiableEntityKeys().add( key );
-
-		// Ensures that containing deletions happen before sub-deletions
-		session.getActionQueue().addAction(
-				new EntityDeleteAction(
-						entityEntry.getId(),
-						deletedState,
-						version,
-						entity,
-						persister,
-						isCascadeDeleteEnabled,
-						session
-				)
-		);
-
-		cascadeAfterDelete( session, persister, entity, transientEntities );
-
-		// the entry will be removed after the flush, and will no longer
-		// override the stale snapshot
-		// This is now handled by removeEntity() in EntityDeleteAction
-		//persistenceContext.removeDatabaseSnapshot(key);
-	}
-
-	private Object[] createDeletedState(EntityPersister persister, Object[] currentState, EventSource session) {
-		Type[] propTypes = persister.getPropertyTypes();
-		final Object[] deletedState = new Object[propTypes.length];
-//		TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session );
-		boolean[] copyability = new boolean[propTypes.length];
-		java.util.Arrays.fill( copyability, true );
-		TypeFactory.deepCopy( currentState, propTypes, copyability, deletedState, session );
-		return deletedState;
-	}
-
-	protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
-		if ( persister.implementsLifecycle( session.getEntityMode() ) ) {
-			log.debug( "calling onDelete()" );
-			if ( ( ( Lifecycle ) entity ).onDelete( session ) ) {
-				log.debug( "deletion vetoed by onDelete()" );
-				return true;
-			}
-		}
-		return false;
-	}
-
-	protected void cascadeBeforeDelete(
-			EventSource session,
-			EntityPersister persister,
-			Object entity,
-			EntityEntry entityEntry,
-			Set transientEntities) throws HibernateException {
-
-		CacheMode cacheMode = session.getCacheMode();
-		session.setCacheMode( CacheMode.GET );
-		session.getPersistenceContext().incrementCascadeLevel();
-		try {
-			// cascade-delete to collections BEFORE the collection owner is deleted
-			new Cascade( CascadingAction.DELETE, Cascade.AFTER_INSERT_BEFORE_DELETE, session )
-					.cascade( persister, entity, transientEntities );
-		}
-		finally {
-			session.getPersistenceContext().decrementCascadeLevel();
-			session.setCacheMode( cacheMode );
-		}
-	}
-
-	protected void cascadeAfterDelete(
-			EventSource session,
-			EntityPersister persister,
-			Object entity,
-			Set transientEntities) throws HibernateException {
-
-		CacheMode cacheMode = session.getCacheMode();
-		session.setCacheMode( CacheMode.GET );
-		session.getPersistenceContext().incrementCascadeLevel();
-		try {
-			// cascade-delete to many-to-one AFTER the parent was deleted
-			new Cascade( CascadingAction.DELETE, Cascade.BEFORE_INSERT_AFTER_DELETE, session )
-					.cascade( persister, entity, transientEntities );
-		}
-		finally {
-			session.getPersistenceContext().decrementCascadeLevel();
-			session.setCacheMode( cacheMode );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,358 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.CacheMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.TransientObjectException;
+import org.hibernate.util.IdentitySet;
+import org.hibernate.action.EntityDeleteAction;
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Nullability;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.Status;
+import org.hibernate.event.DeleteEvent;
+import org.hibernate.event.DeleteEventListener;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * Defines the default delete event listener used by hibernate for deleting entities
+ * from the datastore in response to generated delete events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultDeleteEventListener implements DeleteEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger( DefaultDeleteEventListener.class );
+
+	/**
+	 * Handle the given delete event.
+	 *
+	 * @param event The delete event to be handled.
+	 *
+	 * @throws HibernateException
+	 */
+	public void onDelete(DeleteEvent event) throws HibernateException {
+		onDelete( event, new IdentitySet() );
+	}
+
+	/**
+	 * Handle the given delete event.  This is the cascaded form.
+	 *
+	 * @param event The delete event.
+	 * @param transientEntities The cache of entities already deleted
+	 *
+	 * @throws HibernateException
+	 */
+	public void onDelete(DeleteEvent event, Set transientEntities) throws HibernateException {
+
+		final EventSource source = event.getSession();
+
+		final PersistenceContext persistenceContext = source.getPersistenceContext();
+		Object entity = persistenceContext.unproxyAndReassociate( event.getObject() );
+
+		EntityEntry entityEntry = persistenceContext.getEntry( entity );
+		final EntityPersister persister;
+		final Serializable id;
+		final Object version;
+
+		if ( entityEntry == null ) {
+			log.trace( "entity was not persistent in delete processing" );
+
+			persister = source.getEntityPersister( event.getEntityName(), entity );
+
+			if ( ForeignKeys.isTransient( persister.getEntityName(), entity, null, source ) ) {
+				deleteTransientEntity( source, entity, event.isCascadeDeleteEnabled(), persister, transientEntities );
+				// EARLY EXIT!!!
+				return;
+			}
+			else {
+				performDetachedEntityDeletionCheck( event );
+			}
+
+			id = persister.getIdentifier( entity, source.getEntityMode() );
+
+			if ( id == null ) {
+				throw new TransientObjectException(
+						"the detached instance passed to delete() had a null identifier"
+				);
+			}
+
+			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+
+			persistenceContext.checkUniqueness( key, entity );
+
+			new OnUpdateVisitor( source, id, entity ).process( entity, persister );
+
+			version = persister.getVersion( entity, source.getEntityMode() );
+
+			entityEntry = persistenceContext.addEntity(
+					entity,
+					Status.MANAGED,
+					persister.getPropertyValues( entity, source.getEntityMode() ),
+					key,
+					version,
+					LockMode.NONE,
+					true,
+					persister,
+					false,
+					false
+			);
+		}
+		else {
+			log.trace( "deleting a persistent instance" );
+
+			if ( entityEntry.getStatus() == Status.DELETED || entityEntry.getStatus() == Status.GONE ) {
+				log.trace( "object was already deleted" );
+				return;
+			}
+			persister = entityEntry.getPersister();
+			id = entityEntry.getId();
+			version = entityEntry.getVersion();
+		}
+
+		/*if ( !persister.isMutable() ) {
+			throw new HibernateException(
+					"attempted to delete an object of immutable class: " +
+					MessageHelper.infoString(persister)
+				);
+		}*/
+
+		if ( invokeDeleteLifecycle( source, entity, persister ) ) {
+			return;
+		}
+
+		deleteEntity( source, entity, entityEntry, event.isCascadeDeleteEnabled(), persister, transientEntities );
+
+		if ( source.getFactory().getSettings().isIdentifierRollbackEnabled() ) {
+			persister.resetIdentifier( entity, id, version, source.getEntityMode() );
+		}
+	}
+
+	/**
+	 * Called when we have recognized an attempt to delete a detached entity.
+	 * <p/>
+	 * This is perfectly valid in Hibernate usage; JPA, however, forbids this.
+	 * Thus, this is a hook for HEM to affect this behavior.
+	 *
+	 * @param event The event.
+	 */
+	protected void performDetachedEntityDeletionCheck(DeleteEvent event) {
+		// ok in normal Hibernate usage to delete a detached entity; JPA however
+		// forbids it, thus this is a hook for HEM to affect this behavior
+	}
+
+	/**
+	 * We encountered a delete request on a transient instance.
+	 * <p/>
+	 * This is a deviation from historical Hibernate (pre-3.2) behavior to
+	 * align with the JPA spec, which states that transient entities can be
+	 * passed to remove operation in which case cascades still need to be
+	 * performed.
+	 *
+	 * @param session The session which is the source of the event
+	 * @param entity The entity being delete processed
+	 * @param cascadeDeleteEnabled Is cascading of deletes enabled
+	 * @param persister The entity persister
+	 * @param transientEntities A cache of already visited transient entities
+	 * (to avoid infinite recursion).
+	 */
+	protected void deleteTransientEntity(
+			EventSource session,
+			Object entity,
+			boolean cascadeDeleteEnabled,
+			EntityPersister persister,
+			Set transientEntities) {
+		log.info( "handling transient entity in delete processing" );
+		if ( transientEntities.contains( entity ) ) {
+			log.trace( "already handled transient entity; skipping" );
+			return;
+		}
+		transientEntities.add( entity );
+		cascadeBeforeDelete( session, persister, entity, null, transientEntities );
+		cascadeAfterDelete( session, persister, entity, transientEntities );
+	}
+
+	/**
+	 * Perform the entity deletion.  Well, as with most operations, does not
+	 * really perform it; just schedules an action/execution with the
+	 * {@link org.hibernate.engine.ActionQueue} for execution during flush.
+	 *
+	 * @param session The originating session
+	 * @param entity The entity to delete
+	 * @param entityEntry The entity's entry in the {@link PersistenceContext}
+	 * @param isCascadeDeleteEnabled Is delete cascading enabled?
+	 * @param persister The entity persister.
+	 * @param transientEntities A cache of already deleted entities.
+	 */
+	protected final void deleteEntity(
+			final EventSource session,
+			final Object entity,
+			final EntityEntry entityEntry,
+			final boolean isCascadeDeleteEnabled,
+			final EntityPersister persister,
+			final Set transientEntities) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"deleting " +
+							MessageHelper.infoString( persister, entityEntry.getId(), session.getFactory() )
+			);
+		}
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		final Type[] propTypes = persister.getPropertyTypes();
+		final Object version = entityEntry.getVersion();
+
+		final Object[] currentState;
+		if ( entityEntry.getLoadedState() == null ) { //ie. the entity came in from update()
+			currentState = persister.getPropertyValues( entity, session.getEntityMode() );
+		}
+		else {
+			currentState = entityEntry.getLoadedState();
+		}
+
+		final Object[] deletedState = createDeletedState( persister, currentState, session );
+		entityEntry.setDeletedState( deletedState );
+
+		session.getInterceptor().onDelete(
+				entity,
+				entityEntry.getId(),
+				deletedState,
+				persister.getPropertyNames(),
+				propTypes
+		);
+
+		// before any callbacks, etc, so subdeletions see that this deletion happened first
+		persistenceContext.setEntryStatus( entityEntry, Status.DELETED );
+		EntityKey key = new EntityKey( entityEntry.getId(), persister, session.getEntityMode() );
+
+		cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );
+
+		new ForeignKeys.Nullifier( entity, true, false, session )
+				.nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
+		new Nullability( session ).checkNullability( entityEntry.getDeletedState(), persister, true );
+		persistenceContext.getNullifiableEntityKeys().add( key );
+
+		// Ensures that containing deletions happen before sub-deletions
+		session.getActionQueue().addAction(
+				new EntityDeleteAction(
+						entityEntry.getId(),
+						deletedState,
+						version,
+						entity,
+						persister,
+						isCascadeDeleteEnabled,
+						session
+				)
+		);
+
+		cascadeAfterDelete( session, persister, entity, transientEntities );
+
+		// the entry will be removed after the flush, and will no longer
+		// override the stale snapshot
+		// This is now handled by removeEntity() in EntityDeleteAction
+		//persistenceContext.removeDatabaseSnapshot(key);
+	}
+
+	private Object[] createDeletedState(EntityPersister persister, Object[] currentState, EventSource session) {
+		Type[] propTypes = persister.getPropertyTypes();
+		final Object[] deletedState = new Object[propTypes.length];
+//		TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(), deletedState, session );
+		boolean[] copyability = new boolean[propTypes.length];
+		java.util.Arrays.fill( copyability, true );
+		TypeFactory.deepCopy( currentState, propTypes, copyability, deletedState, session );
+		return deletedState;
+	}
+
+	protected boolean invokeDeleteLifecycle(EventSource session, Object entity, EntityPersister persister) {
+		if ( persister.implementsLifecycle( session.getEntityMode() ) ) {
+			log.debug( "calling onDelete()" );
+			if ( ( ( Lifecycle ) entity ).onDelete( session ) ) {
+				log.debug( "deletion vetoed by onDelete()" );
+				return true;
+			}
+		}
+		return false;
+	}
+
+	protected void cascadeBeforeDelete(
+			EventSource session,
+			EntityPersister persister,
+			Object entity,
+			EntityEntry entityEntry,
+			Set transientEntities) throws HibernateException {
+
+		CacheMode cacheMode = session.getCacheMode();
+		session.setCacheMode( CacheMode.GET );
+		session.getPersistenceContext().incrementCascadeLevel();
+		try {
+			// cascade-delete to collections BEFORE the collection owner is deleted
+			new Cascade( CascadingAction.DELETE, Cascade.AFTER_INSERT_BEFORE_DELETE, session )
+					.cascade( persister, entity, transientEntities );
+		}
+		finally {
+			session.getPersistenceContext().decrementCascadeLevel();
+			session.setCacheMode( cacheMode );
+		}
+	}
+
+	protected void cascadeAfterDelete(
+			EventSource session,
+			EntityPersister persister,
+			Object entity,
+			Set transientEntities) throws HibernateException {
+
+		CacheMode cacheMode = session.getCacheMode();
+		session.setCacheMode( CacheMode.GET );
+		session.getPersistenceContext().incrementCascadeLevel();
+		try {
+			// cascade-delete to many-to-one AFTER the parent was deleted
+			new Cascade( CascadingAction.DELETE, Cascade.BEFORE_INSERT_AFTER_DELETE, session )
+					.cascade( persister, entity, transientEntities );
+		}
+		finally {
+			session.getPersistenceContext().decrementCascadeLevel();
+			session.setCacheMode( cacheMode );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-//$Id: DefaultDirtyCheckEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.event.DirtyCheckEvent;
-import org.hibernate.event.DirtyCheckEventListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Defines the default dirty-check event listener used by hibernate for
- * checking the session for dirtiness in response to generated dirty-check
- * events.
- *
- * @author Steve Ebersole
- */
-public class DefaultDirtyCheckEventListener extends AbstractFlushingEventListener implements DirtyCheckEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultDirtyCheckEventListener.class);
-
-    /** Handle the given dirty-check event.
-     *
-     * @param event The dirty-check event to be handled.
-     * @throws HibernateException
-     */
-	public void onDirtyCheck(DirtyCheckEvent event) throws HibernateException {
-
-		int oldSize = event.getSession().getActionQueue().numberOfCollectionRemovals();
-
-		try {
-			flushEverythingToExecutions(event);
-			boolean wasNeeded = event.getSession().getActionQueue().hasAnyQueuedActions();
-			log.debug( wasNeeded ? "session dirty" : "session not dirty" );
-			event.setDirty( wasNeeded );
-		}
-		finally {
-			event.getSession().getActionQueue().clearFromFlushNeededCheck( oldSize );
-		}
-		
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultDirtyCheckEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.event.DirtyCheckEvent;
+import org.hibernate.event.DirtyCheckEventListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines the default dirty-check event listener used by hibernate for
+ * checking the session for dirtiness in response to generated dirty-check
+ * events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultDirtyCheckEventListener extends AbstractFlushingEventListener implements DirtyCheckEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultDirtyCheckEventListener.class);
+
+    /** Handle the given dirty-check event.
+     *
+     * @param event The dirty-check event to be handled.
+     * @throws HibernateException
+     */
+	public void onDirtyCheck(DirtyCheckEvent event) throws HibernateException {
+
+		int oldSize = event.getSession().getActionQueue().numberOfCollectionRemovals();
+
+		try {
+			flushEverythingToExecutions(event);
+			boolean wasNeeded = event.getSession().getActionQueue().hasAnyQueuedActions();
+			log.debug( wasNeeded ? "session dirty" : "session not dirty" );
+			event.setDirty( wasNeeded );
+		}
+		finally {
+			event.getSession().getActionQueue().clearFromFlushNeededCheck( oldSize );
+		}
+		
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-//$Id: DefaultEvictEventListener.java 10224 2006-08-04 20:29:45Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.EvictEvent;
-import org.hibernate.event.EvictEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-
-/**
- * Defines the default evict event listener used by hibernate for evicting entities
- * in response to generated flush events.  In particular, this implementation will
- * remove any hard references to the entity that are held by the infrastructure
- * (references held by application or other persistent instances are okay)
- *
- * @author Steve Ebersole
- */
-public class DefaultEvictEventListener implements EvictEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultEvictEventListener.class);
-
-	/** 
-	 * Handle the given evict event.
-	 *
-	 * @param event The evict event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onEvict(EvictEvent event) throws HibernateException {
-		EventSource source = event.getSession();
-		final Object object = event.getObject();
-		final PersistenceContext persistenceContext = source.getPersistenceContext();
-
-		if ( object instanceof HibernateProxy ) {
-			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
-			Serializable id = li.getIdentifier();
-			EntityPersister persister = source.getFactory().getEntityPersister( li.getEntityName() );
-			if ( id == null ) {
-				throw new IllegalArgumentException("null identifier");
-			}
-
-			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-			persistenceContext.removeProxy( key );
-
-			if ( !li.isUninitialized() ) {
-				final Object entity = persistenceContext.removeEntity( key );
-				if ( entity != null ) {
-					EntityEntry e = event.getSession().getPersistenceContext().removeEntry( entity );
-					doEvict( entity, key, e.getPersister(), event.getSession() );
-				}
-			}
-			li.setSession( null );
-		}
-		else {
-			EntityEntry e = persistenceContext.removeEntry( object );
-			if ( e != null ) {
-				EntityKey key = new EntityKey( e.getId(), e.getPersister(), source.getEntityMode()  );
-				persistenceContext.removeEntity( key );
-				doEvict( object, key, e.getPersister(), source );
-			}
-		}
-	}
-
-	protected void doEvict(
-		final Object object, 
-		final EntityKey key, 
-		final EntityPersister persister,
-		final EventSource session) 
-	throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "evicting " + MessageHelper.infoString(persister) );
-		}
-
-		// remove all collections for the entity from the session-level cache
-		if ( persister.hasCollections() ) {
-			new EvictVisitor( session ).process( object, persister );
-		}
-
-		// remove any snapshot, not really for memory management purposes, but
-		// rather because it might now be stale, and there is no longer any 
-		// EntityEntry to take precedence
-		// This is now handled by removeEntity()
-		//session.getPersistenceContext().removeDatabaseSnapshot(key);
-
-		new Cascade( CascadingAction.EVICT, Cascade.AFTER_EVICT, session )
-				.cascade( persister, object );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultEvictEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,123 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.EvictEvent;
+import org.hibernate.event.EvictEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+
+/**
+ * Defines the default evict event listener used by hibernate for evicting entities
+ * in response to generated flush events.  In particular, this implementation will
+ * remove any hard references to the entity that are held by the infrastructure
+ * (references held by application or other persistent instances are okay)
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultEvictEventListener implements EvictEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultEvictEventListener.class);
+
+	/** 
+	 * Handle the given evict event.
+	 *
+	 * @param event The evict event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onEvict(EvictEvent event) throws HibernateException {
+		EventSource source = event.getSession();
+		final Object object = event.getObject();
+		final PersistenceContext persistenceContext = source.getPersistenceContext();
+
+		if ( object instanceof HibernateProxy ) {
+			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
+			Serializable id = li.getIdentifier();
+			EntityPersister persister = source.getFactory().getEntityPersister( li.getEntityName() );
+			if ( id == null ) {
+				throw new IllegalArgumentException("null identifier");
+			}
+
+			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+			persistenceContext.removeProxy( key );
+
+			if ( !li.isUninitialized() ) {
+				final Object entity = persistenceContext.removeEntity( key );
+				if ( entity != null ) {
+					EntityEntry e = event.getSession().getPersistenceContext().removeEntry( entity );
+					doEvict( entity, key, e.getPersister(), event.getSession() );
+				}
+			}
+			li.setSession( null );
+		}
+		else {
+			EntityEntry e = persistenceContext.removeEntry( object );
+			if ( e != null ) {
+				EntityKey key = new EntityKey( e.getId(), e.getPersister(), source.getEntityMode()  );
+				persistenceContext.removeEntity( key );
+				doEvict( object, key, e.getPersister(), source );
+			}
+		}
+	}
+
+	protected void doEvict(
+		final Object object, 
+		final EntityKey key, 
+		final EntityPersister persister,
+		final EventSource session) 
+	throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "evicting " + MessageHelper.infoString(persister) );
+		}
+
+		// remove all collections for the entity from the session-level cache
+		if ( persister.hasCollections() ) {
+			new EvictVisitor( session ).process( object, persister );
+		}
+
+		// remove any snapshot, not really for memory management purposes, but
+		// rather because it might now be stale, and there is no longer any 
+		// EntityEntry to take precedence
+		// This is now handled by removeEntity()
+		//session.getPersistenceContext().removeDatabaseSnapshot(key);
+
+		new Cascade( CascadingAction.EVICT, Cascade.AFTER_EVICT, session )
+				.cascade( persister, object );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,527 +0,0 @@
-//$Id: DefaultFlushEntityEventListener.java 10784 2006-11-11 05:13:01Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.action.EntityUpdateAction;
-import org.hibernate.action.DelayedPostInsertIdentifier;
-import org.hibernate.classic.Validatable;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.Nullability;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.FlushEntityEvent;
-import org.hibernate.event.FlushEntityEventListener;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * An event that occurs for each entity instance at flush time
- *
- * @author Gavin King
- */
-public class DefaultFlushEntityEventListener implements FlushEntityEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultFlushEntityEventListener.class);
-
-	/**
-	 * make sure user didn't mangle the id
-	 */
-	public void checkId(Object object, EntityPersister persister, Serializable id, EntityMode entityMode)
-	throws HibernateException {
-
-		if ( id != null && id instanceof DelayedPostInsertIdentifier ) {
-			// this is a situation where the entity id is assigned by a post-insert generator
-			// and was saved outside the transaction forcing it to be delayed
-			return;
-		}
-
-		if ( persister.canExtractIdOutOfEntity() ) {
-
-			Serializable oid = persister.getIdentifier( object, entityMode );
-			if (id==null) {
-				throw new AssertionFailure("null id in " + persister.getEntityName() + " entry (don't flush the Session after an exception occurs)");
-			}
-			if ( !persister.getIdentifierType().isEqual(id, oid, entityMode) ) {
-				throw new HibernateException(
-						"identifier of an instance of " +
-						persister.getEntityName() +
-						" was altered from " + id +
-						" to " + oid
-					);
-			}
-		}
-
-	}
-
-	private void checkNaturalId(
-			EntityPersister persister,
-	        EntityEntry entry,
-	        Object[] current,
-	        Object[] loaded,
-	        EntityMode entityMode,
-	        SessionImplementor session) {
-		if ( persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY ) {
- 			Object[] snapshot = null;			
-			Type[] types = persister.getPropertyTypes();
-			int[] props = persister.getNaturalIdentifierProperties();
-			boolean[] updateable = persister.getPropertyUpdateability();
-			for ( int i=0; i<props.length; i++ ) {
-				int prop = props[i];
-				if ( !updateable[prop] ) {
- 					Object loadedVal;
- 					if ( loaded == null ) {
- 						if ( snapshot == null) {
- 							snapshot = session.getPersistenceContext().getNaturalIdSnapshot( entry.getId(), persister );
- 						}
- 						loadedVal = snapshot[i];
- 					} else {
- 						loadedVal = loaded[prop];
- 					}
- 					if ( !types[prop].isEqual( current[prop], loadedVal, entityMode ) ) {						
-						throw new HibernateException(
-								"immutable natural identifier of an instance of " +
-								persister.getEntityName() +
-								" was altered"
-							);
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Flushes a single entity's state to the database, by scheduling
-	 * an update action, if necessary
-	 */
-	public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
-		final Object entity = event.getEntity();
-		final EntityEntry entry = event.getEntityEntry();
-		final EventSource session = event.getSession();
-		final EntityPersister persister = entry.getPersister();
-		final Status status = entry.getStatus();
-		final EntityMode entityMode = session.getEntityMode();
-		final Type[] types = persister.getPropertyTypes();
-
-		final boolean mightBeDirty = entry.requiresDirtyCheck(entity);
-
-		final Object[] values = getValues( entity, entry, entityMode, mightBeDirty, session );
-
-		event.setPropertyValues(values);
-
-		//TODO: avoid this for non-new instances where mightBeDirty==false
-		boolean substitute = wrapCollections( session, persister, types, values);
-
-		if ( isUpdateNecessary( event, mightBeDirty ) ) {
-			substitute = scheduleUpdate( event ) || substitute;
-		}
-
-		if ( status != Status.DELETED ) {
-			// now update the object .. has to be outside the main if block above (because of collections)
-			if (substitute) persister.setPropertyValues( entity, values, entityMode );
-
-			// Search for collections by reachability, updating their role.
-			// We don't want to touch collections reachable from a deleted object
-			if ( persister.hasCollections() ) {
-				new FlushVisitor(session, entity).processEntityPropertyValues(values, types);
-			}
-		}
-
-	}
-
-	private Object[] getValues(
-			Object entity,
-			EntityEntry entry,
-			EntityMode entityMode,
-			boolean mightBeDirty,
-	        SessionImplementor session
-	) {
-		final Object[] loadedState = entry.getLoadedState();
-		final Status status = entry.getStatus();
-		final EntityPersister persister = entry.getPersister();
-
-		final Object[] values;
-		if ( status == Status.DELETED ) {
-			//grab its state saved at deletion
-			values = entry.getDeletedState();
-		}
-		else if ( !mightBeDirty && loadedState!=null ) {
-			values = loadedState;
-		}
-		else {
-			checkId( entity, persister, entry.getId(), entityMode );
-
-			// grab its current state
-			values = persister.getPropertyValues( entity, entityMode );
-
-			checkNaturalId( persister, entry, values, loadedState, entityMode, session );
-		}
-		return values;
-	}
-
-	private boolean wrapCollections(
-			EventSource session,
-			EntityPersister persister,
-			Type[] types,
-			Object[] values
-	) {
-		if ( persister.hasCollections() ) {
-
-			// wrap up any new collections directly referenced by the object
-			// or its components
-
-			// NOTE: we need to do the wrap here even if its not "dirty",
-			// because collections need wrapping but changes to _them_
-			// don't dirty the container. Also, for versioned data, we
-			// need to wrap before calling searchForDirtyCollections
-
-			WrapVisitor visitor = new WrapVisitor(session);
-			// substitutes into values by side-effect
-			visitor.processEntityPropertyValues(values, types);
-			return visitor.isSubstitutionRequired();
-		}
-		else {
-			return false;
-		}
-	}
-
-	private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mightBeDirty) {
-		final Status status = event.getEntityEntry().getStatus();
-		if ( mightBeDirty || status==Status.DELETED ) {
-			// compare to cached state (ignoring collections unless versioned)
-			dirtyCheck(event);
-			if ( isUpdateNecessary(event) ) {
-				return true;
-			}
-			else {
-				FieldInterceptionHelper.clearDirty( event.getEntity() );
-				return false;
-			}
-		}
-		else {
-			return hasDirtyCollections( event, event.getEntityEntry().getPersister(), status );
-		}
-	}
-
-	private boolean scheduleUpdate(final FlushEntityEvent event) {
-		
-		final EntityEntry entry = event.getEntityEntry();
-		final EventSource session = event.getSession();
-		final Object entity = event.getEntity();
-		final Status status = entry.getStatus();
-		final EntityMode entityMode = session.getEntityMode();
-		final EntityPersister persister = entry.getPersister();
-		final Object[] values = event.getPropertyValues();
-		
-		if ( log.isTraceEnabled() ) {
-			if ( status == Status.DELETED ) {
-				log.trace(
-						"Updating deleted entity: " +
-						MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
-					);
-			}
-			else {
-				log.trace(
-						"Updating entity: " +
-						MessageHelper.infoString( persister, entry.getId(), session.getFactory()  )
-					);
-			}
-		}
-
-		final boolean intercepted;
-		if ( !entry.isBeingReplicated() ) {
-			// give the Interceptor a chance to process property values, if the properties
-			// were modified by the Interceptor, we need to set them back to the object
-			intercepted = handleInterception( event );
-		}
-		else {
-			intercepted = false;
-		}
-
-		validate( entity, persister, status, entityMode );
-
-		// increment the version number (if necessary)
-		final Object nextVersion = getNextVersion(event);
-
-		// if it was dirtied by a collection only
-		int[] dirtyProperties = event.getDirtyProperties();
-		if ( event.isDirtyCheckPossible() && dirtyProperties == null ) {
-			if ( ! intercepted && !event.hasDirtyCollection() ) {
-				throw new AssertionFailure( "dirty, but no dirty properties" );
-			}
-			dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
-		}
-
-		// check nullability but do not perform command execute
-		// we'll use scheduled updates for that.
-		new Nullability(session).checkNullability( values, persister, true );
-
-		// schedule the update
-		// note that we intentionally do _not_ pass in currentPersistentState!
-		session.getActionQueue().addAction(
-				new EntityUpdateAction(
-						entry.getId(),
-						values,
-						dirtyProperties,
-						event.hasDirtyCollection(),
-						entry.getLoadedState(),
-						entry.getVersion(),
-						nextVersion,
-						entity,
-						entry.getRowId(),
-						persister,
-						session
-					)
-			);
-		
-		return intercepted;
-	}
-
-	protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) {
-		// validate() instances of Validatable
-		if ( status == Status.MANAGED && persister.implementsValidatable( entityMode ) ) {
-			( (Validatable) entity ).validate();
-		}
-	}
-	
-	protected boolean handleInterception(FlushEntityEvent event) {
-		SessionImplementor session = event.getSession();
-		EntityEntry entry = event.getEntityEntry();
-		EntityPersister persister = entry.getPersister();
-		Object entity = event.getEntity();
-		
-		//give the Interceptor a chance to modify property values
-		final Object[] values = event.getPropertyValues();
-		final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister );
-
-		//now we might need to recalculate the dirtyProperties array
-		if ( intercepted && event.isDirtyCheckPossible() && !event.isDirtyCheckHandledByInterceptor() ) {
-			int[] dirtyProperties;
-			if ( event.hasDatabaseSnapshot() ) {
-				dirtyProperties = persister.findModified( event.getDatabaseSnapshot(), values, entity, session );
-			}
-			else {
-				dirtyProperties = persister.findDirty( values, entry.getLoadedState(), entity, session );
-			}
-			event.setDirtyProperties(dirtyProperties);
-		}
-		
-		return intercepted;
-	}
-
-	protected boolean invokeInterceptor(
-			SessionImplementor session,
-			Object entity,
-			EntityEntry entry,
-			final Object[] values,
-			EntityPersister persister) {
-		return session.getInterceptor().onFlushDirty(
-				entity,
-				entry.getId(),
-				values,
-				entry.getLoadedState(),
-				persister.getPropertyNames(),
-				persister.getPropertyTypes()
-		);
-	}
-
-	/**
-	 * Convience method to retreive an entities next version value
-	 */
-	private Object getNextVersion(FlushEntityEvent event) throws HibernateException {
-		
-		EntityEntry entry = event.getEntityEntry();
-		EntityPersister persister = entry.getPersister();
-		if ( persister.isVersioned() ) {
-
-			Object[] values = event.getPropertyValues();
-		    
-			if ( entry.isBeingReplicated() ) {
-				return Versioning.getVersion(values, persister);
-			}
-			else {
-				int[] dirtyProperties = event.getDirtyProperties();
-				
-				final boolean isVersionIncrementRequired = isVersionIncrementRequired( 
-						event, 
-						entry, 
-						persister, 
-						dirtyProperties 
-					);
-				
-				final Object nextVersion = isVersionIncrementRequired ?
-						Versioning.increment( entry.getVersion(), persister.getVersionType(), event.getSession() ) :
-						entry.getVersion(); //use the current version
-						
-				Versioning.setVersion(values, nextVersion, persister);
-				
-				return nextVersion;
-			}
-		}
-		else {
-			return null;
-		}
-		
-	}
-
-	private boolean isVersionIncrementRequired(
-			FlushEntityEvent event, 
-			EntityEntry entry, 
-			EntityPersister persister, 
-			int[] dirtyProperties
-	) {
-		final boolean isVersionIncrementRequired = entry.getStatus()!=Status.DELETED && ( 
-				dirtyProperties==null || 
-				Versioning.isVersionIncrementRequired( 
-						dirtyProperties, 
-						event.hasDirtyCollection(),
-						persister.getPropertyVersionability()
-					) 
-			);
-		return isVersionIncrementRequired;
-	}
-
-	/**
-	 * Performs all necessary checking to determine if an entity needs an SQL update
-	 * to synchronize its state to the database. Modifies the event by side-effect!
-	 * Note: this method is quite slow, avoid calling if possible!
-	 */
-	protected final boolean isUpdateNecessary(FlushEntityEvent event) throws HibernateException {
-
-		EntityPersister persister = event.getEntityEntry().getPersister();
-		Status status = event.getEntityEntry().getStatus();
-		
-		if ( !event.isDirtyCheckPossible() ) {
-			return true;
-		}
-		else {
-			
-			int[] dirtyProperties = event.getDirtyProperties();
-			if ( dirtyProperties!=null && dirtyProperties.length!=0 ) {
-				return true; //TODO: suck into event class
-			}
-			else {
-				return hasDirtyCollections( event, persister, status );
-			}
-			
-		}
-	}
-
-	private boolean hasDirtyCollections(FlushEntityEvent event, EntityPersister persister, Status status) {
-		if ( isCollectionDirtyCheckNecessary(persister, status) ) {
-			DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor( 
-					event.getSession(),
-					persister.getPropertyVersionability()
-				);
-			visitor.processEntityPropertyValues( event.getPropertyValues(), persister.getPropertyTypes() );
-			boolean hasDirtyCollections = visitor.wasDirtyCollectionFound();
-			event.setHasDirtyCollection(hasDirtyCollections);
-			return hasDirtyCollections;
-		}
-		else {
-			return false;
-		}
-	}
-
-	private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
-		return status==Status.MANAGED && 
-				persister.isVersioned() && 
-				persister.hasCollections();
-	}
-	
-	/**
-	 * Perform a dirty check, and attach the results to the event
-	 */
-	protected void dirtyCheck(FlushEntityEvent event) throws HibernateException {
-		
-		final Object entity = event.getEntity();
-		final Object[] values = event.getPropertyValues();
-		final SessionImplementor session = event.getSession();
-		final EntityEntry entry = event.getEntityEntry();
-		final EntityPersister persister = entry.getPersister();
-		final Serializable id = entry.getId();
-		final Object[] loadedState = entry.getLoadedState();
-
-		int[] dirtyProperties = session.getInterceptor().findDirty( 
-				entity, 
-				id, 
-				values, 
-				loadedState, 
-				persister.getPropertyNames(), 
-				persister.getPropertyTypes() 
-			);
-		
-		event.setDatabaseSnapshot(null);
-
-		final boolean interceptorHandledDirtyCheck;
-		boolean cannotDirtyCheck;
-		
-		if ( dirtyProperties==null ) {
-			// Interceptor returned null, so do the dirtycheck ourself, if possible
-			interceptorHandledDirtyCheck = false;
-			
-			cannotDirtyCheck = loadedState==null; // object loaded by update()
-			if ( !cannotDirtyCheck ) {
-				// dirty check against the usual snapshot of the entity
-				dirtyProperties = persister.findDirty( values, loadedState, entity, session );
-				
-			}
-			else {
-				// dirty check against the database snapshot, if possible/necessary
-				final Object[] databaseSnapshot = getDatabaseSnapshot(session, persister, id);
-				if ( databaseSnapshot != null ) {
-					dirtyProperties = persister.findModified(databaseSnapshot, values, entity, session);
-					cannotDirtyCheck = false;
-					event.setDatabaseSnapshot(databaseSnapshot);
-				}
-			}
-		}
-		else {
-			// the Interceptor handled the dirty checking
-			cannotDirtyCheck = false;
-			interceptorHandledDirtyCheck = true;
-		}
-		
-		event.setDirtyProperties(dirtyProperties);
-		event.setDirtyCheckHandledByInterceptor(interceptorHandledDirtyCheck);
-		event.setDirtyCheckPossible(!cannotDirtyCheck);
-		
-	}
-
-	private Object[] getDatabaseSnapshot(SessionImplementor session, EntityPersister persister, Serializable id) {
-		if ( persister.isSelectBeforeUpdateRequired() ) {
-			Object[] snapshot = session.getPersistenceContext()
-					.getDatabaseSnapshot(id, persister);
-			if (snapshot==null) {
-				//do we even really need this? the update will fail anyway....
-				if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
-					session.getFactory().getStatisticsImplementor()
-							.optimisticFailure( persister.getEntityName() );
-				}
-				throw new StaleObjectStateException( persister.getEntityName(), id );
-			}
-			else {
-				return snapshot;
-			}
-		}
-		else {
-			//TODO: optimize away this lookup for entities w/o unsaved-value="undefined"
-			EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() );
-			return session.getPersistenceContext()
-					.getCachedDatabaseSnapshot( entityKey ); 
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,550 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.action.EntityUpdateAction;
+import org.hibernate.action.DelayedPostInsertIdentifier;
+import org.hibernate.classic.Validatable;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.Nullability;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.FlushEntityEvent;
+import org.hibernate.event.FlushEntityEventListener;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * An event that occurs for each entity instance at flush time
+ *
+ * @author Gavin King
+ */
+public class DefaultFlushEntityEventListener implements FlushEntityEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultFlushEntityEventListener.class);
+
+	/**
+	 * make sure user didn't mangle the id
+	 */
+	public void checkId(Object object, EntityPersister persister, Serializable id, EntityMode entityMode)
+	throws HibernateException {
+
+		if ( id != null && id instanceof DelayedPostInsertIdentifier ) {
+			// this is a situation where the entity id is assigned by a post-insert generator
+			// and was saved outside the transaction forcing it to be delayed
+			return;
+		}
+
+		if ( persister.canExtractIdOutOfEntity() ) {
+
+			Serializable oid = persister.getIdentifier( object, entityMode );
+			if (id==null) {
+				throw new AssertionFailure("null id in " + persister.getEntityName() + " entry (don't flush the Session after an exception occurs)");
+			}
+			if ( !persister.getIdentifierType().isEqual(id, oid, entityMode) ) {
+				throw new HibernateException(
+						"identifier of an instance of " +
+						persister.getEntityName() +
+						" was altered from " + id +
+						" to " + oid
+					);
+			}
+		}
+
+	}
+
+	private void checkNaturalId(
+			EntityPersister persister,
+	        EntityEntry entry,
+	        Object[] current,
+	        Object[] loaded,
+	        EntityMode entityMode,
+	        SessionImplementor session) {
+		if ( persister.hasNaturalIdentifier() && entry.getStatus() != Status.READ_ONLY ) {
+ 			Object[] snapshot = null;			
+			Type[] types = persister.getPropertyTypes();
+			int[] props = persister.getNaturalIdentifierProperties();
+			boolean[] updateable = persister.getPropertyUpdateability();
+			for ( int i=0; i<props.length; i++ ) {
+				int prop = props[i];
+				if ( !updateable[prop] ) {
+ 					Object loadedVal;
+ 					if ( loaded == null ) {
+ 						if ( snapshot == null) {
+ 							snapshot = session.getPersistenceContext().getNaturalIdSnapshot( entry.getId(), persister );
+ 						}
+ 						loadedVal = snapshot[i];
+ 					} else {
+ 						loadedVal = loaded[prop];
+ 					}
+ 					if ( !types[prop].isEqual( current[prop], loadedVal, entityMode ) ) {						
+						throw new HibernateException(
+								"immutable natural identifier of an instance of " +
+								persister.getEntityName() +
+								" was altered"
+							);
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Flushes a single entity's state to the database, by scheduling
+	 * an update action, if necessary
+	 */
+	public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
+		final Object entity = event.getEntity();
+		final EntityEntry entry = event.getEntityEntry();
+		final EventSource session = event.getSession();
+		final EntityPersister persister = entry.getPersister();
+		final Status status = entry.getStatus();
+		final EntityMode entityMode = session.getEntityMode();
+		final Type[] types = persister.getPropertyTypes();
+
+		final boolean mightBeDirty = entry.requiresDirtyCheck(entity);
+
+		final Object[] values = getValues( entity, entry, entityMode, mightBeDirty, session );
+
+		event.setPropertyValues(values);
+
+		//TODO: avoid this for non-new instances where mightBeDirty==false
+		boolean substitute = wrapCollections( session, persister, types, values);
+
+		if ( isUpdateNecessary( event, mightBeDirty ) ) {
+			substitute = scheduleUpdate( event ) || substitute;
+		}
+
+		if ( status != Status.DELETED ) {
+			// now update the object .. has to be outside the main if block above (because of collections)
+			if (substitute) persister.setPropertyValues( entity, values, entityMode );
+
+			// Search for collections by reachability, updating their role.
+			// We don't want to touch collections reachable from a deleted object
+			if ( persister.hasCollections() ) {
+				new FlushVisitor(session, entity).processEntityPropertyValues(values, types);
+			}
+		}
+
+	}
+
+	private Object[] getValues(
+			Object entity,
+			EntityEntry entry,
+			EntityMode entityMode,
+			boolean mightBeDirty,
+	        SessionImplementor session
+	) {
+		final Object[] loadedState = entry.getLoadedState();
+		final Status status = entry.getStatus();
+		final EntityPersister persister = entry.getPersister();
+
+		final Object[] values;
+		if ( status == Status.DELETED ) {
+			//grab its state saved at deletion
+			values = entry.getDeletedState();
+		}
+		else if ( !mightBeDirty && loadedState!=null ) {
+			values = loadedState;
+		}
+		else {
+			checkId( entity, persister, entry.getId(), entityMode );
+
+			// grab its current state
+			values = persister.getPropertyValues( entity, entityMode );
+
+			checkNaturalId( persister, entry, values, loadedState, entityMode, session );
+		}
+		return values;
+	}
+
+	private boolean wrapCollections(
+			EventSource session,
+			EntityPersister persister,
+			Type[] types,
+			Object[] values
+	) {
+		if ( persister.hasCollections() ) {
+
+			// wrap up any new collections directly referenced by the object
+			// or its components
+
+			// NOTE: we need to do the wrap here even if its not "dirty",
+			// because collections need wrapping but changes to _them_
+			// don't dirty the container. Also, for versioned data, we
+			// need to wrap before calling searchForDirtyCollections
+
+			WrapVisitor visitor = new WrapVisitor(session);
+			// substitutes into values by side-effect
+			visitor.processEntityPropertyValues(values, types);
+			return visitor.isSubstitutionRequired();
+		}
+		else {
+			return false;
+		}
+	}
+
+	private boolean isUpdateNecessary(final FlushEntityEvent event, final boolean mightBeDirty) {
+		final Status status = event.getEntityEntry().getStatus();
+		if ( mightBeDirty || status==Status.DELETED ) {
+			// compare to cached state (ignoring collections unless versioned)
+			dirtyCheck(event);
+			if ( isUpdateNecessary(event) ) {
+				return true;
+			}
+			else {
+				FieldInterceptionHelper.clearDirty( event.getEntity() );
+				return false;
+			}
+		}
+		else {
+			return hasDirtyCollections( event, event.getEntityEntry().getPersister(), status );
+		}
+	}
+
+	private boolean scheduleUpdate(final FlushEntityEvent event) {
+		
+		final EntityEntry entry = event.getEntityEntry();
+		final EventSource session = event.getSession();
+		final Object entity = event.getEntity();
+		final Status status = entry.getStatus();
+		final EntityMode entityMode = session.getEntityMode();
+		final EntityPersister persister = entry.getPersister();
+		final Object[] values = event.getPropertyValues();
+		
+		if ( log.isTraceEnabled() ) {
+			if ( status == Status.DELETED ) {
+				log.trace(
+						"Updating deleted entity: " +
+						MessageHelper.infoString( persister, entry.getId(), session.getFactory() )
+					);
+			}
+			else {
+				log.trace(
+						"Updating entity: " +
+						MessageHelper.infoString( persister, entry.getId(), session.getFactory()  )
+					);
+			}
+		}
+
+		final boolean intercepted;
+		if ( !entry.isBeingReplicated() ) {
+			// give the Interceptor a chance to process property values, if the properties
+			// were modified by the Interceptor, we need to set them back to the object
+			intercepted = handleInterception( event );
+		}
+		else {
+			intercepted = false;
+		}
+
+		validate( entity, persister, status, entityMode );
+
+		// increment the version number (if necessary)
+		final Object nextVersion = getNextVersion(event);
+
+		// if it was dirtied by a collection only
+		int[] dirtyProperties = event.getDirtyProperties();
+		if ( event.isDirtyCheckPossible() && dirtyProperties == null ) {
+			if ( ! intercepted && !event.hasDirtyCollection() ) {
+				throw new AssertionFailure( "dirty, but no dirty properties" );
+			}
+			dirtyProperties = ArrayHelper.EMPTY_INT_ARRAY;
+		}
+
+		// check nullability but do not perform command execute
+		// we'll use scheduled updates for that.
+		new Nullability(session).checkNullability( values, persister, true );
+
+		// schedule the update
+		// note that we intentionally do _not_ pass in currentPersistentState!
+		session.getActionQueue().addAction(
+				new EntityUpdateAction(
+						entry.getId(),
+						values,
+						dirtyProperties,
+						event.hasDirtyCollection(),
+						entry.getLoadedState(),
+						entry.getVersion(),
+						nextVersion,
+						entity,
+						entry.getRowId(),
+						persister,
+						session
+					)
+			);
+		
+		return intercepted;
+	}
+
+	protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) {
+		// validate() instances of Validatable
+		if ( status == Status.MANAGED && persister.implementsValidatable( entityMode ) ) {
+			( (Validatable) entity ).validate();
+		}
+	}
+	
+	protected boolean handleInterception(FlushEntityEvent event) {
+		SessionImplementor session = event.getSession();
+		EntityEntry entry = event.getEntityEntry();
+		EntityPersister persister = entry.getPersister();
+		Object entity = event.getEntity();
+		
+		//give the Interceptor a chance to modify property values
+		final Object[] values = event.getPropertyValues();
+		final boolean intercepted = invokeInterceptor( session, entity, entry, values, persister );
+
+		//now we might need to recalculate the dirtyProperties array
+		if ( intercepted && event.isDirtyCheckPossible() && !event.isDirtyCheckHandledByInterceptor() ) {
+			int[] dirtyProperties;
+			if ( event.hasDatabaseSnapshot() ) {
+				dirtyProperties = persister.findModified( event.getDatabaseSnapshot(), values, entity, session );
+			}
+			else {
+				dirtyProperties = persister.findDirty( values, entry.getLoadedState(), entity, session );
+			}
+			event.setDirtyProperties(dirtyProperties);
+		}
+		
+		return intercepted;
+	}
+
+	protected boolean invokeInterceptor(
+			SessionImplementor session,
+			Object entity,
+			EntityEntry entry,
+			final Object[] values,
+			EntityPersister persister) {
+		return session.getInterceptor().onFlushDirty(
+				entity,
+				entry.getId(),
+				values,
+				entry.getLoadedState(),
+				persister.getPropertyNames(),
+				persister.getPropertyTypes()
+		);
+	}
+
+	/**
+	 * Convience method to retreive an entities next version value
+	 */
+	private Object getNextVersion(FlushEntityEvent event) throws HibernateException {
+		
+		EntityEntry entry = event.getEntityEntry();
+		EntityPersister persister = entry.getPersister();
+		if ( persister.isVersioned() ) {
+
+			Object[] values = event.getPropertyValues();
+		    
+			if ( entry.isBeingReplicated() ) {
+				return Versioning.getVersion(values, persister);
+			}
+			else {
+				int[] dirtyProperties = event.getDirtyProperties();
+				
+				final boolean isVersionIncrementRequired = isVersionIncrementRequired( 
+						event, 
+						entry, 
+						persister, 
+						dirtyProperties 
+					);
+				
+				final Object nextVersion = isVersionIncrementRequired ?
+						Versioning.increment( entry.getVersion(), persister.getVersionType(), event.getSession() ) :
+						entry.getVersion(); //use the current version
+						
+				Versioning.setVersion(values, nextVersion, persister);
+				
+				return nextVersion;
+			}
+		}
+		else {
+			return null;
+		}
+		
+	}
+
+	private boolean isVersionIncrementRequired(
+			FlushEntityEvent event, 
+			EntityEntry entry, 
+			EntityPersister persister, 
+			int[] dirtyProperties
+	) {
+		final boolean isVersionIncrementRequired = entry.getStatus()!=Status.DELETED && ( 
+				dirtyProperties==null || 
+				Versioning.isVersionIncrementRequired( 
+						dirtyProperties, 
+						event.hasDirtyCollection(),
+						persister.getPropertyVersionability()
+					) 
+			);
+		return isVersionIncrementRequired;
+	}
+
+	/**
+	 * Performs all necessary checking to determine if an entity needs an SQL update
+	 * to synchronize its state to the database. Modifies the event by side-effect!
+	 * Note: this method is quite slow, avoid calling if possible!
+	 */
+	protected final boolean isUpdateNecessary(FlushEntityEvent event) throws HibernateException {
+
+		EntityPersister persister = event.getEntityEntry().getPersister();
+		Status status = event.getEntityEntry().getStatus();
+		
+		if ( !event.isDirtyCheckPossible() ) {
+			return true;
+		}
+		else {
+			
+			int[] dirtyProperties = event.getDirtyProperties();
+			if ( dirtyProperties!=null && dirtyProperties.length!=0 ) {
+				return true; //TODO: suck into event class
+			}
+			else {
+				return hasDirtyCollections( event, persister, status );
+			}
+			
+		}
+	}
+
+	private boolean hasDirtyCollections(FlushEntityEvent event, EntityPersister persister, Status status) {
+		if ( isCollectionDirtyCheckNecessary(persister, status) ) {
+			DirtyCollectionSearchVisitor visitor = new DirtyCollectionSearchVisitor( 
+					event.getSession(),
+					persister.getPropertyVersionability()
+				);
+			visitor.processEntityPropertyValues( event.getPropertyValues(), persister.getPropertyTypes() );
+			boolean hasDirtyCollections = visitor.wasDirtyCollectionFound();
+			event.setHasDirtyCollection(hasDirtyCollections);
+			return hasDirtyCollections;
+		}
+		else {
+			return false;
+		}
+	}
+
+	private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
+		return status==Status.MANAGED && 
+				persister.isVersioned() && 
+				persister.hasCollections();
+	}
+	
+	/**
+	 * Perform a dirty check, and attach the results to the event
+	 */
+	protected void dirtyCheck(FlushEntityEvent event) throws HibernateException {
+		
+		final Object entity = event.getEntity();
+		final Object[] values = event.getPropertyValues();
+		final SessionImplementor session = event.getSession();
+		final EntityEntry entry = event.getEntityEntry();
+		final EntityPersister persister = entry.getPersister();
+		final Serializable id = entry.getId();
+		final Object[] loadedState = entry.getLoadedState();
+
+		int[] dirtyProperties = session.getInterceptor().findDirty( 
+				entity, 
+				id, 
+				values, 
+				loadedState, 
+				persister.getPropertyNames(), 
+				persister.getPropertyTypes() 
+			);
+		
+		event.setDatabaseSnapshot(null);
+
+		final boolean interceptorHandledDirtyCheck;
+		boolean cannotDirtyCheck;
+		
+		if ( dirtyProperties==null ) {
+			// Interceptor returned null, so do the dirtycheck ourself, if possible
+			interceptorHandledDirtyCheck = false;
+			
+			cannotDirtyCheck = loadedState==null; // object loaded by update()
+			if ( !cannotDirtyCheck ) {
+				// dirty check against the usual snapshot of the entity
+				dirtyProperties = persister.findDirty( values, loadedState, entity, session );
+				
+			}
+			else {
+				// dirty check against the database snapshot, if possible/necessary
+				final Object[] databaseSnapshot = getDatabaseSnapshot(session, persister, id);
+				if ( databaseSnapshot != null ) {
+					dirtyProperties = persister.findModified(databaseSnapshot, values, entity, session);
+					cannotDirtyCheck = false;
+					event.setDatabaseSnapshot(databaseSnapshot);
+				}
+			}
+		}
+		else {
+			// the Interceptor handled the dirty checking
+			cannotDirtyCheck = false;
+			interceptorHandledDirtyCheck = true;
+		}
+		
+		event.setDirtyProperties(dirtyProperties);
+		event.setDirtyCheckHandledByInterceptor(interceptorHandledDirtyCheck);
+		event.setDirtyCheckPossible(!cannotDirtyCheck);
+		
+	}
+
+	private Object[] getDatabaseSnapshot(SessionImplementor session, EntityPersister persister, Serializable id) {
+		if ( persister.isSelectBeforeUpdateRequired() ) {
+			Object[] snapshot = session.getPersistenceContext()
+					.getDatabaseSnapshot(id, persister);
+			if (snapshot==null) {
+				//do we even really need this? the update will fail anyway....
+				if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
+					session.getFactory().getStatisticsImplementor()
+							.optimisticFailure( persister.getEntityName() );
+				}
+				throw new StaleObjectStateException( persister.getEntityName(), id );
+			}
+			else {
+				return snapshot;
+			}
+		}
+		else {
+			//TODO: optimize away this lookup for entities w/o unsaved-value="undefined"
+			EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() );
+			return session.getPersistenceContext()
+					.getCachedDatabaseSnapshot( entityKey ); 
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-//$Id: DefaultFlushEventListener.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.FlushEvent;
-import org.hibernate.event.FlushEventListener;
-
-/**
- * Defines the default flush event listeners used by hibernate for 
- * flushing session state in response to generated flush events.
- *
- * @author Steve Ebersole
- */
-public class DefaultFlushEventListener extends AbstractFlushingEventListener implements FlushEventListener {
-
-	/** Handle the given flush event.
-	 *
-	 * @param event The flush event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onFlush(FlushEvent event) throws HibernateException {
-		final EventSource source = event.getSession();
-		if ( source.getPersistenceContext().hasNonReadOnlyEntities() ) {
-			
-			flushEverythingToExecutions(event);
-			performExecutions(source);
-			postFlush(source);
-		
-			if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
-				source.getFactory().getStatisticsImplementor().flush();
-			}
-			
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.FlushEvent;
+import org.hibernate.event.FlushEventListener;
+
+/**
+ * Defines the default flush event listeners used by hibernate for 
+ * flushing session state in response to generated flush events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultFlushEventListener extends AbstractFlushingEventListener implements FlushEventListener {
+
+	/** Handle the given flush event.
+	 *
+	 * @param event The flush event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onFlush(FlushEvent event) throws HibernateException {
+		final EventSource source = event.getSession();
+		if ( source.getPersistenceContext().hasNonReadOnlyEntities() ) {
+			
+			flushEverythingToExecutions(event);
+			performExecutions(source);
+			postFlush(source);
+		
+			if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
+				source.getFactory().getStatisticsImplementor().flush();
+			}
+			
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,150 +0,0 @@
-//$Id: DefaultInitializeCollectionEventListener.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.entry.CollectionCacheEntry;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.event.InitializeCollectionEvent;
-import org.hibernate.event.InitializeCollectionEventListener;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-
-/**
- * @author Gavin King
- */
-public class DefaultInitializeCollectionEventListener implements InitializeCollectionEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultInitializeCollectionEventListener.class);
-
-	/**
-	 * called by a collection that wants to initialize itself
-	 */
-	public void onInitializeCollection(InitializeCollectionEvent event)
-	throws HibernateException {
-
-		PersistentCollection collection = event.getCollection();
-		SessionImplementor source = event.getSession();
-
-		CollectionEntry ce = source.getPersistenceContext().getCollectionEntry(collection);
-		if (ce==null) throw new HibernateException("collection was evicted");
-		if ( !collection.wasInitialized() ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"initializing collection " +
-						MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), source.getFactory() )
-					);
-			}
-
-			log.trace("checking second-level cache");
-			final boolean foundInCache = initializeCollectionFromCache(
-					ce.getLoadedKey(),
-					ce.getLoadedPersister(),
-					collection,
-					source
-				);
-
-			if (foundInCache) {
-				log.trace("collection initialized from cache");
-			}
-			else {
-				log.trace("collection not cached");
-				ce.getLoadedPersister().initialize( ce.getLoadedKey(), source );
-				log.trace("collection initialized");
-
-				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
-					source.getFactory().getStatisticsImplementor().fetchCollection( 
-							ce.getLoadedPersister().getRole() 
-						);
-				}
-			}
-		}
-	}
-
-	/**
-	 * Try to initialize a collection from the cache
-	 *
-	 * @param id The id of the collection of initialize
-	 * @param persister The collection persister
-	 * @param collection The collection to initialize
-	 * @param source The originating session
-	 * @return true if we were able to initialize the collection from the cache;
-	 * false otherwise.
-	 */
-	private boolean initializeCollectionFromCache(
-			Serializable id,
-			CollectionPersister persister,
-			PersistentCollection collection,
-			SessionImplementor source) {
-
-		if ( !source.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( source ) ) {
-			log.trace( "disregarding cached version (if any) of collection due to enabled filters ");
-			return false;
-		}
-
-		final boolean useCache = persister.hasCache() && 
-				source.getCacheMode().isGetEnabled();
-
-		if ( !useCache ) {
-			return false;
-		}
-		else {
-			
-			final SessionFactoryImplementor factory = source.getFactory();
-
-			final CacheKey ck = new CacheKey( 
-					id, 
-					persister.getKeyType(), 
-					persister.getRole(), 
-					source.getEntityMode(), 
-					source.getFactory() 
-				);
-			Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
-			
-			if ( factory.getStatistics().isStatisticsEnabled() ) {
-				if ( ce == null ) {
-					factory.getStatisticsImplementor().secondLevelCacheMiss(
-							persister.getCacheAccessStrategy().getRegion().getName()
-					);
-				}
-				else {
-					factory.getStatisticsImplementor().secondLevelCacheHit(
-							persister.getCacheAccessStrategy().getRegion().getName()
-					);
-				}
-
-				
-			}
-			
-			if (ce==null) {
-				return false;
-			}
-			else {
-
-				CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure()
-						.destructure(ce, factory);
-			
-				final PersistenceContext persistenceContext = source.getPersistenceContext();
-				cacheEntry.assemble(
-						collection, 
-						persister,  
-						persistenceContext.getCollectionOwner(id, persister)
-					);
-				persistenceContext.getCollectionEntry(collection).postInitialize(collection);
-				//addInitializedCollection(collection, persister, id);
-				return true;
-			}
-			
-		}
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultInitializeCollectionEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,173 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.entry.CollectionCacheEntry;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.event.InitializeCollectionEvent;
+import org.hibernate.event.InitializeCollectionEventListener;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+
+/**
+ * @author Gavin King
+ */
+public class DefaultInitializeCollectionEventListener implements InitializeCollectionEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultInitializeCollectionEventListener.class);
+
+	/**
+	 * called by a collection that wants to initialize itself
+	 */
+	public void onInitializeCollection(InitializeCollectionEvent event)
+	throws HibernateException {
+
+		PersistentCollection collection = event.getCollection();
+		SessionImplementor source = event.getSession();
+
+		CollectionEntry ce = source.getPersistenceContext().getCollectionEntry(collection);
+		if (ce==null) throw new HibernateException("collection was evicted");
+		if ( !collection.wasInitialized() ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"initializing collection " +
+						MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), source.getFactory() )
+					);
+			}
+
+			log.trace("checking second-level cache");
+			final boolean foundInCache = initializeCollectionFromCache(
+					ce.getLoadedKey(),
+					ce.getLoadedPersister(),
+					collection,
+					source
+				);
+
+			if (foundInCache) {
+				log.trace("collection initialized from cache");
+			}
+			else {
+				log.trace("collection not cached");
+				ce.getLoadedPersister().initialize( ce.getLoadedKey(), source );
+				log.trace("collection initialized");
+
+				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
+					source.getFactory().getStatisticsImplementor().fetchCollection( 
+							ce.getLoadedPersister().getRole() 
+						);
+				}
+			}
+		}
+	}
+
+	/**
+	 * Try to initialize a collection from the cache
+	 *
+	 * @param id The id of the collection of initialize
+	 * @param persister The collection persister
+	 * @param collection The collection to initialize
+	 * @param source The originating session
+	 * @return true if we were able to initialize the collection from the cache;
+	 * false otherwise.
+	 */
+	private boolean initializeCollectionFromCache(
+			Serializable id,
+			CollectionPersister persister,
+			PersistentCollection collection,
+			SessionImplementor source) {
+
+		if ( !source.getEnabledFilters().isEmpty() && persister.isAffectedByEnabledFilters( source ) ) {
+			log.trace( "disregarding cached version (if any) of collection due to enabled filters ");
+			return false;
+		}
+
+		final boolean useCache = persister.hasCache() && 
+				source.getCacheMode().isGetEnabled();
+
+		if ( !useCache ) {
+			return false;
+		}
+		else {
+			
+			final SessionFactoryImplementor factory = source.getFactory();
+
+			final CacheKey ck = new CacheKey( 
+					id, 
+					persister.getKeyType(), 
+					persister.getRole(), 
+					source.getEntityMode(), 
+					source.getFactory() 
+				);
+			Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
+			
+			if ( factory.getStatistics().isStatisticsEnabled() ) {
+				if ( ce == null ) {
+					factory.getStatisticsImplementor().secondLevelCacheMiss(
+							persister.getCacheAccessStrategy().getRegion().getName()
+					);
+				}
+				else {
+					factory.getStatisticsImplementor().secondLevelCacheHit(
+							persister.getCacheAccessStrategy().getRegion().getName()
+					);
+				}
+
+				
+			}
+			
+			if (ce==null) {
+				return false;
+			}
+			else {
+
+				CollectionCacheEntry cacheEntry = (CollectionCacheEntry) persister.getCacheEntryStructure()
+						.destructure(ce, factory);
+			
+				final PersistenceContext persistenceContext = source.getPersistenceContext();
+				cacheEntry.assemble(
+						collection, 
+						persister,  
+						persistenceContext.getCollectionOwner(id, persister)
+					);
+				persistenceContext.getCollectionEntry(collection).postInitialize(collection);
+				//addInitializedCollection(collection, persister, id);
+				return true;
+			}
+			
+		}
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,607 +0,0 @@
-//$Id: DefaultLoadEventListener.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.NonUniqueObjectException;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.TypeMismatchException;
-import org.hibernate.EntityMode;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.access.SoftLock;
-import org.hibernate.cache.entry.CacheEntry;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.TwoPhaseLoad;
-import org.hibernate.engine.Versioning;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.LoadEvent;
-import org.hibernate.event.LoadEventListener;
-import org.hibernate.event.PostLoadEvent;
-import org.hibernate.event.PostLoadEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * Defines the default load event listeners used by hibernate for loading entities
- * in response to generated load events.
- *
- * @author Steve Ebersole
- */
-public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener implements LoadEventListener {
-
-	public static final Object REMOVED_ENTITY_MARKER = new Object();
-	public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object();
-	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultLoadEventListener.class);
-
-
-	/**
-	 * Handle the given load event.
-	 *
-	 * @param event The load event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException {
-
-		final SessionImplementor source = event.getSession();
-
-		EntityPersister persister;
-		if ( event.getInstanceToLoad() != null ) {
-			persister = source.getEntityPersister( null, event.getInstanceToLoad() ); //the load() which takes an entity does not pass an entityName
-			event.setEntityClassName( event.getInstanceToLoad().getClass().getName() );
-		}
-		else {
-			persister = source.getFactory().getEntityPersister( event.getEntityClassName() );
-		}
-
-		if ( persister == null ) {
-			throw new HibernateException(
-					"Unable to locate persister: " +
-					event.getEntityClassName()
-				);
-		}
-
-		if ( persister.getIdentifierType().isComponentType() && EntityMode.DOM4J == event.getSession().getEntityMode() ) {
-			// skip this check for composite-ids relating to dom4j entity-mode;
-			// alternatively, we could add a check to make sure the incoming id value is
-			// an instance of Element...
-		}
-		else {
-			Class idClass = persister.getIdentifierType().getReturnedClass();
-			if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
-				throw new TypeMismatchException(
-						"Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass()
-				);
-			}
-		}
-
-		EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode()  );
-
-		try {
-			if ( loadType.isNakedEntityReturned() ) {
-				//do not return a proxy!
-				//(this option indicates we are initializing a proxy)
-				event.setResult( load(event, persister, keyToLoad, loadType) );
-			}
-			else {
-				//return a proxy if appropriate
-				if ( event.getLockMode() == LockMode.NONE ) {
-					event.setResult( proxyOrLoad(event, persister, keyToLoad, loadType) );
-				}
-				else {
-					event.setResult( lockAndLoad(event, persister, keyToLoad, loadType, source) );
-				}
-			}
-		}
-		catch(HibernateException e) {
-			log.info("Error performing load command", e);
-			throw e;
-		}
-	}
-
-	/**
-	 * Perfoms the load of an entity.
-	 *
-	 * @param event The initiating load request event
-	 * @param persister The persister corresponding to the entity to be loaded
-	 * @param keyToLoad The key of the entity to be loaded
-	 * @param options The defined load options
-	 * @return The loaded entity.
-	 * @throws HibernateException
-	 */
-	protected Object load(
-		final LoadEvent event,
-		final EntityPersister persister,
-		final EntityKey keyToLoad,
-		final LoadEventListener.LoadType options) {
-
-		if ( event.getInstanceToLoad() != null ) {
-			if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) {
-				throw new PersistentObjectException(
-						"attempted to load into an instance that was already associated with the session: " +
-						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
-					);
-			}
-			persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession().getEntityMode() );
-		}
-
-		Object entity = doLoad(event, persister, keyToLoad, options);
-
-		boolean isOptionalInstance = event.getInstanceToLoad() != null;
-
-		if ( !options.isAllowNulls() || isOptionalInstance ) {
-			if ( entity == null ) {
-				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
-			}
-		}
-
-		if ( isOptionalInstance && entity != event.getInstanceToLoad() ) {
-			throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
-		}
-
-		return entity;
-	}
-
-	/**
-	 * Based on configured options, will either return a pre-existing proxy,
-	 * generate a new proxy, or perform an actual load.
-	 *
-	 * @param event The initiating load request event
-	 * @param persister The persister corresponding to the entity to be loaded
-	 * @param keyToLoad The key of the entity to be loaded
-	 * @param options The defined load options
-	 * @return The result of the proxy/load operation.
-	 */
-	protected Object proxyOrLoad(
-		final LoadEvent event,
-		final EntityPersister persister,
-		final EntityKey keyToLoad,
-		final LoadEventListener.LoadType options) {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"loading entity: " +
-					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
-				);
-		}
-
-		if ( !persister.hasProxy() ) {
-			// this class has no proxies (so do a shortcut)
-			return load(event, persister, keyToLoad, options);
-		}
-		else {
-			final PersistenceContext persistenceContext = event.getSession().getPersistenceContext();
-
-			// look for a proxy
-			Object proxy = persistenceContext.getProxy(keyToLoad);
-			if ( proxy != null ) {
-				return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy );
-			}
-			else {
-				if ( options.isAllowProxyCreation() ) {
-					return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
-				}
-				else {
-					// return a newly loaded object
-					return load(event, persister, keyToLoad, options);
-				}
-			}
-
-		}
-	}
-
-	/**
-	 * Given a proxy, initialize it and/or narrow it provided either
-	 * is necessary.
-	 *
-	 * @param event The initiating load request event
-	 * @param persister The persister corresponding to the entity to be loaded
-	 * @param keyToLoad The key of the entity to be loaded
-	 * @param options The defined load options
-	 * @param persistenceContext The originating session
-	 * @param proxy The proxy to narrow
-	 * @return The created/existing proxy
-	 */
-	private Object returnNarrowedProxy(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options,
-			final PersistenceContext persistenceContext,
-			final Object proxy) {
-		log.trace("entity proxy found in session cache");
-		LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
-		if ( li.isUnwrap() ) {
-			return li.getImplementation();
-		}
-		Object impl = null;
-		if ( !options.isAllowProxyCreation() ) {
-			impl = load( event, persister, keyToLoad, options );
-			if ( impl == null ) {
-				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier());
-			}
-		}
-		return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl );
-	}
-
-	/**
-	 * If there is already a corresponding proxy associated with the
-	 * persistence context, return it; otherwise create a proxy, associate it
-	 * with the persistence context, and return the just-created proxy.
-	 *
-	 * @param event The initiating load request event
-	 * @param persister The persister corresponding to the entity to be loaded
-	 * @param keyToLoad The key of the entity to be loaded
-	 * @param options The defined load options
-	 * @param persistenceContext The originating session
-	 * @return The created/existing proxy
-	 */
-	private Object createProxyIfNecessary(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options,
-			final PersistenceContext persistenceContext) {
-		Object existing = persistenceContext.getEntity( keyToLoad );
-		if ( existing != null ) {
-			// return existing object or initialized proxy (unless deleted)
-			log.trace( "entity found in session cache" );
-			if ( options.isCheckDeleted() ) {
-				EntityEntry entry = persistenceContext.getEntry( existing );
-				Status status = entry.getStatus();
-				if ( status == Status.DELETED || status == Status.GONE ) {
-					return null;
-				}
-			}
-			return existing;
-		}
-		else {
-			log.trace( "creating new proxy for entity" );
-			// return new uninitialized proxy
-			Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
-			persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad);
-			persistenceContext.addProxy(keyToLoad, proxy);
-			return proxy;
-		}
-	}
-
-	/**
-	 * If the class to be loaded has been configured with a cache, then lock
-	 * given id in that cache and then perform the load.
-	 *
-	 * @param event The initiating load request event
-	 * @param persister The persister corresponding to the entity to be loaded
-	 * @param keyToLoad The key of the entity to be loaded
-	 * @param options The defined load options
-	 * @param source The originating session
-	 * @return The loaded entity
-	 * @throws HibernateException
-	 */
-	protected Object lockAndLoad(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options,
-			final SessionImplementor source) {
-		SoftLock lock = null;
-		final CacheKey ck;
-		if ( persister.hasCache() ) {
-			ck = new CacheKey(
-					event.getEntityId(),
-					persister.getIdentifierType(),
-					persister.getRootEntityName(),
-					source.getEntityMode(),
-					source.getFactory()
-			);
-			lock = persister.getCacheAccessStrategy().lockItem( ck, null );
-		}
-		else {
-			ck = null;
-		}
-
-		Object entity;
-		try {
-			entity = load(event, persister, keyToLoad, options);
-		}
-		finally {
-			if ( persister.hasCache() ) {
-				persister.getCacheAccessStrategy().unlockItem( ck, lock );
-			}
-		}
-
-		return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
-	}
-
-
-	/**
-	 * Coordinates the efforts to load a given entity.  First, an attempt is
-	 * made to load the entity from the session-level cache.  If not found there,
-	 * an attempt is made to locate it in second-level cache.  Lastly, an
-	 * attempt is made to load it directly from the datasource.
-	 *
-	 * @param event The load event
-	 * @param persister The persister for the entity being requested for load
-	 * @param keyToLoad The EntityKey representing the entity to be loaded.
-	 * @param options The load options.
-	 * @return The loaded entity, or null.
-	 */
-	protected Object doLoad(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options) {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"attempting to resolve: " +
-					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
-				);
-		}
-
-		Object entity = loadFromSessionCache( event, keyToLoad, options );
-		if ( entity == REMOVED_ENTITY_MARKER ) {
-			log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
-			return null;
-		}
-		if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) {
-			log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" );
-			return null;
-		}
-		if ( entity != null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"resolved object in session cache: " +
-						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory()  )
-					);
-			}
-			return entity;
-		}
-
-		entity = loadFromSecondLevelCache(event, persister, options);
-		if ( entity != null ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"resolved object in second-level cache: " +
-						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
-					);
-			}
-			return entity;
-		}
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"object not resolved in any cache: " +
-					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
-				);
-		}
-
-		return loadFromDatasource(event, persister, keyToLoad, options);
-	}
-
-	/**
-	 * Performs the process of loading an entity from the configured
-	 * underlying datasource.
-	 *
-	 * @param event The load event
-	 * @param persister The persister for the entity being requested for load
-	 * @param keyToLoad The EntityKey representing the entity to be loaded.
-	 * @param options The load options.
-	 * @return The object loaded from the datasource, or null if not found.
-	 */
-	protected Object loadFromDatasource(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options) {
-		final SessionImplementor source = event.getSession();
-		Object entity = persister.load(
-				event.getEntityId(),
-				event.getInstanceToLoad(),
-				event.getLockMode(),
-				source
-		);
-
-		if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) {
-			source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() );
-		}
-
-		return entity;
-	}
-
-	/**
-	 * Attempts to locate the entity in the session-level cache.
-	 * <p/>
-	 * If allowed to return nulls, then if the entity happens to be found in
-	 * the session cache, we check the entity type for proper handling
-	 * of entity hierarchies.
-	 * <p/>
-	 * If checkDeleted was set to true, then if the entity is found in the
-	 * session-level cache, it's current status within the session cache
-	 * is checked to see if it has previously been scheduled for deletion.
-	 *
-	 * @param event The load event
-	 * @param keyToLoad The EntityKey representing the entity to be loaded.
-	 * @param options The load options.
-	 * @return The entity from the session-level cache, or null.
-	 * @throws HibernateException Generally indicates problems applying a lock-mode.
-	 */
-	protected Object loadFromSessionCache(
-			final LoadEvent event,
-			final EntityKey keyToLoad,
-			final LoadEventListener.LoadType options) throws HibernateException {
-
-		SessionImplementor session = event.getSession();
-		Object old = session.getEntityUsingInterceptor( keyToLoad );
-
-		if ( old != null ) {
-			// this object was already loaded
-			EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
-			if ( options.isCheckDeleted() ) {
-				Status status = oldEntry.getStatus();
-				if ( status == Status.DELETED || status == Status.GONE ) {
-					return REMOVED_ENTITY_MARKER;
-				}
-			}
-			if ( options.isAllowNulls() ) {
-				EntityPersister persister = event.getSession().getFactory().getEntityPersister( event.getEntityClassName() );
-				if ( ! persister.isInstance( old, event.getSession().getEntityMode() ) ) {
-					return INCONSISTENT_RTN_CLASS_MARKER;
-				}
-			}
-			upgradeLock( old, oldEntry, event.getLockMode(), session );
-		}
-
-		return old;
-	}
-
-	/**
-	 * Attempts to load the entity from the second-level cache.
-	 *
-	 * @param event The load event
-	 * @param persister The persister for the entity being requested for load
-	 * @param options The load options.
-	 * @return The entity from the second-level cache, or null.
-	 */
-	protected Object loadFromSecondLevelCache(
-			final LoadEvent event,
-			final EntityPersister persister,
-			final LoadEventListener.LoadType options) {
-
-		final SessionImplementor source = event.getSession();
-
-		final boolean useCache = persister.hasCache()
-				&& source.getCacheMode().isGetEnabled()
-				&& event.getLockMode().lessThan(LockMode.READ);
-
-		if ( useCache ) {
-
-			final SessionFactoryImplementor factory = source.getFactory();
-
-			final CacheKey ck = new CacheKey(
-					event.getEntityId(),
-					persister.getIdentifierType(),
-					persister.getRootEntityName(),
-					source.getEntityMode(),
-					source.getFactory()
-			);
-			Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
-			if ( factory.getStatistics().isStatisticsEnabled() ) {
-				if ( ce == null ) {
-					factory.getStatisticsImplementor().secondLevelCacheMiss(
-							persister.getCacheAccessStrategy().getRegion().getName()
-					);
-				}
-				else {
-					factory.getStatisticsImplementor().secondLevelCacheHit(
-							persister.getCacheAccessStrategy().getRegion().getName()
-					);
-				}
-			}
-
-			if ( ce != null ) {
-				CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory );
-
-				// Entity was found in second-level cache...
-				return assembleCacheEntry(
-						entry,
-						event.getEntityId(),
-						persister,
-						event
-				);
-			}
-		}
-
-		return null;
-	}
-
-	private Object assembleCacheEntry(
-			final CacheEntry entry,
-			final Serializable id,
-			final EntityPersister persister,
-			final LoadEvent event) throws HibernateException {
-
-		final Object optionalObject = event.getInstanceToLoad();
-		final EventSource session = event.getSession();
-		final SessionFactoryImplementor factory = session.getFactory();
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"assembling entity from second-level cache: " +
-					MessageHelper.infoString( persister, id, factory )
-				);
-		}
-
-		EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() );
-		Object result = optionalObject == null ?
-				session.instantiate( subclassPersister, id ) : optionalObject;
-
-		// make it circular-reference safe
-		TwoPhaseLoad.addUninitializedCachedEntity(
-				new EntityKey( id, subclassPersister, session.getEntityMode() ),
-				result,
-				subclassPersister,
-				LockMode.NONE,
-				entry.areLazyPropertiesUnfetched(),
-				entry.getVersion(),
-				session
-			);
-
-		Type[] types = subclassPersister.getPropertyTypes();
-		Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect
-		TypeFactory.deepCopy(
-				values,
-				types,
-				subclassPersister.getPropertyUpdateability(),
-				values,
-				session
-			);
-
-		Object version = Versioning.getVersion( values, subclassPersister );
-		if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version );
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		persistenceContext.addEntry(
-				result,
-				Status.MANAGED,
-				values,
-				null,
-				id,
-				version,
-				LockMode.NONE,
-				true,
-				subclassPersister,
-				false,
-				entry.areLazyPropertiesUnfetched()
-			);
-		subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
-		persistenceContext.initializeNonLazyCollections();
-		// upgrade the lock if necessary:
-		//lock(result, lockMode);
-
-		//PostLoad is needed for EJB3
-		//TODO: reuse the PostLoadEvent...
-		PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result)
-				.setId(id).setPersister(persister);
-		PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
-		for ( int i = 0; i < listeners.length; i++ ) {
-			listeners[i].onPostLoad(postLoadEvent);
-		}
-
-		return result;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,630 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.NonUniqueObjectException;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.TypeMismatchException;
+import org.hibernate.EntityMode;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.access.SoftLock;
+import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.TwoPhaseLoad;
+import org.hibernate.engine.Versioning;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.LoadEvent;
+import org.hibernate.event.LoadEventListener;
+import org.hibernate.event.PostLoadEvent;
+import org.hibernate.event.PostLoadEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * Defines the default load event listeners used by hibernate for loading entities
+ * in response to generated load events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener implements LoadEventListener {
+
+	public static final Object REMOVED_ENTITY_MARKER = new Object();
+	public static final Object INCONSISTENT_RTN_CLASS_MARKER = new Object();
+	public static final LockMode DEFAULT_LOCK_MODE = LockMode.NONE;
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultLoadEventListener.class);
+
+
+	/**
+	 * Handle the given load event.
+	 *
+	 * @param event The load event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onLoad(LoadEvent event, LoadEventListener.LoadType loadType) throws HibernateException {
+
+		final SessionImplementor source = event.getSession();
+
+		EntityPersister persister;
+		if ( event.getInstanceToLoad() != null ) {
+			persister = source.getEntityPersister( null, event.getInstanceToLoad() ); //the load() which takes an entity does not pass an entityName
+			event.setEntityClassName( event.getInstanceToLoad().getClass().getName() );
+		}
+		else {
+			persister = source.getFactory().getEntityPersister( event.getEntityClassName() );
+		}
+
+		if ( persister == null ) {
+			throw new HibernateException(
+					"Unable to locate persister: " +
+					event.getEntityClassName()
+				);
+		}
+
+		if ( persister.getIdentifierType().isComponentType() && EntityMode.DOM4J == event.getSession().getEntityMode() ) {
+			// skip this check for composite-ids relating to dom4j entity-mode;
+			// alternatively, we could add a check to make sure the incoming id value is
+			// an instance of Element...
+		}
+		else {
+			Class idClass = persister.getIdentifierType().getReturnedClass();
+			if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
+				throw new TypeMismatchException(
+						"Provided id of the wrong type. Expected: " + idClass + ", got " + event.getEntityId().getClass()
+				);
+			}
+		}
+
+		EntityKey keyToLoad = new EntityKey( event.getEntityId(), persister, source.getEntityMode()  );
+
+		try {
+			if ( loadType.isNakedEntityReturned() ) {
+				//do not return a proxy!
+				//(this option indicates we are initializing a proxy)
+				event.setResult( load(event, persister, keyToLoad, loadType) );
+			}
+			else {
+				//return a proxy if appropriate
+				if ( event.getLockMode() == LockMode.NONE ) {
+					event.setResult( proxyOrLoad(event, persister, keyToLoad, loadType) );
+				}
+				else {
+					event.setResult( lockAndLoad(event, persister, keyToLoad, loadType, source) );
+				}
+			}
+		}
+		catch(HibernateException e) {
+			log.info("Error performing load command", e);
+			throw e;
+		}
+	}
+
+	/**
+	 * Perfoms the load of an entity.
+	 *
+	 * @param event The initiating load request event
+	 * @param persister The persister corresponding to the entity to be loaded
+	 * @param keyToLoad The key of the entity to be loaded
+	 * @param options The defined load options
+	 * @return The loaded entity.
+	 * @throws HibernateException
+	 */
+	protected Object load(
+		final LoadEvent event,
+		final EntityPersister persister,
+		final EntityKey keyToLoad,
+		final LoadEventListener.LoadType options) {
+
+		if ( event.getInstanceToLoad() != null ) {
+			if ( event.getSession().getPersistenceContext().getEntry( event.getInstanceToLoad() ) != null ) {
+				throw new PersistentObjectException(
+						"attempted to load into an instance that was already associated with the session: " +
+						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
+					);
+			}
+			persister.setIdentifier( event.getInstanceToLoad(), event.getEntityId(), event.getSession().getEntityMode() );
+		}
+
+		Object entity = doLoad(event, persister, keyToLoad, options);
+
+		boolean isOptionalInstance = event.getInstanceToLoad() != null;
+
+		if ( !options.isAllowNulls() || isOptionalInstance ) {
+			if ( entity == null ) {
+				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( event.getEntityClassName(), event.getEntityId() );
+			}
+		}
+
+		if ( isOptionalInstance && entity != event.getInstanceToLoad() ) {
+			throw new NonUniqueObjectException( event.getEntityId(), event.getEntityClassName() );
+		}
+
+		return entity;
+	}
+
+	/**
+	 * Based on configured options, will either return a pre-existing proxy,
+	 * generate a new proxy, or perform an actual load.
+	 *
+	 * @param event The initiating load request event
+	 * @param persister The persister corresponding to the entity to be loaded
+	 * @param keyToLoad The key of the entity to be loaded
+	 * @param options The defined load options
+	 * @return The result of the proxy/load operation.
+	 */
+	protected Object proxyOrLoad(
+		final LoadEvent event,
+		final EntityPersister persister,
+		final EntityKey keyToLoad,
+		final LoadEventListener.LoadType options) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"loading entity: " +
+					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
+				);
+		}
+
+		if ( !persister.hasProxy() ) {
+			// this class has no proxies (so do a shortcut)
+			return load(event, persister, keyToLoad, options);
+		}
+		else {
+			final PersistenceContext persistenceContext = event.getSession().getPersistenceContext();
+
+			// look for a proxy
+			Object proxy = persistenceContext.getProxy(keyToLoad);
+			if ( proxy != null ) {
+				return returnNarrowedProxy( event, persister, keyToLoad, options, persistenceContext, proxy );
+			}
+			else {
+				if ( options.isAllowProxyCreation() ) {
+					return createProxyIfNecessary( event, persister, keyToLoad, options, persistenceContext );
+				}
+				else {
+					// return a newly loaded object
+					return load(event, persister, keyToLoad, options);
+				}
+			}
+
+		}
+	}
+
+	/**
+	 * Given a proxy, initialize it and/or narrow it provided either
+	 * is necessary.
+	 *
+	 * @param event The initiating load request event
+	 * @param persister The persister corresponding to the entity to be loaded
+	 * @param keyToLoad The key of the entity to be loaded
+	 * @param options The defined load options
+	 * @param persistenceContext The originating session
+	 * @param proxy The proxy to narrow
+	 * @return The created/existing proxy
+	 */
+	private Object returnNarrowedProxy(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options,
+			final PersistenceContext persistenceContext,
+			final Object proxy) {
+		log.trace("entity proxy found in session cache");
+		LazyInitializer li = ( (HibernateProxy) proxy ).getHibernateLazyInitializer();
+		if ( li.isUnwrap() ) {
+			return li.getImplementation();
+		}
+		Object impl = null;
+		if ( !options.isAllowProxyCreation() ) {
+			impl = load( event, persister, keyToLoad, options );
+			if ( impl == null ) {
+				event.getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( persister.getEntityName(), keyToLoad.getIdentifier());
+			}
+		}
+		return persistenceContext.narrowProxy( proxy, persister, keyToLoad, impl );
+	}
+
+	/**
+	 * If there is already a corresponding proxy associated with the
+	 * persistence context, return it; otherwise create a proxy, associate it
+	 * with the persistence context, and return the just-created proxy.
+	 *
+	 * @param event The initiating load request event
+	 * @param persister The persister corresponding to the entity to be loaded
+	 * @param keyToLoad The key of the entity to be loaded
+	 * @param options The defined load options
+	 * @param persistenceContext The originating session
+	 * @return The created/existing proxy
+	 */
+	private Object createProxyIfNecessary(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options,
+			final PersistenceContext persistenceContext) {
+		Object existing = persistenceContext.getEntity( keyToLoad );
+		if ( existing != null ) {
+			// return existing object or initialized proxy (unless deleted)
+			log.trace( "entity found in session cache" );
+			if ( options.isCheckDeleted() ) {
+				EntityEntry entry = persistenceContext.getEntry( existing );
+				Status status = entry.getStatus();
+				if ( status == Status.DELETED || status == Status.GONE ) {
+					return null;
+				}
+			}
+			return existing;
+		}
+		else {
+			log.trace( "creating new proxy for entity" );
+			// return new uninitialized proxy
+			Object proxy = persister.createProxy( event.getEntityId(), event.getSession() );
+			persistenceContext.getBatchFetchQueue().addBatchLoadableEntityKey(keyToLoad);
+			persistenceContext.addProxy(keyToLoad, proxy);
+			return proxy;
+		}
+	}
+
+	/**
+	 * If the class to be loaded has been configured with a cache, then lock
+	 * given id in that cache and then perform the load.
+	 *
+	 * @param event The initiating load request event
+	 * @param persister The persister corresponding to the entity to be loaded
+	 * @param keyToLoad The key of the entity to be loaded
+	 * @param options The defined load options
+	 * @param source The originating session
+	 * @return The loaded entity
+	 * @throws HibernateException
+	 */
+	protected Object lockAndLoad(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options,
+			final SessionImplementor source) {
+		SoftLock lock = null;
+		final CacheKey ck;
+		if ( persister.hasCache() ) {
+			ck = new CacheKey(
+					event.getEntityId(),
+					persister.getIdentifierType(),
+					persister.getRootEntityName(),
+					source.getEntityMode(),
+					source.getFactory()
+			);
+			lock = persister.getCacheAccessStrategy().lockItem( ck, null );
+		}
+		else {
+			ck = null;
+		}
+
+		Object entity;
+		try {
+			entity = load(event, persister, keyToLoad, options);
+		}
+		finally {
+			if ( persister.hasCache() ) {
+				persister.getCacheAccessStrategy().unlockItem( ck, lock );
+			}
+		}
+
+		return event.getSession().getPersistenceContext().proxyFor( persister, keyToLoad, entity );
+	}
+
+
+	/**
+	 * Coordinates the efforts to load a given entity.  First, an attempt is
+	 * made to load the entity from the session-level cache.  If not found there,
+	 * an attempt is made to locate it in second-level cache.  Lastly, an
+	 * attempt is made to load it directly from the datasource.
+	 *
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
+	 * @return The loaded entity, or null.
+	 */
+	protected Object doLoad(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"attempting to resolve: " +
+					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
+				);
+		}
+
+		Object entity = loadFromSessionCache( event, keyToLoad, options );
+		if ( entity == REMOVED_ENTITY_MARKER ) {
+			log.debug( "load request found matching entity in context, but it is scheduled for removal; returning null" );
+			return null;
+		}
+		if ( entity == INCONSISTENT_RTN_CLASS_MARKER ) {
+			log.debug( "load request found matching entity in context, but the matched entity was of an inconsistent return type; returning null" );
+			return null;
+		}
+		if ( entity != null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"resolved object in session cache: " +
+						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory()  )
+					);
+			}
+			return entity;
+		}
+
+		entity = loadFromSecondLevelCache(event, persister, options);
+		if ( entity != null ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"resolved object in second-level cache: " +
+						MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
+					);
+			}
+			return entity;
+		}
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"object not resolved in any cache: " +
+					MessageHelper.infoString( persister, event.getEntityId(), event.getSession().getFactory() )
+				);
+		}
+
+		return loadFromDatasource(event, persister, keyToLoad, options);
+	}
+
+	/**
+	 * Performs the process of loading an entity from the configured
+	 * underlying datasource.
+	 *
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
+	 * @return The object loaded from the datasource, or null if not found.
+	 */
+	protected Object loadFromDatasource(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) {
+		final SessionImplementor source = event.getSession();
+		Object entity = persister.load(
+				event.getEntityId(),
+				event.getInstanceToLoad(),
+				event.getLockMode(),
+				source
+		);
+
+		if ( event.isAssociationFetch() && source.getFactory().getStatistics().isStatisticsEnabled() ) {
+			source.getFactory().getStatisticsImplementor().fetchEntity( event.getEntityClassName() );
+		}
+
+		return entity;
+	}
+
+	/**
+	 * Attempts to locate the entity in the session-level cache.
+	 * <p/>
+	 * If allowed to return nulls, then if the entity happens to be found in
+	 * the session cache, we check the entity type for proper handling
+	 * of entity hierarchies.
+	 * <p/>
+	 * If checkDeleted was set to true, then if the entity is found in the
+	 * session-level cache, it's current status within the session cache
+	 * is checked to see if it has previously been scheduled for deletion.
+	 *
+	 * @param event The load event
+	 * @param keyToLoad The EntityKey representing the entity to be loaded.
+	 * @param options The load options.
+	 * @return The entity from the session-level cache, or null.
+	 * @throws HibernateException Generally indicates problems applying a lock-mode.
+	 */
+	protected Object loadFromSessionCache(
+			final LoadEvent event,
+			final EntityKey keyToLoad,
+			final LoadEventListener.LoadType options) throws HibernateException {
+
+		SessionImplementor session = event.getSession();
+		Object old = session.getEntityUsingInterceptor( keyToLoad );
+
+		if ( old != null ) {
+			// this object was already loaded
+			EntityEntry oldEntry = session.getPersistenceContext().getEntry( old );
+			if ( options.isCheckDeleted() ) {
+				Status status = oldEntry.getStatus();
+				if ( status == Status.DELETED || status == Status.GONE ) {
+					return REMOVED_ENTITY_MARKER;
+				}
+			}
+			if ( options.isAllowNulls() ) {
+				EntityPersister persister = event.getSession().getFactory().getEntityPersister( event.getEntityClassName() );
+				if ( ! persister.isInstance( old, event.getSession().getEntityMode() ) ) {
+					return INCONSISTENT_RTN_CLASS_MARKER;
+				}
+			}
+			upgradeLock( old, oldEntry, event.getLockMode(), session );
+		}
+
+		return old;
+	}
+
+	/**
+	 * Attempts to load the entity from the second-level cache.
+	 *
+	 * @param event The load event
+	 * @param persister The persister for the entity being requested for load
+	 * @param options The load options.
+	 * @return The entity from the second-level cache, or null.
+	 */
+	protected Object loadFromSecondLevelCache(
+			final LoadEvent event,
+			final EntityPersister persister,
+			final LoadEventListener.LoadType options) {
+
+		final SessionImplementor source = event.getSession();
+
+		final boolean useCache = persister.hasCache()
+				&& source.getCacheMode().isGetEnabled()
+				&& event.getLockMode().lessThan(LockMode.READ);
+
+		if ( useCache ) {
+
+			final SessionFactoryImplementor factory = source.getFactory();
+
+			final CacheKey ck = new CacheKey(
+					event.getEntityId(),
+					persister.getIdentifierType(),
+					persister.getRootEntityName(),
+					source.getEntityMode(),
+					source.getFactory()
+			);
+			Object ce = persister.getCacheAccessStrategy().get( ck, source.getTimestamp() );
+			if ( factory.getStatistics().isStatisticsEnabled() ) {
+				if ( ce == null ) {
+					factory.getStatisticsImplementor().secondLevelCacheMiss(
+							persister.getCacheAccessStrategy().getRegion().getName()
+					);
+				}
+				else {
+					factory.getStatisticsImplementor().secondLevelCacheHit(
+							persister.getCacheAccessStrategy().getRegion().getName()
+					);
+				}
+			}
+
+			if ( ce != null ) {
+				CacheEntry entry = (CacheEntry) persister.getCacheEntryStructure().destructure( ce, factory );
+
+				// Entity was found in second-level cache...
+				return assembleCacheEntry(
+						entry,
+						event.getEntityId(),
+						persister,
+						event
+				);
+			}
+		}
+
+		return null;
+	}
+
+	private Object assembleCacheEntry(
+			final CacheEntry entry,
+			final Serializable id,
+			final EntityPersister persister,
+			final LoadEvent event) throws HibernateException {
+
+		final Object optionalObject = event.getInstanceToLoad();
+		final EventSource session = event.getSession();
+		final SessionFactoryImplementor factory = session.getFactory();
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"assembling entity from second-level cache: " +
+					MessageHelper.infoString( persister, id, factory )
+				);
+		}
+
+		EntityPersister subclassPersister = factory.getEntityPersister( entry.getSubclass() );
+		Object result = optionalObject == null ?
+				session.instantiate( subclassPersister, id ) : optionalObject;
+
+		// make it circular-reference safe
+		TwoPhaseLoad.addUninitializedCachedEntity(
+				new EntityKey( id, subclassPersister, session.getEntityMode() ),
+				result,
+				subclassPersister,
+				LockMode.NONE,
+				entry.areLazyPropertiesUnfetched(),
+				entry.getVersion(),
+				session
+			);
+
+		Type[] types = subclassPersister.getPropertyTypes();
+		Object[] values = entry.assemble( result, id, subclassPersister, session.getInterceptor(), session ); // intializes result by side-effect
+		TypeFactory.deepCopy(
+				values,
+				types,
+				subclassPersister.getPropertyUpdateability(),
+				values,
+				session
+			);
+
+		Object version = Versioning.getVersion( values, subclassPersister );
+		if ( log.isTraceEnabled() ) log.trace( "Cached Version: " + version );
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		persistenceContext.addEntry(
+				result,
+				Status.MANAGED,
+				values,
+				null,
+				id,
+				version,
+				LockMode.NONE,
+				true,
+				subclassPersister,
+				false,
+				entry.areLazyPropertiesUnfetched()
+			);
+		subclassPersister.afterInitialize( result, entry.areLazyPropertiesUnfetched(), session );
+		persistenceContext.initializeNonLazyCollections();
+		// upgrade the lock if necessary:
+		//lock(result, lockMode);
+
+		//PostLoad is needed for EJB3
+		//TODO: reuse the PostLoadEvent...
+		PostLoadEvent postLoadEvent = new PostLoadEvent(session).setEntity(result)
+				.setId(id).setPersister(persister);
+		PostLoadEventListener[] listeners = session.getListeners().getPostLoadEventListeners();
+		for ( int i = 0; i < listeners.length; i++ ) {
+			listeners[i].onPostLoad(postLoadEvent);
+		}
+
+		return result;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,79 +0,0 @@
-//$Id: DefaultLockEventListener.java 7019 2005-06-05 05:09:58Z oneovthafew $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.TransientObjectException;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.LockEvent;
-import org.hibernate.event.LockEventListener;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Defines the default lock event listeners used by hibernate to lock entities
- * in response to generated lock events.
- *
- * @author Steve Ebersole
- */
-public class DefaultLockEventListener extends AbstractLockUpgradeEventListener implements LockEventListener {
-
-	/** Handle the given lock event.
-	 *
-	 * @param event The lock event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onLock(LockEvent event) throws HibernateException {
-
-		if ( event.getObject() == null ) {
-			throw new NullPointerException( "attempted to lock null" );
-		}
-
-		if ( event.getLockMode() == LockMode.WRITE ) {
-			throw new HibernateException( "Invalid lock mode for lock()" );
-		}
-
-		SessionImplementor source = event.getSession();
-		
-		Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
-		//TODO: if object was an uninitialized proxy, this is inefficient,
-		//      resulting in two SQL selects
-		
-		EntityEntry entry = source.getPersistenceContext().getEntry(entity);
-		if (entry==null) {
-			final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-			final Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
-			if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) {
-				throw new TransientObjectException(
-						"cannot lock an unsaved transient instance: " +
-						persister.getEntityName()
-				);
-			}
-
-			entry = reassociate(event, entity, id, persister);
-			
-			cascadeOnLock(event, persister, entity);
-		}
-
-		upgradeLock( entity, entry, event.getLockMode(), source );
-	}
-	
-	private void cascadeOnLock(LockEvent event, EntityPersister persister, Object entity) {
-		EventSource source = event.getSession();
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade(CascadingAction.LOCK, Cascade.AFTER_LOCK, source)
-					.cascade( persister, entity, event.getLockMode() );
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultLockEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.TransientObjectException;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.LockEvent;
+import org.hibernate.event.LockEventListener;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Defines the default lock event listeners used by hibernate to lock entities
+ * in response to generated lock events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultLockEventListener extends AbstractLockUpgradeEventListener implements LockEventListener {
+
+	/** Handle the given lock event.
+	 *
+	 * @param event The lock event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onLock(LockEvent event) throws HibernateException {
+
+		if ( event.getObject() == null ) {
+			throw new NullPointerException( "attempted to lock null" );
+		}
+
+		if ( event.getLockMode() == LockMode.WRITE ) {
+			throw new HibernateException( "Invalid lock mode for lock()" );
+		}
+
+		SessionImplementor source = event.getSession();
+		
+		Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
+		//TODO: if object was an uninitialized proxy, this is inefficient,
+		//      resulting in two SQL selects
+		
+		EntityEntry entry = source.getPersistenceContext().getEntry(entity);
+		if (entry==null) {
+			final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+			final Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+			if ( !ForeignKeys.isNotTransient( event.getEntityName(), entity, Boolean.FALSE, source ) ) {
+				throw new TransientObjectException(
+						"cannot lock an unsaved transient instance: " +
+						persister.getEntityName()
+				);
+			}
+
+			entry = reassociate(event, entity, id, persister);
+			
+			cascadeOnLock(event, persister, entity);
+		}
+
+		upgradeLock( entity, entry, event.getLockMode(), source );
+	}
+	
+	private void cascadeOnLock(LockEvent event, EntityPersister persister, Object entity) {
+		EventSource source = event.getSession();
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade(CascadingAction.LOCK, Cascade.AFTER_LOCK, source)
+					.cascade( persister, entity, event.getLockMode() );
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,467 +0,0 @@
-//$Id: DefaultMergeEventListener.java 14513 2008-04-17 23:05:11Z gbadner $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.WrongClassException;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.MergeEvent;
-import org.hibernate.event.MergeEventListener;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.type.ForeignKeyDirection;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.IdentityMap;
-
-/**
- * Defines the default copy event listener used by hibernate for copying entities
- * in response to generated copy events.
- *
- * @author Gavin King
- */
-public class DefaultMergeEventListener extends AbstractSaveEventListener 
-	implements MergeEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultMergeEventListener.class);
-	
-	protected Map getMergeMap(Object anything) {
-		return IdentityMap.invert( (Map) anything );
-	}
-
-	/**
-	 * Handle the given merge event.
-	 *
-	 * @param event The merge event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onMerge(MergeEvent event) throws HibernateException {
-		Map copyCache = IdentityMap.instantiate(10);
-		onMerge( event, copyCache );
-		for ( Iterator it=copyCache.values().iterator(); it.hasNext(); ) {
-			Object entity = it.next();
-			if ( entity instanceof HibernateProxy ) {
-				entity = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getImplementation();
-			}
-			EntityEntry entry = event.getSession().getPersistenceContext().getEntry( entity );
-			if ( entry == null ) {
-				throw new TransientObjectException(
-						"object references an unsaved transient instance - save the transient instance before merging: " +
-						event.getSession().guessEntityName( entity )
-				);
-				// TODO: cache the entity name somewhere so that it is available to this exception
-				// entity name will not be available for non-POJO entities
-			}
-			if ( entry.getStatus() != Status.MANAGED ) {
-				throw new AssertionFailure( "Merged entity does not have status set to MANAGED; "+entry+" status="+entry.getStatus() );
-			}
-		}
-	}
-
-	/** 
-	 * Handle the given merge event.
-	 *
-	 * @param event The merge event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onMerge(MergeEvent event, Map copyCache) throws HibernateException {
-
-		final EventSource source = event.getSession();
-		final Object original = event.getOriginal();
-
-		if ( original != null ) {
-
-			final Object entity;
-			if ( original instanceof HibernateProxy ) {
-				LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
-				if ( li.isUninitialized() ) {
-					log.trace("ignoring uninitialized proxy");
-					event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
-					return; //EARLY EXIT!
-				}
-				else {
-					entity = li.getImplementation();
-				}
-			}
-			else {
-				entity = original;
-			}
-			
-			if ( copyCache.containsKey(entity) &&
-					source.getContextEntityIdentifier( copyCache.get( entity ) ) != null ) {
-				log.trace("already merged");
-				event.setResult(entity);
-			}
-			else {
-				event.setEntity( entity );
-				int entityState = -1;
-
-				// Check the persistence context for an entry relating to this
-				// entity to be merged...
-				EntityEntry entry = source.getPersistenceContext().getEntry( entity );
-				if ( entry == null ) {
-					EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-					Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
-					if ( id != null ) {
-						EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-						Object managedEntity = source.getPersistenceContext().getEntity( key );
-						entry = source.getPersistenceContext().getEntry( managedEntity );
-						if ( entry != null ) {
-							// we have specialized case of a detached entity from the
-							// perspective of the merge operation.  Specifically, we
-							// have an incoming entity instance which has a corresponding
-							// entry in the current persistence context, but registered
-							// under a different entity instance
-							entityState = DETACHED;
-						}
-					}
-				}
-
-				if ( entityState == -1 ) {
-					entityState = getEntityState( entity, event.getEntityName(), entry, source );
-				}
-				
-				switch (entityState) {
-					case DETACHED:
-						entityIsDetached(event, copyCache);
-						break;
-					case TRANSIENT:
-						entityIsTransient(event, copyCache);
-						break;
-					case PERSISTENT:
-						entityIsPersistent(event, copyCache);
-						break;
-					default: //DELETED
-						throw new ObjectDeletedException(
-								"deleted instance passed to merge", 
-								null, 
-								getLoggableName( event.getEntityName(), entity )
-							);			
-				}
-			}
-			
-		}
-		
-	}
-
-	protected void entityIsPersistent(MergeEvent event, Map copyCache) {
-		log.trace("ignoring persistent instance");
-		
-		//TODO: check that entry.getIdentifier().equals(requestedId)
-		
-		final Object entity = event.getEntity();
-		final EventSource source = event.getSession();
-		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-		
-		copyCache.put(entity, entity); //before cascade!
-		
-		cascadeOnMerge(source, persister, entity, copyCache);
-		copyValues(persister, entity, entity, source, copyCache);
-		
-		event.setResult(entity);
-	}
-	
-	protected void entityIsTransient(MergeEvent event, Map copyCache) {
-		
-		log.trace("merging transient instance");
-		
-		final Object entity = event.getEntity();
-		final EventSource source = event.getSession();
-
-		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-		final String entityName = persister.getEntityName();
-		
-		final Serializable id = persister.hasIdentifierProperty() ?
-				persister.getIdentifier( entity, source.getEntityMode() ) :
-		        null;
-		if ( copyCache.containsKey( entity ) ) {
-			persister.setIdentifier( copyCache.get( entity ), id, source.getEntityMode() );
-		}
-		else {
-			copyCache.put(entity, persister.instantiate( id, source.getEntityMode() ) ); //before cascade!
-			//TODO: should this be Session.instantiate(Persister, ...)?
-		}
-		final Object copy = copyCache.get( entity );
-
-		// cascade first, so that all unsaved objects get their
-		// copy created before we actually copy
-		//cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE);
-		super.cascadeBeforeSave(source, persister, entity, copyCache);
-		copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT);
-		
-		//this bit is only *really* absolutely necessary for handling 
-		//requestedId, but is also good if we merge multiple object 
-		//graphs, since it helps ensure uniqueness
-		final Serializable requestedId = event.getRequestedId();
-		if (requestedId==null) {
-			saveWithGeneratedId( copy, entityName, copyCache, source, false );
-		}
-		else {
-			saveWithRequestedId( copy, requestedId, entityName, copyCache, source );
-		}
-		
-		// cascade first, so that all unsaved objects get their 
-		// copy created before we actually copy
-		super.cascadeAfterSave(source, persister, entity, copyCache);
-		copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_TO_PARENT);
-		
-		event.setResult(copy);
-
-	}
-
-	protected void entityIsDetached(MergeEvent event, Map copyCache) {
-		
-		log.trace("merging detached instance");
-		
-		final Object entity = event.getEntity();
-		final EventSource source = event.getSession();
-
-		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-		final String entityName = persister.getEntityName();
-			
-		Serializable id = event.getRequestedId();
-		if ( id == null ) {
-			id = persister.getIdentifier( entity, source.getEntityMode() );
-		}
-		else {
-			// check that entity id = requestedId
-			Serializable entityId = persister.getIdentifier( entity, source.getEntityMode() );
-			if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) {
-				throw new HibernateException( "merge requested with id not matching id of passed entity" );
-			}
-		}
-		
-		String previousFetchProfile = source.getFetchProfile();
-		source.setFetchProfile("merge");
-		//we must clone embedded composite identifiers, or 
-		//we will get back the same instance that we pass in
-		final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType()
-				.deepCopy( id, source.getEntityMode(), source.getFactory() );
-		final Object result = source.get(entityName, clonedIdentifier);
-		source.setFetchProfile(previousFetchProfile);
-		
-		if ( result == null ) {
-			//TODO: we should throw an exception if we really *know* for sure  
-			//      that this is a detached instance, rather than just assuming
-			//throw new StaleObjectStateException(entityName, id);
-			
-			// we got here because we assumed that an instance
-			// with an assigned id was detached, when it was
-			// really persistent
-			entityIsTransient(event, copyCache);
-		}
-		else {
-			copyCache.put(entity, result); //before cascade!
-	
-			final Object target = source.getPersistenceContext().unproxy(result);
-			if ( target == entity ) {
-				throw new AssertionFailure("entity was not detached");
-			}
-			else if ( !source.getEntityName(target).equals(entityName) ) {
-				throw new WrongClassException(
-						"class of the given object did not match class of persistent copy",
-						event.getRequestedId(),
-						entityName
-					);
-			}
-			else if ( isVersionChanged( entity, source, persister, target ) ) {
-				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
-					source.getFactory().getStatisticsImplementor()
-							.optimisticFailure( entityName );
-				}
-				throw new StaleObjectStateException( entityName, id );
-			}
-	
-			// cascade first, so that all unsaved objects get their 
-			// copy created before we actually copy
-			cascadeOnMerge(source, persister, entity, copyCache);
-			copyValues(persister, entity, target, source, copyCache);
-			
-			//copyValues works by reflection, so explicitly mark the entity instance dirty
-			markInterceptorDirty( entity, target );
-			
-			event.setResult(result);
-		}
-
-	}
-
-	private void markInterceptorDirty(final Object entity, final Object target) {
-		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
-			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( target );
-			if ( interceptor != null ) {
-				interceptor.dirty();
-			}
-		}
-	}
-
-	private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) {
-		if ( ! persister.isVersioned() ) {
-			return false;
-		}
-		// for merging of versioned entities, we consider the version having
-		// been changed only when:
-		// 1) the two version values are different;
-		//      *AND*
-		// 2) The target actually represents database state!
-		//
-		// This second condition is a special case which allows
-		// an entity to be merged during the same transaction
-		// (though during a seperate operation) in which it was
-		// originally persisted/saved
-		boolean changed = ! persister.getVersionType().isSame(
-				persister.getVersion( target, source.getEntityMode() ),
-				persister.getVersion( entity, source.getEntityMode() ),
-				source.getEntityMode()
-		);
-
-		// TODO : perhaps we should additionally require that the incoming entity
-		// version be equivalent to the defined unsaved-value?
-		return changed && existsInDatabase( target, source, persister );
-	}
-
-	private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
-		EntityEntry entry = source.getPersistenceContext().getEntry( entity );
-		if ( entry == null ) {
-			Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
-			if ( id != null ) {
-				EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-				Object managedEntity = source.getPersistenceContext().getEntity( key );
-				entry = source.getPersistenceContext().getEntry( managedEntity );
-			}
-		}
-
-		if ( entry == null ) {
-			// perhaps this should be an exception since it is only ever used
-			// in the above method?
-			return false;
-		}
-		else {
-			return entry.isExistsInDatabase();
-		}
-	}
-	
-	protected void copyValues(
-		final EntityPersister persister, 
-		final Object entity, 
-		final Object target, 
-		final SessionImplementor source,
-		final Map copyCache
-	) {
-		
-		final Object[] copiedValues = TypeFactory.replace(
-				persister.getPropertyValues( entity, source.getEntityMode() ),
-				persister.getPropertyValues( target, source.getEntityMode() ),
-				persister.getPropertyTypes(),
-				source,
-				target, 
-				copyCache
-			);
-
-		persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
-	}
-
-	protected void copyValues(
-			final EntityPersister persister,
-			final Object entity, 
-			final Object target, 
-			final SessionImplementor source,
-			final Map copyCache,
-			final ForeignKeyDirection foreignKeyDirection) {
-
-		final Object[] copiedValues;
-
-		if ( foreignKeyDirection == ForeignKeyDirection.FOREIGN_KEY_TO_PARENT ) {
-			// this is the second pass through on a merge op, so here we limit the
-			// replacement to associations types (value types were already replaced
-			// during the first pass)
-			copiedValues = TypeFactory.replaceAssociations(
-					persister.getPropertyValues( entity, source.getEntityMode() ),
-					persister.getPropertyValues( target, source.getEntityMode() ),
-					persister.getPropertyTypes(),
-					source,
-					target,
-					copyCache,
-					foreignKeyDirection
-			);
-		}
-		else {
-			copiedValues = TypeFactory.replace(
-					persister.getPropertyValues( entity, source.getEntityMode() ),
-					persister.getPropertyValues( target, source.getEntityMode() ),
-					persister.getPropertyTypes(),
-					source,
-					target,
-					copyCache,
-					foreignKeyDirection
-			);
-		}
-
-		persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
-	}
-
-	/** 
-	 * Perform any cascades needed as part of this copy event.
-	 *
-	 * @param source The merge event being processed.
-	 * @param persister The persister of the entity being copied.
-	 * @param entity The entity being copied.
-	 * @param copyCache A cache of already copied instance.
-	 */
-	protected void cascadeOnMerge(
-		final EventSource source,
-		final EntityPersister persister,
-		final Object entity,
-		final Map copyCache
-	) {
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( getCascadeAction(), Cascade.BEFORE_MERGE, source )
-					.cascade(persister, entity, copyCache);
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.MERGE;
-	}
-
-	protected Boolean getAssumedUnsaved() {
-		return Boolean.FALSE;
-	}
-	
-	/**
-	 * Cascade behavior is redefined by this subclass, disable superclass behavior
-	 */
-	protected void cascadeAfterSave(EventSource source, EntityPersister persister, Object entity, Object anything) 
-	throws HibernateException {
-	}
-
-	/**
-	 * Cascade behavior is redefined by this subclass, disable superclass behavior
-	 */
-	protected void cascadeBeforeSave(EventSource source, EntityPersister persister, Object entity, Object anything) 
-	throws HibernateException {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultMergeEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,490 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.WrongClassException;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.MergeEvent;
+import org.hibernate.event.MergeEventListener;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.IdentityMap;
+
+/**
+ * Defines the default copy event listener used by hibernate for copying entities
+ * in response to generated copy events.
+ *
+ * @author Gavin King
+ */
+public class DefaultMergeEventListener extends AbstractSaveEventListener 
+	implements MergeEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultMergeEventListener.class);
+	
+	protected Map getMergeMap(Object anything) {
+		return IdentityMap.invert( (Map) anything );
+	}
+
+	/**
+	 * Handle the given merge event.
+	 *
+	 * @param event The merge event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onMerge(MergeEvent event) throws HibernateException {
+		Map copyCache = IdentityMap.instantiate(10);
+		onMerge( event, copyCache );
+		for ( Iterator it=copyCache.values().iterator(); it.hasNext(); ) {
+			Object entity = it.next();
+			if ( entity instanceof HibernateProxy ) {
+				entity = ( (HibernateProxy) entity ).getHibernateLazyInitializer().getImplementation();
+			}
+			EntityEntry entry = event.getSession().getPersistenceContext().getEntry( entity );
+			if ( entry == null ) {
+				throw new TransientObjectException(
+						"object references an unsaved transient instance - save the transient instance before merging: " +
+						event.getSession().guessEntityName( entity )
+				);
+				// TODO: cache the entity name somewhere so that it is available to this exception
+				// entity name will not be available for non-POJO entities
+			}
+			if ( entry.getStatus() != Status.MANAGED ) {
+				throw new AssertionFailure( "Merged entity does not have status set to MANAGED; "+entry+" status="+entry.getStatus() );
+			}
+		}
+	}
+
+	/** 
+	 * Handle the given merge event.
+	 *
+	 * @param event The merge event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onMerge(MergeEvent event, Map copyCache) throws HibernateException {
+
+		final EventSource source = event.getSession();
+		final Object original = event.getOriginal();
+
+		if ( original != null ) {
+
+			final Object entity;
+			if ( original instanceof HibernateProxy ) {
+				LazyInitializer li = ( (HibernateProxy) original ).getHibernateLazyInitializer();
+				if ( li.isUninitialized() ) {
+					log.trace("ignoring uninitialized proxy");
+					event.setResult( source.load( li.getEntityName(), li.getIdentifier() ) );
+					return; //EARLY EXIT!
+				}
+				else {
+					entity = li.getImplementation();
+				}
+			}
+			else {
+				entity = original;
+			}
+			
+			if ( copyCache.containsKey(entity) &&
+					source.getContextEntityIdentifier( copyCache.get( entity ) ) != null ) {
+				log.trace("already merged");
+				event.setResult(entity);
+			}
+			else {
+				event.setEntity( entity );
+				int entityState = -1;
+
+				// Check the persistence context for an entry relating to this
+				// entity to be merged...
+				EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+				if ( entry == null ) {
+					EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+					Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+					if ( id != null ) {
+						EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+						Object managedEntity = source.getPersistenceContext().getEntity( key );
+						entry = source.getPersistenceContext().getEntry( managedEntity );
+						if ( entry != null ) {
+							// we have specialized case of a detached entity from the
+							// perspective of the merge operation.  Specifically, we
+							// have an incoming entity instance which has a corresponding
+							// entry in the current persistence context, but registered
+							// under a different entity instance
+							entityState = DETACHED;
+						}
+					}
+				}
+
+				if ( entityState == -1 ) {
+					entityState = getEntityState( entity, event.getEntityName(), entry, source );
+				}
+				
+				switch (entityState) {
+					case DETACHED:
+						entityIsDetached(event, copyCache);
+						break;
+					case TRANSIENT:
+						entityIsTransient(event, copyCache);
+						break;
+					case PERSISTENT:
+						entityIsPersistent(event, copyCache);
+						break;
+					default: //DELETED
+						throw new ObjectDeletedException(
+								"deleted instance passed to merge", 
+								null, 
+								getLoggableName( event.getEntityName(), entity )
+							);			
+				}
+			}
+			
+		}
+		
+	}
+
+	protected void entityIsPersistent(MergeEvent event, Map copyCache) {
+		log.trace("ignoring persistent instance");
+		
+		//TODO: check that entry.getIdentifier().equals(requestedId)
+		
+		final Object entity = event.getEntity();
+		final EventSource source = event.getSession();
+		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+		
+		copyCache.put(entity, entity); //before cascade!
+		
+		cascadeOnMerge(source, persister, entity, copyCache);
+		copyValues(persister, entity, entity, source, copyCache);
+		
+		event.setResult(entity);
+	}
+	
+	protected void entityIsTransient(MergeEvent event, Map copyCache) {
+		
+		log.trace("merging transient instance");
+		
+		final Object entity = event.getEntity();
+		final EventSource source = event.getSession();
+
+		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+		final String entityName = persister.getEntityName();
+		
+		final Serializable id = persister.hasIdentifierProperty() ?
+				persister.getIdentifier( entity, source.getEntityMode() ) :
+		        null;
+		if ( copyCache.containsKey( entity ) ) {
+			persister.setIdentifier( copyCache.get( entity ), id, source.getEntityMode() );
+		}
+		else {
+			copyCache.put(entity, persister.instantiate( id, source.getEntityMode() ) ); //before cascade!
+			//TODO: should this be Session.instantiate(Persister, ...)?
+		}
+		final Object copy = copyCache.get( entity );
+
+		// cascade first, so that all unsaved objects get their
+		// copy created before we actually copy
+		//cascadeOnMerge(event, persister, entity, copyCache, Cascades.CASCADE_BEFORE_MERGE);
+		super.cascadeBeforeSave(source, persister, entity, copyCache);
+		copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT);
+		
+		//this bit is only *really* absolutely necessary for handling 
+		//requestedId, but is also good if we merge multiple object 
+		//graphs, since it helps ensure uniqueness
+		final Serializable requestedId = event.getRequestedId();
+		if (requestedId==null) {
+			saveWithGeneratedId( copy, entityName, copyCache, source, false );
+		}
+		else {
+			saveWithRequestedId( copy, requestedId, entityName, copyCache, source );
+		}
+		
+		// cascade first, so that all unsaved objects get their 
+		// copy created before we actually copy
+		super.cascadeAfterSave(source, persister, entity, copyCache);
+		copyValues(persister, entity, copy, source, copyCache, ForeignKeyDirection.FOREIGN_KEY_TO_PARENT);
+		
+		event.setResult(copy);
+
+	}
+
+	protected void entityIsDetached(MergeEvent event, Map copyCache) {
+		
+		log.trace("merging detached instance");
+		
+		final Object entity = event.getEntity();
+		final EventSource source = event.getSession();
+
+		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+		final String entityName = persister.getEntityName();
+			
+		Serializable id = event.getRequestedId();
+		if ( id == null ) {
+			id = persister.getIdentifier( entity, source.getEntityMode() );
+		}
+		else {
+			// check that entity id = requestedId
+			Serializable entityId = persister.getIdentifier( entity, source.getEntityMode() );
+			if ( !persister.getIdentifierType().isEqual( id, entityId, source.getEntityMode(), source.getFactory() ) ) {
+				throw new HibernateException( "merge requested with id not matching id of passed entity" );
+			}
+		}
+		
+		String previousFetchProfile = source.getFetchProfile();
+		source.setFetchProfile("merge");
+		//we must clone embedded composite identifiers, or 
+		//we will get back the same instance that we pass in
+		final Serializable clonedIdentifier = (Serializable) persister.getIdentifierType()
+				.deepCopy( id, source.getEntityMode(), source.getFactory() );
+		final Object result = source.get(entityName, clonedIdentifier);
+		source.setFetchProfile(previousFetchProfile);
+		
+		if ( result == null ) {
+			//TODO: we should throw an exception if we really *know* for sure  
+			//      that this is a detached instance, rather than just assuming
+			//throw new StaleObjectStateException(entityName, id);
+			
+			// we got here because we assumed that an instance
+			// with an assigned id was detached, when it was
+			// really persistent
+			entityIsTransient(event, copyCache);
+		}
+		else {
+			copyCache.put(entity, result); //before cascade!
+	
+			final Object target = source.getPersistenceContext().unproxy(result);
+			if ( target == entity ) {
+				throw new AssertionFailure("entity was not detached");
+			}
+			else if ( !source.getEntityName(target).equals(entityName) ) {
+				throw new WrongClassException(
+						"class of the given object did not match class of persistent copy",
+						event.getRequestedId(),
+						entityName
+					);
+			}
+			else if ( isVersionChanged( entity, source, persister, target ) ) {
+				if ( source.getFactory().getStatistics().isStatisticsEnabled() ) {
+					source.getFactory().getStatisticsImplementor()
+							.optimisticFailure( entityName );
+				}
+				throw new StaleObjectStateException( entityName, id );
+			}
+	
+			// cascade first, so that all unsaved objects get their 
+			// copy created before we actually copy
+			cascadeOnMerge(source, persister, entity, copyCache);
+			copyValues(persister, entity, target, source, copyCache);
+			
+			//copyValues works by reflection, so explicitly mark the entity instance dirty
+			markInterceptorDirty( entity, target );
+			
+			event.setResult(result);
+		}
+
+	}
+
+	private void markInterceptorDirty(final Object entity, final Object target) {
+		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
+			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( target );
+			if ( interceptor != null ) {
+				interceptor.dirty();
+			}
+		}
+	}
+
+	private boolean isVersionChanged(Object entity, EventSource source, EntityPersister persister, Object target) {
+		if ( ! persister.isVersioned() ) {
+			return false;
+		}
+		// for merging of versioned entities, we consider the version having
+		// been changed only when:
+		// 1) the two version values are different;
+		//      *AND*
+		// 2) The target actually represents database state!
+		//
+		// This second condition is a special case which allows
+		// an entity to be merged during the same transaction
+		// (though during a seperate operation) in which it was
+		// originally persisted/saved
+		boolean changed = ! persister.getVersionType().isSame(
+				persister.getVersion( target, source.getEntityMode() ),
+				persister.getVersion( entity, source.getEntityMode() ),
+				source.getEntityMode()
+		);
+
+		// TODO : perhaps we should additionally require that the incoming entity
+		// version be equivalent to the defined unsaved-value?
+		return changed && existsInDatabase( target, source, persister );
+	}
+
+	private boolean existsInDatabase(Object entity, EventSource source, EntityPersister persister) {
+		EntityEntry entry = source.getPersistenceContext().getEntry( entity );
+		if ( entry == null ) {
+			Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+			if ( id != null ) {
+				EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+				Object managedEntity = source.getPersistenceContext().getEntity( key );
+				entry = source.getPersistenceContext().getEntry( managedEntity );
+			}
+		}
+
+		if ( entry == null ) {
+			// perhaps this should be an exception since it is only ever used
+			// in the above method?
+			return false;
+		}
+		else {
+			return entry.isExistsInDatabase();
+		}
+	}
+	
+	protected void copyValues(
+		final EntityPersister persister, 
+		final Object entity, 
+		final Object target, 
+		final SessionImplementor source,
+		final Map copyCache
+	) {
+		
+		final Object[] copiedValues = TypeFactory.replace(
+				persister.getPropertyValues( entity, source.getEntityMode() ),
+				persister.getPropertyValues( target, source.getEntityMode() ),
+				persister.getPropertyTypes(),
+				source,
+				target, 
+				copyCache
+			);
+
+		persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+	}
+
+	protected void copyValues(
+			final EntityPersister persister,
+			final Object entity, 
+			final Object target, 
+			final SessionImplementor source,
+			final Map copyCache,
+			final ForeignKeyDirection foreignKeyDirection) {
+
+		final Object[] copiedValues;
+
+		if ( foreignKeyDirection == ForeignKeyDirection.FOREIGN_KEY_TO_PARENT ) {
+			// this is the second pass through on a merge op, so here we limit the
+			// replacement to associations types (value types were already replaced
+			// during the first pass)
+			copiedValues = TypeFactory.replaceAssociations(
+					persister.getPropertyValues( entity, source.getEntityMode() ),
+					persister.getPropertyValues( target, source.getEntityMode() ),
+					persister.getPropertyTypes(),
+					source,
+					target,
+					copyCache,
+					foreignKeyDirection
+			);
+		}
+		else {
+			copiedValues = TypeFactory.replace(
+					persister.getPropertyValues( entity, source.getEntityMode() ),
+					persister.getPropertyValues( target, source.getEntityMode() ),
+					persister.getPropertyTypes(),
+					source,
+					target,
+					copyCache,
+					foreignKeyDirection
+			);
+		}
+
+		persister.setPropertyValues( target, copiedValues, source.getEntityMode() );
+	}
+
+	/** 
+	 * Perform any cascades needed as part of this copy event.
+	 *
+	 * @param source The merge event being processed.
+	 * @param persister The persister of the entity being copied.
+	 * @param entity The entity being copied.
+	 * @param copyCache A cache of already copied instance.
+	 */
+	protected void cascadeOnMerge(
+		final EventSource source,
+		final EntityPersister persister,
+		final Object entity,
+		final Map copyCache
+	) {
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( getCascadeAction(), Cascade.BEFORE_MERGE, source )
+					.cascade(persister, entity, copyCache);
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.MERGE;
+	}
+
+	protected Boolean getAssumedUnsaved() {
+		return Boolean.FALSE;
+	}
+	
+	/**
+	 * Cascade behavior is redefined by this subclass, disable superclass behavior
+	 */
+	protected void cascadeAfterSave(EventSource source, EntityPersister persister, Object entity, Object anything) 
+	throws HibernateException {
+	}
+
+	/**
+	 * Cascade behavior is redefined by this subclass, disable superclass behavior
+	 */
+	protected void cascadeBeforeSave(EventSource source, EntityPersister persister, Object entity, Object anything) 
+	throws HibernateException {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,144 +0,0 @@
-// $Id: DefaultPersistEventListener.java 9673 2006-03-22 14:57:59Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PersistEvent;
-import org.hibernate.event.PersistEventListener;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.util.IdentityMap;
-
-/**
- * Defines the default create event listener used by hibernate for creating
- * transient entities in response to generated create events.
- *
- * @author Gavin King
- */
-public class DefaultPersistEventListener extends AbstractSaveEventListener implements PersistEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultPersistEventListener.class);
-
-	/** 
-	 * Handle the given create event.
-	 *
-	 * @param event The create event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onPersist(PersistEvent event) throws HibernateException {
-		onPersist( event, IdentityMap.instantiate(10) );
-	}
-		
-
-	/** 
-	 * Handle the given create event.
-	 *
-	 * @param event The create event to be handled.
-	 * @throws HibernateException
-	 */
-	public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
-			
-		final SessionImplementor source = event.getSession();
-		final Object object = event.getObject();
-		
-		final Object entity;
-		if (object instanceof HibernateProxy) {
-			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
-			if ( li.isUninitialized() ) {
-				if ( li.getSession()==source ) {
-					return; //NOTE EARLY EXIT!
-				}
-				else {
-					throw new PersistentObjectException("uninitialized proxy passed to persist()");
-				}
-			}
-			entity = li.getImplementation();
-		}
-		else {
-			entity = object;
-		}
-		
-		int entityState = getEntityState( 
-				entity, 
-				event.getEntityName(), 
-				source.getPersistenceContext().getEntry(entity), 
-				source 
-			);
-		
-		switch (entityState) {
-			case DETACHED: 
-				throw new PersistentObjectException( 
-						"detached entity passed to persist: " + 
-						getLoggableName( event.getEntityName(), entity ) 
-					);
-			case PERSISTENT:
-				entityIsPersistent(event, createCache);
-				break;
-			case TRANSIENT:
-				entityIsTransient(event, createCache);
-				break;
-			default: 
-				throw new ObjectDeletedException( 
-						"deleted entity passed to persist", 
-						null, 
-						getLoggableName( event.getEntityName(), entity )
-					);
-		}
-
-	}
-		
-	protected void entityIsPersistent(PersistEvent event, Map createCache) {
-		log.trace("ignoring persistent instance");
-		final EventSource source = event.getSession();
-		
-		//TODO: check that entry.getIdentifier().equals(requestedId)
-		
-		final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
-		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-		
-		if ( createCache.put(entity, entity)==null ) {
-			//TODO: merge into one method!
-			cascadeBeforeSave(source, persister, entity, createCache);
-			cascadeAfterSave(source, persister, entity, createCache);
-		}
-
-	}
-	
-	/** 
-	 * Handle the given create event.
-	 *
-	 * @param event The save event to be handled.
-	 * @throws HibernateException
-	 */
-	protected void entityIsTransient(PersistEvent event, Map createCache) throws HibernateException {
-		
-		log.trace("saving transient instance");
-
-		final EventSource source = event.getSession();
-		
-		final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
-		
-		if ( createCache.put(entity, entity)==null ) {
-			saveWithGeneratedId( entity, event.getEntityName(), createCache, source, false );
-		}
-
-	}
-
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.PERSIST;
-	}
-	
-	protected Boolean getAssumedUnsaved() {
-		return Boolean.TRUE;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,167 @@
+/*
+ * 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.event.def;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PersistEvent;
+import org.hibernate.event.PersistEventListener;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.util.IdentityMap;
+
+/**
+ * Defines the default create event listener used by hibernate for creating
+ * transient entities in response to generated create events.
+ *
+ * @author Gavin King
+ */
+public class DefaultPersistEventListener extends AbstractSaveEventListener implements PersistEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultPersistEventListener.class);
+
+	/** 
+	 * Handle the given create event.
+	 *
+	 * @param event The create event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onPersist(PersistEvent event) throws HibernateException {
+		onPersist( event, IdentityMap.instantiate(10) );
+	}
+		
+
+	/** 
+	 * Handle the given create event.
+	 *
+	 * @param event The create event to be handled.
+	 * @throws HibernateException
+	 */
+	public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
+			
+		final SessionImplementor source = event.getSession();
+		final Object object = event.getObject();
+		
+		final Object entity;
+		if (object instanceof HibernateProxy) {
+			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
+			if ( li.isUninitialized() ) {
+				if ( li.getSession()==source ) {
+					return; //NOTE EARLY EXIT!
+				}
+				else {
+					throw new PersistentObjectException("uninitialized proxy passed to persist()");
+				}
+			}
+			entity = li.getImplementation();
+		}
+		else {
+			entity = object;
+		}
+		
+		int entityState = getEntityState( 
+				entity, 
+				event.getEntityName(), 
+				source.getPersistenceContext().getEntry(entity), 
+				source 
+			);
+		
+		switch (entityState) {
+			case DETACHED: 
+				throw new PersistentObjectException( 
+						"detached entity passed to persist: " + 
+						getLoggableName( event.getEntityName(), entity ) 
+					);
+			case PERSISTENT:
+				entityIsPersistent(event, createCache);
+				break;
+			case TRANSIENT:
+				entityIsTransient(event, createCache);
+				break;
+			default: 
+				throw new ObjectDeletedException( 
+						"deleted entity passed to persist", 
+						null, 
+						getLoggableName( event.getEntityName(), entity )
+					);
+		}
+
+	}
+		
+	protected void entityIsPersistent(PersistEvent event, Map createCache) {
+		log.trace("ignoring persistent instance");
+		final EventSource source = event.getSession();
+		
+		//TODO: check that entry.getIdentifier().equals(requestedId)
+		
+		final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
+		final EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+		
+		if ( createCache.put(entity, entity)==null ) {
+			//TODO: merge into one method!
+			cascadeBeforeSave(source, persister, entity, createCache);
+			cascadeAfterSave(source, persister, entity, createCache);
+		}
+
+	}
+	
+	/** 
+	 * Handle the given create event.
+	 *
+	 * @param event The save event to be handled.
+	 * @throws HibernateException
+	 */
+	protected void entityIsTransient(PersistEvent event, Map createCache) throws HibernateException {
+		
+		log.trace("saving transient instance");
+
+		final EventSource source = event.getSession();
+		
+		final Object entity = source.getPersistenceContext().unproxy( event.getObject() );
+		
+		if ( createCache.put(entity, entity)==null ) {
+			saveWithGeneratedId( entity, event.getEntityName(), createCache, source, false );
+		}
+
+	}
+
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.PERSIST;
+	}
+	
+	protected Boolean getAssumedUnsaved() {
+		return Boolean.TRUE;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-//$Id: DefaultPersistOnFlushEventListener.java 9019 2006-01-11 18:50:33Z epbernard $
-package org.hibernate.event.def;
-
-import org.hibernate.engine.CascadingAction;
-
-/**
- * When persist is used as the cascade action, persistOnFlush should be used
- * @author Emmanuel Bernard
- */
-public class DefaultPersistOnFlushEventListener extends DefaultPersistEventListener {
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.PERSIST_ON_FLUSH;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPersistOnFlushEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.engine.CascadingAction;
+
+/**
+ * When persist is used as the cascade action, persistOnFlush should be used
+ * @author Emmanuel Bernard
+ */
+public class DefaultPersistOnFlushEventListener extends DefaultPersistEventListener {
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.PERSIST_ON_FLUSH;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: DefaultPostLoadEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.event.PostLoadEvent;
-import org.hibernate.event.PostLoadEventListener;
-
-/**
- * Call <tt>Lifecycle</tt> interface if necessary
- *
- * @author Gavin King
- */
-public class DefaultPostLoadEventListener implements PostLoadEventListener {
-	
-	public void onPostLoad(PostLoadEvent event) {
-		if ( event.getPersister().implementsLifecycle( event.getSession().getEntityMode() ) ) {
-			//log.debug( "calling onLoad()" );
-			( ( Lifecycle ) event.getEntity() ).onLoad( event.getSession(), event.getId() );
-		}
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPostLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.event.PostLoadEvent;
+import org.hibernate.event.PostLoadEventListener;
+
+/**
+ * Call <tt>Lifecycle</tt> interface if necessary
+ *
+ * @author Gavin King
+ */
+public class DefaultPostLoadEventListener implements PostLoadEventListener {
+	
+	public void onPostLoad(PostLoadEvent event) {
+		if ( event.getPersister().implementsLifecycle( event.getSession().getEntityMode() ) ) {
+			//log.debug( "calling onLoad()" );
+			( ( Lifecycle ) event.getEntity() ).onLoad( event.getSession(), event.getId() );
+		}
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-//$Id: DefaultPreLoadEventListener.java 7785 2005-08-08 23:24:44Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.event.PreLoadEvent;
-import org.hibernate.event.PreLoadEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * Called before injecting property values into a newly 
- * loaded entity instance.
- *
- * @author Gavin King
- */
-public class DefaultPreLoadEventListener implements PreLoadEventListener {
-	
-	public void onPreLoad(PreLoadEvent event) {
-		EntityPersister persister = event.getPersister();
-		event.getSession()
-			.getInterceptor()
-			.onLoad( 
-					event.getEntity(), 
-					event.getId(), 
-					event.getState(), 
-					persister.getPropertyNames(), 
-					persister.getPropertyTypes() 
-				);
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultPreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.event.PreLoadEvent;
+import org.hibernate.event.PreLoadEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * Called before injecting property values into a newly 
+ * loaded entity instance.
+ *
+ * @author Gavin King
+ */
+public class DefaultPreLoadEventListener implements PreLoadEventListener {
+	
+	public void onPreLoad(PreLoadEvent event) {
+		EntityPersister persister = event.getPersister();
+		event.getSession()
+			.getInterceptor()
+			.onLoad( 
+					event.getEntity(), 
+					event.getId(), 
+					event.getState(), 
+					persister.getPropertyNames(), 
+					persister.getPropertyTypes() 
+				);
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,146 +0,0 @@
-//$Id: DefaultRefreshEventListener.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.RefreshEvent;
-import org.hibernate.event.RefreshEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-import org.hibernate.util.IdentityMap;
-
-/**
- * Defines the default refresh event listener used by hibernate for refreshing entities
- * in response to generated refresh events.
- *
- * @author Steve Ebersole
- */
-public class DefaultRefreshEventListener implements RefreshEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger(DefaultRefreshEventListener.class);
-	
-	public void onRefresh(RefreshEvent event) throws HibernateException {
-		onRefresh( event, IdentityMap.instantiate(10) );
-	}
-
-	/** 
-	 * Handle the given refresh event.
-	 *
-	 * @param event The refresh event to be handled.
-	 */
-	public void onRefresh(RefreshEvent event, Map refreshedAlready) {
-
-		final EventSource source = event.getSession();
-		
-		if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) return;
-
-		final Object object = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
-
-		if ( refreshedAlready.containsKey(object) ) {
-			log.trace("already refreshed");
-			return;
-		}
-
-		final EntityEntry e = source.getPersistenceContext().getEntry( object );
-		final EntityPersister persister;
-		final Serializable id;
-		
-		if ( e == null ) {
-			persister = source.getEntityPersister(null, object); //refresh() does not pass an entityName
-			id = persister.getIdentifier( object, event.getSession().getEntityMode() );
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"refreshing transient " +
-						MessageHelper.infoString( persister, id, source.getFactory() )
-					);
-			}
-			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-			if ( source.getPersistenceContext().getEntry(key) != null ) {
-				throw new PersistentObjectException(
-						"attempted to refresh transient instance when persistent instance was already associated with the Session: " +
-						MessageHelper.infoString(persister, id, source.getFactory() )
-					);
-			}
-		}
-		else {
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"refreshing " +
-						MessageHelper.infoString( e.getPersister(), e.getId(), source.getFactory()  )
-					);
-			}
-			if ( !e.isExistsInDatabase() ) {
-				throw new HibernateException( "this instance does not yet exist as a row in the database" );
-			}
-
-			persister = e.getPersister();
-			id = e.getId();
-		}
-
-		// cascade the refresh prior to refreshing this entity
-		refreshedAlready.put(object, object);
-		new Cascade(CascadingAction.REFRESH, Cascade.BEFORE_REFRESH, source)
-				.cascade( persister, object, refreshedAlready );
-
-		if ( e != null ) {
-			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-			source.getPersistenceContext().removeEntity(key);
-			if ( persister.hasCollections() ) new EvictVisitor( source ).process(object, persister);
-		}
-
-		if ( persister.hasCache() ) {
-			final CacheKey ck = new CacheKey(
-					id,
-					persister.getIdentifierType(),
-					persister.getRootEntityName(),
-					source.getEntityMode(), 
-					source.getFactory()
-			);
-			persister.getCacheAccessStrategy().evict( ck );
-		}
-		
-		evictCachedCollections( persister, id, source.getFactory() );
-		
-		String previousFetchProfile = source.getFetchProfile();
-		source.setFetchProfile("refresh");
-		Object result = persister.load( id, object, event.getLockMode(), source );
-		source.setFetchProfile(previousFetchProfile);
-		
-		UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
-
-	}
-
-	private void evictCachedCollections(EntityPersister persister, Serializable id, SessionFactoryImplementor factory) {
-		evictCachedCollections( persister.getPropertyTypes(), id, factory );
-	}
-
-	private void evictCachedCollections(Type[] types, Serializable id, SessionFactoryImplementor factory)
-	throws HibernateException {
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( types[i].isCollectionType() ) {
-				factory.evictCollection( ( (CollectionType) types[i] ).getRole(), id );
-			}
-			else if ( types[i].isComponentType() ) {
-				AbstractComponentType actype = (AbstractComponentType) types[i];
-				evictCachedCollections( actype.getSubtypes(), id, factory );
-			}
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultRefreshEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,169 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.RefreshEvent;
+import org.hibernate.event.RefreshEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+import org.hibernate.util.IdentityMap;
+
+/**
+ * Defines the default refresh event listener used by hibernate for refreshing entities
+ * in response to generated refresh events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultRefreshEventListener implements RefreshEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger(DefaultRefreshEventListener.class);
+	
+	public void onRefresh(RefreshEvent event) throws HibernateException {
+		onRefresh( event, IdentityMap.instantiate(10) );
+	}
+
+	/** 
+	 * Handle the given refresh event.
+	 *
+	 * @param event The refresh event to be handled.
+	 */
+	public void onRefresh(RefreshEvent event, Map refreshedAlready) {
+
+		final EventSource source = event.getSession();
+		
+		if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) return;
+
+		final Object object = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
+
+		if ( refreshedAlready.containsKey(object) ) {
+			log.trace("already refreshed");
+			return;
+		}
+
+		final EntityEntry e = source.getPersistenceContext().getEntry( object );
+		final EntityPersister persister;
+		final Serializable id;
+		
+		if ( e == null ) {
+			persister = source.getEntityPersister(null, object); //refresh() does not pass an entityName
+			id = persister.getIdentifier( object, event.getSession().getEntityMode() );
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"refreshing transient " +
+						MessageHelper.infoString( persister, id, source.getFactory() )
+					);
+			}
+			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+			if ( source.getPersistenceContext().getEntry(key) != null ) {
+				throw new PersistentObjectException(
+						"attempted to refresh transient instance when persistent instance was already associated with the Session: " +
+						MessageHelper.infoString(persister, id, source.getFactory() )
+					);
+			}
+		}
+		else {
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"refreshing " +
+						MessageHelper.infoString( e.getPersister(), e.getId(), source.getFactory()  )
+					);
+			}
+			if ( !e.isExistsInDatabase() ) {
+				throw new HibernateException( "this instance does not yet exist as a row in the database" );
+			}
+
+			persister = e.getPersister();
+			id = e.getId();
+		}
+
+		// cascade the refresh prior to refreshing this entity
+		refreshedAlready.put(object, object);
+		new Cascade(CascadingAction.REFRESH, Cascade.BEFORE_REFRESH, source)
+				.cascade( persister, object, refreshedAlready );
+
+		if ( e != null ) {
+			EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+			source.getPersistenceContext().removeEntity(key);
+			if ( persister.hasCollections() ) new EvictVisitor( source ).process(object, persister);
+		}
+
+		if ( persister.hasCache() ) {
+			final CacheKey ck = new CacheKey(
+					id,
+					persister.getIdentifierType(),
+					persister.getRootEntityName(),
+					source.getEntityMode(), 
+					source.getFactory()
+			);
+			persister.getCacheAccessStrategy().evict( ck );
+		}
+		
+		evictCachedCollections( persister, id, source.getFactory() );
+		
+		String previousFetchProfile = source.getFetchProfile();
+		source.setFetchProfile("refresh");
+		Object result = persister.load( id, object, event.getLockMode(), source );
+		source.setFetchProfile(previousFetchProfile);
+		
+		UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
+
+	}
+
+	private void evictCachedCollections(EntityPersister persister, Serializable id, SessionFactoryImplementor factory) {
+		evictCachedCollections( persister.getPropertyTypes(), id, factory );
+	}
+
+	private void evictCachedCollections(Type[] types, Serializable id, SessionFactoryImplementor factory)
+	throws HibernateException {
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( types[i].isCollectionType() ) {
+				factory.evictCollection( ( (CollectionType) types[i] ).getRole(), id );
+			}
+			else if ( types[i].isComponentType() ) {
+				AbstractComponentType actype = (AbstractComponentType) types[i];
+				evictCachedCollections( actype.getSubtypes(), id, factory );
+			}
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,206 +0,0 @@
-//$Id: DefaultReplicateEventListener.java 11089 2007-01-24 14:34:22Z max.andersen at jboss.com $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.ReplicationMode;
-import org.hibernate.LockMode;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.Status;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.ReplicateEvent;
-import org.hibernate.event.ReplicateEventListener;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Defines the default replicate event listener used by Hibernate to replicate
- * entities in response to generated replicate events.
- *
- * @author Steve Ebersole
- */
-public class DefaultReplicateEventListener extends AbstractSaveEventListener implements ReplicateEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger( DefaultReplicateEventListener.class );
-
-	/**
-	 * Handle the given replicate event.
-	 *
-	 * @param event The replicate event to be handled.
-	 *
-	 * @throws TransientObjectException An invalid attempt to replicate a transient entity.
-	 */
-	public void onReplicate(ReplicateEvent event) {
-		final EventSource source = event.getSession();
-		if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
-			log.trace( "uninitialized proxy passed to replicate()" );
-			return;
-		}
-
-		Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
-
-		if ( source.getPersistenceContext().isEntryFor( entity ) ) {
-			log.trace( "ignoring persistent instance passed to replicate()" );
-			//hum ... should we cascade anyway? throw an exception? fine like it is?
-			return;
-		}
-
-		EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
-
-		// get the id from the object
-		/*if ( persister.isUnsaved(entity, source) ) {
-			throw new TransientObjectException("transient instance passed to replicate()");
-		}*/
-		Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
-		if ( id == null ) {
-			throw new TransientObjectException( "instance with null id passed to replicate()" );
-		}
-
-		final ReplicationMode replicationMode = event.getReplicationMode();
-
-		final Object oldVersion;
-		if ( replicationMode == ReplicationMode.EXCEPTION ) {
-			//always do an INSERT, and let it fail by constraint violation
-			oldVersion = null;
-		}
-		else {
-			//what is the version on the database?
-			oldVersion = persister.getCurrentVersion( id, source );			
-		}
-
-		if ( oldVersion != null ) { 			
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"found existing row for " +
-								MessageHelper.infoString( persister, id, source.getFactory() )
-				);
-			}
-
-			/// HHH-2378
-			final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
-			
-			boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
-					entity,
-					realOldVersion,
-					persister.getVersion( entity, source.getEntityMode() ),
-					persister.getVersionType()
-			);
-
-			if ( canReplicate ) {
-				//will result in a SQL UPDATE:
-				performReplication( entity, id, realOldVersion, persister, replicationMode, source );
-			}
-			else {
-				//else do nothing (don't even reassociate object!)
-				log.trace( "no need to replicate" );
-			}
-
-			//TODO: would it be better to do a refresh from db?
-		}
-		else {
-			// no existing row - do an insert
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"no existing row, replicating new instance " +
-								MessageHelper.infoString( persister, id, source.getFactory() )
-				);
-			}
-
-			final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
-			final EntityKey key = regenerate ?
-					null : new EntityKey( id, persister, source.getEntityMode() );
-
-			performSaveOrReplicate(
-					entity,
-					key,
-					persister,
-					regenerate,
-					replicationMode,
-					source,
-					true
-			);
-
-		}
-	}
-
-	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
-		//TODO: we use two visitors here, inefficient!
-		OnReplicateVisitor visitor = new OnReplicateVisitor( source, id, entity, false );
-		visitor.processEntityPropertyValues( values, types );
-		return super.visitCollectionsBeforeSave( entity, id, values, types, source );
-	}
-
-	protected boolean substituteValuesIfNecessary(
-			Object entity,
-			Serializable id,
-			Object[] values,
-			EntityPersister persister,
-			SessionImplementor source) {
-		return false;
-	}
-
-	protected boolean isVersionIncrementDisabled() {
-		return true;
-	}
-
-	private void performReplication(
-			Object entity,
-			Serializable id,
-			Object version,
-			EntityPersister persister,
-			ReplicationMode replicationMode,
-			EventSource source) throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"replicating changes to " +
-							MessageHelper.infoString( persister, id, source.getFactory() )
-			);
-		}
-
-		new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );
-
-		source.getPersistenceContext().addEntity(
-				entity,
-				Status.MANAGED,
-				null,
-				new EntityKey( id, persister, source.getEntityMode() ),
-				version,
-				LockMode.NONE,
-				true,
-				persister,
-				true,
-				false
-		);
-
-		cascadeAfterReplicate( entity, persister, replicationMode, source );
-	}
-
-	private void cascadeAfterReplicate(
-			Object entity,
-			EntityPersister persister,
-			ReplicationMode replicationMode,
-			EventSource source) {
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source )
-					.cascade( persister, entity, replicationMode );
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.REPLICATE;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultReplicateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,229 @@
+/*
+ * 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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.ReplicationMode;
+import org.hibernate.LockMode;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.Status;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.ReplicateEvent;
+import org.hibernate.event.ReplicateEventListener;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines the default replicate event listener used by Hibernate to replicate
+ * entities in response to generated replicate events.
+ *
+ * @author Steve Ebersole
+ */
+public class DefaultReplicateEventListener extends AbstractSaveEventListener implements ReplicateEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger( DefaultReplicateEventListener.class );
+
+	/**
+	 * Handle the given replicate event.
+	 *
+	 * @param event The replicate event to be handled.
+	 *
+	 * @throws TransientObjectException An invalid attempt to replicate a transient entity.
+	 */
+	public void onReplicate(ReplicateEvent event) {
+		final EventSource source = event.getSession();
+		if ( source.getPersistenceContext().reassociateIfUninitializedProxy( event.getObject() ) ) {
+			log.trace( "uninitialized proxy passed to replicate()" );
+			return;
+		}
+
+		Object entity = source.getPersistenceContext().unproxyAndReassociate( event.getObject() );
+
+		if ( source.getPersistenceContext().isEntryFor( entity ) ) {
+			log.trace( "ignoring persistent instance passed to replicate()" );
+			//hum ... should we cascade anyway? throw an exception? fine like it is?
+			return;
+		}
+
+		EntityPersister persister = source.getEntityPersister( event.getEntityName(), entity );
+
+		// get the id from the object
+		/*if ( persister.isUnsaved(entity, source) ) {
+			throw new TransientObjectException("transient instance passed to replicate()");
+		}*/
+		Serializable id = persister.getIdentifier( entity, source.getEntityMode() );
+		if ( id == null ) {
+			throw new TransientObjectException( "instance with null id passed to replicate()" );
+		}
+
+		final ReplicationMode replicationMode = event.getReplicationMode();
+
+		final Object oldVersion;
+		if ( replicationMode == ReplicationMode.EXCEPTION ) {
+			//always do an INSERT, and let it fail by constraint violation
+			oldVersion = null;
+		}
+		else {
+			//what is the version on the database?
+			oldVersion = persister.getCurrentVersion( id, source );			
+		}
+
+		if ( oldVersion != null ) { 			
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"found existing row for " +
+								MessageHelper.infoString( persister, id, source.getFactory() )
+				);
+			}
+
+			/// HHH-2378
+			final Object realOldVersion = persister.isVersioned() ? oldVersion : null;
+			
+			boolean canReplicate = replicationMode.shouldOverwriteCurrentVersion(
+					entity,
+					realOldVersion,
+					persister.getVersion( entity, source.getEntityMode() ),
+					persister.getVersionType()
+			);
+
+			if ( canReplicate ) {
+				//will result in a SQL UPDATE:
+				performReplication( entity, id, realOldVersion, persister, replicationMode, source );
+			}
+			else {
+				//else do nothing (don't even reassociate object!)
+				log.trace( "no need to replicate" );
+			}
+
+			//TODO: would it be better to do a refresh from db?
+		}
+		else {
+			// no existing row - do an insert
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"no existing row, replicating new instance " +
+								MessageHelper.infoString( persister, id, source.getFactory() )
+				);
+			}
+
+			final boolean regenerate = persister.isIdentifierAssignedByInsert(); // prefer re-generation of identity!
+			final EntityKey key = regenerate ?
+					null : new EntityKey( id, persister, source.getEntityMode() );
+
+			performSaveOrReplicate(
+					entity,
+					key,
+					persister,
+					regenerate,
+					replicationMode,
+					source,
+					true
+			);
+
+		}
+	}
+
+	protected boolean visitCollectionsBeforeSave(Object entity, Serializable id, Object[] values, Type[] types, EventSource source) {
+		//TODO: we use two visitors here, inefficient!
+		OnReplicateVisitor visitor = new OnReplicateVisitor( source, id, entity, false );
+		visitor.processEntityPropertyValues( values, types );
+		return super.visitCollectionsBeforeSave( entity, id, values, types, source );
+	}
+
+	protected boolean substituteValuesIfNecessary(
+			Object entity,
+			Serializable id,
+			Object[] values,
+			EntityPersister persister,
+			SessionImplementor source) {
+		return false;
+	}
+
+	protected boolean isVersionIncrementDisabled() {
+		return true;
+	}
+
+	private void performReplication(
+			Object entity,
+			Serializable id,
+			Object version,
+			EntityPersister persister,
+			ReplicationMode replicationMode,
+			EventSource source) throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"replicating changes to " +
+							MessageHelper.infoString( persister, id, source.getFactory() )
+			);
+		}
+
+		new OnReplicateVisitor( source, id, entity, true ).process( entity, persister );
+
+		source.getPersistenceContext().addEntity(
+				entity,
+				Status.MANAGED,
+				null,
+				new EntityKey( id, persister, source.getEntityMode() ),
+				version,
+				LockMode.NONE,
+				true,
+				persister,
+				true,
+				false
+		);
+
+		cascadeAfterReplicate( entity, persister, replicationMode, source );
+	}
+
+	private void cascadeAfterReplicate(
+			Object entity,
+			EntityPersister persister,
+			ReplicationMode replicationMode,
+			EventSource source) {
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( CascadingAction.REPLICATE, Cascade.AFTER_UPDATE, source )
+					.cascade( persister, entity, replicationMode );
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.REPLICATE;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-//$Id: DefaultSaveEventListener.java 8486 2005-10-29 10:32:45Z oneovthafew $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.Hibernate;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.Status;
-import org.hibernate.event.SaveOrUpdateEvent;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * An event handler for save() events
- * @author Gavin King
- */
-public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
-
-	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
-		// this implementation is supposed to tolerate incorrect unsaved-value
-		// mappings, for the purpose of backward-compatibility
-		EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
-		if ( entry!=null && entry.getStatus() != Status.DELETED ) {
-			return entityIsPersistent(event);
-		}
-		else {
-			return entityIsTransient(event);
-		}
-	}
-	
-	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
-		if ( event.getRequestedId() == null ) {
-			return super.saveWithGeneratedOrRequestedId(event);
-		}
-		else {
-			return saveWithRequestedId( 
-					event.getEntity(), 
-					event.getRequestedId(), 
-					event.getEntityName(), 
-					null, 
-					event.getSession() 
-				);
-		}
-		
-	}
-
-	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
-		if ( !Hibernate.isInitialized(object) ) {
-			throw new PersistentObjectException("uninitialized proxy passed to save()");
-		}
-		else {
-			return false;
-		}
-	}
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.Hibernate;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.Status;
+import org.hibernate.event.SaveOrUpdateEvent;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * An event handler for save() events
+ * @author Gavin King
+ */
+public class DefaultSaveEventListener extends DefaultSaveOrUpdateEventListener {
+
+	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
+		// this implementation is supposed to tolerate incorrect unsaved-value
+		// mappings, for the purpose of backward-compatibility
+		EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
+		if ( entry!=null && entry.getStatus() != Status.DELETED ) {
+			return entityIsPersistent(event);
+		}
+		else {
+			return entityIsTransient(event);
+		}
+	}
+	
+	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
+		if ( event.getRequestedId() == null ) {
+			return super.saveWithGeneratedOrRequestedId(event);
+		}
+		else {
+			return saveWithRequestedId( 
+					event.getEntity(), 
+					event.getRequestedId(), 
+					event.getEntityName(), 
+					null, 
+					event.getSession() 
+				);
+		}
+		
+	}
+
+	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
+		if ( !Hibernate.isInitialized(object) ) {
+			throw new PersistentObjectException("uninitialized proxy passed to save()");
+		}
+		else {
+			return false;
+		}
+	}
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,12 +0,0 @@
-//$Id: DefaultSaveOrUpdateCopyEventListener.java 7793 2005-08-10 05:06:40Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.engine.CascadingAction;
-
-public class DefaultSaveOrUpdateCopyEventListener extends DefaultMergeEventListener {
-
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.SAVE_UPDATE_COPY;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateCopyEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.engine.CascadingAction;
+
+public class DefaultSaveOrUpdateCopyEventListener extends DefaultMergeEventListener {
+
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.SAVE_UPDATE_COPY;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,368 +0,0 @@
-// $Id: DefaultSaveOrUpdateEventListener.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.PersistentObjectException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.engine.Cascade;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Status;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.SaveOrUpdateEvent;
-import org.hibernate.event.SaveOrUpdateEventListener;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-
-/**
- * Defines the default listener used by Hibernate for handling save-update
- * events.
- *
- * @author Steve Ebersole
- * @author Gavin King
- */
-public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {
-
-	private static final Logger log = LoggerFactory.getLogger( DefaultSaveOrUpdateEventListener.class );
-
-	/**
-	 * Handle the given update event.
-	 *
-	 * @param event The update event to be handled.
-	 */
-	public void onSaveOrUpdate(SaveOrUpdateEvent event) {
-		final SessionImplementor source = event.getSession();
-		final Object object = event.getObject();
-		final Serializable requestedId = event.getRequestedId();
-
-		if ( requestedId != null ) {
-			//assign the requested id to the proxy, *before*
-			//reassociating the proxy
-			if ( object instanceof HibernateProxy ) {
-				( ( HibernateProxy ) object ).getHibernateLazyInitializer().setIdentifier( requestedId );
-			}
-		}
-
-		if ( reassociateIfUninitializedProxy( object, source ) ) {
-			log.trace( "reassociated uninitialized proxy" );
-			// an uninitialized proxy, noop, don't even need to
-			// return an id, since it is never a save()
-		}
-		else {
-			//initialize properties of the event:
-			final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );
-			event.setEntity( entity );
-			event.setEntry( source.getPersistenceContext().getEntry( entity ) );
-			//return the id in the event object
-			event.setResultId( performSaveOrUpdate( event ) );
-		}
-
-	}
-
-	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
-		return source.getPersistenceContext().reassociateIfUninitializedProxy( object );
-	}
-
-	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
-		int entityState = getEntityState(
-				event.getEntity(),
-				event.getEntityName(),
-				event.getEntry(),
-				event.getSession()
-		);
-
-		switch ( entityState ) {
-			case DETACHED:
-				entityIsDetached( event );
-				return null;
-			case PERSISTENT:
-				return entityIsPersistent( event );
-			default: //TRANSIENT or DELETED
-				return entityIsTransient( event );
-		}
-	}
-
-	protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
-		log.trace( "ignoring persistent instance" );
-
-		EntityEntry entityEntry = event.getEntry();
-		if ( entityEntry == null ) {
-			throw new AssertionFailure( "entity was transient or detached" );
-		}
-		else {
-
-			if ( entityEntry.getStatus() == Status.DELETED ) {
-				throw new AssertionFailure( "entity was deleted" );
-			}
-
-			final SessionFactoryImplementor factory = event.getSession().getFactory();
-
-			Serializable requestedId = event.getRequestedId();
-
-			Serializable savedId;
-			if ( requestedId == null ) {
-				savedId = entityEntry.getId();
-			}
-			else {
-
-				final boolean isEqual = !entityEntry.getPersister().getIdentifierType()
-						.isEqual( requestedId, entityEntry.getId(), event.getSession().getEntityMode(), factory );
-
-				if ( isEqual ) {
-					throw new PersistentObjectException(
-							"object passed to save() was already persistent: " +
-									MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
-					);
-				}
-
-				savedId = requestedId;
-
-			}
-
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"object already associated with session: " +
-								MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
-				);
-			}
-
-			return savedId;
-
-		}
-	}
-
-	/**
-	 * The given save-update event named a transient entity.
-	 * <p/>
-	 * Here, we will perform the save processing.
-	 *
-	 * @param event The save event to be handled.
-	 *
-	 * @return The entity's identifier after saving.
-	 */
-	protected Serializable entityIsTransient(SaveOrUpdateEvent event) {
-
-		log.trace( "saving transient instance" );
-
-		final EventSource source = event.getSession();
-
-		EntityEntry entityEntry = event.getEntry();
-		if ( entityEntry != null ) {
-			if ( entityEntry.getStatus() == Status.DELETED ) {
-				source.forceFlush( entityEntry );
-			}
-			else {
-				throw new AssertionFailure( "entity was persistent" );
-			}
-		}
-
-		Serializable id = saveWithGeneratedOrRequestedId( event );
-
-		source.getPersistenceContext().reassociateProxy( event.getObject(), id );
-
-		return id;
-	}
-
-	/**
-	 * Save the transient instance, assigning the right identifier
-	 *
-	 * @param event The initiating event.
-	 *
-	 * @return The entity's identifier value after saving.
-	 */
-	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
-		return saveWithGeneratedId(
-				event.getEntity(),
-				event.getEntityName(),
-				null,
-				event.getSession(),
-				true
-		);
-	}
-
-	/**
-	 * The given save-update event named a detached entity.
-	 * <p/>
-	 * Here, we will perform the update processing.
-	 *
-	 * @param event The update event to be handled.
-	 */
-	protected void entityIsDetached(SaveOrUpdateEvent event) {
-
-		log.trace( "updating detached instance" );
-
-
-		if ( event.getSession().getPersistenceContext().isEntryFor( event.getEntity() ) ) {
-			//TODO: assertion only, could be optimized away
-			throw new AssertionFailure( "entity was persistent" );
-		}
-
-		Object entity = event.getEntity();
-
-		EntityPersister persister = event.getSession().getEntityPersister( event.getEntityName(), entity );
-
-		event.setRequestedId(
-				getUpdateId(
-						entity, persister, event.getRequestedId(), event.getSession().getEntityMode()
-				)
-		);
-
-		performUpdate( event, entity, persister );
-
-	}
-
-	/**
-	 * Determine the id to use for updating.
-	 *
-	 * @param entity The entity.
-	 * @param persister The entity persister
-	 * @param requestedId The requested identifier
-	 * @param entityMode The entity mode.
-	 *
-	 * @return The id.
-	 *
-	 * @throws TransientObjectException If the entity is considered transient.
-	 */
-	protected Serializable getUpdateId(
-			Object entity,
-			EntityPersister persister,
-			Serializable requestedId,
-			EntityMode entityMode) {
-		// use the id assigned to the instance
-		Serializable id = persister.getIdentifier( entity, entityMode );
-		if ( id == null ) {
-			// assume this is a newly instantiated transient object
-			// which should be saved rather than updated
-			throw new TransientObjectException(
-					"The given object has a null identifier: " +
-							persister.getEntityName()
-			);
-		}
-		else {
-			return id;
-		}
-
-	}
-
-	protected void performUpdate(
-			SaveOrUpdateEvent event,
-			Object entity,
-			EntityPersister persister) throws HibernateException {
-
-		if ( !persister.isMutable() ) {
-			log.trace( "immutable instance passed to doUpdate(), locking" );
-			reassociate( event, entity, event.getRequestedId(), persister );
-		}
-		else {
-
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"updating " +
-								MessageHelper.infoString(
-										persister, event.getRequestedId(), event.getSession().getFactory()
-								)
-				);
-			}
-
-			final EventSource source = event.getSession();
-
-			EntityKey key = new EntityKey( event.getRequestedId(), persister, source.getEntityMode() );
-
-			source.getPersistenceContext().checkUniqueness( key, entity );
-
-			if ( invokeUpdateLifecycle( entity, persister, source ) ) {
-				reassociate( event, event.getObject(), event.getRequestedId(), persister );
-				return;
-			}
-
-			// this is a transient object with existing persistent state not loaded by the session
-
-			new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );
-
-			//TODO: put this stuff back in to read snapshot from
-			//      the second-level cache (needs some extra work)
-			/*Object[] cachedState = null;
-
-			if ( persister.hasCache() ) {
-				CacheEntry entry = (CacheEntry) persister.getCache()
-						.get( event.getRequestedId(), source.getTimestamp() );
-			    cachedState = entry==null ?
-			    		null :
-			    		entry.getState(); //TODO: half-assemble this stuff
-			}*/
-
-			source.getPersistenceContext().addEntity(
-					entity,
-					Status.MANAGED,
-					null, //cachedState,
-					key,
-					persister.getVersion( entity, source.getEntityMode() ),
-					LockMode.NONE,
-					true,
-					persister,
-					false,
-					true //assume true, since we don't really know, and it doesn't matter
-			);
-
-			persister.afterReassociate( entity, source );
-
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-						"updating " +
-								MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() )
-				);
-			}
-
-			cascadeOnUpdate( event, persister, entity );
-
-		}
-	}
-
-	protected boolean invokeUpdateLifecycle(Object entity, EntityPersister persister, EventSource source) {
-		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
-			log.debug( "calling onUpdate()" );
-			if ( ( ( Lifecycle ) entity ).onUpdate( source ) ) {
-				log.debug( "update vetoed by onUpdate()" );
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Handles the calls needed to perform cascades as part of an update request
-	 * for the given entity.
-	 *
-	 * @param event The event currently being processed.
-	 * @param persister The defined persister for the entity being updated.
-	 * @param entity The entity being updated.
-	 */
-	private void cascadeOnUpdate(SaveOrUpdateEvent event, EntityPersister persister, Object entity) {
-		EventSource source = event.getSession();
-		source.getPersistenceContext().incrementCascadeLevel();
-		try {
-			new Cascade( CascadingAction.SAVE_UPDATE, Cascade.AFTER_UPDATE, source )
-					.cascade( persister, entity );
-		}
-		finally {
-			source.getPersistenceContext().decrementCascadeLevel();
-		}
-	}
-
-	protected CascadingAction getCascadeAction() {
-		return CascadingAction.SAVE_UPDATE;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultSaveOrUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,391 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.PersistentObjectException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.engine.Cascade;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Status;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.SaveOrUpdateEvent;
+import org.hibernate.event.SaveOrUpdateEventListener;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+
+/**
+ * Defines the default listener used by Hibernate for handling save-update
+ * events.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class DefaultSaveOrUpdateEventListener extends AbstractSaveEventListener implements SaveOrUpdateEventListener {
+
+	private static final Logger log = LoggerFactory.getLogger( DefaultSaveOrUpdateEventListener.class );
+
+	/**
+	 * Handle the given update event.
+	 *
+	 * @param event The update event to be handled.
+	 */
+	public void onSaveOrUpdate(SaveOrUpdateEvent event) {
+		final SessionImplementor source = event.getSession();
+		final Object object = event.getObject();
+		final Serializable requestedId = event.getRequestedId();
+
+		if ( requestedId != null ) {
+			//assign the requested id to the proxy, *before*
+			//reassociating the proxy
+			if ( object instanceof HibernateProxy ) {
+				( ( HibernateProxy ) object ).getHibernateLazyInitializer().setIdentifier( requestedId );
+			}
+		}
+
+		if ( reassociateIfUninitializedProxy( object, source ) ) {
+			log.trace( "reassociated uninitialized proxy" );
+			// an uninitialized proxy, noop, don't even need to
+			// return an id, since it is never a save()
+		}
+		else {
+			//initialize properties of the event:
+			final Object entity = source.getPersistenceContext().unproxyAndReassociate( object );
+			event.setEntity( entity );
+			event.setEntry( source.getPersistenceContext().getEntry( entity ) );
+			//return the id in the event object
+			event.setResultId( performSaveOrUpdate( event ) );
+		}
+
+	}
+
+	protected boolean reassociateIfUninitializedProxy(Object object, SessionImplementor source) {
+		return source.getPersistenceContext().reassociateIfUninitializedProxy( object );
+	}
+
+	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
+		int entityState = getEntityState(
+				event.getEntity(),
+				event.getEntityName(),
+				event.getEntry(),
+				event.getSession()
+		);
+
+		switch ( entityState ) {
+			case DETACHED:
+				entityIsDetached( event );
+				return null;
+			case PERSISTENT:
+				return entityIsPersistent( event );
+			default: //TRANSIENT or DELETED
+				return entityIsTransient( event );
+		}
+	}
+
+	protected Serializable entityIsPersistent(SaveOrUpdateEvent event) throws HibernateException {
+		log.trace( "ignoring persistent instance" );
+
+		EntityEntry entityEntry = event.getEntry();
+		if ( entityEntry == null ) {
+			throw new AssertionFailure( "entity was transient or detached" );
+		}
+		else {
+
+			if ( entityEntry.getStatus() == Status.DELETED ) {
+				throw new AssertionFailure( "entity was deleted" );
+			}
+
+			final SessionFactoryImplementor factory = event.getSession().getFactory();
+
+			Serializable requestedId = event.getRequestedId();
+
+			Serializable savedId;
+			if ( requestedId == null ) {
+				savedId = entityEntry.getId();
+			}
+			else {
+
+				final boolean isEqual = !entityEntry.getPersister().getIdentifierType()
+						.isEqual( requestedId, entityEntry.getId(), event.getSession().getEntityMode(), factory );
+
+				if ( isEqual ) {
+					throw new PersistentObjectException(
+							"object passed to save() was already persistent: " +
+									MessageHelper.infoString( entityEntry.getPersister(), requestedId, factory )
+					);
+				}
+
+				savedId = requestedId;
+
+			}
+
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"object already associated with session: " +
+								MessageHelper.infoString( entityEntry.getPersister(), savedId, factory )
+				);
+			}
+
+			return savedId;
+
+		}
+	}
+
+	/**
+	 * The given save-update event named a transient entity.
+	 * <p/>
+	 * Here, we will perform the save processing.
+	 *
+	 * @param event The save event to be handled.
+	 *
+	 * @return The entity's identifier after saving.
+	 */
+	protected Serializable entityIsTransient(SaveOrUpdateEvent event) {
+
+		log.trace( "saving transient instance" );
+
+		final EventSource source = event.getSession();
+
+		EntityEntry entityEntry = event.getEntry();
+		if ( entityEntry != null ) {
+			if ( entityEntry.getStatus() == Status.DELETED ) {
+				source.forceFlush( entityEntry );
+			}
+			else {
+				throw new AssertionFailure( "entity was persistent" );
+			}
+		}
+
+		Serializable id = saveWithGeneratedOrRequestedId( event );
+
+		source.getPersistenceContext().reassociateProxy( event.getObject(), id );
+
+		return id;
+	}
+
+	/**
+	 * Save the transient instance, assigning the right identifier
+	 *
+	 * @param event The initiating event.
+	 *
+	 * @return The entity's identifier value after saving.
+	 */
+	protected Serializable saveWithGeneratedOrRequestedId(SaveOrUpdateEvent event) {
+		return saveWithGeneratedId(
+				event.getEntity(),
+				event.getEntityName(),
+				null,
+				event.getSession(),
+				true
+		);
+	}
+
+	/**
+	 * The given save-update event named a detached entity.
+	 * <p/>
+	 * Here, we will perform the update processing.
+	 *
+	 * @param event The update event to be handled.
+	 */
+	protected void entityIsDetached(SaveOrUpdateEvent event) {
+
+		log.trace( "updating detached instance" );
+
+
+		if ( event.getSession().getPersistenceContext().isEntryFor( event.getEntity() ) ) {
+			//TODO: assertion only, could be optimized away
+			throw new AssertionFailure( "entity was persistent" );
+		}
+
+		Object entity = event.getEntity();
+
+		EntityPersister persister = event.getSession().getEntityPersister( event.getEntityName(), entity );
+
+		event.setRequestedId(
+				getUpdateId(
+						entity, persister, event.getRequestedId(), event.getSession().getEntityMode()
+				)
+		);
+
+		performUpdate( event, entity, persister );
+
+	}
+
+	/**
+	 * Determine the id to use for updating.
+	 *
+	 * @param entity The entity.
+	 * @param persister The entity persister
+	 * @param requestedId The requested identifier
+	 * @param entityMode The entity mode.
+	 *
+	 * @return The id.
+	 *
+	 * @throws TransientObjectException If the entity is considered transient.
+	 */
+	protected Serializable getUpdateId(
+			Object entity,
+			EntityPersister persister,
+			Serializable requestedId,
+			EntityMode entityMode) {
+		// use the id assigned to the instance
+		Serializable id = persister.getIdentifier( entity, entityMode );
+		if ( id == null ) {
+			// assume this is a newly instantiated transient object
+			// which should be saved rather than updated
+			throw new TransientObjectException(
+					"The given object has a null identifier: " +
+							persister.getEntityName()
+			);
+		}
+		else {
+			return id;
+		}
+
+	}
+
+	protected void performUpdate(
+			SaveOrUpdateEvent event,
+			Object entity,
+			EntityPersister persister) throws HibernateException {
+
+		if ( !persister.isMutable() ) {
+			log.trace( "immutable instance passed to doUpdate(), locking" );
+			reassociate( event, entity, event.getRequestedId(), persister );
+		}
+		else {
+
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"updating " +
+								MessageHelper.infoString(
+										persister, event.getRequestedId(), event.getSession().getFactory()
+								)
+				);
+			}
+
+			final EventSource source = event.getSession();
+
+			EntityKey key = new EntityKey( event.getRequestedId(), persister, source.getEntityMode() );
+
+			source.getPersistenceContext().checkUniqueness( key, entity );
+
+			if ( invokeUpdateLifecycle( entity, persister, source ) ) {
+				reassociate( event, event.getObject(), event.getRequestedId(), persister );
+				return;
+			}
+
+			// this is a transient object with existing persistent state not loaded by the session
+
+			new OnUpdateVisitor( source, event.getRequestedId(), entity ).process( entity, persister );
+
+			//TODO: put this stuff back in to read snapshot from
+			//      the second-level cache (needs some extra work)
+			/*Object[] cachedState = null;
+
+			if ( persister.hasCache() ) {
+				CacheEntry entry = (CacheEntry) persister.getCache()
+						.get( event.getRequestedId(), source.getTimestamp() );
+			    cachedState = entry==null ?
+			    		null :
+			    		entry.getState(); //TODO: half-assemble this stuff
+			}*/
+
+			source.getPersistenceContext().addEntity(
+					entity,
+					Status.MANAGED,
+					null, //cachedState,
+					key,
+					persister.getVersion( entity, source.getEntityMode() ),
+					LockMode.NONE,
+					true,
+					persister,
+					false,
+					true //assume true, since we don't really know, and it doesn't matter
+			);
+
+			persister.afterReassociate( entity, source );
+
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+						"updating " +
+								MessageHelper.infoString( persister, event.getRequestedId(), source.getFactory() )
+				);
+			}
+
+			cascadeOnUpdate( event, persister, entity );
+
+		}
+	}
+
+	protected boolean invokeUpdateLifecycle(Object entity, EntityPersister persister, EventSource source) {
+		if ( persister.implementsLifecycle( source.getEntityMode() ) ) {
+			log.debug( "calling onUpdate()" );
+			if ( ( ( Lifecycle ) entity ).onUpdate( source ) ) {
+				log.debug( "update vetoed by onUpdate()" );
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Handles the calls needed to perform cascades as part of an update request
+	 * for the given entity.
+	 *
+	 * @param event The event currently being processed.
+	 * @param persister The defined persister for the entity being updated.
+	 * @param entity The entity being updated.
+	 */
+	private void cascadeOnUpdate(SaveOrUpdateEvent event, EntityPersister persister, Object entity) {
+		EventSource source = event.getSession();
+		source.getPersistenceContext().incrementCascadeLevel();
+		try {
+			new Cascade( CascadingAction.SAVE_UPDATE, Cascade.AFTER_UPDATE, source )
+					.cascade( persister, entity );
+		}
+		finally {
+			source.getPersistenceContext().decrementCascadeLevel();
+		}
+	}
+
+	protected CascadingAction getCascadeAction() {
+		return CascadingAction.SAVE_UPDATE;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: DefaultUpdateEventListener.java 5839 2005-02-22 03:09:35Z oneovthafew $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.EntityMode;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.Status;
-import org.hibernate.event.SaveOrUpdateEvent;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * An event handler for update() events
- * @author Gavin King
- */
-public class DefaultUpdateEventListener extends DefaultSaveOrUpdateEventListener {
-
-	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
-		// this implementation is supposed to tolerate incorrect unsaved-value
-		// mappings, for the purpose of backward-compatibility
-		EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
-		if ( entry!=null ) {
-			if ( entry.getStatus()==Status.DELETED ) {
-				throw new ObjectDeletedException( "deleted instance passed to update()", null, event.getEntityName() );
-			}
-			else {
-				return entityIsPersistent(event);
-			}
-		}
-		else {
-			entityIsDetached(event);
-			return null;
-		}
-	}
-	
-	/**
-	 * If the user specified an id, assign it to the instance and use that, 
-	 * otherwise use the id already assigned to the instance
-	 */
-	protected Serializable getUpdateId(Object entity, EntityPersister persister, Serializable requestedId, EntityMode entityMode)
-	throws HibernateException {
-
-		if ( requestedId==null ) {
-			return super.getUpdateId(entity, persister, requestedId, entityMode);
-		}
-		else {
-			persister.setIdentifier(entity, requestedId, entityMode);
-			return requestedId;
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DefaultUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.Status;
+import org.hibernate.event.SaveOrUpdateEvent;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * An event handler for update() events
+ * @author Gavin King
+ */
+public class DefaultUpdateEventListener extends DefaultSaveOrUpdateEventListener {
+
+	protected Serializable performSaveOrUpdate(SaveOrUpdateEvent event) {
+		// this implementation is supposed to tolerate incorrect unsaved-value
+		// mappings, for the purpose of backward-compatibility
+		EntityEntry entry = event.getSession().getPersistenceContext().getEntry( event.getEntity() );
+		if ( entry!=null ) {
+			if ( entry.getStatus()==Status.DELETED ) {
+				throw new ObjectDeletedException( "deleted instance passed to update()", null, event.getEntityName() );
+			}
+			else {
+				return entityIsPersistent(event);
+			}
+		}
+		else {
+			entityIsDetached(event);
+			return null;
+		}
+	}
+	
+	/**
+	 * If the user specified an id, assign it to the instance and use that, 
+	 * otherwise use the id already assigned to the instance
+	 */
+	protected Serializable getUpdateId(Object entity, EntityPersister persister, Serializable requestedId, EntityMode entityMode)
+	throws HibernateException {
+
+		if ( requestedId==null ) {
+			return super.getUpdateId(entity, persister, requestedId, entityMode);
+		}
+		else {
+			persister.setIdentifier(entity, requestedId, entityMode);
+			return requestedId;
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-//$Id: DirtyCollectionSearchVisitor.java 7675 2005-07-29 06:25:23Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.type.CollectionType;
-
-/**
- * Do we have a dirty collection here?
- * 1. if it is a new application-instantiated collection, return true (does not occur anymore!)
- * 2. if it is a component, recurse
- * 3. if it is a wrappered collection, ask the collection entry
- *
- * @author Gavin King
- */
-public class DirtyCollectionSearchVisitor extends AbstractVisitor {
-
-	private boolean dirty = false;
-	private boolean[] propertyVersionability;
-
-	DirtyCollectionSearchVisitor(EventSource session, boolean[] propertyVersionability) {
-		super(session);
-		this.propertyVersionability = propertyVersionability;
-	}
-
-	boolean wasDirtyCollectionFound() {
-		return dirty;
-	}
-
-	Object processCollection(Object collection, CollectionType type)
-		throws HibernateException {
-
-		if (collection!=null) {
-
-			SessionImplementor session = getSession();
-
-			final PersistentCollection persistentCollection;
-			if ( type.isArrayType() ) {
-				 persistentCollection = session.getPersistenceContext().getCollectionHolder(collection);
-				// if no array holder we found an unwrappered array (this can't occur,
-				// because we now always call wrap() before getting to here)
-				// return (ah==null) ? true : searchForDirtyCollections(ah, type);
-			}
-			else {
-				// if not wrappered yet, its dirty (this can't occur, because
-				// we now always call wrap() before getting to here)
-				// return ( ! (obj instanceof PersistentCollection) ) ?
-				//true : searchForDirtyCollections( (PersistentCollection) obj, type );
-				persistentCollection = (PersistentCollection) collection;
-			}
-
-			if ( persistentCollection.isDirty() ) { //we need to check even if it was not initialized, because of delayed adds!
-				dirty=true;
-				return null; //NOTE: EARLY EXIT!
-			}
-		}
-
-		return null;
-	}
-
-	boolean includeEntityProperty(Object[] values, int i) {
-		return propertyVersionability[i] && super.includeEntityProperty(values, i);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/DirtyCollectionSearchVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,89 @@
+/*
+ * 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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.type.CollectionType;
+
+/**
+ * Do we have a dirty collection here?
+ * 1. if it is a new application-instantiated collection, return true (does not occur anymore!)
+ * 2. if it is a component, recurse
+ * 3. if it is a wrappered collection, ask the collection entry
+ *
+ * @author Gavin King
+ */
+public class DirtyCollectionSearchVisitor extends AbstractVisitor {
+
+	private boolean dirty = false;
+	private boolean[] propertyVersionability;
+
+	DirtyCollectionSearchVisitor(EventSource session, boolean[] propertyVersionability) {
+		super(session);
+		this.propertyVersionability = propertyVersionability;
+	}
+
+	boolean wasDirtyCollectionFound() {
+		return dirty;
+	}
+
+	Object processCollection(Object collection, CollectionType type)
+		throws HibernateException {
+
+		if (collection!=null) {
+
+			SessionImplementor session = getSession();
+
+			final PersistentCollection persistentCollection;
+			if ( type.isArrayType() ) {
+				 persistentCollection = session.getPersistenceContext().getCollectionHolder(collection);
+				// if no array holder we found an unwrappered array (this can't occur,
+				// because we now always call wrap() before getting to here)
+				// return (ah==null) ? true : searchForDirtyCollections(ah, type);
+			}
+			else {
+				// if not wrappered yet, its dirty (this can't occur, because
+				// we now always call wrap() before getting to here)
+				// return ( ! (obj instanceof PersistentCollection) ) ?
+				//true : searchForDirtyCollections( (PersistentCollection) obj, type );
+				persistentCollection = (PersistentCollection) collection;
+			}
+
+			if ( persistentCollection.isDirty() ) { //we need to check even if it was not initialized, because of delayed adds!
+				dirty=true;
+				return null; //NOTE: EARLY EXIT!
+			}
+		}
+
+		return null;
+	}
+
+	boolean includeEntityProperty(Object[] values, int i) {
+		return propertyVersionability[i] && super.includeEntityProperty(values, i);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/EvictVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-//$Id: EvictVisitor.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.CollectionKey;
-import org.hibernate.event.EventSource;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.CollectionType;
-
-/**
- * Evict any collections referenced by the object from the session cache.
- * This will NOT pick up any collections that were dereferenced, so they
- * will be deleted (suboptimal but not exactly incorrect).
- *
- * @author Gavin King
- */
-public class EvictVisitor extends AbstractVisitor {
-	
-	private static final Logger log = LoggerFactory.getLogger(EvictVisitor.class);
-
-	EvictVisitor(EventSource session) {
-		super(session);
-	}
-
-	Object processCollection(Object collection, CollectionType type)
-		throws HibernateException {
-
-		if (collection!=null) evictCollection(collection, type);
-
-		return null;
-	}
-	public void evictCollection(Object value, CollectionType type) {
-
-		final Object pc;
-		if ( type.hasHolder( getSession().getEntityMode() ) ) {
-			pc = getSession().getPersistenceContext().removeCollectionHolder(value);
-		}
-		else if ( value instanceof PersistentCollection ) {
-			pc = value;
-		}
-		else {
-			return; //EARLY EXIT!
-		}
-
-		PersistentCollection collection = (PersistentCollection) pc;
-		if ( collection.unsetSession( getSession() ) ) evictCollection(collection);
-	}
-
-	private void evictCollection(PersistentCollection collection) {
-		CollectionEntry ce = (CollectionEntry) getSession().getPersistenceContext().getCollectionEntries().remove(collection);
-		if ( log.isDebugEnabled() )
-			log.debug(
-					"evicting collection: " +
-					MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getFactory() )
-			);
-		if ( ce.getLoadedPersister() != null && ce.getLoadedKey() != null ) {
-			//TODO: is this 100% correct?
-			getSession().getPersistenceContext().getCollectionsByKey().remove( 
-					new CollectionKey( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getEntityMode() ) 
-			);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/EvictVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/EvictVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.event.def;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.CollectionKey;
+import org.hibernate.event.EventSource;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.CollectionType;
+
+/**
+ * Evict any collections referenced by the object from the session cache.
+ * This will NOT pick up any collections that were dereferenced, so they
+ * will be deleted (suboptimal but not exactly incorrect).
+ *
+ * @author Gavin King
+ */
+public class EvictVisitor extends AbstractVisitor {
+	
+	private static final Logger log = LoggerFactory.getLogger(EvictVisitor.class);
+
+	EvictVisitor(EventSource session) {
+		super(session);
+	}
+
+	Object processCollection(Object collection, CollectionType type)
+		throws HibernateException {
+
+		if (collection!=null) evictCollection(collection, type);
+
+		return null;
+	}
+	public void evictCollection(Object value, CollectionType type) {
+
+		final Object pc;
+		if ( type.hasHolder( getSession().getEntityMode() ) ) {
+			pc = getSession().getPersistenceContext().removeCollectionHolder(value);
+		}
+		else if ( value instanceof PersistentCollection ) {
+			pc = value;
+		}
+		else {
+			return; //EARLY EXIT!
+		}
+
+		PersistentCollection collection = (PersistentCollection) pc;
+		if ( collection.unsetSession( getSession() ) ) evictCollection(collection);
+	}
+
+	private void evictCollection(PersistentCollection collection) {
+		CollectionEntry ce = (CollectionEntry) getSession().getPersistenceContext().getCollectionEntries().remove(collection);
+		if ( log.isDebugEnabled() )
+			log.debug(
+					"evicting collection: " +
+					MessageHelper.collectionInfoString( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getFactory() )
+			);
+		if ( ce.getLoadedPersister() != null && ce.getLoadedKey() != null ) {
+			//TODO: is this 100% correct?
+			getSession().getPersistenceContext().getCollectionsByKey().remove( 
+					new CollectionKey( ce.getLoadedPersister(), ce.getLoadedKey(), getSession().getEntityMode() ) 
+			);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/FlushVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: FlushVisitor.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.Collections;
-import org.hibernate.event.EventSource;
-import org.hibernate.type.CollectionType;
-
-/**
- * Process collections reachable from an entity. This
- * visitor assumes that wrap was already performed for
- * the entity.
- *
- * @author Gavin King
- */
-public class FlushVisitor extends AbstractVisitor {
-	
-	private Object owner;
-
-	Object processCollection(Object collection, CollectionType type)
-	throws HibernateException {
-		
-		if (collection==CollectionType.UNFETCHED_COLLECTION) {
-			return null;
-		}
-
-		if (collection!=null) {
-			final PersistentCollection coll;
-			if ( type.hasHolder( getSession().getEntityMode() ) ) {
-				coll = getSession().getPersistenceContext().getCollectionHolder(collection);
-			}
-			else {
-				coll = (PersistentCollection) collection;
-			}
-
-			Collections.processReachableCollection( coll, type, owner, getSession() );
-		}
-
-		return null;
-
-	}
-
-	FlushVisitor(EventSource session, Object owner) {
-		super(session);
-		this.owner = owner;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/FlushVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/FlushVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.event.def;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.Collections;
+import org.hibernate.event.EventSource;
+import org.hibernate.type.CollectionType;
+
+/**
+ * Process collections reachable from an entity. This
+ * visitor assumes that wrap was already performed for
+ * the entity.
+ *
+ * @author Gavin King
+ */
+public class FlushVisitor extends AbstractVisitor {
+	
+	private Object owner;
+
+	Object processCollection(Object collection, CollectionType type)
+	throws HibernateException {
+		
+		if (collection==CollectionType.UNFETCHED_COLLECTION) {
+			return null;
+		}
+
+		if (collection!=null) {
+			final PersistentCollection coll;
+			if ( type.hasHolder( getSession().getEntityMode() ) ) {
+				coll = getSession().getPersistenceContext().getCollectionHolder(collection);
+			}
+			else {
+				coll = (PersistentCollection) collection;
+			}
+
+			Collections.processReachableCollection( coll, type, owner, getSession() );
+		}
+
+		return null;
+
+	}
+
+	FlushVisitor(EventSource session, Object owner) {
+		super(session);
+		this.owner = owner;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-//$Id: OnLockVisitor.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.CollectionType;
-
-/**
- * When a transient entity is passed to lock(), we must inspect all its collections and
- * 1. associate any uninitialized PersistentCollections with this session
- * 2. associate any initialized PersistentCollections with this session, using the
- * existing snapshot
- * 3. throw an exception for each "new" collection
- *
- * @author Gavin King
- */
-public class OnLockVisitor extends ReattachVisitor {
-
-	public OnLockVisitor(EventSource session, Serializable key, Object owner) {
-		super( session, key, owner );
-	}
-
-	Object processCollection(Object collection, CollectionType type) throws HibernateException {
-
-		SessionImplementor session = getSession();
-		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
-
-		if ( collection == null ) {
-			//do nothing
-		}
-		else if ( collection instanceof PersistentCollection ) {
-			PersistentCollection persistentCollection = ( PersistentCollection ) collection;
-			if ( persistentCollection.setCurrentSession( session ) ) {
-				if ( isOwnerUnchanged( persistentCollection, persister, extractCollectionKeyFromOwner( persister ) ) ) {
-					// a "detached" collection that originally belonged to the same entity
-					if ( persistentCollection.isDirty() ) {
-						throw new HibernateException( "reassociated object has dirty collection" );
-					}
-					reattachCollection( persistentCollection, type );
-				}
-				else {
-					// a "detached" collection that belonged to a different entity
-					throw new HibernateException( "reassociated object has dirty collection reference" );
-				}
-			}
-			else {
-				// a collection loaded in the current session
-				// can not possibly be the collection belonging
-				// to the entity passed to update()
-				throw new HibernateException( "reassociated object has dirty collection reference" );
-			}
-		}
-		else {
-			// brand new collection
-			//TODO: or an array!! we can't lock objects with arrays now??
-			throw new HibernateException( "reassociated object has dirty collection reference (or an array)" );
-		}
-
-		return null;
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnLockVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.CollectionType;
+
+/**
+ * When a transient entity is passed to lock(), we must inspect all its collections and
+ * 1. associate any uninitialized PersistentCollections with this session
+ * 2. associate any initialized PersistentCollections with this session, using the
+ * existing snapshot
+ * 3. throw an exception for each "new" collection
+ *
+ * @author Gavin King
+ */
+public class OnLockVisitor extends ReattachVisitor {
+
+	public OnLockVisitor(EventSource session, Serializable key, Object owner) {
+		super( session, key, owner );
+	}
+
+	Object processCollection(Object collection, CollectionType type) throws HibernateException {
+
+		SessionImplementor session = getSession();
+		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
+
+		if ( collection == null ) {
+			//do nothing
+		}
+		else if ( collection instanceof PersistentCollection ) {
+			PersistentCollection persistentCollection = ( PersistentCollection ) collection;
+			if ( persistentCollection.setCurrentSession( session ) ) {
+				if ( isOwnerUnchanged( persistentCollection, persister, extractCollectionKeyFromOwner( persister ) ) ) {
+					// a "detached" collection that originally belonged to the same entity
+					if ( persistentCollection.isDirty() ) {
+						throw new HibernateException( "reassociated object has dirty collection" );
+					}
+					reattachCollection( persistentCollection, type );
+				}
+				else {
+					// a "detached" collection that belonged to a different entity
+					throw new HibernateException( "reassociated object has dirty collection reference" );
+				}
+			}
+			else {
+				// a collection loaded in the current session
+				// can not possibly be the collection belonging
+				// to the entity passed to update()
+				throw new HibernateException( "reassociated object has dirty collection reference" );
+			}
+		}
+		else {
+			// brand new collection
+			//TODO: or an array!! we can't lock objects with arrays now??
+			throw new HibernateException( "reassociated object has dirty collection reference (or an array)" );
+		}
+
+		return null;
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-//$Id: OnReplicateVisitor.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.CollectionType;
-
-/**
- * When an entity is passed to replicate(), and there is an existing row, we must
- * inspect all its collections and
- * 1. associate any uninitialized PersistentCollections with this session
- * 2. associate any initialized PersistentCollections with this session, using the
- * existing snapshot
- * 3. execute a collection removal (SQL DELETE) for each null collection property
- * or "new" collection
- *
- * @author Gavin King
- */
-public class OnReplicateVisitor extends ReattachVisitor {
-
-	private boolean isUpdate;
-
-	OnReplicateVisitor(EventSource session, Serializable key, Object owner, boolean isUpdate) {
-		super( session, key, owner );
-		this.isUpdate = isUpdate;
-	}
-
-	Object processCollection(Object collection, CollectionType type)
-			throws HibernateException {
-
-		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
-			return null;
-		}
-
-		EventSource session = getSession();
-		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
-
-		if ( isUpdate ) {
-			removeCollection( persister, extractCollectionKeyFromOwner( persister ), session );
-		}
-		if ( collection != null && ( collection instanceof PersistentCollection ) ) {
-			PersistentCollection wrapper = ( PersistentCollection ) collection;
-			wrapper.setCurrentSession( session );
-			if ( wrapper.wasInitialized() ) {
-				session.getPersistenceContext().addNewCollection( persister, wrapper );
-			}
-			else {
-				reattachCollection( wrapper, type );
-			}
-		}
-		else {
-			// otherwise a null or brand new collection
-			// this will also (inefficiently) handle arrays, which
-			// have no snapshot, so we can't do any better
-			//processArrayOrNewCollection(collection, type);
-		}
-
-		return null;
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnReplicateVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,89 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.CollectionType;
+
+/**
+ * When an entity is passed to replicate(), and there is an existing row, we must
+ * inspect all its collections and
+ * 1. associate any uninitialized PersistentCollections with this session
+ * 2. associate any initialized PersistentCollections with this session, using the
+ * existing snapshot
+ * 3. execute a collection removal (SQL DELETE) for each null collection property
+ * or "new" collection
+ *
+ * @author Gavin King
+ */
+public class OnReplicateVisitor extends ReattachVisitor {
+
+	private boolean isUpdate;
+
+	OnReplicateVisitor(EventSource session, Serializable key, Object owner, boolean isUpdate) {
+		super( session, key, owner );
+		this.isUpdate = isUpdate;
+	}
+
+	Object processCollection(Object collection, CollectionType type)
+			throws HibernateException {
+
+		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
+			return null;
+		}
+
+		EventSource session = getSession();
+		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
+
+		if ( isUpdate ) {
+			removeCollection( persister, extractCollectionKeyFromOwner( persister ), session );
+		}
+		if ( collection != null && ( collection instanceof PersistentCollection ) ) {
+			PersistentCollection wrapper = ( PersistentCollection ) collection;
+			wrapper.setCurrentSession( session );
+			if ( wrapper.wasInitialized() ) {
+				session.getPersistenceContext().addNewCollection( persister, wrapper );
+			}
+			else {
+				reattachCollection( wrapper, type );
+			}
+		}
+		else {
+			// otherwise a null or brand new collection
+			// this will also (inefficiently) handle arrays, which
+			// have no snapshot, so we can't do any better
+			//processArrayOrNewCollection(collection, type);
+		}
+
+		return null;
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-//$Id: OnUpdateVisitor.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.CollectionType;
-
-/**
- * When an entity is passed to update(), we must inspect all its collections and
- * 1. associate any uninitialized PersistentCollections with this session
- * 2. associate any initialized PersistentCollections with this session, using the
- *    existing snapshot
- * 3. execute a collection removal (SQL DELETE) for each null collection property
- *    or "new" collection
- *
- * @author Gavin King
- */
-public class OnUpdateVisitor extends ReattachVisitor {
-
-	OnUpdateVisitor(EventSource session, Serializable key, Object owner) {
-		super( session, key, owner );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	Object processCollection(Object collection, CollectionType type) throws HibernateException {
-
-		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
-			return null;
-		}
-
-		EventSource session = getSession();
-		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
-
-		final Serializable collectionKey = extractCollectionKeyFromOwner( persister );
-		if ( collection!=null && (collection instanceof PersistentCollection) ) {
-			PersistentCollection wrapper = (PersistentCollection) collection;
-			if ( wrapper.setCurrentSession(session) ) {
-				//a "detached" collection!
-				if ( !isOwnerUnchanged( wrapper, persister, collectionKey ) ) {
-					// if the collection belonged to a different entity,
-					// clean up the existing state of the collection
-					removeCollection( persister, collectionKey, session );
-				}
-				reattachCollection(wrapper, type);
-			}
-			else {
-				// a collection loaded in the current session
-				// can not possibly be the collection belonging
-				// to the entity passed to update()
-				removeCollection(persister, collectionKey, session);
-			}
-		}
-		else {
-			// null or brand new collection
-			// this will also (inefficiently) handle arrays, which have
-			// no snapshot, so we can't do any better
-			removeCollection(persister, collectionKey, session);
-		}
-
-		return null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/OnUpdateVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.CollectionType;
+
+/**
+ * When an entity is passed to update(), we must inspect all its collections and
+ * 1. associate any uninitialized PersistentCollections with this session
+ * 2. associate any initialized PersistentCollections with this session, using the
+ *    existing snapshot
+ * 3. execute a collection removal (SQL DELETE) for each null collection property
+ *    or "new" collection
+ *
+ * @author Gavin King
+ */
+public class OnUpdateVisitor extends ReattachVisitor {
+
+	OnUpdateVisitor(EventSource session, Serializable key, Object owner) {
+		super( session, key, owner );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	Object processCollection(Object collection, CollectionType type) throws HibernateException {
+
+		if ( collection == CollectionType.UNFETCHED_COLLECTION ) {
+			return null;
+		}
+
+		EventSource session = getSession();
+		CollectionPersister persister = session.getFactory().getCollectionPersister( type.getRole() );
+
+		final Serializable collectionKey = extractCollectionKeyFromOwner( persister );
+		if ( collection!=null && (collection instanceof PersistentCollection) ) {
+			PersistentCollection wrapper = (PersistentCollection) collection;
+			if ( wrapper.setCurrentSession(session) ) {
+				//a "detached" collection!
+				if ( !isOwnerUnchanged( wrapper, persister, collectionKey ) ) {
+					// if the collection belonged to a different entity,
+					// clean up the existing state of the collection
+					removeCollection( persister, collectionKey, session );
+				}
+				reattachCollection(wrapper, type);
+			}
+			else {
+				// a collection loaded in the current session
+				// can not possibly be the collection belonging
+				// to the entity passed to update()
+				removeCollection(persister, collectionKey, session);
+			}
+		}
+		else {
+			// null or brand new collection
+			// this will also (inefficiently) handle arrays, which have
+			// no snapshot, so we can't do any better
+			removeCollection(persister, collectionKey, session);
+		}
+
+		return null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,79 +0,0 @@
-//$Id: ProxyVisitor.java 7181 2005-06-17 19:36:08Z oneovthafew $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-
-/**
- * Reassociates uninitialized proxies with the session
- * @author Gavin King
- */
-public abstract class ProxyVisitor extends AbstractVisitor {
-
-
-	public ProxyVisitor(EventSource session) {
-		super(session);
-	}
-
-	Object processEntity(Object value, EntityType entityType) throws HibernateException {
-
-		if (value!=null) {
-			getSession().getPersistenceContext().reassociateIfUninitializedProxy(value);
-			// if it is an initialized proxy, let cascade
-			// handle it later on
-		}
-
-		return null;
-	}
-
-	/**
-	 * Has the owner of the collection changed since the collection
-	 * was snapshotted and detached?
-	 */
-	protected static boolean isOwnerUnchanged(
-			final PersistentCollection snapshot, 
-			final CollectionPersister persister, 
-			final Serializable id
-	) {
-		return isCollectionSnapshotValid(snapshot) &&
-				persister.getRole().equals( snapshot.getRole() ) &&
-				id.equals( snapshot.getKey() );
-	}
-
-	private static boolean isCollectionSnapshotValid(PersistentCollection snapshot) {
-		return snapshot != null &&
-				snapshot.getRole() != null &&
-				snapshot.getKey() != null;
-	}
-	
-	/**
-	 * Reattach a detached (disassociated) initialized or uninitialized
-	 * collection wrapper, using a snapshot carried with the collection
-	 * wrapper
-	 */
-	protected void reattachCollection(PersistentCollection collection, CollectionType type)
-	throws HibernateException {
-		if ( collection.wasInitialized() ) {
-			CollectionPersister collectionPersister = getSession().getFactory()
-			.getCollectionPersister( type.getRole() );
-			getSession().getPersistenceContext()
-				.addInitializedDetachedCollection( collectionPersister, collection );
-		}
-		else {
-			if ( !isCollectionSnapshotValid(collection) ) {
-				throw new HibernateException( "could not reassociate uninitialized transient collection" );
-			}
-			CollectionPersister collectionPersister = getSession().getFactory()
-					.getCollectionPersister( collection.getRole() );
-			getSession().getPersistenceContext()
-				.addUninitializedDetachedCollection( collectionPersister, collection );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ProxyVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+
+/**
+ * Reassociates uninitialized proxies with the session
+ * @author Gavin King
+ */
+public abstract class ProxyVisitor extends AbstractVisitor {
+
+
+	public ProxyVisitor(EventSource session) {
+		super(session);
+	}
+
+	Object processEntity(Object value, EntityType entityType) throws HibernateException {
+
+		if (value!=null) {
+			getSession().getPersistenceContext().reassociateIfUninitializedProxy(value);
+			// if it is an initialized proxy, let cascade
+			// handle it later on
+		}
+
+		return null;
+	}
+
+	/**
+	 * Has the owner of the collection changed since the collection
+	 * was snapshotted and detached?
+	 */
+	protected static boolean isOwnerUnchanged(
+			final PersistentCollection snapshot, 
+			final CollectionPersister persister, 
+			final Serializable id
+	) {
+		return isCollectionSnapshotValid(snapshot) &&
+				persister.getRole().equals( snapshot.getRole() ) &&
+				id.equals( snapshot.getKey() );
+	}
+
+	private static boolean isCollectionSnapshotValid(PersistentCollection snapshot) {
+		return snapshot != null &&
+				snapshot.getRole() != null &&
+				snapshot.getKey() != null;
+	}
+	
+	/**
+	 * Reattach a detached (disassociated) initialized or uninitialized
+	 * collection wrapper, using a snapshot carried with the collection
+	 * wrapper
+	 */
+	protected void reattachCollection(PersistentCollection collection, CollectionType type)
+	throws HibernateException {
+		if ( collection.wasInitialized() ) {
+			CollectionPersister collectionPersister = getSession().getFactory()
+			.getCollectionPersister( type.getRole() );
+			getSession().getPersistenceContext()
+				.addInitializedDetachedCollection( collectionPersister, collection );
+		}
+		else {
+			if ( !isCollectionSnapshotValid(collection) ) {
+				throw new HibernateException( "could not reassociate uninitialized transient collection" );
+			}
+			CollectionPersister collectionPersister = getSession().getFactory()
+					.getCollectionPersister( collection.getRole() );
+			getSession().getPersistenceContext()
+				.addUninitializedDetachedCollection( collectionPersister, collection );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,103 +0,0 @@
-//$Id: ReattachVisitor.java 10948 2006-12-07 21:53:10Z steve.ebersole at jboss.com $
-package org.hibernate.event.def;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.action.CollectionRemoveAction;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.Type;
-
-/**
- * Abstract superclass of visitors that reattach collections.
- *
- * @author Gavin King
- */
-public abstract class ReattachVisitor extends ProxyVisitor {
-
-	private static final Logger log = LoggerFactory.getLogger( ReattachVisitor.class );
-
-	private final Serializable ownerIdentifier;
-	private final Object owner;
-
-	public ReattachVisitor(EventSource session, Serializable ownerIdentifier, Object owner) {
-		super( session );
-		this.ownerIdentifier = ownerIdentifier;
-		this.owner = owner;
-	}
-
-	/**
-	 * Retrieve the identifier of the entity being visited.
-	 *
-	 * @return The entity's identifier.
-	 */
-	final Serializable getOwnerIdentifier() {
-		return ownerIdentifier;
-	}
-
-	/**
-	 * Retrieve the entity being visited.
-	 *
-	 * @return The entity.
-	 */
-	final Object getOwner() {
-		return owner;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	Object processComponent(Object component, AbstractComponentType componentType) throws HibernateException {
-		Type[] types = componentType.getSubtypes();
-		if ( component == null ) {
-			processValues( new Object[types.length], types );
-		}
-		else {
-			super.processComponent( component, componentType );
-		}
-
-		return null;
-	}
-
-	/**
-	 * Schedules a collection for deletion.
-	 *
-	 * @param role The persister representing the collection to be removed.
-	 * @param collectionKey The collection key (differs from owner-id in the case of property-refs).
-	 * @param source The session from which the request originated.
-	 * @throws HibernateException
-	 */
-	void removeCollection(CollectionPersister role, Serializable collectionKey, EventSource source) throws HibernateException {
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"collection dereferenced while transient " +
-					MessageHelper.collectionInfoString( role, ownerIdentifier, source.getFactory() )
-			);
-		}
-		source.getActionQueue().addAction( new CollectionRemoveAction( owner, role, collectionKey, false, source ) );
-	}
-
-	/**
-	 * This version is slightly different for say
-	 * {@link org.hibernate.type.CollectionType#getKeyOfOwner} in that here we
-	 * need to assume that the owner is not yet associated with the session,
-	 * and thus we cannot rely on the owner's EntityEntry snapshot...
-	 *
-	 * @param role The persister for the collection role being processed.
-	 * @return
-	 */
-	final Serializable extractCollectionKeyFromOwner(CollectionPersister role) {
-		if ( role.getCollectionType().useLHSPrimaryKey() ) {
-			return ownerIdentifier;
-		}
-		else {
-			return ( Serializable ) role.getOwnerEntityPersister().getPropertyValue( owner, role.getCollectionType().getLHSPropertyName(), getSession().getEntityMode() );
-		}
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/ReattachVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,126 @@
+/*
+ * 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.event.def;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.action.CollectionRemoveAction;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.Type;
+
+/**
+ * Abstract superclass of visitors that reattach collections.
+ *
+ * @author Gavin King
+ */
+public abstract class ReattachVisitor extends ProxyVisitor {
+
+	private static final Logger log = LoggerFactory.getLogger( ReattachVisitor.class );
+
+	private final Serializable ownerIdentifier;
+	private final Object owner;
+
+	public ReattachVisitor(EventSource session, Serializable ownerIdentifier, Object owner) {
+		super( session );
+		this.ownerIdentifier = ownerIdentifier;
+		this.owner = owner;
+	}
+
+	/**
+	 * Retrieve the identifier of the entity being visited.
+	 *
+	 * @return The entity's identifier.
+	 */
+	final Serializable getOwnerIdentifier() {
+		return ownerIdentifier;
+	}
+
+	/**
+	 * Retrieve the entity being visited.
+	 *
+	 * @return The entity.
+	 */
+	final Object getOwner() {
+		return owner;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	Object processComponent(Object component, AbstractComponentType componentType) throws HibernateException {
+		Type[] types = componentType.getSubtypes();
+		if ( component == null ) {
+			processValues( new Object[types.length], types );
+		}
+		else {
+			super.processComponent( component, componentType );
+		}
+
+		return null;
+	}
+
+	/**
+	 * Schedules a collection for deletion.
+	 *
+	 * @param role The persister representing the collection to be removed.
+	 * @param collectionKey The collection key (differs from owner-id in the case of property-refs).
+	 * @param source The session from which the request originated.
+	 * @throws HibernateException
+	 */
+	void removeCollection(CollectionPersister role, Serializable collectionKey, EventSource source) throws HibernateException {
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"collection dereferenced while transient " +
+					MessageHelper.collectionInfoString( role, ownerIdentifier, source.getFactory() )
+			);
+		}
+		source.getActionQueue().addAction( new CollectionRemoveAction( owner, role, collectionKey, false, source ) );
+	}
+
+	/**
+	 * This version is slightly different for say
+	 * {@link org.hibernate.type.CollectionType#getKeyOfOwner} in that here we
+	 * need to assume that the owner is not yet associated with the session,
+	 * and thus we cannot rely on the owner's EntityEntry snapshot...
+	 *
+	 * @param role The persister for the collection role being processed.
+	 * @return
+	 */
+	final Serializable extractCollectionKeyFromOwner(CollectionPersister role) {
+		if ( role.getCollectionType().useLHSPrimaryKey() ) {
+			return ownerIdentifier;
+		}
+		else {
+			return ( Serializable ) role.getOwnerEntityPersister().getPropertyValue( owner, role.getCollectionType().getLHSPropertyName(), getSession().getEntityMode() );
+		}
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/WrapVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,137 +0,0 @@
-//$Id: WrapVisitor.java 7181 2005-06-17 19:36:08Z oneovthafew $
-package org.hibernate.event.def;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-/**
- * Wrap collections in a Hibernate collection
- * wrapper.
- * @author Gavin King
- */
-public class WrapVisitor extends ProxyVisitor {
-
-	private static final Logger log = LoggerFactory.getLogger(WrapVisitor.class);
-
-	boolean substitute = false;
-
-	boolean isSubstitutionRequired() {
-		return substitute;
-	}
-
-	WrapVisitor(EventSource session) {
-		super(session);
-	}
-
-	Object processCollection(Object collection, CollectionType collectionType)
-	throws HibernateException {
-
-		if ( collection!=null && (collection instanceof PersistentCollection) ) {
-
-			final SessionImplementor session = getSession();
-			PersistentCollection coll = (PersistentCollection) collection;
-			if ( coll.setCurrentSession(session) ) {
-				reattachCollection( coll, collectionType );
-			}
-			return null;
-
-		}
-		else {
-			return processArrayOrNewCollection(collection, collectionType);
-		}
-
-	}
-
-	final Object processArrayOrNewCollection(Object collection, CollectionType collectionType)
-	throws HibernateException {
-
-		final SessionImplementor session = getSession();
-
-		if (collection==null) {
-			//do nothing
-			return null;
-		}
-		else {
-			CollectionPersister persister = session.getFactory().getCollectionPersister( collectionType.getRole() );
-
-			final PersistenceContext persistenceContext = session.getPersistenceContext();
-			//TODO: move into collection type, so we can use polymorphism!
-			if ( collectionType.hasHolder( session.getEntityMode() ) ) {
-				
-				if (collection==CollectionType.UNFETCHED_COLLECTION) return null;
-
-				PersistentCollection ah = persistenceContext.getCollectionHolder(collection);
-				if (ah==null) {
-					ah = collectionType.wrap(session, collection);
-					persistenceContext.addNewCollection( persister, ah );
-					persistenceContext.addCollectionHolder(ah);
-				}
-				return null;
-			}
-			else {
-
-				PersistentCollection persistentCollection = collectionType.wrap(session, collection);
-				persistenceContext.addNewCollection( persister, persistentCollection );
-
-				if ( log.isTraceEnabled() ) log.trace( "Wrapped collection in role: " + collectionType.getRole() );
-
-				return persistentCollection; //Force a substitution!
-
-			}
-
-		}
-
-	}
-
-	void processValue(int i, Object[] values, Type[] types) {
-		Object result = processValue( values[i], types[i] );
-		if (result!=null) {
-			substitute = true;
-			values[i] = result;
-		}
-	}
-
-	Object processComponent(Object component, AbstractComponentType componentType)
-	throws HibernateException {
-
-		if (component!=null) {
-			Object[] values = componentType.getPropertyValues( component, getSession() );
-			Type[] types = componentType.getSubtypes();
-			boolean substituteComponent = false;
-			for ( int i=0; i<types.length; i++ ) {
-				Object result = processValue( values[i], types[i] );
-				if (result!=null) {
-					values[i] = result;
-					substituteComponent = true;
-				}
-			}
-			if (substituteComponent) {
-				componentType.setPropertyValues( component, values, getSession().getEntityMode() );
-			}
-		}
-
-		return null;
-	}
-
-	void process(Object object, EntityPersister persister) throws HibernateException {
-		EntityMode entityMode = getSession().getEntityMode();
-		Object[] values = persister.getPropertyValues( object, entityMode );
-		Type[] types = persister.getPropertyTypes();
-		processEntityPropertyValues(values, types);
-		if ( isSubstitutionRequired() ) {
-			persister.setPropertyValues( object, values, entityMode );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/WrapVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/WrapVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,160 @@
+/*
+ * 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.event.def;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+/**
+ * Wrap collections in a Hibernate collection
+ * wrapper.
+ * @author Gavin King
+ */
+public class WrapVisitor extends ProxyVisitor {
+
+	private static final Logger log = LoggerFactory.getLogger(WrapVisitor.class);
+
+	boolean substitute = false;
+
+	boolean isSubstitutionRequired() {
+		return substitute;
+	}
+
+	WrapVisitor(EventSource session) {
+		super(session);
+	}
+
+	Object processCollection(Object collection, CollectionType collectionType)
+	throws HibernateException {
+
+		if ( collection!=null && (collection instanceof PersistentCollection) ) {
+
+			final SessionImplementor session = getSession();
+			PersistentCollection coll = (PersistentCollection) collection;
+			if ( coll.setCurrentSession(session) ) {
+				reattachCollection( coll, collectionType );
+			}
+			return null;
+
+		}
+		else {
+			return processArrayOrNewCollection(collection, collectionType);
+		}
+
+	}
+
+	final Object processArrayOrNewCollection(Object collection, CollectionType collectionType)
+	throws HibernateException {
+
+		final SessionImplementor session = getSession();
+
+		if (collection==null) {
+			//do nothing
+			return null;
+		}
+		else {
+			CollectionPersister persister = session.getFactory().getCollectionPersister( collectionType.getRole() );
+
+			final PersistenceContext persistenceContext = session.getPersistenceContext();
+			//TODO: move into collection type, so we can use polymorphism!
+			if ( collectionType.hasHolder( session.getEntityMode() ) ) {
+				
+				if (collection==CollectionType.UNFETCHED_COLLECTION) return null;
+
+				PersistentCollection ah = persistenceContext.getCollectionHolder(collection);
+				if (ah==null) {
+					ah = collectionType.wrap(session, collection);
+					persistenceContext.addNewCollection( persister, ah );
+					persistenceContext.addCollectionHolder(ah);
+				}
+				return null;
+			}
+			else {
+
+				PersistentCollection persistentCollection = collectionType.wrap(session, collection);
+				persistenceContext.addNewCollection( persister, persistentCollection );
+
+				if ( log.isTraceEnabled() ) log.trace( "Wrapped collection in role: " + collectionType.getRole() );
+
+				return persistentCollection; //Force a substitution!
+
+			}
+
+		}
+
+	}
+
+	void processValue(int i, Object[] values, Type[] types) {
+		Object result = processValue( values[i], types[i] );
+		if (result!=null) {
+			substitute = true;
+			values[i] = result;
+		}
+	}
+
+	Object processComponent(Object component, AbstractComponentType componentType)
+	throws HibernateException {
+
+		if (component!=null) {
+			Object[] values = componentType.getPropertyValues( component, getSession() );
+			Type[] types = componentType.getSubtypes();
+			boolean substituteComponent = false;
+			for ( int i=0; i<types.length; i++ ) {
+				Object result = processValue( values[i], types[i] );
+				if (result!=null) {
+					values[i] = result;
+					substituteComponent = true;
+				}
+			}
+			if (substituteComponent) {
+				componentType.setPropertyValues( component, values, getSession().getEntityMode() );
+			}
+		}
+
+		return null;
+	}
+
+	void process(Object object, EntityPersister persister) throws HibernateException {
+		EntityMode entityMode = getSession().getEntityMode();
+		Object[] values = persister.getPropertyValues( object, entityMode );
+		Type[] types = persister.getPropertyTypes();
+		processEntityPropertyValues(values, types);
+		if ( isSubstitutionRequired() ) {
+			persister.setPropertyValues( object, values, entityMode );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a default set of event listeners that
-	implements the default behaviors of Hibernate.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/def/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/def/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a default set of event listeners that
+	implements the default behaviors of Hibernate.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines an event framework for Hibernate.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/event/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/event/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines an event framework for Hibernate.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-// $Id: $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A SQLExceptionConverter implementation specific to Cach&eacute; SQL,
- * accounting for its custom integrity constraint violation error codes.
- *
- * @author Jonathan Levinson
- */
-public class CacheSQLStateConverter implements SQLExceptionConverter {
-
-	private ViolatedConstraintNameExtracter extracter;
-
-	private static final Set SQL_GRAMMAR_CATEGORIES = new HashSet();
-	private static final Set DATA_CATEGORIES = new HashSet();
-	private static final Set INTEGRITY_VIOLATION_CATEGORIES = new HashSet();
-	private static final Set CONNECTION_CATEGORIES = new HashSet();
-
-	static {
-		SQL_GRAMMAR_CATEGORIES.add( "07" );
-		SQL_GRAMMAR_CATEGORIES.add( "37" );
-		SQL_GRAMMAR_CATEGORIES.add( "42" );
-		SQL_GRAMMAR_CATEGORIES.add( "65" );
-		SQL_GRAMMAR_CATEGORIES.add( "S0" );
-		SQL_GRAMMAR_CATEGORIES.add( "20" );
-
-		DATA_CATEGORIES.add( "22" );
-		DATA_CATEGORIES.add( "21" );
-		DATA_CATEGORIES.add( "02" );
-
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 119 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 120 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 121 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 122 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 123 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 124 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 125 ) );
-		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 127 ) );
-
-		CONNECTION_CATEGORIES.add( "08" );
-	}
-
-	public CacheSQLStateConverter(ViolatedConstraintNameExtracter extracter) {
-		this.extracter = extracter;
-	}
-
-	/**
-	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
-	 *
-	 * @param sqlException The SQLException to be converted.
-	 * @param message	  An optional error message.
-	 * @param sql		  Optionally, the sql being performed when the exception occurred.
-	 * @return The resulting JDBCException.
-	 */
-	public JDBCException convert(SQLException sqlException, String message, String sql) {
-		String sqlStateClassCode = JDBCExceptionHelper.extractSqlStateClassCode( sqlException );
-		Integer errorCode = new Integer( JDBCExceptionHelper.extractErrorCode( sqlException ) );
-		if ( sqlStateClassCode != null ) {
-			if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) {
-				return new SQLGrammarException( message, sqlException, sql );
-			}
-			else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( errorCode ) ) {
-				String constraintName = extracter.extractConstraintName( sqlException );
-				return new ConstraintViolationException( message, sqlException, sql, constraintName );
-			}
-			else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
-				return new JDBCConnectionException( message, sqlException, sql );
-			}
-			else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) {
-				return new DataException( message, sqlException, sql );
-			}
-		}
-		return handledNonSpecificException( sqlException, message, sql );
-	}
-
-	/**
-	 * Handle an exception not converted to a specific type based on the SQLState.
-	 *
-	 * @param sqlException The exception to be handled.
-	 * @param message	  An optional message
-	 * @param sql		  Optionally, the sql being performed when the exception occurred.
-	 * @return The converted exception; should <b>never</b> be null.
-	 */
-	protected JDBCException handledNonSpecificException(SQLException sqlException, String message, String sql) {
-		return new GenericJDBCException( message, sqlException, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/CacheSQLStateConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A SQLExceptionConverter implementation specific to Cach&eacute; SQL,
+ * accounting for its custom integrity constraint violation error codes.
+ *
+ * @author Jonathan Levinson
+ */
+public class CacheSQLStateConverter implements SQLExceptionConverter {
+
+	private ViolatedConstraintNameExtracter extracter;
+
+	private static final Set SQL_GRAMMAR_CATEGORIES = new HashSet();
+	private static final Set DATA_CATEGORIES = new HashSet();
+	private static final Set INTEGRITY_VIOLATION_CATEGORIES = new HashSet();
+	private static final Set CONNECTION_CATEGORIES = new HashSet();
+
+	static {
+		SQL_GRAMMAR_CATEGORIES.add( "07" );
+		SQL_GRAMMAR_CATEGORIES.add( "37" );
+		SQL_GRAMMAR_CATEGORIES.add( "42" );
+		SQL_GRAMMAR_CATEGORIES.add( "65" );
+		SQL_GRAMMAR_CATEGORIES.add( "S0" );
+		SQL_GRAMMAR_CATEGORIES.add( "20" );
+
+		DATA_CATEGORIES.add( "22" );
+		DATA_CATEGORIES.add( "21" );
+		DATA_CATEGORIES.add( "02" );
+
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 119 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 120 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 121 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 122 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 123 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 124 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 125 ) );
+		INTEGRITY_VIOLATION_CATEGORIES.add( new Integer( 127 ) );
+
+		CONNECTION_CATEGORIES.add( "08" );
+	}
+
+	public CacheSQLStateConverter(ViolatedConstraintNameExtracter extracter) {
+		this.extracter = extracter;
+	}
+
+	/**
+	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
+	 *
+	 * @param sqlException The SQLException to be converted.
+	 * @param message	  An optional error message.
+	 * @param sql		  Optionally, the sql being performed when the exception occurred.
+	 * @return The resulting JDBCException.
+	 */
+	public JDBCException convert(SQLException sqlException, String message, String sql) {
+		String sqlStateClassCode = JDBCExceptionHelper.extractSqlStateClassCode( sqlException );
+		Integer errorCode = new Integer( JDBCExceptionHelper.extractErrorCode( sqlException ) );
+		if ( sqlStateClassCode != null ) {
+			if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) {
+				return new SQLGrammarException( message, sqlException, sql );
+			}
+			else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( errorCode ) ) {
+				String constraintName = extracter.extractConstraintName( sqlException );
+				return new ConstraintViolationException( message, sqlException, sql, constraintName );
+			}
+			else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
+				return new JDBCConnectionException( message, sqlException, sql );
+			}
+			else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) {
+				return new DataException( message, sqlException, sql );
+			}
+		}
+		return handledNonSpecificException( sqlException, message, sql );
+	}
+
+	/**
+	 * Handle an exception not converted to a specific type based on the SQLState.
+	 *
+	 * @param sqlException The exception to be handled.
+	 * @param message	  An optional message
+	 * @param sql		  Optionally, the sql being performed when the exception occurred.
+	 * @return The converted exception; should <b>never</b> be null.
+	 */
+	protected JDBCException handledNonSpecificException(SQLException sqlException, String message, String sql) {
+		return new GenericJDBCException( message, sqlException, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/Configurable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-// $Id: Configurable.java 4746 2004-11-11 20:57:28Z steveebersole $
-package org.hibernate.exception;
-
-import org.hibernate.HibernateException;
-
-import java.util.Properties;
-
-/**
- * The Configurable interface defines the contract for SQLExceptionConverter impls that
- * want to be configured prior to usage given the currently defined Hibernate properties.
- *
- * @author Steve Ebersole
- */
-public interface Configurable {
-	// todo: this might really even be moved into the cfg package and used as the basis for all things which are configurable.
-
-	/**
-	 * Configure the component, using the given settings and properties.
-	 *
-	 * @param properties All defined startup properties.
-	 * @throws HibernateException Indicates a configuration exception.
-	 */
-	public void configure(Properties properties) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/Configurable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Configurable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.HibernateException;
+
+import java.util.Properties;
+
+/**
+ * The Configurable interface defines the contract for SQLExceptionConverter impls that
+ * want to be configured prior to usage given the currently defined Hibernate properties.
+ *
+ * @author Steve Ebersole
+ */
+public interface Configurable {
+	// todo: this might really even be moved into the cfg package and used as the basis for all things which are configurable.
+
+	/**
+	 * Configure the component, using the given settings and properties.
+	 *
+	 * @param properties All defined startup properties.
+	 * @throws HibernateException Indicates a configuration exception.
+	 */
+	public void configure(Properties properties) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-// $Id: ConstraintViolationException.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCException indicating that the requested DML operation
- * resulted in a violation of a defined integrity constraint.
- *
- * @author Steve Ebersole
- */
-public class ConstraintViolationException extends JDBCException {
-
-	private String constraintName;
-
-	public ConstraintViolationException(String message, SQLException root, String constraintName) {
-		super( message, root );
-		this.constraintName = constraintName;
-	}
-
-	public ConstraintViolationException(String message, SQLException root, String sql, String constraintName) {
-		super( message, root, sql );
-		this.constraintName = constraintName;
-	}
-
-	/**
-	 * Returns the name of the violated constraint, if known.
-	 *
-	 * @return The name of the violated constraint, or null if not known.
-	 */
-	public String getConstraintName() {
-		return constraintName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ConstraintViolationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCException indicating that the requested DML operation
+ * resulted in a violation of a defined integrity constraint.
+ *
+ * @author Steve Ebersole
+ */
+public class ConstraintViolationException extends JDBCException {
+
+	private String constraintName;
+
+	public ConstraintViolationException(String message, SQLException root, String constraintName) {
+		super( message, root );
+		this.constraintName = constraintName;
+	}
+
+	public ConstraintViolationException(String message, SQLException root, String sql, String constraintName) {
+		super( message, root, sql );
+		this.constraintName = constraintName;
+	}
+
+	/**
+	 * Returns the name of the violated constraint, if known.
+	 *
+	 * @return The name of the violated constraint, or null if not known.
+	 */
+	public String getConstraintName() {
+		return constraintName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/DataException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-// $Id: DataException.java 8062 2005-09-01 15:41:46Z oneovthafew $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCException indicating that evaluation of the
- * valid SQL statement against the given data resulted in some
- * illegal operation, mismatched types or incorrect cardinality.
- *
- * @author Gavin King
- */
-public class DataException extends JDBCException {
-	/**
-	 * Constructor for JDBCException.
-	 *
-	 * @param root The underlying exception.
-	 */
-	public DataException(String message, SQLException root) {
-		super( message, root );
-	}
-
-	/**
-	 * Constructor for JDBCException.
-	 *
-	 * @param message Optional message.
-	 * @param root    The underlying exception.
-	 */
-	public DataException(String message, SQLException root, String sql) {
-		super( message, root, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/DataException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/DataException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCException indicating that evaluation of the
+ * valid SQL statement against the given data resulted in some
+ * illegal operation, mismatched types or incorrect cardinality.
+ *
+ * @author Gavin King
+ */
+public class DataException extends JDBCException {
+	/**
+	 * Constructor for JDBCException.
+	 *
+	 * @param root The underlying exception.
+	 */
+	public DataException(String message, SQLException root) {
+		super( message, root );
+	}
+
+	/**
+	 * Constructor for JDBCException.
+	 *
+	 * @param message Optional message.
+	 * @param root    The underlying exception.
+	 */
+	public DataException(String message, SQLException root, String sql) {
+		super( message, root, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/ExceptionUtils.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,734 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.exception;
-
-import org.hibernate.util.ArrayHelper;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.StringTokenizer;
-
-/**
- * <p>Provides utilities for manipulating and examining
- * <code>Throwable</code> objects.</p>
- *
- * @author <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
- * @author Dmitri Plotnikov
- * @author Stephen Colebourne
- * @author <a href="mailto:ggregory at seagullsw.com">Gary Gregory</a>
- * @author Pete Gieser
- * @version $Id: ExceptionUtils.java 4782 2004-11-21 00:11:27Z pgmjsd $
- * @since 1.0
- */
-public final class ExceptionUtils {
-
-	private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
-
-	/**
-	 * <p>Used when printing stack frames to denote the start of a
-	 * wrapped exception.</p>
-	 * <p/>
-	 * <p>Package private for accessibility by test suite.</p>
-	 */
-	static final String WRAPPED_MARKER = " [wrapped] ";
-
-	/**
-	 * <p>The names of methods commonly used to access a wrapped exception.</p>
-	 */
-	private static final String[] CAUSE_METHOD_NAMES = {
-		"getCause",
-		"getNextException",
-		"getTargetException",
-		"getException",
-		"getSourceException",
-		"getRootCause",
-		"getCausedByException",
-		"getNested"
-	};
-
-	/**
-	 * <p>The Method object for JDK1.4 getCause.</p>
-	 */
-	private static final Method THROWABLE_CAUSE_METHOD;
-
-	static {
-		Method getCauseMethod;
-		try {
-			getCauseMethod = Throwable.class.getMethod( "getCause", null );
-		}
-		catch ( Exception e ) {
-			getCauseMethod = null;
-		}
-		THROWABLE_CAUSE_METHOD = getCauseMethod;
-	}
-
-	private ExceptionUtils() {
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Adds to the list of method names used in the search for <code>Throwable</code>
-	 * objects.</p>
-	 *
-	 * @param methodName  the methodName to add to the list, <code>null</code>
-	 *  and empty strings are ignored
-	 * @since 2.0
-	 */
-	/*public static void addCauseMethodName(String methodName) {
-		if ( StringHelper.isNotEmpty(methodName) ) {
-			List list = new ArrayList( Arrays.asList(CAUSE_METHOD_NAMES );
-			list.add(methodName);
-			CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]);
-		}
-	}*/
-
-	/**
-	 * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
-	 * <p/>
-	 * <p>The method searches for methods with specific names that return a
-	 * <code>Throwable</code> object. This will pick up most wrapping exceptions,
-	 * including those from JDK 1.4, and
-	 * {@link org.apache.commons.lang.exception.NestableException NestableException}.
-	 * The method names can be added to using {@link #addCauseMethodName(String)}.</p>
-	 * <p/>
-	 * <p>The default list searched for are:</p>
-	 * <ul>
-	 * <li><code>getCause()</code></li>
-	 * <li><code>getNextException()</code></li>
-	 * <li><code>getTargetException()</code></li>
-	 * <li><code>getException()</code></li>
-	 * <li><code>getSourceException()</code></li>
-	 * <li><code>getRootCause()</code></li>
-	 * <li><code>getCausedByException()</code></li>
-	 * <li><code>getNested()</code></li>
-	 * </ul>
-	 * <p/>
-	 * <p>In the absence of any such method, the object is inspected for a
-	 * <code>detail</code> field assignable to a <code>Throwable</code>.</p>
-	 * <p/>
-	 * <p>If none of the above is found, returns <code>null</code>.</p>
-	 *
-	 * @param throwable the throwable to introspect for a cause, may be null
-	 * @return the cause of the <code>Throwable</code>,
-	 *         <code>null</code> if none found or null throwable input
-	 */
-	public static Throwable getCause(Throwable throwable) {
-		return getCause( throwable, CAUSE_METHOD_NAMES );
-	}
-
-	/**
-	 * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
-	 * <p/>
-	 * <ol>
-	 * <li>Try known exception types.</li>
-	 * <li>Try the supplied array of method names.</li>
-	 * <li>Try the field 'detail'.</li>
-	 * </ol>
-	 * <p/>
-	 * <p>A <code>null</code> set of method names means use the default set.
-	 * A <code>null</code> in the set of method names will be ignored.</p>
-	 *
-	 * @param throwable   the throwable to introspect for a cause, may be null
-	 * @param methodNames the method names, null treated as default set
-	 * @return the cause of the <code>Throwable</code>,
-	 *         <code>null</code> if none found or null throwable input
-	 */
-	public static Throwable getCause(Throwable throwable, String[] methodNames) {
-		if ( throwable == null ) {
-			return null;
-		}
-		Throwable cause = getCauseUsingWellKnownTypes( throwable );
-		if ( cause == null ) {
-			if ( methodNames == null ) {
-				methodNames = CAUSE_METHOD_NAMES;
-			}
-			for ( int i = 0; i < methodNames.length; i++ ) {
-				String methodName = methodNames[i];
-				if ( methodName != null ) {
-					cause = getCauseUsingMethodName( throwable, methodName );
-					if ( cause != null ) {
-						break;
-					}
-				}
-			}
-
-			if ( cause == null ) {
-				cause = getCauseUsingFieldName( throwable, "detail" );
-			}
-		}
-		return cause;
-	}
-
-	/**
-	 * <p>Introspects the <code>Throwable</code> to obtain the root cause.</p>
-	 * <p/>
-	 * <p>This method walks through the exception chain to the last element,
-	 * "root" of the tree, using {@link #getCause(Throwable)}, and
-	 * returns that exception.</p>
-	 *
-	 * @param throwable the throwable to get the root cause for, may be null
-	 * @return the root cause of the <code>Throwable</code>,
-	 *         <code>null</code> if none found or null throwable input
-	 */
-	public static Throwable getRootCause(Throwable throwable) {
-		Throwable cause = getCause( throwable );
-		if ( cause != null ) {
-			throwable = cause;
-			while ( ( throwable = getCause( throwable ) ) != null ) {
-				cause = throwable;
-			}
-		}
-		return cause;
-	}
-
-	/**
-	 * <p>Finds a <code>Throwable</code> for known types.</p>
-	 * <p/>
-	 * <p>Uses <code>instanceof</code> checks to examine the exception,
-	 * looking for well known types which could contain chained or
-	 * wrapped exceptions.</p>
-	 *
-	 * @param throwable the exception to examine
-	 * @return the wrapped exception, or <code>null</code> if not found
-	 */
-	private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) {
-		if ( throwable instanceof Nestable ) {
-			return ( ( Nestable ) throwable ).getCause();
-		}
-		else if ( throwable instanceof SQLException ) {
-			return ( ( SQLException ) throwable ).getNextException();
-		}
-		else if ( throwable instanceof InvocationTargetException ) {
-			return ( ( InvocationTargetException ) throwable ).getTargetException();
-		}
-		else {
-			return null;
-		}
-	}
-
-	/**
-	 * <p>Finds a <code>Throwable</code> by method name.</p>
-	 *
-	 * @param throwable  the exception to examine
-	 * @param methodName the name of the method to find and invoke
-	 * @return the wrapped exception, or <code>null</code> if not found
-	 */
-	private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) {
-		Method method = null;
-		try {
-			method = throwable.getClass().getMethod( methodName, null );
-		}
-		catch ( NoSuchMethodException ignored ) {
-		}
-		catch ( SecurityException ignored ) {
-		}
-
-		if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
-			try {
-				return ( Throwable ) method.invoke( throwable, ArrayHelper.EMPTY_OBJECT_ARRAY );
-			}
-			catch ( IllegalAccessException ignored ) {
-			}
-			catch ( IllegalArgumentException ignored ) {
-			}
-			catch ( InvocationTargetException ignored ) {
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * <p>Finds a <code>Throwable</code> by field name.</p>
-	 *
-	 * @param throwable the exception to examine
-	 * @param fieldName the name of the attribute to examine
-	 * @return the wrapped exception, or <code>null</code> if not found
-	 */
-	private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) {
-		Field field = null;
-		try {
-			field = throwable.getClass().getField( fieldName );
-		}
-		catch ( NoSuchFieldException ignored ) {
-		}
-		catch ( SecurityException ignored ) {
-		}
-
-		if ( field != null && Throwable.class.isAssignableFrom( field.getType() ) ) {
-			try {
-				return ( Throwable ) field.get( throwable );
-			}
-			catch ( IllegalAccessException ignored ) {
-			}
-			catch ( IllegalArgumentException ignored ) {
-			}
-		}
-		return null;
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Checks if the Throwable class has a <code>getCause</code> method.</p>
-	 * <p/>
-	 * <p>This is true for JDK 1.4 and above.</p>
-	 *
-	 * @return true if Throwable is nestable
-	 * @since 2.0
-	 */
-	public static boolean isThrowableNested() {
-		return ( THROWABLE_CAUSE_METHOD != null );
-	}
-
-	/**
-	 * <p>Checks whether this <code>Throwable</code> class can store a cause.</p>
-	 * <p/>
-	 * <p>This method does <b>not</b> check whether it actually does store a cause.<p>
-	 *
-	 * @param throwable the <code>Throwable</code> to examine, may be null
-	 * @return boolean <code>true</code> if nested otherwise <code>false</code>
-	 * @since 2.0
-	 */
-	public static boolean isNestedThrowable(Throwable throwable) {
-		if ( throwable == null ) {
-			return false;
-		}
-
-		if ( throwable instanceof Nestable ) {
-			return true;
-		}
-		else if ( throwable instanceof SQLException ) {
-			return true;
-		}
-		else if ( throwable instanceof InvocationTargetException ) {
-			return true;
-		}
-		else if ( isThrowableNested() ) {
-			return true;
-		}
-
-		Class cls = throwable.getClass();
-		for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ ) {
-			try {
-				Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null );
-				if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
-					return true;
-				}
-			}
-			catch ( NoSuchMethodException ignored ) {
-			}
-			catch ( SecurityException ignored ) {
-			}
-		}
-
-		try {
-			Field field = cls.getField( "detail" );
-			if ( field != null ) {
-				return true;
-			}
-		}
-		catch ( NoSuchFieldException ignored ) {
-		}
-		catch ( SecurityException ignored ) {
-		}
-
-		return false;
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Counts the number of <code>Throwable</code> objects in the
-	 * exception chain.</p>
-	 * <p/>
-	 * <p>A throwable without cause will return <code>1</code>.
-	 * A throwable with one cause will return <code>2</code> and so on.
-	 * A <code>null</code> throwable will return <code>0</code>.</p>
-	 *
-	 * @param throwable the throwable to inspect, may be null
-	 * @return the count of throwables, zero if null input
-	 */
-	public static int getThrowableCount(Throwable throwable) {
-		int count = 0;
-		while ( throwable != null ) {
-			count++;
-			throwable = ExceptionUtils.getCause( throwable );
-		}
-		return count;
-	}
-
-	/**
-	 * <p>Returns the list of <code>Throwable</code> objects in the
-	 * exception chain.</p>
-	 * <p/>
-	 * <p>A throwable without cause will return an array containing
-	 * one element - the input throwable.
-	 * A throwable with one cause will return an array containing
-	 * two elements. - the input throwable and the cause throwable.
-	 * A <code>null</code> throwable will return an array size zero.</p>
-	 *
-	 * @param throwable the throwable to inspect, may be null
-	 * @return the array of throwables, never null
-	 */
-	public static Throwable[] getThrowables(Throwable throwable) {
-		List list = new ArrayList();
-		while ( throwable != null ) {
-			list.add( throwable );
-			throwable = ExceptionUtils.getCause( throwable );
-		}
-		return ( Throwable[] ) list.toArray( new Throwable[list.size()] );
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Returns the (zero based) index of the first <code>Throwable</code>
-	 * that matches the specified type in the exception chain.</p>
-	 * <p/>
-	 * <p>A <code>null</code> throwable returns <code>-1</code>.
-	 * A <code>null</code> type returns <code>-1</code>.
-	 * No match in the chain returns <code>-1</code>.</p>
-	 *
-	 * @param throwable the throwable to inspect, may be null
-	 * @param type      the type to search for
-	 * @return the index into the throwable chain, -1 if no match or null input
-	 */
-	public static int indexOfThrowable(Throwable throwable, Class type) {
-		return indexOfThrowable( throwable, type, 0 );
-	}
-
-	/**
-	 * <p>Returns the (zero based) index of the first <code>Throwable</code>
-	 * that matches the specified type in the exception chain from
-	 * a specified index.</p>
-	 * <p/>
-	 * <p>A <code>null</code> throwable returns <code>-1</code>.
-	 * A <code>null</code> type returns <code>-1</code>.
-	 * No match in the chain returns <code>-1</code>.
-	 * A negative start index is treated as zero.
-	 * A start index greater than the number of throwables returns <code>-1</code>.</p>
-	 *
-	 * @param throwable the throwable to inspect, may be null
-	 * @param type      the type to search for
-	 * @param fromIndex the (zero based) index of the starting position,
-	 *                  negative treated as zero, larger than chain size returns -1
-	 * @return the index into the throwable chain, -1 if no match or null input
-	 */
-	public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) {
-		if ( throwable == null ) {
-			return -1;
-		}
-		if ( fromIndex < 0 ) {
-			fromIndex = 0;
-		}
-		Throwable[] throwables = ExceptionUtils.getThrowables( throwable );
-		if ( fromIndex >= throwables.length ) {
-			return -1;
-		}
-		for ( int i = fromIndex; i < throwables.length; i++ ) {
-			if ( throwables[i].getClass().equals( type ) ) {
-				return i;
-			}
-		}
-		return -1;
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Prints a compact stack trace for the root cause of a throwable
-	 * to <code>System.err</code>.</p>
-	 * <p/>
-	 * <p>The compact stack trace starts with the root cause and prints
-	 * stack frames up to the place where it was caught and wrapped.
-	 * Then it prints the wrapped exception and continues with stack frames
-	 * until the wrapper exception is caught and wrapped again, etc.</p>
-	 * <p/>
-	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-	 * that don't have nested causes.</p>
-	 *
-	 * @param throwable the throwable to output
-	 * @since 2.0
-	 */
-	public static void printRootCauseStackTrace(Throwable throwable) {
-		printRootCauseStackTrace( throwable, System.err );
-	}
-
-	/**
-	 * <p>Prints a compact stack trace for the root cause of a throwable.</p>
-	 * <p/>
-	 * <p>The compact stack trace starts with the root cause and prints
-	 * stack frames up to the place where it was caught and wrapped.
-	 * Then it prints the wrapped exception and continues with stack frames
-	 * until the wrapper exception is caught and wrapped again, etc.</p>
-	 * <p/>
-	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-	 * that don't have nested causes.</p>
-	 *
-	 * @param throwable the throwable to output, may be null
-	 * @param stream    the stream to output to, may not be null
-	 * @throws IllegalArgumentException if the stream is <code>null</code>
-	 * @since 2.0
-	 */
-	public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) {
-		if ( throwable == null ) {
-			return;
-		}
-		if ( stream == null ) {
-			throw new IllegalArgumentException( "The PrintStream must not be null" );
-		}
-		String trace[] = getRootCauseStackTrace( throwable );
-		for ( int i = 0; i < trace.length; i++ ) {
-			stream.println( trace[i] );
-		}
-		stream.flush();
-	}
-
-	/**
-	 * <p>Prints a compact stack trace for the root cause of a throwable.</p>
-	 * <p/>
-	 * <p>The compact stack trace starts with the root cause and prints
-	 * stack frames up to the place where it was caught and wrapped.
-	 * Then it prints the wrapped exception and continues with stack frames
-	 * until the wrapper exception is caught and wrapped again, etc.</p>
-	 * <p/>
-	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
-	 * that don't have nested causes.</p>
-	 *
-	 * @param throwable the throwable to output, may be null
-	 * @param writer    the writer to output to, may not be null
-	 * @throws IllegalArgumentException if the writer is <code>null</code>
-	 * @since 2.0
-	 */
-	public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) {
-		if ( throwable == null ) {
-			return;
-		}
-		if ( writer == null ) {
-			throw new IllegalArgumentException( "The PrintWriter must not be null" );
-		}
-		String trace[] = getRootCauseStackTrace( throwable );
-		for ( int i = 0; i < trace.length; i++ ) {
-			writer.println( trace[i] );
-		}
-		writer.flush();
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Creates a compact stack trace for the root cause of the supplied
-	 * <code>Throwable</code>.</p>
-	 *
-	 * @param throwable the throwable to examine, may be null
-	 * @return an array of stack trace frames, never null
-	 * @since 2.0
-	 */
-	public static String[] getRootCauseStackTrace(Throwable throwable) {
-		if ( throwable == null ) {
-			return ArrayHelper.EMPTY_STRING_ARRAY;
-		}
-		Throwable throwables[] = getThrowables( throwable );
-		int count = throwables.length;
-		ArrayList frames = new ArrayList();
-		List nextTrace = getStackFrameList( throwables[count - 1] );
-		for ( int i = count; --i >= 0; ) {
-			List trace = nextTrace;
-			if ( i != 0 ) {
-				nextTrace = getStackFrameList( throwables[i - 1] );
-				removeCommonFrames( trace, nextTrace );
-			}
-			if ( i == count - 1 ) {
-				frames.add( throwables[i].toString() );
-			}
-			else {
-				frames.add( WRAPPED_MARKER + throwables[i].toString() );
-			}
-			for ( int j = 0; j < trace.size(); j++ ) {
-				frames.add( trace.get( j ) );
-			}
-		}
-		return ( String[] ) frames.toArray( new String[0] );
-	}
-
-	/**
-	 * <p>Removes common frames from the cause trace given the two stack traces.</p>
-	 *
-	 * @param causeFrames   stack trace of a cause throwable
-	 * @param wrapperFrames stack trace of a wrapper throwable
-	 * @throws IllegalArgumentException if either argument is null
-	 * @since 2.0
-	 */
-	public static void removeCommonFrames(List causeFrames, List wrapperFrames) {
-		if ( causeFrames == null || wrapperFrames == null ) {
-			throw new IllegalArgumentException( "The List must not be null" );
-		}
-		int causeFrameIndex = causeFrames.size() - 1;
-		int wrapperFrameIndex = wrapperFrames.size() - 1;
-		while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 ) {
-			// Remove the frame from the cause trace if it is the same
-			// as in the wrapper trace
-			String causeFrame = ( String ) causeFrames.get( causeFrameIndex );
-			String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex );
-			if ( causeFrame.equals( wrapperFrame ) ) {
-				causeFrames.remove( causeFrameIndex );
-			}
-			causeFrameIndex--;
-			wrapperFrameIndex--;
-		}
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Gets the stack trace from a Throwable as a String.</p>
-	 *
-	 * @param throwable the <code>Throwable</code> to be examined
-	 * @return the stack trace as generated by the exception's
-	 *         <code>printStackTrace(PrintWriter)</code> method
-	 */
-	public static String getStackTrace(Throwable throwable) {
-		StringWriter sw = new StringWriter();
-		PrintWriter pw = new PrintWriter( sw, true );
-		throwable.printStackTrace( pw );
-		return sw.getBuffer().toString();
-	}
-
-	/**
-	 * <p>A way to get the entire nested stack-trace of an throwable.</p>
-	 *
-	 * @param throwable the <code>Throwable</code> to be examined
-	 * @return the nested stack trace, with the root cause first
-	 * @since 2.0
-	 */
-	public static String getFullStackTrace(Throwable throwable) {
-		StringWriter sw = new StringWriter();
-		PrintWriter pw = new PrintWriter( sw, true );
-		Throwable[] ts = getThrowables( throwable );
-		for ( int i = 0; i < ts.length; i++ ) {
-			ts[i].printStackTrace( pw );
-			if ( isNestedThrowable( ts[i] ) ) {
-				break;
-			}
-		}
-		return sw.getBuffer().toString();
-	}
-
-	//-----------------------------------------------------------------------
-	/**
-	 * <p>Captures the stack trace associated with the specified
-	 * <code>Throwable</code> object, decomposing it into a list of
-	 * stack frames.</p>
-	 *
-	 * @param throwable the <code>Throwable</code> to exaamine, may be null
-	 * @return an array of strings describing each stack frame, never null
-	 */
-	public static String[] getStackFrames(Throwable throwable) {
-		if ( throwable == null ) {
-			return ArrayHelper.EMPTY_STRING_ARRAY;
-		}
-		return getStackFrames( getStackTrace( throwable ) );
-	}
-
-	/**
-	 * <p>Functionality shared between the
-	 * <code>getStackFrames(Throwable)</code> methods of this and the
-	 * {@link org.apache.commons.lang.exception.NestableDelegate}
-	 * classes.</p>
-	 */
-	static String[] getStackFrames(String stackTrace) {
-		String linebreak = LINE_SEPARATOR;
-		StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
-		List list = new LinkedList();
-		while ( frames.hasMoreTokens() ) {
-			list.add( frames.nextToken() );
-		}
-		return ( String[] ) list.toArray( new String[list.size()] );
-	}
-
-	/**
-	 * <p>Produces a <code>List</code> of stack frames - the message
-	 * is not included.</p>
-	 * <p/>
-	 * <p>This works in most cases - it will only fail if the exception
-	 * message contains a line that starts with:
-	 * <code>&quot;&nbsp;&nbsp;&nbsp;at&quot;.</code></p>
-	 *
-	 * @param t is any throwable
-	 * @return List of stack frames
-	 */
-	static List getStackFrameList(Throwable t) {
-		String stackTrace = getStackTrace( t );
-		String linebreak = LINE_SEPARATOR;
-		StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
-		List list = new LinkedList();
-		boolean traceStarted = false;
-		while ( frames.hasMoreTokens() ) {
-			String token = frames.nextToken();
-			// Determine if the line starts with <whitespace>at
-			int at = token.indexOf( "at" );
-			if ( at != -1 && token.substring( 0, at ).trim().length() == 0 ) {
-				traceStarted = true;
-				list.add( token );
-			}
-			else if ( traceStarted ) {
-				break;
-			}
-		}
-		return list;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/ExceptionUtils.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ExceptionUtils.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,705 @@
+/*
+ * 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.exception;
+
+import org.hibernate.util.ArrayHelper;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * <p>Provides utilities for manipulating and examining
+ * <code>Throwable</code> objects.</p>
+ *
+ * @author <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
+ * @author Dmitri Plotnikov
+ * @author Stephen Colebourne
+ * @author <a href="mailto:ggregory at seagullsw.com">Gary Gregory</a>
+ * @author Pete Gieser
+ * @version $Id: ExceptionUtils.java 4782 2004-11-21 00:11:27Z pgmjsd $
+ * @since 1.0
+ */
+public final class ExceptionUtils {
+
+	private static final String LINE_SEPARATOR = System.getProperty( "line.separator" );
+
+	/**
+	 * <p>Used when printing stack frames to denote the start of a
+	 * wrapped exception.</p>
+	 * <p/>
+	 * <p>Package private for accessibility by test suite.</p>
+	 */
+	static final String WRAPPED_MARKER = " [wrapped] ";
+
+	/**
+	 * <p>The names of methods commonly used to access a wrapped exception.</p>
+	 */
+	private static final String[] CAUSE_METHOD_NAMES = {
+		"getCause",
+		"getNextException",
+		"getTargetException",
+		"getException",
+		"getSourceException",
+		"getRootCause",
+		"getCausedByException",
+		"getNested"
+	};
+
+	/**
+	 * <p>The Method object for JDK1.4 getCause.</p>
+	 */
+	private static final Method THROWABLE_CAUSE_METHOD;
+
+	static {
+		Method getCauseMethod;
+		try {
+			getCauseMethod = Throwable.class.getMethod( "getCause", null );
+		}
+		catch ( Exception e ) {
+			getCauseMethod = null;
+		}
+		THROWABLE_CAUSE_METHOD = getCauseMethod;
+	}
+
+	private ExceptionUtils() {
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Adds to the list of method names used in the search for <code>Throwable</code>
+	 * objects.</p>
+	 *
+	 * @param methodName  the methodName to add to the list, <code>null</code>
+	 *  and empty strings are ignored
+	 * @since 2.0
+	 */
+	/*public static void addCauseMethodName(String methodName) {
+		if ( StringHelper.isNotEmpty(methodName) ) {
+			List list = new ArrayList( Arrays.asList(CAUSE_METHOD_NAMES );
+			list.add(methodName);
+			CAUSE_METHOD_NAMES = (String[]) list.toArray(new String[list.size()]);
+		}
+	}*/
+
+	/**
+	 * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
+	 * <p/>
+	 * <p>The method searches for methods with specific names that return a
+	 * <code>Throwable</code> object. This will pick up most wrapping exceptions,
+	 * including those from JDK 1.4, and
+	 * {@link org.apache.commons.lang.exception.NestableException NestableException}.
+	 * The method names can be added to using {@link #addCauseMethodName(String)}.</p>
+	 * <p/>
+	 * <p>The default list searched for are:</p>
+	 * <ul>
+	 * <li><code>getCause()</code></li>
+	 * <li><code>getNextException()</code></li>
+	 * <li><code>getTargetException()</code></li>
+	 * <li><code>getException()</code></li>
+	 * <li><code>getSourceException()</code></li>
+	 * <li><code>getRootCause()</code></li>
+	 * <li><code>getCausedByException()</code></li>
+	 * <li><code>getNested()</code></li>
+	 * </ul>
+	 * <p/>
+	 * <p>In the absence of any such method, the object is inspected for a
+	 * <code>detail</code> field assignable to a <code>Throwable</code>.</p>
+	 * <p/>
+	 * <p>If none of the above is found, returns <code>null</code>.</p>
+	 *
+	 * @param throwable the throwable to introspect for a cause, may be null
+	 * @return the cause of the <code>Throwable</code>,
+	 *         <code>null</code> if none found or null throwable input
+	 */
+	public static Throwable getCause(Throwable throwable) {
+		return getCause( throwable, CAUSE_METHOD_NAMES );
+	}
+
+	/**
+	 * <p>Introspects the <code>Throwable</code> to obtain the cause.</p>
+	 * <p/>
+	 * <ol>
+	 * <li>Try known exception types.</li>
+	 * <li>Try the supplied array of method names.</li>
+	 * <li>Try the field 'detail'.</li>
+	 * </ol>
+	 * <p/>
+	 * <p>A <code>null</code> set of method names means use the default set.
+	 * A <code>null</code> in the set of method names will be ignored.</p>
+	 *
+	 * @param throwable   the throwable to introspect for a cause, may be null
+	 * @param methodNames the method names, null treated as default set
+	 * @return the cause of the <code>Throwable</code>,
+	 *         <code>null</code> if none found or null throwable input
+	 */
+	public static Throwable getCause(Throwable throwable, String[] methodNames) {
+		if ( throwable == null ) {
+			return null;
+		}
+		Throwable cause = getCauseUsingWellKnownTypes( throwable );
+		if ( cause == null ) {
+			if ( methodNames == null ) {
+				methodNames = CAUSE_METHOD_NAMES;
+			}
+			for ( int i = 0; i < methodNames.length; i++ ) {
+				String methodName = methodNames[i];
+				if ( methodName != null ) {
+					cause = getCauseUsingMethodName( throwable, methodName );
+					if ( cause != null ) {
+						break;
+					}
+				}
+			}
+
+			if ( cause == null ) {
+				cause = getCauseUsingFieldName( throwable, "detail" );
+			}
+		}
+		return cause;
+	}
+
+	/**
+	 * <p>Introspects the <code>Throwable</code> to obtain the root cause.</p>
+	 * <p/>
+	 * <p>This method walks through the exception chain to the last element,
+	 * "root" of the tree, using {@link #getCause(Throwable)}, and
+	 * returns that exception.</p>
+	 *
+	 * @param throwable the throwable to get the root cause for, may be null
+	 * @return the root cause of the <code>Throwable</code>,
+	 *         <code>null</code> if none found or null throwable input
+	 */
+	public static Throwable getRootCause(Throwable throwable) {
+		Throwable cause = getCause( throwable );
+		if ( cause != null ) {
+			throwable = cause;
+			while ( ( throwable = getCause( throwable ) ) != null ) {
+				cause = throwable;
+			}
+		}
+		return cause;
+	}
+
+	/**
+	 * <p>Finds a <code>Throwable</code> for known types.</p>
+	 * <p/>
+	 * <p>Uses <code>instanceof</code> checks to examine the exception,
+	 * looking for well known types which could contain chained or
+	 * wrapped exceptions.</p>
+	 *
+	 * @param throwable the exception to examine
+	 * @return the wrapped exception, or <code>null</code> if not found
+	 */
+	private static Throwable getCauseUsingWellKnownTypes(Throwable throwable) {
+		if ( throwable instanceof Nestable ) {
+			return ( ( Nestable ) throwable ).getCause();
+		}
+		else if ( throwable instanceof SQLException ) {
+			return ( ( SQLException ) throwable ).getNextException();
+		}
+		else if ( throwable instanceof InvocationTargetException ) {
+			return ( ( InvocationTargetException ) throwable ).getTargetException();
+		}
+		else {
+			return null;
+		}
+	}
+
+	/**
+	 * <p>Finds a <code>Throwable</code> by method name.</p>
+	 *
+	 * @param throwable  the exception to examine
+	 * @param methodName the name of the method to find and invoke
+	 * @return the wrapped exception, or <code>null</code> if not found
+	 */
+	private static Throwable getCauseUsingMethodName(Throwable throwable, String methodName) {
+		Method method = null;
+		try {
+			method = throwable.getClass().getMethod( methodName, null );
+		}
+		catch ( NoSuchMethodException ignored ) {
+		}
+		catch ( SecurityException ignored ) {
+		}
+
+		if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
+			try {
+				return ( Throwable ) method.invoke( throwable, ArrayHelper.EMPTY_OBJECT_ARRAY );
+			}
+			catch ( IllegalAccessException ignored ) {
+			}
+			catch ( IllegalArgumentException ignored ) {
+			}
+			catch ( InvocationTargetException ignored ) {
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * <p>Finds a <code>Throwable</code> by field name.</p>
+	 *
+	 * @param throwable the exception to examine
+	 * @param fieldName the name of the attribute to examine
+	 * @return the wrapped exception, or <code>null</code> if not found
+	 */
+	private static Throwable getCauseUsingFieldName(Throwable throwable, String fieldName) {
+		Field field = null;
+		try {
+			field = throwable.getClass().getField( fieldName );
+		}
+		catch ( NoSuchFieldException ignored ) {
+		}
+		catch ( SecurityException ignored ) {
+		}
+
+		if ( field != null && Throwable.class.isAssignableFrom( field.getType() ) ) {
+			try {
+				return ( Throwable ) field.get( throwable );
+			}
+			catch ( IllegalAccessException ignored ) {
+			}
+			catch ( IllegalArgumentException ignored ) {
+			}
+		}
+		return null;
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Checks if the Throwable class has a <code>getCause</code> method.</p>
+	 * <p/>
+	 * <p>This is true for JDK 1.4 and above.</p>
+	 *
+	 * @return true if Throwable is nestable
+	 * @since 2.0
+	 */
+	public static boolean isThrowableNested() {
+		return ( THROWABLE_CAUSE_METHOD != null );
+	}
+
+	/**
+	 * <p>Checks whether this <code>Throwable</code> class can store a cause.</p>
+	 * <p/>
+	 * <p>This method does <b>not</b> check whether it actually does store a cause.<p>
+	 *
+	 * @param throwable the <code>Throwable</code> to examine, may be null
+	 * @return boolean <code>true</code> if nested otherwise <code>false</code>
+	 * @since 2.0
+	 */
+	public static boolean isNestedThrowable(Throwable throwable) {
+		if ( throwable == null ) {
+			return false;
+		}
+
+		if ( throwable instanceof Nestable ) {
+			return true;
+		}
+		else if ( throwable instanceof SQLException ) {
+			return true;
+		}
+		else if ( throwable instanceof InvocationTargetException ) {
+			return true;
+		}
+		else if ( isThrowableNested() ) {
+			return true;
+		}
+
+		Class cls = throwable.getClass();
+		for ( int i = 0, isize = CAUSE_METHOD_NAMES.length; i < isize; i++ ) {
+			try {
+				Method method = cls.getMethod( CAUSE_METHOD_NAMES[i], null );
+				if ( method != null && Throwable.class.isAssignableFrom( method.getReturnType() ) ) {
+					return true;
+				}
+			}
+			catch ( NoSuchMethodException ignored ) {
+			}
+			catch ( SecurityException ignored ) {
+			}
+		}
+
+		try {
+			Field field = cls.getField( "detail" );
+			if ( field != null ) {
+				return true;
+			}
+		}
+		catch ( NoSuchFieldException ignored ) {
+		}
+		catch ( SecurityException ignored ) {
+		}
+
+		return false;
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Counts the number of <code>Throwable</code> objects in the
+	 * exception chain.</p>
+	 * <p/>
+	 * <p>A throwable without cause will return <code>1</code>.
+	 * A throwable with one cause will return <code>2</code> and so on.
+	 * A <code>null</code> throwable will return <code>0</code>.</p>
+	 *
+	 * @param throwable the throwable to inspect, may be null
+	 * @return the count of throwables, zero if null input
+	 */
+	public static int getThrowableCount(Throwable throwable) {
+		int count = 0;
+		while ( throwable != null ) {
+			count++;
+			throwable = ExceptionUtils.getCause( throwable );
+		}
+		return count;
+	}
+
+	/**
+	 * <p>Returns the list of <code>Throwable</code> objects in the
+	 * exception chain.</p>
+	 * <p/>
+	 * <p>A throwable without cause will return an array containing
+	 * one element - the input throwable.
+	 * A throwable with one cause will return an array containing
+	 * two elements. - the input throwable and the cause throwable.
+	 * A <code>null</code> throwable will return an array size zero.</p>
+	 *
+	 * @param throwable the throwable to inspect, may be null
+	 * @return the array of throwables, never null
+	 */
+	public static Throwable[] getThrowables(Throwable throwable) {
+		List list = new ArrayList();
+		while ( throwable != null ) {
+			list.add( throwable );
+			throwable = ExceptionUtils.getCause( throwable );
+		}
+		return ( Throwable[] ) list.toArray( new Throwable[list.size()] );
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Returns the (zero based) index of the first <code>Throwable</code>
+	 * that matches the specified type in the exception chain.</p>
+	 * <p/>
+	 * <p>A <code>null</code> throwable returns <code>-1</code>.
+	 * A <code>null</code> type returns <code>-1</code>.
+	 * No match in the chain returns <code>-1</code>.</p>
+	 *
+	 * @param throwable the throwable to inspect, may be null
+	 * @param type      the type to search for
+	 * @return the index into the throwable chain, -1 if no match or null input
+	 */
+	public static int indexOfThrowable(Throwable throwable, Class type) {
+		return indexOfThrowable( throwable, type, 0 );
+	}
+
+	/**
+	 * <p>Returns the (zero based) index of the first <code>Throwable</code>
+	 * that matches the specified type in the exception chain from
+	 * a specified index.</p>
+	 * <p/>
+	 * <p>A <code>null</code> throwable returns <code>-1</code>.
+	 * A <code>null</code> type returns <code>-1</code>.
+	 * No match in the chain returns <code>-1</code>.
+	 * A negative start index is treated as zero.
+	 * A start index greater than the number of throwables returns <code>-1</code>.</p>
+	 *
+	 * @param throwable the throwable to inspect, may be null
+	 * @param type      the type to search for
+	 * @param fromIndex the (zero based) index of the starting position,
+	 *                  negative treated as zero, larger than chain size returns -1
+	 * @return the index into the throwable chain, -1 if no match or null input
+	 */
+	public static int indexOfThrowable(Throwable throwable, Class type, int fromIndex) {
+		if ( throwable == null ) {
+			return -1;
+		}
+		if ( fromIndex < 0 ) {
+			fromIndex = 0;
+		}
+		Throwable[] throwables = ExceptionUtils.getThrowables( throwable );
+		if ( fromIndex >= throwables.length ) {
+			return -1;
+		}
+		for ( int i = fromIndex; i < throwables.length; i++ ) {
+			if ( throwables[i].getClass().equals( type ) ) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Prints a compact stack trace for the root cause of a throwable
+	 * to <code>System.err</code>.</p>
+	 * <p/>
+	 * <p>The compact stack trace starts with the root cause and prints
+	 * stack frames up to the place where it was caught and wrapped.
+	 * Then it prints the wrapped exception and continues with stack frames
+	 * until the wrapper exception is caught and wrapped again, etc.</p>
+	 * <p/>
+	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
+	 * that don't have nested causes.</p>
+	 *
+	 * @param throwable the throwable to output
+	 * @since 2.0
+	 */
+	public static void printRootCauseStackTrace(Throwable throwable) {
+		printRootCauseStackTrace( throwable, System.err );
+	}
+
+	/**
+	 * <p>Prints a compact stack trace for the root cause of a throwable.</p>
+	 * <p/>
+	 * <p>The compact stack trace starts with the root cause and prints
+	 * stack frames up to the place where it was caught and wrapped.
+	 * Then it prints the wrapped exception and continues with stack frames
+	 * until the wrapper exception is caught and wrapped again, etc.</p>
+	 * <p/>
+	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
+	 * that don't have nested causes.</p>
+	 *
+	 * @param throwable the throwable to output, may be null
+	 * @param stream    the stream to output to, may not be null
+	 * @throws IllegalArgumentException if the stream is <code>null</code>
+	 * @since 2.0
+	 */
+	public static void printRootCauseStackTrace(Throwable throwable, PrintStream stream) {
+		if ( throwable == null ) {
+			return;
+		}
+		if ( stream == null ) {
+			throw new IllegalArgumentException( "The PrintStream must not be null" );
+		}
+		String trace[] = getRootCauseStackTrace( throwable );
+		for ( int i = 0; i < trace.length; i++ ) {
+			stream.println( trace[i] );
+		}
+		stream.flush();
+	}
+
+	/**
+	 * <p>Prints a compact stack trace for the root cause of a throwable.</p>
+	 * <p/>
+	 * <p>The compact stack trace starts with the root cause and prints
+	 * stack frames up to the place where it was caught and wrapped.
+	 * Then it prints the wrapped exception and continues with stack frames
+	 * until the wrapper exception is caught and wrapped again, etc.</p>
+	 * <p/>
+	 * <p>The method is equivalent to <code>printStackTrace</code> for throwables
+	 * that don't have nested causes.</p>
+	 *
+	 * @param throwable the throwable to output, may be null
+	 * @param writer    the writer to output to, may not be null
+	 * @throws IllegalArgumentException if the writer is <code>null</code>
+	 * @since 2.0
+	 */
+	public static void printRootCauseStackTrace(Throwable throwable, PrintWriter writer) {
+		if ( throwable == null ) {
+			return;
+		}
+		if ( writer == null ) {
+			throw new IllegalArgumentException( "The PrintWriter must not be null" );
+		}
+		String trace[] = getRootCauseStackTrace( throwable );
+		for ( int i = 0; i < trace.length; i++ ) {
+			writer.println( trace[i] );
+		}
+		writer.flush();
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Creates a compact stack trace for the root cause of the supplied
+	 * <code>Throwable</code>.</p>
+	 *
+	 * @param throwable the throwable to examine, may be null
+	 * @return an array of stack trace frames, never null
+	 * @since 2.0
+	 */
+	public static String[] getRootCauseStackTrace(Throwable throwable) {
+		if ( throwable == null ) {
+			return ArrayHelper.EMPTY_STRING_ARRAY;
+		}
+		Throwable throwables[] = getThrowables( throwable );
+		int count = throwables.length;
+		ArrayList frames = new ArrayList();
+		List nextTrace = getStackFrameList( throwables[count - 1] );
+		for ( int i = count; --i >= 0; ) {
+			List trace = nextTrace;
+			if ( i != 0 ) {
+				nextTrace = getStackFrameList( throwables[i - 1] );
+				removeCommonFrames( trace, nextTrace );
+			}
+			if ( i == count - 1 ) {
+				frames.add( throwables[i].toString() );
+			}
+			else {
+				frames.add( WRAPPED_MARKER + throwables[i].toString() );
+			}
+			for ( int j = 0; j < trace.size(); j++ ) {
+				frames.add( trace.get( j ) );
+			}
+		}
+		return ( String[] ) frames.toArray( new String[0] );
+	}
+
+	/**
+	 * <p>Removes common frames from the cause trace given the two stack traces.</p>
+	 *
+	 * @param causeFrames   stack trace of a cause throwable
+	 * @param wrapperFrames stack trace of a wrapper throwable
+	 * @throws IllegalArgumentException if either argument is null
+	 * @since 2.0
+	 */
+	public static void removeCommonFrames(List causeFrames, List wrapperFrames) {
+		if ( causeFrames == null || wrapperFrames == null ) {
+			throw new IllegalArgumentException( "The List must not be null" );
+		}
+		int causeFrameIndex = causeFrames.size() - 1;
+		int wrapperFrameIndex = wrapperFrames.size() - 1;
+		while ( causeFrameIndex >= 0 && wrapperFrameIndex >= 0 ) {
+			// Remove the frame from the cause trace if it is the same
+			// as in the wrapper trace
+			String causeFrame = ( String ) causeFrames.get( causeFrameIndex );
+			String wrapperFrame = ( String ) wrapperFrames.get( wrapperFrameIndex );
+			if ( causeFrame.equals( wrapperFrame ) ) {
+				causeFrames.remove( causeFrameIndex );
+			}
+			causeFrameIndex--;
+			wrapperFrameIndex--;
+		}
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Gets the stack trace from a Throwable as a String.</p>
+	 *
+	 * @param throwable the <code>Throwable</code> to be examined
+	 * @return the stack trace as generated by the exception's
+	 *         <code>printStackTrace(PrintWriter)</code> method
+	 */
+	public static String getStackTrace(Throwable throwable) {
+		StringWriter sw = new StringWriter();
+		PrintWriter pw = new PrintWriter( sw, true );
+		throwable.printStackTrace( pw );
+		return sw.getBuffer().toString();
+	}
+
+	/**
+	 * <p>A way to get the entire nested stack-trace of an throwable.</p>
+	 *
+	 * @param throwable the <code>Throwable</code> to be examined
+	 * @return the nested stack trace, with the root cause first
+	 * @since 2.0
+	 */
+	public static String getFullStackTrace(Throwable throwable) {
+		StringWriter sw = new StringWriter();
+		PrintWriter pw = new PrintWriter( sw, true );
+		Throwable[] ts = getThrowables( throwable );
+		for ( int i = 0; i < ts.length; i++ ) {
+			ts[i].printStackTrace( pw );
+			if ( isNestedThrowable( ts[i] ) ) {
+				break;
+			}
+		}
+		return sw.getBuffer().toString();
+	}
+
+	//-----------------------------------------------------------------------
+	/**
+	 * <p>Captures the stack trace associated with the specified
+	 * <code>Throwable</code> object, decomposing it into a list of
+	 * stack frames.</p>
+	 *
+	 * @param throwable the <code>Throwable</code> to exaamine, may be null
+	 * @return an array of strings describing each stack frame, never null
+	 */
+	public static String[] getStackFrames(Throwable throwable) {
+		if ( throwable == null ) {
+			return ArrayHelper.EMPTY_STRING_ARRAY;
+		}
+		return getStackFrames( getStackTrace( throwable ) );
+	}
+
+	/**
+	 * <p>Functionality shared between the
+	 * <code>getStackFrames(Throwable)</code> methods of this and the
+	 * {@link org.apache.commons.lang.exception.NestableDelegate}
+	 * classes.</p>
+	 */
+	static String[] getStackFrames(String stackTrace) {
+		String linebreak = LINE_SEPARATOR;
+		StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
+		List list = new LinkedList();
+		while ( frames.hasMoreTokens() ) {
+			list.add( frames.nextToken() );
+		}
+		return ( String[] ) list.toArray( new String[list.size()] );
+	}
+
+	/**
+	 * <p>Produces a <code>List</code> of stack frames - the message
+	 * is not included.</p>
+	 * <p/>
+	 * <p>This works in most cases - it will only fail if the exception
+	 * message contains a line that starts with:
+	 * <code>&quot;&nbsp;&nbsp;&nbsp;at&quot;.</code></p>
+	 *
+	 * @param t is any throwable
+	 * @return List of stack frames
+	 */
+	static List getStackFrameList(Throwable t) {
+		String stackTrace = getStackTrace( t );
+		String linebreak = LINE_SEPARATOR;
+		StringTokenizer frames = new StringTokenizer( stackTrace, linebreak );
+		List list = new LinkedList();
+		boolean traceStarted = false;
+		while ( frames.hasMoreTokens() ) {
+			String token = frames.nextToken();
+			// Determine if the line starts with <whitespace>at
+			int at = token.indexOf( "at" );
+			if ( at != -1 && token.substring( 0, at ).trim().length() == 0 ) {
+				traceStarted = true;
+				list.add( token );
+			}
+			else if ( traceStarted ) {
+				break;
+			}
+		}
+		return list;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/GenericJDBCException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-// $Id: GenericJDBCException.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Generic, non-specific JDBCException.
- *
- * @author Steve Ebersole
- */
-public class GenericJDBCException extends JDBCException {
-	public GenericJDBCException(String string, SQLException root) {
-		super( string, root );
-	}
-
-	public GenericJDBCException(String string, SQLException root, String sql) {
-		super( string, root, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/GenericJDBCException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/GenericJDBCException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Generic, non-specific JDBCException.
+ *
+ * @author Steve Ebersole
+ */
+public class GenericJDBCException extends JDBCException {
+	public GenericJDBCException(String string, SQLException root) {
+		super( string, root );
+	}
+
+	public GenericJDBCException(String string, SQLException root, String sql) {
+		super( string, root, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-// $Id: JDBCConnectionException.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCException indicating problems with communicating with the
- * database (can also include incorrect JDBC setup).
- *
- * @author Steve Ebersole
- */
-public class JDBCConnectionException extends JDBCException {
-	public JDBCConnectionException(String string, SQLException root) {
-		super( string, root );
-	}
-
-	public JDBCConnectionException(String string, SQLException root, String sql) {
-		super( string, root, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCConnectionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCException indicating problems with communicating with the
+ * database (can also include incorrect JDBC setup).
+ *
+ * @author Steve Ebersole
+ */
+public class JDBCConnectionException extends JDBCException {
+	public JDBCConnectionException(String string, SQLException root) {
+		super( string, root );
+	}
+
+	public JDBCConnectionException(String string, SQLException root, String sql) {
+		super( string, root, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-// $Id: JDBCExceptionHelper.java 9557 2006-03-06 15:16:27Z steve.ebersole at jboss.com $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-import org.hibernate.util.JDBCExceptionReporter;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCExceptionHelper.
- *
- * @author Steve Ebersole
- */
-public final class JDBCExceptionHelper {
-
-	private JDBCExceptionHelper() {
-	}
-
-	/**
-	 * Converts the given SQLException into Hibernate's JDBCException hierarchy, as well as performing
-	 * appropriate logging.
-	 *
-	 * @param converter    The converter to use.
-	 * @param sqlException The exception to convert.
-	 * @param message      An optional error message.
-	 * @return The converted JDBCException.
-	 */
-	public static JDBCException convert(SQLExceptionConverter converter, SQLException sqlException, String message) {
-		return convert( converter, sqlException, message, "???" );
-	}
-
-	/**
-	 * Converts the given SQLException into Hibernate's JDBCException hierarchy, as well as performing
-	 * appropriate logging.
-	 *
-	 * @param converter    The converter to use.
-	 * @param sqlException The exception to convert.
-	 * @param message      An optional error message.
-	 * @return The converted JDBCException.
-	 */
-	public static JDBCException convert(SQLExceptionConverter converter, SQLException sqlException, String message, String sql) {
-		JDBCExceptionReporter.logExceptions( sqlException, message + " [" + sql + "]" );
-		return converter.convert( sqlException, message, sql );
-	}
-
-	/**
-	 * For the given SQLException, locates the vendor-specific error code.
-	 *
-	 * @param sqlException The exception from which to extract the SQLState
-	 * @return The error code.
-	 */
-	public static int extractErrorCode(SQLException sqlException) {
-		int errorCode = sqlException.getErrorCode();
-		SQLException nested = sqlException.getNextException();
-		while ( errorCode == 0 && nested != null ) {
-			errorCode = nested.getErrorCode();
-			nested = nested.getNextException();
-		}
-		return errorCode;
-	}
-
-	/**
-	 * For the given SQLException, locates the X/Open-compliant SQLState.
-	 *
-	 * @param sqlException The exception from which to extract the SQLState
-	 * @return The SQLState code, or null.
-	 */
-	public static String extractSqlState(SQLException sqlException) {
-		String sqlState = sqlException.getSQLState();
-		SQLException nested = sqlException.getNextException();
-		while ( sqlState == null && nested != null ) {
-			sqlState = nested.getSQLState();
-			nested = nested.getNextException();
-		}
-		return sqlState;
-	}
-
-	/**
-	 * For the given SQLException, locates the X/Open-compliant SQLState's class code.
-	 *
-	 * @param sqlException The exception from which to extract the SQLState class code
-	 * @return The SQLState class code, or null.
-	 */
-	public static String extractSqlStateClassCode(SQLException sqlException) {
-		return determineSqlStateClassCode( extractSqlState( sqlException ) );
-	}
-
-	public static String determineSqlStateClassCode(String sqlState) {
-		if ( sqlState == null || sqlState.length() < 2 ) {
-			return sqlState;
-		}
-		return sqlState.substring( 0, 2 );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/JDBCExceptionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.exception;
+
+import org.hibernate.JDBCException;
+import org.hibernate.util.JDBCExceptionReporter;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCExceptionHelper.
+ *
+ * @author Steve Ebersole
+ */
+public final class JDBCExceptionHelper {
+
+	private JDBCExceptionHelper() {
+	}
+
+	/**
+	 * Converts the given SQLException into Hibernate's JDBCException hierarchy, as well as performing
+	 * appropriate logging.
+	 *
+	 * @param converter    The converter to use.
+	 * @param sqlException The exception to convert.
+	 * @param message      An optional error message.
+	 * @return The converted JDBCException.
+	 */
+	public static JDBCException convert(SQLExceptionConverter converter, SQLException sqlException, String message) {
+		return convert( converter, sqlException, message, "???" );
+	}
+
+	/**
+	 * Converts the given SQLException into Hibernate's JDBCException hierarchy, as well as performing
+	 * appropriate logging.
+	 *
+	 * @param converter    The converter to use.
+	 * @param sqlException The exception to convert.
+	 * @param message      An optional error message.
+	 * @return The converted JDBCException.
+	 */
+	public static JDBCException convert(SQLExceptionConverter converter, SQLException sqlException, String message, String sql) {
+		JDBCExceptionReporter.logExceptions( sqlException, message + " [" + sql + "]" );
+		return converter.convert( sqlException, message, sql );
+	}
+
+	/**
+	 * For the given SQLException, locates the vendor-specific error code.
+	 *
+	 * @param sqlException The exception from which to extract the SQLState
+	 * @return The error code.
+	 */
+	public static int extractErrorCode(SQLException sqlException) {
+		int errorCode = sqlException.getErrorCode();
+		SQLException nested = sqlException.getNextException();
+		while ( errorCode == 0 && nested != null ) {
+			errorCode = nested.getErrorCode();
+			nested = nested.getNextException();
+		}
+		return errorCode;
+	}
+
+	/**
+	 * For the given SQLException, locates the X/Open-compliant SQLState.
+	 *
+	 * @param sqlException The exception from which to extract the SQLState
+	 * @return The SQLState code, or null.
+	 */
+	public static String extractSqlState(SQLException sqlException) {
+		String sqlState = sqlException.getSQLState();
+		SQLException nested = sqlException.getNextException();
+		while ( sqlState == null && nested != null ) {
+			sqlState = nested.getSQLState();
+			nested = nested.getNextException();
+		}
+		return sqlState;
+	}
+
+	/**
+	 * For the given SQLException, locates the X/Open-compliant SQLState's class code.
+	 *
+	 * @param sqlException The exception from which to extract the SQLState class code
+	 * @return The SQLState class code, or null.
+	 */
+	public static String extractSqlStateClassCode(SQLException sqlException) {
+		return determineSqlStateClassCode( extractSqlState( sqlException ) );
+	}
+
+	public static String determineSqlStateClassCode(String sqlState) {
+		if ( sqlState == null || sqlState.length() < 2 ) {
+			return sqlState;
+		}
+		return sqlState.substring( 0, 2 );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-// $Id: LockAcquisitionException.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCException indicating a problem acquiring lock
- * on the database.
- *
- * @author Steve Ebersole
- */
-public class LockAcquisitionException extends JDBCException {
-	public LockAcquisitionException(String string, SQLException root) {
-		super( string, root );
-	}
-
-	public LockAcquisitionException(String string, SQLException root, String sql) {
-		super( string, root, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/LockAcquisitionException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCException indicating a problem acquiring lock
+ * on the database.
+ *
+ * @author Steve Ebersole
+ */
+public class LockAcquisitionException extends JDBCException {
+	public LockAcquisitionException(String string, SQLException root) {
+		super( string, root );
+	}
+
+	public LockAcquisitionException(String string, SQLException root, String sql) {
+		super( string, root, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/Nestable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,203 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.exception;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * An interface to be implemented by {@link java.lang.Throwable}
- * extensions which would like to be able to nest root exceptions
- * inside themselves.
- *
- * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
- * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
- * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
- * @author Pete Gieser
- * @version $Id: Nestable.java 4782 2004-11-21 00:11:27Z pgmjsd $
- * @since 1.0
- */
-public interface Nestable {
-
-	/**
-	 * Returns the reference to the exception or error that caused the
-	 * exception implementing the <code>Nestable</code> to be thrown.
-	 *
-	 * @return throwable that caused the original exception
-	 */
-	public Throwable getCause();
-
-	/**
-	 * Returns the error message of this and any nested
-	 * <code>Throwable</code>.
-	 *
-	 * @return the error message
-	 */
-	public String getMessage();
-
-	/**
-	 * Returns the error message of the <code>Throwable</code> in the chain
-	 * of <code>Throwable</code>s at the specified index, numbererd from 0.
-	 *
-	 * @param index the index of the <code>Throwable</code> in the chain of
-	 *              <code>Throwable</code>s
-	 * @return the error message, or null if the <code>Throwable</code> at the
-	 *         specified index in the chain does not contain a message
-	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
-	 *                                   negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 */
-	public String getMessage(int index);
-
-	/**
-	 * Returns the error message of this and any nested <code>Throwable</code>s
-	 * in an array of Strings, one element for each message. Any
-	 * <code>Throwable</code> not containing a message is represented in the
-	 * array by a null. This has the effect of cause the length of the returned
-	 * array to be equal to the result of the {@link #getThrowableCount()}
-	 * operation.
-	 *
-	 * @return the error messages
-	 */
-	public String[] getMessages();
-
-	/**
-	 * Returns the <code>Throwable</code> in the chain of
-	 * <code>Throwable</code>s at the specified index, numbererd from 0.
-	 *
-	 * @param index the index, numbered from 0, of the <code>Throwable</code> in
-	 *              the chain of <code>Throwable</code>s
-	 * @return the <code>Throwable</code>
-	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
-	 *                                   negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 */
-	public Throwable getThrowable(int index);
-
-	/**
-	 * Returns the number of nested <code>Throwable</code>s represented by
-	 * this <code>Nestable</code>, including this <code>Nestable</code>.
-	 *
-	 * @return the throwable count
-	 */
-	public int getThrowableCount();
-
-	/**
-	 * Returns this <code>Nestable</code> and any nested <code>Throwable</code>s
-	 * in an array of <code>Throwable</code>s, one element for each
-	 * <code>Throwable</code>.
-	 *
-	 * @return the <code>Throwable</code>s
-	 */
-	public Throwable[] getThrowables();
-
-	/**
-	 * Returns the index, numbered from 0, of the first occurrence of the
-	 * specified type in the chain of <code>Throwable</code>s, or -1 if the
-	 * specified type is not found in the chain.
-	 *
-	 * @param type <code>Class</code> to be found
-	 * @return index of the first occurrence of the type in the chain, or -1 if
-	 *         the type is not found
-	 */
-	public int indexOfThrowable(Class type);
-
-	/**
-	 * Returns the index, numbered from 0, of the first <code>Throwable</code>
-	 * that matches the specified type in the chain of <code>Throwable</code>s
-	 * with an index greater than or equal to the specified index, or -1 if
-	 * the type is not found.
-	 *
-	 * @param type      <code>Class</code> to be found
-	 * @param fromIndex the index, numbered from 0, of the starting position in
-	 *                  the chain to be searched
-	 * @return index of the first occurrence of the type in the chain, or -1 if
-	 *         the type is not found
-	 * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
-	 *                                   is negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 */
-	public int indexOfThrowable(Class type, int fromIndex);
-
-	/**
-	 * Prints the stack trace of this exception to the specified print
-	 * writer.  Includes information from the exception, if any,
-	 * which caused this exception.
-	 *
-	 * @param out <code>PrintWriter</code> to use for output.
-	 */
-	public void printStackTrace(PrintWriter out);
-
-	/**
-	 * Prints the stack trace of this exception to the specified print
-	 * stream.  Includes inforamation from the exception, if any,
-	 * which caused this exception.
-	 *
-	 * @param out <code>PrintStream</code> to use for output.
-	 */
-	public void printStackTrace(PrintStream out);
-
-	/**
-	 * Prints the stack trace for this exception only--root cause not
-	 * included--using the provided writer.  Used by {@link
-	 * org.apache.commons.lang.exception.NestableDelegate} to write
-	 * individual stack traces to a buffer.  The implementation of
-	 * this method should call
-	 * <code>super.printStackTrace(out);</code> in most cases.
-	 *
-	 * @param out The writer to use.
-	 */
-	public void printPartialStackTrace(PrintWriter out);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/Nestable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/Nestable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,174 @@
+/*
+ * 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.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * An interface to be implemented by {@link java.lang.Throwable}
+ * extensions which would like to be able to nest root exceptions
+ * inside themselves.
+ *
+ * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
+ * @author Pete Gieser
+ * @version $Id: Nestable.java 4782 2004-11-21 00:11:27Z pgmjsd $
+ * @since 1.0
+ */
+public interface Nestable {
+
+	/**
+	 * Returns the reference to the exception or error that caused the
+	 * exception implementing the <code>Nestable</code> to be thrown.
+	 *
+	 * @return throwable that caused the original exception
+	 */
+	public Throwable getCause();
+
+	/**
+	 * Returns the error message of this and any nested
+	 * <code>Throwable</code>.
+	 *
+	 * @return the error message
+	 */
+	public String getMessage();
+
+	/**
+	 * Returns the error message of the <code>Throwable</code> in the chain
+	 * of <code>Throwable</code>s at the specified index, numbererd from 0.
+	 *
+	 * @param index the index of the <code>Throwable</code> in the chain of
+	 *              <code>Throwable</code>s
+	 * @return the error message, or null if the <code>Throwable</code> at the
+	 *         specified index in the chain does not contain a message
+	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+	 *                                   negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 */
+	public String getMessage(int index);
+
+	/**
+	 * Returns the error message of this and any nested <code>Throwable</code>s
+	 * in an array of Strings, one element for each message. Any
+	 * <code>Throwable</code> not containing a message is represented in the
+	 * array by a null. This has the effect of cause the length of the returned
+	 * array to be equal to the result of the {@link #getThrowableCount()}
+	 * operation.
+	 *
+	 * @return the error messages
+	 */
+	public String[] getMessages();
+
+	/**
+	 * Returns the <code>Throwable</code> in the chain of
+	 * <code>Throwable</code>s at the specified index, numbererd from 0.
+	 *
+	 * @param index the index, numbered from 0, of the <code>Throwable</code> in
+	 *              the chain of <code>Throwable</code>s
+	 * @return the <code>Throwable</code>
+	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+	 *                                   negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 */
+	public Throwable getThrowable(int index);
+
+	/**
+	 * Returns the number of nested <code>Throwable</code>s represented by
+	 * this <code>Nestable</code>, including this <code>Nestable</code>.
+	 *
+	 * @return the throwable count
+	 */
+	public int getThrowableCount();
+
+	/**
+	 * Returns this <code>Nestable</code> and any nested <code>Throwable</code>s
+	 * in an array of <code>Throwable</code>s, one element for each
+	 * <code>Throwable</code>.
+	 *
+	 * @return the <code>Throwable</code>s
+	 */
+	public Throwable[] getThrowables();
+
+	/**
+	 * Returns the index, numbered from 0, of the first occurrence of the
+	 * specified type in the chain of <code>Throwable</code>s, or -1 if the
+	 * specified type is not found in the chain.
+	 *
+	 * @param type <code>Class</code> to be found
+	 * @return index of the first occurrence of the type in the chain, or -1 if
+	 *         the type is not found
+	 */
+	public int indexOfThrowable(Class type);
+
+	/**
+	 * Returns the index, numbered from 0, of the first <code>Throwable</code>
+	 * that matches the specified type in the chain of <code>Throwable</code>s
+	 * with an index greater than or equal to the specified index, or -1 if
+	 * the type is not found.
+	 *
+	 * @param type      <code>Class</code> to be found
+	 * @param fromIndex the index, numbered from 0, of the starting position in
+	 *                  the chain to be searched
+	 * @return index of the first occurrence of the type in the chain, or -1 if
+	 *         the type is not found
+	 * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
+	 *                                   is negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 */
+	public int indexOfThrowable(Class type, int fromIndex);
+
+	/**
+	 * Prints the stack trace of this exception to the specified print
+	 * writer.  Includes information from the exception, if any,
+	 * which caused this exception.
+	 *
+	 * @param out <code>PrintWriter</code> to use for output.
+	 */
+	public void printStackTrace(PrintWriter out);
+
+	/**
+	 * Prints the stack trace of this exception to the specified print
+	 * stream.  Includes inforamation from the exception, if any,
+	 * which caused this exception.
+	 *
+	 * @param out <code>PrintStream</code> to use for output.
+	 */
+	public void printStackTrace(PrintStream out);
+
+	/**
+	 * Prints the stack trace for this exception only--root cause not
+	 * included--using the provided writer.  Used by {@link
+	 * org.apache.commons.lang.exception.NestableDelegate} to write
+	 * individual stack traces to a buffer.  The implementation of
+	 * this method should call
+	 * <code>super.printStackTrace(out);</code> in most cases.
+	 *
+	 * @param out The writer to use.
+	 */
+	public void printPartialStackTrace(PrintWriter out);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/NestableDelegate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,412 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.exception;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.Serializable;
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * <p>A shared implementation of the nestable exception functionality.</p>
- * <p/>
- * The code is shared between
- * {@link org.apache.commons.lang.exception.NestableError NestableError},
- * {@link org.apache.commons.lang.exception.NestableException NestableException} and
- * {@link org.apache.commons.lang.exception.NestableRuntimeException NestableRuntimeException}.
- * </p>
- *
- * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
- * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
- * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
- * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
- * @author Sean C. Sullivan
- * @author Stephen Colebourne
- * @version $Id: NestableDelegate.java 4782 2004-11-21 00:11:27Z pgmjsd $
- * @since 1.0
- */
-public class NestableDelegate implements Serializable {
-
-	/**
-	 * Constructor error message.
-	 */
-	private static final String MUST_BE_THROWABLE =
-			"The Nestable implementation passed to the NestableDelegate(Nestable) "
-			+ "constructor must extend java.lang.Throwable";
-
-	/**
-	 * Holds the reference to the exception or error that we're
-	 * wrapping (which must be a {@link
-	 * org.apache.commons.lang.exception.Nestable} implementation).
-	 */
-	private Throwable nestable = null;
-
-	/**
-	 * Whether to print the stack trace top-down.
-	 * This public flag may be set by calling code, typically in initialisation.
-	 *
-	 * @since 2.0
-	 */
-	private static boolean topDown = true;
-
-	/**
-	 * Whether to trim the repeated stack trace.
-	 * This public flag may be set by calling code, typically in initialisation.
-	 *
-	 * @since 2.0
-	 */
-	private static boolean trimStackFrames = true;
-
-	/**
-	 * Constructs a new <code>NestableDelegate</code> instance to manage the
-	 * specified <code>Nestable</code>.
-	 *
-	 * @param nestable the Nestable implementation (<i>must</i> extend
-	 *                 {@link java.lang.Throwable})
-	 * @since 2.0
-	 */
-	public NestableDelegate(Nestable nestable) {
-		if ( nestable instanceof Throwable ) {
-			this.nestable = ( Throwable ) nestable;
-		}
-		else {
-			throw new IllegalArgumentException( MUST_BE_THROWABLE );
-		}
-	}
-
-	/**
-	 * Returns the error message of the <code>Throwable</code> in the chain
-	 * of <code>Throwable</code>s at the specified index, numbererd from 0.
-	 *
-	 * @param index the index of the <code>Throwable</code> in the chain of
-	 *              <code>Throwable</code>s
-	 * @return the error message, or null if the <code>Throwable</code> at the
-	 *         specified index in the chain does not contain a message
-	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
-	 *                                   negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 * @since 2.0
-	 */
-	public String getMessage(int index) {
-		Throwable t = this.getThrowable( index );
-		if ( Nestable.class.isInstance( t ) ) {
-			return ( ( Nestable ) t ).getMessage( 0 );
-		}
-		else {
-			return t.getMessage();
-		}
-	}
-
-	/**
-	 * Returns the full message contained by the <code>Nestable</code>
-	 * and any nested <code>Throwable</code>s.
-	 *
-	 * @param baseMsg the base message to use when creating the full
-	 *                message. Should be generally be called via
-	 *                <code>nestableHelper.getMessage( super.getMessage() )</code>,
-	 *                where <code>super</code> is an instance of {@link
-	 *                java.lang.Throwable}.
-	 * @return The concatenated message for this and all nested
-	 *         <code>Throwable</code>s
-	 * @since 2.0
-	 */
-	public String getMessage(String baseMsg) {
-		StringBuffer msg = new StringBuffer();
-		if ( baseMsg != null ) {
-			msg.append( baseMsg );
-		}
-
-		Throwable nestedCause = ExceptionUtils.getCause( this.nestable );
-		if ( nestedCause != null ) {
-			String causeMsg = nestedCause.getMessage();
-			if ( causeMsg != null ) {
-				if ( baseMsg != null ) {
-					msg.append( ": " );
-				}
-				msg.append( causeMsg );
-			}
-
-		}
-		return ( msg.length() > 0 ? msg.toString() : null );
-	}
-
-	/**
-	 * Returns the error message of this and any nested <code>Throwable</code>s
-	 * in an array of Strings, one element for each message. Any
-	 * <code>Throwable</code> not containing a message is represented in the
-	 * array by a null. This has the effect of cause the length of the returned
-	 * array to be equal to the result of the {@link #getThrowableCount()}
-	 * operation.
-	 *
-	 * @return the error messages
-	 * @since 2.0
-	 */
-	public String[] getMessages() {
-		Throwable[] throwables = this.getThrowables();
-		String[] msgs = new String[throwables.length];
-		for ( int i = 0; i < throwables.length; i++ ) {
-			msgs[i] = Nestable.class.isInstance( throwables[i] ) ?
-					( ( Nestable ) throwables[i] ).getMessage( 0 ) :
-					throwables[i].getMessage();
-		}
-		return msgs;
-	}
-
-	/**
-	 * Returns the <code>Throwable</code> in the chain of
-	 * <code>Throwable</code>s at the specified index, numbererd from 0.
-	 *
-	 * @param index the index, numbered from 0, of the <code>Throwable</code> in
-	 *              the chain of <code>Throwable</code>s
-	 * @return the <code>Throwable</code>
-	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
-	 *                                   negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 * @since 2.0
-	 */
-	public Throwable getThrowable(int index) {
-		if ( index == 0 ) {
-			return this.nestable;
-		}
-		Throwable[] throwables = this.getThrowables();
-		return throwables[index];
-	}
-
-	/**
-	 * Returns the number of <code>Throwable</code>s contained in the
-	 * <code>Nestable</code> contained by this delegate.
-	 *
-	 * @return the throwable count
-	 * @since 2.0
-	 */
-	public int getThrowableCount() {
-		return ExceptionUtils.getThrowableCount( this.nestable );
-	}
-
-	/**
-	 * Returns this delegate's <code>Nestable</code> and any nested
-	 * <code>Throwable</code>s in an array of <code>Throwable</code>s, one
-	 * element for each <code>Throwable</code>.
-	 *
-	 * @return the <code>Throwable</code>s
-	 * @since 2.0
-	 */
-	public Throwable[] getThrowables() {
-		return ExceptionUtils.getThrowables( this.nestable );
-	}
-
-	/**
-	 * Returns the index, numbered from 0, of the first <code>Throwable</code>
-	 * that matches the specified type in the chain of <code>Throwable</code>s
-	 * held in this delegate's <code>Nestable</code> with an index greater than
-	 * or equal to the specified index, or -1 if the type is not found.
-	 *
-	 * @param type      <code>Class</code> to be found
-	 * @param fromIndex the index, numbered from 0, of the starting position in
-	 *                  the chain to be searched
-	 * @return index of the first occurrence of the type in the chain, or -1 if
-	 *         the type is not found
-	 * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
-	 *                                   is negative or not less than the count of <code>Throwable</code>s in the
-	 *                                   chain
-	 * @since 2.0
-	 */
-	public int indexOfThrowable(Class type, int fromIndex) {
-		if ( fromIndex < 0 ) {
-			throw new IndexOutOfBoundsException( "The start index was out of bounds: " + fromIndex );
-		}
-		Throwable[] throwables = ExceptionUtils.getThrowables( this.nestable );
-		if ( fromIndex >= throwables.length ) {
-			throw new IndexOutOfBoundsException( "The start index was out of bounds: "
-					+ fromIndex + " >= " + throwables.length );
-		}
-		for ( int i = fromIndex; i < throwables.length; i++ ) {
-			if ( throwables[i].getClass().equals( type ) ) {
-				return i;
-			}
-		}
-		return -1;
-	}
-
-	/**
-	 * Prints the stack trace of this exception the the standar error
-	 * stream.
-	 */
-	public void printStackTrace() {
-		printStackTrace( System.err );
-	}
-
-	/**
-	 * Prints the stack trace of this exception to the specified
-	 * stream.
-	 *
-	 * @param out <code>PrintStream</code> to use for output.
-	 * @see #printStackTrace(PrintWriter)
-	 */
-	public void printStackTrace(PrintStream out) {
-		synchronized ( out ) {
-			PrintWriter pw = new PrintWriter( out, false );
-			printStackTrace( pw );
-			// Flush the PrintWriter before it's GC'ed.
-			pw.flush();
-		}
-	}
-
-	/**
-	 * Prints the stack trace of this exception to the specified
-	 * writer. If the Throwable class has a <code>getCause</code>
-	 * method (i.e. running on jre1.4 or higher), this method just
-	 * uses Throwable's printStackTrace() method. Otherwise, generates
-	 * the stack-trace, by taking into account the 'topDown' and
-	 * 'trimStackFrames' parameters. The topDown and trimStackFrames
-	 * are set to 'true' by default (produces jre1.4-like stack trace).
-	 *
-	 * @param out <code>PrintWriter</code> to use for output.
-	 */
-	public void printStackTrace(PrintWriter out) {
-		Throwable throwable = this.nestable;
-		// if running on jre1.4 or higher, use default printStackTrace
-		if ( ExceptionUtils.isThrowableNested() ) {
-			if ( throwable instanceof Nestable ) {
-				( ( Nestable ) throwable ).printPartialStackTrace( out );
-			}
-			else {
-				throwable.printStackTrace( out );
-			}
-			return;
-		}
-
-		// generating the nested stack trace
-		List stacks = new ArrayList();
-		while ( throwable != null ) {
-			String[] st = getStackFrames( throwable );
-			stacks.add( st );
-			throwable = ExceptionUtils.getCause( throwable );
-		}
-
-		// If NOT topDown, reverse the stack
-		String separatorLine = "Caused by: ";
-		if ( !topDown ) {
-			separatorLine = "Rethrown as: ";
-			Collections.reverse( stacks );
-		}
-
-		// Remove the repeated lines in the stack
-		if ( trimStackFrames ) trimStackFrames( stacks );
-
-		synchronized ( out ) {
-			for ( Iterator iter = stacks.iterator(); iter.hasNext(); ) {
-				String[] st = ( String[] ) iter.next();
-				for ( int i = 0, len = st.length; i < len; i++ ) {
-					out.println( st[i] );
-				}
-				if ( iter.hasNext() ) out.print( separatorLine );
-			}
-		}
-	}
-
-	/**
-	 * Captures the stack trace associated with the specified
-	 * <code>Throwable</code> object, decomposing it into a list of
-	 * stack frames.
-	 *
-	 * @param t The <code>Throwable</code>.
-	 * @return An array of strings describing each stack frame.
-	 * @since 2.0
-	 */
-	protected String[] getStackFrames(Throwable t) {
-		StringWriter sw = new StringWriter();
-		PrintWriter pw = new PrintWriter( sw, true );
-
-		// Avoid infinite loop between decompose() and printStackTrace().
-		if ( t instanceof Nestable ) {
-			( ( Nestable ) t ).printPartialStackTrace( pw );
-		}
-		else {
-			t.printStackTrace( pw );
-		}
-		return ExceptionUtils.getStackFrames( sw.getBuffer().toString() );
-	}
-
-	/**
-	 * Trims the stack frames. The first set is left untouched. The rest
-	 * of the frames are truncated from the bottom by comparing with
-	 * one just on top.
-	 *
-	 * @param stacks The list containing String[] elements
-	 * @since 2.0
-	 */
-	protected void trimStackFrames(List stacks) {
-		for ( int size = stacks.size(), i = size - 1; i > 0; i-- ) {
-			String[] curr = ( String[] ) stacks.get( i );
-			String[] next = ( String[] ) stacks.get( i - 1 );
-
-			List currList = new ArrayList( Arrays.asList( curr ) );
-			List nextList = new ArrayList( Arrays.asList( next ) );
-			ExceptionUtils.removeCommonFrames( currList, nextList );
-
-			int trimmed = curr.length - currList.size();
-			if ( trimmed > 0 ) {
-				currList.add( "\t... " + trimmed + " more" );
-				stacks.set( i,
-						currList.toArray( new String[currList.size()] ) );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/NestableDelegate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,383 @@
+/*
+ * 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.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * <p>A shared implementation of the nestable exception functionality.</p>
+ * <p/>
+ * The code is shared between
+ * {@link org.apache.commons.lang.exception.NestableError NestableError},
+ * {@link org.apache.commons.lang.exception.NestableException NestableException} and
+ * {@link org.apache.commons.lang.exception.NestableRuntimeException NestableRuntimeException}.
+ * </p>
+ *
+ * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
+ * @author Sean C. Sullivan
+ * @author Stephen Colebourne
+ * @version $Id: NestableDelegate.java 4782 2004-11-21 00:11:27Z pgmjsd $
+ * @since 1.0
+ */
+public class NestableDelegate implements Serializable {
+
+	/**
+	 * Constructor error message.
+	 */
+	private static final String MUST_BE_THROWABLE =
+			"The Nestable implementation passed to the NestableDelegate(Nestable) "
+			+ "constructor must extend java.lang.Throwable";
+
+	/**
+	 * Holds the reference to the exception or error that we're
+	 * wrapping (which must be a {@link
+	 * org.apache.commons.lang.exception.Nestable} implementation).
+	 */
+	private Throwable nestable = null;
+
+	/**
+	 * Whether to print the stack trace top-down.
+	 * This public flag may be set by calling code, typically in initialisation.
+	 *
+	 * @since 2.0
+	 */
+	private static boolean topDown = true;
+
+	/**
+	 * Whether to trim the repeated stack trace.
+	 * This public flag may be set by calling code, typically in initialisation.
+	 *
+	 * @since 2.0
+	 */
+	private static boolean trimStackFrames = true;
+
+	/**
+	 * Constructs a new <code>NestableDelegate</code> instance to manage the
+	 * specified <code>Nestable</code>.
+	 *
+	 * @param nestable the Nestable implementation (<i>must</i> extend
+	 *                 {@link java.lang.Throwable})
+	 * @since 2.0
+	 */
+	public NestableDelegate(Nestable nestable) {
+		if ( nestable instanceof Throwable ) {
+			this.nestable = ( Throwable ) nestable;
+		}
+		else {
+			throw new IllegalArgumentException( MUST_BE_THROWABLE );
+		}
+	}
+
+	/**
+	 * Returns the error message of the <code>Throwable</code> in the chain
+	 * of <code>Throwable</code>s at the specified index, numbererd from 0.
+	 *
+	 * @param index the index of the <code>Throwable</code> in the chain of
+	 *              <code>Throwable</code>s
+	 * @return the error message, or null if the <code>Throwable</code> at the
+	 *         specified index in the chain does not contain a message
+	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+	 *                                   negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 * @since 2.0
+	 */
+	public String getMessage(int index) {
+		Throwable t = this.getThrowable( index );
+		if ( Nestable.class.isInstance( t ) ) {
+			return ( ( Nestable ) t ).getMessage( 0 );
+		}
+		else {
+			return t.getMessage();
+		}
+	}
+
+	/**
+	 * Returns the full message contained by the <code>Nestable</code>
+	 * and any nested <code>Throwable</code>s.
+	 *
+	 * @param baseMsg the base message to use when creating the full
+	 *                message. Should be generally be called via
+	 *                <code>nestableHelper.getMessage( super.getMessage() )</code>,
+	 *                where <code>super</code> is an instance of {@link
+	 *                java.lang.Throwable}.
+	 * @return The concatenated message for this and all nested
+	 *         <code>Throwable</code>s
+	 * @since 2.0
+	 */
+	public String getMessage(String baseMsg) {
+		StringBuffer msg = new StringBuffer();
+		if ( baseMsg != null ) {
+			msg.append( baseMsg );
+		}
+
+		Throwable nestedCause = ExceptionUtils.getCause( this.nestable );
+		if ( nestedCause != null ) {
+			String causeMsg = nestedCause.getMessage();
+			if ( causeMsg != null ) {
+				if ( baseMsg != null ) {
+					msg.append( ": " );
+				}
+				msg.append( causeMsg );
+			}
+
+		}
+		return ( msg.length() > 0 ? msg.toString() : null );
+	}
+
+	/**
+	 * Returns the error message of this and any nested <code>Throwable</code>s
+	 * in an array of Strings, one element for each message. Any
+	 * <code>Throwable</code> not containing a message is represented in the
+	 * array by a null. This has the effect of cause the length of the returned
+	 * array to be equal to the result of the {@link #getThrowableCount()}
+	 * operation.
+	 *
+	 * @return the error messages
+	 * @since 2.0
+	 */
+	public String[] getMessages() {
+		Throwable[] throwables = this.getThrowables();
+		String[] msgs = new String[throwables.length];
+		for ( int i = 0; i < throwables.length; i++ ) {
+			msgs[i] = Nestable.class.isInstance( throwables[i] ) ?
+					( ( Nestable ) throwables[i] ).getMessage( 0 ) :
+					throwables[i].getMessage();
+		}
+		return msgs;
+	}
+
+	/**
+	 * Returns the <code>Throwable</code> in the chain of
+	 * <code>Throwable</code>s at the specified index, numbererd from 0.
+	 *
+	 * @param index the index, numbered from 0, of the <code>Throwable</code> in
+	 *              the chain of <code>Throwable</code>s
+	 * @return the <code>Throwable</code>
+	 * @throws IndexOutOfBoundsException if the <code>index</code> argument is
+	 *                                   negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 * @since 2.0
+	 */
+	public Throwable getThrowable(int index) {
+		if ( index == 0 ) {
+			return this.nestable;
+		}
+		Throwable[] throwables = this.getThrowables();
+		return throwables[index];
+	}
+
+	/**
+	 * Returns the number of <code>Throwable</code>s contained in the
+	 * <code>Nestable</code> contained by this delegate.
+	 *
+	 * @return the throwable count
+	 * @since 2.0
+	 */
+	public int getThrowableCount() {
+		return ExceptionUtils.getThrowableCount( this.nestable );
+	}
+
+	/**
+	 * Returns this delegate's <code>Nestable</code> and any nested
+	 * <code>Throwable</code>s in an array of <code>Throwable</code>s, one
+	 * element for each <code>Throwable</code>.
+	 *
+	 * @return the <code>Throwable</code>s
+	 * @since 2.0
+	 */
+	public Throwable[] getThrowables() {
+		return ExceptionUtils.getThrowables( this.nestable );
+	}
+
+	/**
+	 * Returns the index, numbered from 0, of the first <code>Throwable</code>
+	 * that matches the specified type in the chain of <code>Throwable</code>s
+	 * held in this delegate's <code>Nestable</code> with an index greater than
+	 * or equal to the specified index, or -1 if the type is not found.
+	 *
+	 * @param type      <code>Class</code> to be found
+	 * @param fromIndex the index, numbered from 0, of the starting position in
+	 *                  the chain to be searched
+	 * @return index of the first occurrence of the type in the chain, or -1 if
+	 *         the type is not found
+	 * @throws IndexOutOfBoundsException if the <code>fromIndex</code> argument
+	 *                                   is negative or not less than the count of <code>Throwable</code>s in the
+	 *                                   chain
+	 * @since 2.0
+	 */
+	public int indexOfThrowable(Class type, int fromIndex) {
+		if ( fromIndex < 0 ) {
+			throw new IndexOutOfBoundsException( "The start index was out of bounds: " + fromIndex );
+		}
+		Throwable[] throwables = ExceptionUtils.getThrowables( this.nestable );
+		if ( fromIndex >= throwables.length ) {
+			throw new IndexOutOfBoundsException( "The start index was out of bounds: "
+					+ fromIndex + " >= " + throwables.length );
+		}
+		for ( int i = fromIndex; i < throwables.length; i++ ) {
+			if ( throwables[i].getClass().equals( type ) ) {
+				return i;
+			}
+		}
+		return -1;
+	}
+
+	/**
+	 * Prints the stack trace of this exception the the standar error
+	 * stream.
+	 */
+	public void printStackTrace() {
+		printStackTrace( System.err );
+	}
+
+	/**
+	 * Prints the stack trace of this exception to the specified
+	 * stream.
+	 *
+	 * @param out <code>PrintStream</code> to use for output.
+	 * @see #printStackTrace(PrintWriter)
+	 */
+	public void printStackTrace(PrintStream out) {
+		synchronized ( out ) {
+			PrintWriter pw = new PrintWriter( out, false );
+			printStackTrace( pw );
+			// Flush the PrintWriter before it's GC'ed.
+			pw.flush();
+		}
+	}
+
+	/**
+	 * Prints the stack trace of this exception to the specified
+	 * writer. If the Throwable class has a <code>getCause</code>
+	 * method (i.e. running on jre1.4 or higher), this method just
+	 * uses Throwable's printStackTrace() method. Otherwise, generates
+	 * the stack-trace, by taking into account the 'topDown' and
+	 * 'trimStackFrames' parameters. The topDown and trimStackFrames
+	 * are set to 'true' by default (produces jre1.4-like stack trace).
+	 *
+	 * @param out <code>PrintWriter</code> to use for output.
+	 */
+	public void printStackTrace(PrintWriter out) {
+		Throwable throwable = this.nestable;
+		// if running on jre1.4 or higher, use default printStackTrace
+		if ( ExceptionUtils.isThrowableNested() ) {
+			if ( throwable instanceof Nestable ) {
+				( ( Nestable ) throwable ).printPartialStackTrace( out );
+			}
+			else {
+				throwable.printStackTrace( out );
+			}
+			return;
+		}
+
+		// generating the nested stack trace
+		List stacks = new ArrayList();
+		while ( throwable != null ) {
+			String[] st = getStackFrames( throwable );
+			stacks.add( st );
+			throwable = ExceptionUtils.getCause( throwable );
+		}
+
+		// If NOT topDown, reverse the stack
+		String separatorLine = "Caused by: ";
+		if ( !topDown ) {
+			separatorLine = "Rethrown as: ";
+			Collections.reverse( stacks );
+		}
+
+		// Remove the repeated lines in the stack
+		if ( trimStackFrames ) trimStackFrames( stacks );
+
+		synchronized ( out ) {
+			for ( Iterator iter = stacks.iterator(); iter.hasNext(); ) {
+				String[] st = ( String[] ) iter.next();
+				for ( int i = 0, len = st.length; i < len; i++ ) {
+					out.println( st[i] );
+				}
+				if ( iter.hasNext() ) out.print( separatorLine );
+			}
+		}
+	}
+
+	/**
+	 * Captures the stack trace associated with the specified
+	 * <code>Throwable</code> object, decomposing it into a list of
+	 * stack frames.
+	 *
+	 * @param t The <code>Throwable</code>.
+	 * @return An array of strings describing each stack frame.
+	 * @since 2.0
+	 */
+	protected String[] getStackFrames(Throwable t) {
+		StringWriter sw = new StringWriter();
+		PrintWriter pw = new PrintWriter( sw, true );
+
+		// Avoid infinite loop between decompose() and printStackTrace().
+		if ( t instanceof Nestable ) {
+			( ( Nestable ) t ).printPartialStackTrace( pw );
+		}
+		else {
+			t.printStackTrace( pw );
+		}
+		return ExceptionUtils.getStackFrames( sw.getBuffer().toString() );
+	}
+
+	/**
+	 * Trims the stack frames. The first set is left untouched. The rest
+	 * of the frames are truncated from the bottom by comparing with
+	 * one just on top.
+	 *
+	 * @param stacks The list containing String[] elements
+	 * @since 2.0
+	 */
+	protected void trimStackFrames(List stacks) {
+		for ( int size = stacks.size(), i = size - 1; i > 0; i-- ) {
+			String[] curr = ( String[] ) stacks.get( i );
+			String[] next = ( String[] ) stacks.get( i - 1 );
+
+			List currList = new ArrayList( Arrays.asList( curr ) );
+			List nextList = new ArrayList( Arrays.asList( next ) );
+			ExceptionUtils.removeCommonFrames( currList, nextList );
+
+			int trimmed = curr.length - currList.size();
+			if ( trimmed > 0 ) {
+				currList.add( "\t... " + trimmed + " more" );
+				stacks.set( i,
+						currList.toArray( new String[currList.size()] ) );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/NestableException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,254 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.exception;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * The base class of all exceptions which can contain other exceptions.
- * <p/>
- * It is intended to ease the debugging by carrying on the information
- * about the exception which was caught and provoked throwing the
- * current exception. Catching and rethrowing may occur multiple
- * times, and provided that all exceptions except the first one
- * are descendands of <code>NestedException</code>, when the
- * exception is finally printed out using any of the <code>
- * printStackTrace()</code> methods, the stacktrace will contain
- * the information about all exceptions thrown and caught on
- * the way.
- * <p> Running the following program
- * <p><blockquote><pre>
- *  1 import org.apache.commons.lang.exception.NestableException;
- *  2
- *  3 public class Test {
- *  4     public static void main( String[] args ) {
- *  5         try {
- *  6             a();
- *  7         } catch(Exception e) {
- *  8             e.printStackTrace();
- *  9         }
- * 10      }
- * 11
- * 12      public static void a() throws Exception {
- * 13          try {
- * 14              b();
- * 15          } catch(Exception e) {
- * 16              throw new NestableException("foo", e);
- * 17          }
- * 18      }
- * 19
- * 20      public static void b() throws Exception {
- * 21          try {
- * 22              c();
- * 23          } catch(Exception e) {
- * 24              throw new NestableException("bar", e);
- * 25          }
- * 26      }
- * 27
- * 28      public static void c() throws Exception {
- * 29          throw new Exception("baz");
- * 30      }
- * 31 }
- * </pre></blockquote>
- * <p>Yields the following stacktrace:
- * <p><blockquote><pre>
- * org.apache.commons.lang.exception.NestableException: foo
- *         at Test.a(Test.java:16)
- *         at Test.main(Test.java:6)
- * Caused by: org.apache.commons.lang.exception.NestableException: bar
- *         at Test.b(Test.java:24)
- *         at Test.a(Test.java:14)
- *         ... 1 more
- * Caused by: java.lang.Exception: baz
- *         at Test.c(Test.java:29)
- *         at Test.b(Test.java:22)
- *         ... 2 more
- * </pre></blockquote><br>
- *
- * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
- * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
- * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
- * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
- * @version $Id: NestableException.java 4782 2004-11-21 00:11:27Z pgmjsd $
- * @since 1.0
- */
-public class NestableException extends Exception implements Nestable {
-
-	/**
-	 * The helper instance which contains much of the code which we
-	 * delegate to.
-	 */
-	protected NestableDelegate delegate = new NestableDelegate( this );
-
-	/**
-	 * Holds the reference to the exception or error that caused
-	 * this exception to be thrown.
-	 */
-	private Throwable cause = null;
-
-	/**
-	 * Constructs a new <code>NestableException</code> without specified
-	 * detail message.
-	 */
-	public NestableException() {
-		super();
-	}
-
-	/**
-	 * Constructs a new <code>NestableException</code> with specified
-	 * detail message.
-	 *
-	 * @param msg The error message.
-	 */
-	public NestableException(String msg) {
-		super( msg );
-	}
-
-	/**
-	 * Constructs a new <code>NestableException</code> with specified
-	 * nested <code>Throwable</code>.
-	 *
-	 * @param cause the exception or error that caused this exception to be
-	 *              thrown
-	 */
-	public NestableException(Throwable cause) {
-		super();
-		this.cause = cause;
-	}
-
-	/**
-	 * Constructs a new <code>NestableException</code> with specified
-	 * detail message and nested <code>Throwable</code>.
-	 *
-	 * @param msg   the error message
-	 * @param cause the exception or error that caused this exception to be
-	 *              thrown
-	 */
-	public NestableException(String msg, Throwable cause) {
-		super( msg );
-		this.cause = cause;
-	}
-
-	public Throwable getCause() {
-		return cause;
-	}
-
-	/**
-	 * Returns the detail message string of this throwable. If it was
-	 * created with a null message, returns the following:
-	 * ( cause==null ? null : cause.toString() ).
-	 */
-	public String getMessage() {
-		if ( super.getMessage() != null ) {
-			return super.getMessage();
-		}
-		else if ( cause != null ) {
-			return cause.toString();
-		}
-		else {
-			return null;
-		}
-	}
-
-	public String getMessage(int index) {
-		if ( index == 0 ) {
-			return super.getMessage();
-		}
-		else {
-			return delegate.getMessage( index );
-		}
-	}
-
-	public String[] getMessages() {
-		return delegate.getMessages();
-	}
-
-	public Throwable getThrowable(int index) {
-		return delegate.getThrowable( index );
-	}
-
-	public int getThrowableCount() {
-		return delegate.getThrowableCount();
-	}
-
-	public Throwable[] getThrowables() {
-		return delegate.getThrowables();
-	}
-
-	public int indexOfThrowable(Class type) {
-		return delegate.indexOfThrowable( type, 0 );
-	}
-
-	public int indexOfThrowable(Class type, int fromIndex) {
-		return delegate.indexOfThrowable( type, fromIndex );
-	}
-
-	public void printStackTrace() {
-		delegate.printStackTrace();
-	}
-
-	public void printStackTrace(PrintStream out) {
-		delegate.printStackTrace( out );
-	}
-
-	public void printStackTrace(PrintWriter out) {
-		delegate.printStackTrace( out );
-	}
-
-	public final void printPartialStackTrace(PrintWriter out) {
-		super.printStackTrace( out );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/NestableException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,225 @@
+/*
+ * 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.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+
+/**
+ * The base class of all exceptions which can contain other exceptions.
+ * <p/>
+ * It is intended to ease the debugging by carrying on the information
+ * about the exception which was caught and provoked throwing the
+ * current exception. Catching and rethrowing may occur multiple
+ * times, and provided that all exceptions except the first one
+ * are descendands of <code>NestedException</code>, when the
+ * exception is finally printed out using any of the <code>
+ * printStackTrace()</code> methods, the stacktrace will contain
+ * the information about all exceptions thrown and caught on
+ * the way.
+ * <p> Running the following program
+ * <p><blockquote><pre>
+ *  1 import org.apache.commons.lang.exception.NestableException;
+ *  2
+ *  3 public class Test {
+ *  4     public static void main( String[] args ) {
+ *  5         try {
+ *  6             a();
+ *  7         } catch(Exception e) {
+ *  8             e.printStackTrace();
+ *  9         }
+ * 10      }
+ * 11
+ * 12      public static void a() throws Exception {
+ * 13          try {
+ * 14              b();
+ * 15          } catch(Exception e) {
+ * 16              throw new NestableException("foo", e);
+ * 17          }
+ * 18      }
+ * 19
+ * 20      public static void b() throws Exception {
+ * 21          try {
+ * 22              c();
+ * 23          } catch(Exception e) {
+ * 24              throw new NestableException("bar", e);
+ * 25          }
+ * 26      }
+ * 27
+ * 28      public static void c() throws Exception {
+ * 29          throw new Exception("baz");
+ * 30      }
+ * 31 }
+ * </pre></blockquote>
+ * <p>Yields the following stacktrace:
+ * <p><blockquote><pre>
+ * org.apache.commons.lang.exception.NestableException: foo
+ *         at Test.a(Test.java:16)
+ *         at Test.main(Test.java:6)
+ * Caused by: org.apache.commons.lang.exception.NestableException: bar
+ *         at Test.b(Test.java:24)
+ *         at Test.a(Test.java:14)
+ *         ... 1 more
+ * Caused by: java.lang.Exception: baz
+ *         at Test.c(Test.java:29)
+ *         at Test.b(Test.java:22)
+ *         ... 2 more
+ * </pre></blockquote><br>
+ *
+ * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
+ * @version $Id: NestableException.java 4782 2004-11-21 00:11:27Z pgmjsd $
+ * @since 1.0
+ */
+public class NestableException extends Exception implements Nestable {
+
+	/**
+	 * The helper instance which contains much of the code which we
+	 * delegate to.
+	 */
+	protected NestableDelegate delegate = new NestableDelegate( this );
+
+	/**
+	 * Holds the reference to the exception or error that caused
+	 * this exception to be thrown.
+	 */
+	private Throwable cause = null;
+
+	/**
+	 * Constructs a new <code>NestableException</code> without specified
+	 * detail message.
+	 */
+	public NestableException() {
+		super();
+	}
+
+	/**
+	 * Constructs a new <code>NestableException</code> with specified
+	 * detail message.
+	 *
+	 * @param msg The error message.
+	 */
+	public NestableException(String msg) {
+		super( msg );
+	}
+
+	/**
+	 * Constructs a new <code>NestableException</code> with specified
+	 * nested <code>Throwable</code>.
+	 *
+	 * @param cause the exception or error that caused this exception to be
+	 *              thrown
+	 */
+	public NestableException(Throwable cause) {
+		super();
+		this.cause = cause;
+	}
+
+	/**
+	 * Constructs a new <code>NestableException</code> with specified
+	 * detail message and nested <code>Throwable</code>.
+	 *
+	 * @param msg   the error message
+	 * @param cause the exception or error that caused this exception to be
+	 *              thrown
+	 */
+	public NestableException(String msg, Throwable cause) {
+		super( msg );
+		this.cause = cause;
+	}
+
+	public Throwable getCause() {
+		return cause;
+	}
+
+	/**
+	 * Returns the detail message string of this throwable. If it was
+	 * created with a null message, returns the following:
+	 * ( cause==null ? null : cause.toString() ).
+	 */
+	public String getMessage() {
+		if ( super.getMessage() != null ) {
+			return super.getMessage();
+		}
+		else if ( cause != null ) {
+			return cause.toString();
+		}
+		else {
+			return null;
+		}
+	}
+
+	public String getMessage(int index) {
+		if ( index == 0 ) {
+			return super.getMessage();
+		}
+		else {
+			return delegate.getMessage( index );
+		}
+	}
+
+	public String[] getMessages() {
+		return delegate.getMessages();
+	}
+
+	public Throwable getThrowable(int index) {
+		return delegate.getThrowable( index );
+	}
+
+	public int getThrowableCount() {
+		return delegate.getThrowableCount();
+	}
+
+	public Throwable[] getThrowables() {
+		return delegate.getThrowables();
+	}
+
+	public int indexOfThrowable(Class type) {
+		return delegate.indexOfThrowable( type, 0 );
+	}
+
+	public int indexOfThrowable(Class type, int fromIndex) {
+		return delegate.indexOfThrowable( type, fromIndex );
+	}
+
+	public void printStackTrace() {
+		delegate.printStackTrace();
+	}
+
+	public void printStackTrace(PrintStream out) {
+		delegate.printStackTrace( out );
+	}
+
+	public void printStackTrace(PrintWriter out) {
+		delegate.printStackTrace( out );
+	}
+
+	public final void printPartialStackTrace(PrintWriter out) {
+		super.printStackTrace( out );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,214 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.exception;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-
-import antlr.RecognitionException;
-
-/**
- * The base class of all runtime exceptions which can contain other
- * exceptions.
- *
- * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
- * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
- * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
- * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
- * @version $Id: NestableRuntimeException.java 8137 2005-09-09 15:21:10Z epbernard $
- * @see org.apache.commons.lang.exception.NestableException
- * @since 1.0
- */
-public class NestableRuntimeException extends RuntimeException implements Nestable {
-
-	/**
-	 * The helper instance which contains much of the code which we
-	 * delegate to.
-	 */
-	protected NestableDelegate delegate = new NestableDelegate( this );
-
-	/**
-	 * Holds the reference to the exception or error that caused
-	 * this exception to be thrown.
-	 */
-	private Throwable cause = null;
-
-	/**
-	 * Constructs a new <code>NestableRuntimeException</code> without specified
-	 * detail message.
-	 */
-	public NestableRuntimeException() {
-		super();
-	}
-
-	/**
-	 * Constructs a new <code>NestableRuntimeException</code> with specified
-	 * detail message.
-	 *
-	 * @param msg the error message
-	 */
-	public NestableRuntimeException(String msg) {
-		super( msg );
-	}
-
-	/**
-	 * Constructs a new <code>NestableRuntimeException</code> with specified
-	 * nested <code>Throwable</code>.
-	 *
-	 * @param cause the exception or error that caused this exception to be
-	 *              thrown
-	 */
-	public NestableRuntimeException(Throwable cause) {
-		super();
-		this.cause = cause;
-	}
-
-	/**
-	 * Constructs a new <code>NestableRuntimeException</code> with specified
-	 * detail message and nested <code>Throwable</code>.
-	 *
-	 * @param msg   the error message
-	 * @param cause the exception or error that caused this exception to be
-	 *              thrown
-	 */
-	public NestableRuntimeException(String msg, Throwable cause) {
-		super( msg );
-		this.cause = cause;
-	}
-
-	public Throwable getCause() {
-		return cause;
-	}
-
-	/**
-	 * Returns the detail message string of this throwable. If it was
-	 * created with a null message, returns the following:
-	 * ( cause==null ? null : cause.toString( ).
-	 */
-	public String getMessage() {
-		if ( super.getMessage() != null ) {
-			return super.getMessage();
-		}
-		else if ( cause != null ) {
-			return cause.toString();
-		}
-		else {
-			return null;
-		}
-	}
-
-	public String getMessage(int index) {
-		if ( index == 0 ) {
-			return super.getMessage();
-		}
-		else {
-			return delegate.getMessage( index );
-		}
-	}
-
-	public String[] getMessages() {
-		return delegate.getMessages();
-	}
-
-	public Throwable getThrowable(int index) {
-		return delegate.getThrowable( index );
-	}
-
-	public int getThrowableCount() {
-		return delegate.getThrowableCount();
-	}
-
-	public Throwable[] getThrowables() {
-		return delegate.getThrowables();
-	}
-
-	public int indexOfThrowable(Class type) {
-		return delegate.indexOfThrowable( type, 0 );
-	}
-
-	public int indexOfThrowable(Class type, int fromIndex) {
-		return delegate.indexOfThrowable( type, fromIndex );
-	}
-
-	public void printStackTrace() {
-		delegate.printStackTrace();
-	}
-
-	public void printStackTrace(PrintStream out) {
-		delegate.printStackTrace( out );
-	}
-
-	public void printStackTrace(PrintWriter out) {
-		delegate.printStackTrace( out );
-	}
-
-	public final void printPartialStackTrace(PrintWriter out) {
-		super.printStackTrace( out );
-	}
-
-
-
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		Throwable tempCause = cause;
-		//don't propagate RecognitionException, might be not serializable
-		if ( cause instanceof RecognitionException ) {
-			cause = null;
-		}
-		oos.defaultWriteObject();
-		cause = tempCause;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/NestableRuntimeException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,185 @@
+/*
+ * 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.exception;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+
+import antlr.RecognitionException;
+
+/**
+ * The base class of all runtime exceptions which can contain other
+ * exceptions.
+ *
+ * @author <a href="mailto:Rafal.Krzewski at e-point.pl">Rafal Krzewski</a>
+ * @author <a href="mailto:dlr at collab.net">Daniel Rall</a>
+ * @author <a href="mailto:knielsen at apache.org">Kasper Nielsen</a>
+ * @author <a href="mailto:steven at caswell.name">Steven Caswell</a>
+ * @version $Id: NestableRuntimeException.java 8137 2005-09-09 15:21:10Z epbernard $
+ * @see org.apache.commons.lang.exception.NestableException
+ * @since 1.0
+ */
+public class NestableRuntimeException extends RuntimeException implements Nestable {
+
+	/**
+	 * The helper instance which contains much of the code which we
+	 * delegate to.
+	 */
+	protected NestableDelegate delegate = new NestableDelegate( this );
+
+	/**
+	 * Holds the reference to the exception or error that caused
+	 * this exception to be thrown.
+	 */
+	private Throwable cause = null;
+
+	/**
+	 * Constructs a new <code>NestableRuntimeException</code> without specified
+	 * detail message.
+	 */
+	public NestableRuntimeException() {
+		super();
+	}
+
+	/**
+	 * Constructs a new <code>NestableRuntimeException</code> with specified
+	 * detail message.
+	 *
+	 * @param msg the error message
+	 */
+	public NestableRuntimeException(String msg) {
+		super( msg );
+	}
+
+	/**
+	 * Constructs a new <code>NestableRuntimeException</code> with specified
+	 * nested <code>Throwable</code>.
+	 *
+	 * @param cause the exception or error that caused this exception to be
+	 *              thrown
+	 */
+	public NestableRuntimeException(Throwable cause) {
+		super();
+		this.cause = cause;
+	}
+
+	/**
+	 * Constructs a new <code>NestableRuntimeException</code> with specified
+	 * detail message and nested <code>Throwable</code>.
+	 *
+	 * @param msg   the error message
+	 * @param cause the exception or error that caused this exception to be
+	 *              thrown
+	 */
+	public NestableRuntimeException(String msg, Throwable cause) {
+		super( msg );
+		this.cause = cause;
+	}
+
+	public Throwable getCause() {
+		return cause;
+	}
+
+	/**
+	 * Returns the detail message string of this throwable. If it was
+	 * created with a null message, returns the following:
+	 * ( cause==null ? null : cause.toString( ).
+	 */
+	public String getMessage() {
+		if ( super.getMessage() != null ) {
+			return super.getMessage();
+		}
+		else if ( cause != null ) {
+			return cause.toString();
+		}
+		else {
+			return null;
+		}
+	}
+
+	public String getMessage(int index) {
+		if ( index == 0 ) {
+			return super.getMessage();
+		}
+		else {
+			return delegate.getMessage( index );
+		}
+	}
+
+	public String[] getMessages() {
+		return delegate.getMessages();
+	}
+
+	public Throwable getThrowable(int index) {
+		return delegate.getThrowable( index );
+	}
+
+	public int getThrowableCount() {
+		return delegate.getThrowableCount();
+	}
+
+	public Throwable[] getThrowables() {
+		return delegate.getThrowables();
+	}
+
+	public int indexOfThrowable(Class type) {
+		return delegate.indexOfThrowable( type, 0 );
+	}
+
+	public int indexOfThrowable(Class type, int fromIndex) {
+		return delegate.indexOfThrowable( type, fromIndex );
+	}
+
+	public void printStackTrace() {
+		delegate.printStackTrace();
+	}
+
+	public void printStackTrace(PrintStream out) {
+		delegate.printStackTrace( out );
+	}
+
+	public void printStackTrace(PrintWriter out) {
+		delegate.printStackTrace( out );
+	}
+
+	public final void printPartialStackTrace(PrintWriter out) {
+		super.printStackTrace( out );
+	}
+
+
+
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		Throwable tempCause = cause;
+		//don't propagate RecognitionException, might be not serializable
+		if ( cause instanceof RecognitionException ) {
+			cause = null;
+		}
+		oos.defaultWriteObject();
+		cause = tempCause;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-// $Id: SQLExceptionConverter.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Defines a contract for implementations that know how to convert a SQLException
- * into Hibernate's JDBCException hierarchy.  Inspired by Spring's
- * SQLExceptionTranslator.
- * <p/>
- * Implementations <b>must</b> have a constructor which takes a
- * {@link ViolatedConstraintNameExtracter} parameter.
- * <p/>
- * Implementations may implement {@link Configurable} if they need to perform
- * configuration steps prior to first use.
- *
- * @author Steve Ebersole
- * @see SQLExceptionConverterFactory
- */
-public interface SQLExceptionConverter {
-	/**
-	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
-	 *
-	 * @param sqlException The SQLException to be converted.
-	 * @param message      An optional error message.
-	 * @return The resulting JDBCException.
-	 * @see ConstraintViolationException, JDBCConnectionException, SQLGrammarException, LockAcquisitionException
-	 */
-	public JDBCException convert(SQLException sqlException, String message, String sql);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Defines a contract for implementations that know how to convert a SQLException
+ * into Hibernate's JDBCException hierarchy.  Inspired by Spring's
+ * SQLExceptionTranslator.
+ * <p/>
+ * Implementations <b>must</b> have a constructor which takes a
+ * {@link ViolatedConstraintNameExtracter} parameter.
+ * <p/>
+ * Implementations may implement {@link Configurable} if they need to perform
+ * configuration steps prior to first use.
+ *
+ * @author Steve Ebersole
+ * @see SQLExceptionConverterFactory
+ */
+public interface SQLExceptionConverter {
+	/**
+	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
+	 *
+	 * @param sqlException The SQLException to be converted.
+	 * @param message      An optional error message.
+	 * @return The resulting JDBCException.
+	 * @see ConstraintViolationException, JDBCConnectionException, SQLGrammarException, LockAcquisitionException
+	 */
+	public JDBCException convert(SQLException sqlException, String message, String sql);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,114 +0,0 @@
-// $Id: SQLExceptionConverterFactory.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-import java.lang.reflect.Constructor;
-import java.sql.SQLException;
-import java.util.Properties;
-
-/**
- * A factory for building SQLExceptionConverter instances.
- *
- * @author Steve Ebersole
- */
-public class SQLExceptionConverterFactory {
-
-	private static final Logger log = LoggerFactory.getLogger( SQLExceptionConverterFactory.class );
-
-	private SQLExceptionConverterFactory() {
-		// Private constructor - stops checkstyle from complaining.
-	}
-
-	/**
-	 * Build a SQLExceptionConverter instance.
-	 * <p/>
-	 * First, looks for a {@link Environment.SQL_EXCEPTION_CONVERTER} property to see
-	 * if the configuration specified the class of a specific converter to use.  If this
-	 * property is set, attempt to construct an instance of that class.  If not set, or
-	 * if construction fails, the converter specific to the dialect will be used.
-	 *
-	 * @param dialect    The defined dialect.
-	 * @param properties The configuration properties.
-	 * @return An appropriate SQLExceptionConverter instance.
-	 * @throws HibernateException There was an error building the SQLExceptionConverter.
-	 */
-	public static SQLExceptionConverter buildSQLExceptionConverter(Dialect dialect, Properties properties) throws HibernateException {
-		SQLExceptionConverter converter = null;
-
-		String converterClassName = ( String ) properties.get( Environment.SQL_EXCEPTION_CONVERTER );
-		if ( StringHelper.isNotEmpty( converterClassName ) ) {
-			converter = constructConverter( converterClassName, dialect.getViolatedConstraintNameExtracter() );
-		}
-
-		if ( converter == null ) {
-			log.trace( "Using dialect defined converter" );
-			converter = dialect.buildSQLExceptionConverter();
-		}
-
-		if ( converter instanceof Configurable ) {
-			try {
-				( ( Configurable ) converter ).configure( properties );
-			}
-			catch ( HibernateException e ) {
-				log.warn( "Unable to configure SQLExceptionConverter", e );
-				throw e;
-			}
-		}
-
-		return converter;
-	}
-
-	/**
-	 * Builds a minimal converter.  The instance returned here just always converts to
-	 * {@link GenericJDBCException}.
-	 *
-	 * @return The minimal converter.
-	 */
-	public static SQLExceptionConverter buildMinimalSQLExceptionConverter() {
-		return new SQLExceptionConverter() {
-			public JDBCException convert(SQLException sqlException, String message, String sql) {
-				return new GenericJDBCException( message, sqlException, sql );
-			}
-		};
-	}
-
-	private static SQLExceptionConverter constructConverter(String converterClassName, ViolatedConstraintNameExtracter violatedConstraintNameExtracter) {
-		try {
-			log.trace( "Attempting to construct instance of specified SQLExceptionConverter [" + converterClassName + "]" );
-			Class converterClass = ReflectHelper.classForName( converterClassName );
-
-			// First, try to find a matching constructor accepting a ViolatedConstraintNameExtracter param...
-			Constructor[] ctors = converterClass.getDeclaredConstructors();
-			for ( int i = 0; i < ctors.length; i++ ) {
-				if ( ctors[i].getParameterTypes() != null && ctors[i].getParameterTypes().length == 1 ) {
-					if ( ViolatedConstraintNameExtracter.class.isAssignableFrom( ctors[i].getParameterTypes()[0] ) ) {
-						try {
-							return ( SQLExceptionConverter )
-									ctors[i].newInstance( new Object[]{violatedConstraintNameExtracter} );
-						}
-						catch ( Throwable t ) {
-							// eat it and try next
-						}
-					}
-				}
-			}
-
-			// Otherwise, try to use the no-arg constructor
-			return ( SQLExceptionConverter ) converterClass.newInstance();
-
-		}
-		catch ( Throwable t ) {
-			log.warn( "Unable to construct instance of specified SQLExceptionConverter", t );
-		}
-
-		return null;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLExceptionConverterFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,137 @@
+/*
+ * 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.exception;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+import java.lang.reflect.Constructor;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ * A factory for building SQLExceptionConverter instances.
+ *
+ * @author Steve Ebersole
+ */
+public class SQLExceptionConverterFactory {
+
+	private static final Logger log = LoggerFactory.getLogger( SQLExceptionConverterFactory.class );
+
+	private SQLExceptionConverterFactory() {
+		// Private constructor - stops checkstyle from complaining.
+	}
+
+	/**
+	 * Build a SQLExceptionConverter instance.
+	 * <p/>
+	 * First, looks for a {@link Environment#SQL_EXCEPTION_CONVERTER} property to see
+	 * if the configuration specified the class of a specific converter to use.  If this
+	 * property is set, attempt to construct an instance of that class.  If not set, or
+	 * if construction fails, the converter specific to the dialect will be used.
+	 *
+	 * @param dialect    The defined dialect.
+	 * @param properties The configuration properties.
+	 * @return An appropriate SQLExceptionConverter instance.
+	 * @throws HibernateException There was an error building the SQLExceptionConverter.
+	 */
+	public static SQLExceptionConverter buildSQLExceptionConverter(Dialect dialect, Properties properties) throws HibernateException {
+		SQLExceptionConverter converter = null;
+
+		String converterClassName = ( String ) properties.get( Environment.SQL_EXCEPTION_CONVERTER );
+		if ( StringHelper.isNotEmpty( converterClassName ) ) {
+			converter = constructConverter( converterClassName, dialect.getViolatedConstraintNameExtracter() );
+		}
+
+		if ( converter == null ) {
+			log.trace( "Using dialect defined converter" );
+			converter = dialect.buildSQLExceptionConverter();
+		}
+
+		if ( converter instanceof Configurable ) {
+			try {
+				( ( Configurable ) converter ).configure( properties );
+			}
+			catch ( HibernateException e ) {
+				log.warn( "Unable to configure SQLExceptionConverter", e );
+				throw e;
+			}
+		}
+
+		return converter;
+	}
+
+	/**
+	 * Builds a minimal converter.  The instance returned here just always converts to
+	 * {@link GenericJDBCException}.
+	 *
+	 * @return The minimal converter.
+	 */
+	public static SQLExceptionConverter buildMinimalSQLExceptionConverter() {
+		return new SQLExceptionConverter() {
+			public JDBCException convert(SQLException sqlException, String message, String sql) {
+				return new GenericJDBCException( message, sqlException, sql );
+			}
+		};
+	}
+
+	private static SQLExceptionConverter constructConverter(String converterClassName, ViolatedConstraintNameExtracter violatedConstraintNameExtracter) {
+		try {
+			log.trace( "Attempting to construct instance of specified SQLExceptionConverter [" + converterClassName + "]" );
+			Class converterClass = ReflectHelper.classForName( converterClassName );
+
+			// First, try to find a matching constructor accepting a ViolatedConstraintNameExtracter param...
+			Constructor[] ctors = converterClass.getDeclaredConstructors();
+			for ( int i = 0; i < ctors.length; i++ ) {
+				if ( ctors[i].getParameterTypes() != null && ctors[i].getParameterTypes().length == 1 ) {
+					if ( ViolatedConstraintNameExtracter.class.isAssignableFrom( ctors[i].getParameterTypes()[0] ) ) {
+						try {
+							return ( SQLExceptionConverter )
+									ctors[i].newInstance( new Object[]{violatedConstraintNameExtracter} );
+						}
+						catch ( Throwable t ) {
+							// eat it and try next
+						}
+					}
+				}
+			}
+
+			// Otherwise, try to use the no-arg constructor
+			return ( SQLExceptionConverter ) converterClass.newInstance();
+
+		}
+		catch ( Throwable t ) {
+			log.warn( "Unable to construct instance of specified SQLExceptionConverter", t );
+		}
+
+		return null;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/SQLGrammarException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-// $Id: SQLGrammarException.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-
-/**
- * Implementation of JDBCException indicating that the SQL sent to the database
- * server was invalid (syntax error, invalid object references, etc).
- *
- * @author Steve Ebersole
- */
-public class SQLGrammarException extends JDBCException {
-	/**
-	 * Constructor for JDBCException.
-	 *
-	 * @param root The underlying exception.
-	 */
-	public SQLGrammarException(String message, SQLException root) {
-		super( message, root );
-	}
-
-	/**
-	 * Constructor for JDBCException.
-	 *
-	 * @param message Optional message.
-	 * @param root    The underlying exception.
-	 */
-	public SQLGrammarException(String message, SQLException root, String sql) {
-		super( message, root, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/SQLGrammarException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLGrammarException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+
+/**
+ * Implementation of JDBCException indicating that the SQL sent to the database
+ * server was invalid (syntax error, invalid object references, etc).
+ *
+ * @author Steve Ebersole
+ */
+public class SQLGrammarException extends JDBCException {
+	/**
+	 * Constructor for JDBCException.
+	 *
+	 * @param root The underlying exception.
+	 */
+	public SQLGrammarException(String message, SQLException root) {
+		super( message, root );
+	}
+
+	/**
+	 * Constructor for JDBCException.
+	 *
+	 * @param message Optional message.
+	 * @param root    The underlying exception.
+	 */
+	public SQLGrammarException(String message, SQLException root, String sql) {
+		super( message, root, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,105 +0,0 @@
-// $Id: SQLStateConverter.java 9557 2006-03-06 15:16:27Z steve.ebersole at jboss.com $
-package org.hibernate.exception;
-
-import org.hibernate.JDBCException;
-
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * A SQLExceptionConverter implementation which performs converion based on
- * the underlying SQLState. Interpretation of a SQL error based on SQLState
- * is not nearly as accurate as using the ErrorCode (which is, however, vendor-
- * specific).  Use of a ErrorCode-based converter should be preferred approach
- * for converting/interpreting SQLExceptions.
- *
- * @author Steve Ebersole
- */
-public class SQLStateConverter implements SQLExceptionConverter {
-
-	private ViolatedConstraintNameExtracter extracter;
-
-	private static final Set SQL_GRAMMAR_CATEGORIES = new HashSet();
-	private static final Set DATA_CATEGORIES = new HashSet();
-	private static final Set INTEGRITY_VIOLATION_CATEGORIES = new HashSet();
-	private static final Set CONNECTION_CATEGORIES = new HashSet();
-
-	static {
-		SQL_GRAMMAR_CATEGORIES.add( "07" );
-		SQL_GRAMMAR_CATEGORIES.add( "37" );
-		SQL_GRAMMAR_CATEGORIES.add( "42" );
-		SQL_GRAMMAR_CATEGORIES.add( "65" );
-		SQL_GRAMMAR_CATEGORIES.add( "S0" );
-		SQL_GRAMMAR_CATEGORIES.add( "20" );
-		
-		DATA_CATEGORIES.add("22");
-		DATA_CATEGORIES.add("21");
-		DATA_CATEGORIES.add("02");
-
-		INTEGRITY_VIOLATION_CATEGORIES.add( "23" );
-		INTEGRITY_VIOLATION_CATEGORIES.add( "27" );
-		INTEGRITY_VIOLATION_CATEGORIES.add( "44" );
-
-		CONNECTION_CATEGORIES.add( "08" );
-	}
-
-	public SQLStateConverter(ViolatedConstraintNameExtracter extracter) {
-		this.extracter = extracter;
-	}
-
-	/**
-	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
-	 *
-	 * @param sqlException The SQLException to be converted.
-	 * @param message      An optional error message.
-	 * @param sql          Optionally, the sql being performed when the exception occurred.
-	 * @return The resulting JDBCException.
-	 */
-	public JDBCException convert(SQLException sqlException, String message, String sql) {
-		String sqlState = JDBCExceptionHelper.extractSqlState( sqlException );
-
-		if ( sqlState != null ) {
-			String sqlStateClassCode = JDBCExceptionHelper.determineSqlStateClassCode( sqlState );
-
-			if ( sqlStateClassCode != null ) {
-				if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) {
-					return new SQLGrammarException( message, sqlException, sql );
-				}
-				else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( sqlStateClassCode ) ) {
-					String constraintName = extracter.extractConstraintName( sqlException );
-					return new ConstraintViolationException( message, sqlException, sql, constraintName );
-				}
-				else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
-					return new JDBCConnectionException( message, sqlException, sql );
-				}
-				else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) {
-					return new DataException( message, sqlException, sql );
-				}
-			}
-
-			if ( "40001".equals( sqlState ) ) {
-				return new LockAcquisitionException( message, sqlException, sql );
-			}
-
-			if ( "61000".equals( sqlState ) ) {
-				// oracle sql-state code for deadlock
-				return new LockAcquisitionException( message, sqlException, sql );
-			}
-		}
-
-		return handledNonSpecificException( sqlException, message, sql );
-	}
-
-	/**
-	 * Handle an exception not converted to a specific type based on the SQLState.
-	 *
-	 * @param sqlException The exception to be handled.
-	 * @param message      An optional message
-	 * @param sql          Optionally, the sql being performed when the exception occurred.
-	 * @return The converted exception; should <b>never</b> be null.
-	 */
-	protected JDBCException handledNonSpecificException(SQLException sqlException, String message, String sql) {
-		return new GenericJDBCException( message, sqlException, sql );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/SQLStateConverter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/SQLStateConverter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+import org.hibernate.JDBCException;
+
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A SQLExceptionConverter implementation which performs converion based on
+ * the underlying SQLState. Interpretation of a SQL error based on SQLState
+ * is not nearly as accurate as using the ErrorCode (which is, however, vendor-
+ * specific).  Use of a ErrorCode-based converter should be preferred approach
+ * for converting/interpreting SQLExceptions.
+ *
+ * @author Steve Ebersole
+ */
+public class SQLStateConverter implements SQLExceptionConverter {
+
+	private ViolatedConstraintNameExtracter extracter;
+
+	private static final Set SQL_GRAMMAR_CATEGORIES = new HashSet();
+	private static final Set DATA_CATEGORIES = new HashSet();
+	private static final Set INTEGRITY_VIOLATION_CATEGORIES = new HashSet();
+	private static final Set CONNECTION_CATEGORIES = new HashSet();
+
+	static {
+		SQL_GRAMMAR_CATEGORIES.add( "07" );
+		SQL_GRAMMAR_CATEGORIES.add( "37" );
+		SQL_GRAMMAR_CATEGORIES.add( "42" );
+		SQL_GRAMMAR_CATEGORIES.add( "65" );
+		SQL_GRAMMAR_CATEGORIES.add( "S0" );
+		SQL_GRAMMAR_CATEGORIES.add( "20" );
+		
+		DATA_CATEGORIES.add("22");
+		DATA_CATEGORIES.add("21");
+		DATA_CATEGORIES.add("02");
+
+		INTEGRITY_VIOLATION_CATEGORIES.add( "23" );
+		INTEGRITY_VIOLATION_CATEGORIES.add( "27" );
+		INTEGRITY_VIOLATION_CATEGORIES.add( "44" );
+
+		CONNECTION_CATEGORIES.add( "08" );
+	}
+
+	public SQLStateConverter(ViolatedConstraintNameExtracter extracter) {
+		this.extracter = extracter;
+	}
+
+	/**
+	 * Convert the given SQLException into Hibernate's JDBCException hierarchy.
+	 *
+	 * @param sqlException The SQLException to be converted.
+	 * @param message      An optional error message.
+	 * @param sql          Optionally, the sql being performed when the exception occurred.
+	 * @return The resulting JDBCException.
+	 */
+	public JDBCException convert(SQLException sqlException, String message, String sql) {
+		String sqlState = JDBCExceptionHelper.extractSqlState( sqlException );
+
+		if ( sqlState != null ) {
+			String sqlStateClassCode = JDBCExceptionHelper.determineSqlStateClassCode( sqlState );
+
+			if ( sqlStateClassCode != null ) {
+				if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) {
+					return new SQLGrammarException( message, sqlException, sql );
+				}
+				else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( sqlStateClassCode ) ) {
+					String constraintName = extracter.extractConstraintName( sqlException );
+					return new ConstraintViolationException( message, sqlException, sql, constraintName );
+				}
+				else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) {
+					return new JDBCConnectionException( message, sqlException, sql );
+				}
+				else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) {
+					return new DataException( message, sqlException, sql );
+				}
+			}
+
+			if ( "40001".equals( sqlState ) ) {
+				return new LockAcquisitionException( message, sqlException, sql );
+			}
+
+			if ( "61000".equals( sqlState ) ) {
+				// oracle sql-state code for deadlock
+				return new LockAcquisitionException( message, sqlException, sql );
+			}
+		}
+
+		return handledNonSpecificException( sqlException, message, sql );
+	}
+
+	/**
+	 * Handle an exception not converted to a specific type based on the SQLState.
+	 *
+	 * @param sqlException The exception to be handled.
+	 * @param message      An optional message
+	 * @param sql          Optionally, the sql being performed when the exception occurred.
+	 * @return The converted exception; should <b>never</b> be null.
+	 */
+	protected JDBCException handledNonSpecificException(SQLException sqlException, String message, String sql) {
+		return new GenericJDBCException( message, sqlException, sql );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-// $Id: TemplatedViolatedConstraintNameExtracter.java 4782 2004-11-21 00:11:27Z pgmjsd $
-package org.hibernate.exception;
-
-
-
-/**
- * Knows how to extract a violated constraint name from an error message based on the
- * fact that the constraint name is templated within the message.
- *
- * @author Steve Ebersole
- */
-public abstract class TemplatedViolatedConstraintNameExtracter implements ViolatedConstraintNameExtracter {
-
-	/**
-	 * Extracts the constraint name based on a template (i.e., <i>templateStart</i><b>constraintName</b><i>templateEnd</i>).
-	 *
-	 * @param templateStart The pattern denoting the start of the constraint name within the message.
-	 * @param templateEnd   The pattern denoting the end of the constraint name within the message.
-	 * @param message       The templated error message containing the constraint name.
-	 * @return The found constraint name, or null.
-	 */
-	protected String extractUsingTemplate(String templateStart, String templateEnd, String message) {
-		int templateStartPosition = message.indexOf( templateStart );
-		if ( templateStartPosition < 0 ) {
-			return null;
-		}
-
-		int start = templateStartPosition + templateStart.length();
-		int end = message.indexOf( templateEnd, start );
-		if ( end < 0 ) {
-			end = message.length();
-		}
-
-		return message.substring( start, end );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/TemplatedViolatedConstraintNameExtracter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.exception;
+
+/**
+ * Knows how to extract a violated constraint name from an error message based on the
+ * fact that the constraint name is templated within the message.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class TemplatedViolatedConstraintNameExtracter implements ViolatedConstraintNameExtracter {
+
+	/**
+	 * Extracts the constraint name based on a template (i.e., <i>templateStart</i><b>constraintName</b><i>templateEnd</i>).
+	 *
+	 * @param templateStart The pattern denoting the start of the constraint name within the message.
+	 * @param templateEnd   The pattern denoting the end of the constraint name within the message.
+	 * @param message       The templated error message containing the constraint name.
+	 * @return The found constraint name, or null.
+	 */
+	protected String extractUsingTemplate(String templateStart, String templateEnd, String message) {
+		int templateStartPosition = message.indexOf( templateStart );
+		if ( templateStartPosition < 0 ) {
+			return null;
+		}
+
+		int start = templateStartPosition + templateStart.length();
+		int end = message.indexOf( templateEnd, start );
+		if ( end < 0 ) {
+			end = message.length();
+		}
+
+		return message.substring( start, end );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-// $Id: ViolatedConstraintNameExtracter.java 4746 2004-11-11 20:57:28Z steveebersole $
-package org.hibernate.exception;
-
-import java.sql.SQLException;
-
-/**
- * Defines a contract for implementations that can extract the name of a violated
- * constraint from a SQLException that is the result of that constraint violation.
- *
- * @author Steve Ebersole
- */
-public interface ViolatedConstraintNameExtracter {
-	/**
-	 * Extract the name of the violated constraint from the given SQLException.
-	 *
-	 * @param sqle The exception that was the result of the constraint violation.
-	 * @return The extracted constraint name.
-	 */
-	public String extractConstraintName(SQLException sqle);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/ViolatedConstraintNameExtracter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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.exception;
+
+import java.sql.SQLException;
+
+/**
+ * Defines a contract for implementations that can extract the name of a violated
+ * constraint from a SQLException that is the result of that constraint violation.
+ *
+ * @author Steve Ebersole
+ */
+public interface ViolatedConstraintNameExtracter {
+	/**
+	 * Extract the name of the violated constraint from the given SQLException.
+	 *
+	 * @param sqle The exception that was the result of the constraint violation.
+	 * @return The extracted constraint name.
+	 */
+	public String extractConstraintName(SQLException sqle);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/exception/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package is a fork of Apache commons-lang nestable exceptions.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/exception/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/exception/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package is a fork of Apache commons-lang nestable exceptions.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/CollectionProperties.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-// $Id: CollectionProperties.java 5699 2005-02-13 11:50:11Z oneovthafew $
-package org.hibernate.hql;
-
-import org.hibernate.persister.collection.CollectionPropertyNames;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Provides a map of collection function names to the corresponding property names.
- *
- * @author josh Aug 16, 2004 7:51:45 PM
- */
-public final class CollectionProperties {
-	public static final Map HQL_COLLECTION_PROPERTIES;
-
-	private static final String COLLECTION_INDEX_LOWER = CollectionPropertyNames.COLLECTION_INDEX.toLowerCase();
-
-	static {
-		HQL_COLLECTION_PROPERTIES = new HashMap();
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_ELEMENTS.toLowerCase(), CollectionPropertyNames.COLLECTION_ELEMENTS );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_INDICES.toLowerCase(), CollectionPropertyNames.COLLECTION_INDICES );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_SIZE.toLowerCase(), CollectionPropertyNames.COLLECTION_SIZE );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MAX_INDEX.toLowerCase(), CollectionPropertyNames.COLLECTION_MAX_INDEX );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MIN_INDEX.toLowerCase(), CollectionPropertyNames.COLLECTION_MIN_INDEX );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MAX_ELEMENT.toLowerCase(), CollectionPropertyNames.COLLECTION_MAX_ELEMENT );
-		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MIN_ELEMENT.toLowerCase(), CollectionPropertyNames.COLLECTION_MIN_ELEMENT );
-		HQL_COLLECTION_PROPERTIES.put( COLLECTION_INDEX_LOWER, CollectionPropertyNames.COLLECTION_INDEX );
-	}
-
-	private CollectionProperties() {
-	}
-
-	public static boolean isCollectionProperty(String name) {
-		String key = name.toLowerCase();
-		// CollectionPropertyMapping processes everything except 'index'.
-		if ( COLLECTION_INDEX_LOWER.equals( key ) ) {
-			return false;
-		}
-		else {
-			return HQL_COLLECTION_PROPERTIES.containsKey( key );
-		}
-	}
-
-	public static String getNormalizedPropertyName(String name) {
-		return ( String ) HQL_COLLECTION_PROPERTIES.get( name );
-	}
-
-	public static boolean isAnyCollectionProperty(String name) {
-		String key = name.toLowerCase();
-		return HQL_COLLECTION_PROPERTIES.containsKey( key );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/CollectionProperties.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionProperties.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import org.hibernate.persister.collection.CollectionPropertyNames;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Provides a map of collection function names to the corresponding property names.
+ *
+ * @author josh
+ */
+public final class CollectionProperties {
+	public static final Map HQL_COLLECTION_PROPERTIES;
+
+	private static final String COLLECTION_INDEX_LOWER = CollectionPropertyNames.COLLECTION_INDEX.toLowerCase();
+
+	static {
+		HQL_COLLECTION_PROPERTIES = new HashMap();
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_ELEMENTS.toLowerCase(), CollectionPropertyNames.COLLECTION_ELEMENTS );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_INDICES.toLowerCase(), CollectionPropertyNames.COLLECTION_INDICES );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_SIZE.toLowerCase(), CollectionPropertyNames.COLLECTION_SIZE );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MAX_INDEX.toLowerCase(), CollectionPropertyNames.COLLECTION_MAX_INDEX );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MIN_INDEX.toLowerCase(), CollectionPropertyNames.COLLECTION_MIN_INDEX );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MAX_ELEMENT.toLowerCase(), CollectionPropertyNames.COLLECTION_MAX_ELEMENT );
+		HQL_COLLECTION_PROPERTIES.put( CollectionPropertyNames.COLLECTION_MIN_ELEMENT.toLowerCase(), CollectionPropertyNames.COLLECTION_MIN_ELEMENT );
+		HQL_COLLECTION_PROPERTIES.put( COLLECTION_INDEX_LOWER, CollectionPropertyNames.COLLECTION_INDEX );
+	}
+
+	private CollectionProperties() {
+	}
+
+	public static boolean isCollectionProperty(String name) {
+		String key = name.toLowerCase();
+		// CollectionPropertyMapping processes everything except 'index'.
+		if ( COLLECTION_INDEX_LOWER.equals( key ) ) {
+			return false;
+		}
+		else {
+			return HQL_COLLECTION_PROPERTIES.containsKey( key );
+		}
+	}
+
+	public static String getNormalizedPropertyName(String name) {
+		return ( String ) HQL_COLLECTION_PROPERTIES.get( name );
+	}
+
+	public static boolean isAnyCollectionProperty(String name) {
+		String key = name.toLowerCase();
+		return HQL_COLLECTION_PROPERTIES.containsKey( key );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-// $Id: CollectionSubqueryFactory.java 9046 2006-01-13 03:10:57Z steveebersole $
-package org.hibernate.hql;
-
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.util.StringHelper;
-
-import java.util.Map;
-
-/**
- * Provides the SQL for collection subqueries.
- * <br>
- * Moved here from PathExpressionParser to make it re-useable.
- * 
- * @author josh
- */
-public final class CollectionSubqueryFactory {
-
-	//TODO: refactor to .sql package
-
-	private CollectionSubqueryFactory() {
-	}
-
-	public static String createCollectionSubquery(
-			JoinSequence joinSequence,
-	        Map enabledFilters,
-	        String[] columns) {
-		try {
-			JoinFragment join = joinSequence.toJoinFragment( enabledFilters, true );
-			return new StringBuffer( "select " )
-					.append( StringHelper.join( ", ", columns ) )
-					.append( " from " )
-					.append( join.toFromFragmentString().substring( 2 ) )// remove initial ", "
-					.append( " where " )
-					.append( join.toWhereFragmentString().substring( 5 ) )// remove initial " and "
-					.toString();
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/CollectionSubqueryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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;
+
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
+
+import java.util.Map;
+
+/**
+ * Provides the SQL for collection subqueries.
+ * <br>
+ * Moved here from PathExpressionParser to make it re-useable.
+ * 
+ * @author josh
+ */
+public final class CollectionSubqueryFactory {
+
+	//TODO: refactor to .sql package
+
+	private CollectionSubqueryFactory() {
+	}
+
+	public static String createCollectionSubquery(
+			JoinSequence joinSequence,
+	        Map enabledFilters,
+	        String[] columns) {
+		try {
+			JoinFragment join = joinSequence.toJoinFragment( enabledFilters, true );
+			return new StringBuffer( "select " )
+					.append( StringHelper.join( ", ", columns ) )
+					.append( " from " )
+					.append( join.toFromFragmentString().substring( 2 ) )// remove initial ", "
+					.append( " where " )
+					.append( join.toWhereFragmentString().substring( 5 ) )// remove initial " and "
+					.toString();
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/FilterTranslator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-// $Id: FilterTranslator.java 4899 2004-12-06 14:17:24Z pgmjsd $
-package org.hibernate.hql;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-
-import java.util.Map;
-
-
-/**
- * Specialized interface for filters.
- *
- * @author josh Mar 14, 2004 11:33:35 AM
- */
-public interface FilterTranslator extends QueryTranslator {
-	/**
-	 * Compile a filter. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 *
-	 * @param collectionRole the role name of the collection used as the basis for the filter.
-	 * @param replacements   Defined query substitutions.
-	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
-	 * @throws QueryException   There was a problem parsing the query string.
-	 * @throws MappingException There was a problem querying defined mappings.
-	 */
-	void compile(String collectionRole, Map replacements, boolean shallow)
-			throws QueryException, MappingException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/FilterTranslator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/FilterTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+
+import java.util.Map;
+
+
+/**
+ * Specialized interface for filters.
+ *
+ * @author josh
+ */
+public interface FilterTranslator extends QueryTranslator {
+	/**
+	 * Compile a filter. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 *
+	 * @param collectionRole the role name of the collection used as the basis for the filter.
+	 * @param replacements   Defined query substitutions.
+	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
+	 * @throws QueryException   There was a problem parsing the query string.
+	 * @throws MappingException There was a problem querying defined mappings.
+	 */
+	void compile(String collectionRole, Map replacements, boolean shallow)
+			throws QueryException, MappingException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/HolderInstantiator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-//$Id: HolderInstantiator.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.hql;
-
-import java.lang.reflect.Constructor;
-
-import org.hibernate.transform.AliasToBeanConstructorResultTransformer;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.transform.Transformers;
-
-/**
- * @author Gavin King
- */
-public final class HolderInstantiator {
-		
-	public static final HolderInstantiator NOOP_INSTANTIATOR = new HolderInstantiator(null,null);
-	
-	private final ResultTransformer transformer;
-	private final String[] queryReturnAliases;
-	
-	public static HolderInstantiator getHolderInstantiator(ResultTransformer selectNewTransformer, ResultTransformer customTransformer, String[] queryReturnAliases) {
-		if(selectNewTransformer!=null) {
-			return new HolderInstantiator(selectNewTransformer, queryReturnAliases);
-		} else {
-			return new HolderInstantiator(customTransformer, queryReturnAliases);
-		}
-	}
-	
-	public static ResultTransformer createSelectNewTransformer(Constructor constructor, boolean returnMaps, boolean returnLists) {
-		if ( constructor != null ) {
-			return new AliasToBeanConstructorResultTransformer(constructor);
-		}
-		else if ( returnMaps ) {
-			return Transformers.ALIAS_TO_ENTITY_MAP;			
-		}
-		else if ( returnLists ) {
-			return Transformers.TO_LIST;
-		}		
-		else {
-			return null;
-		}
-	}
-	
-	static public HolderInstantiator createClassicHolderInstantiator(Constructor constructor, 
-			ResultTransformer transformer) {
-		if ( constructor != null ) {
-			return new HolderInstantiator(new AliasToBeanConstructorResultTransformer(constructor), null);
-		}
-		else {
-			return new HolderInstantiator(transformer, null);
-		}
-	}
-	
-	public HolderInstantiator( 
-			ResultTransformer transformer,
-			String[] queryReturnAliases
-	) {
-		this.transformer = transformer;		
-		this.queryReturnAliases = queryReturnAliases;
-	}
-	
-	public boolean isRequired() {
-		return transformer!=null;
-	}
-	
-	public Object instantiate(Object[] row) {
-		if(transformer==null) {
-			return row;
-		} else {
-			return transformer.transformTuple(row, queryReturnAliases);
-		}
-	}	
-	
-	public String[] getQueryReturnAliases() {
-		return queryReturnAliases;
-	}
-
-	public ResultTransformer getResultTransformer() {
-		return transformer;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/HolderInstantiator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/HolderInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql;
+
+import java.lang.reflect.Constructor;
+
+import org.hibernate.transform.AliasToBeanConstructorResultTransformer;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.transform.Transformers;
+
+/**
+ * @author Gavin King
+ */
+public final class HolderInstantiator {
+		
+	public static final HolderInstantiator NOOP_INSTANTIATOR = new HolderInstantiator(null,null);
+	
+	private final ResultTransformer transformer;
+	private final String[] queryReturnAliases;
+	
+	public static HolderInstantiator getHolderInstantiator(ResultTransformer selectNewTransformer, ResultTransformer customTransformer, String[] queryReturnAliases) {
+		if(selectNewTransformer!=null) {
+			return new HolderInstantiator(selectNewTransformer, queryReturnAliases);
+		} else {
+			return new HolderInstantiator(customTransformer, queryReturnAliases);
+		}
+	}
+	
+	public static ResultTransformer createSelectNewTransformer(Constructor constructor, boolean returnMaps, boolean returnLists) {
+		if ( constructor != null ) {
+			return new AliasToBeanConstructorResultTransformer(constructor);
+		}
+		else if ( returnMaps ) {
+			return Transformers.ALIAS_TO_ENTITY_MAP;			
+		}
+		else if ( returnLists ) {
+			return Transformers.TO_LIST;
+		}		
+		else {
+			return null;
+		}
+	}
+	
+	static public HolderInstantiator createClassicHolderInstantiator(Constructor constructor, 
+			ResultTransformer transformer) {
+		if ( constructor != null ) {
+			return new HolderInstantiator(new AliasToBeanConstructorResultTransformer(constructor), null);
+		}
+		else {
+			return new HolderInstantiator(transformer, null);
+		}
+	}
+	
+	public HolderInstantiator( 
+			ResultTransformer transformer,
+			String[] queryReturnAliases
+	) {
+		this.transformer = transformer;		
+		this.queryReturnAliases = queryReturnAliases;
+	}
+	
+	public boolean isRequired() {
+		return transformer!=null;
+	}
+	
+	public Object instantiate(Object[] row) {
+		if(transformer==null) {
+			return row;
+		} else {
+			return transformer.transformTuple(row, queryReturnAliases);
+		}
+	}	
+	
+	public String[] getQueryReturnAliases() {
+		return queryReturnAliases;
+	}
+
+	public ResultTransformer getResultTransformer() {
+		return transformer;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/NameGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-// $Id: NameGenerator.java 4899 2004-12-06 14:17:24Z pgmjsd $
-package org.hibernate.hql;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Provides utility methods for generating HQL / SQL names.   Shared by both the 'classic' and 'new' query translators.
- *
- * @author josh Mar 18, 2004 7:17:25 AM
- */
-public final class NameGenerator {
-	/**
-	 * Private empty constructor (checkstyle says utility classes should not have default constructors).
-	 */
-	private NameGenerator() {
-	}
-
-	public static String[][] generateColumnNames(Type[] types, SessionFactoryImplementor f) throws MappingException {
-		String[][] columnNames = new String[types.length][];
-		for ( int i = 0; i < types.length; i++ ) {
-			int span = types[i].getColumnSpan( f );
-			columnNames[i] = new String[span];
-			for ( int j = 0; j < span; j++ ) {
-				columnNames[i][j] = NameGenerator.scalarName( i, j );
-			}
-		}
-		return columnNames;
-	}
-
-	public static String scalarName(int x, int y) {
-		return new StringBuffer()
-				.append( "col_" )
-				.append( x )
-				.append( '_' )
-				.append( y )
-				.append( '_' )
-				.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/NameGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/NameGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Provides utility methods for generating HQL / SQL names.   Shared by both the 'classic' and 'new' query translators.
+ *
+ * @author josh
+ */
+public final class NameGenerator {
+	/**
+	 * Private empty constructor (checkstyle says utility classes should not have default constructors).
+	 */
+	private NameGenerator() {
+	}
+
+	public static String[][] generateColumnNames(Type[] types, SessionFactoryImplementor f) throws MappingException {
+		String[][] columnNames = new String[types.length][];
+		for ( int i = 0; i < types.length; i++ ) {
+			int span = types[i].getColumnSpan( f );
+			columnNames[i] = new String[span];
+			for ( int j = 0; j < span; j++ ) {
+				columnNames[i][j] = NameGenerator.scalarName( i, j );
+			}
+		}
+		return columnNames;
+	}
+
+	public static String scalarName(int x, int y) {
+		return new StringBuffer()
+				.append( "col_" )
+				.append( x )
+				.append( '_' )
+				.append( y )
+				.append( '_' )
+				.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ParameterTranslations.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-package org.hibernate.hql;
-
-import org.hibernate.type.Type;
-import java.util.Set;
-
-/**
- * Defines available information about the parameters encountered during
- * query translation.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public interface ParameterTranslations {
-
-	public boolean supportsOrdinalParameterMetadata();
-
-	public int getOrdinalParameterCount();
-
-	public int getOrdinalParameterSqlLocation(int ordinalPosition);
-
-	public Type getOrdinalParameterExpectedType(int ordinalPosition);
-
-	public Set getNamedParameterNames();
-
-	public int[] getNamedParameterSqlLocations(String name);
-
-	public Type getNamedParameterExpectedType(String name);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ParameterTranslations.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ParameterTranslations.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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;
+
+import org.hibernate.type.Type;
+import java.util.Set;
+
+/**
+ * Defines available information about the parameters encountered during
+ * query translation.
+ *
+ * @author Steve Ebersole
+ */
+public interface ParameterTranslations {
+
+	public boolean supportsOrdinalParameterMetadata();
+
+	public int getOrdinalParameterCount();
+
+	public int getOrdinalParameterSqlLocation(int ordinalPosition);
+
+	public Type getOrdinalParameterExpectedType(int ordinalPosition);
+
+	public Set getNamedParameterNames();
+
+	public int[] getNamedParameterSqlLocations(String name);
+
+	public Type getNamedParameterExpectedType(String name);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: $
-package org.hibernate.hql;
-
-import org.hibernate.QueryException;
-
-/**
- * Expecting to execute an illegal operation regarding the query type
- *
- * @author Emmanuel Bernard
- */
-public class QueryExecutionRequestException extends QueryException {
-
-	public QueryExecutionRequestException(String message, String queryString) {
-		super( message, queryString );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryExecutionRequestException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql;
+
+import org.hibernate.QueryException;
+
+/**
+ * Expecting to execute an illegal operation regarding the query type
+ *
+ * @author Emmanuel Bernard
+ */
+public class QueryExecutionRequestException extends QueryException {
+
+	public QueryExecutionRequestException(String message, String queryString) {
+		super( message, queryString );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/QuerySplitter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,134 +0,0 @@
-//$Id: QuerySplitter.java 7646 2005-07-25 07:37:13Z oneovthafew $
-package org.hibernate.hql;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.classic.ParserHelper;
-import org.hibernate.util.StringHelper;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Provides query splitting methods, which were originally in QueryTranslator.
- * <br>
- * TODO: This will need to be refactored at some point.
- *
- * @author josh Mar 14, 2004 10:50:23 AM
- */
-public final class QuerySplitter {
-
-	private static final Logger log = LoggerFactory.getLogger( QuerySplitter.class );
-
-	private static final Set BEFORE_CLASS_TOKENS = new HashSet();
-	private static final Set NOT_AFTER_CLASS_TOKENS = new HashSet();
-
-	static {
-		BEFORE_CLASS_TOKENS.add( "from" );
-		BEFORE_CLASS_TOKENS.add( "delete" );
-		BEFORE_CLASS_TOKENS.add( "update" );
-		//beforeClassTokens.add("new"); DEFINITELY DON'T HAVE THIS!!
-		BEFORE_CLASS_TOKENS.add( "," );
-		NOT_AFTER_CLASS_TOKENS.add( "in" );
-		//notAfterClassTokens.add(",");
-		NOT_AFTER_CLASS_TOKENS.add( "from" );
-		NOT_AFTER_CLASS_TOKENS.add( ")" );
-	}
-
-	/**
-	 * Private empty constructor.
-	 * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
-	 */
-	private QuerySplitter() {
-	}
-
-	/**
-	 * Handle Hibernate "implicit" polymorphism, by translating the query string into
-	 * several "concrete" queries against mapped classes.
-	 */
-	public static String[] concreteQueries(String query, SessionFactoryImplementor factory) throws MappingException {
-
-		//scan the query string for class names appearing in the from clause and replace
-		//with all persistent implementors of the class/interface, returning multiple
-		//query strings (make sure we don't pick up a class in the select clause!)
-
-		//TODO: this is one of the ugliest and most fragile pieces of code in Hibernate....
-
-		String[] tokens = StringHelper.split( StringHelper.WHITESPACE + "(),", query, true );
-		if ( tokens.length == 0 ) return new String[]{query}; // just especially for the trivial collection filter
-		ArrayList placeholders = new ArrayList();
-		ArrayList replacements = new ArrayList();
-		StringBuffer templateQuery = new StringBuffer( 40 );
-		int count = 0;
-		String last = null;
-		int nextIndex = 0;
-		String next = null;
-		boolean isSelectClause = false;
-
-		templateQuery.append( tokens[0] );
-		if ( "select".equals( tokens[0].toLowerCase() ) ) isSelectClause = true;
-        
-		for ( int i = 1; i < tokens.length; i++ ) {
-
-			//update last non-whitespace token, if necessary
-			if ( !ParserHelper.isWhitespace( tokens[i - 1] ) ) last = tokens[i - 1].toLowerCase();
-
-			// select-range is terminated by declaration of "from"
-			if ( "from".equals( tokens[i].toLowerCase() ) ) isSelectClause = false;
-
-			String token = tokens[i];
-			if ( !ParserHelper.isWhitespace( token ) || last == null ) {
-
-				//scan for next non-whitespace token
-				if ( nextIndex <= i ) {
-					for ( nextIndex = i + 1; nextIndex < tokens.length; nextIndex++ ) {
-						next = tokens[nextIndex].toLowerCase();
-						if ( !ParserHelper.isWhitespace( next ) ) break;
-					}
-				}
-
-				boolean process = !isSelectClause && 
-						isJavaIdentifier( token ) && 
-						isPossiblyClassName( last, next );
-						
-				if (process) {
-					String importedClassName = getImportedClass( token, factory );
-					if ( importedClassName != null ) {
-						String[] implementors = factory.getImplementors( importedClassName );
-						String placeholder = "$clazz" + count++ + "$";
-						if ( implementors != null ) {
-							placeholders.add( placeholder );
-							replacements.add( implementors );
-						}
-						token = placeholder; // Note this!!
-					}
-				}
-
-			}
-
-			templateQuery.append( token );
-
-		}
-		String[] results = StringHelper.multiply( templateQuery.toString(), placeholders.iterator(), replacements.iterator() );
-		if ( results.length == 0 ) log.warn( "no persistent classes found for query class: " + query );
-		return results;
-	}
-
-	private static boolean isPossiblyClassName(String last, String next) {
-		return "class".equals( last ) || ( 
-				BEFORE_CLASS_TOKENS.contains( last ) && 
-				!NOT_AFTER_CLASS_TOKENS.contains( next ) 
-			);
-	}
-
-	private static boolean isJavaIdentifier(String token) {
-		return Character.isJavaIdentifierStart( token.charAt( 0 ) );
-	}
-
-	public static String getImportedClass(String name, SessionFactoryImplementor factory) {
-		return factory.getImportedClassName( name );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/QuerySplitter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QuerySplitter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,157 @@
+/*
+ * 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;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.classic.ParserHelper;
+import org.hibernate.util.StringHelper;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Provides query splitting methods, which were originally in QueryTranslator.
+ * <br>
+ * TODO: This will need to be refactored at some point.
+ *
+ * @author josh
+ */
+public final class QuerySplitter {
+
+	private static final Logger log = LoggerFactory.getLogger( QuerySplitter.class );
+
+	private static final Set BEFORE_CLASS_TOKENS = new HashSet();
+	private static final Set NOT_AFTER_CLASS_TOKENS = new HashSet();
+
+	static {
+		BEFORE_CLASS_TOKENS.add( "from" );
+		BEFORE_CLASS_TOKENS.add( "delete" );
+		BEFORE_CLASS_TOKENS.add( "update" );
+		//beforeClassTokens.add("new"); DEFINITELY DON'T HAVE THIS!!
+		BEFORE_CLASS_TOKENS.add( "," );
+		NOT_AFTER_CLASS_TOKENS.add( "in" );
+		//notAfterClassTokens.add(",");
+		NOT_AFTER_CLASS_TOKENS.add( "from" );
+		NOT_AFTER_CLASS_TOKENS.add( ")" );
+	}
+
+	/**
+	 * Private empty constructor.
+	 * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
+	 */
+	private QuerySplitter() {
+	}
+
+	/**
+	 * Handle Hibernate "implicit" polymorphism, by translating the query string into
+	 * several "concrete" queries against mapped classes.
+	 */
+	public static String[] concreteQueries(String query, SessionFactoryImplementor factory) throws MappingException {
+
+		//scan the query string for class names appearing in the from clause and replace
+		//with all persistent implementors of the class/interface, returning multiple
+		//query strings (make sure we don't pick up a class in the select clause!)
+
+		//TODO: this is one of the ugliest and most fragile pieces of code in Hibernate....
+
+		String[] tokens = StringHelper.split( StringHelper.WHITESPACE + "(),", query, true );
+		if ( tokens.length == 0 ) return new String[]{query}; // just especially for the trivial collection filter
+		ArrayList placeholders = new ArrayList();
+		ArrayList replacements = new ArrayList();
+		StringBuffer templateQuery = new StringBuffer( 40 );
+		int count = 0;
+		String last = null;
+		int nextIndex = 0;
+		String next = null;
+		boolean isSelectClause = false;
+
+		templateQuery.append( tokens[0] );
+		if ( "select".equals( tokens[0].toLowerCase() ) ) isSelectClause = true;
+        
+		for ( int i = 1; i < tokens.length; i++ ) {
+
+			//update last non-whitespace token, if necessary
+			if ( !ParserHelper.isWhitespace( tokens[i - 1] ) ) last = tokens[i - 1].toLowerCase();
+
+			// select-range is terminated by declaration of "from"
+			if ( "from".equals( tokens[i].toLowerCase() ) ) isSelectClause = false;
+
+			String token = tokens[i];
+			if ( !ParserHelper.isWhitespace( token ) || last == null ) {
+
+				//scan for next non-whitespace token
+				if ( nextIndex <= i ) {
+					for ( nextIndex = i + 1; nextIndex < tokens.length; nextIndex++ ) {
+						next = tokens[nextIndex].toLowerCase();
+						if ( !ParserHelper.isWhitespace( next ) ) break;
+					}
+				}
+
+				boolean process = !isSelectClause && 
+						isJavaIdentifier( token ) && 
+						isPossiblyClassName( last, next );
+						
+				if (process) {
+					String importedClassName = getImportedClass( token, factory );
+					if ( importedClassName != null ) {
+						String[] implementors = factory.getImplementors( importedClassName );
+						String placeholder = "$clazz" + count++ + "$";
+						if ( implementors != null ) {
+							placeholders.add( placeholder );
+							replacements.add( implementors );
+						}
+						token = placeholder; // Note this!!
+					}
+				}
+
+			}
+
+			templateQuery.append( token );
+
+		}
+		String[] results = StringHelper.multiply( templateQuery.toString(), placeholders.iterator(), replacements.iterator() );
+		if ( results.length == 0 ) log.warn( "no persistent classes found for query class: " + query );
+		return results;
+	}
+
+	private static boolean isPossiblyClassName(String last, String next) {
+		return "class".equals( last ) || ( 
+				BEFORE_CLASS_TOKENS.contains( last ) && 
+				!NOT_AFTER_CLASS_TOKENS.contains( next ) 
+			);
+	}
+
+	private static boolean isJavaIdentifier(String token) {
+		return Character.isJavaIdentifierStart( token.charAt( 0 ) );
+	}
+
+	public static String getImportedClass(String name, SessionFactoryImplementor factory) {
+		return factory.getImportedClassName( name );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/QueryTranslator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,167 +0,0 @@
-//$Id: QueryTranslator.java 9162 2006-01-27 23:40:32Z steveebersole $
-package org.hibernate.hql;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.type.Type;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Defines the constract of an HQL->SQL translator.
- *
- * @author josh
- */
-public interface QueryTranslator {
-
-	// Error message constants.
-	public static final String ERROR_CANNOT_FETCH_WITH_ITERATE = "fetch may not be used with scroll() or iterate()";
-	public static final String ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR = "Named parameter does not appear in Query: ";
-    public static final String ERROR_CANNOT_DETERMINE_TYPE = "Could not determine type of: ";
-	public static final String ERROR_CANNOT_FORMAT_LITERAL =  "Could not format constant value to SQL literal: ";
-
-	/**
-	 * Compile a "normal" query. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 *
-	 * @param replacements Defined query substitutions.
-	 * @param shallow      Does this represent a shallow (scalar or entity-id) select?
-	 * @throws QueryException   There was a problem parsing the query string.
-	 * @throws MappingException There was a problem querying defined mappings.
-	 */
-	void compile(Map replacements, boolean shallow) throws QueryException, MappingException;
-
-	/**
-	 * Perform a list operation given the underlying query definition.
-	 *
-	 * @param session         The session owning this query.
-	 * @param queryParameters The query bind parameters.
-	 * @return The query list results.
-	 * @throws HibernateException
-	 */
-	List list(SessionImplementor session, QueryParameters queryParameters)
-			throws HibernateException;
-
-	/**
-	 * Perform an iterate operation given the underlying query defintion.
-	 *
-	 * @param queryParameters The query bind parameters.
-	 * @param session         The session owning this query.
-	 * @return An iterator over the query results.
-	 * @throws HibernateException
-	 */
-	Iterator iterate(QueryParameters queryParameters, EventSource session)
-			throws HibernateException;
-
-	/**
-	 * Perform a scroll operation given the underlying query defintion.
-	 *
-	 * @param queryParameters The query bind parameters.
-	 * @param session         The session owning this query.
-	 * @return The ScrollableResults wrapper around the query results.
-	 * @throws HibernateException
-	 */
-	ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session)
-			throws HibernateException;
-
-	/**
-	 * Perform a bulk update/delete operation given the underlying query defintion.
-	 *
-	 * @param queryParameters The query bind parameters.
-	 * @param session         The session owning this query.
-	 * @return The number of entities updated or deleted.
-	 * @throws HibernateException
-	 */
-	int executeUpdate(QueryParameters queryParameters, SessionImplementor session)
-			throws HibernateException;
-
-	/**
-	 * Returns the set of query spaces (table names) that the query referrs to.
-	 *
-	 * @return A set of query spaces (table names).
-	 */
-	Set getQuerySpaces();
-
-	/**
-	 * Retrieve the query identifier for this translator.  The query identifier is
-	 * used in stats collection.
-	 *
-	 * @return the identifier
-	 */
-	String getQueryIdentifier();
-
-	/**
-	 * Returns the SQL string generated by the translator.
-	 *
-	 * @return the SQL string generated by the translator.
-	 */
-	String getSQLString();
-
-	List collectSqlStrings();
-
-	/**
-	 * Returns the HQL string processed by the translator.
-	 *
-	 * @return the HQL string processed by the translator.
-	 */
-	String getQueryString();
-
-	/**
-	 * Returns the filters enabled for this query translator.
-	 *
-	 * @return Filters enabled for this query execution.
-	 */
-	Map getEnabledFilters();
-
-	/**
-	 * Returns an array of Types represented in the query result.
-	 *
-	 * @return Query return types.
-	 */
-	Type[] getReturnTypes();
-	
-	/**
-	 * Returns an array of HQL aliases
-	 */
-	String[] getReturnAliases();
-
-	/**
-	 * Returns the column names in the generated SQL.
-	 *
-	 * @return the column names in the generated SQL.
-	 */
-	String[][] getColumnNames();
-
-	/**
-	 * Return information about any parameters encountered during
-	 * translation.
-	 *
-	 * @return The parameter information.
-	 */
-	ParameterTranslations getParameterTranslations();
-
-	/**
-	 * Validate the scrollability of the translated query.
-	 *
-	 * @throws HibernateException
-	 */
-	void validateScrollability() throws HibernateException;
-
-	/**
-	 * Does the translated query contain collection fetches?
-	 *
-	 * @return tru if the query does contain collection fetched;
-	 * false otherwise.
-	 */
-	boolean containsCollectionFetches();
-
-	boolean isManipulationStatement();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/QueryTranslator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,190 @@
+/*
+ * 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;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.type.Type;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Defines the constract of an HQL->SQL translator.
+ *
+ * @author josh
+ */
+public interface QueryTranslator {
+
+	// Error message constants.
+	public static final String ERROR_CANNOT_FETCH_WITH_ITERATE = "fetch may not be used with scroll() or iterate()";
+	public static final String ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR = "Named parameter does not appear in Query: ";
+    public static final String ERROR_CANNOT_DETERMINE_TYPE = "Could not determine type of: ";
+	public static final String ERROR_CANNOT_FORMAT_LITERAL =  "Could not format constant value to SQL literal: ";
+
+	/**
+	 * Compile a "normal" query. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 *
+	 * @param replacements Defined query substitutions.
+	 * @param shallow      Does this represent a shallow (scalar or entity-id) select?
+	 * @throws QueryException   There was a problem parsing the query string.
+	 * @throws MappingException There was a problem querying defined mappings.
+	 */
+	void compile(Map replacements, boolean shallow) throws QueryException, MappingException;
+
+	/**
+	 * Perform a list operation given the underlying query definition.
+	 *
+	 * @param session         The session owning this query.
+	 * @param queryParameters The query bind parameters.
+	 * @return The query list results.
+	 * @throws HibernateException
+	 */
+	List list(SessionImplementor session, QueryParameters queryParameters)
+			throws HibernateException;
+
+	/**
+	 * Perform an iterate operation given the underlying query defintion.
+	 *
+	 * @param queryParameters The query bind parameters.
+	 * @param session         The session owning this query.
+	 * @return An iterator over the query results.
+	 * @throws HibernateException
+	 */
+	Iterator iterate(QueryParameters queryParameters, EventSource session)
+			throws HibernateException;
+
+	/**
+	 * Perform a scroll operation given the underlying query defintion.
+	 *
+	 * @param queryParameters The query bind parameters.
+	 * @param session         The session owning this query.
+	 * @return The ScrollableResults wrapper around the query results.
+	 * @throws HibernateException
+	 */
+	ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session)
+			throws HibernateException;
+
+	/**
+	 * Perform a bulk update/delete operation given the underlying query defintion.
+	 *
+	 * @param queryParameters The query bind parameters.
+	 * @param session         The session owning this query.
+	 * @return The number of entities updated or deleted.
+	 * @throws HibernateException
+	 */
+	int executeUpdate(QueryParameters queryParameters, SessionImplementor session)
+			throws HibernateException;
+
+	/**
+	 * Returns the set of query spaces (table names) that the query referrs to.
+	 *
+	 * @return A set of query spaces (table names).
+	 */
+	Set getQuerySpaces();
+
+	/**
+	 * Retrieve the query identifier for this translator.  The query identifier is
+	 * used in stats collection.
+	 *
+	 * @return the identifier
+	 */
+	String getQueryIdentifier();
+
+	/**
+	 * Returns the SQL string generated by the translator.
+	 *
+	 * @return the SQL string generated by the translator.
+	 */
+	String getSQLString();
+
+	List collectSqlStrings();
+
+	/**
+	 * Returns the HQL string processed by the translator.
+	 *
+	 * @return the HQL string processed by the translator.
+	 */
+	String getQueryString();
+
+	/**
+	 * Returns the filters enabled for this query translator.
+	 *
+	 * @return Filters enabled for this query execution.
+	 */
+	Map getEnabledFilters();
+
+	/**
+	 * Returns an array of Types represented in the query result.
+	 *
+	 * @return Query return types.
+	 */
+	Type[] getReturnTypes();
+	
+	/**
+	 * Returns an array of HQL aliases
+	 */
+	String[] getReturnAliases();
+
+	/**
+	 * Returns the column names in the generated SQL.
+	 *
+	 * @return the column names in the generated SQL.
+	 */
+	String[][] getColumnNames();
+
+	/**
+	 * Return information about any parameters encountered during
+	 * translation.
+	 *
+	 * @return The parameter information.
+	 */
+	ParameterTranslations getParameterTranslations();
+
+	/**
+	 * Validate the scrollability of the translated query.
+	 *
+	 * @throws HibernateException
+	 */
+	void validateScrollability() throws HibernateException;
+
+	/**
+	 * Does the translated query contain collection fetches?
+	 *
+	 * @return tru if the query does contain collection fetched;
+	 * false otherwise.
+	 */
+	boolean containsCollectionFetches();
+
+	boolean isManipulationStatement();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: QueryTranslatorFactory.java 9162 2006-01-27 23:40:32Z steveebersole $
-package org.hibernate.hql;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-import java.util.Map;
-
-/**
- * Facade for generation of {@link QueryTranslator} and {@link FilterTranslator} instances.
- *
- * @author Gavin King
- */
-public interface QueryTranslatorFactory {
-	/**
-	 * Construct a {@link QueryTranslator} instance capable of translating
-	 * an HQL query string.
-	 *
-	 * @param queryIdentifier The query-identifier (used in
-	 * {@link org.hibernate.stat.QueryStatistics} collection). This is
-	 * typically the same as the queryString parameter except for the case of
-	 * split polymorphic queries which result in multiple physical sql
-	 * queries.
-	 * @param queryString The query string to be translated
-	 * @param filters Currently enabled filters
-	 * @param factory The session factory.
-	 * @return an appropriate translator.
-	 */
-	public QueryTranslator createQueryTranslator(String queryIdentifier, String queryString, Map filters, SessionFactoryImplementor factory);
-
-	/**
-	 * Construct a {@link FilterTranslator} instance capable of translating
-	 * an HQL filter string.
-	 *
-	 * @see #createQueryTranslator
-	 */
-	public FilterTranslator createFilterTranslator(String queryIdentifier, String queryString, Map filters, SessionFactoryImplementor factory);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/QueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+import java.util.Map;
+
+/**
+ * Facade for generation of {@link QueryTranslator} and {@link FilterTranslator} instances.
+ *
+ * @author Gavin King
+ */
+public interface QueryTranslatorFactory {
+	/**
+	 * Construct a {@link QueryTranslator} instance capable of translating
+	 * an HQL query string.
+	 *
+	 * @param queryIdentifier The query-identifier (used in
+	 * {@link org.hibernate.stat.QueryStatistics} collection). This is
+	 * typically the same as the queryString parameter except for the case of
+	 * split polymorphic queries which result in multiple physical sql
+	 * queries.
+	 * @param queryString The query string to be translated
+	 * @param filters Currently enabled filters
+	 * @param factory The session factory.
+	 * @return an appropriate translator.
+	 */
+	public QueryTranslator createQueryTranslator(String queryIdentifier, String queryString, Map filters, SessionFactoryImplementor factory);
+
+	/**
+	 * Construct a {@link FilterTranslator} instance capable of translating
+	 * an HQL filter string.
+	 *
+	 * @see #createQueryTranslator
+	 */
+	public FilterTranslator createFilterTranslator(String queryIdentifier, String queryString, Map filters, SessionFactoryImplementor factory);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/antlr/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>A special package for ANTLR-generated parser classes.</p>
-<p><i>NOTE: The classes in this package are generated from the ANTLR grammar files,
-do not register them into version control.</i></p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/antlr/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/antlr/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>A special package for ANTLR-generated parser classes.</p>
+<p><i>NOTE: The classes in this package are generated from the ANTLR grammar files,
+do not register them into version control.</i></p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: ASTQueryTranslatorFactory.java 9162 2006-01-27 23:40:32Z steveebersole $
-package org.hibernate.hql.ast;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.FilterTranslator;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.QueryTranslatorFactory;
-
-import java.util.Map;
-
-/**
- * Generates translators which uses the Antlr-based parser to perform
- * the translation.
- *
- * @author Gavin King
- */
-public class ASTQueryTranslatorFactory implements QueryTranslatorFactory {
-
-	private static final Logger log = LoggerFactory.getLogger( ASTQueryTranslatorFactory.class );
-
-	public ASTQueryTranslatorFactory() {
-		log.info( "Using ASTQueryTranslatorFactory" );
-	}
-
-	/**
-	 * @see QueryTranslatorFactory#createQueryTranslator
-	 */
-	public QueryTranslator createQueryTranslator(
-			String queryIdentifier,
-	        String queryString,
-	        Map filters,
-	        SessionFactoryImplementor factory) {
-		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
-	}
-
-	/**
-	 * @see QueryTranslatorFactory#createFilterTranslator
-	 */
-	public FilterTranslator createFilterTranslator(
-			String queryIdentifier,
-	        String queryString,
-	        Map filters,
-	        SessionFactoryImplementor factory) {
-		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ASTQueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.FilterTranslator;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.QueryTranslatorFactory;
+
+import java.util.Map;
+
+/**
+ * Generates translators which uses the Antlr-based parser to perform
+ * the translation.
+ *
+ * @author Gavin King
+ */
+public class ASTQueryTranslatorFactory implements QueryTranslatorFactory {
+
+	private static final Logger log = LoggerFactory.getLogger( ASTQueryTranslatorFactory.class );
+
+	public ASTQueryTranslatorFactory() {
+		log.info( "Using ASTQueryTranslatorFactory" );
+	}
+
+	/**
+	 * @see QueryTranslatorFactory#createQueryTranslator
+	 */
+	public QueryTranslator createQueryTranslator(
+			String queryIdentifier,
+	        String queryString,
+	        Map filters,
+	        SessionFactoryImplementor factory) {
+		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
+	}
+
+	/**
+	 * @see QueryTranslatorFactory#createFilterTranslator
+	 */
+	public FilterTranslator createFilterTranslator(
+			String queryIdentifier,
+	        String queryString,
+	        Map filters,
+	        SessionFactoryImplementor factory) {
+		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,77 +0,0 @@
-// $Id: DetailedSemanticException.java 5690 2005-02-12 20:27:50Z pgmjsd $
-package org.hibernate.hql.ast;
-
-import antlr.SemanticException;
-
-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.).
- */
-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 );
-		cause = e;
-	}
-
-	/**
-	 * Converts everything to a string.
-	 *
-	 * @return a string.
-	 */
-	public String toString() {
-		if ( cause == null || ( !showCauseMessage ) ) {
-			return super.toString();
-		}
-		else {
-			return super.toString() + "\n[cause=" + cause.toString() + "]";
-		}
-	}
-
-	/**
-	 * Prints a stack trace.
-	 */
-	public void printStackTrace() {
-		super.printStackTrace();
-		if ( cause != null ) {
-			cause.printStackTrace();
-		}
-	}
-
-	/**
-	 * Prints a stack trace to the specified print stream.
-	 *
-	 * @param s the print stream.
-	 */
-	public void printStackTrace(PrintStream s) {
-		super.printStackTrace( s );
-		if ( cause != null ) {
-			s.println( "Cause:" );
-			cause.printStackTrace( s );
-		}
-	}
-
-	/**
-	 * Prints this throwable and its backtrace to the specified print writer.
-	 *
-	 * @param w the print writer.s
-	 */
-	public void printStackTrace(PrintWriter w) {
-		super.printStackTrace( w );
-		if ( cause != null ) {
-			w.println( "Cause:" );
-			cause.printStackTrace( w );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/DetailedSemanticException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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;
+
+import antlr.SemanticException;
+
+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.).
+ */
+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 );
+		cause = e;
+	}
+
+	/**
+	 * Converts everything to a string.
+	 *
+	 * @return a string.
+	 */
+	public String toString() {
+		if ( cause == null || ( !showCauseMessage ) ) {
+			return super.toString();
+		}
+		else {
+			return super.toString() + "\n[cause=" + cause.toString() + "]";
+		}
+	}
+
+	/**
+	 * Prints a stack trace.
+	 */
+	public void printStackTrace() {
+		super.printStackTrace();
+		if ( cause != null ) {
+			cause.printStackTrace();
+		}
+	}
+
+	/**
+	 * Prints a stack trace to the specified print stream.
+	 *
+	 * @param s the print stream.
+	 */
+	public void printStackTrace(PrintStream s) {
+		super.printStackTrace( s );
+		if ( cause != null ) {
+			s.println( "Cause:" );
+			cause.printStackTrace( s );
+		}
+	}
+
+	/**
+	 * Prints this throwable and its backtrace to the specified print writer.
+	 *
+	 * @param w the print writer.s
+	 */
+	public void printStackTrace(PrintWriter w) {
+		super.printStackTrace( w );
+		if ( cause != null ) {
+			w.println( "Cause:" );
+			cause.printStackTrace( w );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-// $Id: ErrorCounter.java 9242 2006-02-09 12:37:36Z steveebersole $
-package org.hibernate.hql.ast;
-
-import antlr.RecognitionException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.QueryException;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * An error handler that counts parsing errors and warnings.
- */
-public class ErrorCounter implements ParseErrorHandler {
-	private Logger log = LoggerFactory.getLogger( ErrorCounter.class );
-	private Logger hqlLog = LoggerFactory.getLogger( "org.hibernate.hql.PARSER" );
-
-	private List errorList = new ArrayList();
-	private List warningList = new ArrayList();
-	private List recognitionExceptions = new ArrayList();
-
-	public void reportError(RecognitionException e) {
-		reportError( e.toString() );
-		recognitionExceptions.add( e );
-		if ( log.isDebugEnabled() ) {
-			log.debug( e.toString(), e );
-		}
-	}
-
-	public void reportError(String message) {
-		hqlLog.error( message );
-		errorList.add( message );
-	}
-
-	public int getErrorCount() {
-		return errorList.size();
-	}
-
-	public void reportWarning(String message) {
-		hqlLog.debug( message );
-		warningList.add( message );
-	}
-
-	private String getErrorString() {
-		StringBuffer buf = new StringBuffer();
-		for ( Iterator iterator = errorList.iterator(); iterator.hasNext(); ) {
-			buf.append( ( String ) iterator.next() );
-			if ( iterator.hasNext() ) buf.append( "\n" );
-
-		}
-		return buf.toString();
-	}
-
-	public void throwQueryException() throws QueryException {
-		if ( getErrorCount() > 0 ) {
-			if ( recognitionExceptions.size() > 0 ) {
-				throw QuerySyntaxException.convert( ( RecognitionException ) recognitionExceptions.get( 0 ) );
-			}
-			else {
-				throw new QueryException( getErrorString() );
-			}
-		}
-		else {
-			// all clear
-			if ( log.isDebugEnabled() ) {
-				log.debug( "throwQueryException() : no errors" );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorCounter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+/*
+ * 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;
+
+import antlr.RecognitionException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.QueryException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An error handler that counts parsing errors and warnings.
+ */
+public class ErrorCounter implements ParseErrorHandler {
+	private Logger log = LoggerFactory.getLogger( ErrorCounter.class );
+	private Logger hqlLog = LoggerFactory.getLogger( "org.hibernate.hql.PARSER" );
+
+	private List errorList = new ArrayList();
+	private List warningList = new ArrayList();
+	private List recognitionExceptions = new ArrayList();
+
+	public void reportError(RecognitionException e) {
+		reportError( e.toString() );
+		recognitionExceptions.add( e );
+		if ( log.isDebugEnabled() ) {
+			log.debug( e.toString(), e );
+		}
+	}
+
+	public void reportError(String message) {
+		hqlLog.error( message );
+		errorList.add( message );
+	}
+
+	public int getErrorCount() {
+		return errorList.size();
+	}
+
+	public void reportWarning(String message) {
+		hqlLog.debug( message );
+		warningList.add( message );
+	}
+
+	private String getErrorString() {
+		StringBuffer buf = new StringBuffer();
+		for ( Iterator iterator = errorList.iterator(); iterator.hasNext(); ) {
+			buf.append( ( String ) iterator.next() );
+			if ( iterator.hasNext() ) buf.append( "\n" );
+
+		}
+		return buf.toString();
+	}
+
+	public void throwQueryException() throws QueryException {
+		if ( getErrorCount() > 0 ) {
+			if ( recognitionExceptions.size() > 0 ) {
+				throw QuerySyntaxException.convert( ( RecognitionException ) recognitionExceptions.get( 0 ) );
+			}
+			else {
+				throw new QueryException( getErrorString() );
+			}
+		}
+		else {
+			// all clear
+			if ( log.isDebugEnabled() ) {
+				log.debug( "throwQueryException() : no errors" );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-// $Id: ErrorReporter.java 3974 2004-06-29 02:40:43Z pgmjsd $
-package org.hibernate.hql.ast;
-
-import antlr.RecognitionException;
-
-/**
- * Implementations will report or handle errors invoked by an ANTLR base parser.
- *
- * @author josh Jun 27, 2004 9:49:55 PM
- */
-public interface ErrorReporter {
-	void reportError(RecognitionException e);
-
-	void reportError(String s);
-
-	void reportWarning(String s);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ErrorReporter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+import antlr.RecognitionException;
+
+/**
+ * Implementations will report or handle errors invoked by an ANTLR base parser.
+ *
+ * @author josh
+ */
+public interface ErrorReporter {
+	void reportError(RecognitionException e);
+
+	void reportError(String s);
+
+	void reportWarning(String s);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-package org.hibernate.hql.ast;
-
-import antlr.ASTFactory;
-import org.hibernate.hql.ast.tree.Node;
-
-/**
- * User: Joshua Davis<br>
- * Date: Sep 23, 2005<br>
- * Time: 12:30:01 PM<br>
- */
-public class HqlASTFactory extends ASTFactory {
-
-	/**
-	 * Returns the class for a given token type (a.k.a. AST node type).
-	 *
-	 * @param tokenType The token type.
-	 * @return Class - The AST node class to instantiate.
-	 */
-	public Class getASTNodeType(int tokenType) {
-		return Node.class;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlASTFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast;
+
+import antlr.ASTFactory;
+import org.hibernate.hql.ast.tree.Node;
+
+/**
+ * User: Joshua Davis<br>
+ * Date: Sep 23, 2005<br>
+ * Time: 12:30:01 PM<br>
+ */
+public class HqlASTFactory extends ASTFactory {
+
+	/**
+	 * Returns the class for a given token type (a.k.a. AST node type).
+	 *
+	 * @param tokenType The token type.
+	 * @return Class - The AST node class to instantiate.
+	 */
+	public Class getASTNodeType(int tokenType) {
+		return Node.class;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-// $Id: HqlLexer.java 7511 2005-07-16 17:28:40Z epbernard $
-package org.hibernate.hql.ast;
-
-import java.io.InputStream;
-import java.io.Reader;
-
-import antlr.Token;
-import org.hibernate.QueryException;
-import org.hibernate.hql.antlr.HqlBaseLexer;
-
-/**
- * Custom lexer for the HQL grammar.  Extends the base lexer generated by ANTLR
- * in order to keep the grammar source file clean.
- */
-class HqlLexer extends HqlBaseLexer {
-	/**
-	 * A logger for this class. *
-	 */
-	private boolean possibleID = false;
-
-	public HqlLexer(InputStream in) {
-		super( in );
-	}
-
-    public HqlLexer(Reader in) {
-        super(in);
-    }
-
-	public void setTokenObjectClass(String cl) {
-		// Ignore the token class name parameter, and use a specific token class.
-		super.setTokenObjectClass( HqlToken.class.getName() );
-	}
-
-	protected void setPossibleID(boolean possibleID) {
-		this.possibleID = possibleID;
-	}
-
-	protected Token makeToken(int i) {
-		HqlToken token = ( HqlToken ) super.makeToken( i );
-		token.setPossibleID( possibleID );
-		possibleID = false;
-		return token;
-	}
-
-	public int testLiteralsTable(int i) {
-		int ttype = super.testLiteralsTable( i );
-		return ttype;
-	}
-
-	public void panic() {
-		//overriden to avoid System.exit
-		panic("CharScanner: panic");
-	}
-
-	public void panic(String s) {
-		//overriden to avoid System.exit
-		throw new QueryException(s);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlLexer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast;
+
+import java.io.InputStream;
+import java.io.Reader;
+
+import antlr.Token;
+import org.hibernate.QueryException;
+import org.hibernate.hql.antlr.HqlBaseLexer;
+
+/**
+ * Custom lexer for the HQL grammar.  Extends the base lexer generated by ANTLR
+ * in order to keep the grammar source file clean.
+ */
+class HqlLexer extends HqlBaseLexer {
+	/**
+	 * A logger for this class. *
+	 */
+	private boolean possibleID = false;
+
+	public HqlLexer(InputStream in) {
+		super( in );
+	}
+
+    public HqlLexer(Reader in) {
+        super(in);
+    }
+
+	public void setTokenObjectClass(String cl) {
+		// Ignore the token class name parameter, and use a specific token class.
+		super.setTokenObjectClass( HqlToken.class.getName() );
+	}
+
+	protected void setPossibleID(boolean possibleID) {
+		this.possibleID = possibleID;
+	}
+
+	protected Token makeToken(int i) {
+		HqlToken token = ( HqlToken ) super.makeToken( i );
+		token.setPossibleID( possibleID );
+		possibleID = false;
+		return token;
+	}
+
+	public int testLiteralsTable(int i) {
+		int ttype = super.testLiteralsTable( i );
+		return ttype;
+	}
+
+	public void panic() {
+		//overriden to avoid System.exit
+		panic("CharScanner: panic");
+	}
+
+	public void panic(String s) {
+		//overriden to avoid System.exit
+		throw new QueryException(s);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,338 +0,0 @@
-// $Id: HqlParser.java 8475 2005-10-27 11:43:19Z oneovthafew $
-package org.hibernate.hql.ast;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.io.StringReader;
-
-import antlr.ASTPair;
-import antlr.MismatchedTokenException;
-import antlr.RecognitionException;
-import antlr.Token;
-import antlr.TokenStream;
-import antlr.TokenStreamException;
-import antlr.collections.AST;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.hql.antlr.HqlBaseParser;
-import org.hibernate.hql.antlr.HqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.QueryException;
-
-/**
- * Implements the semantic action methods defined in the HQL base parser to keep the grammar
- * source file a little cleaner.  Extends the parser class generated by ANTLR.
- *
- * @author Joshua Davis (pgmjsd at sourceforge.net)
- */
-public final class HqlParser extends HqlBaseParser {
-	/**
-	 * A logger for this class.
-	 */
-	private static final Logger log = LoggerFactory.getLogger( HqlParser.class );
-
-	private ParseErrorHandler parseErrorHandler;
-	private ASTPrinter printer = getASTPrinter();
-
-	private static ASTPrinter getASTPrinter() {
-		return new ASTPrinter( org.hibernate.hql.antlr.HqlTokenTypes.class );
-	}
-
-	public static HqlParser getInstance(String hql) {
-        // [jsd] The fix for HHH-558...
-        HqlLexer lexer = new HqlLexer( new StringReader( hql ) );
-		return new HqlParser( lexer );
-	}
-
-	private HqlParser(TokenStream lexer) {
-		super( lexer );
-		initialize();
-	}
-
-	public void reportError(RecognitionException e) {
-		parseErrorHandler.reportError( e ); // Use the delegate.
-	}
-
-	public void reportError(String s) {
-		parseErrorHandler.reportError( s ); // Use the delegate.
-	}
-
-	public void reportWarning(String s) {
-		parseErrorHandler.reportWarning( s );
-	}
-
-	public ParseErrorHandler getParseErrorHandler() {
-		return parseErrorHandler;
-	}
-
-	/**
-	 * 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 HqlToken ) {
-			HqlToken hqlToken = ( HqlToken ) token;
-			// ... and the token could be an identifer and the error is
-			// a mismatched token error ...
-			if ( hqlToken.isPossibleID() && ( ex instanceof MismatchedTokenException ) ) {
-				MismatchedTokenException mte = ( MismatchedTokenException ) ex;
-				// ... and the expected token type was an identifier, then:
-				if ( mte.expecting == HqlTokenTypes.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( HqlTokenTypes.WEIRD_IDENT );
-					astFactory.addASTChild( currentAST, astFactory.create( token ) );
-					consume();
-					AST identifierAST = currentAST.root;
-					return identifierAST;
-				}
-			} // if
-		} // if
-		// Otherwise, handle the error normally.
-		return super.handleIdentifierError( token, ex );
-	}
-
-	/**
-	 * Returns an equivalent tree for (NOT (a relop b) ), for example:<pre>
-	 * (NOT (GT a b) ) => (LE a b)
-	 * </pre>
-	 *
-	 * @param x The sub tree to transform, the parent is assumed to be NOT.
-	 * @return AST - The equivalent sub-tree.
-	 */
-	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 EQ:
-				x.setType( NE );
-				x.setText( "{not}" + x.getText() );
-				return x;	// (NOT (EQ a b) ) => (NE a b)
-			case NE:
-				x.setType( EQ );
-				x.setText( "{not}" + x.getText() );
-				return x;	// (NOT (NE a b) ) => (EQ a b)
-			case GT:
-				x.setType( LE );
-				x.setText( "{not}" + x.getText() );
-				return x;	// (NOT (GT a b) ) => (LE a b)
-			case LT:
-				x.setType( GE );
-				x.setText( "{not}" + x.getText() );
-				return x;	// (NOT (LT a b) ) => (GE a b)
-			case GE:
-				x.setType( LT );
-				x.setText( "{not}" + x.getText() );
-				return x;	// (NOT (GE a b) ) => (LT a b)
-			case LE:
-				x.setType( GT );
-				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)
-/* This can never happen because this rule will always eliminate the child NOT.
-			case NOT:
-				return x.getFirstChild();			// (NOT (NOT x) ) => (x)
-*/
-			default:
-				return super.negateNode( x );		// Just add a 'not' parent.
-		}
-	}
-
-	/**
-	 * Post process equality expressions, clean up the subtree.
-	 *
-	 * @param x The equality expression.
-	 * @return AST - The clean sub-tree.
-	 */
-	public AST processEqualityExpression(AST x) {
-		if ( x == null ) {
-			log.warn( "processEqualityExpression() : No expression to process!" );
-			return null;
-		}
-
-		int type = x.getType();
-		if ( type == EQ || type == NE ) {
-			boolean negated = type == NE;
-			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 );
-	}
-
-	private AST processIsEmpty(AST node, boolean negated) {
-		node.setNextSibling( null );
-		// NOTE: Because we're using ASTUtil.createParent(), the tree must be created from the bottom up.
-		// IS EMPTY x => (EXISTS (QUERY (SELECT_FROM (FROM x) ) ) )
-		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;
-	}
-
-	private AST createSubquery(AST node) {
-		AST ast = ASTUtil.createParent( astFactory, RANGE, "RANGE", node );
-		ast = ASTUtil.createParent( astFactory, FROM, "from", ast );
-		ast = ASTUtil.createParent( astFactory, SELECT_FROM, "SELECT_FROM", ast );
-		ast = ASTUtil.createParent( astFactory, QUERY, "QUERY", ast );
-		return ast;
-	}
-
-	public void showAst(AST ast, PrintStream out) {
-		showAst( ast, new PrintWriter( out ) );
-	}
-
-	private void showAst(AST ast, PrintWriter pw) {
-		printer.showAst( ast, pw );
-	}
-
-	private void initialize() {
-		// Initialize the error handling delegate.
-		parseErrorHandler = new ErrorCounter();
-		setASTFactory(new HqlASTFactory());	// Create nodes that track line and column number.
-	}
-
-	public void weakKeywords() throws TokenStreamException {
-
-		int t = LA( 1 );
-		switch ( t ) {
-			case ORDER:
-			case GROUP:
-                // Case 1: Multi token keywords GROUP BY and ORDER BY
-				// The next token ( LT(2) ) should be 'by'... otherwise, this is just an ident.
-				if ( LA( 2 ) != LITERAL_by ) {
-					LT( 1 ).setType( IDENT );
-					if ( log.isDebugEnabled() ) {
-						log.debug( "weakKeywords() : new LT(1) token - " + LT( 1 ) );
-					}
-				}
-				break;
-			default:
-                // Case 2: The current token is after FROM and before '.'.
-                if (LA(0) == FROM && t != IDENT && LA(2) == DOT) {
-                    HqlToken hqlToken = (HqlToken)LT(1);
-                    if (hqlToken.isPossibleID()) {
-                        hqlToken.setType(IDENT);
-                        if ( log.isDebugEnabled() ) {
-                            log.debug( "weakKeywords() : new LT(1) token - " + LT( 1 ) );
-                        }
-                    }
-                }
-				break;
-		}
-	}
-
-    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...
-        if (LA(1) == DOT && LA(2) != IDENT) {
-            // See if the second lookahed token can be an identifier.
-            HqlToken t = (HqlToken)LT(2);
-            if (t.isPossibleID())
-            {
-                // Set it!
-                LT( 2 ).setType( IDENT );
-                if ( log.isDebugEnabled() ) {
-                    log.debug( "handleDotIdent() : new LT(2) token - " + LT( 1 ) );
-                }
-            }
-        }
-    }
-
-	public void processMemberOf(Token n, AST p, ASTPair currentAST) {
-		AST inAst = n == null ? astFactory.create( IN, "in" ) : astFactory.create( NOT_IN, "not in" );
-		astFactory.makeASTRoot( currentAST, inAst );
-		AST ast = createSubquery( p );
-		ast = ASTUtil.createParent( astFactory, IN_LIST, "inList", ast );
-		inAst.addChild( ast );
-	}
-
-	static public void panic() {
-		//overriden to avoid System.exit
-		throw new QueryException("Parser: panic");
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,361 @@
+/*
+ * 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;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringReader;
+
+import antlr.ASTPair;
+import antlr.MismatchedTokenException;
+import antlr.RecognitionException;
+import antlr.Token;
+import antlr.TokenStream;
+import antlr.TokenStreamException;
+import antlr.collections.AST;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.hql.antlr.HqlBaseParser;
+import org.hibernate.hql.antlr.HqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.QueryException;
+
+/**
+ * Implements the semantic action methods defined in the HQL base parser to keep the grammar
+ * source file a little cleaner.  Extends the parser class generated by ANTLR.
+ *
+ * @author Joshua Davis (pgmjsd at sourceforge.net)
+ */
+public final class HqlParser extends HqlBaseParser {
+	/**
+	 * A logger for this class.
+	 */
+	private static final Logger log = LoggerFactory.getLogger( HqlParser.class );
+
+	private ParseErrorHandler parseErrorHandler;
+	private ASTPrinter printer = getASTPrinter();
+
+	private static ASTPrinter getASTPrinter() {
+		return new ASTPrinter( org.hibernate.hql.antlr.HqlTokenTypes.class );
+	}
+
+	public static HqlParser getInstance(String hql) {
+        // [jsd] The fix for HHH-558...
+        HqlLexer lexer = new HqlLexer( new StringReader( hql ) );
+		return new HqlParser( lexer );
+	}
+
+	private HqlParser(TokenStream lexer) {
+		super( lexer );
+		initialize();
+	}
+
+	public void reportError(RecognitionException e) {
+		parseErrorHandler.reportError( e ); // Use the delegate.
+	}
+
+	public void reportError(String s) {
+		parseErrorHandler.reportError( s ); // Use the delegate.
+	}
+
+	public void reportWarning(String s) {
+		parseErrorHandler.reportWarning( s );
+	}
+
+	public ParseErrorHandler getParseErrorHandler() {
+		return parseErrorHandler;
+	}
+
+	/**
+	 * 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 HqlToken ) {
+			HqlToken hqlToken = ( HqlToken ) token;
+			// ... and the token could be an identifer and the error is
+			// a mismatched token error ...
+			if ( hqlToken.isPossibleID() && ( ex instanceof MismatchedTokenException ) ) {
+				MismatchedTokenException mte = ( MismatchedTokenException ) ex;
+				// ... and the expected token type was an identifier, then:
+				if ( mte.expecting == HqlTokenTypes.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( HqlTokenTypes.WEIRD_IDENT );
+					astFactory.addASTChild( currentAST, astFactory.create( token ) );
+					consume();
+					AST identifierAST = currentAST.root;
+					return identifierAST;
+				}
+			} // if
+		} // if
+		// Otherwise, handle the error normally.
+		return super.handleIdentifierError( token, ex );
+	}
+
+	/**
+	 * Returns an equivalent tree for (NOT (a relop b) ), for example:<pre>
+	 * (NOT (GT a b) ) => (LE a b)
+	 * </pre>
+	 *
+	 * @param x The sub tree to transform, the parent is assumed to be NOT.
+	 * @return AST - The equivalent sub-tree.
+	 */
+	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 EQ:
+				x.setType( NE );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (EQ a b) ) => (NE a b)
+			case NE:
+				x.setType( EQ );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (NE a b) ) => (EQ a b)
+			case GT:
+				x.setType( LE );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (GT a b) ) => (LE a b)
+			case LT:
+				x.setType( GE );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (LT a b) ) => (GE a b)
+			case GE:
+				x.setType( LT );
+				x.setText( "{not}" + x.getText() );
+				return x;	// (NOT (GE a b) ) => (LT a b)
+			case LE:
+				x.setType( GT );
+				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)
+/* This can never happen because this rule will always eliminate the child NOT.
+			case NOT:
+				return x.getFirstChild();			// (NOT (NOT x) ) => (x)
+*/
+			default:
+				return super.negateNode( x );		// Just add a 'not' parent.
+		}
+	}
+
+	/**
+	 * Post process equality expressions, clean up the subtree.
+	 *
+	 * @param x The equality expression.
+	 * @return AST - The clean sub-tree.
+	 */
+	public AST processEqualityExpression(AST x) {
+		if ( x == null ) {
+			log.warn( "processEqualityExpression() : No expression to process!" );
+			return null;
+		}
+
+		int type = x.getType();
+		if ( type == EQ || type == NE ) {
+			boolean negated = type == NE;
+			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 );
+	}
+
+	private AST processIsEmpty(AST node, boolean negated) {
+		node.setNextSibling( null );
+		// NOTE: Because we're using ASTUtil.createParent(), the tree must be created from the bottom up.
+		// IS EMPTY x => (EXISTS (QUERY (SELECT_FROM (FROM x) ) ) )
+		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;
+	}
+
+	private AST createSubquery(AST node) {
+		AST ast = ASTUtil.createParent( astFactory, RANGE, "RANGE", node );
+		ast = ASTUtil.createParent( astFactory, FROM, "from", ast );
+		ast = ASTUtil.createParent( astFactory, SELECT_FROM, "SELECT_FROM", ast );
+		ast = ASTUtil.createParent( astFactory, QUERY, "QUERY", ast );
+		return ast;
+	}
+
+	public void showAst(AST ast, PrintStream out) {
+		showAst( ast, new PrintWriter( out ) );
+	}
+
+	private void showAst(AST ast, PrintWriter pw) {
+		printer.showAst( ast, pw );
+	}
+
+	private void initialize() {
+		// Initialize the error handling delegate.
+		parseErrorHandler = new ErrorCounter();
+		setASTFactory(new HqlASTFactory());	// Create nodes that track line and column number.
+	}
+
+	public void weakKeywords() throws TokenStreamException {
+
+		int t = LA( 1 );
+		switch ( t ) {
+			case ORDER:
+			case GROUP:
+                // Case 1: Multi token keywords GROUP BY and ORDER BY
+				// The next token ( LT(2) ) should be 'by'... otherwise, this is just an ident.
+				if ( LA( 2 ) != LITERAL_by ) {
+					LT( 1 ).setType( IDENT );
+					if ( log.isDebugEnabled() ) {
+						log.debug( "weakKeywords() : new LT(1) token - " + LT( 1 ) );
+					}
+				}
+				break;
+			default:
+                // Case 2: The current token is after FROM and before '.'.
+                if (LA(0) == FROM && t != IDENT && LA(2) == DOT) {
+                    HqlToken hqlToken = (HqlToken)LT(1);
+                    if (hqlToken.isPossibleID()) {
+                        hqlToken.setType(IDENT);
+                        if ( log.isDebugEnabled() ) {
+                            log.debug( "weakKeywords() : new LT(1) token - " + LT( 1 ) );
+                        }
+                    }
+                }
+				break;
+		}
+	}
+
+    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...
+        if (LA(1) == DOT && LA(2) != IDENT) {
+            // See if the second lookahed token can be an identifier.
+            HqlToken t = (HqlToken)LT(2);
+            if (t.isPossibleID())
+            {
+                // Set it!
+                LT( 2 ).setType( IDENT );
+                if ( log.isDebugEnabled() ) {
+                    log.debug( "handleDotIdent() : new LT(2) token - " + LT( 1 ) );
+                }
+            }
+        }
+    }
+
+	public void processMemberOf(Token n, AST p, ASTPair currentAST) {
+		AST inAst = n == null ? astFactory.create( IN, "in" ) : astFactory.create( NOT_IN, "not in" );
+		astFactory.makeASTRoot( currentAST, inAst );
+		AST ast = createSubquery( p );
+		ast = ASTUtil.createParent( astFactory, IN_LIST, "inList", ast );
+		inAst.addChild( ast );
+	}
+
+	static public void panic() {
+		//overriden to avoid System.exit
+		throw new QueryException("Parser: panic");
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1016 +0,0 @@
-// $Id: HqlSqlWalker.java 10945 2006-12-07 14:50:42Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.QueryException;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.engine.ParameterBinder;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.antlr.HqlSqlBaseWalker;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.HqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.tree.AssignmentSpecification;
-import org.hibernate.hql.ast.tree.CollectionFunction;
-import org.hibernate.hql.ast.tree.ConstructorNode;
-import org.hibernate.hql.ast.tree.DeleteStatement;
-import org.hibernate.hql.ast.tree.DotNode;
-import org.hibernate.hql.ast.tree.FromClause;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.FromReferenceNode;
-import org.hibernate.hql.ast.tree.IdentNode;
-import org.hibernate.hql.ast.tree.IndexNode;
-import org.hibernate.hql.ast.tree.InsertStatement;
-import org.hibernate.hql.ast.tree.IntoClause;
-import org.hibernate.hql.ast.tree.MethodNode;
-import org.hibernate.hql.ast.tree.ParameterNode;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.hql.ast.tree.ResolvableNode;
-import org.hibernate.hql.ast.tree.RestrictableStatement;
-import org.hibernate.hql.ast.tree.SelectClause;
-import org.hibernate.hql.ast.tree.SelectExpression;
-import org.hibernate.hql.ast.tree.UpdateStatement;
-import org.hibernate.hql.ast.tree.Node;
-import org.hibernate.hql.ast.tree.OperatorNode;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.util.AliasGenerator;
-import org.hibernate.hql.ast.util.JoinProcessor;
-import org.hibernate.hql.ast.util.LiteralProcessor;
-import org.hibernate.hql.ast.util.SessionFactoryHelper;
-import org.hibernate.hql.ast.util.SyntheticAndFactory;
-import org.hibernate.hql.ast.util.NodeTraverser;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.PostInsertIdentifierGenerator;
-import org.hibernate.id.SequenceGenerator;
-import org.hibernate.param.NamedParameterSpecification;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.param.PositionalParameterSpecification;
-import org.hibernate.param.VersionTypeSeedParameterSpecification;
-import org.hibernate.param.CollectionFilterKeyParameterSpecification;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.type.VersionType;
-import org.hibernate.type.DbTimestampType;
-import org.hibernate.usertype.UserVersionType;
-import org.hibernate.util.ArrayHelper;
-
-import antlr.ASTFactory;
-import antlr.RecognitionException;
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Implements methods used by the HQL->SQL tree transform grammar (a.k.a. the second phase).
- * <ul>
- * <li>Isolates the Hibernate API-specific code from the ANTLR generated code.</li>
- * <li>Handles the SQL framgents generated by the persisters in order to create the SELECT and FROM clauses,
- * taking into account the joins and projections that are implied by the mappings (persister/queryable).</li>
- * <li>Uses SqlASTFactory to create customized AST nodes.</li>
- * </ul>
- *
- * @see SqlASTFactory
- */
-public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, ParameterBinder.NamedParameterSource {
-	private static final Logger log = LoggerFactory.getLogger( HqlSqlWalker.class );
-
-	private final QueryTranslatorImpl queryTranslatorImpl;
-	private final HqlParser hqlParser;
-	private final SessionFactoryHelper sessionFactoryHelper;
-	private final Map tokenReplacements;
-	private final AliasGenerator aliasGenerator = new AliasGenerator();
-	private final LiteralProcessor literalProcessor;
-	private final ParseErrorHandler parseErrorHandler;
-	private final ASTPrinter printer;
-	private final String collectionFilterRole;
-
-	private FromClause currentFromClause = null;
-	private SelectClause selectClause;
-
-	private Set querySpaces = new HashSet();
-
-	private int parameterCount;
-	private Map namedParameters = new HashMap();
-	private ArrayList parameters = new ArrayList();
-	private int numberOfParametersInSetClause;
-	private int positionalParameterCount;
-
-	private ArrayList assignmentSpecifications = new ArrayList();
-
-	private int impliedJoinType;
-
-	/**
-	 * Create a new tree transformer.
-	 *
-	 * @param qti Back pointer to the query translator implementation that is using this tree transform.
-	 * @param sfi The session factory implementor where the Hibernate mappings can be found.
-	 * @param parser A reference to the phase-1 parser
-	 * @param tokenReplacements Registers the token replacement map with the walker.  This map will
-	 * be used to substitute function names and constants.
-	 * @param collectionRole The collection role name of the collection used as the basis for the
-	 * filter, NULL if this is not a collection filter compilation.
-	 */
-	public HqlSqlWalker(
-			QueryTranslatorImpl qti,
-			SessionFactoryImplementor sfi,
-			HqlParser parser,
-			Map tokenReplacements,
-			String collectionRole) {
-		setASTFactory( new SqlASTFactory( this ) );
-		// Initialize the error handling delegate.
-		this.parseErrorHandler = new ErrorCounter();
-		this.queryTranslatorImpl = qti;
-		this.sessionFactoryHelper = new SessionFactoryHelper( sfi );
-		this.literalProcessor = new LiteralProcessor( this );
-		this.tokenReplacements = tokenReplacements;
-		this.collectionFilterRole = collectionRole;
-		this.hqlParser = parser;
-		this.printer = new ASTPrinter( SqlTokenTypes.class );
-	}
-
-
-	protected void prepareFromClauseInputTree(AST fromClauseInput) {
-		if ( !isSubQuery() ) {
-//			// inject param specifications to account for dynamic filter param values
-//			if ( ! getEnabledFilters().isEmpty() ) {
-//				Iterator filterItr = getEnabledFilters().values().iterator();
-//				while ( filterItr.hasNext() ) {
-//					FilterImpl filter = ( FilterImpl ) filterItr.next();
-//					if ( ! filter.getFilterDefinition().getParameterNames().isEmpty() ) {
-//						Iterator paramItr = filter.getFilterDefinition().getParameterNames().iterator();
-//						while ( paramItr.hasNext() ) {
-//							String parameterName = ( String ) paramItr.next();
-//							// currently param filters *only* work with single-column parameter types;
-//							// if that limitation is ever lifted, this logic will need to change to account for that
-//							ParameterNode collectionFilterKeyParameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
-//							DynamicFilterParameterSpecification paramSpec = new DynamicFilterParameterSpecification(
-//									filter.getName(),
-//									parameterName,
-//									filter.getFilterDefinition().getParameterType( parameterName ),
-//									 positionalParameterCount++
-//							);
-//							collectionFilterKeyParameter.setHqlParameterSpecification( paramSpec );
-//							parameters.add( paramSpec );
-//						}
-//					}
-//				}
-//			}
-
-			if ( isFilter() ) {
-				// Handle collection-fiter compilation.
-				// IMPORTANT NOTE: This is modifying the INPUT (HQL) tree, not the output tree!
-				QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
-				Type collectionElementType = persister.getElementType();
-				if ( !collectionElementType.isEntityType() ) {
-					throw new QueryException( "collection of values in filter: this" );
-				}
-
-				String collectionElementEntityName = persister.getElementPersister().getEntityName();
-				ASTFactory inputAstFactory = hqlParser.getASTFactory();
-				AST fromElement = ASTUtil.create( inputAstFactory, HqlTokenTypes.FILTER_ENTITY, collectionElementEntityName );
-				ASTUtil.createSibling( inputAstFactory, HqlTokenTypes.ALIAS, "this", fromElement );
-				fromClauseInput.addChild( fromElement );
-				// Show the modified AST.
-				if ( log.isDebugEnabled() ) {
-					log.debug( "prepareFromClauseInputTree() : Filter - Added 'this' as a from element..." );
-				}
-				queryTranslatorImpl.showHqlAst( hqlParser.getAST() );
-
-				// Create a parameter specification for the collection filter...
-				Type collectionFilterKeyType = sessionFactoryHelper.requireQueryableCollection( collectionFilterRole ).getKeyType();
-				ParameterNode collectionFilterKeyParameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
-				CollectionFilterKeyParameterSpecification collectionFilterKeyParameterSpec = new CollectionFilterKeyParameterSpecification(
-						collectionFilterRole, collectionFilterKeyType, positionalParameterCount++
-				);
-				collectionFilterKeyParameter.setHqlParameterSpecification( collectionFilterKeyParameterSpec );
-				parameters.add( collectionFilterKeyParameterSpec );
-			}
-		}
-	}
-
-	public boolean isFilter() {
-		return collectionFilterRole != null;
-	}
-
-	public SessionFactoryHelper getSessionFactoryHelper() {
-		return sessionFactoryHelper;
-	}
-
-	public Map getTokenReplacements() {
-		return tokenReplacements;
-	}
-
-	public AliasGenerator getAliasGenerator() {
-		return aliasGenerator;
-	}
-
-	public FromClause getCurrentFromClause() {
-		return currentFromClause;
-	}
-
-	public ParseErrorHandler getParseErrorHandler() {
-		return parseErrorHandler;
-	}
-
-	public void reportError(RecognitionException e) {
-		parseErrorHandler.reportError( e ); // Use the delegate.
-	}
-
-	public void reportError(String s) {
-		parseErrorHandler.reportError( s ); // Use the delegate.
-	}
-
-	public void reportWarning(String s) {
-		parseErrorHandler.reportWarning( s );
-	}
-
-	/**
-	 * Returns the set of unique query spaces (a.k.a.
-	 * table names) that occurred in the query.
-	 *
-	 * @return A set of table names (Strings).
-	 */
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	protected AST createFromElement(String path, AST alias, AST propertyFetch) throws SemanticException {
-		FromElement fromElement = currentFromClause.addFromElement( path, alias );
-		fromElement.setAllPropertyFetch(propertyFetch!=null);
-		return fromElement;
-	}
-
-	protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
-		FromElement fromElement = currentFromClause.addFromElement( filterEntity.getText(), alias );
-		FromClause fromClause = fromElement.getFromClause();
-		QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
-		// Get the names of the columns used to link between the collection
-		// owner and the collection elements.
-		String[] keyColumnNames = persister.getKeyColumnNames();
-		String fkTableAlias = persister.isOneToMany()
-				? fromElement.getTableAlias()
-				: fromClause.getAliasGenerator().createName( collectionFilterRole );
-		JoinSequence join = sessionFactoryHelper.createJoinSequence();
-		join.setRoot( persister, fkTableAlias );
-		if ( !persister.isOneToMany() ) {
-			join.addJoin( ( AssociationType ) persister.getElementType(),
-					fromElement.getTableAlias(),
-					JoinFragment.INNER_JOIN,
-					persister.getElementColumnNames( fkTableAlias ) );
-		}
-		join.addCondition( fkTableAlias, keyColumnNames, " = ?" );
-		fromElement.setJoinSequence( join );
-		fromElement.setFilter( true );
-		if ( log.isDebugEnabled() ) {
-			log.debug( "createFromFilterElement() : processed filter FROM element." );
-		}
-		return fromElement;
-	}
-
-	protected void createFromJoinElement(
-	        AST path,
-	        AST alias,
-	        int joinType,
-	        AST fetchNode,
-	        AST propertyFetch,
-	        AST with) throws SemanticException {
-		boolean fetch = fetchNode != null;
-		if ( fetch && isSubQuery() ) {
-			throw new QueryException( "fetch not allowed in subquery from-elements" );
-		}
-		// The path AST should be a DotNode, and it should have been evaluated already.
-		if ( path.getType() != SqlTokenTypes.DOT ) {
-			throw new SemanticException( "Path expected for join!" );
-		}
-		DotNode dot = ( DotNode ) path;
-		int hibernateJoinType = JoinProcessor.toHibernateJoinType( joinType );
-		dot.setJoinType( hibernateJoinType );	// Tell the dot node about the join type.
-		dot.setFetch( fetch );
-		// Generate an explicit join for the root dot node.   The implied joins will be collected and passed up
-		// to the root dot node.
-		dot.resolve( true, false, alias == null ? null : alias.getText() );
-		FromElement fromElement = dot.getImpliedJoin();
-		fromElement.setAllPropertyFetch(propertyFetch!=null);
-
-		if ( with != null ) {
-			if ( fetch ) {
-				throw new SemanticException( "with-clause not allowed on fetched associations; use filters" );
-			}
-			handleWithFragment( fromElement, with );
-		}
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "createFromJoinElement() : " + getASTPrinter().showAsString( fromElement, "-- join tree --" ) );
-		}
-	}
-
-	private void handleWithFragment(FromElement fromElement, AST hqlWithNode) throws SemanticException
-	{
-		try {
-			withClause( hqlWithNode );
-			AST hqlSqlWithNode = returnAST;
-			if ( log.isDebugEnabled() ) {
-				log.debug( "handleWithFragment() : " + getASTPrinter().showAsString( hqlSqlWithNode, "-- with clause --" ) );
-			}
-			WithClauseVisitor visitor = new WithClauseVisitor();
-			NodeTraverser traverser = new NodeTraverser( visitor );
-			traverser.traverseDepthFirst( hqlSqlWithNode );
-			FromElement referencedFromElement = visitor.getReferencedFromElement();
-			if ( referencedFromElement != fromElement ) {
-				throw new InvalidWithClauseException( "with-clause expressions did not reference from-clause element to which the with-clause was associated" );
-			}
-			SqlGenerator sql = new SqlGenerator( getSessionFactoryHelper().getFactory() );
-			sql.whereExpr( hqlSqlWithNode.getFirstChild() );
-			fromElement.setWithClauseFragment( visitor.getJoinAlias(), "(" + sql.getSQL() + ")" );
-
-		}
-		catch( SemanticException e ) {
-			throw e;
-		}
-		catch( InvalidWithClauseException e ) {
-			throw e;
-		}
-		catch ( Exception e) {
-			throw new SemanticException( e.getMessage() );
-		}
-	}
-
-	private static class WithClauseVisitor implements NodeTraverser.VisitationStrategy {
-		private FromElement referencedFromElement;
-		private String joinAlias;
-
-		public void visit(AST node) {
-			// todo : currently expects that the individual with expressions apply to the same sql table join.
-			//      This may not be the case for joined-subclass where the property values
-			//      might be coming from different tables in the joined hierarchy.  At some
-			//      point we should expand this to support that capability.  However, that has
-			//      some difficulties:
-			//          1) the biggest is how to handle ORs when the individual comparisons are
-			//              linked to different sql joins.
-			//          2) here we would need to track each comparison individually, along with
-			//              the join alias to which it applies and then pass that information
-			//              back to the FromElement so it can pass it along to the JoinSequence
-
-			if ( node instanceof DotNode ) {
-				DotNode dotNode = ( DotNode ) node;
-				FromElement fromElement = dotNode.getFromElement();
-				if ( referencedFromElement != null ) {
-					if ( fromElement != referencedFromElement ) {
-						throw new HibernateException( "with-clause referenced two different from-clause elements" );
-					}
-				}
-				else {
-					referencedFromElement = fromElement;
-					joinAlias = extractAppliedAlias( dotNode );
-					// todo : temporary
-					//      needed because currently persister is the one that
-					//      creates and renders the join fragments for inheritence
-					//      hierarchies...
-					if ( !joinAlias.equals( referencedFromElement.getTableAlias() ) ) {
-						throw new InvalidWithClauseException( "with clause can only reference columns in the driving table" );
-					}
-				}
-			}
-		}
-
-		private String extractAppliedAlias(DotNode dotNode) {
-			return dotNode.getText().substring( 0, dotNode.getText().indexOf( '.' ) );
-		}
-
-		public FromElement getReferencedFromElement() {
-			return referencedFromElement;
-		}
-
-		public String getJoinAlias() {
-			return joinAlias;
-		}
-	}
-
-	/**
-	 * Sets the current 'FROM' context.
-	 *
-	 * @param fromNode      The new 'FROM' context.
-	 * @param inputFromNode The from node from the input AST.
-	 */
-	protected void pushFromClause(AST fromNode, AST inputFromNode) {
-		FromClause newFromClause = ( FromClause ) fromNode;
-		newFromClause.setParentFromClause( currentFromClause );
-		currentFromClause = newFromClause;
-	}
-
-	/**
-	 * Returns to the previous 'FROM' context.
-	 */
-	private void popFromClause() {
-		currentFromClause = currentFromClause.getParentFromClause();
-	}
-
-	protected void lookupAlias(AST aliasRef)
-			throws SemanticException {
-		FromElement alias = currentFromClause.getFromElement( aliasRef.getText() );
-		FromReferenceNode aliasRefNode = ( FromReferenceNode ) aliasRef;
-		aliasRefNode.setFromElement( alias );
-	}
-
-	protected void setImpliedJoinType(int joinType) {
-		impliedJoinType = JoinProcessor.toHibernateJoinType( joinType );
-	}
-
-	public int getImpliedJoinType() {
-		return impliedJoinType;
-	}
-
-	protected AST lookupProperty(AST dot, boolean root, boolean inSelect) throws SemanticException {
-		DotNode dotNode = ( DotNode ) dot;
-		FromReferenceNode lhs = dotNode.getLhs();
-		AST rhs = lhs.getNextSibling();
-		switch ( rhs.getType() ) {
-			case SqlTokenTypes.ELEMENTS:
-			case SqlTokenTypes.INDICES:
-				if ( log.isDebugEnabled() ) {
-					log.debug( "lookupProperty() " + dotNode.getPath() + " => " + rhs.getText() + "(" + lhs.getPath() + ")" );
-				}
-				CollectionFunction f = ( CollectionFunction ) rhs;
-				// Re-arrange the tree so that the collection function is the root and the lhs is the path.
-				f.setFirstChild( lhs );
-				lhs.setNextSibling( null );
-				dotNode.setFirstChild( f );
-				resolve( lhs );			// Don't forget to resolve the argument!
-				f.resolve( inSelect );	// Resolve the collection function now.
-				return f;
-			default:
-				// Resolve everything up to this dot, but don't resolve the placeholders yet.
-				dotNode.resolveFirstChild();
-				return dotNode;
-		}
-	}
-
-	protected boolean isNonQualifiedPropertyRef(AST ident) {
-		final String identText = ident.getText();
-		if ( currentFromClause.isFromElementAlias( identText ) ) {
-			return false;
-		}
-
-		List fromElements = currentFromClause.getExplicitFromElements();
-		if ( fromElements.size() == 1 ) {
-			final FromElement fromElement = ( FromElement ) fromElements.get( 0 );
-			try {
-				log.trace( "attempting to resolve property [" + identText + "] as a non-qualified ref" );
-				return fromElement.getPropertyMapping( identText ).toType( identText ) != null;
-			}
-			catch( QueryException e ) {
-				// Should mean that no such property was found
-			}
-		}
-
-		return false;
-	}
-
-	protected AST lookupNonQualifiedProperty(AST property) throws SemanticException {
-		final FromElement fromElement = ( FromElement ) currentFromClause.getExplicitFromElements().get( 0 );
-		AST syntheticDotNode = generateSyntheticDotNodeForNonQualifiedPropertyRef( property, fromElement );
-		return lookupProperty( syntheticDotNode, false, getCurrentClauseType() == HqlSqlTokenTypes.SELECT );
-	}
-
-	private AST generateSyntheticDotNodeForNonQualifiedPropertyRef(AST property, FromElement fromElement) {
-		AST dot = getASTFactory().create( DOT, "{non-qualified-property-ref}" );
-		// TODO : better way?!?
-		( ( DotNode ) dot ).setPropertyPath( ( ( FromReferenceNode ) property ).getPath() );
-
-		IdentNode syntheticAlias = ( IdentNode ) getASTFactory().create( IDENT, "{synthetic-alias}" );
-		syntheticAlias.setFromElement( fromElement );
-		syntheticAlias.setResolved();
-
-		dot.setFirstChild( syntheticAlias );
-		dot.addChild( property );
-
-		return dot;
-	}
-
-	protected void processQuery(AST select, AST query) throws SemanticException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "processQuery() : " + query.toStringTree() );
-		}
-
-		try {
-			QueryNode qn = ( QueryNode ) query;
-
-			// Was there an explicit select expression?
-			boolean explicitSelect = select != null && select.getNumberOfChildren() > 0;
-
-			if ( !explicitSelect ) {
-				// No explicit select expression; render the id and properties
-				// projection lists for every persister in the from clause into
-				// a single 'token node'.
-				//TODO: the only reason we need this stuff now is collection filters,
-				//      we should get rid of derived select clause completely!
-				createSelectClauseFromFromClause( qn );
-			}
-			else {
-				// Use the explicitly declared select expression; determine the
-				// return types indicated by each select token
-				useSelectClause( select );
-			}
-
-			// After that, process the JOINs.
-			// Invoke a delegate to do the work, as this is farily complex.
-			JoinProcessor joinProcessor = new JoinProcessor( astFactory, queryTranslatorImpl );
-			joinProcessor.processJoins( qn, isSubQuery() );
-
-			// Attach any mapping-defined "ORDER BY" fragments
-			Iterator itr = qn.getFromClause().getProjectionList().iterator();
-			while ( itr.hasNext() ) {
-				final FromElement fromElement = ( FromElement ) itr.next();
-//			if ( fromElement.isFetch() && fromElement.isCollectionJoin() ) {
-				if ( fromElement.isFetch() && fromElement.getQueryableCollection() != null ) {
-					// Does the collection referenced by this FromElement
-					// specify an order-by attribute?  If so, attach it to
-					// the query's order-by
-					if ( fromElement.getQueryableCollection().hasOrdering() ) {
-						String orderByFragment = fromElement
-								.getQueryableCollection()
-								.getSQLOrderByString( fromElement.getCollectionTableAlias() );
-						qn.getOrderByClause().addOrderFragment( orderByFragment );
-					}
-					if ( fromElement.getQueryableCollection().hasManyToManyOrdering() ) {
-						String orderByFragment = fromElement.getQueryableCollection()
-								.getManyToManyOrderByString( fromElement.getTableAlias() );
-						qn.getOrderByClause().addOrderFragment( orderByFragment );
-					}
-				}
-			}
-		}
-		finally {
-			popFromClause();
-		}
-	}
-
-	protected void postProcessDML(RestrictableStatement statement) throws SemanticException {
-		statement.getFromClause().resolve();
-
-		FromElement fromElement = ( FromElement ) statement.getFromClause().getFromElements().get( 0 );
-		Queryable persister = fromElement.getQueryable();
-		// Make #@%$^#^&# sure no alias is applied to the table name
-		fromElement.setText( persister.getTableName() );
-
-		// append any filter fragments; the EMPTY_MAP is used under the assumption that
-		// currently enabled filters should not affect this process
-		if ( persister.getDiscriminatorType() != null ) {
-			new SyntheticAndFactory( getASTFactory() ).addDiscriminatorWhereFragment(
-			        statement,
-			        persister,
-			        java.util.Collections.EMPTY_MAP,
-			        fromElement.getTableAlias()
-			);
-		}
-
-	}
-
-	protected void postProcessUpdate(AST update) throws SemanticException {
-		UpdateStatement updateStatement = ( UpdateStatement ) update;
-
-		postProcessDML( updateStatement );
-	}
-
-	protected void postProcessDelete(AST delete) throws SemanticException {
-		postProcessDML( ( DeleteStatement ) delete );
-	}
-
-	public static boolean supportsIdGenWithBulkInsertion(IdentifierGenerator generator) {
-		return SequenceGenerator.class.isAssignableFrom( generator.getClass() )
-		        || PostInsertIdentifierGenerator.class.isAssignableFrom( generator.getClass() );
-	}
-
-	protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
-		InsertStatement insertStatement = ( InsertStatement ) insert;
-		insertStatement.validate();
-
-		SelectClause selectClause = insertStatement.getSelectClause();
-		Queryable persister = insertStatement.getIntoClause().getQueryable();
-
-		if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
-			// We need to generate ids as part of this bulk insert.
-			//
-			// Note that this is only supported for sequence-style generators and
-			// post-insert-style generators; basically, only in-db generators
-			IdentifierGenerator generator = persister.getIdentifierGenerator();
-			if ( !supportsIdGenWithBulkInsertion( generator ) ) {
-				throw new QueryException( "can only generate ids as part of bulk insert with either sequence or post-insert style generators" );
-			}
-
-			AST idSelectExprNode = null;
-
-			if ( SequenceGenerator.class.isAssignableFrom( generator.getClass() ) ) {
-				String seqName = ( String ) ( ( SequenceGenerator ) generator ).generatorKey();
-				String nextval = sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString( seqName );
-				idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, nextval );
-			}
-			else {
-				//Don't need this, because we should never ever be selecting no columns in an insert ... select...
-				//and because it causes a bug on DB2
-				/*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
-				if ( idInsertString != null ) {
-					idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
-				}*/
-			}
-
-			if ( idSelectExprNode != null ) {
-				AST currentFirstSelectExprNode = selectClause.getFirstChild();
-				selectClause.setFirstChild( idSelectExprNode );
-				idSelectExprNode.setNextSibling( currentFirstSelectExprNode );
-
-				insertStatement.getIntoClause().prependIdColumnSpec();
-			}
-		}
-
-		final boolean includeVersionProperty = persister.isVersioned() &&
-				!insertStatement.getIntoClause().isExplicitVersionInsertion() &&
-				persister.isVersionPropertyInsertable();
-		if ( includeVersionProperty ) {
-			// We need to seed the version value as part of this bulk insert
-			VersionType versionType = persister.getVersionType();
-			AST versionValueNode = null;
-
-			if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
-				versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
-				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
-				( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
-				parameters.add( 0, paramSpec );
-			}
-			else {
-				if ( isIntegral( versionType ) ) {
-					try {
-						Object seedValue = versionType.seed( null );
-						versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
-					}
-					catch( Throwable t ) {
-						throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
-					}
-				}
-				else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
-					String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
-					versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
-				}
-				else {
-					throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
-				}
-			}
-
-			AST currentFirstSelectExprNode = selectClause.getFirstChild();
-			selectClause.setFirstChild( versionValueNode );
-			versionValueNode.setNextSibling( currentFirstSelectExprNode );
-
-			insertStatement.getIntoClause().prependVersionColumnSpec();
-		}
-
-		if ( insertStatement.getIntoClause().isDiscriminated() ) {
-			String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
-			AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
-			insertStatement.getSelectClause().addChild( discrimValue );
-		}
-
-	}
-
-	private boolean isDatabaseGeneratedTimestamp(Type type) {
-		// currently only the Hibernate-supplied DbTimestampType is supported here
-		return DbTimestampType.class.isAssignableFrom( type.getClass() );
-	}
-
-	private boolean isIntegral(Type type) {
-		return Long.class.isAssignableFrom( type.getReturnedClass() )
-		       || Integer.class.isAssignableFrom( type.getReturnedClass() )
-		       || long.class.isAssignableFrom( type.getReturnedClass() )
-		       || int.class.isAssignableFrom( type.getReturnedClass() );
-	}
-
-	private void useSelectClause(AST select) throws SemanticException {
-		selectClause = ( SelectClause ) select;
-		selectClause.initializeExplicitSelectClause( currentFromClause );
-	}
-
-	private void createSelectClauseFromFromClause(QueryNode qn) throws SemanticException {
-		AST select = astFactory.create( SELECT_CLAUSE, "{derived select clause}" );
-		AST sibling = qn.getFromClause();
-		qn.setFirstChild( select );
-		select.setNextSibling( sibling );
-		selectClause = ( SelectClause ) select;
-		selectClause.initializeDerivedSelectClause( currentFromClause );
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Derived SELECT clause created." );
-		}
-	}
-
-	protected void resolve(AST node) throws SemanticException {
-		if ( node != null ) {
-			// This is called when it's time to fully resolve a path expression.
-			ResolvableNode r = ( ResolvableNode ) node;
-			if ( isInFunctionCall() ) {
-				r.resolveInFunctionCall( false, true );
-			}
-			else {
-				r.resolve( false, true );	// Generate implicit joins, only if necessary.
-			}
-		}
-	}
-
-	protected void resolveSelectExpression(AST node) throws SemanticException {
-		// This is called when it's time to fully resolve a path expression.
-		int type = node.getType();
-		switch ( type ) {
-			case DOT:
-				DotNode dot = ( DotNode ) node;
-				dot.resolveSelectExpression();
-				break;
-			case ALIAS_REF:
-				// Notify the FROM element that it is being referenced by the select.
-				FromReferenceNode aliasRefNode = ( FromReferenceNode ) node;
-				//aliasRefNode.resolve( false, false, aliasRefNode.getText() ); //TODO: is it kosher to do it here?
-				aliasRefNode.resolve( false, false ); //TODO: is it kosher to do it here?
-				FromElement fromElement = aliasRefNode.getFromElement();
-				if ( fromElement != null ) {
-					fromElement.setIncludeSubclasses( true );
-				}
-			default:
-				break;
-		}
-	}
-
-	protected void beforeSelectClause() throws SemanticException {
-		// Turn off includeSubclasses on all FromElements.
-		FromClause from = getCurrentFromClause();
-		List fromElements = from.getFromElements();
-		for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) {
-			FromElement fromElement = ( FromElement ) iterator.next();
-			fromElement.setIncludeSubclasses( false );
-		}
-	}
-
-	protected AST generatePositionalParameter(AST inputNode) throws SemanticException {
-		if ( namedParameters.size() > 0 ) {
-			throw new SemanticException( "cannot define positional parameter after any named parameters have been defined" );
-		}
-		ParameterNode parameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
-		PositionalParameterSpecification paramSpec = new PositionalParameterSpecification(
-				( ( Node ) inputNode ).getLine(),
-		        ( ( Node ) inputNode ).getColumn(),
-				positionalParameterCount++
-		);
-		parameter.setHqlParameterSpecification( paramSpec );
-		parameters.add( paramSpec );
-		return parameter;
-	}
-
-	protected AST generateNamedParameter(AST delimiterNode, AST nameNode) throws SemanticException {
-		String name = nameNode.getText();
-		trackNamedParameterPositions( name );
-
-		// create the node initially with the param name so that it shows
-		// appropriately in the "original text" attribute
-		ParameterNode parameter = ( ParameterNode ) astFactory.create( NAMED_PARAM, name );
-		parameter.setText( "?" );
-
-		NamedParameterSpecification paramSpec = new NamedParameterSpecification(
-				( ( Node ) delimiterNode ).getLine(),
-		        ( ( Node ) delimiterNode ).getColumn(),
-				name
-		);
-		parameter.setHqlParameterSpecification( paramSpec );
-		parameters.add( paramSpec );
-		return parameter;
-	}
-
-	private void trackNamedParameterPositions(String name) {
-		Integer loc = new Integer( parameterCount++ );
-		Object o = namedParameters.get( name );
-		if ( o == null ) {
-			namedParameters.put( name, loc );
-		}
-		else if ( o instanceof Integer ) {
-			ArrayList list = new ArrayList( 4 );
-			list.add( o );
-			list.add( loc );
-			namedParameters.put( name, list );
-		}
-		else {
-			( ( ArrayList ) o ).add( loc );
-		}
-	}
-
-	protected void processConstant(AST constant) throws SemanticException {
-		literalProcessor.processConstant( constant, true );  // Use the delegate, resolve identifiers as FROM element aliases.
-	}
-
-	protected void processBoolean(AST constant) throws SemanticException {
-		literalProcessor.processBoolean( constant );  // Use the delegate.
-	}
-
-	protected void processNumericLiteral(AST literal) {
-		literalProcessor.processNumeric( literal );
-	}
-
-	protected void processIndex(AST indexOp) throws SemanticException {
-		IndexNode indexNode = ( IndexNode ) indexOp;
-		indexNode.resolve( true, true );
-	}
-
-	protected void processFunction(AST functionCall, boolean inSelect) throws SemanticException {
-		MethodNode methodNode = ( MethodNode ) functionCall;
-		methodNode.resolve( inSelect );
-	}
-
-	protected void processConstructor(AST constructor) throws SemanticException {
-		ConstructorNode constructorNode = ( ConstructorNode ) constructor;
-		constructorNode.prepare();
-	}
-
-    protected void setAlias(AST selectExpr, AST ident) {
-        ((SelectExpression) selectExpr).setAlias(ident.getText());
-    }
-
-	/**
-	 * Returns the locations of all occurrences of the named parameter.
-	 */
-	public int[] getNamedParameterLocations(String name) throws QueryException {
-		Object o = namedParameters.get( name );
-		if ( o == null ) {
-			QueryException qe = new QueryException( QueryTranslator.ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name );
-			qe.setQueryString( queryTranslatorImpl.getQueryString() );
-			throw qe;
-		}
-		if ( o instanceof Integer ) {
-			return new int[]{( ( Integer ) o ).intValue()};
-		}
-		else {
-			return ArrayHelper.toIntArray( ( ArrayList ) o );
-		}
-	}
-
-	public void addQuerySpaces(Serializable[] spaces) {
-		for ( int i = 0; i < spaces.length; i++ ) {
-			querySpaces.add( spaces[i] );
-		}
-	}
-
-	public Type[] getReturnTypes() {
-		return selectClause.getQueryReturnTypes();
-	}
-
-	public String[] getReturnAliases() {
-		return selectClause.getQueryReturnAliases();
-	}
-
-	public SelectClause getSelectClause() {
-		return selectClause;
-	}
-	
-	public FromClause getFinalFromClause() {
-		FromClause top = currentFromClause;
-		while ( top.getParentFromClause() != null ) {
-			top = top.getParentFromClause();
-		}
-		return top;
-	}
-
-	public boolean isShallowQuery() {
-		// select clauses for insert statements should alwasy be treated as shallow
-		return getStatementType() == INSERT || queryTranslatorImpl.isShallowQuery();
-	}
-
-	public Map getEnabledFilters() {
-		return queryTranslatorImpl.getEnabledFilters();
-	}
-
-	public LiteralProcessor getLiteralProcessor() {
-		return literalProcessor;
-	}
-
-	public ASTPrinter getASTPrinter() {
-		return printer;
-	}
-
-	public ArrayList getParameters() {
-		return parameters;
-	}
-
-	public int getNumberOfParametersInSetClause() {
-		return numberOfParametersInSetClause;
-	}
-
-	protected void evaluateAssignment(AST eq) throws SemanticException {
-		prepareLogicOperator( eq );
-		Queryable persister = getCurrentFromClause().getFromElement().getQueryable();
-		evaluateAssignment( eq, persister, -1 );
-	}
-
-	private void evaluateAssignment(AST eq, Queryable persister, int targetIndex) {
-		if ( persister.isMultiTable() ) {
-			// no need to even collect this information if the persister is considered multi-table
-			AssignmentSpecification specification = new AssignmentSpecification( eq, persister );
-			if ( targetIndex >= 0 ) {
-				assignmentSpecifications.add( targetIndex, specification );
-			}
-			else {
-				assignmentSpecifications.add( specification );
-			}
-			numberOfParametersInSetClause += specification.getParameters().length;
-		}
-	}
-
-	public ArrayList getAssignmentSpecifications() {
-		return assignmentSpecifications;
-	}
-
-	protected AST createIntoClause(String path, AST propertySpec) throws SemanticException {
-		Queryable persister = ( Queryable ) getSessionFactoryHelper().requireClassPersister( path );
-
-		IntoClause intoClause = ( IntoClause ) getASTFactory().create( INTO, persister.getEntityName() );
-		intoClause.setFirstChild( propertySpec );
-		intoClause.initialize( persister );
-
-		addQuerySpaces( persister.getQuerySpaces() );
-
-		return intoClause;
-	}
-
-	protected void prepareVersioned(AST updateNode, AST versioned) throws SemanticException {
-		UpdateStatement updateStatement = ( UpdateStatement ) updateNode;
-		FromClause fromClause = updateStatement.getFromClause();
-		if ( versioned != null ) {
-			// Make sure that the persister is versioned
-			Queryable persister = fromClause.getFromElement().getQueryable();
-			if ( !persister.isVersioned() ) {
-				throw new SemanticException( "increment option specified for update of non-versioned entity" );
-			}
-
-			VersionType versionType = persister.getVersionType();
-			if ( versionType instanceof UserVersionType ) {
-				throw new SemanticException( "user-defined version types not supported for increment option" );
-			}
-
-			AST eq = getASTFactory().create( HqlSqlTokenTypes.EQ, "=" );
-			AST versionPropertyNode = generateVersionPropertyNode( persister );
-
-			eq.setFirstChild( versionPropertyNode );
-
-			AST versionIncrementNode = null;
-			if ( Date.class.isAssignableFrom( versionType.getReturnedClass() ) ) {
-				versionIncrementNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
-				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
-				( ( ParameterNode ) versionIncrementNode ).setHqlParameterSpecification( paramSpec );
-				parameters.add( 0, paramSpec );
-			}
-			else {
-				// Not possible to simply re-use the versionPropertyNode here as it causes
-				// OOM errors due to circularity :(
-				versionIncrementNode = getASTFactory().create( HqlSqlTokenTypes.PLUS, "+" );
-				versionIncrementNode.setFirstChild( generateVersionPropertyNode( persister ) );
-				versionIncrementNode.addChild( getASTFactory().create( HqlSqlTokenTypes.IDENT, "1" ) );
-			}
-
-			eq.addChild( versionIncrementNode );
-
-			evaluateAssignment( eq, persister, 0 );
-
-			AST setClause = updateStatement.getSetClause();
-			AST currentFirstSetElement = setClause.getFirstChild();
-			setClause.setFirstChild( eq );
-			eq.setNextSibling( currentFirstSetElement );
-		}
-	}
-
-	private AST generateVersionPropertyNode(Queryable persister) throws SemanticException {
-		String versionPropertyName = persister.getPropertyNames()[ persister.getVersionProperty() ];
-		AST versionPropertyRef = getASTFactory().create( HqlSqlTokenTypes.IDENT, versionPropertyName );
-		AST versionPropertyNode = lookupNonQualifiedProperty( versionPropertyRef );
-		resolve( versionPropertyNode );
-		return versionPropertyNode;
-	}
-
-	protected void prepareLogicOperator(AST operator) throws SemanticException {
-		( ( OperatorNode ) operator ).initialize();
-	}
-
-	protected void prepareArithmeticOperator(AST operator) throws SemanticException {
-		( ( OperatorNode ) operator ).initialize();
-	}
-
-	public static void panic() {
-		throw new QueryException( "TreeWalker: panic" );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlSqlWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1039 @@
+/*
+ * 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;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.engine.ParameterBinder;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.antlr.HqlSqlBaseWalker;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.HqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.tree.AssignmentSpecification;
+import org.hibernate.hql.ast.tree.CollectionFunction;
+import org.hibernate.hql.ast.tree.ConstructorNode;
+import org.hibernate.hql.ast.tree.DeleteStatement;
+import org.hibernate.hql.ast.tree.DotNode;
+import org.hibernate.hql.ast.tree.FromClause;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.FromReferenceNode;
+import org.hibernate.hql.ast.tree.IdentNode;
+import org.hibernate.hql.ast.tree.IndexNode;
+import org.hibernate.hql.ast.tree.InsertStatement;
+import org.hibernate.hql.ast.tree.IntoClause;
+import org.hibernate.hql.ast.tree.MethodNode;
+import org.hibernate.hql.ast.tree.ParameterNode;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.hql.ast.tree.ResolvableNode;
+import org.hibernate.hql.ast.tree.RestrictableStatement;
+import org.hibernate.hql.ast.tree.SelectClause;
+import org.hibernate.hql.ast.tree.SelectExpression;
+import org.hibernate.hql.ast.tree.UpdateStatement;
+import org.hibernate.hql.ast.tree.Node;
+import org.hibernate.hql.ast.tree.OperatorNode;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.AliasGenerator;
+import org.hibernate.hql.ast.util.JoinProcessor;
+import org.hibernate.hql.ast.util.LiteralProcessor;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+import org.hibernate.hql.ast.util.SyntheticAndFactory;
+import org.hibernate.hql.ast.util.NodeTraverser;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.PostInsertIdentifierGenerator;
+import org.hibernate.id.SequenceGenerator;
+import org.hibernate.param.NamedParameterSpecification;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.param.PositionalParameterSpecification;
+import org.hibernate.param.VersionTypeSeedParameterSpecification;
+import org.hibernate.param.CollectionFilterKeyParameterSpecification;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.VersionType;
+import org.hibernate.type.DbTimestampType;
+import org.hibernate.usertype.UserVersionType;
+import org.hibernate.util.ArrayHelper;
+
+import antlr.ASTFactory;
+import antlr.RecognitionException;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Implements methods used by the HQL->SQL tree transform grammar (a.k.a. the second phase).
+ * <ul>
+ * <li>Isolates the Hibernate API-specific code from the ANTLR generated code.</li>
+ * <li>Handles the SQL framgents generated by the persisters in order to create the SELECT and FROM clauses,
+ * taking into account the joins and projections that are implied by the mappings (persister/queryable).</li>
+ * <li>Uses SqlASTFactory to create customized AST nodes.</li>
+ * </ul>
+ *
+ * @see SqlASTFactory
+ */
+public class HqlSqlWalker extends HqlSqlBaseWalker implements ErrorReporter, ParameterBinder.NamedParameterSource {
+	private static final Logger log = LoggerFactory.getLogger( HqlSqlWalker.class );
+
+	private final QueryTranslatorImpl queryTranslatorImpl;
+	private final HqlParser hqlParser;
+	private final SessionFactoryHelper sessionFactoryHelper;
+	private final Map tokenReplacements;
+	private final AliasGenerator aliasGenerator = new AliasGenerator();
+	private final LiteralProcessor literalProcessor;
+	private final ParseErrorHandler parseErrorHandler;
+	private final ASTPrinter printer;
+	private final String collectionFilterRole;
+
+	private FromClause currentFromClause = null;
+	private SelectClause selectClause;
+
+	private Set querySpaces = new HashSet();
+
+	private int parameterCount;
+	private Map namedParameters = new HashMap();
+	private ArrayList parameters = new ArrayList();
+	private int numberOfParametersInSetClause;
+	private int positionalParameterCount;
+
+	private ArrayList assignmentSpecifications = new ArrayList();
+
+	private int impliedJoinType;
+
+	/**
+	 * Create a new tree transformer.
+	 *
+	 * @param qti Back pointer to the query translator implementation that is using this tree transform.
+	 * @param sfi The session factory implementor where the Hibernate mappings can be found.
+	 * @param parser A reference to the phase-1 parser
+	 * @param tokenReplacements Registers the token replacement map with the walker.  This map will
+	 * be used to substitute function names and constants.
+	 * @param collectionRole The collection role name of the collection used as the basis for the
+	 * filter, NULL if this is not a collection filter compilation.
+	 */
+	public HqlSqlWalker(
+			QueryTranslatorImpl qti,
+			SessionFactoryImplementor sfi,
+			HqlParser parser,
+			Map tokenReplacements,
+			String collectionRole) {
+		setASTFactory( new SqlASTFactory( this ) );
+		// Initialize the error handling delegate.
+		this.parseErrorHandler = new ErrorCounter();
+		this.queryTranslatorImpl = qti;
+		this.sessionFactoryHelper = new SessionFactoryHelper( sfi );
+		this.literalProcessor = new LiteralProcessor( this );
+		this.tokenReplacements = tokenReplacements;
+		this.collectionFilterRole = collectionRole;
+		this.hqlParser = parser;
+		this.printer = new ASTPrinter( SqlTokenTypes.class );
+	}
+
+
+	protected void prepareFromClauseInputTree(AST fromClauseInput) {
+		if ( !isSubQuery() ) {
+//			// inject param specifications to account for dynamic filter param values
+//			if ( ! getEnabledFilters().isEmpty() ) {
+//				Iterator filterItr = getEnabledFilters().values().iterator();
+//				while ( filterItr.hasNext() ) {
+//					FilterImpl filter = ( FilterImpl ) filterItr.next();
+//					if ( ! filter.getFilterDefinition().getParameterNames().isEmpty() ) {
+//						Iterator paramItr = filter.getFilterDefinition().getParameterNames().iterator();
+//						while ( paramItr.hasNext() ) {
+//							String parameterName = ( String ) paramItr.next();
+//							// currently param filters *only* work with single-column parameter types;
+//							// if that limitation is ever lifted, this logic will need to change to account for that
+//							ParameterNode collectionFilterKeyParameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
+//							DynamicFilterParameterSpecification paramSpec = new DynamicFilterParameterSpecification(
+//									filter.getName(),
+//									parameterName,
+//									filter.getFilterDefinition().getParameterType( parameterName ),
+//									 positionalParameterCount++
+//							);
+//							collectionFilterKeyParameter.setHqlParameterSpecification( paramSpec );
+//							parameters.add( paramSpec );
+//						}
+//					}
+//				}
+//			}
+
+			if ( isFilter() ) {
+				// Handle collection-fiter compilation.
+				// IMPORTANT NOTE: This is modifying the INPUT (HQL) tree, not the output tree!
+				QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
+				Type collectionElementType = persister.getElementType();
+				if ( !collectionElementType.isEntityType() ) {
+					throw new QueryException( "collection of values in filter: this" );
+				}
+
+				String collectionElementEntityName = persister.getElementPersister().getEntityName();
+				ASTFactory inputAstFactory = hqlParser.getASTFactory();
+				AST fromElement = ASTUtil.create( inputAstFactory, HqlTokenTypes.FILTER_ENTITY, collectionElementEntityName );
+				ASTUtil.createSibling( inputAstFactory, HqlTokenTypes.ALIAS, "this", fromElement );
+				fromClauseInput.addChild( fromElement );
+				// Show the modified AST.
+				if ( log.isDebugEnabled() ) {
+					log.debug( "prepareFromClauseInputTree() : Filter - Added 'this' as a from element..." );
+				}
+				queryTranslatorImpl.showHqlAst( hqlParser.getAST() );
+
+				// Create a parameter specification for the collection filter...
+				Type collectionFilterKeyType = sessionFactoryHelper.requireQueryableCollection( collectionFilterRole ).getKeyType();
+				ParameterNode collectionFilterKeyParameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
+				CollectionFilterKeyParameterSpecification collectionFilterKeyParameterSpec = new CollectionFilterKeyParameterSpecification(
+						collectionFilterRole, collectionFilterKeyType, positionalParameterCount++
+				);
+				collectionFilterKeyParameter.setHqlParameterSpecification( collectionFilterKeyParameterSpec );
+				parameters.add( collectionFilterKeyParameterSpec );
+			}
+		}
+	}
+
+	public boolean isFilter() {
+		return collectionFilterRole != null;
+	}
+
+	public SessionFactoryHelper getSessionFactoryHelper() {
+		return sessionFactoryHelper;
+	}
+
+	public Map getTokenReplacements() {
+		return tokenReplacements;
+	}
+
+	public AliasGenerator getAliasGenerator() {
+		return aliasGenerator;
+	}
+
+	public FromClause getCurrentFromClause() {
+		return currentFromClause;
+	}
+
+	public ParseErrorHandler getParseErrorHandler() {
+		return parseErrorHandler;
+	}
+
+	public void reportError(RecognitionException e) {
+		parseErrorHandler.reportError( e ); // Use the delegate.
+	}
+
+	public void reportError(String s) {
+		parseErrorHandler.reportError( s ); // Use the delegate.
+	}
+
+	public void reportWarning(String s) {
+		parseErrorHandler.reportWarning( s );
+	}
+
+	/**
+	 * Returns the set of unique query spaces (a.k.a.
+	 * table names) that occurred in the query.
+	 *
+	 * @return A set of table names (Strings).
+	 */
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	protected AST createFromElement(String path, AST alias, AST propertyFetch) throws SemanticException {
+		FromElement fromElement = currentFromClause.addFromElement( path, alias );
+		fromElement.setAllPropertyFetch(propertyFetch!=null);
+		return fromElement;
+	}
+
+	protected AST createFromFilterElement(AST filterEntity, AST alias) throws SemanticException {
+		FromElement fromElement = currentFromClause.addFromElement( filterEntity.getText(), alias );
+		FromClause fromClause = fromElement.getFromClause();
+		QueryableCollection persister = sessionFactoryHelper.getCollectionPersister( collectionFilterRole );
+		// Get the names of the columns used to link between the collection
+		// owner and the collection elements.
+		String[] keyColumnNames = persister.getKeyColumnNames();
+		String fkTableAlias = persister.isOneToMany()
+				? fromElement.getTableAlias()
+				: fromClause.getAliasGenerator().createName( collectionFilterRole );
+		JoinSequence join = sessionFactoryHelper.createJoinSequence();
+		join.setRoot( persister, fkTableAlias );
+		if ( !persister.isOneToMany() ) {
+			join.addJoin( ( AssociationType ) persister.getElementType(),
+					fromElement.getTableAlias(),
+					JoinFragment.INNER_JOIN,
+					persister.getElementColumnNames( fkTableAlias ) );
+		}
+		join.addCondition( fkTableAlias, keyColumnNames, " = ?" );
+		fromElement.setJoinSequence( join );
+		fromElement.setFilter( true );
+		if ( log.isDebugEnabled() ) {
+			log.debug( "createFromFilterElement() : processed filter FROM element." );
+		}
+		return fromElement;
+	}
+
+	protected void createFromJoinElement(
+	        AST path,
+	        AST alias,
+	        int joinType,
+	        AST fetchNode,
+	        AST propertyFetch,
+	        AST with) throws SemanticException {
+		boolean fetch = fetchNode != null;
+		if ( fetch && isSubQuery() ) {
+			throw new QueryException( "fetch not allowed in subquery from-elements" );
+		}
+		// The path AST should be a DotNode, and it should have been evaluated already.
+		if ( path.getType() != SqlTokenTypes.DOT ) {
+			throw new SemanticException( "Path expected for join!" );
+		}
+		DotNode dot = ( DotNode ) path;
+		int hibernateJoinType = JoinProcessor.toHibernateJoinType( joinType );
+		dot.setJoinType( hibernateJoinType );	// Tell the dot node about the join type.
+		dot.setFetch( fetch );
+		// Generate an explicit join for the root dot node.   The implied joins will be collected and passed up
+		// to the root dot node.
+		dot.resolve( true, false, alias == null ? null : alias.getText() );
+		FromElement fromElement = dot.getImpliedJoin();
+		fromElement.setAllPropertyFetch(propertyFetch!=null);
+
+		if ( with != null ) {
+			if ( fetch ) {
+				throw new SemanticException( "with-clause not allowed on fetched associations; use filters" );
+			}
+			handleWithFragment( fromElement, with );
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "createFromJoinElement() : " + getASTPrinter().showAsString( fromElement, "-- join tree --" ) );
+		}
+	}
+
+	private void handleWithFragment(FromElement fromElement, AST hqlWithNode) throws SemanticException
+	{
+		try {
+			withClause( hqlWithNode );
+			AST hqlSqlWithNode = returnAST;
+			if ( log.isDebugEnabled() ) {
+				log.debug( "handleWithFragment() : " + getASTPrinter().showAsString( hqlSqlWithNode, "-- with clause --" ) );
+			}
+			WithClauseVisitor visitor = new WithClauseVisitor();
+			NodeTraverser traverser = new NodeTraverser( visitor );
+			traverser.traverseDepthFirst( hqlSqlWithNode );
+			FromElement referencedFromElement = visitor.getReferencedFromElement();
+			if ( referencedFromElement != fromElement ) {
+				throw new InvalidWithClauseException( "with-clause expressions did not reference from-clause element to which the with-clause was associated" );
+			}
+			SqlGenerator sql = new SqlGenerator( getSessionFactoryHelper().getFactory() );
+			sql.whereExpr( hqlSqlWithNode.getFirstChild() );
+			fromElement.setWithClauseFragment( visitor.getJoinAlias(), "(" + sql.getSQL() + ")" );
+
+		}
+		catch( SemanticException e ) {
+			throw e;
+		}
+		catch( InvalidWithClauseException e ) {
+			throw e;
+		}
+		catch ( Exception e) {
+			throw new SemanticException( e.getMessage() );
+		}
+	}
+
+	private static class WithClauseVisitor implements NodeTraverser.VisitationStrategy {
+		private FromElement referencedFromElement;
+		private String joinAlias;
+
+		public void visit(AST node) {
+			// todo : currently expects that the individual with expressions apply to the same sql table join.
+			//      This may not be the case for joined-subclass where the property values
+			//      might be coming from different tables in the joined hierarchy.  At some
+			//      point we should expand this to support that capability.  However, that has
+			//      some difficulties:
+			//          1) the biggest is how to handle ORs when the individual comparisons are
+			//              linked to different sql joins.
+			//          2) here we would need to track each comparison individually, along with
+			//              the join alias to which it applies and then pass that information
+			//              back to the FromElement so it can pass it along to the JoinSequence
+
+			if ( node instanceof DotNode ) {
+				DotNode dotNode = ( DotNode ) node;
+				FromElement fromElement = dotNode.getFromElement();
+				if ( referencedFromElement != null ) {
+					if ( fromElement != referencedFromElement ) {
+						throw new HibernateException( "with-clause referenced two different from-clause elements" );
+					}
+				}
+				else {
+					referencedFromElement = fromElement;
+					joinAlias = extractAppliedAlias( dotNode );
+					// todo : temporary
+					//      needed because currently persister is the one that
+					//      creates and renders the join fragments for inheritence
+					//      hierarchies...
+					if ( !joinAlias.equals( referencedFromElement.getTableAlias() ) ) {
+						throw new InvalidWithClauseException( "with clause can only reference columns in the driving table" );
+					}
+				}
+			}
+		}
+
+		private String extractAppliedAlias(DotNode dotNode) {
+			return dotNode.getText().substring( 0, dotNode.getText().indexOf( '.' ) );
+		}
+
+		public FromElement getReferencedFromElement() {
+			return referencedFromElement;
+		}
+
+		public String getJoinAlias() {
+			return joinAlias;
+		}
+	}
+
+	/**
+	 * Sets the current 'FROM' context.
+	 *
+	 * @param fromNode      The new 'FROM' context.
+	 * @param inputFromNode The from node from the input AST.
+	 */
+	protected void pushFromClause(AST fromNode, AST inputFromNode) {
+		FromClause newFromClause = ( FromClause ) fromNode;
+		newFromClause.setParentFromClause( currentFromClause );
+		currentFromClause = newFromClause;
+	}
+
+	/**
+	 * Returns to the previous 'FROM' context.
+	 */
+	private void popFromClause() {
+		currentFromClause = currentFromClause.getParentFromClause();
+	}
+
+	protected void lookupAlias(AST aliasRef)
+			throws SemanticException {
+		FromElement alias = currentFromClause.getFromElement( aliasRef.getText() );
+		FromReferenceNode aliasRefNode = ( FromReferenceNode ) aliasRef;
+		aliasRefNode.setFromElement( alias );
+	}
+
+	protected void setImpliedJoinType(int joinType) {
+		impliedJoinType = JoinProcessor.toHibernateJoinType( joinType );
+	}
+
+	public int getImpliedJoinType() {
+		return impliedJoinType;
+	}
+
+	protected AST lookupProperty(AST dot, boolean root, boolean inSelect) throws SemanticException {
+		DotNode dotNode = ( DotNode ) dot;
+		FromReferenceNode lhs = dotNode.getLhs();
+		AST rhs = lhs.getNextSibling();
+		switch ( rhs.getType() ) {
+			case SqlTokenTypes.ELEMENTS:
+			case SqlTokenTypes.INDICES:
+				if ( log.isDebugEnabled() ) {
+					log.debug( "lookupProperty() " + dotNode.getPath() + " => " + rhs.getText() + "(" + lhs.getPath() + ")" );
+				}
+				CollectionFunction f = ( CollectionFunction ) rhs;
+				// Re-arrange the tree so that the collection function is the root and the lhs is the path.
+				f.setFirstChild( lhs );
+				lhs.setNextSibling( null );
+				dotNode.setFirstChild( f );
+				resolve( lhs );			// Don't forget to resolve the argument!
+				f.resolve( inSelect );	// Resolve the collection function now.
+				return f;
+			default:
+				// Resolve everything up to this dot, but don't resolve the placeholders yet.
+				dotNode.resolveFirstChild();
+				return dotNode;
+		}
+	}
+
+	protected boolean isNonQualifiedPropertyRef(AST ident) {
+		final String identText = ident.getText();
+		if ( currentFromClause.isFromElementAlias( identText ) ) {
+			return false;
+		}
+
+		List fromElements = currentFromClause.getExplicitFromElements();
+		if ( fromElements.size() == 1 ) {
+			final FromElement fromElement = ( FromElement ) fromElements.get( 0 );
+			try {
+				log.trace( "attempting to resolve property [" + identText + "] as a non-qualified ref" );
+				return fromElement.getPropertyMapping( identText ).toType( identText ) != null;
+			}
+			catch( QueryException e ) {
+				// Should mean that no such property was found
+			}
+		}
+
+		return false;
+	}
+
+	protected AST lookupNonQualifiedProperty(AST property) throws SemanticException {
+		final FromElement fromElement = ( FromElement ) currentFromClause.getExplicitFromElements().get( 0 );
+		AST syntheticDotNode = generateSyntheticDotNodeForNonQualifiedPropertyRef( property, fromElement );
+		return lookupProperty( syntheticDotNode, false, getCurrentClauseType() == HqlSqlTokenTypes.SELECT );
+	}
+
+	private AST generateSyntheticDotNodeForNonQualifiedPropertyRef(AST property, FromElement fromElement) {
+		AST dot = getASTFactory().create( DOT, "{non-qualified-property-ref}" );
+		// TODO : better way?!?
+		( ( DotNode ) dot ).setPropertyPath( ( ( FromReferenceNode ) property ).getPath() );
+
+		IdentNode syntheticAlias = ( IdentNode ) getASTFactory().create( IDENT, "{synthetic-alias}" );
+		syntheticAlias.setFromElement( fromElement );
+		syntheticAlias.setResolved();
+
+		dot.setFirstChild( syntheticAlias );
+		dot.addChild( property );
+
+		return dot;
+	}
+
+	protected void processQuery(AST select, AST query) throws SemanticException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "processQuery() : " + query.toStringTree() );
+		}
+
+		try {
+			QueryNode qn = ( QueryNode ) query;
+
+			// Was there an explicit select expression?
+			boolean explicitSelect = select != null && select.getNumberOfChildren() > 0;
+
+			if ( !explicitSelect ) {
+				// No explicit select expression; render the id and properties
+				// projection lists for every persister in the from clause into
+				// a single 'token node'.
+				//TODO: the only reason we need this stuff now is collection filters,
+				//      we should get rid of derived select clause completely!
+				createSelectClauseFromFromClause( qn );
+			}
+			else {
+				// Use the explicitly declared select expression; determine the
+				// return types indicated by each select token
+				useSelectClause( select );
+			}
+
+			// After that, process the JOINs.
+			// Invoke a delegate to do the work, as this is farily complex.
+			JoinProcessor joinProcessor = new JoinProcessor( astFactory, queryTranslatorImpl );
+			joinProcessor.processJoins( qn, isSubQuery() );
+
+			// Attach any mapping-defined "ORDER BY" fragments
+			Iterator itr = qn.getFromClause().getProjectionList().iterator();
+			while ( itr.hasNext() ) {
+				final FromElement fromElement = ( FromElement ) itr.next();
+//			if ( fromElement.isFetch() && fromElement.isCollectionJoin() ) {
+				if ( fromElement.isFetch() && fromElement.getQueryableCollection() != null ) {
+					// Does the collection referenced by this FromElement
+					// specify an order-by attribute?  If so, attach it to
+					// the query's order-by
+					if ( fromElement.getQueryableCollection().hasOrdering() ) {
+						String orderByFragment = fromElement
+								.getQueryableCollection()
+								.getSQLOrderByString( fromElement.getCollectionTableAlias() );
+						qn.getOrderByClause().addOrderFragment( orderByFragment );
+					}
+					if ( fromElement.getQueryableCollection().hasManyToManyOrdering() ) {
+						String orderByFragment = fromElement.getQueryableCollection()
+								.getManyToManyOrderByString( fromElement.getTableAlias() );
+						qn.getOrderByClause().addOrderFragment( orderByFragment );
+					}
+				}
+			}
+		}
+		finally {
+			popFromClause();
+		}
+	}
+
+	protected void postProcessDML(RestrictableStatement statement) throws SemanticException {
+		statement.getFromClause().resolve();
+
+		FromElement fromElement = ( FromElement ) statement.getFromClause().getFromElements().get( 0 );
+		Queryable persister = fromElement.getQueryable();
+		// Make #@%$^#^&# sure no alias is applied to the table name
+		fromElement.setText( persister.getTableName() );
+
+		// append any filter fragments; the EMPTY_MAP is used under the assumption that
+		// currently enabled filters should not affect this process
+		if ( persister.getDiscriminatorType() != null ) {
+			new SyntheticAndFactory( getASTFactory() ).addDiscriminatorWhereFragment(
+			        statement,
+			        persister,
+			        java.util.Collections.EMPTY_MAP,
+			        fromElement.getTableAlias()
+			);
+		}
+
+	}
+
+	protected void postProcessUpdate(AST update) throws SemanticException {
+		UpdateStatement updateStatement = ( UpdateStatement ) update;
+
+		postProcessDML( updateStatement );
+	}
+
+	protected void postProcessDelete(AST delete) throws SemanticException {
+		postProcessDML( ( DeleteStatement ) delete );
+	}
+
+	public static boolean supportsIdGenWithBulkInsertion(IdentifierGenerator generator) {
+		return SequenceGenerator.class.isAssignableFrom( generator.getClass() )
+		        || PostInsertIdentifierGenerator.class.isAssignableFrom( generator.getClass() );
+	}
+
+	protected void postProcessInsert(AST insert) throws SemanticException, QueryException {
+		InsertStatement insertStatement = ( InsertStatement ) insert;
+		insertStatement.validate();
+
+		SelectClause selectClause = insertStatement.getSelectClause();
+		Queryable persister = insertStatement.getIntoClause().getQueryable();
+
+		if ( !insertStatement.getIntoClause().isExplicitIdInsertion() ) {
+			// We need to generate ids as part of this bulk insert.
+			//
+			// Note that this is only supported for sequence-style generators and
+			// post-insert-style generators; basically, only in-db generators
+			IdentifierGenerator generator = persister.getIdentifierGenerator();
+			if ( !supportsIdGenWithBulkInsertion( generator ) ) {
+				throw new QueryException( "can only generate ids as part of bulk insert with either sequence or post-insert style generators" );
+			}
+
+			AST idSelectExprNode = null;
+
+			if ( SequenceGenerator.class.isAssignableFrom( generator.getClass() ) ) {
+				String seqName = ( String ) ( ( SequenceGenerator ) generator ).generatorKey();
+				String nextval = sessionFactoryHelper.getFactory().getDialect().getSelectSequenceNextValString( seqName );
+				idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, nextval );
+			}
+			else {
+				//Don't need this, because we should never ever be selecting no columns in an insert ... select...
+				//and because it causes a bug on DB2
+				/*String idInsertString = sessionFactoryHelper.getFactory().getDialect().getIdentityInsertString();
+				if ( idInsertString != null ) {
+					idSelectExprNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, idInsertString );
+				}*/
+			}
+
+			if ( idSelectExprNode != null ) {
+				AST currentFirstSelectExprNode = selectClause.getFirstChild();
+				selectClause.setFirstChild( idSelectExprNode );
+				idSelectExprNode.setNextSibling( currentFirstSelectExprNode );
+
+				insertStatement.getIntoClause().prependIdColumnSpec();
+			}
+		}
+
+		final boolean includeVersionProperty = persister.isVersioned() &&
+				!insertStatement.getIntoClause().isExplicitVersionInsertion() &&
+				persister.isVersionPropertyInsertable();
+		if ( includeVersionProperty ) {
+			// We need to seed the version value as part of this bulk insert
+			VersionType versionType = persister.getVersionType();
+			AST versionValueNode = null;
+
+			if ( sessionFactoryHelper.getFactory().getDialect().supportsParametersInInsertSelect() ) {
+				versionValueNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
+				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
+				( ( ParameterNode ) versionValueNode ).setHqlParameterSpecification( paramSpec );
+				parameters.add( 0, paramSpec );
+			}
+			else {
+				if ( isIntegral( versionType ) ) {
+					try {
+						Object seedValue = versionType.seed( null );
+						versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, seedValue.toString() );
+					}
+					catch( Throwable t ) {
+						throw new QueryException( "could not determine seed value for version on bulk insert [" + versionType + "]" );
+					}
+				}
+				else if ( isDatabaseGeneratedTimestamp( versionType ) ) {
+					String functionName = sessionFactoryHelper.getFactory().getDialect().getCurrentTimestampSQLFunctionName();
+					versionValueNode = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, functionName );
+				}
+				else {
+					throw new QueryException( "cannot handle version type [" + versionType + "] on bulk inserts with dialects not supporting parameters in insert-select statements" );
+				}
+			}
+
+			AST currentFirstSelectExprNode = selectClause.getFirstChild();
+			selectClause.setFirstChild( versionValueNode );
+			versionValueNode.setNextSibling( currentFirstSelectExprNode );
+
+			insertStatement.getIntoClause().prependVersionColumnSpec();
+		}
+
+		if ( insertStatement.getIntoClause().isDiscriminated() ) {
+			String sqlValue = insertStatement.getIntoClause().getQueryable().getDiscriminatorSQLValue();
+			AST discrimValue = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, sqlValue );
+			insertStatement.getSelectClause().addChild( discrimValue );
+		}
+
+	}
+
+	private boolean isDatabaseGeneratedTimestamp(Type type) {
+		// currently only the Hibernate-supplied DbTimestampType is supported here
+		return DbTimestampType.class.isAssignableFrom( type.getClass() );
+	}
+
+	private boolean isIntegral(Type type) {
+		return Long.class.isAssignableFrom( type.getReturnedClass() )
+		       || Integer.class.isAssignableFrom( type.getReturnedClass() )
+		       || long.class.isAssignableFrom( type.getReturnedClass() )
+		       || int.class.isAssignableFrom( type.getReturnedClass() );
+	}
+
+	private void useSelectClause(AST select) throws SemanticException {
+		selectClause = ( SelectClause ) select;
+		selectClause.initializeExplicitSelectClause( currentFromClause );
+	}
+
+	private void createSelectClauseFromFromClause(QueryNode qn) throws SemanticException {
+		AST select = astFactory.create( SELECT_CLAUSE, "{derived select clause}" );
+		AST sibling = qn.getFromClause();
+		qn.setFirstChild( select );
+		select.setNextSibling( sibling );
+		selectClause = ( SelectClause ) select;
+		selectClause.initializeDerivedSelectClause( currentFromClause );
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Derived SELECT clause created." );
+		}
+	}
+
+	protected void resolve(AST node) throws SemanticException {
+		if ( node != null ) {
+			// This is called when it's time to fully resolve a path expression.
+			ResolvableNode r = ( ResolvableNode ) node;
+			if ( isInFunctionCall() ) {
+				r.resolveInFunctionCall( false, true );
+			}
+			else {
+				r.resolve( false, true );	// Generate implicit joins, only if necessary.
+			}
+		}
+	}
+
+	protected void resolveSelectExpression(AST node) throws SemanticException {
+		// This is called when it's time to fully resolve a path expression.
+		int type = node.getType();
+		switch ( type ) {
+			case DOT:
+				DotNode dot = ( DotNode ) node;
+				dot.resolveSelectExpression();
+				break;
+			case ALIAS_REF:
+				// Notify the FROM element that it is being referenced by the select.
+				FromReferenceNode aliasRefNode = ( FromReferenceNode ) node;
+				//aliasRefNode.resolve( false, false, aliasRefNode.getText() ); //TODO: is it kosher to do it here?
+				aliasRefNode.resolve( false, false ); //TODO: is it kosher to do it here?
+				FromElement fromElement = aliasRefNode.getFromElement();
+				if ( fromElement != null ) {
+					fromElement.setIncludeSubclasses( true );
+				}
+			default:
+				break;
+		}
+	}
+
+	protected void beforeSelectClause() throws SemanticException {
+		// Turn off includeSubclasses on all FromElements.
+		FromClause from = getCurrentFromClause();
+		List fromElements = from.getFromElements();
+		for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) {
+			FromElement fromElement = ( FromElement ) iterator.next();
+			fromElement.setIncludeSubclasses( false );
+		}
+	}
+
+	protected AST generatePositionalParameter(AST inputNode) throws SemanticException {
+		if ( namedParameters.size() > 0 ) {
+			throw new SemanticException( "cannot define positional parameter after any named parameters have been defined" );
+		}
+		ParameterNode parameter = ( ParameterNode ) astFactory.create( PARAM, "?" );
+		PositionalParameterSpecification paramSpec = new PositionalParameterSpecification(
+				( ( Node ) inputNode ).getLine(),
+		        ( ( Node ) inputNode ).getColumn(),
+				positionalParameterCount++
+		);
+		parameter.setHqlParameterSpecification( paramSpec );
+		parameters.add( paramSpec );
+		return parameter;
+	}
+
+	protected AST generateNamedParameter(AST delimiterNode, AST nameNode) throws SemanticException {
+		String name = nameNode.getText();
+		trackNamedParameterPositions( name );
+
+		// create the node initially with the param name so that it shows
+		// appropriately in the "original text" attribute
+		ParameterNode parameter = ( ParameterNode ) astFactory.create( NAMED_PARAM, name );
+		parameter.setText( "?" );
+
+		NamedParameterSpecification paramSpec = new NamedParameterSpecification(
+				( ( Node ) delimiterNode ).getLine(),
+		        ( ( Node ) delimiterNode ).getColumn(),
+				name
+		);
+		parameter.setHqlParameterSpecification( paramSpec );
+		parameters.add( paramSpec );
+		return parameter;
+	}
+
+	private void trackNamedParameterPositions(String name) {
+		Integer loc = new Integer( parameterCount++ );
+		Object o = namedParameters.get( name );
+		if ( o == null ) {
+			namedParameters.put( name, loc );
+		}
+		else if ( o instanceof Integer ) {
+			ArrayList list = new ArrayList( 4 );
+			list.add( o );
+			list.add( loc );
+			namedParameters.put( name, list );
+		}
+		else {
+			( ( ArrayList ) o ).add( loc );
+		}
+	}
+
+	protected void processConstant(AST constant) throws SemanticException {
+		literalProcessor.processConstant( constant, true );  // Use the delegate, resolve identifiers as FROM element aliases.
+	}
+
+	protected void processBoolean(AST constant) throws SemanticException {
+		literalProcessor.processBoolean( constant );  // Use the delegate.
+	}
+
+	protected void processNumericLiteral(AST literal) {
+		literalProcessor.processNumeric( literal );
+	}
+
+	protected void processIndex(AST indexOp) throws SemanticException {
+		IndexNode indexNode = ( IndexNode ) indexOp;
+		indexNode.resolve( true, true );
+	}
+
+	protected void processFunction(AST functionCall, boolean inSelect) throws SemanticException {
+		MethodNode methodNode = ( MethodNode ) functionCall;
+		methodNode.resolve( inSelect );
+	}
+
+	protected void processConstructor(AST constructor) throws SemanticException {
+		ConstructorNode constructorNode = ( ConstructorNode ) constructor;
+		constructorNode.prepare();
+	}
+
+    protected void setAlias(AST selectExpr, AST ident) {
+        ((SelectExpression) selectExpr).setAlias(ident.getText());
+    }
+
+	/**
+	 * Returns the locations of all occurrences of the named parameter.
+	 */
+	public int[] getNamedParameterLocations(String name) throws QueryException {
+		Object o = namedParameters.get( name );
+		if ( o == null ) {
+			QueryException qe = new QueryException( QueryTranslator.ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name );
+			qe.setQueryString( queryTranslatorImpl.getQueryString() );
+			throw qe;
+		}
+		if ( o instanceof Integer ) {
+			return new int[]{( ( Integer ) o ).intValue()};
+		}
+		else {
+			return ArrayHelper.toIntArray( ( ArrayList ) o );
+		}
+	}
+
+	public void addQuerySpaces(Serializable[] spaces) {
+		for ( int i = 0; i < spaces.length; i++ ) {
+			querySpaces.add( spaces[i] );
+		}
+	}
+
+	public Type[] getReturnTypes() {
+		return selectClause.getQueryReturnTypes();
+	}
+
+	public String[] getReturnAliases() {
+		return selectClause.getQueryReturnAliases();
+	}
+
+	public SelectClause getSelectClause() {
+		return selectClause;
+	}
+	
+	public FromClause getFinalFromClause() {
+		FromClause top = currentFromClause;
+		while ( top.getParentFromClause() != null ) {
+			top = top.getParentFromClause();
+		}
+		return top;
+	}
+
+	public boolean isShallowQuery() {
+		// select clauses for insert statements should alwasy be treated as shallow
+		return getStatementType() == INSERT || queryTranslatorImpl.isShallowQuery();
+	}
+
+	public Map getEnabledFilters() {
+		return queryTranslatorImpl.getEnabledFilters();
+	}
+
+	public LiteralProcessor getLiteralProcessor() {
+		return literalProcessor;
+	}
+
+	public ASTPrinter getASTPrinter() {
+		return printer;
+	}
+
+	public ArrayList getParameters() {
+		return parameters;
+	}
+
+	public int getNumberOfParametersInSetClause() {
+		return numberOfParametersInSetClause;
+	}
+
+	protected void evaluateAssignment(AST eq) throws SemanticException {
+		prepareLogicOperator( eq );
+		Queryable persister = getCurrentFromClause().getFromElement().getQueryable();
+		evaluateAssignment( eq, persister, -1 );
+	}
+
+	private void evaluateAssignment(AST eq, Queryable persister, int targetIndex) {
+		if ( persister.isMultiTable() ) {
+			// no need to even collect this information if the persister is considered multi-table
+			AssignmentSpecification specification = new AssignmentSpecification( eq, persister );
+			if ( targetIndex >= 0 ) {
+				assignmentSpecifications.add( targetIndex, specification );
+			}
+			else {
+				assignmentSpecifications.add( specification );
+			}
+			numberOfParametersInSetClause += specification.getParameters().length;
+		}
+	}
+
+	public ArrayList getAssignmentSpecifications() {
+		return assignmentSpecifications;
+	}
+
+	protected AST createIntoClause(String path, AST propertySpec) throws SemanticException {
+		Queryable persister = ( Queryable ) getSessionFactoryHelper().requireClassPersister( path );
+
+		IntoClause intoClause = ( IntoClause ) getASTFactory().create( INTO, persister.getEntityName() );
+		intoClause.setFirstChild( propertySpec );
+		intoClause.initialize( persister );
+
+		addQuerySpaces( persister.getQuerySpaces() );
+
+		return intoClause;
+	}
+
+	protected void prepareVersioned(AST updateNode, AST versioned) throws SemanticException {
+		UpdateStatement updateStatement = ( UpdateStatement ) updateNode;
+		FromClause fromClause = updateStatement.getFromClause();
+		if ( versioned != null ) {
+			// Make sure that the persister is versioned
+			Queryable persister = fromClause.getFromElement().getQueryable();
+			if ( !persister.isVersioned() ) {
+				throw new SemanticException( "increment option specified for update of non-versioned entity" );
+			}
+
+			VersionType versionType = persister.getVersionType();
+			if ( versionType instanceof UserVersionType ) {
+				throw new SemanticException( "user-defined version types not supported for increment option" );
+			}
+
+			AST eq = getASTFactory().create( HqlSqlTokenTypes.EQ, "=" );
+			AST versionPropertyNode = generateVersionPropertyNode( persister );
+
+			eq.setFirstChild( versionPropertyNode );
+
+			AST versionIncrementNode = null;
+			if ( Date.class.isAssignableFrom( versionType.getReturnedClass() ) ) {
+				versionIncrementNode = getASTFactory().create( HqlSqlTokenTypes.PARAM, "?" );
+				ParameterSpecification paramSpec = new VersionTypeSeedParameterSpecification( versionType );
+				( ( ParameterNode ) versionIncrementNode ).setHqlParameterSpecification( paramSpec );
+				parameters.add( 0, paramSpec );
+			}
+			else {
+				// Not possible to simply re-use the versionPropertyNode here as it causes
+				// OOM errors due to circularity :(
+				versionIncrementNode = getASTFactory().create( HqlSqlTokenTypes.PLUS, "+" );
+				versionIncrementNode.setFirstChild( generateVersionPropertyNode( persister ) );
+				versionIncrementNode.addChild( getASTFactory().create( HqlSqlTokenTypes.IDENT, "1" ) );
+			}
+
+			eq.addChild( versionIncrementNode );
+
+			evaluateAssignment( eq, persister, 0 );
+
+			AST setClause = updateStatement.getSetClause();
+			AST currentFirstSetElement = setClause.getFirstChild();
+			setClause.setFirstChild( eq );
+			eq.setNextSibling( currentFirstSetElement );
+		}
+	}
+
+	private AST generateVersionPropertyNode(Queryable persister) throws SemanticException {
+		String versionPropertyName = persister.getPropertyNames()[ persister.getVersionProperty() ];
+		AST versionPropertyRef = getASTFactory().create( HqlSqlTokenTypes.IDENT, versionPropertyName );
+		AST versionPropertyNode = lookupNonQualifiedProperty( versionPropertyRef );
+		resolve( versionPropertyNode );
+		return versionPropertyNode;
+	}
+
+	protected void prepareLogicOperator(AST operator) throws SemanticException {
+		( ( OperatorNode ) operator ).initialize();
+	}
+
+	protected void prepareArithmeticOperator(AST operator) throws SemanticException {
+		( ( OperatorNode ) operator ).initialize();
+	}
+
+	public static void panic() {
+		throw new QueryException( "TreeWalker: panic" );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlToken.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-// $Id: HqlToken.java 4335 2004-08-15 17:03:43Z pgmjsd $
-package org.hibernate.hql.ast;
-
-/**
- * A custom token class for the HQL grammar.
- * <p><i>NOTE:<i> This class must be public becuase it is instantiated by the ANTLR library.  Ignore any suggestions
- * by various code 'analyzers' about this class being package local.</p>
- */
-public class HqlToken extends antlr.CommonToken {
-	/**
-	 * True if this token could be an identifier. *
-	 */
-	private boolean possibleID = false;
-	/**
-	 * The previous token type. *
-	 */
-	private int tokenType;
-
-	/**
-	 * Returns true if the token could be an identifier.
-	 *
-	 * @return True if the token could be interpreted as in identifier,
-	 *         false if not.
-	 */
-	public boolean isPossibleID() {
-		return possibleID;
-	}
-
-	/**
-	 * Sets the type of the token, remembering the previous type.
-	 *
-	 * @param t The new token type.
-	 */
-	public void setType(int t) {
-		this.tokenType = getType();
-		super.setType( t );
-	}
-
-	/**
-	 * Returns the previous token type.
-	 *
-	 * @return int - The old token type.
-	 */
-	private int getPreviousType() {
-		return tokenType;
-	}
-
-	/**
-	 * Set to true if this token can be interpreted as an identifier,
-	 * false if not.
-	 *
-	 * @param possibleID True if this is a keyword/identifier, false if not.
-	 */
-	public void setPossibleID(boolean possibleID) {
-		this.possibleID = possibleID;
-	}
-
-	/**
-	 * Returns a string representation of the object.
-	 *
-	 * @return String - The debug string.
-	 */
-	public String toString() {
-		return "[\""
-				+ getText()
-				+ "\",<" + getType() + "> previously: <" + getPreviousType() + ">,line="
-				+ line + ",col="
-				+ col + ",possibleID=" + possibleID + "]";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/HqlToken.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/HqlToken.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+/**
+ * A custom token class for the HQL grammar.
+ * <p><i>NOTE:<i> This class must be public becuase it is instantiated by the ANTLR library.  Ignore any suggestions
+ * by various code 'analyzers' about this class being package local.</p>
+ */
+public class HqlToken extends antlr.CommonToken {
+	/**
+	 * True if this token could be an identifier. *
+	 */
+	private boolean possibleID = false;
+	/**
+	 * The previous token type. *
+	 */
+	private int tokenType;
+
+	/**
+	 * Returns true if the token could be an identifier.
+	 *
+	 * @return True if the token could be interpreted as in identifier,
+	 *         false if not.
+	 */
+	public boolean isPossibleID() {
+		return possibleID;
+	}
+
+	/**
+	 * Sets the type of the token, remembering the previous type.
+	 *
+	 * @param t The new token type.
+	 */
+	public void setType(int t) {
+		this.tokenType = getType();
+		super.setType( t );
+	}
+
+	/**
+	 * Returns the previous token type.
+	 *
+	 * @return int - The old token type.
+	 */
+	private int getPreviousType() {
+		return tokenType;
+	}
+
+	/**
+	 * Set to true if this token can be interpreted as an identifier,
+	 * false if not.
+	 *
+	 * @param possibleID True if this is a keyword/identifier, false if not.
+	 */
+	public void setPossibleID(boolean possibleID) {
+		this.possibleID = possibleID;
+	}
+
+	/**
+	 * Returns a string representation of the object.
+	 *
+	 * @return String - The debug string.
+	 */
+	public String toString() {
+		return "[\""
+				+ getText()
+				+ "\",<" + getType() + "> previously: <" + getPreviousType() + ">,line="
+				+ line + ",col="
+				+ col + ",possibleID=" + possibleID + "]";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-// $Id: InvalidPathException.java 4903 2004-12-07 07:53:10Z pgmjsd $
-package org.hibernate.hql.ast;
-
-import antlr.SemanticException;
-
-/**
- * Exception thrown when an invalid path is found in a query.
- *
- * @author josh Dec 5, 2004 7:05:34 PM
- */
-public class InvalidPathException extends SemanticException {
-	public InvalidPathException(String s) {
-		super( s );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidPathException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast;
+
+import antlr.SemanticException;
+
+/**
+ * Exception thrown when an invalid path is found in a query.
+ *
+ * @author josh
+ */
+public class InvalidPathException extends SemanticException {
+	public InvalidPathException(String s) {
+		super( s );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-package org.hibernate.hql.ast;
-
-import org.hibernate.QueryException;
-
-/**
- * {@inheritDoc}
- *
- * @author Steve Ebersole
- */
-public class InvalidWithClauseException extends QuerySyntaxException {
-	public InvalidWithClauseException(String message) {
-		super( message );
-	}
-
-	public InvalidWithClauseException(String message, String queryString) {
-		super( message, queryString );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/InvalidWithClauseException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class InvalidWithClauseException extends QuerySyntaxException {
+	public InvalidWithClauseException(String message) {
+		super( message );
+	}
+
+	public InvalidWithClauseException(String message, String queryString) {
+		super( message, queryString );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,149 +0,0 @@
-package org.hibernate.hql.ast;
-
-import org.hibernate.hql.ParameterTranslations;
-import org.hibernate.type.Type;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.param.PositionalParameterSpecification;
-import org.hibernate.param.NamedParameterSpecification;
-import org.hibernate.util.ArrayHelper;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.io.Serializable;
-
-/**
- * Defines the information available for parameters encountered during
- * query translation through the antlr-based parser.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public class ParameterTranslationsImpl implements ParameterTranslations {
-
-	private final Map namedParameters;
-	private final ParameterInfo[] ordinalParameters;
-
-	public boolean supportsOrdinalParameterMetadata() {
-		return true;
-	}
-
-	public int getOrdinalParameterCount() {
-		return ordinalParameters.length;
-	}
-
-	public ParameterInfo getOrdinalParameterInfo(int ordinalPosition) {
-		// remember that ordinal parameters numbers are 1-based!!!
-		return ordinalParameters[ordinalPosition - 1];
-	}
-
-	public int getOrdinalParameterSqlLocation(int ordinalPosition) {
-		return getOrdinalParameterInfo( ordinalPosition ).getSqlLocations()[0];
-	}
-
-	public Type getOrdinalParameterExpectedType(int ordinalPosition) {
-		return getOrdinalParameterInfo( ordinalPosition ).getExpectedType();
-	}
-
-	public Set getNamedParameterNames() {
-		return namedParameters.keySet();
-	}
-
-	public ParameterInfo getNamedParameterInfo(String name) {
-		return ( ParameterInfo ) namedParameters.get( name );
-	}
-
-	public int[] getNamedParameterSqlLocations(String name) {
-		return getNamedParameterInfo( name ).getSqlLocations();
-	}
-
-	public Type getNamedParameterExpectedType(String name) {
-		return getNamedParameterInfo( name ).getExpectedType();
-	}
-
-	/**
-	 * Constructs a parameter metadata object given a list of parameter
-	 * specifications.
-	 * </p>
-	 * Note: the order in the incoming list denotes the parameter's
-	 * psudeo-position within the resulting sql statement.
-	 *
-	 * @param parameterSpecifications
-	 */
-	public ParameterTranslationsImpl(List parameterSpecifications) {
-
-		class NamedParamTempHolder {
-			String name;
-			Type type;
-			List positions = new ArrayList();
-		}
-
-		int size = parameterSpecifications.size();
-		List ordinalParameterList = new ArrayList();
-		Map namedParameterMap = new HashMap();
-		for ( int i = 0; i < size; i++ ) {
-			final ParameterSpecification spec = ( ParameterSpecification ) parameterSpecifications.get( i );
-			if ( PositionalParameterSpecification.class.isAssignableFrom( spec.getClass() ) ) {
-				PositionalParameterSpecification ordinalSpec = ( PositionalParameterSpecification ) spec;
-				ordinalParameterList.add( new ParameterInfo( i, ordinalSpec.getExpectedType() ) );
-			}
-			else if ( NamedParameterSpecification.class.isAssignableFrom( spec.getClass() ) ) {
-				NamedParameterSpecification namedSpec = ( NamedParameterSpecification ) spec;
-				NamedParamTempHolder paramHolder = ( NamedParamTempHolder ) namedParameterMap.get( namedSpec.getName() );
-				if ( paramHolder == null ) {
-					paramHolder = new NamedParamTempHolder();
-					paramHolder.name = namedSpec.getName();
-					paramHolder.type = namedSpec.getExpectedType();
-					namedParameterMap.put( namedSpec.getName(), paramHolder );
-				}
-				paramHolder.positions.add( new Integer( i ) );
-			}
-			else {
-				// don't care about other param types here, just those explicitly user-defined...
-			}
-		}
-
-		ordinalParameters = ( ParameterInfo[] ) ordinalParameterList.toArray( new ParameterInfo[ordinalParameterList.size()] );
-
-		if ( namedParameterMap.isEmpty() ) {
-			namedParameters = java.util.Collections.EMPTY_MAP;
-		}
-		else {
-			Map namedParametersBacking = new HashMap( namedParameterMap.size() );
-			Iterator itr = namedParameterMap.values().iterator();
-			while( itr.hasNext() ) {
-				final NamedParamTempHolder holder = ( NamedParamTempHolder ) itr.next();
-				namedParametersBacking.put(
-						holder.name,
-				        new ParameterInfo( ArrayHelper.toIntArray( holder.positions ), holder.type )
-				);
-			}
-			namedParameters = java.util.Collections.unmodifiableMap( namedParametersBacking );
-		}
-	}
-
-	public static class ParameterInfo implements Serializable {
-		private final int[] sqlLocations;
-		private final Type expectedType;
-
-		public ParameterInfo(int[] sqlPositions, Type expectedType) {
-			this.sqlLocations = sqlPositions;
-			this.expectedType = expectedType;
-		}
-
-		public ParameterInfo(int sqlPosition, Type expectedType) {
-			this.sqlLocations = new int[] { sqlPosition };
-			this.expectedType = expectedType;
-		}
-
-		public int[] getSqlLocations() {
-			return sqlLocations;
-		}
-
-		public Type getExpectedType() {
-			return expectedType;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParameterTranslationsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,173 @@
+/*
+ * 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;
+
+import org.hibernate.hql.ParameterTranslations;
+import org.hibernate.type.Type;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.param.PositionalParameterSpecification;
+import org.hibernate.param.NamedParameterSpecification;
+import org.hibernate.util.ArrayHelper;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.io.Serializable;
+
+/**
+ * Defines the information available for parameters encountered during
+ * query translation through the antlr-based parser.
+ *
+ * @author Steve Ebersole
+ */
+public class ParameterTranslationsImpl implements ParameterTranslations {
+
+	private final Map namedParameters;
+	private final ParameterInfo[] ordinalParameters;
+
+	public boolean supportsOrdinalParameterMetadata() {
+		return true;
+	}
+
+	public int getOrdinalParameterCount() {
+		return ordinalParameters.length;
+	}
+
+	public ParameterInfo getOrdinalParameterInfo(int ordinalPosition) {
+		// remember that ordinal parameters numbers are 1-based!!!
+		return ordinalParameters[ordinalPosition - 1];
+	}
+
+	public int getOrdinalParameterSqlLocation(int ordinalPosition) {
+		return getOrdinalParameterInfo( ordinalPosition ).getSqlLocations()[0];
+	}
+
+	public Type getOrdinalParameterExpectedType(int ordinalPosition) {
+		return getOrdinalParameterInfo( ordinalPosition ).getExpectedType();
+	}
+
+	public Set getNamedParameterNames() {
+		return namedParameters.keySet();
+	}
+
+	public ParameterInfo getNamedParameterInfo(String name) {
+		return ( ParameterInfo ) namedParameters.get( name );
+	}
+
+	public int[] getNamedParameterSqlLocations(String name) {
+		return getNamedParameterInfo( name ).getSqlLocations();
+	}
+
+	public Type getNamedParameterExpectedType(String name) {
+		return getNamedParameterInfo( name ).getExpectedType();
+	}
+
+	/**
+	 * Constructs a parameter metadata object given a list of parameter
+	 * specifications.
+	 * </p>
+	 * Note: the order in the incoming list denotes the parameter's
+	 * psudeo-position within the resulting sql statement.
+	 *
+	 * @param parameterSpecifications
+	 */
+	public ParameterTranslationsImpl(List parameterSpecifications) {
+
+		class NamedParamTempHolder {
+			String name;
+			Type type;
+			List positions = new ArrayList();
+		}
+
+		int size = parameterSpecifications.size();
+		List ordinalParameterList = new ArrayList();
+		Map namedParameterMap = new HashMap();
+		for ( int i = 0; i < size; i++ ) {
+			final ParameterSpecification spec = ( ParameterSpecification ) parameterSpecifications.get( i );
+			if ( PositionalParameterSpecification.class.isAssignableFrom( spec.getClass() ) ) {
+				PositionalParameterSpecification ordinalSpec = ( PositionalParameterSpecification ) spec;
+				ordinalParameterList.add( new ParameterInfo( i, ordinalSpec.getExpectedType() ) );
+			}
+			else if ( NamedParameterSpecification.class.isAssignableFrom( spec.getClass() ) ) {
+				NamedParameterSpecification namedSpec = ( NamedParameterSpecification ) spec;
+				NamedParamTempHolder paramHolder = ( NamedParamTempHolder ) namedParameterMap.get( namedSpec.getName() );
+				if ( paramHolder == null ) {
+					paramHolder = new NamedParamTempHolder();
+					paramHolder.name = namedSpec.getName();
+					paramHolder.type = namedSpec.getExpectedType();
+					namedParameterMap.put( namedSpec.getName(), paramHolder );
+				}
+				paramHolder.positions.add( new Integer( i ) );
+			}
+			else {
+				// don't care about other param types here, just those explicitly user-defined...
+			}
+		}
+
+		ordinalParameters = ( ParameterInfo[] ) ordinalParameterList.toArray( new ParameterInfo[ordinalParameterList.size()] );
+
+		if ( namedParameterMap.isEmpty() ) {
+			namedParameters = java.util.Collections.EMPTY_MAP;
+		}
+		else {
+			Map namedParametersBacking = new HashMap( namedParameterMap.size() );
+			Iterator itr = namedParameterMap.values().iterator();
+			while( itr.hasNext() ) {
+				final NamedParamTempHolder holder = ( NamedParamTempHolder ) itr.next();
+				namedParametersBacking.put(
+						holder.name,
+				        new ParameterInfo( ArrayHelper.toIntArray( holder.positions ), holder.type )
+				);
+			}
+			namedParameters = java.util.Collections.unmodifiableMap( namedParametersBacking );
+		}
+	}
+
+	public static class ParameterInfo implements Serializable {
+		private final int[] sqlLocations;
+		private final Type expectedType;
+
+		public ParameterInfo(int[] sqlPositions, Type expectedType) {
+			this.sqlLocations = sqlPositions;
+			this.expectedType = expectedType;
+		}
+
+		public ParameterInfo(int sqlPosition, Type expectedType) {
+			this.sqlLocations = new int[] { sqlPosition };
+			this.expectedType = expectedType;
+		}
+
+		public int[] getSqlLocations() {
+			return sqlLocations;
+		}
+
+		public Type getExpectedType() {
+			return expectedType;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-// $Id: ParseErrorHandler.java 4941 2004-12-11 16:31:18Z pgmjsd $
-
-package org.hibernate.hql.ast;
-
-import org.hibernate.QueryException;
-
-
-/**
- * Defines the behavior of an error handler for the HQL parsers.
- * User: josh
- * Date: Dec 6, 2003
- * Time: 12:20:43 PM
- */
-public interface ParseErrorHandler extends ErrorReporter {
-
-	int getErrorCount();
-
-	// --Commented out by Inspection (12/11/04 10:56 AM): int getWarningCount();
-
-	void throwQueryException() throws QueryException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/ParseErrorHandler.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+import org.hibernate.QueryException;
+
+
+/**
+ * Defines the behavior of an error handler for the HQL parsers.
+ * User: josh
+ * Date: Dec 6, 2003
+ * Time: 12:20:43 PM
+ */
+public interface ParseErrorHandler extends ErrorReporter {
+
+	int getErrorCount();
+
+	// --Commented out by Inspection (12/11/04 10:56 AM): int getWarningCount();
+
+	void throwQueryException() throws QueryException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-// $Id: QuerySyntaxException.java 9242 2006-02-09 12:37:36Z steveebersole $
-package org.hibernate.hql.ast;
-
-import antlr.RecognitionException;
-import org.hibernate.QueryException;
-
-/**
- * Exception thrown when there is a syntax error in the HQL.
- *
- * @author josh
- */
-public class QuerySyntaxException extends QueryException {
-
-	public QuerySyntaxException(String message) {
-		super( message );
-	}
-
-	public QuerySyntaxException(String message, String hql) {
-		this( message );
-		setQueryString( hql );
-	}
-
-	public static QuerySyntaxException convert(RecognitionException e) {
-		return convert( e, null );
-	}
-
-	public static QuerySyntaxException convert(RecognitionException e, String hql) {
-		String positionInfo = e.getLine() > 0 && e.getColumn() > 0
-				? " near line " + e.getLine() + ", column " + e.getColumn()
-				: "";
-		return new QuerySyntaxException( e.getMessage() + positionInfo, hql );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QuerySyntaxException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import antlr.RecognitionException;
+import org.hibernate.QueryException;
+
+/**
+ * Exception thrown when there is a syntax error in the HQL.
+ *
+ * @author josh
+ */
+public class QuerySyntaxException extends QueryException {
+
+	public QuerySyntaxException(String message) {
+		super( message );
+	}
+
+	public QuerySyntaxException(String message, String hql) {
+		this( message );
+		setQueryString( hql );
+	}
+
+	public static QuerySyntaxException convert(RecognitionException e) {
+		return convert( e, null );
+	}
+
+	public static QuerySyntaxException convert(RecognitionException e, String hql) {
+		String positionInfo = e.getLine() > 0 && e.getColumn() > 0
+				? " near line " + e.getLine() + ", column " + e.getColumn()
+				: "";
+		return new QuerySyntaxException( e.getMessage() + positionInfo, hql );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,577 +0,0 @@
-// $Id: QueryTranslatorImpl.java 10000 2006-06-08 21:04:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast;
-
-import antlr.ANTLRException;
-import antlr.RecognitionException;
-import antlr.TokenStreamException;
-import antlr.collections.AST;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.hql.FilterTranslator;
-import org.hibernate.hql.QueryExecutionRequestException;
-import org.hibernate.hql.ParameterTranslations;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.HqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.exec.BasicExecutor;
-import org.hibernate.hql.ast.exec.MultiTableDeleteExecutor;
-import org.hibernate.hql.ast.exec.MultiTableUpdateExecutor;
-import org.hibernate.hql.ast.exec.StatementExecutor;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.InsertStatement;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.hql.ast.tree.Statement;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.hql.ast.util.NodeTraverser;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.loader.hql.QueryLoader;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.Type;
-import org.hibernate.util.IdentitySet;
-import org.hibernate.util.StringHelper;
-import org.hibernate.util.ReflectHelper;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.ArrayList;
-
-/**
- * A QueryTranslator that uses an Antlr-based parser.
- *
- * @author Joshua Davis (pgmjsd at sourceforge.net)
- */
-public class QueryTranslatorImpl implements FilterTranslator {
-
-	private static final Logger log = LoggerFactory.getLogger( QueryTranslatorImpl.class );
-	private static final Logger AST_LOG = LoggerFactory.getLogger( "org.hibernate.hql.ast.AST" );
-
-	private SessionFactoryImplementor factory;
-
-	private final String queryIdentifier;
-	private String hql;
-	private boolean shallowQuery;
-	private Map tokenReplacements;
-
-	private Map enabledFilters; //TODO:this is only needed during compilation .. can we eliminate the instvar?
-
-	private boolean compiled;
-	private QueryLoader queryLoader;
-	private StatementExecutor statementExecutor;
-
-	private Statement sqlAst;
-	private String sql;
-
-	private ParameterTranslations paramTranslations;
-
-	/**
-	 * Creates a new AST-based query translator.
-	 *
-	 * @param queryIdentifier The query-identifier (used in stats collection)
-	 * @param query The hql query to translate
-	 * @param enabledFilters Currently enabled filters
-	 * @param factory The session factory constructing this translator instance.
-	 */
-	public QueryTranslatorImpl(
-			String queryIdentifier,
-	        String query,
-	        Map enabledFilters,
-	        SessionFactoryImplementor factory) {
-		this.queryIdentifier = queryIdentifier;
-		this.hql = query;
-		this.compiled = false;
-		this.shallowQuery = false;
-		this.enabledFilters = enabledFilters;
-		this.factory = factory;
-	}
-
-	/**
-	 * Compile a "normal" query. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 *
-	 * @param replacements Defined query substitutions.
-	 * @param shallow      Does this represent a shallow (scalar or entity-id) select?
-	 * @throws QueryException   There was a problem parsing the query string.
-	 * @throws MappingException There was a problem querying defined mappings.
-	 */
-	public void compile(
-	        Map replacements,
-	        boolean shallow) throws QueryException, MappingException {
-		doCompile( replacements, shallow, null );
-	}
-
-	/**
-	 * Compile a filter. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 *
-	 * @param collectionRole the role name of the collection used as the basis for the filter.
-	 * @param replacements   Defined query substitutions.
-	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
-	 * @throws QueryException   There was a problem parsing the query string.
-	 * @throws MappingException There was a problem querying defined mappings.
-	 */
-	public void compile(
-	        String collectionRole,
-	        Map replacements,
-	        boolean shallow) throws QueryException, MappingException {
-		doCompile( replacements, shallow, collectionRole );
-	}
-
-	/**
-	 * Performs both filter and non-filter compiling.
-	 *
-	 * @param replacements   Defined query substitutions.
-	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
-	 * @param collectionRole the role name of the collection used as the basis for the filter, NULL if this
-	 *                       is not a filter.
-	 */
-	private synchronized void doCompile(Map replacements, boolean shallow, String collectionRole) {
-		// If the query is already compiled, skip the compilation.
-		if ( compiled ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "compile() : The query is already compiled, skipping..." );
-			}
-			return;
-		}
-
-		// Remember the parameters for the compilation.
-		this.tokenReplacements = replacements;
-		if ( tokenReplacements == null ) {
-			tokenReplacements = new HashMap();
-		}
-		this.shallowQuery = shallow;
-
-		try {
-			// PHASE 1 : Parse the HQL into an AST.
-			HqlParser parser = parse( true );
-
-			// PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
-			HqlSqlWalker w = analyze( parser, collectionRole );
-
-			sqlAst = ( Statement ) w.getAST();
-
-			// at some point the generate phase needs to be moved out of here,
-			// because a single object-level DML might spawn multiple SQL DML
-			// command executions.
-			//
-			// Possible to just move the sql generation for dml stuff, but for
-			// consistency-sake probably best to just move responsiblity for
-			// the generation phase completely into the delegates
-			// (QueryLoader/StatementExecutor) themselves.  Also, not sure why
-			// QueryLoader currently even has a dependency on this at all; does
-			// it need it?  Ideally like to see the walker itself given to the delegates directly...
-
-			if ( sqlAst.needsExecutor() ) {
-				statementExecutor = buildAppropriateStatementExecutor( w );
-			}
-			else {
-				// PHASE 3 : Generate the SQL.
-				generate( ( QueryNode ) sqlAst );
-				queryLoader = new QueryLoader( this, factory, w.getSelectClause() );
-			}
-
-			compiled = true;
-		}
-		catch ( QueryException qe ) {
-			qe.setQueryString( hql );
-			throw qe;
-		}
-		catch ( RecognitionException e ) {
-			// we do not actually propogate ANTLRExceptions as a cause, so
-			// log it here for diagnostic purposes
-			if ( log.isTraceEnabled() ) {
-				log.trace( "converted antlr.RecognitionException", e );
-			}
-			throw QuerySyntaxException.convert( e, hql );
-		}
-		catch ( ANTLRException e ) {
-			// we do not actually propogate ANTLRExceptions as a cause, so
-			// log it here for diagnostic purposes
-			if ( log.isTraceEnabled() ) {
-				log.trace( "converted antlr.ANTLRException", e );
-			}
-			throw new QueryException( e.getMessage(), hql );
-		}
-
-		this.enabledFilters = null; //only needed during compilation phase...
-	}
-
-	private void generate(AST sqlAst) throws QueryException, RecognitionException {
-		if ( sql == null ) {
-			SqlGenerator gen = new SqlGenerator(factory);
-			gen.statement( sqlAst );
-			sql = gen.getSQL();
-			if ( log.isDebugEnabled() ) {
-				log.debug( "HQL: " + hql );
-				log.debug( "SQL: " + sql );
-			}
-			gen.getParseErrorHandler().throwQueryException();
-		}
-	}
-
-	private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
-		HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
-		AST hqlAst = parser.getAST();
-
-		// Transform the tree.
-		w.statement( hqlAst );
-
-		if ( AST_LOG.isDebugEnabled() ) {
-			ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class );
-			AST_LOG.debug( printer.showAsString( w.getAST(), "--- SQL AST ---" ) );
-		}
-
-		w.getParseErrorHandler().throwQueryException();
-
-		return w;
-	}
-
-	private HqlParser parse(boolean filter) throws TokenStreamException, RecognitionException {
-		// Parse the query string into an HQL AST.
-		HqlParser parser = HqlParser.getInstance( hql );
-		parser.setFilter( filter );
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "parse() - HQL: " + hql );
-		}
-		parser.statement();
-
-		AST hqlAst = parser.getAST();
-
-		JavaConstantConverter converter = new JavaConstantConverter();
-		NodeTraverser walker = new NodeTraverser( converter );
-		walker.traverseDepthFirst( hqlAst );
-
-		showHqlAst( hqlAst );
-
-		parser.getParseErrorHandler().throwQueryException();
-		return parser;
-	}
-
-	void showHqlAst(AST hqlAst) {
-		if ( AST_LOG.isDebugEnabled() ) {
-			ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
-			printer.setShowClassNames( false ); // The class names aren't interesting in the first tree.
-			AST_LOG.debug( printer.showAsString( hqlAst, "--- HQL AST ---" ) );
-		}
-	}
-
-	private void errorIfDML() throws HibernateException {
-		if ( sqlAst.needsExecutor() ) {
-			throw new QueryExecutionRequestException( "Not supported for DML operations", hql );
-		}
-	}
-
-	private void errorIfSelect() throws HibernateException {
-		if ( !sqlAst.needsExecutor() ) {
-			throw new QueryExecutionRequestException( "Not supported for select queries", hql );
-		}
-	}
-
-	public String getQueryIdentifier() {
-		return queryIdentifier;
-	}
-
-	public Statement getSqlAST() {
-		return sqlAst;
-	}
-
-	private HqlSqlWalker getWalker() {
-		return sqlAst.getWalker();
-	}
-
-	/**
-	 * Types of the return values of an <tt>iterate()</tt> style query.
-	 *
-	 * @return an array of <tt>Type</tt>s.
-	 */
-	public Type[] getReturnTypes() {
-		errorIfDML();
-		return getWalker().getReturnTypes();
-	}
-
-	public String[] getReturnAliases() {
-		errorIfDML();
-		return getWalker().getReturnAliases();
-	}
-
-	public String[][] getColumnNames() {
-		errorIfDML();
-		return getWalker().getSelectClause().getColumnNames();
-	}
-
-	public Set getQuerySpaces() {
-		return getWalker().getQuerySpaces();
-	}
-
-	public List list(SessionImplementor session, QueryParameters queryParameters)
-			throws HibernateException {
-		// Delegate to the QueryLoader...
-		errorIfDML();
-		QueryNode query = ( QueryNode ) sqlAst;
-		boolean hasLimit = queryParameters.getRowSelection() != null && queryParameters.getRowSelection().definesLimits();
-		boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) && containsCollectionFetches();
-
-		QueryParameters queryParametersToUse;
-		if ( hasLimit && containsCollectionFetches() ) {
-			log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );
-			RowSelection selection = new RowSelection();
-			selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
-			selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
-			queryParametersToUse = queryParameters.createCopyUsing( selection );
-		}
-		else {
-			queryParametersToUse = queryParameters;
-		}
-
-		List results = queryLoader.list( session, queryParametersToUse );
-
-		if ( needsDistincting ) {
-			int includedCount = -1;
-			// NOTE : firstRow is zero-based
-			int first = !hasLimit || queryParameters.getRowSelection().getFirstRow() == null
-						? 0
-						: queryParameters.getRowSelection().getFirstRow().intValue();
-			int max = !hasLimit || queryParameters.getRowSelection().getMaxRows() == null
-						? -1
-						: queryParameters.getRowSelection().getMaxRows().intValue();
-			int size = results.size();
-			List tmp = new ArrayList();
-			IdentitySet distinction = new IdentitySet();
-			for ( int i = 0; i < size; i++ ) {
-				final Object result = results.get( i );
-				if ( !distinction.add( result ) ) {
-					continue;
-				}
-				includedCount++;
-				if ( includedCount < first ) {
-					continue;
-				}
-				tmp.add( result );
-				// NOTE : ( max - 1 ) because first is zero-based while max is not...
-				if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) {
-					break;
-				}
-			}
-			results = tmp;
-		}
-
-		return results;
-	}
-
-	/**
-	 * Return the query results as an iterator
-	 */
-	public Iterator iterate(QueryParameters queryParameters, EventSource session)
-			throws HibernateException {
-		// Delegate to the QueryLoader...
-		errorIfDML();
-		return queryLoader.iterate( queryParameters, session );
-	}
-
-	/**
-	 * Return the query results, as an instance of <tt>ScrollableResults</tt>
-	 */
-	public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session)
-			throws HibernateException {
-		// Delegate to the QueryLoader...
-		errorIfDML();
-		return queryLoader.scroll( queryParameters, session );
-	}
-
-	public int executeUpdate(QueryParameters queryParameters, SessionImplementor session)
-			throws HibernateException {
-		errorIfSelect();
-		return statementExecutor.execute( queryParameters, session );
-	}
-
-	/**
-	 * The SQL query string to be called; implemented by all subclasses
-	 */
-	public String getSQLString() {
-		return sql;
-	}
-
-	public List collectSqlStrings() {
-		ArrayList list = new ArrayList();
-		if ( isManipulationStatement() ) {
-			String[] sqlStatements = statementExecutor.getSqlStatements();
-			for ( int i = 0; i < sqlStatements.length; i++ ) {
-				list.add( sqlStatements[i] );
-			}
-		}
-		else {
-			list.add( sql );
-		}
-		return list;
-	}
-
-	// -- Package local methods for the QueryLoader delegate --
-
-	public boolean isShallowQuery() {
-		return shallowQuery;
-	}
-
-	public String getQueryString() {
-		return hql;
-	}
-
-	public Map getEnabledFilters() {
-		return enabledFilters;
-	}
-
-	public int[] getNamedParameterLocs(String name) {
-		return getWalker().getNamedParameterLocations( name );
-	}
-
-	public boolean containsCollectionFetches() {
-		errorIfDML();
-		List collectionFetches = ( ( QueryNode ) sqlAst ).getFromClause().getCollectionFetches();
-		return collectionFetches != null && collectionFetches.size() > 0;
-	}
-
-	public boolean isManipulationStatement() {
-		return sqlAst.needsExecutor();
-	}
-
-	public void validateScrollability() throws HibernateException {
-		// Impl Note: allows multiple collection fetches as long as the
-		// entire fecthed graph still "points back" to a single
-		// root entity for return
-
-		errorIfDML();
-
-		QueryNode query = ( QueryNode ) sqlAst;
-
-		// If there are no collection fetches, then no further checks are needed
-		List collectionFetches = query.getFromClause().getCollectionFetches();
-		if ( collectionFetches.isEmpty() ) {
-			return;
-		}
-
-		// A shallow query is ok (although technically there should be no fetching here...)
-		if ( isShallowQuery() ) {
-			return;
-		}
-
-		// Otherwise, we have a non-scalar select with defined collection fetch(es).
-		// Make sure that there is only a single root entity in the return (no tuples)
-		if ( getReturnTypes().length > 1 ) {
-			throw new HibernateException( "cannot scroll with collection fetches and returned tuples" );
-		}
-
-		FromElement owner = null;
-		Iterator itr = query.getSelectClause().getFromElementsForLoad().iterator();
-		while ( itr.hasNext() ) {
-			// should be the first, but just to be safe...
-			final FromElement fromElement = ( FromElement ) itr.next();
-			if ( fromElement.getOrigin() == null ) {
-				owner = fromElement;
-				break;
-			}
-		}
-
-		if ( owner == null ) {
-			throw new HibernateException( "unable to locate collection fetch(es) owner for scrollability checks" );
-		}
-
-		// This is not strictly true.  We actually just need to make sure that
-		// it is ordered by root-entity PK and that that order-by comes before
-		// any non-root-entity ordering...
-
-		AST primaryOrdering = query.getOrderByClause().getFirstChild();
-		if ( primaryOrdering != null ) {
-			// TODO : this is a bit dodgy, come up with a better way to check this (plus see above comment)
-			String [] idColNames = owner.getQueryable().getIdentifierColumnNames();
-			String expectedPrimaryOrderSeq = StringHelper.join(
-			        ", ",
-			        StringHelper.qualify( owner.getTableAlias(), idColNames )
-			);
-			if (  !primaryOrdering.getText().startsWith( expectedPrimaryOrderSeq ) ) {
-				throw new HibernateException( "cannot scroll results with collection fetches which are not ordered primarily by the root entity's PK" );
-			}
-		}
-	}
-
-	private StatementExecutor buildAppropriateStatementExecutor(HqlSqlWalker walker) {
-		Statement statement = ( Statement ) walker.getAST();
-		if ( walker.getStatementType() == HqlSqlTokenTypes.DELETE ) {
-			FromElement fromElement = walker.getFinalFromClause().getFromElement();
-			Queryable persister = fromElement.getQueryable();
-			if ( persister.isMultiTable() ) {
-				return new MultiTableDeleteExecutor( walker );
-			}
-			else {
-				return new BasicExecutor( walker, persister );
-			}
-		}
-		else if ( walker.getStatementType() == HqlSqlTokenTypes.UPDATE ) {
-			FromElement fromElement = walker.getFinalFromClause().getFromElement();
-			Queryable persister = fromElement.getQueryable();
-			if ( persister.isMultiTable() ) {
-				// even here, if only properties mapped to the "base table" are referenced
-				// in the set and where clauses, this could be handled by the BasicDelegate.
-				// TODO : decide if it is better performance-wise to perform that check, or to simply use the MultiTableUpdateDelegate
-				return new MultiTableUpdateExecutor( walker );
-			}
-			else {
-				return new BasicExecutor( walker, persister );
-			}
-		}
-		else if ( walker.getStatementType() == HqlSqlTokenTypes.INSERT ) {
-			return new BasicExecutor( walker, ( ( InsertStatement ) statement ).getIntoClause().getQueryable() );
-		}
-		else {
-			throw new QueryException( "Unexpected statement type" );
-		}
-	}
-
-	public ParameterTranslations getParameterTranslations() {
-		if ( paramTranslations == null ) {
-			paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() );
-		}
-		return paramTranslations;
-	}
-
-	public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
-		private AST dotRoot;
-		public void visit(AST node) {
-			if ( dotRoot != null ) {
-				// we are already processing a dot-structure
-				if ( ASTUtil.isSubtreeChild( dotRoot, node ) ) {
-					// igndore it...
-					return;
-				}
-				else {
-					// we are now at a new tree level
-					dotRoot = null;
-				}
-			}
-
-			if ( dotRoot == null && node.getType() == HqlTokenTypes.DOT ) {
-				dotRoot = node;
-				handleDotStructure( dotRoot );
-			}
-		}
-		private void handleDotStructure(AST dotStructureRoot) {
-			String expression = ASTUtil.getPathText( dotStructureRoot );
-			Object constant = ReflectHelper.getConstantValue( expression );
-			if ( constant != null ) {
-				dotStructureRoot.setFirstChild( null );
-				dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT );
-				dotStructureRoot.setText( expression );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/QueryTranslatorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,600 @@
+/*
+ * 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;
+
+import antlr.ANTLRException;
+import antlr.RecognitionException;
+import antlr.TokenStreamException;
+import antlr.collections.AST;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.hql.FilterTranslator;
+import org.hibernate.hql.QueryExecutionRequestException;
+import org.hibernate.hql.ParameterTranslations;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.HqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.exec.BasicExecutor;
+import org.hibernate.hql.ast.exec.MultiTableDeleteExecutor;
+import org.hibernate.hql.ast.exec.MultiTableUpdateExecutor;
+import org.hibernate.hql.ast.exec.StatementExecutor;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.InsertStatement;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.hql.ast.tree.Statement;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.hql.ast.util.NodeTraverser;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.loader.hql.QueryLoader;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.Type;
+import org.hibernate.util.IdentitySet;
+import org.hibernate.util.StringHelper;
+import org.hibernate.util.ReflectHelper;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.ArrayList;
+
+/**
+ * A QueryTranslator that uses an Antlr-based parser.
+ *
+ * @author Joshua Davis (pgmjsd at sourceforge.net)
+ */
+public class QueryTranslatorImpl implements FilterTranslator {
+
+	private static final Logger log = LoggerFactory.getLogger( QueryTranslatorImpl.class );
+	private static final Logger AST_LOG = LoggerFactory.getLogger( "org.hibernate.hql.ast.AST" );
+
+	private SessionFactoryImplementor factory;
+
+	private final String queryIdentifier;
+	private String hql;
+	private boolean shallowQuery;
+	private Map tokenReplacements;
+
+	private Map enabledFilters; //TODO:this is only needed during compilation .. can we eliminate the instvar?
+
+	private boolean compiled;
+	private QueryLoader queryLoader;
+	private StatementExecutor statementExecutor;
+
+	private Statement sqlAst;
+	private String sql;
+
+	private ParameterTranslations paramTranslations;
+
+	/**
+	 * Creates a new AST-based query translator.
+	 *
+	 * @param queryIdentifier The query-identifier (used in stats collection)
+	 * @param query The hql query to translate
+	 * @param enabledFilters Currently enabled filters
+	 * @param factory The session factory constructing this translator instance.
+	 */
+	public QueryTranslatorImpl(
+			String queryIdentifier,
+	        String query,
+	        Map enabledFilters,
+	        SessionFactoryImplementor factory) {
+		this.queryIdentifier = queryIdentifier;
+		this.hql = query;
+		this.compiled = false;
+		this.shallowQuery = false;
+		this.enabledFilters = enabledFilters;
+		this.factory = factory;
+	}
+
+	/**
+	 * Compile a "normal" query. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 *
+	 * @param replacements Defined query substitutions.
+	 * @param shallow      Does this represent a shallow (scalar or entity-id) select?
+	 * @throws QueryException   There was a problem parsing the query string.
+	 * @throws MappingException There was a problem querying defined mappings.
+	 */
+	public void compile(
+	        Map replacements,
+	        boolean shallow) throws QueryException, MappingException {
+		doCompile( replacements, shallow, null );
+	}
+
+	/**
+	 * Compile a filter. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 *
+	 * @param collectionRole the role name of the collection used as the basis for the filter.
+	 * @param replacements   Defined query substitutions.
+	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
+	 * @throws QueryException   There was a problem parsing the query string.
+	 * @throws MappingException There was a problem querying defined mappings.
+	 */
+	public void compile(
+	        String collectionRole,
+	        Map replacements,
+	        boolean shallow) throws QueryException, MappingException {
+		doCompile( replacements, shallow, collectionRole );
+	}
+
+	/**
+	 * Performs both filter and non-filter compiling.
+	 *
+	 * @param replacements   Defined query substitutions.
+	 * @param shallow        Does this represent a shallow (scalar or entity-id) select?
+	 * @param collectionRole the role name of the collection used as the basis for the filter, NULL if this
+	 *                       is not a filter.
+	 */
+	private synchronized void doCompile(Map replacements, boolean shallow, String collectionRole) {
+		// If the query is already compiled, skip the compilation.
+		if ( compiled ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "compile() : The query is already compiled, skipping..." );
+			}
+			return;
+		}
+
+		// Remember the parameters for the compilation.
+		this.tokenReplacements = replacements;
+		if ( tokenReplacements == null ) {
+			tokenReplacements = new HashMap();
+		}
+		this.shallowQuery = shallow;
+
+		try {
+			// PHASE 1 : Parse the HQL into an AST.
+			HqlParser parser = parse( true );
+
+			// PHASE 2 : Analyze the HQL AST, and produce an SQL AST.
+			HqlSqlWalker w = analyze( parser, collectionRole );
+
+			sqlAst = ( Statement ) w.getAST();
+
+			// at some point the generate phase needs to be moved out of here,
+			// because a single object-level DML might spawn multiple SQL DML
+			// command executions.
+			//
+			// Possible to just move the sql generation for dml stuff, but for
+			// consistency-sake probably best to just move responsiblity for
+			// the generation phase completely into the delegates
+			// (QueryLoader/StatementExecutor) themselves.  Also, not sure why
+			// QueryLoader currently even has a dependency on this at all; does
+			// it need it?  Ideally like to see the walker itself given to the delegates directly...
+
+			if ( sqlAst.needsExecutor() ) {
+				statementExecutor = buildAppropriateStatementExecutor( w );
+			}
+			else {
+				// PHASE 3 : Generate the SQL.
+				generate( ( QueryNode ) sqlAst );
+				queryLoader = new QueryLoader( this, factory, w.getSelectClause() );
+			}
+
+			compiled = true;
+		}
+		catch ( QueryException qe ) {
+			qe.setQueryString( hql );
+			throw qe;
+		}
+		catch ( RecognitionException e ) {
+			// we do not actually propogate ANTLRExceptions as a cause, so
+			// log it here for diagnostic purposes
+			if ( log.isTraceEnabled() ) {
+				log.trace( "converted antlr.RecognitionException", e );
+			}
+			throw QuerySyntaxException.convert( e, hql );
+		}
+		catch ( ANTLRException e ) {
+			// we do not actually propogate ANTLRExceptions as a cause, so
+			// log it here for diagnostic purposes
+			if ( log.isTraceEnabled() ) {
+				log.trace( "converted antlr.ANTLRException", e );
+			}
+			throw new QueryException( e.getMessage(), hql );
+		}
+
+		this.enabledFilters = null; //only needed during compilation phase...
+	}
+
+	private void generate(AST sqlAst) throws QueryException, RecognitionException {
+		if ( sql == null ) {
+			SqlGenerator gen = new SqlGenerator(factory);
+			gen.statement( sqlAst );
+			sql = gen.getSQL();
+			if ( log.isDebugEnabled() ) {
+				log.debug( "HQL: " + hql );
+				log.debug( "SQL: " + sql );
+			}
+			gen.getParseErrorHandler().throwQueryException();
+		}
+	}
+
+	private HqlSqlWalker analyze(HqlParser parser, String collectionRole) throws QueryException, RecognitionException {
+		HqlSqlWalker w = new HqlSqlWalker( this, factory, parser, tokenReplacements, collectionRole );
+		AST hqlAst = parser.getAST();
+
+		// Transform the tree.
+		w.statement( hqlAst );
+
+		if ( AST_LOG.isDebugEnabled() ) {
+			ASTPrinter printer = new ASTPrinter( SqlTokenTypes.class );
+			AST_LOG.debug( printer.showAsString( w.getAST(), "--- SQL AST ---" ) );
+		}
+
+		w.getParseErrorHandler().throwQueryException();
+
+		return w;
+	}
+
+	private HqlParser parse(boolean filter) throws TokenStreamException, RecognitionException {
+		// Parse the query string into an HQL AST.
+		HqlParser parser = HqlParser.getInstance( hql );
+		parser.setFilter( filter );
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "parse() - HQL: " + hql );
+		}
+		parser.statement();
+
+		AST hqlAst = parser.getAST();
+
+		JavaConstantConverter converter = new JavaConstantConverter();
+		NodeTraverser walker = new NodeTraverser( converter );
+		walker.traverseDepthFirst( hqlAst );
+
+		showHqlAst( hqlAst );
+
+		parser.getParseErrorHandler().throwQueryException();
+		return parser;
+	}
+
+	void showHqlAst(AST hqlAst) {
+		if ( AST_LOG.isDebugEnabled() ) {
+			ASTPrinter printer = new ASTPrinter( HqlTokenTypes.class );
+			printer.setShowClassNames( false ); // The class names aren't interesting in the first tree.
+			AST_LOG.debug( printer.showAsString( hqlAst, "--- HQL AST ---" ) );
+		}
+	}
+
+	private void errorIfDML() throws HibernateException {
+		if ( sqlAst.needsExecutor() ) {
+			throw new QueryExecutionRequestException( "Not supported for DML operations", hql );
+		}
+	}
+
+	private void errorIfSelect() throws HibernateException {
+		if ( !sqlAst.needsExecutor() ) {
+			throw new QueryExecutionRequestException( "Not supported for select queries", hql );
+		}
+	}
+
+	public String getQueryIdentifier() {
+		return queryIdentifier;
+	}
+
+	public Statement getSqlAST() {
+		return sqlAst;
+	}
+
+	private HqlSqlWalker getWalker() {
+		return sqlAst.getWalker();
+	}
+
+	/**
+	 * Types of the return values of an <tt>iterate()</tt> style query.
+	 *
+	 * @return an array of <tt>Type</tt>s.
+	 */
+	public Type[] getReturnTypes() {
+		errorIfDML();
+		return getWalker().getReturnTypes();
+	}
+
+	public String[] getReturnAliases() {
+		errorIfDML();
+		return getWalker().getReturnAliases();
+	}
+
+	public String[][] getColumnNames() {
+		errorIfDML();
+		return getWalker().getSelectClause().getColumnNames();
+	}
+
+	public Set getQuerySpaces() {
+		return getWalker().getQuerySpaces();
+	}
+
+	public List list(SessionImplementor session, QueryParameters queryParameters)
+			throws HibernateException {
+		// Delegate to the QueryLoader...
+		errorIfDML();
+		QueryNode query = ( QueryNode ) sqlAst;
+		boolean hasLimit = queryParameters.getRowSelection() != null && queryParameters.getRowSelection().definesLimits();
+		boolean needsDistincting = ( query.getSelectClause().isDistinct() || hasLimit ) && containsCollectionFetches();
+
+		QueryParameters queryParametersToUse;
+		if ( hasLimit && containsCollectionFetches() ) {
+			log.warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );
+			RowSelection selection = new RowSelection();
+			selection.setFetchSize( queryParameters.getRowSelection().getFetchSize() );
+			selection.setTimeout( queryParameters.getRowSelection().getTimeout() );
+			queryParametersToUse = queryParameters.createCopyUsing( selection );
+		}
+		else {
+			queryParametersToUse = queryParameters;
+		}
+
+		List results = queryLoader.list( session, queryParametersToUse );
+
+		if ( needsDistincting ) {
+			int includedCount = -1;
+			// NOTE : firstRow is zero-based
+			int first = !hasLimit || queryParameters.getRowSelection().getFirstRow() == null
+						? 0
+						: queryParameters.getRowSelection().getFirstRow().intValue();
+			int max = !hasLimit || queryParameters.getRowSelection().getMaxRows() == null
+						? -1
+						: queryParameters.getRowSelection().getMaxRows().intValue();
+			int size = results.size();
+			List tmp = new ArrayList();
+			IdentitySet distinction = new IdentitySet();
+			for ( int i = 0; i < size; i++ ) {
+				final Object result = results.get( i );
+				if ( !distinction.add( result ) ) {
+					continue;
+				}
+				includedCount++;
+				if ( includedCount < first ) {
+					continue;
+				}
+				tmp.add( result );
+				// NOTE : ( max - 1 ) because first is zero-based while max is not...
+				if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) {
+					break;
+				}
+			}
+			results = tmp;
+		}
+
+		return results;
+	}
+
+	/**
+	 * Return the query results as an iterator
+	 */
+	public Iterator iterate(QueryParameters queryParameters, EventSource session)
+			throws HibernateException {
+		// Delegate to the QueryLoader...
+		errorIfDML();
+		return queryLoader.iterate( queryParameters, session );
+	}
+
+	/**
+	 * Return the query results, as an instance of <tt>ScrollableResults</tt>
+	 */
+	public ScrollableResults scroll(QueryParameters queryParameters, SessionImplementor session)
+			throws HibernateException {
+		// Delegate to the QueryLoader...
+		errorIfDML();
+		return queryLoader.scroll( queryParameters, session );
+	}
+
+	public int executeUpdate(QueryParameters queryParameters, SessionImplementor session)
+			throws HibernateException {
+		errorIfSelect();
+		return statementExecutor.execute( queryParameters, session );
+	}
+
+	/**
+	 * The SQL query string to be called; implemented by all subclasses
+	 */
+	public String getSQLString() {
+		return sql;
+	}
+
+	public List collectSqlStrings() {
+		ArrayList list = new ArrayList();
+		if ( isManipulationStatement() ) {
+			String[] sqlStatements = statementExecutor.getSqlStatements();
+			for ( int i = 0; i < sqlStatements.length; i++ ) {
+				list.add( sqlStatements[i] );
+			}
+		}
+		else {
+			list.add( sql );
+		}
+		return list;
+	}
+
+	// -- Package local methods for the QueryLoader delegate --
+
+	public boolean isShallowQuery() {
+		return shallowQuery;
+	}
+
+	public String getQueryString() {
+		return hql;
+	}
+
+	public Map getEnabledFilters() {
+		return enabledFilters;
+	}
+
+	public int[] getNamedParameterLocs(String name) {
+		return getWalker().getNamedParameterLocations( name );
+	}
+
+	public boolean containsCollectionFetches() {
+		errorIfDML();
+		List collectionFetches = ( ( QueryNode ) sqlAst ).getFromClause().getCollectionFetches();
+		return collectionFetches != null && collectionFetches.size() > 0;
+	}
+
+	public boolean isManipulationStatement() {
+		return sqlAst.needsExecutor();
+	}
+
+	public void validateScrollability() throws HibernateException {
+		// Impl Note: allows multiple collection fetches as long as the
+		// entire fecthed graph still "points back" to a single
+		// root entity for return
+
+		errorIfDML();
+
+		QueryNode query = ( QueryNode ) sqlAst;
+
+		// If there are no collection fetches, then no further checks are needed
+		List collectionFetches = query.getFromClause().getCollectionFetches();
+		if ( collectionFetches.isEmpty() ) {
+			return;
+		}
+
+		// A shallow query is ok (although technically there should be no fetching here...)
+		if ( isShallowQuery() ) {
+			return;
+		}
+
+		// Otherwise, we have a non-scalar select with defined collection fetch(es).
+		// Make sure that there is only a single root entity in the return (no tuples)
+		if ( getReturnTypes().length > 1 ) {
+			throw new HibernateException( "cannot scroll with collection fetches and returned tuples" );
+		}
+
+		FromElement owner = null;
+		Iterator itr = query.getSelectClause().getFromElementsForLoad().iterator();
+		while ( itr.hasNext() ) {
+			// should be the first, but just to be safe...
+			final FromElement fromElement = ( FromElement ) itr.next();
+			if ( fromElement.getOrigin() == null ) {
+				owner = fromElement;
+				break;
+			}
+		}
+
+		if ( owner == null ) {
+			throw new HibernateException( "unable to locate collection fetch(es) owner for scrollability checks" );
+		}
+
+		// This is not strictly true.  We actually just need to make sure that
+		// it is ordered by root-entity PK and that that order-by comes before
+		// any non-root-entity ordering...
+
+		AST primaryOrdering = query.getOrderByClause().getFirstChild();
+		if ( primaryOrdering != null ) {
+			// TODO : this is a bit dodgy, come up with a better way to check this (plus see above comment)
+			String [] idColNames = owner.getQueryable().getIdentifierColumnNames();
+			String expectedPrimaryOrderSeq = StringHelper.join(
+			        ", ",
+			        StringHelper.qualify( owner.getTableAlias(), idColNames )
+			);
+			if (  !primaryOrdering.getText().startsWith( expectedPrimaryOrderSeq ) ) {
+				throw new HibernateException( "cannot scroll results with collection fetches which are not ordered primarily by the root entity's PK" );
+			}
+		}
+	}
+
+	private StatementExecutor buildAppropriateStatementExecutor(HqlSqlWalker walker) {
+		Statement statement = ( Statement ) walker.getAST();
+		if ( walker.getStatementType() == HqlSqlTokenTypes.DELETE ) {
+			FromElement fromElement = walker.getFinalFromClause().getFromElement();
+			Queryable persister = fromElement.getQueryable();
+			if ( persister.isMultiTable() ) {
+				return new MultiTableDeleteExecutor( walker );
+			}
+			else {
+				return new BasicExecutor( walker, persister );
+			}
+		}
+		else if ( walker.getStatementType() == HqlSqlTokenTypes.UPDATE ) {
+			FromElement fromElement = walker.getFinalFromClause().getFromElement();
+			Queryable persister = fromElement.getQueryable();
+			if ( persister.isMultiTable() ) {
+				// even here, if only properties mapped to the "base table" are referenced
+				// in the set and where clauses, this could be handled by the BasicDelegate.
+				// TODO : decide if it is better performance-wise to perform that check, or to simply use the MultiTableUpdateDelegate
+				return new MultiTableUpdateExecutor( walker );
+			}
+			else {
+				return new BasicExecutor( walker, persister );
+			}
+		}
+		else if ( walker.getStatementType() == HqlSqlTokenTypes.INSERT ) {
+			return new BasicExecutor( walker, ( ( InsertStatement ) statement ).getIntoClause().getQueryable() );
+		}
+		else {
+			throw new QueryException( "Unexpected statement type" );
+		}
+	}
+
+	public ParameterTranslations getParameterTranslations() {
+		if ( paramTranslations == null ) {
+			paramTranslations = new ParameterTranslationsImpl( getWalker().getParameters() );
+		}
+		return paramTranslations;
+	}
+
+	public static class JavaConstantConverter implements NodeTraverser.VisitationStrategy {
+		private AST dotRoot;
+		public void visit(AST node) {
+			if ( dotRoot != null ) {
+				// we are already processing a dot-structure
+				if ( ASTUtil.isSubtreeChild( dotRoot, node ) ) {
+					// igndore it...
+					return;
+				}
+				else {
+					// we are now at a new tree level
+					dotRoot = null;
+				}
+			}
+
+			if ( dotRoot == null && node.getType() == HqlTokenTypes.DOT ) {
+				dotRoot = node;
+				handleDotStructure( dotRoot );
+			}
+		}
+		private void handleDotStructure(AST dotStructureRoot) {
+			String expression = ASTUtil.getPathText( dotStructureRoot );
+			Object constant = ReflectHelper.getConstantValue( expression );
+			if ( constant != null ) {
+				dotStructureRoot.setFirstChild( null );
+				dotStructureRoot.setType( HqlTokenTypes.JAVA_CONSTANT );
+				dotStructureRoot.setText( expression );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,225 +0,0 @@
-// $Id: SqlASTFactory.java 10060 2006-06-28 02:53:39Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast;
-
-import antlr.ASTFactory;
-import antlr.Token;
-import antlr.collections.AST;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.tree.AggregateNode;
-import org.hibernate.hql.ast.tree.BinaryArithmeticOperatorNode;
-import org.hibernate.hql.ast.tree.BinaryLogicOperatorNode;
-import org.hibernate.hql.ast.tree.Case2Node;
-import org.hibernate.hql.ast.tree.CaseNode;
-import org.hibernate.hql.ast.tree.CollectionFunction;
-import org.hibernate.hql.ast.tree.ConstructorNode;
-import org.hibernate.hql.ast.tree.CountNode;
-import org.hibernate.hql.ast.tree.DeleteStatement;
-import org.hibernate.hql.ast.tree.DotNode;
-import org.hibernate.hql.ast.tree.FromClause;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.IdentNode;
-import org.hibernate.hql.ast.tree.ImpliedFromElement;
-import org.hibernate.hql.ast.tree.IndexNode;
-import org.hibernate.hql.ast.tree.InitializeableNode;
-import org.hibernate.hql.ast.tree.InsertStatement;
-import org.hibernate.hql.ast.tree.IntoClause;
-import org.hibernate.hql.ast.tree.LiteralNode;
-import org.hibernate.hql.ast.tree.MethodNode;
-import org.hibernate.hql.ast.tree.OrderByClause;
-import org.hibernate.hql.ast.tree.ParameterNode;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.hql.ast.tree.SelectClause;
-import org.hibernate.hql.ast.tree.SelectExpressionImpl;
-import org.hibernate.hql.ast.tree.SqlFragment;
-import org.hibernate.hql.ast.tree.SqlNode;
-import org.hibernate.hql.ast.tree.UnaryArithmeticNode;
-import org.hibernate.hql.ast.tree.UpdateStatement;
-import org.hibernate.hql.ast.tree.BetweenOperatorNode;
-import org.hibernate.hql.ast.tree.UnaryLogicOperatorNode;
-import org.hibernate.hql.ast.tree.InLogicOperatorNode;
-import org.hibernate.hql.ast.tree.JavaConstantNode;
-import org.hibernate.hql.ast.tree.SessionFactoryAwareNode;
-import org.hibernate.hql.ast.tree.BooleanLiteralNode;
-import org.hibernate.hql.ast.tree.IsNullLogicOperatorNode;
-import org.hibernate.hql.ast.tree.IsNotNullLogicOperatorNode;
-
-import java.lang.reflect.Constructor;
-
-/**
- * Custom AST factory the intermediate tree that causes ANTLR to create specialized
- * AST nodes, given the AST node type (from HqlSqlTokenTypes).   HqlSqlWalker registers
- * this factory with itself when it is initialized.
- *
- * @author Joshua
- */
-public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes {
-	private HqlSqlWalker walker;
-
-	/**
-	 * Create factory with a specific mapping from token type
-	 * to Java AST node type.  Your subclasses of ASTFactory
-	 * can override and reuse the map stuff.
-	 */
-	public SqlASTFactory(HqlSqlWalker walker) {
-		super();
-		this.walker = walker;
-	}
-
-	/**
-	 * Returns the class for a given token type (a.k.a. AST node type).
-	 *
-	 * @param tokenType The token type.
-	 * @return Class - The AST node class to instantiate.
-	 */
-	public Class getASTNodeType(int tokenType) {
-		switch ( tokenType ) {
-			case SELECT:
-			case QUERY:
-				return QueryNode.class;
-			case UPDATE:
-				return UpdateStatement.class;
-			case DELETE:
-				return DeleteStatement.class;
-			case INSERT:
-				return InsertStatement.class;
-			case INTO:
-				return IntoClause.class;
-			case FROM:
-				return FromClause.class;
-			case FROM_FRAGMENT:
-				return FromElement.class;
-			case IMPLIED_FROM:
-				return ImpliedFromElement.class;
-			case DOT:
-				return DotNode.class;
-			case INDEX_OP:
-				return IndexNode.class;
-				// Alias references and identifiers use the same node class.
-			case ALIAS_REF:
-			case IDENT:
-				return IdentNode.class;
-			case SQL_TOKEN:
-				return SqlFragment.class;
-			case METHOD_CALL:
-				return MethodNode.class;
-			case ELEMENTS:
-			case INDICES:
-				return CollectionFunction.class;
-			case SELECT_CLAUSE:
-				return SelectClause.class;
-			case SELECT_EXPR:
-				return SelectExpressionImpl.class;
-			case AGGREGATE:
-				return AggregateNode.class;
-			case COUNT:
-				return CountNode.class;
-			case CONSTRUCTOR:
-				return ConstructorNode.class;
-			case NUM_INT:
-			case NUM_FLOAT:
-			case NUM_LONG:
-			case NUM_DOUBLE:
-			case QUOTED_STRING:
-				return LiteralNode.class;
-			case TRUE:
-			case FALSE:
-				return BooleanLiteralNode.class;
-			case JAVA_CONSTANT:
-				return JavaConstantNode.class;
-			case ORDER:
-				return OrderByClause.class;
-			case PLUS:
-			case MINUS:
-			case STAR:
-			case DIV:
-				return BinaryArithmeticOperatorNode.class;
-			case UNARY_MINUS:
-			case UNARY_PLUS:
-				return UnaryArithmeticNode.class;
-			case CASE2:
-				return Case2Node.class;
-			case CASE:
-				return CaseNode.class;
-			case PARAM:
-			case NAMED_PARAM:
-				return ParameterNode.class;
-			case EQ:
-			case NE:
-			case LT:
-			case GT:
-			case LE:
-			case GE:
-			case LIKE:
-			case NOT_LIKE:
-				return BinaryLogicOperatorNode.class;
-			case IN:
-			case NOT_IN:
-				return InLogicOperatorNode.class;
-			case BETWEEN:
-			case NOT_BETWEEN:
-				return BetweenOperatorNode.class;
-			case IS_NULL:
-				return IsNullLogicOperatorNode.class;
-			case IS_NOT_NULL:
-				return IsNotNullLogicOperatorNode.class;
-			case EXISTS:
-				return UnaryLogicOperatorNode.class;
-			default:
-				return SqlNode.class;
-		} // switch
-	}
-
-	protected AST createUsingCtor(Token token, String className) {
-		Class c;
-		AST t;
-		try {
-			c = Class.forName( className );
-			Class[] tokenArgType = new Class[]{antlr.Token.class};
-			Constructor ctor = c.getConstructor( tokenArgType );
-			if ( ctor != null ) {
-				t = ( AST ) ctor.newInstance( new Object[]{token} ); // make a new one
-				initializeSqlNode( t );
-			}
-			else {
-				// just do the regular thing if you can't find the ctor
-				// Your AST must have default ctor to use this.
-				t = create( c );
-			}
-		}
-		catch ( Exception e ) {
-			throw new IllegalArgumentException( "Invalid class or can't make instance, " + className );
-		}
-		return t;
-	}
-
-	private void initializeSqlNode(AST t) {
-		// Initialize SQL nodes here.
-		if ( t instanceof InitializeableNode ) {
-			InitializeableNode initializeableNode = ( InitializeableNode ) t;
-			initializeableNode.initialize( walker );
-		}
-		if ( t instanceof SessionFactoryAwareNode ) {
-			( ( SessionFactoryAwareNode ) t ).setSessionFactory( walker.getSessionFactoryHelper().getFactory() );
-		}
-	}
-
-	/**
-	 * Actually instantiate the AST node.
-	 *
-	 * @param c The class to instantiate.
-	 * @return The instantiated and initialized node.
-	 */
-	protected AST create(Class c) {
-		AST t;
-		try {
-			t = ( AST ) c.newInstance(); // make a new one
-			initializeSqlNode( t );
-		}
-		catch ( Exception e ) {
-			error( "Can't create AST Node " + c.getName() );
-			return null;
-		}
-		return t;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlASTFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,248 @@
+/*
+ * 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;
+
+import antlr.ASTFactory;
+import antlr.Token;
+import antlr.collections.AST;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.tree.AggregateNode;
+import org.hibernate.hql.ast.tree.BinaryArithmeticOperatorNode;
+import org.hibernate.hql.ast.tree.BinaryLogicOperatorNode;
+import org.hibernate.hql.ast.tree.Case2Node;
+import org.hibernate.hql.ast.tree.CaseNode;
+import org.hibernate.hql.ast.tree.CollectionFunction;
+import org.hibernate.hql.ast.tree.ConstructorNode;
+import org.hibernate.hql.ast.tree.CountNode;
+import org.hibernate.hql.ast.tree.DeleteStatement;
+import org.hibernate.hql.ast.tree.DotNode;
+import org.hibernate.hql.ast.tree.FromClause;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.IdentNode;
+import org.hibernate.hql.ast.tree.ImpliedFromElement;
+import org.hibernate.hql.ast.tree.IndexNode;
+import org.hibernate.hql.ast.tree.InitializeableNode;
+import org.hibernate.hql.ast.tree.InsertStatement;
+import org.hibernate.hql.ast.tree.IntoClause;
+import org.hibernate.hql.ast.tree.LiteralNode;
+import org.hibernate.hql.ast.tree.MethodNode;
+import org.hibernate.hql.ast.tree.OrderByClause;
+import org.hibernate.hql.ast.tree.ParameterNode;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.hql.ast.tree.SelectClause;
+import org.hibernate.hql.ast.tree.SelectExpressionImpl;
+import org.hibernate.hql.ast.tree.SqlFragment;
+import org.hibernate.hql.ast.tree.SqlNode;
+import org.hibernate.hql.ast.tree.UnaryArithmeticNode;
+import org.hibernate.hql.ast.tree.UpdateStatement;
+import org.hibernate.hql.ast.tree.BetweenOperatorNode;
+import org.hibernate.hql.ast.tree.UnaryLogicOperatorNode;
+import org.hibernate.hql.ast.tree.InLogicOperatorNode;
+import org.hibernate.hql.ast.tree.JavaConstantNode;
+import org.hibernate.hql.ast.tree.SessionFactoryAwareNode;
+import org.hibernate.hql.ast.tree.BooleanLiteralNode;
+import org.hibernate.hql.ast.tree.IsNullLogicOperatorNode;
+import org.hibernate.hql.ast.tree.IsNotNullLogicOperatorNode;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Custom AST factory the intermediate tree that causes ANTLR to create specialized
+ * AST nodes, given the AST node type (from HqlSqlTokenTypes).   HqlSqlWalker registers
+ * this factory with itself when it is initialized.
+ *
+ * @author Joshua
+ */
+public class SqlASTFactory extends ASTFactory implements HqlSqlTokenTypes {
+	private HqlSqlWalker walker;
+
+	/**
+	 * Create factory with a specific mapping from token type
+	 * to Java AST node type.  Your subclasses of ASTFactory
+	 * can override and reuse the map stuff.
+	 */
+	public SqlASTFactory(HqlSqlWalker walker) {
+		super();
+		this.walker = walker;
+	}
+
+	/**
+	 * Returns the class for a given token type (a.k.a. AST node type).
+	 *
+	 * @param tokenType The token type.
+	 * @return Class - The AST node class to instantiate.
+	 */
+	public Class getASTNodeType(int tokenType) {
+		switch ( tokenType ) {
+			case SELECT:
+			case QUERY:
+				return QueryNode.class;
+			case UPDATE:
+				return UpdateStatement.class;
+			case DELETE:
+				return DeleteStatement.class;
+			case INSERT:
+				return InsertStatement.class;
+			case INTO:
+				return IntoClause.class;
+			case FROM:
+				return FromClause.class;
+			case FROM_FRAGMENT:
+				return FromElement.class;
+			case IMPLIED_FROM:
+				return ImpliedFromElement.class;
+			case DOT:
+				return DotNode.class;
+			case INDEX_OP:
+				return IndexNode.class;
+				// Alias references and identifiers use the same node class.
+			case ALIAS_REF:
+			case IDENT:
+				return IdentNode.class;
+			case SQL_TOKEN:
+				return SqlFragment.class;
+			case METHOD_CALL:
+				return MethodNode.class;
+			case ELEMENTS:
+			case INDICES:
+				return CollectionFunction.class;
+			case SELECT_CLAUSE:
+				return SelectClause.class;
+			case SELECT_EXPR:
+				return SelectExpressionImpl.class;
+			case AGGREGATE:
+				return AggregateNode.class;
+			case COUNT:
+				return CountNode.class;
+			case CONSTRUCTOR:
+				return ConstructorNode.class;
+			case NUM_INT:
+			case NUM_FLOAT:
+			case NUM_LONG:
+			case NUM_DOUBLE:
+			case QUOTED_STRING:
+				return LiteralNode.class;
+			case TRUE:
+			case FALSE:
+				return BooleanLiteralNode.class;
+			case JAVA_CONSTANT:
+				return JavaConstantNode.class;
+			case ORDER:
+				return OrderByClause.class;
+			case PLUS:
+			case MINUS:
+			case STAR:
+			case DIV:
+				return BinaryArithmeticOperatorNode.class;
+			case UNARY_MINUS:
+			case UNARY_PLUS:
+				return UnaryArithmeticNode.class;
+			case CASE2:
+				return Case2Node.class;
+			case CASE:
+				return CaseNode.class;
+			case PARAM:
+			case NAMED_PARAM:
+				return ParameterNode.class;
+			case EQ:
+			case NE:
+			case LT:
+			case GT:
+			case LE:
+			case GE:
+			case LIKE:
+			case NOT_LIKE:
+				return BinaryLogicOperatorNode.class;
+			case IN:
+			case NOT_IN:
+				return InLogicOperatorNode.class;
+			case BETWEEN:
+			case NOT_BETWEEN:
+				return BetweenOperatorNode.class;
+			case IS_NULL:
+				return IsNullLogicOperatorNode.class;
+			case IS_NOT_NULL:
+				return IsNotNullLogicOperatorNode.class;
+			case EXISTS:
+				return UnaryLogicOperatorNode.class;
+			default:
+				return SqlNode.class;
+		} // switch
+	}
+
+	protected AST createUsingCtor(Token token, String className) {
+		Class c;
+		AST t;
+		try {
+			c = Class.forName( className );
+			Class[] tokenArgType = new Class[]{antlr.Token.class};
+			Constructor ctor = c.getConstructor( tokenArgType );
+			if ( ctor != null ) {
+				t = ( AST ) ctor.newInstance( new Object[]{token} ); // make a new one
+				initializeSqlNode( t );
+			}
+			else {
+				// just do the regular thing if you can't find the ctor
+				// Your AST must have default ctor to use this.
+				t = create( c );
+			}
+		}
+		catch ( Exception e ) {
+			throw new IllegalArgumentException( "Invalid class or can't make instance, " + className );
+		}
+		return t;
+	}
+
+	private void initializeSqlNode(AST t) {
+		// Initialize SQL nodes here.
+		if ( t instanceof InitializeableNode ) {
+			InitializeableNode initializeableNode = ( InitializeableNode ) t;
+			initializeableNode.initialize( walker );
+		}
+		if ( t instanceof SessionFactoryAwareNode ) {
+			( ( SessionFactoryAwareNode ) t ).setSessionFactory( walker.getSessionFactoryHelper().getFactory() );
+		}
+	}
+
+	/**
+	 * Actually instantiate the AST node.
+	 *
+	 * @param c The class to instantiate.
+	 * @return The instantiated and initialized node.
+	 */
+	protected AST create(Class c) {
+		AST t;
+		try {
+			t = ( AST ) c.newInstance(); // make a new one
+			initializeSqlNode( t );
+		}
+		catch ( Exception e ) {
+			error( "Can't create AST Node " + c.getName() );
+			return null;
+		}
+		return t;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,267 +0,0 @@
-// $Id: SqlGenerator.java 10060 2006-06-28 02:53:39Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-import antlr.RecognitionException;
-import antlr.collections.AST;
-import org.hibernate.QueryException;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.antlr.SqlGeneratorBase;
-import org.hibernate.hql.ast.tree.MethodNode;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.Node;
-
-/**
- * Generates SQL by overriding callback methods in the base class, which does
- * the actual SQL AST walking.
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
-	/**
-	 * Handles parser errors.
-	 */
-	private ParseErrorHandler parseErrorHandler;
-
-	/**
-	 * all append invocations on the buf should go through this Output instance variable.
-	 * The value of this variable may be temporarily substitued by sql function processing code
-	 * to catch generated arguments.
-	 * This is because sql function templates need arguments as seperate string chunks
-	 * that will be assembled into the target dialect-specific function call.
-	 */
-	private SqlWriter writer = new DefaultWriter();
-
-	private SessionFactoryImplementor sessionFactory;
-
-	private LinkedList outputStack = new LinkedList();
-
-	protected void out(String s) {
-		writer.clause( s );
-	}
-
-	protected void out(AST n) {
-		if ( n instanceof Node ) {
-			out( ( ( Node ) n ).getRenderText( sessionFactory ) );
-		}
-		else {
-			super.out( n );
-		}
-	}
-
-	protected void commaBetweenParameters(String comma) {
-		writer.commaBetweenParameters( comma );
-	}
-
-	public void reportError(RecognitionException e) {
-		parseErrorHandler.reportError( e ); // Use the delegate.
-	}
-
-	public void reportError(String s) {
-		parseErrorHandler.reportError( s ); // Use the delegate.
-	}
-
-	public void reportWarning(String s) {
-		parseErrorHandler.reportWarning( s );
-	}
-
-	public ParseErrorHandler getParseErrorHandler() {
-		return parseErrorHandler;
-	}
-
-	public SqlGenerator(SessionFactoryImplementor sfi) {
-		super();
-		parseErrorHandler = new ErrorCounter();
-		sessionFactory = sfi;
-	}
-
-	public String getSQL() {
-		return getStringBuffer().toString();
-	}
-
-	protected void optionalSpace() {
-		int c = getLastChar();
-		switch ( c ) {
-			case -1:
-				return;
-			case ' ':
-				return;
-			case ')':
-				return;
-			case '(':
-				return;
-			default:
-				out( " " );
-		}
-	}
-
-	protected void beginFunctionTemplate(AST m, AST i) {
-		MethodNode methodNode = ( MethodNode ) m;
-		SQLFunction template = methodNode.getSQLFunction();
-		if ( template == null ) {
-			// if template is null we just write the function out as it appears in the hql statement
-			super.beginFunctionTemplate( m, i );
-		}
-		else {
-			// this function has a template -> redirect output and catch the arguments
-			outputStack.addFirst( writer );
-			writer = new FunctionArguments();
-		}
-	}
-
-	protected void endFunctionTemplate(AST m) {
-		MethodNode methodNode = ( MethodNode ) m;
-		SQLFunction template = methodNode.getSQLFunction();
-		if ( template == null ) {
-			super.endFunctionTemplate( m );
-		}
-		else {
-			// this function has a template -> restore output, apply the template and write the result out
-			FunctionArguments functionArguments = ( FunctionArguments ) writer;   // TODO: Downcast to avoid using an interface?  Yuck.
-			writer = ( SqlWriter ) outputStack.removeFirst();
-			out( template.render( functionArguments.getArgs(), sessionFactory ) );
-		}
-	}
-
-	// --- Inner classes (moved here from sql-gen.g) ---
-
-	/**
-	 * Writes SQL fragments.
-	 */
-	interface SqlWriter {
-		void clause(String clause);
-
-		/**
-		 * todo remove this hack
-		 * The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old
-		 * sql generator uses " , " in the WHERE and ", " in SELECT.
-		 *
-		 * @param comma either " , " or ", "
-		 */
-		void commaBetweenParameters(String comma);
-	}
-
-	/**
-	 * SQL function processing code redirects generated SQL output to an instance of this class
-	 * which catches function arguments.
-	 */
-	class FunctionArguments implements SqlWriter {
-		private int argInd;
-		private final List args = new ArrayList( 3 );
-
-		public void clause(String clause) {
-			if ( argInd == args.size() ) {
-				args.add( clause );
-			}
-			else {
-				args.set( argInd, args.get( argInd ) + clause );
-			}
-		}
-
-		public void commaBetweenParameters(String comma) {
-			++argInd;
-		}
-
-		public List getArgs() {
-			return args;
-		}
-	}
-
-	/**
-	 * The default SQL writer.
-	 */
-	class DefaultWriter implements SqlWriter {
-		public void clause(String clause) {
-			getStringBuffer().append( clause );
-		}
-
-		public void commaBetweenParameters(String comma) {
-			getStringBuffer().append( comma );
-		}
-	}
-
-    public static void panic() {
-		throw new QueryException( "TreeWalker: panic" );
-	}
-
-	protected void fromFragmentSeparator(AST a) {
-		// check two "adjecent" nodes at the top of the from-clause tree
-		AST next = a.getNextSibling();
-		if ( next == null || !hasText( a ) ) {
-			return;
-		}
-
-		FromElement left = ( FromElement ) a;
-		FromElement right = ( FromElement ) next;
-
-		///////////////////////////////////////////////////////////////////////
-		// HACK ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!
-		// Attempt to work around "ghost" ImpliedFromElements that occasionally
-		// show up between the actual things being joined.  This consistently
-		// occurs from index nodes (at least against many-to-many).  Not sure
-		// if there are other conditions
-		//
-		// Essentially, look-ahead to the next FromElement that actually
-		// writes something to the SQL
-		while ( right != null && !hasText( right ) ) {
-			right = ( FromElement ) right.getNextSibling();
-		}
-		if ( right == null ) {
-			return;
-		}
-		///////////////////////////////////////////////////////////////////////
-
-		if ( !hasText( right ) ) {
-			return;
-		}
-
-		if ( right.getRealOrigin() == left ||
-		     ( right.getRealOrigin() != null && right.getRealOrigin() == left.getRealOrigin() ) ) {
-			// right represents a joins originating from left; or
-			// both right and left reprersent joins originating from the same FromElement
-			if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
-				out( ", " );
-			}
-			else {
-				out( " " );
-			}
-		}
-		else {
-			// these are just two unrelated table references
-			out( ", " );
-		}
-	}
-
-	protected void nestedFromFragment(AST d, AST parent) {
-		// check a set of parent/child nodes in the from-clause tree
-		// to determine if a comma is required between them
-		if ( d != null && hasText( d ) ) {
-			if ( parent != null && hasText( parent ) ) {
-				// again, both should be FromElements
-				FromElement left = ( FromElement ) parent;
-				FromElement right = ( FromElement ) d;
-				if ( right.getRealOrigin() == left ) {
-					// right represents a joins originating from left...
-					if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
-						out( ", " );
-					}
-					else {
-						out( " " );
-					}
-				}
-				else {
-					// not so sure this is even valid subtree.  but if it was, it'd
-					// represent two unrelated table references...
-					out( ", " );
-				}
-			}
-			out( d );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/SqlGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,290 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import antlr.RecognitionException;
+import antlr.collections.AST;
+import org.hibernate.QueryException;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.antlr.SqlGeneratorBase;
+import org.hibernate.hql.ast.tree.MethodNode;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.Node;
+
+/**
+ * Generates SQL by overriding callback methods in the base class, which does
+ * the actual SQL AST walking.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class SqlGenerator extends SqlGeneratorBase implements ErrorReporter {
+	/**
+	 * Handles parser errors.
+	 */
+	private ParseErrorHandler parseErrorHandler;
+
+	/**
+	 * all append invocations on the buf should go through this Output instance variable.
+	 * The value of this variable may be temporarily substitued by sql function processing code
+	 * to catch generated arguments.
+	 * This is because sql function templates need arguments as seperate string chunks
+	 * that will be assembled into the target dialect-specific function call.
+	 */
+	private SqlWriter writer = new DefaultWriter();
+
+	private SessionFactoryImplementor sessionFactory;
+
+	private LinkedList outputStack = new LinkedList();
+
+	protected void out(String s) {
+		writer.clause( s );
+	}
+
+	protected void out(AST n) {
+		if ( n instanceof Node ) {
+			out( ( ( Node ) n ).getRenderText( sessionFactory ) );
+		}
+		else {
+			super.out( n );
+		}
+	}
+
+	protected void commaBetweenParameters(String comma) {
+		writer.commaBetweenParameters( comma );
+	}
+
+	public void reportError(RecognitionException e) {
+		parseErrorHandler.reportError( e ); // Use the delegate.
+	}
+
+	public void reportError(String s) {
+		parseErrorHandler.reportError( s ); // Use the delegate.
+	}
+
+	public void reportWarning(String s) {
+		parseErrorHandler.reportWarning( s );
+	}
+
+	public ParseErrorHandler getParseErrorHandler() {
+		return parseErrorHandler;
+	}
+
+	public SqlGenerator(SessionFactoryImplementor sfi) {
+		super();
+		parseErrorHandler = new ErrorCounter();
+		sessionFactory = sfi;
+	}
+
+	public String getSQL() {
+		return getStringBuffer().toString();
+	}
+
+	protected void optionalSpace() {
+		int c = getLastChar();
+		switch ( c ) {
+			case -1:
+				return;
+			case ' ':
+				return;
+			case ')':
+				return;
+			case '(':
+				return;
+			default:
+				out( " " );
+		}
+	}
+
+	protected void beginFunctionTemplate(AST m, AST i) {
+		MethodNode methodNode = ( MethodNode ) m;
+		SQLFunction template = methodNode.getSQLFunction();
+		if ( template == null ) {
+			// if template is null we just write the function out as it appears in the hql statement
+			super.beginFunctionTemplate( m, i );
+		}
+		else {
+			// this function has a template -> redirect output and catch the arguments
+			outputStack.addFirst( writer );
+			writer = new FunctionArguments();
+		}
+	}
+
+	protected void endFunctionTemplate(AST m) {
+		MethodNode methodNode = ( MethodNode ) m;
+		SQLFunction template = methodNode.getSQLFunction();
+		if ( template == null ) {
+			super.endFunctionTemplate( m );
+		}
+		else {
+			// this function has a template -> restore output, apply the template and write the result out
+			FunctionArguments functionArguments = ( FunctionArguments ) writer;   // TODO: Downcast to avoid using an interface?  Yuck.
+			writer = ( SqlWriter ) outputStack.removeFirst();
+			out( template.render( functionArguments.getArgs(), sessionFactory ) );
+		}
+	}
+
+	// --- Inner classes (moved here from sql-gen.g) ---
+
+	/**
+	 * Writes SQL fragments.
+	 */
+	interface SqlWriter {
+		void clause(String clause);
+
+		/**
+		 * todo remove this hack
+		 * The parameter is either ", " or " , ". This is needed to pass sql generating tests as the old
+		 * sql generator uses " , " in the WHERE and ", " in SELECT.
+		 *
+		 * @param comma either " , " or ", "
+		 */
+		void commaBetweenParameters(String comma);
+	}
+
+	/**
+	 * SQL function processing code redirects generated SQL output to an instance of this class
+	 * which catches function arguments.
+	 */
+	class FunctionArguments implements SqlWriter {
+		private int argInd;
+		private final List args = new ArrayList( 3 );
+
+		public void clause(String clause) {
+			if ( argInd == args.size() ) {
+				args.add( clause );
+			}
+			else {
+				args.set( argInd, args.get( argInd ) + clause );
+			}
+		}
+
+		public void commaBetweenParameters(String comma) {
+			++argInd;
+		}
+
+		public List getArgs() {
+			return args;
+		}
+	}
+
+	/**
+	 * The default SQL writer.
+	 */
+	class DefaultWriter implements SqlWriter {
+		public void clause(String clause) {
+			getStringBuffer().append( clause );
+		}
+
+		public void commaBetweenParameters(String comma) {
+			getStringBuffer().append( comma );
+		}
+	}
+
+    public static void panic() {
+		throw new QueryException( "TreeWalker: panic" );
+	}
+
+	protected void fromFragmentSeparator(AST a) {
+		// check two "adjecent" nodes at the top of the from-clause tree
+		AST next = a.getNextSibling();
+		if ( next == null || !hasText( a ) ) {
+			return;
+		}
+
+		FromElement left = ( FromElement ) a;
+		FromElement right = ( FromElement ) next;
+
+		///////////////////////////////////////////////////////////////////////
+		// HACK ALERT !!!!!!!!!!!!!!!!!!!!!!!!!!!!
+		// Attempt to work around "ghost" ImpliedFromElements that occasionally
+		// show up between the actual things being joined.  This consistently
+		// occurs from index nodes (at least against many-to-many).  Not sure
+		// if there are other conditions
+		//
+		// Essentially, look-ahead to the next FromElement that actually
+		// writes something to the SQL
+		while ( right != null && !hasText( right ) ) {
+			right = ( FromElement ) right.getNextSibling();
+		}
+		if ( right == null ) {
+			return;
+		}
+		///////////////////////////////////////////////////////////////////////
+
+		if ( !hasText( right ) ) {
+			return;
+		}
+
+		if ( right.getRealOrigin() == left ||
+		     ( right.getRealOrigin() != null && right.getRealOrigin() == left.getRealOrigin() ) ) {
+			// right represents a joins originating from left; or
+			// both right and left reprersent joins originating from the same FromElement
+			if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
+				out( ", " );
+			}
+			else {
+				out( " " );
+			}
+		}
+		else {
+			// these are just two unrelated table references
+			out( ", " );
+		}
+	}
+
+	protected void nestedFromFragment(AST d, AST parent) {
+		// check a set of parent/child nodes in the from-clause tree
+		// to determine if a comma is required between them
+		if ( d != null && hasText( d ) ) {
+			if ( parent != null && hasText( parent ) ) {
+				// again, both should be FromElements
+				FromElement left = ( FromElement ) parent;
+				FromElement right = ( FromElement ) d;
+				if ( right.getRealOrigin() == left ) {
+					// right represents a joins originating from left...
+					if ( right.getJoinSequence() != null && right.getJoinSequence().isThetaStyle() ) {
+						out( ", " );
+					}
+					else {
+						out( " " );
+					}
+				}
+				else {
+					// not so sure this is even valid subtree.  but if it was, it'd
+					// represent two unrelated table references...
+					out( ", " );
+				}
+			}
+			out( d );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,227 +0,0 @@
-// $Id: AbstractStatementExecutor.java 11288 2007-03-15 11:38:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.exec;
-
-import java.sql.PreparedStatement;
-import java.sql.Connection;
-import java.sql.Statement;
-
-import org.hibernate.HibernateException;
-import org.hibernate.action.BulkOperationCleanupAction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.transaction.Isolater;
-import org.hibernate.engine.transaction.IsolatedWork;
-import org.hibernate.event.EventSource;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.SqlGenerator;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.InsertSelect;
-import org.hibernate.sql.Select;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.util.StringHelper;
-
-import antlr.RecognitionException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-
-/**
- * Implementation of AbstractStatementExecutor.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractStatementExecutor implements StatementExecutor {
-
-	private final Logger log;
-	private final HqlSqlWalker walker;
-
-	public AbstractStatementExecutor(HqlSqlWalker walker, Logger log) {
-		this.walker = walker;
-		this.log = log;
-	}
-
-	protected HqlSqlWalker getWalker() {
-		return walker;
-	}
-
-	protected SessionFactoryImplementor getFactory() {
-		return walker.getSessionFactoryHelper().getFactory();
-	}
-
-	protected abstract Queryable[] getAffectedQueryables();
-
-	protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
-		Select select = new Select( getFactory().getDialect() );
-		SelectFragment selectFragment = new SelectFragment()
-				.addColumns( tableAlias, persister.getIdentifierColumnNames(), persister.getIdentifierColumnNames() );
-		select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
-
-		String rootTableName = persister.getTableName();
-		String fromJoinFragment = persister.fromJoinFragment( tableAlias, true, false );
-		String whereJoinFragment = persister.whereJoinFragment( tableAlias, true, false );
-
-		select.setFromClause( rootTableName + ' ' + tableAlias + fromJoinFragment );
-
-		if ( whereJoinFragment == null ) {
-			whereJoinFragment = "";
-		}
-		else {
-			whereJoinFragment = whereJoinFragment.trim();
-			if ( whereJoinFragment.startsWith( "and" ) ) {
-				whereJoinFragment = whereJoinFragment.substring( 4 );
-			}
-		}
-
-		String userWhereClause = "";
-		if ( whereClause.getNumberOfChildren() != 0 ) {
-			// If a where clause was specified in the update/delete query, use it to limit the
-			// returned ids here...
-			try {
-				SqlGenerator sqlGenerator = new SqlGenerator( getFactory() );
-				sqlGenerator.whereClause( whereClause );
-				userWhereClause = sqlGenerator.getSQL().substring( 7 );  // strip the " where "
-			}
-			catch ( RecognitionException e ) {
-				throw new HibernateException( "Unable to generate id select for DML operation", e );
-			}
-			if ( whereJoinFragment.length() > 0 ) {
-				whereJoinFragment += " and ";
-			}
-		}
-
-		select.setWhereClause( whereJoinFragment + userWhereClause );
-
-		InsertSelect insert = new InsertSelect( getFactory().getDialect() );
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			insert.setComment( "insert-select for " + persister.getEntityName() + " ids" );
-		}
-		insert.setTableName( persister.getTemporaryIdTableName() );
-		insert.setSelect( select );
-		return insert.toStatementString();
-	}
-
-	protected String generateIdSubselect(Queryable persister) {
-		return "select " + StringHelper.join( ", ", persister.getIdentifierColumnNames() ) +
-			        " from " + persister.getTemporaryIdTableName();
-	}
-
-	protected void createTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
-		// Don't really know all the codes required to adequately decipher returned jdbc exceptions here.
-		// simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
-		IsolatedWork work = new IsolatedWork() {
-			public void doWork(Connection connection) throws HibernateException {
-				Statement stmnt = null;
-				try {
-					stmnt = connection.createStatement();
-					stmnt.executeUpdate( persister.getTemporaryIdTableDDL() );
-				}
-				catch( Throwable t ) {
-					log.debug( "unable to create temporary id table [" + t.getMessage() + "]" );
-				}
-				finally {
-					if ( stmnt != null ) {
-						try {
-							stmnt.close();
-						}
-						catch( Throwable ignore ) {
-							// ignore
-						}
-					}
-				}
-			}
-		};
-		if ( shouldIsolateTemporaryTableDDL() ) {
-			if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
-				Isolater.doIsolatedWork( work, session );
-			}
-			else {
-				Isolater.doNonTransactedWork( work, session );
-			}
-		}
-		else {
-			work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
-			session.getJDBCContext().getConnectionManager().afterStatement();
-		}
-	}
-
-	protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
-		if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
-			IsolatedWork work = new IsolatedWork() {
-				public void doWork(Connection connection) throws HibernateException {
-					Statement stmnt = null;
-					try {
-						stmnt = connection.createStatement();
-						stmnt.executeUpdate( "drop table " + persister.getTemporaryIdTableName() );
-					}
-					catch( Throwable t ) {
-						log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" );
-					}
-					finally {
-						if ( stmnt != null ) {
-							try {
-								stmnt.close();
-							}
-							catch( Throwable ignore ) {
-								// ignore
-							}
-						}
-					}
-				}
-			};
-
-			if ( shouldIsolateTemporaryTableDDL() ) {
-				if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
-					Isolater.doIsolatedWork( work, session );
-				}
-				else {
-					Isolater.doNonTransactedWork( work, session );
-				}
-			}
-			else {
-				work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
-				session.getJDBCContext().getConnectionManager().afterStatement();
-			}
-		}
-		else {
-			// at the very least cleanup the data :)
-			PreparedStatement ps = null;
-			try {
-				ps = session.getBatcher().prepareStatement( "delete from " + persister.getTemporaryIdTableName() );
-				ps.executeUpdate();
-			}
-			catch( Throwable t ) {
-				log.warn( "unable to cleanup temporary id table after use [" + t + "]" );
-			}
-			finally {
-				if ( ps != null ) {
-					try {
-						session.getBatcher().closeStatement( ps );
-					}
-					catch( Throwable ignore ) {
-						// ignore
-					}
-				}
-			}
-		}
-	}
-
-	protected void coordinateSharedCacheCleanup(SessionImplementor session) {
-		BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getAffectedQueryables() );
-
-		action.init();
-
-		if ( session.isEventSource() ) {
-			( ( EventSource ) session ).getActionQueue().addAction( action );
-		}
-	}
-
-	protected boolean shouldIsolateTemporaryTableDDL() {
-		Boolean dialectVote = getFactory().getDialect().performTemporaryTableDDLInIsolation();
-		if ( dialectVote != null ) {
-			return dialectVote.booleanValue();
-		}
-		else {
-			return getFactory().getSettings().isDataDefinitionImplicitCommit();
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/AbstractStatementExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,250 @@
+/*
+ * 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.exec;
+
+import java.sql.PreparedStatement;
+import java.sql.Connection;
+import java.sql.Statement;
+
+import org.hibernate.HibernateException;
+import org.hibernate.action.BulkOperationCleanupAction;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.transaction.Isolater;
+import org.hibernate.engine.transaction.IsolatedWork;
+import org.hibernate.event.EventSource;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.SqlGenerator;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.InsertSelect;
+import org.hibernate.sql.Select;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.util.StringHelper;
+
+import antlr.RecognitionException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+
+/**
+ * Implementation of AbstractStatementExecutor.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractStatementExecutor implements StatementExecutor {
+
+	private final Logger log;
+	private final HqlSqlWalker walker;
+
+	public AbstractStatementExecutor(HqlSqlWalker walker, Logger log) {
+		this.walker = walker;
+		this.log = log;
+	}
+
+	protected HqlSqlWalker getWalker() {
+		return walker;
+	}
+
+	protected SessionFactoryImplementor getFactory() {
+		return walker.getSessionFactoryHelper().getFactory();
+	}
+
+	protected abstract Queryable[] getAffectedQueryables();
+
+	protected String generateIdInsertSelect(Queryable persister, String tableAlias, AST whereClause) {
+		Select select = new Select( getFactory().getDialect() );
+		SelectFragment selectFragment = new SelectFragment()
+				.addColumns( tableAlias, persister.getIdentifierColumnNames(), persister.getIdentifierColumnNames() );
+		select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
+
+		String rootTableName = persister.getTableName();
+		String fromJoinFragment = persister.fromJoinFragment( tableAlias, true, false );
+		String whereJoinFragment = persister.whereJoinFragment( tableAlias, true, false );
+
+		select.setFromClause( rootTableName + ' ' + tableAlias + fromJoinFragment );
+
+		if ( whereJoinFragment == null ) {
+			whereJoinFragment = "";
+		}
+		else {
+			whereJoinFragment = whereJoinFragment.trim();
+			if ( whereJoinFragment.startsWith( "and" ) ) {
+				whereJoinFragment = whereJoinFragment.substring( 4 );
+			}
+		}
+
+		String userWhereClause = "";
+		if ( whereClause.getNumberOfChildren() != 0 ) {
+			// If a where clause was specified in the update/delete query, use it to limit the
+			// returned ids here...
+			try {
+				SqlGenerator sqlGenerator = new SqlGenerator( getFactory() );
+				sqlGenerator.whereClause( whereClause );
+				userWhereClause = sqlGenerator.getSQL().substring( 7 );  // strip the " where "
+			}
+			catch ( RecognitionException e ) {
+				throw new HibernateException( "Unable to generate id select for DML operation", e );
+			}
+			if ( whereJoinFragment.length() > 0 ) {
+				whereJoinFragment += " and ";
+			}
+		}
+
+		select.setWhereClause( whereJoinFragment + userWhereClause );
+
+		InsertSelect insert = new InsertSelect( getFactory().getDialect() );
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			insert.setComment( "insert-select for " + persister.getEntityName() + " ids" );
+		}
+		insert.setTableName( persister.getTemporaryIdTableName() );
+		insert.setSelect( select );
+		return insert.toStatementString();
+	}
+
+	protected String generateIdSubselect(Queryable persister) {
+		return "select " + StringHelper.join( ", ", persister.getIdentifierColumnNames() ) +
+			        " from " + persister.getTemporaryIdTableName();
+	}
+
+	protected void createTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
+		// Don't really know all the codes required to adequately decipher returned jdbc exceptions here.
+		// simply allow the failure to be eaten and the subsequent insert-selects/deletes should fail
+		IsolatedWork work = new IsolatedWork() {
+			public void doWork(Connection connection) throws HibernateException {
+				Statement stmnt = null;
+				try {
+					stmnt = connection.createStatement();
+					stmnt.executeUpdate( persister.getTemporaryIdTableDDL() );
+				}
+				catch( Throwable t ) {
+					log.debug( "unable to create temporary id table [" + t.getMessage() + "]" );
+				}
+				finally {
+					if ( stmnt != null ) {
+						try {
+							stmnt.close();
+						}
+						catch( Throwable ignore ) {
+							// ignore
+						}
+					}
+				}
+			}
+		};
+		if ( shouldIsolateTemporaryTableDDL() ) {
+			if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
+				Isolater.doIsolatedWork( work, session );
+			}
+			else {
+				Isolater.doNonTransactedWork( work, session );
+			}
+		}
+		else {
+			work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
+			session.getJDBCContext().getConnectionManager().afterStatement();
+		}
+	}
+
+	protected void dropTemporaryTableIfNecessary(final Queryable persister, final SessionImplementor session) {
+		if ( getFactory().getDialect().dropTemporaryTableAfterUse() ) {
+			IsolatedWork work = new IsolatedWork() {
+				public void doWork(Connection connection) throws HibernateException {
+					Statement stmnt = null;
+					try {
+						stmnt = connection.createStatement();
+						stmnt.executeUpdate( "drop table " + persister.getTemporaryIdTableName() );
+					}
+					catch( Throwable t ) {
+						log.warn( "unable to drop temporary id table after use [" + t.getMessage() + "]" );
+					}
+					finally {
+						if ( stmnt != null ) {
+							try {
+								stmnt.close();
+							}
+							catch( Throwable ignore ) {
+								// ignore
+							}
+						}
+					}
+				}
+			};
+
+			if ( shouldIsolateTemporaryTableDDL() ) {
+				if ( getFactory().getSettings().isDataDefinitionInTransactionSupported() ) {
+					Isolater.doIsolatedWork( work, session );
+				}
+				else {
+					Isolater.doNonTransactedWork( work, session );
+				}
+			}
+			else {
+				work.doWork( session.getJDBCContext().getConnectionManager().getConnection() );
+				session.getJDBCContext().getConnectionManager().afterStatement();
+			}
+		}
+		else {
+			// at the very least cleanup the data :)
+			PreparedStatement ps = null;
+			try {
+				ps = session.getBatcher().prepareStatement( "delete from " + persister.getTemporaryIdTableName() );
+				ps.executeUpdate();
+			}
+			catch( Throwable t ) {
+				log.warn( "unable to cleanup temporary id table after use [" + t + "]" );
+			}
+			finally {
+				if ( ps != null ) {
+					try {
+						session.getBatcher().closeStatement( ps );
+					}
+					catch( Throwable ignore ) {
+						// ignore
+					}
+				}
+			}
+		}
+	}
+
+	protected void coordinateSharedCacheCleanup(SessionImplementor session) {
+		BulkOperationCleanupAction action = new BulkOperationCleanupAction( session, getAffectedQueryables() );
+
+		action.init();
+
+		if ( session.isEventSource() ) {
+			( ( EventSource ) session ).getActionQueue().addAction( action );
+		}
+	}
+
+	protected boolean shouldIsolateTemporaryTableDDL() {
+		Boolean dialectVote = getFactory().getDialect().performTemporaryTableDDLInIsolation();
+		if ( dialectVote != null ) {
+			return dialectVote.booleanValue();
+		}
+		else {
+			return getFactory().getSettings().isDataDefinitionImplicitCommit();
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,96 +0,0 @@
-// $Id: BasicExecutor.java 9242 2006-02-09 12:37:36Z steveebersole $
-package org.hibernate.hql.ast.exec;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.QuerySyntaxException;
-import org.hibernate.hql.ast.SqlGenerator;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.persister.entity.Queryable;
-
-import antlr.RecognitionException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of BasicExecutor.
- *
- * @author Steve Ebersole
- */
-public class BasicExecutor extends AbstractStatementExecutor {
-	private static final Logger log = LoggerFactory.getLogger( BasicExecutor.class );
-
-	private final Queryable persister;
-	private final String sql;
-
-	public BasicExecutor(HqlSqlWalker walker, Queryable persister) {
-		super( walker, log );
-		this.persister = persister;
-		try {
-			SqlGenerator gen = new SqlGenerator( getFactory() );
-			gen.statement( walker.getAST() );
-			sql = gen.getSQL();
-			gen.getParseErrorHandler().throwQueryException();
-		}
-		catch ( RecognitionException e ) {
-			throw QuerySyntaxException.convert( e );
-		}
-	}
-
-	public String[] getSqlStatements() {
-		return new String[] { sql };
-	}
-
-	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
-
-		coordinateSharedCacheCleanup( session );
-
-		PreparedStatement st = null;
-		RowSelection selection = parameters.getRowSelection();
-
-		try {
-			try {
-				st = session.getBatcher().prepareStatement( sql );
-				Iterator paramSpecifications = getWalker().getParameters().iterator();
-				int pos = 1;
-				while ( paramSpecifications.hasNext() ) {
-					final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
-					pos += paramSpec.bind( st, parameters, session, pos );
-				}
-				if ( selection != null ) {
-					if ( selection.getTimeout() != null ) {
-						st.setQueryTimeout( selection.getTimeout().intValue() );
-					}
-				}
-
-				return st.executeUpdate();
-			}
-			finally {
-				if ( st != null ) {
-					session.getBatcher().closeStatement( st );
-				}
-			}
-		}
-		catch( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not execute update query",
-			        sql
-				);
-		}
-	}
-
-	protected Queryable[] getAffectedQueryables() {
-		return new Queryable[] { persister };
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/BasicExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,119 @@
+/*
+ * 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.exec;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.QuerySyntaxException;
+import org.hibernate.hql.ast.SqlGenerator;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.persister.entity.Queryable;
+
+import antlr.RecognitionException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of BasicExecutor.
+ *
+ * @author Steve Ebersole
+ */
+public class BasicExecutor extends AbstractStatementExecutor {
+	private static final Logger log = LoggerFactory.getLogger( BasicExecutor.class );
+
+	private final Queryable persister;
+	private final String sql;
+
+	public BasicExecutor(HqlSqlWalker walker, Queryable persister) {
+		super( walker, log );
+		this.persister = persister;
+		try {
+			SqlGenerator gen = new SqlGenerator( getFactory() );
+			gen.statement( walker.getAST() );
+			sql = gen.getSQL();
+			gen.getParseErrorHandler().throwQueryException();
+		}
+		catch ( RecognitionException e ) {
+			throw QuerySyntaxException.convert( e );
+		}
+	}
+
+	public String[] getSqlStatements() {
+		return new String[] { sql };
+	}
+
+	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
+
+		coordinateSharedCacheCleanup( session );
+
+		PreparedStatement st = null;
+		RowSelection selection = parameters.getRowSelection();
+
+		try {
+			try {
+				st = session.getBatcher().prepareStatement( sql );
+				Iterator paramSpecifications = getWalker().getParameters().iterator();
+				int pos = 1;
+				while ( paramSpecifications.hasNext() ) {
+					final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
+					pos += paramSpec.bind( st, parameters, session, pos );
+				}
+				if ( selection != null ) {
+					if ( selection.getTimeout() != null ) {
+						st.setQueryTimeout( selection.getTimeout().intValue() );
+					}
+				}
+
+				return st.executeUpdate();
+			}
+			finally {
+				if ( st != null ) {
+					session.getBatcher().closeStatement( st );
+				}
+			}
+		}
+		catch( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not execute update query",
+			        sql
+				);
+		}
+	}
+
+	protected Queryable[] getAffectedQueryables() {
+		return new Queryable[] { persister };
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,143 +0,0 @@
-// $Id: MultiTableDeleteExecutor.java 11288 2007-03-15 11:38:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.exec;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.tree.DeleteStatement;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.Delete;
-import org.hibernate.util.StringHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of MultiTableDeleteExecutor.
- *
- * @author Steve Ebersole
- */
-public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
-	private static final Logger log = LoggerFactory.getLogger( MultiTableDeleteExecutor.class );
-
-	private final Queryable persister;
-	private final String idInsertSelect;
-	private final String[] deletes;
-
-	public MultiTableDeleteExecutor(HqlSqlWalker walker) {
-		super( walker, log );
-
-		if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
-			throw new HibernateException( "cannot perform multi-table deletes using dialect not supporting temp tables" );
-		}
-
-		DeleteStatement deleteStatement = ( DeleteStatement ) walker.getAST();
-		FromElement fromElement = deleteStatement.getFromClause().getFromElement();
-		String bulkTargetAlias = fromElement.getTableAlias();
-		this.persister = fromElement.getQueryable();
-
-		this.idInsertSelect = generateIdInsertSelect( persister, bulkTargetAlias, deleteStatement.getWhereClause() );
-		log.trace( "Generated ID-INSERT-SELECT SQL (multi-table delete) : " +  idInsertSelect );
-
-		String[] tableNames = persister.getConstraintOrderedTableNameClosure();
-		String[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
-		String idSubselect = generateIdSubselect( persister );
-
-		deletes = new String[tableNames.length];
-		for ( int i = tableNames.length - 1; i >= 0; i-- ) {
-			// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
-			//      the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
-			//          the table info gotten here should really be self-contained (i.e., a class representation
-			//          defining all the needed attributes), then we could then get an array of those
-			final Delete delete = new Delete()
-					.setTableName( tableNames[i] )
-					.setWhere( "(" + StringHelper.join( ", ", columnNames[i] ) + ") IN (" + idSubselect + ")" );
-			if ( getFactory().getSettings().isCommentsEnabled() ) {
-				delete.setComment( "bulk delete" );
-			}
-
-			deletes[i] = delete.toStatementString();
-		}
-	}
-
-	public String[] getSqlStatements() {
-		return deletes;
-	}
-
-	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
-		coordinateSharedCacheCleanup( session );
-
-		createTemporaryTableIfNecessary( persister, session );
-
-		try {
-			// First, save off the pertinent ids, saving the number of pertinent ids for return
-			PreparedStatement ps = null;
-			int resultCount = 0;
-			try {
-				try {
-					ps = session.getBatcher().prepareStatement( idInsertSelect );
-					Iterator paramSpecifications = getWalker().getParameters().iterator();
-					int pos = 1;
-					while ( paramSpecifications.hasNext() ) {
-						final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
-						pos += paramSpec.bind( ps, parameters, session, pos );
-					}
-					resultCount = ps.executeUpdate();
-				}
-				finally {
-					if ( ps != null ) {
-						session.getBatcher().closeStatement( ps );
-					}
-				}
-			}
-			catch( SQLException e ) {
-				throw JDBCExceptionHelper.convert(
-						getFactory().getSQLExceptionConverter(),
-				        e,
-				        "could not insert/select ids for bulk delete",
-				        idInsertSelect
-					);
-			}
-
-			// Start performing the deletes
-			for ( int i = 0; i < deletes.length; i++ ) {
-				try {
-					try {
-						ps = session.getBatcher().prepareStatement( deletes[i] );
-						ps.executeUpdate();
-					}
-					finally {
-						if ( ps != null ) {
-							session.getBatcher().closeStatement( ps );
-						}
-					}
-				}
-				catch( SQLException e ) {
-					throw JDBCExceptionHelper.convert(
-							getFactory().getSQLExceptionConverter(),
-					        e,
-					        "error performing bulk delete",
-					        deletes[i]
-						);
-				}
-			}
-
-			return resultCount;
-		}
-		finally {
-			dropTemporaryTableIfNecessary( persister, session );
-		}
-	}
-
-	protected Queryable[] getAffectedQueryables() {
-		return new Queryable[] { persister };
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableDeleteExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,166 @@
+/*
+ * 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.exec;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.tree.DeleteStatement;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.Delete;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of MultiTableDeleteExecutor.
+ *
+ * @author Steve Ebersole
+ */
+public class MultiTableDeleteExecutor extends AbstractStatementExecutor {
+	private static final Logger log = LoggerFactory.getLogger( MultiTableDeleteExecutor.class );
+
+	private final Queryable persister;
+	private final String idInsertSelect;
+	private final String[] deletes;
+
+	public MultiTableDeleteExecutor(HqlSqlWalker walker) {
+		super( walker, log );
+
+		if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
+			throw new HibernateException( "cannot perform multi-table deletes using dialect not supporting temp tables" );
+		}
+
+		DeleteStatement deleteStatement = ( DeleteStatement ) walker.getAST();
+		FromElement fromElement = deleteStatement.getFromClause().getFromElement();
+		String bulkTargetAlias = fromElement.getTableAlias();
+		this.persister = fromElement.getQueryable();
+
+		this.idInsertSelect = generateIdInsertSelect( persister, bulkTargetAlias, deleteStatement.getWhereClause() );
+		log.trace( "Generated ID-INSERT-SELECT SQL (multi-table delete) : " +  idInsertSelect );
+
+		String[] tableNames = persister.getConstraintOrderedTableNameClosure();
+		String[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
+		String idSubselect = generateIdSubselect( persister );
+
+		deletes = new String[tableNames.length];
+		for ( int i = tableNames.length - 1; i >= 0; i-- ) {
+			// TODO : an optimization here would be to consider cascade deletes and not gen those delete statements;
+			//      the difficulty is the ordering of the tables here vs the cascade attributes on the persisters ->
+			//          the table info gotten here should really be self-contained (i.e., a class representation
+			//          defining all the needed attributes), then we could then get an array of those
+			final Delete delete = new Delete()
+					.setTableName( tableNames[i] )
+					.setWhere( "(" + StringHelper.join( ", ", columnNames[i] ) + ") IN (" + idSubselect + ")" );
+			if ( getFactory().getSettings().isCommentsEnabled() ) {
+				delete.setComment( "bulk delete" );
+			}
+
+			deletes[i] = delete.toStatementString();
+		}
+	}
+
+	public String[] getSqlStatements() {
+		return deletes;
+	}
+
+	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
+		coordinateSharedCacheCleanup( session );
+
+		createTemporaryTableIfNecessary( persister, session );
+
+		try {
+			// First, save off the pertinent ids, saving the number of pertinent ids for return
+			PreparedStatement ps = null;
+			int resultCount = 0;
+			try {
+				try {
+					ps = session.getBatcher().prepareStatement( idInsertSelect );
+					Iterator paramSpecifications = getWalker().getParameters().iterator();
+					int pos = 1;
+					while ( paramSpecifications.hasNext() ) {
+						final ParameterSpecification paramSpec = ( ParameterSpecification ) paramSpecifications.next();
+						pos += paramSpec.bind( ps, parameters, session, pos );
+					}
+					resultCount = ps.executeUpdate();
+				}
+				finally {
+					if ( ps != null ) {
+						session.getBatcher().closeStatement( ps );
+					}
+				}
+			}
+			catch( SQLException e ) {
+				throw JDBCExceptionHelper.convert(
+						getFactory().getSQLExceptionConverter(),
+				        e,
+				        "could not insert/select ids for bulk delete",
+				        idInsertSelect
+					);
+			}
+
+			// Start performing the deletes
+			for ( int i = 0; i < deletes.length; i++ ) {
+				try {
+					try {
+						ps = session.getBatcher().prepareStatement( deletes[i] );
+						ps.executeUpdate();
+					}
+					finally {
+						if ( ps != null ) {
+							session.getBatcher().closeStatement( ps );
+						}
+					}
+				}
+				catch( SQLException e ) {
+					throw JDBCExceptionHelper.convert(
+							getFactory().getSQLExceptionConverter(),
+					        e,
+					        "error performing bulk delete",
+					        deletes[i]
+						);
+				}
+			}
+
+			return resultCount;
+		}
+		finally {
+			dropTemporaryTableIfNecessary( persister, session );
+		}
+	}
+
+	protected Queryable[] getAffectedQueryables() {
+		return new Queryable[] { persister };
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,177 +0,0 @@
-// $Id: MultiTableUpdateExecutor.java 11288 2007-03-15 11:38:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.exec;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.tree.AssignmentSpecification;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.UpdateStatement;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.Update;
-import org.hibernate.util.StringHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implementation of MultiTableUpdateExecutor.
- *
- * @author Steve Ebersole
- */
-public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
-	private static final Logger log = LoggerFactory.getLogger( MultiTableUpdateExecutor.class );
-
-	private final Queryable persister;
-	private final String idInsertSelect;
-	private final String[] updates;
-	private final ParameterSpecification[][] hqlParameters;
-
-	public MultiTableUpdateExecutor(HqlSqlWalker walker) {
-		super( walker, log );
-
-		if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
-			throw new HibernateException( "cannot perform multi-table updates using dialect not supporting temp tables" );
-		}
-
-		UpdateStatement updateStatement = ( UpdateStatement ) walker.getAST();
-		FromElement fromElement = updateStatement.getFromClause().getFromElement();
-		String bulkTargetAlias = fromElement.getTableAlias();
-		this.persister = fromElement.getQueryable();
-
-		this.idInsertSelect = generateIdInsertSelect( persister, bulkTargetAlias, updateStatement.getWhereClause() );
-		log.trace( "Generated ID-INSERT-SELECT SQL (multi-table update) : " +  idInsertSelect );
-
-		String[] tableNames = persister.getConstraintOrderedTableNameClosure();
-		String[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
-
-		String idSubselect = generateIdSubselect( persister );
-		List assignmentSpecifications = walker.getAssignmentSpecifications();
-
-		updates = new String[tableNames.length];
-		hqlParameters = new ParameterSpecification[tableNames.length][];
-		for ( int tableIndex = 0; tableIndex < tableNames.length; tableIndex++ ) {
-			boolean affected = false;
-			List parameterList = new ArrayList();
-			Update update = new Update( getFactory().getDialect() )
-					.setTableName( tableNames[tableIndex] )
-					.setWhere( "(" + StringHelper.join( ", ", columnNames[tableIndex] ) + ") IN (" + idSubselect + ")" );
-			if ( getFactory().getSettings().isCommentsEnabled() ) {
-				update.setComment( "bulk update" );
-			}
-			final Iterator itr = assignmentSpecifications.iterator();
-			while ( itr.hasNext() ) {
-				final AssignmentSpecification specification = ( AssignmentSpecification ) itr.next();
-				if ( specification.affectsTable( tableNames[tableIndex] ) ) {
-					affected = true;
-					update.appendAssignmentFragment( specification.getSqlAssignmentFragment() );
-					if ( specification.getParameters() != null ) {
-						for ( int paramIndex = 0; paramIndex < specification.getParameters().length; paramIndex++ ) {
-							parameterList.add( specification.getParameters()[paramIndex] );
-						}
-					}
-				}
-			}
-			if ( affected ) {
-				updates[tableIndex] = update.toStatementString();
-				hqlParameters[tableIndex] = ( ParameterSpecification[] ) parameterList.toArray( new ParameterSpecification[0] );
-			}
-		}
-	}
-
-	public Queryable getAffectedQueryable() {
-		return persister;
-	}
-
-	public String[] getSqlStatements() {
-		return updates;
-	}
-
-	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
-		coordinateSharedCacheCleanup( session );
-
-		createTemporaryTableIfNecessary( persister, session );
-
-		try {
-			// First, save off the pertinent ids, as the return value
-			PreparedStatement ps = null;
-			int resultCount = 0;
-			try {
-				try {
-					ps = session.getBatcher().prepareStatement( idInsertSelect );
-					int parameterStart = getWalker().getNumberOfParametersInSetClause();
-					List allParams = getWalker().getParameters();
-					Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
-					int sum = 1; // jdbc params are 1-based
-					while ( whereParams.hasNext() ) {
-						sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
-					}
-					resultCount = ps.executeUpdate();
-				}
-				finally {
-					if ( ps != null ) {
-						session.getBatcher().closeStatement( ps );
-					}
-				}
-			}
-			catch( SQLException e ) {
-				throw JDBCExceptionHelper.convert(
-						getFactory().getSQLExceptionConverter(),
-				        e,
-				        "could not insert/select ids for bulk update",
-				        idInsertSelect
-					);
-			}
-
-			// Start performing the updates
-			for ( int i = 0; i < updates.length; i++ ) {
-				if ( updates[i] == null ) {
-					continue;
-				}
-				try {
-					try {
-						ps = session.getBatcher().prepareStatement( updates[i] );
-						if ( hqlParameters[i] != null ) {
-							int position = 1; // jdbc params are 1-based
-							for ( int x = 0; x < hqlParameters[i].length; x++ ) {
-								position += hqlParameters[i][x].bind( ps, parameters, session, position );
-							}
-						}
-						ps.executeUpdate();
-					}
-					finally {
-						if ( ps != null ) {
-							session.getBatcher().closeStatement( ps );
-						}
-					}
-				}
-				catch( SQLException e ) {
-					throw JDBCExceptionHelper.convert(
-							getFactory().getSQLExceptionConverter(),
-					        e,
-					        "error performing bulk update",
-					        updates[i]
-						);
-				}
-			}
-
-			return resultCount;
-		}
-		finally {
-			dropTemporaryTableIfNecessary( persister, session );
-		}
-	}
-
-	protected Queryable[] getAffectedQueryables() {
-		return new Queryable[] { persister };
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/MultiTableUpdateExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,200 @@
+/*
+ * 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.exec;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.tree.AssignmentSpecification;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.UpdateStatement;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.Update;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of MultiTableUpdateExecutor.
+ *
+ * @author Steve Ebersole
+ */
+public class MultiTableUpdateExecutor extends AbstractStatementExecutor {
+	private static final Logger log = LoggerFactory.getLogger( MultiTableUpdateExecutor.class );
+
+	private final Queryable persister;
+	private final String idInsertSelect;
+	private final String[] updates;
+	private final ParameterSpecification[][] hqlParameters;
+
+	public MultiTableUpdateExecutor(HqlSqlWalker walker) {
+		super( walker, log );
+
+		if ( !walker.getSessionFactoryHelper().getFactory().getDialect().supportsTemporaryTables() ) {
+			throw new HibernateException( "cannot perform multi-table updates using dialect not supporting temp tables" );
+		}
+
+		UpdateStatement updateStatement = ( UpdateStatement ) walker.getAST();
+		FromElement fromElement = updateStatement.getFromClause().getFromElement();
+		String bulkTargetAlias = fromElement.getTableAlias();
+		this.persister = fromElement.getQueryable();
+
+		this.idInsertSelect = generateIdInsertSelect( persister, bulkTargetAlias, updateStatement.getWhereClause() );
+		log.trace( "Generated ID-INSERT-SELECT SQL (multi-table update) : " +  idInsertSelect );
+
+		String[] tableNames = persister.getConstraintOrderedTableNameClosure();
+		String[][] columnNames = persister.getContraintOrderedTableKeyColumnClosure();
+
+		String idSubselect = generateIdSubselect( persister );
+		List assignmentSpecifications = walker.getAssignmentSpecifications();
+
+		updates = new String[tableNames.length];
+		hqlParameters = new ParameterSpecification[tableNames.length][];
+		for ( int tableIndex = 0; tableIndex < tableNames.length; tableIndex++ ) {
+			boolean affected = false;
+			List parameterList = new ArrayList();
+			Update update = new Update( getFactory().getDialect() )
+					.setTableName( tableNames[tableIndex] )
+					.setWhere( "(" + StringHelper.join( ", ", columnNames[tableIndex] ) + ") IN (" + idSubselect + ")" );
+			if ( getFactory().getSettings().isCommentsEnabled() ) {
+				update.setComment( "bulk update" );
+			}
+			final Iterator itr = assignmentSpecifications.iterator();
+			while ( itr.hasNext() ) {
+				final AssignmentSpecification specification = ( AssignmentSpecification ) itr.next();
+				if ( specification.affectsTable( tableNames[tableIndex] ) ) {
+					affected = true;
+					update.appendAssignmentFragment( specification.getSqlAssignmentFragment() );
+					if ( specification.getParameters() != null ) {
+						for ( int paramIndex = 0; paramIndex < specification.getParameters().length; paramIndex++ ) {
+							parameterList.add( specification.getParameters()[paramIndex] );
+						}
+					}
+				}
+			}
+			if ( affected ) {
+				updates[tableIndex] = update.toStatementString();
+				hqlParameters[tableIndex] = ( ParameterSpecification[] ) parameterList.toArray( new ParameterSpecification[0] );
+			}
+		}
+	}
+
+	public Queryable getAffectedQueryable() {
+		return persister;
+	}
+
+	public String[] getSqlStatements() {
+		return updates;
+	}
+
+	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException {
+		coordinateSharedCacheCleanup( session );
+
+		createTemporaryTableIfNecessary( persister, session );
+
+		try {
+			// First, save off the pertinent ids, as the return value
+			PreparedStatement ps = null;
+			int resultCount = 0;
+			try {
+				try {
+					ps = session.getBatcher().prepareStatement( idInsertSelect );
+					int parameterStart = getWalker().getNumberOfParametersInSetClause();
+					List allParams = getWalker().getParameters();
+					Iterator whereParams = allParams.subList( parameterStart, allParams.size() ).iterator();
+					int sum = 1; // jdbc params are 1-based
+					while ( whereParams.hasNext() ) {
+						sum += ( ( ParameterSpecification ) whereParams.next() ).bind( ps, parameters, session, sum );
+					}
+					resultCount = ps.executeUpdate();
+				}
+				finally {
+					if ( ps != null ) {
+						session.getBatcher().closeStatement( ps );
+					}
+				}
+			}
+			catch( SQLException e ) {
+				throw JDBCExceptionHelper.convert(
+						getFactory().getSQLExceptionConverter(),
+				        e,
+				        "could not insert/select ids for bulk update",
+				        idInsertSelect
+					);
+			}
+
+			// Start performing the updates
+			for ( int i = 0; i < updates.length; i++ ) {
+				if ( updates[i] == null ) {
+					continue;
+				}
+				try {
+					try {
+						ps = session.getBatcher().prepareStatement( updates[i] );
+						if ( hqlParameters[i] != null ) {
+							int position = 1; // jdbc params are 1-based
+							for ( int x = 0; x < hqlParameters[i].length; x++ ) {
+								position += hqlParameters[i][x].bind( ps, parameters, session, position );
+							}
+						}
+						ps.executeUpdate();
+					}
+					finally {
+						if ( ps != null ) {
+							session.getBatcher().closeStatement( ps );
+						}
+					}
+				}
+				catch( SQLException e ) {
+					throw JDBCExceptionHelper.convert(
+							getFactory().getSQLExceptionConverter(),
+					        e,
+					        "error performing bulk update",
+					        updates[i]
+						);
+				}
+			}
+
+			return resultCount;
+		}
+		finally {
+			dropTemporaryTableIfNecessary( persister, session );
+		}
+	}
+
+	protected Queryable[] getAffectedQueryables() {
+		return new Queryable[] { persister };
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-// $Id: StatementExecutor.java 8631 2005-11-21 17:02:24Z steveebersole $
-package org.hibernate.hql.ast.exec;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Encapsulates the strategy required to execute various types of update, delete,
- * and insert statements issued through HQL.
- *
- * @author Steve Ebersole
- */
-public interface StatementExecutor {
-
-	public String[] getSqlStatements();
-
-	/**
-	 * Execute the sql managed by this executor using the given parameters.
-	 *
-	 * @param parameters Essentially bind information for this processing.
-	 * @param session The session originating the request.
-	 * @return The number of entities updated/deleted.
-	 * @throws HibernateException
-	 */
-	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/exec/StatementExecutor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.exec;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Encapsulates the strategy required to execute various types of update, delete,
+ * and insert statements issued through HQL.
+ *
+ * @author Steve Ebersole
+ */
+public interface StatementExecutor {
+
+	public String[] getSqlStatements();
+
+	/**
+	 * Execute the sql managed by this executor using the given parameters.
+	 *
+	 * @param parameters Essentially bind information for this processing.
+	 * @param session The session originating the request.
+	 * @return The number of entities updated/deleted.
+	 * @throws HibernateException
+	 */
+	public int execute(QueryParameters parameters, SessionImplementor session) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,6 +0,0 @@
-<html><head></head><body>
-<p>An ANTLR-based parser for Hibernate Query Language.</p>
-<p>
-	Classes in this package extend the ANTLR-generated parser classes.
-</p>
-</body></html>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html><head></head><body>
+<p>An ANTLR-based parser for Hibernate Query Language.</p>
+<p>
+	Classes in this package extend the ANTLR-generated parser classes.
+</p>
+</body></html>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.hql.ast.tree;
-
-import antlr.collections.AST;
-
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.util.StringHelper;
-import org.hibernate.HibernateException;
-
-/**
- * Base class for nodes dealing 'is null' and 'is not null' operators.
- * <p/>
- * todo : a good deal of this is copied from BinaryLogicOperatorNode; look at consolidating these code fragments
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractNullnessCheckNode extends UnaryLogicOperatorNode {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void initialize() {
-		// TODO : this really needs to be delayed unitl after we definitively know the operand node type;
-		// where this is currently a problem is parameters for which where we cannot unequivocally
-		// resolve an expected type
-		Type operandType = extractDataType( getOperand() );
-		if ( operandType == null ) {
-			return;
-		}
-		SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
-		int operandColumnSpan = operandType.getColumnSpan( sessionFactory );
-		if ( operandColumnSpan > 1 ) {
-			mutateRowValueConstructorSyntax( operandColumnSpan );
-		}
-	}
-
-	/**
-	 * When (if) we need to expand a row value constructor, what is the type of connector to use between the
-	 * expansion fragments.
-	 *
-	 * @return The expansion connector type.
-	 */
-	protected abstract int getExpansionConnectorType();
-
-	/**
-	 * When (if) we need to expand a row value constructor, what is the text of the connector to use between the
-	 * expansion fragments.
-	 *
-	 * @return The expansion connector text.
-	 */
-	protected abstract String getExpansionConnectorText();
-
-	private void mutateRowValueConstructorSyntax(int operandColumnSpan) {
-		final int comparisonType = getType();
-		final String comparisonText = getText();
-
-		final int expansionConnectorType = getExpansionConnectorType();
-		final String expansionConnectorText = getExpansionConnectorText();
-
-		setType( expansionConnectorType );
-		setText( expansionConnectorText );
-
-		String[] mutationTexts = extractMutationTexts( getOperand(), operandColumnSpan );
-
-		AST container = this;
-		for ( int i = operandColumnSpan - 1; i > 0; i-- ) {
-			if ( i == 1 ) {
-				AST op1 = getASTFactory().create( comparisonType, comparisonText );
-				AST operand1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[0] );
-				op1.setFirstChild( operand1 );
-				container.setFirstChild( op1 );
-				AST op2 = getASTFactory().create( comparisonType, comparisonText );
-				AST operand2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[1] );
-				op2.setFirstChild( operand2 );
-				op1.setNextSibling( op2 );
-			}
-			else {
-				AST op = getASTFactory().create( comparisonType, comparisonText );
-				AST operand = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[i] );
-				op.setFirstChild( operand );
-				AST newContainer = getASTFactory().create( expansionConnectorType, expansionConnectorText );
-				container.setFirstChild( newContainer );
-				newContainer.setNextSibling( op );
-				container = newContainer;
-			}
-		}
-	}
-
-	private static Type extractDataType(Node operand) {
-		Type type = null;
-		if ( operand instanceof SqlNode ) {
-			type = ( ( SqlNode ) operand ).getDataType();
-		}
-		if ( type == null && operand instanceof ExpectedTypeAwareNode ) {
-			type = ( ( ExpectedTypeAwareNode ) operand ).getExpectedType();
-		}
-		return type;
-	}
-
-	private static String[] extractMutationTexts(Node operand, int count) {
-		if ( operand instanceof ParameterNode ) {
-			String[] rtn = new String[count];
-			for ( int i = 0; i < count; i++ ) {
-				rtn[i] = "?";
-			}
-			return rtn;
-		}
-		else if ( operand.getType() == HqlSqlTokenTypes.VECTOR_EXPR ) {
-			String[] rtn = new String[ operand.getNumberOfChildren() ];
-			int x = 0;
-			AST node = operand.getFirstChild();
-			while ( node != null ) {
-				rtn[ x++ ] = node.getText();
-				node = node.getNextSibling();
-			}
-			return rtn;
-		}
-		else if ( operand instanceof SqlNode ) {
-			String nodeText = operand.getText();
-			if ( nodeText.startsWith( "(" ) ) {
-				nodeText = nodeText.substring( 1 );
-			}
-			if ( nodeText.endsWith( ")" ) ) {
-				nodeText = nodeText.substring( 0, nodeText.length() - 1 );
-			}
-			String[] splits = StringHelper.split( ", ", nodeText );
-			if ( count != splits.length ) {
-				throw new HibernateException( "SqlNode's text did not reference expected number of columns" );
-			}
-			return splits;
-		}
-		else {
-			throw new HibernateException( "dont know how to extract row value elements from node : " + operand );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractNullnessCheckNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,161 @@
+/*
+ * 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.tree;
+
+import antlr.collections.AST;
+
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.util.StringHelper;
+import org.hibernate.HibernateException;
+
+/**
+ * Base class for nodes dealing 'is null' and 'is not null' operators.
+ * <p/>
+ * todo : a good deal of this is copied from BinaryLogicOperatorNode; look at consolidating these code fragments
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractNullnessCheckNode extends UnaryLogicOperatorNode {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void initialize() {
+		// TODO : this really needs to be delayed unitl after we definitively know the operand node type;
+		// where this is currently a problem is parameters for which where we cannot unequivocally
+		// resolve an expected type
+		Type operandType = extractDataType( getOperand() );
+		if ( operandType == null ) {
+			return;
+		}
+		SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
+		int operandColumnSpan = operandType.getColumnSpan( sessionFactory );
+		if ( operandColumnSpan > 1 ) {
+			mutateRowValueConstructorSyntax( operandColumnSpan );
+		}
+	}
+
+	/**
+	 * When (if) we need to expand a row value constructor, what is the type of connector to use between the
+	 * expansion fragments.
+	 *
+	 * @return The expansion connector type.
+	 */
+	protected abstract int getExpansionConnectorType();
+
+	/**
+	 * When (if) we need to expand a row value constructor, what is the text of the connector to use between the
+	 * expansion fragments.
+	 *
+	 * @return The expansion connector text.
+	 */
+	protected abstract String getExpansionConnectorText();
+
+	private void mutateRowValueConstructorSyntax(int operandColumnSpan) {
+		final int comparisonType = getType();
+		final String comparisonText = getText();
+
+		final int expansionConnectorType = getExpansionConnectorType();
+		final String expansionConnectorText = getExpansionConnectorText();
+
+		setType( expansionConnectorType );
+		setText( expansionConnectorText );
+
+		String[] mutationTexts = extractMutationTexts( getOperand(), operandColumnSpan );
+
+		AST container = this;
+		for ( int i = operandColumnSpan - 1; i > 0; i-- ) {
+			if ( i == 1 ) {
+				AST op1 = getASTFactory().create( comparisonType, comparisonText );
+				AST operand1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[0] );
+				op1.setFirstChild( operand1 );
+				container.setFirstChild( op1 );
+				AST op2 = getASTFactory().create( comparisonType, comparisonText );
+				AST operand2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[1] );
+				op2.setFirstChild( operand2 );
+				op1.setNextSibling( op2 );
+			}
+			else {
+				AST op = getASTFactory().create( comparisonType, comparisonText );
+				AST operand = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, mutationTexts[i] );
+				op.setFirstChild( operand );
+				AST newContainer = getASTFactory().create( expansionConnectorType, expansionConnectorText );
+				container.setFirstChild( newContainer );
+				newContainer.setNextSibling( op );
+				container = newContainer;
+			}
+		}
+	}
+
+	private static Type extractDataType(Node operand) {
+		Type type = null;
+		if ( operand instanceof SqlNode ) {
+			type = ( ( SqlNode ) operand ).getDataType();
+		}
+		if ( type == null && operand instanceof ExpectedTypeAwareNode ) {
+			type = ( ( ExpectedTypeAwareNode ) operand ).getExpectedType();
+		}
+		return type;
+	}
+
+	private static String[] extractMutationTexts(Node operand, int count) {
+		if ( operand instanceof ParameterNode ) {
+			String[] rtn = new String[count];
+			for ( int i = 0; i < count; i++ ) {
+				rtn[i] = "?";
+			}
+			return rtn;
+		}
+		else if ( operand.getType() == HqlSqlTokenTypes.VECTOR_EXPR ) {
+			String[] rtn = new String[ operand.getNumberOfChildren() ];
+			int x = 0;
+			AST node = operand.getFirstChild();
+			while ( node != null ) {
+				rtn[ x++ ] = node.getText();
+				node = node.getNextSibling();
+			}
+			return rtn;
+		}
+		else if ( operand instanceof SqlNode ) {
+			String nodeText = operand.getText();
+			if ( nodeText.startsWith( "(" ) ) {
+				nodeText = nodeText.substring( 1 );
+			}
+			if ( nodeText.endsWith( ")" ) ) {
+				nodeText = nodeText.substring( 0, nodeText.length() - 1 );
+			}
+			String[] splits = StringHelper.split( ", ", nodeText );
+			if ( count != splits.length ) {
+				throw new HibernateException( "SqlNode's text did not reference expected number of columns" );
+			}
+			return splits;
+		}
+		else {
+			throw new HibernateException( "dont know how to extract row value elements from node : " + operand );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,64 +0,0 @@
-// $Id: AbstractRestrictableStatement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-
-/**
- * Convenience implementation of RestrictableStatement to centralize common functionality.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractRestrictableStatement extends AbstractStatement implements RestrictableStatement {
-
-	private FromClause fromClause;
-	private AST whereClause;
-
-	protected abstract int getWhereClauseParentTokenType();
-	protected abstract Logger getLog();
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.RestrictableStatement#getFromClause
-	 */
-	public final FromClause getFromClause() {
-		if ( fromClause == null ) {
-			fromClause = ( FromClause ) ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.FROM );
-		}
-		return fromClause;
-	}
-
-	/**
-	 * @see RestrictableStatement#hasWhereClause
-	 */
-	public final boolean hasWhereClause() {
-		AST whereClause = locateWhereClause();
-		return whereClause != null && whereClause.getNumberOfChildren() > 0;
-	}
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.RestrictableStatement#getWhereClause
-	 */
-	public final AST getWhereClause() {
-		if ( whereClause == null ) {
-			whereClause = locateWhereClause();
-			// If there is no WHERE node, make one.
-			if ( whereClause == null ) {
-				getLog().debug( "getWhereClause() : Creating a new WHERE clause..." );
-				whereClause = ASTUtil.create( getWalker().getASTFactory(), HqlSqlTokenTypes.WHERE, "WHERE" );
-				// inject the WHERE after the parent
-				AST parent = ASTUtil.findTypeInChildren( this, getWhereClauseParentTokenType() );
-				whereClause.setNextSibling( parent.getNextSibling() );
-				parent.setNextSibling( whereClause );
-			}
-		}
-		return whereClause;
-	}
-
-	protected AST locateWhereClause() {
-		return ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.WHERE );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractRestrictableStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+
+/**
+ * Convenience implementation of {@link RestrictableStatement}
+ * to centralize common functionality.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractRestrictableStatement extends AbstractStatement implements RestrictableStatement {
+
+	private FromClause fromClause;
+	private AST whereClause;
+
+	protected abstract int getWhereClauseParentTokenType();
+	protected abstract Logger getLog();
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.RestrictableStatement#getFromClause
+	 */
+	public final FromClause getFromClause() {
+		if ( fromClause == null ) {
+			fromClause = ( FromClause ) ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.FROM );
+		}
+		return fromClause;
+	}
+
+	/**
+	 * @see RestrictableStatement#hasWhereClause
+	 */
+	public final boolean hasWhereClause() {
+		AST whereClause = locateWhereClause();
+		return whereClause != null && whereClause.getNumberOfChildren() > 0;
+	}
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.RestrictableStatement#getWhereClause
+	 */
+	public final AST getWhereClause() {
+		if ( whereClause == null ) {
+			whereClause = locateWhereClause();
+			// If there is no WHERE node, make one.
+			if ( whereClause == null ) {
+				getLog().debug( "getWhereClause() : Creating a new WHERE clause..." );
+				whereClause = ASTUtil.create( getWalker().getASTFactory(), HqlSqlTokenTypes.WHERE, "WHERE" );
+				// inject the WHERE after the parent
+				AST parent = ASTUtil.findTypeInChildren( this, getWhereClauseParentTokenType() );
+				whereClause.setNextSibling( parent.getNextSibling() );
+				parent.setNextSibling( whereClause );
+			}
+		}
+		return whereClause;
+	}
+
+	protected AST locateWhereClause() {
+		return ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.WHERE );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-// $Id: AbstractSelectExpression.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Partial implementation of SelectExpression for all the nodes that aren't constructors.
- *
- * @author josh Nov 11, 2004 7:09:11 AM
- */
-public abstract class AbstractSelectExpression extends HqlSqlWalkerNode implements SelectExpression {
-	
-	private String alias;
-	
-	public final void setAlias(String alias) {
-		this.alias = alias;
-	}
-	
-	public final String getAlias() {
-		return alias;
-	}
-
-	public boolean isConstructor() {
-		return false;
-	}
-
-	public boolean isReturnableEntity() throws SemanticException {
-		return false;
-	}
-
-	public FromElement getFromElement() {
-		return null;
-	}
-
-	public boolean isScalar() throws SemanticException {
-		// Default implementation:
-		// If this node has a data type, and that data type is not an association, then this is scalar.
-		Type type = getDataType();
-		return type != null && !type.isAssociationType();	// Moved here from SelectClause [jsd]
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractSelectExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Partial implementation of SelectExpression for all the nodes that aren't constructors.
+ *
+ * @author Joshua Davis
+ */
+public abstract class AbstractSelectExpression extends HqlSqlWalkerNode implements SelectExpression {
+	
+	private String alias;
+	
+	public final void setAlias(String alias) {
+		this.alias = alias;
+	}
+	
+	public final String getAlias() {
+		return alias;
+	}
+
+	public boolean isConstructor() {
+		return false;
+	}
+
+	public boolean isReturnableEntity() throws SemanticException {
+		return false;
+	}
+
+	public FromElement getFromElement() {
+		return null;
+	}
+
+	public boolean isScalar() throws SemanticException {
+		// Default implementation:
+		// If this node has a data type, and that data type is not an association, then this is scalar.
+		Type type = getDataType();
+		return type != null && !type.isAssociationType();	// Moved here from SelectClause [jsd]
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-// $Id: AbstractStatement.java 7486 2005-07-15 04:39:41Z oneovthafew $
-package org.hibernate.hql.ast.tree;
-
-import java.util.Iterator;
-
-/**
- * Convenience implementation of Statement to centralize common functionality.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractStatement extends HqlSqlWalkerNode implements DisplayableNode, Statement {
-
-	/**
-	 * Returns additional display text for the AST node.
-	 *
-	 * @return String - The additional display text.
-	 */
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		if ( getWalker().getQuerySpaces().size() > 0 ) {
-			buf.append( " querySpaces (" );
-			for ( Iterator iterator = getWalker().getQuerySpaces().iterator(); iterator.hasNext(); ) {
-				buf.append( iterator.next() );
-				if ( iterator.hasNext() ) {
-					buf.append( "," );
-				}
-			}
-			buf.append( ")" );
-		}
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AbstractStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import java.util.Iterator;
+
+/**
+ * Convenience implementation of Statement to centralize common functionality.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractStatement extends HqlSqlWalkerNode implements DisplayableNode, Statement {
+
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return String - The additional display text.
+	 */
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		if ( getWalker().getQuerySpaces().size() > 0 ) {
+			buf.append( " querySpaces (" );
+			for ( Iterator iterator = getWalker().getQuerySpaces().iterator(); iterator.hasNext(); ) {
+				buf.append( iterator.next() );
+				if ( iterator.hasNext() ) {
+					buf.append( "," );
+				}
+			}
+			buf.append( ")" );
+		}
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-// $Id: AggregateNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents an aggregate function i.e. min, max, sum, avg.
- *
- * @author josh Sep 21, 2004 9:22:02 PM
- */
-public class AggregateNode extends AbstractSelectExpression implements SelectExpression {
-
-	public AggregateNode() {
-	}
-
-	public Type getDataType() {
-		// Get the function return value type, based on the type of the first argument.
-		return getSessionFactoryHelper().findFunctionReturnType( getText(), getFirstChild() );
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AggregateNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents an aggregate function i.e. min, max, sum, avg.
+ *
+ * @author Joshua Davis
+ */
+public class AggregateNode extends AbstractSelectExpression implements SelectExpression {
+
+	public AggregateNode() {
+	}
+
+	public Type getDataType() {
+		// Get the function return value type, based on the type of the first argument.
+		return getSessionFactoryHelper().findFunctionReturnType( getText(), getFirstChild() );
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,143 +0,0 @@
-// $Id: AssignmentSpecification.java 8273 2005-09-30 17:54:42Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.SqlGenerator;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.persister.entity.UnionSubclassEntityPersister;
-
-import antlr.collections.AST;
-
-/**
- * Encapsulates the information relating to an individual assignment within the
- * set clause of an HQL update statement.  This information is used during execution
- * of the update statements when the updates occur against "multi-table" stuff.
- *
- * @author Steve Ebersole
- */
-public class AssignmentSpecification {
-
-	private final Set tableNames;
-	private final ParameterSpecification[] hqlParameters;
-	private final AST eq;
-	private final SessionFactoryImplementor factory;
-
-	private String sqlAssignmentString;
-
-	public AssignmentSpecification(AST eq, Queryable persister) {
-		if ( eq.getType() != HqlSqlTokenTypes.EQ ) {
-			throw new QueryException( "assignment in set-clause not associated with equals" );
-		}
-
-		this.eq = eq;
-		this.factory = persister.getFactory();
-
-		// Needed to bump this up to DotNode, because that is the only thing which currently
-		// knows about the property-ref path in the correct format; it is either this, or
-		// recurse over the DotNodes constructing the property path just like DotNode does
-		// internally
-		DotNode lhs = ( DotNode ) eq.getFirstChild();
-		SqlNode rhs = ( SqlNode ) lhs.getNextSibling();
-
-		validateLhs( lhs );
-
-		final String propertyPath = lhs.getPropertyPath();
-		Set temp = new HashSet();
-		// yuck!
-		if ( persister instanceof UnionSubclassEntityPersister ) {
-			UnionSubclassEntityPersister usep = ( UnionSubclassEntityPersister ) persister;
-			String[] tables = persister.getConstraintOrderedTableNameClosure();
-			int size = tables.length;
-			for ( int i = 0; i < size; i ++ ) {
-				temp.add( tables[i] );
-			}
-		}
-		else {
-			temp.add(
-					persister.getSubclassTableName( persister.getSubclassPropertyTableNumber( propertyPath ) )
-			);
-		}
-		this.tableNames = Collections.unmodifiableSet( temp );
-
-		if (rhs==null) {
-			hqlParameters = new ParameterSpecification[0];
-		}
-		else if ( isParam( rhs ) ) {
-			hqlParameters = new ParameterSpecification[] { ( ( ParameterNode ) rhs ).getHqlParameterSpecification() };
-		}
-		else {
-			List parameterList = ASTUtil.collectChildren(
-			        rhs,
-			        new ASTUtil.IncludePredicate() {
-				        public boolean include(AST node) {
-					        return isParam( node );
-			            }
-			        }
-			);
-			hqlParameters = new ParameterSpecification[ parameterList.size() ];
-			Iterator itr = parameterList.iterator();
-			int i = 0;
-			while( itr.hasNext() ) {
-				hqlParameters[i++] = ( ( ParameterNode ) itr.next() ).getHqlParameterSpecification();
-			}
-		}
-	}
-
-	public boolean affectsTable(String tableName) {
-		return this.tableNames.contains( tableName );
-	}
-
-	public ParameterSpecification[] getParameters() {
-		return hqlParameters;
-	}
-
-	public String getSqlAssignmentFragment() {
-		if ( sqlAssignmentString == null ) {
-			try {
-				SqlGenerator sqlGenerator = new SqlGenerator( factory );
-				sqlGenerator.comparisonExpr( eq, false );  // false indicates to not generate parens around the assignment
-				sqlAssignmentString = sqlGenerator.getSQL();
-			}
-			catch( Throwable t ) {
-				throw new QueryException( "cannot interpret set-clause assignment" );
-			}
-		}
-		return sqlAssignmentString;
-	}
-
-	private static boolean isParam(AST node) {
-		return node.getType() == HqlSqlTokenTypes.PARAM || node.getType() == HqlSqlTokenTypes.NAMED_PARAM;
-	}
-
-	private void validateLhs(FromReferenceNode lhs) {
-		// make sure the lhs is "assignable"...
-		if ( !lhs.isResolved() ) {
-			throw new UnsupportedOperationException( "cannot validate assignablity of unresolved node" );
-		}
-
-		if ( lhs.getDataType().isCollectionType() ) {
-			throw new QueryException( "collections not assignable in update statements" );
-		}
-		else if ( lhs.getDataType().isComponentType() ) {
-			throw new QueryException( "Components currently not assignable in update statements" );
-		}
-		else if ( lhs.getDataType().isEntityType() ) {
-			// currently allowed...
-		}
-
-		// TODO : why aren't these the same?
-		if ( lhs.getImpliedJoin() != null || lhs.getFromElement().isImplied() ) {
-			throw new QueryException( "Implied join paths are not assignable in update statements" );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/AssignmentSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,166 @@
+/*
+ * 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.tree;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.SqlGenerator;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+
+import antlr.collections.AST;
+
+/**
+ * Encapsulates the information relating to an individual assignment within the
+ * set clause of an HQL update statement.  This information is used during execution
+ * of the update statements when the updates occur against "multi-table" stuff.
+ *
+ * @author Steve Ebersole
+ */
+public class AssignmentSpecification {
+
+	private final Set tableNames;
+	private final ParameterSpecification[] hqlParameters;
+	private final AST eq;
+	private final SessionFactoryImplementor factory;
+
+	private String sqlAssignmentString;
+
+	public AssignmentSpecification(AST eq, Queryable persister) {
+		if ( eq.getType() != HqlSqlTokenTypes.EQ ) {
+			throw new QueryException( "assignment in set-clause not associated with equals" );
+		}
+
+		this.eq = eq;
+		this.factory = persister.getFactory();
+
+		// Needed to bump this up to DotNode, because that is the only thing which currently
+		// knows about the property-ref path in the correct format; it is either this, or
+		// recurse over the DotNodes constructing the property path just like DotNode does
+		// internally
+		DotNode lhs = ( DotNode ) eq.getFirstChild();
+		SqlNode rhs = ( SqlNode ) lhs.getNextSibling();
+
+		validateLhs( lhs );
+
+		final String propertyPath = lhs.getPropertyPath();
+		Set temp = new HashSet();
+		// yuck!
+		if ( persister instanceof UnionSubclassEntityPersister ) {
+			UnionSubclassEntityPersister usep = ( UnionSubclassEntityPersister ) persister;
+			String[] tables = persister.getConstraintOrderedTableNameClosure();
+			int size = tables.length;
+			for ( int i = 0; i < size; i ++ ) {
+				temp.add( tables[i] );
+			}
+		}
+		else {
+			temp.add(
+					persister.getSubclassTableName( persister.getSubclassPropertyTableNumber( propertyPath ) )
+			);
+		}
+		this.tableNames = Collections.unmodifiableSet( temp );
+
+		if (rhs==null) {
+			hqlParameters = new ParameterSpecification[0];
+		}
+		else if ( isParam( rhs ) ) {
+			hqlParameters = new ParameterSpecification[] { ( ( ParameterNode ) rhs ).getHqlParameterSpecification() };
+		}
+		else {
+			List parameterList = ASTUtil.collectChildren(
+			        rhs,
+			        new ASTUtil.IncludePredicate() {
+				        public boolean include(AST node) {
+					        return isParam( node );
+			            }
+			        }
+			);
+			hqlParameters = new ParameterSpecification[ parameterList.size() ];
+			Iterator itr = parameterList.iterator();
+			int i = 0;
+			while( itr.hasNext() ) {
+				hqlParameters[i++] = ( ( ParameterNode ) itr.next() ).getHqlParameterSpecification();
+			}
+		}
+	}
+
+	public boolean affectsTable(String tableName) {
+		return this.tableNames.contains( tableName );
+	}
+
+	public ParameterSpecification[] getParameters() {
+		return hqlParameters;
+	}
+
+	public String getSqlAssignmentFragment() {
+		if ( sqlAssignmentString == null ) {
+			try {
+				SqlGenerator sqlGenerator = new SqlGenerator( factory );
+				sqlGenerator.comparisonExpr( eq, false );  // false indicates to not generate parens around the assignment
+				sqlAssignmentString = sqlGenerator.getSQL();
+			}
+			catch( Throwable t ) {
+				throw new QueryException( "cannot interpret set-clause assignment" );
+			}
+		}
+		return sqlAssignmentString;
+	}
+
+	private static boolean isParam(AST node) {
+		return node.getType() == HqlSqlTokenTypes.PARAM || node.getType() == HqlSqlTokenTypes.NAMED_PARAM;
+	}
+
+	private void validateLhs(FromReferenceNode lhs) {
+		// make sure the lhs is "assignable"...
+		if ( !lhs.isResolved() ) {
+			throw new UnsupportedOperationException( "cannot validate assignablity of unresolved node" );
+		}
+
+		if ( lhs.getDataType().isCollectionType() ) {
+			throw new QueryException( "collections not assignable in update statements" );
+		}
+		else if ( lhs.getDataType().isComponentType() ) {
+			throw new QueryException( "Components currently not assignable in update statements" );
+		}
+		else if ( lhs.getDataType().isEntityType() ) {
+			// currently allowed...
+		}
+
+		// TODO : why aren't these the same?
+		if ( lhs.getImpliedJoin() != null || lhs.getFromElement().isImplied() ) {
+			throw new QueryException( "Implied join paths are not assignable in update statements" );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import org.hibernate.Hibernate;
-import antlr.SemanticException;
-
-/**
- * Contract for nodes representing logcial BETWEEN (ternary) operators.
- *
- * @author Steve Ebersole
- */
-public class BetweenOperatorNode extends SqlNode implements OperatorNode {
-
-	public void initialize() throws SemanticException {
-		Node fixture = getFixtureOperand();
-		if ( fixture == null ) {
-			throw new SemanticException( "fixture operand of a between operator was null" );
-		}
-		Node low = getLowOperand();
-		if ( low == null ) {
-			throw new SemanticException( "low operand of a between operator was null" );
-		}
-		Node high = getHighOperand();
-		if ( high == null ) {
-			throw new SemanticException( "high operand of a between operator was null" );
-		}
-		check( fixture, low, high );
-		check( low, high, fixture );
-		check( high, fixture, low );
-	}
-
-	public Type getDataType() {
-		// logic operators by definition resolve to boolean.
-		return Hibernate.BOOLEAN;
-	}
-
-	public Node getFixtureOperand() {
-		return ( Node ) getFirstChild();
-	}
-
-	public Node getLowOperand() {
-		return ( Node ) getFirstChild().getNextSibling();
-	}
-
-	public Node getHighOperand() {
-		return ( Node ) getFirstChild().getNextSibling().getNextSibling();
-	}
-
-	private void check(Node check, Node first, Node second) {
-		if ( ExpectedTypeAwareNode.class.isAssignableFrom( check.getClass() ) ) {
-			Type expectedType = null;
-			if ( SqlNode.class.isAssignableFrom( first.getClass() ) ) {
-				expectedType = ( ( SqlNode ) first ).getDataType();
-			}
-			if ( expectedType == null && SqlNode.class.isAssignableFrom( second.getClass() ) ) {
-				expectedType = ( ( SqlNode ) second ).getDataType();
-			}
-			( ( ExpectedTypeAwareNode ) check ).setExpectedType( expectedType );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BetweenOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import org.hibernate.Hibernate;
+import antlr.SemanticException;
+
+/**
+ * Contract for nodes representing logcial BETWEEN (ternary) operators.
+ *
+ * @author Steve Ebersole
+ */
+public class BetweenOperatorNode extends SqlNode implements OperatorNode {
+
+	public void initialize() throws SemanticException {
+		Node fixture = getFixtureOperand();
+		if ( fixture == null ) {
+			throw new SemanticException( "fixture operand of a between operator was null" );
+		}
+		Node low = getLowOperand();
+		if ( low == null ) {
+			throw new SemanticException( "low operand of a between operator was null" );
+		}
+		Node high = getHighOperand();
+		if ( high == null ) {
+			throw new SemanticException( "high operand of a between operator was null" );
+		}
+		check( fixture, low, high );
+		check( low, high, fixture );
+		check( high, fixture, low );
+	}
+
+	public Type getDataType() {
+		// logic operators by definition resolve to boolean.
+		return Hibernate.BOOLEAN;
+	}
+
+	public Node getFixtureOperand() {
+		return ( Node ) getFirstChild();
+	}
+
+	public Node getLowOperand() {
+		return ( Node ) getFirstChild().getNextSibling();
+	}
+
+	public Node getHighOperand() {
+		return ( Node ) getFirstChild().getNextSibling().getNextSibling();
+	}
+
+	private void check(Node check, Node first, Node second) {
+		if ( ExpectedTypeAwareNode.class.isAssignableFrom( check.getClass() ) ) {
+			Type expectedType = null;
+			if ( SqlNode.class.isAssignableFrom( first.getClass() ) ) {
+				expectedType = ( ( SqlNode ) first ).getDataType();
+			}
+			if ( expectedType == null && SqlNode.class.isAssignableFrom( second.getClass() ) ) {
+				expectedType = ( ( SqlNode ) second ).getDataType();
+			}
+			( ( ExpectedTypeAwareNode ) check ).setExpectedType( expectedType );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,191 +0,0 @@
-//$Id: BinaryArithmeticOperatorNode.java 10000 2006-06-08 21:04:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.Hibernate;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Nodes which represent binary arithmetic operators.
- *
- * @author Gavin King
- */
-public class BinaryArithmeticOperatorNode extends AbstractSelectExpression implements BinaryOperatorNode, DisplayableNode {
-
-	public void initialize() throws SemanticException {
-		Node lhs = getLeftHandOperand();
-		Node rhs = getRightHandOperand();
-		if ( lhs == null ) {
-			throw new SemanticException( "left-hand operand of a binary operator was null" );
-		}
-		if ( rhs == null ) {
-			throw new SemanticException( "right-hand operand of a binary operator was null" );
-		}
-
-		Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
-		Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
-
-		if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) && rhType != null ) {
-			Type expectedType = null;
-			// we have something like : "? [op] rhs"
-			if ( isDateTimeType( rhType ) ) {
-				// more specifically : "? [op] datetime"
-				//      1) if the operator is MINUS, the param needs to be of
-				//          some datetime type
-				//      2) if the operator is PLUS, the param needs to be of
-				//          some numeric type
-				expectedType = getType() == HqlSqlTokenTypes.PLUS ? Hibernate.DOUBLE : rhType;
-			}
-			else {
-				expectedType = rhType;
-			}
-			( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( expectedType );
-		}
-		else if ( ParameterNode.class.isAssignableFrom( rhs.getClass() ) && lhType != null ) {
-			Type expectedType = null;
-			// we have something like : "lhs [op] ?"
-			if ( isDateTimeType( lhType ) ) {
-				// more specifically : "datetime [op] ?"
-				//      1) if the operator is MINUS, we really cannot determine
-				//          the expected type as either another datetime or
-				//          numeric would be valid
-				//      2) if the operator is PLUS, the param needs to be of
-				//          some numeric type
-				if ( getType() == HqlSqlTokenTypes.PLUS ) {
-					expectedType = Hibernate.DOUBLE;
-				}
-			}
-			else {
-				expectedType = lhType;
-			}
-			( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( expectedType );
-		}
-	}
-
-	/**
-	 * Figure out the type of the binary expression by looking at
-	 * the types of the operands. Sometimes we don't know both types,
-	 * if, for example, one is a parameter.
-	 */
-	public Type getDataType() {
-		if ( super.getDataType() == null ) {
-			super.setDataType( resolveDataType() );
-		}
-		return super.getDataType();
-	}
-
-	private Type resolveDataType() {
-		// TODO : we may also want to check that the types here map to exactly one column/JDBC-type
-		//      can't think of a situation where arithmetic expression between multi-column mappings
-		//      makes any sense.
-		Node lhs = getLeftHandOperand();
-		Node rhs = getRightHandOperand();
-		Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
-		Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
-		if ( isDateTimeType( lhType ) || isDateTimeType( rhType ) ) {
-			return resolveDateTimeArithmeticResultType( lhType, rhType );
-		}
-		else {
-			if ( lhType == null ) {
-				if ( rhType == null ) {
-					// we do not know either type
-					return Hibernate.DOUBLE; //BLIND GUESS!
-				}
-				else {
-					// we know only the rhs-hand type, so use that
-					return rhType;
-				}
-			}
-			else {
-				if ( rhType == null ) {
-					// we know only the lhs-hand type, so use that
-					return lhType;
-				}
-				else {
-					if ( lhType==Hibernate.DOUBLE || rhType==Hibernate.DOUBLE ) return Hibernate.DOUBLE;
-					if ( lhType==Hibernate.FLOAT || rhType==Hibernate.FLOAT ) return Hibernate.FLOAT;
-					if ( lhType==Hibernate.BIG_DECIMAL || rhType==Hibernate.BIG_DECIMAL ) return Hibernate.BIG_DECIMAL;
-					if ( lhType==Hibernate.BIG_INTEGER || rhType==Hibernate.BIG_INTEGER ) return Hibernate.BIG_INTEGER;
-					if ( lhType==Hibernate.LONG || rhType==Hibernate.LONG ) return Hibernate.LONG;
-					if ( lhType==Hibernate.INTEGER || rhType==Hibernate.INTEGER ) return Hibernate.INTEGER;
-					return lhType;
-				}
-			}
-		}
-	}
-
-	private boolean isDateTimeType(Type type) {
-		if ( type == null ) {
-			return false;
-		}
-		return java.util.Date.class.isAssignableFrom( type.getReturnedClass() ) ||
-	           java.util.Calendar.class.isAssignableFrom( type.getReturnedClass() );
-	}
-
-	private Type resolveDateTimeArithmeticResultType(Type lhType, Type rhType) {
-		// here, we work under the following assumptions:
-		//      ------------ valid cases --------------------------------------
-		//      1) datetime + {something other than datetime} : always results
-		//              in a datetime ( db will catch invalid conversions )
-		//      2) datetime - datetime : always results in a DOUBLE
-		//      3) datetime - {something other than datetime} : always results
-		//              in a datetime ( db will catch invalid conversions )
-		//      ------------ invalid cases ------------------------------------
-		//      4) datetime + datetime
-		//      5) {something other than datetime} - datetime
-		//      6) datetime * {any type}
-		//      7) datetime / {any type}
-		//      8) {any type} / datetime
-		// doing so allows us to properly handle parameters as either the left
-		// or right side here in the majority of cases
-		boolean lhsIsDateTime = isDateTimeType( lhType );
-		boolean rhsIsDateTime = isDateTimeType( rhType );
-
-		// handle the (assumed) valid cases:
-		// #1 - the only valid datetime addition synatx is one or the other is a datetime (but not both)
-		if ( getType() == HqlSqlTokenTypes.PLUS ) {
-			// one or the other needs to be a datetime for us to get into this method in the first place...
-			return lhsIsDateTime ? lhType : rhType;
-		}
-		else if ( getType() == HqlSqlTokenTypes.MINUS ) {
-			// #3 - note that this is also true of "datetime - :param"...
-			if ( lhsIsDateTime && !rhsIsDateTime ) {
-				return lhType;
-			}
-			// #2
-			if ( lhsIsDateTime && rhsIsDateTime ) {
-				return Hibernate.DOUBLE;
-			}
-		}
-		return null;
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-	/**
-	 * Retrieves the left-hand operand of the operator.
-	 *
-	 * @return The left-hand operand
-	 */
-	public Node getLeftHandOperand() {
-		return ( Node ) getFirstChild();
-	}
-
-	/**
-	 * Retrieves the right-hand operand of the operator.
-	 *
-	 * @return The right-hand operand
-	 */
-	public Node getRightHandOperand() {
-		return ( Node ) getFirstChild().getNextSibling();
-	}
-
-	public String getDisplayText() {
-		return "{dataType=" + getDataType() + "}";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryArithmeticOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.Hibernate;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Nodes which represent binary arithmetic operators.
+ *
+ * @author Gavin King
+ */
+public class BinaryArithmeticOperatorNode extends AbstractSelectExpression implements BinaryOperatorNode, DisplayableNode {
+
+	public void initialize() throws SemanticException {
+		Node lhs = getLeftHandOperand();
+		Node rhs = getRightHandOperand();
+		if ( lhs == null ) {
+			throw new SemanticException( "left-hand operand of a binary operator was null" );
+		}
+		if ( rhs == null ) {
+			throw new SemanticException( "right-hand operand of a binary operator was null" );
+		}
+
+		Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
+		Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
+
+		if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) && rhType != null ) {
+			Type expectedType = null;
+			// we have something like : "? [op] rhs"
+			if ( isDateTimeType( rhType ) ) {
+				// more specifically : "? [op] datetime"
+				//      1) if the operator is MINUS, the param needs to be of
+				//          some datetime type
+				//      2) if the operator is PLUS, the param needs to be of
+				//          some numeric type
+				expectedType = getType() == HqlSqlTokenTypes.PLUS ? Hibernate.DOUBLE : rhType;
+			}
+			else {
+				expectedType = rhType;
+			}
+			( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( expectedType );
+		}
+		else if ( ParameterNode.class.isAssignableFrom( rhs.getClass() ) && lhType != null ) {
+			Type expectedType = null;
+			// we have something like : "lhs [op] ?"
+			if ( isDateTimeType( lhType ) ) {
+				// more specifically : "datetime [op] ?"
+				//      1) if the operator is MINUS, we really cannot determine
+				//          the expected type as either another datetime or
+				//          numeric would be valid
+				//      2) if the operator is PLUS, the param needs to be of
+				//          some numeric type
+				if ( getType() == HqlSqlTokenTypes.PLUS ) {
+					expectedType = Hibernate.DOUBLE;
+				}
+			}
+			else {
+				expectedType = lhType;
+			}
+			( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( expectedType );
+		}
+	}
+
+	/**
+	 * Figure out the type of the binary expression by looking at
+	 * the types of the operands. Sometimes we don't know both types,
+	 * if, for example, one is a parameter.
+	 */
+	public Type getDataType() {
+		if ( super.getDataType() == null ) {
+			super.setDataType( resolveDataType() );
+		}
+		return super.getDataType();
+	}
+
+	private Type resolveDataType() {
+		// TODO : we may also want to check that the types here map to exactly one column/JDBC-type
+		//      can't think of a situation where arithmetic expression between multi-column mappings
+		//      makes any sense.
+		Node lhs = getLeftHandOperand();
+		Node rhs = getRightHandOperand();
+		Type lhType = ( lhs instanceof SqlNode ) ? ( ( SqlNode ) lhs ).getDataType() : null;
+		Type rhType = ( rhs instanceof SqlNode ) ? ( ( SqlNode ) rhs ).getDataType() : null;
+		if ( isDateTimeType( lhType ) || isDateTimeType( rhType ) ) {
+			return resolveDateTimeArithmeticResultType( lhType, rhType );
+		}
+		else {
+			if ( lhType == null ) {
+				if ( rhType == null ) {
+					// we do not know either type
+					return Hibernate.DOUBLE; //BLIND GUESS!
+				}
+				else {
+					// we know only the rhs-hand type, so use that
+					return rhType;
+				}
+			}
+			else {
+				if ( rhType == null ) {
+					// we know only the lhs-hand type, so use that
+					return lhType;
+				}
+				else {
+					if ( lhType==Hibernate.DOUBLE || rhType==Hibernate.DOUBLE ) return Hibernate.DOUBLE;
+					if ( lhType==Hibernate.FLOAT || rhType==Hibernate.FLOAT ) return Hibernate.FLOAT;
+					if ( lhType==Hibernate.BIG_DECIMAL || rhType==Hibernate.BIG_DECIMAL ) return Hibernate.BIG_DECIMAL;
+					if ( lhType==Hibernate.BIG_INTEGER || rhType==Hibernate.BIG_INTEGER ) return Hibernate.BIG_INTEGER;
+					if ( lhType==Hibernate.LONG || rhType==Hibernate.LONG ) return Hibernate.LONG;
+					if ( lhType==Hibernate.INTEGER || rhType==Hibernate.INTEGER ) return Hibernate.INTEGER;
+					return lhType;
+				}
+			}
+		}
+	}
+
+	private boolean isDateTimeType(Type type) {
+		if ( type == null ) {
+			return false;
+		}
+		return java.util.Date.class.isAssignableFrom( type.getReturnedClass() ) ||
+	           java.util.Calendar.class.isAssignableFrom( type.getReturnedClass() );
+	}
+
+	private Type resolveDateTimeArithmeticResultType(Type lhType, Type rhType) {
+		// here, we work under the following assumptions:
+		//      ------------ valid cases --------------------------------------
+		//      1) datetime + {something other than datetime} : always results
+		//              in a datetime ( db will catch invalid conversions )
+		//      2) datetime - datetime : always results in a DOUBLE
+		//      3) datetime - {something other than datetime} : always results
+		//              in a datetime ( db will catch invalid conversions )
+		//      ------------ invalid cases ------------------------------------
+		//      4) datetime + datetime
+		//      5) {something other than datetime} - datetime
+		//      6) datetime * {any type}
+		//      7) datetime / {any type}
+		//      8) {any type} / datetime
+		// doing so allows us to properly handle parameters as either the left
+		// or right side here in the majority of cases
+		boolean lhsIsDateTime = isDateTimeType( lhType );
+		boolean rhsIsDateTime = isDateTimeType( rhType );
+
+		// handle the (assumed) valid cases:
+		// #1 - the only valid datetime addition synatx is one or the other is a datetime (but not both)
+		if ( getType() == HqlSqlTokenTypes.PLUS ) {
+			// one or the other needs to be a datetime for us to get into this method in the first place...
+			return lhsIsDateTime ? lhType : rhType;
+		}
+		else if ( getType() == HqlSqlTokenTypes.MINUS ) {
+			// #3 - note that this is also true of "datetime - :param"...
+			if ( lhsIsDateTime && !rhsIsDateTime ) {
+				return lhType;
+			}
+			// #2
+			if ( lhsIsDateTime && rhsIsDateTime ) {
+				return Hibernate.DOUBLE;
+			}
+		}
+		return null;
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+	/**
+	 * Retrieves the left-hand operand of the operator.
+	 *
+	 * @return The left-hand operand
+	 */
+	public Node getLeftHandOperand() {
+		return ( Node ) getFirstChild();
+	}
+
+	/**
+	 * Retrieves the right-hand operand of the operator.
+	 *
+	 * @return The right-hand operand
+	 */
+	public Node getRightHandOperand() {
+		return ( Node ) getFirstChild().getNextSibling();
+	}
+
+	public String getDisplayText() {
+		return "{dataType=" + getDataType() + "}";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,198 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import org.hibernate.Hibernate;
-import org.hibernate.TypeMismatchException;
-import org.hibernate.HibernateException;
-import org.hibernate.util.StringHelper;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.dialect.HSQLDialect;
-import org.hibernate.engine.SessionFactoryImplementor;
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Contract for nodes representing binary operators.
- *
- * @author Steve Ebersole
- */
-public class BinaryLogicOperatorNode extends HqlSqlWalkerNode implements BinaryOperatorNode {
-	/**
-	 * Performs the operator node initialization by seeking out any parameter
-	 * nodes and setting their expected type, if possible.
-	 */
-	public void initialize() throws SemanticException {
-		Node lhs = getLeftHandOperand();
-		if ( lhs == null ) {
-			throw new SemanticException( "left-hand operand of a binary operator was null" );
-		}
-		Node rhs = getRightHandOperand();
-		if ( rhs == null ) {
-			throw new SemanticException( "right-hand operand of a binary operator was null" );
-		}
-
-		Type lhsType = extractDataType( lhs );
-		Type rhsType = extractDataType( rhs );
-
-		if ( lhsType == null ) {
-			lhsType = rhsType;
-		}
-		if ( rhsType == null ) {
-			rhsType = lhsType;
-		}
-
-		if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) ) {
-			( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( rhsType );
-		}
-		if ( ExpectedTypeAwareNode.class.isAssignableFrom( rhs.getClass() ) ) {
-			( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( lhsType );
-		}
-
-		mutateRowValueConstructorSyntaxesIfNecessary( lhsType, rhsType );
-	}
-
-	protected final void mutateRowValueConstructorSyntaxesIfNecessary(Type lhsType, Type rhsType) {
-		// TODO : this really needs to be delayed unitl after we definitively know all node types
-		// where this is currently a problem is parameters for which where we cannot unequivocally
-		// resolve an expected type
-		SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
-		if ( lhsType != null && rhsType != null ) {
-			int lhsColumnSpan = lhsType.getColumnSpan( sessionFactory );
-			if ( lhsColumnSpan != rhsType.getColumnSpan( sessionFactory ) ) {
-				throw new TypeMismatchException(
-						"left and right hand sides of a binary logic operator were incompatibile [" +
-						lhsType.getName() + " : "+ rhsType.getName() + "]"
-				);
-			}
-			if ( lhsColumnSpan > 1 ) {
-				// for dialects which are known to not support ANSI-SQL row-value-constructor syntax,
-				// we should mutate the tree.
-				if ( !sessionFactory.getDialect().supportsRowValueConstructorSyntax() ) {
-					mutateRowValueConstructorSyntax( lhsColumnSpan );
-				}
-			}
-		}
-	}
-
-	/**
-	 * Mutate the subtree relating to a row-value-constructor to instead use
-	 * a series of ANDed predicates.  This allows multi-column type comparisons
-	 * and explicit row-value-constructor syntax even on databases which do
-	 * not support row-value-constructor.
-	 * <p/>
-	 * For example, here we'd mutate "... where (col1, col2) = ('val1', 'val2) ..." to
-	 * "... where col1 = 'val1' and col2 = 'val2' ..."
-	 *
-	 * @param valueElements The number of elements in the row value constructor list.
-	 */
-	private void mutateRowValueConstructorSyntax(int valueElements) {
-		// mutation depends on the types of nodes invloved...
-		int comparisonType = getType();
-		String comparisonText = getText();
-		setType( HqlSqlTokenTypes.AND );
-		setText( "AND" );
-		String[] lhsElementTexts = extractMutationTexts( getLeftHandOperand(), valueElements );
-		String[] rhsElementTexts = extractMutationTexts( getRightHandOperand(), valueElements );
-
-		AST container = this;
-		for ( int i = valueElements - 1; i > 0; i-- ) {
-
-			if ( i == 1 ) {
-				AST op1 = getASTFactory().create( comparisonType, comparisonText );
-				AST lhs1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[0] );
-				AST rhs1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[0] );
-				op1.setFirstChild( lhs1 );
-				lhs1.setNextSibling( rhs1 );
-				container.setFirstChild( op1 );
-				AST op2 = getASTFactory().create( comparisonType, comparisonText );
-				AST lhs2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[1] );
-				AST rhs2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[1] );
-				op2.setFirstChild( lhs2 );
-				lhs2.setNextSibling( rhs2 );
-				op1.setNextSibling( op2 );
-			}
-			else {
-				AST op = getASTFactory().create( comparisonType, comparisonText );
-				AST lhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[i] );
-				AST rhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[i] );
-				op.setFirstChild( lhs );
-				lhs.setNextSibling( rhs );
-				AST newContainer = getASTFactory().create( HqlSqlTokenTypes.AND, "AND" );
-				container.setFirstChild( newContainer );
-				newContainer.setNextSibling( op );
-				container = newContainer;
-			}
-		}
-	}
-
-	private static String[] extractMutationTexts(Node operand, int count) {
-		if ( operand instanceof ParameterNode ) {
-			String[] rtn = new String[count];
-			for ( int i = 0; i < count; i++ ) {
-				rtn[i] = "?";
-			}
-			return rtn;
-		}
-		else if ( operand.getType() == HqlSqlTokenTypes.VECTOR_EXPR ) {
-			String[] rtn = new String[ operand.getNumberOfChildren() ];
-			int x = 0;
-			AST node = operand.getFirstChild();
-			while ( node != null ) {
-				rtn[ x++ ] = node.getText();
-				node = node.getNextSibling();
-			}
-			return rtn;
-		}
-		else if ( operand instanceof SqlNode ) {
-			String nodeText = operand.getText();
-			if ( nodeText.startsWith( "(" ) ) {
-				nodeText = nodeText.substring( 1 );
-			}
-			if ( nodeText.endsWith( ")" ) ) {
-				nodeText = nodeText.substring( 0, nodeText.length() - 1 );
-			}
-			String[] splits = StringHelper.split( ", ", nodeText );
-			if ( count != splits.length ) {
-				throw new HibernateException( "SqlNode's text did not reference expected number of columns" );
-			}
-			return splits;
-		}
-		else {
-			throw new HibernateException( "dont know how to extract row value elements from node : " + operand );
-		}
-	}
-
-	protected Type extractDataType(Node operand) {
-		Type type = null;
-		if ( operand instanceof SqlNode ) {
-			type = ( ( SqlNode ) operand ).getDataType();
-		}
-		if ( type == null && operand instanceof ExpectedTypeAwareNode ) {
-			type = ( ( ExpectedTypeAwareNode ) operand ).getExpectedType();
-		}
-		return type;
-	}
-
-	public Type getDataType() {
-		// logic operators by definition resolve to booleans
-		return Hibernate.BOOLEAN;
-	}
-
-	/**
-	 * Retrieves the left-hand operand of the operator.
-	 *
-	 * @return The left-hand operand
-	 */
-	public Node getLeftHandOperand() {
-		return ( Node ) getFirstChild();
-	}
-
-	/**
-	 * Retrieves the right-hand operand of the operator.
-	 *
-	 * @return The right-hand operand
-	 */
-	public Node getRightHandOperand() {
-		return ( Node ) getFirstChild().getNextSibling();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,221 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import org.hibernate.Hibernate;
+import org.hibernate.TypeMismatchException;
+import org.hibernate.HibernateException;
+import org.hibernate.util.StringHelper;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.engine.SessionFactoryImplementor;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Contract for nodes representing binary operators.
+ *
+ * @author Steve Ebersole
+ */
+public class BinaryLogicOperatorNode extends HqlSqlWalkerNode implements BinaryOperatorNode {
+	/**
+	 * Performs the operator node initialization by seeking out any parameter
+	 * nodes and setting their expected type, if possible.
+	 */
+	public void initialize() throws SemanticException {
+		Node lhs = getLeftHandOperand();
+		if ( lhs == null ) {
+			throw new SemanticException( "left-hand operand of a binary operator was null" );
+		}
+		Node rhs = getRightHandOperand();
+		if ( rhs == null ) {
+			throw new SemanticException( "right-hand operand of a binary operator was null" );
+		}
+
+		Type lhsType = extractDataType( lhs );
+		Type rhsType = extractDataType( rhs );
+
+		if ( lhsType == null ) {
+			lhsType = rhsType;
+		}
+		if ( rhsType == null ) {
+			rhsType = lhsType;
+		}
+
+		if ( ExpectedTypeAwareNode.class.isAssignableFrom( lhs.getClass() ) ) {
+			( ( ExpectedTypeAwareNode ) lhs ).setExpectedType( rhsType );
+		}
+		if ( ExpectedTypeAwareNode.class.isAssignableFrom( rhs.getClass() ) ) {
+			( ( ExpectedTypeAwareNode ) rhs ).setExpectedType( lhsType );
+		}
+
+		mutateRowValueConstructorSyntaxesIfNecessary( lhsType, rhsType );
+	}
+
+	protected final void mutateRowValueConstructorSyntaxesIfNecessary(Type lhsType, Type rhsType) {
+		// TODO : this really needs to be delayed unitl after we definitively know all node types
+		// where this is currently a problem is parameters for which where we cannot unequivocally
+		// resolve an expected type
+		SessionFactoryImplementor sessionFactory = getSessionFactoryHelper().getFactory();
+		if ( lhsType != null && rhsType != null ) {
+			int lhsColumnSpan = lhsType.getColumnSpan( sessionFactory );
+			if ( lhsColumnSpan != rhsType.getColumnSpan( sessionFactory ) ) {
+				throw new TypeMismatchException(
+						"left and right hand sides of a binary logic operator were incompatibile [" +
+						lhsType.getName() + " : "+ rhsType.getName() + "]"
+				);
+			}
+			if ( lhsColumnSpan > 1 ) {
+				// for dialects which are known to not support ANSI-SQL row-value-constructor syntax,
+				// we should mutate the tree.
+				if ( !sessionFactory.getDialect().supportsRowValueConstructorSyntax() ) {
+					mutateRowValueConstructorSyntax( lhsColumnSpan );
+				}
+			}
+		}
+	}
+
+	/**
+	 * Mutate the subtree relating to a row-value-constructor to instead use
+	 * a series of ANDed predicates.  This allows multi-column type comparisons
+	 * and explicit row-value-constructor syntax even on databases which do
+	 * not support row-value-constructor.
+	 * <p/>
+	 * For example, here we'd mutate "... where (col1, col2) = ('val1', 'val2) ..." to
+	 * "... where col1 = 'val1' and col2 = 'val2' ..."
+	 *
+	 * @param valueElements The number of elements in the row value constructor list.
+	 */
+	private void mutateRowValueConstructorSyntax(int valueElements) {
+		// mutation depends on the types of nodes invloved...
+		int comparisonType = getType();
+		String comparisonText = getText();
+		setType( HqlSqlTokenTypes.AND );
+		setText( "AND" );
+		String[] lhsElementTexts = extractMutationTexts( getLeftHandOperand(), valueElements );
+		String[] rhsElementTexts = extractMutationTexts( getRightHandOperand(), valueElements );
+
+		AST container = this;
+		for ( int i = valueElements - 1; i > 0; i-- ) {
+
+			if ( i == 1 ) {
+				AST op1 = getASTFactory().create( comparisonType, comparisonText );
+				AST lhs1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[0] );
+				AST rhs1 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[0] );
+				op1.setFirstChild( lhs1 );
+				lhs1.setNextSibling( rhs1 );
+				container.setFirstChild( op1 );
+				AST op2 = getASTFactory().create( comparisonType, comparisonText );
+				AST lhs2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[1] );
+				AST rhs2 = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[1] );
+				op2.setFirstChild( lhs2 );
+				lhs2.setNextSibling( rhs2 );
+				op1.setNextSibling( op2 );
+			}
+			else {
+				AST op = getASTFactory().create( comparisonType, comparisonText );
+				AST lhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, lhsElementTexts[i] );
+				AST rhs = getASTFactory().create( HqlSqlTokenTypes.SQL_TOKEN, rhsElementTexts[i] );
+				op.setFirstChild( lhs );
+				lhs.setNextSibling( rhs );
+				AST newContainer = getASTFactory().create( HqlSqlTokenTypes.AND, "AND" );
+				container.setFirstChild( newContainer );
+				newContainer.setNextSibling( op );
+				container = newContainer;
+			}
+		}
+	}
+
+	private static String[] extractMutationTexts(Node operand, int count) {
+		if ( operand instanceof ParameterNode ) {
+			String[] rtn = new String[count];
+			for ( int i = 0; i < count; i++ ) {
+				rtn[i] = "?";
+			}
+			return rtn;
+		}
+		else if ( operand.getType() == HqlSqlTokenTypes.VECTOR_EXPR ) {
+			String[] rtn = new String[ operand.getNumberOfChildren() ];
+			int x = 0;
+			AST node = operand.getFirstChild();
+			while ( node != null ) {
+				rtn[ x++ ] = node.getText();
+				node = node.getNextSibling();
+			}
+			return rtn;
+		}
+		else if ( operand instanceof SqlNode ) {
+			String nodeText = operand.getText();
+			if ( nodeText.startsWith( "(" ) ) {
+				nodeText = nodeText.substring( 1 );
+			}
+			if ( nodeText.endsWith( ")" ) ) {
+				nodeText = nodeText.substring( 0, nodeText.length() - 1 );
+			}
+			String[] splits = StringHelper.split( ", ", nodeText );
+			if ( count != splits.length ) {
+				throw new HibernateException( "SqlNode's text did not reference expected number of columns" );
+			}
+			return splits;
+		}
+		else {
+			throw new HibernateException( "dont know how to extract row value elements from node : " + operand );
+		}
+	}
+
+	protected Type extractDataType(Node operand) {
+		Type type = null;
+		if ( operand instanceof SqlNode ) {
+			type = ( ( SqlNode ) operand ).getDataType();
+		}
+		if ( type == null && operand instanceof ExpectedTypeAwareNode ) {
+			type = ( ( ExpectedTypeAwareNode ) operand ).getExpectedType();
+		}
+		return type;
+	}
+
+	public Type getDataType() {
+		// logic operators by definition resolve to booleans
+		return Hibernate.BOOLEAN;
+	}
+
+	/**
+	 * Retrieves the left-hand operand of the operator.
+	 *
+	 * @return The left-hand operand
+	 */
+	public Node getLeftHandOperand() {
+		return ( Node ) getFirstChild();
+	}
+
+	/**
+	 * Retrieves the right-hand operand of the operator.
+	 *
+	 * @return The right-hand operand
+	 */
+	public Node getRightHandOperand() {
+		return ( Node ) getFirstChild().getNextSibling();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-/**
- * Contract for nodes representing binary operators.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public interface BinaryOperatorNode extends OperatorNode {
-	/**
-	 * Retrieves the left-hand operand of the operator.
-	 *
-	 * @return The left-hand operand
-	 */
-	public Node getLeftHandOperand();
-
-	/**
-	 * Retrieves the right-hand operand of the operator.
-	 *
-	 * @return The right-hand operand
-	 */
-	public Node getRightHandOperand();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BinaryOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+/**
+ * Contract for nodes representing binary operators.
+ *
+ * @author Steve Ebersole
+ */
+public interface BinaryOperatorNode extends OperatorNode {
+	/**
+	 * Retrieves the left-hand operand of the operator.
+	 *
+	 * @return The left-hand operand
+	 */
+	public Node getLeftHandOperand();
+
+	/**
+	 * Retrieves the right-hand operand of the operator.
+	 *
+	 * @return The right-hand operand
+	 */
+	public Node getRightHandOperand();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import org.hibernate.type.BooleanType;
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Represents a boolean literal within a query.
- *
- * @author Steve Ebersole
- */
-public class BooleanLiteralNode extends LiteralNode implements ExpectedTypeAwareNode {
-	private Type expectedType;
-
-	public Type getDataType() {
-		return expectedType == null ? Hibernate.BOOLEAN : expectedType;
-	}
-
-	public BooleanType getTypeInternal() {
-		return ( BooleanType ) getDataType();
-	}
-
-	public Boolean getValue() {
-		return getType() == TRUE ? Boolean.TRUE : Boolean.FALSE;
-	}
-
-	/**
-	 * Expected-types really only pertinent here for boolean literals...
-	 *
-	 * @param expectedType
-	 */
-	public void setExpectedType(Type expectedType) {
-		this.expectedType = expectedType;
-	}
-
-	public Type getExpectedType() {
-		return expectedType;
-	}
-
-	public String getRenderText(SessionFactoryImplementor sessionFactory) {
-		try {
-			return getTypeInternal().objectToSQLString( getValue(), sessionFactory.getDialect() );
-		}
-		catch( Throwable t ) {
-			throw new QueryException( "Unable to render boolean literal value", t );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/BooleanLiteralNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import org.hibernate.type.BooleanType;
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Represents a boolean literal within a query.
+ *
+ * @author Steve Ebersole
+ */
+public class BooleanLiteralNode extends LiteralNode implements ExpectedTypeAwareNode {
+	private Type expectedType;
+
+	public Type getDataType() {
+		return expectedType == null ? Hibernate.BOOLEAN : expectedType;
+	}
+
+	public BooleanType getTypeInternal() {
+		return ( BooleanType ) getDataType();
+	}
+
+	public Boolean getValue() {
+		return getType() == TRUE ? Boolean.TRUE : Boolean.FALSE;
+	}
+
+	/**
+	 * Expected-types really only pertinent here for boolean literals...
+	 *
+	 * @param expectedType
+	 */
+	public void setExpectedType(Type expectedType) {
+		this.expectedType = expectedType;
+	}
+
+	public Type getExpectedType() {
+		return expectedType;
+	}
+
+	public String getRenderText(SessionFactoryImplementor sessionFactory) {
+		try {
+			return getTypeInternal().objectToSQLString( getValue(), sessionFactory.getDialect() );
+		}
+		catch( Throwable t ) {
+			throw new QueryException( "Unable to render boolean literal value", t );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-// $Id: Case2Node.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents a case ... when .. then ... else ... end expression in a select.
- *
- * @author Gavin King
- */
-public class Case2Node extends AbstractSelectExpression implements SelectExpression {
-	
-	public Type getDataType() {
-		return getFirstThenNode().getDataType();
-	}
-
-	private SelectExpression getFirstThenNode() {
-		return (SelectExpression) getFirstChild().getNextSibling().getFirstChild().getNextSibling();
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Case2Node.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents a case ... when .. then ... else ... end expression in a select.
+ *
+ * @author Gavin King
+ */
+public class Case2Node extends AbstractSelectExpression implements SelectExpression {
+	
+	public Type getDataType() {
+		return getFirstThenNode().getDataType();
+	}
+
+	private SelectExpression getFirstThenNode() {
+		return (SelectExpression) getFirstChild().getNextSibling().getFirstChild().getNextSibling();
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-// $Id: CaseNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents a case ... when .. then ... else ... end expression in a select.
- *
- * @author Gavin King
- */
-public class CaseNode extends AbstractSelectExpression implements SelectExpression {
-	
-	public Type getDataType() {
-		return getFirstThenNode().getDataType();
-	}
-
-	private SelectExpression getFirstThenNode() {
-		return (SelectExpression) getFirstChild().getFirstChild().getNextSibling();
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CaseNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents a case ... when .. then ... else ... end expression in a select.
+ *
+ * @author Gavin King
+ */
+public class CaseNode extends AbstractSelectExpression implements SelectExpression {
+	
+	public Type getDataType() {
+		return getFirstThenNode().getDataType();
+	}
+
+	private SelectExpression getFirstThenNode() {
+		return (SelectExpression) getFirstChild().getFirstChild().getNextSibling();
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-// $Id: CollectionFunction.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Represents 'elements()' or 'indices()'.
- *
- * @author josh Dec 6, 2004 8:36:42 AM
- */
-public class CollectionFunction extends MethodNode implements DisplayableNode {
-	public void resolve(boolean inSelect) throws SemanticException {
-		initializeMethodNode( this, inSelect );
-		if ( !isCollectionPropertyMethod() ) {
-			throw new SemanticException( this.getText() + " is not a collection property name!" );
-		}
-		AST expr = getFirstChild();
-		if ( expr == null ) {
-			throw new SemanticException( this.getText() + " requires a path!" );
-		}
-		resolveCollectionProperty( expr );
-	}
-
-	protected void prepareSelectColumns(String[] selectColumns) {
-		// we need to strip off the embedded parens so that sql-gen does not double these up
-		String subselect = selectColumns[0].trim();
-		if ( subselect.startsWith( "(") && subselect.endsWith( ")" ) ) {
-			subselect = subselect.substring( 1, subselect.length() -1 );
-		}
-		selectColumns[0] = subselect;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CollectionFunction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Represents 'elements()' or 'indices()'.
+ *
+ * @author josh
+ */
+public class CollectionFunction extends MethodNode implements DisplayableNode {
+	public void resolve(boolean inSelect) throws SemanticException {
+		initializeMethodNode( this, inSelect );
+		if ( !isCollectionPropertyMethod() ) {
+			throw new SemanticException( this.getText() + " is not a collection property name!" );
+		}
+		AST expr = getFirstChild();
+		if ( expr == null ) {
+			throw new SemanticException( this.getText() + " requires a path!" );
+		}
+		resolveCollectionProperty( expr );
+	}
+
+	protected void prepareSelectColumns(String[] selectColumns) {
+		// we need to strip off the embedded parens so that sql-gen does not double these up
+		String subselect = selectColumns[0].trim();
+		if ( subselect.startsWith( "(") && subselect.endsWith( ")" ) ) {
+			subselect = subselect.substring( 1, subselect.length() -1 );
+		}
+		selectColumns[0] = subselect;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,158 +0,0 @@
-// $Id: ConstructorNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import java.lang.reflect.Constructor;
-import java.util.Arrays;
-import java.util.List;
-
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.hql.ast.DetailedSemanticException;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Represents a constructor (new) in a SELECT.
- *
- * @author josh Sep 24, 2004 6:46:08 PM
- */
-public class ConstructorNode extends SelectExpressionList implements SelectExpression {
-
-	private Constructor constructor;
-	private Type[] constructorArgumentTypes;
-	private boolean isMap;
-	private boolean isList;
-	
-	public boolean isMap() {
-		return isMap;
-	}
-	
-	public boolean isList() {
-		return isList;
-	}
-	
-	public String[] getAliases() {
-		SelectExpression[] selectExpressions = collectSelectExpressions();
-		String[] aliases = new String[selectExpressions.length] ;
-		for ( int i=0; i<selectExpressions.length; i++ ) {
-			String alias = selectExpressions[i].getAlias();
-			aliases[i] = alias==null ? Integer.toString(i) : alias;
-		}
-		return aliases;
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		SelectExpression[] selectExpressions = collectSelectExpressions();
-		// Invoke setScalarColumnText on each constructor argument.
-		for ( int j = 0; j < selectExpressions.length; j++ ) {
-			SelectExpression selectExpression = selectExpressions[j];
-			selectExpression.setScalarColumnText( j );
-		}
-	}
-
-	protected AST getFirstSelectExpression() {
-		// Collect the select expressions, skip the first child because it is the class name.
-		return getFirstChild().getNextSibling();
-	}
-
-	/**
-	 * @deprecated (tell clover to ignore this method)
-	 */
-	public Type getDataType() {
-/*
-		// Return the type of the object created by the constructor.
-		AST firstChild = getFirstChild();
-		String text = firstChild.getText();
-		if ( firstChild.getType() == SqlTokenTypes.DOT ) {
-			DotNode dot = ( DotNode ) firstChild;
-			text = dot.getPath();
-		}
-		return getSessionFactoryHelper().requireEntityType( text );
-*/
-		throw new UnsupportedOperationException( "getDataType() is not supported by ConstructorNode!" );
-	}
-
-	public void prepare() throws SemanticException {
-		constructorArgumentTypes = resolveConstructorArgumentTypes();
-		String path = ( ( PathNode ) getFirstChild() ).getPath();
-		if ( "map".equals( path.toLowerCase() ) ) {
-			isMap = true;
-		}
-		else if ( "list".equals( path.toLowerCase() ) ) {
-			isList = true;
-		}
-		else {
-			constructor = resolveConstructor(path);
-		}
-	}
-
-	private Type[] resolveConstructorArgumentTypes() throws SemanticException {
-		SelectExpression[] argumentExpressions = collectSelectExpressions();
-		if ( argumentExpressions == null ) {
-			// return an empty Type array
-			return new Type[]{};
-		}
-
-		Type[] types = new Type[argumentExpressions.length];
-		for ( int x = 0; x < argumentExpressions.length; x++ ) {
-			types[x] = argumentExpressions[x].getDataType();
-		}
-		return types;
-	}
-
-	private Constructor resolveConstructor(String path) throws SemanticException {
-		String importedClassName = getSessionFactoryHelper().getImportedClassName( path );
-		String className = StringHelper.isEmpty( importedClassName ) ? path : importedClassName;
-		if ( className == null ) {
-			throw new SemanticException( "Unable to locate class [" + path + "]" );
-		}
-		try {
-			Class holderClass = ReflectHelper.classForName( className );
-			return ReflectHelper.getConstructor( holderClass, constructorArgumentTypes );
-		}
-		catch ( ClassNotFoundException e ) {
-			throw new DetailedSemanticException( "Unable to locate class [" + className + "]", e );
-		}
-		catch ( PropertyNotFoundException e ) {
-			// this is the exception returned by ReflectHelper.getConstructor() if it cannot
-			// locate an appropriate constructor
-			throw new DetailedSemanticException( "Unable to locate appropriate constructor on class [" + className + "]", e );
-		}
-	}
-	
-	public Constructor getConstructor() {
-		return constructor;
-	}
-
-	public List getConstructorArgumentTypeList() {
-		return Arrays.asList( constructorArgumentTypes );
-	}
-
-	public FromElement getFromElement() {
-		return null;
-	}
-
-	public boolean isConstructor() {
-		return true;
-	}
-
-	public boolean isReturnableEntity() throws SemanticException {
-		return false;
-	}
-
-	public boolean isScalar() {
-		// Constructors are always considered scalar results.
-		return true;
-	}
-	
-	public void setAlias(String alias) {
-		throw new UnsupportedOperationException("constructor may not be aliased");
-	}
-	
-	public String getAlias() {
-		throw new UnsupportedOperationException("constructor may not be aliased");
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ConstructorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,181 @@
+/*
+ * 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.tree;
+
+import java.lang.reflect.Constructor;
+import java.util.Arrays;
+import java.util.List;
+
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.hql.ast.DetailedSemanticException;
+import org.hibernate.type.Type;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Represents a constructor (new) in a SELECT.
+ *
+ * @author josh
+ */
+public class ConstructorNode extends SelectExpressionList implements SelectExpression {
+
+	private Constructor constructor;
+	private Type[] constructorArgumentTypes;
+	private boolean isMap;
+	private boolean isList;
+	
+	public boolean isMap() {
+		return isMap;
+	}
+	
+	public boolean isList() {
+		return isList;
+	}
+	
+	public String[] getAliases() {
+		SelectExpression[] selectExpressions = collectSelectExpressions();
+		String[] aliases = new String[selectExpressions.length] ;
+		for ( int i=0; i<selectExpressions.length; i++ ) {
+			String alias = selectExpressions[i].getAlias();
+			aliases[i] = alias==null ? Integer.toString(i) : alias;
+		}
+		return aliases;
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		SelectExpression[] selectExpressions = collectSelectExpressions();
+		// Invoke setScalarColumnText on each constructor argument.
+		for ( int j = 0; j < selectExpressions.length; j++ ) {
+			SelectExpression selectExpression = selectExpressions[j];
+			selectExpression.setScalarColumnText( j );
+		}
+	}
+
+	protected AST getFirstSelectExpression() {
+		// Collect the select expressions, skip the first child because it is the class name.
+		return getFirstChild().getNextSibling();
+	}
+
+	/**
+	 * @deprecated (tell clover to ignore this method)
+	 */
+	public Type getDataType() {
+/*
+		// Return the type of the object created by the constructor.
+		AST firstChild = getFirstChild();
+		String text = firstChild.getText();
+		if ( firstChild.getType() == SqlTokenTypes.DOT ) {
+			DotNode dot = ( DotNode ) firstChild;
+			text = dot.getPath();
+		}
+		return getSessionFactoryHelper().requireEntityType( text );
+*/
+		throw new UnsupportedOperationException( "getDataType() is not supported by ConstructorNode!" );
+	}
+
+	public void prepare() throws SemanticException {
+		constructorArgumentTypes = resolveConstructorArgumentTypes();
+		String path = ( ( PathNode ) getFirstChild() ).getPath();
+		if ( "map".equals( path.toLowerCase() ) ) {
+			isMap = true;
+		}
+		else if ( "list".equals( path.toLowerCase() ) ) {
+			isList = true;
+		}
+		else {
+			constructor = resolveConstructor(path);
+		}
+	}
+
+	private Type[] resolveConstructorArgumentTypes() throws SemanticException {
+		SelectExpression[] argumentExpressions = collectSelectExpressions();
+		if ( argumentExpressions == null ) {
+			// return an empty Type array
+			return new Type[]{};
+		}
+
+		Type[] types = new Type[argumentExpressions.length];
+		for ( int x = 0; x < argumentExpressions.length; x++ ) {
+			types[x] = argumentExpressions[x].getDataType();
+		}
+		return types;
+	}
+
+	private Constructor resolveConstructor(String path) throws SemanticException {
+		String importedClassName = getSessionFactoryHelper().getImportedClassName( path );
+		String className = StringHelper.isEmpty( importedClassName ) ? path : importedClassName;
+		if ( className == null ) {
+			throw new SemanticException( "Unable to locate class [" + path + "]" );
+		}
+		try {
+			Class holderClass = ReflectHelper.classForName( className );
+			return ReflectHelper.getConstructor( holderClass, constructorArgumentTypes );
+		}
+		catch ( ClassNotFoundException e ) {
+			throw new DetailedSemanticException( "Unable to locate class [" + className + "]", e );
+		}
+		catch ( PropertyNotFoundException e ) {
+			// this is the exception returned by ReflectHelper.getConstructor() if it cannot
+			// locate an appropriate constructor
+			throw new DetailedSemanticException( "Unable to locate appropriate constructor on class [" + className + "]", e );
+		}
+	}
+	
+	public Constructor getConstructor() {
+		return constructor;
+	}
+
+	public List getConstructorArgumentTypeList() {
+		return Arrays.asList( constructorArgumentTypes );
+	}
+
+	public FromElement getFromElement() {
+		return null;
+	}
+
+	public boolean isConstructor() {
+		return true;
+	}
+
+	public boolean isReturnableEntity() throws SemanticException {
+		return false;
+	}
+
+	public boolean isScalar() {
+		// Constructors are always considered scalar results.
+		return true;
+	}
+	
+	public void setAlias(String alias) {
+		throw new UnsupportedOperationException("constructor may not be aliased");
+	}
+	
+	public String getAlias() {
+		throw new UnsupportedOperationException("constructor may not be aliased");
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-// $Id: CountNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents a COUNT expression in a select.
- *
- * @author josh Sep 21, 2004 9:23:40 PM
- */
-public class CountNode extends AbstractSelectExpression implements SelectExpression {
-	
-	public Type getDataType() {
-		return getSessionFactoryHelper().findFunctionReturnType( getText(), null );
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/CountNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents a COUNT expression in a select.
+ *
+ * @author josh
+ */
+public class CountNode extends AbstractSelectExpression implements SelectExpression {
+	
+	public Type getDataType() {
+		return getSessionFactoryHelper().findFunctionReturnType( getText(), null );
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-// $Id: DeleteStatement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Defines a top-level AST node representing an HQL delete statement.
- *
- * @author Steve Ebersole
- */
-public class DeleteStatement extends AbstractRestrictableStatement {
-
-	private static final Logger log = LoggerFactory.getLogger( DeleteStatement.class );
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.Statement#getStatementType()
-	 */
-	public int getStatementType() {
-		return HqlSqlTokenTypes.DELETE;
-	}
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.Statement#needsExecutor()
-	 */
-	public boolean needsExecutor() {
-		return true;
-	}
-
-	protected int getWhereClauseParentTokenType() {
-		return SqlTokenTypes.FROM;
-	}
-
-	protected Logger getLog() {
-		return log;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DeleteStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines a top-level AST node representing an HQL delete statement.
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteStatement extends AbstractRestrictableStatement {
+
+	private static final Logger log = LoggerFactory.getLogger( DeleteStatement.class );
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.Statement#getStatementType()
+	 */
+	public int getStatementType() {
+		return HqlSqlTokenTypes.DELETE;
+	}
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.Statement#needsExecutor()
+	 */
+	public boolean needsExecutor() {
+		return true;
+	}
+
+	protected int getWhereClauseParentTokenType() {
+		return SqlTokenTypes.FROM;
+	}
+
+	protected Logger getLog() {
+		return log;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-// $Id: DisplayableNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-/**
- * Implementors will return additional display text, which will be used
- * by the ASTPrinter to display information (besides the node type and node
- * text).
- */
-public interface DisplayableNode {
-	/**
-	 * Returns additional display text for the AST node.
-	 *
-	 * @return String - The additional display text.
-	 */
-	String getDisplayText();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DisplayableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+/**
+ * Implementors will return additional display text, which will be used
+ * by the ASTPrinter to display information (besides the node type and node
+ * text).
+ */
+public interface DisplayableNode {
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return String - The additional display text.
+	 */
+	String getDisplayText();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,667 +0,0 @@
-// $Id: DotNode.java 11378 2007-03-30 11:23:48Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a reference to a property or alias expression.  This should duplicate the relevant behaviors in
- * PathExpressionParser.
- *
- * @author Joshua Davis
- */
-public class DotNode extends FromReferenceNode implements DisplayableNode, SelectExpression {
-
-	///////////////////////////////////////////////////////////////////////////
-	// USED ONLY FOR REGRESSION TESTING!!!!
-	//
-	// todo : obviously get rid of all this junk ;)
-	///////////////////////////////////////////////////////////////////////////
-	public static boolean useThetaStyleImplicitJoins = false;
-	public static boolean REGRESSION_STYLE_JOIN_SUPPRESSION = false;
-	public static interface IllegalCollectionDereferenceExceptionBuilder {
-		public QueryException buildIllegalCollectionDereferenceException(String collectionPropertyName, FromReferenceNode lhs);
-	}
-	public static final IllegalCollectionDereferenceExceptionBuilder DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER = new IllegalCollectionDereferenceExceptionBuilder() {
-		public QueryException buildIllegalCollectionDereferenceException(String propertyName, FromReferenceNode lhs) {
-			String lhsPath = ASTUtil.getPathText( lhs );
-			return new QueryException( "illegal attempt to dereference collection [" + lhsPath + "] with element property reference [" + propertyName + "]" );
-		}
-	};
-	public static IllegalCollectionDereferenceExceptionBuilder ILLEGAL_COLL_DEREF_EXCP_BUILDER = DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER;
-	///////////////////////////////////////////////////////////////////////////
-
-	private static final Logger log = LoggerFactory.getLogger( DotNode.class );
-
-	private static final int DEREF_UNKNOWN = 0;
-	private static final int DEREF_ENTITY = 1;
-	private static final int DEREF_COMPONENT = 2;
-	private static final int DEREF_COLLECTION = 3;
-	private static final int DEREF_PRIMITIVE = 4;
-	private static final int DEREF_IDENTIFIER = 5;
-	private static final int DEREF_JAVA_CONSTANT = 6;
-
-	/**
-	 * The identifier that is the name of the property.
-	 */
-	private String propertyName;
-	/**
-	 * The full path, to the root alias of this dot node.
-	 */
-	private String path;
-	/**
-	 * The unresolved property path relative to this dot node.
-	 */
-	private String propertyPath;
-
-	/**
-	 * The column names that this resolves to.
-	 */
-	private String[] columns;
-
-	/**
-	 * The type of join to create.   Default is an inner join.
-	 */
-	private int joinType = JoinFragment.INNER_JOIN;
-
-	/**
-	 * Fetch join or not.
-	 */
-	private boolean fetch = false;
-
-	/**
-	 * The type of dereference that hapened (DEREF_xxx).
-	 */
-	private int dereferenceType = DEREF_UNKNOWN;
-
-	private FromElement impliedJoin;
-
-	/**
-	 * Sets the join type for this '.' node structure.
-	 *
-	 * @param joinType The type of join to use.
-	 * @see JoinFragment
-	 */
-	public void setJoinType(int joinType) {
-		this.joinType = joinType;
-	}
-
-	private String[] getColumns() throws QueryException {
-		if ( columns == null ) {
-			// Use the table fromElement and the property name to get the array of column names.
-			String tableAlias = getLhs().getFromElement().getTableAlias();
-			columns = getFromElement().toColumns( tableAlias, propertyPath, false );
-		}
-		return columns;
-	}
-
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		FromElement fromElement = getFromElement();
-		buf.append( "{propertyName=" ).append( propertyName );
-		buf.append( ",dereferenceType=" ).append( ASTPrinter.getConstantName( getClass(), dereferenceType ) );
-		buf.append( ",propertyPath=" ).append( propertyPath );
-		buf.append( ",path=" ).append( getPath() );
-		if ( fromElement != null ) {
-			buf.append( ",tableAlias=" ).append( fromElement.getTableAlias() );
-			buf.append( ",className=" ).append( fromElement.getClassName() );
-			buf.append( ",classAlias=" ).append( fromElement.getClassAlias() );
-		}
-		else {
-			buf.append( ",no from element" );
-		}
-		buf.append( '}' );
-		return buf.toString();
-	}
-
-	/**
-	 * Resolves the left hand side of the DOT.
-	 *
-	 * @throws SemanticException
-	 */
-	public void resolveFirstChild() throws SemanticException {
-		FromReferenceNode lhs = ( FromReferenceNode ) getFirstChild();
-		SqlNode property = ( SqlNode ) lhs.getNextSibling();
-
-		// Set the attributes of the property reference expression.
-		String propName = property.getText();
-		propertyName = propName;
-		// If the uresolved property path isn't set yet, just use the property name.
-		if ( propertyPath == null ) {
-			propertyPath = propName;
-		}
-		// Resolve the LHS fully, generate implicit joins.  Pass in the property name so that the resolver can
-		// discover foreign key (id) properties.
-		lhs.resolve( true, true, null, this );
-		setFromElement( lhs.getFromElement() );			// The 'from element' that the property is in.
-
-		checkSubclassOrSuperclassPropertyReference( lhs, propName );
-	}
-
-	public void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException {
-		if ( isResolved() ) {
-			return;
-		}
-		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
-		if ( propertyType!=null && propertyType.isCollectionType() ) {
-			resolveIndex(null);
-		}
-		else {
-			resolveFirstChild();
-			super.resolve(generateJoin, implicitJoin);
-		}
-	}
-
-
-	public void resolveIndex(AST parent) throws SemanticException {
-		if ( isResolved() ) {
-			return;
-		}
-		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
-		dereferenceCollection( ( CollectionType ) propertyType, true, true, null, parent );
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent)
-	throws SemanticException {
-		// If this dot has already been resolved, stop now.
-		if ( isResolved() ) {
-			return;
-		}
-		Type propertyType = prepareLhs(); // Prepare the left hand side and get the data type.
-
-		// If there is no data type for this node, and we're at the end of the path (top most dot node), then
-		// this might be a Java constant.
-		if ( propertyType == null ) {
-			if ( parent == null ) {
-				getWalker().getLiteralProcessor().lookupConstant( this );
-			}
-			// If the propertyType is null and there isn't a parent, just
-			// stop now... there was a problem resolving the node anyway.
-			return;
-		}
-
-		if ( propertyType.isComponentType() ) {
-			// The property is a component...
-			checkLhsIsNotCollection();
-			dereferenceComponent( parent );
-			initText();
-		}
-		else if ( propertyType.isEntityType() ) {
-			// The property is another class..
-			checkLhsIsNotCollection();
-			dereferenceEntity( ( EntityType ) propertyType, implicitJoin, classAlias, generateJoin, parent );
-			initText();
-		}
-		else if ( propertyType.isCollectionType() ) {
-			// The property is a collection...
-			checkLhsIsNotCollection();
-			dereferenceCollection( ( CollectionType ) propertyType, implicitJoin, false, classAlias, parent );
-		}
-		else {
-			// Otherwise, this is a primitive type.
-			if ( ! CollectionProperties.isAnyCollectionProperty( propertyName ) ) {
-				checkLhsIsNotCollection();
-			}
-			dereferenceType = DEREF_PRIMITIVE;
-			initText();
-		}
-		setResolved();
-	}
-
-	private void initText() {
-		String[] cols = getColumns();
-		String text = StringHelper.join( ", ", cols );
-		if ( cols.length > 1 && getWalker().isComparativeExpressionClause() ) {
-			text = "(" + text + ")";
-		}
-		setText( text );
-	}
-
-	private Type prepareLhs() throws SemanticException {
-		FromReferenceNode lhs = getLhs();
-		lhs.prepareForDot( propertyName );
-		return getDataType();
-	}
-
-	private void dereferenceCollection(CollectionType collectionType, boolean implicitJoin, boolean indexed, String classAlias, AST parent)
-	throws SemanticException {
-
-		dereferenceType = DEREF_COLLECTION;
-		String role = collectionType.getRole();
-
-		//foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness)
-		boolean isSizeProperty = getNextSibling()!=null &&
-			CollectionProperties.isAnyCollectionProperty( getNextSibling().getText() );
-
-		if ( isSizeProperty ) indexed = true; //yuck!
-
-		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection( role );
-		String propName = getPath();
-		FromClause currentFromClause = getWalker().getCurrentFromClause();
-
-		if ( getWalker().getStatementType() != SqlTokenTypes.SELECT && indexed && classAlias == null ) {
-			// should indicate that we are processing an INSERT/UPDATE/DELETE
-			// query with a subquery implied via a collection property
-			// function. Here, we need to use the table name itself as the
-			// qualification alias.
-			// TODO : verify this works for all databases...
-			// TODO : is this also the case in non-"indexed" scenarios?
-			String alias = getLhs().getFromElement().getQueryable().getTableName();
-			columns = getFromElement().toColumns( alias, propertyPath, false, true );
-		}
-
-		//We do not look for an existing join on the same path, because
-		//it makes sense to join twice on the same collection role
-		FromElementFactory factory = new FromElementFactory(
-		        currentFromClause,
-		        getLhs().getFromElement(),
-		        propName,
-				classAlias,
-		        getColumns(),
-		        implicitJoin
-		);
-		FromElement elem = factory.createCollection( queryableCollection, role, joinType, fetch, indexed );
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "dereferenceCollection() : Created new FROM element for " + propName + " : " + elem );
-		}
-
-		setImpliedJoin( elem );
-		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.
-
-		if ( isSizeProperty ) {
-			elem.setText("");
-			elem.setUseWhereFragment(false);
-		}
-
-		if ( !implicitJoin ) {
-			EntityPersister entityPersister = elem.getEntityPersister();
-			if ( entityPersister != null ) {
-				getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
-			}
-		}
-		getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );	// Always add the collection's query spaces.
-	}
-
-	private void dereferenceEntity(EntityType entityType, boolean implicitJoin, String classAlias, boolean generateJoin, AST parent) throws SemanticException {
-		checkForCorrelatedSubquery( "dereferenceEntity" );
-		// three general cases we check here as to whether to render a physical SQL join:
-		// 1) is our parent a DotNode as well?  If so, our property reference is
-		// 		being further de-referenced...
-		// 2) is this a DML statement
-		// 3) we were asked to generate any needed joins (generateJoins==true) *OR*
-		//		we are currently processing a select or from clause
-		// (an additional check is the REGRESSION_STYLE_JOIN_SUPPRESSION check solely intended for the test suite)
-		//
-		// The REGRESSION_STYLE_JOIN_SUPPRESSION is an additional check
-		// intended solely for use within the test suite.  This forces the
-		// implicit join resolution to behave more like the classic parser.
-		// The underlying issue is that classic translator is simply wrong
-		// about its decisions on whether or not to render an implicit join
-		// into a physical SQL join in a lot of cases.  The piece it generally
-		// tends to miss is that INNER joins effect the results by further
-		// restricting the data set!  A particular manifestation of this is
-		// the fact that the classic translator will skip the physical join
-		// for ToOne implicit joins *if the query is shallow*; the result
-		// being that Query.list() and Query.iterate() could return
-		// different number of results!
-		DotNode parentAsDotNode = null;
-		String property = propertyName;
-		final boolean joinIsNeeded;
-
-		if ( isDotNode( parent ) ) {
-			// our parent is another dot node, meaning we are being further dereferenced.
-			// thus we need to generate a join unless the parent refers to the associated
-			// entity's PK (because 'our' table would know the FK).
-			parentAsDotNode = ( DotNode ) parent;
-			property = parentAsDotNode.propertyName;
-			joinIsNeeded = generateJoin && !isReferenceToPrimaryKey( parentAsDotNode.propertyName, entityType );
-		}
-		else if ( ! getWalker().isSelectStatement() ) {
-			// in non-select queries, the only time we should need to join is if we are in a subquery from clause
-			joinIsNeeded = getWalker().getCurrentStatementType() == SqlTokenTypes.SELECT && getWalker().isInFrom();
-		}
-		else if ( REGRESSION_STYLE_JOIN_SUPPRESSION ) {
-			// this is the regression style determination which matches the logic of the classic translator
-			joinIsNeeded = generateJoin && ( !getWalker().isInSelect() || !getWalker().isShallowQuery() );
-		}
-		else {
-			joinIsNeeded = generateJoin || ( getWalker().isInSelect() || getWalker().isInFrom() );
-		}
-
-		if ( joinIsNeeded ) {
-			dereferenceEntityJoin( classAlias, entityType, implicitJoin, parent );
-		}
-		else {
-			dereferenceEntityIdentifier( property, parentAsDotNode );
-		}
-
-	}
-
-	private boolean isDotNode(AST n) {
-		return n != null && n.getType() == SqlTokenTypes.DOT;
-	}
-
-	private void dereferenceEntityJoin(String classAlias, EntityType propertyType, boolean impliedJoin, AST parent)
-	throws SemanticException {
-		dereferenceType = DEREF_ENTITY;
-		if ( log.isDebugEnabled() ) {
-			log.debug( "dereferenceEntityJoin() : generating join for " + propertyName + " in "
-					+ getFromElement().getClassName() + " "
-					+ ( ( classAlias == null ) ? "{no alias}" : "(" + classAlias + ")" )
-					+ " parent = " + ASTUtil.getDebugString( parent )
-			);
-		}
-		// Create a new FROM node for the referenced class.
-		String associatedEntityName = propertyType.getAssociatedEntityName();
-		String tableAlias = getAliasGenerator().createName( associatedEntityName );
-
-		String[] joinColumns = getColumns();
-		String joinPath = getPath();
-
-		if ( impliedJoin && getWalker().isInFrom() ) {
-			joinType = getWalker().getImpliedJoinType();
-		}
-
-		FromClause currentFromClause = getWalker().getCurrentFromClause();
-		FromElement elem = currentFromClause.findJoinByPath( joinPath );
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// This is the piece which recognizes the condition where an implicit join path
-// resolved earlier in a correlated subquery is now being referenced in the
-// outer query.  For 3.0final, we just let this generate a second join (which
-// is exactly how the old parser handles this).  Eventually we need to add this
-// logic back in and complete the logic in FromClause.promoteJoin; however,
-// FromClause.promoteJoin has its own difficulties (see the comments in
-// FromClause.promoteJoin).
-//
-//		if ( elem == null ) {
-//			// see if this joinPath has been used in a "child" FromClause, and if so
-//			// promote that element to the outer query
-//			FromClause currentNodeOwner = getFromElement().getFromClause();
-//			FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath );
-//			if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) {
-//				elem = currentJoinOwner.findJoinByPathLocal( joinPath );
-//				if ( elem != null ) {
-//					currentFromClause.promoteJoin( elem );
-//					// EARLY EXIT!!!
-//					return;
-//				}
-//			}
-//		}
-//
-///////////////////////////////////////////////////////////////////////////////
-
-		if ( elem == null ) {
-			// If this is an implied join in a from element, then use the impled join type which is part of the
-			// tree parser's state (set by the gramamar actions).
-			JoinSequence joinSequence = getSessionFactoryHelper()
-				.createJoinSequence( impliedJoin, propertyType, tableAlias, joinType, joinColumns );
-
-			FromElementFactory factory = new FromElementFactory(
-			        currentFromClause,
-					getLhs().getFromElement(),
-					joinPath,
-					classAlias,
-					joinColumns,
-					impliedJoin
-			);
-			elem = factory.createEntityJoin(
-					associatedEntityName,
-					tableAlias,
-					joinSequence,
-					fetch,
-					getWalker().isInFrom(),
-					propertyType
-			);
-		}
-		else {
-			currentFromClause.addDuplicateAlias(classAlias, elem);
-		}
-		setImpliedJoin( elem );
-		getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
-		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.
-	}
-
-	private void setImpliedJoin(FromElement elem) {
-		this.impliedJoin = elem;
-		if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
-			DotNode dotLhs = ( DotNode ) getFirstChild();
-			if ( dotLhs.getImpliedJoin() != null ) {
-				this.impliedJoin = dotLhs.getImpliedJoin();
-			}
-		}
-	}
-
-	public FromElement getImpliedJoin() {
-		return impliedJoin;
-	}
-
-	/**
-	 * 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 entity's (owningType->associatedEntity)
-	 * primary key; false otherwise.
-	 */
-	private boolean isReferenceToPrimaryKey(String propertyName, EntityType owningType) {
-		EntityPersister persister = getSessionFactoryHelper()
-				.getFactory()
-				.getEntityPersister( owningType.getAssociatedEntityName() );
-		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 = getSessionFactoryHelper().getIdentifierOrUniqueKeyPropertyName( owningType );
-				return keyPropertyName != null && keyPropertyName.equals( propertyName ) && owningType.isReferenceToPrimaryKey();
-			}
-		}
-	}
-
-	private void checkForCorrelatedSubquery(String methodName) {
-		if ( isCorrelatedSubselect() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( methodName + "() : correlated subquery" );
-			}
-		}
-	}
-
-	private boolean isCorrelatedSubselect() {
-		return getWalker().isSubQuery() &&
-			getFromElement().getFromClause() != getWalker().getCurrentFromClause();
-	}
-
-	private void checkLhsIsNotCollection() throws SemanticException {
-		if ( getLhs().getDataType() != null && getLhs().getDataType().isCollectionType() ) {
-			throw ILLEGAL_COLL_DEREF_EXCP_BUILDER.buildIllegalCollectionDereferenceException( propertyName, getLhs() );
-		}
-	}
-	private void dereferenceComponent(AST parent) {
-		dereferenceType = DEREF_COMPONENT;
-		setPropertyNameAndPath( parent );
-	}
-
-	private void dereferenceEntityIdentifier(String propertyName, DotNode dotParent) {
-		// special shortcut for id properties, skip the join!
-		// this must only occur at the _end_ of a path expression
-		if ( log.isDebugEnabled() ) {
-			log.debug( "dereferenceShortcut() : property " +
-				propertyName + " in " + getFromElement().getClassName() +
-				" does not require a join." );
-		}
-
-		initText();
-		setPropertyNameAndPath( dotParent ); // Set the unresolved path in this node and the parent.
-		// Set the text for the parent.
-		if ( dotParent != null ) {
-			dotParent.dereferenceType = DEREF_IDENTIFIER;
-			dotParent.setText( getText() );
-			dotParent.columns = getColumns();
-		}
-	}
-
-	private void setPropertyNameAndPath(AST parent) {
-		if ( isDotNode( parent ) ) {
-			DotNode dotNode = ( DotNode ) parent;
-			AST lhs = dotNode.getFirstChild();
-			AST rhs = lhs.getNextSibling();
-			propertyName = rhs.getText();
-			propertyPath = propertyPath + "." + propertyName; // Append the new property name onto the unresolved path.
-			dotNode.propertyPath = propertyPath;
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Unresolved property path is now '" + dotNode.propertyPath + "'" );
-			}
-		}
-		else {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "terminal propertyPath = [" + propertyPath + "]" );
-			}
-		}
-	}
-
-	public Type getDataType() {
-		if ( super.getDataType() == null ) {
-			FromElement fromElement = getLhs().getFromElement();
-			if ( fromElement == null ) {
-				return null;
-			}
-			// If the lhs is a collection, use CollectionPropertyMapping
-			Type propertyType = fromElement.getPropertyType( propertyName, propertyPath );
-			if ( log.isDebugEnabled() ) {
-				log.debug( "getDataType() : " + propertyPath + " -> " + propertyType );
-			}
-			super.setDataType( propertyType );
-		}
-		return super.getDataType();
-	}
-
-	public void setPropertyPath(String propertyPath) {
-		this.propertyPath = propertyPath;
-	}
-
-	public String getPropertyPath() {
-		return propertyPath;
-	}
-
-	public FromReferenceNode getLhs() {
-		FromReferenceNode lhs = ( ( FromReferenceNode ) getFirstChild() );
-		if ( lhs == null ) {
-			throw new IllegalStateException( "DOT node with no left-hand-side!" );
-		}
-		return lhs;
-	}
-
-	/**
-	 * Returns the full path of the node.
-	 *
-	 * @return the full path of the node.
-	 */
-	public String getPath() {
-		if ( path == null ) {
-			FromReferenceNode lhs = getLhs();
-			if ( lhs == null ) {
-				path = getText();
-			}
-			else {
-				SqlNode rhs = ( SqlNode ) lhs.getNextSibling();
-				path = lhs.getPath() + "." + rhs.getOriginalText();
-			}
-		}
-		return path;
-	}
-
-	public void setFetch(boolean fetch) {
-		this.fetch = fetch;
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		String[] sqlColumns = getColumns();
-		ColumnHelper.generateScalarColumns( this, sqlColumns, i );
-	}
-
-	/**
-	 * Special method to resolve expressions in the SELECT list.
-	 *
-	 * @throws SemanticException if this cannot be resolved.
-	 */
-	public void resolveSelectExpression() throws SemanticException {
-		if ( getWalker().isShallowQuery() || getWalker().getCurrentFromClause().isSubQuery() ) {
-			resolve(false, true);
-		}
-		else {
-			resolve(true, false);
-			Type type = getDataType();
-			if ( type.isEntityType() ) {
-				FromElement fromElement = getFromElement();
-				fromElement.setIncludeSubclasses( true ); // Tell the destination fromElement to 'includeSubclasses'.
-				if ( useThetaStyleImplicitJoins ) {
-					fromElement.getJoinSequence().setUseThetaStyle( true );	// Use theta style (for regression)
-					// Move the node up, after the origin node.
-					FromElement origin = fromElement.getOrigin();
-					if ( origin != null ) {
-						ASTUtil.makeSiblingOfParent( origin, fromElement );
-					}
-				}
-			}
-		}
-
-		FromReferenceNode lhs = getLhs();
-		while ( lhs != null ) {
-			checkSubclassOrSuperclassPropertyReference( lhs, lhs.getNextSibling().getText() );
-			lhs = ( FromReferenceNode ) lhs.getFirstChild();
-		}
-	}
-
-	public void setResolvedConstant(String text) {
-		path = text;
-		dereferenceType = DEREF_JAVA_CONSTANT;
-		setResolved(); // Don't resolve the node again.
-	}
-
-	private boolean checkSubclassOrSuperclassPropertyReference(FromReferenceNode lhs, String propertyName) {
-		if ( lhs != null && !( lhs instanceof IndexNode ) ) {
-			final FromElement source = lhs.getFromElement();
-			if ( source != null ) {
-				source.handlePropertyBeingDereferenced( lhs.getDataType(), propertyName );
-			}
-		}
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/DotNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,690 @@
+/*
+ * 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.tree;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a reference to a property or alias expression.  This should duplicate the relevant behaviors in
+ * PathExpressionParser.
+ *
+ * @author Joshua Davis
+ */
+public class DotNode extends FromReferenceNode implements DisplayableNode, SelectExpression {
+
+	///////////////////////////////////////////////////////////////////////////
+	// USED ONLY FOR REGRESSION TESTING!!!!
+	//
+	// todo : obviously get rid of all this junk ;)
+	///////////////////////////////////////////////////////////////////////////
+	public static boolean useThetaStyleImplicitJoins = false;
+	public static boolean REGRESSION_STYLE_JOIN_SUPPRESSION = false;
+	public static interface IllegalCollectionDereferenceExceptionBuilder {
+		public QueryException buildIllegalCollectionDereferenceException(String collectionPropertyName, FromReferenceNode lhs);
+	}
+	public static final IllegalCollectionDereferenceExceptionBuilder DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER = new IllegalCollectionDereferenceExceptionBuilder() {
+		public QueryException buildIllegalCollectionDereferenceException(String propertyName, FromReferenceNode lhs) {
+			String lhsPath = ASTUtil.getPathText( lhs );
+			return new QueryException( "illegal attempt to dereference collection [" + lhsPath + "] with element property reference [" + propertyName + "]" );
+		}
+	};
+	public static IllegalCollectionDereferenceExceptionBuilder ILLEGAL_COLL_DEREF_EXCP_BUILDER = DEF_ILLEGAL_COLL_DEREF_EXCP_BUILDER;
+	///////////////////////////////////////////////////////////////////////////
+
+	private static final Logger log = LoggerFactory.getLogger( DotNode.class );
+
+	private static final int DEREF_UNKNOWN = 0;
+	private static final int DEREF_ENTITY = 1;
+	private static final int DEREF_COMPONENT = 2;
+	private static final int DEREF_COLLECTION = 3;
+	private static final int DEREF_PRIMITIVE = 4;
+	private static final int DEREF_IDENTIFIER = 5;
+	private static final int DEREF_JAVA_CONSTANT = 6;
+
+	/**
+	 * The identifier that is the name of the property.
+	 */
+	private String propertyName;
+	/**
+	 * The full path, to the root alias of this dot node.
+	 */
+	private String path;
+	/**
+	 * The unresolved property path relative to this dot node.
+	 */
+	private String propertyPath;
+
+	/**
+	 * The column names that this resolves to.
+	 */
+	private String[] columns;
+
+	/**
+	 * The type of join to create.   Default is an inner join.
+	 */
+	private int joinType = JoinFragment.INNER_JOIN;
+
+	/**
+	 * Fetch join or not.
+	 */
+	private boolean fetch = false;
+
+	/**
+	 * The type of dereference that hapened (DEREF_xxx).
+	 */
+	private int dereferenceType = DEREF_UNKNOWN;
+
+	private FromElement impliedJoin;
+
+	/**
+	 * Sets the join type for this '.' node structure.
+	 *
+	 * @param joinType The type of join to use.
+	 * @see JoinFragment
+	 */
+	public void setJoinType(int joinType) {
+		this.joinType = joinType;
+	}
+
+	private String[] getColumns() throws QueryException {
+		if ( columns == null ) {
+			// Use the table fromElement and the property name to get the array of column names.
+			String tableAlias = getLhs().getFromElement().getTableAlias();
+			columns = getFromElement().toColumns( tableAlias, propertyPath, false );
+		}
+		return columns;
+	}
+
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		FromElement fromElement = getFromElement();
+		buf.append( "{propertyName=" ).append( propertyName );
+		buf.append( ",dereferenceType=" ).append( ASTPrinter.getConstantName( getClass(), dereferenceType ) );
+		buf.append( ",propertyPath=" ).append( propertyPath );
+		buf.append( ",path=" ).append( getPath() );
+		if ( fromElement != null ) {
+			buf.append( ",tableAlias=" ).append( fromElement.getTableAlias() );
+			buf.append( ",className=" ).append( fromElement.getClassName() );
+			buf.append( ",classAlias=" ).append( fromElement.getClassAlias() );
+		}
+		else {
+			buf.append( ",no from element" );
+		}
+		buf.append( '}' );
+		return buf.toString();
+	}
+
+	/**
+	 * Resolves the left hand side of the DOT.
+	 *
+	 * @throws SemanticException
+	 */
+	public void resolveFirstChild() throws SemanticException {
+		FromReferenceNode lhs = ( FromReferenceNode ) getFirstChild();
+		SqlNode property = ( SqlNode ) lhs.getNextSibling();
+
+		// Set the attributes of the property reference expression.
+		String propName = property.getText();
+		propertyName = propName;
+		// If the uresolved property path isn't set yet, just use the property name.
+		if ( propertyPath == null ) {
+			propertyPath = propName;
+		}
+		// Resolve the LHS fully, generate implicit joins.  Pass in the property name so that the resolver can
+		// discover foreign key (id) properties.
+		lhs.resolve( true, true, null, this );
+		setFromElement( lhs.getFromElement() );			// The 'from element' that the property is in.
+
+		checkSubclassOrSuperclassPropertyReference( lhs, propName );
+	}
+
+	public void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException {
+		if ( isResolved() ) {
+			return;
+		}
+		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
+		if ( propertyType!=null && propertyType.isCollectionType() ) {
+			resolveIndex(null);
+		}
+		else {
+			resolveFirstChild();
+			super.resolve(generateJoin, implicitJoin);
+		}
+	}
+
+
+	public void resolveIndex(AST parent) throws SemanticException {
+		if ( isResolved() ) {
+			return;
+		}
+		Type propertyType = prepareLhs();			// Prepare the left hand side and get the data type.
+		dereferenceCollection( ( CollectionType ) propertyType, true, true, null, parent );
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent)
+	throws SemanticException {
+		// If this dot has already been resolved, stop now.
+		if ( isResolved() ) {
+			return;
+		}
+		Type propertyType = prepareLhs(); // Prepare the left hand side and get the data type.
+
+		// If there is no data type for this node, and we're at the end of the path (top most dot node), then
+		// this might be a Java constant.
+		if ( propertyType == null ) {
+			if ( parent == null ) {
+				getWalker().getLiteralProcessor().lookupConstant( this );
+			}
+			// If the propertyType is null and there isn't a parent, just
+			// stop now... there was a problem resolving the node anyway.
+			return;
+		}
+
+		if ( propertyType.isComponentType() ) {
+			// The property is a component...
+			checkLhsIsNotCollection();
+			dereferenceComponent( parent );
+			initText();
+		}
+		else if ( propertyType.isEntityType() ) {
+			// The property is another class..
+			checkLhsIsNotCollection();
+			dereferenceEntity( ( EntityType ) propertyType, implicitJoin, classAlias, generateJoin, parent );
+			initText();
+		}
+		else if ( propertyType.isCollectionType() ) {
+			// The property is a collection...
+			checkLhsIsNotCollection();
+			dereferenceCollection( ( CollectionType ) propertyType, implicitJoin, false, classAlias, parent );
+		}
+		else {
+			// Otherwise, this is a primitive type.
+			if ( ! CollectionProperties.isAnyCollectionProperty( propertyName ) ) {
+				checkLhsIsNotCollection();
+			}
+			dereferenceType = DEREF_PRIMITIVE;
+			initText();
+		}
+		setResolved();
+	}
+
+	private void initText() {
+		String[] cols = getColumns();
+		String text = StringHelper.join( ", ", cols );
+		if ( cols.length > 1 && getWalker().isComparativeExpressionClause() ) {
+			text = "(" + text + ")";
+		}
+		setText( text );
+	}
+
+	private Type prepareLhs() throws SemanticException {
+		FromReferenceNode lhs = getLhs();
+		lhs.prepareForDot( propertyName );
+		return getDataType();
+	}
+
+	private void dereferenceCollection(CollectionType collectionType, boolean implicitJoin, boolean indexed, String classAlias, AST parent)
+	throws SemanticException {
+
+		dereferenceType = DEREF_COLLECTION;
+		String role = collectionType.getRole();
+
+		//foo.bars.size (also handles deprecated stuff like foo.bars.maxelement for backwardness)
+		boolean isSizeProperty = getNextSibling()!=null &&
+			CollectionProperties.isAnyCollectionProperty( getNextSibling().getText() );
+
+		if ( isSizeProperty ) indexed = true; //yuck!
+
+		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection( role );
+		String propName = getPath();
+		FromClause currentFromClause = getWalker().getCurrentFromClause();
+
+		if ( getWalker().getStatementType() != SqlTokenTypes.SELECT && indexed && classAlias == null ) {
+			// should indicate that we are processing an INSERT/UPDATE/DELETE
+			// query with a subquery implied via a collection property
+			// function. Here, we need to use the table name itself as the
+			// qualification alias.
+			// TODO : verify this works for all databases...
+			// TODO : is this also the case in non-"indexed" scenarios?
+			String alias = getLhs().getFromElement().getQueryable().getTableName();
+			columns = getFromElement().toColumns( alias, propertyPath, false, true );
+		}
+
+		//We do not look for an existing join on the same path, because
+		//it makes sense to join twice on the same collection role
+		FromElementFactory factory = new FromElementFactory(
+		        currentFromClause,
+		        getLhs().getFromElement(),
+		        propName,
+				classAlias,
+		        getColumns(),
+		        implicitJoin
+		);
+		FromElement elem = factory.createCollection( queryableCollection, role, joinType, fetch, indexed );
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "dereferenceCollection() : Created new FROM element for " + propName + " : " + elem );
+		}
+
+		setImpliedJoin( elem );
+		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.
+
+		if ( isSizeProperty ) {
+			elem.setText("");
+			elem.setUseWhereFragment(false);
+		}
+
+		if ( !implicitJoin ) {
+			EntityPersister entityPersister = elem.getEntityPersister();
+			if ( entityPersister != null ) {
+				getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
+			}
+		}
+		getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );	// Always add the collection's query spaces.
+	}
+
+	private void dereferenceEntity(EntityType entityType, boolean implicitJoin, String classAlias, boolean generateJoin, AST parent) throws SemanticException {
+		checkForCorrelatedSubquery( "dereferenceEntity" );
+		// three general cases we check here as to whether to render a physical SQL join:
+		// 1) is our parent a DotNode as well?  If so, our property reference is
+		// 		being further de-referenced...
+		// 2) is this a DML statement
+		// 3) we were asked to generate any needed joins (generateJoins==true) *OR*
+		//		we are currently processing a select or from clause
+		// (an additional check is the REGRESSION_STYLE_JOIN_SUPPRESSION check solely intended for the test suite)
+		//
+		// The REGRESSION_STYLE_JOIN_SUPPRESSION is an additional check
+		// intended solely for use within the test suite.  This forces the
+		// implicit join resolution to behave more like the classic parser.
+		// The underlying issue is that classic translator is simply wrong
+		// about its decisions on whether or not to render an implicit join
+		// into a physical SQL join in a lot of cases.  The piece it generally
+		// tends to miss is that INNER joins effect the results by further
+		// restricting the data set!  A particular manifestation of this is
+		// the fact that the classic translator will skip the physical join
+		// for ToOne implicit joins *if the query is shallow*; the result
+		// being that Query.list() and Query.iterate() could return
+		// different number of results!
+		DotNode parentAsDotNode = null;
+		String property = propertyName;
+		final boolean joinIsNeeded;
+
+		if ( isDotNode( parent ) ) {
+			// our parent is another dot node, meaning we are being further dereferenced.
+			// thus we need to generate a join unless the parent refers to the associated
+			// entity's PK (because 'our' table would know the FK).
+			parentAsDotNode = ( DotNode ) parent;
+			property = parentAsDotNode.propertyName;
+			joinIsNeeded = generateJoin && !isReferenceToPrimaryKey( parentAsDotNode.propertyName, entityType );
+		}
+		else if ( ! getWalker().isSelectStatement() ) {
+			// in non-select queries, the only time we should need to join is if we are in a subquery from clause
+			joinIsNeeded = getWalker().getCurrentStatementType() == SqlTokenTypes.SELECT && getWalker().isInFrom();
+		}
+		else if ( REGRESSION_STYLE_JOIN_SUPPRESSION ) {
+			// this is the regression style determination which matches the logic of the classic translator
+			joinIsNeeded = generateJoin && ( !getWalker().isInSelect() || !getWalker().isShallowQuery() );
+		}
+		else {
+			joinIsNeeded = generateJoin || ( getWalker().isInSelect() || getWalker().isInFrom() );
+		}
+
+		if ( joinIsNeeded ) {
+			dereferenceEntityJoin( classAlias, entityType, implicitJoin, parent );
+		}
+		else {
+			dereferenceEntityIdentifier( property, parentAsDotNode );
+		}
+
+	}
+
+	private boolean isDotNode(AST n) {
+		return n != null && n.getType() == SqlTokenTypes.DOT;
+	}
+
+	private void dereferenceEntityJoin(String classAlias, EntityType propertyType, boolean impliedJoin, AST parent)
+	throws SemanticException {
+		dereferenceType = DEREF_ENTITY;
+		if ( log.isDebugEnabled() ) {
+			log.debug( "dereferenceEntityJoin() : generating join for " + propertyName + " in "
+					+ getFromElement().getClassName() + " "
+					+ ( ( classAlias == null ) ? "{no alias}" : "(" + classAlias + ")" )
+					+ " parent = " + ASTUtil.getDebugString( parent )
+			);
+		}
+		// Create a new FROM node for the referenced class.
+		String associatedEntityName = propertyType.getAssociatedEntityName();
+		String tableAlias = getAliasGenerator().createName( associatedEntityName );
+
+		String[] joinColumns = getColumns();
+		String joinPath = getPath();
+
+		if ( impliedJoin && getWalker().isInFrom() ) {
+			joinType = getWalker().getImpliedJoinType();
+		}
+
+		FromClause currentFromClause = getWalker().getCurrentFromClause();
+		FromElement elem = currentFromClause.findJoinByPath( joinPath );
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// This is the piece which recognizes the condition where an implicit join path
+// resolved earlier in a correlated subquery is now being referenced in the
+// outer query.  For 3.0final, we just let this generate a second join (which
+// is exactly how the old parser handles this).  Eventually we need to add this
+// logic back in and complete the logic in FromClause.promoteJoin; however,
+// FromClause.promoteJoin has its own difficulties (see the comments in
+// FromClause.promoteJoin).
+//
+//		if ( elem == null ) {
+//			// see if this joinPath has been used in a "child" FromClause, and if so
+//			// promote that element to the outer query
+//			FromClause currentNodeOwner = getFromElement().getFromClause();
+//			FromClause currentJoinOwner = currentNodeOwner.locateChildFromClauseWithJoinByPath( joinPath );
+//			if ( currentJoinOwner != null && currentNodeOwner != currentJoinOwner ) {
+//				elem = currentJoinOwner.findJoinByPathLocal( joinPath );
+//				if ( elem != null ) {
+//					currentFromClause.promoteJoin( elem );
+//					// EARLY EXIT!!!
+//					return;
+//				}
+//			}
+//		}
+//
+///////////////////////////////////////////////////////////////////////////////
+
+		if ( elem == null ) {
+			// If this is an implied join in a from element, then use the impled join type which is part of the
+			// tree parser's state (set by the gramamar actions).
+			JoinSequence joinSequence = getSessionFactoryHelper()
+				.createJoinSequence( impliedJoin, propertyType, tableAlias, joinType, joinColumns );
+
+			FromElementFactory factory = new FromElementFactory(
+			        currentFromClause,
+					getLhs().getFromElement(),
+					joinPath,
+					classAlias,
+					joinColumns,
+					impliedJoin
+			);
+			elem = factory.createEntityJoin(
+					associatedEntityName,
+					tableAlias,
+					joinSequence,
+					fetch,
+					getWalker().isInFrom(),
+					propertyType
+			);
+		}
+		else {
+			currentFromClause.addDuplicateAlias(classAlias, elem);
+		}
+		setImpliedJoin( elem );
+		getWalker().addQuerySpaces( elem.getEntityPersister().getQuerySpaces() );
+		setFromElement( elem );	// This 'dot' expression now refers to the resulting from element.
+	}
+
+	private void setImpliedJoin(FromElement elem) {
+		this.impliedJoin = elem;
+		if ( getFirstChild().getType() == SqlTokenTypes.DOT ) {
+			DotNode dotLhs = ( DotNode ) getFirstChild();
+			if ( dotLhs.getImpliedJoin() != null ) {
+				this.impliedJoin = dotLhs.getImpliedJoin();
+			}
+		}
+	}
+
+	public FromElement getImpliedJoin() {
+		return impliedJoin;
+	}
+
+	/**
+	 * 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 entity's (owningType->associatedEntity)
+	 * primary key; false otherwise.
+	 */
+	private boolean isReferenceToPrimaryKey(String propertyName, EntityType owningType) {
+		EntityPersister persister = getSessionFactoryHelper()
+				.getFactory()
+				.getEntityPersister( owningType.getAssociatedEntityName() );
+		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 = getSessionFactoryHelper().getIdentifierOrUniqueKeyPropertyName( owningType );
+				return keyPropertyName != null && keyPropertyName.equals( propertyName ) && owningType.isReferenceToPrimaryKey();
+			}
+		}
+	}
+
+	private void checkForCorrelatedSubquery(String methodName) {
+		if ( isCorrelatedSubselect() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( methodName + "() : correlated subquery" );
+			}
+		}
+	}
+
+	private boolean isCorrelatedSubselect() {
+		return getWalker().isSubQuery() &&
+			getFromElement().getFromClause() != getWalker().getCurrentFromClause();
+	}
+
+	private void checkLhsIsNotCollection() throws SemanticException {
+		if ( getLhs().getDataType() != null && getLhs().getDataType().isCollectionType() ) {
+			throw ILLEGAL_COLL_DEREF_EXCP_BUILDER.buildIllegalCollectionDereferenceException( propertyName, getLhs() );
+		}
+	}
+	private void dereferenceComponent(AST parent) {
+		dereferenceType = DEREF_COMPONENT;
+		setPropertyNameAndPath( parent );
+	}
+
+	private void dereferenceEntityIdentifier(String propertyName, DotNode dotParent) {
+		// special shortcut for id properties, skip the join!
+		// this must only occur at the _end_ of a path expression
+		if ( log.isDebugEnabled() ) {
+			log.debug( "dereferenceShortcut() : property " +
+				propertyName + " in " + getFromElement().getClassName() +
+				" does not require a join." );
+		}
+
+		initText();
+		setPropertyNameAndPath( dotParent ); // Set the unresolved path in this node and the parent.
+		// Set the text for the parent.
+		if ( dotParent != null ) {
+			dotParent.dereferenceType = DEREF_IDENTIFIER;
+			dotParent.setText( getText() );
+			dotParent.columns = getColumns();
+		}
+	}
+
+	private void setPropertyNameAndPath(AST parent) {
+		if ( isDotNode( parent ) ) {
+			DotNode dotNode = ( DotNode ) parent;
+			AST lhs = dotNode.getFirstChild();
+			AST rhs = lhs.getNextSibling();
+			propertyName = rhs.getText();
+			propertyPath = propertyPath + "." + propertyName; // Append the new property name onto the unresolved path.
+			dotNode.propertyPath = propertyPath;
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Unresolved property path is now '" + dotNode.propertyPath + "'" );
+			}
+		}
+		else {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "terminal propertyPath = [" + propertyPath + "]" );
+			}
+		}
+	}
+
+	public Type getDataType() {
+		if ( super.getDataType() == null ) {
+			FromElement fromElement = getLhs().getFromElement();
+			if ( fromElement == null ) {
+				return null;
+			}
+			// If the lhs is a collection, use CollectionPropertyMapping
+			Type propertyType = fromElement.getPropertyType( propertyName, propertyPath );
+			if ( log.isDebugEnabled() ) {
+				log.debug( "getDataType() : " + propertyPath + " -> " + propertyType );
+			}
+			super.setDataType( propertyType );
+		}
+		return super.getDataType();
+	}
+
+	public void setPropertyPath(String propertyPath) {
+		this.propertyPath = propertyPath;
+	}
+
+	public String getPropertyPath() {
+		return propertyPath;
+	}
+
+	public FromReferenceNode getLhs() {
+		FromReferenceNode lhs = ( ( FromReferenceNode ) getFirstChild() );
+		if ( lhs == null ) {
+			throw new IllegalStateException( "DOT node with no left-hand-side!" );
+		}
+		return lhs;
+	}
+
+	/**
+	 * Returns the full path of the node.
+	 *
+	 * @return the full path of the node.
+	 */
+	public String getPath() {
+		if ( path == null ) {
+			FromReferenceNode lhs = getLhs();
+			if ( lhs == null ) {
+				path = getText();
+			}
+			else {
+				SqlNode rhs = ( SqlNode ) lhs.getNextSibling();
+				path = lhs.getPath() + "." + rhs.getOriginalText();
+			}
+		}
+		return path;
+	}
+
+	public void setFetch(boolean fetch) {
+		this.fetch = fetch;
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		String[] sqlColumns = getColumns();
+		ColumnHelper.generateScalarColumns( this, sqlColumns, i );
+	}
+
+	/**
+	 * Special method to resolve expressions in the SELECT list.
+	 *
+	 * @throws SemanticException if this cannot be resolved.
+	 */
+	public void resolveSelectExpression() throws SemanticException {
+		if ( getWalker().isShallowQuery() || getWalker().getCurrentFromClause().isSubQuery() ) {
+			resolve(false, true);
+		}
+		else {
+			resolve(true, false);
+			Type type = getDataType();
+			if ( type.isEntityType() ) {
+				FromElement fromElement = getFromElement();
+				fromElement.setIncludeSubclasses( true ); // Tell the destination fromElement to 'includeSubclasses'.
+				if ( useThetaStyleImplicitJoins ) {
+					fromElement.getJoinSequence().setUseThetaStyle( true );	// Use theta style (for regression)
+					// Move the node up, after the origin node.
+					FromElement origin = fromElement.getOrigin();
+					if ( origin != null ) {
+						ASTUtil.makeSiblingOfParent( origin, fromElement );
+					}
+				}
+			}
+		}
+
+		FromReferenceNode lhs = getLhs();
+		while ( lhs != null ) {
+			checkSubclassOrSuperclassPropertyReference( lhs, lhs.getNextSibling().getText() );
+			lhs = ( FromReferenceNode ) lhs.getFirstChild();
+		}
+	}
+
+	public void setResolvedConstant(String text) {
+		path = text;
+		dereferenceType = DEREF_JAVA_CONSTANT;
+		setResolved(); // Don't resolve the node again.
+	}
+
+	private boolean checkSubclassOrSuperclassPropertyReference(FromReferenceNode lhs, String propertyName) {
+		if ( lhs != null && !( lhs instanceof IndexNode ) ) {
+			final FromElement source = lhs.getFromElement();
+			if ( source != null ) {
+				source.handlePropertyBeingDereferenced( lhs.getDataType(), propertyName );
+			}
+		}
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-
-/**
- * Interface for nodes which wish to be made aware of any determined "expected
- * type" based on the context within they appear in the query.
- *
- * @author Steve Ebersole
- */
-public interface ExpectedTypeAwareNode {
-	public void setExpectedType(Type expectedType);
-	public Type getExpectedType();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ExpectedTypeAwareNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.type.Type;
+
+/**
+ * Interface for nodes which wish to be made aware of any determined "expected
+ * type" based on the context within they appear in the query.
+ *
+ * @author Steve Ebersole
+ */
+public interface ExpectedTypeAwareNode {
+	public void setExpectedType(Type expectedType);
+	public Type getExpectedType();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,365 +0,0 @@
-// $Id: FromClause.java 10172 2006-07-26 18:01:49Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTIterator;
-import org.hibernate.hql.ast.util.ASTUtil;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Represents the 'FROM' part of a query or subquery, containing all mapped class references.
- *
- * @author josh
- */
-public class FromClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes, DisplayableNode {
-	private static Logger log = LoggerFactory.getLogger( FromClause.class );
-	public static final int ROOT_LEVEL = 1;
-
-	private int level = ROOT_LEVEL;
-	private Set fromElements = new HashSet();
-	private Map fromElementByClassAlias = new HashMap();
-	private Map fromElementByTableAlias = new HashMap();
-	private Map fromElementsByPath = new HashMap();
-
-	/**
-	 * All of the implicit FROM xxx JOIN yyy elements that are the destination of a collection.  These are created from
-	 * index operators on collection property references.
-	 */
-	private Map collectionJoinFromElementsByPath = new HashMap();
-	/**
-	 * Pointer to the parent FROM clause, if there is one.
-	 */
-	private FromClause parentFromClause;
-	/**
-	 * Collection of FROM clauses of which this is the parent.
-	 */
-	private Set childFromClauses;
-	/**
-	 * Counts the from elements as they are added.
-	 */
-	private int fromElementCounter = 0;
-	/**
-	 * Implied FROM elements to add onto the end of the FROM clause.
-	 */
-	private List impliedElements = new LinkedList();
-
-	/**
-	 * Adds a new from element to the from node.
-	 *
-	 * @param path  The reference to the class.
-	 * @param alias The alias AST.
-	 * @return FromElement - The new FROM element.
-	 */
-	public FromElement addFromElement(String path, AST alias) throws SemanticException {
-		// The path may be a reference to an alias defined in the parent query.
-		String classAlias = ( alias == null ) ? null : alias.getText();
-		checkForDuplicateClassAlias( classAlias );
-		FromElementFactory factory = new FromElementFactory( this, null, path, classAlias, null, false );
-		return factory.addFromElement();
-	}
-
-	void registerFromElement(FromElement element) {
-		fromElements.add( element );
-		String classAlias = element.getClassAlias();
-		if ( classAlias != null ) {
-			// The HQL class alias refers to the class name.
-			fromElementByClassAlias.put( classAlias, element );
-		}
-		// Associate the table alias with the element.
-		String tableAlias = element.getTableAlias();
-		if ( tableAlias != null ) {
-			fromElementByTableAlias.put( tableAlias, element );
-		}
-	}
-
-	void addDuplicateAlias(String alias, FromElement element) {
-		if ( alias != null ) {
-			fromElementByClassAlias.put( alias, element );
-		}
-	}
-
-	private void checkForDuplicateClassAlias(String classAlias) throws SemanticException {
-		if ( classAlias != null && fromElementByClassAlias.containsKey( classAlias ) ) {
-			throw new SemanticException( "Duplicate definition of alias '" + classAlias + "'" );
-		}
-	}
-
-	/**
-	 * Retreives the from-element represented by the given alias.
-	 *
-	 * @param aliasOrClassName The alias by which to locate the from-element.
-	 * @return The from-element assigned the given alias, or null if none.
-	 */
-	public FromElement getFromElement(String aliasOrClassName) {
-		FromElement fromElement = ( FromElement ) fromElementByClassAlias.get( aliasOrClassName );
-		if ( fromElement == null && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
-			fromElement = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( aliasOrClassName );
-		}
-		if ( fromElement == null && parentFromClause != null ) {
-			fromElement = parentFromClause.getFromElement( aliasOrClassName );
-		}
-		return fromElement;
-	}
-
-	private FromElement findIntendedAliasedFromElementBasedOnCrazyJPARequirements(String specifiedAlias) {
-		Iterator itr = fromElementByClassAlias.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			String alias = ( String ) entry.getKey();
-			if ( alias.equalsIgnoreCase( specifiedAlias ) ) {
-				return ( FromElement ) entry.getValue();
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Convenience method to check whether a given token represents a from-element alias.
-	 *
-	 * @param possibleAlias The potential from-element alias to check.
-	 * @return True if the possibleAlias is an alias to a from-element visible
-	 *         from this point in the query graph.
-	 */
-	public boolean isFromElementAlias(String possibleAlias) {
-		boolean isAlias = containsClassAlias( possibleAlias );
-		if ( !isAlias && parentFromClause != null ) {
-			// try the parent FromClause...
-			isAlias = parentFromClause.isFromElementAlias( possibleAlias );
-		}
-		return isAlias;
-	}
-
-	/**
-	 * Returns the list of from elements in order.
-	 *
-	 * @return the list of from elements (instances of FromElement).
-	 */
-	public List getFromElements() {
-		return ASTUtil.collectChildren( this, fromElementPredicate );
-	}
-	
-	public FromElement getFromElement() {
-		// TODO: not sure about this one
-//		List fromElements = getFromElements();
-//		if ( fromElements == null || fromElements.isEmpty() ) {
-//			throw new QueryException( "Unable to locate from element" );
-//		}
-		return (FromElement) getFromElements().get(0);
-	}
-
-	/**
-	 * Returns the list of from elements that will be part of the result set.
-	 *
-	 * @return the list of from elements that will be part of the result set.
-	 */
-	public List getProjectionList() {
-		return ASTUtil.collectChildren( this, projectionListPredicate );
-	}
-
-	public List getCollectionFetches() {
-		return ASTUtil.collectChildren( this, collectionFetchPredicate );
-	}
-
-	public boolean hasCollectionFecthes() {
-		return getCollectionFetches().size() > 0;
-	}
-
-	public List getExplicitFromElements() {
-		return ASTUtil.collectChildren( this, explicitFromPredicate );
-	}
-
-	private static ASTUtil.FilterPredicate fromElementPredicate = new ASTUtil.IncludePredicate() {
-		public boolean include(AST node) {
-			FromElement fromElement = ( FromElement ) node;
-			return fromElement.isFromOrJoinFragment();
-		}
-	};
-
-	private static ASTUtil.FilterPredicate projectionListPredicate = new ASTUtil.IncludePredicate() {
-		public boolean include(AST node) {
-			FromElement fromElement = ( FromElement ) node;
-			return fromElement.inProjectionList();
-		}
-	};
-
-	private static ASTUtil.FilterPredicate collectionFetchPredicate = new ASTUtil.IncludePredicate() {
-		public boolean include(AST node) {
-			FromElement fromElement = ( FromElement ) node;
-			return fromElement.isFetch() && fromElement.getQueryableCollection() != null;
-		}
-	};
-
-	private static ASTUtil.FilterPredicate explicitFromPredicate = new ASTUtil.IncludePredicate() {
-		public boolean include(AST node) {
-			final FromElement fromElement = ( FromElement ) node;
-			return !fromElement.isImplied();
-		}
-	};
-
-	FromElement findCollectionJoin(String path) {
-		return ( FromElement ) collectionJoinFromElementsByPath.get( path );
-	}
-
-	/**
-	 * Look for an existing implicit or explicit join by the
-	 * given path.
-	 */
-	FromElement findJoinByPath(String path) {
-		FromElement elem = findJoinByPathLocal( path );
-		if ( elem == null && parentFromClause != null ) {
-			elem = parentFromClause.findJoinByPath( path );
-		}
-		return elem;
-	}
-
-	FromElement findJoinByPathLocal(String path) {
-		Map joinsByPath = fromElementsByPath;
-		return ( FromElement ) joinsByPath.get( path );
-	}
-
-	void addJoinByPathMap(String path, FromElement destination) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "addJoinByPathMap() : " + path + " -> " + destination );
-		}
-		fromElementsByPath.put( path, destination );
-	}
-
-	/**
-	 * Returns true if the from node contains the class alias name.
-	 *
-	 * @param alias The HQL class alias name.
-	 * @return true if the from node contains the class alias name.
-	 */
-	public boolean containsClassAlias(String alias) {
-		boolean isAlias = fromElementByClassAlias.containsKey( alias );
-		if ( !isAlias && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
-			isAlias = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( alias ) != null;
-		}
-		return isAlias;
-	}
-
-	/**
-	 * Returns true if the from node contains the table alias name.
-	 *
-	 * @param alias The SQL table alias name.
-	 * @return true if the from node contains the table alias name.
-	 */
-	public boolean containsTableAlias(String alias) {
-		return fromElementByTableAlias.keySet().contains( alias );
-	}
-
-	public String getDisplayText() {
-		return "FromClause{" +
-				"level=" + level +
-				", fromElementCounter=" + fromElementCounter +
-				", fromElements=" + fromElements.size() +
-				", fromElementByClassAlias=" + fromElementByClassAlias.keySet() +
-				", fromElementByTableAlias=" + fromElementByTableAlias.keySet() +
-				", fromElementsByPath=" + fromElementsByPath.keySet() +
-				", collectionJoinFromElementsByPath=" + collectionJoinFromElementsByPath.keySet() +
-				", impliedElements=" + impliedElements +
-				"}";
-	}
-
-	public void setParentFromClause(FromClause parentFromClause) {
-		this.parentFromClause = parentFromClause;
-		if ( parentFromClause != null ) {
-			level = parentFromClause.getLevel() + 1;
-			parentFromClause.addChild( this );
-		}
-	}
-
-	private void addChild(FromClause fromClause) {
-		if ( childFromClauses == null ) {
-			childFromClauses = new HashSet();
-		}
-		childFromClauses.add( fromClause );
-	}
-
-	public FromClause locateChildFromClauseWithJoinByPath(String path) {
-		if ( childFromClauses != null && !childFromClauses.isEmpty() ) {
-			Iterator children = childFromClauses.iterator();
-			while ( children.hasNext() ) {
-				FromClause child = ( FromClause ) children.next();
-				if ( child.findJoinByPathLocal( path ) != null ) {
-					return child;
-				}
-			}
-		}
-		return null;
-	}
-
-	public void promoteJoin(FromElement elem) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Promoting [" + elem + "] to [" + this + "]" );
-		}
-		//TODO: implement functionality
-		//  this might be painful to do here, as the "join post processing" for
-		//  the subquery has already been performed (meaning that for
-		//  theta-join dialects, the join conditions have already been moved
-		//  over to the where clause).  A "simple" solution here might to
-		//  perform "join post processing" once for the entire query (including
-		//  any subqueries) at one fell swoop
-	}
-
-	public boolean isSubQuery() {
-		// TODO : this is broke for subqueries in statements other than selects...
-		return parentFromClause != null;
-	}
-
-	void addCollectionJoinFromElementByPath(String path, FromElement destination) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "addCollectionJoinFromElementByPath() : " + path + " -> " + destination );
-		}
-		collectionJoinFromElementsByPath.put( path, destination );	// Add the new node to the map so that we don't create it twice.
-	}
-
-	public FromClause getParentFromClause() {
-		return parentFromClause;
-	}
-
-	public int getLevel() {
-		return level;
-	}
-
-	public int nextFromElementCounter() {
-		return fromElementCounter++;
-	}
-
-	public void resolve() {
-		// Make sure that all from elements registered with this FROM clause are actually in the AST.
-		ASTIterator iter = new ASTIterator( this.getFirstChild() );
-		Set childrenInTree = new HashSet();
-		while ( iter.hasNext() ) {
-			childrenInTree.add( iter.next() );
-		}
-		for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) {
-			FromElement fromElement = ( FromElement ) iterator.next();
-			if ( !childrenInTree.contains( fromElement ) ) {
-				throw new IllegalStateException( "Element not in AST: " + fromElement );
-			}
-		}
-	}
-
-	public void addImpliedFromElement(FromElement element) {
-		impliedElements.add( element );
-	}
-
-	public String toString() {
-		return "FromClause{" +
-				"level=" + level +
-				"}";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,388 @@
+/*
+ * 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.tree;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTIterator;
+import org.hibernate.hql.ast.util.ASTUtil;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Represents the 'FROM' part of a query or subquery, containing all mapped class references.
+ *
+ * @author josh
+ */
+public class FromClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes, DisplayableNode {
+	private static Logger log = LoggerFactory.getLogger( FromClause.class );
+	public static final int ROOT_LEVEL = 1;
+
+	private int level = ROOT_LEVEL;
+	private Set fromElements = new HashSet();
+	private Map fromElementByClassAlias = new HashMap();
+	private Map fromElementByTableAlias = new HashMap();
+	private Map fromElementsByPath = new HashMap();
+
+	/**
+	 * All of the implicit FROM xxx JOIN yyy elements that are the destination of a collection.  These are created from
+	 * index operators on collection property references.
+	 */
+	private Map collectionJoinFromElementsByPath = new HashMap();
+	/**
+	 * Pointer to the parent FROM clause, if there is one.
+	 */
+	private FromClause parentFromClause;
+	/**
+	 * Collection of FROM clauses of which this is the parent.
+	 */
+	private Set childFromClauses;
+	/**
+	 * Counts the from elements as they are added.
+	 */
+	private int fromElementCounter = 0;
+	/**
+	 * Implied FROM elements to add onto the end of the FROM clause.
+	 */
+	private List impliedElements = new LinkedList();
+
+	/**
+	 * Adds a new from element to the from node.
+	 *
+	 * @param path  The reference to the class.
+	 * @param alias The alias AST.
+	 * @return FromElement - The new FROM element.
+	 */
+	public FromElement addFromElement(String path, AST alias) throws SemanticException {
+		// The path may be a reference to an alias defined in the parent query.
+		String classAlias = ( alias == null ) ? null : alias.getText();
+		checkForDuplicateClassAlias( classAlias );
+		FromElementFactory factory = new FromElementFactory( this, null, path, classAlias, null, false );
+		return factory.addFromElement();
+	}
+
+	void registerFromElement(FromElement element) {
+		fromElements.add( element );
+		String classAlias = element.getClassAlias();
+		if ( classAlias != null ) {
+			// The HQL class alias refers to the class name.
+			fromElementByClassAlias.put( classAlias, element );
+		}
+		// Associate the table alias with the element.
+		String tableAlias = element.getTableAlias();
+		if ( tableAlias != null ) {
+			fromElementByTableAlias.put( tableAlias, element );
+		}
+	}
+
+	void addDuplicateAlias(String alias, FromElement element) {
+		if ( alias != null ) {
+			fromElementByClassAlias.put( alias, element );
+		}
+	}
+
+	private void checkForDuplicateClassAlias(String classAlias) throws SemanticException {
+		if ( classAlias != null && fromElementByClassAlias.containsKey( classAlias ) ) {
+			throw new SemanticException( "Duplicate definition of alias '" + classAlias + "'" );
+		}
+	}
+
+	/**
+	 * Retreives the from-element represented by the given alias.
+	 *
+	 * @param aliasOrClassName The alias by which to locate the from-element.
+	 * @return The from-element assigned the given alias, or null if none.
+	 */
+	public FromElement getFromElement(String aliasOrClassName) {
+		FromElement fromElement = ( FromElement ) fromElementByClassAlias.get( aliasOrClassName );
+		if ( fromElement == null && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
+			fromElement = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( aliasOrClassName );
+		}
+		if ( fromElement == null && parentFromClause != null ) {
+			fromElement = parentFromClause.getFromElement( aliasOrClassName );
+		}
+		return fromElement;
+	}
+
+	private FromElement findIntendedAliasedFromElementBasedOnCrazyJPARequirements(String specifiedAlias) {
+		Iterator itr = fromElementByClassAlias.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			String alias = ( String ) entry.getKey();
+			if ( alias.equalsIgnoreCase( specifiedAlias ) ) {
+				return ( FromElement ) entry.getValue();
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Convenience method to check whether a given token represents a from-element alias.
+	 *
+	 * @param possibleAlias The potential from-element alias to check.
+	 * @return True if the possibleAlias is an alias to a from-element visible
+	 *         from this point in the query graph.
+	 */
+	public boolean isFromElementAlias(String possibleAlias) {
+		boolean isAlias = containsClassAlias( possibleAlias );
+		if ( !isAlias && parentFromClause != null ) {
+			// try the parent FromClause...
+			isAlias = parentFromClause.isFromElementAlias( possibleAlias );
+		}
+		return isAlias;
+	}
+
+	/**
+	 * Returns the list of from elements in order.
+	 *
+	 * @return the list of from elements (instances of FromElement).
+	 */
+	public List getFromElements() {
+		return ASTUtil.collectChildren( this, fromElementPredicate );
+	}
+	
+	public FromElement getFromElement() {
+		// TODO: not sure about this one
+//		List fromElements = getFromElements();
+//		if ( fromElements == null || fromElements.isEmpty() ) {
+//			throw new QueryException( "Unable to locate from element" );
+//		}
+		return (FromElement) getFromElements().get(0);
+	}
+
+	/**
+	 * Returns the list of from elements that will be part of the result set.
+	 *
+	 * @return the list of from elements that will be part of the result set.
+	 */
+	public List getProjectionList() {
+		return ASTUtil.collectChildren( this, projectionListPredicate );
+	}
+
+	public List getCollectionFetches() {
+		return ASTUtil.collectChildren( this, collectionFetchPredicate );
+	}
+
+	public boolean hasCollectionFecthes() {
+		return getCollectionFetches().size() > 0;
+	}
+
+	public List getExplicitFromElements() {
+		return ASTUtil.collectChildren( this, explicitFromPredicate );
+	}
+
+	private static ASTUtil.FilterPredicate fromElementPredicate = new ASTUtil.IncludePredicate() {
+		public boolean include(AST node) {
+			FromElement fromElement = ( FromElement ) node;
+			return fromElement.isFromOrJoinFragment();
+		}
+	};
+
+	private static ASTUtil.FilterPredicate projectionListPredicate = new ASTUtil.IncludePredicate() {
+		public boolean include(AST node) {
+			FromElement fromElement = ( FromElement ) node;
+			return fromElement.inProjectionList();
+		}
+	};
+
+	private static ASTUtil.FilterPredicate collectionFetchPredicate = new ASTUtil.IncludePredicate() {
+		public boolean include(AST node) {
+			FromElement fromElement = ( FromElement ) node;
+			return fromElement.isFetch() && fromElement.getQueryableCollection() != null;
+		}
+	};
+
+	private static ASTUtil.FilterPredicate explicitFromPredicate = new ASTUtil.IncludePredicate() {
+		public boolean include(AST node) {
+			final FromElement fromElement = ( FromElement ) node;
+			return !fromElement.isImplied();
+		}
+	};
+
+	FromElement findCollectionJoin(String path) {
+		return ( FromElement ) collectionJoinFromElementsByPath.get( path );
+	}
+
+	/**
+	 * Look for an existing implicit or explicit join by the
+	 * given path.
+	 */
+	FromElement findJoinByPath(String path) {
+		FromElement elem = findJoinByPathLocal( path );
+		if ( elem == null && parentFromClause != null ) {
+			elem = parentFromClause.findJoinByPath( path );
+		}
+		return elem;
+	}
+
+	FromElement findJoinByPathLocal(String path) {
+		Map joinsByPath = fromElementsByPath;
+		return ( FromElement ) joinsByPath.get( path );
+	}
+
+	void addJoinByPathMap(String path, FromElement destination) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "addJoinByPathMap() : " + path + " -> " + destination );
+		}
+		fromElementsByPath.put( path, destination );
+	}
+
+	/**
+	 * Returns true if the from node contains the class alias name.
+	 *
+	 * @param alias The HQL class alias name.
+	 * @return true if the from node contains the class alias name.
+	 */
+	public boolean containsClassAlias(String alias) {
+		boolean isAlias = fromElementByClassAlias.containsKey( alias );
+		if ( !isAlias && getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() ) {
+			isAlias = findIntendedAliasedFromElementBasedOnCrazyJPARequirements( alias ) != null;
+		}
+		return isAlias;
+	}
+
+	/**
+	 * Returns true if the from node contains the table alias name.
+	 *
+	 * @param alias The SQL table alias name.
+	 * @return true if the from node contains the table alias name.
+	 */
+	public boolean containsTableAlias(String alias) {
+		return fromElementByTableAlias.keySet().contains( alias );
+	}
+
+	public String getDisplayText() {
+		return "FromClause{" +
+				"level=" + level +
+				", fromElementCounter=" + fromElementCounter +
+				", fromElements=" + fromElements.size() +
+				", fromElementByClassAlias=" + fromElementByClassAlias.keySet() +
+				", fromElementByTableAlias=" + fromElementByTableAlias.keySet() +
+				", fromElementsByPath=" + fromElementsByPath.keySet() +
+				", collectionJoinFromElementsByPath=" + collectionJoinFromElementsByPath.keySet() +
+				", impliedElements=" + impliedElements +
+				"}";
+	}
+
+	public void setParentFromClause(FromClause parentFromClause) {
+		this.parentFromClause = parentFromClause;
+		if ( parentFromClause != null ) {
+			level = parentFromClause.getLevel() + 1;
+			parentFromClause.addChild( this );
+		}
+	}
+
+	private void addChild(FromClause fromClause) {
+		if ( childFromClauses == null ) {
+			childFromClauses = new HashSet();
+		}
+		childFromClauses.add( fromClause );
+	}
+
+	public FromClause locateChildFromClauseWithJoinByPath(String path) {
+		if ( childFromClauses != null && !childFromClauses.isEmpty() ) {
+			Iterator children = childFromClauses.iterator();
+			while ( children.hasNext() ) {
+				FromClause child = ( FromClause ) children.next();
+				if ( child.findJoinByPathLocal( path ) != null ) {
+					return child;
+				}
+			}
+		}
+		return null;
+	}
+
+	public void promoteJoin(FromElement elem) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Promoting [" + elem + "] to [" + this + "]" );
+		}
+		//TODO: implement functionality
+		//  this might be painful to do here, as the "join post processing" for
+		//  the subquery has already been performed (meaning that for
+		//  theta-join dialects, the join conditions have already been moved
+		//  over to the where clause).  A "simple" solution here might to
+		//  perform "join post processing" once for the entire query (including
+		//  any subqueries) at one fell swoop
+	}
+
+	public boolean isSubQuery() {
+		// TODO : this is broke for subqueries in statements other than selects...
+		return parentFromClause != null;
+	}
+
+	void addCollectionJoinFromElementByPath(String path, FromElement destination) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "addCollectionJoinFromElementByPath() : " + path + " -> " + destination );
+		}
+		collectionJoinFromElementsByPath.put( path, destination );	// Add the new node to the map so that we don't create it twice.
+	}
+
+	public FromClause getParentFromClause() {
+		return parentFromClause;
+	}
+
+	public int getLevel() {
+		return level;
+	}
+
+	public int nextFromElementCounter() {
+		return fromElementCounter++;
+	}
+
+	public void resolve() {
+		// Make sure that all from elements registered with this FROM clause are actually in the AST.
+		ASTIterator iter = new ASTIterator( this.getFirstChild() );
+		Set childrenInTree = new HashSet();
+		while ( iter.hasNext() ) {
+			childrenInTree.add( iter.next() );
+		}
+		for ( Iterator iterator = fromElements.iterator(); iterator.hasNext(); ) {
+			FromElement fromElement = ( FromElement ) iterator.next();
+			if ( !childrenInTree.contains( fromElement ) ) {
+				throw new IllegalStateException( "Element not in AST: " + fromElement );
+			}
+		}
+	}
+
+	public void addImpliedFromElement(FromElement element) {
+		impliedElements.add( element );
+	}
+
+	public String toString() {
+		return "FromClause{" +
+				"level=" + level +
+				"}";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,551 +0,0 @@
-// $Id: FromElement.java 10852 2006-11-21 17:39:14Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import java.util.LinkedList;
-import java.util.List;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a single mapped class mentioned in an HQL FROM clause.  Each
- * class reference will have the following symbols:
- * <ul>
- * <li>A class name - This is the name of the Java class that is mapped by Hibernate.</li>
- * <li>[optional] an HQL alias for the mapped class.</li>
- * <li>A table name - The name of the table that is mapped to the Java class.</li>
- * <li>A table alias - The alias for the table that will be used in the resulting SQL.</li>
- * </ul>
- * <br>
- * User: josh<br>
- * Date: Dec 6, 2003<br>
- * Time: 10:28:17 AM<br>
- */
-public class FromElement extends HqlSqlWalkerNode implements DisplayableNode {
-	private static final Logger log = LoggerFactory.getLogger( FromElement.class );
-
-	private String className;
-	private String classAlias;
-	private String tableAlias;
-	private String collectionTableAlias;
-	private FromClause fromClause;
-	private boolean includeSubclasses = true;
-	private boolean collectionJoin = false;
-	private FromElement origin;
-	private String[] columns;
-	private String role;
-	private boolean fetch;
-	private boolean isAllPropertyFetch;
-	private boolean filter = false;
-	private int sequence = -1;
-	private boolean useFromFragment = false;
-	private boolean initialized = false;
-	private FromElementType elementType;
-	private boolean useWhereFragment = true;
-	private List destinations = new LinkedList();
-	private boolean manyToMany = false;
-	private String withClauseFragment = null;
-	private String withClauseJoinAlias;
-	private boolean dereferencedBySuperclassProperty;
-	private boolean dereferencedBySubclassProperty;
-
-	public FromElement() {
-	}
-
-	public String getCollectionSuffix() {
-		return elementType.getCollectionSuffix();
-	}
-
-	public void setCollectionSuffix(String suffix) {
-		elementType.setCollectionSuffix(suffix);
-	}
-
-	public void initializeCollection(FromClause fromClause, String classAlias, String tableAlias) {
-		doInitialize( fromClause, tableAlias, null, classAlias, null, null );
-		initialized = true;
-	}
-
-	public void initializeEntity(
-	        FromClause fromClause,
-	        String className,
-	        EntityPersister persister,
-	        EntityType type,
-	        String classAlias,
-	        String tableAlias) {
-		doInitialize( fromClause, tableAlias, className, classAlias, persister, type );
-		this.sequence = fromClause.nextFromElementCounter();
-		initialized = true;
-	}
-
-	private void doInitialize(FromClause fromClause, String tableAlias, String className, String classAlias,
-							  EntityPersister persister, EntityType type) {
-		if ( initialized ) {
-			throw new IllegalStateException( "Already initialized!!" );
-		}
-		this.fromClause = fromClause;
-		this.tableAlias = tableAlias;
-		this.className = className;
-		this.classAlias = classAlias;
-		this.elementType = new FromElementType( this, persister, type );
-		// Register the FromElement with the FROM clause, now that we have the names and aliases.
-		fromClause.registerFromElement( this );
-		if ( log.isDebugEnabled() ) {
-			log.debug( fromClause + " :  " + className + " ("
-					+ ( classAlias == null ? "no alias" : classAlias ) + ") -> " + tableAlias );
-		}
-	}
-
-	public EntityPersister getEntityPersister() {
-		return elementType.getEntityPersister();
-	}
-
-	public Type getDataType() {
-		return elementType.getDataType();
-	}
-
-	public Type getSelectType() {
-		return elementType.getSelectType();
-	}
-
-	public Queryable getQueryable() {
-		return elementType.getQueryable();
-	}
-
-	public String getClassName() {
-		return className;
-	}
-
-	public String getClassAlias() {
-		return classAlias;
-		//return classAlias == null ? className : classAlias;
-	}
-
-	private String getTableName() {
-		Queryable queryable = getQueryable();
-		return ( queryable != null ) ? queryable.getTableName() : "{none}";
-	}
-
-	public String getTableAlias() {
-		return tableAlias;
-	}
-
-	/**
-	 * Render the identifier select, but in a 'scalar' context (i.e. generate the column alias).
-	 *
-	 * @param i the sequence of the returned type
-	 * @return the identifier select with the column alias.
-	 */
-	String renderScalarIdentifierSelect(int i) {
-		return elementType.renderScalarIdentifierSelect( i );
-	}
-
-	void checkInitialized() {
-		if ( !initialized ) {
-			throw new IllegalStateException( "FromElement has not been initialized!" );
-		}
-	}
-
-	/**
-	 * Returns the identifier select SQL fragment.
-	 *
-	 * @param size The total number of returned types.
-	 * @param k    The sequence of the current returned type.
-	 * @return the identifier select SQL fragment.
-	 */
-	String renderIdentifierSelect(int size, int k) {
-		return elementType.renderIdentifierSelect( size, k );
-	}
-
-	/**
-	 * Returns the property select SQL fragment.
-	 *
-	 * @param size The total number of returned types.
-	 * @param k    The sequence of the current returned type.
-	 * @return the property select SQL fragment.
-	 */
-	String renderPropertySelect(int size, int k) {
-		return elementType.renderPropertySelect( size, k, isAllPropertyFetch );
-	}
-
-	String renderCollectionSelectFragment(int size, int k) {
-		return elementType.renderCollectionSelectFragment( size, k );
-	}
-
-	String renderValueCollectionSelectFragment(int size, int k) {
-		return elementType.renderValueCollectionSelectFragment( size, k );
-	}
-
-	public FromClause getFromClause() {
-		return fromClause;
-	}
-
-	/**
-	 * Returns true if this FromElement was implied by a path, or false if this FROM element is explicitly declared in
-	 * the FROM clause.
-	 *
-	 * @return true if this FromElement was implied by a path, or false if this FROM element is explicitly declared
-	 */
-	public boolean isImplied() {
-		return false;	// This is an explicit FROM element.
-	}
-
-	/**
-	 * Returns additional display text for the AST node.
-	 *
-	 * @return String - The additional display text.
-	 */
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "FromElement{" );
-		appendDisplayText( buf );
-		buf.append( "}" );
-		return buf.toString();
-	}
-
-	protected void appendDisplayText(StringBuffer buf) {
-		buf.append( isImplied() ? (
-				isImpliedInFromClause() ? "implied in FROM clause" : "implied" )
-				: "explicit" );
-		buf.append( "," ).append( isCollectionJoin() ? "collection join" : "not a collection join" );
-		buf.append( "," ).append( fetch ? "fetch join" : "not a fetch join" );
-		buf.append( "," ).append( isAllPropertyFetch ? "fetch all properties" : "fetch non-lazy properties" );
-		buf.append( ",classAlias=" ).append( getClassAlias() );
-		buf.append( ",role=" ).append( role );
-		buf.append( ",tableName=" ).append( getTableName() );
-		buf.append( ",tableAlias=" ).append( getTableAlias() );
-		FromElement origin = getRealOrigin();
-		buf.append( ",origin=" ).append( origin == null ? "null" : origin.getText() );
-		buf.append( ",colums={" );
-		if ( columns != null ) {
-			for ( int i = 0; i < columns.length; i++ ) {
-				buf.append( columns[i] );
-				if ( i < columns.length ) {
-					buf.append( " " );
-				}
-			}
-		}
-		buf.append( ",className=" ).append( className );
-		buf.append( "}" );
-	}
-
-	public int hashCode() {
-		return super.hashCode();
-	}
-
-	public boolean equals(Object obj) {
-		return super.equals( obj );
-	}
-
-
-	public void setJoinSequence(JoinSequence joinSequence) {
-		elementType.setJoinSequence( joinSequence );
-	}
-
-	public JoinSequence getJoinSequence() {
-		return elementType.getJoinSequence();
-	}
-
-	public void setIncludeSubclasses(boolean includeSubclasses) {
-		if ( isDereferencedBySuperclassOrSubclassProperty() ) {
-			if ( !includeSubclasses && log.isTraceEnabled() ) {
-				log.trace( "attempt to disable subclass-inclusions", new Exception( "stack-trace source" ) );
-			}
-		}
-		this.includeSubclasses = includeSubclasses;
-	}
-
-	public boolean isIncludeSubclasses() {
-		return includeSubclasses;
-	}
-
-	public boolean isDereferencedBySuperclassOrSubclassProperty() {
-		return dereferencedBySubclassProperty || dereferencedBySuperclassProperty;
-	}
-
-	public String getIdentityColumn() {
-		checkInitialized();
-		String table = getTableAlias();
-		if ( table == null ) {
-			throw new IllegalStateException( "No table alias for node " + this );
-		}
-		String[] cols;
-		String propertyName;
-		if ( getEntityPersister() != null && getEntityPersister().getEntityMetamodel() != null
-				&& getEntityPersister().getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
-			propertyName = getEntityPersister().getIdentifierPropertyName();
-		}
-		else {
-			propertyName = EntityPersister.ENTITY_ID;
-		}
-		if ( getWalker().getStatementType() == HqlSqlWalker.SELECT ) {
-			cols = getPropertyMapping( propertyName ).toColumns( table, propertyName );
-		}
-		else {
-			cols = getPropertyMapping( propertyName ).toColumns( propertyName );
-		}
-		String result = StringHelper.join( ", ", cols );
-		return  cols.length == 1 ? result : "(" + result + ")";
-	}
-
-	public void setCollectionJoin(boolean collectionJoin) {
-		this.collectionJoin = collectionJoin;
-	}
-
-	public boolean isCollectionJoin() {
-		return collectionJoin;
-	}
-
-	public void setRole(String role) {
-		this.role = role;
-	}
-
-	public void setQueryableCollection(QueryableCollection queryableCollection) {
-		elementType.setQueryableCollection( queryableCollection );
-	}
-
-	public QueryableCollection getQueryableCollection() {
-		return elementType.getQueryableCollection();
-	}
-
-	public void setColumns(String[] columns) {
-		this.columns = columns;
-	}
-
-	public void setOrigin(FromElement origin, boolean manyToMany) {
-		this.origin = origin;
-		this.manyToMany = manyToMany;
-		origin.addDestination( this );
-		if ( origin.getFromClause() == this.getFromClause() ) {
-			// TODO: Figure out a better way to get the FROM elements in a proper tree structure.
-			// If this is not the destination of a many-to-many, add it as a child of the origin.
-			if ( manyToMany ) {
-				ASTUtil.appendSibling( origin, this );
-			}
-			else {
-				if ( !getWalker().isInFrom() && !getWalker().isInSelect() ) {
-					getFromClause().addChild( this );
-				}
-				else {
-					origin.addChild( this );
-				}
-			}
-		}
-		else if ( !getWalker().isInFrom() ) {
-			// HHH-276 : implied joins in a subselect where clause - The destination needs to be added
-			// to the destination's from clause.
-			getFromClause().addChild( this );	// Not sure if this is will fix everything, but it works.
-		}
-		else {
-			// Otherwise, the destination node was implied by the FROM clause and the FROM clause processor
-			// will automatically add it in the right place.
-		}
-	}
-
-	public boolean isManyToMany() {
-		return manyToMany;
-	}
-
-	private void addDestination(FromElement fromElement) {
-		destinations.add( fromElement );
-	}
-
-	public List getDestinations() {
-		return destinations;
-	}
-
-	public FromElement getOrigin() {
-		return origin;
-	}
-
-	public FromElement getRealOrigin() {
-		if ( origin == null ) {
-			return null;
-		}
-		if ( origin.getText() == null || "".equals( origin.getText() ) ) {
-			return origin.getRealOrigin();
-		}
-		return origin;
-	}
-
-	public Type getPropertyType(String propertyName, String propertyPath) {
-		return elementType.getPropertyType( propertyName, propertyPath );
-	}
-
-	public String[] toColumns(String tableAlias, String path, boolean inSelect) {
-		return elementType.toColumns( tableAlias, path, inSelect );
-	}
-
-	public String[] toColumns(String tableAlias, String path, boolean inSelect, boolean forceAlias) {
-		return elementType.toColumns( tableAlias, path, inSelect, forceAlias );
-	}
-
-	public PropertyMapping getPropertyMapping(String propertyName) {
-		return elementType.getPropertyMapping( propertyName );
-	}
-
-	public void setFetch(boolean fetch) {
-		this.fetch = fetch;
-		// Fetch can't be used with scroll() or iterate().
-		if ( fetch && getWalker().isShallowQuery() ) {
-			throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE );
-		}
-	}
-
-	public boolean isFetch() {
-		return fetch;
-	}
-
-	public int getSequence() {
-		return sequence;
-	}
-
-	public void setFilter(boolean b) {
-		filter = b;
-	}
-
-	public boolean isFilter() {
-		return filter;
-	}
-
-	public boolean useFromFragment() {
-		checkInitialized();
-		// If it's not implied or it is implied and it's a many to many join where the target wasn't found.
-		return !isImplied() || this.useFromFragment;
-	}
-
-	public void setUseFromFragment(boolean useFromFragment) {
-		this.useFromFragment = useFromFragment;
-	}
-
-	public boolean useWhereFragment() {
-		return useWhereFragment;
-	}
-
-	public void setUseWhereFragment(boolean b) {
-		useWhereFragment = b;
-	}
-
-
-	public void setCollectionTableAlias(String collectionTableAlias) {
-		this.collectionTableAlias = collectionTableAlias;
-	}
-
-	public String getCollectionTableAlias() {
-		return collectionTableAlias;
-	}
-
-	public boolean isCollectionOfValuesOrComponents() {
-		return elementType.isCollectionOfValuesOrComponents();
-	}
-
-	public boolean isEntity() {
-		return elementType.isEntity();
-	}
-
-	public void setImpliedInFromClause(boolean flag) {
-		throw new UnsupportedOperationException( "Explicit FROM elements can't be implied in the FROM clause!" );
-	}
-
-	public boolean isImpliedInFromClause() {
-		return false;	// Since this is an explicit FROM element, it can't be implied in the FROM clause.
-	}
-
-	public void setInProjectionList(boolean inProjectionList) {
-		// Do nothing, eplicit from elements are *always* in the projection list.
-	}
-
-	public boolean inProjectionList() {
-		return !isImplied() && isFromOrJoinFragment();
-	}
-
-	public boolean isFromOrJoinFragment() {
-		return getType() == SqlTokenTypes.FROM_FRAGMENT || getType() == SqlTokenTypes.JOIN_FRAGMENT;
-	}
-
-	public boolean isAllPropertyFetch() {
-		return isAllPropertyFetch;
-	}
-
-	public void setAllPropertyFetch(boolean fetch) {
-		isAllPropertyFetch = fetch;
-	}
-
-	public String getWithClauseFragment() {
-		return withClauseFragment;
-	}
-
-	public String getWithClauseJoinAlias() {
-		return withClauseJoinAlias;
-	}
-
-	public void setWithClauseFragment(String withClauseJoinAlias, String withClauseFragment) {
-		this.withClauseJoinAlias = withClauseJoinAlias;
-		this.withClauseFragment = withClauseFragment;
-	}
-
-	public boolean hasCacheablePersister() {
-		if ( getQueryableCollection() != null ) {
-			return getQueryableCollection().hasCache();
-		}
-		else {
-			return getQueryable().hasCache();
-		}
-	}
-
-	public void handlePropertyBeingDereferenced(Type propertySource, String propertyName) {
-		if ( getQueryableCollection() != null && CollectionProperties.isCollectionProperty( propertyName ) ) {
-			// propertyName refers to something like collection.size...
-			return;
-		}
-		if ( propertySource.isComponentType() ) {
-			// property name is a sub-path of a component...
-			return;
-		}
-
-		Queryable persister = getQueryable();
-		if ( persister != null ) {
-			try {
-				Queryable.Declarer propertyDeclarer = persister.getSubclassPropertyDeclarer( propertyName );
-				if ( log.isTraceEnabled() ) {
-					log.trace( "handling property dereference [" + persister.getEntityName() + " (" + getClassAlias() + ") -> " + propertyName + " (" + propertyDeclarer + ")]" );
-				}
-				if ( propertyDeclarer == Queryable.Declarer.SUBCLASS ) {
-					dereferencedBySubclassProperty = true;
-					includeSubclasses = true;
-				}
-				else if ( propertyDeclarer == Queryable.Declarer.SUPERCLASS ) {
-					dereferencedBySuperclassProperty = true;
-				}
-			}
-			catch( QueryException ignore ) {
-				// ignore it; the incoming property could not be found so we
-				// cannot be sure what to do here.  At the very least, the
-				// safest is to simply not apply any dereference toggling...
-
-			}
-		}
-	}
-
-	public boolean isDereferencedBySuperclassProperty() {
-		return dereferencedBySuperclassProperty;
-	}
-
-	public boolean isDereferencedBySubclassProperty() {
-		return dereferencedBySubclassProperty;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,572 @@
+/*
+ * 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.tree;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a single mapped class mentioned in an HQL FROM clause.  Each
+ * class reference will have the following symbols:
+ * <ul>
+ * <li>A class name - This is the name of the Java class that is mapped by Hibernate.</li>
+ * <li>[optional] an HQL alias for the mapped class.</li>
+ * <li>A table name - The name of the table that is mapped to the Java class.</li>
+ * <li>A table alias - The alias for the table that will be used in the resulting SQL.</li>
+ * </ul>
+ *
+ * @author josh
+ */
+public class FromElement extends HqlSqlWalkerNode implements DisplayableNode {
+	private static final Logger log = LoggerFactory.getLogger( FromElement.class );
+
+	private String className;
+	private String classAlias;
+	private String tableAlias;
+	private String collectionTableAlias;
+	private FromClause fromClause;
+	private boolean includeSubclasses = true;
+	private boolean collectionJoin = false;
+	private FromElement origin;
+	private String[] columns;
+	private String role;
+	private boolean fetch;
+	private boolean isAllPropertyFetch;
+	private boolean filter = false;
+	private int sequence = -1;
+	private boolean useFromFragment = false;
+	private boolean initialized = false;
+	private FromElementType elementType;
+	private boolean useWhereFragment = true;
+	private List destinations = new LinkedList();
+	private boolean manyToMany = false;
+	private String withClauseFragment = null;
+	private String withClauseJoinAlias;
+	private boolean dereferencedBySuperclassProperty;
+	private boolean dereferencedBySubclassProperty;
+
+	public FromElement() {
+	}
+
+	public String getCollectionSuffix() {
+		return elementType.getCollectionSuffix();
+	}
+
+	public void setCollectionSuffix(String suffix) {
+		elementType.setCollectionSuffix(suffix);
+	}
+
+	public void initializeCollection(FromClause fromClause, String classAlias, String tableAlias) {
+		doInitialize( fromClause, tableAlias, null, classAlias, null, null );
+		initialized = true;
+	}
+
+	public void initializeEntity(
+	        FromClause fromClause,
+	        String className,
+	        EntityPersister persister,
+	        EntityType type,
+	        String classAlias,
+	        String tableAlias) {
+		doInitialize( fromClause, tableAlias, className, classAlias, persister, type );
+		this.sequence = fromClause.nextFromElementCounter();
+		initialized = true;
+	}
+
+	private void doInitialize(FromClause fromClause, String tableAlias, String className, String classAlias,
+							  EntityPersister persister, EntityType type) {
+		if ( initialized ) {
+			throw new IllegalStateException( "Already initialized!!" );
+		}
+		this.fromClause = fromClause;
+		this.tableAlias = tableAlias;
+		this.className = className;
+		this.classAlias = classAlias;
+		this.elementType = new FromElementType( this, persister, type );
+		// Register the FromElement with the FROM clause, now that we have the names and aliases.
+		fromClause.registerFromElement( this );
+		if ( log.isDebugEnabled() ) {
+			log.debug( fromClause + " :  " + className + " ("
+					+ ( classAlias == null ? "no alias" : classAlias ) + ") -> " + tableAlias );
+		}
+	}
+
+	public EntityPersister getEntityPersister() {
+		return elementType.getEntityPersister();
+	}
+
+	public Type getDataType() {
+		return elementType.getDataType();
+	}
+
+	public Type getSelectType() {
+		return elementType.getSelectType();
+	}
+
+	public Queryable getQueryable() {
+		return elementType.getQueryable();
+	}
+
+	public String getClassName() {
+		return className;
+	}
+
+	public String getClassAlias() {
+		return classAlias;
+		//return classAlias == null ? className : classAlias;
+	}
+
+	private String getTableName() {
+		Queryable queryable = getQueryable();
+		return ( queryable != null ) ? queryable.getTableName() : "{none}";
+	}
+
+	public String getTableAlias() {
+		return tableAlias;
+	}
+
+	/**
+	 * Render the identifier select, but in a 'scalar' context (i.e. generate the column alias).
+	 *
+	 * @param i the sequence of the returned type
+	 * @return the identifier select with the column alias.
+	 */
+	String renderScalarIdentifierSelect(int i) {
+		return elementType.renderScalarIdentifierSelect( i );
+	}
+
+	void checkInitialized() {
+		if ( !initialized ) {
+			throw new IllegalStateException( "FromElement has not been initialized!" );
+		}
+	}
+
+	/**
+	 * Returns the identifier select SQL fragment.
+	 *
+	 * @param size The total number of returned types.
+	 * @param k    The sequence of the current returned type.
+	 * @return the identifier select SQL fragment.
+	 */
+	String renderIdentifierSelect(int size, int k) {
+		return elementType.renderIdentifierSelect( size, k );
+	}
+
+	/**
+	 * Returns the property select SQL fragment.
+	 *
+	 * @param size The total number of returned types.
+	 * @param k    The sequence of the current returned type.
+	 * @return the property select SQL fragment.
+	 */
+	String renderPropertySelect(int size, int k) {
+		return elementType.renderPropertySelect( size, k, isAllPropertyFetch );
+	}
+
+	String renderCollectionSelectFragment(int size, int k) {
+		return elementType.renderCollectionSelectFragment( size, k );
+	}
+
+	String renderValueCollectionSelectFragment(int size, int k) {
+		return elementType.renderValueCollectionSelectFragment( size, k );
+	}
+
+	public FromClause getFromClause() {
+		return fromClause;
+	}
+
+	/**
+	 * Returns true if this FromElement was implied by a path, or false if this FROM element is explicitly declared in
+	 * the FROM clause.
+	 *
+	 * @return true if this FromElement was implied by a path, or false if this FROM element is explicitly declared
+	 */
+	public boolean isImplied() {
+		return false;	// This is an explicit FROM element.
+	}
+
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return String - The additional display text.
+	 */
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "FromElement{" );
+		appendDisplayText( buf );
+		buf.append( "}" );
+		return buf.toString();
+	}
+
+	protected void appendDisplayText(StringBuffer buf) {
+		buf.append( isImplied() ? (
+				isImpliedInFromClause() ? "implied in FROM clause" : "implied" )
+				: "explicit" );
+		buf.append( "," ).append( isCollectionJoin() ? "collection join" : "not a collection join" );
+		buf.append( "," ).append( fetch ? "fetch join" : "not a fetch join" );
+		buf.append( "," ).append( isAllPropertyFetch ? "fetch all properties" : "fetch non-lazy properties" );
+		buf.append( ",classAlias=" ).append( getClassAlias() );
+		buf.append( ",role=" ).append( role );
+		buf.append( ",tableName=" ).append( getTableName() );
+		buf.append( ",tableAlias=" ).append( getTableAlias() );
+		FromElement origin = getRealOrigin();
+		buf.append( ",origin=" ).append( origin == null ? "null" : origin.getText() );
+		buf.append( ",colums={" );
+		if ( columns != null ) {
+			for ( int i = 0; i < columns.length; i++ ) {
+				buf.append( columns[i] );
+				if ( i < columns.length ) {
+					buf.append( " " );
+				}
+			}
+		}
+		buf.append( ",className=" ).append( className );
+		buf.append( "}" );
+	}
+
+	public int hashCode() {
+		return super.hashCode();
+	}
+
+	public boolean equals(Object obj) {
+		return super.equals( obj );
+	}
+
+
+	public void setJoinSequence(JoinSequence joinSequence) {
+		elementType.setJoinSequence( joinSequence );
+	}
+
+	public JoinSequence getJoinSequence() {
+		return elementType.getJoinSequence();
+	}
+
+	public void setIncludeSubclasses(boolean includeSubclasses) {
+		if ( isDereferencedBySuperclassOrSubclassProperty() ) {
+			if ( !includeSubclasses && log.isTraceEnabled() ) {
+				log.trace( "attempt to disable subclass-inclusions", new Exception( "stack-trace source" ) );
+			}
+		}
+		this.includeSubclasses = includeSubclasses;
+	}
+
+	public boolean isIncludeSubclasses() {
+		return includeSubclasses;
+	}
+
+	public boolean isDereferencedBySuperclassOrSubclassProperty() {
+		return dereferencedBySubclassProperty || dereferencedBySuperclassProperty;
+	}
+
+	public String getIdentityColumn() {
+		checkInitialized();
+		String table = getTableAlias();
+		if ( table == null ) {
+			throw new IllegalStateException( "No table alias for node " + this );
+		}
+		String[] cols;
+		String propertyName;
+		if ( getEntityPersister() != null && getEntityPersister().getEntityMetamodel() != null
+				&& getEntityPersister().getEntityMetamodel().hasNonIdentifierPropertyNamedId() ) {
+			propertyName = getEntityPersister().getIdentifierPropertyName();
+		}
+		else {
+			propertyName = EntityPersister.ENTITY_ID;
+		}
+		if ( getWalker().getStatementType() == HqlSqlWalker.SELECT ) {
+			cols = getPropertyMapping( propertyName ).toColumns( table, propertyName );
+		}
+		else {
+			cols = getPropertyMapping( propertyName ).toColumns( propertyName );
+		}
+		String result = StringHelper.join( ", ", cols );
+		return  cols.length == 1 ? result : "(" + result + ")";
+	}
+
+	public void setCollectionJoin(boolean collectionJoin) {
+		this.collectionJoin = collectionJoin;
+	}
+
+	public boolean isCollectionJoin() {
+		return collectionJoin;
+	}
+
+	public void setRole(String role) {
+		this.role = role;
+	}
+
+	public void setQueryableCollection(QueryableCollection queryableCollection) {
+		elementType.setQueryableCollection( queryableCollection );
+	}
+
+	public QueryableCollection getQueryableCollection() {
+		return elementType.getQueryableCollection();
+	}
+
+	public void setColumns(String[] columns) {
+		this.columns = columns;
+	}
+
+	public void setOrigin(FromElement origin, boolean manyToMany) {
+		this.origin = origin;
+		this.manyToMany = manyToMany;
+		origin.addDestination( this );
+		if ( origin.getFromClause() == this.getFromClause() ) {
+			// TODO: Figure out a better way to get the FROM elements in a proper tree structure.
+			// If this is not the destination of a many-to-many, add it as a child of the origin.
+			if ( manyToMany ) {
+				ASTUtil.appendSibling( origin, this );
+			}
+			else {
+				if ( !getWalker().isInFrom() && !getWalker().isInSelect() ) {
+					getFromClause().addChild( this );
+				}
+				else {
+					origin.addChild( this );
+				}
+			}
+		}
+		else if ( !getWalker().isInFrom() ) {
+			// HHH-276 : implied joins in a subselect where clause - The destination needs to be added
+			// to the destination's from clause.
+			getFromClause().addChild( this );	// Not sure if this is will fix everything, but it works.
+		}
+		else {
+			// Otherwise, the destination node was implied by the FROM clause and the FROM clause processor
+			// will automatically add it in the right place.
+		}
+	}
+
+	public boolean isManyToMany() {
+		return manyToMany;
+	}
+
+	private void addDestination(FromElement fromElement) {
+		destinations.add( fromElement );
+	}
+
+	public List getDestinations() {
+		return destinations;
+	}
+
+	public FromElement getOrigin() {
+		return origin;
+	}
+
+	public FromElement getRealOrigin() {
+		if ( origin == null ) {
+			return null;
+		}
+		if ( origin.getText() == null || "".equals( origin.getText() ) ) {
+			return origin.getRealOrigin();
+		}
+		return origin;
+	}
+
+	public Type getPropertyType(String propertyName, String propertyPath) {
+		return elementType.getPropertyType( propertyName, propertyPath );
+	}
+
+	public String[] toColumns(String tableAlias, String path, boolean inSelect) {
+		return elementType.toColumns( tableAlias, path, inSelect );
+	}
+
+	public String[] toColumns(String tableAlias, String path, boolean inSelect, boolean forceAlias) {
+		return elementType.toColumns( tableAlias, path, inSelect, forceAlias );
+	}
+
+	public PropertyMapping getPropertyMapping(String propertyName) {
+		return elementType.getPropertyMapping( propertyName );
+	}
+
+	public void setFetch(boolean fetch) {
+		this.fetch = fetch;
+		// Fetch can't be used with scroll() or iterate().
+		if ( fetch && getWalker().isShallowQuery() ) {
+			throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE );
+		}
+	}
+
+	public boolean isFetch() {
+		return fetch;
+	}
+
+	public int getSequence() {
+		return sequence;
+	}
+
+	public void setFilter(boolean b) {
+		filter = b;
+	}
+
+	public boolean isFilter() {
+		return filter;
+	}
+
+	public boolean useFromFragment() {
+		checkInitialized();
+		// If it's not implied or it is implied and it's a many to many join where the target wasn't found.
+		return !isImplied() || this.useFromFragment;
+	}
+
+	public void setUseFromFragment(boolean useFromFragment) {
+		this.useFromFragment = useFromFragment;
+	}
+
+	public boolean useWhereFragment() {
+		return useWhereFragment;
+	}
+
+	public void setUseWhereFragment(boolean b) {
+		useWhereFragment = b;
+	}
+
+
+	public void setCollectionTableAlias(String collectionTableAlias) {
+		this.collectionTableAlias = collectionTableAlias;
+	}
+
+	public String getCollectionTableAlias() {
+		return collectionTableAlias;
+	}
+
+	public boolean isCollectionOfValuesOrComponents() {
+		return elementType.isCollectionOfValuesOrComponents();
+	}
+
+	public boolean isEntity() {
+		return elementType.isEntity();
+	}
+
+	public void setImpliedInFromClause(boolean flag) {
+		throw new UnsupportedOperationException( "Explicit FROM elements can't be implied in the FROM clause!" );
+	}
+
+	public boolean isImpliedInFromClause() {
+		return false;	// Since this is an explicit FROM element, it can't be implied in the FROM clause.
+	}
+
+	public void setInProjectionList(boolean inProjectionList) {
+		// Do nothing, eplicit from elements are *always* in the projection list.
+	}
+
+	public boolean inProjectionList() {
+		return !isImplied() && isFromOrJoinFragment();
+	}
+
+	public boolean isFromOrJoinFragment() {
+		return getType() == SqlTokenTypes.FROM_FRAGMENT || getType() == SqlTokenTypes.JOIN_FRAGMENT;
+	}
+
+	public boolean isAllPropertyFetch() {
+		return isAllPropertyFetch;
+	}
+
+	public void setAllPropertyFetch(boolean fetch) {
+		isAllPropertyFetch = fetch;
+	}
+
+	public String getWithClauseFragment() {
+		return withClauseFragment;
+	}
+
+	public String getWithClauseJoinAlias() {
+		return withClauseJoinAlias;
+	}
+
+	public void setWithClauseFragment(String withClauseJoinAlias, String withClauseFragment) {
+		this.withClauseJoinAlias = withClauseJoinAlias;
+		this.withClauseFragment = withClauseFragment;
+	}
+
+	public boolean hasCacheablePersister() {
+		if ( getQueryableCollection() != null ) {
+			return getQueryableCollection().hasCache();
+		}
+		else {
+			return getQueryable().hasCache();
+		}
+	}
+
+	public void handlePropertyBeingDereferenced(Type propertySource, String propertyName) {
+		if ( getQueryableCollection() != null && CollectionProperties.isCollectionProperty( propertyName ) ) {
+			// propertyName refers to something like collection.size...
+			return;
+		}
+		if ( propertySource.isComponentType() ) {
+			// property name is a sub-path of a component...
+			return;
+		}
+
+		Queryable persister = getQueryable();
+		if ( persister != null ) {
+			try {
+				Queryable.Declarer propertyDeclarer = persister.getSubclassPropertyDeclarer( propertyName );
+				if ( log.isTraceEnabled() ) {
+					log.trace( "handling property dereference [" + persister.getEntityName() + " (" + getClassAlias() + ") -> " + propertyName + " (" + propertyDeclarer + ")]" );
+				}
+				if ( propertyDeclarer == Queryable.Declarer.SUBCLASS ) {
+					dereferencedBySubclassProperty = true;
+					includeSubclasses = true;
+				}
+				else if ( propertyDeclarer == Queryable.Declarer.SUPERCLASS ) {
+					dereferencedBySuperclassProperty = true;
+				}
+			}
+			catch( QueryException ignore ) {
+				// ignore it; the incoming property could not be found so we
+				// cannot be sure what to do here.  At the very least, the
+				// safest is to simply not apply any dereference toggling...
+
+			}
+		}
+	}
+
+	public boolean isDereferencedBySuperclassProperty() {
+		return dereferencedBySuperclassProperty;
+	}
+
+	public boolean isDereferencedBySubclassProperty() {
+		return dereferencedBySubclassProperty;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,500 +0,0 @@
-// $Id: FromElementFactory.java 9586 2006-03-09 21:11:44Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.util.AliasGenerator;
-import org.hibernate.hql.ast.util.PathHelper;
-import org.hibernate.hql.ast.util.SessionFactoryHelper;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-import antlr.ASTFactory;
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Encapsulates the creation of FromElements and JoinSequences.
- *
- * @author josh Oct 12, 2004 4:54:25 AM
- */
-class FromElementFactory implements SqlTokenTypes {
-
-	private static final Logger log = LoggerFactory.getLogger( FromElementFactory.class );
-
-	private FromClause fromClause;
-	private FromElement origin;
-	private String path;
-
-	private String classAlias;
-	private String[] columns;
-	private boolean implied;
-	private boolean inElementsFunction;
-	private boolean collection;
-	private QueryableCollection queryableCollection;
-	private CollectionType collectionType;
-
-	/**
-	 * Creates entity from elements.
-	 */
-	public FromElementFactory(FromClause fromClause, FromElement origin, String path) {
-		this.fromClause = fromClause;
-		this.origin = origin;
-		this.path = path;
-		collection = false;
-	}
-
-	/**
-	 * Creates collection from elements.
-	 */
-	public FromElementFactory(
-	        FromClause fromClause,
-	        FromElement origin,
-	        String path,
-	        String classAlias,
-	        String[] columns,
-	        boolean implied) {
-		this( fromClause, origin, path );
-		this.classAlias = classAlias;
-		this.columns = columns;
-		this.implied = implied;
-		collection = true;
-	}
-
-	FromElement addFromElement() throws SemanticException {
-		FromClause parentFromClause = fromClause.getParentFromClause();
-		if ( parentFromClause != null ) {
-			// Look up class name using the first identifier in the path.
-			String pathAlias = PathHelper.getAlias( path );
-			FromElement parentFromElement = parentFromClause.getFromElement( pathAlias );
-			if ( parentFromElement != null ) {
-				return createFromElementInSubselect( path, pathAlias, parentFromElement, classAlias );
-			}
-		}
-
-		EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( path );
-
-		FromElement elem = createAndAddFromElement( path,
-				classAlias,
-				entityPersister,
-				( EntityType ) ( ( Queryable ) entityPersister ).getType(),
-				null );
-
-		// Add to the query spaces.
-		fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
-
-		return elem;
-	}
-
-	private FromElement createFromElementInSubselect(
-	        String path,
-	        String pathAlias,
-	        FromElement parentFromElement,
-	        String classAlias) throws SemanticException {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "createFromElementInSubselect() : path = " + path );
-		}
-		// Create an DotNode AST for the path and resolve it.
-		FromElement fromElement = evaluateFromElementPath( path, classAlias );
-		EntityPersister entityPersister = fromElement.getEntityPersister();
-
-		// If the first identifier in the path referrs to the class alias (not the class name), then this
-		// is a correlated subselect.  If it's a correlated sub-select, use the existing table alias.  Otherwise
-		// generate a new one.
-		String tableAlias = null;
-		boolean correlatedSubselect = pathAlias.equals( parentFromElement.getClassAlias() );
-		if ( correlatedSubselect ) {
-			tableAlias = fromElement.getTableAlias();
-		}
-		else {
-			tableAlias = null;
-		}
-
-		// If the from element isn't in the same clause, create a new from element.
-		if ( fromElement.getFromClause() != fromClause ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "createFromElementInSubselect() : creating a new FROM element..." );
-			}
-			fromElement = createFromElement( entityPersister );
-			initializeAndAddFromElement( fromElement,
-					path,
-					classAlias,
-					entityPersister,
-					( EntityType ) ( ( Queryable ) entityPersister ).getType(),
-					tableAlias
-			);
-		}
-		if ( log.isDebugEnabled() ) {
-			log.debug( "createFromElementInSubselect() : " + path + " -> " + fromElement );
-		}
-		return fromElement;
-	}
-
-	private FromElement evaluateFromElementPath(String path, String classAlias) throws SemanticException {
-		ASTFactory factory = fromClause.getASTFactory();
-		FromReferenceNode pathNode = ( FromReferenceNode ) PathHelper.parsePath( path, factory );
-		pathNode.recursiveResolve( FromReferenceNode.ROOT_LEVEL, // This is the root level node.
-				false, // Generate an explicit from clause at the root.
-				classAlias,
-		        null
-		);
-		if ( pathNode.getImpliedJoin() != null ) {
-			return pathNode.getImpliedJoin();
-		}
-		else {
-			return pathNode.getFromElement();
-		}
-	}
-
-	FromElement createCollectionElementsJoin(
-	        QueryableCollection queryableCollection,
-	        String collectionName) throws SemanticException {
-		JoinSequence collectionJoinSequence = fromClause.getSessionFactoryHelper()
-		        .createCollectionJoinSequence( queryableCollection, collectionName );
-		this.queryableCollection = queryableCollection;
-		return createCollectionJoin( collectionJoinSequence, null );
-	}
-
-	FromElement createCollection(
-	        QueryableCollection queryableCollection,
-	        String role,
-	        int joinType,
-	        boolean fetchFlag,
-	        boolean indexed)
-			throws SemanticException {
-		if ( !collection ) {
-			throw new IllegalStateException( "FromElementFactory not initialized for collections!" );
-		}
-		this.inElementsFunction = indexed;
-		FromElement elem;
-		this.queryableCollection = queryableCollection;
-		collectionType = queryableCollection.getCollectionType();
-		String roleAlias = fromClause.getAliasGenerator().createName( role );
-
-		// Correlated subqueries create 'special' implied from nodes
-		// because correlated subselects can't use an ANSI-style join
-		boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied;
-		if ( explicitSubqueryFromElement ) {
-			String pathRoot = StringHelper.root( path );
-			FromElement origin = fromClause.getFromElement( pathRoot );
-			if ( origin == null || origin.getFromClause() != fromClause ) {
-				implied = true;
-			}
-		}
-
-		// super-duper-classic-parser-regression-testing-mojo-magic...
-		if ( explicitSubqueryFromElement && DotNode.useThetaStyleImplicitJoins ) {
-			implied = true;
-		}
-
-		Type elementType = queryableCollection.getElementType();
-		if ( elementType.isEntityType() ) { 			// A collection of entities...
-			elem = createEntityAssociation( role, roleAlias, joinType );
-		}
-		else if ( elementType.isComponentType() ) {		// A collection of components...
-			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
-			elem = createCollectionJoin( joinSequence, roleAlias );
-		}
-		else {											// A collection of scalar elements...
-			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
-			elem = createCollectionJoin( joinSequence, roleAlias );
-		}
-
-		elem.setRole( role );
-		elem.setQueryableCollection( queryableCollection );
-		// Don't include sub-classes for implied collection joins or subquery joins.
-		if ( implied ) {
-			elem.setIncludeSubclasses( false );
-		}
-
-		if ( explicitSubqueryFromElement ) {
-			elem.setInProjectionList( true );	// Treat explict from elements in sub-queries properly.
-		}
-
-		if ( fetchFlag ) {
-			elem.setFetch( true );
-		}
-		return elem;
-	}
-
-	FromElement createEntityJoin(
-	        String entityClass,
-	        String tableAlias,
-	        JoinSequence joinSequence,
-	        boolean fetchFlag,
-	        boolean inFrom,
-	        EntityType type) throws SemanticException {
-		FromElement elem = createJoin( entityClass, tableAlias, joinSequence, type, false );
-		elem.setFetch( fetchFlag );
-		EntityPersister entityPersister = elem.getEntityPersister();
-		int numberOfTables = entityPersister.getQuerySpaces().length;
-		if ( numberOfTables > 1 && implied && !elem.useFromFragment() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "createEntityJoin() : Implied multi-table entity join" );
-			}
-			elem.setUseFromFragment( true );
-		}
-
-		// If this is an implied join in a FROM clause, then use ANSI-style joining, and set the
-		// flag on the FromElement that indicates that it was implied in the FROM clause itself.
-		if ( implied && inFrom ) {
-			joinSequence.setUseThetaStyle( false );
-			elem.setUseFromFragment( true );
-			elem.setImpliedInFromClause( true );
-		}
-		if ( elem.getWalker().isSubQuery() ) {
-			// two conditions where we need to transform this to a theta-join syntax:
-			//      1) 'elem' is the "root from-element" in correlated subqueries
-			//      2) The DotNode.useThetaStyleImplicitJoins has been set to true
-			//          and 'elem' represents an implicit join
-			if ( elem.getFromClause() != elem.getOrigin().getFromClause() ||
-//			        ( implied && DotNode.useThetaStyleImplicitJoins ) ) {
-			        DotNode.useThetaStyleImplicitJoins ) {
-				// the "root from-element" in correlated subqueries do need this piece
-				elem.setType( FROM_FRAGMENT );
-				joinSequence.setUseThetaStyle( true );
-				elem.setUseFromFragment( false );
-			}
-		}
-
-		return elem;
-	}
-
-	FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
-		FromElement elem;
-
-		implied = true; //TODO: always true for now, but not if we later decide to support elements() in the from clause
-		inElementsFunction = true;
-		Type elementType = queryableCollection.getElementType();
-		if ( !elementType.isEntityType() ) {
-			throw new IllegalArgumentException( "Cannot create element join for a collection of non-entities!" );
-		}
-		this.queryableCollection = queryableCollection;
-		SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
-		FromElement destination = null;
-		String tableAlias = null;
-		EntityPersister entityPersister = queryableCollection.getElementPersister();
-		tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() );
-		String associatedEntityName = entityPersister.getEntityName();
-		EntityPersister targetEntityPersister = sfh.requireClassPersister( associatedEntityName );
-		// Create the FROM element for the target (the elements of the collection).
-		destination = createAndAddFromElement( 
-				associatedEntityName,
-				classAlias,
-				targetEntityPersister,
-				( EntityType ) queryableCollection.getElementType(),
-				tableAlias
-			);
-		// If the join is implied, then don't include sub-classes on the element.
-		if ( implied ) {
-			destination.setIncludeSubclasses( false );
-		}
-		fromClause.addCollectionJoinFromElementByPath( path, destination );
-//		origin.addDestination(destination);
-		// Add the query spaces.
-		fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
-
-		CollectionType type = queryableCollection.getCollectionType();
-		String role = type.getRole();
-		String roleAlias = origin.getTableAlias();
-
-		String[] targetColumns = sfh.getCollectionElementColumns( role, roleAlias );
-		AssociationType elementAssociationType = sfh.getElementAssociationType( type );
-
-		// Create the join element under the from element.
-		int joinType = JoinFragment.INNER_JOIN;
-		JoinSequence joinSequence = sfh.createJoinSequence( implied, elementAssociationType, tableAlias, joinType, targetColumns );
-		elem = initializeJoin( path, destination, joinSequence, targetColumns, origin, false );
-		elem.setUseFromFragment( true );	// The associated entity is implied, but it must be included in the FROM.
-		elem.setCollectionTableAlias( roleAlias );	// The collection alias is the role.
-		return elem;
-	}
-
-	private FromElement createCollectionJoin(JoinSequence collectionJoinSequence, String tableAlias) throws SemanticException {
-		String text = queryableCollection.getTableName();
-		AST ast = createFromElement( text );
-		FromElement destination = ( FromElement ) ast;
-		Type elementType = queryableCollection.getElementType();
-		if ( elementType.isCollectionType() ) {
-			throw new SemanticException( "Collections of collections are not supported!" );
-		}
-		destination.initializeCollection( fromClause, classAlias, tableAlias );
-		destination.setType( JOIN_FRAGMENT );		// Tag this node as a JOIN.
-		destination.setIncludeSubclasses( false );	// Don't include subclasses in the join.
-		destination.setCollectionJoin( true );		// This is a clollection join.
-		destination.setJoinSequence( collectionJoinSequence );
-		destination.setOrigin( origin, false );
-		destination.setCollectionTableAlias(tableAlias);
-//		origin.addDestination( destination );
-// This was the cause of HHH-242
-//		origin.setType( FROM_FRAGMENT );			// Set the parent node type so that the AST is properly formed.
-		origin.setText( "" );						// The destination node will have all the FROM text.
-		origin.setCollectionJoin( true );			// The parent node is a collection join too (voodoo - see JoinProcessor)
-		fromClause.addCollectionJoinFromElementByPath( path, destination );
-		fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );
-		return destination;
-	}
-
-	private FromElement createEntityAssociation(
-	        String role,
-	        String roleAlias,
-	        int joinType) throws SemanticException {
-		FromElement elem;
-		Queryable entityPersister = ( Queryable ) queryableCollection.getElementPersister();
-		String associatedEntityName = entityPersister.getEntityName();
-		// Get the class name of the associated entity.
-		if ( queryableCollection.isOneToMany() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "createEntityAssociation() : One to many - path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName );
-			}
-			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
-
-			elem = createJoin( associatedEntityName, roleAlias, joinSequence, ( EntityType ) queryableCollection.getElementType(), false );
-		}
-		else {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "createManyToMany() : path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName );
-			}
-			elem = createManyToMany( role, associatedEntityName,
-					roleAlias, entityPersister, ( EntityType ) queryableCollection.getElementType(), joinType );
-			fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );
-		}
-		elem.setCollectionTableAlias( roleAlias );
-		return elem;
-	}
-
-	private FromElement createJoin(
-	        String entityClass,
-	        String tableAlias,
-	        JoinSequence joinSequence,
-	        EntityType type,
-	        boolean manyToMany) throws SemanticException {
-		//  origin, path, implied, columns, classAlias,
-		EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( entityClass );
-		FromElement destination = createAndAddFromElement( entityClass,
-				classAlias,
-				entityPersister,
-				type,
-				tableAlias );
-		return initializeJoin( path, destination, joinSequence, getColumns(), origin, manyToMany );
-	}
-
-	private FromElement createManyToMany(
-	        String role,
-	        String associatedEntityName,
-	        String roleAlias,
-	        Queryable entityPersister,
-	        EntityType type,
-	        int joinType) throws SemanticException {
-		FromElement elem;
-		SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
-		if ( inElementsFunction /*implied*/ ) {
-			// For implied many-to-many, just add the end join.
-			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
-			elem = createJoin( associatedEntityName, roleAlias, joinSequence, type, true );
-		}
-		else {
-			// For an explicit many-to-many relationship, add a second join from the intermediate 
-			// (many-to-many) table to the destination table.  Also, make sure that the from element's 
-			// idea of the destination is the destination table.
-			String tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() );
-			String[] secondJoinColumns = sfh.getCollectionElementColumns( role, roleAlias );
-			// Add the second join, the one that ends in the destination table.
-			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
-			joinSequence.addJoin( sfh.getElementAssociationType( collectionType ), tableAlias, joinType, secondJoinColumns );
-			elem = createJoin( associatedEntityName, tableAlias, joinSequence, type, false );
-			elem.setUseFromFragment( true );
-		}
-		return elem;
-	}
-
-	private JoinSequence createJoinSequence(String roleAlias, int joinType) {
-		SessionFactoryHelper sessionFactoryHelper = fromClause.getSessionFactoryHelper();
-		String[] joinColumns = getColumns();
-		if ( collectionType == null ) {
-			throw new IllegalStateException( "collectionType is null!" );
-		}
-		return sessionFactoryHelper.createJoinSequence( implied, collectionType, roleAlias, joinType, joinColumns );
-	}
-
-	private FromElement createAndAddFromElement(
-	        String className,
-	        String classAlias,
-	        EntityPersister entityPersister,
-	        EntityType type,
-	        String tableAlias) {
-		if ( !( entityPersister instanceof Joinable ) ) {
-			throw new IllegalArgumentException( "EntityPersister " + entityPersister + " does not implement Joinable!" );
-		}
-		FromElement element = createFromElement( entityPersister );
-		initializeAndAddFromElement( element, className, classAlias, entityPersister, type, tableAlias );
-		return element;
-	}
-
-	private void initializeAndAddFromElement(
-	        FromElement element,
-	        String className,
-	        String classAlias,
-	        EntityPersister entityPersister,
-	        EntityType type,
-	        String tableAlias) {
-		if ( tableAlias == null ) {
-			AliasGenerator aliasGenerator = fromClause.getAliasGenerator();
-			tableAlias = aliasGenerator.createName( entityPersister.getEntityName() );
-		}
-		element.initializeEntity( fromClause, className, entityPersister, type, classAlias, tableAlias );
-	}
-
-	private FromElement createFromElement(EntityPersister entityPersister) {
-		Joinable joinable = ( Joinable ) entityPersister;
-		String text = joinable.getTableName();
-		AST ast = createFromElement( text );
-		FromElement element = ( FromElement ) ast;
-		return element;
-	}
-
-	private AST createFromElement(String text) {
-		AST ast = ASTUtil.create( fromClause.getASTFactory(),
-				implied ? IMPLIED_FROM : FROM_FRAGMENT, // This causes the factory to instantiate the desired class.
-				text );
-		// Reset the node type, because the rest of the system is expecting FROM_FRAGMENT, all we wanted was
-		// for the factory to create the right sub-class.  This might get reset again later on anyway to make the
-		// SQL generation simpler.
-		ast.setType( FROM_FRAGMENT );
-		return ast;
-	}
-
-	private FromElement initializeJoin(
-	        String path,
-	        FromElement destination,
-	        JoinSequence joinSequence,
-	        String[] columns,
-	        FromElement origin,
-	        boolean manyToMany) {
-		destination.setType( JOIN_FRAGMENT );
-		destination.setJoinSequence( joinSequence );
-		destination.setColumns( columns );
-		destination.setOrigin( origin, manyToMany );
-		fromClause.addJoinByPathMap( path, destination );
-		return destination;
-	}
-
-	private String[] getColumns() {
-		if ( columns == null ) {
-			throw new IllegalStateException( "No foriegn key columns were supplied!" );
-		}
-		return columns;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,523 @@
+/*
+ * 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.tree;
+
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.AliasGenerator;
+import org.hibernate.hql.ast.util.PathHelper;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+import antlr.ASTFactory;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the creation of FromElements and JoinSequences.
+ *
+ * @author josh
+ */
+class FromElementFactory implements SqlTokenTypes {
+
+	private static final Logger log = LoggerFactory.getLogger( FromElementFactory.class );
+
+	private FromClause fromClause;
+	private FromElement origin;
+	private String path;
+
+	private String classAlias;
+	private String[] columns;
+	private boolean implied;
+	private boolean inElementsFunction;
+	private boolean collection;
+	private QueryableCollection queryableCollection;
+	private CollectionType collectionType;
+
+	/**
+	 * Creates entity from elements.
+	 */
+	public FromElementFactory(FromClause fromClause, FromElement origin, String path) {
+		this.fromClause = fromClause;
+		this.origin = origin;
+		this.path = path;
+		collection = false;
+	}
+
+	/**
+	 * Creates collection from elements.
+	 */
+	public FromElementFactory(
+	        FromClause fromClause,
+	        FromElement origin,
+	        String path,
+	        String classAlias,
+	        String[] columns,
+	        boolean implied) {
+		this( fromClause, origin, path );
+		this.classAlias = classAlias;
+		this.columns = columns;
+		this.implied = implied;
+		collection = true;
+	}
+
+	FromElement addFromElement() throws SemanticException {
+		FromClause parentFromClause = fromClause.getParentFromClause();
+		if ( parentFromClause != null ) {
+			// Look up class name using the first identifier in the path.
+			String pathAlias = PathHelper.getAlias( path );
+			FromElement parentFromElement = parentFromClause.getFromElement( pathAlias );
+			if ( parentFromElement != null ) {
+				return createFromElementInSubselect( path, pathAlias, parentFromElement, classAlias );
+			}
+		}
+
+		EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( path );
+
+		FromElement elem = createAndAddFromElement( path,
+				classAlias,
+				entityPersister,
+				( EntityType ) ( ( Queryable ) entityPersister ).getType(),
+				null );
+
+		// Add to the query spaces.
+		fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
+
+		return elem;
+	}
+
+	private FromElement createFromElementInSubselect(
+	        String path,
+	        String pathAlias,
+	        FromElement parentFromElement,
+	        String classAlias) throws SemanticException {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "createFromElementInSubselect() : path = " + path );
+		}
+		// Create an DotNode AST for the path and resolve it.
+		FromElement fromElement = evaluateFromElementPath( path, classAlias );
+		EntityPersister entityPersister = fromElement.getEntityPersister();
+
+		// If the first identifier in the path referrs to the class alias (not the class name), then this
+		// is a correlated subselect.  If it's a correlated sub-select, use the existing table alias.  Otherwise
+		// generate a new one.
+		String tableAlias = null;
+		boolean correlatedSubselect = pathAlias.equals( parentFromElement.getClassAlias() );
+		if ( correlatedSubselect ) {
+			tableAlias = fromElement.getTableAlias();
+		}
+		else {
+			tableAlias = null;
+		}
+
+		// If the from element isn't in the same clause, create a new from element.
+		if ( fromElement.getFromClause() != fromClause ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "createFromElementInSubselect() : creating a new FROM element..." );
+			}
+			fromElement = createFromElement( entityPersister );
+			initializeAndAddFromElement( fromElement,
+					path,
+					classAlias,
+					entityPersister,
+					( EntityType ) ( ( Queryable ) entityPersister ).getType(),
+					tableAlias
+			);
+		}
+		if ( log.isDebugEnabled() ) {
+			log.debug( "createFromElementInSubselect() : " + path + " -> " + fromElement );
+		}
+		return fromElement;
+	}
+
+	private FromElement evaluateFromElementPath(String path, String classAlias) throws SemanticException {
+		ASTFactory factory = fromClause.getASTFactory();
+		FromReferenceNode pathNode = ( FromReferenceNode ) PathHelper.parsePath( path, factory );
+		pathNode.recursiveResolve( FromReferenceNode.ROOT_LEVEL, // This is the root level node.
+				false, // Generate an explicit from clause at the root.
+				classAlias,
+		        null
+		);
+		if ( pathNode.getImpliedJoin() != null ) {
+			return pathNode.getImpliedJoin();
+		}
+		else {
+			return pathNode.getFromElement();
+		}
+	}
+
+	FromElement createCollectionElementsJoin(
+	        QueryableCollection queryableCollection,
+	        String collectionName) throws SemanticException {
+		JoinSequence collectionJoinSequence = fromClause.getSessionFactoryHelper()
+		        .createCollectionJoinSequence( queryableCollection, collectionName );
+		this.queryableCollection = queryableCollection;
+		return createCollectionJoin( collectionJoinSequence, null );
+	}
+
+	FromElement createCollection(
+	        QueryableCollection queryableCollection,
+	        String role,
+	        int joinType,
+	        boolean fetchFlag,
+	        boolean indexed)
+			throws SemanticException {
+		if ( !collection ) {
+			throw new IllegalStateException( "FromElementFactory not initialized for collections!" );
+		}
+		this.inElementsFunction = indexed;
+		FromElement elem;
+		this.queryableCollection = queryableCollection;
+		collectionType = queryableCollection.getCollectionType();
+		String roleAlias = fromClause.getAliasGenerator().createName( role );
+
+		// Correlated subqueries create 'special' implied from nodes
+		// because correlated subselects can't use an ANSI-style join
+		boolean explicitSubqueryFromElement = fromClause.isSubQuery() && !implied;
+		if ( explicitSubqueryFromElement ) {
+			String pathRoot = StringHelper.root( path );
+			FromElement origin = fromClause.getFromElement( pathRoot );
+			if ( origin == null || origin.getFromClause() != fromClause ) {
+				implied = true;
+			}
+		}
+
+		// super-duper-classic-parser-regression-testing-mojo-magic...
+		if ( explicitSubqueryFromElement && DotNode.useThetaStyleImplicitJoins ) {
+			implied = true;
+		}
+
+		Type elementType = queryableCollection.getElementType();
+		if ( elementType.isEntityType() ) { 			// A collection of entities...
+			elem = createEntityAssociation( role, roleAlias, joinType );
+		}
+		else if ( elementType.isComponentType() ) {		// A collection of components...
+			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
+			elem = createCollectionJoin( joinSequence, roleAlias );
+		}
+		else {											// A collection of scalar elements...
+			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
+			elem = createCollectionJoin( joinSequence, roleAlias );
+		}
+
+		elem.setRole( role );
+		elem.setQueryableCollection( queryableCollection );
+		// Don't include sub-classes for implied collection joins or subquery joins.
+		if ( implied ) {
+			elem.setIncludeSubclasses( false );
+		}
+
+		if ( explicitSubqueryFromElement ) {
+			elem.setInProjectionList( true );	// Treat explict from elements in sub-queries properly.
+		}
+
+		if ( fetchFlag ) {
+			elem.setFetch( true );
+		}
+		return elem;
+	}
+
+	FromElement createEntityJoin(
+	        String entityClass,
+	        String tableAlias,
+	        JoinSequence joinSequence,
+	        boolean fetchFlag,
+	        boolean inFrom,
+	        EntityType type) throws SemanticException {
+		FromElement elem = createJoin( entityClass, tableAlias, joinSequence, type, false );
+		elem.setFetch( fetchFlag );
+		EntityPersister entityPersister = elem.getEntityPersister();
+		int numberOfTables = entityPersister.getQuerySpaces().length;
+		if ( numberOfTables > 1 && implied && !elem.useFromFragment() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "createEntityJoin() : Implied multi-table entity join" );
+			}
+			elem.setUseFromFragment( true );
+		}
+
+		// If this is an implied join in a FROM clause, then use ANSI-style joining, and set the
+		// flag on the FromElement that indicates that it was implied in the FROM clause itself.
+		if ( implied && inFrom ) {
+			joinSequence.setUseThetaStyle( false );
+			elem.setUseFromFragment( true );
+			elem.setImpliedInFromClause( true );
+		}
+		if ( elem.getWalker().isSubQuery() ) {
+			// two conditions where we need to transform this to a theta-join syntax:
+			//      1) 'elem' is the "root from-element" in correlated subqueries
+			//      2) The DotNode.useThetaStyleImplicitJoins has been set to true
+			//          and 'elem' represents an implicit join
+			if ( elem.getFromClause() != elem.getOrigin().getFromClause() ||
+//			        ( implied && DotNode.useThetaStyleImplicitJoins ) ) {
+			        DotNode.useThetaStyleImplicitJoins ) {
+				// the "root from-element" in correlated subqueries do need this piece
+				elem.setType( FROM_FRAGMENT );
+				joinSequence.setUseThetaStyle( true );
+				elem.setUseFromFragment( false );
+			}
+		}
+
+		return elem;
+	}
+
+	FromElement createElementJoin(QueryableCollection queryableCollection) throws SemanticException {
+		FromElement elem;
+
+		implied = true; //TODO: always true for now, but not if we later decide to support elements() in the from clause
+		inElementsFunction = true;
+		Type elementType = queryableCollection.getElementType();
+		if ( !elementType.isEntityType() ) {
+			throw new IllegalArgumentException( "Cannot create element join for a collection of non-entities!" );
+		}
+		this.queryableCollection = queryableCollection;
+		SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
+		FromElement destination = null;
+		String tableAlias = null;
+		EntityPersister entityPersister = queryableCollection.getElementPersister();
+		tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() );
+		String associatedEntityName = entityPersister.getEntityName();
+		EntityPersister targetEntityPersister = sfh.requireClassPersister( associatedEntityName );
+		// Create the FROM element for the target (the elements of the collection).
+		destination = createAndAddFromElement( 
+				associatedEntityName,
+				classAlias,
+				targetEntityPersister,
+				( EntityType ) queryableCollection.getElementType(),
+				tableAlias
+			);
+		// If the join is implied, then don't include sub-classes on the element.
+		if ( implied ) {
+			destination.setIncludeSubclasses( false );
+		}
+		fromClause.addCollectionJoinFromElementByPath( path, destination );
+//		origin.addDestination(destination);
+		// Add the query spaces.
+		fromClause.getWalker().addQuerySpaces( entityPersister.getQuerySpaces() );
+
+		CollectionType type = queryableCollection.getCollectionType();
+		String role = type.getRole();
+		String roleAlias = origin.getTableAlias();
+
+		String[] targetColumns = sfh.getCollectionElementColumns( role, roleAlias );
+		AssociationType elementAssociationType = sfh.getElementAssociationType( type );
+
+		// Create the join element under the from element.
+		int joinType = JoinFragment.INNER_JOIN;
+		JoinSequence joinSequence = sfh.createJoinSequence( implied, elementAssociationType, tableAlias, joinType, targetColumns );
+		elem = initializeJoin( path, destination, joinSequence, targetColumns, origin, false );
+		elem.setUseFromFragment( true );	// The associated entity is implied, but it must be included in the FROM.
+		elem.setCollectionTableAlias( roleAlias );	// The collection alias is the role.
+		return elem;
+	}
+
+	private FromElement createCollectionJoin(JoinSequence collectionJoinSequence, String tableAlias) throws SemanticException {
+		String text = queryableCollection.getTableName();
+		AST ast = createFromElement( text );
+		FromElement destination = ( FromElement ) ast;
+		Type elementType = queryableCollection.getElementType();
+		if ( elementType.isCollectionType() ) {
+			throw new SemanticException( "Collections of collections are not supported!" );
+		}
+		destination.initializeCollection( fromClause, classAlias, tableAlias );
+		destination.setType( JOIN_FRAGMENT );		// Tag this node as a JOIN.
+		destination.setIncludeSubclasses( false );	// Don't include subclasses in the join.
+		destination.setCollectionJoin( true );		// This is a clollection join.
+		destination.setJoinSequence( collectionJoinSequence );
+		destination.setOrigin( origin, false );
+		destination.setCollectionTableAlias(tableAlias);
+//		origin.addDestination( destination );
+// This was the cause of HHH-242
+//		origin.setType( FROM_FRAGMENT );			// Set the parent node type so that the AST is properly formed.
+		origin.setText( "" );						// The destination node will have all the FROM text.
+		origin.setCollectionJoin( true );			// The parent node is a collection join too (voodoo - see JoinProcessor)
+		fromClause.addCollectionJoinFromElementByPath( path, destination );
+		fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );
+		return destination;
+	}
+
+	private FromElement createEntityAssociation(
+	        String role,
+	        String roleAlias,
+	        int joinType) throws SemanticException {
+		FromElement elem;
+		Queryable entityPersister = ( Queryable ) queryableCollection.getElementPersister();
+		String associatedEntityName = entityPersister.getEntityName();
+		// Get the class name of the associated entity.
+		if ( queryableCollection.isOneToMany() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "createEntityAssociation() : One to many - path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName );
+			}
+			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
+
+			elem = createJoin( associatedEntityName, roleAlias, joinSequence, ( EntityType ) queryableCollection.getElementType(), false );
+		}
+		else {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "createManyToMany() : path = " + path + " role = " + role + " associatedEntityName = " + associatedEntityName );
+			}
+			elem = createManyToMany( role, associatedEntityName,
+					roleAlias, entityPersister, ( EntityType ) queryableCollection.getElementType(), joinType );
+			fromClause.getWalker().addQuerySpaces( queryableCollection.getCollectionSpaces() );
+		}
+		elem.setCollectionTableAlias( roleAlias );
+		return elem;
+	}
+
+	private FromElement createJoin(
+	        String entityClass,
+	        String tableAlias,
+	        JoinSequence joinSequence,
+	        EntityType type,
+	        boolean manyToMany) throws SemanticException {
+		//  origin, path, implied, columns, classAlias,
+		EntityPersister entityPersister = fromClause.getSessionFactoryHelper().requireClassPersister( entityClass );
+		FromElement destination = createAndAddFromElement( entityClass,
+				classAlias,
+				entityPersister,
+				type,
+				tableAlias );
+		return initializeJoin( path, destination, joinSequence, getColumns(), origin, manyToMany );
+	}
+
+	private FromElement createManyToMany(
+	        String role,
+	        String associatedEntityName,
+	        String roleAlias,
+	        Queryable entityPersister,
+	        EntityType type,
+	        int joinType) throws SemanticException {
+		FromElement elem;
+		SessionFactoryHelper sfh = fromClause.getSessionFactoryHelper();
+		if ( inElementsFunction /*implied*/ ) {
+			// For implied many-to-many, just add the end join.
+			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
+			elem = createJoin( associatedEntityName, roleAlias, joinSequence, type, true );
+		}
+		else {
+			// For an explicit many-to-many relationship, add a second join from the intermediate 
+			// (many-to-many) table to the destination table.  Also, make sure that the from element's 
+			// idea of the destination is the destination table.
+			String tableAlias = fromClause.getAliasGenerator().createName( entityPersister.getEntityName() );
+			String[] secondJoinColumns = sfh.getCollectionElementColumns( role, roleAlias );
+			// Add the second join, the one that ends in the destination table.
+			JoinSequence joinSequence = createJoinSequence( roleAlias, joinType );
+			joinSequence.addJoin( sfh.getElementAssociationType( collectionType ), tableAlias, joinType, secondJoinColumns );
+			elem = createJoin( associatedEntityName, tableAlias, joinSequence, type, false );
+			elem.setUseFromFragment( true );
+		}
+		return elem;
+	}
+
+	private JoinSequence createJoinSequence(String roleAlias, int joinType) {
+		SessionFactoryHelper sessionFactoryHelper = fromClause.getSessionFactoryHelper();
+		String[] joinColumns = getColumns();
+		if ( collectionType == null ) {
+			throw new IllegalStateException( "collectionType is null!" );
+		}
+		return sessionFactoryHelper.createJoinSequence( implied, collectionType, roleAlias, joinType, joinColumns );
+	}
+
+	private FromElement createAndAddFromElement(
+	        String className,
+	        String classAlias,
+	        EntityPersister entityPersister,
+	        EntityType type,
+	        String tableAlias) {
+		if ( !( entityPersister instanceof Joinable ) ) {
+			throw new IllegalArgumentException( "EntityPersister " + entityPersister + " does not implement Joinable!" );
+		}
+		FromElement element = createFromElement( entityPersister );
+		initializeAndAddFromElement( element, className, classAlias, entityPersister, type, tableAlias );
+		return element;
+	}
+
+	private void initializeAndAddFromElement(
+	        FromElement element,
+	        String className,
+	        String classAlias,
+	        EntityPersister entityPersister,
+	        EntityType type,
+	        String tableAlias) {
+		if ( tableAlias == null ) {
+			AliasGenerator aliasGenerator = fromClause.getAliasGenerator();
+			tableAlias = aliasGenerator.createName( entityPersister.getEntityName() );
+		}
+		element.initializeEntity( fromClause, className, entityPersister, type, classAlias, tableAlias );
+	}
+
+	private FromElement createFromElement(EntityPersister entityPersister) {
+		Joinable joinable = ( Joinable ) entityPersister;
+		String text = joinable.getTableName();
+		AST ast = createFromElement( text );
+		FromElement element = ( FromElement ) ast;
+		return element;
+	}
+
+	private AST createFromElement(String text) {
+		AST ast = ASTUtil.create( fromClause.getASTFactory(),
+				implied ? IMPLIED_FROM : FROM_FRAGMENT, // This causes the factory to instantiate the desired class.
+				text );
+		// Reset the node type, because the rest of the system is expecting FROM_FRAGMENT, all we wanted was
+		// for the factory to create the right sub-class.  This might get reset again later on anyway to make the
+		// SQL generation simpler.
+		ast.setType( FROM_FRAGMENT );
+		return ast;
+	}
+
+	private FromElement initializeJoin(
+	        String path,
+	        FromElement destination,
+	        JoinSequence joinSequence,
+	        String[] columns,
+	        FromElement origin,
+	        boolean manyToMany) {
+		destination.setType( JOIN_FRAGMENT );
+		destination.setJoinSequence( joinSequence );
+		destination.setColumns( columns );
+		destination.setOrigin( origin, manyToMany );
+		fromClause.addJoinByPathMap( path, destination );
+		return destination;
+	}
+
+	private String[] getColumns() {
+		if ( columns == null ) {
+			throw new IllegalStateException( "No foriegn key columns were supplied!" );
+		}
+		return columns;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,415 +0,0 @@
-// $Id: FromElementType.java 10824 2006-11-16 19:32:48Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.hql.CollectionSubqueryFactory;
-import org.hibernate.hql.NameGenerator;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.persister.collection.CollectionPropertyMapping;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Delegate that handles the type and join sequence information for a FromElement.
- *
- * @author josh Feb 12, 2005 10:17:34 AM
- */
-class FromElementType {
-	private static final Logger log = LoggerFactory.getLogger( FromElementType.class );
-
-	private FromElement fromElement;
-	private EntityType entityType;
-	private EntityPersister persister;
-	private QueryableCollection queryableCollection;
-	private CollectionPropertyMapping collectionPropertyMapping;
-	private JoinSequence joinSequence;
-	private String collectionSuffix;
-
-	public FromElementType(FromElement fromElement, EntityPersister persister, EntityType entityType) {
-		this.fromElement = fromElement;
-		this.persister = persister;
-		this.entityType = entityType;
-		if ( persister != null ) {
-			fromElement.setText( ( ( Queryable ) persister ).getTableName() + " " + getTableAlias() );
-		}
-	}
-
-	private String getTableAlias() {
-		return fromElement.getTableAlias();
-	}
-
-	private String getCollectionTableAlias() {
-		return fromElement.getCollectionTableAlias();
-	}
-
-	public String getCollectionSuffix() {
-		return collectionSuffix;
-	}
-
-	public void setCollectionSuffix(String suffix) {
-		collectionSuffix = suffix;
-	}
-
-	public EntityPersister getEntityPersister() {
-		return persister;
-	}
-
-	public Type getDataType() {
-		if ( persister == null ) {
-			if ( queryableCollection == null ) {
-				return null;
-			}
-			return queryableCollection.getType();
-		}
-		else {
-			return entityType;
-		}
-	}
-
-	public Type getSelectType() {
-		if (entityType==null) return null;
-		boolean shallow = fromElement.getFromClause().getWalker().isShallowQuery();
-		return TypeFactory.manyToOne( entityType.getAssociatedEntityName(), shallow );
-	}
-
-	/**
-	 * Returns the Hibernate queryable implementation for the HQL class.
-	 *
-	 * @return the Hibernate queryable implementation for the HQL class.
-	 */
-	public Queryable getQueryable() {
-		return ( persister instanceof Queryable ) ? ( Queryable ) persister : null;
-	}
-
-	/**
-	 * Render the identifier select, but in a 'scalar' context (i.e. generate the column alias).
-	 *
-	 * @param i the sequence of the returned type
-	 * @return the identifier select with the column alias.
-	 */
-	String renderScalarIdentifierSelect(int i) {
-		checkInitialized();
-		String[] cols = getPropertyMapping( EntityPersister.ENTITY_ID ).toColumns( getTableAlias(), EntityPersister.ENTITY_ID );
-		StringBuffer buf = new StringBuffer();
-		// For property references generate <tablealias>.<columnname> as <projectionalias>
-		for ( int j = 0; j < cols.length; j++ ) {
-			String column = cols[j];
-			if ( j > 0 ) {
-				buf.append( ", " );
-			}
-			buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, j ) );
-		}
-		return buf.toString();
-	}
-
-	/**
-	 * Returns the identifier select SQL fragment.
-	 *
-	 * @param size The total number of returned types.
-	 * @param k    The sequence of the current returned type.
-	 * @return the identifier select SQL fragment.
-	 */
-	String renderIdentifierSelect(int size, int k) {
-		checkInitialized();
-		// Render the identifier select fragment using the table alias.
-		if ( fromElement.getFromClause().isSubQuery() ) {
-			// TODO: Replace this with a more elegant solution.
-			String[] idColumnNames = ( persister != null ) ?
-					( ( Queryable ) persister ).getIdentifierColumnNames() : new String[0];
-			StringBuffer buf = new StringBuffer();
-			for ( int i = 0; i < idColumnNames.length; i++ ) {
-				buf.append( fromElement.getTableAlias() ).append( '.' ).append( idColumnNames[i] );
-				if ( i != idColumnNames.length - 1 ) buf.append( ", " );
-			}
-			return buf.toString();
-		}
-		else {
-			if (persister==null) {
-				throw new QueryException( "not an entity" );
-			}
-			String fragment = ( ( Queryable ) persister ).identifierSelectFragment( getTableAlias(), getSuffix( size, k ) );
-			return trimLeadingCommaAndSpaces( fragment );
-		}
-	}
-
-	private String getSuffix(int size, int sequence) {
-		return generateSuffix( size, sequence );
-	}
-
-	private static String generateSuffix(int size, int k) {
-		String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
-		return suffix;
-	}
-
-	private void checkInitialized() {
-		fromElement.checkInitialized();
-	}
-
-	/**
-	 * Returns the property select SQL fragment.
-	 * @param size The total number of returned types.
-	 * @param k    The sequence of the current returned type.
-	 * @return the property select SQL fragment.
-	 */
-	String renderPropertySelect(int size, int k, boolean allProperties) {
-		checkInitialized();
-		if ( persister == null ) {
-			return "";
-		}
-		else {
-			String fragment =  ( ( Queryable ) persister ).propertySelectFragment(
-					getTableAlias(),
-					getSuffix( size, k ),
-					allProperties
-				);
-			return trimLeadingCommaAndSpaces( fragment );
-		}
-	}
-
-	String renderCollectionSelectFragment(int size, int k) {
-		if ( queryableCollection == null ) {
-			return "";
-		}
-		else {
-			if ( collectionSuffix == null ) {
-				collectionSuffix = generateSuffix( size, k );
-			}
-			String fragment = queryableCollection.selectFragment( getCollectionTableAlias(), collectionSuffix );
-			return trimLeadingCommaAndSpaces( fragment );
-		}
-	}
-
-	public String renderValueCollectionSelectFragment(int size, int k) {
-		if ( queryableCollection == null ) {
-			return "";
-		}
-		else {
-			if ( collectionSuffix == null ) {
-				collectionSuffix = generateSuffix( size, k );
-			}
-			String fragment =  queryableCollection.selectFragment( getTableAlias(), collectionSuffix );
-			return trimLeadingCommaAndSpaces( fragment );
-		}
-	}
-
-	/**
-	 * This accounts for a quirk in Queryable, where it sometimes generates ',  ' in front of the
-	 * SQL fragment.  :-P
-	 *
-	 * @param fragment An SQL fragment.
-	 * @return The fragment, without the leading comma and spaces.
-	 */
-	private static String trimLeadingCommaAndSpaces(String fragment) {
-		if ( fragment.length() > 0 && fragment.charAt( 0 ) == ',' ) {
-			fragment = fragment.substring( 1 );
-		}
-		fragment = fragment.trim();
-		return fragment.trim();
-	}
-
-	public void setJoinSequence(JoinSequence joinSequence) {
-		this.joinSequence = joinSequence;
-	}
-
-	public JoinSequence getJoinSequence() {
-		if ( joinSequence != null ) {
-			return joinSequence;
-		}
-
-		// Class names in the FROM clause result in a JoinSequence (the old FromParser does this).
-		if ( persister instanceof Joinable ) {
-			Joinable joinable = ( Joinable ) persister;
-			return fromElement.getSessionFactoryHelper().createJoinSequence().setRoot( joinable, getTableAlias() );
-		}
-		else {
-			return null;	// TODO: Should this really return null?  If not, figure out something better to do here.
-		}
-	}
-
-	public void setQueryableCollection(QueryableCollection queryableCollection) {
-		if ( this.queryableCollection != null ) {
-			throw new IllegalStateException( "QueryableCollection is already defined for " + this + "!" );
-		}
-		this.queryableCollection = queryableCollection;
-		if ( !queryableCollection.isOneToMany() ) {
-			// For many-to-many joins, use the tablename from the queryable collection for the default text.
-			fromElement.setText( queryableCollection.getTableName() + " " + getTableAlias() );
-		}
-	}
-
-	public QueryableCollection getQueryableCollection() {
-		return queryableCollection;
-	}
-
-	/**
-	 * Returns the type of a property, given it's name (the last part) and the full path.
-	 *
-	 * @param propertyName The last part of the full path to the property.
-	 * @return The type.
-	 * @0param propertyPath The full property path.
-	 */
-	public Type getPropertyType(String propertyName, String propertyPath) {
-		checkInitialized();
-		Type type = null;
-		// If this is an entity and the property is the identifier property, then use getIdentifierType().
-		//      Note that the propertyName.equals( propertyPath ) checks whether we have a component
-		//      key reference, where the component class property name is the same as the
-		//      entity id property name; if the two are not equal, this is the case and
-		//      we'd need to "fall through" to using the property mapping.
-		if ( persister != null && propertyName.equals( propertyPath ) && propertyName.equals( persister.getIdentifierPropertyName() ) ) {
-			type = persister.getIdentifierType();
-		}
-		else {	// Otherwise, use the property mapping.
-			PropertyMapping mapping = getPropertyMapping( propertyName );
-			type = mapping.toType( propertyPath );
-		}
-		if ( type == null ) {
-			throw new MappingException( "Property " + propertyName + " does not exist in " +
-					( ( queryableCollection == null ) ? "class" : "collection" ) + " "
-					+ ( ( queryableCollection == null ) ? fromElement.getClassName() : queryableCollection.getRole() ) );
-		}
-		return type;
-	}
-
-	String[] toColumns(String tableAlias, String path, boolean inSelect) {
-		return toColumns( tableAlias, path, inSelect, false );
-	}
-
-	String[] toColumns(String tableAlias, String path, boolean inSelect, boolean forceAlias) {
-		checkInitialized();
-		PropertyMapping propertyMapping = getPropertyMapping( path );
-		// If this from element is a collection and the path is a collection property (maxIndex, etc.) then
-		// generate a sub-query.
-		if ( !inSelect && queryableCollection != null && CollectionProperties.isCollectionProperty( path ) ) {
-			Map enabledFilters = fromElement.getWalker().getEnabledFilters();
-			String subquery = CollectionSubqueryFactory.createCollectionSubquery(
-					joinSequence,
-			        enabledFilters,
-					propertyMapping.toColumns( tableAlias, path )
-			);
-			if ( log.isDebugEnabled() ) {
-				log.debug( "toColumns(" + tableAlias + "," + path + ") : subquery = " + subquery );
-			}
-			return new String[]{"(" + subquery + ")"};
-		}
-		else {
-			if ( forceAlias ) {
-				return propertyMapping.toColumns( tableAlias, path );
-			}
-			else if ( fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.SELECT ) {
-				return propertyMapping.toColumns( tableAlias, path );
-			}
-			else if ( fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.SELECT ) {
-				return propertyMapping.toColumns( tableAlias, path );
-			}
-			else if ( fromElement.getWalker().isSubQuery() ) {
-				// for a subquery, the alias to use depends on a few things (we
-				// already know this is not an overall SELECT):
-				//      1) if this FROM_ELEMENT represents a correlation to the
-				//          outer-most query
-				//              A) if the outer query represents a multi-table
-				//                  persister, we need to use the given alias
-				//                  in anticipation of one of the multi-table
-				//                  executors being used (as this subquery will
-				//                  actually be used in the "id select" phase
-				//                  of that multi-table executor)
-				//              B) otherwise, we need to use the persister's
-				//                  table name as the column qualification
-				//      2) otherwise (not correlated), use the given alias
-				if ( isCorrelation() ) {
-					if ( isMultiTable() ) {
-						return propertyMapping.toColumns( tableAlias, path );
-					}
-					else {
-						return propertyMapping.toColumns( extractTableName(), path );
-					}
-				}
-				else {
-					return propertyMapping.toColumns( tableAlias, path );
-				}
-			}
-			else {
-				String[] columns = propertyMapping.toColumns( path );
-				log.trace( "Using non-qualified column reference [" + path + " -> (" + ArrayHelper.toString( columns ) + ")]" );
-				return columns;
-			}
-		}
-	}
-
-	private boolean isCorrelation() {
-		FromClause top = fromElement.getWalker().getFinalFromClause();
-		return fromElement.getFromClause() != fromElement.getWalker().getCurrentFromClause() &&
-	           fromElement.getFromClause() == top;
-	}
-
-	private boolean isMultiTable() {
-		// should be safe to only ever expect EntityPersister references here
-		return fromElement.getQueryable() != null &&
-	           fromElement.getQueryable().isMultiTable();
-	}
-
-	private String extractTableName() {
-		// should be safe to only ever expect EntityPersister references here
-		return fromElement.getQueryable().getTableName();
-	}
-
-	PropertyMapping getPropertyMapping(String propertyName) {
-		checkInitialized();
-		if ( queryableCollection == null ) {		// Not a collection?
-			return ( PropertyMapping ) persister;	// Return the entity property mapping.
-		}
-		// If the property is a special collection property name, return a CollectionPropertyMapping.
-		if ( CollectionProperties.isCollectionProperty( propertyName ) ) {
-			if ( collectionPropertyMapping == null ) {
-				collectionPropertyMapping = new CollectionPropertyMapping( queryableCollection );
-			}
-			return collectionPropertyMapping;
-		}
-		if ( queryableCollection.getElementType().isAnyType() ) {
-			// collection of <many-to-any/> mappings...
-			// used to circumvent the component-collection check below...
-			return queryableCollection;
-
-		}
-		if ( queryableCollection.getElementType().isComponentType() ) {
-			// Collection of components.
-			if ( propertyName.equals( EntityPersister.ENTITY_ID ) ) {
-				return ( PropertyMapping ) queryableCollection.getOwnerEntityPersister();
-			}
-		}
-		return queryableCollection;
-	}
-
-	public boolean isCollectionOfValuesOrComponents() {
-		if ( persister == null ) {
-			if ( queryableCollection == null ) {
-				return false;
-			}
-			else {
-				return !queryableCollection.getElementType().isEntityType();
-			}
-		}
-		else {
-			return false;
-		}
-	}
-
-	public boolean isEntity() {
-		return persister != null;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromElementType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,438 @@
+/*
+ * 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.tree;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.hql.CollectionSubqueryFactory;
+import org.hibernate.hql.NameGenerator;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Delegate that handles the type and join sequence information for a FromElement.
+ *
+ * @author josh
+ */
+class FromElementType {
+	private static final Logger log = LoggerFactory.getLogger( FromElementType.class );
+
+	private FromElement fromElement;
+	private EntityType entityType;
+	private EntityPersister persister;
+	private QueryableCollection queryableCollection;
+	private CollectionPropertyMapping collectionPropertyMapping;
+	private JoinSequence joinSequence;
+	private String collectionSuffix;
+
+	public FromElementType(FromElement fromElement, EntityPersister persister, EntityType entityType) {
+		this.fromElement = fromElement;
+		this.persister = persister;
+		this.entityType = entityType;
+		if ( persister != null ) {
+			fromElement.setText( ( ( Queryable ) persister ).getTableName() + " " + getTableAlias() );
+		}
+	}
+
+	private String getTableAlias() {
+		return fromElement.getTableAlias();
+	}
+
+	private String getCollectionTableAlias() {
+		return fromElement.getCollectionTableAlias();
+	}
+
+	public String getCollectionSuffix() {
+		return collectionSuffix;
+	}
+
+	public void setCollectionSuffix(String suffix) {
+		collectionSuffix = suffix;
+	}
+
+	public EntityPersister getEntityPersister() {
+		return persister;
+	}
+
+	public Type getDataType() {
+		if ( persister == null ) {
+			if ( queryableCollection == null ) {
+				return null;
+			}
+			return queryableCollection.getType();
+		}
+		else {
+			return entityType;
+		}
+	}
+
+	public Type getSelectType() {
+		if (entityType==null) return null;
+		boolean shallow = fromElement.getFromClause().getWalker().isShallowQuery();
+		return TypeFactory.manyToOne( entityType.getAssociatedEntityName(), shallow );
+	}
+
+	/**
+	 * Returns the Hibernate queryable implementation for the HQL class.
+	 *
+	 * @return the Hibernate queryable implementation for the HQL class.
+	 */
+	public Queryable getQueryable() {
+		return ( persister instanceof Queryable ) ? ( Queryable ) persister : null;
+	}
+
+	/**
+	 * Render the identifier select, but in a 'scalar' context (i.e. generate the column alias).
+	 *
+	 * @param i the sequence of the returned type
+	 * @return the identifier select with the column alias.
+	 */
+	String renderScalarIdentifierSelect(int i) {
+		checkInitialized();
+		String[] cols = getPropertyMapping( EntityPersister.ENTITY_ID ).toColumns( getTableAlias(), EntityPersister.ENTITY_ID );
+		StringBuffer buf = new StringBuffer();
+		// For property references generate <tablealias>.<columnname> as <projectionalias>
+		for ( int j = 0; j < cols.length; j++ ) {
+			String column = cols[j];
+			if ( j > 0 ) {
+				buf.append( ", " );
+			}
+			buf.append( column ).append( " as " ).append( NameGenerator.scalarName( i, j ) );
+		}
+		return buf.toString();
+	}
+
+	/**
+	 * Returns the identifier select SQL fragment.
+	 *
+	 * @param size The total number of returned types.
+	 * @param k    The sequence of the current returned type.
+	 * @return the identifier select SQL fragment.
+	 */
+	String renderIdentifierSelect(int size, int k) {
+		checkInitialized();
+		// Render the identifier select fragment using the table alias.
+		if ( fromElement.getFromClause().isSubQuery() ) {
+			// TODO: Replace this with a more elegant solution.
+			String[] idColumnNames = ( persister != null ) ?
+					( ( Queryable ) persister ).getIdentifierColumnNames() : new String[0];
+			StringBuffer buf = new StringBuffer();
+			for ( int i = 0; i < idColumnNames.length; i++ ) {
+				buf.append( fromElement.getTableAlias() ).append( '.' ).append( idColumnNames[i] );
+				if ( i != idColumnNames.length - 1 ) buf.append( ", " );
+			}
+			return buf.toString();
+		}
+		else {
+			if (persister==null) {
+				throw new QueryException( "not an entity" );
+			}
+			String fragment = ( ( Queryable ) persister ).identifierSelectFragment( getTableAlias(), getSuffix( size, k ) );
+			return trimLeadingCommaAndSpaces( fragment );
+		}
+	}
+
+	private String getSuffix(int size, int sequence) {
+		return generateSuffix( size, sequence );
+	}
+
+	private static String generateSuffix(int size, int k) {
+		String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
+		return suffix;
+	}
+
+	private void checkInitialized() {
+		fromElement.checkInitialized();
+	}
+
+	/**
+	 * Returns the property select SQL fragment.
+	 * @param size The total number of returned types.
+	 * @param k    The sequence of the current returned type.
+	 * @return the property select SQL fragment.
+	 */
+	String renderPropertySelect(int size, int k, boolean allProperties) {
+		checkInitialized();
+		if ( persister == null ) {
+			return "";
+		}
+		else {
+			String fragment =  ( ( Queryable ) persister ).propertySelectFragment(
+					getTableAlias(),
+					getSuffix( size, k ),
+					allProperties
+				);
+			return trimLeadingCommaAndSpaces( fragment );
+		}
+	}
+
+	String renderCollectionSelectFragment(int size, int k) {
+		if ( queryableCollection == null ) {
+			return "";
+		}
+		else {
+			if ( collectionSuffix == null ) {
+				collectionSuffix = generateSuffix( size, k );
+			}
+			String fragment = queryableCollection.selectFragment( getCollectionTableAlias(), collectionSuffix );
+			return trimLeadingCommaAndSpaces( fragment );
+		}
+	}
+
+	public String renderValueCollectionSelectFragment(int size, int k) {
+		if ( queryableCollection == null ) {
+			return "";
+		}
+		else {
+			if ( collectionSuffix == null ) {
+				collectionSuffix = generateSuffix( size, k );
+			}
+			String fragment =  queryableCollection.selectFragment( getTableAlias(), collectionSuffix );
+			return trimLeadingCommaAndSpaces( fragment );
+		}
+	}
+
+	/**
+	 * This accounts for a quirk in Queryable, where it sometimes generates ',  ' in front of the
+	 * SQL fragment.  :-P
+	 *
+	 * @param fragment An SQL fragment.
+	 * @return The fragment, without the leading comma and spaces.
+	 */
+	private static String trimLeadingCommaAndSpaces(String fragment) {
+		if ( fragment.length() > 0 && fragment.charAt( 0 ) == ',' ) {
+			fragment = fragment.substring( 1 );
+		}
+		fragment = fragment.trim();
+		return fragment.trim();
+	}
+
+	public void setJoinSequence(JoinSequence joinSequence) {
+		this.joinSequence = joinSequence;
+	}
+
+	public JoinSequence getJoinSequence() {
+		if ( joinSequence != null ) {
+			return joinSequence;
+		}
+
+		// Class names in the FROM clause result in a JoinSequence (the old FromParser does this).
+		if ( persister instanceof Joinable ) {
+			Joinable joinable = ( Joinable ) persister;
+			return fromElement.getSessionFactoryHelper().createJoinSequence().setRoot( joinable, getTableAlias() );
+		}
+		else {
+			return null;	// TODO: Should this really return null?  If not, figure out something better to do here.
+		}
+	}
+
+	public void setQueryableCollection(QueryableCollection queryableCollection) {
+		if ( this.queryableCollection != null ) {
+			throw new IllegalStateException( "QueryableCollection is already defined for " + this + "!" );
+		}
+		this.queryableCollection = queryableCollection;
+		if ( !queryableCollection.isOneToMany() ) {
+			// For many-to-many joins, use the tablename from the queryable collection for the default text.
+			fromElement.setText( queryableCollection.getTableName() + " " + getTableAlias() );
+		}
+	}
+
+	public QueryableCollection getQueryableCollection() {
+		return queryableCollection;
+	}
+
+	/**
+	 * Returns the type of a property, given it's name (the last part) and the full path.
+	 *
+	 * @param propertyName The last part of the full path to the property.
+	 * @return The type.
+	 * @0param propertyPath The full property path.
+	 */
+	public Type getPropertyType(String propertyName, String propertyPath) {
+		checkInitialized();
+		Type type = null;
+		// If this is an entity and the property is the identifier property, then use getIdentifierType().
+		//      Note that the propertyName.equals( propertyPath ) checks whether we have a component
+		//      key reference, where the component class property name is the same as the
+		//      entity id property name; if the two are not equal, this is the case and
+		//      we'd need to "fall through" to using the property mapping.
+		if ( persister != null && propertyName.equals( propertyPath ) && propertyName.equals( persister.getIdentifierPropertyName() ) ) {
+			type = persister.getIdentifierType();
+		}
+		else {	// Otherwise, use the property mapping.
+			PropertyMapping mapping = getPropertyMapping( propertyName );
+			type = mapping.toType( propertyPath );
+		}
+		if ( type == null ) {
+			throw new MappingException( "Property " + propertyName + " does not exist in " +
+					( ( queryableCollection == null ) ? "class" : "collection" ) + " "
+					+ ( ( queryableCollection == null ) ? fromElement.getClassName() : queryableCollection.getRole() ) );
+		}
+		return type;
+	}
+
+	String[] toColumns(String tableAlias, String path, boolean inSelect) {
+		return toColumns( tableAlias, path, inSelect, false );
+	}
+
+	String[] toColumns(String tableAlias, String path, boolean inSelect, boolean forceAlias) {
+		checkInitialized();
+		PropertyMapping propertyMapping = getPropertyMapping( path );
+		// If this from element is a collection and the path is a collection property (maxIndex, etc.) then
+		// generate a sub-query.
+		if ( !inSelect && queryableCollection != null && CollectionProperties.isCollectionProperty( path ) ) {
+			Map enabledFilters = fromElement.getWalker().getEnabledFilters();
+			String subquery = CollectionSubqueryFactory.createCollectionSubquery(
+					joinSequence,
+			        enabledFilters,
+					propertyMapping.toColumns( tableAlias, path )
+			);
+			if ( log.isDebugEnabled() ) {
+				log.debug( "toColumns(" + tableAlias + "," + path + ") : subquery = " + subquery );
+			}
+			return new String[]{"(" + subquery + ")"};
+		}
+		else {
+			if ( forceAlias ) {
+				return propertyMapping.toColumns( tableAlias, path );
+			}
+			else if ( fromElement.getWalker().getStatementType() == HqlSqlTokenTypes.SELECT ) {
+				return propertyMapping.toColumns( tableAlias, path );
+			}
+			else if ( fromElement.getWalker().getCurrentClauseType() == HqlSqlTokenTypes.SELECT ) {
+				return propertyMapping.toColumns( tableAlias, path );
+			}
+			else if ( fromElement.getWalker().isSubQuery() ) {
+				// for a subquery, the alias to use depends on a few things (we
+				// already know this is not an overall SELECT):
+				//      1) if this FROM_ELEMENT represents a correlation to the
+				//          outer-most query
+				//              A) if the outer query represents a multi-table
+				//                  persister, we need to use the given alias
+				//                  in anticipation of one of the multi-table
+				//                  executors being used (as this subquery will
+				//                  actually be used in the "id select" phase
+				//                  of that multi-table executor)
+				//              B) otherwise, we need to use the persister's
+				//                  table name as the column qualification
+				//      2) otherwise (not correlated), use the given alias
+				if ( isCorrelation() ) {
+					if ( isMultiTable() ) {
+						return propertyMapping.toColumns( tableAlias, path );
+					}
+					else {
+						return propertyMapping.toColumns( extractTableName(), path );
+					}
+				}
+				else {
+					return propertyMapping.toColumns( tableAlias, path );
+				}
+			}
+			else {
+				String[] columns = propertyMapping.toColumns( path );
+				log.trace( "Using non-qualified column reference [" + path + " -> (" + ArrayHelper.toString( columns ) + ")]" );
+				return columns;
+			}
+		}
+	}
+
+	private boolean isCorrelation() {
+		FromClause top = fromElement.getWalker().getFinalFromClause();
+		return fromElement.getFromClause() != fromElement.getWalker().getCurrentFromClause() &&
+	           fromElement.getFromClause() == top;
+	}
+
+	private boolean isMultiTable() {
+		// should be safe to only ever expect EntityPersister references here
+		return fromElement.getQueryable() != null &&
+	           fromElement.getQueryable().isMultiTable();
+	}
+
+	private String extractTableName() {
+		// should be safe to only ever expect EntityPersister references here
+		return fromElement.getQueryable().getTableName();
+	}
+
+	PropertyMapping getPropertyMapping(String propertyName) {
+		checkInitialized();
+		if ( queryableCollection == null ) {		// Not a collection?
+			return ( PropertyMapping ) persister;	// Return the entity property mapping.
+		}
+		// If the property is a special collection property name, return a CollectionPropertyMapping.
+		if ( CollectionProperties.isCollectionProperty( propertyName ) ) {
+			if ( collectionPropertyMapping == null ) {
+				collectionPropertyMapping = new CollectionPropertyMapping( queryableCollection );
+			}
+			return collectionPropertyMapping;
+		}
+		if ( queryableCollection.getElementType().isAnyType() ) {
+			// collection of <many-to-any/> mappings...
+			// used to circumvent the component-collection check below...
+			return queryableCollection;
+
+		}
+		if ( queryableCollection.getElementType().isComponentType() ) {
+			// Collection of components.
+			if ( propertyName.equals( EntityPersister.ENTITY_ID ) ) {
+				return ( PropertyMapping ) queryableCollection.getOwnerEntityPersister();
+			}
+		}
+		return queryableCollection;
+	}
+
+	public boolean isCollectionOfValuesOrComponents() {
+		if ( persister == null ) {
+			if ( queryableCollection == null ) {
+				return false;
+			}
+			else {
+				return !queryableCollection.getElementType().isEntityType();
+			}
+		}
+		else {
+			return false;
+		}
+	}
+
+	public boolean isEntity() {
+		return persister != null;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,109 +0,0 @@
-// $Id: FromReferenceNode.java 7494 2005-07-15 16:20:04Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a reference to a FROM element, for example a class alias in a WHERE clause.
- *
- * @author josh Jul 21, 2004 7:02:04 AM
- */
-public abstract class FromReferenceNode extends AbstractSelectExpression
-        implements ResolvableNode, DisplayableNode, InitializeableNode, PathNode {
-
-	private static final Logger log = LoggerFactory.getLogger( FromReferenceNode.class );
-
-	private FromElement fromElement;
-	private boolean resolved = false;
-	public static final int ROOT_LEVEL = 0;
-
-	public FromElement getFromElement() {
-		return fromElement;
-	}
-
-	public void setFromElement(FromElement fromElement) {
-		this.fromElement = fromElement;
-	}
-
-	/**
-	 * Resolves the left hand side of the DOT.
-	 *
-	 * @throws SemanticException
-	 */
-	public void resolveFirstChild() throws SemanticException {
-	}
-
-	public String getPath() {
-		return getOriginalText();
-	}
-
-	public boolean isResolved() {
-		return resolved;
-	}
-
-	public void setResolved() {
-		this.resolved = true;
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Resolved :  " + this.getPath() + " -> " + this.getText() );
-		}
-	}
-
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "{" ).append( ( fromElement == null ) ? "no fromElement" : fromElement.getDisplayText() );
-		buf.append( "}" );
-		return buf.toString();
-	}
-
-	public void recursiveResolve(int level, boolean impliedAtRoot, String classAlias) throws SemanticException {
-		recursiveResolve( level, impliedAtRoot, classAlias, this );
-	}
-
-	public void recursiveResolve(int level, boolean impliedAtRoot, String classAlias, AST parent) throws SemanticException {
-		AST lhs = getFirstChild();
-		int nextLevel = level + 1;
-		if ( lhs != null ) {
-			FromReferenceNode n = ( FromReferenceNode ) lhs;
-			n.recursiveResolve( nextLevel, impliedAtRoot, null, this );
-		}
-		resolveFirstChild();
-		boolean impliedJoin = true;
-		if ( level == ROOT_LEVEL && !impliedAtRoot ) {
-			impliedJoin = false;
-		}
-		resolve( true, impliedJoin, classAlias, parent );
-	}
-
-	public boolean isReturnableEntity() throws SemanticException {
-		return !isScalar() && fromElement.isEntity();
-	}
-
-	public void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException {
-		resolve( generateJoin, implicitJoin );
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin) throws SemanticException {
-		resolve( generateJoin, implicitJoin, null );
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias) throws SemanticException {
-		resolve( generateJoin, implicitJoin, classAlias, null );
-	}
-
-	public void prepareForDot(String propertyName) throws SemanticException {
-	}
-
-	/**
-	 * Sub-classes can override this method if they produce implied joins (e.g. DotNode).
-	 *
-	 * @return an implied join created by this from reference.
-	 */
-	public FromElement getImpliedJoin() {
-		return null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/FromReferenceNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,132 @@
+/*
+ * 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.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a reference to a FROM element, for example a class alias in a WHERE clause.
+ *
+ * @author josh
+ */
+public abstract class FromReferenceNode extends AbstractSelectExpression
+        implements ResolvableNode, DisplayableNode, InitializeableNode, PathNode {
+
+	private static final Logger log = LoggerFactory.getLogger( FromReferenceNode.class );
+
+	private FromElement fromElement;
+	private boolean resolved = false;
+	public static final int ROOT_LEVEL = 0;
+
+	public FromElement getFromElement() {
+		return fromElement;
+	}
+
+	public void setFromElement(FromElement fromElement) {
+		this.fromElement = fromElement;
+	}
+
+	/**
+	 * Resolves the left hand side of the DOT.
+	 *
+	 * @throws SemanticException
+	 */
+	public void resolveFirstChild() throws SemanticException {
+	}
+
+	public String getPath() {
+		return getOriginalText();
+	}
+
+	public boolean isResolved() {
+		return resolved;
+	}
+
+	public void setResolved() {
+		this.resolved = true;
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Resolved :  " + this.getPath() + " -> " + this.getText() );
+		}
+	}
+
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "{" ).append( ( fromElement == null ) ? "no fromElement" : fromElement.getDisplayText() );
+		buf.append( "}" );
+		return buf.toString();
+	}
+
+	public void recursiveResolve(int level, boolean impliedAtRoot, String classAlias) throws SemanticException {
+		recursiveResolve( level, impliedAtRoot, classAlias, this );
+	}
+
+	public void recursiveResolve(int level, boolean impliedAtRoot, String classAlias, AST parent) throws SemanticException {
+		AST lhs = getFirstChild();
+		int nextLevel = level + 1;
+		if ( lhs != null ) {
+			FromReferenceNode n = ( FromReferenceNode ) lhs;
+			n.recursiveResolve( nextLevel, impliedAtRoot, null, this );
+		}
+		resolveFirstChild();
+		boolean impliedJoin = true;
+		if ( level == ROOT_LEVEL && !impliedAtRoot ) {
+			impliedJoin = false;
+		}
+		resolve( true, impliedJoin, classAlias, parent );
+	}
+
+	public boolean isReturnableEntity() throws SemanticException {
+		return !isScalar() && fromElement.isEntity();
+	}
+
+	public void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException {
+		resolve( generateJoin, implicitJoin );
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin) throws SemanticException {
+		resolve( generateJoin, implicitJoin, null );
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias) throws SemanticException {
+		resolve( generateJoin, implicitJoin, classAlias, null );
+	}
+
+	public void prepareForDot(String propertyName) throws SemanticException {
+	}
+
+	/**
+	 * Sub-classes can override this method if they produce implied joins (e.g. DotNode).
+	 *
+	 * @return an implied join created by this from reference.
+	 */
+	public FromElement getImpliedJoin() {
+		return null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-// $Id: HqlSqlWalkerNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.util.AliasGenerator;
-import org.hibernate.hql.ast.util.SessionFactoryHelper;
-
-import antlr.ASTFactory;
-
-/**
- * A semantic analysis node, that points back to the main analyzer.
- *
- * @author josh Sep 24, 2004 4:08:13 PM
- */
-public class HqlSqlWalkerNode extends SqlNode implements InitializeableNode {
-	/**
-	 * A pointer back to the phase 2 processor.
-	 */
-	private HqlSqlWalker walker;
-
-	public void initialize(Object param) {
-		walker = ( HqlSqlWalker ) param;
-	}
-
-	public HqlSqlWalker getWalker() {
-		return walker;
-	}
-
-	public SessionFactoryHelper getSessionFactoryHelper() {
-		return walker.getSessionFactoryHelper();
-	}
-
-	public ASTFactory getASTFactory() {
-		return walker.getASTFactory();
-	}
-
-	public AliasGenerator getAliasGenerator() {
-		return walker.getAliasGenerator();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/HqlSqlWalkerNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.util.AliasGenerator;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+
+import antlr.ASTFactory;
+
+/**
+ * A semantic analysis node, that points back to the main analyzer.
+ *
+ * @author josh
+ */
+public class HqlSqlWalkerNode extends SqlNode implements InitializeableNode {
+	/**
+	 * A pointer back to the phase 2 processor.
+	 */
+	private HqlSqlWalker walker;
+
+	public void initialize(Object param) {
+		walker = ( HqlSqlWalker ) param;
+	}
+
+	public HqlSqlWalker getWalker() {
+		return walker;
+	}
+
+	public SessionFactoryHelper getSessionFactoryHelper() {
+		return walker.getSessionFactoryHelper();
+	}
+
+	public ASTFactory getASTFactory() {
+		return walker.getASTFactory();
+	}
+
+	public AliasGenerator getAliasGenerator() {
+		return walker.getAliasGenerator();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,307 +0,0 @@
-// $Id: IdentNode.java 10059 2006-06-28 02:37:56Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-import org.hibernate.QueryException;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-import java.util.List;
-
-/**
- * Represents an identifier all by itself, which may be a function name,
- * a class alias, or a form of naked property-ref depending on the
- * context.
- *
- * @author josh Aug 16, 2004 7:20:55 AM
- */
-public class IdentNode extends FromReferenceNode implements SelectExpression {
-
-	private static final int UNKNOWN = 0;
-	private static final int PROPERTY_REF = 1;
-	private static final int COMPONENT_REF = 2;
-
-	private boolean nakedPropertyRef = false;
-
-	public void resolveIndex(AST parent) throws SemanticException {
-		// An ident node can represent an index expression if the ident
-		// represents a naked property ref
-		//      *Note: this makes the assumption (which is currently the case
-		//      in the hql-sql grammar) that the ident is first resolved
-		//      itself (addrExpr -> resolve()).  The other option, if that
-		//      changes, is to call resolve from here; but it is
-		//      currently un-needed overhead.
-		if (!(isResolved() && nakedPropertyRef)) {
-			throw new UnsupportedOperationException();
-		}
-
-		String propertyName = getOriginalText();
-		if (!getDataType().isCollectionType()) {
-			throw new SemanticException("Collection expected; [" + propertyName + "] does not refer to a collection property");
-		}
-
-		// TODO : most of below was taken verbatim from DotNode; should either delegate this logic or super-type it
-		CollectionType type = (CollectionType) getDataType();
-		String role = type.getRole();
-		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection(role);
-
-		String alias = null;  // DotNode uses null here...
-		String columnTableAlias = getFromElement().getTableAlias();
-		int joinType = JoinFragment.INNER_JOIN;
-		boolean fetch = false;
-
-		FromElementFactory factory = new FromElementFactory(
-				getWalker().getCurrentFromClause(),
-				getFromElement(),
-				propertyName,
-				alias,
-				getFromElement().toColumns(columnTableAlias, propertyName, false),
-				true
-		);
-		FromElement elem = factory.createCollection(queryableCollection, role, joinType, fetch, true);
-		setFromElement(elem);
-		getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces());	// Always add the collection's query spaces.
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) {
-		if (!isResolved()) {
-			if (getWalker().getCurrentFromClause().isFromElementAlias(getText())) {
-				if (resolveAsAlias()) {
-					setResolved();
-					// We represent a from-clause alias
-				}
-			}
-			else if (parent != null && parent.getType() == SqlTokenTypes.DOT) {
-				DotNode dot = (DotNode) parent;
-				if (parent.getFirstChild() == this) {
-					if (resolveAsNakedComponentPropertyRefLHS(dot)) {
-						// we are the LHS of the DOT representing a naked comp-prop-ref
-						setResolved();
-					}
-				}
-				else {
-					if (resolveAsNakedComponentPropertyRefRHS(dot)) {
-						// we are the RHS of the DOT representing a naked comp-prop-ref
-						setResolved();
-					}
-				}
-			}
-			else {
-				int result = resolveAsNakedPropertyRef();
-				if (result == PROPERTY_REF) {
-					// we represent a naked (simple) prop-ref
-					setResolved();
-				}
-				else if (result == COMPONENT_REF) {
-					// EARLY EXIT!!!  return so the resolve call explicitly coming from DotNode can
-					// resolve this...
-					return;
-				}
-			}
-
-			// if we are still not resolved, we might represent a constant.
-			//      needed to add this here because the allowance of
-			//      naked-prop-refs in the grammar collides with the
-			//      definition of literals/constants ("nondeterminism").
-			//      TODO: cleanup the grammar so that "processConstants" is always just handled from here
-			if (!isResolved()) {
-				try {
-					getWalker().getLiteralProcessor().processConstant(this, false);
-				}
-				catch (Throwable ignore) {
-					// just ignore it for now, it'll get resolved later...
-				}
-			}
-		}
-	}
-
-	private boolean resolveAsAlias() {
-		// This is not actually a constant, but a reference to FROM element.
-		FromElement element = getWalker().getCurrentFromClause().getFromElement(getText());
-		if (element != null) {
-			setFromElement(element);
-			setText(element.getIdentityColumn());
-			setType(SqlTokenTypes.ALIAS_REF);
-			return true;
-		}
-		return false;
-	}
-
-	private Type getNakedPropertyType(FromElement fromElement)
-	{
-		if (fromElement == null) {
-			return null;
-		}
-		String property = getOriginalText();
-		Type propertyType = null;
-		try {
-			propertyType = fromElement.getPropertyType(property, property);
-		}
-		catch (Throwable t) {
-		}
-		return propertyType;
-	}
-
-	private int resolveAsNakedPropertyRef() {
-		FromElement fromElement = locateSingleFromElement();
-		if (fromElement == null) {
-			return UNKNOWN;
-		}
-		Queryable persister = fromElement.getQueryable();
-		if (persister == null) {
-			return UNKNOWN;
-		}
-		Type propertyType = getNakedPropertyType(fromElement);
-		if (propertyType == null) {
-			// assume this ident's text does *not* refer to a property on the given persister
-			return UNKNOWN;
-		}
-
-		if ((propertyType.isComponentType() || propertyType.isAssociationType() )) {
-			return COMPONENT_REF;
-		}
-
-		setFromElement(fromElement);
-		String property = getText();
-		String[] columns = getWalker().isSelectStatement()
-				? persister.toColumns(fromElement.getTableAlias(), property)
-				: persister.toColumns(property);
-		String text = StringHelper.join(", ", columns);
-		setText(columns.length == 1 ? text : "(" + text + ")");
-		setType(SqlTokenTypes.SQL_TOKEN);
-
-		// these pieces are needed for usage in select clause
-		super.setDataType(propertyType);
-		nakedPropertyRef = true;
-
-		return PROPERTY_REF;
-	}
-
-	private boolean resolveAsNakedComponentPropertyRefLHS(DotNode parent) {
-		FromElement fromElement = locateSingleFromElement();
-		if (fromElement == null) {
-			return false;
-		}
-
-		Type componentType = getNakedPropertyType(fromElement);
-		if ( componentType == null ) {
-			throw new QueryException( "Unable to resolve path [" + parent.getPath() + "], unexpected token [" + getOriginalText() + "]" );
-		}
-		if (!componentType.isComponentType()) {
-			throw new QueryException("Property '" + getOriginalText() + "' is not a component.  Use an alias to reference associations or collections.");
-		}
-
-		Type propertyType = null;  // used to set the type of the parent dot node
-		String propertyPath = getText() + "." + getNextSibling().getText();
-		try {
-			// check to see if our "propPath" actually
-			// represents a property on the persister
-			propertyType = fromElement.getPropertyType(getText(), propertyPath);
-		}
-		catch (Throwable t) {
-			// assume we do *not* refer to a property on the given persister
-			return false;
-		}
-
-		setFromElement(fromElement);
-		parent.setPropertyPath(propertyPath);
-		parent.setDataType(propertyType);
-
-		return true;
-	}
-
-	private boolean resolveAsNakedComponentPropertyRefRHS(DotNode parent) {
-		FromElement fromElement = locateSingleFromElement();
-		if (fromElement == null) {
-			return false;
-		}
-
-		Type propertyType = null;
-		String propertyPath = parent.getLhs().getText() + "." + getText();
-		try {
-			// check to see if our "propPath" actually
-			// represents a property on the persister
-			propertyType = fromElement.getPropertyType(getText(), propertyPath);
-		}
-		catch (Throwable t) {
-			// assume we do *not* refer to a property on the given persister
-			return false;
-		}
-
-		setFromElement(fromElement);
-		// this piece is needed for usage in select clause
-		super.setDataType(propertyType);
-		nakedPropertyRef = true;
-
-		return true;
-	}
-
-	private FromElement locateSingleFromElement() {
-		List fromElements = getWalker().getCurrentFromClause().getFromElements();
-		if (fromElements == null || fromElements.size() != 1) {
-			// TODO : should this be an error?
-			return null;
-		}
-		FromElement element = (FromElement) fromElements.get(0);
-		if (element.getClassAlias() != null) {
-			// naked property-refs cannot be used with an aliased from element
-			return null;
-		}
-		return element;
-	}
-
-	public Type getDataType() {
-		Type type = super.getDataType();
-		if (type != null) return type;
-		FromElement fe = getFromElement();
-		if (fe != null) return fe.getDataType();
-		SQLFunction sf = getWalker().getSessionFactoryHelper().findSQLFunction(getText());
-		return sf == null ? null : sf.getReturnType(null, null);
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		if (nakedPropertyRef) {
-			// do *not* over-write the column text, as that has already been
-			// "rendered" during resolve
-			ColumnHelper.generateSingleScalarColumn(this, i);
-		}
-		else {
-			FromElement fe = getFromElement();
-			if (fe != null) {
-				setText(fe.renderScalarIdentifierSelect(i));
-			}
-			else {
-				ColumnHelper.generateSingleScalarColumn(this, i);
-			}
-		}
-	}
-
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-
-		if (getType() == SqlTokenTypes.ALIAS_REF) {
-			buf.append("{alias=").append(getOriginalText());
-			if (getFromElement() == null) {
-				buf.append(", no from element");
-			}
-			else {
-				buf.append(", className=").append(getFromElement().getClassName());
-				buf.append(", tableAlias=").append(getFromElement().getTableAlias());
-			}
-			buf.append("}");
-		}
-		else {
-			buf.append("{originalText=" + getOriginalText()).append("}");
-		}
-		return buf.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IdentNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,330 @@
+/*
+ * 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.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+import org.hibernate.QueryException;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+import java.util.List;
+
+/**
+ * Represents an identifier all by itself, which may be a function name,
+ * a class alias, or a form of naked property-ref depending on the
+ * context.
+ *
+ * @author josh
+ */
+public class IdentNode extends FromReferenceNode implements SelectExpression {
+
+	private static final int UNKNOWN = 0;
+	private static final int PROPERTY_REF = 1;
+	private static final int COMPONENT_REF = 2;
+
+	private boolean nakedPropertyRef = false;
+
+	public void resolveIndex(AST parent) throws SemanticException {
+		// An ident node can represent an index expression if the ident
+		// represents a naked property ref
+		//      *Note: this makes the assumption (which is currently the case
+		//      in the hql-sql grammar) that the ident is first resolved
+		//      itself (addrExpr -> resolve()).  The other option, if that
+		//      changes, is to call resolve from here; but it is
+		//      currently un-needed overhead.
+		if (!(isResolved() && nakedPropertyRef)) {
+			throw new UnsupportedOperationException();
+		}
+
+		String propertyName = getOriginalText();
+		if (!getDataType().isCollectionType()) {
+			throw new SemanticException("Collection expected; [" + propertyName + "] does not refer to a collection property");
+		}
+
+		// TODO : most of below was taken verbatim from DotNode; should either delegate this logic or super-type it
+		CollectionType type = (CollectionType) getDataType();
+		String role = type.getRole();
+		QueryableCollection queryableCollection = getSessionFactoryHelper().requireQueryableCollection(role);
+
+		String alias = null;  // DotNode uses null here...
+		String columnTableAlias = getFromElement().getTableAlias();
+		int joinType = JoinFragment.INNER_JOIN;
+		boolean fetch = false;
+
+		FromElementFactory factory = new FromElementFactory(
+				getWalker().getCurrentFromClause(),
+				getFromElement(),
+				propertyName,
+				alias,
+				getFromElement().toColumns(columnTableAlias, propertyName, false),
+				true
+		);
+		FromElement elem = factory.createCollection(queryableCollection, role, joinType, fetch, true);
+		setFromElement(elem);
+		getWalker().addQuerySpaces(queryableCollection.getCollectionSpaces());	// Always add the collection's query spaces.
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) {
+		if (!isResolved()) {
+			if (getWalker().getCurrentFromClause().isFromElementAlias(getText())) {
+				if (resolveAsAlias()) {
+					setResolved();
+					// We represent a from-clause alias
+				}
+			}
+			else if (parent != null && parent.getType() == SqlTokenTypes.DOT) {
+				DotNode dot = (DotNode) parent;
+				if (parent.getFirstChild() == this) {
+					if (resolveAsNakedComponentPropertyRefLHS(dot)) {
+						// we are the LHS of the DOT representing a naked comp-prop-ref
+						setResolved();
+					}
+				}
+				else {
+					if (resolveAsNakedComponentPropertyRefRHS(dot)) {
+						// we are the RHS of the DOT representing a naked comp-prop-ref
+						setResolved();
+					}
+				}
+			}
+			else {
+				int result = resolveAsNakedPropertyRef();
+				if (result == PROPERTY_REF) {
+					// we represent a naked (simple) prop-ref
+					setResolved();
+				}
+				else if (result == COMPONENT_REF) {
+					// EARLY EXIT!!!  return so the resolve call explicitly coming from DotNode can
+					// resolve this...
+					return;
+				}
+			}
+
+			// if we are still not resolved, we might represent a constant.
+			//      needed to add this here because the allowance of
+			//      naked-prop-refs in the grammar collides with the
+			//      definition of literals/constants ("nondeterminism").
+			//      TODO: cleanup the grammar so that "processConstants" is always just handled from here
+			if (!isResolved()) {
+				try {
+					getWalker().getLiteralProcessor().processConstant(this, false);
+				}
+				catch (Throwable ignore) {
+					// just ignore it for now, it'll get resolved later...
+				}
+			}
+		}
+	}
+
+	private boolean resolveAsAlias() {
+		// This is not actually a constant, but a reference to FROM element.
+		FromElement element = getWalker().getCurrentFromClause().getFromElement(getText());
+		if (element != null) {
+			setFromElement(element);
+			setText(element.getIdentityColumn());
+			setType(SqlTokenTypes.ALIAS_REF);
+			return true;
+		}
+		return false;
+	}
+
+	private Type getNakedPropertyType(FromElement fromElement)
+	{
+		if (fromElement == null) {
+			return null;
+		}
+		String property = getOriginalText();
+		Type propertyType = null;
+		try {
+			propertyType = fromElement.getPropertyType(property, property);
+		}
+		catch (Throwable t) {
+		}
+		return propertyType;
+	}
+
+	private int resolveAsNakedPropertyRef() {
+		FromElement fromElement = locateSingleFromElement();
+		if (fromElement == null) {
+			return UNKNOWN;
+		}
+		Queryable persister = fromElement.getQueryable();
+		if (persister == null) {
+			return UNKNOWN;
+		}
+		Type propertyType = getNakedPropertyType(fromElement);
+		if (propertyType == null) {
+			// assume this ident's text does *not* refer to a property on the given persister
+			return UNKNOWN;
+		}
+
+		if ((propertyType.isComponentType() || propertyType.isAssociationType() )) {
+			return COMPONENT_REF;
+		}
+
+		setFromElement(fromElement);
+		String property = getText();
+		String[] columns = getWalker().isSelectStatement()
+				? persister.toColumns(fromElement.getTableAlias(), property)
+				: persister.toColumns(property);
+		String text = StringHelper.join(", ", columns);
+		setText(columns.length == 1 ? text : "(" + text + ")");
+		setType(SqlTokenTypes.SQL_TOKEN);
+
+		// these pieces are needed for usage in select clause
+		super.setDataType(propertyType);
+		nakedPropertyRef = true;
+
+		return PROPERTY_REF;
+	}
+
+	private boolean resolveAsNakedComponentPropertyRefLHS(DotNode parent) {
+		FromElement fromElement = locateSingleFromElement();
+		if (fromElement == null) {
+			return false;
+		}
+
+		Type componentType = getNakedPropertyType(fromElement);
+		if ( componentType == null ) {
+			throw new QueryException( "Unable to resolve path [" + parent.getPath() + "], unexpected token [" + getOriginalText() + "]" );
+		}
+		if (!componentType.isComponentType()) {
+			throw new QueryException("Property '" + getOriginalText() + "' is not a component.  Use an alias to reference associations or collections.");
+		}
+
+		Type propertyType = null;  // used to set the type of the parent dot node
+		String propertyPath = getText() + "." + getNextSibling().getText();
+		try {
+			// check to see if our "propPath" actually
+			// represents a property on the persister
+			propertyType = fromElement.getPropertyType(getText(), propertyPath);
+		}
+		catch (Throwable t) {
+			// assume we do *not* refer to a property on the given persister
+			return false;
+		}
+
+		setFromElement(fromElement);
+		parent.setPropertyPath(propertyPath);
+		parent.setDataType(propertyType);
+
+		return true;
+	}
+
+	private boolean resolveAsNakedComponentPropertyRefRHS(DotNode parent) {
+		FromElement fromElement = locateSingleFromElement();
+		if (fromElement == null) {
+			return false;
+		}
+
+		Type propertyType = null;
+		String propertyPath = parent.getLhs().getText() + "." + getText();
+		try {
+			// check to see if our "propPath" actually
+			// represents a property on the persister
+			propertyType = fromElement.getPropertyType(getText(), propertyPath);
+		}
+		catch (Throwable t) {
+			// assume we do *not* refer to a property on the given persister
+			return false;
+		}
+
+		setFromElement(fromElement);
+		// this piece is needed for usage in select clause
+		super.setDataType(propertyType);
+		nakedPropertyRef = true;
+
+		return true;
+	}
+
+	private FromElement locateSingleFromElement() {
+		List fromElements = getWalker().getCurrentFromClause().getFromElements();
+		if (fromElements == null || fromElements.size() != 1) {
+			// TODO : should this be an error?
+			return null;
+		}
+		FromElement element = (FromElement) fromElements.get(0);
+		if (element.getClassAlias() != null) {
+			// naked property-refs cannot be used with an aliased from element
+			return null;
+		}
+		return element;
+	}
+
+	public Type getDataType() {
+		Type type = super.getDataType();
+		if (type != null) return type;
+		FromElement fe = getFromElement();
+		if (fe != null) return fe.getDataType();
+		SQLFunction sf = getWalker().getSessionFactoryHelper().findSQLFunction(getText());
+		return sf == null ? null : sf.getReturnType(null, null);
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		if (nakedPropertyRef) {
+			// do *not* over-write the column text, as that has already been
+			// "rendered" during resolve
+			ColumnHelper.generateSingleScalarColumn(this, i);
+		}
+		else {
+			FromElement fe = getFromElement();
+			if (fe != null) {
+				setText(fe.renderScalarIdentifierSelect(i));
+			}
+			else {
+				ColumnHelper.generateSingleScalarColumn(this, i);
+			}
+		}
+	}
+
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+
+		if (getType() == SqlTokenTypes.ALIAS_REF) {
+			buf.append("{alias=").append(getOriginalText());
+			if (getFromElement() == null) {
+				buf.append(", no from element");
+			}
+			else {
+				buf.append(", className=").append(getFromElement().getClassName());
+				buf.append(", tableAlias=").append(getFromElement().getTableAlias());
+			}
+			buf.append("}");
+		}
+		else {
+			buf.append("{originalText=" + getOriginalText()).append("}");
+		}
+		return buf.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-// $Id: ImpliedFromElement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-/**
- * Represents a FROM element implied by a path expression or a collection reference.
- *
- * @author josh Feb 10, 2005 12:31:03 AM
- */
-public class ImpliedFromElement extends FromElement {
-	/**
-	 * True if this from element was implied from a path in the FROM clause, but not
-	 * explicitly declard in the from clause.
-	 */
-	private boolean impliedInFromClause = false;
-
-	/**
-	 * True if this implied from element should be included in the projection list.
-	 */
-	private boolean inProjectionList = false;
-
-	public boolean isImplied() {
-		return true;
-	}
-
-	public void setImpliedInFromClause(boolean flag) {
-		impliedInFromClause = flag;
-	}
-
-	public boolean isImpliedInFromClause() {
-		return impliedInFromClause;
-	}
-
-	public void setInProjectionList(boolean inProjectionList) {
-		this.inProjectionList = inProjectionList;
-	}
-
-	public boolean inProjectionList() {
-		return inProjectionList && isFromOrJoinFragment();
-	}
-
-	public boolean isIncludeSubclasses() {
-		return false;	// Never include subclasses for implied from elements.
-	}
-
-	/**
-	 * Returns additional display text for the AST node.
-	 *
-	 * @return String - The additional display text.
-	 */
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "ImpliedFromElement{" );
-		appendDisplayText( buf );
-		buf.append( "}" );
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ImpliedFromElement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.tree;
+
+/**
+ * Represents a FROM element implied by a path expression or a collection reference.
+ *
+ * @author josh
+ */
+public class ImpliedFromElement extends FromElement {
+	/**
+	 * True if this from element was implied from a path in the FROM clause, but not
+	 * explicitly declard in the from clause.
+	 */
+	private boolean impliedInFromClause = false;
+
+	/**
+	 * True if this implied from element should be included in the projection list.
+	 */
+	private boolean inProjectionList = false;
+
+	public boolean isImplied() {
+		return true;
+	}
+
+	public void setImpliedInFromClause(boolean flag) {
+		impliedInFromClause = flag;
+	}
+
+	public boolean isImpliedInFromClause() {
+		return impliedInFromClause;
+	}
+
+	public void setInProjectionList(boolean inProjectionList) {
+		this.inProjectionList = inProjectionList;
+	}
+
+	public boolean inProjectionList() {
+		return inProjectionList && isFromOrJoinFragment();
+	}
+
+	public boolean isIncludeSubclasses() {
+		return false;	// Never include subclasses for implied from elements.
+	}
+
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return String - The additional display text.
+	 */
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "ImpliedFromElement{" );
+		appendDisplayText( buf );
+		buf.append( "}" );
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-import org.hibernate.type.Type;
-
-/**
- * @author Steve Ebersole
- */
-public class InLogicOperatorNode extends BinaryLogicOperatorNode implements BinaryOperatorNode {
-
-	public Node getInList() {
-		return getRightHandOperand();
-	}
-
-	public void initialize() throws SemanticException {
-		Node lhs = getLeftHandOperand();
-		if ( lhs == null ) {
-			throw new SemanticException( "left-hand operand of in operator was null" );
-		}
-		Node inList = getInList();
-		if ( inList == null ) {
-			throw new SemanticException( "right-hand operand of in operator was null" );
-		}
-
-		// for expected parameter type injection, we expect that the lhs represents
-		// some form of property ref and that the children of the in-list represent
-		// one-or-more params.
-		if ( SqlNode.class.isAssignableFrom( lhs.getClass() ) ) {
-			Type lhsType = ( ( SqlNode ) lhs ).getDataType();
-			AST inListChild = inList.getFirstChild();
-			while ( inListChild != null ) {
-				if ( ExpectedTypeAwareNode.class.isAssignableFrom( inListChild.getClass() ) ) {
-					( ( ExpectedTypeAwareNode ) inListChild ).setExpectedType( lhsType );
-				}
-				inListChild = inListChild.getNextSibling();
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+import org.hibernate.type.Type;
+
+/**
+ * @author Steve Ebersole
+ */
+public class InLogicOperatorNode extends BinaryLogicOperatorNode implements BinaryOperatorNode {
+
+	public Node getInList() {
+		return getRightHandOperand();
+	}
+
+	public void initialize() throws SemanticException {
+		Node lhs = getLeftHandOperand();
+		if ( lhs == null ) {
+			throw new SemanticException( "left-hand operand of in operator was null" );
+		}
+		Node inList = getInList();
+		if ( inList == null ) {
+			throw new SemanticException( "right-hand operand of in operator was null" );
+		}
+
+		// for expected parameter type injection, we expect that the lhs represents
+		// some form of property ref and that the children of the in-list represent
+		// one-or-more params.
+		if ( SqlNode.class.isAssignableFrom( lhs.getClass() ) ) {
+			Type lhsType = ( ( SqlNode ) lhs ).getDataType();
+			AST inListChild = inList.getFirstChild();
+			while ( inListChild != null ) {
+				if ( ExpectedTypeAwareNode.class.isAssignableFrom( inListChild.getClass() ) ) {
+					( ( ExpectedTypeAwareNode ) inListChild ).setExpectedType( lhsType );
+				}
+				inListChild = inListChild.getNextSibling();
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,134 +0,0 @@
-// $Id: IndexNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.ast.SqlGenerator;
-import org.hibernate.hql.ast.util.SessionFactoryHelper;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-import antlr.RecognitionException;
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents the [] operator and provides it's semantics.
- *
- * @author josh Aug 14, 2004 7:07:10 AM
- */
-public class IndexNode extends FromReferenceNode {
-
-	private static final Logger log = LoggerFactory.getLogger( IndexNode.class );
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		throw new UnsupportedOperationException( "An IndexNode cannot generate column text!" );
-	}
-
-	public void prepareForDot(String propertyName) throws SemanticException {
-		FromElement fromElement = getFromElement();
-		if ( fromElement == null ) {
-			throw new IllegalStateException( "No FROM element for index operator!" );
-		}
-		QueryableCollection queryableCollection = fromElement.getQueryableCollection();
-		if ( queryableCollection != null && !queryableCollection.isOneToMany() ) {
-
-			FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
-			String path = collectionNode.getPath() + "[]." + propertyName;
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Creating join for many-to-many elements for " + path );
-			}
-			FromElementFactory factory = new FromElementFactory( fromElement.getFromClause(), fromElement, path );
-			// This will add the new from element to the origin.
-			FromElement elementJoin = factory.createElementJoin( queryableCollection );
-			setFromElement( elementJoin );
-		}
-	}
-
-	public void resolveIndex(AST parent) throws SemanticException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) 
-	throws SemanticException {
-		if ( isResolved() ) {
-			return;
-		}
-		FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
-		SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
-		collectionNode.resolveIndex( this );		// Fully resolve the map reference, create implicit joins.
-
-		Type type = collectionNode.getDataType();
-		if ( !type.isCollectionType() ) {
-			throw new SemanticException( "The [] operator cannot be applied to type " + type.toString() );
-		}
-		String collectionRole = ( ( CollectionType ) type ).getRole();
-		QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection( collectionRole );
-		if ( !queryableCollection.hasIndex() ) {
-			throw new QueryException( "unindexed fromElement before []: " + collectionNode.getPath() );
-		}
-
-		// Generate the inner join -- The elements need to be joined to the collection they are in.
-		FromElement fromElement = collectionNode.getFromElement();
-		String elementTable = fromElement.getTableAlias();
-		FromClause fromClause = fromElement.getFromClause();
-		String path = collectionNode.getPath();
-
-		FromElement elem = fromClause.findCollectionJoin( path );
-		if ( elem == null ) {
-			FromElementFactory factory = new FromElementFactory( fromClause, fromElement, path );
-			elem = factory.createCollectionElementsJoin( queryableCollection, elementTable );
-			if ( log.isDebugEnabled() ) {
-				log.debug( "No FROM element found for the elements of collection join path " + path
-						+ ", created " + elem );
-			}
-		}
-		else {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "FROM element found for collection join path " + path );
-			}
-		}
-
-		// Add the condition to the join sequence that qualifies the indexed element.
-		AST index = collectionNode.getNextSibling();	// The index should be a constant, which will have been processed already.
-		if ( index == null ) {
-			throw new QueryException( "No index value!" );
-		}
-
-		setFromElement( fromElement );							// The 'from element' that represents the elements of the collection.
-
-		// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
-		String collectionTableAlias = elementTable;
-		if ( elem.getCollectionTableAlias() != null ) {
-			collectionTableAlias = elem.getCollectionTableAlias();
-		}
-
-		// TODO: get SQL rendering out of here, create an AST for the join expressions.
-		// Use the SQL generator grammar to generate the SQL text for the index expression.
-		JoinSequence joinSequence = fromElement.getJoinSequence();
-		String[] indexCols = queryableCollection.getIndexColumnNames();
-		if ( indexCols.length != 1 ) {
-			throw new QueryException( "composite-index appears in []: " + collectionNode.getPath() );
-		}
-		SqlGenerator gen = new SqlGenerator( getSessionFactoryHelper().getFactory() );
-		try {
-			gen.simpleExpr( index ); //TODO: used to be exprNoParens! was this needed?
-		}
-		catch ( RecognitionException e ) {
-			throw new QueryException( e.getMessage(), e );
-		}
-		String expression = gen.getSQL();
-		joinSequence.addCondition( collectionTableAlias + '.' + indexCols[0] + " = " + expression );
-
-		// Now, set the text for this node.  It should be the element columns.
-		String[] elementColumns = queryableCollection.getElementColumnNames( elementTable );
-		setText( elementColumns[0] );
-		setResolved();
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IndexNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,157 @@
+/*
+ * 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.tree;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.ast.SqlGenerator;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+import antlr.RecognitionException;
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents the [] operator and provides it's semantics.
+ *
+ * @author josh
+ */
+public class IndexNode extends FromReferenceNode {
+
+	private static final Logger log = LoggerFactory.getLogger( IndexNode.class );
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		throw new UnsupportedOperationException( "An IndexNode cannot generate column text!" );
+	}
+
+	public void prepareForDot(String propertyName) throws SemanticException {
+		FromElement fromElement = getFromElement();
+		if ( fromElement == null ) {
+			throw new IllegalStateException( "No FROM element for index operator!" );
+		}
+		QueryableCollection queryableCollection = fromElement.getQueryableCollection();
+		if ( queryableCollection != null && !queryableCollection.isOneToMany() ) {
+
+			FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
+			String path = collectionNode.getPath() + "[]." + propertyName;
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Creating join for many-to-many elements for " + path );
+			}
+			FromElementFactory factory = new FromElementFactory( fromElement.getFromClause(), fromElement, path );
+			// This will add the new from element to the origin.
+			FromElement elementJoin = factory.createElementJoin( queryableCollection );
+			setFromElement( elementJoin );
+		}
+	}
+
+	public void resolveIndex(AST parent) throws SemanticException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) 
+	throws SemanticException {
+		if ( isResolved() ) {
+			return;
+		}
+		FromReferenceNode collectionNode = ( FromReferenceNode ) getFirstChild();
+		SessionFactoryHelper sessionFactoryHelper = getSessionFactoryHelper();
+		collectionNode.resolveIndex( this );		// Fully resolve the map reference, create implicit joins.
+
+		Type type = collectionNode.getDataType();
+		if ( !type.isCollectionType() ) {
+			throw new SemanticException( "The [] operator cannot be applied to type " + type.toString() );
+		}
+		String collectionRole = ( ( CollectionType ) type ).getRole();
+		QueryableCollection queryableCollection = sessionFactoryHelper.requireQueryableCollection( collectionRole );
+		if ( !queryableCollection.hasIndex() ) {
+			throw new QueryException( "unindexed fromElement before []: " + collectionNode.getPath() );
+		}
+
+		// Generate the inner join -- The elements need to be joined to the collection they are in.
+		FromElement fromElement = collectionNode.getFromElement();
+		String elementTable = fromElement.getTableAlias();
+		FromClause fromClause = fromElement.getFromClause();
+		String path = collectionNode.getPath();
+
+		FromElement elem = fromClause.findCollectionJoin( path );
+		if ( elem == null ) {
+			FromElementFactory factory = new FromElementFactory( fromClause, fromElement, path );
+			elem = factory.createCollectionElementsJoin( queryableCollection, elementTable );
+			if ( log.isDebugEnabled() ) {
+				log.debug( "No FROM element found for the elements of collection join path " + path
+						+ ", created " + elem );
+			}
+		}
+		else {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "FROM element found for collection join path " + path );
+			}
+		}
+
+		// Add the condition to the join sequence that qualifies the indexed element.
+		AST index = collectionNode.getNextSibling();	// The index should be a constant, which will have been processed already.
+		if ( index == null ) {
+			throw new QueryException( "No index value!" );
+		}
+
+		setFromElement( fromElement );							// The 'from element' that represents the elements of the collection.
+
+		// Sometimes use the element table alias, sometimes use the... umm... collection table alias (many to many)
+		String collectionTableAlias = elementTable;
+		if ( elem.getCollectionTableAlias() != null ) {
+			collectionTableAlias = elem.getCollectionTableAlias();
+		}
+
+		// TODO: get SQL rendering out of here, create an AST for the join expressions.
+		// Use the SQL generator grammar to generate the SQL text for the index expression.
+		JoinSequence joinSequence = fromElement.getJoinSequence();
+		String[] indexCols = queryableCollection.getIndexColumnNames();
+		if ( indexCols.length != 1 ) {
+			throw new QueryException( "composite-index appears in []: " + collectionNode.getPath() );
+		}
+		SqlGenerator gen = new SqlGenerator( getSessionFactoryHelper().getFactory() );
+		try {
+			gen.simpleExpr( index ); //TODO: used to be exprNoParens! was this needed?
+		}
+		catch ( RecognitionException e ) {
+			throw new QueryException( e.getMessage(), e );
+		}
+		String expression = gen.getSQL();
+		joinSequence.addCondition( collectionTableAlias + '.' + indexCols[0] + " = " + expression );
+
+		// Now, set the text for this node.  It should be the element columns.
+		String[] elementColumns = queryableCollection.getElementColumnNames( elementTable );
+		setText( elementColumns[0] );
+		setResolved();
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-// $Id: InitializeableNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-
-package org.hibernate.hql.ast.tree;
-
-/**
- * An interface for initializeable AST nodes.
- */
-public interface InitializeableNode {
-	/**
-	 * Initializes the node with the parameter.
-	 *
-	 * @param param the initialization parameter.
-	 */
-	void initialize(Object param);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InitializeableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+/**
+ * An interface for initializeable AST nodes.
+ */
+public interface InitializeableNode {
+	/**
+	 * Initializes the node with the parameter.
+	 *
+	 * @param param the initialization parameter.
+	 */
+	void initialize(Object param);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-// $Id: InsertStatement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.QueryException;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-
-/**
- * Defines a top-level AST node representing an HQL "insert select" statement.
- *
- * @author Steve Ebersole
- */
-public class InsertStatement extends AbstractStatement {
-
-	/**
-	 * @see Statement#getStatementType()
-	 */
-	public int getStatementType() {
-		return HqlSqlTokenTypes.INSERT;
-	}
-
-	/**
-	 * @see Statement#needsExecutor()
-	 */
-	public boolean needsExecutor() {
-		return true;
-	}
-
-	/**
-	 * Performs detailed semantic validation on this insert statement tree.
-	 *
-	 * @throws QueryException Indicates validation failure.
-	 */
-	public void validate() throws QueryException {
-		getIntoClause().validateTypes( getSelectClause() );
-	}
-
-	/**
-	 * Retreive this insert statement's into-clause.
-	 *
-	 * @return The into-clause
-	 */
-	public IntoClause getIntoClause() {
-		return ( IntoClause ) getFirstChild();
-	}
-
-	/**
-	 * Retreive this insert statement's select-clause.
-	 *
-	 * @return The select-clause.
-	 */
-	public SelectClause getSelectClause() {
-		return ( ( QueryNode ) getIntoClause().getNextSibling() ).getSelectClause();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/InsertStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.tree;
+
+import org.hibernate.QueryException;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+
+/**
+ * Defines a top-level AST node representing an HQL "insert select" statement.
+ *
+ * @author Steve Ebersole
+ */
+public class InsertStatement extends AbstractStatement {
+
+	/**
+	 * @see Statement#getStatementType()
+	 */
+	public int getStatementType() {
+		return HqlSqlTokenTypes.INSERT;
+	}
+
+	/**
+	 * @see Statement#needsExecutor()
+	 */
+	public boolean needsExecutor() {
+		return true;
+	}
+
+	/**
+	 * Performs detailed semantic validation on this insert statement tree.
+	 *
+	 * @throws QueryException Indicates validation failure.
+	 */
+	public void validate() throws QueryException {
+		getIntoClause().validateTypes( getSelectClause() );
+	}
+
+	/**
+	 * Retreive this insert statement's into-clause.
+	 *
+	 * @return The into-clause
+	 */
+	public IntoClause getIntoClause() {
+		return ( IntoClause ) getFirstChild();
+	}
+
+	/**
+	 * Retreive this insert statement's select-clause.
+	 *
+	 * @return The select-clause.
+	 */
+	public SelectClause getSelectClause() {
+		return ( ( QueryNode ) getIntoClause().getNextSibling() ).getSelectClause();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,234 +0,0 @@
-// $Id: IntoClause.java 8050 2005-08-31 15:02:23Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.sql.Types;
-
-import org.hibernate.QueryException;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-import antlr.collections.AST;
-
-/**
- * Represents an entity referenced in the INTO clause of an HQL
- * INSERT statement.
- *
- * @author Steve Ebersole
- */
-public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
-
-	private Queryable persister;
-	private String columnSpec = "";
-	private Type[] types;
-
-	private boolean discriminated;
-	private boolean explicitIdInsertion;
-	private boolean explicitVersionInsertion;
-
-
-	public void initialize(Queryable persister) {
-		if ( persister.isAbstract() ) {
-			throw new QueryException( "cannot insert into abstract class (no table)" );
-		}
-		this.persister = persister;
-		initializeColumns();
-
-		if ( getWalker().getSessionFactoryHelper().hasPhysicalDiscriminatorColumn( persister ) ) {
-			discriminated = true;
-			columnSpec += ", " + persister.getDiscriminatorColumnName();
-		}
-
-		resetText();
-	}
-
-	private void resetText() {
-		setText( "into " + getTableName() + " ( " + columnSpec + " )" );
-	}
-
-	public String getTableName() {
-		return persister.getSubclassTableName( 0 );
-	}
-
-	public Queryable getQueryable() {
-		return persister;
-	}
-
-	public String getEntityName() {
-		return persister.getEntityName();
-	}
-
-	public Type[] getInsertionTypes() {
-		return types;
-	}
-
-	public boolean isDiscriminated() {
-		return discriminated;
-	}
-
-	public boolean isExplicitIdInsertion() {
-		return explicitIdInsertion;
-	}
-
-	public boolean isExplicitVersionInsertion() {
-		return explicitVersionInsertion;
-	}
-
-	public void prependIdColumnSpec() {
-		columnSpec = persister.getIdentifierColumnNames()[0] + ", " + columnSpec;
-		resetText();
-	}
-
-	public void prependVersionColumnSpec() {
-		columnSpec = persister.getPropertyColumnNames( persister.getVersionProperty() )[0] + ", " + columnSpec;
-		resetText();
-	}
-
-	public void validateTypes(SelectClause selectClause) throws QueryException {
-		Type[] selectTypes = selectClause.getQueryReturnTypes();
-		if ( selectTypes.length != types.length ) {
-			throw new QueryException( "number of select types did not match those for insert" );
-		}
-
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( !areCompatible( types[i], selectTypes[i] ) ) {
-				throw new QueryException(
-				        "insertion type [" + types[i] + "] and selection type [" +
-				        selectTypes[i] + "] at position " + i + " are not compatible"
-				);
-			}
-		}
-
-		// otherwise, everything ok.
-	}
-
-	/**
-	 * Returns additional display text for the AST node.
-	 *
-	 * @return String - The additional display text.
-	 */
-	public String getDisplayText() {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "IntoClause{" );
-		buf.append( "entityName=" ).append( getEntityName() );
-		buf.append( ",tableName=" ).append( getTableName() );
-		buf.append( ",columns={" ).append( columnSpec ).append( "}" );
-		buf.append( "}" );
-		return buf.toString();
-	}
-
-	private void initializeColumns() {
-		AST propertySpec = getFirstChild();
-		List types = new ArrayList();
-		visitPropertySpecNodes( propertySpec.getFirstChild(), types );
-		this.types = ArrayHelper.toTypeArray( types );
-		columnSpec = columnSpec.substring( 0, columnSpec.length() - 2 );
-	}
-
-	private void visitPropertySpecNodes(AST propertyNode, List types) {
-		if ( propertyNode == null ) {
-			return;
-		}
-		// TODO : we really need to be able to deal with component paths here also;
-		// this is difficult because the hql-sql grammar expects all those node types
-		// to be FromReferenceNodes.  One potential fix here would be to convert the
-		// IntoClause to just use a FromClause/FromElement combo (as a child of the
-		// InsertStatement) and move all this logic into the InsertStatement.  That's
-		// probably the easiest approach (read: least amount of changes to the grammar
-		// and code), but just doesn't feel right as then an insert would contain
-		// 2 from-clauses
-		String name = propertyNode.getText();
-		if ( isSuperclassProperty( name ) ) {
-			throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" );
-		}
-
-		if ( name.equals( persister.getIdentifierPropertyName() ) ) {
-			explicitIdInsertion = true;
-		}
-
-		if ( persister.isVersioned() ) {
-			if ( name.equals( persister.getPropertyNames()[ persister.getVersionProperty() ] ) ) {
-				explicitVersionInsertion = true;
-			}
-		}
-
-		String[] columnNames = persister.toColumns( name );
-		renderColumns( columnNames );
-		types.add( persister.toType( name ) );
-
-		// visit width-first, then depth
-		visitPropertySpecNodes( propertyNode.getNextSibling(), types );
-		visitPropertySpecNodes( propertyNode.getFirstChild(), types );
-	}
-
-	private void renderColumns(String[] columnNames) {
-		for ( int i = 0; i < columnNames.length; i++ ) {
-			columnSpec += columnNames[i] + ", ";
-		}
-	}
-
-	private boolean isSuperclassProperty(String propertyName) {
-		// really there are two situations where it should be ok to allow the insertion
-		// into properties defined on a superclass:
-		//      1) union-subclass with an abstract root entity
-		//      2) discrim-subclass
-		//
-		// #1 is handled already because of the fact that
-		// UnionSubclassPersister alreay always returns 0
-		// for this call...
-		//
-		// we may want to disallow it for discrim-subclass just for
-		// consistency-sake (currently does not work anyway)...
-		return persister.getSubclassPropertyTableNumber( propertyName ) != 0;
-	}
-
-	/**
-	 * Determine whether the two types are "assignment compatible".
-	 *
-	 * @param target The type defined in the into-clause.
-	 * @param source The type defined in the select clause.
-	 * @return True if they are assignment compatible.
-	 */
-	private boolean areCompatible(Type target, Type source) {
-		if ( target.equals( source ) ) {
-			// if the types report logical equivalence, return true...
-			return true;
-		}
-
-		// otherwise, perform a "deep equivalence" check...
-
-		if ( !target.getReturnedClass().isAssignableFrom( source.getReturnedClass() ) ) {
-			return false;
-		}
-
-		int[] targetDatatypes = target.sqlTypes( getSessionFactoryHelper().getFactory() );
-		int[] sourceDatatypes = source.sqlTypes( getSessionFactoryHelper().getFactory() );
-
-		if ( targetDatatypes.length != sourceDatatypes.length ) {
-			return false;
-		}
-
-		for ( int i = 0; i < targetDatatypes.length; i++ ) {
-			if ( !areSqlTypesCompatible( targetDatatypes[i], sourceDatatypes[i] ) ) {
-				return false;
-			}
-		}
-
-		return true;
-	}
-
-	private boolean areSqlTypesCompatible(int target, int source) {
-		switch ( target ) {
-			case Types.TIMESTAMP:
-				return source == Types.DATE || source == Types.TIME || source == Types.TIMESTAMP;
-			case Types.DATE:
-				return source == Types.DATE || source == Types.TIMESTAMP;
-			case Types.TIME:
-				return source == Types.TIME || source == Types.TIMESTAMP;
-			default:
-				return target == source;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IntoClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,257 @@
+/*
+ * 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.tree;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.sql.Types;
+
+import org.hibernate.QueryException;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+import antlr.collections.AST;
+
+/**
+ * Represents an entity referenced in the INTO clause of an HQL
+ * INSERT statement.
+ *
+ * @author Steve Ebersole
+ */
+public class IntoClause extends HqlSqlWalkerNode implements DisplayableNode {
+
+	private Queryable persister;
+	private String columnSpec = "";
+	private Type[] types;
+
+	private boolean discriminated;
+	private boolean explicitIdInsertion;
+	private boolean explicitVersionInsertion;
+
+
+	public void initialize(Queryable persister) {
+		if ( persister.isAbstract() ) {
+			throw new QueryException( "cannot insert into abstract class (no table)" );
+		}
+		this.persister = persister;
+		initializeColumns();
+
+		if ( getWalker().getSessionFactoryHelper().hasPhysicalDiscriminatorColumn( persister ) ) {
+			discriminated = true;
+			columnSpec += ", " + persister.getDiscriminatorColumnName();
+		}
+
+		resetText();
+	}
+
+	private void resetText() {
+		setText( "into " + getTableName() + " ( " + columnSpec + " )" );
+	}
+
+	public String getTableName() {
+		return persister.getSubclassTableName( 0 );
+	}
+
+	public Queryable getQueryable() {
+		return persister;
+	}
+
+	public String getEntityName() {
+		return persister.getEntityName();
+	}
+
+	public Type[] getInsertionTypes() {
+		return types;
+	}
+
+	public boolean isDiscriminated() {
+		return discriminated;
+	}
+
+	public boolean isExplicitIdInsertion() {
+		return explicitIdInsertion;
+	}
+
+	public boolean isExplicitVersionInsertion() {
+		return explicitVersionInsertion;
+	}
+
+	public void prependIdColumnSpec() {
+		columnSpec = persister.getIdentifierColumnNames()[0] + ", " + columnSpec;
+		resetText();
+	}
+
+	public void prependVersionColumnSpec() {
+		columnSpec = persister.getPropertyColumnNames( persister.getVersionProperty() )[0] + ", " + columnSpec;
+		resetText();
+	}
+
+	public void validateTypes(SelectClause selectClause) throws QueryException {
+		Type[] selectTypes = selectClause.getQueryReturnTypes();
+		if ( selectTypes.length != types.length ) {
+			throw new QueryException( "number of select types did not match those for insert" );
+		}
+
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( !areCompatible( types[i], selectTypes[i] ) ) {
+				throw new QueryException(
+				        "insertion type [" + types[i] + "] and selection type [" +
+				        selectTypes[i] + "] at position " + i + " are not compatible"
+				);
+			}
+		}
+
+		// otherwise, everything ok.
+	}
+
+	/**
+	 * Returns additional display text for the AST node.
+	 *
+	 * @return String - The additional display text.
+	 */
+	public String getDisplayText() {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "IntoClause{" );
+		buf.append( "entityName=" ).append( getEntityName() );
+		buf.append( ",tableName=" ).append( getTableName() );
+		buf.append( ",columns={" ).append( columnSpec ).append( "}" );
+		buf.append( "}" );
+		return buf.toString();
+	}
+
+	private void initializeColumns() {
+		AST propertySpec = getFirstChild();
+		List types = new ArrayList();
+		visitPropertySpecNodes( propertySpec.getFirstChild(), types );
+		this.types = ArrayHelper.toTypeArray( types );
+		columnSpec = columnSpec.substring( 0, columnSpec.length() - 2 );
+	}
+
+	private void visitPropertySpecNodes(AST propertyNode, List types) {
+		if ( propertyNode == null ) {
+			return;
+		}
+		// TODO : we really need to be able to deal with component paths here also;
+		// this is difficult because the hql-sql grammar expects all those node types
+		// to be FromReferenceNodes.  One potential fix here would be to convert the
+		// IntoClause to just use a FromClause/FromElement combo (as a child of the
+		// InsertStatement) and move all this logic into the InsertStatement.  That's
+		// probably the easiest approach (read: least amount of changes to the grammar
+		// and code), but just doesn't feel right as then an insert would contain
+		// 2 from-clauses
+		String name = propertyNode.getText();
+		if ( isSuperclassProperty( name ) ) {
+			throw new QueryException( "INSERT statements cannot refer to superclass/joined properties [" + name + "]" );
+		}
+
+		if ( name.equals( persister.getIdentifierPropertyName() ) ) {
+			explicitIdInsertion = true;
+		}
+
+		if ( persister.isVersioned() ) {
+			if ( name.equals( persister.getPropertyNames()[ persister.getVersionProperty() ] ) ) {
+				explicitVersionInsertion = true;
+			}
+		}
+
+		String[] columnNames = persister.toColumns( name );
+		renderColumns( columnNames );
+		types.add( persister.toType( name ) );
+
+		// visit width-first, then depth
+		visitPropertySpecNodes( propertyNode.getNextSibling(), types );
+		visitPropertySpecNodes( propertyNode.getFirstChild(), types );
+	}
+
+	private void renderColumns(String[] columnNames) {
+		for ( int i = 0; i < columnNames.length; i++ ) {
+			columnSpec += columnNames[i] + ", ";
+		}
+	}
+
+	private boolean isSuperclassProperty(String propertyName) {
+		// really there are two situations where it should be ok to allow the insertion
+		// into properties defined on a superclass:
+		//      1) union-subclass with an abstract root entity
+		//      2) discrim-subclass
+		//
+		// #1 is handled already because of the fact that
+		// UnionSubclassPersister alreay always returns 0
+		// for this call...
+		//
+		// we may want to disallow it for discrim-subclass just for
+		// consistency-sake (currently does not work anyway)...
+		return persister.getSubclassPropertyTableNumber( propertyName ) != 0;
+	}
+
+	/**
+	 * Determine whether the two types are "assignment compatible".
+	 *
+	 * @param target The type defined in the into-clause.
+	 * @param source The type defined in the select clause.
+	 * @return True if they are assignment compatible.
+	 */
+	private boolean areCompatible(Type target, Type source) {
+		if ( target.equals( source ) ) {
+			// if the types report logical equivalence, return true...
+			return true;
+		}
+
+		// otherwise, perform a "deep equivalence" check...
+
+		if ( !target.getReturnedClass().isAssignableFrom( source.getReturnedClass() ) ) {
+			return false;
+		}
+
+		int[] targetDatatypes = target.sqlTypes( getSessionFactoryHelper().getFactory() );
+		int[] sourceDatatypes = source.sqlTypes( getSessionFactoryHelper().getFactory() );
+
+		if ( targetDatatypes.length != sourceDatatypes.length ) {
+			return false;
+		}
+
+		for ( int i = 0; i < targetDatatypes.length; i++ ) {
+			if ( !areSqlTypesCompatible( targetDatatypes[i], sourceDatatypes[i] ) ) {
+				return false;
+			}
+		}
+
+		return true;
+	}
+
+	private boolean areSqlTypesCompatible(int target, int source) {
+		switch ( target ) {
+			case Types.TIMESTAMP:
+				return source == Types.DATE || source == Types.TIME || source == Types.TIMESTAMP;
+			case Types.DATE:
+				return source == Types.DATE || source == Types.TIMESTAMP;
+			case Types.TIME:
+				return source == Types.TIME || source == Types.TIMESTAMP;
+			default:
+				return target == source;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-
-/**
- * IsNotNullLogicOperatorNode implementation
- *
- * @author Steve Ebersole
- */
-public class IsNotNullLogicOperatorNode extends AbstractNullnessCheckNode {
-	protected int getExpansionConnectorType() {
-		return HqlSqlTokenTypes.OR;
-	}
-
-	protected String getExpansionConnectorText() {
-		return "OR";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNotNullLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+
+/**
+ * IsNotNullLogicOperatorNode implementation
+ *
+ * @author Steve Ebersole
+ */
+public class IsNotNullLogicOperatorNode extends AbstractNullnessCheckNode {
+	protected int getExpansionConnectorType() {
+		return HqlSqlTokenTypes.OR;
+	}
+
+	protected String getExpansionConnectorText() {
+		return "OR";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-
-/**
- * Represents a 'is null' check.
- *
- * @author Steve Ebersole
- */
-public class IsNullLogicOperatorNode extends AbstractNullnessCheckNode {
-	protected int getExpansionConnectorType() {
-		return HqlSqlTokenTypes.AND;
-	}
-
-	protected String getExpansionConnectorText() {
-		return "AND";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/IsNullLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+
+/**
+ * Represents a 'is null' check.
+ *
+ * @author Steve Ebersole
+ */
+public class IsNullLogicOperatorNode extends AbstractNullnessCheckNode {
+	protected int getExpansionConnectorType() {
+		return HqlSqlTokenTypes.AND;
+	}
+
+	protected String getExpansionConnectorText() {
+		return "AND";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.type.LiteralType;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.QueryException;
-import org.hibernate.hql.QueryTranslator;
-
-/**
- * A node representing a static Java constant.
- *
- * @author Steve Ebersole
- */
-public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, SessionFactoryAwareNode {
-
-	private SessionFactoryImplementor factory;
-
-	private String constantExpression;
-	private Object constantValue;
-	private Type heuristicType;
-
-	private Type expectedType;
-
-	public void setText(String s) {
-		// for some reason the antlr.CommonAST initialization routines force
-		// this method to get called twice.  The first time with an empty string
-		if ( StringHelper.isNotEmpty( s ) ) {
-			constantExpression = s;
-			constantValue = ReflectHelper.getConstantValue( s );
-			heuristicType = TypeFactory.heuristicType( constantValue.getClass().getName() );
-			super.setText( s );
-		}
-	}
-
-	public void setExpectedType(Type expectedType) {
-		this.expectedType = expectedType;
-	}
-
-	public Type getExpectedType() {
-		return expectedType;
-	}
-
-	public void setSessionFactory(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	private String resolveToLiteralString(Type type) {
-		try {
-			LiteralType literalType = ( LiteralType ) type;
-			Dialect dialect = factory.getDialect();
-			return literalType.objectToSQLString( constantValue, dialect );
-		}
-		catch ( Throwable t ) {
-			throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + constantExpression, t );
-		}
-	}
-
-	public String getRenderText(SessionFactoryImplementor sessionFactory) {
-		Type type = expectedType == null ? heuristicType : expectedType;
-		return resolveToLiteralString( type );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/JavaConstantNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,90 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.type.LiteralType;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.QueryException;
+import org.hibernate.hql.QueryTranslator;
+
+/**
+ * A node representing a static Java constant.
+ *
+ * @author Steve Ebersole
+ */
+public class JavaConstantNode extends Node implements ExpectedTypeAwareNode, SessionFactoryAwareNode {
+
+	private SessionFactoryImplementor factory;
+
+	private String constantExpression;
+	private Object constantValue;
+	private Type heuristicType;
+
+	private Type expectedType;
+
+	public void setText(String s) {
+		// for some reason the antlr.CommonAST initialization routines force
+		// this method to get called twice.  The first time with an empty string
+		if ( StringHelper.isNotEmpty( s ) ) {
+			constantExpression = s;
+			constantValue = ReflectHelper.getConstantValue( s );
+			heuristicType = TypeFactory.heuristicType( constantValue.getClass().getName() );
+			super.setText( s );
+		}
+	}
+
+	public void setExpectedType(Type expectedType) {
+		this.expectedType = expectedType;
+	}
+
+	public Type getExpectedType() {
+		return expectedType;
+	}
+
+	public void setSessionFactory(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	private String resolveToLiteralString(Type type) {
+		try {
+			LiteralType literalType = ( LiteralType ) type;
+			Dialect dialect = factory.getDialect();
+			return literalType.objectToSQLString( constantValue, dialect );
+		}
+		catch ( Throwable t ) {
+			throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + constantExpression, t );
+		}
+	}
+
+	public String getRenderText(SessionFactoryImplementor sessionFactory) {
+		Type type = expectedType == null ? heuristicType : expectedType;
+		return resolveToLiteralString( type );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-// $Id: LiteralNode.java 10060 2006-06-28 02:53:39Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.Hibernate;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents a literal.
- *
- * @author josh Jan 8, 2005 10:09:53 AM
- */
-public class LiteralNode extends AbstractSelectExpression implements HqlSqlTokenTypes {
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-	public Type getDataType() {
-		switch ( getType() ) {
-			case NUM_INT:
-				return Hibernate.INTEGER;
-			case NUM_FLOAT:
-				return Hibernate.FLOAT;
-			case NUM_LONG:
-				return Hibernate.LONG;
-			case NUM_DOUBLE:
-				return Hibernate.DOUBLE;
-			case QUOTED_STRING:
-				return Hibernate.STRING;
-			case TRUE:
-			case FALSE:
-				return Hibernate.BOOLEAN;
-			default:
-				return null;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/LiteralNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.Hibernate;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents a literal.
+ *
+ * @author josh
+ */
+public class LiteralNode extends AbstractSelectExpression implements HqlSqlTokenTypes {
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+	public Type getDataType() {
+		switch ( getType() ) {
+			case NUM_INT:
+				return Hibernate.INTEGER;
+			case NUM_FLOAT:
+				return Hibernate.FLOAT;
+			case NUM_LONG:
+				return Hibernate.LONG;
+			case NUM_DOUBLE:
+				return Hibernate.DOUBLE;
+			case QUOTED_STRING:
+				return Hibernate.STRING;
+			case TRUE:
+			case FALSE:
+				return Hibernate.BOOLEAN;
+			default:
+				return null;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,190 +0,0 @@
-// $Id: MethodNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import java.util.Arrays;
-
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.persister.collection.CollectionPropertyNames;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Represents a method call.
- *
- * @author josh Aug 16, 2004 7:59:42 AM
- */
-public class MethodNode extends AbstractSelectExpression implements SelectExpression {
-
-	private static final Logger log = LoggerFactory.getLogger( MethodNode.class );
-
-	private String methodName;
-	private FromElement fromElement;
-	private String[] selectColumns;
-	private SQLFunction function;
-	private boolean inSelect;
-
-	public void resolve(boolean inSelect) throws SemanticException {
-		// Get the function name node.
-		AST name = getFirstChild();
-		initializeMethodNode( name, inSelect );
-		AST exprList = name.getNextSibling();
-		// If the expression list has exactly one expression, and the type of the expression is a collection
-		// then this might be a collection function, such as index(c) or size(c).
-		if ( ASTUtil.hasExactlyOneChild( exprList ) && isCollectionPropertyMethod() ) {
-			collectionProperty( exprList.getFirstChild(), name );
-		}
-		else {
-			dialectFunction( exprList );
-		}
-	}
-
-	public SQLFunction getSQLFunction() {
-		return function;
-	}
-
-	private void dialectFunction(AST exprList) {
-		function = getSessionFactoryHelper().findSQLFunction( methodName );
-		if ( function != null ) {
-			AST firstChild = exprList != null ? exprList.getFirstChild() : null;
-			Type functionReturnType = getSessionFactoryHelper()
-					.findFunctionReturnType( methodName, firstChild );
-			setDataType( functionReturnType );
-		}
-		//TODO:
-		/*else {
-			methodName = (String) getWalker().getTokenReplacements().get( methodName );
-		}*/
-	}
-
-	public boolean isCollectionPropertyMethod() {
-		return CollectionProperties.isAnyCollectionProperty( methodName );
-	}
-
-	public void initializeMethodNode(AST name, boolean inSelect) {
-		name.setType( SqlTokenTypes.METHOD_NAME );
-		String text = name.getText();
-		methodName = text.toLowerCase();	// Use the lower case function name.
-		this.inSelect = inSelect;			// Remember whether we're in a SELECT clause or not.
-	}
-
-	private String getMethodName() {
-		return methodName;
-	}
-
-	private void collectionProperty(AST path, AST name) throws SemanticException {
-		if ( path == null ) {
-			throw new SemanticException( "Collection function " + name.getText() + " has no path!" );
-		}
-
-		SqlNode expr = ( SqlNode ) path;
-		Type type = expr.getDataType();
-		if ( log.isDebugEnabled() ) {
-			log.debug( "collectionProperty() :  name=" + name + " type=" + type );
-		}
-
-		resolveCollectionProperty( expr );
-	}
-
-	public boolean isScalar() throws SemanticException {
-		// Method expressions in a SELECT should always be considered scalar.
-		return true;
-	}
-
-	public void resolveCollectionProperty(AST expr) throws SemanticException {
-		String propertyName = CollectionProperties.getNormalizedPropertyName( getMethodName() );
-		if ( expr instanceof FromReferenceNode ) {
-			FromReferenceNode collectionNode = ( FromReferenceNode ) expr;
-			// If this is 'elements' then create a new FROM element.
-			if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( propertyName ) ) {
-				handleElements( collectionNode, propertyName );
-			}
-			else {
-				// Not elements(x)
-				fromElement = collectionNode.getFromElement();
-				setDataType( fromElement.getPropertyType( propertyName, propertyName ) );
-				selectColumns = fromElement.toColumns( fromElement.getTableAlias(), propertyName, inSelect );
-			}
-			if ( collectionNode instanceof DotNode ) {
-				prepareAnyImplicitJoins( ( DotNode ) collectionNode );
-			}
-			if ( !inSelect ) {
-				fromElement.setText( "" );
-				fromElement.setUseWhereFragment( false );
-			}
-			prepareSelectColumns( selectColumns );
-			setText( selectColumns[0] );
-			setType( SqlTokenTypes.SQL_TOKEN );
-		}
-		else {
-			throw new SemanticException( 
-					"Unexpected expression " + expr + 
-					" found for collection function " + propertyName 
-				);
-		}
-	}
-
-	private void prepareAnyImplicitJoins(DotNode dotNode) throws SemanticException {
-		if ( dotNode.getLhs() instanceof DotNode ) {
-			DotNode lhs = ( DotNode ) dotNode.getLhs();
-			FromElement lhsOrigin = lhs.getFromElement();
-			if ( lhsOrigin != null && "".equals( lhsOrigin.getText() ) ) {
-				String lhsOriginText = lhsOrigin.getQueryable().getTableName() +
-				        " " + lhsOrigin.getTableAlias();
-				lhsOrigin.setText( lhsOriginText );
-			}
-			prepareAnyImplicitJoins( lhs );
-		}
-	}
-
-	private void handleElements(FromReferenceNode collectionNode, String propertyName) {
-		FromElement collectionFromElement = collectionNode.getFromElement();
-		QueryableCollection queryableCollection = collectionFromElement.getQueryableCollection();
-
-		String path = collectionNode.getPath() + "[]." + propertyName;
-		log.debug( "Creating elements for " + path );
-
-		fromElement = collectionFromElement;
-		if ( !collectionFromElement.isCollectionOfValuesOrComponents() ) {
-			getWalker().addQuerySpaces( queryableCollection.getElementPersister().getQuerySpaces() );
-		}
-
-		setDataType( queryableCollection.getElementType() );
-		selectColumns = collectionFromElement.toColumns( fromElement.getTableAlias(), propertyName, inSelect );
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		if ( selectColumns == null ) { 	// Dialect function
-			ColumnHelper.generateSingleScalarColumn( this, i );
-		}
-		else {	// Collection 'property function'
-			ColumnHelper.generateScalarColumns( this, selectColumns, i );
-		}
-	}
-
-	protected void prepareSelectColumns(String[] columns) {
-		return;
-	}
-
-	public FromElement getFromElement() {
-		return fromElement;
-	}
-
-	public String getDisplayText() {
-		return "{" +
-				"method=" + getMethodName() +
-				",selectColumns=" + ( selectColumns == null ? 
-						null : Arrays.asList( selectColumns ) ) +
-				",fromElement=" + fromElement.getTableAlias() +
-				"}";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/MethodNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,213 @@
+/*
+ * 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.tree;
+
+import java.util.Arrays;
+
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.persister.collection.CollectionPropertyNames;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Represents a method call.
+ *
+ * @author josh
+ */
+public class MethodNode extends AbstractSelectExpression implements SelectExpression {
+
+	private static final Logger log = LoggerFactory.getLogger( MethodNode.class );
+
+	private String methodName;
+	private FromElement fromElement;
+	private String[] selectColumns;
+	private SQLFunction function;
+	private boolean inSelect;
+
+	public void resolve(boolean inSelect) throws SemanticException {
+		// Get the function name node.
+		AST name = getFirstChild();
+		initializeMethodNode( name, inSelect );
+		AST exprList = name.getNextSibling();
+		// If the expression list has exactly one expression, and the type of the expression is a collection
+		// then this might be a collection function, such as index(c) or size(c).
+		if ( ASTUtil.hasExactlyOneChild( exprList ) && isCollectionPropertyMethod() ) {
+			collectionProperty( exprList.getFirstChild(), name );
+		}
+		else {
+			dialectFunction( exprList );
+		}
+	}
+
+	public SQLFunction getSQLFunction() {
+		return function;
+	}
+
+	private void dialectFunction(AST exprList) {
+		function = getSessionFactoryHelper().findSQLFunction( methodName );
+		if ( function != null ) {
+			AST firstChild = exprList != null ? exprList.getFirstChild() : null;
+			Type functionReturnType = getSessionFactoryHelper()
+					.findFunctionReturnType( methodName, firstChild );
+			setDataType( functionReturnType );
+		}
+		//TODO:
+		/*else {
+			methodName = (String) getWalker().getTokenReplacements().get( methodName );
+		}*/
+	}
+
+	public boolean isCollectionPropertyMethod() {
+		return CollectionProperties.isAnyCollectionProperty( methodName );
+	}
+
+	public void initializeMethodNode(AST name, boolean inSelect) {
+		name.setType( SqlTokenTypes.METHOD_NAME );
+		String text = name.getText();
+		methodName = text.toLowerCase();	// Use the lower case function name.
+		this.inSelect = inSelect;			// Remember whether we're in a SELECT clause or not.
+	}
+
+	private String getMethodName() {
+		return methodName;
+	}
+
+	private void collectionProperty(AST path, AST name) throws SemanticException {
+		if ( path == null ) {
+			throw new SemanticException( "Collection function " + name.getText() + " has no path!" );
+		}
+
+		SqlNode expr = ( SqlNode ) path;
+		Type type = expr.getDataType();
+		if ( log.isDebugEnabled() ) {
+			log.debug( "collectionProperty() :  name=" + name + " type=" + type );
+		}
+
+		resolveCollectionProperty( expr );
+	}
+
+	public boolean isScalar() throws SemanticException {
+		// Method expressions in a SELECT should always be considered scalar.
+		return true;
+	}
+
+	public void resolveCollectionProperty(AST expr) throws SemanticException {
+		String propertyName = CollectionProperties.getNormalizedPropertyName( getMethodName() );
+		if ( expr instanceof FromReferenceNode ) {
+			FromReferenceNode collectionNode = ( FromReferenceNode ) expr;
+			// If this is 'elements' then create a new FROM element.
+			if ( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( propertyName ) ) {
+				handleElements( collectionNode, propertyName );
+			}
+			else {
+				// Not elements(x)
+				fromElement = collectionNode.getFromElement();
+				setDataType( fromElement.getPropertyType( propertyName, propertyName ) );
+				selectColumns = fromElement.toColumns( fromElement.getTableAlias(), propertyName, inSelect );
+			}
+			if ( collectionNode instanceof DotNode ) {
+				prepareAnyImplicitJoins( ( DotNode ) collectionNode );
+			}
+			if ( !inSelect ) {
+				fromElement.setText( "" );
+				fromElement.setUseWhereFragment( false );
+			}
+			prepareSelectColumns( selectColumns );
+			setText( selectColumns[0] );
+			setType( SqlTokenTypes.SQL_TOKEN );
+		}
+		else {
+			throw new SemanticException( 
+					"Unexpected expression " + expr + 
+					" found for collection function " + propertyName 
+				);
+		}
+	}
+
+	private void prepareAnyImplicitJoins(DotNode dotNode) throws SemanticException {
+		if ( dotNode.getLhs() instanceof DotNode ) {
+			DotNode lhs = ( DotNode ) dotNode.getLhs();
+			FromElement lhsOrigin = lhs.getFromElement();
+			if ( lhsOrigin != null && "".equals( lhsOrigin.getText() ) ) {
+				String lhsOriginText = lhsOrigin.getQueryable().getTableName() +
+				        " " + lhsOrigin.getTableAlias();
+				lhsOrigin.setText( lhsOriginText );
+			}
+			prepareAnyImplicitJoins( lhs );
+		}
+	}
+
+	private void handleElements(FromReferenceNode collectionNode, String propertyName) {
+		FromElement collectionFromElement = collectionNode.getFromElement();
+		QueryableCollection queryableCollection = collectionFromElement.getQueryableCollection();
+
+		String path = collectionNode.getPath() + "[]." + propertyName;
+		log.debug( "Creating elements for " + path );
+
+		fromElement = collectionFromElement;
+		if ( !collectionFromElement.isCollectionOfValuesOrComponents() ) {
+			getWalker().addQuerySpaces( queryableCollection.getElementPersister().getQuerySpaces() );
+		}
+
+		setDataType( queryableCollection.getElementType() );
+		selectColumns = collectionFromElement.toColumns( fromElement.getTableAlias(), propertyName, inSelect );
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		if ( selectColumns == null ) { 	// Dialect function
+			ColumnHelper.generateSingleScalarColumn( this, i );
+		}
+		else {	// Collection 'property function'
+			ColumnHelper.generateScalarColumns( this, selectColumns, i );
+		}
+	}
+
+	protected void prepareSelectColumns(String[] columns) {
+		return;
+	}
+
+	public FromElement getFromElement() {
+		return fromElement;
+	}
+
+	public String getDisplayText() {
+		return "{" +
+				"method=" + getMethodName() +
+				",selectColumns=" + ( selectColumns == null ? 
+						null : Arrays.asList( selectColumns ) ) +
+				",fromElement=" + fromElement.getTableAlias() +
+				"}";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Node.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import antlr.collections.AST;
-import antlr.Token;
-import org.hibernate.util.StringHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Base node class for use by Hibernate within its AST trees.
- *
- * @author Joshua Davis
- * @author Steve Ebersole
- */
-public class Node extends antlr.CommonAST {
-	private String filename;
-	private int line;
-	private int column;
-	private int textLength;
-
-	public Node() {
-		super();
-	}
-
-	public Node(Token tok) {
-		super(tok);  // This will call initialize(tok)!
-	}
-
-	/**
-	 * Retrieve the text to be used for rendering this particular node.
-	 *
-	 * @param sessionFactory The session factory
-	 * @return The text to use for rendering
-	 */
-	public String getRenderText(SessionFactoryImplementor sessionFactory) {
-		// The basic implementation is to simply use the node's text
-		return getText();
-	}
-
-	public void initialize(Token tok) {
-		super.initialize(tok);
-		filename = tok.getFilename();
-		line = tok.getLine();
-		column = tok.getColumn();
-		String text = tok.getText();
-		textLength = StringHelper.isEmpty(text) ? 0 : text.length();
-	}
-
-	public void initialize(AST t) {
-		super.initialize( t );
-		if ( t instanceof Node ) {
-			Node n = (Node)t;
-			filename = n.filename;
-			line = n.line;
-			column = n.column;
-			textLength = n.textLength;
-		}
-	}
-
-	public String getFilename() {
-		return filename;
-	}
-
-	public int getLine() {
-		return line;
-	}
-
-	public int getColumn() {
-		return column;
-	}
-
-	public int getTextLength() {
-		return textLength;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Node.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Node.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import antlr.collections.AST;
+import antlr.Token;
+import org.hibernate.util.StringHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Base node class for use by Hibernate within its AST trees.
+ *
+ * @author Joshua Davis
+ * @author Steve Ebersole
+ */
+public class Node extends antlr.CommonAST {
+	private String filename;
+	private int line;
+	private int column;
+	private int textLength;
+
+	public Node() {
+		super();
+	}
+
+	public Node(Token tok) {
+		super(tok);  // This will call initialize(tok)!
+	}
+
+	/**
+	 * Retrieve the text to be used for rendering this particular node.
+	 *
+	 * @param sessionFactory The session factory
+	 * @return The text to use for rendering
+	 */
+	public String getRenderText(SessionFactoryImplementor sessionFactory) {
+		// The basic implementation is to simply use the node's text
+		return getText();
+	}
+
+	public void initialize(Token tok) {
+		super.initialize(tok);
+		filename = tok.getFilename();
+		line = tok.getLine();
+		column = tok.getColumn();
+		String text = tok.getText();
+		textLength = StringHelper.isEmpty(text) ? 0 : text.length();
+	}
+
+	public void initialize(AST t) {
+		super.initialize( t );
+		if ( t instanceof Node ) {
+			Node n = (Node)t;
+			filename = n.filename;
+			line = n.line;
+			column = n.column;
+			textLength = n.textLength;
+		}
+	}
+
+	public String getFilename() {
+		return filename;
+	}
+
+	public int getLine() {
+		return line;
+	}
+
+	public int getColumn() {
+		return column;
+	}
+
+	public int getTextLength() {
+		return textLength;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import antlr.SemanticException;
-
-/**
- * Contract for nodes representing operators (logic or arithmetic).
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public interface OperatorNode {
-	/**
-	 * Called by the tree walker during hql-sql semantic analysis
-	 * after the operator sub-tree is completely built.
-	 */
-	public abstract void initialize() throws SemanticException;
-
-	/**
-	 * Retrieves the data type for the overall operator expression.
-	 *
-	 * @return The expression's data type.
-	 */
-	public Type getDataType();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import antlr.SemanticException;
+
+/**
+ * Contract for nodes representing operators (logic or arithmetic).
+ *
+ * @author Steve Ebersole
+ */
+public interface OperatorNode {
+	/**
+	 * Called by the tree walker during hql-sql semantic analysis
+	 * after the operator sub-tree is completely built.
+	 */
+	public abstract void initialize() throws SemanticException;
+
+	/**
+	 * Retrieves the data type for the overall operator expression.
+	 *
+	 * @return The expression's data type.
+	 */
+	public Type getDataType();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-// $Id: OrderByClause.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-
-import antlr.collections.AST;
-
-/**
- * Implementation of OrderByClause.
- *
- * @author Steve Ebersole
- */
-public class OrderByClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes {
-
-	public void addOrderFragment(String orderByFragment) {
-		AST fragment = ASTUtil.create( getASTFactory(), SQL_TOKEN, orderByFragment );
-		if ( getFirstChild() == null ) {
-            setFirstChild( fragment );
-		}
-		else {
-			addChild( fragment );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/OrderByClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+
+import antlr.collections.AST;
+
+/**
+ * Implementation of OrderByClause.
+ *
+ * @author Steve Ebersole
+ */
+public class OrderByClause extends HqlSqlWalkerNode implements HqlSqlTokenTypes {
+
+	public void addOrderFragment(String orderByFragment) {
+		AST fragment = ASTUtil.create( getASTFactory(), SQL_TOKEN, orderByFragment );
+		if ( getFirstChild() == null ) {
+            setFirstChild( fragment );
+		}
+		else {
+			addChild( fragment );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-// $Id: ParameterNode.java 10060 2006-06-28 02:53:39Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Implementation of ParameterNode.
- *
- * @author Steve Ebersole
- */
-public class ParameterNode extends HqlSqlWalkerNode implements DisplayableNode, ExpectedTypeAwareNode {
-	private ParameterSpecification parameterSpecification;
-
-	public ParameterSpecification getHqlParameterSpecification() {
-		return parameterSpecification;
-	}
-
-	public void setHqlParameterSpecification(ParameterSpecification parameterSpecification) {
-		this.parameterSpecification = parameterSpecification;
-	}
-
-	public String getDisplayText() {
-		return "{" + ( parameterSpecification == null ? "???" : parameterSpecification.renderDisplayInfo() ) + "}";
-	}
-
-	public void setExpectedType(Type expectedType) {
-		getHqlParameterSpecification().setExpectedType( expectedType );
-		setDataType( expectedType );
-	}
-
-	public Type getExpectedType() {
-		return getHqlParameterSpecification() == null ? null : getHqlParameterSpecification().getExpectedType();
-	}
-
-	public String getRenderText(SessionFactoryImplementor sessionFactory) {
-		int count = 0;
-		if ( getExpectedType() != null && ( count = getExpectedType().getColumnSpan( sessionFactory ) ) > 1 ) {
-			StringBuffer buffer = new StringBuffer();
-			buffer.append( "(?" );
-			for ( int i = 1; i < count; i++ ) {
-				buffer.append( ", ?" );
-			}
-			buffer.append( ")" );
-			return buffer.toString();
-		}
-		else {
-			return "?";
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ParameterNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.tree;
+
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Implementation of ParameterNode.
+ *
+ * @author Steve Ebersole
+ */
+public class ParameterNode extends HqlSqlWalkerNode implements DisplayableNode, ExpectedTypeAwareNode {
+	private ParameterSpecification parameterSpecification;
+
+	public ParameterSpecification getHqlParameterSpecification() {
+		return parameterSpecification;
+	}
+
+	public void setHqlParameterSpecification(ParameterSpecification parameterSpecification) {
+		this.parameterSpecification = parameterSpecification;
+	}
+
+	public String getDisplayText() {
+		return "{" + ( parameterSpecification == null ? "???" : parameterSpecification.renderDisplayInfo() ) + "}";
+	}
+
+	public void setExpectedType(Type expectedType) {
+		getHqlParameterSpecification().setExpectedType( expectedType );
+		setDataType( expectedType );
+	}
+
+	public Type getExpectedType() {
+		return getHqlParameterSpecification() == null ? null : getHqlParameterSpecification().getExpectedType();
+	}
+
+	public String getRenderText(SessionFactoryImplementor sessionFactory) {
+		int count = 0;
+		if ( getExpectedType() != null && ( count = getExpectedType().getColumnSpan( sessionFactory ) ) > 1 ) {
+			StringBuffer buffer = new StringBuffer();
+			buffer.append( "(?" );
+			for ( int i = 1; i < count; i++ ) {
+				buffer.append( ", ?" );
+			}
+			buffer.append( ")" );
+			return buffer.toString();
+		}
+		else {
+			return "?";
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-// $Id: PathNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-/**
- * An AST node with a path property.  This path property will be the fully qualified name.
- *
- * @author josh Nov 7, 2004 10:56:49 AM
- */
-public interface PathNode {
-	/**
-	 * Returns the full path name represented by the node.
-	 *
-	 * @return the full path name represented by the node.
-	 */
-	String getPath();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/PathNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+/**
+ * An AST node with a path property.  This path property will be the fully qualified name.
+ *
+ * @author josh
+ */
+public interface PathNode {
+	/**
+	 * Returns the full path name represented by the node.
+	 *
+	 * @return the full path name represented by the node.
+	 */
+	String getPath();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,133 +0,0 @@
-// $Id: QueryNode.java 7486 2005-07-15 04:39:41Z oneovthafew $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Defines a top-level AST node representing an HQL select statement.
- *
- * @author Joshua Davis
- */
-public class QueryNode extends AbstractRestrictableStatement implements SelectExpression {
-
-	private static final Logger log = LoggerFactory.getLogger( QueryNode.class );
-
-	private OrderByClause orderByClause;
-
-	/**
-	 * @see Statement#getStatementType() 
-	 */
-	public int getStatementType() {
-		return HqlSqlTokenTypes.QUERY;
-	}
-
-	/**
-	 * @see Statement#needsExecutor()
-	 */
-	public boolean needsExecutor() {
-		return false;
-	}
-
-	protected int getWhereClauseParentTokenType() {
-		return SqlTokenTypes.FROM;
-	}
-
-	protected Logger getLog() {
-		return log;
-	}
-
-	/**
-	 * Locate the select clause that is part of this select statement.
-	 * </p>
-	 * Note, that this might return null as derived select clauses (i.e., no
-	 * select clause at the HQL-level) get generated much later than when we
-	 * get created; thus it depends upon lifecycle.
-	 *
-	 * @return Our select clause, or null.
-	 */
-	public final SelectClause getSelectClause() {
-		// Due to the complexity in initializing the SelectClause, do not generate one here.
-		// If it is not found; simply return null...
-		//
-		// Also, do not cache since it gets generated well after we are created.
-		return ( SelectClause ) ASTUtil.findTypeInChildren( this, SqlTokenTypes.SELECT_CLAUSE );
-	}
-
-	public final boolean hasOrderByClause() {
-		OrderByClause orderByClause = locateOrderByClause();
-		return orderByClause != null && orderByClause.getNumberOfChildren() > 0;
-	}
-
-	public final OrderByClause getOrderByClause() {
-		if ( orderByClause == null ) {
-			orderByClause = locateOrderByClause();
-
-			// if there is no order by, make one
-			if ( orderByClause == null ) {
-				log.debug( "getOrderByClause() : Creating a new ORDER BY clause" );
-				orderByClause = ( OrderByClause ) ASTUtil.create( getWalker().getASTFactory(), SqlTokenTypes.ORDER, "ORDER" );
-
-				// Find the WHERE; if there is no WHERE, find the FROM...
-				AST prevSibling = ASTUtil.findTypeInChildren( this, SqlTokenTypes.WHERE );
-				if ( prevSibling == null ) {
-					prevSibling = ASTUtil.findTypeInChildren( this, SqlTokenTypes.FROM );
-				}
-
-				// Now, inject the newly built ORDER BY into the tree
-				orderByClause.setNextSibling( prevSibling.getNextSibling() );
-				prevSibling.setNextSibling( orderByClause );
-			}
-		}
-		return orderByClause;
-	}
-
-	private OrderByClause locateOrderByClause() {
-		return ( OrderByClause ) ASTUtil.findTypeInChildren( this, SqlTokenTypes.ORDER );
-	}
-	
-	
-	private String alias;
-
-	public String getAlias() {
-		return alias;
-	}
-
-	public FromElement getFromElement() {
-		return null;
-	}
-
-	public boolean isConstructor() {
-		return false;
-	}
-
-	public boolean isReturnableEntity() throws SemanticException {
-		return false;
-	}
-
-	public boolean isScalar() throws SemanticException {
-		return true;
-	}
-
-	public void setAlias(String alias) {
-		this.alias = alias;
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-	public Type getDataType() {
-		return ( (SelectExpression) getSelectClause().getFirstSelectExpression() ).getDataType();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/QueryNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,156 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines a top-level AST node representing an HQL select statement.
+ *
+ * @author Joshua Davis
+ */
+public class QueryNode extends AbstractRestrictableStatement implements SelectExpression {
+
+	private static final Logger log = LoggerFactory.getLogger( QueryNode.class );
+
+	private OrderByClause orderByClause;
+
+	/**
+	 * @see Statement#getStatementType() 
+	 */
+	public int getStatementType() {
+		return HqlSqlTokenTypes.QUERY;
+	}
+
+	/**
+	 * @see Statement#needsExecutor()
+	 */
+	public boolean needsExecutor() {
+		return false;
+	}
+
+	protected int getWhereClauseParentTokenType() {
+		return SqlTokenTypes.FROM;
+	}
+
+	protected Logger getLog() {
+		return log;
+	}
+
+	/**
+	 * Locate the select clause that is part of this select statement.
+	 * </p>
+	 * Note, that this might return null as derived select clauses (i.e., no
+	 * select clause at the HQL-level) get generated much later than when we
+	 * get created; thus it depends upon lifecycle.
+	 *
+	 * @return Our select clause, or null.
+	 */
+	public final SelectClause getSelectClause() {
+		// Due to the complexity in initializing the SelectClause, do not generate one here.
+		// If it is not found; simply return null...
+		//
+		// Also, do not cache since it gets generated well after we are created.
+		return ( SelectClause ) ASTUtil.findTypeInChildren( this, SqlTokenTypes.SELECT_CLAUSE );
+	}
+
+	public final boolean hasOrderByClause() {
+		OrderByClause orderByClause = locateOrderByClause();
+		return orderByClause != null && orderByClause.getNumberOfChildren() > 0;
+	}
+
+	public final OrderByClause getOrderByClause() {
+		if ( orderByClause == null ) {
+			orderByClause = locateOrderByClause();
+
+			// if there is no order by, make one
+			if ( orderByClause == null ) {
+				log.debug( "getOrderByClause() : Creating a new ORDER BY clause" );
+				orderByClause = ( OrderByClause ) ASTUtil.create( getWalker().getASTFactory(), SqlTokenTypes.ORDER, "ORDER" );
+
+				// Find the WHERE; if there is no WHERE, find the FROM...
+				AST prevSibling = ASTUtil.findTypeInChildren( this, SqlTokenTypes.WHERE );
+				if ( prevSibling == null ) {
+					prevSibling = ASTUtil.findTypeInChildren( this, SqlTokenTypes.FROM );
+				}
+
+				// Now, inject the newly built ORDER BY into the tree
+				orderByClause.setNextSibling( prevSibling.getNextSibling() );
+				prevSibling.setNextSibling( orderByClause );
+			}
+		}
+		return orderByClause;
+	}
+
+	private OrderByClause locateOrderByClause() {
+		return ( OrderByClause ) ASTUtil.findTypeInChildren( this, SqlTokenTypes.ORDER );
+	}
+	
+	
+	private String alias;
+
+	public String getAlias() {
+		return alias;
+	}
+
+	public FromElement getFromElement() {
+		return null;
+	}
+
+	public boolean isConstructor() {
+		return false;
+	}
+
+	public boolean isReturnableEntity() throws SemanticException {
+		return false;
+	}
+
+	public boolean isScalar() throws SemanticException {
+		return true;
+	}
+
+	public void setAlias(String alias) {
+		this.alias = alias;
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+	public Type getDataType() {
+		return ( (SelectExpression) getSelectClause().getFirstSelectExpression() ).getDataType();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-// $Id: ResolvableNode.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * The contract for expression sub-trees that can resolve themselves.
- *
- * @author josh Sep 25, 2004 11:27:36 AM
- */
-public interface ResolvableNode {
-	/**
-	 * Does the work of resolving an identifier or a dot
-	 */
-	void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) throws SemanticException;
-
-	/**
-	 * Does the work of resolving an identifier or a dot, but without a parent node
-	 */
-	void resolve(boolean generateJoin, boolean implicitJoin, String classAlias) throws SemanticException;
-
-	/**
-	 * Does the work of resolving an identifier or a dot, but without a parent node or alias
-	 */
-	void resolve(boolean generateJoin, boolean implicitJoin) throws SemanticException;
-
-	/**
-	 * Does the work of resolving inside of the scope of a function call
-	 */
-	void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException;
-
-	/**
-	 * Does the work of resolving an an index [].
-	 */
-	void resolveIndex(AST parent) throws SemanticException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/ResolvableNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * The contract for expression sub-trees that can resolve themselves.
+ *
+ * @author josh
+ */
+public interface ResolvableNode {
+	/**
+	 * Does the work of resolving an identifier or a dot
+	 */
+	void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) throws SemanticException;
+
+	/**
+	 * Does the work of resolving an identifier or a dot, but without a parent node
+	 */
+	void resolve(boolean generateJoin, boolean implicitJoin, String classAlias) throws SemanticException;
+
+	/**
+	 * Does the work of resolving an identifier or a dot, but without a parent node or alias
+	 */
+	void resolve(boolean generateJoin, boolean implicitJoin) throws SemanticException;
+
+	/**
+	 * Does the work of resolving inside of the scope of a function call
+	 */
+	void resolveInFunctionCall(boolean generateJoin, boolean implicitJoin) throws SemanticException;
+
+	/**
+	 * Does the work of resolving an an index [].
+	 */
+	void resolveIndex(AST parent) throws SemanticException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-// $Id: RestrictableStatement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import antlr.collections.AST;
-
-/**
- * Type definition for Statements which are restrictable via a where-clause (and
- * thus also having a from-clause).
- *
- * @author Steve Ebersole
- */
-public interface RestrictableStatement extends Statement {
-	/**
-	 * Retreives the from-clause in effect for this statement.
-	 *
-	 * @return The from-clause for this statement; could be null if the from-clause
-	 * has not yet been parsed/generated.
-	 */
-	public FromClause getFromClause();
-
-	/**
-	 * Does this statement tree currently contain a where clause?
-	 *
-	 * @return True if a where-clause is found in the statement tree and
-	 * that where clause actually defines restrictions; false otherwise.
-	 */
-	public boolean hasWhereClause();
-
-	/**
-	 * Retreives the where-clause defining the restriction(s) in effect for
-	 * this statement.
-	 * <p/>
-	 * Note that this will generate a where-clause if one was not found, so caution
-	 * needs to taken prior to calling this that restrictions will actually exist
-	 * in the resulting statement tree (otherwise "unexpected end of subtree" errors
-	 * might occur during rendering).
-	 *
-	 * @return The where clause.
-	 */
-	public AST getWhereClause();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/RestrictableStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import antlr.collections.AST;
+
+/**
+ * Type definition for Statements which are restrictable via a where-clause (and
+ * thus also having a from-clause).
+ *
+ * @author Steve Ebersole
+ */
+public interface RestrictableStatement extends Statement {
+	/**
+	 * Retreives the from-clause in effect for this statement.
+	 *
+	 * @return The from-clause for this statement; could be null if the from-clause
+	 * has not yet been parsed/generated.
+	 */
+	public FromClause getFromClause();
+
+	/**
+	 * Does this statement tree currently contain a where clause?
+	 *
+	 * @return True if a where-clause is found in the statement tree and
+	 * that where clause actually defines restrictions; false otherwise.
+	 */
+	public boolean hasWhereClause();
+
+	/**
+	 * Retreives the where-clause defining the restriction(s) in effect for
+	 * this statement.
+	 * <p/>
+	 * Note that this will generate a where-clause if one was not found, so caution
+	 * needs to taken prior to calling this that restrictions will actually exist
+	 * in the resulting statement tree (otherwise "unexpected end of subtree" errors
+	 * might occur during rendering).
+	 *
+	 * @return The where clause.
+	 */
+	public AST getWhereClause();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,442 +0,0 @@
-// $Id: SelectClause.java 10527 2006-09-25 15:13:41Z epbernard $
-package org.hibernate.hql.ast.tree;
-
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTAppender;
-import org.hibernate.hql.ast.util.ASTIterator;
-import org.hibernate.hql.ast.util.ASTPrinter;
-import org.hibernate.hql.ast.QuerySyntaxException;
-import org.hibernate.type.Type;
-import org.hibernate.QueryException;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Represents the list of expressions in a SELECT clause.
- *
- * @author josh Sep 21, 2004 7:53:55 AM
- */
-public class SelectClause extends SelectExpressionList {
-
-	private boolean prepared = false;
-	private boolean scalarSelect;
-
-	private List fromElementsForLoad = new ArrayList();
-	//private Type[] sqlResultTypes;
-	private Type[] queryReturnTypes;
-	private String[][] columnNames;
-	private ConstructorNode constructorNode;
-	private List collectionFromElements;
-	private String[] aliases;
-
-	/**
-	 * Does this SelectClause represent a scalar query
-	 *
-	 * @return True if this is a scalara select clause; false otherwise.
-	 */
-	public boolean isScalarSelect() {
-		return scalarSelect;
-	}
-
-	public boolean isDistinct() {
-		return getFirstChild() != null && getFirstChild().getType() == SqlTokenTypes.DISTINCT;
-	}
-
-	/**
-	 * FromElements which need to be accounted for in the load phase (either for return or for fetch).
-	 *
-	 * @return List of appropriate FromElements.
-	 */
-	public List getFromElementsForLoad() {
-		return fromElementsForLoad;
-	}
-
-	/*
-	 * The types represented in the SQL result set.
-	 *
-	 * @return The types represented in the SQL result set.
-	 */
-	/*public Type[] getSqlResultTypes() {
-		return sqlResultTypes;
-	}*/
-
-	/**
-	 * The types actually being returned from this query at the "object level".
-	 *
-	 * @return The query return types.
-	 */
-	public Type[] getQueryReturnTypes() {
-		return queryReturnTypes;
-	}
-	
-	/**
-	 * The HQL aliases, or generated aliases
-	 */
-	public String[] getQueryReturnAliases() {
-		return aliases;
-	}
-
-	/**
-	 * The column alias names being used in the generated SQL.
-	 *
-	 * @return The SQL column aliases.
-	 */
-	public String[][] getColumnNames() {
-		return columnNames;
-	}
-
-	/**
-	 * The constructor to use for dynamic instantiation queries.
-	 *
-	 * @return The appropriate Constructor reference, or null if not a
-	 *         dynamic instantiation query.
-	 */
-	public Constructor getConstructor() {
-		return constructorNode == null ? null : constructorNode.getConstructor();
-	}
-	
-	public boolean isMap() {
-		return constructorNode == null ? false : constructorNode.isMap();
-	}
-	
-	public boolean isList() {
-		return constructorNode == null ? false : constructorNode.isList();
-	}
-	
-	/**
-	 * Prepares an explicitly defined select clause.
-	 *
-	 * @param fromClause The from clause linked to this select clause.
-	 * @throws SemanticException
-	 */
-	public void initializeExplicitSelectClause(FromClause fromClause) throws SemanticException {
-		if ( prepared ) {
-			throw new IllegalStateException( "SelectClause was already prepared!" );
-		}
-
-		//explicit = true;	// This is an explict Select.
-		//ArrayList sqlResultTypeList = new ArrayList();
-		ArrayList queryReturnTypeList = new ArrayList();
-
-		// First, collect all of the select expressions.
-		// NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText()
-		// changes the AST!!!
-		SelectExpression[] selectExpressions = collectSelectExpressions();
-		
-		for ( int i = 0; i < selectExpressions.length; i++ ) {
-			SelectExpression expr = selectExpressions[i];
-
-			if ( expr.isConstructor() ) {
-				constructorNode = ( ConstructorNode ) expr;
-				List constructorArgumentTypeList = constructorNode.getConstructorArgumentTypeList();
-				//sqlResultTypeList.addAll( constructorArgumentTypeList );
-				queryReturnTypeList.addAll( constructorArgumentTypeList );
-				scalarSelect = true;
-			}
-			else {
-				Type type = expr.getDataType();
-				if ( type == null ) {
-					throw new IllegalStateException( "No data type for node: " + expr.getClass().getName() + " "
-							+ new ASTPrinter( SqlTokenTypes.class ).showAsString( ( AST ) expr, "" ) );
-				}
-				//sqlResultTypeList.add( type );
-
-				// If the data type is not an association type, it could not have been in the FROM clause.
-				if ( expr.isScalar() ) {
-					scalarSelect = true;
-				}
-
-				if ( isReturnableEntity( expr ) ) {
-					fromElementsForLoad.add( expr.getFromElement() );
-				}
-
-				// Always add the type to the return type list.
-				queryReturnTypeList.add( type );
-			}
-		}
-
-		//init the aliases, after initing the constructornode
-		initAliases(selectExpressions);
-
-		if ( !getWalker().isShallowQuery() ) {
-			// add the fetched entities
-			List fromElements = fromClause.getProjectionList();
-	
-			ASTAppender appender = new ASTAppender( getASTFactory(), this );	// Get ready to start adding nodes.
-			int size = fromElements.size();
-	
-			Iterator iterator = fromElements.iterator();
-			for ( int k = 0; iterator.hasNext(); k++ ) {
-				FromElement fromElement = ( FromElement ) iterator.next();
-	
-				if ( fromElement.isFetch() ) {
-					FromElement origin = null;
-					if ( fromElement.getRealOrigin() == null ) {
-						// work around that crazy issue where the tree contains
-						// "empty" FromElements (no text); afaict, this is caused
-						// by FromElementFactory.createCollectionJoin()
-						if ( fromElement.getOrigin() == null ) {
-							throw new QueryException( "Unable to determine origin of join fetch [" + fromElement.getDisplayText() + "]" );
-						}
-						else {
-							origin = fromElement.getOrigin();
-						}
-					}
-					else {
-						origin = fromElement.getRealOrigin();
-					}
-					if ( !fromElementsForLoad.contains( origin ) ) {
-						throw new QueryException(
-								"query specified join fetching, but the owner " +
-								"of the fetched association was not present in the select list " +
-								"[" + fromElement.getDisplayText() + "]"
-						);
-					}
-					Type type = fromElement.getSelectType();
-					addCollectionFromElement( fromElement );
-					if ( type != null ) {
-						boolean collectionOfElements = fromElement.isCollectionOfValuesOrComponents();
-						if ( !collectionOfElements ) {
-							// Add the type to the list of returned sqlResultTypes.
-							fromElement.setIncludeSubclasses( true );
-							fromElementsForLoad.add( fromElement );
-							//sqlResultTypeList.add( type );
-							// Generate the select expression.
-							String text = fromElement.renderIdentifierSelect( size, k );
-							SelectExpressionImpl generatedExpr = ( SelectExpressionImpl ) appender.append( SqlTokenTypes.SELECT_EXPR, text, false );
-							if ( generatedExpr != null ) {
-								generatedExpr.setFromElement( fromElement );
-							}
-						}
-					}
-				}
-			}
-	
-			// generate id select fragment and then property select fragment for
-			// each expression, just like generateSelectFragments().
-			renderNonScalarSelects( collectSelectExpressions(), fromClause );
-		}
-
-		if ( scalarSelect || getWalker().isShallowQuery() ) {
-			// If there are any scalars (non-entities) selected, render the select column aliases.
-			renderScalarSelects( selectExpressions, fromClause );
-		}
-
-		finishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList );
-	}
-
-	private void finishInitialization(/*ArrayList sqlResultTypeList,*/ ArrayList queryReturnTypeList) {
-		//sqlResultTypes = ( Type[] ) sqlResultTypeList.toArray( new Type[sqlResultTypeList.size()] );
-		queryReturnTypes = ( Type[] ) queryReturnTypeList.toArray( new Type[queryReturnTypeList.size()] );
-		initializeColumnNames();
-		prepared = true;
-	}
-
-	private void initializeColumnNames() {
-		// Generate an 2d array of column names, the first dimension is parallel with the
-		// return types array.  The second dimension is the list of column names for each
-		// type.
-
-		// todo: we should really just collect these from the various SelectExpressions, rather than regenerating here
-		columnNames = getSessionFactoryHelper().generateColumnNames( queryReturnTypes );
-	}
-
-	/**
-	 * Prepares a derived (i.e., not explicitly defined in the query) select clause.
-	 *
-	 * @param fromClause The from clause to which this select clause is linked.
-	 */
-	public void initializeDerivedSelectClause(FromClause fromClause) throws SemanticException {
-		if ( prepared ) {
-			throw new IllegalStateException( "SelectClause was already prepared!" );
-		}
-		//Used to be tested by the TCK but the test is no longer here
-//		if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && !getWalker().isSubQuery() ) {
-//			// NOTE : the isSubQuery() bit is a temporary hack...
-//			throw new QuerySyntaxException( "JPA-QL compliance requires select clause" );
-//		}
-		List fromElements = fromClause.getProjectionList();
-
-		ASTAppender appender = new ASTAppender( getASTFactory(), this );	// Get ready to start adding nodes.
-		int size = fromElements.size();
-		ArrayList sqlResultTypeList = new ArrayList( size );
-		ArrayList queryReturnTypeList = new ArrayList( size );
-
-		Iterator iterator = fromElements.iterator();
-		for ( int k = 0; iterator.hasNext(); k++ ) {
-			FromElement fromElement = ( FromElement ) iterator.next();
-			Type type = fromElement.getSelectType();
-
-			addCollectionFromElement( fromElement );
-
-			if ( type != null ) {
-				boolean collectionOfElements = fromElement.isCollectionOfValuesOrComponents();
-				if ( !collectionOfElements ) {
-					if ( !fromElement.isFetch() ) {
-						// Add the type to the list of returned sqlResultTypes.
-						queryReturnTypeList.add( type );
-					}
-					fromElementsForLoad.add( fromElement );
-					sqlResultTypeList.add( type );
-					// Generate the select expression.
-					String text = fromElement.renderIdentifierSelect( size, k );
-					SelectExpressionImpl generatedExpr = ( SelectExpressionImpl ) appender.append( SqlTokenTypes.SELECT_EXPR, text, false );
-					if ( generatedExpr != null ) {
-						generatedExpr.setFromElement( fromElement );
-					}
-				}
-			}
-		}
-
-		// Get all the select expressions (that we just generated) and render the select.
-		SelectExpression[] selectExpressions = collectSelectExpressions();
-
-		if ( getWalker().isShallowQuery() ) {
-			renderScalarSelects( selectExpressions, fromClause );
-		}
-		else {
-			renderNonScalarSelects( selectExpressions, fromClause );
-		}
-		finishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList );
-	}
-	
-	public static boolean VERSION2_SQL = false;
-
-	private void addCollectionFromElement(FromElement fromElement) {
-		if ( fromElement.isFetch() ) {
-			if ( fromElement.isCollectionJoin() || fromElement.getQueryableCollection() != null ) {
-				String suffix;
-				if (collectionFromElements==null) {
-					collectionFromElements = new ArrayList();
-					suffix = VERSION2_SQL ? "__" : "0__";
-				}
-				else {
-					suffix = Integer.toString( collectionFromElements.size() ) + "__";
-				}
-				collectionFromElements.add( fromElement );
-				fromElement.setCollectionSuffix( suffix );
-			}
-		}
-	}
-
-	protected AST getFirstSelectExpression() {
-		AST n = getFirstChild();
-		// Skip 'DISTINCT' and 'ALL', so we return the first expression node.
-		while ( n != null && ( n.getType() == SqlTokenTypes.DISTINCT || n.getType() == SqlTokenTypes.ALL ) ) {
-			n = n.getNextSibling();
-		}
-		return n;
-	}
-
-	private boolean isReturnableEntity(SelectExpression selectExpression) throws SemanticException {
-		FromElement fromElement = selectExpression.getFromElement();
-		boolean isFetchOrValueCollection = fromElement != null && 
-				( fromElement.isFetch() || fromElement.isCollectionOfValuesOrComponents() ); 
-		if ( isFetchOrValueCollection ) {
-			return false;
-		}
-		else {
-			return selectExpression.isReturnableEntity();
-		}
-	}
-
-	private void renderScalarSelects(SelectExpression[] se, FromClause currentFromClause) throws SemanticException {
-		if ( !currentFromClause.isSubQuery() ) {
-			for ( int i = 0; i < se.length; i++ ) {
-				SelectExpression expr = se[i];
-				expr.setScalarColumnText( i );	// Create SQL_TOKEN nodes for the columns.
-			}
-		}
-	}
-	
-	private void initAliases(SelectExpression[] selectExpressions) {
-		if (constructorNode==null) {
-			aliases = new String[selectExpressions.length];
-			for ( int i=0; i<selectExpressions.length; i++ ) {
-				String alias = selectExpressions[i].getAlias();
-				aliases[i] = alias==null ? Integer.toString(i) : alias;
-			}
-		}
-		else {
-			aliases = constructorNode.getAliases();
-		}
-	}
-
-	private void renderNonScalarSelects(SelectExpression[] selectExpressions, FromClause currentFromClause) 
-	throws SemanticException {
-		ASTAppender appender = new ASTAppender( getASTFactory(), this );
-		final int size = selectExpressions.length;
-		int nonscalarSize = 0;
-		for ( int i = 0; i < size; i++ ) {
-			if ( !selectExpressions[i].isScalar() ) nonscalarSize++;
-		}
-
-		int j = 0;
-		for ( int i = 0; i < size; i++ ) {
-			if ( !selectExpressions[i].isScalar() ) {
-				SelectExpression expr = selectExpressions[i];
-				FromElement fromElement = expr.getFromElement();
-				if ( fromElement != null ) {
-					renderNonScalarIdentifiers( fromElement, nonscalarSize, j, expr, appender );
-					j++;
-				}
-			}
-		}
-
-		if ( !currentFromClause.isSubQuery() ) {
-			// Generate the property select tokens.
-			int k = 0;
-			for ( int i = 0; i < size; i++ ) {
-				if ( !selectExpressions[i].isScalar() ) {
-					FromElement fromElement = selectExpressions[i].getFromElement();
-					if ( fromElement != null ) {
-						renderNonScalarProperties( appender, fromElement, nonscalarSize, k );
-						k++;
-					}
-				}
-			}
-		}
-	}
-
-	private void renderNonScalarIdentifiers(FromElement fromElement, int nonscalarSize, int j, SelectExpression expr, ASTAppender appender) {
-		String text = fromElement.renderIdentifierSelect( nonscalarSize, j );
-		if ( !fromElement.getFromClause().isSubQuery() ) {
-			if ( !scalarSelect && !getWalker().isShallowQuery() ) {
-				//TODO: is this a bit ugly?
-				expr.setText( text );
-			}
-			else {
-				appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
-			}
-		}
-	}
-
-	private void renderNonScalarProperties(ASTAppender appender, FromElement fromElement, int nonscalarSize, int k) {
-		String text = fromElement.renderPropertySelect( nonscalarSize, k );
-		appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
-		if ( fromElement.getQueryableCollection() != null && fromElement.isFetch() ) {
-			text = fromElement.renderCollectionSelectFragment( nonscalarSize, k );
-			appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
-		}
-		// Look through the FromElement's children to find any collections of values that should be fetched...
-		ASTIterator iter = new ASTIterator( fromElement );
-		while ( iter.hasNext() ) {
-			FromElement child = ( FromElement ) iter.next();
-			if ( child.isCollectionOfValuesOrComponents() && child.isFetch() ) {
-				// Need a better way to define the suffixes here...
-				text = child.renderValueCollectionSelectFragment( nonscalarSize, nonscalarSize + k );
-				appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
-			}
-		}
-	}
-
-	public List getCollectionFromElements() {
-		return collectionFromElements;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectClause.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,464 @@
+/*
+ * 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.tree;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTAppender;
+import org.hibernate.hql.ast.util.ASTIterator;
+import org.hibernate.hql.ast.util.ASTPrinter;
+import org.hibernate.type.Type;
+import org.hibernate.QueryException;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Represents the list of expressions in a SELECT clause.
+ *
+ * @author josh
+ */
+public class SelectClause extends SelectExpressionList {
+
+	private boolean prepared = false;
+	private boolean scalarSelect;
+
+	private List fromElementsForLoad = new ArrayList();
+	//private Type[] sqlResultTypes;
+	private Type[] queryReturnTypes;
+	private String[][] columnNames;
+	private ConstructorNode constructorNode;
+	private List collectionFromElements;
+	private String[] aliases;
+
+	/**
+	 * Does this SelectClause represent a scalar query
+	 *
+	 * @return True if this is a scalara select clause; false otherwise.
+	 */
+	public boolean isScalarSelect() {
+		return scalarSelect;
+	}
+
+	public boolean isDistinct() {
+		return getFirstChild() != null && getFirstChild().getType() == SqlTokenTypes.DISTINCT;
+	}
+
+	/**
+	 * FromElements which need to be accounted for in the load phase (either for return or for fetch).
+	 *
+	 * @return List of appropriate FromElements.
+	 */
+	public List getFromElementsForLoad() {
+		return fromElementsForLoad;
+	}
+
+	/*
+	 * The types represented in the SQL result set.
+	 *
+	 * @return The types represented in the SQL result set.
+	 */
+	/*public Type[] getSqlResultTypes() {
+		return sqlResultTypes;
+	}*/
+
+	/**
+	 * The types actually being returned from this query at the "object level".
+	 *
+	 * @return The query return types.
+	 */
+	public Type[] getQueryReturnTypes() {
+		return queryReturnTypes;
+	}
+	
+	/**
+	 * The HQL aliases, or generated aliases
+	 */
+	public String[] getQueryReturnAliases() {
+		return aliases;
+	}
+
+	/**
+	 * The column alias names being used in the generated SQL.
+	 *
+	 * @return The SQL column aliases.
+	 */
+	public String[][] getColumnNames() {
+		return columnNames;
+	}
+
+	/**
+	 * The constructor to use for dynamic instantiation queries.
+	 *
+	 * @return The appropriate Constructor reference, or null if not a
+	 *         dynamic instantiation query.
+	 */
+	public Constructor getConstructor() {
+		return constructorNode == null ? null : constructorNode.getConstructor();
+	}
+	
+	public boolean isMap() {
+		return constructorNode == null ? false : constructorNode.isMap();
+	}
+	
+	public boolean isList() {
+		return constructorNode == null ? false : constructorNode.isList();
+	}
+	
+	/**
+	 * Prepares an explicitly defined select clause.
+	 *
+	 * @param fromClause The from clause linked to this select clause.
+	 * @throws SemanticException
+	 */
+	public void initializeExplicitSelectClause(FromClause fromClause) throws SemanticException {
+		if ( prepared ) {
+			throw new IllegalStateException( "SelectClause was already prepared!" );
+		}
+
+		//explicit = true;	// This is an explict Select.
+		//ArrayList sqlResultTypeList = new ArrayList();
+		ArrayList queryReturnTypeList = new ArrayList();
+
+		// First, collect all of the select expressions.
+		// NOTE: This must be done *before* invoking setScalarColumnText() because setScalarColumnText()
+		// changes the AST!!!
+		SelectExpression[] selectExpressions = collectSelectExpressions();
+		
+		for ( int i = 0; i < selectExpressions.length; i++ ) {
+			SelectExpression expr = selectExpressions[i];
+
+			if ( expr.isConstructor() ) {
+				constructorNode = ( ConstructorNode ) expr;
+				List constructorArgumentTypeList = constructorNode.getConstructorArgumentTypeList();
+				//sqlResultTypeList.addAll( constructorArgumentTypeList );
+				queryReturnTypeList.addAll( constructorArgumentTypeList );
+				scalarSelect = true;
+			}
+			else {
+				Type type = expr.getDataType();
+				if ( type == null ) {
+					throw new IllegalStateException( "No data type for node: " + expr.getClass().getName() + " "
+							+ new ASTPrinter( SqlTokenTypes.class ).showAsString( ( AST ) expr, "" ) );
+				}
+				//sqlResultTypeList.add( type );
+
+				// If the data type is not an association type, it could not have been in the FROM clause.
+				if ( expr.isScalar() ) {
+					scalarSelect = true;
+				}
+
+				if ( isReturnableEntity( expr ) ) {
+					fromElementsForLoad.add( expr.getFromElement() );
+				}
+
+				// Always add the type to the return type list.
+				queryReturnTypeList.add( type );
+			}
+		}
+
+		//init the aliases, after initing the constructornode
+		initAliases(selectExpressions);
+
+		if ( !getWalker().isShallowQuery() ) {
+			// add the fetched entities
+			List fromElements = fromClause.getProjectionList();
+	
+			ASTAppender appender = new ASTAppender( getASTFactory(), this );	// Get ready to start adding nodes.
+			int size = fromElements.size();
+	
+			Iterator iterator = fromElements.iterator();
+			for ( int k = 0; iterator.hasNext(); k++ ) {
+				FromElement fromElement = ( FromElement ) iterator.next();
+	
+				if ( fromElement.isFetch() ) {
+					FromElement origin = null;
+					if ( fromElement.getRealOrigin() == null ) {
+						// work around that crazy issue where the tree contains
+						// "empty" FromElements (no text); afaict, this is caused
+						// by FromElementFactory.createCollectionJoin()
+						if ( fromElement.getOrigin() == null ) {
+							throw new QueryException( "Unable to determine origin of join fetch [" + fromElement.getDisplayText() + "]" );
+						}
+						else {
+							origin = fromElement.getOrigin();
+						}
+					}
+					else {
+						origin = fromElement.getRealOrigin();
+					}
+					if ( !fromElementsForLoad.contains( origin ) ) {
+						throw new QueryException(
+								"query specified join fetching, but the owner " +
+								"of the fetched association was not present in the select list " +
+								"[" + fromElement.getDisplayText() + "]"
+						);
+					}
+					Type type = fromElement.getSelectType();
+					addCollectionFromElement( fromElement );
+					if ( type != null ) {
+						boolean collectionOfElements = fromElement.isCollectionOfValuesOrComponents();
+						if ( !collectionOfElements ) {
+							// Add the type to the list of returned sqlResultTypes.
+							fromElement.setIncludeSubclasses( true );
+							fromElementsForLoad.add( fromElement );
+							//sqlResultTypeList.add( type );
+							// Generate the select expression.
+							String text = fromElement.renderIdentifierSelect( size, k );
+							SelectExpressionImpl generatedExpr = ( SelectExpressionImpl ) appender.append( SqlTokenTypes.SELECT_EXPR, text, false );
+							if ( generatedExpr != null ) {
+								generatedExpr.setFromElement( fromElement );
+							}
+						}
+					}
+				}
+			}
+	
+			// generate id select fragment and then property select fragment for
+			// each expression, just like generateSelectFragments().
+			renderNonScalarSelects( collectSelectExpressions(), fromClause );
+		}
+
+		if ( scalarSelect || getWalker().isShallowQuery() ) {
+			// If there are any scalars (non-entities) selected, render the select column aliases.
+			renderScalarSelects( selectExpressions, fromClause );
+		}
+
+		finishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList );
+	}
+
+	private void finishInitialization(/*ArrayList sqlResultTypeList,*/ ArrayList queryReturnTypeList) {
+		//sqlResultTypes = ( Type[] ) sqlResultTypeList.toArray( new Type[sqlResultTypeList.size()] );
+		queryReturnTypes = ( Type[] ) queryReturnTypeList.toArray( new Type[queryReturnTypeList.size()] );
+		initializeColumnNames();
+		prepared = true;
+	}
+
+	private void initializeColumnNames() {
+		// Generate an 2d array of column names, the first dimension is parallel with the
+		// return types array.  The second dimension is the list of column names for each
+		// type.
+
+		// todo: we should really just collect these from the various SelectExpressions, rather than regenerating here
+		columnNames = getSessionFactoryHelper().generateColumnNames( queryReturnTypes );
+	}
+
+	/**
+	 * Prepares a derived (i.e., not explicitly defined in the query) select clause.
+	 *
+	 * @param fromClause The from clause to which this select clause is linked.
+	 */
+	public void initializeDerivedSelectClause(FromClause fromClause) throws SemanticException {
+		if ( prepared ) {
+			throw new IllegalStateException( "SelectClause was already prepared!" );
+		}
+		//Used to be tested by the TCK but the test is no longer here
+//		if ( getSessionFactoryHelper().isStrictJPAQLComplianceEnabled() && !getWalker().isSubQuery() ) {
+//			// NOTE : the isSubQuery() bit is a temporary hack...
+//			throw new QuerySyntaxException( "JPA-QL compliance requires select clause" );
+//		}
+		List fromElements = fromClause.getProjectionList();
+
+		ASTAppender appender = new ASTAppender( getASTFactory(), this );	// Get ready to start adding nodes.
+		int size = fromElements.size();
+		ArrayList sqlResultTypeList = new ArrayList( size );
+		ArrayList queryReturnTypeList = new ArrayList( size );
+
+		Iterator iterator = fromElements.iterator();
+		for ( int k = 0; iterator.hasNext(); k++ ) {
+			FromElement fromElement = ( FromElement ) iterator.next();
+			Type type = fromElement.getSelectType();
+
+			addCollectionFromElement( fromElement );
+
+			if ( type != null ) {
+				boolean collectionOfElements = fromElement.isCollectionOfValuesOrComponents();
+				if ( !collectionOfElements ) {
+					if ( !fromElement.isFetch() ) {
+						// Add the type to the list of returned sqlResultTypes.
+						queryReturnTypeList.add( type );
+					}
+					fromElementsForLoad.add( fromElement );
+					sqlResultTypeList.add( type );
+					// Generate the select expression.
+					String text = fromElement.renderIdentifierSelect( size, k );
+					SelectExpressionImpl generatedExpr = ( SelectExpressionImpl ) appender.append( SqlTokenTypes.SELECT_EXPR, text, false );
+					if ( generatedExpr != null ) {
+						generatedExpr.setFromElement( fromElement );
+					}
+				}
+			}
+		}
+
+		// Get all the select expressions (that we just generated) and render the select.
+		SelectExpression[] selectExpressions = collectSelectExpressions();
+
+		if ( getWalker().isShallowQuery() ) {
+			renderScalarSelects( selectExpressions, fromClause );
+		}
+		else {
+			renderNonScalarSelects( selectExpressions, fromClause );
+		}
+		finishInitialization( /*sqlResultTypeList,*/ queryReturnTypeList );
+	}
+	
+	public static boolean VERSION2_SQL = false;
+
+	private void addCollectionFromElement(FromElement fromElement) {
+		if ( fromElement.isFetch() ) {
+			if ( fromElement.isCollectionJoin() || fromElement.getQueryableCollection() != null ) {
+				String suffix;
+				if (collectionFromElements==null) {
+					collectionFromElements = new ArrayList();
+					suffix = VERSION2_SQL ? "__" : "0__";
+				}
+				else {
+					suffix = Integer.toString( collectionFromElements.size() ) + "__";
+				}
+				collectionFromElements.add( fromElement );
+				fromElement.setCollectionSuffix( suffix );
+			}
+		}
+	}
+
+	protected AST getFirstSelectExpression() {
+		AST n = getFirstChild();
+		// Skip 'DISTINCT' and 'ALL', so we return the first expression node.
+		while ( n != null && ( n.getType() == SqlTokenTypes.DISTINCT || n.getType() == SqlTokenTypes.ALL ) ) {
+			n = n.getNextSibling();
+		}
+		return n;
+	}
+
+	private boolean isReturnableEntity(SelectExpression selectExpression) throws SemanticException {
+		FromElement fromElement = selectExpression.getFromElement();
+		boolean isFetchOrValueCollection = fromElement != null && 
+				( fromElement.isFetch() || fromElement.isCollectionOfValuesOrComponents() ); 
+		if ( isFetchOrValueCollection ) {
+			return false;
+		}
+		else {
+			return selectExpression.isReturnableEntity();
+		}
+	}
+
+	private void renderScalarSelects(SelectExpression[] se, FromClause currentFromClause) throws SemanticException {
+		if ( !currentFromClause.isSubQuery() ) {
+			for ( int i = 0; i < se.length; i++ ) {
+				SelectExpression expr = se[i];
+				expr.setScalarColumnText( i );	// Create SQL_TOKEN nodes for the columns.
+			}
+		}
+	}
+	
+	private void initAliases(SelectExpression[] selectExpressions) {
+		if (constructorNode==null) {
+			aliases = new String[selectExpressions.length];
+			for ( int i=0; i<selectExpressions.length; i++ ) {
+				String alias = selectExpressions[i].getAlias();
+				aliases[i] = alias==null ? Integer.toString(i) : alias;
+			}
+		}
+		else {
+			aliases = constructorNode.getAliases();
+		}
+	}
+
+	private void renderNonScalarSelects(SelectExpression[] selectExpressions, FromClause currentFromClause) 
+	throws SemanticException {
+		ASTAppender appender = new ASTAppender( getASTFactory(), this );
+		final int size = selectExpressions.length;
+		int nonscalarSize = 0;
+		for ( int i = 0; i < size; i++ ) {
+			if ( !selectExpressions[i].isScalar() ) nonscalarSize++;
+		}
+
+		int j = 0;
+		for ( int i = 0; i < size; i++ ) {
+			if ( !selectExpressions[i].isScalar() ) {
+				SelectExpression expr = selectExpressions[i];
+				FromElement fromElement = expr.getFromElement();
+				if ( fromElement != null ) {
+					renderNonScalarIdentifiers( fromElement, nonscalarSize, j, expr, appender );
+					j++;
+				}
+			}
+		}
+
+		if ( !currentFromClause.isSubQuery() ) {
+			// Generate the property select tokens.
+			int k = 0;
+			for ( int i = 0; i < size; i++ ) {
+				if ( !selectExpressions[i].isScalar() ) {
+					FromElement fromElement = selectExpressions[i].getFromElement();
+					if ( fromElement != null ) {
+						renderNonScalarProperties( appender, fromElement, nonscalarSize, k );
+						k++;
+					}
+				}
+			}
+		}
+	}
+
+	private void renderNonScalarIdentifiers(FromElement fromElement, int nonscalarSize, int j, SelectExpression expr, ASTAppender appender) {
+		String text = fromElement.renderIdentifierSelect( nonscalarSize, j );
+		if ( !fromElement.getFromClause().isSubQuery() ) {
+			if ( !scalarSelect && !getWalker().isShallowQuery() ) {
+				//TODO: is this a bit ugly?
+				expr.setText( text );
+			}
+			else {
+				appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
+			}
+		}
+	}
+
+	private void renderNonScalarProperties(ASTAppender appender, FromElement fromElement, int nonscalarSize, int k) {
+		String text = fromElement.renderPropertySelect( nonscalarSize, k );
+		appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
+		if ( fromElement.getQueryableCollection() != null && fromElement.isFetch() ) {
+			text = fromElement.renderCollectionSelectFragment( nonscalarSize, k );
+			appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
+		}
+		// Look through the FromElement's children to find any collections of values that should be fetched...
+		ASTIterator iter = new ASTIterator( fromElement );
+		while ( iter.hasNext() ) {
+			FromElement child = ( FromElement ) iter.next();
+			if ( child.isCollectionOfValuesOrComponents() && child.isFetch() ) {
+				// Need a better way to define the suffixes here...
+				text = child.renderValueCollectionSelectFragment( nonscalarSize, nonscalarSize + k );
+				appender.append( SqlTokenTypes.SQL_TOKEN, text, false );
+			}
+		}
+	}
+
+	public List getCollectionFromElements() {
+		return collectionFromElements;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-// $Id: SelectExpression.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-/**
- * Represents an element of a projection list, i.e. a select expression.
- *
- * @author josh Sep 21, 2004 9:00:13 PM
- */
-public interface SelectExpression {
-	/**
-	 * Returns the data type of the select expression.
-	 *
-	 * @return The data type of the select expression.
-	 */
-	Type getDataType();
-
-	/**
-	 * Appends AST nodes that represent the columns after the current AST node.
-	 * (e.g. 'as col0_O_')
-	 *
-	 * @param i The index of the select expression in the projection list.
-	 */
-	void setScalarColumnText(int i) throws SemanticException;
-
-	/**
-	 * Returns the FROM element that this expression refers to.
-	 *
-	 * @return The FROM element.
-	 */
-	FromElement getFromElement();
-
-	/**
-	 * Returns true if the element is a constructor (e.g. new Foo).
-	 *
-	 * @return true if the element is a constructor (e.g. new Foo).
-	 */
-	boolean isConstructor();
-
-	/**
-	 * Returns true if this select expression represents an entity that can be returned.
-	 *
-	 * @return true if this select expression represents an entity that can be returned.
-	 */
-	boolean isReturnableEntity() throws SemanticException;
-
-	/**
-	 * Sets the text of the node.
-	 *
-	 * @param text the new node text.
-	 */
-	void setText(String text);
-
-	boolean isScalar() throws SemanticException;
-	
-	void setAlias(String alias);
-	String getAlias();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpression.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+/**
+ * Represents an element of a projection list, i.e. a select expression.
+ *
+ * @author josh
+ */
+public interface SelectExpression {
+	/**
+	 * Returns the data type of the select expression.
+	 *
+	 * @return The data type of the select expression.
+	 */
+	Type getDataType();
+
+	/**
+	 * Appends AST nodes that represent the columns after the current AST node.
+	 * (e.g. 'as col0_O_')
+	 *
+	 * @param i The index of the select expression in the projection list.
+	 */
+	void setScalarColumnText(int i) throws SemanticException;
+
+	/**
+	 * Returns the FROM element that this expression refers to.
+	 *
+	 * @return The FROM element.
+	 */
+	FromElement getFromElement();
+
+	/**
+	 * Returns true if the element is a constructor (e.g. new Foo).
+	 *
+	 * @return true if the element is a constructor (e.g. new Foo).
+	 */
+	boolean isConstructor();
+
+	/**
+	 * Returns true if this select expression represents an entity that can be returned.
+	 *
+	 * @return true if this select expression represents an entity that can be returned.
+	 */
+	boolean isReturnableEntity() throws SemanticException;
+
+	/**
+	 * Sets the text of the node.
+	 *
+	 * @param text the new node text.
+	 */
+	void setText(String text);
+
+	boolean isScalar() throws SemanticException;
+	
+	void setAlias(String alias);
+	String getAlias();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-// $Id: SelectExpressionImpl.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * A select expression that was generated by a FROM element.
- *
- * @author josh Nov 6, 2004 8:27:38 AM
- */
-public class SelectExpressionImpl extends FromReferenceNode implements SelectExpression {
-
-	public void resolveIndex(AST parent) throws SemanticException {
-		throw new UnsupportedOperationException();
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		String text = getFromElement().renderScalarIdentifierSelect( i );
-		setText( text );
-	}
-
-	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) throws SemanticException {
-		// Generated select expressions are already resolved, nothing to do.
-		return;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.tree;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * A select expression that was generated by a FROM element.
+ *
+ * @author josh
+ */
+public class SelectExpressionImpl extends FromReferenceNode implements SelectExpression {
+
+	public void resolveIndex(AST parent) throws SemanticException {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		String text = getFromElement().renderScalarIdentifierSelect( i );
+		setText( text );
+	}
+
+	public void resolve(boolean generateJoin, boolean implicitJoin, String classAlias, AST parent) throws SemanticException {
+		// Generated select expressions are already resolved, nothing to do.
+		return;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-// $Id: SelectExpressionList.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import java.util.ArrayList;
-
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTPrinter;
-
-import antlr.collections.AST;
-
-/**
- * Common behavior - a node that contains a list of select expressions.
- *
- * @author josh Nov 6, 2004 8:51:00 AM
- */
-public abstract class SelectExpressionList extends HqlSqlWalkerNode {
-	/**
-	 * Returns an array of SelectExpressions gathered from the children of the given parent AST node.
-	 *
-	 * @return an array of SelectExpressions gathered from the children of the given parent AST node.
-	 */
-	public SelectExpression[] collectSelectExpressions() {
-		// Get the first child to be considered.  Sub-classes may do this differently in order to skip nodes that
-		// are not select expressions (e.g. DISTINCT).
-		AST firstChild = getFirstSelectExpression();
-		AST parent = this;
-		ArrayList list = new ArrayList( parent.getNumberOfChildren() );
-		for ( AST n = firstChild; n != null; n = n.getNextSibling() ) {
-			if ( n instanceof SelectExpression ) {
-				list.add( n );
-			}
-			else {
-				throw new IllegalStateException( "Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" ) );
-			}
-		}
-		return ( SelectExpression[] ) list.toArray( new SelectExpression[list.size()] );
-	}
-
-	/**
-	 * Returns the first select expression node that should be considered when building the array of select
-	 * expressions.
-	 *
-	 * @return the first select expression node that should be considered when building the array of select
-	 *         expressions
-	 */
-	protected abstract AST getFirstSelectExpression();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SelectExpressionList.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.tree;
+
+import java.util.ArrayList;
+
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTPrinter;
+
+import antlr.collections.AST;
+
+/**
+ * Common behavior - a node that contains a list of select expressions.
+ *
+ * @author josh
+ */
+public abstract class SelectExpressionList extends HqlSqlWalkerNode {
+	/**
+	 * Returns an array of SelectExpressions gathered from the children of the given parent AST node.
+	 *
+	 * @return an array of SelectExpressions gathered from the children of the given parent AST node.
+	 */
+	public SelectExpression[] collectSelectExpressions() {
+		// Get the first child to be considered.  Sub-classes may do this differently in order to skip nodes that
+		// are not select expressions (e.g. DISTINCT).
+		AST firstChild = getFirstSelectExpression();
+		AST parent = this;
+		ArrayList list = new ArrayList( parent.getNumberOfChildren() );
+		for ( AST n = firstChild; n != null; n = n.getNextSibling() ) {
+			if ( n instanceof SelectExpression ) {
+				list.add( n );
+			}
+			else {
+				throw new IllegalStateException( "Unexpected AST: " + n.getClass().getName() + " " + new ASTPrinter( SqlTokenTypes.class ).showAsString( n, "" ) );
+			}
+		}
+		return ( SelectExpression[] ) list.toArray( new SelectExpression[list.size()] );
+	}
+
+	/**
+	 * Returns the first select expression node that should be considered when building the array of select
+	 * expressions.
+	 *
+	 * @return the first select expression node that should be considered when building the array of select
+	 *         expressions
+	 */
+	protected abstract AST getFirstSelectExpression();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,12 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Interface for nodes which require access to the SessionFactory
- *
- * @author Steve Ebersole
- */
-public interface SessionFactoryAwareNode {
-	public void setSessionFactory(SessionFactoryImplementor sessionFactory);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SessionFactoryAwareNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Interface for nodes which require access to the SessionFactory
+ *
+ * @author Steve Ebersole
+ */
+public interface SessionFactoryAwareNode {
+	public void setSessionFactory(SessionFactoryImplementor sessionFactory);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,30 +0,0 @@
-// $Id: SqlFragment.java 8215 2005-09-23 16:51:56Z pgmjsd $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.sql.JoinFragment;
-
-/**
- * Represents an SQL fragment in the AST.
- *
- * @author josh Dec 5, 2004 9:01:52 AM
- */
-public class SqlFragment extends Node {
-	private JoinFragment joinFragment;
-	private FromElement fromElement;
-
-	public void setJoinFragment(JoinFragment joinFragment) {
-		this.joinFragment = joinFragment;
-	}
-
-	public boolean hasFilterCondition() {
-		return joinFragment.hasFilterCondition();
-	}
-
-	public void setFromElement(FromElement fromElement) {
-		this.fromElement = fromElement;
-	}
-
-	public FromElement getFromElement() {
-		return fromElement;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.sql.JoinFragment;
+
+/**
+ * Represents an SQL fragment in the AST.
+ *
+ * @author josh
+ */
+public class SqlFragment extends Node {
+	private JoinFragment joinFragment;
+	private FromElement fromElement;
+
+	public void setJoinFragment(JoinFragment joinFragment) {
+		this.joinFragment = joinFragment;
+	}
+
+	public boolean hasFilterCondition() {
+		return joinFragment.hasFilterCondition();
+	}
+
+	public void setFromElement(FromElement fromElement) {
+		this.fromElement = fromElement;
+	}
+
+	public FromElement getFromElement() {
+		return fromElement;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-// $Id: SqlNode.java 8215 2005-09-23 16:51:56Z pgmjsd $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-
-/**
- * A base AST node for the intermediate tree.
- * User: josh
- * Date: Dec 6, 2003
- * Time: 10:29:14 AM
- */
-public class SqlNode extends Node {
-	/**
-	 * The original text for the node, mostly for debugging.
-	 */
-	private String originalText;
-	/**
-	 * The data type of this node.  Null for 'no type'.
-	 */
-	private Type dataType;
-
-	public void setText(String s) {
-		super.setText( s );
-		if ( s != null && s.length() > 0 && originalText == null ) {
-			originalText = s;
-		}
-	}
-
-	public String getOriginalText() {
-		return originalText;
-	}
-
-	public Type getDataType() {
-		return dataType;
-	}
-
-	public void setDataType(Type dataType) {
-		this.dataType = dataType;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/SqlNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.type.Type;
+
+/**
+ * A base AST node for the intermediate tree.
+ * User: josh
+ * Date: Dec 6, 2003
+ * Time: 10:29:14 AM
+ */
+public class SqlNode extends Node {
+	/**
+	 * The original text for the node, mostly for debugging.
+	 */
+	private String originalText;
+	/**
+	 * The data type of this node.  Null for 'no type'.
+	 */
+	private Type dataType;
+
+	public void setText(String s) {
+		super.setText( s );
+		if ( s != null && s.length() > 0 && originalText == null ) {
+			originalText = s;
+		}
+	}
+
+	public String getOriginalText() {
+		return originalText;
+	}
+
+	public Type getDataType() {
+		return dataType;
+	}
+
+	public void setDataType(Type dataType) {
+		this.dataType = dataType;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-// $Id: Statement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.HqlSqlWalker;
-
-/**
- * Common interface modeling the different HQL statements (i.e., INSERT, UPDATE, DELETE, SELECT).
- *
- * @author Steve Ebersole
- */
-public interface Statement {
-
-	/**
-	 * Retreive the "phase 2" walker which generated this statement tree.
-	 *
-	 * @return The HqlSqlWalker instance which generated this statement tree.
-	 */
-	public HqlSqlWalker getWalker();
-
-	/**
-	 * Return the main token type representing the type of this statement.
-	 *
-	 * @return The corresponding token type.
-	 */
-	public int getStatementType();
-
-	/**
-	 * Does this statement require the StatementExecutor?
-	 * </p>
-	 * Essentially, at the JDBC level, does this require an executeUpdate()?
-	 *
-	 * @return True if this statement should be handed off to the
-	 * StatementExecutor to be executed; false otherwise.
-	 */
-	public boolean needsExecutor();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/Statement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+import org.hibernate.hql.ast.HqlSqlWalker;
+
+/**
+ * Common interface modeling the different HQL statements (i.e., INSERT, UPDATE, DELETE, SELECT).
+ *
+ * @author Steve Ebersole
+ */
+public interface Statement {
+
+	/**
+	 * Retreive the "phase 2" walker which generated this statement tree.
+	 *
+	 * @return The HqlSqlWalker instance which generated this statement tree.
+	 */
+	public HqlSqlWalker getWalker();
+
+	/**
+	 * Return the main token type representing the type of this statement.
+	 *
+	 * @return The corresponding token type.
+	 */
+	public int getStatementType();
+
+	/**
+	 * Does this statement require the StatementExecutor?
+	 * </p>
+	 * Essentially, at the JDBC level, does this require an executeUpdate()?
+	 *
+	 * @return True if this statement should be handed off to the
+	 * StatementExecutor to be executed; false otherwise.
+	 */
+	public boolean needsExecutor();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: UnaryArithmeticNode.java 8407 2005-10-14 17:23:18Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.ast.util.ColumnHelper;
-import org.hibernate.type.Type;
-
-import antlr.SemanticException;
-
-public class UnaryArithmeticNode extends AbstractSelectExpression implements UnaryOperatorNode {
-
-	public Type getDataType() {
-		return ( ( SqlNode ) getOperand() ).getDataType();
-	}
-
-	public void setScalarColumnText(int i) throws SemanticException {
-		ColumnHelper.generateSingleScalarColumn( this, i );
-	}
-
-	public void initialize() {
-		// nothing to do; even if the operand is a parameter, no way we could
-		// infer an appropriate expected type here
-	}
-
-	public Node getOperand() {
-		return ( Node ) getFirstChild();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryArithmeticNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+ *
+ */
+
+//$Id: UnaryArithmeticNode.java 8407 2005-10-14 17:23:18Z steveebersole $
+package org.hibernate.hql.ast.tree;
+
+import org.hibernate.hql.ast.util.ColumnHelper;
+import org.hibernate.type.Type;
+
+import antlr.SemanticException;
+
+public class UnaryArithmeticNode extends AbstractSelectExpression implements UnaryOperatorNode {
+
+	public Type getDataType() {
+		return ( ( SqlNode ) getOperand() ).getDataType();
+	}
+
+	public void setScalarColumnText(int i) throws SemanticException {
+		ColumnHelper.generateSingleScalarColumn( this, i );
+	}
+
+	public void initialize() {
+		// nothing to do; even if the operand is a parameter, no way we could
+		// infer an appropriate expected type here
+	}
+
+	public Node getOperand() {
+		return ( Node ) getFirstChild();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.type.Type;
-import org.hibernate.Hibernate;
-
-/**
- * Represents a unary operator node.
- *
- * @author Steve Ebersole
- */
-public class UnaryLogicOperatorNode extends HqlSqlWalkerNode implements UnaryOperatorNode {
-	public Node getOperand() {
-		return ( Node ) getFirstChild();
-	}
-
-	public void initialize() {
-		// nothing to do; even if the operand is a parameter, no way we could
-		// infer an appropriate expected type here
-	}
-
-	public Type getDataType() {
-		// logic operators by definition resolve to booleans
-		return Hibernate.BOOLEAN;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryLogicOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.tree;
+
+import org.hibernate.type.Type;
+import org.hibernate.Hibernate;
+
+/**
+ * Represents a unary operator node.
+ *
+ * @author Steve Ebersole
+ */
+public class UnaryLogicOperatorNode extends HqlSqlWalkerNode implements UnaryOperatorNode {
+	public Node getOperand() {
+		return ( Node ) getFirstChild();
+	}
+
+	public void initialize() {
+		// nothing to do; even if the operand is a parameter, no way we could
+		// infer an appropriate expected type here
+	}
+
+	public Type getDataType() {
+		// logic operators by definition resolve to booleans
+		return Hibernate.BOOLEAN;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-package org.hibernate.hql.ast.tree;
-
-/**
- * Contract for nodes representing unary operators.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public interface UnaryOperatorNode extends OperatorNode {
-	/**
-	 * Retrievs the node representing the operator's single operand.
-	 * 
-	 * @return The operator's single operand.
-	 */
-	public Node getOperand();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UnaryOperatorNode.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.tree;
+
+/**
+ * Contract for nodes representing unary operators.
+ *
+ * @author Steve Ebersole
+ */
+public interface UnaryOperatorNode extends OperatorNode {
+	/**
+	 * Retrievs the node representing the operator's single operand.
+	 * 
+	 * @return The operator's single operand.
+	 */
+	public Node getOperand();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +0,0 @@
-// $Id: UpdateStatement.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.tree;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.util.ASTUtil;
-
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Defines a top-level AST node representing an HQL update statement.
- *
- * @author Steve Ebersole
- */
-public class UpdateStatement extends AbstractRestrictableStatement {
-
-	private static final Logger log = LoggerFactory.getLogger( UpdateStatement.class );
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.Statement#getStatementType()
-	 */
-	public int getStatementType() {
-		return SqlTokenTypes.UPDATE;
-	}
-
-	/**
-	 * @see org.hibernate.hql.ast.tree.Statement#needsExecutor()
-	 */
-	public boolean needsExecutor() {
-		return true;
-	}
-
-	protected int getWhereClauseParentTokenType() {
-		return SqlTokenTypes.SET;
-	}
-
-	protected Logger getLog() {
-		return log;
-	}
-
-	public AST getSetClause() {
-		return ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.SET );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/tree/UpdateStatement.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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.tree;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.util.ASTUtil;
+
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Defines a top-level AST node representing an HQL update statement.
+ *
+ * @author Steve Ebersole
+ */
+public class UpdateStatement extends AbstractRestrictableStatement {
+
+	private static final Logger log = LoggerFactory.getLogger( UpdateStatement.class );
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.Statement#getStatementType()
+	 */
+	public int getStatementType() {
+		return SqlTokenTypes.UPDATE;
+	}
+
+	/**
+	 * @see org.hibernate.hql.ast.tree.Statement#needsExecutor()
+	 */
+	public boolean needsExecutor() {
+		return true;
+	}
+
+	protected int getWhereClauseParentTokenType() {
+		return SqlTokenTypes.SET;
+	}
+
+	protected Logger getLog() {
+		return log;
+	}
+
+	public AST getSetClause() {
+		return ASTUtil.findTypeInChildren( this, HqlSqlTokenTypes.SET );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-// $Id: ASTAppender.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-/**
- * Appends child nodes to a parent efficiently.
- *
- * @author josh Jul 24, 2004 8:28:23 AM
- */
-public class ASTAppender {
-	private AST parent;
-	private AST last;
-	private ASTFactory factory;
-
-	public ASTAppender(ASTFactory factory, AST parent) {
-		this( parent );
-		this.factory = factory;
-	}
-
-	public ASTAppender(AST parent) {
-		this.parent = parent;
-		this.last = ASTUtil.getLastChild( parent );
-	}
-
-	public AST append(int type, String text, boolean appendIfEmpty) {
-		if ( text != null && ( appendIfEmpty || text.length() > 0 ) ) {
-			return append( factory.create( type, text ) );
-		}
-		else {
-			return null;
-		}
-	}
-
-	public AST append(AST child) {
-		if ( last == null ) {
-			parent.setFirstChild( child );
-		}
-		else {
-			last.setNextSibling( child );
-		}
-		last = child;
-		return last;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTAppender.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.util;
+
+import antlr.ASTFactory;
+import antlr.collections.AST;
+
+/**
+ * Appends child nodes to a parent efficiently.
+ *
+ * @author Joshua Davis
+ */
+public class ASTAppender {
+	private AST parent;
+	private AST last;
+	private ASTFactory factory;
+
+	public ASTAppender(ASTFactory factory, AST parent) {
+		this( parent );
+		this.factory = factory;
+	}
+
+	public ASTAppender(AST parent) {
+		this.parent = parent;
+		this.last = ASTUtil.getLastChild( parent );
+	}
+
+	public AST append(int type, String text, boolean appendIfEmpty) {
+		if ( text != null && ( appendIfEmpty || text.length() > 0 ) ) {
+			return append( factory.create( type, text ) );
+		}
+		else {
+			return null;
+		}
+	}
+
+	public AST append(AST child) {
+		if ( last == null ) {
+			parent.setFirstChild( child );
+		}
+		else {
+			last.setNextSibling( child );
+		}
+		last = child;
+		return last;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,70 +0,0 @@
-// $Id: ASTIterator.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import antlr.collections.AST;
-
-/**
- * Depth first iteration of an ANTLR AST.
- *
- * @author josh Sep 25, 2004 7:44:39 AM
- */
-public class ASTIterator implements Iterator {
-	private AST next, current;
-	private LinkedList parents = new LinkedList();
-
-	public void remove() {
-		throw new UnsupportedOperationException( "remove() is not supported" );
-	}
-
-	public boolean hasNext() {
-		return next != null;
-	}
-
-	public Object next() {
-		return nextNode();
-	}
-
-	public ASTIterator(AST tree) {
-		next = tree;
-		down();
-	}
-
-	public AST nextNode() {
-		current = next;
-		if ( next != null ) {
-			AST nextSibling = next.getNextSibling();
-			if ( nextSibling == null ) {
-				next = pop();
-			}
-			else {
-				next = nextSibling;
-				down();
-			}
-		}
-		return current;
-	}
-
-	private void down() {
-		while ( next != null && next.getFirstChild() != null ) {
-			push( next );
-			next = next.getFirstChild();
-		}
-	}
-
-	private void push(AST parent) {
-		parents.addFirst( parent );
-	}
-
-	private AST pop() {
-		if ( parents.size() == 0 ) {
-			return null;
-		}
-		else {
-			return ( AST ) parents.removeFirst();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import antlr.collections.AST;
+
+/**
+ * Depth first iteration of an ANTLR AST.
+ *
+ * @author josh
+ */
+public class ASTIterator implements Iterator {
+	private AST next, current;
+	private LinkedList parents = new LinkedList();
+
+	public void remove() {
+		throw new UnsupportedOperationException( "remove() is not supported" );
+	}
+
+	public boolean hasNext() {
+		return next != null;
+	}
+
+	public Object next() {
+		return nextNode();
+	}
+
+	public ASTIterator(AST tree) {
+		next = tree;
+		down();
+	}
+
+	public AST nextNode() {
+		current = next;
+		if ( next != null ) {
+			AST nextSibling = next.getNextSibling();
+			if ( nextSibling == null ) {
+				next = pop();
+			}
+			else {
+				next = nextSibling;
+				down();
+			}
+		}
+		return current;
+	}
+
+	private void down() {
+		while ( next != null && next.getFirstChild() != null ) {
+			push( next );
+			next = next.getFirstChild();
+		}
+	}
+
+	private void push(AST parent) {
+		parents.addFirst( parent );
+	}
+
+	private AST pop() {
+		if ( parents.size() == 0 ) {
+			return null;
+		}
+		else {
+			return ( AST ) parents.removeFirst();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,73 +0,0 @@
-// $Id: ASTParentsFirstIterator.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-
-import antlr.collections.AST;
-
-/**
- * Depth first iteration of an ANTLR AST.
- *
- * @author josh Sep 25, 2004 7:44:39 AM
- */
-public class ASTParentsFirstIterator implements Iterator {
-	private AST next, current, tree;
-	private LinkedList parents = new LinkedList();
-
-	public void remove() {
-		throw new UnsupportedOperationException( "remove() is not supported" );
-	}
-
-	public boolean hasNext() {
-		return next != null;
-	}
-
-	public Object next() {
-		return nextNode();
-	}
-
-	public ASTParentsFirstIterator(AST tree) {
-		this.tree = next = tree;
-	}
-
-	public AST nextNode() {
-		current = next;
-		if ( next != null ) {
-			AST child = next.getFirstChild();
-			if ( child == null ) {
-				AST sibling = next.getNextSibling();
-				if ( sibling == null ) {
-					AST parent = pop();
-					while ( parent != null && parent.getNextSibling() == null )
-						parent = pop();
-					next = ( parent != null ) ? parent.getNextSibling() : null;
-				}
-				else {
-					next = sibling;
-				}
-			}
-			else {
-				if ( next != tree ) {
-					push( next );
-				}
-				next = child;
-			}
-		}
-		return current;
-	}
-
-	private void push(AST parent) {
-		parents.addFirst( parent );
-	}
-
-	private AST pop() {
-		if ( parents.size() == 0 ) {
-			return null;
-		}
-		else {
-			return ( AST ) parents.removeFirst();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTParentsFirstIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import antlr.collections.AST;
+
+/**
+ * Depth first iteration of an ANTLR AST.
+ *
+ * @author josh
+ */
+public class ASTParentsFirstIterator implements Iterator {
+	private AST next, current, tree;
+	private LinkedList parents = new LinkedList();
+
+	public void remove() {
+		throw new UnsupportedOperationException( "remove() is not supported" );
+	}
+
+	public boolean hasNext() {
+		return next != null;
+	}
+
+	public Object next() {
+		return nextNode();
+	}
+
+	public ASTParentsFirstIterator(AST tree) {
+		this.tree = next = tree;
+	}
+
+	public AST nextNode() {
+		current = next;
+		if ( next != null ) {
+			AST child = next.getFirstChild();
+			if ( child == null ) {
+				AST sibling = next.getNextSibling();
+				if ( sibling == null ) {
+					AST parent = pop();
+					while ( parent != null && parent.getNextSibling() == null )
+						parent = pop();
+					next = ( parent != null ) ? parent.getNextSibling() : null;
+				}
+				else {
+					next = sibling;
+				}
+			}
+			else {
+				if ( next != tree ) {
+					push( next );
+				}
+				next = child;
+			}
+		}
+		return current;
+	}
+
+	private void push(AST parent) {
+		parents.addFirst( parent );
+	}
+
+	private AST pop() {
+		if ( parents.size() == 0 ) {
+			return null;
+		}
+		else {
+			return ( AST ) parents.removeFirst();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,262 +0,0 @@
-// $Id: ASTPrinter.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.PrintStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.hql.ast.tree.DisplayableNode;
-import org.hibernate.util.StringHelper;
-
-import antlr.collections.AST;
-
-/**
- * An 'ASCII art' AST printer for debugging ANTLR grammars.
- *
- * @author Joshua Davis (pgmjsd at sourceforge.net)
- */
-public class ASTPrinter {
-	private Map tokenTypeNamesByTokenType;
-	private Class tokenTypeConstants;
-	private boolean showClassNames = true;
-
-	/**
-	 * Constructs an org.hibernate.hql.antlr.ASTPrinter, given the class that contains the token type
-	 * constants (typically the '{grammar}TokenTypes' interface generated by
-	 * ANTLR).
-	 *
-	 * @param tokenTypeConstants The class with token type constants in it.
-	 */
-	public ASTPrinter(Class tokenTypeConstants) {
-		this.tokenTypeConstants = tokenTypeConstants;
-	}
-
-	/**
-	 * Returns true if the node class names will be displayed.
-	 *
-	 * @return true if the node class names will be displayed.
-	 */
-	public boolean isShowClassNames() {
-		return showClassNames;
-	}
-
-	/**
-	 * Enables or disables AST node class name display.
-	 *
-	 * @param showClassNames true to enable class name display, false to disable
-	 */
-	public void setShowClassNames(boolean showClassNames) {
-		this.showClassNames = showClassNames;
-	}
-
-	/**
-	 * Prints the AST in 'ASCII art' tree form to the specified print stream.
-	 *
-	 * @param ast The AST to print.
-	 * @param out The print stream.
-	 */
-	private void showAst(AST ast, PrintStream out) {
-		showAst( ast, new PrintWriter( out ) );
-	}
-
-	/**
-	 * Prints the AST in 'ASCII art' tree form to the specified print writer.
-	 *
-	 * @param ast The AST to print.
-	 * @param pw  The print writer.
-	 */
-	public void showAst(AST ast, PrintWriter pw) {
-		ArrayList parents = new ArrayList();
-		showAst( parents, pw, ast );
-		pw.flush();
-	}
-
-	/**
-	 * Prints the AST in 'ASCII art' tree form into a string.
-	 *
-	 * @param ast    The AST to display.
-	 * @param header The header for the display.
-	 * @return The AST in 'ASCII art' form, as a string.
-	 */
-	public String showAsString(AST ast, String header) {
-		ByteArrayOutputStream baos = new ByteArrayOutputStream();
-		PrintStream ps = new PrintStream( baos );
-		ps.println( header );
-		showAst( ast, ps );
-		ps.flush();
-		return new String( baos.toByteArray() );
-	}
-
-	/**
-	 * Get a single token type name in the specified set of token type constants (interface).
-	 *
-	 * @param tokenTypeConstants Token type constants interface (e.g. HqlSqlTokenTypes.class).
-	 * @param type               The token type ( typically from ast.getType() ).
-	 * @return The token type name, *or* the integer value if the name could not be found for some reason.
-	 */
-	public static String getConstantName(Class tokenTypeConstants, int type) {
-		String tokenTypeName = null;
-		if ( tokenTypeConstants != null ) {
-			Field[] fields = tokenTypeConstants.getFields();
-			for ( int i = 0; i < fields.length; i++ ) {
-				Field field = fields[i];
-				tokenTypeName = getTokenTypeName( field, type, true );
-				if ( tokenTypeName != null ) {
-					break;	// Stop if found.
-				}
-			} // for
-		} // if type constants were provided
-
-		// Use the integer value if no token type name was found
-		if ( tokenTypeName == null ) {
-			tokenTypeName = Integer.toString( type );
-		}
-
-		return tokenTypeName;
-	}
-
-	private static String getTokenTypeName(Field field, int type, boolean checkType) {
-		if ( Modifier.isStatic( field.getModifiers() ) ) {
-			try {
-				Object value = field.get( null );
-				if ( !checkType ) {
-					return field.getName();
-				}
-				else if ( value instanceof Integer ) {
-					Integer integer = ( Integer ) value;
-					if ( integer.intValue() == type ) {
-						return field.getName();
-					}
-				} // if value is an integer
-			} // try
-			catch ( IllegalArgumentException ignore ) {
-			}
-			catch ( IllegalAccessException ignore ) {
-			}
-		} // if the field is static
-		return null;
-	}
-
-	/**
-	 * Returns the token type name for the given token type.
-	 *
-	 * @param type The token type.
-	 * @return String - The token type name from the token type constant class,
-	 *         or just the integer as a string if none exists.
-	 */
-	private String getTokenTypeName(int type) {
-		// If the class with the constants in it was not supplied, just
-		// use the integer token type as the token type name.
-		if ( tokenTypeConstants == null ) {
-			return Integer.toString( type );
-		}
-
-		// Otherwise, create a type id -> name map from the class if it
-		// hasn't already been created.
-		if ( tokenTypeNamesByTokenType == null ) {
-			Field[] fields = tokenTypeConstants.getFields();
-			tokenTypeNamesByTokenType = new HashMap();
-			String tokenTypeName = null;
-			for ( int i = 0; i < fields.length; i++ ) {
-				Field field = fields[i];
-				tokenTypeName = getTokenTypeName( field, type, false );
-				if ( tokenTypeName != null ) {
-					try {
-						tokenTypeNamesByTokenType.put( field.get( null ), field.getName() );
-					}
-					catch ( IllegalAccessException ignore ) {
-					}
-				}
-			} // for
-		} // if the map hasn't been created.
-
-		return ( String ) tokenTypeNamesByTokenType.get( new Integer( type ) );
-	}
-
-	private void showAst(ArrayList parents, PrintWriter pw, AST ast) {
-		if ( ast == null ) {
-			pw.println( "AST is null!" );
-			return;
-		}
-
-		for ( int i = 0; i < parents.size(); i++ ) {
-			AST parent = ( AST ) parents.get( i );
-			if ( parent.getNextSibling() == null ) {
-
-				pw.print( "   " );
-			}
-			else {
-				pw.print( " | " );
-			}
-		}
-
-		if ( ast.getNextSibling() == null ) {
-			pw.print( " \\-" );
-		}
-		else {
-			pw.print( " +-" );
-		}
-
-		showNode( pw, ast );
-
-		ArrayList newParents = new ArrayList( parents );
-		newParents.add( ast );
-		for ( AST child = ast.getFirstChild(); child != null; child = child.getNextSibling() ) {
-			showAst( newParents, pw, child );
-		}
-		newParents.clear();
-	}
-
-	private void showNode(PrintWriter pw, AST ast) {
-		String s = nodeToString( ast, isShowClassNames() );
-		pw.println( s );
-	}
-
-	public String nodeToString(AST ast, boolean showClassName) {
-		if ( ast == null ) {
-			return "{null}";
-		}
-		StringBuffer buf = new StringBuffer();
-		buf.append( "[" ).append( getTokenTypeName( ast.getType() ) ).append( "] " );
-		if ( showClassName ) {
-			buf.append( StringHelper.unqualify( ast.getClass().getName() ) ).append( ": " );
-		}
-
-        buf.append( "'" );
-        String text = ast.getText();
-        appendEscapedMultibyteChars(text, buf);
-        buf.append( "'" );
-		if ( ast instanceof DisplayableNode ) {
-			DisplayableNode displayableNode = ( DisplayableNode ) ast;
-			// Add a space before the display text.
-			buf.append( " " ).append( displayableNode.getDisplayText() );
-		}
-		String s = buf.toString();
-		return s;
-	}
-
-    public static void appendEscapedMultibyteChars(String text, StringBuffer buf) {
-        char[] chars = text.toCharArray();
-        for (int i = 0; i < chars.length; i++) {
-            char aChar = chars[i];
-            if (aChar > 256) {
-                buf.append("\\u");
-                buf.append(Integer.toHexString(aChar));
-            }
-            else
-                buf.append(aChar);
-        }
-    }
-
-    public static String escapeMultibyteChars(String text)
-    {
-        StringBuffer buf = new StringBuffer();
-        appendEscapedMultibyteChars(text,buf);
-        return buf.toString();
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTPrinter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,285 @@
+/*
+ * 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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.hql.ast.tree.DisplayableNode;
+import org.hibernate.util.StringHelper;
+
+import antlr.collections.AST;
+
+/**
+ * An 'ASCII art' AST printer for debugging ANTLR grammars.
+ *
+ * @author Joshua Davis
+ */
+public class ASTPrinter {
+	private Map tokenTypeNamesByTokenType;
+	private Class tokenTypeConstants;
+	private boolean showClassNames = true;
+
+	/**
+	 * Constructs an org.hibernate.hql.antlr.ASTPrinter, given the class that contains the token type
+	 * constants (typically the '{grammar}TokenTypes' interface generated by
+	 * ANTLR).
+	 *
+	 * @param tokenTypeConstants The class with token type constants in it.
+	 */
+	public ASTPrinter(Class tokenTypeConstants) {
+		this.tokenTypeConstants = tokenTypeConstants;
+	}
+
+	/**
+	 * Returns true if the node class names will be displayed.
+	 *
+	 * @return true if the node class names will be displayed.
+	 */
+	public boolean isShowClassNames() {
+		return showClassNames;
+	}
+
+	/**
+	 * Enables or disables AST node class name display.
+	 *
+	 * @param showClassNames true to enable class name display, false to disable
+	 */
+	public void setShowClassNames(boolean showClassNames) {
+		this.showClassNames = showClassNames;
+	}
+
+	/**
+	 * Prints the AST in 'ASCII art' tree form to the specified print stream.
+	 *
+	 * @param ast The AST to print.
+	 * @param out The print stream.
+	 */
+	private void showAst(AST ast, PrintStream out) {
+		showAst( ast, new PrintWriter( out ) );
+	}
+
+	/**
+	 * Prints the AST in 'ASCII art' tree form to the specified print writer.
+	 *
+	 * @param ast The AST to print.
+	 * @param pw  The print writer.
+	 */
+	public void showAst(AST ast, PrintWriter pw) {
+		ArrayList parents = new ArrayList();
+		showAst( parents, pw, ast );
+		pw.flush();
+	}
+
+	/**
+	 * Prints the AST in 'ASCII art' tree form into a string.
+	 *
+	 * @param ast    The AST to display.
+	 * @param header The header for the display.
+	 * @return The AST in 'ASCII art' form, as a string.
+	 */
+	public String showAsString(AST ast, String header) {
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+		PrintStream ps = new PrintStream( baos );
+		ps.println( header );
+		showAst( ast, ps );
+		ps.flush();
+		return new String( baos.toByteArray() );
+	}
+
+	/**
+	 * Get a single token type name in the specified set of token type constants (interface).
+	 *
+	 * @param tokenTypeConstants Token type constants interface (e.g. HqlSqlTokenTypes.class).
+	 * @param type               The token type ( typically from ast.getType() ).
+	 * @return The token type name, *or* the integer value if the name could not be found for some reason.
+	 */
+	public static String getConstantName(Class tokenTypeConstants, int type) {
+		String tokenTypeName = null;
+		if ( tokenTypeConstants != null ) {
+			Field[] fields = tokenTypeConstants.getFields();
+			for ( int i = 0; i < fields.length; i++ ) {
+				Field field = fields[i];
+				tokenTypeName = getTokenTypeName( field, type, true );
+				if ( tokenTypeName != null ) {
+					break;	// Stop if found.
+				}
+			} // for
+		} // if type constants were provided
+
+		// Use the integer value if no token type name was found
+		if ( tokenTypeName == null ) {
+			tokenTypeName = Integer.toString( type );
+		}
+
+		return tokenTypeName;
+	}
+
+	private static String getTokenTypeName(Field field, int type, boolean checkType) {
+		if ( Modifier.isStatic( field.getModifiers() ) ) {
+			try {
+				Object value = field.get( null );
+				if ( !checkType ) {
+					return field.getName();
+				}
+				else if ( value instanceof Integer ) {
+					Integer integer = ( Integer ) value;
+					if ( integer.intValue() == type ) {
+						return field.getName();
+					}
+				} // if value is an integer
+			} // try
+			catch ( IllegalArgumentException ignore ) {
+			}
+			catch ( IllegalAccessException ignore ) {
+			}
+		} // if the field is static
+		return null;
+	}
+
+	/**
+	 * Returns the token type name for the given token type.
+	 *
+	 * @param type The token type.
+	 * @return String - The token type name from the token type constant class,
+	 *         or just the integer as a string if none exists.
+	 */
+	private String getTokenTypeName(int type) {
+		// If the class with the constants in it was not supplied, just
+		// use the integer token type as the token type name.
+		if ( tokenTypeConstants == null ) {
+			return Integer.toString( type );
+		}
+
+		// Otherwise, create a type id -> name map from the class if it
+		// hasn't already been created.
+		if ( tokenTypeNamesByTokenType == null ) {
+			Field[] fields = tokenTypeConstants.getFields();
+			tokenTypeNamesByTokenType = new HashMap();
+			String tokenTypeName = null;
+			for ( int i = 0; i < fields.length; i++ ) {
+				Field field = fields[i];
+				tokenTypeName = getTokenTypeName( field, type, false );
+				if ( tokenTypeName != null ) {
+					try {
+						tokenTypeNamesByTokenType.put( field.get( null ), field.getName() );
+					}
+					catch ( IllegalAccessException ignore ) {
+					}
+				}
+			} // for
+		} // if the map hasn't been created.
+
+		return ( String ) tokenTypeNamesByTokenType.get( new Integer( type ) );
+	}
+
+	private void showAst(ArrayList parents, PrintWriter pw, AST ast) {
+		if ( ast == null ) {
+			pw.println( "AST is null!" );
+			return;
+		}
+
+		for ( int i = 0; i < parents.size(); i++ ) {
+			AST parent = ( AST ) parents.get( i );
+			if ( parent.getNextSibling() == null ) {
+
+				pw.print( "   " );
+			}
+			else {
+				pw.print( " | " );
+			}
+		}
+
+		if ( ast.getNextSibling() == null ) {
+			pw.print( " \\-" );
+		}
+		else {
+			pw.print( " +-" );
+		}
+
+		showNode( pw, ast );
+
+		ArrayList newParents = new ArrayList( parents );
+		newParents.add( ast );
+		for ( AST child = ast.getFirstChild(); child != null; child = child.getNextSibling() ) {
+			showAst( newParents, pw, child );
+		}
+		newParents.clear();
+	}
+
+	private void showNode(PrintWriter pw, AST ast) {
+		String s = nodeToString( ast, isShowClassNames() );
+		pw.println( s );
+	}
+
+	public String nodeToString(AST ast, boolean showClassName) {
+		if ( ast == null ) {
+			return "{null}";
+		}
+		StringBuffer buf = new StringBuffer();
+		buf.append( "[" ).append( getTokenTypeName( ast.getType() ) ).append( "] " );
+		if ( showClassName ) {
+			buf.append( StringHelper.unqualify( ast.getClass().getName() ) ).append( ": " );
+		}
+
+        buf.append( "'" );
+        String text = ast.getText();
+        appendEscapedMultibyteChars(text, buf);
+        buf.append( "'" );
+		if ( ast instanceof DisplayableNode ) {
+			DisplayableNode displayableNode = ( DisplayableNode ) ast;
+			// Add a space before the display text.
+			buf.append( " " ).append( displayableNode.getDisplayText() );
+		}
+		String s = buf.toString();
+		return s;
+	}
+
+    public static void appendEscapedMultibyteChars(String text, StringBuffer buf) {
+        char[] chars = text.toCharArray();
+        for (int i = 0; i < chars.length; i++) {
+            char aChar = chars[i];
+            if (aChar > 256) {
+                buf.append("\\u");
+                buf.append(Integer.toHexString(aChar));
+            }
+            else
+                buf.append(aChar);
+        }
+    }
+
+    public static String escapeMultibyteChars(String text)
+    {
+        StringBuffer buf = new StringBuffer();
+        appendEscapedMultibyteChars(text,buf);
+        return buf.toString();
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,360 +0,0 @@
-// $Id: ASTUtil.java 10000 2006-06-08 21:04:45Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.util;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import antlr.ASTFactory;
-import antlr.collections.AST;
-import antlr.collections.impl.ASTArray;
-
-/**
- * Provides utility methods for AST traversal and manipulation.
- *
- * @author Joshua Davis (pgmjsd at sourceforge.net)
- */
-public final class ASTUtil {
-	/**
-	 * Private empty constructor.
-	 * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
-	 *
-	 * @deprecated (tell clover to ignore this)
-	 */
-	private ASTUtil() {
-	}
-
-	/**
-	 * Creates a single node AST.
-	 *
-	 * @param astFactory The factory.
-	 * @param type       The node type.
-	 * @param text       The node text.
-	 * @return AST - A single node tree.
-	 */
-	public static AST create(ASTFactory astFactory, int type, String text) {
-		AST node = astFactory.create( type, text );
-		return node;
-	}
-
-	/**
-	 * Creates a single node AST as a sibling.
-	 *
-	 * @param astFactory  The factory.
-	 * @param type        The node type.
-	 * @param text        The node text.
-	 * @param prevSibling The previous sibling.
-	 * @return AST - A single node tree.
-	 */
-	public static AST createSibling(ASTFactory astFactory, int type, String text, AST prevSibling) {
-		AST node = astFactory.create( type, text );
-		node.setNextSibling( prevSibling.getNextSibling() );
-		prevSibling.setNextSibling( node );
-		return node;
-	}
-
-	public static AST insertSibling(AST node, AST prevSibling) {
-		node.setNextSibling( prevSibling.getNextSibling() );
-		prevSibling.setNextSibling( node );
-		return node;
-	}
-
-	/**
-	 * Creates a 'binary operator' subtree, given the information about the
-	 * parent and the two child nodex.
-	 *
-	 * @param factory    The AST factory.
-	 * @param parentType The type of the parent node.
-	 * @param parentText The text of the parent node.
-	 * @param child1     The first child.
-	 * @param child2     The second child.
-	 * @return AST - A new sub-tree of the form "(parent child1 child2)"
-	 */
-	public static AST createBinarySubtree(ASTFactory factory, int parentType, String parentText, AST child1, AST child2) {
-		ASTArray array = createAstArray( factory, 3, parentType, parentText, child1 );
-		array.add( child2 );
-		return factory.make( array );
-	}
-
-	/**
-	 * Creates a single parent of the specified child (i.e. a 'unary operator'
-	 * subtree).
-	 *
-	 * @param factory    The AST factory.
-	 * @param parentType The type of the parent node.
-	 * @param parentText The text of the parent node.
-	 * @param child      The child.
-	 * @return AST - A new sub-tree of the form "(parent child)"
-	 */
-	public static AST createParent(ASTFactory factory, int parentType, String parentText, AST child) {
-		ASTArray array = createAstArray( factory, 2, parentType, parentText, child );
-		return factory.make( array );
-	}
-
-	public static AST createTree(ASTFactory factory, AST[] nestedChildren) {
-		AST[] array = new AST[2];
-		int limit = nestedChildren.length - 1;
-		for ( int i = limit; i >= 0; i-- ) {
-			if ( i != limit ) {
-				array[1] = nestedChildren[i + 1];
-				array[0] = nestedChildren[i];
-				factory.make( array );
-			}
-		}
-		return array[0];
-	}
-
-	/**
-	 * Finds the first node of the specified type in the chain of children.
-	 *
-	 * @param parent The parent
-	 * @param type   The type to find.
-	 * @return The first node of the specified type, or null if not found.
-	 */
-	public static AST findTypeInChildren(AST parent, int type) {
-		AST n = parent.getFirstChild();
-		while ( n != null && n.getType() != type ) {
-			n = n.getNextSibling();
-		}
-		return n;
-	}
-
-	/**
-	 * Returns the last direct child of 'n'.
-	 *
-	 * @param n The parent
-	 * @return The last direct child of 'n'.
-	 */
-	public static AST getLastChild(AST n) {
-		return getLastSibling( n.getFirstChild() );
-	}
-
-	/**
-	 * Returns the last sibling of 'a'.
-	 *
-	 * @param a The sibling.
-	 * @return The last sibling of 'a'.
-	 */
-	private static AST getLastSibling(AST a) {
-		AST last = null;
-		while ( a != null ) {
-			last = a;
-			a = a.getNextSibling();
-		}
-		return last;
-	}
-
-	/**
-	 * Returns the 'list' representation with some brackets around it for debugging.
-	 *
-	 * @param n The tree.
-	 * @return The list representation of the tree.
-	 */
-	public static String getDebugString(AST n) {
-		StringBuffer buf = new StringBuffer();
-		buf.append( "[ " );
-		buf.append( ( n == null ) ? "{null}" : n.toStringTree() );
-		buf.append( " ]" );
-		return buf.toString();
-	}
-
-	/**
-	 * Find the previous sibling in the parent for the given child.
-	 *
-	 * @param parent the parent node
-	 * @param child  the child to find the previous sibling of
-	 * @return the previous sibling of the child
-	 */
-	public static AST findPreviousSibling(AST parent, AST child) {
-		AST prev = null;
-		AST n = parent.getFirstChild();
-		while ( n != null ) {
-			if ( n == child ) {
-				return prev;
-			}
-			prev = n;
-			n = n.getNextSibling();
-		}
-		throw new IllegalArgumentException( "Child not found in parent!" );
-	}
-
-	/**
-	 * Determine if a given node (test) is a direct (throtle to one level down)
-	 * child of another given node (fixture).
-	 *
-	 * @param fixture The node against which to testto be checked for children.
-	 * @param test The node to be tested as being a child of the parent.
-	 * @return True if test is contained in the fixtures's direct children;
-	 * false otherwise.
-	 */
-	public static boolean isDirectChild(AST fixture, AST test) {
-		AST n = fixture.getFirstChild();
-		while ( n != null ) {
-			if ( n == test ) {
-				return true;
-			}
-			n = n.getNextSibling();
-		}
-		return false;
-	}
-
-	/**
-	 * Determine if a given node (test) is contained anywhere in the subtree
-	 * of another given node (fixture).
-	 *
-	 * @param fixture The node against which to testto be checked for children.
-	 * @param test The node to be tested as being a subtree child of the parent.
-	 * @return True if child is contained in the parent's collection of children.
-	 */
-	public static boolean isSubtreeChild(AST fixture, AST test) {
-		AST n = fixture.getFirstChild();
-		while ( n != null ) {
-			if ( n == test ) {
-				return true;
-			}
-			if ( n.getFirstChild() != null && isSubtreeChild( n, test ) ) {
-				return true;
-			}
-			n = n.getNextSibling();
-		}
-		return false;
-	}
-
-	/**
-	 * Makes the child node a sibling of the parent, reconnecting all siblings.
-	 *
-	 * @param parent the parent
-	 * @param child  the child
-	 */
-	public static void makeSiblingOfParent(AST parent, AST child) {
-		AST prev = findPreviousSibling( parent, child );
-		if ( prev != null ) {
-			prev.setNextSibling( child.getNextSibling() );
-		}
-		else { // child == parent.getFirstChild()
-			parent.setFirstChild( child.getNextSibling() );
-		}
-		child.setNextSibling( parent.getNextSibling() );
-		parent.setNextSibling( child );
-	}
-
-	public static String getPathText(AST n) {
-		StringBuffer buf = new StringBuffer();
-		getPathText( buf, n );
-		return buf.toString();
-	}
-
-	private static void getPathText(StringBuffer buf, AST n) {
-		AST firstChild = n.getFirstChild();
-		// If the node has a first child, recurse into the first child.
-		if ( firstChild != null ) {
-			getPathText( buf, firstChild );
-		}
-		// Append the text of the current node.
-		buf.append( n.getText() );
-		// If there is a second child (RHS), recurse into that child.
-		if ( firstChild != null && firstChild.getNextSibling() != null ) {
-			getPathText( buf, firstChild.getNextSibling() );
-		}
-	}
-
-	public static boolean hasExactlyOneChild(AST n) {
-		return n != null && n.getFirstChild() != null && n.getFirstChild().getNextSibling() == null;
-	}
-
-	public static void appendSibling(AST n, AST s) {
-		while ( n.getNextSibling() != null ) {
-			n = n.getNextSibling();
-		}
-		n.setNextSibling( s );
-	}
-
-	/**
-	 * Inserts the child as the first child of the parent, all other children are shifted over to the 'right'.
-	 *
-	 * @param parent the parent
-	 * @param child  the new first child
-	 */
-	public static void insertChild(AST parent, AST child) {
-		if ( parent.getFirstChild() == null ) {
-			parent.setFirstChild( child );
-		}
-		else {
-			AST n = parent.getFirstChild();
-			parent.setFirstChild( child );
-			child.setNextSibling( n );
-		}
-	}
-
-	/**
-	 * Filters nodes out of a tree.
-	 */
-	public static interface FilterPredicate {
-		/**
-		 * Returns true if the node should be filtered out.
-		 *
-		 * @param n The node.
-		 * @return true if the node should be filtered out, false to keep the node.
-		 */
-		boolean exclude(AST n);
-	}
-
-	/**
-	 * A predicate that uses inclusion, rather than exclusion semantics.
-	 */
-	public abstract static class IncludePredicate implements FilterPredicate {
-		public final boolean exclude(AST node) {
-			return !include( node );
-		}
-
-		public abstract boolean include(AST node);
-	}
-
-	private static ASTArray createAstArray(ASTFactory factory, int size, int parentType, String parentText, AST child1) {
-		ASTArray array = new ASTArray( size );
-		array.add( factory.create( parentType, parentText ) );
-		array.add( child1 );
-		return array;
-	}
-
-	public static List collectChildren(AST root, FilterPredicate predicate) {
-//		List children = new ArrayList();
-//		collectChildren( children, root, predicate );
-//		return children;
-		return new CollectingNodeVisitor( predicate ).collect( root );
-	}
-
-	private static class CollectingNodeVisitor implements NodeTraverser.VisitationStrategy {
-		private final FilterPredicate predicate;
-		private final List collectedNodes = new ArrayList();
-
-		public CollectingNodeVisitor(FilterPredicate predicate) {
-			this.predicate = predicate;
-		}
-
-		public void visit(AST node) {
-			if ( predicate == null || !predicate.exclude( node ) ) {
-				collectedNodes.add( node );
-			}
-		}
-
-		public List getCollectedNodes() {
-			return collectedNodes;
-		}
-
-		public List collect(AST root) {
-			NodeTraverser traverser = new NodeTraverser( this );
-			traverser.traverseDepthFirst( root );
-			return collectedNodes;
-		}
-	}
-
-	private static void collectChildren(List children, AST root, FilterPredicate predicate) {
-		for ( AST n = root.getFirstChild(); n != null; n = n.getNextSibling() ) {
-			if ( predicate == null || !predicate.exclude( n ) ) {
-				children.add( n );
-			}
-			collectChildren( children, n, predicate );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ASTUtil.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,383 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import antlr.ASTFactory;
+import antlr.collections.AST;
+import antlr.collections.impl.ASTArray;
+
+/**
+ * Provides utility methods for AST traversal and manipulation.
+ *
+ * @author Joshua Davis
+ */
+public final class ASTUtil {
+	/**
+	 * Private empty constructor.
+	 * (or else checkstyle says: 'warning: Utility classes should not have a public or default constructor.')
+	 *
+	 * @deprecated (tell clover to ignore this)
+	 */
+	private ASTUtil() {
+	}
+
+	/**
+	 * Creates a single node AST.
+	 *
+	 * @param astFactory The factory.
+	 * @param type       The node type.
+	 * @param text       The node text.
+	 * @return AST - A single node tree.
+	 */
+	public static AST create(ASTFactory astFactory, int type, String text) {
+		AST node = astFactory.create( type, text );
+		return node;
+	}
+
+	/**
+	 * Creates a single node AST as a sibling.
+	 *
+	 * @param astFactory  The factory.
+	 * @param type        The node type.
+	 * @param text        The node text.
+	 * @param prevSibling The previous sibling.
+	 * @return AST - A single node tree.
+	 */
+	public static AST createSibling(ASTFactory astFactory, int type, String text, AST prevSibling) {
+		AST node = astFactory.create( type, text );
+		node.setNextSibling( prevSibling.getNextSibling() );
+		prevSibling.setNextSibling( node );
+		return node;
+	}
+
+	public static AST insertSibling(AST node, AST prevSibling) {
+		node.setNextSibling( prevSibling.getNextSibling() );
+		prevSibling.setNextSibling( node );
+		return node;
+	}
+
+	/**
+	 * Creates a 'binary operator' subtree, given the information about the
+	 * parent and the two child nodex.
+	 *
+	 * @param factory    The AST factory.
+	 * @param parentType The type of the parent node.
+	 * @param parentText The text of the parent node.
+	 * @param child1     The first child.
+	 * @param child2     The second child.
+	 * @return AST - A new sub-tree of the form "(parent child1 child2)"
+	 */
+	public static AST createBinarySubtree(ASTFactory factory, int parentType, String parentText, AST child1, AST child2) {
+		ASTArray array = createAstArray( factory, 3, parentType, parentText, child1 );
+		array.add( child2 );
+		return factory.make( array );
+	}
+
+	/**
+	 * Creates a single parent of the specified child (i.e. a 'unary operator'
+	 * subtree).
+	 *
+	 * @param factory    The AST factory.
+	 * @param parentType The type of the parent node.
+	 * @param parentText The text of the parent node.
+	 * @param child      The child.
+	 * @return AST - A new sub-tree of the form "(parent child)"
+	 */
+	public static AST createParent(ASTFactory factory, int parentType, String parentText, AST child) {
+		ASTArray array = createAstArray( factory, 2, parentType, parentText, child );
+		return factory.make( array );
+	}
+
+	public static AST createTree(ASTFactory factory, AST[] nestedChildren) {
+		AST[] array = new AST[2];
+		int limit = nestedChildren.length - 1;
+		for ( int i = limit; i >= 0; i-- ) {
+			if ( i != limit ) {
+				array[1] = nestedChildren[i + 1];
+				array[0] = nestedChildren[i];
+				factory.make( array );
+			}
+		}
+		return array[0];
+	}
+
+	/**
+	 * Finds the first node of the specified type in the chain of children.
+	 *
+	 * @param parent The parent
+	 * @param type   The type to find.
+	 * @return The first node of the specified type, or null if not found.
+	 */
+	public static AST findTypeInChildren(AST parent, int type) {
+		AST n = parent.getFirstChild();
+		while ( n != null && n.getType() != type ) {
+			n = n.getNextSibling();
+		}
+		return n;
+	}
+
+	/**
+	 * Returns the last direct child of 'n'.
+	 *
+	 * @param n The parent
+	 * @return The last direct child of 'n'.
+	 */
+	public static AST getLastChild(AST n) {
+		return getLastSibling( n.getFirstChild() );
+	}
+
+	/**
+	 * Returns the last sibling of 'a'.
+	 *
+	 * @param a The sibling.
+	 * @return The last sibling of 'a'.
+	 */
+	private static AST getLastSibling(AST a) {
+		AST last = null;
+		while ( a != null ) {
+			last = a;
+			a = a.getNextSibling();
+		}
+		return last;
+	}
+
+	/**
+	 * Returns the 'list' representation with some brackets around it for debugging.
+	 *
+	 * @param n The tree.
+	 * @return The list representation of the tree.
+	 */
+	public static String getDebugString(AST n) {
+		StringBuffer buf = new StringBuffer();
+		buf.append( "[ " );
+		buf.append( ( n == null ) ? "{null}" : n.toStringTree() );
+		buf.append( " ]" );
+		return buf.toString();
+	}
+
+	/**
+	 * Find the previous sibling in the parent for the given child.
+	 *
+	 * @param parent the parent node
+	 * @param child  the child to find the previous sibling of
+	 * @return the previous sibling of the child
+	 */
+	public static AST findPreviousSibling(AST parent, AST child) {
+		AST prev = null;
+		AST n = parent.getFirstChild();
+		while ( n != null ) {
+			if ( n == child ) {
+				return prev;
+			}
+			prev = n;
+			n = n.getNextSibling();
+		}
+		throw new IllegalArgumentException( "Child not found in parent!" );
+	}
+
+	/**
+	 * Determine if a given node (test) is a direct (throtle to one level down)
+	 * child of another given node (fixture).
+	 *
+	 * @param fixture The node against which to testto be checked for children.
+	 * @param test The node to be tested as being a child of the parent.
+	 * @return True if test is contained in the fixtures's direct children;
+	 * false otherwise.
+	 */
+	public static boolean isDirectChild(AST fixture, AST test) {
+		AST n = fixture.getFirstChild();
+		while ( n != null ) {
+			if ( n == test ) {
+				return true;
+			}
+			n = n.getNextSibling();
+		}
+		return false;
+	}
+
+	/**
+	 * Determine if a given node (test) is contained anywhere in the subtree
+	 * of another given node (fixture).
+	 *
+	 * @param fixture The node against which to testto be checked for children.
+	 * @param test The node to be tested as being a subtree child of the parent.
+	 * @return True if child is contained in the parent's collection of children.
+	 */
+	public static boolean isSubtreeChild(AST fixture, AST test) {
+		AST n = fixture.getFirstChild();
+		while ( n != null ) {
+			if ( n == test ) {
+				return true;
+			}
+			if ( n.getFirstChild() != null && isSubtreeChild( n, test ) ) {
+				return true;
+			}
+			n = n.getNextSibling();
+		}
+		return false;
+	}
+
+	/**
+	 * Makes the child node a sibling of the parent, reconnecting all siblings.
+	 *
+	 * @param parent the parent
+	 * @param child  the child
+	 */
+	public static void makeSiblingOfParent(AST parent, AST child) {
+		AST prev = findPreviousSibling( parent, child );
+		if ( prev != null ) {
+			prev.setNextSibling( child.getNextSibling() );
+		}
+		else { // child == parent.getFirstChild()
+			parent.setFirstChild( child.getNextSibling() );
+		}
+		child.setNextSibling( parent.getNextSibling() );
+		parent.setNextSibling( child );
+	}
+
+	public static String getPathText(AST n) {
+		StringBuffer buf = new StringBuffer();
+		getPathText( buf, n );
+		return buf.toString();
+	}
+
+	private static void getPathText(StringBuffer buf, AST n) {
+		AST firstChild = n.getFirstChild();
+		// If the node has a first child, recurse into the first child.
+		if ( firstChild != null ) {
+			getPathText( buf, firstChild );
+		}
+		// Append the text of the current node.
+		buf.append( n.getText() );
+		// If there is a second child (RHS), recurse into that child.
+		if ( firstChild != null && firstChild.getNextSibling() != null ) {
+			getPathText( buf, firstChild.getNextSibling() );
+		}
+	}
+
+	public static boolean hasExactlyOneChild(AST n) {
+		return n != null && n.getFirstChild() != null && n.getFirstChild().getNextSibling() == null;
+	}
+
+	public static void appendSibling(AST n, AST s) {
+		while ( n.getNextSibling() != null ) {
+			n = n.getNextSibling();
+		}
+		n.setNextSibling( s );
+	}
+
+	/**
+	 * Inserts the child as the first child of the parent, all other children are shifted over to the 'right'.
+	 *
+	 * @param parent the parent
+	 * @param child  the new first child
+	 */
+	public static void insertChild(AST parent, AST child) {
+		if ( parent.getFirstChild() == null ) {
+			parent.setFirstChild( child );
+		}
+		else {
+			AST n = parent.getFirstChild();
+			parent.setFirstChild( child );
+			child.setNextSibling( n );
+		}
+	}
+
+	/**
+	 * Filters nodes out of a tree.
+	 */
+	public static interface FilterPredicate {
+		/**
+		 * Returns true if the node should be filtered out.
+		 *
+		 * @param n The node.
+		 * @return true if the node should be filtered out, false to keep the node.
+		 */
+		boolean exclude(AST n);
+	}
+
+	/**
+	 * A predicate that uses inclusion, rather than exclusion semantics.
+	 */
+	public abstract static class IncludePredicate implements FilterPredicate {
+		public final boolean exclude(AST node) {
+			return !include( node );
+		}
+
+		public abstract boolean include(AST node);
+	}
+
+	private static ASTArray createAstArray(ASTFactory factory, int size, int parentType, String parentText, AST child1) {
+		ASTArray array = new ASTArray( size );
+		array.add( factory.create( parentType, parentText ) );
+		array.add( child1 );
+		return array;
+	}
+
+	public static List collectChildren(AST root, FilterPredicate predicate) {
+//		List children = new ArrayList();
+//		collectChildren( children, root, predicate );
+//		return children;
+		return new CollectingNodeVisitor( predicate ).collect( root );
+	}
+
+	private static class CollectingNodeVisitor implements NodeTraverser.VisitationStrategy {
+		private final FilterPredicate predicate;
+		private final List collectedNodes = new ArrayList();
+
+		public CollectingNodeVisitor(FilterPredicate predicate) {
+			this.predicate = predicate;
+		}
+
+		public void visit(AST node) {
+			if ( predicate == null || !predicate.exclude( node ) ) {
+				collectedNodes.add( node );
+			}
+		}
+
+		public List getCollectedNodes() {
+			return collectedNodes;
+		}
+
+		public List collect(AST root) {
+			NodeTraverser traverser = new NodeTraverser( this );
+			traverser.traverseDepthFirst( root );
+			return collectedNodes;
+		}
+	}
+
+	private static void collectChildren(List children, AST root, FilterPredicate predicate) {
+		for ( AST n = root.getFirstChild(); n != null; n = n.getNextSibling() ) {
+			if ( predicate == null || !predicate.exclude( n ) ) {
+				children.add( n );
+			}
+			collectChildren( children, n, predicate );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-// $Id: AliasGenerator.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * Generates class/table/column aliases during semantic analysis and SQL rendering.
- * <p/>
- * Its essential purpose is to keep an internal counter to ensure that the
- * generated aliases are unique.
- */
-public class AliasGenerator {
-	private int next = 0;
-
-	private int nextCount() {
-		return next++;
-	}
-
-	public String createName(String name) {
-		return StringHelper.generateAlias( name, nextCount() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/AliasGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.util;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * Generates class/table/column aliases during semantic analysis and SQL rendering.
+ * <p/>
+ * Its essential purpose is to keep an internal counter to ensure that the
+ * generated aliases are unique.
+ */
+public class AliasGenerator {
+	private int next = 0;
+
+	private int nextCount() {
+		return next++;
+	}
+
+	public String createName(String name) {
+		return StringHelper.generateAlias( name, nextCount() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-// $Id: ColumnHelper.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import org.hibernate.hql.NameGenerator;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.tree.HqlSqlWalkerNode;
-
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-/**
- * Provides utility methods for dealing with arrays of SQL column names.
- *
- * @author josh Jan 3, 2005 9:08:47 AM
- */
-public final class ColumnHelper {
-
-	/**
-	 * @deprecated (tell clover to filter this out)
-	 */
-	private ColumnHelper() {
-	}
-
-	public static void generateSingleScalarColumn(HqlSqlWalkerNode node, int i) {
-		ASTFactory factory = node.getASTFactory();
-		ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName( i, 0 ), node );
-	}
-
-	/**
-	 * Generates the scalar column AST nodes for a given array of SQL columns
-	 */
-	public static void generateScalarColumns(HqlSqlWalkerNode node, String sqlColumns[], int i) {
-		if ( sqlColumns.length == 1 ) {
-			generateSingleScalarColumn( node, i );
-		}
-		else {
-			ASTFactory factory = node.getASTFactory();
-			AST n = node;
-			n.setText( sqlColumns[0] );	// Use the DOT node to emit the first column name.
-			// Create the column names, folled by the column aliases.
-			for ( int j = 0; j < sqlColumns.length; j++ ) {
-				if ( j > 0 ) {
-					n = ASTUtil.createSibling( factory, SqlTokenTypes.SQL_TOKEN, sqlColumns[j], n );
-				}
-				n = ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName( i, j ), n );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/ColumnHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.util;
+
+import org.hibernate.hql.NameGenerator;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.tree.HqlSqlWalkerNode;
+
+import antlr.ASTFactory;
+import antlr.collections.AST;
+
+/**
+ * Provides utility methods for dealing with arrays of SQL column names.
+ *
+ * @author josh
+ */
+public final class ColumnHelper {
+
+	/**
+	 * @deprecated (tell clover to filter this out)
+	 */
+	private ColumnHelper() {
+	}
+
+	public static void generateSingleScalarColumn(HqlSqlWalkerNode node, int i) {
+		ASTFactory factory = node.getASTFactory();
+		ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName( i, 0 ), node );
+	}
+
+	/**
+	 * Generates the scalar column AST nodes for a given array of SQL columns
+	 */
+	public static void generateScalarColumns(HqlSqlWalkerNode node, String sqlColumns[], int i) {
+		if ( sqlColumns.length == 1 ) {
+			generateSingleScalarColumn( node, i );
+		}
+		else {
+			ASTFactory factory = node.getASTFactory();
+			AST n = node;
+			n.setText( sqlColumns[0] );	// Use the DOT node to emit the first column name.
+			// Create the column names, folled by the column aliases.
+			for ( int j = 0; j < sqlColumns.length; j++ ) {
+				if ( j > 0 ) {
+					n = ASTUtil.createSibling( factory, SqlTokenTypes.SQL_TOKEN, sqlColumns[j], n );
+				}
+				n = ASTUtil.createSibling( factory, SqlTokenTypes.SELECT_COLUMNS, " as " + NameGenerator.scalarName( i, j ), n );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,164 +0,0 @@
-// $Id: JoinProcessor.java 10824 2006-11-16 19:32:48Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.util;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.ListIterator;
-import java.util.Collections;
-import java.util.List;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.QueryTranslatorImpl;
-import org.hibernate.hql.ast.tree.FromClause;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.hql.ast.tree.DotNode;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.util.StringHelper;
-
-import antlr.ASTFactory;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Performs the post-processing of the join information gathered during semantic analysis.
- * The join generating classes are complex, this encapsulates some of the JoinSequence-related
- * code.
- *
- * @author Joshua Davis
- */
-public class JoinProcessor implements SqlTokenTypes {
-
-	private static final Logger log = LoggerFactory.getLogger( JoinProcessor.class );
-
-	private QueryTranslatorImpl queryTranslatorImpl;
-	private SyntheticAndFactory andFactory;
-
-	/**
-	 * Constructs a new JoinProcessor.
-	 *
-	 * @param astFactory		  The factory for AST node creation.
-	 * @param queryTranslatorImpl The query translator.
-	 */
-	public JoinProcessor(ASTFactory astFactory, QueryTranslatorImpl queryTranslatorImpl) {
-		this.andFactory = new SyntheticAndFactory( astFactory );
-		this.queryTranslatorImpl = queryTranslatorImpl;
-	}
-
-	/**
-	 * Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
-	 *
-	 * @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
-	 * @return a JoinFragment.XXX join type.
-	 * @see JoinFragment
-	 * @see SqlTokenTypes
-	 */
-	public static int toHibernateJoinType(int astJoinType) {
-		switch ( astJoinType ) {
-			case LEFT_OUTER:
-				return JoinFragment.LEFT_OUTER_JOIN;
-			case INNER:
-				return JoinFragment.INNER_JOIN;
-			case RIGHT_OUTER:
-				return JoinFragment.RIGHT_OUTER_JOIN;
-			default:
-				throw new AssertionFailure( "undefined join type " + astJoinType );
-		}
-	}
-
-	public void processJoins(QueryNode query, boolean inSubquery) {
-		final FromClause fromClause = query.getFromClause();
-
-		final List fromElements;
-		if ( DotNode.useThetaStyleImplicitJoins ) {
-			// for regression testing against output from the old parser...
-			// found it easiest to simply reorder the FromElements here into ascending order
-			// in terms of injecting them into the resulting sql ast in orders relative to those
-			// expected by the old parser; this is definitely another of those "only needed
-			// for regression purposes".  The SyntheticAndFactory, then, simply injects them as it
-			// encounters them.
-			fromElements = new ArrayList();
-			ListIterator liter = fromClause.getFromElements().listIterator( fromClause.getFromElements().size() );
-			while ( liter.hasPrevious() ) {
-				fromElements.add( liter.previous() );
-			}
-		}
-		else {
-			fromElements = fromClause.getFromElements();
-		}
-
-		// Iterate through the alias,JoinSequence pairs and generate SQL token nodes.
-		Iterator iter = fromElements.iterator();
-		while ( iter.hasNext() ) {
-			final FromElement fromElement = ( FromElement ) iter.next();
-			JoinSequence join = fromElement.getJoinSequence();
-			join.setSelector(
-					new JoinSequence.Selector() {
-						public boolean includeSubclasses(String alias) {
-							// The uber-rule here is that we need to include  subclass joins if
-							// the FromElement is in any way dereferenced by a property from
-							// the subclass table; otherwise we end up with column references
-							// qualified by a non-existent table reference in the resulting SQL...
-							boolean containsTableAlias = fromClause.containsTableAlias( alias );
-							if ( fromElement.isDereferencedBySubclassProperty() ) {
-								// TODO : or should we return 'containsTableAlias'??
-								log.trace( "forcing inclusion of extra joins [alias=" + alias + ", containsTableAlias=" + containsTableAlias + "]" );
-								return true;
-							}
-							boolean shallowQuery = queryTranslatorImpl.isShallowQuery();
-							boolean includeSubclasses = fromElement.isIncludeSubclasses();
-							boolean subQuery = fromClause.isSubQuery();
-							return includeSubclasses && containsTableAlias && !subQuery && !shallowQuery;
-						}
-					}
-			);
-			addJoinNodes( query, join, fromElement, inSubquery );
-		}
-
-	}
-
-	private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement, boolean inSubquery) {
-		// Generate FROM and WHERE fragments for the from element.
-		JoinFragment joinFragment = join.toJoinFragment(
-				inSubquery ? Collections.EMPTY_MAP : queryTranslatorImpl.getEnabledFilters(),
-				fromElement.useFromFragment() || fromElement.isDereferencedBySuperclassOrSubclassProperty(),
-				fromElement.getWithClauseFragment(),
-				fromElement.getWithClauseJoinAlias()
-		);
-
-		String frag = joinFragment.toFromFragmentString();
-		String whereFrag = joinFragment.toWhereFragmentString();
-
-		// If the from element represents a JOIN_FRAGMENT and it is
-		// a theta-style join, convert its type from JOIN_FRAGMENT
-		// to FROM_FRAGMENT
-		if ( fromElement.getType() == JOIN_FRAGMENT &&
-				( join.isThetaStyle() || StringHelper.isNotEmpty( whereFrag ) ) ) {
-			fromElement.setType( FROM_FRAGMENT );
-			fromElement.getJoinSequence().setUseThetaStyle( true ); // this is used during SqlGenerator processing
-		}
-
-		// If there is a FROM fragment and the FROM element is an explicit, then add the from part.
-		if ( fromElement.useFromFragment() /*&& StringHelper.isNotEmpty( frag )*/ ) {
-			String fromFragment = processFromFragment( frag, join );
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Using FROM fragment [" + fromFragment + "]" );
-			}
-			fromElement.setText( fromFragment.trim() ); // Set the text of the fromElement.
-		}
-		andFactory.addWhereFragment( joinFragment, whereFrag, query, fromElement );
-	}
-
-	private String processFromFragment(String frag, JoinSequence join) {
-		String fromFragment = frag.trim();
-		// The FROM fragment will probably begin with ', '.  Remove this if it is present.
-		if ( fromFragment.startsWith( ", " ) ) {
-			fromFragment = fromFragment.substring( 2 );
-		}
-		return fromFragment;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/JoinProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,187 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.ListIterator;
+import java.util.Collections;
+import java.util.List;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.QueryTranslatorImpl;
+import org.hibernate.hql.ast.tree.FromClause;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.hql.ast.tree.DotNode;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.util.StringHelper;
+
+import antlr.ASTFactory;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Performs the post-processing of the join information gathered during semantic analysis.
+ * The join generating classes are complex, this encapsulates some of the JoinSequence-related
+ * code.
+ *
+ * @author Joshua Davis
+ */
+public class JoinProcessor implements SqlTokenTypes {
+
+	private static final Logger log = LoggerFactory.getLogger( JoinProcessor.class );
+
+	private QueryTranslatorImpl queryTranslatorImpl;
+	private SyntheticAndFactory andFactory;
+
+	/**
+	 * Constructs a new JoinProcessor.
+	 *
+	 * @param astFactory		  The factory for AST node creation.
+	 * @param queryTranslatorImpl The query translator.
+	 */
+	public JoinProcessor(ASTFactory astFactory, QueryTranslatorImpl queryTranslatorImpl) {
+		this.andFactory = new SyntheticAndFactory( astFactory );
+		this.queryTranslatorImpl = queryTranslatorImpl;
+	}
+
+	/**
+	 * Translates an AST join type (i.e., the token type) into a JoinFragment.XXX join type.
+	 *
+	 * @param astJoinType The AST join type (from HqlSqlTokenTypes or SqlTokenTypes)
+	 * @return a JoinFragment.XXX join type.
+	 * @see JoinFragment
+	 * @see SqlTokenTypes
+	 */
+	public static int toHibernateJoinType(int astJoinType) {
+		switch ( astJoinType ) {
+			case LEFT_OUTER:
+				return JoinFragment.LEFT_OUTER_JOIN;
+			case INNER:
+				return JoinFragment.INNER_JOIN;
+			case RIGHT_OUTER:
+				return JoinFragment.RIGHT_OUTER_JOIN;
+			default:
+				throw new AssertionFailure( "undefined join type " + astJoinType );
+		}
+	}
+
+	public void processJoins(QueryNode query, boolean inSubquery) {
+		final FromClause fromClause = query.getFromClause();
+
+		final List fromElements;
+		if ( DotNode.useThetaStyleImplicitJoins ) {
+			// for regression testing against output from the old parser...
+			// found it easiest to simply reorder the FromElements here into ascending order
+			// in terms of injecting them into the resulting sql ast in orders relative to those
+			// expected by the old parser; this is definitely another of those "only needed
+			// for regression purposes".  The SyntheticAndFactory, then, simply injects them as it
+			// encounters them.
+			fromElements = new ArrayList();
+			ListIterator liter = fromClause.getFromElements().listIterator( fromClause.getFromElements().size() );
+			while ( liter.hasPrevious() ) {
+				fromElements.add( liter.previous() );
+			}
+		}
+		else {
+			fromElements = fromClause.getFromElements();
+		}
+
+		// Iterate through the alias,JoinSequence pairs and generate SQL token nodes.
+		Iterator iter = fromElements.iterator();
+		while ( iter.hasNext() ) {
+			final FromElement fromElement = ( FromElement ) iter.next();
+			JoinSequence join = fromElement.getJoinSequence();
+			join.setSelector(
+					new JoinSequence.Selector() {
+						public boolean includeSubclasses(String alias) {
+							// The uber-rule here is that we need to include  subclass joins if
+							// the FromElement is in any way dereferenced by a property from
+							// the subclass table; otherwise we end up with column references
+							// qualified by a non-existent table reference in the resulting SQL...
+							boolean containsTableAlias = fromClause.containsTableAlias( alias );
+							if ( fromElement.isDereferencedBySubclassProperty() ) {
+								// TODO : or should we return 'containsTableAlias'??
+								log.trace( "forcing inclusion of extra joins [alias=" + alias + ", containsTableAlias=" + containsTableAlias + "]" );
+								return true;
+							}
+							boolean shallowQuery = queryTranslatorImpl.isShallowQuery();
+							boolean includeSubclasses = fromElement.isIncludeSubclasses();
+							boolean subQuery = fromClause.isSubQuery();
+							return includeSubclasses && containsTableAlias && !subQuery && !shallowQuery;
+						}
+					}
+			);
+			addJoinNodes( query, join, fromElement, inSubquery );
+		}
+
+	}
+
+	private void addJoinNodes(QueryNode query, JoinSequence join, FromElement fromElement, boolean inSubquery) {
+		// Generate FROM and WHERE fragments for the from element.
+		JoinFragment joinFragment = join.toJoinFragment(
+				inSubquery ? Collections.EMPTY_MAP : queryTranslatorImpl.getEnabledFilters(),
+				fromElement.useFromFragment() || fromElement.isDereferencedBySuperclassOrSubclassProperty(),
+				fromElement.getWithClauseFragment(),
+				fromElement.getWithClauseJoinAlias()
+		);
+
+		String frag = joinFragment.toFromFragmentString();
+		String whereFrag = joinFragment.toWhereFragmentString();
+
+		// If the from element represents a JOIN_FRAGMENT and it is
+		// a theta-style join, convert its type from JOIN_FRAGMENT
+		// to FROM_FRAGMENT
+		if ( fromElement.getType() == JOIN_FRAGMENT &&
+				( join.isThetaStyle() || StringHelper.isNotEmpty( whereFrag ) ) ) {
+			fromElement.setType( FROM_FRAGMENT );
+			fromElement.getJoinSequence().setUseThetaStyle( true ); // this is used during SqlGenerator processing
+		}
+
+		// If there is a FROM fragment and the FROM element is an explicit, then add the from part.
+		if ( fromElement.useFromFragment() /*&& StringHelper.isNotEmpty( frag )*/ ) {
+			String fromFragment = processFromFragment( frag, join );
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Using FROM fragment [" + fromFragment + "]" );
+			}
+			fromElement.setText( fromFragment.trim() ); // Set the text of the fromElement.
+		}
+		andFactory.addWhereFragment( joinFragment, whereFrag, query, fromElement );
+	}
+
+	private String processFromFragment(String frag, JoinSequence join) {
+		String fromFragment = frag.trim();
+		// The FROM fragment will probably begin with ', '.  Remove this if it is present.
+		if ( fromFragment.startsWith( ", " ) ) {
+			fromFragment = fromFragment.substring( 2 );
+		}
+		return fromFragment;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,297 +0,0 @@
-// $Id: LiteralProcessor.java 11257 2007-03-07 22:39:25Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.util;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.antlr.SqlTokenTypes;
-import org.hibernate.hql.ast.HqlSqlWalker;
-import org.hibernate.hql.ast.InvalidPathException;
-import org.hibernate.hql.ast.tree.DotNode;
-import org.hibernate.hql.ast.tree.FromClause;
-import org.hibernate.hql.ast.tree.IdentNode;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.InFragment;
-import org.hibernate.type.LiteralType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ReflectHelper;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigDecimal;
-import java.text.DecimalFormat;
-
-/**
- * A delegate that handles literals and constants for HqlSqlWalker, performing the token replacement functions and
- * classifying literals.
- *
- * @author josh Sep 2, 2004 7:15:30 AM
- */
-public class LiteralProcessor implements HqlSqlTokenTypes {
-	/**
-	 * Indicates that Float and Double literal values should
-	 * be treated using the SQL "exact" format (i.e., '.001')
-	 */
-	public static final int EXACT = 0;
-	/**
-	 * Indicates that Float and Double literal values should
-	 * be treated using the SQL "approximate" format (i.e., '1E-3')
-	 */
-	public static final int APPROXIMATE = 1;
-	/**
-	 * In what format should Float and Double literal values be sent
-	 * to the database?
-	 * @see #EXACT, #APPROXIMATE
-	 */
-	public static int DECIMAL_LITERAL_FORMAT = EXACT;
-
-	private static final Logger log = LoggerFactory.getLogger( LiteralProcessor.class );
-
-	private HqlSqlWalker walker;
-
-	public LiteralProcessor(HqlSqlWalker hqlSqlWalker) {
-		this.walker = hqlSqlWalker;
-	}
-
-	public boolean isAlias(String alias) {
-		FromClause from = walker.getCurrentFromClause();
-		while ( from.isSubQuery() ) {
-			if ( from.containsClassAlias(alias) ) {
-				return true;
-			}
-			from = from.getParentFromClause();
-		}
-		return from.containsClassAlias(alias);
-	}
-
-	public void processConstant(AST constant, boolean resolveIdent) throws SemanticException {
-		// If the constant is an IDENT, figure out what it means...
-		boolean isIdent = ( constant.getType() == IDENT || constant.getType() == WEIRD_IDENT );
-		if ( resolveIdent && isIdent && isAlias( constant.getText() ) ) { // IDENT is a class alias in the FROM.
-			IdentNode ident = ( IdentNode ) constant;
-			// Resolve to an identity column.
-			ident.resolve(false, true);
-		}
-		else {	// IDENT might be the name of a class.
-			Queryable queryable = walker.getSessionFactoryHelper().findQueryableUsingImports( constant.getText() );
-			if ( isIdent && queryable != null ) {
-				constant.setText( queryable.getDiscriminatorSQLValue() );
-			}
-			// Otherwise, it's a literal.
-			else {
-				processLiteral( constant );
-			}
-		}
-	}
-
-	public void lookupConstant(DotNode node) throws SemanticException {
-		String text = ASTUtil.getPathText( node );
-		Queryable persister = walker.getSessionFactoryHelper().findQueryableUsingImports( text );
-		if ( persister != null ) {
-			// the name of an entity class
-			final String discrim = persister.getDiscriminatorSQLValue();
-			node.setDataType( persister.getDiscriminatorType() );
-			if ( InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim) ) {
-				throw new InvalidPathException( "subclass test not allowed for null or not null discriminator: '" + text + "'" );
-			}
-			else {
-				setSQLValue( node, text, discrim ); //the class discriminator value
-			}
-		}
-		else {
-			Object value = ReflectHelper.getConstantValue( text );
-			if ( value == null ) {
-				throw new InvalidPathException( "Invalid path: '" + text + "'" );
-			}
-			else {
-				setConstantValue( node, text, value );
-			}
-		}
-	}
-
-	private void setSQLValue(DotNode node, String text, String value) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "setSQLValue() " + text + " -> " + value );
-		}
-		node.setFirstChild( null );	// Chop off the rest of the tree.
-		node.setType( SqlTokenTypes.SQL_TOKEN );
-		node.setText(value);
-		node.setResolvedConstant( text );
-	}
-
-	private void setConstantValue(DotNode node, String text, Object value) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "setConstantValue() " + text + " -> " + value + " " + value.getClass().getName() );
-		}
-		node.setFirstChild( null );	// Chop off the rest of the tree.
-		if ( value instanceof String ) {
-			node.setType( SqlTokenTypes.QUOTED_STRING );
-		}
-		else if ( value instanceof Character ) {
-			node.setType( SqlTokenTypes.QUOTED_STRING );
-		}
-		else if ( value instanceof Byte ) {
-			node.setType( SqlTokenTypes.NUM_INT );
-		}
-		else if ( value instanceof Short ) {
-			node.setType( SqlTokenTypes.NUM_INT );
-		}
-		else if ( value instanceof Integer ) {
-			node.setType( SqlTokenTypes.NUM_INT );
-		}
-		else if ( value instanceof Long ) {
-			node.setType( SqlTokenTypes.NUM_LONG );
-		}
-		else if ( value instanceof Double ) {
-			node.setType( SqlTokenTypes.NUM_DOUBLE );
-		}
-		else if ( value instanceof Float ) {
-			node.setType( SqlTokenTypes.NUM_FLOAT );
-		}
-		else {
-			node.setType( SqlTokenTypes.CONSTANT );
-		}
-		Type type;
-		try {
-			type = TypeFactory.heuristicType( value.getClass().getName() );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-		if ( type == null ) {
-			throw new QueryException( QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + node.getText() );
-		}
-		try {
-			LiteralType literalType = ( LiteralType ) type;
-			Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
-			node.setText( literalType.objectToSQLString( value, dialect ) );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + node.getText(), e );
-		}
-		node.setDataType( type );
-		node.setResolvedConstant( text );
-	}
-
-	public void processBoolean(AST constant) {
-		// TODO: something much better - look at the type of the other expression!
-		// TODO: Have comparisonExpression and/or arithmeticExpression rules complete the resolution of boolean nodes.
-		String replacement = ( String ) walker.getTokenReplacements().get( constant.getText() );
-		if ( replacement != null ) {
-			constant.setText( replacement );
-		}
-		else {
-			boolean bool = "true".equals( constant.getText().toLowerCase() );
-			Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
-			constant.setText( dialect.toBooleanValueString(bool) );
-		}
-	}
-
-	private void processLiteral(AST constant) {
-		String replacement = ( String ) walker.getTokenReplacements().get( constant.getText() );
-		if ( replacement != null ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "processConstant() : Replacing '" + constant.getText() + "' with '" + replacement + "'" );
-			}
-			constant.setText( replacement );
-		}
-	}
-
-	public void processNumeric(AST literal) {
-		if ( literal.getType() == NUM_INT || literal.getType() == NUM_LONG ) {
-			literal.setText( determineIntegerRepresentation( literal.getText(), literal.getType() ) );
-		}
-		else if ( literal.getType() == NUM_FLOAT || literal.getType() == NUM_DOUBLE ) {
-			literal.setText( determineDecimalRepresentation( literal.getText(), literal.getType() ) );
-		}
-		else {
-			log.warn( "Unexpected literal token type [" + literal.getType() + "] passed for numeric processing" );
-		}
-	}
-
-	private String determineIntegerRepresentation(String text, int type) {
-		try {
-			if ( type == NUM_INT ) {
-				try {
-					return Integer.valueOf( text ).toString();
-				}
-				catch( NumberFormatException e ) {
-					log.trace( "could not format incoming text [" + text + "] as a NUM_INT; assuming numeric overflow and attempting as NUM_LONG" );
-				}
-			}
-			String literalValue = text;
-			if ( literalValue.endsWith( "l" ) || literalValue.endsWith( "L" ) ) {
-				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
-			}
-			return Long.valueOf( literalValue ).toString();
-		}
-		catch( Throwable t ) {
-			throw new HibernateException( "Could not parse literal [" + text + "] as integer", t );
-		}
-	}
-
-	public String determineDecimalRepresentation(String text, int type) {
-		String literalValue = text;
-		if ( type == NUM_FLOAT ) {
-			if ( literalValue.endsWith( "f" ) || literalValue.endsWith( "F" ) ) {
-				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
-			}
-		}
-		else if ( type == NUM_DOUBLE ) {
-			if ( literalValue.endsWith( "d" ) || literalValue.endsWith( "D" ) ) {
-				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
-			}
-		}
-
-		BigDecimal number = null;
-		try {
-			number = new BigDecimal( literalValue );
-		}
-		catch( Throwable t ) {
-			throw new HibernateException( "Could not parse literal [" + text + "] as big-decimal", t );
-		}
-
-		return formatters[ DECIMAL_LITERAL_FORMAT ].format( number );
-	}
-
-	private static interface DecimalFormatter {
-		String format(BigDecimal number);
-	}
-
-	private static class ExactDecimalFormatter implements DecimalFormatter {
-		public String format(BigDecimal number) {
-			return number.toString();
-		}
-	}
-
-	private static class ApproximateDecimalFormatter implements DecimalFormatter {
-		private static final String FORMAT_STRING = "#0.0E0";
-		public String format(BigDecimal number) {
-			try {
-				// TODO : what amount of significant digits need to be supported here?
-				//      - from the DecimalFormat docs:
-				//          [significant digits] = [minimum integer digits] + [maximum fraction digits]
-				DecimalFormat jdkFormatter = new DecimalFormat( FORMAT_STRING );
-				jdkFormatter.setMinimumIntegerDigits( 1 );
-				jdkFormatter.setMaximumFractionDigits( Integer.MAX_VALUE );
-				return jdkFormatter.format( number );
-			}
-			catch( Throwable t ) {
-				throw new HibernateException( "Unable to format decimal literal in approximate format [" + number.toString() + "]", t );
-			}
-		}
-	}
-
-	private static final DecimalFormatter[] formatters = new DecimalFormatter[] {
-			new ExactDecimalFormatter(),
-			new ApproximateDecimalFormatter()
-	};
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/LiteralProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,320 @@
+/*
+ * 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.util;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.antlr.SqlTokenTypes;
+import org.hibernate.hql.ast.HqlSqlWalker;
+import org.hibernate.hql.ast.InvalidPathException;
+import org.hibernate.hql.ast.tree.DotNode;
+import org.hibernate.hql.ast.tree.FromClause;
+import org.hibernate.hql.ast.tree.IdentNode;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.InFragment;
+import org.hibernate.type.LiteralType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ReflectHelper;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+
+/**
+ * A delegate that handles literals and constants for HqlSqlWalker, performing the token replacement functions and
+ * classifying literals.
+ *
+ * @author josh
+ */
+public class LiteralProcessor implements HqlSqlTokenTypes {
+	/**
+	 * Indicates that Float and Double literal values should
+	 * be treated using the SQL "exact" format (i.e., '.001')
+	 */
+	public static final int EXACT = 0;
+	/**
+	 * Indicates that Float and Double literal values should
+	 * be treated using the SQL "approximate" format (i.e., '1E-3')
+	 */
+	public static final int APPROXIMATE = 1;
+	/**
+	 * In what format should Float and Double literal values be sent
+	 * to the database?
+	 * @see #EXACT, #APPROXIMATE
+	 */
+	public static int DECIMAL_LITERAL_FORMAT = EXACT;
+
+	private static final Logger log = LoggerFactory.getLogger( LiteralProcessor.class );
+
+	private HqlSqlWalker walker;
+
+	public LiteralProcessor(HqlSqlWalker hqlSqlWalker) {
+		this.walker = hqlSqlWalker;
+	}
+
+	public boolean isAlias(String alias) {
+		FromClause from = walker.getCurrentFromClause();
+		while ( from.isSubQuery() ) {
+			if ( from.containsClassAlias(alias) ) {
+				return true;
+			}
+			from = from.getParentFromClause();
+		}
+		return from.containsClassAlias(alias);
+	}
+
+	public void processConstant(AST constant, boolean resolveIdent) throws SemanticException {
+		// If the constant is an IDENT, figure out what it means...
+		boolean isIdent = ( constant.getType() == IDENT || constant.getType() == WEIRD_IDENT );
+		if ( resolveIdent && isIdent && isAlias( constant.getText() ) ) { // IDENT is a class alias in the FROM.
+			IdentNode ident = ( IdentNode ) constant;
+			// Resolve to an identity column.
+			ident.resolve(false, true);
+		}
+		else {	// IDENT might be the name of a class.
+			Queryable queryable = walker.getSessionFactoryHelper().findQueryableUsingImports( constant.getText() );
+			if ( isIdent && queryable != null ) {
+				constant.setText( queryable.getDiscriminatorSQLValue() );
+			}
+			// Otherwise, it's a literal.
+			else {
+				processLiteral( constant );
+			}
+		}
+	}
+
+	public void lookupConstant(DotNode node) throws SemanticException {
+		String text = ASTUtil.getPathText( node );
+		Queryable persister = walker.getSessionFactoryHelper().findQueryableUsingImports( text );
+		if ( persister != null ) {
+			// the name of an entity class
+			final String discrim = persister.getDiscriminatorSQLValue();
+			node.setDataType( persister.getDiscriminatorType() );
+			if ( InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim) ) {
+				throw new InvalidPathException( "subclass test not allowed for null or not null discriminator: '" + text + "'" );
+			}
+			else {
+				setSQLValue( node, text, discrim ); //the class discriminator value
+			}
+		}
+		else {
+			Object value = ReflectHelper.getConstantValue( text );
+			if ( value == null ) {
+				throw new InvalidPathException( "Invalid path: '" + text + "'" );
+			}
+			else {
+				setConstantValue( node, text, value );
+			}
+		}
+	}
+
+	private void setSQLValue(DotNode node, String text, String value) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "setSQLValue() " + text + " -> " + value );
+		}
+		node.setFirstChild( null );	// Chop off the rest of the tree.
+		node.setType( SqlTokenTypes.SQL_TOKEN );
+		node.setText(value);
+		node.setResolvedConstant( text );
+	}
+
+	private void setConstantValue(DotNode node, String text, Object value) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "setConstantValue() " + text + " -> " + value + " " + value.getClass().getName() );
+		}
+		node.setFirstChild( null );	// Chop off the rest of the tree.
+		if ( value instanceof String ) {
+			node.setType( SqlTokenTypes.QUOTED_STRING );
+		}
+		else if ( value instanceof Character ) {
+			node.setType( SqlTokenTypes.QUOTED_STRING );
+		}
+		else if ( value instanceof Byte ) {
+			node.setType( SqlTokenTypes.NUM_INT );
+		}
+		else if ( value instanceof Short ) {
+			node.setType( SqlTokenTypes.NUM_INT );
+		}
+		else if ( value instanceof Integer ) {
+			node.setType( SqlTokenTypes.NUM_INT );
+		}
+		else if ( value instanceof Long ) {
+			node.setType( SqlTokenTypes.NUM_LONG );
+		}
+		else if ( value instanceof Double ) {
+			node.setType( SqlTokenTypes.NUM_DOUBLE );
+		}
+		else if ( value instanceof Float ) {
+			node.setType( SqlTokenTypes.NUM_FLOAT );
+		}
+		else {
+			node.setType( SqlTokenTypes.CONSTANT );
+		}
+		Type type;
+		try {
+			type = TypeFactory.heuristicType( value.getClass().getName() );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+		if ( type == null ) {
+			throw new QueryException( QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + node.getText() );
+		}
+		try {
+			LiteralType literalType = ( LiteralType ) type;
+			Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
+			node.setText( literalType.objectToSQLString( value, dialect ) );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + node.getText(), e );
+		}
+		node.setDataType( type );
+		node.setResolvedConstant( text );
+	}
+
+	public void processBoolean(AST constant) {
+		// TODO: something much better - look at the type of the other expression!
+		// TODO: Have comparisonExpression and/or arithmeticExpression rules complete the resolution of boolean nodes.
+		String replacement = ( String ) walker.getTokenReplacements().get( constant.getText() );
+		if ( replacement != null ) {
+			constant.setText( replacement );
+		}
+		else {
+			boolean bool = "true".equals( constant.getText().toLowerCase() );
+			Dialect dialect = walker.getSessionFactoryHelper().getFactory().getDialect();
+			constant.setText( dialect.toBooleanValueString(bool) );
+		}
+	}
+
+	private void processLiteral(AST constant) {
+		String replacement = ( String ) walker.getTokenReplacements().get( constant.getText() );
+		if ( replacement != null ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "processConstant() : Replacing '" + constant.getText() + "' with '" + replacement + "'" );
+			}
+			constant.setText( replacement );
+		}
+	}
+
+	public void processNumeric(AST literal) {
+		if ( literal.getType() == NUM_INT || literal.getType() == NUM_LONG ) {
+			literal.setText( determineIntegerRepresentation( literal.getText(), literal.getType() ) );
+		}
+		else if ( literal.getType() == NUM_FLOAT || literal.getType() == NUM_DOUBLE ) {
+			literal.setText( determineDecimalRepresentation( literal.getText(), literal.getType() ) );
+		}
+		else {
+			log.warn( "Unexpected literal token type [" + literal.getType() + "] passed for numeric processing" );
+		}
+	}
+
+	private String determineIntegerRepresentation(String text, int type) {
+		try {
+			if ( type == NUM_INT ) {
+				try {
+					return Integer.valueOf( text ).toString();
+				}
+				catch( NumberFormatException e ) {
+					log.trace( "could not format incoming text [" + text + "] as a NUM_INT; assuming numeric overflow and attempting as NUM_LONG" );
+				}
+			}
+			String literalValue = text;
+			if ( literalValue.endsWith( "l" ) || literalValue.endsWith( "L" ) ) {
+				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
+			}
+			return Long.valueOf( literalValue ).toString();
+		}
+		catch( Throwable t ) {
+			throw new HibernateException( "Could not parse literal [" + text + "] as integer", t );
+		}
+	}
+
+	public String determineDecimalRepresentation(String text, int type) {
+		String literalValue = text;
+		if ( type == NUM_FLOAT ) {
+			if ( literalValue.endsWith( "f" ) || literalValue.endsWith( "F" ) ) {
+				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
+			}
+		}
+		else if ( type == NUM_DOUBLE ) {
+			if ( literalValue.endsWith( "d" ) || literalValue.endsWith( "D" ) ) {
+				literalValue = literalValue.substring( 0, literalValue.length() - 1 );
+			}
+		}
+
+		BigDecimal number = null;
+		try {
+			number = new BigDecimal( literalValue );
+		}
+		catch( Throwable t ) {
+			throw new HibernateException( "Could not parse literal [" + text + "] as big-decimal", t );
+		}
+
+		return formatters[ DECIMAL_LITERAL_FORMAT ].format( number );
+	}
+
+	private static interface DecimalFormatter {
+		String format(BigDecimal number);
+	}
+
+	private static class ExactDecimalFormatter implements DecimalFormatter {
+		public String format(BigDecimal number) {
+			return number.toString();
+		}
+	}
+
+	private static class ApproximateDecimalFormatter implements DecimalFormatter {
+		private static final String FORMAT_STRING = "#0.0E0";
+		public String format(BigDecimal number) {
+			try {
+				// TODO : what amount of significant digits need to be supported here?
+				//      - from the DecimalFormat docs:
+				//          [significant digits] = [minimum integer digits] + [maximum fraction digits]
+				DecimalFormat jdkFormatter = new DecimalFormat( FORMAT_STRING );
+				jdkFormatter.setMinimumIntegerDigits( 1 );
+				jdkFormatter.setMaximumFractionDigits( Integer.MAX_VALUE );
+				return jdkFormatter.format( number );
+			}
+			catch( Throwable t ) {
+				throw new HibernateException( "Unable to format decimal literal in approximate format [" + number.toString() + "]", t );
+			}
+		}
+	}
+
+	private static final DecimalFormatter[] formatters = new DecimalFormatter[] {
+			new ExactDecimalFormatter(),
+			new ApproximateDecimalFormatter()
+	};
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-package org.hibernate.hql.ast.util;
-
-import antlr.collections.AST;
-
-/**
- * A visitor for traversing an AST tree.
- *
- * @author Steve Ebersole
- */
-public class NodeTraverser {
-	public static interface VisitationStrategy {
-		public void visit(AST node);
-	}
-
-	private final VisitationStrategy strategy;
-
-	public NodeTraverser(VisitationStrategy strategy) {
-		this.strategy = strategy;
-	}
-
-	/**
-	 * Traverse the AST tree depth first.
-	 * <p/>
-	 * Note that the AST passed in is not visited itself.  Visitation starts
-	 * with its children.
-	 *
-	 * @param ast
-	 */
-	public void traverseDepthFirst(AST ast) {
-		if ( ast == null ) {
-			throw new IllegalArgumentException( "node to traverse cannot be null!" );
-		}
-		visitDepthFirst( ast.getFirstChild() );
-	}
-
-	private void visitDepthFirst(AST ast) {
-		if ( ast == null ) {
-			return;
-		}
-		strategy.visit( ast );
-		visitDepthFirst( ast.getFirstChild() );
-		visitDepthFirst( ast.getNextSibling() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/NodeTraverser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.util;
+
+import antlr.collections.AST;
+
+/**
+ * A visitor for traversing an AST tree.
+ *
+ * @author Steve Ebersole
+ */
+public class NodeTraverser {
+	public static interface VisitationStrategy {
+		public void visit(AST node);
+	}
+
+	private final VisitationStrategy strategy;
+
+	public NodeTraverser(VisitationStrategy strategy) {
+		this.strategy = strategy;
+	}
+
+	/**
+	 * Traverse the AST tree depth first.
+	 * <p/>
+	 * Note that the AST passed in is not visited itself.  Visitation starts
+	 * with its children.
+	 *
+	 * @param ast
+	 */
+	public void traverseDepthFirst(AST ast) {
+		if ( ast == null ) {
+			throw new IllegalArgumentException( "node to traverse cannot be null!" );
+		}
+		visitDepthFirst( ast.getFirstChild() );
+	}
+
+	private void visitDepthFirst(AST ast) {
+		if ( ast == null ) {
+			return;
+		}
+		strategy.visit( ast );
+		visitDepthFirst( ast.getFirstChild() );
+		visitDepthFirst( ast.getNextSibling() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-// $Id: PathHelper.java 7460 2005-07-12 20:27:29Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.util.StringHelper;
-
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides utility methods for paths.
- *
- * @author josh Sep 14, 2004 8:16:29 AM
- */
-public final class PathHelper {
-
-	private static final Logger log = LoggerFactory.getLogger( PathHelper.class );
-
-	private PathHelper() {
-	}
-
-	/**
-	 * Turns a path into an AST.
-	 *
-	 * @param path    The path.
-	 * @param factory The AST factory to use.
-	 * @return An HQL AST representing the path.
-	 */
-	public static AST parsePath(String path, ASTFactory factory) {
-		String[] identifiers = StringHelper.split( ".", path );
-		AST lhs = null;
-		for ( int i = 0; i < identifiers.length; i++ ) {
-			String identifier = identifiers[i];
-			AST child = ASTUtil.create( factory, HqlSqlTokenTypes.IDENT, identifier );
-			if ( i == 0 ) {
-				lhs = child;
-			}
-			else {
-				lhs = ASTUtil.createBinarySubtree( factory, HqlSqlTokenTypes.DOT, ".", lhs, child );
-			}
-		}
-		if ( log.isDebugEnabled() ) {
-			log.debug( "parsePath() : " + path + " -> " + ASTUtil.getDebugString( lhs ) );
-		}
-		return lhs;
-	}
-
-	public static String getAlias(String path) {
-		return StringHelper.root( path );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/PathHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.ast.util;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.util.StringHelper;
+
+import antlr.ASTFactory;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides utility methods for paths.
+ *
+ * @author josh
+ */
+public final class PathHelper {
+
+	private static final Logger log = LoggerFactory.getLogger( PathHelper.class );
+
+	private PathHelper() {
+	}
+
+	/**
+	 * Turns a path into an AST.
+	 *
+	 * @param path    The path.
+	 * @param factory The AST factory to use.
+	 * @return An HQL AST representing the path.
+	 */
+	public static AST parsePath(String path, ASTFactory factory) {
+		String[] identifiers = StringHelper.split( ".", path );
+		AST lhs = null;
+		for ( int i = 0; i < identifiers.length; i++ ) {
+			String identifier = identifiers[i];
+			AST child = ASTUtil.create( factory, HqlSqlTokenTypes.IDENT, identifier );
+			if ( i == 0 ) {
+				lhs = child;
+			}
+			else {
+				lhs = ASTUtil.createBinarySubtree( factory, HqlSqlTokenTypes.DOT, ".", lhs, child );
+			}
+		}
+		if ( log.isDebugEnabled() ) {
+			log.debug( "parsePath() : " + path + " -> " + ASTUtil.getDebugString( lhs ) );
+		}
+		return lhs;
+	}
+
+	public static String getAlias(String path) {
+		return StringHelper.root( path );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,392 +0,0 @@
-// $Id: SessionFactoryHelper.java 10824 2006-11-16 19:32:48Z steve.ebersole at jboss.com $
-package org.hibernate.hql.ast.util;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.NameGenerator;
-import org.hibernate.hql.ast.DetailedSemanticException;
-import org.hibernate.hql.ast.QuerySyntaxException;
-import org.hibernate.hql.ast.tree.SqlNode;
-import org.hibernate.persister.collection.CollectionPropertyMapping;
-import org.hibernate.persister.collection.CollectionPropertyNames;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-import antlr.SemanticException;
-import antlr.collections.AST;
-
-/**
- * Helper for performing common and/or complex operations with the
- * {@link SessionFactoryImplementor} during translation of an HQL query.
- *
- * @author Joshua Davis
- */
-public class SessionFactoryHelper {
-
-	private SessionFactoryImplementor sfi;
-	private Map collectionPropertyMappingByRole;
-
-	/**
-	 * Construct a new SessionFactoryHelper instance.
-	 *
-	 * @param sfi The SessionFactory impl to be encapsualted.
-	 */
-	public SessionFactoryHelper(SessionFactoryImplementor sfi) {
-		this.sfi = sfi;
-		collectionPropertyMappingByRole = new HashMap();
-	}
-
-	/**
-	 * Get a handle to the encapsulated SessionFactory.
-	 *
-	 * @return The encapsulated SessionFactory.
-	 */
-	public SessionFactoryImplementor getFactory() {
-		return sfi;
-	}
-
-	/**
-	 * Does the given persister define a physical discriminator column
-	 * for the purpose of inheritence discrimination?
-	 *
-	 * @param persister The persister to be checked.
-	 * @return True if the persister does define an actual discriminator column.
-	 */
-	public boolean hasPhysicalDiscriminatorColumn(Queryable persister) {
-		if ( persister.getDiscriminatorType() != null ) {
-			String discrimColumnName = persister.getDiscriminatorColumnName();
-			// Needed the "clazz_" check to work around union-subclasses
-			// TODO : is there a way to tell whether a persister is truly discrim-column based inheritence?
-			if ( discrimColumnName != null && !"clazz_".equals( discrimColumnName ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	/**
-	 * Given a (potentially unqualified) class name, locate its imported qualified name.
-	 *
-	 * @param className The potentially unqualified class name
-	 * @return The qualified class name.
-	 */
-	public String getImportedClassName(String className) {
-		return sfi.getImportedClassName( className );
-	}
-
-	/**
-	 * Given a (potentially unqualified) class name, locate its persister.
-	 *
-	 * @param className The (potentially unqualified) class name.
-	 * @return The defined persister for this class, or null if none found.
-	 */
-	public Queryable findQueryableUsingImports(String className) {
-		return findQueryableUsingImports( sfi, className );
-	}
-
-
-	/**
-	 * Given a (potentially unqualified) class name, locate its persister.
-	 *
-	 * @param sfi The session factory implementor.
-	 * @param className The (potentially unqualified) class name.
-	 * @return The defined persister for this class, or null if none found.
-	 */
-	public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) {
-		final String importedClassName = sfi.getImportedClassName( className );
-		if ( importedClassName == null ) {
-			return null;
-		}
-		try {
-			return ( Queryable ) sfi.getEntityPersister( importedClassName );
-		}
-		catch ( MappingException me ) {
-			return null;
-		}
-	}
-
-	/**
-	 * Locate the persister by class or entity name.
-	 *
-	 * @param name The class or entity name
-	 * @return The defined persister for this entity, or null if none found.
-	 * @throws MappingException
-	 */
-	private EntityPersister findEntityPersisterByName(String name) throws MappingException {
-		// First, try to get the persister using the given name directly.
-		try {
-			return sfi.getEntityPersister( name );
-		}
-		catch ( MappingException ignore ) {
-			// unable to locate it using this name
-		}
-
-		// If that didn't work, try using the 'import' name.
-		String importedClassName = sfi.getImportedClassName( name );
-		if ( importedClassName == null ) {
-			return null;
-		}
-		return sfi.getEntityPersister( importedClassName );
-	}
-
-	/**
-	 * Locate the persister by class or entity name, requiring that such a persister
-	 * exist.
-	 *
-	 * @param name The class or entity name
-	 * @return The defined persister for this entity
-	 * @throws SemanticException Indicates the persister could not be found
-	 */
-	public EntityPersister requireClassPersister(String name) throws SemanticException {
-		EntityPersister cp;
-		try {
-			cp = findEntityPersisterByName( name );
-			if ( cp == null ) {
-				throw new QuerySyntaxException( name + " is not mapped" );
-			}
-		}
-		catch ( MappingException e ) {
-			throw new DetailedSemanticException( e.getMessage(), e );
-		}
-		return cp;
-	}
-
-	/**
-	 * Locate the collection persister by the collection role.
-	 *
-	 * @param role The collection role name.
-	 * @return The defined CollectionPersister for this collection role, or null.
-	 */
-	public QueryableCollection getCollectionPersister(String role) {
-		try {
-			return ( QueryableCollection ) sfi.getCollectionPersister( role );
-		}
-		catch ( ClassCastException cce ) {
-			throw new QueryException( "collection is not queryable: " + role );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( "collection not found: " + role );
-		}
-	}
-
-	/**
-	 * Locate the collection persister by the collection role, requiring that
-	 * such a persister exist.
-	 *
-	 * @param role The collection role name.
-	 * @return The defined CollectionPersister for this collection role.
-	 * @throws QueryException Indicates that the collection persister could not be found.
-	 */
-	public QueryableCollection requireQueryableCollection(String role) throws QueryException {
-		try {
-			QueryableCollection queryableCollection = ( QueryableCollection ) sfi.getCollectionPersister( role );
-			if ( queryableCollection != null ) {
-				collectionPropertyMappingByRole.put( role, new CollectionPropertyMapping( queryableCollection ) );
-			}
-			return queryableCollection;
-		}
-		catch ( ClassCastException cce ) {
-			throw new QueryException( "collection role is not queryable: " + role );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( "collection role not found: " + role );
-		}
-	}
-
-	/**
-	 * Retreive a PropertyMapping describing the given collection role.
-	 *
-	 * @param role The collection role for whcih to retrieve the property mapping.
-	 * @return The property mapping.
-	 */
-	private PropertyMapping getCollectionPropertyMapping(String role) {
-		return ( PropertyMapping ) collectionPropertyMappingByRole.get( role );
-	}
-
-	/**
-	 * Retrieves the column names corresponding to the collection elements for the given
-	 * collection role.
-	 *
-	 * @param role The collection role
-	 * @param roleAlias The sql column-qualification alias (i.e., the table alias)
-	 * @return the collection element columns
-	 */
-	public String[] getCollectionElementColumns(String role, String roleAlias) {
-		return getCollectionPropertyMapping( role ).toColumns( roleAlias, CollectionPropertyNames.COLLECTION_ELEMENTS );
-	}
-
-	/**
-	 * Generate an empty join sequence instance.
-	 *
-	 * @return The generate join sequence.
-	 */
-	public JoinSequence createJoinSequence() {
-		return new JoinSequence( sfi );
-	}
-
-	/**
-	 * Generate a join sequence representing the given association type.
-	 *
-	 * @param implicit Should implicit joins (theta-style) or explicit joins (ANSI-style) be rendered
-	 * @param associationType The type representing the thing to be joined into.
-	 * @param tableAlias The table alias to use in qualifing the join conditions
-	 * @param joinType The type of join to render (inner, outer, etc);  see {@link org.hibernate.sql.JoinFragment}
-	 * @param columns The columns making up the condition of the join.
-	 * @return The generated join sequence.
-	 */
-	public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, int joinType, String[] columns) {
-		JoinSequence joinSequence = createJoinSequence();
-		joinSequence.setUseThetaStyle( implicit );	// Implicit joins use theta style (WHERE pk = fk), explicit joins use JOIN (after from)
-		joinSequence.addJoin( associationType, tableAlias, joinType, columns );
-		return joinSequence;
-	}
-
-	/**
-	 * Create a join sequence rooted at the given collection.
-	 *
-	 * @param collPersister The persister for the collection at which the join should be rooted.
-	 * @param collectionName The alias to use for qualifying column references.
-	 * @return The generated join sequence.
-	 */
-	public JoinSequence createCollectionJoinSequence(QueryableCollection collPersister, String collectionName) {
-		JoinSequence joinSequence = createJoinSequence();
-		joinSequence.setRoot( collPersister, collectionName );
-		joinSequence.setUseThetaStyle( true );		// TODO: figure out how this should be set.
-///////////////////////////////////////////////////////////////////////////////
-// This was the reason for failures regarding INDEX_OP and subclass joins on
-// theta-join dialects; not sure what behaviour we were trying to emulate ;)
-//		joinSequence = joinSequence.getFromPart();	// Emulate the old addFromOnly behavior.
-		return joinSequence;
-	}
-
-	/**
-	 * Determine the name of the property for the entity encapsulated by the
-	 * given type which represents the id or unique-key.
-	 *
-	 * @param entityType The type representing the entity.
-	 * @return The corresponding property name
-	 * @throws QueryException Indicates such a property could not be found.
-	 */
-	public String getIdentifierOrUniqueKeyPropertyName(EntityType entityType) {
-		try {
-			return entityType.getIdentifierOrUniqueKeyPropertyName( sfi );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-
-	/**
-	 * Retreive the number of columns represented by this type.
-	 *
-	 * @param type The type.
-	 * @return The number of columns.
-	 */
-	public int getColumnSpan(Type type) {
-		return type.getColumnSpan( sfi );
-	}
-
-	/**
-	 * Given a collection type, determine the entity name of the elements
-	 * contained within instance of that collection.
-	 *
-	 * @param collectionType The collection type to check.
-	 * @return The entity name of the elements of this collection.
-	 */
-	public String getAssociatedEntityName(CollectionType collectionType) {
-		return collectionType.getAssociatedEntityName( sfi );
-	}
-
-	/**
-	 * Given a collection type, determine the Type representing elements
-	 * within instances of that collection.
-	 *
-	 * @param collectionType The collection type to be checked.
-	 * @return The Type of the elements of the collection.
-	 */
-	private Type getElementType(CollectionType collectionType) {
-		return collectionType.getElementType( sfi );
-	}
-
-	/**
-	 * Essentially the same as {@link #getElementType}, but requiring that the
-	 * element type be an association type.
-	 *
-	 * @param collectionType The collection type to be checked.
-	 * @return The AssociationType of the elements of the collection.
-	 */
-	public AssociationType getElementAssociationType(CollectionType collectionType) {
-		return ( AssociationType ) getElementType( collectionType );
-	}
-
-	/**
-	 * Locate a registered sql function by name.
-	 *
-	 * @param functionName The name of the function to locate
-	 * @return The sql function, or null if not found.
-	 */
-	public SQLFunction findSQLFunction(String functionName) {
-		return sfi.getSqlFunctionRegistry().findSQLFunction( functionName.toLowerCase() );
-	}
-
-	/**
-	 * Locate a registered sql function by name, requiring that such a registered function exist.
-	 *
-	 * @param functionName The name of the function to locate
-	 * @return The sql function.
-	 * @throws QueryException Indicates no matching sql functions could be found.
-	 */
-	private SQLFunction requireSQLFunction(String functionName) {
-		SQLFunction f = findSQLFunction( functionName );
-		if ( f == null ) {
-			throw new QueryException( "Unable to find SQL function: " + functionName );
-		}
-		return f;
-	}
-
-	/**
-	 * Find the function return type given the function name and the first argument expression node.
-	 *
-	 * @param functionName The function name.
-	 * @param first        The first argument expression.
-	 * @return the function return type given the function name and the first argument expression node.
-	 */
-	public Type findFunctionReturnType(String functionName, AST first) {
-		// locate the registered function by the given name
-		SQLFunction sqlFunction = requireSQLFunction( functionName );
-
-		// determine the type of the first argument...
-		Type argumentType = null;
-		if ( first != null ) {
-			if ( "cast".equals(functionName) ) {
-				argumentType = TypeFactory.heuristicType( first.getNextSibling().getText() );
-			}
-			else if ( first instanceof SqlNode ) {
-				argumentType = ( (SqlNode) first ).getDataType();
-			}
-		}
-
-		return sqlFunction.getReturnType( argumentType, sfi );
-	}
-
-	public String[][] generateColumnNames(Type[] sqlResultTypes) {
-		return NameGenerator.generateColumnNames( sqlResultTypes, sfi );
-	}
-
-	public boolean isStrictJPAQLComplianceEnabled() {
-		return sfi.getSettings().isStrictJPAQLCompliance();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SessionFactoryHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,415 @@
+/*
+ * 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.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.NameGenerator;
+import org.hibernate.hql.ast.DetailedSemanticException;
+import org.hibernate.hql.ast.QuerySyntaxException;
+import org.hibernate.hql.ast.tree.SqlNode;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.collection.CollectionPropertyNames;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+import antlr.SemanticException;
+import antlr.collections.AST;
+
+/**
+ * Helper for performing common and/or complex operations with the
+ * {@link SessionFactoryImplementor} during translation of an HQL query.
+ *
+ * @author Joshua Davis
+ */
+public class SessionFactoryHelper {
+
+	private SessionFactoryImplementor sfi;
+	private Map collectionPropertyMappingByRole;
+
+	/**
+	 * Construct a new SessionFactoryHelper instance.
+	 *
+	 * @param sfi The SessionFactory impl to be encapsualted.
+	 */
+	public SessionFactoryHelper(SessionFactoryImplementor sfi) {
+		this.sfi = sfi;
+		collectionPropertyMappingByRole = new HashMap();
+	}
+
+	/**
+	 * Get a handle to the encapsulated SessionFactory.
+	 *
+	 * @return The encapsulated SessionFactory.
+	 */
+	public SessionFactoryImplementor getFactory() {
+		return sfi;
+	}
+
+	/**
+	 * Does the given persister define a physical discriminator column
+	 * for the purpose of inheritence discrimination?
+	 *
+	 * @param persister The persister to be checked.
+	 * @return True if the persister does define an actual discriminator column.
+	 */
+	public boolean hasPhysicalDiscriminatorColumn(Queryable persister) {
+		if ( persister.getDiscriminatorType() != null ) {
+			String discrimColumnName = persister.getDiscriminatorColumnName();
+			// Needed the "clazz_" check to work around union-subclasses
+			// TODO : is there a way to tell whether a persister is truly discrim-column based inheritence?
+			if ( discrimColumnName != null && !"clazz_".equals( discrimColumnName ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Given a (potentially unqualified) class name, locate its imported qualified name.
+	 *
+	 * @param className The potentially unqualified class name
+	 * @return The qualified class name.
+	 */
+	public String getImportedClassName(String className) {
+		return sfi.getImportedClassName( className );
+	}
+
+	/**
+	 * Given a (potentially unqualified) class name, locate its persister.
+	 *
+	 * @param className The (potentially unqualified) class name.
+	 * @return The defined persister for this class, or null if none found.
+	 */
+	public Queryable findQueryableUsingImports(String className) {
+		return findQueryableUsingImports( sfi, className );
+	}
+
+
+	/**
+	 * Given a (potentially unqualified) class name, locate its persister.
+	 *
+	 * @param sfi The session factory implementor.
+	 * @param className The (potentially unqualified) class name.
+	 * @return The defined persister for this class, or null if none found.
+	 */
+	public static Queryable findQueryableUsingImports(SessionFactoryImplementor sfi, String className) {
+		final String importedClassName = sfi.getImportedClassName( className );
+		if ( importedClassName == null ) {
+			return null;
+		}
+		try {
+			return ( Queryable ) sfi.getEntityPersister( importedClassName );
+		}
+		catch ( MappingException me ) {
+			return null;
+		}
+	}
+
+	/**
+	 * Locate the persister by class or entity name.
+	 *
+	 * @param name The class or entity name
+	 * @return The defined persister for this entity, or null if none found.
+	 * @throws MappingException
+	 */
+	private EntityPersister findEntityPersisterByName(String name) throws MappingException {
+		// First, try to get the persister using the given name directly.
+		try {
+			return sfi.getEntityPersister( name );
+		}
+		catch ( MappingException ignore ) {
+			// unable to locate it using this name
+		}
+
+		// If that didn't work, try using the 'import' name.
+		String importedClassName = sfi.getImportedClassName( name );
+		if ( importedClassName == null ) {
+			return null;
+		}
+		return sfi.getEntityPersister( importedClassName );
+	}
+
+	/**
+	 * Locate the persister by class or entity name, requiring that such a persister
+	 * exist.
+	 *
+	 * @param name The class or entity name
+	 * @return The defined persister for this entity
+	 * @throws SemanticException Indicates the persister could not be found
+	 */
+	public EntityPersister requireClassPersister(String name) throws SemanticException {
+		EntityPersister cp;
+		try {
+			cp = findEntityPersisterByName( name );
+			if ( cp == null ) {
+				throw new QuerySyntaxException( name + " is not mapped" );
+			}
+		}
+		catch ( MappingException e ) {
+			throw new DetailedSemanticException( e.getMessage(), e );
+		}
+		return cp;
+	}
+
+	/**
+	 * Locate the collection persister by the collection role.
+	 *
+	 * @param role The collection role name.
+	 * @return The defined CollectionPersister for this collection role, or null.
+	 */
+	public QueryableCollection getCollectionPersister(String role) {
+		try {
+			return ( QueryableCollection ) sfi.getCollectionPersister( role );
+		}
+		catch ( ClassCastException cce ) {
+			throw new QueryException( "collection is not queryable: " + role );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( "collection not found: " + role );
+		}
+	}
+
+	/**
+	 * Locate the collection persister by the collection role, requiring that
+	 * such a persister exist.
+	 *
+	 * @param role The collection role name.
+	 * @return The defined CollectionPersister for this collection role.
+	 * @throws QueryException Indicates that the collection persister could not be found.
+	 */
+	public QueryableCollection requireQueryableCollection(String role) throws QueryException {
+		try {
+			QueryableCollection queryableCollection = ( QueryableCollection ) sfi.getCollectionPersister( role );
+			if ( queryableCollection != null ) {
+				collectionPropertyMappingByRole.put( role, new CollectionPropertyMapping( queryableCollection ) );
+			}
+			return queryableCollection;
+		}
+		catch ( ClassCastException cce ) {
+			throw new QueryException( "collection role is not queryable: " + role );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( "collection role not found: " + role );
+		}
+	}
+
+	/**
+	 * Retreive a PropertyMapping describing the given collection role.
+	 *
+	 * @param role The collection role for whcih to retrieve the property mapping.
+	 * @return The property mapping.
+	 */
+	private PropertyMapping getCollectionPropertyMapping(String role) {
+		return ( PropertyMapping ) collectionPropertyMappingByRole.get( role );
+	}
+
+	/**
+	 * Retrieves the column names corresponding to the collection elements for the given
+	 * collection role.
+	 *
+	 * @param role The collection role
+	 * @param roleAlias The sql column-qualification alias (i.e., the table alias)
+	 * @return the collection element columns
+	 */
+	public String[] getCollectionElementColumns(String role, String roleAlias) {
+		return getCollectionPropertyMapping( role ).toColumns( roleAlias, CollectionPropertyNames.COLLECTION_ELEMENTS );
+	}
+
+	/**
+	 * Generate an empty join sequence instance.
+	 *
+	 * @return The generate join sequence.
+	 */
+	public JoinSequence createJoinSequence() {
+		return new JoinSequence( sfi );
+	}
+
+	/**
+	 * Generate a join sequence representing the given association type.
+	 *
+	 * @param implicit Should implicit joins (theta-style) or explicit joins (ANSI-style) be rendered
+	 * @param associationType The type representing the thing to be joined into.
+	 * @param tableAlias The table alias to use in qualifing the join conditions
+	 * @param joinType The type of join to render (inner, outer, etc);  see {@link org.hibernate.sql.JoinFragment}
+	 * @param columns The columns making up the condition of the join.
+	 * @return The generated join sequence.
+	 */
+	public JoinSequence createJoinSequence(boolean implicit, AssociationType associationType, String tableAlias, int joinType, String[] columns) {
+		JoinSequence joinSequence = createJoinSequence();
+		joinSequence.setUseThetaStyle( implicit );	// Implicit joins use theta style (WHERE pk = fk), explicit joins use JOIN (after from)
+		joinSequence.addJoin( associationType, tableAlias, joinType, columns );
+		return joinSequence;
+	}
+
+	/**
+	 * Create a join sequence rooted at the given collection.
+	 *
+	 * @param collPersister The persister for the collection at which the join should be rooted.
+	 * @param collectionName The alias to use for qualifying column references.
+	 * @return The generated join sequence.
+	 */
+	public JoinSequence createCollectionJoinSequence(QueryableCollection collPersister, String collectionName) {
+		JoinSequence joinSequence = createJoinSequence();
+		joinSequence.setRoot( collPersister, collectionName );
+		joinSequence.setUseThetaStyle( true );		// TODO: figure out how this should be set.
+///////////////////////////////////////////////////////////////////////////////
+// This was the reason for failures regarding INDEX_OP and subclass joins on
+// theta-join dialects; not sure what behaviour we were trying to emulate ;)
+//		joinSequence = joinSequence.getFromPart();	// Emulate the old addFromOnly behavior.
+		return joinSequence;
+	}
+
+	/**
+	 * Determine the name of the property for the entity encapsulated by the
+	 * given type which represents the id or unique-key.
+	 *
+	 * @param entityType The type representing the entity.
+	 * @return The corresponding property name
+	 * @throws QueryException Indicates such a property could not be found.
+	 */
+	public String getIdentifierOrUniqueKeyPropertyName(EntityType entityType) {
+		try {
+			return entityType.getIdentifierOrUniqueKeyPropertyName( sfi );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+
+	/**
+	 * Retreive the number of columns represented by this type.
+	 *
+	 * @param type The type.
+	 * @return The number of columns.
+	 */
+	public int getColumnSpan(Type type) {
+		return type.getColumnSpan( sfi );
+	}
+
+	/**
+	 * Given a collection type, determine the entity name of the elements
+	 * contained within instance of that collection.
+	 *
+	 * @param collectionType The collection type to check.
+	 * @return The entity name of the elements of this collection.
+	 */
+	public String getAssociatedEntityName(CollectionType collectionType) {
+		return collectionType.getAssociatedEntityName( sfi );
+	}
+
+	/**
+	 * Given a collection type, determine the Type representing elements
+	 * within instances of that collection.
+	 *
+	 * @param collectionType The collection type to be checked.
+	 * @return The Type of the elements of the collection.
+	 */
+	private Type getElementType(CollectionType collectionType) {
+		return collectionType.getElementType( sfi );
+	}
+
+	/**
+	 * Essentially the same as {@link #getElementType}, but requiring that the
+	 * element type be an association type.
+	 *
+	 * @param collectionType The collection type to be checked.
+	 * @return The AssociationType of the elements of the collection.
+	 */
+	public AssociationType getElementAssociationType(CollectionType collectionType) {
+		return ( AssociationType ) getElementType( collectionType );
+	}
+
+	/**
+	 * Locate a registered sql function by name.
+	 *
+	 * @param functionName The name of the function to locate
+	 * @return The sql function, or null if not found.
+	 */
+	public SQLFunction findSQLFunction(String functionName) {
+		return sfi.getSqlFunctionRegistry().findSQLFunction( functionName.toLowerCase() );
+	}
+
+	/**
+	 * Locate a registered sql function by name, requiring that such a registered function exist.
+	 *
+	 * @param functionName The name of the function to locate
+	 * @return The sql function.
+	 * @throws QueryException Indicates no matching sql functions could be found.
+	 */
+	private SQLFunction requireSQLFunction(String functionName) {
+		SQLFunction f = findSQLFunction( functionName );
+		if ( f == null ) {
+			throw new QueryException( "Unable to find SQL function: " + functionName );
+		}
+		return f;
+	}
+
+	/**
+	 * Find the function return type given the function name and the first argument expression node.
+	 *
+	 * @param functionName The function name.
+	 * @param first        The first argument expression.
+	 * @return the function return type given the function name and the first argument expression node.
+	 */
+	public Type findFunctionReturnType(String functionName, AST first) {
+		// locate the registered function by the given name
+		SQLFunction sqlFunction = requireSQLFunction( functionName );
+
+		// determine the type of the first argument...
+		Type argumentType = null;
+		if ( first != null ) {
+			if ( "cast".equals(functionName) ) {
+				argumentType = TypeFactory.heuristicType( first.getNextSibling().getText() );
+			}
+			else if ( first instanceof SqlNode ) {
+				argumentType = ( (SqlNode) first ).getDataType();
+			}
+		}
+
+		return sqlFunction.getReturnType( argumentType, sfi );
+	}
+
+	public String[][] generateColumnNames(Type[] sqlResultTypes) {
+		return NameGenerator.generateColumnNames( sqlResultTypes, sfi );
+	}
+
+	public boolean isStrictJPAQLComplianceEnabled() {
+		return sfi.getSettings().isStrictJPAQLCompliance();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,134 +0,0 @@
-// $Id: SyntheticAndFactory.java 8755 2005-12-06 00:18:35Z steveebersole $
-package org.hibernate.hql.ast.util;
-
-import java.util.Map;
-import java.util.StringTokenizer;
-
-import org.hibernate.hql.antlr.HqlSqlTokenTypes;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.hql.ast.tree.RestrictableStatement;
-import org.hibernate.hql.ast.tree.SqlFragment;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.util.StringHelper;
-
-import antlr.ASTFactory;
-import antlr.collections.AST;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Creates synthetic and nodes based on the where fragment part of a JoinSequence.
- *
- * @author josh Dec 5, 2004 12:25:20 PM
- */
-public class SyntheticAndFactory implements HqlSqlTokenTypes {
-	private static final Logger log = LoggerFactory.getLogger( SyntheticAndFactory.class );
-
-	private ASTFactory astFactory;
-	private AST thetaJoins;
-	private AST filters;
-
-	public SyntheticAndFactory(ASTFactory astFactory) {
-		this.astFactory = astFactory;
-	}
-
-	public void addWhereFragment(JoinFragment joinFragment, String whereFragment, QueryNode query, FromElement fromElement) {
-
-		if ( whereFragment == null ) {
-			return;
-		}
-
-		whereFragment = whereFragment.trim();
-		if ( StringHelper.isEmpty( whereFragment ) ) {
-			return;
-		}
-		else if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
-			return;
-		}
-
-		// Forcefully remove leading ands from where fragments; the grammar will
-		// handle adding them
-		if ( whereFragment.startsWith( "and" ) ) {
-			whereFragment = whereFragment.substring( 4 );
-		}
-
-		if ( log.isDebugEnabled() ) log.debug( "Using WHERE fragment [" + whereFragment + "]" );
-
-		SqlFragment fragment = ( SqlFragment ) ASTUtil.create( astFactory, SQL_TOKEN, whereFragment );
-		fragment.setJoinFragment( joinFragment );
-		fragment.setFromElement( fromElement );
-
-		// Filter conditions need to be inserted before the HQL where condition and the
-		// theta join node.  This is because org.hibernate.loader.Loader binds the filter parameters first,
-		// then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
-		if ( fragment.getFromElement().isFilter() || fragment.hasFilterCondition() ) {
-			if ( filters == null ) {
-				// Find or create the WHERE clause
-				AST where = query.getWhereClause();
-				// Create a new FILTERS node as a parent of all filters
-				filters = astFactory.create( FILTERS, "{filter conditions}" );
-				// Put the FILTERS node before the HQL condition and theta joins
-				ASTUtil.insertChild( where, filters );
-			}
-			
-			// add the current fragment to the FILTERS node
-			filters.addChild( fragment );
-		}
-		else {
-			if ( thetaJoins == null ) {
-				// Find or create the WHERE clause
-				AST where = query.getWhereClause();
-				// Create a new THETA_JOINS node as a parent of all filters
-				thetaJoins = astFactory.create( THETA_JOINS, "{theta joins}" );
-				// Put the THETA_JOINS node before the HQL condition, after the filters.
-				if (filters==null) {
-					ASTUtil.insertChild( where, thetaJoins );
-				}
-				else {
-					ASTUtil.insertSibling( thetaJoins, filters );
-				}
-			}
-			
-			// add the current fragment to the THETA_JOINS node
-			thetaJoins.addChild(fragment);
-		}
-
-	}
-
-	public void addDiscriminatorWhereFragment(RestrictableStatement statement, Queryable persister, Map enabledFilters, String alias) {
-		String whereFragment = persister.filterFragment( alias, enabledFilters ).trim();
-		if ( "".equals( whereFragment ) ) {
-			return;
-		}
-		if ( whereFragment.startsWith( "and" ) ) {
-			whereFragment = whereFragment.substring( 4 );
-		}
-
-		// Need to parse off the column qualifiers; this is assuming (which is true as of now)
-		// that this is only used from update and delete HQL statement parsing
-		whereFragment = StringHelper.replace( whereFragment, persister.generateFilterConditionAlias( alias ) + ".", "" );
-
-		// Note: this simply constructs a "raw" SQL_TOKEN representing the
-		// where fragment and injects this into the tree.  This "works";
-		// however it is probably not the best long-term solution.
-		//
-		// At some point we probably want to apply an additional grammar to
-		// properly tokenize this where fragment into constituent parts
-		// focused on the operators embedded within the fragment.
-		AST discrimNode = astFactory.create( SQL_TOKEN, whereFragment );
-
-		if ( statement.getWhereClause().getNumberOfChildren() == 0 ) {
-			statement.getWhereClause().setFirstChild( discrimNode );
-		}
-		else {
-			AST and = astFactory.create( AND, "{and}" );
-			AST currentFirstChild = statement.getWhereClause().getFirstChild();
-			and.setFirstChild( discrimNode );
-			and.addChild( currentFirstChild );
-			statement.getWhereClause().setFirstChild( and );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/ast/util/SyntheticAndFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,156 @@
+/*
+ * 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.util;
+
+import java.util.Map;
+
+import org.hibernate.hql.antlr.HqlSqlTokenTypes;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.hql.ast.tree.RestrictableStatement;
+import org.hibernate.hql.ast.tree.SqlFragment;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.util.StringHelper;
+
+import antlr.ASTFactory;
+import antlr.collections.AST;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Creates synthetic and nodes based on the where fragment part of a JoinSequence.
+ *
+ * @author josh
+ */
+public class SyntheticAndFactory implements HqlSqlTokenTypes {
+	private static final Logger log = LoggerFactory.getLogger( SyntheticAndFactory.class );
+
+	private ASTFactory astFactory;
+	private AST thetaJoins;
+	private AST filters;
+
+	public SyntheticAndFactory(ASTFactory astFactory) {
+		this.astFactory = astFactory;
+	}
+
+	public void addWhereFragment(JoinFragment joinFragment, String whereFragment, QueryNode query, FromElement fromElement) {
+
+		if ( whereFragment == null ) {
+			return;
+		}
+
+		whereFragment = whereFragment.trim();
+		if ( StringHelper.isEmpty( whereFragment ) ) {
+			return;
+		}
+		else if ( !fromElement.useWhereFragment() && !joinFragment.hasThetaJoins() ) {
+			return;
+		}
+
+		// Forcefully remove leading ands from where fragments; the grammar will
+		// handle adding them
+		if ( whereFragment.startsWith( "and" ) ) {
+			whereFragment = whereFragment.substring( 4 );
+		}
+
+		if ( log.isDebugEnabled() ) log.debug( "Using WHERE fragment [" + whereFragment + "]" );
+
+		SqlFragment fragment = ( SqlFragment ) ASTUtil.create( astFactory, SQL_TOKEN, whereFragment );
+		fragment.setJoinFragment( joinFragment );
+		fragment.setFromElement( fromElement );
+
+		// Filter conditions need to be inserted before the HQL where condition and the
+		// theta join node.  This is because org.hibernate.loader.Loader binds the filter parameters first,
+		// then it binds all the HQL query parameters, see org.hibernate.loader.Loader.processFilterParameters().
+		if ( fragment.getFromElement().isFilter() || fragment.hasFilterCondition() ) {
+			if ( filters == null ) {
+				// Find or create the WHERE clause
+				AST where = query.getWhereClause();
+				// Create a new FILTERS node as a parent of all filters
+				filters = astFactory.create( FILTERS, "{filter conditions}" );
+				// Put the FILTERS node before the HQL condition and theta joins
+				ASTUtil.insertChild( where, filters );
+			}
+			
+			// add the current fragment to the FILTERS node
+			filters.addChild( fragment );
+		}
+		else {
+			if ( thetaJoins == null ) {
+				// Find or create the WHERE clause
+				AST where = query.getWhereClause();
+				// Create a new THETA_JOINS node as a parent of all filters
+				thetaJoins = astFactory.create( THETA_JOINS, "{theta joins}" );
+				// Put the THETA_JOINS node before the HQL condition, after the filters.
+				if (filters==null) {
+					ASTUtil.insertChild( where, thetaJoins );
+				}
+				else {
+					ASTUtil.insertSibling( thetaJoins, filters );
+				}
+			}
+			
+			// add the current fragment to the THETA_JOINS node
+			thetaJoins.addChild(fragment);
+		}
+
+	}
+
+	public void addDiscriminatorWhereFragment(RestrictableStatement statement, Queryable persister, Map enabledFilters, String alias) {
+		String whereFragment = persister.filterFragment( alias, enabledFilters ).trim();
+		if ( "".equals( whereFragment ) ) {
+			return;
+		}
+		if ( whereFragment.startsWith( "and" ) ) {
+			whereFragment = whereFragment.substring( 4 );
+		}
+
+		// Need to parse off the column qualifiers; this is assuming (which is true as of now)
+		// that this is only used from update and delete HQL statement parsing
+		whereFragment = StringHelper.replace( whereFragment, persister.generateFilterConditionAlias( alias ) + ".", "" );
+
+		// Note: this simply constructs a "raw" SQL_TOKEN representing the
+		// where fragment and injects this into the tree.  This "works";
+		// however it is probably not the best long-term solution.
+		//
+		// At some point we probably want to apply an additional grammar to
+		// properly tokenize this where fragment into constituent parts
+		// focused on the operators embedded within the fragment.
+		AST discrimNode = astFactory.create( SQL_TOKEN, whereFragment );
+
+		if ( statement.getWhereClause().getNumberOfChildren() == 0 ) {
+			statement.getWhereClause().setFirstChild( discrimNode );
+		}
+		else {
+			AST and = astFactory.create( AND, "{and}" );
+			AST currentFirstChild = statement.getWhereClause().getFirstChild();
+			and.setFirstChild( discrimNode );
+			and.addChild( currentFirstChild );
+			statement.getWhereClause().setFirstChild( and );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-//$Id: ClassicQueryTranslatorFactory.java 9162 2006-01-27 23:40:32Z steveebersole $
-package org.hibernate.hql.classic;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.hql.FilterTranslator;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.hql.QueryTranslatorFactory;
-
-import java.util.Map;
-
-/**
- * Generates translators which uses the older hand-written parser to perform
- * the translation.
- *
- * @author Gavin King
- */
-public class ClassicQueryTranslatorFactory implements QueryTranslatorFactory {
-
-	/**
-	 * @see QueryTranslatorFactory#createQueryTranslator
-	 */
-	public QueryTranslator createQueryTranslator(
-			String queryIdentifier,
-	        String queryString,
-	        Map filters,
-	        SessionFactoryImplementor factory) {
-		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
-	}
-
-	/**
-	 * @see QueryTranslatorFactory#createFilterTranslator
-	 */
-	public FilterTranslator createFilterTranslator(
-			String queryIdentifier,
-			String queryString,
-	        Map filters,
-	        SessionFactoryImplementor factory) {
-		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClassicQueryTranslatorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.classic;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.hql.FilterTranslator;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.hql.QueryTranslatorFactory;
+
+import java.util.Map;
+
+/**
+ * Generates translators which uses the older hand-written parser to perform
+ * the translation.
+ *
+ * @author Gavin King
+ */
+public class ClassicQueryTranslatorFactory implements QueryTranslatorFactory {
+
+	/**
+	 * @see QueryTranslatorFactory#createQueryTranslator
+	 */
+	public QueryTranslator createQueryTranslator(
+			String queryIdentifier,
+	        String queryString,
+	        Map filters,
+	        SessionFactoryImplementor factory) {
+		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
+	}
+
+	/**
+	 * @see QueryTranslatorFactory#createFilterTranslator
+	 */
+	public FilterTranslator createFilterTranslator(
+			String queryIdentifier,
+			String queryString,
+	        Map filters,
+	        SessionFactoryImplementor factory) {
+		return new QueryTranslatorImpl( queryIdentifier, queryString, filters, factory );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,129 +0,0 @@
-//$Id: ClauseParser.java 4907 2004-12-08 00:24:14Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Parses the Hibernate query into its constituent clauses.
- */
-public class ClauseParser implements Parser {
-
-	private Parser child;
-	private List selectTokens;
-	private boolean cacheSelectTokens = false;
-	private boolean byExpected = false;
-	private int parenCount = 0;
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-		String lcToken = token.toLowerCase();
-
-		if ( "(".equals( token ) ) {
-			parenCount++;
-		}
-		else if ( ")".equals( token ) ) {
-			parenCount--;
-		}
-
-		if ( byExpected && !lcToken.equals( "by" ) ) {
-			throw new QueryException( "BY expected after GROUP or ORDER: " + token );
-		}
-
-		boolean isClauseStart = parenCount == 0; //ignore subselect keywords
-
-		if ( isClauseStart ) {
-			if ( lcToken.equals( "select" ) ) {
-				selectTokens = new ArrayList();
-				cacheSelectTokens = true;
-			}
-			else if ( lcToken.equals( "from" ) ) {
-				child = new FromParser();
-				child.start( q );
-				cacheSelectTokens = false;
-			}
-			else if ( lcToken.equals( "where" ) ) {
-				endChild( q );
-				child = new WhereParser();
-				child.start( q );
-			}
-			else if ( lcToken.equals( "order" ) ) {
-				endChild( q );
-				child = new OrderByParser();
-				byExpected = true;
-			}
-			else if ( lcToken.equals( "having" ) ) {
-				endChild( q );
-				child = new HavingParser();
-				child.start( q );
-			}
-			else if ( lcToken.equals( "group" ) ) {
-				endChild( q );
-				child = new GroupByParser();
-				byExpected = true;
-			}
-			else if ( lcToken.equals( "by" ) ) {
-				if ( !byExpected ) throw new QueryException( "GROUP or ORDER expected before BY" );
-				child.start( q );
-				byExpected = false;
-			}
-			else {
-				isClauseStart = false;
-			}
-		}
-
-		if ( !isClauseStart ) {
-			if ( cacheSelectTokens ) {
-				selectTokens.add( token );
-			}
-			else {
-				if ( child == null ) {
-					throw new QueryException( "query must begin with SELECT or FROM: " + token );
-				}
-				else {
-					child.token( token, q );
-				}
-			}
-		}
-
-	}
-
-	private void endChild(QueryTranslatorImpl q) throws QueryException {
-		if ( child == null ) {
-			//null child could occur for no from clause in a filter
-			cacheSelectTokens = false;
-		}
-		else {
-			child.end( q );
-		}
-	}
-
-	public void start(QueryTranslatorImpl q) {
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		endChild( q );
-		if ( selectTokens != null ) {
-			child = new SelectParser();
-			child.start( q );
-			Iterator iter = selectTokens.iterator();
-			while ( iter.hasNext() ) {
-				token( ( String ) iter.next(), q );
-			}
-			child.end( q );
-		}
-		byExpected = false;
-		parenCount = 0;
-		cacheSelectTokens = false;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ClauseParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,152 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parses the Hibernate query into its constituent clauses.
+ */
+public class ClauseParser implements Parser {
+
+	private Parser child;
+	private List selectTokens;
+	private boolean cacheSelectTokens = false;
+	private boolean byExpected = false;
+	private int parenCount = 0;
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+		String lcToken = token.toLowerCase();
+
+		if ( "(".equals( token ) ) {
+			parenCount++;
+		}
+		else if ( ")".equals( token ) ) {
+			parenCount--;
+		}
+
+		if ( byExpected && !lcToken.equals( "by" ) ) {
+			throw new QueryException( "BY expected after GROUP or ORDER: " + token );
+		}
+
+		boolean isClauseStart = parenCount == 0; //ignore subselect keywords
+
+		if ( isClauseStart ) {
+			if ( lcToken.equals( "select" ) ) {
+				selectTokens = new ArrayList();
+				cacheSelectTokens = true;
+			}
+			else if ( lcToken.equals( "from" ) ) {
+				child = new FromParser();
+				child.start( q );
+				cacheSelectTokens = false;
+			}
+			else if ( lcToken.equals( "where" ) ) {
+				endChild( q );
+				child = new WhereParser();
+				child.start( q );
+			}
+			else if ( lcToken.equals( "order" ) ) {
+				endChild( q );
+				child = new OrderByParser();
+				byExpected = true;
+			}
+			else if ( lcToken.equals( "having" ) ) {
+				endChild( q );
+				child = new HavingParser();
+				child.start( q );
+			}
+			else if ( lcToken.equals( "group" ) ) {
+				endChild( q );
+				child = new GroupByParser();
+				byExpected = true;
+			}
+			else if ( lcToken.equals( "by" ) ) {
+				if ( !byExpected ) throw new QueryException( "GROUP or ORDER expected before BY" );
+				child.start( q );
+				byExpected = false;
+			}
+			else {
+				isClauseStart = false;
+			}
+		}
+
+		if ( !isClauseStart ) {
+			if ( cacheSelectTokens ) {
+				selectTokens.add( token );
+			}
+			else {
+				if ( child == null ) {
+					throw new QueryException( "query must begin with SELECT or FROM: " + token );
+				}
+				else {
+					child.token( token, q );
+				}
+			}
+		}
+
+	}
+
+	private void endChild(QueryTranslatorImpl q) throws QueryException {
+		if ( child == null ) {
+			//null child could occur for no from clause in a filter
+			cacheSelectTokens = false;
+		}
+		else {
+			child.end( q );
+		}
+	}
+
+	public void start(QueryTranslatorImpl q) {
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		endChild( q );
+		if ( selectTokens != null ) {
+			child = new SelectParser();
+			child.start( q );
+			Iterator iter = selectTokens.iterator();
+			while ( iter.hasNext() ) {
+				token( ( String ) iter.next(), q );
+			}
+			child.end( q );
+		}
+		byExpected = false;
+		parenCount = 0;
+		cacheSelectTokens = false;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/FromParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,231 +0,0 @@
-//$Id: FromParser.java 5699 2005-02-13 11:50:11Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Parses the from clause of a hibernate query, looking for tables and
- * aliases for the SQL query.
- */
-
-public class FromParser implements Parser {
-
-	private final PathExpressionParser peParser = new FromPathExpressionParser();
-	private String entityName;
-	private String alias;
-	private boolean afterIn;
-	private boolean afterAs;
-	private boolean afterClass;
-	private boolean expectingJoin;
-	private boolean expectingIn;
-	private boolean expectingAs;
-	private boolean afterJoinType;
-	private int joinType;
-	private boolean afterFetch;
-
-	private static final int NONE = -666;
-
-	private static final Map JOIN_TYPES = new HashMap();
-
-	static {
-		JOIN_TYPES.put( "left", new Integer( JoinFragment.LEFT_OUTER_JOIN ) );
-		JOIN_TYPES.put( "right", new Integer( JoinFragment.RIGHT_OUTER_JOIN ) );
-		JOIN_TYPES.put( "full", new Integer( JoinFragment.FULL_JOIN ) );
-		JOIN_TYPES.put( "inner", new Integer( JoinFragment.INNER_JOIN ) );
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		// start by looking for HQL keywords...
-		String lcToken = token.toLowerCase();
-		if ( lcToken.equals( "," ) ) {
-			if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: ," );
-			expectingJoin = false;
-			expectingAs = false;
-		}
-		else if ( lcToken.equals( "join" ) ) {
-			if ( !afterJoinType ) {
-				if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: join" );
-				// inner joins can be abbreviated to 'join'
-				joinType = JoinFragment.INNER_JOIN;
-				expectingJoin = false;
-				expectingAs = false;
-			}
-			else {
-				afterJoinType = false;
-			}
-		}
-		else if ( lcToken.equals( "fetch" ) ) {
-			if ( q.isShallowQuery() ) throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE );
-			if ( joinType == NONE ) throw new QueryException( "unexpected token: fetch" );
-			if ( joinType == JoinFragment.FULL_JOIN || joinType == JoinFragment.RIGHT_OUTER_JOIN ) {
-				throw new QueryException( "fetch may only be used with inner join or left outer join" );
-			}
-			afterFetch = true;
-		}
-		else if ( lcToken.equals( "outer" ) ) {
-			// 'outer' is optional and is ignored
-			if ( !afterJoinType ||
-					( joinType != JoinFragment.LEFT_OUTER_JOIN && joinType != JoinFragment.RIGHT_OUTER_JOIN )
-			) {
-				throw new QueryException( "unexpected token: outer" );
-			}
-		}
-		else if ( JOIN_TYPES.containsKey( lcToken ) ) {
-			if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: " + token );
-			joinType = ( ( Integer ) JOIN_TYPES.get( lcToken ) ).intValue();
-			afterJoinType = true;
-			expectingJoin = false;
-			expectingAs = false;
-		}
-		else if ( lcToken.equals( "class" ) ) {
-			if ( !afterIn ) throw new QueryException( "unexpected token: class" );
-			if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
-			afterClass = true;
-		}
-		else if ( lcToken.equals( "in" ) ) {
-			if ( !expectingIn ) throw new QueryException( "unexpected token: in" );
-			afterIn = true;
-			expectingIn = false;
-		}
-		else if ( lcToken.equals( "as" ) ) {
-			if ( !expectingAs ) throw new QueryException( "unexpected token: as" );
-			afterAs = true;
-			expectingAs = false;
-		}
-		else {
-
-			if ( afterJoinType ) throw new QueryException( "join expected: " + token );
-			if ( expectingJoin ) throw new QueryException( "unexpected token: " + token );
-			if ( expectingIn ) throw new QueryException( "in expected: " + token );
-
-			// now anything that is not a HQL keyword
-
-			if ( afterAs || expectingAs ) {
-
-				// (AS is always optional, for consistency with SQL/OQL)
-
-				// process the "new" HQL style where aliases are assigned
-				// _after_ the class name or path expression ie. using
-				// the AS construction
-
-				if ( entityName != null ) {
-					q.setAliasName( token, entityName );
-				}
-				else {
-					throw new QueryException( "unexpected: as " + token );
-				}
-				afterAs = false;
-				expectingJoin = true;
-				expectingAs = false;
-				entityName = null;
-
-			}
-			else if ( afterIn ) {
-
-				// process the "old" HQL style where aliases appear _first_
-				// ie. using the IN or IN CLASS constructions
-
-				if ( alias == null ) throw new QueryException( "alias not specified for: " + token );
-
-				if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
-
-				if ( afterClass ) {
-					// treat it as a classname
-					Queryable p = q.getEntityPersisterUsingImports( token );
-					if ( p == null ) throw new QueryException( "persister not found: " + token );
-					q.addFromClass( alias, p );
-				}
-				else {
-					// treat it as a path expression
-					peParser.setJoinType( JoinFragment.INNER_JOIN );
-					peParser.setUseThetaStyleJoin( true );
-					ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-					if ( !peParser.isCollectionValued() ) throw new QueryException( "path expression did not resolve to collection: " + token );
-					String nm = peParser.addFromCollection( q );
-					q.setAliasName( alias, nm );
-				}
-
-				alias = null;
-				afterIn = false;
-				afterClass = false;
-				expectingJoin = true;
-			}
-			else {
-
-				// handle a path expression or class name that
-				// appears at the start, in the "new" HQL
-				// style or an alias that appears at the start
-				// in the "old" HQL style
-
-				Queryable p = q.getEntityPersisterUsingImports( token );
-				if ( p != null ) {
-					// starts with the name of a mapped class (new style)
-					if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
-					entityName = q.createNameFor( p.getEntityName() );
-					q.addFromClass( entityName, p );
-					expectingAs = true;
-				}
-				else if ( token.indexOf( '.' ) < 0 ) {
-					// starts with an alias (old style)
-					// semi-bad thing about this: can't re-alias another alias.....
-					alias = token;
-					expectingIn = true;
-				}
-				else {
-
-					// starts with a path expression (new style)
-
-					// force HQL style: from Person p inner join p.cars c
-					//if (joinType==NONE) throw new QueryException("path expression must be preceded by full, left, right or inner join");
-
-					//allow ODMG OQL style: from Person p, p.cars c
-					if ( joinType != NONE ) {
-						peParser.setJoinType( joinType );
-					}
-					else {
-						peParser.setJoinType( JoinFragment.INNER_JOIN );
-					}
-					peParser.setUseThetaStyleJoin( q.isSubquery() );
-
-					ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-					entityName = peParser.addFromAssociation( q );
-
-					joinType = NONE;
-					peParser.setJoinType( JoinFragment.INNER_JOIN );
-
-					if ( afterFetch ) {
-						peParser.fetch( q, entityName );
-						afterFetch = false;
-					}
-
-					expectingAs = true;
-
-				}
-			}
-		}
-
-	}
-
-	public void start(QueryTranslatorImpl q) {
-		entityName = null;
-		alias = null;
-		afterIn = false;
-		afterAs = false;
-		afterClass = false;
-		expectingJoin = false;
-		expectingIn = false;
-		expectingAs = false;
-		joinType = NONE;
-	}
-
-	public void end(QueryTranslatorImpl q) {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/FromParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,254 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Parses the from clause of a hibernate query, looking for tables and
+ * aliases for the SQL query.
+ */
+
+public class FromParser implements Parser {
+
+	private final PathExpressionParser peParser = new FromPathExpressionParser();
+	private String entityName;
+	private String alias;
+	private boolean afterIn;
+	private boolean afterAs;
+	private boolean afterClass;
+	private boolean expectingJoin;
+	private boolean expectingIn;
+	private boolean expectingAs;
+	private boolean afterJoinType;
+	private int joinType;
+	private boolean afterFetch;
+
+	private static final int NONE = -666;
+
+	private static final Map JOIN_TYPES = new HashMap();
+
+	static {
+		JOIN_TYPES.put( "left", new Integer( JoinFragment.LEFT_OUTER_JOIN ) );
+		JOIN_TYPES.put( "right", new Integer( JoinFragment.RIGHT_OUTER_JOIN ) );
+		JOIN_TYPES.put( "full", new Integer( JoinFragment.FULL_JOIN ) );
+		JOIN_TYPES.put( "inner", new Integer( JoinFragment.INNER_JOIN ) );
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		// start by looking for HQL keywords...
+		String lcToken = token.toLowerCase();
+		if ( lcToken.equals( "," ) ) {
+			if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: ," );
+			expectingJoin = false;
+			expectingAs = false;
+		}
+		else if ( lcToken.equals( "join" ) ) {
+			if ( !afterJoinType ) {
+				if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: join" );
+				// inner joins can be abbreviated to 'join'
+				joinType = JoinFragment.INNER_JOIN;
+				expectingJoin = false;
+				expectingAs = false;
+			}
+			else {
+				afterJoinType = false;
+			}
+		}
+		else if ( lcToken.equals( "fetch" ) ) {
+			if ( q.isShallowQuery() ) throw new QueryException( QueryTranslator.ERROR_CANNOT_FETCH_WITH_ITERATE );
+			if ( joinType == NONE ) throw new QueryException( "unexpected token: fetch" );
+			if ( joinType == JoinFragment.FULL_JOIN || joinType == JoinFragment.RIGHT_OUTER_JOIN ) {
+				throw new QueryException( "fetch may only be used with inner join or left outer join" );
+			}
+			afterFetch = true;
+		}
+		else if ( lcToken.equals( "outer" ) ) {
+			// 'outer' is optional and is ignored
+			if ( !afterJoinType ||
+					( joinType != JoinFragment.LEFT_OUTER_JOIN && joinType != JoinFragment.RIGHT_OUTER_JOIN )
+			) {
+				throw new QueryException( "unexpected token: outer" );
+			}
+		}
+		else if ( JOIN_TYPES.containsKey( lcToken ) ) {
+			if ( !( expectingJoin | expectingAs ) ) throw new QueryException( "unexpected token: " + token );
+			joinType = ( ( Integer ) JOIN_TYPES.get( lcToken ) ).intValue();
+			afterJoinType = true;
+			expectingJoin = false;
+			expectingAs = false;
+		}
+		else if ( lcToken.equals( "class" ) ) {
+			if ( !afterIn ) throw new QueryException( "unexpected token: class" );
+			if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
+			afterClass = true;
+		}
+		else if ( lcToken.equals( "in" ) ) {
+			if ( !expectingIn ) throw new QueryException( "unexpected token: in" );
+			afterIn = true;
+			expectingIn = false;
+		}
+		else if ( lcToken.equals( "as" ) ) {
+			if ( !expectingAs ) throw new QueryException( "unexpected token: as" );
+			afterAs = true;
+			expectingAs = false;
+		}
+		else {
+
+			if ( afterJoinType ) throw new QueryException( "join expected: " + token );
+			if ( expectingJoin ) throw new QueryException( "unexpected token: " + token );
+			if ( expectingIn ) throw new QueryException( "in expected: " + token );
+
+			// now anything that is not a HQL keyword
+
+			if ( afterAs || expectingAs ) {
+
+				// (AS is always optional, for consistency with SQL/OQL)
+
+				// process the "new" HQL style where aliases are assigned
+				// _after_ the class name or path expression ie. using
+				// the AS construction
+
+				if ( entityName != null ) {
+					q.setAliasName( token, entityName );
+				}
+				else {
+					throw new QueryException( "unexpected: as " + token );
+				}
+				afterAs = false;
+				expectingJoin = true;
+				expectingAs = false;
+				entityName = null;
+
+			}
+			else if ( afterIn ) {
+
+				// process the "old" HQL style where aliases appear _first_
+				// ie. using the IN or IN CLASS constructions
+
+				if ( alias == null ) throw new QueryException( "alias not specified for: " + token );
+
+				if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
+
+				if ( afterClass ) {
+					// treat it as a classname
+					Queryable p = q.getEntityPersisterUsingImports( token );
+					if ( p == null ) throw new QueryException( "persister not found: " + token );
+					q.addFromClass( alias, p );
+				}
+				else {
+					// treat it as a path expression
+					peParser.setJoinType( JoinFragment.INNER_JOIN );
+					peParser.setUseThetaStyleJoin( true );
+					ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+					if ( !peParser.isCollectionValued() ) throw new QueryException( "path expression did not resolve to collection: " + token );
+					String nm = peParser.addFromCollection( q );
+					q.setAliasName( alias, nm );
+				}
+
+				alias = null;
+				afterIn = false;
+				afterClass = false;
+				expectingJoin = true;
+			}
+			else {
+
+				// handle a path expression or class name that
+				// appears at the start, in the "new" HQL
+				// style or an alias that appears at the start
+				// in the "old" HQL style
+
+				Queryable p = q.getEntityPersisterUsingImports( token );
+				if ( p != null ) {
+					// starts with the name of a mapped class (new style)
+					if ( joinType != NONE ) throw new QueryException( "outer or full join must be followed by path expression" );
+					entityName = q.createNameFor( p.getEntityName() );
+					q.addFromClass( entityName, p );
+					expectingAs = true;
+				}
+				else if ( token.indexOf( '.' ) < 0 ) {
+					// starts with an alias (old style)
+					// semi-bad thing about this: can't re-alias another alias.....
+					alias = token;
+					expectingIn = true;
+				}
+				else {
+
+					// starts with a path expression (new style)
+
+					// force HQL style: from Person p inner join p.cars c
+					//if (joinType==NONE) throw new QueryException("path expression must be preceded by full, left, right or inner join");
+
+					//allow ODMG OQL style: from Person p, p.cars c
+					if ( joinType != NONE ) {
+						peParser.setJoinType( joinType );
+					}
+					else {
+						peParser.setJoinType( JoinFragment.INNER_JOIN );
+					}
+					peParser.setUseThetaStyleJoin( q.isSubquery() );
+
+					ParserHelper.parse( peParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+					entityName = peParser.addFromAssociation( q );
+
+					joinType = NONE;
+					peParser.setJoinType( JoinFragment.INNER_JOIN );
+
+					if ( afterFetch ) {
+						peParser.fetch( q, entityName );
+						afterFetch = false;
+					}
+
+					expectingAs = true;
+
+				}
+			}
+		}
+
+	}
+
+	public void start(QueryTranslatorImpl q) {
+		entityName = null;
+		alias = null;
+		afterIn = false;
+		afterAs = false;
+		afterClass = false;
+		expectingJoin = false;
+		expectingIn = false;
+		expectingAs = false;
+		joinType = NONE;
+	}
+
+	public void end(QueryTranslatorImpl q) {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: FromPathExpressionParser.java 5861 2005-02-22 14:07:36Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.persister.collection.CollectionPropertyNames;
-import org.hibernate.type.Type;
-
-public class FromPathExpressionParser extends PathExpressionParser {
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		if ( !isCollectionValued() ) {
-			Type type = getPropertyType();
-			if ( type.isEntityType() ) {
-				// "finish off" the join
-				token( ".", q );
-				token( null, q );
-			}
-			else if ( type.isCollectionType() ) {
-				// default to element set if no elements() specified
-				token( ".", q );
-				token( CollectionPropertyNames.COLLECTION_ELEMENTS, q );
-			}
-		}
-		super.end( q );
-	}
-
-	protected void setExpectingCollectionIndex() throws QueryException {
-		throw new QueryException( "illegal syntax near collection-valued path expression in from: "  + getCollectionName() );
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/FromPathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.persister.collection.CollectionPropertyNames;
+import org.hibernate.type.Type;
+
+public class FromPathExpressionParser extends PathExpressionParser {
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		if ( !isCollectionValued() ) {
+			Type type = getPropertyType();
+			if ( type.isEntityType() ) {
+				// "finish off" the join
+				token( ".", q );
+				token( null, q );
+			}
+			else if ( type.isCollectionType() ) {
+				// default to element set if no elements() specified
+				token( ".", q );
+				token( CollectionPropertyNames.COLLECTION_ELEMENTS, q );
+			}
+		}
+		super.end( q );
+	}
+
+	protected void setExpectingCollectionIndex() throws QueryException {
+		throw new QueryException( "illegal syntax near collection-valued path expression in from: "  + getCollectionName() );
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-//$Id: GroupByParser.java 4907 2004-12-08 00:24:14Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.util.StringHelper;
-
-/**
- * Parses the GROUP BY clause of an aggregate query
- */
-public class GroupByParser implements Parser {
-
-	//this is basically a copy/paste of OrderByParser ... might be worth refactoring
-
-	// This uses a PathExpressionParser but notice that compound paths are not valid,
-	// only bare names and simple paths:
-
-	// SELECT p FROM p IN CLASS eg.Person GROUP BY p.Name, p.Address, p
-
-	// The reason for this is SQL doesn't let you sort by an expression you are
-	// not returning in the result set.
-
-	private final PathExpressionParser pathExpressionParser;
-
-	{
-		pathExpressionParser = new PathExpressionParser();
-		pathExpressionParser.setUseThetaStyleJoin( true ); //TODO: would be nice to use false, but issues with MS SQL
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		if ( q.isName( StringHelper.root( token ) ) ) {
-			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-			q.appendGroupByToken( pathExpressionParser.getWhereColumn() );
-			pathExpressionParser.addAssociation( q );
-		}
-		else {
-			q.appendGroupByToken( token );
-		}
-	}
-
-	public void start(QueryTranslatorImpl q) throws QueryException {
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-	}
-
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/GroupByParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Parses the GROUP BY clause of an aggregate query
+ */
+public class GroupByParser implements Parser {
+
+	//this is basically a copy/paste of OrderByParser ... might be worth refactoring
+
+	// This uses a PathExpressionParser but notice that compound paths are not valid,
+	// only bare names and simple paths:
+
+	// SELECT p FROM p IN CLASS eg.Person GROUP BY p.Name, p.Address, p
+
+	// The reason for this is SQL doesn't let you sort by an expression you are
+	// not returning in the result set.
+
+	private final PathExpressionParser pathExpressionParser;
+
+	{
+		pathExpressionParser = new PathExpressionParser();
+		pathExpressionParser.setUseThetaStyleJoin( true ); //TODO: would be nice to use false, but issues with MS SQL
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		if ( q.isName( StringHelper.root( token ) ) ) {
+			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+			q.appendGroupByToken( pathExpressionParser.getWhereColumn() );
+			pathExpressionParser.addAssociation( q );
+		}
+		else {
+			q.appendGroupByToken( token );
+		}
+	}
+
+	public void start(QueryTranslatorImpl q) throws QueryException {
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+	}
+
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/HavingParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: HavingParser.java 4907 2004-12-08 00:24:14Z oneovthafew $
-package org.hibernate.hql.classic;
-
-
-/**
- * Parses the having clause of a hibernate query and translates it to an
- * SQL having clause.
- */
-public class HavingParser extends WhereParser {
-
-	void appendToken(QueryTranslatorImpl q, String token) {
-		q.appendHavingToken( token );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/HavingParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/HavingParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.classic;
+
+/**
+ * Parses the having clause of a hibernate query and translates it to an
+ * SQL having clause.
+ */
+public class HavingParser extends WhereParser {
+
+	void appendToken(QueryTranslatorImpl q, String token) {
+		q.appendHavingToken( token );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: OrderByParser.java 4907 2004-12-08 00:24:14Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.util.StringHelper;
-
-/**
- * Parses the ORDER BY clause of a query
- */
-
-public class OrderByParser implements Parser {
-
-	// This uses a PathExpressionParser but notice that compound paths are not valid,
-	// only bare names and simple paths:
-
-	// SELECT p FROM p IN CLASS eg.Person ORDER BY p.Name, p.Address, p
-
-	// The reason for this is SQL doesn't let you sort by an expression you are
-	// not returning in the result set.
-
-	private final PathExpressionParser pathExpressionParser;
-
-	{
-		pathExpressionParser = new PathExpressionParser();
-		pathExpressionParser.setUseThetaStyleJoin( true ); //TODO: would be nice to use false, but issues with MS SQL
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		if ( q.isName( StringHelper.root( token ) ) ) {
-			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-			q.appendOrderByToken( pathExpressionParser.getWhereColumn() );
-			pathExpressionParser.addAssociation( q );
-		}
-		else if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) { //named query parameter
-			q.addNamedParameter( token.substring( 1 ) );
-			q.appendOrderByToken( "?" );
-		}
-		else {
-			q.appendOrderByToken( token );
-		}
-	}
-
-	public void start(QueryTranslatorImpl q) throws QueryException {
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/OrderByParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Parses the ORDER BY clause of a query
+ */
+
+public class OrderByParser implements Parser {
+
+	// This uses a PathExpressionParser but notice that compound paths are not valid,
+	// only bare names and simple paths:
+
+	// SELECT p FROM p IN CLASS eg.Person ORDER BY p.Name, p.Address, p
+
+	// The reason for this is SQL doesn't let you sort by an expression you are
+	// not returning in the result set.
+
+	private final PathExpressionParser pathExpressionParser;
+
+	{
+		pathExpressionParser = new PathExpressionParser();
+		pathExpressionParser.setUseThetaStyleJoin( true ); //TODO: would be nice to use false, but issues with MS SQL
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		if ( q.isName( StringHelper.root( token ) ) ) {
+			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+			q.appendOrderByToken( pathExpressionParser.getWhereColumn() );
+			pathExpressionParser.addAssociation( q );
+		}
+		else if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) { //named query parameter
+			q.addNamedParameter( token.substring( 1 ) );
+			q.appendOrderByToken( "?" );
+		}
+		else {
+			q.appendOrderByToken( token );
+		}
+	}
+
+	public void start(QueryTranslatorImpl q) throws QueryException {
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/Parser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: Parser.java 4907 2004-12-08 00:24:14Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-
-/**
- * A parser is a state machine that accepts a string of tokens,
- * bounded by start() and end() and modifies a QueryTranslator. Parsers
- * are NOT intended to be threadsafe. They SHOULD be reuseable
- * for more than one token stream.
- */
-
-public interface Parser {
-	public void token(String token, QueryTranslatorImpl q) throws QueryException;
-
-	public void start(QueryTranslatorImpl q) throws QueryException;
-
-	public void end(QueryTranslatorImpl q) throws QueryException;
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/Parser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/Parser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+
+/**
+ * A parser is a state machine that accepts a string of tokens,
+ * bounded by start() and end() and modifies a QueryTranslator. Parsers
+ * are NOT intended to be threadsafe. They SHOULD be reuseable
+ * for more than one token stream.
+ */
+
+public interface Parser {
+	public void token(String token, QueryTranslatorImpl q) throws QueryException;
+
+	public void start(QueryTranslatorImpl q) throws QueryException;
+
+	public void end(QueryTranslatorImpl q) throws QueryException;
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: ParserHelper.java 6879 2005-05-23 19:54:13Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.util.StringHelper;
-
-import java.util.StringTokenizer;
-
-public final class ParserHelper {
-
-	public static final String HQL_VARIABLE_PREFIX = ":";
-
-	public static final String HQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\";
-	//NOTICE: no " or . since they are part of (compound) identifiers
-	public static final String PATH_SEPARATORS = ".";
-
-	public static boolean isWhitespace(String str) {
-		return StringHelper.WHITESPACE.indexOf( str ) > -1;
-	}
-
-	private ParserHelper() {
-		//cannot instantiate
-	}
-
-	public static void parse(Parser p, String text, String seperators, QueryTranslatorImpl q) throws QueryException {
-		StringTokenizer tokens = new StringTokenizer( text, seperators, true );
-		p.start( q );
-		while ( tokens.hasMoreElements() ) p.token( tokens.nextToken(), q );
-		p.end( q );
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/ParserHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.hql.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.util.StringHelper;
+
+import java.util.StringTokenizer;
+
+public final class ParserHelper {
+
+	public static final String HQL_VARIABLE_PREFIX = ":";
+
+	public static final String HQL_SEPARATORS = " \n\r\f\t,()=<>&|+-=/*'^![]#~\\";
+	//NOTICE: no " or . since they are part of (compound) identifiers
+	public static final String PATH_SEPARATORS = ".";
+
+	public static boolean isWhitespace(String str) {
+		return StringHelper.WHITESPACE.indexOf( str ) > -1;
+	}
+
+	private ParserHelper() {
+		//cannot instantiate
+	}
+
+	public static void parse(Parser p, String text, String seperators, QueryTranslatorImpl q) throws QueryException {
+		StringTokenizer tokens = new StringTokenizer( text, seperators, true );
+		p.start( q );
+		while ( tokens.hasMoreElements() ) p.token( tokens.nextToken(), q );
+		p.end( q );
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,504 +0,0 @@
-//$Id: PathExpressionParser.java 10830 2006-11-16 20:22:07Z steve.ebersole at jboss.com $
-package org.hibernate.hql.classic;
-
-import java.util.LinkedList;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.CollectionSubqueryFactory;
-import org.hibernate.persister.collection.CollectionPropertyMapping;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * Parses an expression of the form foo.bar.baz and builds up an expression
- * involving two less table joins than there are path components.
- */
-public class PathExpressionParser implements Parser {
-
-	//TODO: this class does too many things! we need a different
-	//kind of path expression parser for each of the diffferent
-	//ways in which path expressions can occur
-
-	//We should actually rework this class to not implement Parser
-	//and just process path expressions in the most convenient way.
-
-	//The class is now way to complex!
-
-	private int dotcount;
-	private String currentName;
-	private String currentProperty;
-	private String oneToOneOwnerName;
-	private AssociationType ownerAssociationType;
-	private String[] columns;
-	private String collectionName;
-	private String collectionOwnerName;
-	private String collectionRole;
-	private final StringBuffer componentPath = new StringBuffer();
-	private Type type;
-	private final StringBuffer path = new StringBuffer();
-	private boolean ignoreInitialJoin;
-	private boolean continuation;
-	private int joinType = JoinFragment.INNER_JOIN; //default mode
-	private boolean useThetaStyleJoin = true;
-	private PropertyMapping currentPropertyMapping;
-	private JoinSequence joinSequence;
-
-	private boolean expectingCollectionIndex;
-	private LinkedList collectionElements = new LinkedList();
-
-	void setJoinType(int joinType) {
-		this.joinType = joinType;
-	}
-
-	void setUseThetaStyleJoin(boolean useThetaStyleJoin) {
-		this.useThetaStyleJoin = useThetaStyleJoin;
-	}
-
-	private void addJoin(String name, AssociationType joinableType) throws QueryException {
-		try {
-			joinSequence.addJoin( joinableType, name, joinType, currentColumns() );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-
-	private void addJoin(String name, AssociationType joinableType, String[] foreignKeyColumns) throws QueryException {
-		try {
-			joinSequence.addJoin( joinableType, name, joinType, foreignKeyColumns );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-
-	String continueFromManyToMany(String entityName, String[] joinColumns, QueryTranslatorImpl q) throws QueryException {
-		start( q );
-		continuation = true;
-		currentName = q.createNameFor( entityName );
-		q.addType( currentName, entityName );
-		Queryable classPersister = q.getEntityPersister( entityName );
-		//QueryJoinFragment join = q.createJoinFragment(useThetaStyleJoin);
-		addJoin( currentName, TypeFactory.manyToOne( entityName ), joinColumns );
-		currentPropertyMapping = classPersister;
-		return currentName;
-	}
-
-	public void ignoreInitialJoin() {
-		ignoreInitialJoin = true;
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		if ( token != null ) path.append( token );
-
-		String alias = q.getPathAlias( path.toString() );
-		if ( alias != null ) {
-			reset( q ); //reset the dotcount (but not the path)
-			currentName = alias; //after reset!
-			currentPropertyMapping = q.getPropertyMapping( currentName );
-			if ( !ignoreInitialJoin ) {
-				JoinSequence ojf = q.getPathJoin( path.toString() );
-				try {
-					joinSequence.addCondition( ojf.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() ); //after reset!
-				}
-				catch ( MappingException me ) {
-					throw new QueryException( me );
-				}
-				// we don't need to worry about any condition in the ON clause
-				// here (toFromFragmentString), since anything in the ON condition
-				// is already applied to the whole query
-			}
-		}
-		else if ( ".".equals( token ) ) {
-			dotcount++;
-		}
-		else {
-			if ( dotcount == 0 ) {
-				if ( !continuation ) {
-					if ( !q.isName( token ) ) throw new QueryException( "undefined alias: " + token );
-					currentName = token;
-					currentPropertyMapping = q.getPropertyMapping( currentName );
-				}
-			}
-			else if ( dotcount == 1 ) {
-				if ( currentName != null ) {
-					currentProperty = token;
-				}
-				else if ( collectionName != null ) {
-					//processCollectionProperty(token, q.getCollectionPersister(collectionRole), collectionName);
-					continuation = false;
-				}
-				else {
-					throw new QueryException( "unexpected" );
-				}
-			}
-			else { // dotcount>=2
-
-				// Do the corresponding RHS
-				Type propertyType = getPropertyType();
-
-				if ( propertyType == null ) {
-					throw new QueryException( "unresolved property: " + path );
-				}
-
-				if ( propertyType.isComponentType() ) {
-					dereferenceComponent( token );
-				}
-				else if ( propertyType.isEntityType() ) {
-					if ( !isCollectionValued() ) dereferenceEntity( token, ( EntityType ) propertyType, q );
-				}
-				else if ( propertyType.isCollectionType() ) {
-					dereferenceCollection( token, ( ( CollectionType ) propertyType ).getRole(), q );
-
-				}
-				else {
-					if ( token != null ) throw new QueryException( "dereferenced: " + path );
-				}
-
-			}
-		}
-	}
-
-	private void dereferenceEntity(String propertyName, EntityType propertyType, QueryTranslatorImpl q)
-			throws QueryException {
-		//NOTE: we avoid joining to the next table if the named property is just the foreign key value
-
-		//if its "id"
-		boolean isIdShortcut = EntityPersister.ENTITY_ID.equals( propertyName ) &&
-				propertyType.isReferenceToPrimaryKey();
-
-		//or its the id property name
-		final String idPropertyName;
-		try {
-			idPropertyName = propertyType.getIdentifierOrUniqueKeyPropertyName( q.getFactory() );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-		boolean isNamedIdPropertyShortcut = idPropertyName != null
-				&& idPropertyName.equals( propertyName )
-				&& propertyType.isReferenceToPrimaryKey();
-
-
-		if ( isIdShortcut || isNamedIdPropertyShortcut ) {
-			// special shortcut for id properties, skip the join!
-			// this must only occur at the _end_ of a path expression
-			if ( componentPath.length() > 0 ) componentPath.append( '.' );
-			componentPath.append( propertyName );
-		}
-		else {
-			String entityClass = propertyType.getAssociatedEntityName();
-			String name = q.createNameFor( entityClass );
-			q.addType( name, entityClass );
-			addJoin( name, propertyType );
-			if ( propertyType.isOneToOne() ) oneToOneOwnerName = currentName;
-			ownerAssociationType = propertyType;
-			currentName = name;
-			currentProperty = propertyName;
-			q.addPathAliasAndJoin( path.substring( 0, path.toString().lastIndexOf( '.' ) ), name, joinSequence.copy() );
-			componentPath.setLength( 0 );
-			currentPropertyMapping = q.getEntityPersister( entityClass );
-		}
-	}
-
-	private void dereferenceComponent(String propertyName) {
-		if ( propertyName != null ) {
-			if ( componentPath.length() > 0 ) componentPath.append( '.' );
-			componentPath.append( propertyName );
-		}
-	}
-
-	private void dereferenceCollection(String propertyName, String role, QueryTranslatorImpl q) throws QueryException {
-		collectionRole = role;
-		QueryableCollection collPersister = q.getCollectionPersister( role );
-		String name = q.createNameForCollection( role );
-		addJoin( name, collPersister.getCollectionType() );
-		//if ( collPersister.hasWhere() ) join.addCondition( collPersister.getSQLWhereString(name) );
-		collectionName = name;
-		collectionOwnerName = currentName;
-		currentName = name;
-		currentProperty = propertyName;
-		componentPath.setLength( 0 );
-		currentPropertyMapping = new CollectionPropertyMapping( collPersister );
-	}
-
-	private String getPropertyPath() {
-		if ( currentProperty == null ) {
-			return EntityPersister.ENTITY_ID;
-		}
-		else {
-			if ( componentPath.length() > 0 ) {
-				return new StringBuffer()
-						.append( currentProperty )
-						.append( '.' )
-						.append( componentPath.toString() )
-						.toString();
-			}
-			else {
-				return currentProperty;
-			}
-		}
-	}
-
-	private PropertyMapping getPropertyMapping() {
-		return currentPropertyMapping;
-	}
-
-	private void setType() throws QueryException {
-		if ( currentProperty == null ) {
-			type = getPropertyMapping().getType();
-		}
-		else {
-			type = getPropertyType();
-		}
-	}
-
-	protected Type getPropertyType() throws QueryException {
-		String propertyPath = getPropertyPath();
-		Type propertyType = getPropertyMapping().toType( propertyPath );
-		if ( propertyType == null ) {
-			throw new QueryException( "could not resolve property type: " + propertyPath );
-		}
-		return propertyType;
-	}
-
-	protected String[] currentColumns() throws QueryException {
-		String propertyPath = getPropertyPath();
-		String[] propertyColumns = getPropertyMapping().toColumns( currentName, propertyPath );
-		if ( propertyColumns == null ) {
-			throw new QueryException( "could not resolve property columns: " + propertyPath );
-		}
-		return propertyColumns;
-	}
-
-	private void reset(QueryTranslatorImpl q) {
-		//join = q.createJoinFragment(useThetaStyleJoin);
-		dotcount = 0;
-		currentName = null;
-		currentProperty = null;
-		collectionName = null;
-		collectionRole = null;
-		componentPath.setLength( 0 );
-		type = null;
-		collectionName = null;
-		columns = null;
-		expectingCollectionIndex = false;
-		continuation = false;
-		currentPropertyMapping = null;
-	}
-
-	public void start(QueryTranslatorImpl q) {
-		if ( !continuation ) {
-			reset( q );
-			path.setLength( 0 );
-			joinSequence = new JoinSequence( q.getFactory() ).setUseThetaStyle( useThetaStyleJoin );
-		}
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		ignoreInitialJoin = false;
-
-		Type propertyType = getPropertyType();
-		if ( propertyType != null && propertyType.isCollectionType() ) {
-			collectionRole = ( ( CollectionType ) propertyType ).getRole();
-			collectionName = q.createNameForCollection( collectionRole );
-			prepareForIndex( q );
-		}
-		else {
-			columns = currentColumns();
-			setType();
-		}
-
-		//important!!
-		continuation = false;
-
-	}
-
-	private void prepareForIndex(QueryTranslatorImpl q) throws QueryException {
-
-		QueryableCollection collPersister = q.getCollectionPersister( collectionRole );
-
-		if ( !collPersister.hasIndex() ) throw new QueryException( "unindexed collection before []: " + path );
-		String[] indexCols = collPersister.getIndexColumnNames();
-		if ( indexCols.length != 1 ) throw new QueryException( "composite-index appears in []: " + path );
-		//String[] keyCols = collPersister.getKeyColumnNames();
-
-		JoinSequence fromJoins = new JoinSequence( q.getFactory() )
-				.setUseThetaStyle( useThetaStyleJoin )
-				.setRoot( collPersister, collectionName )
-				.setNext( joinSequence.copy() );
-
-		if ( !continuation ) addJoin( collectionName, collPersister.getCollectionType() );
-
-		joinSequence.addCondition( collectionName + '.' + indexCols[0] + " = " ); //TODO: get SQL rendering out of here
-
-		CollectionElement elem = new CollectionElement();
-		elem.elementColumns = collPersister.getElementColumnNames(collectionName);
-		elem.elementType = collPersister.getElementType();
-		elem.isOneToMany = collPersister.isOneToMany();
-		elem.alias = collectionName;
-		elem.joinSequence = joinSequence;
-		collectionElements.addLast( elem );
-		setExpectingCollectionIndex();
-
-		q.addCollection( collectionName, collectionRole );
-		q.addFromJoinOnly( collectionName, fromJoins );
-	}
-
-	static final class CollectionElement {
-		Type elementType;
-		boolean isOneToMany;
-		String alias;
-		String[] elementColumns;
-		JoinSequence joinSequence;
-		StringBuffer indexValue = new StringBuffer();
-	}
-
-	public CollectionElement lastCollectionElement() {
-		return ( CollectionElement ) collectionElements.removeLast();
-	}
-
-	public void setLastCollectionElementIndexValue(String value) {
-		( ( CollectionElement ) collectionElements.getLast() ).indexValue.append( value );
-	}
-
-	public boolean isExpectingCollectionIndex() {
-		return expectingCollectionIndex;
-	}
-
-	protected void setExpectingCollectionIndex() throws QueryException {
-		expectingCollectionIndex = true;
-	}
-
-	public JoinSequence getWhereJoin() {
-		return joinSequence;
-	}
-
-	public String getWhereColumn() throws QueryException {
-		if ( columns.length != 1 ) {
-			throw new QueryException( "path expression ends in a composite value: " + path );
-		}
-		return columns[0];
-	}
-
-	public String[] getWhereColumns() {
-		return columns;
-	}
-
-	public Type getWhereColumnType() {
-		return type;
-	}
-
-	public String getName() {
-		return currentName == null ? collectionName : currentName;
-	}
-
-
-	public String getCollectionSubquery(Map enabledFilters) throws QueryException {
-		return CollectionSubqueryFactory.createCollectionSubquery( joinSequence, enabledFilters, currentColumns() );
-	}
-
-	public boolean isCollectionValued() throws QueryException {
-		//TODO: is there a better way?
-		return collectionName != null && !getPropertyType().isCollectionType();
-	}
-
-	public void addAssociation(QueryTranslatorImpl q) throws QueryException {
-		q.addJoin( getName(), joinSequence );
-	}
-
-	public String addFromAssociation(QueryTranslatorImpl q) throws QueryException {
-		if ( isCollectionValued() ) {
-			return addFromCollection( q );
-		}
-		else {
-			q.addFrom( currentName, joinSequence );
-			return currentName;
-		}
-	}
-
-	public String addFromCollection(QueryTranslatorImpl q) throws QueryException {
-		Type collectionElementType = getPropertyType();
-
-		if ( collectionElementType == null ) {
-			throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path );
-		}
-
-		if ( collectionElementType.isEntityType() ) {
-			// an association
-			QueryableCollection collectionPersister = q.getCollectionPersister( collectionRole );
-			Queryable entityPersister = ( Queryable ) collectionPersister.getElementPersister();
-			String clazz = entityPersister.getEntityName();
-
-			final String elementName;
-			if ( collectionPersister.isOneToMany() ) {
-				elementName = collectionName;
-				//allow index() function:
-				q.decoratePropertyMapping( elementName, collectionPersister );
-			}
-			else { //many-to-many
-				q.addCollection( collectionName, collectionRole );
-				elementName = q.createNameFor( clazz );
-				addJoin( elementName, ( AssociationType ) collectionElementType );
-			}
-			q.addFrom( elementName, clazz, joinSequence );
-			currentPropertyMapping = new CollectionPropertyMapping( collectionPersister );
-			return elementName;
-		}
-		else {
-			// collections of values
-			q.addFromCollection( collectionName, collectionRole, joinSequence );
-			return collectionName;
-		}
-
-	}
-
-	String getCollectionName() {
-		return collectionName;
-	}
-
-	String getCollectionRole() {
-		return collectionRole;
-	}
-
-	String getCollectionOwnerName() {
-		return collectionOwnerName;
-	}
-
-	String getOneToOneOwnerName() {
-		return oneToOneOwnerName;
-	}
-
-	AssociationType getOwnerAssociationType() {
-		return ownerAssociationType;
-	}
-
-	String getCurrentProperty() {
-		return currentProperty;
-	}
-
-	String getCurrentName() {
-		return currentName;
-	}
-
-	public void fetch(QueryTranslatorImpl q, String entityName) throws QueryException {
-		if ( isCollectionValued() ) {
-			q.setCollectionToFetch( getCollectionRole(), getCollectionName(), getCollectionOwnerName(), entityName );
-		}
-		else {
-			q.addEntityToFetch( entityName, getOneToOneOwnerName(), getOwnerAssociationType() );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,527 @@
+/*
+ * 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.classic;
+
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.CollectionSubqueryFactory;
+import org.hibernate.persister.collection.CollectionPropertyMapping;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * Parses an expression of the form foo.bar.baz and builds up an expression
+ * involving two less table joins than there are path components.
+ */
+public class PathExpressionParser implements Parser {
+
+	//TODO: this class does too many things! we need a different
+	//kind of path expression parser for each of the diffferent
+	//ways in which path expressions can occur
+
+	//We should actually rework this class to not implement Parser
+	//and just process path expressions in the most convenient way.
+
+	//The class is now way to complex!
+
+	private int dotcount;
+	private String currentName;
+	private String currentProperty;
+	private String oneToOneOwnerName;
+	private AssociationType ownerAssociationType;
+	private String[] columns;
+	private String collectionName;
+	private String collectionOwnerName;
+	private String collectionRole;
+	private final StringBuffer componentPath = new StringBuffer();
+	private Type type;
+	private final StringBuffer path = new StringBuffer();
+	private boolean ignoreInitialJoin;
+	private boolean continuation;
+	private int joinType = JoinFragment.INNER_JOIN; //default mode
+	private boolean useThetaStyleJoin = true;
+	private PropertyMapping currentPropertyMapping;
+	private JoinSequence joinSequence;
+
+	private boolean expectingCollectionIndex;
+	private LinkedList collectionElements = new LinkedList();
+
+	void setJoinType(int joinType) {
+		this.joinType = joinType;
+	}
+
+	void setUseThetaStyleJoin(boolean useThetaStyleJoin) {
+		this.useThetaStyleJoin = useThetaStyleJoin;
+	}
+
+	private void addJoin(String name, AssociationType joinableType) throws QueryException {
+		try {
+			joinSequence.addJoin( joinableType, name, joinType, currentColumns() );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+
+	private void addJoin(String name, AssociationType joinableType, String[] foreignKeyColumns) throws QueryException {
+		try {
+			joinSequence.addJoin( joinableType, name, joinType, foreignKeyColumns );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+
+	String continueFromManyToMany(String entityName, String[] joinColumns, QueryTranslatorImpl q) throws QueryException {
+		start( q );
+		continuation = true;
+		currentName = q.createNameFor( entityName );
+		q.addType( currentName, entityName );
+		Queryable classPersister = q.getEntityPersister( entityName );
+		//QueryJoinFragment join = q.createJoinFragment(useThetaStyleJoin);
+		addJoin( currentName, TypeFactory.manyToOne( entityName ), joinColumns );
+		currentPropertyMapping = classPersister;
+		return currentName;
+	}
+
+	public void ignoreInitialJoin() {
+		ignoreInitialJoin = true;
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		if ( token != null ) path.append( token );
+
+		String alias = q.getPathAlias( path.toString() );
+		if ( alias != null ) {
+			reset( q ); //reset the dotcount (but not the path)
+			currentName = alias; //after reset!
+			currentPropertyMapping = q.getPropertyMapping( currentName );
+			if ( !ignoreInitialJoin ) {
+				JoinSequence ojf = q.getPathJoin( path.toString() );
+				try {
+					joinSequence.addCondition( ojf.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() ); //after reset!
+				}
+				catch ( MappingException me ) {
+					throw new QueryException( me );
+				}
+				// we don't need to worry about any condition in the ON clause
+				// here (toFromFragmentString), since anything in the ON condition
+				// is already applied to the whole query
+			}
+		}
+		else if ( ".".equals( token ) ) {
+			dotcount++;
+		}
+		else {
+			if ( dotcount == 0 ) {
+				if ( !continuation ) {
+					if ( !q.isName( token ) ) throw new QueryException( "undefined alias: " + token );
+					currentName = token;
+					currentPropertyMapping = q.getPropertyMapping( currentName );
+				}
+			}
+			else if ( dotcount == 1 ) {
+				if ( currentName != null ) {
+					currentProperty = token;
+				}
+				else if ( collectionName != null ) {
+					//processCollectionProperty(token, q.getCollectionPersister(collectionRole), collectionName);
+					continuation = false;
+				}
+				else {
+					throw new QueryException( "unexpected" );
+				}
+			}
+			else { // dotcount>=2
+
+				// Do the corresponding RHS
+				Type propertyType = getPropertyType();
+
+				if ( propertyType == null ) {
+					throw new QueryException( "unresolved property: " + path );
+				}
+
+				if ( propertyType.isComponentType() ) {
+					dereferenceComponent( token );
+				}
+				else if ( propertyType.isEntityType() ) {
+					if ( !isCollectionValued() ) dereferenceEntity( token, ( EntityType ) propertyType, q );
+				}
+				else if ( propertyType.isCollectionType() ) {
+					dereferenceCollection( token, ( ( CollectionType ) propertyType ).getRole(), q );
+
+				}
+				else {
+					if ( token != null ) throw new QueryException( "dereferenced: " + path );
+				}
+
+			}
+		}
+	}
+
+	private void dereferenceEntity(String propertyName, EntityType propertyType, QueryTranslatorImpl q)
+			throws QueryException {
+		//NOTE: we avoid joining to the next table if the named property is just the foreign key value
+
+		//if its "id"
+		boolean isIdShortcut = EntityPersister.ENTITY_ID.equals( propertyName ) &&
+				propertyType.isReferenceToPrimaryKey();
+
+		//or its the id property name
+		final String idPropertyName;
+		try {
+			idPropertyName = propertyType.getIdentifierOrUniqueKeyPropertyName( q.getFactory() );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+		boolean isNamedIdPropertyShortcut = idPropertyName != null
+				&& idPropertyName.equals( propertyName )
+				&& propertyType.isReferenceToPrimaryKey();
+
+
+		if ( isIdShortcut || isNamedIdPropertyShortcut ) {
+			// special shortcut for id properties, skip the join!
+			// this must only occur at the _end_ of a path expression
+			if ( componentPath.length() > 0 ) componentPath.append( '.' );
+			componentPath.append( propertyName );
+		}
+		else {
+			String entityClass = propertyType.getAssociatedEntityName();
+			String name = q.createNameFor( entityClass );
+			q.addType( name, entityClass );
+			addJoin( name, propertyType );
+			if ( propertyType.isOneToOne() ) oneToOneOwnerName = currentName;
+			ownerAssociationType = propertyType;
+			currentName = name;
+			currentProperty = propertyName;
+			q.addPathAliasAndJoin( path.substring( 0, path.toString().lastIndexOf( '.' ) ), name, joinSequence.copy() );
+			componentPath.setLength( 0 );
+			currentPropertyMapping = q.getEntityPersister( entityClass );
+		}
+	}
+
+	private void dereferenceComponent(String propertyName) {
+		if ( propertyName != null ) {
+			if ( componentPath.length() > 0 ) componentPath.append( '.' );
+			componentPath.append( propertyName );
+		}
+	}
+
+	private void dereferenceCollection(String propertyName, String role, QueryTranslatorImpl q) throws QueryException {
+		collectionRole = role;
+		QueryableCollection collPersister = q.getCollectionPersister( role );
+		String name = q.createNameForCollection( role );
+		addJoin( name, collPersister.getCollectionType() );
+		//if ( collPersister.hasWhere() ) join.addCondition( collPersister.getSQLWhereString(name) );
+		collectionName = name;
+		collectionOwnerName = currentName;
+		currentName = name;
+		currentProperty = propertyName;
+		componentPath.setLength( 0 );
+		currentPropertyMapping = new CollectionPropertyMapping( collPersister );
+	}
+
+	private String getPropertyPath() {
+		if ( currentProperty == null ) {
+			return EntityPersister.ENTITY_ID;
+		}
+		else {
+			if ( componentPath.length() > 0 ) {
+				return new StringBuffer()
+						.append( currentProperty )
+						.append( '.' )
+						.append( componentPath.toString() )
+						.toString();
+			}
+			else {
+				return currentProperty;
+			}
+		}
+	}
+
+	private PropertyMapping getPropertyMapping() {
+		return currentPropertyMapping;
+	}
+
+	private void setType() throws QueryException {
+		if ( currentProperty == null ) {
+			type = getPropertyMapping().getType();
+		}
+		else {
+			type = getPropertyType();
+		}
+	}
+
+	protected Type getPropertyType() throws QueryException {
+		String propertyPath = getPropertyPath();
+		Type propertyType = getPropertyMapping().toType( propertyPath );
+		if ( propertyType == null ) {
+			throw new QueryException( "could not resolve property type: " + propertyPath );
+		}
+		return propertyType;
+	}
+
+	protected String[] currentColumns() throws QueryException {
+		String propertyPath = getPropertyPath();
+		String[] propertyColumns = getPropertyMapping().toColumns( currentName, propertyPath );
+		if ( propertyColumns == null ) {
+			throw new QueryException( "could not resolve property columns: " + propertyPath );
+		}
+		return propertyColumns;
+	}
+
+	private void reset(QueryTranslatorImpl q) {
+		//join = q.createJoinFragment(useThetaStyleJoin);
+		dotcount = 0;
+		currentName = null;
+		currentProperty = null;
+		collectionName = null;
+		collectionRole = null;
+		componentPath.setLength( 0 );
+		type = null;
+		collectionName = null;
+		columns = null;
+		expectingCollectionIndex = false;
+		continuation = false;
+		currentPropertyMapping = null;
+	}
+
+	public void start(QueryTranslatorImpl q) {
+		if ( !continuation ) {
+			reset( q );
+			path.setLength( 0 );
+			joinSequence = new JoinSequence( q.getFactory() ).setUseThetaStyle( useThetaStyleJoin );
+		}
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		ignoreInitialJoin = false;
+
+		Type propertyType = getPropertyType();
+		if ( propertyType != null && propertyType.isCollectionType() ) {
+			collectionRole = ( ( CollectionType ) propertyType ).getRole();
+			collectionName = q.createNameForCollection( collectionRole );
+			prepareForIndex( q );
+		}
+		else {
+			columns = currentColumns();
+			setType();
+		}
+
+		//important!!
+		continuation = false;
+
+	}
+
+	private void prepareForIndex(QueryTranslatorImpl q) throws QueryException {
+
+		QueryableCollection collPersister = q.getCollectionPersister( collectionRole );
+
+		if ( !collPersister.hasIndex() ) throw new QueryException( "unindexed collection before []: " + path );
+		String[] indexCols = collPersister.getIndexColumnNames();
+		if ( indexCols.length != 1 ) throw new QueryException( "composite-index appears in []: " + path );
+		//String[] keyCols = collPersister.getKeyColumnNames();
+
+		JoinSequence fromJoins = new JoinSequence( q.getFactory() )
+				.setUseThetaStyle( useThetaStyleJoin )
+				.setRoot( collPersister, collectionName )
+				.setNext( joinSequence.copy() );
+
+		if ( !continuation ) addJoin( collectionName, collPersister.getCollectionType() );
+
+		joinSequence.addCondition( collectionName + '.' + indexCols[0] + " = " ); //TODO: get SQL rendering out of here
+
+		CollectionElement elem = new CollectionElement();
+		elem.elementColumns = collPersister.getElementColumnNames(collectionName);
+		elem.elementType = collPersister.getElementType();
+		elem.isOneToMany = collPersister.isOneToMany();
+		elem.alias = collectionName;
+		elem.joinSequence = joinSequence;
+		collectionElements.addLast( elem );
+		setExpectingCollectionIndex();
+
+		q.addCollection( collectionName, collectionRole );
+		q.addFromJoinOnly( collectionName, fromJoins );
+	}
+
+	static final class CollectionElement {
+		Type elementType;
+		boolean isOneToMany;
+		String alias;
+		String[] elementColumns;
+		JoinSequence joinSequence;
+		StringBuffer indexValue = new StringBuffer();
+	}
+
+	public CollectionElement lastCollectionElement() {
+		return ( CollectionElement ) collectionElements.removeLast();
+	}
+
+	public void setLastCollectionElementIndexValue(String value) {
+		( ( CollectionElement ) collectionElements.getLast() ).indexValue.append( value );
+	}
+
+	public boolean isExpectingCollectionIndex() {
+		return expectingCollectionIndex;
+	}
+
+	protected void setExpectingCollectionIndex() throws QueryException {
+		expectingCollectionIndex = true;
+	}
+
+	public JoinSequence getWhereJoin() {
+		return joinSequence;
+	}
+
+	public String getWhereColumn() throws QueryException {
+		if ( columns.length != 1 ) {
+			throw new QueryException( "path expression ends in a composite value: " + path );
+		}
+		return columns[0];
+	}
+
+	public String[] getWhereColumns() {
+		return columns;
+	}
+
+	public Type getWhereColumnType() {
+		return type;
+	}
+
+	public String getName() {
+		return currentName == null ? collectionName : currentName;
+	}
+
+
+	public String getCollectionSubquery(Map enabledFilters) throws QueryException {
+		return CollectionSubqueryFactory.createCollectionSubquery( joinSequence, enabledFilters, currentColumns() );
+	}
+
+	public boolean isCollectionValued() throws QueryException {
+		//TODO: is there a better way?
+		return collectionName != null && !getPropertyType().isCollectionType();
+	}
+
+	public void addAssociation(QueryTranslatorImpl q) throws QueryException {
+		q.addJoin( getName(), joinSequence );
+	}
+
+	public String addFromAssociation(QueryTranslatorImpl q) throws QueryException {
+		if ( isCollectionValued() ) {
+			return addFromCollection( q );
+		}
+		else {
+			q.addFrom( currentName, joinSequence );
+			return currentName;
+		}
+	}
+
+	public String addFromCollection(QueryTranslatorImpl q) throws QueryException {
+		Type collectionElementType = getPropertyType();
+
+		if ( collectionElementType == null ) {
+			throw new QueryException( "must specify 'elements' for collection valued property in from clause: " + path );
+		}
+
+		if ( collectionElementType.isEntityType() ) {
+			// an association
+			QueryableCollection collectionPersister = q.getCollectionPersister( collectionRole );
+			Queryable entityPersister = ( Queryable ) collectionPersister.getElementPersister();
+			String clazz = entityPersister.getEntityName();
+
+			final String elementName;
+			if ( collectionPersister.isOneToMany() ) {
+				elementName = collectionName;
+				//allow index() function:
+				q.decoratePropertyMapping( elementName, collectionPersister );
+			}
+			else { //many-to-many
+				q.addCollection( collectionName, collectionRole );
+				elementName = q.createNameFor( clazz );
+				addJoin( elementName, ( AssociationType ) collectionElementType );
+			}
+			q.addFrom( elementName, clazz, joinSequence );
+			currentPropertyMapping = new CollectionPropertyMapping( collectionPersister );
+			return elementName;
+		}
+		else {
+			// collections of values
+			q.addFromCollection( collectionName, collectionRole, joinSequence );
+			return collectionName;
+		}
+
+	}
+
+	String getCollectionName() {
+		return collectionName;
+	}
+
+	String getCollectionRole() {
+		return collectionRole;
+	}
+
+	String getCollectionOwnerName() {
+		return collectionOwnerName;
+	}
+
+	String getOneToOneOwnerName() {
+		return oneToOneOwnerName;
+	}
+
+	AssociationType getOwnerAssociationType() {
+		return ownerAssociationType;
+	}
+
+	String getCurrentProperty() {
+		return currentProperty;
+	}
+
+	String getCurrentName() {
+		return currentName;
+	}
+
+	public void fetch(QueryTranslatorImpl q, String entityName) throws QueryException {
+		if ( isCollectionValued() ) {
+			q.setCollectionToFetch( getCollectionRole(), getCollectionName(), getCollectionOwnerName(), entityName );
+		}
+		else {
+			q.addEntityToFetch( entityName, getOneToOneOwnerName(), getOwnerAssociationType() );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,133 +0,0 @@
-//$Id: PreprocessingParser.java 5063 2004-12-24 03:51:20Z pgmjsd $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-import org.hibernate.hql.CollectionProperties;
-import org.hibernate.util.StringHelper;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- *
- */
-public class PreprocessingParser implements Parser {
-
-	private static final Set HQL_OPERATORS;
-
-	static {
-		HQL_OPERATORS = new HashSet();
-		HQL_OPERATORS.add( "<=" );
-		HQL_OPERATORS.add( ">=" );
-		HQL_OPERATORS.add( "=>" );
-		HQL_OPERATORS.add( "=<" );
-		HQL_OPERATORS.add( "!=" );
-		HQL_OPERATORS.add( "<>" );
-		HQL_OPERATORS.add( "!#" );
-		HQL_OPERATORS.add( "!~" );
-		HQL_OPERATORS.add( "!<" );
-		HQL_OPERATORS.add( "!>" );
-		HQL_OPERATORS.add( "is not" );
-		HQL_OPERATORS.add( "not like" );
-		HQL_OPERATORS.add( "not in" );
-		HQL_OPERATORS.add( "not between" );
-		HQL_OPERATORS.add( "not exists" );
-	}
-
-	private Map replacements;
-	private boolean quoted;
-	private StringBuffer quotedString;
-	private ClauseParser parser = new ClauseParser();
-	private String lastToken;
-	private String currentCollectionProp;
-
-	public PreprocessingParser(Map replacements) {
-		this.replacements = replacements;
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		//handle quoted strings
-		if ( quoted ) {
-			quotedString.append( token );
-		}
-		if ( "'".equals( token ) ) {
-			if ( quoted ) {
-				token = quotedString.toString();
-			}
-			else {
-				quotedString = new StringBuffer( 20 ).append( token );
-			}
-			quoted = !quoted;
-		}
-		if ( quoted ) return;
-
-		//ignore whitespace
-		if ( ParserHelper.isWhitespace( token ) ) return;
-
-		//do replacements
-		String substoken = ( String ) replacements.get( token );
-		token = ( substoken == null ) ? token : substoken;
-
-		//handle HQL2 collection syntax
-		if ( currentCollectionProp != null ) {
-			if ( "(".equals( token ) ) {
-				return;
-			}
-			else if ( ")".equals( token ) ) {
-				currentCollectionProp = null;
-				return;
-			}
-			else {
-				token = StringHelper.qualify( token, currentCollectionProp );
-			}
-		}
-		else {
-			String prop = CollectionProperties.getNormalizedPropertyName( token.toLowerCase() );
-			if ( prop != null ) {
-				currentCollectionProp = prop;
-				return;
-			}
-		}
-
-
-		//handle <=, >=, !=, is not, not between, not in
-		if ( lastToken == null ) {
-			lastToken = token;
-		}
-		else {
-			String doubleToken = ( token.length() > 1 ) ?
-					lastToken + ' ' + token :
-					lastToken + token;
-			if ( HQL_OPERATORS.contains( doubleToken.toLowerCase() ) ) {
-				parser.token( doubleToken, q );
-				lastToken = null;
-			}
-			else {
-				parser.token( lastToken, q );
-				lastToken = token;
-			}
-		}
-
-	}
-
-	public void start(QueryTranslatorImpl q) throws QueryException {
-		quoted = false;
-		parser.start( q );
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		if ( lastToken != null ) parser.token( lastToken, q );
-		parser.end( q );
-		lastToken = null;
-		currentCollectionProp = null;
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/PreprocessingParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,156 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+import org.hibernate.hql.CollectionProperties;
+import org.hibernate.util.StringHelper;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ */
+public class PreprocessingParser implements Parser {
+
+	private static final Set HQL_OPERATORS;
+
+	static {
+		HQL_OPERATORS = new HashSet();
+		HQL_OPERATORS.add( "<=" );
+		HQL_OPERATORS.add( ">=" );
+		HQL_OPERATORS.add( "=>" );
+		HQL_OPERATORS.add( "=<" );
+		HQL_OPERATORS.add( "!=" );
+		HQL_OPERATORS.add( "<>" );
+		HQL_OPERATORS.add( "!#" );
+		HQL_OPERATORS.add( "!~" );
+		HQL_OPERATORS.add( "!<" );
+		HQL_OPERATORS.add( "!>" );
+		HQL_OPERATORS.add( "is not" );
+		HQL_OPERATORS.add( "not like" );
+		HQL_OPERATORS.add( "not in" );
+		HQL_OPERATORS.add( "not between" );
+		HQL_OPERATORS.add( "not exists" );
+	}
+
+	private Map replacements;
+	private boolean quoted;
+	private StringBuffer quotedString;
+	private ClauseParser parser = new ClauseParser();
+	private String lastToken;
+	private String currentCollectionProp;
+
+	public PreprocessingParser(Map replacements) {
+		this.replacements = replacements;
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		//handle quoted strings
+		if ( quoted ) {
+			quotedString.append( token );
+		}
+		if ( "'".equals( token ) ) {
+			if ( quoted ) {
+				token = quotedString.toString();
+			}
+			else {
+				quotedString = new StringBuffer( 20 ).append( token );
+			}
+			quoted = !quoted;
+		}
+		if ( quoted ) return;
+
+		//ignore whitespace
+		if ( ParserHelper.isWhitespace( token ) ) return;
+
+		//do replacements
+		String substoken = ( String ) replacements.get( token );
+		token = ( substoken == null ) ? token : substoken;
+
+		//handle HQL2 collection syntax
+		if ( currentCollectionProp != null ) {
+			if ( "(".equals( token ) ) {
+				return;
+			}
+			else if ( ")".equals( token ) ) {
+				currentCollectionProp = null;
+				return;
+			}
+			else {
+				token = StringHelper.qualify( token, currentCollectionProp );
+			}
+		}
+		else {
+			String prop = CollectionProperties.getNormalizedPropertyName( token.toLowerCase() );
+			if ( prop != null ) {
+				currentCollectionProp = prop;
+				return;
+			}
+		}
+
+
+		//handle <=, >=, !=, is not, not between, not in
+		if ( lastToken == null ) {
+			lastToken = token;
+		}
+		else {
+			String doubleToken = ( token.length() > 1 ) ?
+					lastToken + ' ' + token :
+					lastToken + token;
+			if ( HQL_OPERATORS.contains( doubleToken.toLowerCase() ) ) {
+				parser.token( doubleToken, q );
+				lastToken = null;
+			}
+			else {
+				parser.token( lastToken, q );
+				lastToken = token;
+			}
+		}
+
+	}
+
+	public void start(QueryTranslatorImpl q) throws QueryException {
+		quoted = false;
+		parser.start( q );
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		if ( lastToken != null ) parser.token( lastToken, q );
+		parser.end( q );
+		lastToken = null;
+		currentCollectionProp = null;
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1161 +0,0 @@
-//$Id: QueryTranslatorImpl.java 11080 2007-01-23 16:29:18Z steve.ebersole at jboss.com $
-package org.hibernate.hql.classic;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.FilterTranslator;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.hql.NameGenerator;
-import org.hibernate.hql.ParameterTranslations;
-import org.hibernate.impl.IteratorImpl;
-import org.hibernate.loader.BasicLoader;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.QuerySelect;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * An instance of <tt>QueryTranslator</tt> translates a Hibernate
- * query string to SQL.
- */
-public class QueryTranslatorImpl extends BasicLoader implements FilterTranslator {
-
-	private static final String[] NO_RETURN_ALIASES = new String[] {};
-
-	private final String queryIdentifier;
-	private final String queryString;
-
-	private final Map typeMap = new LinkedHashMap();
-	private final Map collections = new LinkedHashMap();
-	private List returnedTypes = new ArrayList();
-	private final List fromTypes = new ArrayList();
-	private final List scalarTypes = new ArrayList();
-	private final Map namedParameters = new HashMap();
-	private final Map aliasNames = new HashMap();
-	private final Map oneToOneOwnerNames = new HashMap();
-	private final Map uniqueKeyOwnerReferences = new HashMap();
-	private final Map decoratedPropertyMappings = new HashMap();
-
-	private final List scalarSelectTokens = new ArrayList();
-	private final List whereTokens = new ArrayList();
-	private final List havingTokens = new ArrayList();
-	private final Map joins = new LinkedHashMap();
-	private final List orderByTokens = new ArrayList();
-	private final List groupByTokens = new ArrayList();
-	private final Set querySpaces = new HashSet();
-	private final Set entitiesToFetch = new HashSet();
-
-	private final Map pathAliases = new HashMap();
-	private final Map pathJoins = new HashMap();
-
-	private Queryable[] persisters;
-	private int[] owners;
-	private EntityType[] ownerAssociationTypes;
-	private String[] names;
-	private boolean[] includeInSelect;
-	private int selectLength;
-	private Type[] returnTypes;
-	private Type[] actualReturnTypes;
-	private String[][] scalarColumnNames;
-	private Map tokenReplacements;
-	private int nameCount = 0;
-	private int parameterCount = 0;
-	private boolean distinct = false;
-	private boolean compiled;
-	private String sqlString;
-	private Class holderClass;
-	private Constructor holderConstructor;
-	private boolean hasScalars;
-	private boolean shallowQuery;
-	private QueryTranslatorImpl superQuery;
-
-	private QueryableCollection collectionPersister;
-	private int collectionOwnerColumn = -1;
-	private String collectionOwnerName;
-	private String fetchName;
-
-	private String[] suffixes;
-
-	private Map enabledFilters;
-
-	private static final Logger log = LoggerFactory.getLogger( QueryTranslatorImpl.class );
-
-	/**
-	 * Construct a query translator
-	 *
-	 * @param queryIdentifier A unique identifier for the query of which this
-	 * translation is part; typically this is the original, user-supplied query string.
-	 * @param queryString The "preprocessed" query string; at the very least
-	 * already processed by {@link org.hibernate.hql.QuerySplitter}.
-	 * @param enabledFilters Any enabled filters.
-	 * @param factory The session factory.
-	 */
-	public QueryTranslatorImpl(
-			String queryIdentifier,
-	        String queryString,
-	        Map enabledFilters,
-	        SessionFactoryImplementor factory) {
-		super( factory );
-		this.queryIdentifier = queryIdentifier;
-		this.queryString = queryString;
-		this.enabledFilters = enabledFilters;
-	}
-
-	/**
-	 * Construct a query translator; this form used internally.
-	 *
-	 * @param queryString The query string to process.
-	 * @param enabledFilters Any enabled filters.
-	 * @param factory The session factory.
-	 */
-	public QueryTranslatorImpl(
-	        String queryString,
-	        Map enabledFilters,
-	        SessionFactoryImplementor factory) {
-		this( queryString, queryString, enabledFilters, factory );
-	}
-
-	/**
-	 * Compile a subquery.
-	 *
-	 * @param superquery The containing query of the query to be compiled.
-	 *
-	 * @throws org.hibernate.MappingException Indicates problems resolving
-	 * things referenced in the query.
-	 * @throws org.hibernate.QueryException Generally some form of syntatic
-	 * failure.
-	 */
-	void compile(QueryTranslatorImpl superquery) throws QueryException, MappingException {
-		this.tokenReplacements = superquery.tokenReplacements;
-		this.superQuery = superquery;
-		this.shallowQuery = true;
-		this.enabledFilters = superquery.getEnabledFilters();
-		compile();
-	}
-
-
-	/**
-	 * Compile a "normal" query. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 */
-	public synchronized void compile(
-			Map replacements,
-			boolean scalar) throws QueryException, MappingException {
-		if ( !compiled ) {
-			this.tokenReplacements = replacements;
-			this.shallowQuery = scalar;
-			compile();
-		}
-	}
-
-	/**
-	 * Compile a filter. This method may be called multiple
-	 * times. Subsequent invocations are no-ops.
-	 */
-	public synchronized void compile(
-			String collectionRole,
-			Map replacements,
-			boolean scalar) throws QueryException, MappingException {
-
-		if ( !isCompiled() ) {
-			addFromAssociation( "this", collectionRole );
-			compile( replacements, scalar );
-		}
-	}
-
-	/**
-	 * Compile the query (generate the SQL).
-	 *
-	 * @throws org.hibernate.MappingException Indicates problems resolving
-	 * things referenced in the query.
-	 * @throws org.hibernate.QueryException Generally some form of syntatic
-	 * failure.
-	 */
-	private void compile() throws QueryException, MappingException {
-
-		log.trace( "compiling query" );
-		try {
-			ParserHelper.parse( new PreprocessingParser( tokenReplacements ),
-					queryString,
-					ParserHelper.HQL_SEPARATORS,
-					this );
-			renderSQL();
-		}
-		catch ( QueryException qe ) {
-			qe.setQueryString( queryString );
-			throw qe;
-		}
-		catch ( MappingException me ) {
-			throw me;
-		}
-		catch ( Exception e ) {
-			log.debug( "unexpected query compilation problem", e );
-			e.printStackTrace();
-			QueryException qe = new QueryException( "Incorrect query syntax", e );
-			qe.setQueryString( queryString );
-			throw qe;
-		}
-
-		postInstantiate();
-
-		compiled = true;
-
-	}
-
-	public String getSQLString() {
-		return sqlString;
-	}
-
-	public List collectSqlStrings() {
-		return ArrayHelper.toList( new String[] { sqlString } );
-	}
-
-	public String getQueryString() {
-		return queryString;
-	}
-
-	/**
-	 * Persisters for the return values of a <tt>find()</tt> style query.
-	 *
-	 * @return an array of <tt>EntityPersister</tt>s.
-	 */
-	protected Loadable[] getEntityPersisters() {
-		return persisters;
-	}
-
-	/**
-	 * Types of the return values of an <tt>iterate()</tt> style query.
-	 *
-	 * @return an array of <tt>Type</tt>s.
-	 */
-	public Type[] getReturnTypes() {
-		return actualReturnTypes;
-	}
-	
-	public String[] getReturnAliases() {
-		// return aliases not supported in classic translator!
-		return NO_RETURN_ALIASES;
-	}
-
-	public String[][] getColumnNames() {
-		return scalarColumnNames;
-	}
-
-	private static void logQuery(String hql, String sql) {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "HQL: " + hql );
-			log.debug( "SQL: " + sql );
-		}
-	}
-
-	void setAliasName(String alias, String name) {
-		aliasNames.put( alias, name );
-	}
-
-	public String getAliasName(String alias) {
-		String name = ( String ) aliasNames.get( alias );
-		if ( name == null ) {
-			if ( superQuery != null ) {
-				name = superQuery.getAliasName( alias );
-			}
-			else {
-				name = alias;
-			}
-		}
-		return name;
-	}
-
-	String unalias(String path) {
-		String alias = StringHelper.root( path );
-		String name = getAliasName( alias );
-		if ( name != null ) {
-			return name + path.substring( alias.length() );
-		}
-		else {
-			return path;
-		}
-	}
-
-	void addEntityToFetch(String name, String oneToOneOwnerName, AssociationType ownerAssociationType) {
-		addEntityToFetch( name );
-		if ( oneToOneOwnerName != null ) oneToOneOwnerNames.put( name, oneToOneOwnerName );
-		if ( ownerAssociationType != null ) uniqueKeyOwnerReferences.put( name, ownerAssociationType );
-	}
-
-	private void addEntityToFetch(String name) {
-		entitiesToFetch.add( name );
-	}
-
-	private int nextCount() {
-		return ( superQuery == null ) ? nameCount++ : superQuery.nameCount++;
-	}
-
-	String createNameFor(String type) {
-		return StringHelper.generateAlias( type, nextCount() );
-	}
-
-	String createNameForCollection(String role) {
-		return StringHelper.generateAlias( role, nextCount() );
-	}
-
-	private String getType(String name) {
-		String type = ( String ) typeMap.get( name );
-		if ( type == null && superQuery != null ) {
-			type = superQuery.getType( name );
-		}
-		return type;
-	}
-
-	private String getRole(String name) {
-		String role = ( String ) collections.get( name );
-		if ( role == null && superQuery != null ) {
-			role = superQuery.getRole( name );
-		}
-		return role;
-	}
-
-	boolean isName(String name) {
-		return aliasNames.containsKey( name ) ||
-				typeMap.containsKey( name ) ||
-				collections.containsKey( name ) || (
-				superQuery != null && superQuery.isName( name )
-				);
-	}
-
-	PropertyMapping getPropertyMapping(String name) throws QueryException {
-		PropertyMapping decorator = getDecoratedPropertyMapping( name );
-		if ( decorator != null ) return decorator;
-
-		String type = getType( name );
-		if ( type == null ) {
-			String role = getRole( name );
-			if ( role == null ) {
-				throw new QueryException( "alias not found: " + name );
-			}
-			return getCollectionPersister( role ); //.getElementPropertyMapping();
-		}
-		else {
-			Queryable persister = getEntityPersister( type );
-			if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
-			return persister;
-		}
-	}
-
-	private PropertyMapping getDecoratedPropertyMapping(String name) {
-		return ( PropertyMapping ) decoratedPropertyMappings.get( name );
-	}
-
-	void decoratePropertyMapping(String name, PropertyMapping mapping) {
-		decoratedPropertyMappings.put( name, mapping );
-	}
-
-	private Queryable getEntityPersisterForName(String name) throws QueryException {
-		String type = getType( name );
-		Queryable persister = getEntityPersister( type );
-		if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
-		return persister;
-	}
-
-	Queryable getEntityPersisterUsingImports(String className) {
-		final String importedClassName = getFactory().getImportedClassName( className );
-		if ( importedClassName == null ) {
-			return null;
-		}
-		try {
-			return ( Queryable ) getFactory().getEntityPersister( importedClassName );
-		}
-		catch ( MappingException me ) {
-			return null;
-		}
-	}
-
-	Queryable getEntityPersister(String entityName) throws QueryException {
-		try {
-			return ( Queryable ) getFactory().getEntityPersister( entityName );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( "persistent class not found: " + entityName );
-		}
-	}
-
-	QueryableCollection getCollectionPersister(String role) throws QueryException {
-		try {
-			return ( QueryableCollection ) getFactory().getCollectionPersister( role );
-		}
-		catch ( ClassCastException cce ) {
-			throw new QueryException( "collection role is not queryable: " + role );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( "collection role not found: " + role );
-		}
-	}
-
-	void addType(String name, String type) {
-		typeMap.put( name, type );
-	}
-
-	void addCollection(String name, String role) {
-		collections.put( name, role );
-	}
-
-	void addFrom(String name, String type, JoinSequence joinSequence)
-			throws QueryException {
-		addType( name, type );
-		addFrom( name, joinSequence );
-	}
-
-	void addFromCollection(String name, String collectionRole, JoinSequence joinSequence)
-			throws QueryException {
-		//register collection role
-		addCollection( name, collectionRole );
-		addJoin( name, joinSequence );
-	}
-
-	void addFrom(String name, JoinSequence joinSequence)
-			throws QueryException {
-		fromTypes.add( name );
-		addJoin( name, joinSequence );
-	}
-
-	void addFromClass(String name, Queryable classPersister)
-			throws QueryException {
-		JoinSequence joinSequence = new JoinSequence( getFactory() )
-				.setRoot( classPersister, name );
-		//crossJoins.add(name);
-		addFrom( name, classPersister.getEntityName(), joinSequence );
-	}
-
-	void addSelectClass(String name) {
-		returnedTypes.add( name );
-	}
-
-	void addSelectScalar(Type type) {
-		scalarTypes.add( type );
-	}
-
-	void appendWhereToken(String token) {
-		whereTokens.add( token );
-	}
-
-	void appendHavingToken(String token) {
-		havingTokens.add( token );
-	}
-
-	void appendOrderByToken(String token) {
-		orderByTokens.add( token );
-	}
-
-	void appendGroupByToken(String token) {
-		groupByTokens.add( token );
-	}
-
-	void appendScalarSelectToken(String token) {
-		scalarSelectTokens.add( token );
-	}
-
-	void appendScalarSelectTokens(String[] tokens) {
-		scalarSelectTokens.add( tokens );
-	}
-
-	void addFromJoinOnly(String name, JoinSequence joinSequence) throws QueryException {
-		addJoin( name, joinSequence.getFromPart() );
-	}
-
-	void addJoin(String name, JoinSequence joinSequence) throws QueryException {
-		if ( !joins.containsKey( name ) ) joins.put( name, joinSequence );
-	}
-
-	void addNamedParameter(String name) {
-		if ( superQuery != null ) superQuery.addNamedParameter( name );
-		Integer loc = new Integer( parameterCount++ );
-		Object o = namedParameters.get( name );
-		if ( o == null ) {
-			namedParameters.put( name, loc );
-		}
-		else if ( o instanceof Integer ) {
-			ArrayList list = new ArrayList( 4 );
-			list.add( o );
-			list.add( loc );
-			namedParameters.put( name, list );
-		}
-		else {
-			( ( ArrayList ) o ).add( loc );
-		}
-	}
-
-	public int[] getNamedParameterLocs(String name) throws QueryException {
-		Object o = namedParameters.get( name );
-		if ( o == null ) {
-			QueryException qe = new QueryException( ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name );
-			qe.setQueryString( queryString );
-			throw qe;
-		}
-		if ( o instanceof Integer ) {
-			return new int[]{ ( ( Integer ) o ).intValue() };
-		}
-		else {
-			return ArrayHelper.toIntArray( ( ArrayList ) o );
-		}
-	}
-
-	private void renderSQL() throws QueryException, MappingException {
-
-		final int rtsize;
-		if ( returnedTypes.size() == 0 && scalarTypes.size() == 0 ) {
-			//ie no select clause in HQL
-			returnedTypes = fromTypes;
-			rtsize = returnedTypes.size();
-		}
-		else {
-			rtsize = returnedTypes.size();
-			Iterator iter = entitiesToFetch.iterator();
-			while ( iter.hasNext() ) {
-				returnedTypes.add( iter.next() );
-			}
-		}
-		int size = returnedTypes.size();
-		persisters = new Queryable[size];
-		names = new String[size];
-		owners = new int[size];
-		ownerAssociationTypes = new EntityType[size];
-		suffixes = new String[size];
-		includeInSelect = new boolean[size];
-		for ( int i = 0; i < size; i++ ) {
-			String name = ( String ) returnedTypes.get( i );
-			//if ( !isName(name) ) throw new QueryException("unknown type: " + name);
-			persisters[i] = getEntityPersisterForName( name );
-			// TODO: cannot use generateSuffixes() - it handles the initial suffix differently.
-			suffixes[i] = ( size == 1 ) ? "" : Integer.toString( i ) + '_';
-			names[i] = name;
-			includeInSelect[i] = !entitiesToFetch.contains( name );
-			if ( includeInSelect[i] ) selectLength++;
-			if ( name.equals( collectionOwnerName ) ) collectionOwnerColumn = i;
-			String oneToOneOwner = ( String ) oneToOneOwnerNames.get( name );
-			owners[i] = ( oneToOneOwner == null ) ? -1 : returnedTypes.indexOf( oneToOneOwner );
-			ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get( name );
-		}
-
-		if ( ArrayHelper.isAllNegative( owners ) ) owners = null;
-
-		String scalarSelect = renderScalarSelect(); //Must be done here because of side-effect! yuck...
-
-		int scalarSize = scalarTypes.size();
-		hasScalars = scalarTypes.size() != rtsize;
-
-		returnTypes = new Type[scalarSize];
-		for ( int i = 0; i < scalarSize; i++ ) {
-			returnTypes[i] = ( Type ) scalarTypes.get( i );
-		}
-
-		QuerySelect sql = new QuerySelect( getFactory().getDialect() );
-		sql.setDistinct( distinct );
-
-		if ( !shallowQuery ) {
-			renderIdentifierSelect( sql );
-			renderPropertiesSelect( sql );
-		}
-
-		if ( collectionPersister != null ) {
-			sql.addSelectFragmentString( collectionPersister.selectFragment( fetchName, "__" ) );
-		}
-
-		if ( hasScalars || shallowQuery ) sql.addSelectFragmentString( scalarSelect );
-
-		//TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings
-		mergeJoins( sql.getJoinFragment() );
-
-		sql.setWhereTokens( whereTokens.iterator() );
-
-		sql.setGroupByTokens( groupByTokens.iterator() );
-		sql.setHavingTokens( havingTokens.iterator() );
-		sql.setOrderByTokens( orderByTokens.iterator() );
-
-		if ( collectionPersister != null && collectionPersister.hasOrdering() ) {
-			sql.addOrderBy( collectionPersister.getSQLOrderByString( fetchName ) );
-		}
-
-		scalarColumnNames = NameGenerator.generateColumnNames( returnTypes, getFactory() );
-
-		// initialize the Set of queried identifier spaces (ie. tables)
-		Iterator iter = collections.values().iterator();
-		while ( iter.hasNext() ) {
-			CollectionPersister p = getCollectionPersister( ( String ) iter.next() );
-			addQuerySpaces( p.getCollectionSpaces() );
-		}
-		iter = typeMap.keySet().iterator();
-		while ( iter.hasNext() ) {
-			Queryable p = getEntityPersisterForName( ( String ) iter.next() );
-			addQuerySpaces( p.getQuerySpaces() );
-		}
-
-		sqlString = sql.toQueryString();
-
-		if ( holderClass != null ) holderConstructor = ReflectHelper.getConstructor( holderClass, returnTypes );
-
-		if ( hasScalars ) {
-			actualReturnTypes = returnTypes;
-		}
-		else {
-			actualReturnTypes = new Type[selectLength];
-			int j = 0;
-			for ( int i = 0; i < persisters.length; i++ ) {
-				if ( includeInSelect[i] ) {
-					actualReturnTypes[j++] = TypeFactory.manyToOne( persisters[i].getEntityName(), shallowQuery );
-				}
-			}
-		}
-
-	}
-
-	private void renderIdentifierSelect(QuerySelect sql) {
-		int size = returnedTypes.size();
-
-		for ( int k = 0; k < size; k++ ) {
-			String name = ( String ) returnedTypes.get( k );
-			String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
-			sql.addSelectFragmentString( persisters[k].identifierSelectFragment( name, suffix ) );
-		}
-
-	}
-
-	/*private String renderOrderByPropertiesSelect() {
-		StringBuffer buf = new StringBuffer(10);
-
-		//add the columns we are ordering by to the select ID select clause
-		Iterator iter = orderByTokens.iterator();
-		while ( iter.hasNext() ) {
-			String token = (String) iter.next();
-			if ( token.lastIndexOf(".") > 0 ) {
-				//ie. it is of form "foo.bar", not of form "asc" or "desc"
-				buf.append(StringHelper.COMMA_SPACE).append(token);
-			}
-		}
-
-		return buf.toString();
-	}*/
-
-	private void renderPropertiesSelect(QuerySelect sql) {
-		int size = returnedTypes.size();
-		for ( int k = 0; k < size; k++ ) {
-			String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
-			String name = ( String ) returnedTypes.get( k );
-			sql.addSelectFragmentString( persisters[k].propertySelectFragment( name, suffix, false ) );
-		}
-	}
-
-	/**
-	 * WARNING: side-effecty
-	 */
-	private String renderScalarSelect() {
-
-		boolean isSubselect = superQuery != null;
-
-		StringBuffer buf = new StringBuffer( 20 );
-
-		if ( scalarTypes.size() == 0 ) {
-			//ie. no select clause
-			int size = returnedTypes.size();
-			for ( int k = 0; k < size; k++ ) {
-
-				scalarTypes.add( TypeFactory.manyToOne( persisters[k].getEntityName(), shallowQuery ) );
-
-				String[] idColumnNames = persisters[k].getIdentifierColumnNames();
-				for ( int i = 0; i < idColumnNames.length; i++ ) {
-					buf.append( returnedTypes.get( k ) ).append( '.' ).append( idColumnNames[i] );
-					if ( !isSubselect ) buf.append( " as " ).append( NameGenerator.scalarName( k, i ) );
-					if ( i != idColumnNames.length - 1 || k != size - 1 ) buf.append( ", " );
-				}
-
-			}
-
-		}
-		else {
-			//there _was_ a select clause
-			Iterator iter = scalarSelectTokens.iterator();
-			int c = 0;
-			boolean nolast = false; //real hacky...
-			int parenCount = 0; // used to count the nesting of parentheses
-			while ( iter.hasNext() ) {
-				Object next = iter.next();
-				if ( next instanceof String ) {
-					String token = ( String ) next;
-
-					if ( "(".equals( token ) ) {
-						parenCount++;
-					}
-					else if ( ")".equals( token ) ) {
-						parenCount--;
-					}
-
-					String lc = token.toLowerCase();
-					if ( lc.equals( ", " ) ) {
-						if ( nolast ) {
-							nolast = false;
-						}
-						else {
-							if ( !isSubselect && parenCount == 0 ) {
-								int x = c++;
-								buf.append( " as " )
-										.append( NameGenerator.scalarName( x, 0 ) );
-							}
-						}
-					}
-					buf.append( token );
-					if ( lc.equals( "distinct" ) || lc.equals( "all" ) ) {
-						buf.append( ' ' );
-					}
-				}
-				else {
-					nolast = true;
-					String[] tokens = ( String[] ) next;
-					for ( int i = 0; i < tokens.length; i++ ) {
-						buf.append( tokens[i] );
-						if ( !isSubselect ) {
-							buf.append( " as " )
-									.append( NameGenerator.scalarName( c, i ) );
-						}
-						if ( i != tokens.length - 1 ) buf.append( ", " );
-					}
-					c++;
-				}
-			}
-			if ( !isSubselect && !nolast ) {
-				int x = c++;
-				buf.append( " as " )
-						.append( NameGenerator.scalarName( x, 0 ) );
-			}
-
-		}
-
-		return buf.toString();
-	}
-
-	private void mergeJoins(JoinFragment ojf) throws MappingException, QueryException {
-
-		Iterator iter = joins.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) iter.next();
-			String name = ( String ) me.getKey();
-			JoinSequence join = ( JoinSequence ) me.getValue();
-			join.setSelector( new JoinSequence.Selector() {
-				public boolean includeSubclasses(String alias) {
-					boolean include = returnedTypes.contains( alias ) && !isShallowQuery();
-					return include;
-				}
-			} );
-
-			if ( typeMap.containsKey( name ) ) {
-				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
-			}
-			else if ( collections.containsKey( name ) ) {
-				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
-			}
-			else {
-				//name from a super query (a bit inelegant that it shows up here)
-			}
-
-		}
-
-	}
-
-	public final Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	/**
-	 * Is this query called by scroll() or iterate()?
-	 *
-	 * @return true if it is, false if it is called by find() or list()
-	 */
-	boolean isShallowQuery() {
-		return shallowQuery;
-	}
-
-	void addQuerySpaces(Serializable[] spaces) {
-		for ( int i = 0; i < spaces.length; i++ ) {
-			querySpaces.add( spaces[i] );
-		}
-		if ( superQuery != null ) superQuery.addQuerySpaces( spaces );
-	}
-
-	void setDistinct(boolean distinct) {
-		this.distinct = distinct;
-	}
-
-	boolean isSubquery() {
-		return superQuery != null;
-	}
-
-	/**
-	 * Overrides method from Loader
-	 */
-	public CollectionPersister[] getCollectionPersisters() {
-		return collectionPersister == null ? null : new CollectionPersister[] { collectionPersister };
-	}
-
-	protected String[] getCollectionSuffixes() {
-		return collectionPersister == null ? null : new String[] { "__" };
-	}
-
-	void setCollectionToFetch(String role, String name, String ownerName, String entityName)
-			throws QueryException {
-		fetchName = name;
-		collectionPersister = getCollectionPersister( role );
-		collectionOwnerName = ownerName;
-		if ( collectionPersister.getElementType().isEntityType() ) {
-			addEntityToFetch( entityName );
-		}
-	}
-
-	protected String[] getSuffixes() {
-		return suffixes;
-	}
-
-	protected String[] getAliases() {
-		return names;
-	}
-
-	/**
-	 * Used for collection filters
-	 */
-	private void addFromAssociation(final String elementName, final String collectionRole)
-			throws QueryException {
-		//q.addCollection(collectionName, collectionRole);
-		QueryableCollection persister = getCollectionPersister( collectionRole );
-		Type collectionElementType = persister.getElementType();
-		if ( !collectionElementType.isEntityType() ) {
-			throw new QueryException( "collection of values in filter: " + elementName );
-		}
-
-		String[] keyColumnNames = persister.getKeyColumnNames();
-		//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);
-
-		String collectionName;
-		JoinSequence join = new JoinSequence( getFactory() );
-		collectionName = persister.isOneToMany() ?
-				elementName :
-				createNameForCollection( collectionRole );
-		join.setRoot( persister, collectionName );
-		if ( !persister.isOneToMany() ) {
-			//many-to-many
-			addCollection( collectionName, collectionRole );
-			try {
-				join.addJoin( ( AssociationType ) persister.getElementType(),
-						elementName,
-						JoinFragment.INNER_JOIN,
-						persister.getElementColumnNames(collectionName) );
-			}
-			catch ( MappingException me ) {
-				throw new QueryException( me );
-			}
-		}
-		join.addCondition( collectionName, keyColumnNames, " = ?" );
-		//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
-		EntityType elemType = ( EntityType ) collectionElementType;
-		addFrom( elementName, elemType.getAssociatedEntityName(), join );
-
-	}
-
-	String getPathAlias(String path) {
-		return ( String ) pathAliases.get( path );
-	}
-
-	JoinSequence getPathJoin(String path) {
-		return ( JoinSequence ) pathJoins.get( path );
-	}
-
-	void addPathAliasAndJoin(String path, String alias, JoinSequence joinSequence) {
-		pathAliases.put( path, alias );
-		pathJoins.put( path, joinSequence );
-	}
-
-	public List list(SessionImplementor session, QueryParameters queryParameters)
-			throws HibernateException {
-		return list( session, queryParameters, getQuerySpaces(), actualReturnTypes );
-	}
-
-	/**
-	 * Return the query results as an iterator
-	 */
-	public Iterator iterate(QueryParameters queryParameters, EventSource session)
-			throws HibernateException {
-
-		boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
-		long startTime = 0;
-		if ( stats ) startTime = System.currentTimeMillis();
-
-		try {
-
-			PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
-			ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session );
-			HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
-			Iterator result = new IteratorImpl( rs, st, session, returnTypes, getColumnNames(), hi );
-
-			if ( stats ) {
-				session.getFactory().getStatisticsImplementor().queryExecuted(
-						"HQL: " + queryString,
-						0,
-						System.currentTimeMillis() - startTime
-					);
-			}
-
-			return result;
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert( 
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not execute query using iterate",
-					getSQLString() 
-				);
-		}
-
-	}
-
-	public int executeUpdate(QueryParameters queryParameters, SessionImplementor session) throws HibernateException {
-		throw new UnsupportedOperationException( "Not supported!  Use the AST translator...");
-	}
-
-	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
-			throws SQLException, HibernateException {
-		row = toResultRow( row );
-		if ( hasScalars ) {
-			String[][] scalarColumns = getColumnNames();
-			int queryCols = returnTypes.length;
-			if ( holderClass == null && queryCols == 1 ) {
-				return returnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null );
-			}
-			else {
-				row = new Object[queryCols];
-				for ( int i = 0; i < queryCols; i++ )
-					row[i] = returnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null );
-				return row;
-			}
-		}
-		else if ( holderClass == null ) {
-			return row.length == 1 ? row[0] : row;
-		}
-		else {
-			return row;
-		}
-
-	}
-
-	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
-		if ( holderClass != null ) {
-			for ( int i = 0; i < results.size(); i++ ) {
-				Object[] row = ( Object[] ) results.get( i );
-				try {
-					results.set( i, holderConstructor.newInstance( row ) );
-				}
-				catch ( Exception e ) {
-					throw new QueryException( "could not instantiate: " + holderClass, e );
-				}
-			}
-		}
-		return results;
-	}
-
-	private Object[] toResultRow(Object[] row) {
-		if ( selectLength == row.length ) {
-			return row;
-		}
-		else {
-			Object[] result = new Object[selectLength];
-			int j = 0;
-			for ( int i = 0; i < row.length; i++ ) {
-				if ( includeInSelect[i] ) result[j++] = row[i];
-			}
-			return result;
-		}
-	}
-
-	void setHolderClass(Class clazz) {
-		holderClass = clazz;
-	}
-
-	protected LockMode[] getLockModes(Map lockModes) {
-		// unfortunately this stuff can't be cached because
-		// it is per-invocation, not constant for the
-		// QueryTranslator instance
-		HashMap nameLockModes = new HashMap();
-		if ( lockModes != null ) {
-			Iterator iter = lockModes.entrySet().iterator();
-			while ( iter.hasNext() ) {
-				Map.Entry me = ( Map.Entry ) iter.next();
-				nameLockModes.put( getAliasName( ( String ) me.getKey() ),
-						me.getValue() );
-			}
-		}
-		LockMode[] lockModeArray = new LockMode[names.length];
-		for ( int i = 0; i < names.length; i++ ) {
-			LockMode lm = ( LockMode ) nameLockModes.get( names[i] );
-			if ( lm == null ) lm = LockMode.NONE;
-			lockModeArray[i] = lm;
-		}
-		return lockModeArray;
-	}
-
-	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException {
-		// can't cache this stuff either (per-invocation)
-		final String result;
-		if ( lockModes == null || lockModes.size() == 0 ) {
-			result = sql;
-		}
-		else {
-			Map aliasedLockModes = new HashMap();
-			Iterator iter = lockModes.entrySet().iterator();
-			while ( iter.hasNext() ) {
-				Map.Entry me = ( Map.Entry ) iter.next();
-				aliasedLockModes.put( getAliasName( ( String ) me.getKey() ), me.getValue() );
-			}
-			Map keyColumnNames = null;
-			if ( dialect.forUpdateOfColumns() ) {
-				keyColumnNames = new HashMap();
-				for ( int i = 0; i < names.length; i++ ) {
-					keyColumnNames.put( names[i], persisters[i].getIdentifierColumnNames() );
-				}
-			}
-			result = dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
-		}
-		logQuery( queryString, result );
-		return result;
-	}
-
-	protected boolean upgradeLocks() {
-		return true;
-	}
-
-	protected int[] getCollectionOwners() {
-		return new int[] { collectionOwnerColumn };
-	}
-
-	protected boolean isCompiled() {
-		return compiled;
-	}
-
-	public String toString() {
-		return queryString;
-	}
-
-	protected int[] getOwners() {
-		return owners;
-	}
-
-	protected EntityType[] getOwnerAssociationTypes() {
-		return ownerAssociationTypes;
-	}
-
-	public Class getHolderClass() {
-		return holderClass;
-	}
-
-	public Map getEnabledFilters() {
-		return enabledFilters;
-	}
-
-	public ScrollableResults scroll(final QueryParameters queryParameters,
-									final SessionImplementor session)
-			throws HibernateException {
-		HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
-		return scroll( queryParameters, returnTypes, hi, session );
-	}
-
-	public String getQueryIdentifier() {
-		return queryIdentifier;
-	}
-
-	protected boolean isSubselectLoadingEnabled() {
-		return hasSubselectLoadableCollections();
-	}
-
-	public void validateScrollability() throws HibernateException {
-		// This is the legacy behaviour for HQL queries...
-		if ( getCollectionPersisters() != null ) {
-			throw new HibernateException( "Cannot scroll queries which initialize collections" );
-		}
-	}
-
-	public boolean containsCollectionFetches() {
-		return false;
-	}
-
-	public boolean isManipulationStatement() {
-		// classic parser does not support bulk manipulation statements
-		return false;
-	}
-
-	public ParameterTranslations getParameterTranslations() {
-		return new ParameterTranslations() {
-
-			public boolean supportsOrdinalParameterMetadata() {
-				// classic translator does not support collection of ordinal
-				// param metadata
-				return false;
-			}
-
-			public int getOrdinalParameterCount() {
-				return 0; // not known!
-			}
-
-			public int getOrdinalParameterSqlLocation(int ordinalPosition) {
-				return 0; // not known!
-			}
-
-			public Type getOrdinalParameterExpectedType(int ordinalPosition) {
-				return null; // not known!
-			}
-
-			public Set getNamedParameterNames() {
-				return namedParameters.keySet();
-			}
-
-			public int[] getNamedParameterSqlLocations(String name) {
-				return getNamedParameterLocs( name );
-			}
-
-			public Type getNamedParameterExpectedType(String name) {
-				return null; // not known!
-			}
-		};
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/QueryTranslatorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1184 @@
+/*
+ * 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.classic;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.FilterTranslator;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.hql.NameGenerator;
+import org.hibernate.hql.ParameterTranslations;
+import org.hibernate.impl.IteratorImpl;
+import org.hibernate.loader.BasicLoader;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.QuerySelect;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * An instance of <tt>QueryTranslator</tt> translates a Hibernate
+ * query string to SQL.
+ */
+public class QueryTranslatorImpl extends BasicLoader implements FilterTranslator {
+
+	private static final String[] NO_RETURN_ALIASES = new String[] {};
+
+	private final String queryIdentifier;
+	private final String queryString;
+
+	private final Map typeMap = new LinkedHashMap();
+	private final Map collections = new LinkedHashMap();
+	private List returnedTypes = new ArrayList();
+	private final List fromTypes = new ArrayList();
+	private final List scalarTypes = new ArrayList();
+	private final Map namedParameters = new HashMap();
+	private final Map aliasNames = new HashMap();
+	private final Map oneToOneOwnerNames = new HashMap();
+	private final Map uniqueKeyOwnerReferences = new HashMap();
+	private final Map decoratedPropertyMappings = new HashMap();
+
+	private final List scalarSelectTokens = new ArrayList();
+	private final List whereTokens = new ArrayList();
+	private final List havingTokens = new ArrayList();
+	private final Map joins = new LinkedHashMap();
+	private final List orderByTokens = new ArrayList();
+	private final List groupByTokens = new ArrayList();
+	private final Set querySpaces = new HashSet();
+	private final Set entitiesToFetch = new HashSet();
+
+	private final Map pathAliases = new HashMap();
+	private final Map pathJoins = new HashMap();
+
+	private Queryable[] persisters;
+	private int[] owners;
+	private EntityType[] ownerAssociationTypes;
+	private String[] names;
+	private boolean[] includeInSelect;
+	private int selectLength;
+	private Type[] returnTypes;
+	private Type[] actualReturnTypes;
+	private String[][] scalarColumnNames;
+	private Map tokenReplacements;
+	private int nameCount = 0;
+	private int parameterCount = 0;
+	private boolean distinct = false;
+	private boolean compiled;
+	private String sqlString;
+	private Class holderClass;
+	private Constructor holderConstructor;
+	private boolean hasScalars;
+	private boolean shallowQuery;
+	private QueryTranslatorImpl superQuery;
+
+	private QueryableCollection collectionPersister;
+	private int collectionOwnerColumn = -1;
+	private String collectionOwnerName;
+	private String fetchName;
+
+	private String[] suffixes;
+
+	private Map enabledFilters;
+
+	private static final Logger log = LoggerFactory.getLogger( QueryTranslatorImpl.class );
+
+	/**
+	 * Construct a query translator
+	 *
+	 * @param queryIdentifier A unique identifier for the query of which this
+	 * translation is part; typically this is the original, user-supplied query string.
+	 * @param queryString The "preprocessed" query string; at the very least
+	 * already processed by {@link org.hibernate.hql.QuerySplitter}.
+	 * @param enabledFilters Any enabled filters.
+	 * @param factory The session factory.
+	 */
+	public QueryTranslatorImpl(
+			String queryIdentifier,
+	        String queryString,
+	        Map enabledFilters,
+	        SessionFactoryImplementor factory) {
+		super( factory );
+		this.queryIdentifier = queryIdentifier;
+		this.queryString = queryString;
+		this.enabledFilters = enabledFilters;
+	}
+
+	/**
+	 * Construct a query translator; this form used internally.
+	 *
+	 * @param queryString The query string to process.
+	 * @param enabledFilters Any enabled filters.
+	 * @param factory The session factory.
+	 */
+	public QueryTranslatorImpl(
+	        String queryString,
+	        Map enabledFilters,
+	        SessionFactoryImplementor factory) {
+		this( queryString, queryString, enabledFilters, factory );
+	}
+
+	/**
+	 * Compile a subquery.
+	 *
+	 * @param superquery The containing query of the query to be compiled.
+	 *
+	 * @throws org.hibernate.MappingException Indicates problems resolving
+	 * things referenced in the query.
+	 * @throws org.hibernate.QueryException Generally some form of syntatic
+	 * failure.
+	 */
+	void compile(QueryTranslatorImpl superquery) throws QueryException, MappingException {
+		this.tokenReplacements = superquery.tokenReplacements;
+		this.superQuery = superquery;
+		this.shallowQuery = true;
+		this.enabledFilters = superquery.getEnabledFilters();
+		compile();
+	}
+
+
+	/**
+	 * Compile a "normal" query. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 */
+	public synchronized void compile(
+			Map replacements,
+			boolean scalar) throws QueryException, MappingException {
+		if ( !compiled ) {
+			this.tokenReplacements = replacements;
+			this.shallowQuery = scalar;
+			compile();
+		}
+	}
+
+	/**
+	 * Compile a filter. This method may be called multiple
+	 * times. Subsequent invocations are no-ops.
+	 */
+	public synchronized void compile(
+			String collectionRole,
+			Map replacements,
+			boolean scalar) throws QueryException, MappingException {
+
+		if ( !isCompiled() ) {
+			addFromAssociation( "this", collectionRole );
+			compile( replacements, scalar );
+		}
+	}
+
+	/**
+	 * Compile the query (generate the SQL).
+	 *
+	 * @throws org.hibernate.MappingException Indicates problems resolving
+	 * things referenced in the query.
+	 * @throws org.hibernate.QueryException Generally some form of syntatic
+	 * failure.
+	 */
+	private void compile() throws QueryException, MappingException {
+
+		log.trace( "compiling query" );
+		try {
+			ParserHelper.parse( new PreprocessingParser( tokenReplacements ),
+					queryString,
+					ParserHelper.HQL_SEPARATORS,
+					this );
+			renderSQL();
+		}
+		catch ( QueryException qe ) {
+			qe.setQueryString( queryString );
+			throw qe;
+		}
+		catch ( MappingException me ) {
+			throw me;
+		}
+		catch ( Exception e ) {
+			log.debug( "unexpected query compilation problem", e );
+			e.printStackTrace();
+			QueryException qe = new QueryException( "Incorrect query syntax", e );
+			qe.setQueryString( queryString );
+			throw qe;
+		}
+
+		postInstantiate();
+
+		compiled = true;
+
+	}
+
+	public String getSQLString() {
+		return sqlString;
+	}
+
+	public List collectSqlStrings() {
+		return ArrayHelper.toList( new String[] { sqlString } );
+	}
+
+	public String getQueryString() {
+		return queryString;
+	}
+
+	/**
+	 * Persisters for the return values of a <tt>find()</tt> style query.
+	 *
+	 * @return an array of <tt>EntityPersister</tt>s.
+	 */
+	protected Loadable[] getEntityPersisters() {
+		return persisters;
+	}
+
+	/**
+	 * Types of the return values of an <tt>iterate()</tt> style query.
+	 *
+	 * @return an array of <tt>Type</tt>s.
+	 */
+	public Type[] getReturnTypes() {
+		return actualReturnTypes;
+	}
+	
+	public String[] getReturnAliases() {
+		// return aliases not supported in classic translator!
+		return NO_RETURN_ALIASES;
+	}
+
+	public String[][] getColumnNames() {
+		return scalarColumnNames;
+	}
+
+	private static void logQuery(String hql, String sql) {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "HQL: " + hql );
+			log.debug( "SQL: " + sql );
+		}
+	}
+
+	void setAliasName(String alias, String name) {
+		aliasNames.put( alias, name );
+	}
+
+	public String getAliasName(String alias) {
+		String name = ( String ) aliasNames.get( alias );
+		if ( name == null ) {
+			if ( superQuery != null ) {
+				name = superQuery.getAliasName( alias );
+			}
+			else {
+				name = alias;
+			}
+		}
+		return name;
+	}
+
+	String unalias(String path) {
+		String alias = StringHelper.root( path );
+		String name = getAliasName( alias );
+		if ( name != null ) {
+			return name + path.substring( alias.length() );
+		}
+		else {
+			return path;
+		}
+	}
+
+	void addEntityToFetch(String name, String oneToOneOwnerName, AssociationType ownerAssociationType) {
+		addEntityToFetch( name );
+		if ( oneToOneOwnerName != null ) oneToOneOwnerNames.put( name, oneToOneOwnerName );
+		if ( ownerAssociationType != null ) uniqueKeyOwnerReferences.put( name, ownerAssociationType );
+	}
+
+	private void addEntityToFetch(String name) {
+		entitiesToFetch.add( name );
+	}
+
+	private int nextCount() {
+		return ( superQuery == null ) ? nameCount++ : superQuery.nameCount++;
+	}
+
+	String createNameFor(String type) {
+		return StringHelper.generateAlias( type, nextCount() );
+	}
+
+	String createNameForCollection(String role) {
+		return StringHelper.generateAlias( role, nextCount() );
+	}
+
+	private String getType(String name) {
+		String type = ( String ) typeMap.get( name );
+		if ( type == null && superQuery != null ) {
+			type = superQuery.getType( name );
+		}
+		return type;
+	}
+
+	private String getRole(String name) {
+		String role = ( String ) collections.get( name );
+		if ( role == null && superQuery != null ) {
+			role = superQuery.getRole( name );
+		}
+		return role;
+	}
+
+	boolean isName(String name) {
+		return aliasNames.containsKey( name ) ||
+				typeMap.containsKey( name ) ||
+				collections.containsKey( name ) || (
+				superQuery != null && superQuery.isName( name )
+				);
+	}
+
+	PropertyMapping getPropertyMapping(String name) throws QueryException {
+		PropertyMapping decorator = getDecoratedPropertyMapping( name );
+		if ( decorator != null ) return decorator;
+
+		String type = getType( name );
+		if ( type == null ) {
+			String role = getRole( name );
+			if ( role == null ) {
+				throw new QueryException( "alias not found: " + name );
+			}
+			return getCollectionPersister( role ); //.getElementPropertyMapping();
+		}
+		else {
+			Queryable persister = getEntityPersister( type );
+			if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
+			return persister;
+		}
+	}
+
+	private PropertyMapping getDecoratedPropertyMapping(String name) {
+		return ( PropertyMapping ) decoratedPropertyMappings.get( name );
+	}
+
+	void decoratePropertyMapping(String name, PropertyMapping mapping) {
+		decoratedPropertyMappings.put( name, mapping );
+	}
+
+	private Queryable getEntityPersisterForName(String name) throws QueryException {
+		String type = getType( name );
+		Queryable persister = getEntityPersister( type );
+		if ( persister == null ) throw new QueryException( "persistent class not found: " + type );
+		return persister;
+	}
+
+	Queryable getEntityPersisterUsingImports(String className) {
+		final String importedClassName = getFactory().getImportedClassName( className );
+		if ( importedClassName == null ) {
+			return null;
+		}
+		try {
+			return ( Queryable ) getFactory().getEntityPersister( importedClassName );
+		}
+		catch ( MappingException me ) {
+			return null;
+		}
+	}
+
+	Queryable getEntityPersister(String entityName) throws QueryException {
+		try {
+			return ( Queryable ) getFactory().getEntityPersister( entityName );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( "persistent class not found: " + entityName );
+		}
+	}
+
+	QueryableCollection getCollectionPersister(String role) throws QueryException {
+		try {
+			return ( QueryableCollection ) getFactory().getCollectionPersister( role );
+		}
+		catch ( ClassCastException cce ) {
+			throw new QueryException( "collection role is not queryable: " + role );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( "collection role not found: " + role );
+		}
+	}
+
+	void addType(String name, String type) {
+		typeMap.put( name, type );
+	}
+
+	void addCollection(String name, String role) {
+		collections.put( name, role );
+	}
+
+	void addFrom(String name, String type, JoinSequence joinSequence)
+			throws QueryException {
+		addType( name, type );
+		addFrom( name, joinSequence );
+	}
+
+	void addFromCollection(String name, String collectionRole, JoinSequence joinSequence)
+			throws QueryException {
+		//register collection role
+		addCollection( name, collectionRole );
+		addJoin( name, joinSequence );
+	}
+
+	void addFrom(String name, JoinSequence joinSequence)
+			throws QueryException {
+		fromTypes.add( name );
+		addJoin( name, joinSequence );
+	}
+
+	void addFromClass(String name, Queryable classPersister)
+			throws QueryException {
+		JoinSequence joinSequence = new JoinSequence( getFactory() )
+				.setRoot( classPersister, name );
+		//crossJoins.add(name);
+		addFrom( name, classPersister.getEntityName(), joinSequence );
+	}
+
+	void addSelectClass(String name) {
+		returnedTypes.add( name );
+	}
+
+	void addSelectScalar(Type type) {
+		scalarTypes.add( type );
+	}
+
+	void appendWhereToken(String token) {
+		whereTokens.add( token );
+	}
+
+	void appendHavingToken(String token) {
+		havingTokens.add( token );
+	}
+
+	void appendOrderByToken(String token) {
+		orderByTokens.add( token );
+	}
+
+	void appendGroupByToken(String token) {
+		groupByTokens.add( token );
+	}
+
+	void appendScalarSelectToken(String token) {
+		scalarSelectTokens.add( token );
+	}
+
+	void appendScalarSelectTokens(String[] tokens) {
+		scalarSelectTokens.add( tokens );
+	}
+
+	void addFromJoinOnly(String name, JoinSequence joinSequence) throws QueryException {
+		addJoin( name, joinSequence.getFromPart() );
+	}
+
+	void addJoin(String name, JoinSequence joinSequence) throws QueryException {
+		if ( !joins.containsKey( name ) ) joins.put( name, joinSequence );
+	}
+
+	void addNamedParameter(String name) {
+		if ( superQuery != null ) superQuery.addNamedParameter( name );
+		Integer loc = new Integer( parameterCount++ );
+		Object o = namedParameters.get( name );
+		if ( o == null ) {
+			namedParameters.put( name, loc );
+		}
+		else if ( o instanceof Integer ) {
+			ArrayList list = new ArrayList( 4 );
+			list.add( o );
+			list.add( loc );
+			namedParameters.put( name, list );
+		}
+		else {
+			( ( ArrayList ) o ).add( loc );
+		}
+	}
+
+	public int[] getNamedParameterLocs(String name) throws QueryException {
+		Object o = namedParameters.get( name );
+		if ( o == null ) {
+			QueryException qe = new QueryException( ERROR_NAMED_PARAMETER_DOES_NOT_APPEAR + name );
+			qe.setQueryString( queryString );
+			throw qe;
+		}
+		if ( o instanceof Integer ) {
+			return new int[]{ ( ( Integer ) o ).intValue() };
+		}
+		else {
+			return ArrayHelper.toIntArray( ( ArrayList ) o );
+		}
+	}
+
+	private void renderSQL() throws QueryException, MappingException {
+
+		final int rtsize;
+		if ( returnedTypes.size() == 0 && scalarTypes.size() == 0 ) {
+			//ie no select clause in HQL
+			returnedTypes = fromTypes;
+			rtsize = returnedTypes.size();
+		}
+		else {
+			rtsize = returnedTypes.size();
+			Iterator iter = entitiesToFetch.iterator();
+			while ( iter.hasNext() ) {
+				returnedTypes.add( iter.next() );
+			}
+		}
+		int size = returnedTypes.size();
+		persisters = new Queryable[size];
+		names = new String[size];
+		owners = new int[size];
+		ownerAssociationTypes = new EntityType[size];
+		suffixes = new String[size];
+		includeInSelect = new boolean[size];
+		for ( int i = 0; i < size; i++ ) {
+			String name = ( String ) returnedTypes.get( i );
+			//if ( !isName(name) ) throw new QueryException("unknown type: " + name);
+			persisters[i] = getEntityPersisterForName( name );
+			// TODO: cannot use generateSuffixes() - it handles the initial suffix differently.
+			suffixes[i] = ( size == 1 ) ? "" : Integer.toString( i ) + '_';
+			names[i] = name;
+			includeInSelect[i] = !entitiesToFetch.contains( name );
+			if ( includeInSelect[i] ) selectLength++;
+			if ( name.equals( collectionOwnerName ) ) collectionOwnerColumn = i;
+			String oneToOneOwner = ( String ) oneToOneOwnerNames.get( name );
+			owners[i] = ( oneToOneOwner == null ) ? -1 : returnedTypes.indexOf( oneToOneOwner );
+			ownerAssociationTypes[i] = (EntityType) uniqueKeyOwnerReferences.get( name );
+		}
+
+		if ( ArrayHelper.isAllNegative( owners ) ) owners = null;
+
+		String scalarSelect = renderScalarSelect(); //Must be done here because of side-effect! yuck...
+
+		int scalarSize = scalarTypes.size();
+		hasScalars = scalarTypes.size() != rtsize;
+
+		returnTypes = new Type[scalarSize];
+		for ( int i = 0; i < scalarSize; i++ ) {
+			returnTypes[i] = ( Type ) scalarTypes.get( i );
+		}
+
+		QuerySelect sql = new QuerySelect( getFactory().getDialect() );
+		sql.setDistinct( distinct );
+
+		if ( !shallowQuery ) {
+			renderIdentifierSelect( sql );
+			renderPropertiesSelect( sql );
+		}
+
+		if ( collectionPersister != null ) {
+			sql.addSelectFragmentString( collectionPersister.selectFragment( fetchName, "__" ) );
+		}
+
+		if ( hasScalars || shallowQuery ) sql.addSelectFragmentString( scalarSelect );
+
+		//TODO: for some dialects it would be appropriate to add the renderOrderByPropertiesSelect() to other select strings
+		mergeJoins( sql.getJoinFragment() );
+
+		sql.setWhereTokens( whereTokens.iterator() );
+
+		sql.setGroupByTokens( groupByTokens.iterator() );
+		sql.setHavingTokens( havingTokens.iterator() );
+		sql.setOrderByTokens( orderByTokens.iterator() );
+
+		if ( collectionPersister != null && collectionPersister.hasOrdering() ) {
+			sql.addOrderBy( collectionPersister.getSQLOrderByString( fetchName ) );
+		}
+
+		scalarColumnNames = NameGenerator.generateColumnNames( returnTypes, getFactory() );
+
+		// initialize the Set of queried identifier spaces (ie. tables)
+		Iterator iter = collections.values().iterator();
+		while ( iter.hasNext() ) {
+			CollectionPersister p = getCollectionPersister( ( String ) iter.next() );
+			addQuerySpaces( p.getCollectionSpaces() );
+		}
+		iter = typeMap.keySet().iterator();
+		while ( iter.hasNext() ) {
+			Queryable p = getEntityPersisterForName( ( String ) iter.next() );
+			addQuerySpaces( p.getQuerySpaces() );
+		}
+
+		sqlString = sql.toQueryString();
+
+		if ( holderClass != null ) holderConstructor = ReflectHelper.getConstructor( holderClass, returnTypes );
+
+		if ( hasScalars ) {
+			actualReturnTypes = returnTypes;
+		}
+		else {
+			actualReturnTypes = new Type[selectLength];
+			int j = 0;
+			for ( int i = 0; i < persisters.length; i++ ) {
+				if ( includeInSelect[i] ) {
+					actualReturnTypes[j++] = TypeFactory.manyToOne( persisters[i].getEntityName(), shallowQuery );
+				}
+			}
+		}
+
+	}
+
+	private void renderIdentifierSelect(QuerySelect sql) {
+		int size = returnedTypes.size();
+
+		for ( int k = 0; k < size; k++ ) {
+			String name = ( String ) returnedTypes.get( k );
+			String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
+			sql.addSelectFragmentString( persisters[k].identifierSelectFragment( name, suffix ) );
+		}
+
+	}
+
+	/*private String renderOrderByPropertiesSelect() {
+		StringBuffer buf = new StringBuffer(10);
+
+		//add the columns we are ordering by to the select ID select clause
+		Iterator iter = orderByTokens.iterator();
+		while ( iter.hasNext() ) {
+			String token = (String) iter.next();
+			if ( token.lastIndexOf(".") > 0 ) {
+				//ie. it is of form "foo.bar", not of form "asc" or "desc"
+				buf.append(StringHelper.COMMA_SPACE).append(token);
+			}
+		}
+
+		return buf.toString();
+	}*/
+
+	private void renderPropertiesSelect(QuerySelect sql) {
+		int size = returnedTypes.size();
+		for ( int k = 0; k < size; k++ ) {
+			String suffix = size == 1 ? "" : Integer.toString( k ) + '_';
+			String name = ( String ) returnedTypes.get( k );
+			sql.addSelectFragmentString( persisters[k].propertySelectFragment( name, suffix, false ) );
+		}
+	}
+
+	/**
+	 * WARNING: side-effecty
+	 */
+	private String renderScalarSelect() {
+
+		boolean isSubselect = superQuery != null;
+
+		StringBuffer buf = new StringBuffer( 20 );
+
+		if ( scalarTypes.size() == 0 ) {
+			//ie. no select clause
+			int size = returnedTypes.size();
+			for ( int k = 0; k < size; k++ ) {
+
+				scalarTypes.add( TypeFactory.manyToOne( persisters[k].getEntityName(), shallowQuery ) );
+
+				String[] idColumnNames = persisters[k].getIdentifierColumnNames();
+				for ( int i = 0; i < idColumnNames.length; i++ ) {
+					buf.append( returnedTypes.get( k ) ).append( '.' ).append( idColumnNames[i] );
+					if ( !isSubselect ) buf.append( " as " ).append( NameGenerator.scalarName( k, i ) );
+					if ( i != idColumnNames.length - 1 || k != size - 1 ) buf.append( ", " );
+				}
+
+			}
+
+		}
+		else {
+			//there _was_ a select clause
+			Iterator iter = scalarSelectTokens.iterator();
+			int c = 0;
+			boolean nolast = false; //real hacky...
+			int parenCount = 0; // used to count the nesting of parentheses
+			while ( iter.hasNext() ) {
+				Object next = iter.next();
+				if ( next instanceof String ) {
+					String token = ( String ) next;
+
+					if ( "(".equals( token ) ) {
+						parenCount++;
+					}
+					else if ( ")".equals( token ) ) {
+						parenCount--;
+					}
+
+					String lc = token.toLowerCase();
+					if ( lc.equals( ", " ) ) {
+						if ( nolast ) {
+							nolast = false;
+						}
+						else {
+							if ( !isSubselect && parenCount == 0 ) {
+								int x = c++;
+								buf.append( " as " )
+										.append( NameGenerator.scalarName( x, 0 ) );
+							}
+						}
+					}
+					buf.append( token );
+					if ( lc.equals( "distinct" ) || lc.equals( "all" ) ) {
+						buf.append( ' ' );
+					}
+				}
+				else {
+					nolast = true;
+					String[] tokens = ( String[] ) next;
+					for ( int i = 0; i < tokens.length; i++ ) {
+						buf.append( tokens[i] );
+						if ( !isSubselect ) {
+							buf.append( " as " )
+									.append( NameGenerator.scalarName( c, i ) );
+						}
+						if ( i != tokens.length - 1 ) buf.append( ", " );
+					}
+					c++;
+				}
+			}
+			if ( !isSubselect && !nolast ) {
+				int x = c++;
+				buf.append( " as " )
+						.append( NameGenerator.scalarName( x, 0 ) );
+			}
+
+		}
+
+		return buf.toString();
+	}
+
+	private void mergeJoins(JoinFragment ojf) throws MappingException, QueryException {
+
+		Iterator iter = joins.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			String name = ( String ) me.getKey();
+			JoinSequence join = ( JoinSequence ) me.getValue();
+			join.setSelector( new JoinSequence.Selector() {
+				public boolean includeSubclasses(String alias) {
+					boolean include = returnedTypes.contains( alias ) && !isShallowQuery();
+					return include;
+				}
+			} );
+
+			if ( typeMap.containsKey( name ) ) {
+				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
+			}
+			else if ( collections.containsKey( name ) ) {
+				ojf.addFragment( join.toJoinFragment( enabledFilters, true ) );
+			}
+			else {
+				//name from a super query (a bit inelegant that it shows up here)
+			}
+
+		}
+
+	}
+
+	public final Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	/**
+	 * Is this query called by scroll() or iterate()?
+	 *
+	 * @return true if it is, false if it is called by find() or list()
+	 */
+	boolean isShallowQuery() {
+		return shallowQuery;
+	}
+
+	void addQuerySpaces(Serializable[] spaces) {
+		for ( int i = 0; i < spaces.length; i++ ) {
+			querySpaces.add( spaces[i] );
+		}
+		if ( superQuery != null ) superQuery.addQuerySpaces( spaces );
+	}
+
+	void setDistinct(boolean distinct) {
+		this.distinct = distinct;
+	}
+
+	boolean isSubquery() {
+		return superQuery != null;
+	}
+
+	/**
+	 * Overrides method from Loader
+	 */
+	public CollectionPersister[] getCollectionPersisters() {
+		return collectionPersister == null ? null : new CollectionPersister[] { collectionPersister };
+	}
+
+	protected String[] getCollectionSuffixes() {
+		return collectionPersister == null ? null : new String[] { "__" };
+	}
+
+	void setCollectionToFetch(String role, String name, String ownerName, String entityName)
+			throws QueryException {
+		fetchName = name;
+		collectionPersister = getCollectionPersister( role );
+		collectionOwnerName = ownerName;
+		if ( collectionPersister.getElementType().isEntityType() ) {
+			addEntityToFetch( entityName );
+		}
+	}
+
+	protected String[] getSuffixes() {
+		return suffixes;
+	}
+
+	protected String[] getAliases() {
+		return names;
+	}
+
+	/**
+	 * Used for collection filters
+	 */
+	private void addFromAssociation(final String elementName, final String collectionRole)
+			throws QueryException {
+		//q.addCollection(collectionName, collectionRole);
+		QueryableCollection persister = getCollectionPersister( collectionRole );
+		Type collectionElementType = persister.getElementType();
+		if ( !collectionElementType.isEntityType() ) {
+			throw new QueryException( "collection of values in filter: " + elementName );
+		}
+
+		String[] keyColumnNames = persister.getKeyColumnNames();
+		//if (keyColumnNames.length!=1) throw new QueryException("composite-key collection in filter: " + collectionRole);
+
+		String collectionName;
+		JoinSequence join = new JoinSequence( getFactory() );
+		collectionName = persister.isOneToMany() ?
+				elementName :
+				createNameForCollection( collectionRole );
+		join.setRoot( persister, collectionName );
+		if ( !persister.isOneToMany() ) {
+			//many-to-many
+			addCollection( collectionName, collectionRole );
+			try {
+				join.addJoin( ( AssociationType ) persister.getElementType(),
+						elementName,
+						JoinFragment.INNER_JOIN,
+						persister.getElementColumnNames(collectionName) );
+			}
+			catch ( MappingException me ) {
+				throw new QueryException( me );
+			}
+		}
+		join.addCondition( collectionName, keyColumnNames, " = ?" );
+		//if ( persister.hasWhere() ) join.addCondition( persister.getSQLWhereString(collectionName) );
+		EntityType elemType = ( EntityType ) collectionElementType;
+		addFrom( elementName, elemType.getAssociatedEntityName(), join );
+
+	}
+
+	String getPathAlias(String path) {
+		return ( String ) pathAliases.get( path );
+	}
+
+	JoinSequence getPathJoin(String path) {
+		return ( JoinSequence ) pathJoins.get( path );
+	}
+
+	void addPathAliasAndJoin(String path, String alias, JoinSequence joinSequence) {
+		pathAliases.put( path, alias );
+		pathJoins.put( path, joinSequence );
+	}
+
+	public List list(SessionImplementor session, QueryParameters queryParameters)
+			throws HibernateException {
+		return list( session, queryParameters, getQuerySpaces(), actualReturnTypes );
+	}
+
+	/**
+	 * Return the query results as an iterator
+	 */
+	public Iterator iterate(QueryParameters queryParameters, EventSource session)
+			throws HibernateException {
+
+		boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
+		long startTime = 0;
+		if ( stats ) startTime = System.currentTimeMillis();
+
+		try {
+
+			PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
+			ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session );
+			HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
+			Iterator result = new IteratorImpl( rs, st, session, returnTypes, getColumnNames(), hi );
+
+			if ( stats ) {
+				session.getFactory().getStatisticsImplementor().queryExecuted(
+						"HQL: " + queryString,
+						0,
+						System.currentTimeMillis() - startTime
+					);
+			}
+
+			return result;
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert( 
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not execute query using iterate",
+					getSQLString() 
+				);
+		}
+
+	}
+
+	public int executeUpdate(QueryParameters queryParameters, SessionImplementor session) throws HibernateException {
+		throw new UnsupportedOperationException( "Not supported!  Use the AST translator...");
+	}
+
+	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
+			throws SQLException, HibernateException {
+		row = toResultRow( row );
+		if ( hasScalars ) {
+			String[][] scalarColumns = getColumnNames();
+			int queryCols = returnTypes.length;
+			if ( holderClass == null && queryCols == 1 ) {
+				return returnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null );
+			}
+			else {
+				row = new Object[queryCols];
+				for ( int i = 0; i < queryCols; i++ )
+					row[i] = returnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null );
+				return row;
+			}
+		}
+		else if ( holderClass == null ) {
+			return row.length == 1 ? row[0] : row;
+		}
+		else {
+			return row;
+		}
+
+	}
+
+	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
+		if ( holderClass != null ) {
+			for ( int i = 0; i < results.size(); i++ ) {
+				Object[] row = ( Object[] ) results.get( i );
+				try {
+					results.set( i, holderConstructor.newInstance( row ) );
+				}
+				catch ( Exception e ) {
+					throw new QueryException( "could not instantiate: " + holderClass, e );
+				}
+			}
+		}
+		return results;
+	}
+
+	private Object[] toResultRow(Object[] row) {
+		if ( selectLength == row.length ) {
+			return row;
+		}
+		else {
+			Object[] result = new Object[selectLength];
+			int j = 0;
+			for ( int i = 0; i < row.length; i++ ) {
+				if ( includeInSelect[i] ) result[j++] = row[i];
+			}
+			return result;
+		}
+	}
+
+	void setHolderClass(Class clazz) {
+		holderClass = clazz;
+	}
+
+	protected LockMode[] getLockModes(Map lockModes) {
+		// unfortunately this stuff can't be cached because
+		// it is per-invocation, not constant for the
+		// QueryTranslator instance
+		HashMap nameLockModes = new HashMap();
+		if ( lockModes != null ) {
+			Iterator iter = lockModes.entrySet().iterator();
+			while ( iter.hasNext() ) {
+				Map.Entry me = ( Map.Entry ) iter.next();
+				nameLockModes.put( getAliasName( ( String ) me.getKey() ),
+						me.getValue() );
+			}
+		}
+		LockMode[] lockModeArray = new LockMode[names.length];
+		for ( int i = 0; i < names.length; i++ ) {
+			LockMode lm = ( LockMode ) nameLockModes.get( names[i] );
+			if ( lm == null ) lm = LockMode.NONE;
+			lockModeArray[i] = lm;
+		}
+		return lockModeArray;
+	}
+
+	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException {
+		// can't cache this stuff either (per-invocation)
+		final String result;
+		if ( lockModes == null || lockModes.size() == 0 ) {
+			result = sql;
+		}
+		else {
+			Map aliasedLockModes = new HashMap();
+			Iterator iter = lockModes.entrySet().iterator();
+			while ( iter.hasNext() ) {
+				Map.Entry me = ( Map.Entry ) iter.next();
+				aliasedLockModes.put( getAliasName( ( String ) me.getKey() ), me.getValue() );
+			}
+			Map keyColumnNames = null;
+			if ( dialect.forUpdateOfColumns() ) {
+				keyColumnNames = new HashMap();
+				for ( int i = 0; i < names.length; i++ ) {
+					keyColumnNames.put( names[i], persisters[i].getIdentifierColumnNames() );
+				}
+			}
+			result = dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
+		}
+		logQuery( queryString, result );
+		return result;
+	}
+
+	protected boolean upgradeLocks() {
+		return true;
+	}
+
+	protected int[] getCollectionOwners() {
+		return new int[] { collectionOwnerColumn };
+	}
+
+	protected boolean isCompiled() {
+		return compiled;
+	}
+
+	public String toString() {
+		return queryString;
+	}
+
+	protected int[] getOwners() {
+		return owners;
+	}
+
+	protected EntityType[] getOwnerAssociationTypes() {
+		return ownerAssociationTypes;
+	}
+
+	public Class getHolderClass() {
+		return holderClass;
+	}
+
+	public Map getEnabledFilters() {
+		return enabledFilters;
+	}
+
+	public ScrollableResults scroll(final QueryParameters queryParameters,
+									final SessionImplementor session)
+			throws HibernateException {
+		HolderInstantiator hi = HolderInstantiator.createClassicHolderInstantiator(holderConstructor, queryParameters.getResultTransformer());
+		return scroll( queryParameters, returnTypes, hi, session );
+	}
+
+	public String getQueryIdentifier() {
+		return queryIdentifier;
+	}
+
+	protected boolean isSubselectLoadingEnabled() {
+		return hasSubselectLoadableCollections();
+	}
+
+	public void validateScrollability() throws HibernateException {
+		// This is the legacy behaviour for HQL queries...
+		if ( getCollectionPersisters() != null ) {
+			throw new HibernateException( "Cannot scroll queries which initialize collections" );
+		}
+	}
+
+	public boolean containsCollectionFetches() {
+		return false;
+	}
+
+	public boolean isManipulationStatement() {
+		// classic parser does not support bulk manipulation statements
+		return false;
+	}
+
+	public ParameterTranslations getParameterTranslations() {
+		return new ParameterTranslations() {
+
+			public boolean supportsOrdinalParameterMetadata() {
+				// classic translator does not support collection of ordinal
+				// param metadata
+				return false;
+			}
+
+			public int getOrdinalParameterCount() {
+				return 0; // not known!
+			}
+
+			public int getOrdinalParameterSqlLocation(int ordinalPosition) {
+				return 0; // not known!
+			}
+
+			public Type getOrdinalParameterExpectedType(int ordinalPosition) {
+				return null; // not known!
+			}
+
+			public Set getNamedParameterNames() {
+				return namedParameters.keySet();
+			}
+
+			public int[] getNamedParameterSqlLocations(String name) {
+				return getNamedParameterLocs( name );
+			}
+
+			public Type getNamedParameterExpectedType(String name) {
+				return null; // not known!
+			}
+		};
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/SelectParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,228 +0,0 @@
-//$Id: SelectParser.java 9915 2006-05-09 09:38:15Z max.andersen at jboss.com $
-package org.hibernate.hql.classic;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.dialect.function.SQLFunction;
-import org.hibernate.hql.QuerySplitter;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Parsers the select clause of a Hibernate query.
- *
- * @author Gavin King, David Channon
- */
-public class SelectParser implements Parser {
-
-	//TODO: arithmetic expressions, multiple new Foo(...)
-
-	private static final Set COUNT_MODIFIERS = new HashSet();
-
-	static {
-		COUNT_MODIFIERS.add( "distinct" );
-		COUNT_MODIFIERS.add( "all" );
-		COUNT_MODIFIERS.add( "*" );
-	}
-
-	private LinkedList aggregateFuncTokenList = new LinkedList();
-
-	private boolean ready;
-	private boolean aggregate;
-	private boolean first;
-	private boolean afterNew;
-	private boolean insideNew;
-	private boolean aggregateAddSelectScalar;
-	private Class holderClass;
-
-	private final SelectPathExpressionParser pathExpressionParser;
-	private final PathExpressionParser aggregatePathExpressionParser;
-
-	{
-		pathExpressionParser = new SelectPathExpressionParser();
-		aggregatePathExpressionParser = new PathExpressionParser();
-		//TODO: would be nice to use false, but issues with MS SQL
-		pathExpressionParser.setUseThetaStyleJoin( true );
-		aggregatePathExpressionParser.setUseThetaStyleJoin( true );
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		String lctoken = token.toLowerCase();
-
-		if ( first ) {
-			first = false;
-			if ( "distinct".equals( lctoken ) ) {
-				q.setDistinct( true );
-				return;
-			}
-			else if ( "all".equals( lctoken ) ) {
-				q.setDistinct( false );
-				return;
-			}
-		}
-
-		if ( afterNew ) {
-			afterNew = false;
-			try {
-				holderClass = ReflectHelper.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) );
-			}
-			catch ( ClassNotFoundException cnfe ) {
-				throw new QueryException( cnfe );
-			}
-			if ( holderClass == null ) throw new QueryException( "class not found: " + token );
-			q.setHolderClass( holderClass );
-			insideNew = true;
-		}
-		else if ( token.equals( "," ) ) {
-			if ( !aggregate && ready ) throw new QueryException( "alias or expression expected in SELECT" );
-			q.appendScalarSelectToken( ", " );
-			ready = true;
-		}
-		else if ( "new".equals( lctoken ) ) {
-			afterNew = true;
-			ready = false;
-		}
-		else if ( "(".equals( token ) ) {
-			if ( insideNew && !aggregate && !ready ) {
-				//opening paren in new Foo ( ... )
-				ready = true;
-			}
-			else if ( aggregate ) {
-				q.appendScalarSelectToken( token );
-			}
-			else {
-				throw new QueryException( "aggregate function expected before ( in SELECT" );
-			}
-			ready = true;
-		}
-		else if ( ")".equals( token ) ) {
-			if ( insideNew && !aggregate && !ready ) {
-				//if we are inside a new Result(), but not inside a nested function
-				insideNew = false;
-			}
-			else if ( aggregate && ready ) {
-				q.appendScalarSelectToken( token );
-				aggregateFuncTokenList.removeLast();
-				if ( aggregateFuncTokenList.size() < 1 ) {
-					aggregate = false;
-					ready = false;
-				}
-			}
-			else {
-				throw new QueryException( "( expected before ) in select" );
-			}
-		}
-		else if ( COUNT_MODIFIERS.contains( lctoken ) ) {
-			if ( !ready || !aggregate ) throw new QueryException( token + " only allowed inside aggregate function in SELECT" );
-			q.appendScalarSelectToken( token );
-			if ( "*".equals( token ) ) q.addSelectScalar( getFunction( "count", q ).getReturnType( Hibernate.LONG, q.getFactory() ) ); //special case
-		}
-		else if ( getFunction( lctoken, q ) != null && token.equals( q.unalias( token ) ) ) {
-			// the name of an SQL function
-			if ( !ready ) throw new QueryException( ", expected before aggregate function in SELECT: " + token );
-			aggregate = true;
-			aggregateAddSelectScalar = true;
-			aggregateFuncTokenList.add( lctoken );
-			ready = false;
-			q.appendScalarSelectToken( token );
-			if ( !aggregateHasArgs( lctoken, q ) ) {
-				q.addSelectScalar( aggregateType( aggregateFuncTokenList, null, q ) );
-				if ( !aggregateFuncNoArgsHasParenthesis( lctoken, q ) ) {
-					aggregateFuncTokenList.removeLast();
-					if ( aggregateFuncTokenList.size() < 1 ) {
-						aggregate = false;
-						ready = false;
-					}
-					else {
-						ready = true;
-					}
-				}
-			}
-		}
-		else if ( aggregate ) {
-			boolean constantToken = false;
-			if ( !ready ) throw new QueryException( "( expected after aggregate function in SELECT" );
-			try {
-				ParserHelper.parse( aggregatePathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-			}
-			catch ( QueryException qex ) {
-				constantToken = true;
-			}
-
-			if ( constantToken ) {
-				q.appendScalarSelectToken( token );
-			}
-			else {
-				if ( aggregatePathExpressionParser.isCollectionValued() ) {
-					q.addCollection( aggregatePathExpressionParser.getCollectionName(),
-							aggregatePathExpressionParser.getCollectionRole() );
-				}
-				q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() );
-				if ( aggregateAddSelectScalar ) {
-					q.addSelectScalar( aggregateType( aggregateFuncTokenList, aggregatePathExpressionParser.getWhereColumnType(), q ) );
-					aggregateAddSelectScalar = false;
-				}
-				aggregatePathExpressionParser.addAssociation( q );
-			}
-		}
-		else {
-			if ( !ready ) throw new QueryException( ", expected in SELECT" );
-			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
-			if ( pathExpressionParser.isCollectionValued() ) {
-				q.addCollection( pathExpressionParser.getCollectionName(),
-						pathExpressionParser.getCollectionRole() );
-			}
-			else if ( pathExpressionParser.getWhereColumnType().isEntityType() ) {
-				q.addSelectClass( pathExpressionParser.getSelectName() );
-			}
-			q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() );
-			q.addSelectScalar( pathExpressionParser.getWhereColumnType() );
-			pathExpressionParser.addAssociation( q );
-
-			ready = false;
-		}
-	}
-
-	public boolean aggregateHasArgs(String funcToken, QueryTranslatorImpl q) {
-		return getFunction( funcToken, q ).hasArguments();
-	}
-
-	public boolean aggregateFuncNoArgsHasParenthesis(String funcToken, QueryTranslatorImpl q) {
-		return getFunction( funcToken, q ).hasParenthesesIfNoArguments();
-	}
-
-	public Type aggregateType(List funcTokenList, Type type, QueryTranslatorImpl q) throws QueryException {
-		Type retType = type;
-		Type argType;
-		for ( int i = funcTokenList.size() - 1; i >= 0; i-- ) {
-			argType = retType;
-			String funcToken = ( String ) funcTokenList.get( i );
-			retType = getFunction( funcToken, q ).getReturnType( argType, q.getFactory() );
-		}
-		return retType;
-	}
-
-	private SQLFunction getFunction(String name, QueryTranslatorImpl q) {
-		return q.getFactory().getSqlFunctionRegistry().findSQLFunction( name );
-	}
-
-	public void start(QueryTranslatorImpl q) {
-		ready = true;
-		first = true;
-		aggregate = false;
-		afterNew = false;
-		insideNew = false;
-		holderClass = null;
-		aggregateFuncTokenList.clear();
-	}
-
-	public void end(QueryTranslatorImpl q) {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/SelectParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,251 @@
+/*
+ * 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.classic;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.dialect.function.SQLFunction;
+import org.hibernate.hql.QuerySplitter;
+import org.hibernate.type.Type;
+import org.hibernate.util.ReflectHelper;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Parsers the select clause of a Hibernate query.
+ *
+ * @author Gavin King, David Channon
+ */
+public class SelectParser implements Parser {
+
+	//TODO: arithmetic expressions, multiple new Foo(...)
+
+	private static final Set COUNT_MODIFIERS = new HashSet();
+
+	static {
+		COUNT_MODIFIERS.add( "distinct" );
+		COUNT_MODIFIERS.add( "all" );
+		COUNT_MODIFIERS.add( "*" );
+	}
+
+	private LinkedList aggregateFuncTokenList = new LinkedList();
+
+	private boolean ready;
+	private boolean aggregate;
+	private boolean first;
+	private boolean afterNew;
+	private boolean insideNew;
+	private boolean aggregateAddSelectScalar;
+	private Class holderClass;
+
+	private final SelectPathExpressionParser pathExpressionParser;
+	private final PathExpressionParser aggregatePathExpressionParser;
+
+	{
+		pathExpressionParser = new SelectPathExpressionParser();
+		aggregatePathExpressionParser = new PathExpressionParser();
+		//TODO: would be nice to use false, but issues with MS SQL
+		pathExpressionParser.setUseThetaStyleJoin( true );
+		aggregatePathExpressionParser.setUseThetaStyleJoin( true );
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		String lctoken = token.toLowerCase();
+
+		if ( first ) {
+			first = false;
+			if ( "distinct".equals( lctoken ) ) {
+				q.setDistinct( true );
+				return;
+			}
+			else if ( "all".equals( lctoken ) ) {
+				q.setDistinct( false );
+				return;
+			}
+		}
+
+		if ( afterNew ) {
+			afterNew = false;
+			try {
+				holderClass = ReflectHelper.classForName( QuerySplitter.getImportedClass( token, q.getFactory() ) );
+			}
+			catch ( ClassNotFoundException cnfe ) {
+				throw new QueryException( cnfe );
+			}
+			if ( holderClass == null ) throw new QueryException( "class not found: " + token );
+			q.setHolderClass( holderClass );
+			insideNew = true;
+		}
+		else if ( token.equals( "," ) ) {
+			if ( !aggregate && ready ) throw new QueryException( "alias or expression expected in SELECT" );
+			q.appendScalarSelectToken( ", " );
+			ready = true;
+		}
+		else if ( "new".equals( lctoken ) ) {
+			afterNew = true;
+			ready = false;
+		}
+		else if ( "(".equals( token ) ) {
+			if ( insideNew && !aggregate && !ready ) {
+				//opening paren in new Foo ( ... )
+				ready = true;
+			}
+			else if ( aggregate ) {
+				q.appendScalarSelectToken( token );
+			}
+			else {
+				throw new QueryException( "aggregate function expected before ( in SELECT" );
+			}
+			ready = true;
+		}
+		else if ( ")".equals( token ) ) {
+			if ( insideNew && !aggregate && !ready ) {
+				//if we are inside a new Result(), but not inside a nested function
+				insideNew = false;
+			}
+			else if ( aggregate && ready ) {
+				q.appendScalarSelectToken( token );
+				aggregateFuncTokenList.removeLast();
+				if ( aggregateFuncTokenList.size() < 1 ) {
+					aggregate = false;
+					ready = false;
+				}
+			}
+			else {
+				throw new QueryException( "( expected before ) in select" );
+			}
+		}
+		else if ( COUNT_MODIFIERS.contains( lctoken ) ) {
+			if ( !ready || !aggregate ) throw new QueryException( token + " only allowed inside aggregate function in SELECT" );
+			q.appendScalarSelectToken( token );
+			if ( "*".equals( token ) ) q.addSelectScalar( getFunction( "count", q ).getReturnType( Hibernate.LONG, q.getFactory() ) ); //special case
+		}
+		else if ( getFunction( lctoken, q ) != null && token.equals( q.unalias( token ) ) ) {
+			// the name of an SQL function
+			if ( !ready ) throw new QueryException( ", expected before aggregate function in SELECT: " + token );
+			aggregate = true;
+			aggregateAddSelectScalar = true;
+			aggregateFuncTokenList.add( lctoken );
+			ready = false;
+			q.appendScalarSelectToken( token );
+			if ( !aggregateHasArgs( lctoken, q ) ) {
+				q.addSelectScalar( aggregateType( aggregateFuncTokenList, null, q ) );
+				if ( !aggregateFuncNoArgsHasParenthesis( lctoken, q ) ) {
+					aggregateFuncTokenList.removeLast();
+					if ( aggregateFuncTokenList.size() < 1 ) {
+						aggregate = false;
+						ready = false;
+					}
+					else {
+						ready = true;
+					}
+				}
+			}
+		}
+		else if ( aggregate ) {
+			boolean constantToken = false;
+			if ( !ready ) throw new QueryException( "( expected after aggregate function in SELECT" );
+			try {
+				ParserHelper.parse( aggregatePathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+			}
+			catch ( QueryException qex ) {
+				constantToken = true;
+			}
+
+			if ( constantToken ) {
+				q.appendScalarSelectToken( token );
+			}
+			else {
+				if ( aggregatePathExpressionParser.isCollectionValued() ) {
+					q.addCollection( aggregatePathExpressionParser.getCollectionName(),
+							aggregatePathExpressionParser.getCollectionRole() );
+				}
+				q.appendScalarSelectToken( aggregatePathExpressionParser.getWhereColumn() );
+				if ( aggregateAddSelectScalar ) {
+					q.addSelectScalar( aggregateType( aggregateFuncTokenList, aggregatePathExpressionParser.getWhereColumnType(), q ) );
+					aggregateAddSelectScalar = false;
+				}
+				aggregatePathExpressionParser.addAssociation( q );
+			}
+		}
+		else {
+			if ( !ready ) throw new QueryException( ", expected in SELECT" );
+			ParserHelper.parse( pathExpressionParser, q.unalias( token ), ParserHelper.PATH_SEPARATORS, q );
+			if ( pathExpressionParser.isCollectionValued() ) {
+				q.addCollection( pathExpressionParser.getCollectionName(),
+						pathExpressionParser.getCollectionRole() );
+			}
+			else if ( pathExpressionParser.getWhereColumnType().isEntityType() ) {
+				q.addSelectClass( pathExpressionParser.getSelectName() );
+			}
+			q.appendScalarSelectTokens( pathExpressionParser.getWhereColumns() );
+			q.addSelectScalar( pathExpressionParser.getWhereColumnType() );
+			pathExpressionParser.addAssociation( q );
+
+			ready = false;
+		}
+	}
+
+	public boolean aggregateHasArgs(String funcToken, QueryTranslatorImpl q) {
+		return getFunction( funcToken, q ).hasArguments();
+	}
+
+	public boolean aggregateFuncNoArgsHasParenthesis(String funcToken, QueryTranslatorImpl q) {
+		return getFunction( funcToken, q ).hasParenthesesIfNoArguments();
+	}
+
+	public Type aggregateType(List funcTokenList, Type type, QueryTranslatorImpl q) throws QueryException {
+		Type retType = type;
+		Type argType;
+		for ( int i = funcTokenList.size() - 1; i >= 0; i-- ) {
+			argType = retType;
+			String funcToken = ( String ) funcTokenList.get( i );
+			retType = getFunction( funcToken, q ).getReturnType( argType, q.getFactory() );
+		}
+		return retType;
+	}
+
+	private SQLFunction getFunction(String name, QueryTranslatorImpl q) {
+		return q.getFactory().getSqlFunctionRegistry().findSQLFunction( name );
+	}
+
+	public void start(QueryTranslatorImpl q) {
+		ready = true;
+		first = true;
+		aggregate = false;
+		afterNew = false;
+		insideNew = false;
+		holderClass = null;
+		aggregateFuncTokenList.clear();
+	}
+
+	public void end(QueryTranslatorImpl q) {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-//$Id: SelectPathExpressionParser.java 5861 2005-02-22 14:07:36Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import org.hibernate.QueryException;
-
-public class SelectPathExpressionParser extends PathExpressionParser {
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		if ( getCurrentProperty() != null && !q.isShallowQuery() ) {
-			// "finish off" the join
-			token( ".", q );
-			token( null, q );
-		}
-		super.end( q );
-	}
-
-	protected void setExpectingCollectionIndex() throws QueryException {
-		throw new QueryException( "illegal syntax near collection-valued path expression in select: "  + getCollectionName() );
-	}
-
-	public String getSelectName() {
-		return getCurrentName();
-	}
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/SelectPathExpressionParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.classic;
+
+import org.hibernate.QueryException;
+
+public class SelectPathExpressionParser extends PathExpressionParser {
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		if ( getCurrentProperty() != null && !q.isShallowQuery() ) {
+			// "finish off" the join
+			token( ".", q );
+			token( null, q );
+		}
+		super.end( q );
+	}
+
+	protected void setExpectingCollectionIndex() throws QueryException {
+		throw new QueryException( "illegal syntax near collection-valued path expression in select: "  + getCollectionName() );
+	}
+
+	public String getSelectName() {
+		return getCurrentName();
+	}
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/WhereParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,493 +0,0 @@
-//$Id: WhereParser.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.hql.classic;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.JoinSequence;
-import org.hibernate.hql.QueryTranslator;
-import org.hibernate.persister.collection.CollectionPropertyNames;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.sql.InFragment;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.LiteralType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Parses the where clause of a hibernate query and translates it to an
- * SQL where clause.
- */
-
-// We should reengineer this class so that, rather than the current ad -
-// hoc linear approach to processing a stream of tokens, we instead
-// build up a tree of expressions.
-
-// We would probably refactor to have LogicParser (builds a tree of simple
-// expressions connected by and, or, not), ExpressionParser (translates
-// from OO terms like foo, foo.Bar, foo.Bar.Baz to SQL terms like
-// FOOS.ID, FOOS.BAR_ID, etc) and PathExpressionParser (which does much
-// the same thing it does now)
-
-public class WhereParser implements Parser {
-
-	private final PathExpressionParser pathExpressionParser;
-
-	{
-		pathExpressionParser = new PathExpressionParser();
-		pathExpressionParser.setUseThetaStyleJoin( true ); //Need this, since join condition can appear inside parens!
-	}
-
-	private static final Set EXPRESSION_TERMINATORS = new HashSet();   //tokens that close a sub expression
-	private static final Set EXPRESSION_OPENERS = new HashSet();       //tokens that open a sub expression
-	private static final Set BOOLEAN_OPERATORS = new HashSet();        //tokens that would indicate a sub expression is a boolean expression
-	private static final Map NEGATIONS = new HashMap();
-
-	static {
-		EXPRESSION_TERMINATORS.add( "and" );
-		EXPRESSION_TERMINATORS.add( "or" );
-		EXPRESSION_TERMINATORS.add( ")" );
-		//expressionTerminators.add(","); // deliberately excluded
-
-		EXPRESSION_OPENERS.add( "and" );
-		EXPRESSION_OPENERS.add( "or" );
-		EXPRESSION_OPENERS.add( "(" );
-		//expressionOpeners.add(","); // deliberately excluded
-
-		BOOLEAN_OPERATORS.add( "<" );
-		BOOLEAN_OPERATORS.add( "=" );
-		BOOLEAN_OPERATORS.add( ">" );
-		BOOLEAN_OPERATORS.add( "#" );
-		BOOLEAN_OPERATORS.add( "~" );
-		BOOLEAN_OPERATORS.add( "like" );
-		BOOLEAN_OPERATORS.add( "ilike" );
-		BOOLEAN_OPERATORS.add( "regexp" );
-		BOOLEAN_OPERATORS.add( "rlike" );
-		BOOLEAN_OPERATORS.add( "is" );
-		BOOLEAN_OPERATORS.add( "in" );
-		BOOLEAN_OPERATORS.add( "any" );
-		BOOLEAN_OPERATORS.add( "some" );
-		BOOLEAN_OPERATORS.add( "all" );
-		BOOLEAN_OPERATORS.add( "exists" );
-		BOOLEAN_OPERATORS.add( "between" );
-		BOOLEAN_OPERATORS.add( "<=" );
-		BOOLEAN_OPERATORS.add( ">=" );
-		BOOLEAN_OPERATORS.add( "=>" );
-		BOOLEAN_OPERATORS.add( "=<" );
-		BOOLEAN_OPERATORS.add( "!=" );
-		BOOLEAN_OPERATORS.add( "<>" );
-		BOOLEAN_OPERATORS.add( "!#" );
-		BOOLEAN_OPERATORS.add( "!~" );
-		BOOLEAN_OPERATORS.add( "!<" );
-		BOOLEAN_OPERATORS.add( "!>" );
-		BOOLEAN_OPERATORS.add( "is not" );
-		BOOLEAN_OPERATORS.add( "not like" );
-		BOOLEAN_OPERATORS.add( "not ilike" );
-		BOOLEAN_OPERATORS.add( "not regexp" );
-		BOOLEAN_OPERATORS.add( "not rlike" );
-		BOOLEAN_OPERATORS.add( "not in" );
-		BOOLEAN_OPERATORS.add( "not between" );
-		BOOLEAN_OPERATORS.add( "not exists" );
-
-		NEGATIONS.put( "and", "or" );
-		NEGATIONS.put( "or", "and" );
-		NEGATIONS.put( "<", ">=" );
-		NEGATIONS.put( "=", "<>" );
-		NEGATIONS.put( ">", "<=" );
-		NEGATIONS.put( "#", "!#" );
-		NEGATIONS.put( "~", "!~" );
-		NEGATIONS.put( "like", "not like" );
-		NEGATIONS.put( "ilike", "not ilike" );
-		NEGATIONS.put( "regexp", "not regexp" );
-		NEGATIONS.put( "rlike", "not rlike" );
-		NEGATIONS.put( "is", "is not" );
-		NEGATIONS.put( "in", "not in" );
-		NEGATIONS.put( "exists", "not exists" );
-		NEGATIONS.put( "between", "not between" );
-		NEGATIONS.put( "<=", ">" );
-		NEGATIONS.put( ">=", "<" );
-		NEGATIONS.put( "=>", "<" );
-		NEGATIONS.put( "=<", ">" );
-		NEGATIONS.put( "!=", "=" );
-		NEGATIONS.put( "<>", "=" );
-		NEGATIONS.put( "!#", "#" );
-		NEGATIONS.put( "!~", "~" );
-		NEGATIONS.put( "!<", "<" );
-		NEGATIONS.put( "!>", ">" );
-		NEGATIONS.put( "is not", "is" );
-		NEGATIONS.put( "not like", "like" );
-		NEGATIONS.put( "not ilike", "ilike" );
-		NEGATIONS.put( "not regexp", "regexp" );
-		NEGATIONS.put( "not rlike", "rlike" );
-		NEGATIONS.put( "not in", "in" );
-		NEGATIONS.put( "not between", "between" );
-		NEGATIONS.put( "not exists", "exists" );
-
-	}
-	// Handles things like:
-	// a and b or c
-	// a and ( b or c )
-	// not a and not b
-	// not ( a and b )
-	// x between y and z            (overloaded "and")
-	// x in ( a, b, c )             (overloaded brackets)
-	// not not a
-	// a is not null                (overloaded "not")
-	// etc......
-	// and expressions like
-	// foo = bar                    (maps to: foo.id = bar.id)
-	// foo.Bar = 'foo'              (maps to: foo.bar = 'foo')
-	// foo.Bar.Baz = 1.0            (maps to: foo.bar = bar.id and bar.baz = 1.0)
-	// 1.0 = foo.Bar.Baz            (maps to: bar.baz = 1.0 and foo.Bar = bar.id)
-	// foo.Bar.Baz = a.B.C          (maps to: bar.Baz = b.C and foo.Bar = bar.id and a.B = b.id)
-	// foo.Bar.Baz + a.B.C          (maps to: bar.Baz + b.C and foo.Bar = bar.id and a.B = b.id)
-	// ( foo.Bar.Baz + 1.0 ) < 2.0  (maps to: ( bar.Baz + 1.0 ) < 2.0 and foo.Bar = bar.id)
-
-	private boolean betweenSpecialCase = false;       //Inside a BETWEEN ... AND ... expression
-	private boolean negated = false;
-
-	private boolean inSubselect = false;
-	private int bracketsSinceSelect = 0;
-	private StringBuffer subselect;
-
-	private boolean expectingPathContinuation = false;
-	private int expectingIndex = 0;
-
-	// The following variables are stacks that keep information about each subexpression
-	// in the list of nested subexpressions we are currently processing.
-
-	private LinkedList nots = new LinkedList();           //were an odd or even number of NOTs encountered
-	private LinkedList joins = new LinkedList();          //the join string built up by compound paths inside this expression
-	private LinkedList booleanTests = new LinkedList();   //a flag indicating if the subexpression is known to be boolean
-
-	private String getElementName(PathExpressionParser.CollectionElement element, QueryTranslatorImpl q) throws QueryException {
-		String name;
-		if ( element.isOneToMany ) {
-			name = element.alias;
-		}
-		else {
-			Type type = element.elementType;
-			if ( type.isEntityType() ) { //ie. a many-to-many
-				String entityName = ( ( EntityType ) type ).getAssociatedEntityName();
-				name = pathExpressionParser.continueFromManyToMany( entityName, element.elementColumns, q );
-			}
-			else {
-				throw new QueryException( "illegally dereferenced collection element" );
-			}
-		}
-		return name;
-	}
-
-	public void token(String token, QueryTranslatorImpl q) throws QueryException {
-
-		String lcToken = token.toLowerCase();
-
-		//Cope with [,]
-		if ( token.equals( "[" ) && !expectingPathContinuation ) {
-			expectingPathContinuation = false;
-			if ( expectingIndex == 0 ) throw new QueryException( "unexpected [" );
-			return;
-		}
-		else if ( token.equals( "]" ) ) {
-			expectingIndex--;
-			expectingPathContinuation = true;
-			return;
-		}
-
-		//Cope with a continued path expression (ie. ].baz)
-		if ( expectingPathContinuation ) {
-			boolean pathExpressionContinuesFurther = continuePathExpression( token, q );
-			if ( pathExpressionContinuesFurther ) return; //NOTE: early return
-		}
-
-		//Cope with a subselect
-		if ( !inSubselect && ( lcToken.equals( "select" ) || lcToken.equals( "from" ) ) ) {
-			inSubselect = true;
-			subselect = new StringBuffer( 20 );
-		}
-		if ( inSubselect && token.equals( ")" ) ) {
-			bracketsSinceSelect--;
-
-			if ( bracketsSinceSelect == -1 ) {
-				QueryTranslatorImpl subq = new QueryTranslatorImpl(
-				        subselect.toString(),
-						q.getEnabledFilters(),
-						q.getFactory()
-				);
-				try {
-					subq.compile( q );
-				}
-				catch ( MappingException me ) {
-					throw new QueryException( "MappingException occurred compiling subquery", me );
-				}
-				appendToken( q, subq.getSQLString() );
-				inSubselect = false;
-				bracketsSinceSelect = 0;
-			}
-		}
-		if ( inSubselect ) {
-			if ( token.equals( "(" ) ) bracketsSinceSelect++;
-			subselect.append( token ).append( ' ' );
-			return;
-		}
-
-		//Cope with special cases of AND, NOT, ()
-		specialCasesBefore( lcToken );
-
-		//Close extra brackets we opened
-		if ( !betweenSpecialCase && EXPRESSION_TERMINATORS.contains( lcToken ) ) {
-			closeExpression( q, lcToken );
-		}
-
-		//take note when this is a boolean expression
-		if ( BOOLEAN_OPERATORS.contains( lcToken ) ) {
-			booleanTests.removeLast();
-			booleanTests.addLast( Boolean.TRUE );
-		}
-
-		if ( lcToken.equals( "not" ) ) {
-			nots.addLast( new Boolean( !( ( Boolean ) nots.removeLast() ).booleanValue() ) );
-			negated = !negated;
-			return; //NOTE: early return
-		}
-
-		//process a token, mapping OO path expressions to SQL expressions
-		doToken( token, q );
-
-		//Open any extra brackets we might need.
-		if ( !betweenSpecialCase && EXPRESSION_OPENERS.contains( lcToken ) ) {
-			openExpression( q, lcToken );
-		}
-
-		//Cope with special cases of AND, NOT, )
-		specialCasesAfter( lcToken );
-
-	}
-
-	public void start(QueryTranslatorImpl q) throws QueryException {
-		token( "(", q );
-	}
-
-	public void end(QueryTranslatorImpl q) throws QueryException {
-		if ( expectingPathContinuation ) {
-			expectingPathContinuation = false;
-			PathExpressionParser.CollectionElement element = pathExpressionParser.lastCollectionElement();
-			if ( element.elementColumns.length != 1 ) throw new QueryException( "path expression ended in composite collection element" );
-			appendToken( q, element.elementColumns[0] );
-			addToCurrentJoin( element );
-		}
-		token( ")", q );
-	}
-
-	private void closeExpression(QueryTranslatorImpl q, String lcToken) {
-		if ( ( ( Boolean ) booleanTests.removeLast() ).booleanValue() ) { //it was a boolean expression
-
-			if ( booleanTests.size() > 0 ) {
-				// the next one up must also be
-				booleanTests.removeLast();
-				booleanTests.addLast( Boolean.TRUE );
-			}
-
-			// Add any joins
-			appendToken( q, ( joins.removeLast() ).toString() );
-
-		}
-		else {
-			StringBuffer join = ( StringBuffer ) joins.removeLast();
-			( ( StringBuffer ) joins.getLast() ).append( join.toString() );
-		}
-
-		if ( ( ( Boolean ) nots.removeLast() ).booleanValue() ) negated = !negated;
-
-		if ( !")".equals( lcToken ) ) appendToken( q, ")" );
-	}
-
-	private void openExpression(QueryTranslatorImpl q, String lcToken) {
-		nots.addLast( Boolean.FALSE );
-		booleanTests.addLast( Boolean.FALSE );
-		joins.addLast( new StringBuffer() );
-		if ( !"(".equals( lcToken ) ) appendToken( q, "(" );
-	}
-
-	private void preprocess(String token, QueryTranslatorImpl q) throws QueryException {
-		// ugly hack for cases like "elements(foo.bar.collection)"
-		// (multi-part path expression ending in elements or indices)
-		String[] tokens = StringHelper.split( ".", token, true );
-		if (
-				tokens.length > 5 &&
-				( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( tokens[tokens.length - 1] )
-				|| CollectionPropertyNames.COLLECTION_INDICES.equals( tokens[tokens.length - 1] ) )
-		) {
-			pathExpressionParser.start( q );
-			for ( int i = 0; i < tokens.length - 3; i++ ) {
-				pathExpressionParser.token( tokens[i], q );
-			}
-			pathExpressionParser.token( null, q );
-			pathExpressionParser.end( q );
-			addJoin( pathExpressionParser.getWhereJoin(), q );
-			pathExpressionParser.ignoreInitialJoin();
-		}
-	}
-
-	private void doPathExpression(String token, QueryTranslatorImpl q) throws QueryException {
-
-		preprocess( token, q );
-
-		StringTokenizer tokens = new StringTokenizer( token, ".", true );
-		pathExpressionParser.start( q );
-		while ( tokens.hasMoreTokens() ) {
-			pathExpressionParser.token( tokens.nextToken(), q );
-		}
-		pathExpressionParser.end( q );
-		if ( pathExpressionParser.isCollectionValued() ) {
-			openExpression( q, "" );
-			appendToken( q, pathExpressionParser.getCollectionSubquery( q.getEnabledFilters() ) );
-			closeExpression( q, "" );
-			// this is ugly here, but needed because its a subquery
-			q.addQuerySpaces( q.getCollectionPersister( pathExpressionParser.getCollectionRole() ).getCollectionSpaces() );
-		}
-		else {
-			if ( pathExpressionParser.isExpectingCollectionIndex() ) {
-				expectingIndex++;
-			}
-			else {
-				addJoin( pathExpressionParser.getWhereJoin(), q );
-				appendToken( q, pathExpressionParser.getWhereColumn() );
-			}
-		}
-	}
-
-	private void addJoin(JoinSequence joinSequence, QueryTranslatorImpl q) throws QueryException {
-		//JoinFragment fromClause = q.createJoinFragment(true);
-		//fromClause.addJoins( join.toJoinFragment().toFromFragmentString(), StringHelper.EMPTY_STRING );
-		q.addFromJoinOnly( pathExpressionParser.getName(), joinSequence );
-		try {
-			addToCurrentJoin( joinSequence.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-
-	private void doToken(String token, QueryTranslatorImpl q) throws QueryException {
-		if ( q.isName( StringHelper.root( token ) ) ) { //path expression
-			doPathExpression( q.unalias( token ), q );
-		}
-		else if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) { //named query parameter
-			q.addNamedParameter( token.substring( 1 ) );
-			appendToken( q, "?" );
-		}
-		else {
-			Queryable persister = q.getEntityPersisterUsingImports( token );
-			if ( persister != null ) { // the name of a class
-				final String discrim = persister.getDiscriminatorSQLValue();
-				if ( InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim) ) {
-					throw new QueryException( "subclass test not allowed for null or not null discriminator" );
-				}
-				else {
-					appendToken( q, discrim );
-				}
-			}
-			else {
-				Object constant;
-				if (
-						token.indexOf( '.' ) > -1 &&
-						( constant = ReflectHelper.getConstantValue( token ) ) != null
-				) {
-					Type type;
-					try {
-						type = TypeFactory.heuristicType( constant.getClass().getName() );
-					}
-					catch ( MappingException me ) {
-						throw new QueryException( me );
-					}
-					if ( type == null ) throw new QueryException( QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + token );
-					try {
-						appendToken( q, ( ( LiteralType ) type ).objectToSQLString( constant, q.getFactory().getDialect() ) );
-					}
-					catch ( Exception e ) {
-						throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + token, e );
-					}
-				}
-				else { //anything else
-
-					String negatedToken = negated ? ( String ) NEGATIONS.get( token.toLowerCase() ) : null;
-					if ( negatedToken != null && ( !betweenSpecialCase || !"or".equals( negatedToken ) ) ) {
-						appendToken( q, negatedToken );
-					}
-					else {
-						appendToken( q, token );
-					}
-				}
-			}
-		}
-	}
-
-	private void addToCurrentJoin(String sql) {
-		( ( StringBuffer ) joins.getLast() ).append( sql );
-	}
-
-	private void addToCurrentJoin(PathExpressionParser.CollectionElement ce)
-			throws QueryException {
-		try {
-			addToCurrentJoin( ce.joinSequence.toJoinFragment().toWhereFragmentString() + ce.indexValue.toString() );
-		}
-		catch ( MappingException me ) {
-			throw new QueryException( me );
-		}
-	}
-
-	private void specialCasesBefore(String lcToken) {
-		if ( lcToken.equals( "between" ) || lcToken.equals( "not between" ) ) {
-			betweenSpecialCase = true;
-		}
-	}
-
-	private void specialCasesAfter(String lcToken) {
-		if ( betweenSpecialCase && lcToken.equals( "and" ) ) {
-			betweenSpecialCase = false;
-		}
-	}
-
-	void appendToken(QueryTranslatorImpl q, String token) {
-		if ( expectingIndex > 0 ) {
-			pathExpressionParser.setLastCollectionElementIndexValue( token );
-		}
-		else {
-			q.appendWhereToken( token );
-		}
-	}
-
-	private boolean continuePathExpression(String token, QueryTranslatorImpl q) throws QueryException {
-
-		expectingPathContinuation = false;
-
-		PathExpressionParser.CollectionElement element = pathExpressionParser.lastCollectionElement();
-
-		if ( token.startsWith( "." ) ) { // the path expression continues after a ]
-
-			doPathExpression( getElementName( element, q ) + token, q ); // careful with this!
-
-			addToCurrentJoin( element );
-			return true; //NOTE: EARLY EXIT!
-
-		}
-
-		else { // the path expression ends at the ]
-			if ( element.elementColumns.length != 1 ) {
-				throw new QueryException( "path expression ended in composite collection element" );
-			}
-			appendToken( q, element.elementColumns[0] );
-			addToCurrentJoin( element );
-			return false;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/WhereParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/WhereParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,516 @@
+/*
+ * 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.classic;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.JoinSequence;
+import org.hibernate.hql.QueryTranslator;
+import org.hibernate.persister.collection.CollectionPropertyNames;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.sql.InFragment;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.LiteralType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Parses the where clause of a hibernate query and translates it to an
+ * SQL where clause.
+ */
+
+// We should reengineer this class so that, rather than the current ad -
+// hoc linear approach to processing a stream of tokens, we instead
+// build up a tree of expressions.
+
+// We would probably refactor to have LogicParser (builds a tree of simple
+// expressions connected by and, or, not), ExpressionParser (translates
+// from OO terms like foo, foo.Bar, foo.Bar.Baz to SQL terms like
+// FOOS.ID, FOOS.BAR_ID, etc) and PathExpressionParser (which does much
+// the same thing it does now)
+
+public class WhereParser implements Parser {
+
+	private final PathExpressionParser pathExpressionParser;
+
+	{
+		pathExpressionParser = new PathExpressionParser();
+		pathExpressionParser.setUseThetaStyleJoin( true ); //Need this, since join condition can appear inside parens!
+	}
+
+	private static final Set EXPRESSION_TERMINATORS = new HashSet();   //tokens that close a sub expression
+	private static final Set EXPRESSION_OPENERS = new HashSet();       //tokens that open a sub expression
+	private static final Set BOOLEAN_OPERATORS = new HashSet();        //tokens that would indicate a sub expression is a boolean expression
+	private static final Map NEGATIONS = new HashMap();
+
+	static {
+		EXPRESSION_TERMINATORS.add( "and" );
+		EXPRESSION_TERMINATORS.add( "or" );
+		EXPRESSION_TERMINATORS.add( ")" );
+		//expressionTerminators.add(","); // deliberately excluded
+
+		EXPRESSION_OPENERS.add( "and" );
+		EXPRESSION_OPENERS.add( "or" );
+		EXPRESSION_OPENERS.add( "(" );
+		//expressionOpeners.add(","); // deliberately excluded
+
+		BOOLEAN_OPERATORS.add( "<" );
+		BOOLEAN_OPERATORS.add( "=" );
+		BOOLEAN_OPERATORS.add( ">" );
+		BOOLEAN_OPERATORS.add( "#" );
+		BOOLEAN_OPERATORS.add( "~" );
+		BOOLEAN_OPERATORS.add( "like" );
+		BOOLEAN_OPERATORS.add( "ilike" );
+		BOOLEAN_OPERATORS.add( "regexp" );
+		BOOLEAN_OPERATORS.add( "rlike" );
+		BOOLEAN_OPERATORS.add( "is" );
+		BOOLEAN_OPERATORS.add( "in" );
+		BOOLEAN_OPERATORS.add( "any" );
+		BOOLEAN_OPERATORS.add( "some" );
+		BOOLEAN_OPERATORS.add( "all" );
+		BOOLEAN_OPERATORS.add( "exists" );
+		BOOLEAN_OPERATORS.add( "between" );
+		BOOLEAN_OPERATORS.add( "<=" );
+		BOOLEAN_OPERATORS.add( ">=" );
+		BOOLEAN_OPERATORS.add( "=>" );
+		BOOLEAN_OPERATORS.add( "=<" );
+		BOOLEAN_OPERATORS.add( "!=" );
+		BOOLEAN_OPERATORS.add( "<>" );
+		BOOLEAN_OPERATORS.add( "!#" );
+		BOOLEAN_OPERATORS.add( "!~" );
+		BOOLEAN_OPERATORS.add( "!<" );
+		BOOLEAN_OPERATORS.add( "!>" );
+		BOOLEAN_OPERATORS.add( "is not" );
+		BOOLEAN_OPERATORS.add( "not like" );
+		BOOLEAN_OPERATORS.add( "not ilike" );
+		BOOLEAN_OPERATORS.add( "not regexp" );
+		BOOLEAN_OPERATORS.add( "not rlike" );
+		BOOLEAN_OPERATORS.add( "not in" );
+		BOOLEAN_OPERATORS.add( "not between" );
+		BOOLEAN_OPERATORS.add( "not exists" );
+
+		NEGATIONS.put( "and", "or" );
+		NEGATIONS.put( "or", "and" );
+		NEGATIONS.put( "<", ">=" );
+		NEGATIONS.put( "=", "<>" );
+		NEGATIONS.put( ">", "<=" );
+		NEGATIONS.put( "#", "!#" );
+		NEGATIONS.put( "~", "!~" );
+		NEGATIONS.put( "like", "not like" );
+		NEGATIONS.put( "ilike", "not ilike" );
+		NEGATIONS.put( "regexp", "not regexp" );
+		NEGATIONS.put( "rlike", "not rlike" );
+		NEGATIONS.put( "is", "is not" );
+		NEGATIONS.put( "in", "not in" );
+		NEGATIONS.put( "exists", "not exists" );
+		NEGATIONS.put( "between", "not between" );
+		NEGATIONS.put( "<=", ">" );
+		NEGATIONS.put( ">=", "<" );
+		NEGATIONS.put( "=>", "<" );
+		NEGATIONS.put( "=<", ">" );
+		NEGATIONS.put( "!=", "=" );
+		NEGATIONS.put( "<>", "=" );
+		NEGATIONS.put( "!#", "#" );
+		NEGATIONS.put( "!~", "~" );
+		NEGATIONS.put( "!<", "<" );
+		NEGATIONS.put( "!>", ">" );
+		NEGATIONS.put( "is not", "is" );
+		NEGATIONS.put( "not like", "like" );
+		NEGATIONS.put( "not ilike", "ilike" );
+		NEGATIONS.put( "not regexp", "regexp" );
+		NEGATIONS.put( "not rlike", "rlike" );
+		NEGATIONS.put( "not in", "in" );
+		NEGATIONS.put( "not between", "between" );
+		NEGATIONS.put( "not exists", "exists" );
+
+	}
+	// Handles things like:
+	// a and b or c
+	// a and ( b or c )
+	// not a and not b
+	// not ( a and b )
+	// x between y and z            (overloaded "and")
+	// x in ( a, b, c )             (overloaded brackets)
+	// not not a
+	// a is not null                (overloaded "not")
+	// etc......
+	// and expressions like
+	// foo = bar                    (maps to: foo.id = bar.id)
+	// foo.Bar = 'foo'              (maps to: foo.bar = 'foo')
+	// foo.Bar.Baz = 1.0            (maps to: foo.bar = bar.id and bar.baz = 1.0)
+	// 1.0 = foo.Bar.Baz            (maps to: bar.baz = 1.0 and foo.Bar = bar.id)
+	// foo.Bar.Baz = a.B.C          (maps to: bar.Baz = b.C and foo.Bar = bar.id and a.B = b.id)
+	// foo.Bar.Baz + a.B.C          (maps to: bar.Baz + b.C and foo.Bar = bar.id and a.B = b.id)
+	// ( foo.Bar.Baz + 1.0 ) < 2.0  (maps to: ( bar.Baz + 1.0 ) < 2.0 and foo.Bar = bar.id)
+
+	private boolean betweenSpecialCase = false;       //Inside a BETWEEN ... AND ... expression
+	private boolean negated = false;
+
+	private boolean inSubselect = false;
+	private int bracketsSinceSelect = 0;
+	private StringBuffer subselect;
+
+	private boolean expectingPathContinuation = false;
+	private int expectingIndex = 0;
+
+	// The following variables are stacks that keep information about each subexpression
+	// in the list of nested subexpressions we are currently processing.
+
+	private LinkedList nots = new LinkedList();           //were an odd or even number of NOTs encountered
+	private LinkedList joins = new LinkedList();          //the join string built up by compound paths inside this expression
+	private LinkedList booleanTests = new LinkedList();   //a flag indicating if the subexpression is known to be boolean
+
+	private String getElementName(PathExpressionParser.CollectionElement element, QueryTranslatorImpl q) throws QueryException {
+		String name;
+		if ( element.isOneToMany ) {
+			name = element.alias;
+		}
+		else {
+			Type type = element.elementType;
+			if ( type.isEntityType() ) { //ie. a many-to-many
+				String entityName = ( ( EntityType ) type ).getAssociatedEntityName();
+				name = pathExpressionParser.continueFromManyToMany( entityName, element.elementColumns, q );
+			}
+			else {
+				throw new QueryException( "illegally dereferenced collection element" );
+			}
+		}
+		return name;
+	}
+
+	public void token(String token, QueryTranslatorImpl q) throws QueryException {
+
+		String lcToken = token.toLowerCase();
+
+		//Cope with [,]
+		if ( token.equals( "[" ) && !expectingPathContinuation ) {
+			expectingPathContinuation = false;
+			if ( expectingIndex == 0 ) throw new QueryException( "unexpected [" );
+			return;
+		}
+		else if ( token.equals( "]" ) ) {
+			expectingIndex--;
+			expectingPathContinuation = true;
+			return;
+		}
+
+		//Cope with a continued path expression (ie. ].baz)
+		if ( expectingPathContinuation ) {
+			boolean pathExpressionContinuesFurther = continuePathExpression( token, q );
+			if ( pathExpressionContinuesFurther ) return; //NOTE: early return
+		}
+
+		//Cope with a subselect
+		if ( !inSubselect && ( lcToken.equals( "select" ) || lcToken.equals( "from" ) ) ) {
+			inSubselect = true;
+			subselect = new StringBuffer( 20 );
+		}
+		if ( inSubselect && token.equals( ")" ) ) {
+			bracketsSinceSelect--;
+
+			if ( bracketsSinceSelect == -1 ) {
+				QueryTranslatorImpl subq = new QueryTranslatorImpl(
+				        subselect.toString(),
+						q.getEnabledFilters(),
+						q.getFactory()
+				);
+				try {
+					subq.compile( q );
+				}
+				catch ( MappingException me ) {
+					throw new QueryException( "MappingException occurred compiling subquery", me );
+				}
+				appendToken( q, subq.getSQLString() );
+				inSubselect = false;
+				bracketsSinceSelect = 0;
+			}
+		}
+		if ( inSubselect ) {
+			if ( token.equals( "(" ) ) bracketsSinceSelect++;
+			subselect.append( token ).append( ' ' );
+			return;
+		}
+
+		//Cope with special cases of AND, NOT, ()
+		specialCasesBefore( lcToken );
+
+		//Close extra brackets we opened
+		if ( !betweenSpecialCase && EXPRESSION_TERMINATORS.contains( lcToken ) ) {
+			closeExpression( q, lcToken );
+		}
+
+		//take note when this is a boolean expression
+		if ( BOOLEAN_OPERATORS.contains( lcToken ) ) {
+			booleanTests.removeLast();
+			booleanTests.addLast( Boolean.TRUE );
+		}
+
+		if ( lcToken.equals( "not" ) ) {
+			nots.addLast( new Boolean( !( ( Boolean ) nots.removeLast() ).booleanValue() ) );
+			negated = !negated;
+			return; //NOTE: early return
+		}
+
+		//process a token, mapping OO path expressions to SQL expressions
+		doToken( token, q );
+
+		//Open any extra brackets we might need.
+		if ( !betweenSpecialCase && EXPRESSION_OPENERS.contains( lcToken ) ) {
+			openExpression( q, lcToken );
+		}
+
+		//Cope with special cases of AND, NOT, )
+		specialCasesAfter( lcToken );
+
+	}
+
+	public void start(QueryTranslatorImpl q) throws QueryException {
+		token( "(", q );
+	}
+
+	public void end(QueryTranslatorImpl q) throws QueryException {
+		if ( expectingPathContinuation ) {
+			expectingPathContinuation = false;
+			PathExpressionParser.CollectionElement element = pathExpressionParser.lastCollectionElement();
+			if ( element.elementColumns.length != 1 ) throw new QueryException( "path expression ended in composite collection element" );
+			appendToken( q, element.elementColumns[0] );
+			addToCurrentJoin( element );
+		}
+		token( ")", q );
+	}
+
+	private void closeExpression(QueryTranslatorImpl q, String lcToken) {
+		if ( ( ( Boolean ) booleanTests.removeLast() ).booleanValue() ) { //it was a boolean expression
+
+			if ( booleanTests.size() > 0 ) {
+				// the next one up must also be
+				booleanTests.removeLast();
+				booleanTests.addLast( Boolean.TRUE );
+			}
+
+			// Add any joins
+			appendToken( q, ( joins.removeLast() ).toString() );
+
+		}
+		else {
+			StringBuffer join = ( StringBuffer ) joins.removeLast();
+			( ( StringBuffer ) joins.getLast() ).append( join.toString() );
+		}
+
+		if ( ( ( Boolean ) nots.removeLast() ).booleanValue() ) negated = !negated;
+
+		if ( !")".equals( lcToken ) ) appendToken( q, ")" );
+	}
+
+	private void openExpression(QueryTranslatorImpl q, String lcToken) {
+		nots.addLast( Boolean.FALSE );
+		booleanTests.addLast( Boolean.FALSE );
+		joins.addLast( new StringBuffer() );
+		if ( !"(".equals( lcToken ) ) appendToken( q, "(" );
+	}
+
+	private void preprocess(String token, QueryTranslatorImpl q) throws QueryException {
+		// ugly hack for cases like "elements(foo.bar.collection)"
+		// (multi-part path expression ending in elements or indices)
+		String[] tokens = StringHelper.split( ".", token, true );
+		if (
+				tokens.length > 5 &&
+				( CollectionPropertyNames.COLLECTION_ELEMENTS.equals( tokens[tokens.length - 1] )
+				|| CollectionPropertyNames.COLLECTION_INDICES.equals( tokens[tokens.length - 1] ) )
+		) {
+			pathExpressionParser.start( q );
+			for ( int i = 0; i < tokens.length - 3; i++ ) {
+				pathExpressionParser.token( tokens[i], q );
+			}
+			pathExpressionParser.token( null, q );
+			pathExpressionParser.end( q );
+			addJoin( pathExpressionParser.getWhereJoin(), q );
+			pathExpressionParser.ignoreInitialJoin();
+		}
+	}
+
+	private void doPathExpression(String token, QueryTranslatorImpl q) throws QueryException {
+
+		preprocess( token, q );
+
+		StringTokenizer tokens = new StringTokenizer( token, ".", true );
+		pathExpressionParser.start( q );
+		while ( tokens.hasMoreTokens() ) {
+			pathExpressionParser.token( tokens.nextToken(), q );
+		}
+		pathExpressionParser.end( q );
+		if ( pathExpressionParser.isCollectionValued() ) {
+			openExpression( q, "" );
+			appendToken( q, pathExpressionParser.getCollectionSubquery( q.getEnabledFilters() ) );
+			closeExpression( q, "" );
+			// this is ugly here, but needed because its a subquery
+			q.addQuerySpaces( q.getCollectionPersister( pathExpressionParser.getCollectionRole() ).getCollectionSpaces() );
+		}
+		else {
+			if ( pathExpressionParser.isExpectingCollectionIndex() ) {
+				expectingIndex++;
+			}
+			else {
+				addJoin( pathExpressionParser.getWhereJoin(), q );
+				appendToken( q, pathExpressionParser.getWhereColumn() );
+			}
+		}
+	}
+
+	private void addJoin(JoinSequence joinSequence, QueryTranslatorImpl q) throws QueryException {
+		//JoinFragment fromClause = q.createJoinFragment(true);
+		//fromClause.addJoins( join.toJoinFragment().toFromFragmentString(), StringHelper.EMPTY_STRING );
+		q.addFromJoinOnly( pathExpressionParser.getName(), joinSequence );
+		try {
+			addToCurrentJoin( joinSequence.toJoinFragment( q.getEnabledFilters(), true ).toWhereFragmentString() );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+
+	private void doToken(String token, QueryTranslatorImpl q) throws QueryException {
+		if ( q.isName( StringHelper.root( token ) ) ) { //path expression
+			doPathExpression( q.unalias( token ), q );
+		}
+		else if ( token.startsWith( ParserHelper.HQL_VARIABLE_PREFIX ) ) { //named query parameter
+			q.addNamedParameter( token.substring( 1 ) );
+			appendToken( q, "?" );
+		}
+		else {
+			Queryable persister = q.getEntityPersisterUsingImports( token );
+			if ( persister != null ) { // the name of a class
+				final String discrim = persister.getDiscriminatorSQLValue();
+				if ( InFragment.NULL.equals(discrim) || InFragment.NOT_NULL.equals(discrim) ) {
+					throw new QueryException( "subclass test not allowed for null or not null discriminator" );
+				}
+				else {
+					appendToken( q, discrim );
+				}
+			}
+			else {
+				Object constant;
+				if (
+						token.indexOf( '.' ) > -1 &&
+						( constant = ReflectHelper.getConstantValue( token ) ) != null
+				) {
+					Type type;
+					try {
+						type = TypeFactory.heuristicType( constant.getClass().getName() );
+					}
+					catch ( MappingException me ) {
+						throw new QueryException( me );
+					}
+					if ( type == null ) throw new QueryException( QueryTranslator.ERROR_CANNOT_DETERMINE_TYPE + token );
+					try {
+						appendToken( q, ( ( LiteralType ) type ).objectToSQLString( constant, q.getFactory().getDialect() ) );
+					}
+					catch ( Exception e ) {
+						throw new QueryException( QueryTranslator.ERROR_CANNOT_FORMAT_LITERAL + token, e );
+					}
+				}
+				else { //anything else
+
+					String negatedToken = negated ? ( String ) NEGATIONS.get( token.toLowerCase() ) : null;
+					if ( negatedToken != null && ( !betweenSpecialCase || !"or".equals( negatedToken ) ) ) {
+						appendToken( q, negatedToken );
+					}
+					else {
+						appendToken( q, token );
+					}
+				}
+			}
+		}
+	}
+
+	private void addToCurrentJoin(String sql) {
+		( ( StringBuffer ) joins.getLast() ).append( sql );
+	}
+
+	private void addToCurrentJoin(PathExpressionParser.CollectionElement ce)
+			throws QueryException {
+		try {
+			addToCurrentJoin( ce.joinSequence.toJoinFragment().toWhereFragmentString() + ce.indexValue.toString() );
+		}
+		catch ( MappingException me ) {
+			throw new QueryException( me );
+		}
+	}
+
+	private void specialCasesBefore(String lcToken) {
+		if ( lcToken.equals( "between" ) || lcToken.equals( "not between" ) ) {
+			betweenSpecialCase = true;
+		}
+	}
+
+	private void specialCasesAfter(String lcToken) {
+		if ( betweenSpecialCase && lcToken.equals( "and" ) ) {
+			betweenSpecialCase = false;
+		}
+	}
+
+	void appendToken(QueryTranslatorImpl q, String token) {
+		if ( expectingIndex > 0 ) {
+			pathExpressionParser.setLastCollectionElementIndexValue( token );
+		}
+		else {
+			q.appendWhereToken( token );
+		}
+	}
+
+	private boolean continuePathExpression(String token, QueryTranslatorImpl q) throws QueryException {
+
+		expectingPathContinuation = false;
+
+		PathExpressionParser.CollectionElement element = pathExpressionParser.lastCollectionElement();
+
+		if ( token.startsWith( "." ) ) { // the path expression continues after a ]
+
+			doPathExpression( getElementName( element, q ) + token, q ); // careful with this!
+
+			addToCurrentJoin( element );
+			return true; //NOTE: EARLY EXIT!
+
+		}
+
+		else { // the path expression ends at the ]
+			if ( element.elementColumns.length != 1 ) {
+				throw new QueryException( "path expression ended in composite collection element" );
+			}
+			appendToken( q, element.elementColumns[0] );
+			addToCurrentJoin( element );
+			return false;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/classic/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package contains the Hibernate 2.x query parser which 
-	is being end-of-lifed.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/classic/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/classic/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package contains the Hibernate 2.x query parser which 
+	is being end-of-lifed.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/hql/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines the interface between Hibernate and
-	the HQL query parser implementation (to allow switching
-	between the 2.x and 3.0 HQL parsers).
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/hql/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/hql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines the interface between Hibernate and
+	the HQL query parser implementation (to allow switching
+	between the 2.x and 3.0 HQL parsers).
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: AbstractPostInsertGenerator.java 9681 2006-03-24 18:10:04Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * @author Gavin King
- */
-public abstract class AbstractPostInsertGenerator implements PostInsertIdentifierGenerator{
-	public Serializable generate(SessionImplementor s, Object obj) {
-		return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractPostInsertGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Basic implementation of the {@link PostInsertIdentifierGenerator}
+ * contract.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractPostInsertGenerator implements PostInsertIdentifierGenerator {
+	/**
+	 * {@inheritDoc} 
+	 */
+	public Serializable generate(SessionImplementor s, Object obj) {
+		return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,77 +0,0 @@
-//$Id: AbstractUUIDGenerator.java 5002 2004-12-19 16:25:07Z oneovthafew $
-package org.hibernate.id;
-
-import java.net.InetAddress;
-import org.hibernate.util.BytesHelper;
-
-/**
- * The base class for identifier generators that use a UUID algorithm. This
- * class implements the algorithm, subclasses define the identifier
- * format.
- *
- * @see UUIDHexGenerator
- * @author Gavin King
- */
-
-public abstract class AbstractUUIDGenerator implements IdentifierGenerator {
-
-	private static final int IP;
-	static {
-		int ipadd;
-		try {
-			ipadd = BytesHelper.toInt( InetAddress.getLocalHost().getAddress() );
-		}
-		catch (Exception e) {
-			ipadd = 0;
-		}
-		IP = ipadd;
-	}
-	private static short counter = (short) 0;
-	private static final int JVM = (int) ( System.currentTimeMillis() >>> 8 );
-
-	public AbstractUUIDGenerator() {
-	}
-
-	/**
-	 * Unique across JVMs on this machine (unless they load this class
-	 * in the same quater second - very unlikely)
-	 */
-	protected int getJVM() {
-		return JVM;
-	}
-
-	/**
-	 * Unique in a millisecond for this JVM instance (unless there
-	 * are > Short.MAX_VALUE instances created in a millisecond)
-	 */
-	protected short getCount() {
-		synchronized(AbstractUUIDGenerator.class) {
-			if (counter<0) counter=0;
-			return counter++;
-		}
-	}
-
-	/**
-	 * Unique in a local network
-	 */
-	protected int getIP() {
-		return IP;
-	}
-
-	/**
-	 * Unique down to millisecond
-	 */
-	protected short getHiTime() {
-		return (short) ( System.currentTimeMillis() >>> 32 );
-	}
-	protected int getLoTime() {
-		return (int) System.currentTimeMillis();
-	}
-
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/AbstractUUIDGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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.id;
+
+import java.net.InetAddress;
+import org.hibernate.util.BytesHelper;
+
+/**
+ * The base class for identifier generators that use a UUID algorithm. This
+ * class implements the algorithm, subclasses define the identifier
+ * format.
+ *
+ * @see UUIDHexGenerator
+ * @author Gavin King
+ */
+
+public abstract class AbstractUUIDGenerator implements IdentifierGenerator {
+
+	private static final int IP;
+	static {
+		int ipadd;
+		try {
+			ipadd = BytesHelper.toInt( InetAddress.getLocalHost().getAddress() );
+		}
+		catch (Exception e) {
+			ipadd = 0;
+		}
+		IP = ipadd;
+	}
+	private static short counter = (short) 0;
+	private static final int JVM = (int) ( System.currentTimeMillis() >>> 8 );
+
+	public AbstractUUIDGenerator() {
+	}
+
+	/**
+	 * Unique across JVMs on this machine (unless they load this class
+	 * in the same quater second - very unlikely)
+	 */
+	protected int getJVM() {
+		return JVM;
+	}
+
+	/**
+	 * Unique in a millisecond for this JVM instance (unless there
+	 * are > Short.MAX_VALUE instances created in a millisecond)
+	 */
+	protected short getCount() {
+		synchronized(AbstractUUIDGenerator.class) {
+			if (counter<0) counter=0;
+			return counter++;
+		}
+	}
+
+	/**
+	 * Unique in a local network
+	 */
+	protected int getIP() {
+		return IP;
+	}
+
+	/**
+	 * Unique down to millisecond
+	 */
+	protected short getHiTime() {
+		return (short) ( System.currentTimeMillis() >>> 32 );
+	}
+	protected int getLoTime() {
+		return (int) System.currentTimeMillis();
+	}
+
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/Assigned.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: Assigned.java 6914 2005-05-26 03:58:24Z oneovthafew $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * <b>assigned</b><br>
- * <br>
- * An <tt>IdentifierGenerator</tt> that returns the current identifier assigned
- * to an instance.
- *
- * @author Gavin King
- */
-
-public class Assigned implements IdentifierGenerator, Configurable {
-	
-	private String entityName;
-
-	public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
-		
-		final Serializable id = session.getEntityPersister( entityName, obj ) 
-				//TODO: cache the persister, this shows up in yourkit
-				.getIdentifier( obj, session.getEntityMode() );
-		
-		if (id==null) {
-			throw new IdentifierGenerationException(
-				"ids for this class must be manually assigned before calling save(): " + 
-				entityName
-			);
-		}
-		
-		return id;
-	}
-
-	public void configure(Type type, Properties params, Dialect d)
-	throws MappingException {
-		entityName = params.getProperty(ENTITY_NAME);
-		if (entityName==null) {
-			throw new MappingException("no entity name");
-		}
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/Assigned.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Assigned.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * <b>assigned</b><br>
+ * <br>
+ * An <tt>IdentifierGenerator</tt> that returns the current identifier assigned
+ * to an instance.
+ *
+ * @author Gavin King
+ */
+
+public class Assigned implements IdentifierGenerator, Configurable {
+	
+	private String entityName;
+
+	public Serializable generate(SessionImplementor session, Object obj) throws HibernateException {
+		
+		final Serializable id = session.getEntityPersister( entityName, obj ) 
+				//TODO: cache the persister, this shows up in yourkit
+				.getIdentifier( obj, session.getEntityMode() );
+		
+		if (id==null) {
+			throw new IdentifierGenerationException(
+				"ids for this class must be manually assigned before calling save(): " + 
+				entityName
+			);
+		}
+		
+		return id;
+	}
+
+	public void configure(Type type, Properties params, Dialect d)
+	throws MappingException {
+		entityName = params.getProperty(ENTITY_NAME);
+		if (entityName==null) {
+			throw new MappingException("no entity name");
+		}
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/Configurable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: Configurable.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.id;
-
-import java.util.Properties;
-
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.type.Type;
-
-/**
- * An <tt>IdentifierGenerator</tt> that supports "configuration".
- *
- * @see IdentifierGenerator
- * @author Gavin King
- */
-public interface Configurable {
-
-	/**
-	 * Configure this instance, given the value of parameters
-	 * specified by the user as <tt>&lt;param&gt;</tt> elements.
-	 * This method is called just once, following instantiation.
-	 *
-	 * @param params param values, keyed by parameter name
-	 */
-	public void configure(Type type, Properties params, Dialect d) throws MappingException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/Configurable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/Configurable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.id;
+
+import java.util.Properties;
+
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.type.Type;
+
+/**
+ * An <tt>IdentifierGenerator</tt> that supports "configuration".
+ *
+ * @see IdentifierGenerator
+ * @author Gavin King
+ */
+public interface Configurable {
+
+	/**
+	 * Configure this instance, given the value of parameters
+	 * specified by the user as <tt>&lt;param&gt;</tt> elements.
+	 * This method is called just once, following instantiation.
+	 *
+	 * @param params param values, keyed by parameter name
+	 */
+	public void configure(Type type, Properties params, Dialect d) throws MappingException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,87 +0,0 @@
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.Session;
-import org.hibernate.TransientObjectException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-
-/**
- * <b>foreign</b><br>
- * <br>
- * An <tt>Identifier</tt> generator that uses the value of the id property of an
- * associated object<br>
- * <br>
- * One mapping parameter is required: property.
- *
- * @author Gavin King
- */
-public class ForeignGenerator implements IdentifierGenerator, Configurable {
-
-	private String propertyName;
-	private String entityName;
-
-	/**
-	 * @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object)
-	 */
-	public Serializable generate(SessionImplementor sessionImplementor, Object object)
-	throws HibernateException {
-		
-		Session session = (Session) sessionImplementor;
-
-		Object associatedObject = sessionImplementor.getFactory()
-		        .getClassMetadata( entityName )
-		        .getPropertyValue( object, propertyName, session.getEntityMode() );
-		
-		if ( associatedObject == null ) {
-			throw new IdentifierGenerationException(
-					"attempted to assign id from null one-to-one property: " + 
-					propertyName
-				);
-		}
-		
-		EntityType type = (EntityType) sessionImplementor.getFactory()
-        	.getClassMetadata( entityName )
-        	.getPropertyType( propertyName );
-
-		Serializable id;
-		try {
-			id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
-					type.getAssociatedEntityName(), 
-					associatedObject, 
-					sessionImplementor
-				); 
-		}
-		catch (TransientObjectException toe) {
-			id = session.save( type.getAssociatedEntityName(), associatedObject );
-		}
-
-		if ( session.contains(object) ) {
-			//abort the save (the object is already saved by a circular cascade)
-			return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR;
-			//throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association");
-		}
-		return id;
-	}
-
-	/**
-	 * @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect)
-	 */
-	public void configure(Type type, Properties params, Dialect d)
-		throws MappingException {
-
-		propertyName = params.getProperty("property");
-		entityName = params.getProperty(ENTITY_NAME);
-		if (propertyName==null) throw new MappingException(
-			"param named \"property\" is required for foreign id generation strategy"
-		);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/ForeignGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/ForeignGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,111 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.Session;
+import org.hibernate.TransientObjectException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * <b>foreign</b><br>
+ * <br>
+ * An <tt>Identifier</tt> generator that uses the value of the id property of an
+ * associated object<br>
+ * <br>
+ * One mapping parameter is required: property.
+ *
+ * @author Gavin King
+ */
+public class ForeignGenerator implements IdentifierGenerator, Configurable {
+
+	private String propertyName;
+	private String entityName;
+
+	/**
+	 * @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object)
+	 */
+	public Serializable generate(SessionImplementor sessionImplementor, Object object)
+	throws HibernateException {
+		
+		Session session = (Session) sessionImplementor;
+
+		Object associatedObject = sessionImplementor.getFactory()
+		        .getClassMetadata( entityName )
+		        .getPropertyValue( object, propertyName, session.getEntityMode() );
+		
+		if ( associatedObject == null ) {
+			throw new IdentifierGenerationException(
+					"attempted to assign id from null one-to-one property: " + 
+					propertyName
+				);
+		}
+		
+		EntityType type = (EntityType) sessionImplementor.getFactory()
+        	.getClassMetadata( entityName )
+        	.getPropertyType( propertyName );
+
+		Serializable id;
+		try {
+			id = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+					type.getAssociatedEntityName(), 
+					associatedObject, 
+					sessionImplementor
+				); 
+		}
+		catch (TransientObjectException toe) {
+			id = session.save( type.getAssociatedEntityName(), associatedObject );
+		}
+
+		if ( session.contains(object) ) {
+			//abort the save (the object is already saved by a circular cascade)
+			return IdentifierGeneratorFactory.SHORT_CIRCUIT_INDICATOR;
+			//throw new IdentifierGenerationException("save associated object first, or disable cascade for inverse association");
+		}
+		return id;
+	}
+
+	/**
+	 * @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect)
+	 */
+	public void configure(Type type, Properties params, Dialect d)
+		throws MappingException {
+
+		propertyName = params.getProperty("property");
+		entityName = params.getProperty(ENTITY_NAME);
+		if (propertyName==null) throw new MappingException(
+			"param named \"property\" is required for foreign id generation strategy"
+		);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/GUIDGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-//$Id: GUIDGenerator.java 7265 2005-06-22 04:19:34Z oneovthafew $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-/**
- * Generates <tt>string</tt> values using the SQL Server NEWID() function.
- *
- * @author Joseph Fifield
- */
-public class GUIDGenerator implements IdentifierGenerator {
-
-	private static final Logger log = LoggerFactory.getLogger(GUIDGenerator.class);
-
-	public Serializable generate(SessionImplementor session, Object obj) 
-	throws HibernateException {
-		
-		final String sql = session.getFactory().getDialect().getSelectGUIDString();
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
-			try {
-				ResultSet rs = st.executeQuery();
-				final String result;
-				try {
-					rs.next();
-					result = rs.getString(1);
-				}
-				finally {
-					rs.close();
-				}
-				log.debug("GUID identifier generated: " + result);
-				return result;
-			}
-			finally {
-				session.getBatcher().closeStatement(st);
-			}
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve GUID",
-					sql
-				);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/GUIDGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/GUIDGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,80 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+/**
+ * Generates <tt>string</tt> values using the SQL Server NEWID() function.
+ *
+ * @author Joseph Fifield
+ */
+public class GUIDGenerator implements IdentifierGenerator {
+
+	private static final Logger log = LoggerFactory.getLogger(GUIDGenerator.class);
+
+	public Serializable generate(SessionImplementor session, Object obj) 
+	throws HibernateException {
+		
+		final String sql = session.getFactory().getDialect().getSelectGUIDString();
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
+			try {
+				ResultSet rs = st.executeQuery();
+				final String result;
+				try {
+					rs.next();
+					result = rs.getString(1);
+				}
+				finally {
+					rs.close();
+				}
+				log.debug("GUID identifier generated: " + result);
+				return result;
+			}
+			finally {
+				session.getBatcher().closeStatement(st);
+			}
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve GUID",
+					sql
+				);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,30 +0,0 @@
-//$Id: IdentifierGenerationException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.id;
-
-import org.hibernate.HibernateException;
-
-/**
- * Thrown by <tt>IdentifierGenerator</tt> implementation class when
- * ID generation fails.
- *
- * @see IdentifierGenerator
- * @author Gavin King
- */
-
-public class IdentifierGenerationException extends HibernateException {
-
-	public IdentifierGenerationException(String msg) {
-		super(msg);
-	}
-
-	public IdentifierGenerationException(String msg, Throwable t) {
-		super(msg, t);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Thrown by <tt>IdentifierGenerator</tt> implementation class when
+ * ID generation fails.
+ *
+ * @see IdentifierGenerator
+ * @author Gavin King
+ */
+
+public class IdentifierGenerationException extends HibernateException {
+
+	public IdentifierGenerationException(String msg) {
+		super(msg);
+	}
+
+	public IdentifierGenerationException(String msg, Throwable t) {
+		super(msg, t);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: IdentifierGenerator.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.id;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-import java.io.Serializable;
-
-/**
- * The general contract between a class that generates unique
- * identifiers and the <tt>Session</tt>. It is not intended that
- * this interface ever be exposed to the application. It <b>is</b>
- * intended that users implement this interface to provide
- * custom identifier generation strategies.<br>
- * <br>
- * Implementors should provide a public default constructor.<br>
- * <br>
- * Implementations that accept configuration parameters should
- * also implement <tt>Configurable</tt>.
- * <br>
- * Implementors <em>must</em> be threadsafe
- *
- * @author Gavin King
- * @see PersistentIdentifierGenerator
- * @see Configurable
- */
-public interface IdentifierGenerator {
-
-    /**
-     * The configuration parameter holding the entity name
-     */
-    public static final String ENTITY_NAME = "entity_name";
-    
-	/**
-	 * Generate a new identifier.
-	 * @param session
-	 * @param object the entity or toplevel collection for which the id is being generated
-	 *
-	 * @return a new identifier
-	 * @throws HibernateException
-	 */
-	public Serializable generate(SessionImplementor session, Object object) 
-	throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/IdentifierGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.id;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+import java.io.Serializable;
+
+/**
+ * The general contract between a class that generates unique
+ * identifiers and the <tt>Session</tt>. It is not intended that
+ * this interface ever be exposed to the application. It <b>is</b>
+ * intended that users implement this interface to provide
+ * custom identifier generation strategies.<br>
+ * <br>
+ * Implementors should provide a public default constructor.<br>
+ * <br>
+ * Implementations that accept configuration parameters should
+ * also implement <tt>Configurable</tt>.
+ * <br>
+ * Implementors <em>must</em> be threadsafe
+ *
+ * @author Gavin King
+ * @see PersistentIdentifierGenerator
+ * @see Configurable
+ */
+public interface IdentifierGenerator {
+
+    /**
+     * The configuration parameter holding the entity name
+     */
+    public static final String ENTITY_NAME = "entity_name";
+    
+	/**
+	 * Generate a new identifier.
+	 * @param session
+	 * @param object the entity or toplevel collection for which the id is being generated
+	 *
+	 * @return a new identifier
+	 * @throws HibernateException
+	 */
+	public Serializable generate(SessionImplementor session, Object object) 
+	throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,154 +0,0 @@
-//$Id: IdentifierGeneratorFactory.java 9686 2006-03-27 16:47:06Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Factory and helper methods for <tt>IdentifierGenerator</tt> framework.
- *
- * @author Gavin King
- */
-public final class IdentifierGeneratorFactory {
-
-	private static final Logger log = LoggerFactory.getLogger( IdentifierGeneratorFactory.class );
-
-	private static final HashMap GENERATORS = new HashMap();
-	static {
-		GENERATORS.put( "uuid", UUIDHexGenerator.class );
-		GENERATORS.put( "hilo", TableHiLoGenerator.class );
-		GENERATORS.put( "assigned", Assigned.class );
-		GENERATORS.put( "identity", IdentityGenerator.class );
-		GENERATORS.put( "select", SelectGenerator.class );
-		GENERATORS.put( "sequence", SequenceGenerator.class );
-		GENERATORS.put( "seqhilo", SequenceHiLoGenerator.class );
-		GENERATORS.put( "increment", IncrementGenerator.class );
-		GENERATORS.put( "foreign", ForeignGenerator.class );
-		GENERATORS.put( "guid", GUIDGenerator.class );
-		GENERATORS.put( "uuid.hex", UUIDHexGenerator.class ); 	// uuid.hex is deprecated
-		GENERATORS.put( "sequence-identity", SequenceIdentityGenerator.class );
-	}
-
-	public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
-		public String toString() {
-			return "SHORT_CIRCUIT_INDICATOR";
-		}
-	};
-
-	public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
-		public String toString() {
-			return "POST_INSERT_INDICATOR";
-		}
-	};
-
-	/**
-	 * Get the generated identifier when using identity columns
-	 *
-	 * @param rs The result set from which to extract the the generated identity.
-	 * @param type The expected type mapping for the identity value.
-	 * @return The generated identity value
-	 * @throws SQLException Can be thrown while accessing the result set
-	 * @throws HibernateException Indicates a problem reading back a generated identity value.
-	 */
-	public static Serializable getGeneratedIdentity(ResultSet rs, Type type) throws SQLException, HibernateException {
-		if ( !rs.next() ) {
-			throw new HibernateException( "The database returned no natively generated identity value" );
-		}
-		final Serializable id = IdentifierGeneratorFactory.get( rs, type );
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Natively generated identity: " + id );
-		}
-		return id;
-	}
-
-	// unhappy about this being public ... is there a better way?
-	public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
-		Class clazz = type.getReturnedClass();
-		if ( clazz == Long.class ) {
-			return new Long( rs.getLong( 1 ) );
-		}
-		else if ( clazz == Integer.class ) {
-			return new Integer( rs.getInt( 1 ) );
-		}
-		else if ( clazz == Short.class ) {
-			return new Short( rs.getShort( 1 ) );
-		}
-		else if ( clazz == String.class ) {
-			return rs.getString( 1 );
-		}
-		else {
-			throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
-		}
-
-	}
-
-	public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect)
-			throws MappingException {
-		try {
-			Class clazz = getIdentifierGeneratorClass( strategy, dialect );
-			IdentifierGenerator idgen = ( IdentifierGenerator ) clazz.newInstance();
-			if ( idgen instanceof Configurable ) {
-				( ( Configurable ) idgen ).configure( type, params, dialect );
-			}
-			return idgen;
-		}
-		catch ( Exception e ) {
-			throw new MappingException(
-					"could not instantiate id generator [entity-name=" + params.get(
-							IdentifierGenerator.ENTITY_NAME
-					) + "]", e
-			);
-		}
-	}
-
-	public static Class getIdentifierGeneratorClass(String strategy, Dialect dialect) {
-		Class clazz = ( Class ) GENERATORS.get( strategy );
-		if ( "native".equals( strategy ) ) {
-			clazz = dialect.getNativeIdentifierGeneratorClass();
-		}
-		try {
-			if ( clazz == null ) {
-				clazz = ReflectHelper.classForName( strategy );
-			}
-		}
-		catch ( ClassNotFoundException e ) {
-			throw new MappingException( "could not interpret id generator strategy: " + strategy );
-		}
-		return clazz;
-	}
-
-	public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
-		if ( clazz == Long.class ) {
-			return new Long( value );
-		}
-		else if ( clazz == Integer.class ) {
-			return new Integer( ( int ) value );
-		}
-		else if ( clazz == Short.class ) {
-			return new Short( ( short ) value );
-		}
-		else {
-			throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
-		}
-	}
-
-	/**
-	 * Disallow instantiation.
-	 */
-	private IdentifierGeneratorFactory() {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentifierGeneratorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,177 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.type.Type;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Factory and helper methods for <tt>IdentifierGenerator</tt> framework.
+ *
+ * @author Gavin King
+ */
+public final class IdentifierGeneratorFactory {
+
+	private static final Logger log = LoggerFactory.getLogger( IdentifierGeneratorFactory.class );
+
+	private static final HashMap GENERATORS = new HashMap();
+	static {
+		GENERATORS.put( "uuid", UUIDHexGenerator.class );
+		GENERATORS.put( "hilo", TableHiLoGenerator.class );
+		GENERATORS.put( "assigned", Assigned.class );
+		GENERATORS.put( "identity", IdentityGenerator.class );
+		GENERATORS.put( "select", SelectGenerator.class );
+		GENERATORS.put( "sequence", SequenceGenerator.class );
+		GENERATORS.put( "seqhilo", SequenceHiLoGenerator.class );
+		GENERATORS.put( "increment", IncrementGenerator.class );
+		GENERATORS.put( "foreign", ForeignGenerator.class );
+		GENERATORS.put( "guid", GUIDGenerator.class );
+		GENERATORS.put( "uuid.hex", UUIDHexGenerator.class ); 	// uuid.hex is deprecated
+		GENERATORS.put( "sequence-identity", SequenceIdentityGenerator.class );
+	}
+
+	public static final Serializable SHORT_CIRCUIT_INDICATOR = new Serializable() {
+		public String toString() {
+			return "SHORT_CIRCUIT_INDICATOR";
+		}
+	};
+
+	public static final Serializable POST_INSERT_INDICATOR = new Serializable() {
+		public String toString() {
+			return "POST_INSERT_INDICATOR";
+		}
+	};
+
+	/**
+	 * Get the generated identifier when using identity columns
+	 *
+	 * @param rs The result set from which to extract the the generated identity.
+	 * @param type The expected type mapping for the identity value.
+	 * @return The generated identity value
+	 * @throws SQLException Can be thrown while accessing the result set
+	 * @throws HibernateException Indicates a problem reading back a generated identity value.
+	 */
+	public static Serializable getGeneratedIdentity(ResultSet rs, Type type) throws SQLException, HibernateException {
+		if ( !rs.next() ) {
+			throw new HibernateException( "The database returned no natively generated identity value" );
+		}
+		final Serializable id = IdentifierGeneratorFactory.get( rs, type );
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Natively generated identity: " + id );
+		}
+		return id;
+	}
+
+	// unhappy about this being public ... is there a better way?
+	public static Serializable get(ResultSet rs, Type type) throws SQLException, IdentifierGenerationException {
+		Class clazz = type.getReturnedClass();
+		if ( clazz == Long.class ) {
+			return new Long( rs.getLong( 1 ) );
+		}
+		else if ( clazz == Integer.class ) {
+			return new Integer( rs.getInt( 1 ) );
+		}
+		else if ( clazz == Short.class ) {
+			return new Short( rs.getShort( 1 ) );
+		}
+		else if ( clazz == String.class ) {
+			return rs.getString( 1 );
+		}
+		else {
+			throw new IdentifierGenerationException( "this id generator generates long, integer, short or string" );
+		}
+
+	}
+
+	public static IdentifierGenerator create(String strategy, Type type, Properties params, Dialect dialect)
+			throws MappingException {
+		try {
+			Class clazz = getIdentifierGeneratorClass( strategy, dialect );
+			IdentifierGenerator idgen = ( IdentifierGenerator ) clazz.newInstance();
+			if ( idgen instanceof Configurable ) {
+				( ( Configurable ) idgen ).configure( type, params, dialect );
+			}
+			return idgen;
+		}
+		catch ( Exception e ) {
+			throw new MappingException(
+					"could not instantiate id generator [entity-name=" + params.get(
+							IdentifierGenerator.ENTITY_NAME
+					) + "]", e
+			);
+		}
+	}
+
+	public static Class getIdentifierGeneratorClass(String strategy, Dialect dialect) {
+		Class clazz = ( Class ) GENERATORS.get( strategy );
+		if ( "native".equals( strategy ) ) {
+			clazz = dialect.getNativeIdentifierGeneratorClass();
+		}
+		try {
+			if ( clazz == null ) {
+				clazz = ReflectHelper.classForName( strategy );
+			}
+		}
+		catch ( ClassNotFoundException e ) {
+			throw new MappingException( "could not interpret id generator strategy: " + strategy );
+		}
+		return clazz;
+	}
+
+	public static Number createNumber(long value, Class clazz) throws IdentifierGenerationException {
+		if ( clazz == Long.class ) {
+			return new Long( value );
+		}
+		else if ( clazz == Integer.class ) {
+			return new Integer( ( int ) value );
+		}
+		else if ( clazz == Short.class ) {
+			return new Short( ( short ) value );
+		}
+		else {
+			throw new IdentifierGenerationException( "this id generator generates long, integer, short" );
+		}
+	}
+
+	/**
+	 * Disallow instantiation.
+	 */
+	private IdentifierGeneratorFactory() {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,169 +0,0 @@
-//$Id: IdentityGenerator.java 9681 2006-03-24 18:10:04Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
-import org.hibernate.id.insert.IdentifierGeneratingInsert;
-import org.hibernate.id.insert.AbstractSelectingDelegate;
-import org.hibernate.id.insert.AbstractReturningDelegate;
-import org.hibernate.id.insert.InsertSelectIdentityInsert;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.HibernateException;
-import org.hibernate.AssertionFailure;
-
-
-/**
- * A generator for use with ANSI-SQL IDENTITY columns used as the primary key.
- * The IdentityGenerator for autoincrement/identity key generation.
- * <br><br>
- * Indicates to the <tt>Session</tt> that identity (ie. identity/autoincrement
- * column) key generation should be used.
- *
- * @author Christoph Sturm
- */
-public class IdentityGenerator extends AbstractPostInsertGenerator {
-
-	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
-			PostInsertIdentityPersister persister,
-	        Dialect dialect,
-	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
-		if ( isGetGeneratedKeysEnabled ) {
-			return new GetGeneratedKeysDelegate( persister, dialect );
-		}
-		else if ( dialect.supportsInsertSelectIdentity() ) {
-			return new InsertSelectDelegate( persister, dialect );
-		}
-		else {
-			return new BasicDelegate( persister, dialect );
-		}
-	}
-
-	/**
-	 * Delegate for dealing with IDENTITY columns using JDBC3 getGeneratedKeys
-	 */
-	public static class GetGeneratedKeysDelegate
-			extends AbstractReturningDelegate
-			implements InsertGeneratedIdentifierDelegate {
-		private final PostInsertIdentityPersister persister;
-		private final Dialect dialect;
-
-		public GetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
-			super( persister );
-			this.persister = persister;
-			this.dialect = dialect;
-		}
-
-		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
-			IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
-			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
-			return insert;
-		}
-
-		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
-			return session.getBatcher().prepareStatement( insertSQL, true );
-		}
-
-		public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
-			insert.executeUpdate();
-			ResultSet rs = null;
-			try {
-				rs = insert.getGeneratedKeys();
-				return IdentifierGeneratorFactory.getGeneratedIdentity(
-						rs,
-						persister.getIdentifierType()
-				);
-			}
-			finally {
-				if ( rs != null ) {
-					rs.close();
-				}
-			}
-		}
-	}
-
-	/**
-	 * Delegate for dealing with IDENTITY columns where the dialect supports returning
-	 * the generated IDENTITY value directly from the insert statement.
-	 */
-	public static class InsertSelectDelegate
-			extends AbstractReturningDelegate
-			implements InsertGeneratedIdentifierDelegate {
-		private final PostInsertIdentityPersister persister;
-		private final Dialect dialect;
-
-		public InsertSelectDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
-			super( persister );
-			this.persister = persister;
-			this.dialect = dialect;
-		}
-
-		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
-			InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert( dialect );
-			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
-			return insert;
-		}
-
-		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
-			return session.getBatcher().prepareStatement( insertSQL, false );
-		}
-
-		public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
-			if ( !insert.execute() ) {
-				while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
-					// do nothing until we hit the rsult set containing the generated id
-				}
-			}
-			ResultSet rs = insert.getResultSet();
-			try {
-				return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
-			}
-			finally {
-				rs.close();
-			}
-		}
-
-		public Serializable determineGeneratedIdentifier(SessionImplementor session, Object entity) {
-			throw new AssertionFailure( "insert statement returns generated value" );
-		}
-	}
-
-	/**
-	 * Delegate for dealing with IDENTITY columns where the dialect requires an
-	 * additional command execution to retrieve the generated IDENTITY value
-	 */
-	public static class BasicDelegate
-			extends AbstractSelectingDelegate
-			implements InsertGeneratedIdentifierDelegate {
-		private final PostInsertIdentityPersister persister;
-		private final Dialect dialect;
-
-		public BasicDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
-			super( persister );
-			this.persister = persister;
-			this.dialect = dialect;
-		}
-
-		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
-			IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
-			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
-			return insert;
-		}
-
-		protected String getSelectSQL() {
-			return persister.getIdentitySelectString();
-		}
-
-		protected Serializable getResult(
-				SessionImplementor session,
-		        ResultSet rs,
-		        Object object) throws SQLException {
-			return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/IdentityGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IdentityGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,191 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.IdentifierGeneratingInsert;
+import org.hibernate.id.insert.AbstractSelectingDelegate;
+import org.hibernate.id.insert.AbstractReturningDelegate;
+import org.hibernate.id.insert.InsertSelectIdentityInsert;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+import org.hibernate.AssertionFailure;
+
+/**
+ * A generator for use with ANSI-SQL IDENTITY columns used as the primary key.
+ * The IdentityGenerator for autoincrement/identity key generation.
+ * <br><br>
+ * Indicates to the <tt>Session</tt> that identity (ie. identity/autoincrement
+ * column) key generation should be used.
+ *
+ * @author Christoph Sturm
+ */
+public class IdentityGenerator extends AbstractPostInsertGenerator {
+
+	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+			PostInsertIdentityPersister persister,
+	        Dialect dialect,
+	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
+		if ( isGetGeneratedKeysEnabled ) {
+			return new GetGeneratedKeysDelegate( persister, dialect );
+		}
+		else if ( dialect.supportsInsertSelectIdentity() ) {
+			return new InsertSelectDelegate( persister, dialect );
+		}
+		else {
+			return new BasicDelegate( persister, dialect );
+		}
+	}
+
+	/**
+	 * Delegate for dealing with IDENTITY columns using JDBC3 getGeneratedKeys
+	 */
+	public static class GetGeneratedKeysDelegate
+			extends AbstractReturningDelegate
+			implements InsertGeneratedIdentifierDelegate {
+		private final PostInsertIdentityPersister persister;
+		private final Dialect dialect;
+
+		public GetGeneratedKeysDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+			super( persister );
+			this.persister = persister;
+			this.dialect = dialect;
+		}
+
+		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+			IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
+			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+			return insert;
+		}
+
+		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
+			return session.getBatcher().prepareStatement( insertSQL, true );
+		}
+
+		public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
+			insert.executeUpdate();
+			ResultSet rs = null;
+			try {
+				rs = insert.getGeneratedKeys();
+				return IdentifierGeneratorFactory.getGeneratedIdentity(
+						rs,
+						persister.getIdentifierType()
+				);
+			}
+			finally {
+				if ( rs != null ) {
+					rs.close();
+				}
+			}
+		}
+	}
+
+	/**
+	 * Delegate for dealing with IDENTITY columns where the dialect supports returning
+	 * the generated IDENTITY value directly from the insert statement.
+	 */
+	public static class InsertSelectDelegate
+			extends AbstractReturningDelegate
+			implements InsertGeneratedIdentifierDelegate {
+		private final PostInsertIdentityPersister persister;
+		private final Dialect dialect;
+
+		public InsertSelectDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+			super( persister );
+			this.persister = persister;
+			this.dialect = dialect;
+		}
+
+		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+			InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert( dialect );
+			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+			return insert;
+		}
+
+		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
+			return session.getBatcher().prepareStatement( insertSQL, false );
+		}
+
+		public Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
+			if ( !insert.execute() ) {
+				while ( !insert.getMoreResults() && insert.getUpdateCount() != -1 ) {
+					// do nothing until we hit the rsult set containing the generated id
+				}
+			}
+			ResultSet rs = insert.getResultSet();
+			try {
+				return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+			}
+			finally {
+				rs.close();
+			}
+		}
+
+		public Serializable determineGeneratedIdentifier(SessionImplementor session, Object entity) {
+			throw new AssertionFailure( "insert statement returns generated value" );
+		}
+	}
+
+	/**
+	 * Delegate for dealing with IDENTITY columns where the dialect requires an
+	 * additional command execution to retrieve the generated IDENTITY value
+	 */
+	public static class BasicDelegate
+			extends AbstractSelectingDelegate
+			implements InsertGeneratedIdentifierDelegate {
+		private final PostInsertIdentityPersister persister;
+		private final Dialect dialect;
+
+		public BasicDelegate(PostInsertIdentityPersister persister, Dialect dialect) {
+			super( persister );
+			this.persister = persister;
+			this.dialect = dialect;
+		}
+
+		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+			IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect );
+			insert.addIdentityColumn( persister.getRootTableKeyColumnNames()[0] );
+			return insert;
+		}
+
+		protected String getSelectSQL() {
+			return persister.getIdentitySelectString();
+		}
+
+		protected Serializable getResult(
+				SessionImplementor session,
+		        ResultSet rs,
+		        Object object) throws SQLException {
+			return IdentifierGeneratorFactory.getGeneratedIdentity( rs, persister.getIdentifierType() );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,116 +0,0 @@
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-import org.hibernate.util.StringHelper;
-
-/**
- * <b>increment</b><br>
- * <br>
- * An <tt>IdentifierGenerator</tt> that returns a <tt>long</tt>, constructed by
- * counting from the maximum primary key value at startup. Not safe for use in a
- * cluster!<br>
- * <br>
- * Mapping parameters supported, but not usually needed: tables, column.
- * (The tables parameter specified a comma-separated list of table names.)
- *
- * @author Gavin King
- */
-public class IncrementGenerator implements IdentifierGenerator, Configurable {
-
-	private static final Logger log = LoggerFactory.getLogger(IncrementGenerator.class);
-
-	private long next;
-	private String sql;
-	private Class returnClass;
-
-	public synchronized Serializable generate(SessionImplementor session, Object object) 
-	throws HibernateException {
-
-		if (sql!=null) {
-			getNext( session );
-		}
-		return IdentifierGeneratorFactory.createNumber(next++, returnClass);
-	}
-
-	public void configure(Type type, Properties params, Dialect dialect)
-	throws MappingException {
-
-		String tableList = params.getProperty("tables");
-		if (tableList==null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES);
-		String[] tables = StringHelper.split(", ", tableList);
-		String column = params.getProperty("column");
-		if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
-		String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
-		String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG);
-		returnClass = type.getReturnedClass();
-		
-
-		StringBuffer buf = new StringBuffer();
-		for ( int i=0; i<tables.length; i++ ) {
-			if (tables.length>1) {
-				buf.append("select ").append(column).append(" from ");
-			}
-			buf.append( Table.qualify( catalog, schema, tables[i] ) );
-			if ( i<tables.length-1) buf.append(" union ");
-		}
-		if (tables.length>1) {
-			buf.insert(0, "( ").append(" ) ids_");
-			column = "ids_." + column;
-		}
-		
-		sql = "select max(" + column + ") from " + buf.toString();
-	}
-
-	private void getNext( SessionImplementor session ) {
-
-		log.debug("fetching initial value: " + sql);
-		
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
-			try {
-				ResultSet rs = st.executeQuery();
-				try {
-					if ( rs.next() ) {
-						next = rs.getLong(1) + 1;
-						if ( rs.wasNull() ) next = 1;
-					}
-					else {
-						next = 1;
-					}
-					sql=null;
-					log.debug("first free id: " + next);
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement(st);
-			}
-			
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not fetch initial value for increment generator",
-					sql
-				);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/IncrementGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/IncrementGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,140 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * <b>increment</b><br>
+ * <br>
+ * An <tt>IdentifierGenerator</tt> that returns a <tt>long</tt>, constructed by
+ * counting from the maximum primary key value at startup. Not safe for use in a
+ * cluster!<br>
+ * <br>
+ * Mapping parameters supported, but not usually needed: tables, column.
+ * (The tables parameter specified a comma-separated list of table names.)
+ *
+ * @author Gavin King
+ */
+public class IncrementGenerator implements IdentifierGenerator, Configurable {
+
+	private static final Logger log = LoggerFactory.getLogger(IncrementGenerator.class);
+
+	private long next;
+	private String sql;
+	private Class returnClass;
+
+	public synchronized Serializable generate(SessionImplementor session, Object object) 
+	throws HibernateException {
+
+		if (sql!=null) {
+			getNext( session );
+		}
+		return IdentifierGeneratorFactory.createNumber(next++, returnClass);
+	}
+
+	public void configure(Type type, Properties params, Dialect dialect)
+	throws MappingException {
+
+		String tableList = params.getProperty("tables");
+		if (tableList==null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES);
+		String[] tables = StringHelper.split(", ", tableList);
+		String column = params.getProperty("column");
+		if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
+		String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
+		String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG);
+		returnClass = type.getReturnedClass();
+		
+
+		StringBuffer buf = new StringBuffer();
+		for ( int i=0; i<tables.length; i++ ) {
+			if (tables.length>1) {
+				buf.append("select ").append(column).append(" from ");
+			}
+			buf.append( Table.qualify( catalog, schema, tables[i] ) );
+			if ( i<tables.length-1) buf.append(" union ");
+		}
+		if (tables.length>1) {
+			buf.insert(0, "( ").append(" ) ids_");
+			column = "ids_." + column;
+		}
+		
+		sql = "select max(" + column + ") from " + buf.toString();
+	}
+
+	private void getNext( SessionImplementor session ) {
+
+		log.debug("fetching initial value: " + sql);
+		
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
+			try {
+				ResultSet rs = st.executeQuery();
+				try {
+					if ( rs.next() ) {
+						next = rs.getLong(1) + 1;
+						if ( rs.wasNull() ) next = 1;
+					}
+					else {
+						next = 1;
+					}
+					sql=null;
+					log.debug("first free id: " + next);
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement(st);
+			}
+			
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not fetch initial value for increment generator",
+					sql
+				);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,242 +0,0 @@
-//$Id: MultipleHiLoPerTableGenerator.java 11320 2007-03-20 11:50:53Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- *
- * A hilo <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
- * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction
- * to the <tt>Session</tt> transaction so the generator must be able to obtain
- * a new connection and commit it. Hence this implementation may not
- * be used  when the user is supplying connections. In this
- * case a <tt>SequenceHiLoGenerator</tt> would be a better choice (where
- * supported).<br>
- * <br>
- *
- * A hilo <tt>IdentifierGenerator</tt> that uses a database
- * table to store the last generated values. A table can contains
- * several hi values. They are distinct from each other through a key
- * <p/>
- * <p>This implementation is not compliant with a user connection</p>
- * <p/>
- * 
- * <p>Allowed parameters (all of them are optional):</p>
- * <ul>
- * <li>table: table name (default <tt>hibernate_sequences</tt>)</li>
- * <li>primary_key_column: key column name (default <tt>sequence_name</tt>)</li>
- * <li>value_column: hi value column name(default <tt>sequence_next_hi_value</tt>)</li>
- * <li>primary_key_value: key value for the current entity (default to the entity's primary table name)</li>
- * <li>primary_key_length: length of the key column in DB represented as a varchar (default to 255)</li>
- * <li>max_lo: max low value before increasing hi (default to Short.MAX_VALUE)</li>
- * </ul>
- *
- * @author Emmanuel Bernard
- * @author <a href="mailto:kr at hbt.de">Klaus Richarz</a>.
- */
-public class MultipleHiLoPerTableGenerator 
-	extends TransactionHelper
-	implements PersistentIdentifierGenerator, Configurable {
-	
-	private static final Logger log = LoggerFactory.getLogger(MultipleHiLoPerTableGenerator.class);
-	
-	public static final String ID_TABLE = "table";
-	public static final String PK_COLUMN_NAME = "primary_key_column";
-	public static final String PK_VALUE_NAME = "primary_key_value";
-	public static final String VALUE_COLUMN_NAME = "value_column";
-	public static final String PK_LENGTH_NAME = "primary_key_length";
-
-	private static final int DEFAULT_PK_LENGTH = 255;
-	public static final String DEFAULT_TABLE = "hibernate_sequences";
-	private static final String DEFAULT_PK_COLUMN = "sequence_name";
-	private static final String DEFAULT_VALUE_COLUMN = "sequence_next_hi_value";
-	
-	private String tableName;
-	private String pkColumnName;
-	private String valueColumnName;
-	private String query;
-	private String insert;
-	private String update;
-
-	//hilo params
-	public static final String MAX_LO = "max_lo";
-
-	private long hi;
-	private int lo;
-	private int maxLo;
-	private Class returnClass;
-	private int keySize;
-
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		return new String[] {
-			new StringBuffer( dialect.getCreateTableString() )
-					.append( ' ' )
-					.append( tableName )
-					.append( " ( " )
-					.append( pkColumnName )
-					.append( ' ' )
-					.append( dialect.getTypeName( Types.VARCHAR, keySize, 0, 0 ) )
-					.append( ",  " )
-					.append( valueColumnName )
-					.append( ' ' )
-					.append( dialect.getTypeName( Types.INTEGER ) )
-					.append( " ) " )
-					.toString()
-		};
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		StringBuffer sqlDropString = new StringBuffer( "drop table " );
-		if ( dialect.supportsIfExistsBeforeTableName() ) {
-			sqlDropString.append( "if exists " );
-		}
-		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
-		if ( dialect.supportsIfExistsAfterTableName() ) {
-			sqlDropString.append( " if exists" );
-		}
-		return new String[] { sqlDropString.toString() };
-	}
-
-	public Object generatorKey() {
-		return tableName;
-	}
-
-	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
-		int result;
-		int rows;
-		do {
-			// The loop ensures atomicity of the
-			// select + update even for no transaction
-			// or read committed isolation level
-
-			//sql = query;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement qps = conn.prepareStatement(query);
-			PreparedStatement ips = null;
-			try {
-				//qps.setString(1, key);
-				ResultSet rs = qps.executeQuery();
-				boolean isInitialized = rs.next();
-				if ( !isInitialized ) {
-					result = 0;
-					ips = conn.prepareStatement(insert);
-					//ips.setString(1, key);
-					ips.setInt(1, result);
-					ips.execute();
-				}
-				else {
-					result = rs.getInt(1);
-				}
-				rs.close();
-			}
-			catch (SQLException sqle) {
-				log.error("could not read or init a hi value", sqle);
-				throw sqle;
-			}
-			finally {
-				if (ips != null) {
-					ips.close();
-				}
-				qps.close();
-			}
-
-			//sql = update;
-			PreparedStatement ups = conn.prepareStatement(update);
-			try {
-				ups.setInt( 1, result + 1 );
-				ups.setInt( 2, result );
-				//ups.setString( 3, key );
-				rows = ups.executeUpdate();
-			}
-			catch (SQLException sqle) {
-				log.error("could not update hi value in: " + tableName, sqle);
-				throw sqle;
-			}
-			finally {
-				ups.close();
-			}
-		}
-		while (rows==0);
-		return new Integer(result);
-	}
-
-	public synchronized Serializable generate(SessionImplementor session, Object obj)
-		throws HibernateException {
-		if (maxLo < 1) {
-			//keep the behavior consistent even for boundary usages
-			int val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
-			if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
-			return IdentifierGeneratorFactory.createNumber( val, returnClass );
-		}
-		if (lo>maxLo) {
-			int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue();
-			lo = (hival == 0) ? 1 : 0;
-			hi = hival * (maxLo+1);
-			log.debug("new hi value: " + hival);
-		}
-		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
-	}
-
-	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
-		tableName = PropertiesHelper.getString(ID_TABLE, params, DEFAULT_TABLE);
-		pkColumnName = PropertiesHelper.getString(PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN);
-		valueColumnName = PropertiesHelper.getString(VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN);
-		String schemaName = params.getProperty(SCHEMA);
-		String catalogName = params.getProperty(CATALOG);
-		keySize = PropertiesHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH);
-		String keyValue = PropertiesHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) );
-
-		if ( tableName.indexOf( '.' )<0 ) {
-			tableName = Table.qualify( catalogName, schemaName, tableName );
-		}
-
-		query = "select " +
-			valueColumnName +
-			" from " +
-			dialect.appendLockHint(LockMode.UPGRADE, tableName) +
-			" where " + pkColumnName + " = '" + keyValue + "'" +
-			dialect.getForUpdateString();
-
-		update = "update " +
-			tableName +
-			" set " +
-			valueColumnName +
-			" = ? where " +
-			valueColumnName +
-			" = ? and " +
-			pkColumnName +
-			" = '" + 
-			keyValue 
-			+ "'";
-		
-		insert = "insert into " + tableName +
-			"(" + pkColumnName + ", " +	valueColumnName + ") " +
-			"values('"+ keyValue +"', ?)";
-
-
-		//hilo config
-		maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
-		lo = maxLo + 1; // so we "clock over" on the first invocation
-		returnClass = type.getReturnedClass();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/MultipleHiLoPerTableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,265 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TransactionHelper;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ *
+ * A hilo <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
+ * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction
+ * to the <tt>Session</tt> transaction so the generator must be able to obtain
+ * a new connection and commit it. Hence this implementation may not
+ * be used  when the user is supplying connections. In this
+ * case a <tt>SequenceHiLoGenerator</tt> would be a better choice (where
+ * supported).<br>
+ * <br>
+ *
+ * A hilo <tt>IdentifierGenerator</tt> that uses a database
+ * table to store the last generated values. A table can contains
+ * several hi values. They are distinct from each other through a key
+ * <p/>
+ * <p>This implementation is not compliant with a user connection</p>
+ * <p/>
+ * 
+ * <p>Allowed parameters (all of them are optional):</p>
+ * <ul>
+ * <li>table: table name (default <tt>hibernate_sequences</tt>)</li>
+ * <li>primary_key_column: key column name (default <tt>sequence_name</tt>)</li>
+ * <li>value_column: hi value column name(default <tt>sequence_next_hi_value</tt>)</li>
+ * <li>primary_key_value: key value for the current entity (default to the entity's primary table name)</li>
+ * <li>primary_key_length: length of the key column in DB represented as a varchar (default to 255)</li>
+ * <li>max_lo: max low value before increasing hi (default to Short.MAX_VALUE)</li>
+ * </ul>
+ *
+ * @author Emmanuel Bernard
+ * @author <a href="mailto:kr at hbt.de">Klaus Richarz</a>.
+ */
+public class MultipleHiLoPerTableGenerator 
+	extends TransactionHelper
+	implements PersistentIdentifierGenerator, Configurable {
+	
+	private static final Logger log = LoggerFactory.getLogger(MultipleHiLoPerTableGenerator.class);
+	
+	public static final String ID_TABLE = "table";
+	public static final String PK_COLUMN_NAME = "primary_key_column";
+	public static final String PK_VALUE_NAME = "primary_key_value";
+	public static final String VALUE_COLUMN_NAME = "value_column";
+	public static final String PK_LENGTH_NAME = "primary_key_length";
+
+	private static final int DEFAULT_PK_LENGTH = 255;
+	public static final String DEFAULT_TABLE = "hibernate_sequences";
+	private static final String DEFAULT_PK_COLUMN = "sequence_name";
+	private static final String DEFAULT_VALUE_COLUMN = "sequence_next_hi_value";
+	
+	private String tableName;
+	private String pkColumnName;
+	private String valueColumnName;
+	private String query;
+	private String insert;
+	private String update;
+
+	//hilo params
+	public static final String MAX_LO = "max_lo";
+
+	private long hi;
+	private int lo;
+	private int maxLo;
+	private Class returnClass;
+	private int keySize;
+
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		return new String[] {
+			new StringBuffer( dialect.getCreateTableString() )
+					.append( ' ' )
+					.append( tableName )
+					.append( " ( " )
+					.append( pkColumnName )
+					.append( ' ' )
+					.append( dialect.getTypeName( Types.VARCHAR, keySize, 0, 0 ) )
+					.append( ",  " )
+					.append( valueColumnName )
+					.append( ' ' )
+					.append( dialect.getTypeName( Types.INTEGER ) )
+					.append( " ) " )
+					.toString()
+		};
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		StringBuffer sqlDropString = new StringBuffer( "drop table " );
+		if ( dialect.supportsIfExistsBeforeTableName() ) {
+			sqlDropString.append( "if exists " );
+		}
+		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
+		if ( dialect.supportsIfExistsAfterTableName() ) {
+			sqlDropString.append( " if exists" );
+		}
+		return new String[] { sqlDropString.toString() };
+	}
+
+	public Object generatorKey() {
+		return tableName;
+	}
+
+	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
+		int result;
+		int rows;
+		do {
+			// The loop ensures atomicity of the
+			// select + update even for no transaction
+			// or read committed isolation level
+
+			//sql = query;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement qps = conn.prepareStatement(query);
+			PreparedStatement ips = null;
+			try {
+				//qps.setString(1, key);
+				ResultSet rs = qps.executeQuery();
+				boolean isInitialized = rs.next();
+				if ( !isInitialized ) {
+					result = 0;
+					ips = conn.prepareStatement(insert);
+					//ips.setString(1, key);
+					ips.setInt(1, result);
+					ips.execute();
+				}
+				else {
+					result = rs.getInt(1);
+				}
+				rs.close();
+			}
+			catch (SQLException sqle) {
+				log.error("could not read or init a hi value", sqle);
+				throw sqle;
+			}
+			finally {
+				if (ips != null) {
+					ips.close();
+				}
+				qps.close();
+			}
+
+			//sql = update;
+			PreparedStatement ups = conn.prepareStatement(update);
+			try {
+				ups.setInt( 1, result + 1 );
+				ups.setInt( 2, result );
+				//ups.setString( 3, key );
+				rows = ups.executeUpdate();
+			}
+			catch (SQLException sqle) {
+				log.error("could not update hi value in: " + tableName, sqle);
+				throw sqle;
+			}
+			finally {
+				ups.close();
+			}
+		}
+		while (rows==0);
+		return new Integer(result);
+	}
+
+	public synchronized Serializable generate(SessionImplementor session, Object obj)
+		throws HibernateException {
+		if (maxLo < 1) {
+			//keep the behavior consistent even for boundary usages
+			int val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
+			if (val == 0) val = ( (Integer) doWorkInNewTransaction(session) ).intValue();
+			return IdentifierGeneratorFactory.createNumber( val, returnClass );
+		}
+		if (lo>maxLo) {
+			int hival = ( (Integer) doWorkInNewTransaction(session) ).intValue();
+			lo = (hival == 0) ? 1 : 0;
+			hi = hival * (maxLo+1);
+			log.debug("new hi value: " + hival);
+		}
+		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+	}
+
+	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
+		tableName = PropertiesHelper.getString(ID_TABLE, params, DEFAULT_TABLE);
+		pkColumnName = PropertiesHelper.getString(PK_COLUMN_NAME, params, DEFAULT_PK_COLUMN);
+		valueColumnName = PropertiesHelper.getString(VALUE_COLUMN_NAME, params, DEFAULT_VALUE_COLUMN);
+		String schemaName = params.getProperty(SCHEMA);
+		String catalogName = params.getProperty(CATALOG);
+		keySize = PropertiesHelper.getInt(PK_LENGTH_NAME, params, DEFAULT_PK_LENGTH);
+		String keyValue = PropertiesHelper.getString(PK_VALUE_NAME, params, params.getProperty(TABLE) );
+
+		if ( tableName.indexOf( '.' )<0 ) {
+			tableName = Table.qualify( catalogName, schemaName, tableName );
+		}
+
+		query = "select " +
+			valueColumnName +
+			" from " +
+			dialect.appendLockHint(LockMode.UPGRADE, tableName) +
+			" where " + pkColumnName + " = '" + keyValue + "'" +
+			dialect.getForUpdateString();
+
+		update = "update " +
+			tableName +
+			" set " +
+			valueColumnName +
+			" = ? where " +
+			valueColumnName +
+			" = ? and " +
+			pkColumnName +
+			" = '" + 
+			keyValue 
+			+ "'";
+		
+		insert = "insert into " + tableName +
+			"(" + pkColumnName + ", " +	valueColumnName + ") " +
+			"values('"+ keyValue +"', ?)";
+
+
+		//hilo config
+		maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
+		lo = maxLo + 1; // so we "clock over" on the first invocation
+		returnClass = type.getReturnedClass();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: PersistentIdentifierGenerator.java 6514 2005-04-26 06:37:54Z oneovthafew $
-package org.hibernate.id;
-
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-
-/**
- * An <tt>IdentifierGenerator</tt> that requires creation of database objects.
- * <br><br>
- * All <tt>PersistentIdentifierGenerator</tt>s that also implement
- * <tt>Configurable</tt> have access to a special mapping parameter: schema
- *
- * @see IdentifierGenerator
- * @see Configurable
- * @author Gavin King
- */
-public interface PersistentIdentifierGenerator extends IdentifierGenerator {
-
-	/**
-	 * The configuration parameter holding the schema name
-	 */
-	public static final String SCHEMA = "schema";
-
-	/**
-	 * The configuration parameter holding the table name for the
-	 * generated id
-	 */
-	public static final String TABLE = "target_table";
-
-	/**
-	 * The configuration parameter holding the table names for all
-	 * tables for which the id must be unique
-	 */
-	public static final String TABLES = "identity_tables";
-
-	/**
-	 * The configuration parameter holding the primary key column
-	 * name of the generated id
-	 */
-	public static final String PK = "target_column";
-
-    /**
-     * The configuration parameter holding the catalog name
-     */
-    public static final String CATALOG = "catalog";
-    
-	/**
-	 * The SQL required to create the underlying database objects.
-	 *
-	 * @param dialect The dialect against which to generate the create command(s)
-	 * @return The create command(s)
-	 * @throws HibernateException problem creating the create command(s)
-	 */
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException;
-
-	/**
-	 * The SQL required to remove the underlying database objects.
-	 *
-	 * @param dialect The dialect against which to generate the drop command(s)
-	 * @return The drop command(s)
-	 * @throws HibernateException problem creating the drop command(s)
-	 */
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException;
-
-	/**
-	 * Return a key unique to the underlying database objects. Prevents us from
-	 * trying to create/remove them multiple times.
-	 * 
-	 * @return Object an identifying key for this generator
-	 */
-	public Object generatorKey();
-
-	static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PersistentIdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.id;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+
+/**
+ * An <tt>IdentifierGenerator</tt> that requires creation of database objects.
+ * <br><br>
+ * All <tt>PersistentIdentifierGenerator</tt>s that also implement
+ * <tt>Configurable</tt> have access to a special mapping parameter: schema
+ *
+ * @see IdentifierGenerator
+ * @see Configurable
+ * @author Gavin King
+ */
+public interface PersistentIdentifierGenerator extends IdentifierGenerator {
+
+	/**
+	 * The configuration parameter holding the schema name
+	 */
+	public static final String SCHEMA = "schema";
+
+	/**
+	 * The configuration parameter holding the table name for the
+	 * generated id
+	 */
+	public static final String TABLE = "target_table";
+
+	/**
+	 * The configuration parameter holding the table names for all
+	 * tables for which the id must be unique
+	 */
+	public static final String TABLES = "identity_tables";
+
+	/**
+	 * The configuration parameter holding the primary key column
+	 * name of the generated id
+	 */
+	public static final String PK = "target_column";
+
+    /**
+     * The configuration parameter holding the catalog name
+     */
+    public static final String CATALOG = "catalog";
+    
+	/**
+	 * The SQL required to create the underlying database objects.
+	 *
+	 * @param dialect The dialect against which to generate the create command(s)
+	 * @return The create command(s)
+	 * @throws HibernateException problem creating the create command(s)
+	 */
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException;
+
+	/**
+	 * The SQL required to remove the underlying database objects.
+	 *
+	 * @param dialect The dialect against which to generate the drop command(s)
+	 * @return The drop command(s)
+	 * @throws HibernateException problem creating the drop command(s)
+	 */
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException;
+
+	/**
+	 * Return a key unique to the underlying database objects. Prevents us from
+	 * trying to create/remove them multiple times.
+	 * 
+	 * @return Object an identifying key for this generator
+	 */
+	public Object generatorKey();
+
+	static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: PostInsertIdentifierGenerator.java 9681 2006-03-24 18:10:04Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
-
-/**
- * @author Gavin King
- */
-public interface PostInsertIdentifierGenerator extends IdentifierGenerator {
-	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
-			PostInsertIdentityPersister persister,
-	        Dialect dialect,
-	        boolean isGetGeneratedKeysEnabled) throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentifierGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+
+/**
+ * @author Gavin King
+ */
+public interface PostInsertIdentifierGenerator extends IdentifierGenerator {
+	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+			PostInsertIdentityPersister persister,
+	        Dialect dialect,
+	        boolean isGetGeneratedKeysEnabled) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: PostInsertIdentityPersister.java 9681 2006-03-24 18:10:04Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * A persister that may have an identity assigned by execution of 
- * a SQL <tt>INSERT</tt>.
- *
- * @author Gavin King
- */
-public interface PostInsertIdentityPersister extends EntityPersister {
-	/**
-	 * Get a SQL select string that performs a select based on a unique
-	 * key determined by the given property name).
-	 *
-	 * @param propertyName The name of the property which maps to the
-	 * column(s) to use in the select statement restriction.
-	 * @return The SQL select string
-	 */
-	public String getSelectByUniqueKeyString(String propertyName);
-
-	/**
-	 * Get the database-specific SQL command to retrieve the last
-	 * generated IDENTITY value.
-	 *
-	 * @return The SQL command string
-	 */
-	public String getIdentitySelectString();
-
-	/**
-	 * The names of the primary key columns in the root table.
-	 *
-	 * @return The primary key column names.
-	 */
-	public String[] getRootTableKeyColumnNames();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/PostInsertIdentityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.id;
+
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * A persister that may have an identity assigned by execution of 
+ * a SQL <tt>INSERT</tt>.
+ *
+ * @author Gavin King
+ */
+public interface PostInsertIdentityPersister extends EntityPersister {
+	/**
+	 * Get a SQL select string that performs a select based on a unique
+	 * key determined by the given property name).
+	 *
+	 * @param propertyName The name of the property which maps to the
+	 * column(s) to use in the select statement restriction.
+	 * @return The SQL select string
+	 */
+	public String getSelectByUniqueKeyString(String propertyName);
+
+	/**
+	 * Get the database-specific SQL command to retrieve the last
+	 * generated IDENTITY value.
+	 *
+	 * @return The SQL command string
+	 */
+	public String getIdentitySelectString();
+
+	/**
+	 * The names of the primary key columns in the root table.
+	 *
+	 * @return The primary key column names.
+	 */
+	public String[] getRootTableKeyColumnNames();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SelectGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,138 +0,0 @@
-//$Id: SelectGenerator.java 11060 2007-01-19 12:51:31Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import org.hibernate.MappingException;
-import org.hibernate.HibernateException;
-import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
-import org.hibernate.id.insert.IdentifierGeneratingInsert;
-import org.hibernate.id.insert.AbstractSelectingDelegate;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.ValueInclusion;
-import org.hibernate.type.Type;
-
-/**
- * A generator that selects the just inserted row to determine the identifier
- * value assigned by the database. The correct row is located using a unique
- * key.
- * <p/>
- * One mapping parameter is required: key (unless a natural-id is defined in the mapping).
- *
- * @author Gavin King
- */
-public class SelectGenerator extends AbstractPostInsertGenerator implements Configurable {
-	
-	private String uniqueKeyPropertyName;
-
-	public void configure(Type type, Properties params, Dialect d) throws MappingException {
-		uniqueKeyPropertyName = params.getProperty( "key" );
-	}
-
-	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
-			PostInsertIdentityPersister persister,
-	        Dialect dialect,
-	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
-		return new SelectGeneratorDelegate( persister, dialect, uniqueKeyPropertyName );
-	}
-
-	private static String determineNameOfPropertyToUse(PostInsertIdentityPersister persister, String supplied) {
-		if ( supplied != null ) {
-			return supplied;
-		}
-		int[] naturalIdPropertyIndices = persister.getNaturalIdentifierProperties();
-		if ( naturalIdPropertyIndices == null ){
-			throw new IdentifierGenerationException(
-					"no natural-id property defined; need to specify [key] in " +
-					"generator parameters"
-			);
-		}
-		if ( naturalIdPropertyIndices.length > 1 ) {
-			throw new IdentifierGenerationException(
-					"select generator does not currently support composite " +
-					"natural-id properties; need to specify [key] in generator parameters"
-			);
-		}
-		ValueInclusion inclusion = persister.getPropertyInsertGenerationInclusions() [ naturalIdPropertyIndices[0] ];
-		if ( inclusion != ValueInclusion.NONE ) {
-			throw new IdentifierGenerationException(
-					"natural-id also defined as insert-generated; need to specify [key] " +
-					"in generator parameters"
-			);
-		}
-		return persister.getPropertyNames() [ naturalIdPropertyIndices[0] ];
-	}
-
-
-	/**
-	 * The delegate for the select generation strategy.
-	 */
-	public static class SelectGeneratorDelegate
-			extends AbstractSelectingDelegate
-			implements InsertGeneratedIdentifierDelegate {
-		private final PostInsertIdentityPersister persister;
-		private final Dialect dialect;
-
-		private final String uniqueKeyPropertyName;
-		private final Type uniqueKeyType;
-		private final Type idType;
-
-		private final String idSelectString;
-
-		private SelectGeneratorDelegate(
-				PostInsertIdentityPersister persister,
-		        Dialect dialect,
-		        String suppliedUniqueKeyPropertyName) {
-			super( persister );
-			this.persister = persister;
-			this.dialect = dialect;
-			this.uniqueKeyPropertyName = determineNameOfPropertyToUse( persister, suppliedUniqueKeyPropertyName );
-
-			idSelectString = persister.getSelectByUniqueKeyString( uniqueKeyPropertyName );
-			uniqueKeyType = persister.getPropertyType( uniqueKeyPropertyName );
-			idType = persister.getIdentifierType();
-		}
-
-		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
-			return new IdentifierGeneratingInsert( dialect );
-		}
-
-
-		// AbstractSelectingDelegate impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		protected String getSelectSQL() {
-			return idSelectString;
-		}
-
-		protected void bindParameters(
-				SessionImplementor session,
-		        PreparedStatement ps,
-		        Object entity) throws SQLException {
-			Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName, session.getEntityMode() );
-			uniqueKeyType.nullSafeSet( ps, uniqueKeyValue, 1, session );
-		}
-
-		protected Serializable getResult(
-				SessionImplementor session,
-		        ResultSet rs,
-		        Object entity) throws SQLException {
-			if ( !rs.next() ) {
-				throw new IdentifierGenerationException(
-						"the inserted row could not be located by the unique key: " +
-						uniqueKeyPropertyName
-				);
-			}
-			return ( Serializable ) idType.nullSafeGet(
-					rs,
-					persister.getRootTableKeyColumnNames(),
-					session,
-					entity
-			);
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/SelectGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SelectGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,161 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.hibernate.MappingException;
+import org.hibernate.HibernateException;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.IdentifierGeneratingInsert;
+import org.hibernate.id.insert.AbstractSelectingDelegate;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.ValueInclusion;
+import org.hibernate.type.Type;
+
+/**
+ * A generator that selects the just inserted row to determine the identifier
+ * value assigned by the database. The correct row is located using a unique
+ * key.
+ * <p/>
+ * One mapping parameter is required: key (unless a natural-id is defined in the mapping).
+ *
+ * @author Gavin King
+ */
+public class SelectGenerator extends AbstractPostInsertGenerator implements Configurable {
+	
+	private String uniqueKeyPropertyName;
+
+	public void configure(Type type, Properties params, Dialect d) throws MappingException {
+		uniqueKeyPropertyName = params.getProperty( "key" );
+	}
+
+	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+			PostInsertIdentityPersister persister,
+	        Dialect dialect,
+	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
+		return new SelectGeneratorDelegate( persister, dialect, uniqueKeyPropertyName );
+	}
+
+	private static String determineNameOfPropertyToUse(PostInsertIdentityPersister persister, String supplied) {
+		if ( supplied != null ) {
+			return supplied;
+		}
+		int[] naturalIdPropertyIndices = persister.getNaturalIdentifierProperties();
+		if ( naturalIdPropertyIndices == null ){
+			throw new IdentifierGenerationException(
+					"no natural-id property defined; need to specify [key] in " +
+					"generator parameters"
+			);
+		}
+		if ( naturalIdPropertyIndices.length > 1 ) {
+			throw new IdentifierGenerationException(
+					"select generator does not currently support composite " +
+					"natural-id properties; need to specify [key] in generator parameters"
+			);
+		}
+		ValueInclusion inclusion = persister.getPropertyInsertGenerationInclusions() [ naturalIdPropertyIndices[0] ];
+		if ( inclusion != ValueInclusion.NONE ) {
+			throw new IdentifierGenerationException(
+					"natural-id also defined as insert-generated; need to specify [key] " +
+					"in generator parameters"
+			);
+		}
+		return persister.getPropertyNames() [ naturalIdPropertyIndices[0] ];
+	}
+
+
+	/**
+	 * The delegate for the select generation strategy.
+	 */
+	public static class SelectGeneratorDelegate
+			extends AbstractSelectingDelegate
+			implements InsertGeneratedIdentifierDelegate {
+		private final PostInsertIdentityPersister persister;
+		private final Dialect dialect;
+
+		private final String uniqueKeyPropertyName;
+		private final Type uniqueKeyType;
+		private final Type idType;
+
+		private final String idSelectString;
+
+		private SelectGeneratorDelegate(
+				PostInsertIdentityPersister persister,
+		        Dialect dialect,
+		        String suppliedUniqueKeyPropertyName) {
+			super( persister );
+			this.persister = persister;
+			this.dialect = dialect;
+			this.uniqueKeyPropertyName = determineNameOfPropertyToUse( persister, suppliedUniqueKeyPropertyName );
+
+			idSelectString = persister.getSelectByUniqueKeyString( uniqueKeyPropertyName );
+			uniqueKeyType = persister.getPropertyType( uniqueKeyPropertyName );
+			idType = persister.getIdentifierType();
+		}
+
+		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+			return new IdentifierGeneratingInsert( dialect );
+		}
+
+
+		// AbstractSelectingDelegate impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		protected String getSelectSQL() {
+			return idSelectString;
+		}
+
+		protected void bindParameters(
+				SessionImplementor session,
+		        PreparedStatement ps,
+		        Object entity) throws SQLException {
+			Object uniqueKeyValue = persister.getPropertyValue( entity, uniqueKeyPropertyName, session.getEntityMode() );
+			uniqueKeyType.nullSafeSet( ps, uniqueKeyValue, 1, session );
+		}
+
+		protected Serializable getResult(
+				SessionImplementor session,
+		        ResultSet rs,
+		        Object entity) throws SQLException {
+			if ( !rs.next() ) {
+				throw new IdentifierGenerationException(
+						"the inserted row could not be located by the unique key: " +
+						uniqueKeyPropertyName
+				);
+			}
+			return ( Serializable ) idType.nullSafeGet(
+					rs,
+					persister.getRootTableKeyColumnNames(),
+					session,
+					entity
+			);
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,126 +0,0 @@
-//$Id: SequenceGenerator.java 9686 2006-03-27 16:47:06Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- * <b>sequence</b><br>
- * <br>
- * Generates <tt>long</tt> values using an oracle-style sequence. A higher
- * performance algorithm is <tt>SequenceHiLoGenerator</tt>.<br>
- * <br>
- * Mapping parameters supported: sequence, parameters.
- *
- * @see SequenceHiLoGenerator
- * @see TableHiLoGenerator
- * @author Gavin King
- */
-
-public class SequenceGenerator implements PersistentIdentifierGenerator, Configurable {
-
-	/**
-	 * The sequence parameter
-	 */
-	public static final String SEQUENCE = "sequence";
-
-	/**
-	 * The parameters parameter, appended to the create sequence DDL.
-	 * For example (Oracle): <tt>INCREMENT BY 1 START WITH 1 MAXVALUE 100 NOCACHE</tt>.
-	 */
-	public static final String PARAMETERS = "parameters";
-
-	private String sequenceName;
-	private String parameters;
-	private Type identifierType;
-	private String sql;
-
-	private static final Logger log = LoggerFactory.getLogger(SequenceGenerator.class);
-
-	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
-		sequenceName = PropertiesHelper.getString(SEQUENCE, params, "hibernate_sequence");
-		parameters = params.getProperty(PARAMETERS);
-		String schemaName = params.getProperty(SCHEMA);
-		String catalogName = params.getProperty(CATALOG);
-
-		if (sequenceName.indexOf( '.' ) < 0) {
-			sequenceName = Table.qualify( catalogName, schemaName, sequenceName );
-		}
-
-		this.identifierType = type;
-		sql = dialect.getSequenceNextValString(sequenceName);
-	}
-
-	public Serializable generate(SessionImplementor session, Object obj) 
-	throws HibernateException {
-		
-		try {
-
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
-			try {
-				ResultSet rs = st.executeQuery();
-				try {
-					rs.next();
-					Serializable result = IdentifierGeneratorFactory.get(
-							rs, identifierType
-						);
-					if ( log.isDebugEnabled() ) {
-						log.debug("Sequence identifier generated: " + result);
-					}
-					return result;
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement(st);
-			}
-			
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not get next sequence value",
-					sql
-				);
-		}
-
-	}
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		String[] ddl = dialect.getCreateSequenceStrings(sequenceName);
-		if ( parameters != null ) {
-			ddl[ddl.length - 1] += ' ' + parameters;
-		}
-		return ddl;
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		return dialect.getDropSequenceStrings(sequenceName);
-	}
-
-	public Object generatorKey() {
-		return sequenceName;
-	}
-
-	public String getSequenceName() {
-		return sequenceName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/SequenceGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,149 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ * <b>sequence</b><br>
+ * <br>
+ * Generates <tt>long</tt> values using an oracle-style sequence. A higher
+ * performance algorithm is <tt>SequenceHiLoGenerator</tt>.<br>
+ * <br>
+ * Mapping parameters supported: sequence, parameters.
+ *
+ * @see SequenceHiLoGenerator
+ * @see TableHiLoGenerator
+ * @author Gavin King
+ */
+
+public class SequenceGenerator implements PersistentIdentifierGenerator, Configurable {
+
+	/**
+	 * The sequence parameter
+	 */
+	public static final String SEQUENCE = "sequence";
+
+	/**
+	 * The parameters parameter, appended to the create sequence DDL.
+	 * For example (Oracle): <tt>INCREMENT BY 1 START WITH 1 MAXVALUE 100 NOCACHE</tt>.
+	 */
+	public static final String PARAMETERS = "parameters";
+
+	private String sequenceName;
+	private String parameters;
+	private Type identifierType;
+	private String sql;
+
+	private static final Logger log = LoggerFactory.getLogger(SequenceGenerator.class);
+
+	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
+		sequenceName = PropertiesHelper.getString(SEQUENCE, params, "hibernate_sequence");
+		parameters = params.getProperty(PARAMETERS);
+		String schemaName = params.getProperty(SCHEMA);
+		String catalogName = params.getProperty(CATALOG);
+
+		if (sequenceName.indexOf( '.' ) < 0) {
+			sequenceName = Table.qualify( catalogName, schemaName, sequenceName );
+		}
+
+		this.identifierType = type;
+		sql = dialect.getSequenceNextValString(sequenceName);
+	}
+
+	public Serializable generate(SessionImplementor session, Object obj) 
+	throws HibernateException {
+		
+		try {
+
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
+			try {
+				ResultSet rs = st.executeQuery();
+				try {
+					rs.next();
+					Serializable result = IdentifierGeneratorFactory.get(
+							rs, identifierType
+						);
+					if ( log.isDebugEnabled() ) {
+						log.debug("Sequence identifier generated: " + result);
+					}
+					return result;
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement(st);
+			}
+			
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not get next sequence value",
+					sql
+				);
+		}
+
+	}
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		String[] ddl = dialect.getCreateSequenceStrings(sequenceName);
+		if ( parameters != null ) {
+			ddl[ddl.length - 1] += ' ' + parameters;
+		}
+		return ddl;
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		return dialect.getDropSequenceStrings(sequenceName);
+	}
+
+	public Object generatorKey() {
+		return sequenceName;
+	}
+
+	public String getSequenceName() {
+		return sequenceName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-//$Id: SequenceHiLoGenerator.java 9720 2006-03-31 00:11:54Z epbernard $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- * <b>seqhilo</b><br>
- * <br>
- * An <tt>IdentifierGenerator</tt> that combines a hi/lo algorithm with an underlying
- * oracle-style sequence that generates hi values. The user may specify a
- * maximum lo value to determine how often new hi values are fetched.<br>
- * <br>
- * If sequences are not available, <tt>TableHiLoGenerator</tt> might be an
- * alternative.<br>
- * <br>
- * Mapping parameters supported: sequence, max_lo, parameters.
- *
- * @see TableHiLoGenerator
- * @author Gavin King
- */
-public class SequenceHiLoGenerator extends SequenceGenerator {
-
-	public static final String MAX_LO = "max_lo";
-
-	private static final Logger log = LoggerFactory.getLogger(SequenceHiLoGenerator.class);
-
-	private int maxLo;
-	private int lo;
-	private long hi;
-	private Class returnClass;
-
-	public void configure(Type type, Properties params, Dialect d) throws MappingException {
-		super.configure(type, params, d);
-		maxLo = PropertiesHelper.getInt(MAX_LO, params, 9);
-		lo = maxLo + 1; // so we "clock over" on the first invocation
-		returnClass = type.getReturnedClass();
-	}
-
-	public synchronized Serializable generate(SessionImplementor session, Object obj) 
-	throws HibernateException {
-		if (maxLo < 1) {
-			//keep the behavior consistent even for boundary usages
-			long val = ( (Number) super.generate(session, obj) ).longValue();
-			if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
-			return IdentifierGeneratorFactory.createNumber( val, returnClass );
-		}
-		if ( lo>maxLo ) {
-			long hival = ( (Number) super.generate(session, obj) ).longValue();
-			lo = (hival == 0) ? 1 : 0;
-			hi = hival * ( maxLo+1 );
-			if ( log.isDebugEnabled() )
-				log.debug("new hi value: " + hival);
-		}
-
-		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceHiLoGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ * <b>seqhilo</b><br>
+ * <br>
+ * An <tt>IdentifierGenerator</tt> that combines a hi/lo algorithm with an underlying
+ * oracle-style sequence that generates hi values. The user may specify a
+ * maximum lo value to determine how often new hi values are fetched.<br>
+ * <br>
+ * If sequences are not available, <tt>TableHiLoGenerator</tt> might be an
+ * alternative.<br>
+ * <br>
+ * Mapping parameters supported: sequence, max_lo, parameters.
+ *
+ * @see TableHiLoGenerator
+ * @author Gavin King
+ */
+public class SequenceHiLoGenerator extends SequenceGenerator {
+
+	public static final String MAX_LO = "max_lo";
+
+	private static final Logger log = LoggerFactory.getLogger(SequenceHiLoGenerator.class);
+
+	private int maxLo;
+	private int lo;
+	private long hi;
+	private Class returnClass;
+
+	public void configure(Type type, Properties params, Dialect d) throws MappingException {
+		super.configure(type, params, d);
+		maxLo = PropertiesHelper.getInt(MAX_LO, params, 9);
+		lo = maxLo + 1; // so we "clock over" on the first invocation
+		returnClass = type.getReturnedClass();
+	}
+
+	public synchronized Serializable generate(SessionImplementor session, Object obj) 
+	throws HibernateException {
+		if (maxLo < 1) {
+			//keep the behavior consistent even for boundary usages
+			long val = ( (Number) super.generate(session, obj) ).longValue();
+			if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
+			return IdentifierGeneratorFactory.createNumber( val, returnClass );
+		}
+		if ( lo>maxLo ) {
+			long hival = ( (Number) super.generate(session, obj) ).longValue();
+			lo = (hival == 0) ? 1 : 0;
+			hi = hival * ( maxLo+1 );
+			if ( log.isDebugEnabled() )
+				log.debug("new hi value: " + hival);
+		}
+
+		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,99 +0,0 @@
-package org.hibernate.id;
-
-import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
-import org.hibernate.id.insert.AbstractReturningDelegate;
-import org.hibernate.id.insert.IdentifierGeneratingInsert;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.sql.Insert;
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionImplementor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Properties;
-
-/**
- * A generator which combines sequence generation with immediate retrieval
- * through JDBC3 {@link java.sql.Connection#prepareStatement(String, String[]) getGeneratedKeys}.
- * In this respect it works much like ANSI-SQL IDENTITY generation.
- * <p/>
- * This generator only known to work with newer Oracle drivers compiled for
- * JDK 1.4 (JDBC3).
- * <p/>
- * Note: Due to a bug in Oracle drivers, sql comments on these insert statements
- * are completely disabled.
- *
- * @author Steve Ebersole
- */
-public class SequenceIdentityGenerator extends SequenceGenerator
-		implements PostInsertIdentifierGenerator {
-
-	private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class );
-
-	public Serializable generate(SessionImplementor s, Object obj) {
-		return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
-	}
-
-	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
-			PostInsertIdentityPersister persister,
-	        Dialect dialect,
-	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
-		return new Delegate( persister, dialect, getSequenceName() );
-	}
-
-	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
-		super.configure( type, params, dialect );
-	}
-
-	public static class Delegate extends AbstractReturningDelegate {
-		private final Dialect dialect;
-		private final String sequenceNextValFragment;
-		private final String[] keyColumns;
-
-		public Delegate(PostInsertIdentityPersister persister, Dialect dialect, String sequenceName) {
-			super( persister );
-			this.dialect = dialect;
-			this.sequenceNextValFragment = dialect.getSelectSequenceNextValString( sequenceName );
-			this.keyColumns = getPersister().getRootTableKeyColumnNames();
-			if ( keyColumns.length > 1 ) {
-				throw new HibernateException( "sequence-identity generator cannot be used with with multi-column keys" );
-			}
-		}
-
-		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
-			NoCommentsInsert insert = new NoCommentsInsert( dialect );
-			insert.addColumn( getPersister().getRootTableKeyColumnNames()[0], sequenceNextValFragment );
-			return insert;
-		}
-
-		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
-			return session.getBatcher().prepareStatement( insertSQL, keyColumns );
-		}
-
-		protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
-			insert.executeUpdate();
-			return IdentifierGeneratorFactory.getGeneratedIdentity(
-					insert.getGeneratedKeys(),
-			        getPersister().getIdentifierType()
-			);
-		}
-	}
-
-	public static class NoCommentsInsert extends IdentifierGeneratingInsert {
-		public NoCommentsInsert(Dialect dialect) {
-			super( dialect );
-		}
-
-		public Insert setComment(String comment) {
-			// don't allow comments on these insert statements as comments totally
-			// blow up the Oracle getGeneratedKeys "support" :(
-			log.info( "disallowing insert statement comment for select-identity due to Oracle driver bug" );
-			return this;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/SequenceIdentityGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,123 @@
+/*
+ * 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.id;
+
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.AbstractReturningDelegate;
+import org.hibernate.id.insert.IdentifierGeneratingInsert;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.sql.Insert;
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionImplementor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Properties;
+
+/**
+ * A generator which combines sequence generation with immediate retrieval
+ * through JDBC3 {@link java.sql.Connection#prepareStatement(String, String[]) getGeneratedKeys}.
+ * In this respect it works much like ANSI-SQL IDENTITY generation.
+ * <p/>
+ * This generator only known to work with newer Oracle drivers compiled for
+ * JDK 1.4 (JDBC3).
+ * <p/>
+ * Note: Due to a bug in Oracle drivers, sql comments on these insert statements
+ * are completely disabled.
+ *
+ * @author Steve Ebersole
+ */
+public class SequenceIdentityGenerator extends SequenceGenerator
+		implements PostInsertIdentifierGenerator {
+
+	private static final Logger log = LoggerFactory.getLogger( SequenceIdentityGenerator.class );
+
+	public Serializable generate(SessionImplementor s, Object obj) {
+		return IdentifierGeneratorFactory.POST_INSERT_INDICATOR;
+	}
+
+	public InsertGeneratedIdentifierDelegate getInsertGeneratedIdentifierDelegate(
+			PostInsertIdentityPersister persister,
+	        Dialect dialect,
+	        boolean isGetGeneratedKeysEnabled) throws HibernateException {
+		return new Delegate( persister, dialect, getSequenceName() );
+	}
+
+	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
+		super.configure( type, params, dialect );
+	}
+
+	public static class Delegate extends AbstractReturningDelegate {
+		private final Dialect dialect;
+		private final String sequenceNextValFragment;
+		private final String[] keyColumns;
+
+		public Delegate(PostInsertIdentityPersister persister, Dialect dialect, String sequenceName) {
+			super( persister );
+			this.dialect = dialect;
+			this.sequenceNextValFragment = dialect.getSelectSequenceNextValString( sequenceName );
+			this.keyColumns = getPersister().getRootTableKeyColumnNames();
+			if ( keyColumns.length > 1 ) {
+				throw new HibernateException( "sequence-identity generator cannot be used with with multi-column keys" );
+			}
+		}
+
+		public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert() {
+			NoCommentsInsert insert = new NoCommentsInsert( dialect );
+			insert.addColumn( getPersister().getRootTableKeyColumnNames()[0], sequenceNextValFragment );
+			return insert;
+		}
+
+		protected PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException {
+			return session.getBatcher().prepareStatement( insertSQL, keyColumns );
+		}
+
+		protected Serializable executeAndExtract(PreparedStatement insert) throws SQLException {
+			insert.executeUpdate();
+			return IdentifierGeneratorFactory.getGeneratedIdentity(
+					insert.getGeneratedKeys(),
+			        getPersister().getIdentifierType()
+			);
+		}
+	}
+
+	public static class NoCommentsInsert extends IdentifierGeneratingInsert {
+		public NoCommentsInsert(Dialect dialect) {
+			super( dialect );
+		}
+
+		public Insert setComment(String comment) {
+			// don't allow comments on these insert statements as comments totally
+			// blow up the Oracle getGeneratedKeys "support" :(
+			log.info( "disallowing insert statement comment for select-identity due to Oracle driver bug" );
+			return this;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,171 +0,0 @@
-//$Id: TableGenerator.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.mapping.Table;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- * An <tt>IdentifierGenerator</tt> that uses a database
- * table to store the last generated value. It is not
- * intended that applications use this strategy directly.
- * However, it may be used to build other (efficient)
- * strategies. The returned type is <tt>Integer</tt>.<br>
- * <br>
- * The hi value MUST be fetched in a seperate transaction
- * to the <tt>Session</tt> transaction so the generator must
- * be able to obtain a new connection and commit it. Hence
- * this implementation may not be used when Hibernate is
- * fetching connections  when the user is supplying
- * connections.<br>
- * <br>
- * The returned value is of type <tt>integer</tt>.<br>
- * <br>
- * Mapping parameters supported: table, column
- *
- * @see TableHiLoGenerator
- * @author Gavin King
- */
-public class TableGenerator extends TransactionHelper
-	implements PersistentIdentifierGenerator, Configurable {
-	/* COLUMN and TABLE should be renamed but it would break the public API */
-	/** The column parameter */
-	public static final String COLUMN = "column";
-	
-	/** Default column name */
-	public static final String DEFAULT_COLUMN_NAME = "next_hi";
-	
-	/** The table parameter */
-	public static final String TABLE = "table";
-	
-	/** Default table name */	
-	public static final String DEFAULT_TABLE_NAME = "hibernate_unique_key";
-
-	private static final Logger log = LoggerFactory.getLogger(TableGenerator.class);
-
-	private String tableName;
-	private String columnName;
-	private String query;
-	private String update;
-
-	public void configure(Type type, Properties params, Dialect dialect) {
-
-		tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME);
-		columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME);
-		String schemaName = params.getProperty(SCHEMA);
-		String catalogName = params.getProperty(CATALOG);
-
-		if ( tableName.indexOf( '.' )<0 ) {
-			tableName = Table.qualify( catalogName, schemaName, tableName );
-		}
-
-		query = "select " + 
-			columnName + 
-			" from " + 
-			dialect.appendLockHint(LockMode.UPGRADE, tableName) +
-			dialect.getForUpdateString();
-
-		update = "update " + 
-			tableName + 
-			" set " + 
-			columnName + 
-			" = ? where " + 
-			columnName + 
-			" = ?";
-	}
-
-	public synchronized Serializable generate(SessionImplementor session, Object object)
-		throws HibernateException {
-		int result = ( (Integer) doWorkInNewTransaction(session) ).intValue();
-		return new Integer(result);
-	}
-
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		return new String[] {
-			dialect.getCreateTableString() + " " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )",
-			"insert into " + tableName + " values ( 0 )"
-		};
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) {
-		StringBuffer sqlDropString = new StringBuffer( "drop table " );
-		if ( dialect.supportsIfExistsBeforeTableName() ) {
-			sqlDropString.append( "if exists " );
-		}
-		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
-		if ( dialect.supportsIfExistsAfterTableName() ) {
-			sqlDropString.append( " if exists" );
-		}
-		return new String[] { sqlDropString.toString() };
-	}
-
-	public Object generatorKey() {
-		return tableName;
-	}
-
-	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
-		int result;
-		int rows;
-		do {
-			// The loop ensures atomicity of the
-			// select + update even for no transaction
-			// or read committed isolation level
-
-			sql = query;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement qps = conn.prepareStatement(query);
-			try {
-				ResultSet rs = qps.executeQuery();
-				if ( !rs.next() ) {
-					String err = "could not read a hi value - you need to populate the table: " + tableName;
-					log.error(err);
-					throw new IdentifierGenerationException(err);
-				}
-				result = rs.getInt(1);
-				rs.close();
-			}
-			catch (SQLException sqle) {
-				log.error("could not read a hi value", sqle);
-				throw sqle;
-			}
-			finally {
-				qps.close();
-			}
-
-			sql = update;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement ups = conn.prepareStatement(update);
-			try {
-				ups.setInt( 1, result + 1 );
-				ups.setInt( 2, result );
-				rows = ups.executeUpdate();
-			}
-			catch (SQLException sqle) {
-				log.error("could not update hi value in: " + tableName, sqle);
-				throw sqle;
-			}
-			finally {
-				ups.close();
-			}
-		}
-		while (rows==0);
-		return new Integer(result);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/TableGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,194 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TransactionHelper;
+import org.hibernate.mapping.Table;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ * An <tt>IdentifierGenerator</tt> that uses a database
+ * table to store the last generated value. It is not
+ * intended that applications use this strategy directly.
+ * However, it may be used to build other (efficient)
+ * strategies. The returned type is <tt>Integer</tt>.<br>
+ * <br>
+ * The hi value MUST be fetched in a seperate transaction
+ * to the <tt>Session</tt> transaction so the generator must
+ * be able to obtain a new connection and commit it. Hence
+ * this implementation may not be used when Hibernate is
+ * fetching connections  when the user is supplying
+ * connections.<br>
+ * <br>
+ * The returned value is of type <tt>integer</tt>.<br>
+ * <br>
+ * Mapping parameters supported: table, column
+ *
+ * @see TableHiLoGenerator
+ * @author Gavin King
+ */
+public class TableGenerator extends TransactionHelper
+	implements PersistentIdentifierGenerator, Configurable {
+	/* COLUMN and TABLE should be renamed but it would break the public API */
+	/** The column parameter */
+	public static final String COLUMN = "column";
+	
+	/** Default column name */
+	public static final String DEFAULT_COLUMN_NAME = "next_hi";
+	
+	/** The table parameter */
+	public static final String TABLE = "table";
+	
+	/** Default table name */	
+	public static final String DEFAULT_TABLE_NAME = "hibernate_unique_key";
+
+	private static final Logger log = LoggerFactory.getLogger(TableGenerator.class);
+
+	private String tableName;
+	private String columnName;
+	private String query;
+	private String update;
+
+	public void configure(Type type, Properties params, Dialect dialect) {
+
+		tableName = PropertiesHelper.getString(TABLE, params, DEFAULT_TABLE_NAME);
+		columnName = PropertiesHelper.getString(COLUMN, params, DEFAULT_COLUMN_NAME);
+		String schemaName = params.getProperty(SCHEMA);
+		String catalogName = params.getProperty(CATALOG);
+
+		if ( tableName.indexOf( '.' )<0 ) {
+			tableName = Table.qualify( catalogName, schemaName, tableName );
+		}
+
+		query = "select " + 
+			columnName + 
+			" from " + 
+			dialect.appendLockHint(LockMode.UPGRADE, tableName) +
+			dialect.getForUpdateString();
+
+		update = "update " + 
+			tableName + 
+			" set " + 
+			columnName + 
+			" = ? where " + 
+			columnName + 
+			" = ?";
+	}
+
+	public synchronized Serializable generate(SessionImplementor session, Object object)
+		throws HibernateException {
+		int result = ( (Integer) doWorkInNewTransaction(session) ).intValue();
+		return new Integer(result);
+	}
+
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		return new String[] {
+			dialect.getCreateTableString() + " " + tableName + " ( " + columnName + " " + dialect.getTypeName(Types.INTEGER) + " )",
+			"insert into " + tableName + " values ( 0 )"
+		};
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) {
+		StringBuffer sqlDropString = new StringBuffer( "drop table " );
+		if ( dialect.supportsIfExistsBeforeTableName() ) {
+			sqlDropString.append( "if exists " );
+		}
+		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
+		if ( dialect.supportsIfExistsAfterTableName() ) {
+			sqlDropString.append( " if exists" );
+		}
+		return new String[] { sqlDropString.toString() };
+	}
+
+	public Object generatorKey() {
+		return tableName;
+	}
+
+	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
+		int result;
+		int rows;
+		do {
+			// The loop ensures atomicity of the
+			// select + update even for no transaction
+			// or read committed isolation level
+
+			sql = query;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement qps = conn.prepareStatement(query);
+			try {
+				ResultSet rs = qps.executeQuery();
+				if ( !rs.next() ) {
+					String err = "could not read a hi value - you need to populate the table: " + tableName;
+					log.error(err);
+					throw new IdentifierGenerationException(err);
+				}
+				result = rs.getInt(1);
+				rs.close();
+			}
+			catch (SQLException sqle) {
+				log.error("could not read a hi value", sqle);
+				throw sqle;
+			}
+			finally {
+				qps.close();
+			}
+
+			sql = update;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement ups = conn.prepareStatement(update);
+			try {
+				ups.setInt( 1, result + 1 );
+				ups.setInt( 2, result );
+				rows = ups.executeUpdate();
+			}
+			catch (SQLException sqle) {
+				log.error("could not update hi value in: " + tableName, sqle);
+				throw sqle;
+			}
+			finally {
+				ups.close();
+			}
+		}
+		while (rows==0);
+		return new Integer(result);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-//$Id: TableHiLoGenerator.java 11123 2007-01-31 23:46:11Z steve.ebersole at jboss.com $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- * <b>hilo</b><br>
- * <br>
- * An <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
- * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction
- * to the <tt>Session</tt> transaction so the generator must be able to obtain
- * a new connection and commit it. Hence this implementation may not
- * be used  when the user is supplying connections. In this
- * case a <tt>SequenceHiLoGenerator</tt> would be a better choice (where
- * supported).<br>
- * <br>
- * Mapping parameters supported: table, column, max_lo
- *
- * @see SequenceHiLoGenerator
- * @author Gavin King
- */
-
-public class TableHiLoGenerator extends TableGenerator {
-
-	/**
-	 * The max_lo parameter
-	 */
-	public static final String MAX_LO = "max_lo";
-
-	private long hi;
-	private int lo;
-	private int maxLo;
-	private Class returnClass;
-
-	private static final Logger log = LoggerFactory.getLogger(TableHiLoGenerator.class);
-
-	public void configure(Type type, Properties params, Dialect d) {
-		super.configure(type, params, d);
-		maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
-		lo = maxLo + 1; // so we "clock over" on the first invocation
-		returnClass = type.getReturnedClass();
-	}
-
-	public synchronized Serializable generate(SessionImplementor session, Object obj) 
-	throws HibernateException {
-        if (maxLo < 1) {
-			//keep the behavior consistent even for boundary usages
-			long val = ( (Number) super.generate(session, obj) ).longValue();
-			if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
-			return IdentifierGeneratorFactory.createNumber( val, returnClass );
-		}
-		if (lo>maxLo) {
-			long hival = ( (Number) super.generate(session, obj) ).longValue();
-			lo = (hival == 0) ? 1 : 0;
-			hi = hival * (maxLo+1);
-			log.debug("new hi value: " + hival);
-		}
-
-		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/TableHiLoGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.id;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ * <b>hilo</b><br>
+ * <br>
+ * An <tt>IdentifierGenerator</tt> that returns a <tt>Long</tt>, constructed using
+ * a hi/lo algorithm. The hi value MUST be fetched in a seperate transaction
+ * to the <tt>Session</tt> transaction so the generator must be able to obtain
+ * a new connection and commit it. Hence this implementation may not
+ * be used  when the user is supplying connections. In this
+ * case a <tt>SequenceHiLoGenerator</tt> would be a better choice (where
+ * supported).<br>
+ * <br>
+ * Mapping parameters supported: table, column, max_lo
+ *
+ * @see SequenceHiLoGenerator
+ * @author Gavin King
+ */
+public class TableHiLoGenerator extends TableGenerator {
+
+	/**
+	 * The max_lo parameter
+	 */
+	public static final String MAX_LO = "max_lo";
+
+	private long hi;
+	private int lo;
+	private int maxLo;
+	private Class returnClass;
+
+	private static final Logger log = LoggerFactory.getLogger(TableHiLoGenerator.class);
+
+	public void configure(Type type, Properties params, Dialect d) {
+		super.configure(type, params, d);
+		maxLo = PropertiesHelper.getInt(MAX_LO, params, Short.MAX_VALUE);
+		lo = maxLo + 1; // so we "clock over" on the first invocation
+		returnClass = type.getReturnedClass();
+	}
+
+	public synchronized Serializable generate(SessionImplementor session, Object obj) 
+	throws HibernateException {
+        if (maxLo < 1) {
+			//keep the behavior consistent even for boundary usages
+			long val = ( (Number) super.generate(session, obj) ).longValue();
+			if (val == 0) val = ( (Number) super.generate(session, obj) ).longValue();
+			return IdentifierGeneratorFactory.createNumber( val, returnClass );
+		}
+		if (lo>maxLo) {
+			long hival = ( (Number) super.generate(session, obj) ).longValue();
+			lo = (hival == 0) ? 1 : 0;
+			hi = hival * (maxLo+1);
+			log.debug("new hi value: " + hival);
+		}
+
+		return IdentifierGeneratorFactory.createNumber( hi + lo++, returnClass );
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,75 +0,0 @@
-//$Id: UUIDHexGenerator.java 8049 2005-08-30 23:28:50Z turin42 $
-package org.hibernate.id;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-import org.hibernate.Hibernate;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-import org.hibernate.util.PropertiesHelper;
-
-/**
- * <b>uuid</b><br>
- * <br>
- * A <tt>UUIDGenerator</tt> that returns a string of length 32,
- * This string will consist of only hex digits. Optionally,
- * the string may be generated with separators between each
- * component of the UUID.
- *
- * Mapping parameters supported: separator.
- *
- * @author Gavin King
- */
-
-public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configurable {
-
-	private String sep = "";
-
-	protected String format(int intval) {
-		String formatted = Integer.toHexString(intval);
-		StringBuffer buf = new StringBuffer("00000000");
-		buf.replace( 8-formatted.length(), 8, formatted );
-		return buf.toString();
-	}
-
-	protected String format(short shortval) {
-		String formatted = Integer.toHexString(shortval);
-		StringBuffer buf = new StringBuffer("0000");
-		buf.replace( 4-formatted.length(), 4, formatted );
-		return buf.toString();
-	}
-
-	public Serializable generate(SessionImplementor session, Object obj) {
-		return new StringBuffer(36)
-			.append( format( getIP() ) ).append(sep)
-			.append( format( getJVM() ) ).append(sep)
-			.append( format( getHiTime() ) ).append(sep)
-			.append( format( getLoTime() ) ).append(sep)
-			.append( format( getCount() ) )
-			.toString();
-	}
-
-	public void configure(Type type, Properties params, Dialect d) {
-		sep = PropertiesHelper.getString("separator", params, "");
-	}
-
-	public static void main( String[] args ) throws Exception {
-		Properties props = new Properties();
-		props.setProperty("separator", "/");
-		IdentifierGenerator gen = new UUIDHexGenerator();
-		( (Configurable) gen ).configure(Hibernate.STRING, props, null);
-		IdentifierGenerator gen2 = new UUIDHexGenerator();
-		( (Configurable) gen2 ).configure(Hibernate.STRING, props, null);
-
-		for ( int i=0; i<10; i++) {
-			String id = (String) gen.generate(null, null);
-			System.out.println(id);
-			String id2 = (String) gen2.generate(null, null);
-			System.out.println(id2);
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/UUIDHexGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+import org.hibernate.Hibernate;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+import org.hibernate.util.PropertiesHelper;
+
+/**
+ * <b>uuid</b><br>
+ * <br>
+ * A <tt>UUIDGenerator</tt> that returns a string of length 32,
+ * This string will consist of only hex digits. Optionally,
+ * the string may be generated with separators between each
+ * component of the UUID.
+ *
+ * Mapping parameters supported: separator.
+ *
+ * @author Gavin King
+ */
+
+public class UUIDHexGenerator extends AbstractUUIDGenerator implements Configurable {
+
+	private String sep = "";
+
+	protected String format(int intval) {
+		String formatted = Integer.toHexString(intval);
+		StringBuffer buf = new StringBuffer("00000000");
+		buf.replace( 8-formatted.length(), 8, formatted );
+		return buf.toString();
+	}
+
+	protected String format(short shortval) {
+		String formatted = Integer.toHexString(shortval);
+		StringBuffer buf = new StringBuffer("0000");
+		buf.replace( 4-formatted.length(), 4, formatted );
+		return buf.toString();
+	}
+
+	public Serializable generate(SessionImplementor session, Object obj) {
+		return new StringBuffer(36)
+			.append( format( getIP() ) ).append(sep)
+			.append( format( getJVM() ) ).append(sep)
+			.append( format( getHiTime() ) ).append(sep)
+			.append( format( getLoTime() ) ).append(sep)
+			.append( format( getCount() ) )
+			.toString();
+	}
+
+	public void configure(Type type, Properties params, Dialect d) {
+		sep = PropertiesHelper.getString("separator", params, "");
+	}
+
+	public static void main( String[] args ) throws Exception {
+		Properties props = new Properties();
+		props.setProperty("separator", "/");
+		IdentifierGenerator gen = new UUIDHexGenerator();
+		( (Configurable) gen ).configure(Hibernate.STRING, props, null);
+		IdentifierGenerator gen2 = new UUIDHexGenerator();
+		( (Configurable) gen2 ).configure(Hibernate.STRING, props, null);
+
+		for ( int i=0; i<10; i++) {
+			String id = (String) gen.generate(null, null);
+			System.out.println(id);
+			String id2 = (String) gen2.generate(null, null);
+			System.out.println(id2);
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-package org.hibernate.id.enhanced;
-
-/**
- * Contract for providing callback access to a {@link DatabaseStructure},
- * typically from the {@link Optimizer}.
- *
- * @author Steve Ebersole
- */
-public interface AccessCallback {
-	/**
-	 * Retrieve the next value from the underlying source.
-	 *
-	 * @return The next value.
-	 */
-	public long getNextValue();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/AccessCallback.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.id.enhanced;
+
+/**
+ * Contract for providing callback access to a {@link DatabaseStructure},
+ * typically from the {@link Optimizer}.
+ *
+ * @author Steve Ebersole
+ */
+public interface AccessCallback {
+	/**
+	 * Retrieve the next value from the underlying source.
+	 *
+	 * @return The next value.
+	 */
+	public long getNextValue();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.dialect.Dialect;
-
-/**
- * Encapsulates definition of the underlying data structure backing a
- * sequence-style generator.
- *
- * @author Steve Ebersole
- */
-public interface DatabaseStructure {
-	/**
-	 * The name of the database structure (table or sequence).
-	 * @return The structure name.
-	 */
-	public String getName();
-
-	/**
-	 * How many times has this structure been accessed through this reference?
-	 * @return The number of accesses.
-	 */
-	public int getTimesAccessed();
-
-	/**
-	 * The configured increment size
-	 * @return The configured increment size
-	 */
-	public int getIncrementSize();
-
-	/**
-	 * A callback to be able to get the next value from the underlying
-	 * structure as needed.
-	 *
-	 * @param session The session.
-	 * @return The next value.
-	 */
-	public AccessCallback buildCallback(SessionImplementor session);
-
-	/**
-	 * Prepare this structure for use.  Called sometime after instantiation,
-	 * but before first use.
-	 *
-	 * @param optimizer The optimizer being applied to the generator.
-	 */
-	public void prepare(Optimizer optimizer);
-
-	/**
-	 * Commands needed to create the underlying structures.
-	 * @param dialect The database dialect being used.
-	 * @return The creation commands.
-	 */
-	public String[] sqlCreateStrings(Dialect dialect);
-
-	/**
-	 * Commands needed to drop the underlying structures.
-	 * @param dialect The database dialect being used.
-	 * @return The drop commands.
-	 */
-	public String[] sqlDropStrings(Dialect dialect);
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/DatabaseStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.id.enhanced;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Encapsulates definition of the underlying data structure backing a
+ * sequence-style generator.
+ *
+ * @author Steve Ebersole
+ */
+public interface DatabaseStructure {
+	/**
+	 * The name of the database structure (table or sequence).
+	 * @return The structure name.
+	 */
+	public String getName();
+
+	/**
+	 * How many times has this structure been accessed through this reference?
+	 * @return The number of accesses.
+	 */
+	public int getTimesAccessed();
+
+	/**
+	 * The configured increment size
+	 * @return The configured increment size
+	 */
+	public int getIncrementSize();
+
+	/**
+	 * A callback to be able to get the next value from the underlying
+	 * structure as needed.
+	 *
+	 * @param session The session.
+	 * @return The next value.
+	 */
+	public AccessCallback buildCallback(SessionImplementor session);
+
+	/**
+	 * Prepare this structure for use.  Called sometime after instantiation,
+	 * but before first use.
+	 *
+	 * @param optimizer The optimizer being applied to the generator.
+	 */
+	public void prepare(Optimizer optimizer);
+
+	/**
+	 * Commands needed to create the underlying structures.
+	 * @param dialect The database dialect being used.
+	 * @return The creation commands.
+	 */
+	public String[] sqlCreateStrings(Dialect dialect);
+
+	/**
+	 * Commands needed to drop the underlying structures.
+	 * @param dialect The database dialect being used.
+	 * @return The drop commands.
+	 */
+	public String[] sqlDropStrings(Dialect dialect);
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.io.Serializable;
-
-/**
- * Performs optimization on an optimizable identifier generator.  Typically
- * this optimization takes the form of trying to ensure we do not have to
- * hit the database on each and every request to get an identifier value.
- * <p/>
- * Optimizers work on constructor injection.  They should provide
- * a constructor with the following arguments <ol>
- * <li>java.lang.Class - The return type for the generated values</li>
- * <li>int - The increment size</li>
- * </ol>
- *
- * @author Steve Ebersole
- */
-public interface Optimizer {
-	/**
-	 * Generate an identifier value accounting for this specific optimization.
-	 *
-	 * @param callback Callback to access the underlying value source.
-	 * @return The generated identifier value.
-	 */
-	public Serializable generate(AccessCallback callback);
-
-	/**
-	 * A common means to access the last value obtained from the underlying
-	 * source.  This is intended for testing purposes, since accessing the
-	 * unerlying database source directly is much more difficult.
-	 *
-	 * @return The last value we obtained from the underlying source;
-	 * -1 indicates we have not yet consulted with the source.
-	 */
-	public long getLastSourceValue();
-
-	/**
-	 * Retrieves the defined increment size.
-	 *
-	 * @return The increment size.
-	 */
-	public int getIncrementSize();
-
-	/**
-	 * Are increments to be applied to the values stored in the underlying
-	 * value source?
-	 *
-	 * @return True if the values in the source are to be incremented
-	 * according to the defined increment size; false otherwise, in which
-	 * case the increment is totally an in memory construct.
-	 */
-	public boolean applyIncrementSizeToSourceValues();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/Optimizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id.enhanced;
+
+import java.io.Serializable;
+
+/**
+ * Performs optimization on an optimizable identifier generator.  Typically
+ * this optimization takes the form of trying to ensure we do not have to
+ * hit the database on each and every request to get an identifier value.
+ * <p/>
+ * Optimizers work on constructor injection.  They should provide
+ * a constructor with the following arguments <ol>
+ * <li>java.lang.Class - The return type for the generated values</li>
+ * <li>int - The increment size</li>
+ * </ol>
+ *
+ * @author Steve Ebersole
+ */
+public interface Optimizer {
+	/**
+	 * Generate an identifier value accounting for this specific optimization.
+	 *
+	 * @param callback Callback to access the underlying value source.
+	 * @return The generated identifier value.
+	 */
+	public Serializable generate(AccessCallback callback);
+
+	/**
+	 * A common means to access the last value obtained from the underlying
+	 * source.  This is intended for testing purposes, since accessing the
+	 * unerlying database source directly is much more difficult.
+	 *
+	 * @return The last value we obtained from the underlying source;
+	 * -1 indicates we have not yet consulted with the source.
+	 */
+	public long getLastSourceValue();
+
+	/**
+	 * Retrieves the defined increment size.
+	 *
+	 * @return The increment size.
+	 */
+	public int getIncrementSize();
+
+	/**
+	 * Are increments to be applied to the values stored in the underlying
+	 * value source?
+	 *
+	 * @return True if the values in the source are to be incremented
+	 * according to the defined increment size; false otherwise, in which
+	 * case the increment is totally an in memory construct.
+	 */
+	public boolean applyIncrementSizeToSourceValues();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,202 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.id.IdentifierGeneratorFactory;
-
-/**
- * Factory for {@link Optimizer} instances.
- *
- * @author Steve Ebersole
- */
-public class OptimizerFactory {
-	private static final Logger log = LoggerFactory.getLogger( OptimizerFactory.class );
-
-	public static final String NONE = "none";
-	public static final String HILO = "hilo";
-	public static final String POOL = "pooled";
-
-	private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
-
-	public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
-		String optimizerClassName;
-		if ( NONE.equals( type ) ) {
-			optimizerClassName = NoopOptimizer.class.getName();
-		}
-		else if ( HILO.equals( type ) ) {
-			optimizerClassName = HiLoOptimizer.class.getName();
-		}
-		else if ( POOL.equals( type ) ) {
-			optimizerClassName = PooledOptimizer.class.getName();
-		}
-		else {
-			optimizerClassName = type;
-		}
-
-		try {
-			Class optimizerClass = ReflectHelper.classForName( optimizerClassName );
-			Constructor ctor = optimizerClass.getConstructor( CTOR_SIG );
-			return ( Optimizer ) ctor.newInstance( new Object[] { returnClass, new Integer( incrementSize ) } );
-		}
-		catch( Throwable ignore ) {
-			// intentionally empty
-		}
-
-		// the default...
-		return new NoopOptimizer( returnClass, incrementSize );
-	}
-
-	public static abstract class OptimizerSupport implements Optimizer {
-		protected final Class returnClass;
-		protected final int incrementSize;
-
-		protected OptimizerSupport(Class returnClass, int incrementSize) {
-			if ( returnClass == null ) {
-				throw new HibernateException( "return class is required" );
-			}
-			this.returnClass = returnClass;
-			this.incrementSize = incrementSize;
-		}
-
-		protected Serializable make(long value) {
-			return IdentifierGeneratorFactory.createNumber( value, returnClass );
-		}
-
-		public Class getReturnClass() {
-			return returnClass;
-		}
-
-		public int getIncrementSize() {
-			return incrementSize;
-		}
-	}
-
-	public static class NoopOptimizer extends OptimizerSupport {
-		private long lastSourceValue = -1;
-
-		public NoopOptimizer(Class returnClass, int incrementSize) {
-			super( returnClass, incrementSize );
-		}
-
-		public Serializable generate(AccessCallback callback) {
-			if ( lastSourceValue == -1 ) {
-				while( lastSourceValue <= 0 ) {
-					lastSourceValue = callback.getNextValue();
-				}
-			}
-			else {
-				lastSourceValue = callback.getNextValue();
-			}
-			return make( lastSourceValue );
-		}
-
-		public long getLastSourceValue() {
-			return lastSourceValue;
-		}
-
-		public boolean applyIncrementSizeToSourceValues() {
-			return false;
-		}
-	}
-
-	public static class HiLoOptimizer extends OptimizerSupport {
-		private long lastSourceValue = -1;
-		private long value;
-		private long hiValue;
-
-		public HiLoOptimizer(Class returnClass, int incrementSize) {
-			super( returnClass, incrementSize );
-			if ( incrementSize < 1 ) {
-				throw new HibernateException( "increment size cannot be less than 1" );
-			}
-			if ( log.isTraceEnabled() ) {
-				log.trace( "creating hilo optimizer with [incrementSize=" + incrementSize + "; returnClass="  + returnClass.getName() + "]" );
-			}
-		}
-
-		public synchronized Serializable generate(AccessCallback callback) {
-			if ( lastSourceValue < 0 ) {
-				lastSourceValue = callback.getNextValue();
-				while ( lastSourceValue <= 0 ) {
-					lastSourceValue = callback.getNextValue();
-				}
-				hiValue = ( lastSourceValue * incrementSize ) + 1;
-				value = hiValue - incrementSize;
-			}
-			else if ( value >= hiValue ) {
-				lastSourceValue = callback.getNextValue();
-				hiValue = ( lastSourceValue * incrementSize ) + 1;
-			}
-			return make( value++ );
-		}
-
-
-		public long getLastSourceValue() {
-			return lastSourceValue;
-		}
-
-		public boolean applyIncrementSizeToSourceValues() {
-			return false;
-		}
-
-		public long getLastValue() {
-			return value - 1;
-		}
-
-		public long getHiValue() {
-			return hiValue;
-		}
-	}
-
-	public static class PooledOptimizer extends OptimizerSupport {
-		private long value;
-		private long hiValue = -1;
-
-		public PooledOptimizer(Class returnClass, int incrementSize) {
-			super( returnClass, incrementSize );
-			if ( incrementSize < 1 ) {
-				throw new HibernateException( "increment size cannot be less than 1" );
-			}
-			if ( log.isTraceEnabled() ) {
-				log.trace( "creating pooled optimizer with [incrementSize=" + incrementSize + "; returnClass="  + returnClass.getName() + "]" );
-			}
-		}
-
-		public synchronized Serializable generate(AccessCallback callback) {
-			if ( hiValue < 0 ) {
-				value = callback.getNextValue();
-				if ( value < 1 ) {
-					// unfortunately not really safe to normalize this
-					// to 1 as an initial value like we do the others
-					// because we would not be able to control this if
-					// we are using a sequence...
-					log.info( "pooled optimizer source reported [" + value + "] as the initial value; use of 1 or greater highly recommended" );
-				}
-				hiValue = callback.getNextValue();
-			}
-			else if ( value >= hiValue ) {
-				hiValue = callback.getNextValue();
-				value = hiValue - incrementSize;
-			}
-			return make( value++ );
-		}
-
-		public long getLastSourceValue() {
-			return hiValue;
-		}
-
-		public boolean applyIncrementSizeToSourceValues() {
-			return true;
-		}
-
-		public long getLastValue() {
-			return value - 1;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/OptimizerFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,226 @@
+/*
+ * 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.id.enhanced;
+
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.id.IdentifierGeneratorFactory;
+
+/**
+ * Factory for {@link Optimizer} instances.
+ *
+ * @author Steve Ebersole
+ */
+public class OptimizerFactory {
+	private static final Logger log = LoggerFactory.getLogger( OptimizerFactory.class );
+
+	public static final String NONE = "none";
+	public static final String HILO = "hilo";
+	public static final String POOL = "pooled";
+
+	private static Class[] CTOR_SIG = new Class[] { Class.class, int.class };
+
+	public static Optimizer buildOptimizer(String type, Class returnClass, int incrementSize) {
+		String optimizerClassName;
+		if ( NONE.equals( type ) ) {
+			optimizerClassName = NoopOptimizer.class.getName();
+		}
+		else if ( HILO.equals( type ) ) {
+			optimizerClassName = HiLoOptimizer.class.getName();
+		}
+		else if ( POOL.equals( type ) ) {
+			optimizerClassName = PooledOptimizer.class.getName();
+		}
+		else {
+			optimizerClassName = type;
+		}
+
+		try {
+			Class optimizerClass = ReflectHelper.classForName( optimizerClassName );
+			Constructor ctor = optimizerClass.getConstructor( CTOR_SIG );
+			return ( Optimizer ) ctor.newInstance( new Object[] { returnClass, new Integer( incrementSize ) } );
+		}
+		catch( Throwable ignore ) {
+			// intentionally empty
+		}
+
+		// the default...
+		return new NoopOptimizer( returnClass, incrementSize );
+	}
+
+	public static abstract class OptimizerSupport implements Optimizer {
+		protected final Class returnClass;
+		protected final int incrementSize;
+
+		protected OptimizerSupport(Class returnClass, int incrementSize) {
+			if ( returnClass == null ) {
+				throw new HibernateException( "return class is required" );
+			}
+			this.returnClass = returnClass;
+			this.incrementSize = incrementSize;
+		}
+
+		protected Serializable make(long value) {
+			return IdentifierGeneratorFactory.createNumber( value, returnClass );
+		}
+
+		public Class getReturnClass() {
+			return returnClass;
+		}
+
+		public int getIncrementSize() {
+			return incrementSize;
+		}
+	}
+
+	public static class NoopOptimizer extends OptimizerSupport {
+		private long lastSourceValue = -1;
+
+		public NoopOptimizer(Class returnClass, int incrementSize) {
+			super( returnClass, incrementSize );
+		}
+
+		public Serializable generate(AccessCallback callback) {
+			if ( lastSourceValue == -1 ) {
+				while( lastSourceValue <= 0 ) {
+					lastSourceValue = callback.getNextValue();
+				}
+			}
+			else {
+				lastSourceValue = callback.getNextValue();
+			}
+			return make( lastSourceValue );
+		}
+
+		public long getLastSourceValue() {
+			return lastSourceValue;
+		}
+
+		public boolean applyIncrementSizeToSourceValues() {
+			return false;
+		}
+	}
+
+	public static class HiLoOptimizer extends OptimizerSupport {
+		private long lastSourceValue = -1;
+		private long value;
+		private long hiValue;
+
+		public HiLoOptimizer(Class returnClass, int incrementSize) {
+			super( returnClass, incrementSize );
+			if ( incrementSize < 1 ) {
+				throw new HibernateException( "increment size cannot be less than 1" );
+			}
+			if ( log.isTraceEnabled() ) {
+				log.trace( "creating hilo optimizer with [incrementSize=" + incrementSize + "; returnClass="  + returnClass.getName() + "]" );
+			}
+		}
+
+		public synchronized Serializable generate(AccessCallback callback) {
+			if ( lastSourceValue < 0 ) {
+				lastSourceValue = callback.getNextValue();
+				while ( lastSourceValue <= 0 ) {
+					lastSourceValue = callback.getNextValue();
+				}
+				hiValue = ( lastSourceValue * incrementSize ) + 1;
+				value = hiValue - incrementSize;
+			}
+			else if ( value >= hiValue ) {
+				lastSourceValue = callback.getNextValue();
+				hiValue = ( lastSourceValue * incrementSize ) + 1;
+			}
+			return make( value++ );
+		}
+
+
+		public long getLastSourceValue() {
+			return lastSourceValue;
+		}
+
+		public boolean applyIncrementSizeToSourceValues() {
+			return false;
+		}
+
+		public long getLastValue() {
+			return value - 1;
+		}
+
+		public long getHiValue() {
+			return hiValue;
+		}
+	}
+
+	public static class PooledOptimizer extends OptimizerSupport {
+		private long value;
+		private long hiValue = -1;
+
+		public PooledOptimizer(Class returnClass, int incrementSize) {
+			super( returnClass, incrementSize );
+			if ( incrementSize < 1 ) {
+				throw new HibernateException( "increment size cannot be less than 1" );
+			}
+			if ( log.isTraceEnabled() ) {
+				log.trace( "creating pooled optimizer with [incrementSize=" + incrementSize + "; returnClass="  + returnClass.getName() + "]" );
+			}
+		}
+
+		public synchronized Serializable generate(AccessCallback callback) {
+			if ( hiValue < 0 ) {
+				value = callback.getNextValue();
+				if ( value < 1 ) {
+					// unfortunately not really safe to normalize this
+					// to 1 as an initial value like we do the others
+					// because we would not be able to control this if
+					// we are using a sequence...
+					log.info( "pooled optimizer source reported [" + value + "] as the initial value; use of 1 or greater highly recommended" );
+				}
+				hiValue = callback.getNextValue();
+			}
+			else if ( value >= hiValue ) {
+				hiValue = callback.getNextValue();
+				value = hiValue - incrementSize;
+			}
+			return make( value++ );
+		}
+
+		public long getLastSourceValue() {
+			return hiValue;
+		}
+
+		public boolean applyIncrementSizeToSourceValues() {
+			return true;
+		}
+
+		public long getLastValue() {
+			return value - 1;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,103 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.HibernateException;
-
-/**
- * Describes a sequence.
- *
- * @author Steve Ebersole
- */
-public class SequenceStructure implements DatabaseStructure {
-	private static final Logger log = LoggerFactory.getLogger( SequenceStructure.class );
-
-	private final String sequenceName;
-	private final int initialValue;
-	private final int incrementSize;
-	private final String sql;
-	private boolean applyIncrementSizeToSourceValues;
-	private int accessCounter;
-
-	public SequenceStructure(Dialect dialect, String sequenceName, int initialValue, int incrementSize) {
-		this.sequenceName = sequenceName;
-		this.initialValue = initialValue;
-		this.incrementSize = incrementSize;
-		sql = dialect.getSequenceNextValString( sequenceName );
-	}
-
-	public String getName() {
-		return sequenceName;
-	}
-
-	public int getIncrementSize() {
-		return incrementSize;
-	}
-
-	public int getTimesAccessed() {
-		return accessCounter;
-	}
-
-	public AccessCallback buildCallback(final SessionImplementor session) {
-		return new AccessCallback() {
-			public long getNextValue() {
-				accessCounter++;
-				try {
-					PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
-					try {
-						ResultSet rs = st.executeQuery();
-						try {
-							rs.next();
-							long result = rs.getLong( 1 );
-							if ( log.isDebugEnabled() ) {
-								log.debug("Sequence identifier generated: " + result);
-							}
-							return result;
-						}
-						finally {
-							try {
-								rs.close();
-							}
-							catch( Throwable ignore ) {
-								// intentionally empty
-							}
-						}
-					}
-					finally {
-						session.getBatcher().closeStatement( st );
-					}
-
-				}
-				catch ( SQLException sqle) {
-					throw JDBCExceptionHelper.convert(
-							session.getFactory().getSQLExceptionConverter(),
-							sqle,
-							"could not get next sequence value",
-							sql
-					);
-				}
-			}
-		};
-	}
-
-	public void prepare(Optimizer optimizer) {
-		applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
-	}
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		int sourceIncrementSize = applyIncrementSizeToSourceValues ? incrementSize : 1;
-		return dialect.getCreateSequenceStrings( sequenceName, initialValue, sourceIncrementSize );
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		return dialect.getDropSequenceStrings( sequenceName );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,127 @@
+/*
+ * 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.id.enhanced;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.HibernateException;
+
+/**
+ * Describes a sequence.
+ *
+ * @author Steve Ebersole
+ */
+public class SequenceStructure implements DatabaseStructure {
+	private static final Logger log = LoggerFactory.getLogger( SequenceStructure.class );
+
+	private final String sequenceName;
+	private final int initialValue;
+	private final int incrementSize;
+	private final String sql;
+	private boolean applyIncrementSizeToSourceValues;
+	private int accessCounter;
+
+	public SequenceStructure(Dialect dialect, String sequenceName, int initialValue, int incrementSize) {
+		this.sequenceName = sequenceName;
+		this.initialValue = initialValue;
+		this.incrementSize = incrementSize;
+		sql = dialect.getSequenceNextValString( sequenceName );
+	}
+
+	public String getName() {
+		return sequenceName;
+	}
+
+	public int getIncrementSize() {
+		return incrementSize;
+	}
+
+	public int getTimesAccessed() {
+		return accessCounter;
+	}
+
+	public AccessCallback buildCallback(final SessionImplementor session) {
+		return new AccessCallback() {
+			public long getNextValue() {
+				accessCounter++;
+				try {
+					PreparedStatement st = session.getBatcher().prepareSelectStatement( sql );
+					try {
+						ResultSet rs = st.executeQuery();
+						try {
+							rs.next();
+							long result = rs.getLong( 1 );
+							if ( log.isDebugEnabled() ) {
+								log.debug("Sequence identifier generated: " + result);
+							}
+							return result;
+						}
+						finally {
+							try {
+								rs.close();
+							}
+							catch( Throwable ignore ) {
+								// intentionally empty
+							}
+						}
+					}
+					finally {
+						session.getBatcher().closeStatement( st );
+					}
+
+				}
+				catch ( SQLException sqle) {
+					throw JDBCExceptionHelper.convert(
+							session.getFactory().getSQLExceptionConverter(),
+							sqle,
+							"could not get next sequence value",
+							sql
+					);
+				}
+			}
+		};
+	}
+
+	public void prepare(Optimizer optimizer) {
+		applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
+	}
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		int sourceIncrementSize = applyIncrementSizeToSourceValues ? incrementSize : 1;
+		return dialect.getCreateSequenceStrings( sequenceName, initialValue, sourceIncrementSize );
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		return dialect.getDropSequenceStrings( sequenceName );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,175 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.util.Properties;
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.id.Configurable;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.mapping.Table;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.type.Type;
-import org.hibernate.dialect.Dialect;
-
-/**
- * Generates identifier values based on an sequence-style database structure.
- * Variations range from actually using a sequence to using a table to mimic
- * a sequence.  These variations are encapsulated by the {@link DatabaseStructure}
- * interface internally.
- * <p/>
- * General configuration parameters:
- * <table>
- * 	 <tr>
- *     <td><b>NAME</b></td>
- *     <td><b>DEFAULT</b></td>
- *     <td><b>DESCRIPTION</b></td>
- *   </tr>
- *   <tr>
- *     <td>{@link #SEQUENCE_PARAM}</td>
- *     <td>{@link #DEF_SEQUENCE_NAME}</td>
- *     <td>The name of the sequence/table to use to store/retrieve values</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #INITIAL_PARAM}</td>
- *     <td>{@link #DEFAULT_INITIAL_VALUE}</td>
- *     <td>The initial value to be stored for the given segment; the effect in terms of storage varies based on {@link Optimizer} and {@link DatabaseStructure}</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #INCREMENT_PARAM}</td>
- *     <td>{@link #DEFAULT_INCREMENT_SIZE}</td>
- *     <td>The increment size for the underlying segment; the effect in terms of storage varies based on {@link Optimizer} and {@link DatabaseStructure}</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #OPT_PARAM}</td>
- *     <td><i>depends on defined increment size</i></td>
- *     <td>Allows explicit definition of which optimization strategy to use</td>
- *   </tr>
- *     <td>{@link #FORCE_TBL_PARAM}</td>
- *     <td><b><i>false<i/></b></td>
- *     <td>Allows explicit definition of which optimization strategy to use</td>
- *   </tr>
- * </table>
- * <p/>
- * Configuration parameters used specifically when the underlying structure is a table:
- * <table>
- * 	 <tr>
- *     <td><b>NAME</b></td>
- *     <td><b>DEFAULT</b></td>
- *     <td><b>DESCRIPTION</b></td>
- *   </tr>
- *   <tr>
- *     <td>{@link #VALUE_COLUMN_PARAM}</td>
- *     <td>{@link #DEF_VALUE_COLUMN}</td>
- *     <td>The name of column which holds the sequence value for the given segment</td>
- *   </tr>
- * </table>
- *
- * @author Steve Ebersole
- */
-public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Configurable {
-	private static final Logger log = LoggerFactory.getLogger( SequenceStyleGenerator.class );
-
-	// general purpose parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	public static final String SEQUENCE_PARAM = "sequence_name";
-	public static final String DEF_SEQUENCE_NAME = "hibernate_sequence";
-
-	public static final String INITIAL_PARAM = "initial_value";
-	public static final int DEFAULT_INITIAL_VALUE = 1;
-
-	public static final String INCREMENT_PARAM = "increment_size";
-	public static final int DEFAULT_INCREMENT_SIZE = 1;
-
-	public static final String OPT_PARAM = "optimizer";
-
-	public static final String FORCE_TBL_PARAM = "force_table_use";
-
-
-	// table-specific parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	public static final String VALUE_COLUMN_PARAM = "value_column";
-	public static final String DEF_VALUE_COLUMN = "next_val";
-
-
-	// state ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	private DatabaseStructure databaseStructure;
-	private Optimizer optimizer;
-	private Type identifierType;
-
-	public DatabaseStructure getDatabaseStructure() {
-		return databaseStructure;
-	}
-
-	public Optimizer getOptimizer() {
-		return optimizer;
-	}
-
-	public Type getIdentifierType() {
-		return identifierType;
-	}
-
-
-	// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
-		identifierType = type;
-		boolean forceTableUse = PropertiesHelper.getBoolean( FORCE_TBL_PARAM, params, false );
-
-		String sequenceName = PropertiesHelper.getString( SEQUENCE_PARAM, params, DEF_SEQUENCE_NAME );
-		if ( sequenceName.indexOf( '.' ) < 0 ) {
-			String schemaName = params.getProperty( SCHEMA );
-			String catalogName = params.getProperty( CATALOG );
-			sequenceName = Table.qualify( catalogName, schemaName, sequenceName );
-		}
-		int initialValue = PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
-		int incrementSize = PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
-
-		String valueColumnName = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
-
-		String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
-		String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
-		if ( OptimizerFactory.NONE.equals( optimizationStrategy ) && incrementSize > 1 ) {
-			log.warn( "config specified explicit optimizer of [" + OptimizerFactory.NONE + "], but [" + INCREMENT_PARAM + "=" + incrementSize + "; honoring optimizer setting" );
-			incrementSize = 1;
-		}
-		if ( dialect.supportsSequences() && !forceTableUse ) {
-			if ( OptimizerFactory.POOL.equals( optimizationStrategy ) && !dialect.supportsPooledSequences() ) {
-				// TODO : may even be better to fall back to a pooled table strategy here so that the db stored values remain consistent... 
-				optimizationStrategy = OptimizerFactory.HILO;
-			}
-			databaseStructure = new SequenceStructure( dialect, sequenceName, initialValue, incrementSize );
-		}
-		else {
-			databaseStructure = new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize );
-		}
-
-		optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
-		databaseStructure.prepare( optimizer );
-	}
-
-
-	// IdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
-		return optimizer.generate( databaseStructure.buildCallback( session ) );
-	}
-
-
-	// PersistentIdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Object generatorKey() {
-		return databaseStructure.getName();
-	}
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		return databaseStructure.sqlCreateStrings( dialect );
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		return databaseStructure.sqlDropStrings( dialect );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/SequenceStyleGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,199 @@
+/*
+ * 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.id.enhanced;
+
+import java.util.Properties;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.Configurable;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.mapping.Table;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.type.Type;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Generates identifier values based on an sequence-style database structure.
+ * Variations range from actually using a sequence to using a table to mimic
+ * a sequence.  These variations are encapsulated by the {@link DatabaseStructure}
+ * interface internally.
+ * <p/>
+ * General configuration parameters:
+ * <table>
+ * 	 <tr>
+ *     <td><b>NAME</b></td>
+ *     <td><b>DEFAULT</b></td>
+ *     <td><b>DESCRIPTION</b></td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #SEQUENCE_PARAM}</td>
+ *     <td>{@link #DEF_SEQUENCE_NAME}</td>
+ *     <td>The name of the sequence/table to use to store/retrieve values</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #INITIAL_PARAM}</td>
+ *     <td>{@link #DEFAULT_INITIAL_VALUE}</td>
+ *     <td>The initial value to be stored for the given segment; the effect in terms of storage varies based on {@link Optimizer} and {@link DatabaseStructure}</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #INCREMENT_PARAM}</td>
+ *     <td>{@link #DEFAULT_INCREMENT_SIZE}</td>
+ *     <td>The increment size for the underlying segment; the effect in terms of storage varies based on {@link Optimizer} and {@link DatabaseStructure}</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #OPT_PARAM}</td>
+ *     <td><i>depends on defined increment size</i></td>
+ *     <td>Allows explicit definition of which optimization strategy to use</td>
+ *   </tr>
+ *     <td>{@link #FORCE_TBL_PARAM}</td>
+ *     <td><b><i>false<i/></b></td>
+ *     <td>Allows explicit definition of which optimization strategy to use</td>
+ *   </tr>
+ * </table>
+ * <p/>
+ * Configuration parameters used specifically when the underlying structure is a table:
+ * <table>
+ * 	 <tr>
+ *     <td><b>NAME</b></td>
+ *     <td><b>DEFAULT</b></td>
+ *     <td><b>DESCRIPTION</b></td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #VALUE_COLUMN_PARAM}</td>
+ *     <td>{@link #DEF_VALUE_COLUMN}</td>
+ *     <td>The name of column which holds the sequence value for the given segment</td>
+ *   </tr>
+ * </table>
+ *
+ * @author Steve Ebersole
+ */
+public class SequenceStyleGenerator implements PersistentIdentifierGenerator, Configurable {
+	private static final Logger log = LoggerFactory.getLogger( SequenceStyleGenerator.class );
+
+	// general purpose parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	public static final String SEQUENCE_PARAM = "sequence_name";
+	public static final String DEF_SEQUENCE_NAME = "hibernate_sequence";
+
+	public static final String INITIAL_PARAM = "initial_value";
+	public static final int DEFAULT_INITIAL_VALUE = 1;
+
+	public static final String INCREMENT_PARAM = "increment_size";
+	public static final int DEFAULT_INCREMENT_SIZE = 1;
+
+	public static final String OPT_PARAM = "optimizer";
+
+	public static final String FORCE_TBL_PARAM = "force_table_use";
+
+
+	// table-specific parameters ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	public static final String VALUE_COLUMN_PARAM = "value_column";
+	public static final String DEF_VALUE_COLUMN = "next_val";
+
+
+	// state ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private DatabaseStructure databaseStructure;
+	private Optimizer optimizer;
+	private Type identifierType;
+
+	public DatabaseStructure getDatabaseStructure() {
+		return databaseStructure;
+	}
+
+	public Optimizer getOptimizer() {
+		return optimizer;
+	}
+
+	public Type getIdentifierType() {
+		return identifierType;
+	}
+
+
+	// Configurable implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
+		identifierType = type;
+		boolean forceTableUse = PropertiesHelper.getBoolean( FORCE_TBL_PARAM, params, false );
+
+		String sequenceName = PropertiesHelper.getString( SEQUENCE_PARAM, params, DEF_SEQUENCE_NAME );
+		if ( sequenceName.indexOf( '.' ) < 0 ) {
+			String schemaName = params.getProperty( SCHEMA );
+			String catalogName = params.getProperty( CATALOG );
+			sequenceName = Table.qualify( catalogName, schemaName, sequenceName );
+		}
+		int initialValue = PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
+		int incrementSize = PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
+
+		String valueColumnName = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
+
+		String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
+		String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+		if ( OptimizerFactory.NONE.equals( optimizationStrategy ) && incrementSize > 1 ) {
+			log.warn( "config specified explicit optimizer of [" + OptimizerFactory.NONE + "], but [" + INCREMENT_PARAM + "=" + incrementSize + "; honoring optimizer setting" );
+			incrementSize = 1;
+		}
+		if ( dialect.supportsSequences() && !forceTableUse ) {
+			if ( OptimizerFactory.POOL.equals( optimizationStrategy ) && !dialect.supportsPooledSequences() ) {
+				// TODO : may even be better to fall back to a pooled table strategy here so that the db stored values remain consistent... 
+				optimizationStrategy = OptimizerFactory.HILO;
+			}
+			databaseStructure = new SequenceStructure( dialect, sequenceName, initialValue, incrementSize );
+		}
+		else {
+			databaseStructure = new TableStructure( dialect, sequenceName, valueColumnName, initialValue, incrementSize );
+		}
+
+		optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+		databaseStructure.prepare( optimizer );
+	}
+
+
+	// IdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Serializable generate(SessionImplementor session, Object object) throws HibernateException {
+		return optimizer.generate( databaseStructure.buildCallback( session ) );
+	}
+
+
+	// PersistentIdentifierGenerator implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Object generatorKey() {
+		return databaseStructure.getName();
+	}
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		return databaseStructure.sqlCreateStrings( dialect );
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		return databaseStructure.sqlDropStrings( dialect );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,322 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.sql.Types;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.util.Properties;
-import java.util.HashMap;
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.id.Configurable;
-import org.hibernate.type.Type;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.LockMode;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.mapping.Table;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.StringHelper;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * An enhanced version of explicit table-based generator.  The main basis
- * conceptualization is similiar to the legacy
- * {@link org.hibernate.id.MultipleHiLoPerTableGenerator} in terms of the
- * underlying storage structure (namely a single table capable of holding
- * multiple generator values).  The differentiator is, as with
- * {@link SequenceStyleGenerator} as well, the externalization of the notion
- * of an optimizer.
- * <p/>
- * Configuration parameters:
- * <table>
- * 	 <tr>
- *     <td><b>NAME</b></td>
- *     <td><b>DEFAULT</b></td>
- *     <td><b>DESCRIPTION</b></td>
- *   </tr>
- *   <tr>
- *     <td>{@link #TABLE_PARAM}</td>
- *     <td>{@link #DEF_TABLE}</td>
- *     <td>The name of the table to use to store/retrieve values</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #VALUE_COLUMN_PARAM}</td>
- *     <td>{@link #DEF_VALUE_COLUMN}</td>
- *     <td>The name of column which holds the sequence value for the given segment</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #SEGMENT_COLUMN_PARAM}</td>
- *     <td>{@link #DEF_SEGMENT_COLUMN}</td>
- *     <td>The name of the column which holds the segment key</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #SEGMENT_VALUE_PARAM}</td>
- *     <td>{@link #DEF_SEGMENT_VALUE}</td>
- *     <td>The value indicating which segment is used by this generator; refers to values in the {@link #SEGMENT_COLUMN_PARAM} column</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #SEGMENT_LENGTH_PARAM}</td>
- *     <td>{@link #DEF_SEGMENT_LENGTH}</td>
- *     <td>The data length of the {@link #SEGMENT_COLUMN_PARAM} column; used for schema creation</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #INITIAL_PARAM}</td>
- *     <td>{@link #DEFAULT_INITIAL_VALUE}</td>
- *     <td>The initial value to be stored for the given segment</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #INCREMENT_PARAM}</td>
- *     <td>{@link #DEFAULT_INCREMENT_SIZE}</td>
- *     <td>The increment size for the underlying segment; see the discussion on {@link Optimizer} for more details.</td>
- *   </tr>
- *   <tr>
- *     <td>{@link #OPT_PARAM}</td>
- *     <td><i>depends on defined increment size</i></td>
- *     <td>Allows explicit definition of which optimization strategy to use</td>
- *   </tr>
- * </table>
- *
- * @author Steve Ebersole
- */
-public class TableGenerator extends TransactionHelper implements PersistentIdentifierGenerator, Configurable {
-	private static final Logger log = LoggerFactory.getLogger( TableGenerator.class );
-
-	public static final String TABLE_PARAM = "table_name";
-	public static final String DEF_TABLE = "hibernate_sequences";
-
-	public static final String VALUE_COLUMN_PARAM = "value_column_name";
-	public static final String DEF_VALUE_COLUMN = "next_val";
-
-	public static final String SEGMENT_COLUMN_PARAM = "segment_column_name";
-	public static final String DEF_SEGMENT_COLUMN = "sequence_name";
-
-	public static final String SEGMENT_VALUE_PARAM = "segment_value";
-	public static final String DEF_SEGMENT_VALUE = "default";
-
-	public static final String SEGMENT_LENGTH_PARAM = "segment_value_length";
-	public static final int DEF_SEGMENT_LENGTH = 255;
-
-	public static final String INITIAL_PARAM = "initial_value";
-	public static final int DEFAULT_INITIAL_VALUE = 1;
-
-	public static final String INCREMENT_PARAM = "increment_size";
-	public static final int DEFAULT_INCREMENT_SIZE = 1;
-
-	public static final String OPT_PARAM = "optimizer";
-
-
-	private String tableName;
-	private String valueColumnName;
-	private String segmentColumnName;
-	private String segmentValue;
-	private int segmentValueLength;
-	private int initialValue;
-	private int incrementSize;
-
-	private Type identifierType;
-
-	private String query;
-	private String insert;
-	private String update;
-
-	private Optimizer optimizer;
-	private long accessCount = 0;
-
-	public String getTableName() {
-		return tableName;
-	}
-
-	public String getSegmentColumnName() {
-		return segmentColumnName;
-	}
-
-	public String getSegmentValue() {
-		return segmentValue;
-	}
-
-	public int getSegmentValueLength() {
-		return segmentValueLength;
-	}
-
-	public String getValueColumnName() {
-		return valueColumnName;
-	}
-
-	public Type getIdentifierType() {
-		return identifierType;
-	}
-
-	public int getInitialValue() {
-		return initialValue;
-	}
-
-	public int getIncrementSize() {
-		return incrementSize;
-	}
-
-	public Optimizer getOptimizer() {
-		return optimizer;
-	}
-
-	public long getTableAccessCount() {
-		return accessCount;
-	}
-
-	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
-		tableName = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE );
-		if ( tableName.indexOf( '.' ) < 0 ) {
-			String schemaName = params.getProperty( SCHEMA );
-			String catalogName = params.getProperty( CATALOG );
-			tableName = Table.qualify( catalogName, schemaName, tableName );
-		}
-
-		segmentColumnName = PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN );
-		segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
-		if ( StringHelper.isEmpty( segmentValue ) ) {
-			log.debug( "explicit segment value for id generator [" + tableName + '.' + segmentColumnName + "] suggested; using default [" + DEF_SEGMENT_VALUE + "]" );
-			segmentValue = DEF_SEGMENT_VALUE;
-		}
-		segmentValueLength = PropertiesHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH );
-		valueColumnName = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
-		initialValue = PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
-		incrementSize = PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
-		identifierType = type;
-
-		String query = "select " + valueColumnName +
-				" from " + tableName + " tbl" +
-				" where tbl." + segmentColumnName + "=?";
-		HashMap lockMap = new HashMap();
-		lockMap.put( "tbl", LockMode.UPGRADE );
-		this.query = dialect.applyLocksToSql( query, lockMap, CollectionHelper.EMPTY_MAP );
-
-		update = "update " + tableName +
-				" set " + valueColumnName + "=? " +
-				" where " + valueColumnName + "=? and " + segmentColumnName + "=?";
-
-		insert = "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";
-
-		String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
-		String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
-		optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
-	}
-
-	public synchronized Serializable generate(final SessionImplementor session, Object obj) {
-		return optimizer.generate(
-				new AccessCallback() {
-					public long getNextValue() {
-						return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
-					}
-				}
-		);
-	}
-
-	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
-		int result;
-		int rows;
-		do {
-			sql = query;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement queryPS = conn.prepareStatement( query );
-			try {
-				queryPS.setString( 1, segmentValue );
-				ResultSet queryRS = queryPS.executeQuery();
-				if ( !queryRS.next() ) {
-					PreparedStatement insertPS = null;
-					try {
-						result = initialValue;
-						sql = insert;
-						SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-						insertPS = conn.prepareStatement( insert );
-						insertPS.setString( 1, segmentValue );
-						insertPS.setLong( 2, result );
-						insertPS.execute();
-					}
-					finally {
-						if ( insertPS != null ) {
-							insertPS.close();
-						}
-					}
-				}
-				else {
-					result = queryRS.getInt( 1 );
-				}
-				queryRS.close();
-			}
-			catch ( SQLException sqle ) {
-				log.error( "could not read or init a hi value", sqle );
-				throw sqle;
-			}
-			finally {
-				queryPS.close();
-			}
-
-			sql = update;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement updatePS = conn.prepareStatement( update );
-			try {
-				long newValue = optimizer.applyIncrementSizeToSourceValues()
-						? result + incrementSize : result + 1;
-				updatePS.setLong( 1, newValue );
-				updatePS.setLong( 2, result );
-				updatePS.setString( 3, segmentValue );
-				rows = updatePS.executeUpdate();
-			}
-			catch ( SQLException sqle ) {
-				log.error( "could not update hi value in: " + tableName, sqle );
-				throw sqle;
-			}
-			finally {
-				updatePS.close();
-			}
-		}
-		while ( rows == 0 );
-
-		accessCount++;
-
-		return new Integer( result );
-	}
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		return new String[] {
-				new StringBuffer()
-						.append( dialect.getCreateTableString() )
-						.append( ' ' )
-						.append( tableName )
-						.append( " ( " )
-						.append( segmentColumnName )
-						.append( ' ' )
-						.append( dialect.getTypeName( Types.VARCHAR, segmentValueLength, 0, 0 ) )
-						.append( ",  " )
-						.append( valueColumnName )
-						.append( ' ' )
-						.append( dialect.getTypeName( Types.BIGINT ) )
-						.append( " ) " )
-						.toString()
-		};
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
-		if ( dialect.supportsIfExistsBeforeTableName() ) {
-			sqlDropString.append( "if exists " );
-		}
-		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
-		if ( dialect.supportsIfExistsAfterTableName() ) {
-			sqlDropString.append( " if exists" );
-		}
-		return new String[] { sqlDropString.toString() };
-	}
-
-	public Object generatorKey() {
-		return tableName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableGenerator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,346 @@
+/*
+ * 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.id.enhanced;
+
+import java.sql.Types;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Properties;
+import java.util.HashMap;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.engine.TransactionHelper;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.id.Configurable;
+import org.hibernate.type.Type;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.LockMode;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.mapping.Table;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.StringHelper;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * An enhanced version of explicit table-based generator.  The main basis
+ * conceptualization is similiar to the legacy
+ * {@link org.hibernate.id.MultipleHiLoPerTableGenerator} in terms of the
+ * underlying storage structure (namely a single table capable of holding
+ * multiple generator values).  The differentiator is, as with
+ * {@link SequenceStyleGenerator} as well, the externalization of the notion
+ * of an optimizer.
+ * <p/>
+ * Configuration parameters:
+ * <table>
+ * 	 <tr>
+ *     <td><b>NAME</b></td>
+ *     <td><b>DEFAULT</b></td>
+ *     <td><b>DESCRIPTION</b></td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #TABLE_PARAM}</td>
+ *     <td>{@link #DEF_TABLE}</td>
+ *     <td>The name of the table to use to store/retrieve values</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #VALUE_COLUMN_PARAM}</td>
+ *     <td>{@link #DEF_VALUE_COLUMN}</td>
+ *     <td>The name of column which holds the sequence value for the given segment</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #SEGMENT_COLUMN_PARAM}</td>
+ *     <td>{@link #DEF_SEGMENT_COLUMN}</td>
+ *     <td>The name of the column which holds the segment key</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #SEGMENT_VALUE_PARAM}</td>
+ *     <td>{@link #DEF_SEGMENT_VALUE}</td>
+ *     <td>The value indicating which segment is used by this generator; refers to values in the {@link #SEGMENT_COLUMN_PARAM} column</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #SEGMENT_LENGTH_PARAM}</td>
+ *     <td>{@link #DEF_SEGMENT_LENGTH}</td>
+ *     <td>The data length of the {@link #SEGMENT_COLUMN_PARAM} column; used for schema creation</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #INITIAL_PARAM}</td>
+ *     <td>{@link #DEFAULT_INITIAL_VALUE}</td>
+ *     <td>The initial value to be stored for the given segment</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #INCREMENT_PARAM}</td>
+ *     <td>{@link #DEFAULT_INCREMENT_SIZE}</td>
+ *     <td>The increment size for the underlying segment; see the discussion on {@link Optimizer} for more details.</td>
+ *   </tr>
+ *   <tr>
+ *     <td>{@link #OPT_PARAM}</td>
+ *     <td><i>depends on defined increment size</i></td>
+ *     <td>Allows explicit definition of which optimization strategy to use</td>
+ *   </tr>
+ * </table>
+ *
+ * @author Steve Ebersole
+ */
+public class TableGenerator extends TransactionHelper implements PersistentIdentifierGenerator, Configurable {
+	private static final Logger log = LoggerFactory.getLogger( TableGenerator.class );
+
+	public static final String TABLE_PARAM = "table_name";
+	public static final String DEF_TABLE = "hibernate_sequences";
+
+	public static final String VALUE_COLUMN_PARAM = "value_column_name";
+	public static final String DEF_VALUE_COLUMN = "next_val";
+
+	public static final String SEGMENT_COLUMN_PARAM = "segment_column_name";
+	public static final String DEF_SEGMENT_COLUMN = "sequence_name";
+
+	public static final String SEGMENT_VALUE_PARAM = "segment_value";
+	public static final String DEF_SEGMENT_VALUE = "default";
+
+	public static final String SEGMENT_LENGTH_PARAM = "segment_value_length";
+	public static final int DEF_SEGMENT_LENGTH = 255;
+
+	public static final String INITIAL_PARAM = "initial_value";
+	public static final int DEFAULT_INITIAL_VALUE = 1;
+
+	public static final String INCREMENT_PARAM = "increment_size";
+	public static final int DEFAULT_INCREMENT_SIZE = 1;
+
+	public static final String OPT_PARAM = "optimizer";
+
+
+	private String tableName;
+	private String valueColumnName;
+	private String segmentColumnName;
+	private String segmentValue;
+	private int segmentValueLength;
+	private int initialValue;
+	private int incrementSize;
+
+	private Type identifierType;
+
+	private String query;
+	private String insert;
+	private String update;
+
+	private Optimizer optimizer;
+	private long accessCount = 0;
+
+	public String getTableName() {
+		return tableName;
+	}
+
+	public String getSegmentColumnName() {
+		return segmentColumnName;
+	}
+
+	public String getSegmentValue() {
+		return segmentValue;
+	}
+
+	public int getSegmentValueLength() {
+		return segmentValueLength;
+	}
+
+	public String getValueColumnName() {
+		return valueColumnName;
+	}
+
+	public Type getIdentifierType() {
+		return identifierType;
+	}
+
+	public int getInitialValue() {
+		return initialValue;
+	}
+
+	public int getIncrementSize() {
+		return incrementSize;
+	}
+
+	public Optimizer getOptimizer() {
+		return optimizer;
+	}
+
+	public long getTableAccessCount() {
+		return accessCount;
+	}
+
+	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
+		tableName = PropertiesHelper.getString( TABLE_PARAM, params, DEF_TABLE );
+		if ( tableName.indexOf( '.' ) < 0 ) {
+			String schemaName = params.getProperty( SCHEMA );
+			String catalogName = params.getProperty( CATALOG );
+			tableName = Table.qualify( catalogName, schemaName, tableName );
+		}
+
+		segmentColumnName = PropertiesHelper.getString( SEGMENT_COLUMN_PARAM, params, DEF_SEGMENT_COLUMN );
+		segmentValue = params.getProperty( SEGMENT_VALUE_PARAM );
+		if ( StringHelper.isEmpty( segmentValue ) ) {
+			log.debug( "explicit segment value for id generator [" + tableName + '.' + segmentColumnName + "] suggested; using default [" + DEF_SEGMENT_VALUE + "]" );
+			segmentValue = DEF_SEGMENT_VALUE;
+		}
+		segmentValueLength = PropertiesHelper.getInt( SEGMENT_LENGTH_PARAM, params, DEF_SEGMENT_LENGTH );
+		valueColumnName = PropertiesHelper.getString( VALUE_COLUMN_PARAM, params, DEF_VALUE_COLUMN );
+		initialValue = PropertiesHelper.getInt( INITIAL_PARAM, params, DEFAULT_INITIAL_VALUE );
+		incrementSize = PropertiesHelper.getInt( INCREMENT_PARAM, params, DEFAULT_INCREMENT_SIZE );
+		identifierType = type;
+
+		String query = "select " + valueColumnName +
+				" from " + tableName + " tbl" +
+				" where tbl." + segmentColumnName + "=?";
+		HashMap lockMap = new HashMap();
+		lockMap.put( "tbl", LockMode.UPGRADE );
+		this.query = dialect.applyLocksToSql( query, lockMap, CollectionHelper.EMPTY_MAP );
+
+		update = "update " + tableName +
+				" set " + valueColumnName + "=? " +
+				" where " + valueColumnName + "=? and " + segmentColumnName + "=?";
+
+		insert = "insert into " + tableName + " (" + segmentColumnName + ", " + valueColumnName + ") " + " values (?,?)";
+
+		String defOptStrategy = incrementSize <= 1 ? OptimizerFactory.NONE : OptimizerFactory.POOL;
+		String optimizationStrategy = PropertiesHelper.getString( OPT_PARAM, params, defOptStrategy );
+		optimizer = OptimizerFactory.buildOptimizer( optimizationStrategy, identifierType.getReturnedClass(), incrementSize );
+	}
+
+	public synchronized Serializable generate(final SessionImplementor session, Object obj) {
+		return optimizer.generate(
+				new AccessCallback() {
+					public long getNextValue() {
+						return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
+					}
+				}
+		);
+	}
+
+	public Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
+		int result;
+		int rows;
+		do {
+			sql = query;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement queryPS = conn.prepareStatement( query );
+			try {
+				queryPS.setString( 1, segmentValue );
+				ResultSet queryRS = queryPS.executeQuery();
+				if ( !queryRS.next() ) {
+					PreparedStatement insertPS = null;
+					try {
+						result = initialValue;
+						sql = insert;
+						SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+						insertPS = conn.prepareStatement( insert );
+						insertPS.setString( 1, segmentValue );
+						insertPS.setLong( 2, result );
+						insertPS.execute();
+					}
+					finally {
+						if ( insertPS != null ) {
+							insertPS.close();
+						}
+					}
+				}
+				else {
+					result = queryRS.getInt( 1 );
+				}
+				queryRS.close();
+			}
+			catch ( SQLException sqle ) {
+				log.error( "could not read or init a hi value", sqle );
+				throw sqle;
+			}
+			finally {
+				queryPS.close();
+			}
+
+			sql = update;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement updatePS = conn.prepareStatement( update );
+			try {
+				long newValue = optimizer.applyIncrementSizeToSourceValues()
+						? result + incrementSize : result + 1;
+				updatePS.setLong( 1, newValue );
+				updatePS.setLong( 2, result );
+				updatePS.setString( 3, segmentValue );
+				rows = updatePS.executeUpdate();
+			}
+			catch ( SQLException sqle ) {
+				log.error( "could not update hi value in: " + tableName, sqle );
+				throw sqle;
+			}
+			finally {
+				updatePS.close();
+			}
+		}
+		while ( rows == 0 );
+
+		accessCount++;
+
+		return new Integer( result );
+	}
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		return new String[] {
+				new StringBuffer()
+						.append( dialect.getCreateTableString() )
+						.append( ' ' )
+						.append( tableName )
+						.append( " ( " )
+						.append( segmentColumnName )
+						.append( ' ' )
+						.append( dialect.getTypeName( Types.VARCHAR, segmentValueLength, 0, 0 ) )
+						.append( ",  " )
+						.append( valueColumnName )
+						.append( ' ' )
+						.append( dialect.getTypeName( Types.BIGINT ) )
+						.append( " ) " )
+						.toString()
+		};
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
+		if ( dialect.supportsIfExistsBeforeTableName() ) {
+			sqlDropString.append( "if exists " );
+		}
+		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
+		if ( dialect.supportsIfExistsAfterTableName() ) {
+			sqlDropString.append( " if exists" );
+		}
+		return new String[] { sqlDropString.toString() };
+	}
+
+	public Object generatorKey() {
+		return tableName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,146 +0,0 @@
-package org.hibernate.id.enhanced;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TransactionHelper;
-import org.hibernate.id.IdentifierGenerationException;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-
-/**
- * Describes a table used to mimic sequence behavior
- *
- * @author Steve Ebersole
- */
-public class TableStructure extends TransactionHelper implements DatabaseStructure {
-	private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
-	private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
-
-	private final String tableName;
-	private final String valueColumnName;
-	private final int initialValue;
-	private final int incrementSize;
-	private final String select;
-	private final String update;
-	private boolean applyIncrementSizeToSourceValues;
-	private int accessCounter;
-
-	public TableStructure(Dialect dialect, String tableName, String valueColumnName, int initialValue, int incrementSize) {
-		this.tableName = tableName;
-		this.initialValue = initialValue;
-		this.incrementSize = incrementSize;
-		this.valueColumnName = valueColumnName;
-
-		select = "select " + valueColumnName + " id_val" +
-				" from " + dialect.appendLockHint( LockMode.UPGRADE, tableName ) +
-				dialect.getForUpdateString();
-
-		update = "update " + tableName +
-				" set " + valueColumnName + "= ?" +
-				" where " + valueColumnName + "=?";
-	}
-
-	public String getName() {
-		return tableName;
-	}
-
-	public int getIncrementSize() {
-		return incrementSize;
-	}
-
-	public int getTimesAccessed() {
-		return accessCounter;
-	}
-
-	public void prepare(Optimizer optimizer) {
-		applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
-	}
-
-	public AccessCallback buildCallback(final SessionImplementor session) {
-		return new AccessCallback() {
-			public long getNextValue() {
-				return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
-			}
-		};
-	}
-
-	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
-		return new String[] {
-				dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )",
-				"insert into " + tableName + " values ( " + initialValue + " )"
-		};
-	}
-
-	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
-		StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
-		if ( dialect.supportsIfExistsBeforeTableName() ) {
-			sqlDropString.append( "if exists " );
-		}
-		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
-		if ( dialect.supportsIfExistsAfterTableName() ) {
-			sqlDropString.append( " if exists" );
-		}
-		return new String[] { sqlDropString.toString() };
-	}
-
-	protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
-		long result;
-		int rows;
-		do {
-			sql = select;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement qps = conn.prepareStatement( select );
-			try {
-				ResultSet rs = qps.executeQuery();
-				if ( !rs.next() ) {
-					String err = "could not read a hi value - you need to populate the table: " + tableName;
-					log.error( err );
-					throw new IdentifierGenerationException( err );
-				}
-				result = rs.getLong( 1 );
-				rs.close();
-			}
-			catch ( SQLException sqle ) {
-				log.error( "could not read a hi value", sqle );
-				throw sqle;
-			}
-			finally {
-				qps.close();
-			}
-
-			sql = update;
-			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
-			PreparedStatement ups = conn.prepareStatement( update );
-			try {
-				int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
-				ups.setLong( 1, result + increment );
-				ups.setLong( 2, result );
-				rows = ups.executeUpdate();
-			}
-			catch ( SQLException sqle ) {
-				log.error( "could not update hi value in: " + tableName, sqle );
-				throw sqle;
-			}
-			finally {
-				ups.close();
-			}
-		} while ( rows == 0 );
-
-		accessCounter++;
-
-		return new Long( result );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/enhanced/TableStructure.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,170 @@
+/*
+ * 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.id.enhanced;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TransactionHelper;
+import org.hibernate.id.IdentifierGenerationException;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+
+/**
+ * Describes a table used to mimic sequence behavior
+ *
+ * @author Steve Ebersole
+ */
+public class TableStructure extends TransactionHelper implements DatabaseStructure {
+	private static final Logger log = LoggerFactory.getLogger( TableStructure.class );
+	private static final SQLStatementLogger SQL_STATEMENT_LOGGER = new SQLStatementLogger( false, false );
+
+	private final String tableName;
+	private final String valueColumnName;
+	private final int initialValue;
+	private final int incrementSize;
+	private final String select;
+	private final String update;
+	private boolean applyIncrementSizeToSourceValues;
+	private int accessCounter;
+
+	public TableStructure(Dialect dialect, String tableName, String valueColumnName, int initialValue, int incrementSize) {
+		this.tableName = tableName;
+		this.initialValue = initialValue;
+		this.incrementSize = incrementSize;
+		this.valueColumnName = valueColumnName;
+
+		select = "select " + valueColumnName + " id_val" +
+				" from " + dialect.appendLockHint( LockMode.UPGRADE, tableName ) +
+				dialect.getForUpdateString();
+
+		update = "update " + tableName +
+				" set " + valueColumnName + "= ?" +
+				" where " + valueColumnName + "=?";
+	}
+
+	public String getName() {
+		return tableName;
+	}
+
+	public int getIncrementSize() {
+		return incrementSize;
+	}
+
+	public int getTimesAccessed() {
+		return accessCounter;
+	}
+
+	public void prepare(Optimizer optimizer) {
+		applyIncrementSizeToSourceValues = optimizer.applyIncrementSizeToSourceValues();
+	}
+
+	public AccessCallback buildCallback(final SessionImplementor session) {
+		return new AccessCallback() {
+			public long getNextValue() {
+				return ( ( Number ) doWorkInNewTransaction( session ) ).longValue();
+			}
+		};
+	}
+
+	public String[] sqlCreateStrings(Dialect dialect) throws HibernateException {
+		return new String[] {
+				dialect.getCreateTableString() + " " + tableName + " ( " + valueColumnName + " " + dialect.getTypeName( Types.BIGINT ) + " )",
+				"insert into " + tableName + " values ( " + initialValue + " )"
+		};
+	}
+
+	public String[] sqlDropStrings(Dialect dialect) throws HibernateException {
+		StringBuffer sqlDropString = new StringBuffer().append( "drop table " );
+		if ( dialect.supportsIfExistsBeforeTableName() ) {
+			sqlDropString.append( "if exists " );
+		}
+		sqlDropString.append( tableName ).append( dialect.getCascadeConstraintsString() );
+		if ( dialect.supportsIfExistsAfterTableName() ) {
+			sqlDropString.append( " if exists" );
+		}
+		return new String[] { sqlDropString.toString() };
+	}
+
+	protected Serializable doWorkInCurrentTransaction(Connection conn, String sql) throws SQLException {
+		long result;
+		int rows;
+		do {
+			sql = select;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement qps = conn.prepareStatement( select );
+			try {
+				ResultSet rs = qps.executeQuery();
+				if ( !rs.next() ) {
+					String err = "could not read a hi value - you need to populate the table: " + tableName;
+					log.error( err );
+					throw new IdentifierGenerationException( err );
+				}
+				result = rs.getLong( 1 );
+				rs.close();
+			}
+			catch ( SQLException sqle ) {
+				log.error( "could not read a hi value", sqle );
+				throw sqle;
+			}
+			finally {
+				qps.close();
+			}
+
+			sql = update;
+			SQL_STATEMENT_LOGGER.logStatement( sql, FormatStyle.BASIC );
+			PreparedStatement ups = conn.prepareStatement( update );
+			try {
+				int increment = applyIncrementSizeToSourceValues ? incrementSize : 1;
+				ups.setLong( 1, result + increment );
+				ups.setLong( 2, result );
+				rows = ups.executeUpdate();
+			}
+			catch ( SQLException sqle ) {
+				log.error( "could not update hi value in: " + tableName, sqle );
+				throw sqle;
+			}
+			finally {
+				ups.close();
+			}
+		} while ( rows == 0 );
+
+		accessCounter++;
+
+		return new Long( result );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-package org.hibernate.id.insert;
-
-import org.hibernate.id.PostInsertIdentityPersister;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.pretty.MessageHelper;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Abstract InsertGeneratedIdentifierDelegate implementation where the
- * underlying strategy causes the enerated identitifer to be returned as an
- * effect of performing the insert statement.  Thus, there is no need for an
- * additional sql statement to determine the generated identitifer.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractReturningDelegate implements InsertGeneratedIdentifierDelegate {
-	private final PostInsertIdentityPersister persister;
-
-	public AbstractReturningDelegate(PostInsertIdentityPersister persister) {
-		this.persister = persister;
-	}
-
-	public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
-		try {
-			// prepare and execute the insert
-			PreparedStatement insert = prepare( insertSQL, session );
-			try {
-				binder.bindValues( insert );
-				return executeAndExtract( insert );
-			}
-			finally {
-				releaseStatement( insert, session );
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not insert: " + MessageHelper.infoString( persister ),
-			        insertSQL
-				);
-		}
-	}
-
-	protected PostInsertIdentityPersister getPersister() {
-		return persister;
-	}
-
-	protected abstract PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException;
-
-	protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException;
-
-	protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException {
-		session.getBatcher().closeStatement( insert );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractReturningDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.id.insert;
+
+import org.hibernate.id.PostInsertIdentityPersister;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.pretty.MessageHelper;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Abstract InsertGeneratedIdentifierDelegate implementation where the
+ * underlying strategy causes the enerated identitifer to be returned as an
+ * effect of performing the insert statement.  Thus, there is no need for an
+ * additional sql statement to determine the generated identitifer.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractReturningDelegate implements InsertGeneratedIdentifierDelegate {
+	private final PostInsertIdentityPersister persister;
+
+	public AbstractReturningDelegate(PostInsertIdentityPersister persister) {
+		this.persister = persister;
+	}
+
+	public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
+		try {
+			// prepare and execute the insert
+			PreparedStatement insert = prepare( insertSQL, session );
+			try {
+				binder.bindValues( insert );
+				return executeAndExtract( insert );
+			}
+			finally {
+				releaseStatement( insert, session );
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not insert: " + MessageHelper.infoString( persister ),
+			        insertSQL
+				);
+		}
+	}
+
+	protected PostInsertIdentityPersister getPersister() {
+		return persister;
+	}
+
+	protected abstract PreparedStatement prepare(String insertSQL, SessionImplementor session) throws SQLException;
+
+	protected abstract Serializable executeAndExtract(PreparedStatement insert) throws SQLException;
+
+	protected void releaseStatement(PreparedStatement insert, SessionImplementor session) throws SQLException {
+		session.getBatcher().closeStatement( insert );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,113 +0,0 @@
-package org.hibernate.id.insert;
-
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.PostInsertIdentityPersister;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.ResultSet;
-import java.io.Serializable;
-
-/**
- * Abstract InsertGeneratedIdentifierDelegate implementation where the
- * underlying strategy requires an subsequent select after the insert
- * to determine the generated identifier.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractSelectingDelegate implements InsertGeneratedIdentifierDelegate {
-	private final PostInsertIdentityPersister persister;
-
-	protected AbstractSelectingDelegate(PostInsertIdentityPersister persister) {
-		this.persister = persister;
-	}
-
-	public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
-		try {
-			// prepare and execute the insert
-			PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false );
-			try {
-				binder.bindValues( insert );
-				insert.executeUpdate();
-			}
-			finally {
-				session.getBatcher().closeStatement( insert );
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not insert: " + MessageHelper.infoString( persister ),
-			        insertSQL
-				);
-		}
-
-		final String selectSQL = getSelectSQL();
-
-		try {
-			//fetch the generated id in a separate query
-			PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL );
-			try {
-				bindParameters( session, idSelect, binder.getEntity() );
-				ResultSet rs = idSelect.executeQuery();
-				try {
-					return getResult( session, rs, binder.getEntity() );
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( idSelect );
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not retrieve generated id after insert: " + MessageHelper.infoString( persister ),
-			        insertSQL
-			);
-		}
-	}
-
-	/**
-	 * Get the SQL statement to be used to retrieve generated key values.
-	 *
-	 * @return The SQL command string
-	 */
-	protected abstract String getSelectSQL();
-
-	/**
-	 * Bind any required parameter values into the SQL command {@link #getSelectSQL}.
-	 *
-	 * @param session The session
-	 * @param ps The prepared {@link #getSelectSQL SQL} command
-	 * @param entity The entity being saved.
-	 * @throws SQLException
-	 */
-	protected void bindParameters(
-			SessionImplementor session,
-	        PreparedStatement ps,
-	        Object entity) throws SQLException {
-	}
-
-	/**
-	 * Extract the generated key value from the given result set.
-	 *
-	 * @param session The session
-	 * @param rs The result set containing the generated primay key values.
-	 * @param entity The entity being saved.
-	 * @return The generated identifier
-	 * @throws SQLException
-	 */
-	protected abstract Serializable getResult(
-			SessionImplementor session,
-	        ResultSet rs,
-	        Object entity) throws SQLException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/AbstractSelectingDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,137 @@
+/*
+ * 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.id.insert;
+
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.PostInsertIdentityPersister;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.io.Serializable;
+
+/**
+ * Abstract InsertGeneratedIdentifierDelegate implementation where the
+ * underlying strategy requires an subsequent select after the insert
+ * to determine the generated identifier.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractSelectingDelegate implements InsertGeneratedIdentifierDelegate {
+	private final PostInsertIdentityPersister persister;
+
+	protected AbstractSelectingDelegate(PostInsertIdentityPersister persister) {
+		this.persister = persister;
+	}
+
+	public final Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder) {
+		try {
+			// prepare and execute the insert
+			PreparedStatement insert = session.getBatcher().prepareStatement( insertSQL, false );
+			try {
+				binder.bindValues( insert );
+				insert.executeUpdate();
+			}
+			finally {
+				session.getBatcher().closeStatement( insert );
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not insert: " + MessageHelper.infoString( persister ),
+			        insertSQL
+				);
+		}
+
+		final String selectSQL = getSelectSQL();
+
+		try {
+			//fetch the generated id in a separate query
+			PreparedStatement idSelect = session.getBatcher().prepareStatement( selectSQL );
+			try {
+				bindParameters( session, idSelect, binder.getEntity() );
+				ResultSet rs = idSelect.executeQuery();
+				try {
+					return getResult( session, rs, binder.getEntity() );
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( idSelect );
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not retrieve generated id after insert: " + MessageHelper.infoString( persister ),
+			        insertSQL
+			);
+		}
+	}
+
+	/**
+	 * Get the SQL statement to be used to retrieve generated key values.
+	 *
+	 * @return The SQL command string
+	 */
+	protected abstract String getSelectSQL();
+
+	/**
+	 * Bind any required parameter values into the SQL command {@link #getSelectSQL}.
+	 *
+	 * @param session The session
+	 * @param ps The prepared {@link #getSelectSQL SQL} command
+	 * @param entity The entity being saved.
+	 * @throws SQLException
+	 */
+	protected void bindParameters(
+			SessionImplementor session,
+	        PreparedStatement ps,
+	        Object entity) throws SQLException {
+	}
+
+	/**
+	 * Extract the generated key value from the given result set.
+	 *
+	 * @param session The session
+	 * @param rs The result set containing the generated primay key values.
+	 * @param entity The entity being saved.
+	 * @return The generated identifier
+	 * @throws SQLException
+	 */
+	protected abstract Serializable getResult(
+			SessionImplementor session,
+	        ResultSet rs,
+	        Object entity) throws SQLException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/Binder.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,12 +0,0 @@
-package org.hibernate.id.insert;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * @author Steve Ebersole
- */
-public interface Binder {
-	public void bindValues(PreparedStatement ps) throws SQLException;
-	public Object getEntity();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/Binder.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/Binder.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id.insert;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * @author Steve Ebersole
+ */
+public interface Binder {
+	public void bindValues(PreparedStatement ps) throws SQLException;
+	public Object getEntity();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-package org.hibernate.id.insert;
-
-import org.hibernate.sql.Insert;
-import org.hibernate.dialect.Dialect;
-
-/**
- * Nothing more than a distinguishing subclass of Insert used to indicate
- * intent.  Some subclasses of this also provided some additional
- * functionality or semantic to the genernated SQL statement string.
- *
- * @author Steve Ebersole
- */
-public class IdentifierGeneratingInsert extends Insert {
-	public IdentifierGeneratingInsert(Dialect dialect) {
-		super( dialect );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id.insert;
+
+import org.hibernate.sql.Insert;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Nothing more than a distinguishing subclass of Insert used to indicate
+ * intent.  Some subclasses of this also provided some additional
+ * functionality or semantic to the genernated SQL statement string.
+ *
+ * @author Steve Ebersole
+ */
+public class IdentifierGeneratingInsert extends Insert {
+	public IdentifierGeneratingInsert(Dialect dialect) {
+		super( dialect );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-package org.hibernate.id.insert;
-
-import org.hibernate.engine.SessionImplementor;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Responsible for handling delegation relating to variants in how
- * insert-generated-identifier generator strategies dictate processing:<ul>
- * <li>building the sql insert statement
- * <li>determination of the generated identifier value
- * </ul>
- *
- * @author Steve Ebersole
- */
-public interface InsertGeneratedIdentifierDelegate {
-
-	/**
-	 * Build a {@link org.hibernate.sql.Insert} specific to the delegate's mode
-	 * of handling generated key values.
-	 *
-	 * @return The insert object.
-	 */
-	public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert();
-
-	/**
-	 * Perform the indicated insert SQL statement and determine the identifier value
-	 * generated.
-	 *
-	 * @param insertSQL
-	 * @param session
-	 * @param binder
-	 * @return The generated identifier value.
-	 */
-	public Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertGeneratedIdentifierDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.id.insert;
+
+import org.hibernate.engine.SessionImplementor;
+
+import java.io.Serializable;
+
+/**
+ * Responsible for handling delegation relating to variants in how
+ * insert-generated-identifier generator strategies dictate processing:<ul>
+ * <li>building the sql insert statement
+ * <li>determination of the generated identifier value
+ * </ul>
+ *
+ * @author Steve Ebersole
+ */
+public interface InsertGeneratedIdentifierDelegate {
+
+	/**
+	 * Build a {@link org.hibernate.sql.Insert} specific to the delegate's mode
+	 * of handling generated key values.
+	 *
+	 * @return The insert object.
+	 */
+	public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert();
+
+	/**
+	 * Perform the indicated insert SQL statement and determine the identifier value
+	 * generated.
+	 *
+	 * @param insertSQL The INSERT statement string
+	 * @param session The session in which we are operating
+	 * @param binder The param binder
+	 * @return The generated identifier value.
+	 */
+	public Serializable performInsert(String insertSQL, SessionImplementor session, Binder binder);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-package org.hibernate.id.insert;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * Specialized IdentifierGeneratingInsert which appends the database
- * specific clause which signifies to return generated IDENTITY values
- * to the end of the insert statement.
- * 
- * @author Steve Ebersole
- */
-public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert {
-	public InsertSelectIdentityInsert(Dialect dialect) {
-		super( dialect );
-	}
-
-	public String toStatementString() {
-		return getDialect().appendIdentitySelectToInsert( super.toStatementString() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.id.insert;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Specialized IdentifierGeneratingInsert which appends the database
+ * specific clause which signifies to return generated IDENTITY values
+ * to the end of the insert statement.
+ * 
+ * @author Steve Ebersole
+ */
+public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert {
+	public InsertSelectIdentityInsert(Dialect dialect) {
+		super( dialect );
+	}
+
+	public String toStatementString() {
+		return getDialect().appendIdentitySelectToInsert( super.toStatementString() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/id/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package contains internal implementation classes for the
-	main API interfaces.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/id/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/id/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package contains internal implementation classes for the
+	main API interfaces.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,878 +0,0 @@
-//$Id: AbstractQueryImpl.java 10856 2006-11-21 21:57:42Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.CacheMode;
-import org.hibernate.FlushMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.NonUniqueResultException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.Query;
-import org.hibernate.QueryException;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.engine.query.ParameterMetadata;
-import org.hibernate.hql.classic.ParserHelper;
-import org.hibernate.property.Getter;
-import org.hibernate.proxy.HibernateProxyHelper;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.SerializableType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.MarkerObject;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Abstract implementation of the Query interface.
- *
- * @author Gavin King, Max Andersen
- */
-public abstract class AbstractQueryImpl implements Query {
-
-	private static final Object UNSET_PARAMETER = new MarkerObject("<unset parameter>");
-	private static final Object UNSET_TYPE = new MarkerObject("<unset type>");
-
-	private final String queryString;
-	protected final SessionImplementor session;
-	protected final ParameterMetadata parameterMetadata;
-
-	// parameter bind values...
-	private List values = new ArrayList(4);
-	private List types = new ArrayList(4);
-	private Map namedParameters = new HashMap(4);
-	private Map namedParameterLists = new HashMap(4);
-
-	private Object optionalObject;
-	private Serializable optionalId;
-	private String optionalEntityName;
-
-	private RowSelection selection;
-	private boolean cacheable;
-	private String cacheRegion;
-	private String comment;
-	private FlushMode flushMode;
-	private CacheMode cacheMode;
-	private FlushMode sessionFlushMode;
-	private CacheMode sessionCacheMode;
-	private Serializable collectionKey;
-	private boolean readOnly;
-	private ResultTransformer resultTransformer;
-
-	public AbstractQueryImpl(
-			String queryString,
-	        FlushMode flushMode,
-	        SessionImplementor session,
-	        ParameterMetadata parameterMetadata) {
-		this.session = session;
-		this.queryString = queryString;
-		this.selection = new RowSelection();
-		this.flushMode = flushMode;
-		this.cacheMode = null;
-		this.parameterMetadata = parameterMetadata;
-	}
-
-	public String toString() {
-		return StringHelper.unqualify( getClass().getName() ) + '(' + queryString + ')';
-	}
-
-	public final String getQueryString() {
-		return queryString;
-	}
-
-	//TODO: maybe call it getRowSelection() ?
-	public RowSelection getSelection() {
-		return selection;
-	}
-	
-	public Query setFlushMode(FlushMode flushMode) {
-		this.flushMode = flushMode;
-		return this;
-	}
-	
-	public Query setCacheMode(CacheMode cacheMode) {
-		this.cacheMode = cacheMode;
-		return this;
-	}
-
-	public Query setCacheable(boolean cacheable) {
-		this.cacheable = cacheable;
-		return this;
-	}
-
-	public Query setCacheRegion(String cacheRegion) {
-		if (cacheRegion != null)
-			this.cacheRegion = cacheRegion.trim();
-		return this;
-	}
-
-	public Query setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public Query setFirstResult(int firstResult) {
-		selection.setFirstRow( new Integer(firstResult) );
-		return this;
-	}
-
-	public Query setMaxResults(int maxResults) {
-		selection.setMaxRows( new Integer(maxResults) );
-		return this;
-	}
-
-	public Query setTimeout(int timeout) {
-		selection.setTimeout( new Integer(timeout) );
-		return this;
-	}
-	public Query setFetchSize(int fetchSize) {
-		selection.setFetchSize( new Integer(fetchSize) );
-		return this;
-	}
-
-	public Type[] getReturnTypes() throws HibernateException {
-		return session.getFactory().getReturnTypes( queryString );
-	}
-
-	public String[] getReturnAliases() throws HibernateException {
-		return session.getFactory().getReturnAliases( queryString );
-	}
-
-	public Query setCollectionKey(Serializable collectionKey) {
-		this.collectionKey = collectionKey;
-		return this;
-	}
-
-	public boolean isReadOnly() {
-		return readOnly;
-	}
-
-	public Query setReadOnly(boolean readOnly) {
-		this.readOnly = readOnly;
-		return this;
-	}
-
-	public Query setResultTransformer(ResultTransformer transformer) {
-		this.resultTransformer = transformer;
-		return this;
-	}
-	
-	public void setOptionalEntityName(String optionalEntityName) {
-		this.optionalEntityName = optionalEntityName;
-	}
-
-	public void setOptionalId(Serializable optionalId) {
-		this.optionalId = optionalId;
-	}
-
-	public void setOptionalObject(Object optionalObject) {
-		this.optionalObject = optionalObject;
-	}
-
-	SessionImplementor getSession() {
-		return session;
-	}
-
-	protected abstract Map getLockModes();
-
-
-	// Parameter handling code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Returns a shallow copy of the named parameter value map.
-	 *
-	 * @return Shallow copy of the named parameter value map
-	 */
-	protected Map getNamedParams() {
-		return new HashMap( namedParameters );
-	}
-
-	/**
-	 * Returns an array representing all named parameter names encountered
-	 * during (intial) parsing of the query.
-	 * <p/>
-	 * Note <i>initial</i> here means different things depending on whether
-	 * this is a native-sql query or an HQL/filter query.  For native-sql, a
-	 * precursory inspection of the query string is performed specifically to
-	 * locate defined parameters.  For HQL/filter queries, this is the
-	 * information returned from the query-translator.  This distinction
-	 * holds true for all parameter metadata exposed here.
-	 *
-	 * @return Array of named parameter names.
-	 * @throws HibernateException
-	 */
-	public String[] getNamedParameters() throws HibernateException {
-		return ArrayHelper.toStringArray( parameterMetadata.getNamedParameterNames() );
-	}
-
-	/**
-	 * Does this query contain named parameters?
-	 *
-	 * @return True if the query was found to contain named parameters; false
-	 * otherwise;
-	 */
-	public boolean hasNamedParameters() {
-		return parameterMetadata.getNamedParameterNames().size() > 0;
-	}
-
-	/**
-	 * Retreive the value map for any named parameter lists (i.e., for
-	 * auto-expansion) bound to this query.
-	 *
-	 * @return The parameter list value map.
-	 */
-	protected Map getNamedParameterLists() {
-		return namedParameterLists;
-	}
-
-	/**
-	 * Retreives the list of parameter values bound to this query for
-	 * ordinal parameters.
-	 *
-	 * @return The ordinal parameter values.
-	 */
-	protected List getValues() {
-		return values;
-	}
-
-	/**
-	 * Retreives the list of parameter {@link Type type}s bound to this query for
-	 * ordinal parameters.
-	 *
-	 * @return The ordinal parameter types.
-	 */
-	protected List getTypes() {
-		return types;
-	}
-
-	/**
-	 * Perform parameter validation.  Used prior to executing the encapsulated
-	 * query.
-	 *
-	 * @throws QueryException
-	 */
-	protected void verifyParameters() throws QueryException {
-		verifyParameters(false);
-	}
-
-	/**
-	 * Perform parameter validation.  Used prior to executing the encapsulated
-	 * query.
-	 *
-	 * @param reserveFirstParameter if true, the first ? will not be verified since
-	 * its needed for e.g. callable statements returning a out parameter
-	 * @throws HibernateException
-	 */
-	protected void verifyParameters(boolean reserveFirstParameter) throws HibernateException {
-		if ( parameterMetadata.getNamedParameterNames().size() != namedParameters.size() + namedParameterLists.size() ) {
-			Set missingParams = new HashSet( parameterMetadata.getNamedParameterNames() );
-			missingParams.removeAll( namedParameterLists.keySet() );
-			missingParams.removeAll( namedParameters.keySet() );
-			throw new QueryException( "Not all named parameters have been set: " + missingParams, getQueryString() );
-		}
-
-		int positionalValueSpan = 0;
-		for ( int i = 0; i < values.size(); i++ ) {
-			Object object = types.get( i );
-			if( values.get( i ) == UNSET_PARAMETER || object == UNSET_TYPE ) {
-				if ( reserveFirstParameter && i==0 ) {
-					continue;
-				}
-				else {
-					throw new QueryException( "Unset positional parameter at position: " + i, getQueryString() );
-				}
-			}
-			positionalValueSpan += ( (Type) object ).getColumnSpan( session.getFactory() );
-		}
-
-		if ( parameterMetadata.getOrdinalParameterCount() != positionalValueSpan ) {
-			if ( reserveFirstParameter && parameterMetadata.getOrdinalParameterCount() - 1 != positionalValueSpan ) {
-				throw new QueryException(
-				 		"Expected positional parameter count: " +
-				 		(parameterMetadata.getOrdinalParameterCount()-1) +
-				 		", actual parameters: " +
-				 		values,
-				 		getQueryString()
-				 	);
-			}
-			else if ( !reserveFirstParameter ) {
-				throw new QueryException(
-				 		"Expected positional parameter count: " +
-				 		parameterMetadata.getOrdinalParameterCount() +
-				 		", actual parameters: " +
-				 		values,
-				 		getQueryString()
-				 	);
-			}
-		}
-	}
-
-	public Query setParameter(int position, Object val, Type type) {
-		if ( parameterMetadata.getOrdinalParameterCount() == 0 ) {
-			throw new IllegalArgumentException("No positional parameters in query: " + getQueryString() );
-		}
-		if ( position < 0 || position > parameterMetadata.getOrdinalParameterCount() - 1 ) {
-			throw new IllegalArgumentException("Positional parameter does not exist: " + position + " in query: " + getQueryString() );
-		}
-		int size = values.size();
-		if ( position < size ) {
-			values.set( position, val );
-			types.set( position, type );
-		}
-		else {
-			// prepend value and type list with null for any positions before the wanted position.
-			for ( int i = 0; i < position - size; i++ ) {
-				values.add( UNSET_PARAMETER );
-				types.add( UNSET_TYPE );
-			}
-			values.add( val );
-			types.add( type );
-		}
-		return this;
-	}
-
-	public Query setParameter(String name, Object val, Type type) {
-		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
-			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
-		}
-		else {
-			 namedParameters.put( name, new TypedValue( type, val, session.getEntityMode() ) );
-			 return this;
-		}
-	}
-
-	public Query setParameter(int position, Object val) throws HibernateException {
-		if (val == null) {
-			setParameter( position, val, Hibernate.SERIALIZABLE );
-		}
-		else {
-			setParameter( position, val, determineType( position, val ) );
-		}
-		return this;
-	}
-
-	public Query setParameter(String name, Object val) throws HibernateException {
-		if (val == null) {
-			Type type = parameterMetadata.getNamedParameterExpectedType( name );
-			if ( type == null ) {
-				type = Hibernate.SERIALIZABLE;
-			}
-			setParameter( name, val, type );
-		}
-		else {
-			setParameter( name, val, determineType( name, val ) );
-		}
-		return this;
-	}
-
-	protected Type determineType(int paramPosition, Object paramValue, Type defaultType) {
-		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
-		if ( type == null ) {
-			type = defaultType;
-		}
-		return type;
-	}
-
-	protected Type determineType(int paramPosition, Object paramValue) throws HibernateException {
-		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
-		if ( type == null ) {
-			type = guessType( paramValue );
-		}
-		return type;
-	}
-
-	protected Type determineType(String paramName, Object paramValue, Type defaultType) {
-		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
-		if ( type == null ) {
-			type = defaultType;
-		}
-		return type;
-	}
-
-	protected Type determineType(String paramName, Object paramValue) throws HibernateException {
-		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
-		if ( type == null ) {
-			type = guessType( paramValue );
-		}
-		return type;
-	}
-
-	protected Type determineType(String paramName, Class clazz) throws HibernateException {
-		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
-		if ( type == null ) {
-			type = guessType( clazz );
-		}
-		return type;
-	}
-
-	private Type guessType(Object param) throws HibernateException {
-		Class clazz = HibernateProxyHelper.getClassWithoutInitializingProxy( param );
-		return guessType( clazz );
-	}
-
-	private Type guessType(Class clazz) throws HibernateException {
-		String typename = clazz.getName();
-		Type type = TypeFactory.heuristicType(typename);
-		boolean serializable = type!=null && type instanceof SerializableType;
-		if (type==null || serializable) {
-			try {
-				session.getFactory().getEntityPersister( clazz.getName() );
-			}
-			catch (MappingException me) {
-				if (serializable) {
-					return type;
-				}
-				else {
-					throw new HibernateException("Could not determine a type for class: " + typename);
-				}
-			}
-			return Hibernate.entity(clazz);
-		}
-		else {
-			return type;
-		}
-	}
-
-	public Query setString(int position, String val) {
-		setParameter(position, val, Hibernate.STRING);
-		return this;
-	}
-
-	public Query setCharacter(int position, char val) {
-		setParameter(position, new Character(val), Hibernate.CHARACTER);
-		return this;
-	}
-
-	public Query setBoolean(int position, boolean val) {
-		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
-		Type typeToUse = determineType( position, valueToUse, Hibernate.BOOLEAN );
-		setParameter( position, valueToUse, typeToUse );
-		return this;
-	}
-
-	public Query setByte(int position, byte val) {
-		setParameter(position, new Byte(val), Hibernate.BYTE);
-		return this;
-	}
-
-	public Query setShort(int position, short val) {
-		setParameter(position, new Short(val), Hibernate.SHORT);
-		return this;
-	}
-
-	public Query setInteger(int position, int val) {
-		setParameter(position, new Integer(val), Hibernate.INTEGER);
-		return this;
-	}
-
-	public Query setLong(int position, long val) {
-		setParameter(position, new Long(val), Hibernate.LONG);
-		return this;
-	}
-
-	public Query setFloat(int position, float val) {
-		setParameter(position, new Float(val), Hibernate.FLOAT);
-		return this;
-	}
-
-	public Query setDouble(int position, double val) {
-		setParameter(position, new Double(val), Hibernate.DOUBLE);
-		return this;
-	}
-
-	public Query setBinary(int position, byte[] val) {
-		setParameter(position, val, Hibernate.BINARY);
-		return this;
-	}
-
-	public Query setText(int position, String val) {
-		setParameter(position, val, Hibernate.TEXT);
-		return this;
-	}
-
-	public Query setSerializable(int position, Serializable val) {
-		setParameter(position, val, Hibernate.SERIALIZABLE);
-		return this;
-	}
-
-	public Query setDate(int position, Date date) {
-		setParameter(position, date, Hibernate.DATE);
-		return this;
-	}
-
-	public Query setTime(int position, Date date) {
-		setParameter(position, date, Hibernate.TIME);
-		return this;
-	}
-
-	public Query setTimestamp(int position, Date date) {
-		setParameter(position, date, Hibernate.TIMESTAMP);
-		return this;
-	}
-
-	public Query setEntity(int position, Object val) {
-		setParameter( position, val, Hibernate.entity( resolveEntityName( val ) ) );
-		return this;
-	}
-
-	private String resolveEntityName(Object val) {
-		if ( val == null ) {
-			throw new IllegalArgumentException( "entity for parameter binding cannot be null" );
-		}
-		return session.bestGuessEntityName( val );
-	}
-
-	public Query setLocale(int position, Locale locale) {
-		setParameter(position, locale, Hibernate.LOCALE);
-		return this;
-	}
-
-	public Query setCalendar(int position, Calendar calendar) {
-		setParameter(position, calendar, Hibernate.CALENDAR);
-		return this;
-	}
-
-	public Query setCalendarDate(int position, Calendar calendar) {
-		setParameter(position, calendar, Hibernate.CALENDAR_DATE);
-		return this;
-	}
-
-	public Query setBinary(String name, byte[] val) {
-		setParameter(name, val, Hibernate.BINARY);
-		return this;
-	}
-
-	public Query setText(String name, String val) {
-		setParameter(name, val, Hibernate.TEXT);
-		return this;
-	}
-
-	public Query setBoolean(String name, boolean val) {
-		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
-		Type typeToUse = determineType( name, valueToUse, Hibernate.BOOLEAN );
-		setParameter( name, valueToUse, typeToUse );
-		return this;
-	}
-
-	public Query setByte(String name, byte val) {
-		setParameter(name, new Byte(val), Hibernate.BYTE);
-		return this;
-	}
-
-	public Query setCharacter(String name, char val) {
-		setParameter(name, new Character(val), Hibernate.CHARACTER);
-		return this;
-	}
-
-	public Query setDate(String name, Date date) {
-		setParameter(name, date, Hibernate.DATE);
-		return this;
-	}
-
-	public Query setDouble(String name, double val) {
-		setParameter(name, new Double(val), Hibernate.DOUBLE);
-		return this;
-	}
-
-	public Query setEntity(String name, Object val) {
-		setParameter( name, val, Hibernate.entity( resolveEntityName( val ) ) );
-		return this;
-	}
-
-	public Query setFloat(String name, float val) {
-		setParameter(name, new Float(val), Hibernate.FLOAT);
-		return this;
-	}
-
-	public Query setInteger(String name, int val) {
-		setParameter(name, new Integer(val), Hibernate.INTEGER);
-		return this;
-	}
-
-	public Query setLocale(String name, Locale locale) {
-		setParameter(name, locale, Hibernate.LOCALE);
-		return this;
-	}
-
-	public Query setCalendar(String name, Calendar calendar) {
-		setParameter(name, calendar, Hibernate.CALENDAR);
-		return this;
-	}
-
-	public Query setCalendarDate(String name, Calendar calendar) {
-		setParameter(name, calendar, Hibernate.CALENDAR_DATE);
-		return this;
-	}
-
-	public Query setLong(String name, long val) {
-		setParameter(name, new Long(val), Hibernate.LONG);
-		return this;
-	}
-
-	public Query setSerializable(String name, Serializable val) {
-		setParameter(name, val, Hibernate.SERIALIZABLE);
-		return this;
-	}
-
-	public Query setShort(String name, short val) {
-		setParameter(name, new Short(val), Hibernate.SHORT);
-		return this;
-	}
-
-	public Query setString(String name, String val) {
-		setParameter(name, val, Hibernate.STRING);
-		return this;
-	}
-
-	public Query setTime(String name, Date date) {
-		setParameter(name, date, Hibernate.TIME);
-		return this;
-	}
-
-	public Query setTimestamp(String name, Date date) {
-		setParameter(name, date, Hibernate.TIMESTAMP);
-		return this;
-	}
-
-	public Query setBigDecimal(int position, BigDecimal number) {
-		setParameter(position, number, Hibernate.BIG_DECIMAL);
-		return this;
-	}
-
-	public Query setBigDecimal(String name, BigDecimal number) {
-		setParameter(name, number, Hibernate.BIG_DECIMAL);
-		return this;
-	}
-
-	public Query setBigInteger(int position, BigInteger number) {
-		setParameter(position, number, Hibernate.BIG_INTEGER);
-		return this;
-	}
-
-	public Query setBigInteger(String name, BigInteger number) {
-		setParameter(name, number, Hibernate.BIG_INTEGER);
-		return this;
-	}
-
-	public Query setParameterList(String name, Collection vals, Type type) throws HibernateException {
-		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
-			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
-		}
-		namedParameterLists.put( name, new TypedValue( type, vals, session.getEntityMode() ) );
-		return this;
-	}
-	
-	/**
-	 * Warning: adds new parameters to the argument by side-effect, as well as
-	 * mutating the query string!
-	 */
-	protected String expandParameterLists(Map namedParamsCopy) {
-		String query = this.queryString;
-		Iterator iter = namedParameterLists.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			query = expandParameterList( query, (String) me.getKey(), (TypedValue) me.getValue(), namedParamsCopy );
-		}
-		return query;
-	}
-
-	/**
-	 * Warning: adds new parameters to the argument by side-effect, as well as
-	 * mutating the query string!
-	 */
-	private String expandParameterList(String query, String name, TypedValue typedList, Map namedParamsCopy) {
-		Collection vals = (Collection) typedList.getValue();
-		Type type = typedList.getType();
-		if ( vals.size() == 1 ) {
-			// short-circuit for performance...
-			namedParamsCopy.put( name, new TypedValue( type, vals.iterator().next(), session.getEntityMode() ) );
-			return query;
-		}
-
-		StringBuffer list = new StringBuffer( 16 );
-		Iterator iter = vals.iterator();
-		int i = 0;
-		boolean isJpaPositionalParam = parameterMetadata.getNamedParameterDescriptor( name ).isJpaStyle();
-		while ( iter.hasNext() ) {
-			String alias = ( isJpaPositionalParam ? 'x' + name : name ) + i++ + '_';
-			namedParamsCopy.put( alias, new TypedValue( type, iter.next(), session.getEntityMode() ) );
-			list.append( ParserHelper.HQL_VARIABLE_PREFIX ).append( alias );
-			if ( iter.hasNext() ) {
-				list.append( ", " );
-			}
-		}
-		String paramPrefix = isJpaPositionalParam ? "?" : ParserHelper.HQL_VARIABLE_PREFIX;
-		return StringHelper.replace( query, paramPrefix + name, list.toString(), true );
-	}
-
-	public Query setParameterList(String name, Collection vals) throws HibernateException {
-		if ( vals == null ) {
-			throw new QueryException( "Collection must be not null!" );
-		}
-
-		if( vals.size() == 0 ) {
-			setParameterList( name, vals, null );
-		}
-		else {
-			setParameterList(name, vals, determineType( name, vals.iterator().next() ) );
-		}
-
-		return this;
-	}
-
-	public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException {
-		return setParameterList( name, Arrays.asList(vals), type );
-	}
-
-	public Query setParameterList(String name, Object[] vals) throws HibernateException {
-		return setParameterList( name, Arrays.asList(vals) );
-	}
-
-	public Query setProperties(Map map) throws HibernateException {
-		String[] params = getNamedParameters();
-		for (int i = 0; i < params.length; i++) {
-			String namedParam = params[i];
-				final Object object = map.get(namedParam);
-				if(object==null) {
-					continue;
-				}
-				Class retType = object.getClass();
-				if ( Collection.class.isAssignableFrom( retType ) ) {
-					setParameterList( namedParam, ( Collection ) object );
-				}
-				else if ( retType.isArray() ) {
-					setParameterList( namedParam, ( Object[] ) object );
-				}
-				else {
-					setParameter( namedParam, object, determineType( namedParam, retType ) );
-				}
-
-			
-		}
-		return this;				
-	}
-	
-	public Query setProperties(Object bean) throws HibernateException {
-		Class clazz = bean.getClass();
-		String[] params = getNamedParameters();
-		for (int i = 0; i < params.length; i++) {
-			String namedParam = params[i];
-			try {
-				Getter getter = ReflectHelper.getGetter( clazz, namedParam );
-				Class retType = getter.getReturnType();
-				final Object object = getter.get( bean );
-				if ( Collection.class.isAssignableFrom( retType ) ) {
-					setParameterList( namedParam, ( Collection ) object );
-				}
-				else if ( retType.isArray() ) {
-				 	setParameterList( namedParam, ( Object[] ) object );
-				}
-				else {
-					setParameter( namedParam, object, determineType( namedParam, retType ) );
-				}
-			}
-			catch (PropertyNotFoundException pnfe) {
-				// ignore
-			}
-		}
-		return this;
-	}
-
-	public Query setParameters(Object[] values, Type[] types) {
-		this.values = Arrays.asList(values);
-		this.types = Arrays.asList(types);
-		return this;
-	}
-
-
-	// Execution methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Object uniqueResult() throws HibernateException {
-		return uniqueElement( list() );
-	}
-
-	static Object uniqueElement(List list) throws NonUniqueResultException {
-		int size = list.size();
-		if (size==0) return null;
-		Object first = list.get(0);
-		for ( int i=1; i<size; i++ ) {
-			if ( list.get(i)!=first ) {
-				throw new NonUniqueResultException( list.size() );
-			}
-		}
-		return first;
-	}
-
-	protected RowSelection getRowSelection() {
-		return selection;
-	}
-
-	public Type[] typeArray() {
-		return ArrayHelper.toTypeArray( getTypes() );
-	}
-	
-	public Object[] valueArray() {
-		return getValues().toArray();
-	}
-
-	public QueryParameters getQueryParameters(Map namedParams) {
-		return new QueryParameters(
-				typeArray(),
-				valueArray(),
-				namedParams,
-				getLockModes(),
-				getSelection(),
-				readOnly,
-				cacheable,
-				cacheRegion,
-				comment,
-				collectionKey == null ? null : new Serializable[] { collectionKey },
-				optionalObject,
-				optionalEntityName,
-				optionalId,
-				resultTransformer
-		);
-	}
-	
-	protected void before() {
-		if ( flushMode!=null ) {
-			sessionFlushMode = getSession().getFlushMode();
-			getSession().setFlushMode(flushMode);
-		}
-		if ( cacheMode!=null ) {
-			sessionCacheMode = getSession().getCacheMode();
-			getSession().setCacheMode(cacheMode);
-		}
-	}
-	
-	protected void after() {
-		if (sessionFlushMode!=null) {
-			getSession().setFlushMode(sessionFlushMode);
-			sessionFlushMode = null;
-		}
-		if (sessionCacheMode!=null) {
-			getSession().setCacheMode(sessionCacheMode);
-			sessionCacheMode = null;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractQueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,902 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.CacheMode;
+import org.hibernate.FlushMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.NonUniqueResultException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.Query;
+import org.hibernate.QueryException;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.engine.query.ParameterMetadata;
+import org.hibernate.hql.classic.ParserHelper;
+import org.hibernate.property.Getter;
+import org.hibernate.proxy.HibernateProxyHelper;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.SerializableType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.MarkerObject;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Abstract implementation of the Query interface.
+ *
+ * @author Gavin King
+ * @author Max Andersen
+ */
+public abstract class AbstractQueryImpl implements Query {
+
+	private static final Object UNSET_PARAMETER = new MarkerObject("<unset parameter>");
+	private static final Object UNSET_TYPE = new MarkerObject("<unset type>");
+
+	private final String queryString;
+	protected final SessionImplementor session;
+	protected final ParameterMetadata parameterMetadata;
+
+	// parameter bind values...
+	private List values = new ArrayList(4);
+	private List types = new ArrayList(4);
+	private Map namedParameters = new HashMap(4);
+	private Map namedParameterLists = new HashMap(4);
+
+	private Object optionalObject;
+	private Serializable optionalId;
+	private String optionalEntityName;
+
+	private RowSelection selection;
+	private boolean cacheable;
+	private String cacheRegion;
+	private String comment;
+	private FlushMode flushMode;
+	private CacheMode cacheMode;
+	private FlushMode sessionFlushMode;
+	private CacheMode sessionCacheMode;
+	private Serializable collectionKey;
+	private boolean readOnly;
+	private ResultTransformer resultTransformer;
+
+	public AbstractQueryImpl(
+			String queryString,
+	        FlushMode flushMode,
+	        SessionImplementor session,
+	        ParameterMetadata parameterMetadata) {
+		this.session = session;
+		this.queryString = queryString;
+		this.selection = new RowSelection();
+		this.flushMode = flushMode;
+		this.cacheMode = null;
+		this.parameterMetadata = parameterMetadata;
+	}
+
+	public String toString() {
+		return StringHelper.unqualify( getClass().getName() ) + '(' + queryString + ')';
+	}
+
+	public final String getQueryString() {
+		return queryString;
+	}
+
+	//TODO: maybe call it getRowSelection() ?
+	public RowSelection getSelection() {
+		return selection;
+	}
+	
+	public Query setFlushMode(FlushMode flushMode) {
+		this.flushMode = flushMode;
+		return this;
+	}
+	
+	public Query setCacheMode(CacheMode cacheMode) {
+		this.cacheMode = cacheMode;
+		return this;
+	}
+
+	public Query setCacheable(boolean cacheable) {
+		this.cacheable = cacheable;
+		return this;
+	}
+
+	public Query setCacheRegion(String cacheRegion) {
+		if (cacheRegion != null)
+			this.cacheRegion = cacheRegion.trim();
+		return this;
+	}
+
+	public Query setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public Query setFirstResult(int firstResult) {
+		selection.setFirstRow( new Integer(firstResult) );
+		return this;
+	}
+
+	public Query setMaxResults(int maxResults) {
+		selection.setMaxRows( new Integer(maxResults) );
+		return this;
+	}
+
+	public Query setTimeout(int timeout) {
+		selection.setTimeout( new Integer(timeout) );
+		return this;
+	}
+	public Query setFetchSize(int fetchSize) {
+		selection.setFetchSize( new Integer(fetchSize) );
+		return this;
+	}
+
+	public Type[] getReturnTypes() throws HibernateException {
+		return session.getFactory().getReturnTypes( queryString );
+	}
+
+	public String[] getReturnAliases() throws HibernateException {
+		return session.getFactory().getReturnAliases( queryString );
+	}
+
+	public Query setCollectionKey(Serializable collectionKey) {
+		this.collectionKey = collectionKey;
+		return this;
+	}
+
+	public boolean isReadOnly() {
+		return readOnly;
+	}
+
+	public Query setReadOnly(boolean readOnly) {
+		this.readOnly = readOnly;
+		return this;
+	}
+
+	public Query setResultTransformer(ResultTransformer transformer) {
+		this.resultTransformer = transformer;
+		return this;
+	}
+	
+	public void setOptionalEntityName(String optionalEntityName) {
+		this.optionalEntityName = optionalEntityName;
+	}
+
+	public void setOptionalId(Serializable optionalId) {
+		this.optionalId = optionalId;
+	}
+
+	public void setOptionalObject(Object optionalObject) {
+		this.optionalObject = optionalObject;
+	}
+
+	SessionImplementor getSession() {
+		return session;
+	}
+
+	protected abstract Map getLockModes();
+
+
+	// Parameter handling code ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Returns a shallow copy of the named parameter value map.
+	 *
+	 * @return Shallow copy of the named parameter value map
+	 */
+	protected Map getNamedParams() {
+		return new HashMap( namedParameters );
+	}
+
+	/**
+	 * Returns an array representing all named parameter names encountered
+	 * during (intial) parsing of the query.
+	 * <p/>
+	 * Note <i>initial</i> here means different things depending on whether
+	 * this is a native-sql query or an HQL/filter query.  For native-sql, a
+	 * precursory inspection of the query string is performed specifically to
+	 * locate defined parameters.  For HQL/filter queries, this is the
+	 * information returned from the query-translator.  This distinction
+	 * holds true for all parameter metadata exposed here.
+	 *
+	 * @return Array of named parameter names.
+	 * @throws HibernateException
+	 */
+	public String[] getNamedParameters() throws HibernateException {
+		return ArrayHelper.toStringArray( parameterMetadata.getNamedParameterNames() );
+	}
+
+	/**
+	 * Does this query contain named parameters?
+	 *
+	 * @return True if the query was found to contain named parameters; false
+	 * otherwise;
+	 */
+	public boolean hasNamedParameters() {
+		return parameterMetadata.getNamedParameterNames().size() > 0;
+	}
+
+	/**
+	 * Retreive the value map for any named parameter lists (i.e., for
+	 * auto-expansion) bound to this query.
+	 *
+	 * @return The parameter list value map.
+	 */
+	protected Map getNamedParameterLists() {
+		return namedParameterLists;
+	}
+
+	/**
+	 * Retreives the list of parameter values bound to this query for
+	 * ordinal parameters.
+	 *
+	 * @return The ordinal parameter values.
+	 */
+	protected List getValues() {
+		return values;
+	}
+
+	/**
+	 * Retreives the list of parameter {@link Type type}s bound to this query for
+	 * ordinal parameters.
+	 *
+	 * @return The ordinal parameter types.
+	 */
+	protected List getTypes() {
+		return types;
+	}
+
+	/**
+	 * Perform parameter validation.  Used prior to executing the encapsulated
+	 * query.
+	 *
+	 * @throws QueryException
+	 */
+	protected void verifyParameters() throws QueryException {
+		verifyParameters(false);
+	}
+
+	/**
+	 * Perform parameter validation.  Used prior to executing the encapsulated
+	 * query.
+	 *
+	 * @param reserveFirstParameter if true, the first ? will not be verified since
+	 * its needed for e.g. callable statements returning a out parameter
+	 * @throws HibernateException
+	 */
+	protected void verifyParameters(boolean reserveFirstParameter) throws HibernateException {
+		if ( parameterMetadata.getNamedParameterNames().size() != namedParameters.size() + namedParameterLists.size() ) {
+			Set missingParams = new HashSet( parameterMetadata.getNamedParameterNames() );
+			missingParams.removeAll( namedParameterLists.keySet() );
+			missingParams.removeAll( namedParameters.keySet() );
+			throw new QueryException( "Not all named parameters have been set: " + missingParams, getQueryString() );
+		}
+
+		int positionalValueSpan = 0;
+		for ( int i = 0; i < values.size(); i++ ) {
+			Object object = types.get( i );
+			if( values.get( i ) == UNSET_PARAMETER || object == UNSET_TYPE ) {
+				if ( reserveFirstParameter && i==0 ) {
+					continue;
+				}
+				else {
+					throw new QueryException( "Unset positional parameter at position: " + i, getQueryString() );
+				}
+			}
+			positionalValueSpan += ( (Type) object ).getColumnSpan( session.getFactory() );
+		}
+
+		if ( parameterMetadata.getOrdinalParameterCount() != positionalValueSpan ) {
+			if ( reserveFirstParameter && parameterMetadata.getOrdinalParameterCount() - 1 != positionalValueSpan ) {
+				throw new QueryException(
+				 		"Expected positional parameter count: " +
+				 		(parameterMetadata.getOrdinalParameterCount()-1) +
+				 		", actual parameters: " +
+				 		values,
+				 		getQueryString()
+				 	);
+			}
+			else if ( !reserveFirstParameter ) {
+				throw new QueryException(
+				 		"Expected positional parameter count: " +
+				 		parameterMetadata.getOrdinalParameterCount() +
+				 		", actual parameters: " +
+				 		values,
+				 		getQueryString()
+				 	);
+			}
+		}
+	}
+
+	public Query setParameter(int position, Object val, Type type) {
+		if ( parameterMetadata.getOrdinalParameterCount() == 0 ) {
+			throw new IllegalArgumentException("No positional parameters in query: " + getQueryString() );
+		}
+		if ( position < 0 || position > parameterMetadata.getOrdinalParameterCount() - 1 ) {
+			throw new IllegalArgumentException("Positional parameter does not exist: " + position + " in query: " + getQueryString() );
+		}
+		int size = values.size();
+		if ( position < size ) {
+			values.set( position, val );
+			types.set( position, type );
+		}
+		else {
+			// prepend value and type list with null for any positions before the wanted position.
+			for ( int i = 0; i < position - size; i++ ) {
+				values.add( UNSET_PARAMETER );
+				types.add( UNSET_TYPE );
+			}
+			values.add( val );
+			types.add( type );
+		}
+		return this;
+	}
+
+	public Query setParameter(String name, Object val, Type type) {
+		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
+			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
+		}
+		else {
+			 namedParameters.put( name, new TypedValue( type, val, session.getEntityMode() ) );
+			 return this;
+		}
+	}
+
+	public Query setParameter(int position, Object val) throws HibernateException {
+		if (val == null) {
+			setParameter( position, val, Hibernate.SERIALIZABLE );
+		}
+		else {
+			setParameter( position, val, determineType( position, val ) );
+		}
+		return this;
+	}
+
+	public Query setParameter(String name, Object val) throws HibernateException {
+		if (val == null) {
+			Type type = parameterMetadata.getNamedParameterExpectedType( name );
+			if ( type == null ) {
+				type = Hibernate.SERIALIZABLE;
+			}
+			setParameter( name, val, type );
+		}
+		else {
+			setParameter( name, val, determineType( name, val ) );
+		}
+		return this;
+	}
+
+	protected Type determineType(int paramPosition, Object paramValue, Type defaultType) {
+		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
+		if ( type == null ) {
+			type = defaultType;
+		}
+		return type;
+	}
+
+	protected Type determineType(int paramPosition, Object paramValue) throws HibernateException {
+		Type type = parameterMetadata.getOrdinalParameterExpectedType( paramPosition + 1 );
+		if ( type == null ) {
+			type = guessType( paramValue );
+		}
+		return type;
+	}
+
+	protected Type determineType(String paramName, Object paramValue, Type defaultType) {
+		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
+		if ( type == null ) {
+			type = defaultType;
+		}
+		return type;
+	}
+
+	protected Type determineType(String paramName, Object paramValue) throws HibernateException {
+		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
+		if ( type == null ) {
+			type = guessType( paramValue );
+		}
+		return type;
+	}
+
+	protected Type determineType(String paramName, Class clazz) throws HibernateException {
+		Type type = parameterMetadata.getNamedParameterExpectedType( paramName );
+		if ( type == null ) {
+			type = guessType( clazz );
+		}
+		return type;
+	}
+
+	private Type guessType(Object param) throws HibernateException {
+		Class clazz = HibernateProxyHelper.getClassWithoutInitializingProxy( param );
+		return guessType( clazz );
+	}
+
+	private Type guessType(Class clazz) throws HibernateException {
+		String typename = clazz.getName();
+		Type type = TypeFactory.heuristicType(typename);
+		boolean serializable = type!=null && type instanceof SerializableType;
+		if (type==null || serializable) {
+			try {
+				session.getFactory().getEntityPersister( clazz.getName() );
+			}
+			catch (MappingException me) {
+				if (serializable) {
+					return type;
+				}
+				else {
+					throw new HibernateException("Could not determine a type for class: " + typename);
+				}
+			}
+			return Hibernate.entity(clazz);
+		}
+		else {
+			return type;
+		}
+	}
+
+	public Query setString(int position, String val) {
+		setParameter(position, val, Hibernate.STRING);
+		return this;
+	}
+
+	public Query setCharacter(int position, char val) {
+		setParameter(position, new Character(val), Hibernate.CHARACTER);
+		return this;
+	}
+
+	public Query setBoolean(int position, boolean val) {
+		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
+		Type typeToUse = determineType( position, valueToUse, Hibernate.BOOLEAN );
+		setParameter( position, valueToUse, typeToUse );
+		return this;
+	}
+
+	public Query setByte(int position, byte val) {
+		setParameter(position, new Byte(val), Hibernate.BYTE);
+		return this;
+	}
+
+	public Query setShort(int position, short val) {
+		setParameter(position, new Short(val), Hibernate.SHORT);
+		return this;
+	}
+
+	public Query setInteger(int position, int val) {
+		setParameter(position, new Integer(val), Hibernate.INTEGER);
+		return this;
+	}
+
+	public Query setLong(int position, long val) {
+		setParameter(position, new Long(val), Hibernate.LONG);
+		return this;
+	}
+
+	public Query setFloat(int position, float val) {
+		setParameter(position, new Float(val), Hibernate.FLOAT);
+		return this;
+	}
+
+	public Query setDouble(int position, double val) {
+		setParameter(position, new Double(val), Hibernate.DOUBLE);
+		return this;
+	}
+
+	public Query setBinary(int position, byte[] val) {
+		setParameter(position, val, Hibernate.BINARY);
+		return this;
+	}
+
+	public Query setText(int position, String val) {
+		setParameter(position, val, Hibernate.TEXT);
+		return this;
+	}
+
+	public Query setSerializable(int position, Serializable val) {
+		setParameter(position, val, Hibernate.SERIALIZABLE);
+		return this;
+	}
+
+	public Query setDate(int position, Date date) {
+		setParameter(position, date, Hibernate.DATE);
+		return this;
+	}
+
+	public Query setTime(int position, Date date) {
+		setParameter(position, date, Hibernate.TIME);
+		return this;
+	}
+
+	public Query setTimestamp(int position, Date date) {
+		setParameter(position, date, Hibernate.TIMESTAMP);
+		return this;
+	}
+
+	public Query setEntity(int position, Object val) {
+		setParameter( position, val, Hibernate.entity( resolveEntityName( val ) ) );
+		return this;
+	}
+
+	private String resolveEntityName(Object val) {
+		if ( val == null ) {
+			throw new IllegalArgumentException( "entity for parameter binding cannot be null" );
+		}
+		return session.bestGuessEntityName( val );
+	}
+
+	public Query setLocale(int position, Locale locale) {
+		setParameter(position, locale, Hibernate.LOCALE);
+		return this;
+	}
+
+	public Query setCalendar(int position, Calendar calendar) {
+		setParameter(position, calendar, Hibernate.CALENDAR);
+		return this;
+	}
+
+	public Query setCalendarDate(int position, Calendar calendar) {
+		setParameter(position, calendar, Hibernate.CALENDAR_DATE);
+		return this;
+	}
+
+	public Query setBinary(String name, byte[] val) {
+		setParameter(name, val, Hibernate.BINARY);
+		return this;
+	}
+
+	public Query setText(String name, String val) {
+		setParameter(name, val, Hibernate.TEXT);
+		return this;
+	}
+
+	public Query setBoolean(String name, boolean val) {
+		Boolean valueToUse = val ? Boolean.TRUE : Boolean.FALSE;
+		Type typeToUse = determineType( name, valueToUse, Hibernate.BOOLEAN );
+		setParameter( name, valueToUse, typeToUse );
+		return this;
+	}
+
+	public Query setByte(String name, byte val) {
+		setParameter(name, new Byte(val), Hibernate.BYTE);
+		return this;
+	}
+
+	public Query setCharacter(String name, char val) {
+		setParameter(name, new Character(val), Hibernate.CHARACTER);
+		return this;
+	}
+
+	public Query setDate(String name, Date date) {
+		setParameter(name, date, Hibernate.DATE);
+		return this;
+	}
+
+	public Query setDouble(String name, double val) {
+		setParameter(name, new Double(val), Hibernate.DOUBLE);
+		return this;
+	}
+
+	public Query setEntity(String name, Object val) {
+		setParameter( name, val, Hibernate.entity( resolveEntityName( val ) ) );
+		return this;
+	}
+
+	public Query setFloat(String name, float val) {
+		setParameter(name, new Float(val), Hibernate.FLOAT);
+		return this;
+	}
+
+	public Query setInteger(String name, int val) {
+		setParameter(name, new Integer(val), Hibernate.INTEGER);
+		return this;
+	}
+
+	public Query setLocale(String name, Locale locale) {
+		setParameter(name, locale, Hibernate.LOCALE);
+		return this;
+	}
+
+	public Query setCalendar(String name, Calendar calendar) {
+		setParameter(name, calendar, Hibernate.CALENDAR);
+		return this;
+	}
+
+	public Query setCalendarDate(String name, Calendar calendar) {
+		setParameter(name, calendar, Hibernate.CALENDAR_DATE);
+		return this;
+	}
+
+	public Query setLong(String name, long val) {
+		setParameter(name, new Long(val), Hibernate.LONG);
+		return this;
+	}
+
+	public Query setSerializable(String name, Serializable val) {
+		setParameter(name, val, Hibernate.SERIALIZABLE);
+		return this;
+	}
+
+	public Query setShort(String name, short val) {
+		setParameter(name, new Short(val), Hibernate.SHORT);
+		return this;
+	}
+
+	public Query setString(String name, String val) {
+		setParameter(name, val, Hibernate.STRING);
+		return this;
+	}
+
+	public Query setTime(String name, Date date) {
+		setParameter(name, date, Hibernate.TIME);
+		return this;
+	}
+
+	public Query setTimestamp(String name, Date date) {
+		setParameter(name, date, Hibernate.TIMESTAMP);
+		return this;
+	}
+
+	public Query setBigDecimal(int position, BigDecimal number) {
+		setParameter(position, number, Hibernate.BIG_DECIMAL);
+		return this;
+	}
+
+	public Query setBigDecimal(String name, BigDecimal number) {
+		setParameter(name, number, Hibernate.BIG_DECIMAL);
+		return this;
+	}
+
+	public Query setBigInteger(int position, BigInteger number) {
+		setParameter(position, number, Hibernate.BIG_INTEGER);
+		return this;
+	}
+
+	public Query setBigInteger(String name, BigInteger number) {
+		setParameter(name, number, Hibernate.BIG_INTEGER);
+		return this;
+	}
+
+	public Query setParameterList(String name, Collection vals, Type type) throws HibernateException {
+		if ( !parameterMetadata.getNamedParameterNames().contains( name ) ) {
+			throw new IllegalArgumentException("Parameter " + name + " does not exist as a named parameter in [" + getQueryString() + "]");
+		}
+		namedParameterLists.put( name, new TypedValue( type, vals, session.getEntityMode() ) );
+		return this;
+	}
+	
+	/**
+	 * Warning: adds new parameters to the argument by side-effect, as well as
+	 * mutating the query string!
+	 */
+	protected String expandParameterLists(Map namedParamsCopy) {
+		String query = this.queryString;
+		Iterator iter = namedParameterLists.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			query = expandParameterList( query, (String) me.getKey(), (TypedValue) me.getValue(), namedParamsCopy );
+		}
+		return query;
+	}
+
+	/**
+	 * Warning: adds new parameters to the argument by side-effect, as well as
+	 * mutating the query string!
+	 */
+	private String expandParameterList(String query, String name, TypedValue typedList, Map namedParamsCopy) {
+		Collection vals = (Collection) typedList.getValue();
+		Type type = typedList.getType();
+		if ( vals.size() == 1 ) {
+			// short-circuit for performance...
+			namedParamsCopy.put( name, new TypedValue( type, vals.iterator().next(), session.getEntityMode() ) );
+			return query;
+		}
+
+		StringBuffer list = new StringBuffer( 16 );
+		Iterator iter = vals.iterator();
+		int i = 0;
+		boolean isJpaPositionalParam = parameterMetadata.getNamedParameterDescriptor( name ).isJpaStyle();
+		while ( iter.hasNext() ) {
+			String alias = ( isJpaPositionalParam ? 'x' + name : name ) + i++ + '_';
+			namedParamsCopy.put( alias, new TypedValue( type, iter.next(), session.getEntityMode() ) );
+			list.append( ParserHelper.HQL_VARIABLE_PREFIX ).append( alias );
+			if ( iter.hasNext() ) {
+				list.append( ", " );
+			}
+		}
+		String paramPrefix = isJpaPositionalParam ? "?" : ParserHelper.HQL_VARIABLE_PREFIX;
+		return StringHelper.replace( query, paramPrefix + name, list.toString(), true );
+	}
+
+	public Query setParameterList(String name, Collection vals) throws HibernateException {
+		if ( vals == null ) {
+			throw new QueryException( "Collection must be not null!" );
+		}
+
+		if( vals.size() == 0 ) {
+			setParameterList( name, vals, null );
+		}
+		else {
+			setParameterList(name, vals, determineType( name, vals.iterator().next() ) );
+		}
+
+		return this;
+	}
+
+	public Query setParameterList(String name, Object[] vals, Type type) throws HibernateException {
+		return setParameterList( name, Arrays.asList(vals), type );
+	}
+
+	public Query setParameterList(String name, Object[] vals) throws HibernateException {
+		return setParameterList( name, Arrays.asList(vals) );
+	}
+
+	public Query setProperties(Map map) throws HibernateException {
+		String[] params = getNamedParameters();
+		for (int i = 0; i < params.length; i++) {
+			String namedParam = params[i];
+				final Object object = map.get(namedParam);
+				if(object==null) {
+					continue;
+				}
+				Class retType = object.getClass();
+				if ( Collection.class.isAssignableFrom( retType ) ) {
+					setParameterList( namedParam, ( Collection ) object );
+				}
+				else if ( retType.isArray() ) {
+					setParameterList( namedParam, ( Object[] ) object );
+				}
+				else {
+					setParameter( namedParam, object, determineType( namedParam, retType ) );
+				}
+
+			
+		}
+		return this;				
+	}
+	
+	public Query setProperties(Object bean) throws HibernateException {
+		Class clazz = bean.getClass();
+		String[] params = getNamedParameters();
+		for (int i = 0; i < params.length; i++) {
+			String namedParam = params[i];
+			try {
+				Getter getter = ReflectHelper.getGetter( clazz, namedParam );
+				Class retType = getter.getReturnType();
+				final Object object = getter.get( bean );
+				if ( Collection.class.isAssignableFrom( retType ) ) {
+					setParameterList( namedParam, ( Collection ) object );
+				}
+				else if ( retType.isArray() ) {
+				 	setParameterList( namedParam, ( Object[] ) object );
+				}
+				else {
+					setParameter( namedParam, object, determineType( namedParam, retType ) );
+				}
+			}
+			catch (PropertyNotFoundException pnfe) {
+				// ignore
+			}
+		}
+		return this;
+	}
+
+	public Query setParameters(Object[] values, Type[] types) {
+		this.values = Arrays.asList(values);
+		this.types = Arrays.asList(types);
+		return this;
+	}
+
+
+	// Execution methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Object uniqueResult() throws HibernateException {
+		return uniqueElement( list() );
+	}
+
+	static Object uniqueElement(List list) throws NonUniqueResultException {
+		int size = list.size();
+		if (size==0) return null;
+		Object first = list.get(0);
+		for ( int i=1; i<size; i++ ) {
+			if ( list.get(i)!=first ) {
+				throw new NonUniqueResultException( list.size() );
+			}
+		}
+		return first;
+	}
+
+	protected RowSelection getRowSelection() {
+		return selection;
+	}
+
+	public Type[] typeArray() {
+		return ArrayHelper.toTypeArray( getTypes() );
+	}
+	
+	public Object[] valueArray() {
+		return getValues().toArray();
+	}
+
+	public QueryParameters getQueryParameters(Map namedParams) {
+		return new QueryParameters(
+				typeArray(),
+				valueArray(),
+				namedParams,
+				getLockModes(),
+				getSelection(),
+				readOnly,
+				cacheable,
+				cacheRegion,
+				comment,
+				collectionKey == null ? null : new Serializable[] { collectionKey },
+				optionalObject,
+				optionalEntityName,
+				optionalId,
+				resultTransformer
+		);
+	}
+	
+	protected void before() {
+		if ( flushMode!=null ) {
+			sessionFlushMode = getSession().getFlushMode();
+			getSession().setFlushMode(flushMode);
+		}
+		if ( cacheMode!=null ) {
+			sessionCacheMode = getSession().getCacheMode();
+			getSession().setCacheMode(cacheMode);
+		}
+	}
+	
+	protected void after() {
+		if (sessionFlushMode!=null) {
+			getSession().setFlushMode(sessionFlushMode);
+			sessionFlushMode = null;
+		}
+		if (sessionCacheMode!=null) {
+			getSession().setCacheMode(sessionCacheMode);
+			sessionCacheMode = null;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,268 +0,0 @@
-//$Id: AbstractScrollableResults.java 7469 2005-07-14 13:12:19Z steveebersole $
-package org.hibernate.impl;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Locale;
-import java.util.TimeZone;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.loader.Loader;
-import org.hibernate.type.Type;
-
-/**
- * Implementation of the <tt>ScrollableResults</tt> interface
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractScrollableResults implements ScrollableResults {
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractScrollableResults.class );
-
-	private final ResultSet resultSet;
-	private final PreparedStatement ps;
-	private final SessionImplementor session;
-	private final Loader loader;
-	private final QueryParameters queryParameters;
-	private final Type[] types;
-	private HolderInstantiator holderInstantiator;
-
-	public AbstractScrollableResults(
-	        ResultSet rs,
-	        PreparedStatement ps,
-	        SessionImplementor sess,
-			Loader loader,
-			QueryParameters queryParameters,
-	        Type[] types,
-	        HolderInstantiator holderInstantiator) throws MappingException {
-		this.resultSet=rs;
-		this.ps=ps;
-		this.session = sess;
-		this.loader = loader;
-		this.queryParameters = queryParameters;
-		this.types = types;
-		this.holderInstantiator = holderInstantiator!=null && holderInstantiator.isRequired()
-		        ? holderInstantiator 
-		        : null;
-	}
-
-	protected abstract Object[] getCurrentRow();
-
-	protected ResultSet getResultSet() {
-		return resultSet;
-	}
-
-	protected PreparedStatement getPs() {
-		return ps;
-	}
-
-	protected SessionImplementor getSession() {
-		return session;
-	}
-
-	protected Loader getLoader() {
-		return loader;
-	}
-
-	protected QueryParameters getQueryParameters() {
-		return queryParameters;
-	}
-
-	protected Type[] getTypes() {
-		return types;
-	}
-
-	protected HolderInstantiator getHolderInstantiator() {
-		return holderInstantiator;
-	}
-
-	public final void close() throws HibernateException {
-		try {
-			// not absolutely necessary, but does help with aggressive release
-			session.getBatcher().closeQueryStatement( ps, resultSet );
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not close results"
-				);
-		}
-		finally {
-			try {
-				session.getPersistenceContext().getLoadContexts().cleanup( resultSet );
-			}
-			catch( Throwable ignore ) {
-				// ignore this error for now
-				log.trace( "exception trying to cleanup load context : " + ignore.getMessage() );
-			}
-		}
-	}
-
-	public final Object[] get() throws HibernateException {
-		return getCurrentRow();
-	}
-
-	public final Object get(int col) throws HibernateException {
-		return getCurrentRow()[col];
-	}
-
-	/**
-	 * Check that the requested type is compatible with the result type, and
-	 * return the column value.  This version makes sure the the classes
-	 * are identical.
-	 *
-	 * @param col the column
-	 * @param returnType a "final" type
-	 */
-	protected final Object getFinal(int col, Type returnType) throws HibernateException {
-		if ( holderInstantiator!=null ) {
-			throw new HibernateException("query specifies a holder class");
-		}
-		
-		if ( returnType.getReturnedClass()==types[col].getReturnedClass() ) {
-			return get(col);
-		}
-		else {
-			return throwInvalidColumnTypeException(col, types[col], returnType);
-		}
-	}
-
-	/**
-	 * Check that the requested type is compatible with the result type, and
-	 * return the column value.  This version makes sure the the classes
-	 * are "assignable".
-	 *
-	 * @param col the column
-	 * @param returnType any type
-	 */
-	protected final Object getNonFinal(int col, Type returnType) throws HibernateException {
-		if ( holderInstantiator!=null ) {
-			throw new HibernateException("query specifies a holder class");
-		}
-		
-		if ( returnType.getReturnedClass().isAssignableFrom( types[col].getReturnedClass() ) ) {
-			return get(col);
-		}
-		else {
-			return throwInvalidColumnTypeException(col, types[col], returnType);
-		}
-	}
-
-	public final BigDecimal getBigDecimal(int col) throws HibernateException {
-		return (BigDecimal) getFinal(col, Hibernate.BIG_DECIMAL);
-	}
-
-	public final BigInteger getBigInteger(int col) throws HibernateException {
-		return (BigInteger) getFinal(col, Hibernate.BIG_INTEGER);
-	}
-
-	public final byte[] getBinary(int col) throws HibernateException {
-		return (byte[]) getFinal(col, Hibernate.BINARY);
-	}
-
-	public final String getText(int col) throws HibernateException {
-		return (String) getFinal(col, Hibernate.TEXT);
-	}
-
-	public final Blob getBlob(int col) throws HibernateException {
-		return (Blob) getNonFinal(col, Hibernate.BLOB);
-	}
-
-	public final Clob getClob(int col) throws HibernateException {
-		return (Clob) getNonFinal(col, Hibernate.CLOB);
-	}
-
-	public final Boolean getBoolean(int col) throws HibernateException {
-		return (Boolean) getFinal(col, Hibernate.BOOLEAN);
-	}
-
-	public final Byte getByte(int col) throws HibernateException {
-		return (Byte) getFinal(col, Hibernate.BYTE);
-	}
-
-	public final Character getCharacter(int col) throws HibernateException {
-		return (Character) getFinal(col, Hibernate.CHARACTER);
-	}
-
-	public final Date getDate(int col) throws HibernateException {
-		return (Date) getNonFinal(col, Hibernate.TIMESTAMP);
-	}
-
-	public final Calendar getCalendar(int col) throws HibernateException {
-		return (Calendar) getNonFinal(col, Hibernate.CALENDAR);
-	}
-
-	public final Double getDouble(int col) throws HibernateException {
-		return (Double) getFinal(col, Hibernate.DOUBLE);
-	}
-
-	public final Float getFloat(int col) throws HibernateException {
-		return (Float) getFinal(col, Hibernate.FLOAT);
-	}
-
-	public final Integer getInteger(int col) throws HibernateException {
-		return (Integer) getFinal(col, Hibernate.INTEGER);
-	}
-
-	public final Long getLong(int col) throws HibernateException {
-		return (Long) getFinal(col, Hibernate.LONG);
-	}
-
-	public final Short getShort(int col) throws HibernateException {
-		return (Short) getFinal(col, Hibernate.SHORT);
-	}
-
-	public final String getString(int col) throws HibernateException {
-		return (String) getFinal(col, Hibernate.STRING);
-	}
-
-	public final Locale getLocale(int col) throws HibernateException {
-		return (Locale) getFinal(col, Hibernate.LOCALE);
-	}
-
-	/*public final Currency getCurrency(int col) throws HibernateException {
-		return (Currency) get(col);
-	}*/
-
-	public final TimeZone getTimeZone(int col) throws HibernateException {
-		return (TimeZone) getNonFinal(col, Hibernate.TIMEZONE);
-	}
-
-	public final Type getType(int i) {
-		return types[i];
-	}
-
-	private Object throwInvalidColumnTypeException(
-	        int i,
-	        Type type,
-	        Type returnType) throws HibernateException {
-		throw new HibernateException( 
-				"incompatible column types: " + 
-				type.getName() + 
-				", " + 
-				returnType.getName() 
-		);
-	}
-
-	protected void afterScrollOperation() {
-		session.afterScrollOperation();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractScrollableResults.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,291 @@
+/*
+ * 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.impl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.loader.Loader;
+import org.hibernate.type.Type;
+
+/**
+ * Implementation of the <tt>ScrollableResults</tt> interface
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractScrollableResults implements ScrollableResults {
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractScrollableResults.class );
+
+	private final ResultSet resultSet;
+	private final PreparedStatement ps;
+	private final SessionImplementor session;
+	private final Loader loader;
+	private final QueryParameters queryParameters;
+	private final Type[] types;
+	private HolderInstantiator holderInstantiator;
+
+	public AbstractScrollableResults(
+	        ResultSet rs,
+	        PreparedStatement ps,
+	        SessionImplementor sess,
+			Loader loader,
+			QueryParameters queryParameters,
+	        Type[] types,
+	        HolderInstantiator holderInstantiator) throws MappingException {
+		this.resultSet=rs;
+		this.ps=ps;
+		this.session = sess;
+		this.loader = loader;
+		this.queryParameters = queryParameters;
+		this.types = types;
+		this.holderInstantiator = holderInstantiator!=null && holderInstantiator.isRequired()
+		        ? holderInstantiator 
+		        : null;
+	}
+
+	protected abstract Object[] getCurrentRow();
+
+	protected ResultSet getResultSet() {
+		return resultSet;
+	}
+
+	protected PreparedStatement getPs() {
+		return ps;
+	}
+
+	protected SessionImplementor getSession() {
+		return session;
+	}
+
+	protected Loader getLoader() {
+		return loader;
+	}
+
+	protected QueryParameters getQueryParameters() {
+		return queryParameters;
+	}
+
+	protected Type[] getTypes() {
+		return types;
+	}
+
+	protected HolderInstantiator getHolderInstantiator() {
+		return holderInstantiator;
+	}
+
+	public final void close() throws HibernateException {
+		try {
+			// not absolutely necessary, but does help with aggressive release
+			session.getBatcher().closeQueryStatement( ps, resultSet );
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not close results"
+				);
+		}
+		finally {
+			try {
+				session.getPersistenceContext().getLoadContexts().cleanup( resultSet );
+			}
+			catch( Throwable ignore ) {
+				// ignore this error for now
+				log.trace( "exception trying to cleanup load context : " + ignore.getMessage() );
+			}
+		}
+	}
+
+	public final Object[] get() throws HibernateException {
+		return getCurrentRow();
+	}
+
+	public final Object get(int col) throws HibernateException {
+		return getCurrentRow()[col];
+	}
+
+	/**
+	 * Check that the requested type is compatible with the result type, and
+	 * return the column value.  This version makes sure the the classes
+	 * are identical.
+	 *
+	 * @param col the column
+	 * @param returnType a "final" type
+	 */
+	protected final Object getFinal(int col, Type returnType) throws HibernateException {
+		if ( holderInstantiator!=null ) {
+			throw new HibernateException("query specifies a holder class");
+		}
+		
+		if ( returnType.getReturnedClass()==types[col].getReturnedClass() ) {
+			return get(col);
+		}
+		else {
+			return throwInvalidColumnTypeException(col, types[col], returnType);
+		}
+	}
+
+	/**
+	 * Check that the requested type is compatible with the result type, and
+	 * return the column value.  This version makes sure the the classes
+	 * are "assignable".
+	 *
+	 * @param col the column
+	 * @param returnType any type
+	 */
+	protected final Object getNonFinal(int col, Type returnType) throws HibernateException {
+		if ( holderInstantiator!=null ) {
+			throw new HibernateException("query specifies a holder class");
+		}
+		
+		if ( returnType.getReturnedClass().isAssignableFrom( types[col].getReturnedClass() ) ) {
+			return get(col);
+		}
+		else {
+			return throwInvalidColumnTypeException(col, types[col], returnType);
+		}
+	}
+
+	public final BigDecimal getBigDecimal(int col) throws HibernateException {
+		return (BigDecimal) getFinal(col, Hibernate.BIG_DECIMAL);
+	}
+
+	public final BigInteger getBigInteger(int col) throws HibernateException {
+		return (BigInteger) getFinal(col, Hibernate.BIG_INTEGER);
+	}
+
+	public final byte[] getBinary(int col) throws HibernateException {
+		return (byte[]) getFinal(col, Hibernate.BINARY);
+	}
+
+	public final String getText(int col) throws HibernateException {
+		return (String) getFinal(col, Hibernate.TEXT);
+	}
+
+	public final Blob getBlob(int col) throws HibernateException {
+		return (Blob) getNonFinal(col, Hibernate.BLOB);
+	}
+
+	public final Clob getClob(int col) throws HibernateException {
+		return (Clob) getNonFinal(col, Hibernate.CLOB);
+	}
+
+	public final Boolean getBoolean(int col) throws HibernateException {
+		return (Boolean) getFinal(col, Hibernate.BOOLEAN);
+	}
+
+	public final Byte getByte(int col) throws HibernateException {
+		return (Byte) getFinal(col, Hibernate.BYTE);
+	}
+
+	public final Character getCharacter(int col) throws HibernateException {
+		return (Character) getFinal(col, Hibernate.CHARACTER);
+	}
+
+	public final Date getDate(int col) throws HibernateException {
+		return (Date) getNonFinal(col, Hibernate.TIMESTAMP);
+	}
+
+	public final Calendar getCalendar(int col) throws HibernateException {
+		return (Calendar) getNonFinal(col, Hibernate.CALENDAR);
+	}
+
+	public final Double getDouble(int col) throws HibernateException {
+		return (Double) getFinal(col, Hibernate.DOUBLE);
+	}
+
+	public final Float getFloat(int col) throws HibernateException {
+		return (Float) getFinal(col, Hibernate.FLOAT);
+	}
+
+	public final Integer getInteger(int col) throws HibernateException {
+		return (Integer) getFinal(col, Hibernate.INTEGER);
+	}
+
+	public final Long getLong(int col) throws HibernateException {
+		return (Long) getFinal(col, Hibernate.LONG);
+	}
+
+	public final Short getShort(int col) throws HibernateException {
+		return (Short) getFinal(col, Hibernate.SHORT);
+	}
+
+	public final String getString(int col) throws HibernateException {
+		return (String) getFinal(col, Hibernate.STRING);
+	}
+
+	public final Locale getLocale(int col) throws HibernateException {
+		return (Locale) getFinal(col, Hibernate.LOCALE);
+	}
+
+	/*public final Currency getCurrency(int col) throws HibernateException {
+		return (Currency) get(col);
+	}*/
+
+	public final TimeZone getTimeZone(int col) throws HibernateException {
+		return (TimeZone) getNonFinal(col, Hibernate.TIMEZONE);
+	}
+
+	public final Type getType(int i) {
+		return types[i];
+	}
+
+	private Object throwInvalidColumnTypeException(
+	        int i,
+	        Type type,
+	        Type returnType) throws HibernateException {
+		throw new HibernateException( 
+				"incompatible column types: " + 
+				type.getName() + 
+				", " + 
+				returnType.getName() 
+		);
+	}
+
+	protected void afterScrollOperation() {
+		session.afterScrollOperation();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,150 +0,0 @@
-//$Id: AbstractSessionImpl.java 10018 2006-06-15 05:21:06Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import org.hibernate.MappingException;
-import org.hibernate.Query;
-import org.hibernate.SQLQuery;
-import org.hibernate.HibernateException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.SessionException;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.query.HQLQueryPlan;
-import org.hibernate.engine.query.NativeSQLQueryPlan;
-
-import java.util.List;
-
-/**
- * Functionality common to stateless and stateful sessions
- * 
- * @author Gavin King
- */
-public abstract class AbstractSessionImpl implements SessionImplementor {
-
-	protected transient SessionFactoryImpl factory;
-	private boolean closed = false;
-
-	protected AbstractSessionImpl(SessionFactoryImpl factory) {
-		this.factory = factory;
-	}
-
-	public SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	public boolean isClosed() {
-		return closed;
-	}
-
-	protected void setClosed() {
-		closed = true;
-	}
-
-	protected void errorIfClosed() {
-		if ( closed ) {
-			throw new SessionException( "Session is closed!" );
-		}
-	}
-
-	public Query getNamedQuery(String queryName) throws MappingException {
-		errorIfClosed();
-		NamedQueryDefinition nqd = factory.getNamedQuery( queryName );
-		final Query query;
-		if ( nqd != null ) {
-			String queryString = nqd.getQueryString();
-			query = new QueryImpl(
-					queryString,
-			        nqd.getFlushMode(),
-			        this,
-			        getHQLQueryPlan( queryString, false ).getParameterMetadata()
-			);
-			query.setComment( "named HQL query " + queryName );
-		}
-		else {
-			NamedSQLQueryDefinition nsqlqd = factory.getNamedSQLQuery( queryName );
-			if ( nsqlqd==null ) {
-				throw new MappingException( "Named query not known: " + queryName );
-			}
-			query = new SQLQueryImpl(
-					nsqlqd,
-			        this,
-			        factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() )
-			);
-			query.setComment( "named native SQL query " + queryName );
-			nqd = nsqlqd;
-		}
-		initQuery( query, nqd );
-		return query;
-	}
-
-	public Query getNamedSQLQuery(String queryName) throws MappingException {
-		errorIfClosed();
-		NamedSQLQueryDefinition nsqlqd = factory.getNamedSQLQuery( queryName );
-		if ( nsqlqd==null ) {
-			throw new MappingException( "Named SQL query not known: " + queryName );
-		}
-		Query query = new SQLQueryImpl(
-				nsqlqd,
-		        this,
-		        factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() )
-		);
-		query.setComment( "named native SQL query " + queryName );
-		initQuery( query, nsqlqd );
-		return query;
-	}
-
-	private void initQuery(Query query, NamedQueryDefinition nqd) {
-		query.setCacheable( nqd.isCacheable() );
-		query.setCacheRegion( nqd.getCacheRegion() );
-		if ( nqd.getTimeout()!=null ) query.setTimeout( nqd.getTimeout().intValue() );
-		if ( nqd.getFetchSize()!=null ) query.setFetchSize( nqd.getFetchSize().intValue() );
-		if ( nqd.getCacheMode() != null ) query.setCacheMode( nqd.getCacheMode() );
-		query.setReadOnly( nqd.isReadOnly() );
-		if ( nqd.getComment() != null ) query.setComment( nqd.getComment() );
-	}
-
-	public Query createQuery(String queryString) {
-		errorIfClosed();
-		QueryImpl query = new QueryImpl(
-				queryString,
-		        this,
-		        getHQLQueryPlan( queryString, false ).getParameterMetadata()
-		);
-		query.setComment( queryString );
-		return query;
-	}
-
-	public SQLQuery createSQLQuery(String sql) {
-		errorIfClosed();
-		SQLQueryImpl query = new SQLQueryImpl(
-				sql,
-		        this,
-		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
-		);
-		query.setComment( "dynamic native SQL query" );
-		return query;
-	}
-
-	protected HQLQueryPlan getHQLQueryPlan(String query, boolean shallow) throws HibernateException {
-		return factory.getQueryPlanCache().getHQLQueryPlan( query, shallow, getEnabledFilters() );
-	}
-
-	protected NativeSQLQueryPlan getNativeSQLQueryPlan(NativeSQLQuerySpecification spec) throws HibernateException {
-		return factory.getQueryPlanCache().getNativeSQLQueryPlan( spec );
-	}
-
-	public List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
-			throws HibernateException {
-		return listCustomQuery( getNativeSQLQueryPlan( spec ).getCustomQuery(), queryParameters );
-	}
-
-	public ScrollableResults scroll(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
-			throws HibernateException {
-		return scrollCustomQuery( getNativeSQLQueryPlan( spec ).getCustomQuery(), queryParameters );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/AbstractSessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,173 @@
+/*
+ * 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.impl;
+
+import org.hibernate.MappingException;
+import org.hibernate.Query;
+import org.hibernate.SQLQuery;
+import org.hibernate.HibernateException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.SessionException;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.query.HQLQueryPlan;
+import org.hibernate.engine.query.NativeSQLQueryPlan;
+
+import java.util.List;
+
+/**
+ * Functionality common to stateless and stateful sessions
+ * 
+ * @author Gavin King
+ */
+public abstract class AbstractSessionImpl implements SessionImplementor {
+
+	protected transient SessionFactoryImpl factory;
+	private boolean closed = false;
+
+	protected AbstractSessionImpl(SessionFactoryImpl factory) {
+		this.factory = factory;
+	}
+
+	public SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	public boolean isClosed() {
+		return closed;
+	}
+
+	protected void setClosed() {
+		closed = true;
+	}
+
+	protected void errorIfClosed() {
+		if ( closed ) {
+			throw new SessionException( "Session is closed!" );
+		}
+	}
+
+	public Query getNamedQuery(String queryName) throws MappingException {
+		errorIfClosed();
+		NamedQueryDefinition nqd = factory.getNamedQuery( queryName );
+		final Query query;
+		if ( nqd != null ) {
+			String queryString = nqd.getQueryString();
+			query = new QueryImpl(
+					queryString,
+			        nqd.getFlushMode(),
+			        this,
+			        getHQLQueryPlan( queryString, false ).getParameterMetadata()
+			);
+			query.setComment( "named HQL query " + queryName );
+		}
+		else {
+			NamedSQLQueryDefinition nsqlqd = factory.getNamedSQLQuery( queryName );
+			if ( nsqlqd==null ) {
+				throw new MappingException( "Named query not known: " + queryName );
+			}
+			query = new SQLQueryImpl(
+					nsqlqd,
+			        this,
+			        factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() )
+			);
+			query.setComment( "named native SQL query " + queryName );
+			nqd = nsqlqd;
+		}
+		initQuery( query, nqd );
+		return query;
+	}
+
+	public Query getNamedSQLQuery(String queryName) throws MappingException {
+		errorIfClosed();
+		NamedSQLQueryDefinition nsqlqd = factory.getNamedSQLQuery( queryName );
+		if ( nsqlqd==null ) {
+			throw new MappingException( "Named SQL query not known: " + queryName );
+		}
+		Query query = new SQLQueryImpl(
+				nsqlqd,
+		        this,
+		        factory.getQueryPlanCache().getSQLParameterMetadata( nsqlqd.getQueryString() )
+		);
+		query.setComment( "named native SQL query " + queryName );
+		initQuery( query, nsqlqd );
+		return query;
+	}
+
+	private void initQuery(Query query, NamedQueryDefinition nqd) {
+		query.setCacheable( nqd.isCacheable() );
+		query.setCacheRegion( nqd.getCacheRegion() );
+		if ( nqd.getTimeout()!=null ) query.setTimeout( nqd.getTimeout().intValue() );
+		if ( nqd.getFetchSize()!=null ) query.setFetchSize( nqd.getFetchSize().intValue() );
+		if ( nqd.getCacheMode() != null ) query.setCacheMode( nqd.getCacheMode() );
+		query.setReadOnly( nqd.isReadOnly() );
+		if ( nqd.getComment() != null ) query.setComment( nqd.getComment() );
+	}
+
+	public Query createQuery(String queryString) {
+		errorIfClosed();
+		QueryImpl query = new QueryImpl(
+				queryString,
+		        this,
+		        getHQLQueryPlan( queryString, false ).getParameterMetadata()
+		);
+		query.setComment( queryString );
+		return query;
+	}
+
+	public SQLQuery createSQLQuery(String sql) {
+		errorIfClosed();
+		SQLQueryImpl query = new SQLQueryImpl(
+				sql,
+		        this,
+		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
+		);
+		query.setComment( "dynamic native SQL query" );
+		return query;
+	}
+
+	protected HQLQueryPlan getHQLQueryPlan(String query, boolean shallow) throws HibernateException {
+		return factory.getQueryPlanCache().getHQLQueryPlan( query, shallow, getEnabledFilters() );
+	}
+
+	protected NativeSQLQueryPlan getNativeSQLQueryPlan(NativeSQLQuerySpecification spec) throws HibernateException {
+		return factory.getQueryPlanCache().getNativeSQLQueryPlan( spec );
+	}
+
+	public List list(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
+			throws HibernateException {
+		return listCustomQuery( getNativeSQLQueryPlan( spec ).getCustomQuery(), queryParameters );
+	}
+
+	public ScrollableResults scroll(NativeSQLQuerySpecification spec, QueryParameters queryParameters)
+			throws HibernateException {
+		return scrollCustomQuery( getNativeSQLQueryPlan( spec ).getCustomQuery(), queryParameters );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-//$Id: CollectionFilterImpl.java 8524 2005-11-04 21:28:49Z steveebersole $
-package org.hibernate.impl;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.query.ParameterMetadata;
-import org.hibernate.type.Type;
-
-/**
- * implementation of the <tt>Query</tt> interface for collection filters
- * @author Gavin King
- */
-public class CollectionFilterImpl extends QueryImpl {
-
-	private Object collection;
-
-	public CollectionFilterImpl(
-			String queryString,
-	        Object collection,
-	        SessionImplementor session,
-	        ParameterMetadata parameterMetadata) {
-		super( queryString, session, parameterMetadata );
-		this.collection = collection;
-	}
-
-
-	/**
-	 * @see org.hibernate.Query#iterate()
-	 */
-	public Iterator iterate() throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		return getSession().iterateFilter( 
-				collection, 
-				expandParameterLists(namedParams),
-				getQueryParameters(namedParams) 
-		);
-	}
-
-	/**
-	 * @see org.hibernate.Query#list()
-	 */
-	public List list() throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		return getSession().listFilter( 
-				collection, 
-				expandParameterLists(namedParams),
-				getQueryParameters(namedParams) 
-		);
-	}
-
-	/**
-	 * @see org.hibernate.Query#scroll()
-	 */
-	public ScrollableResults scroll() throws HibernateException {
-		throw new UnsupportedOperationException("Can't scroll filters");
-	}
-
-	public Type[] typeArray() {
-		List typeList = getTypes();
-		int size = typeList.size();
-		Type[] result = new Type[size+1];
-		for (int i=0; i<size; i++) result[i+1] = (Type) typeList.get(i);
-		return result;
-	}
-
-	public Object[] valueArray() {
-		List valueList = getValues();
-		int size = valueList.size();
-		Object[] result = new Object[size+1];
-		for (int i=0; i<size; i++) result[i+1] = valueList.get(i);
-		return result;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CollectionFilterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.impl;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.ParameterMetadata;
+import org.hibernate.type.Type;
+
+/**
+ * implementation of the <tt>Query</tt> interface for collection filters
+ * @author Gavin King
+ */
+public class CollectionFilterImpl extends QueryImpl {
+
+	private Object collection;
+
+	public CollectionFilterImpl(
+			String queryString,
+	        Object collection,
+	        SessionImplementor session,
+	        ParameterMetadata parameterMetadata) {
+		super( queryString, session, parameterMetadata );
+		this.collection = collection;
+	}
+
+
+	/**
+	 * @see org.hibernate.Query#iterate()
+	 */
+	public Iterator iterate() throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		return getSession().iterateFilter( 
+				collection, 
+				expandParameterLists(namedParams),
+				getQueryParameters(namedParams) 
+		);
+	}
+
+	/**
+	 * @see org.hibernate.Query#list()
+	 */
+	public List list() throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		return getSession().listFilter( 
+				collection, 
+				expandParameterLists(namedParams),
+				getQueryParameters(namedParams) 
+		);
+	}
+
+	/**
+	 * @see org.hibernate.Query#scroll()
+	 */
+	public ScrollableResults scroll() throws HibernateException {
+		throw new UnsupportedOperationException("Can't scroll filters");
+	}
+
+	public Type[] typeArray() {
+		List typeList = getTypes();
+		int size = typeList.size();
+		Type[] result = new Type[size+1];
+		for (int i=0; i<size; i++) result[i+1] = (Type) typeList.get(i);
+		return result;
+	}
+
+	public Object[] valueArray() {
+		List valueList = getValues();
+		int size = valueList.size();
+		Object[] result = new Object[size+1];
+		for (int i=0; i<size; i++) result[i+1] = valueList.get(i);
+		return result;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,575 +0,0 @@
-//$Id: CriteriaImpl.java 9116 2006-01-23 21:21:01Z steveebersole $
-package org.hibernate.impl;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.CacheMode;
-import org.hibernate.Criteria;
-import org.hibernate.FetchMode;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.criterion.Criterion;
-import org.hibernate.criterion.NaturalIdentifier;
-import org.hibernate.criterion.Order;
-import org.hibernate.criterion.Projection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.util.StringHelper;
-
-/**
- * Implementation of the <tt>Criteria</tt> interface
- * @author Gavin King
- */
-public class CriteriaImpl implements Criteria, Serializable {
-
-	private final String entityOrClassName;
-	private transient SessionImplementor session;
-	private final String rootAlias;
-
-	private List criterionEntries = new ArrayList();
-	private List orderEntries = new ArrayList();
-	private Projection projection;
-	private Criteria projectionCriteria;
-
-	private List subcriteriaList = new ArrayList();
-
-	private Map fetchModes = new HashMap();
-	private Map lockModes = new HashMap();
-
-	private Integer maxResults;
-	private Integer firstResult;
-	private Integer timeout;
-	private Integer fetchSize;
-
-	private boolean cacheable;
-	private String cacheRegion;
-	private String comment;
-
-	private FlushMode flushMode;
-	private CacheMode cacheMode;
-	private FlushMode sessionFlushMode;
-	private CacheMode sessionCacheMode;
-	
-	private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;
-
-
-	// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public CriteriaImpl(String entityOrClassName, SessionImplementor session) {
-		this(entityOrClassName, ROOT_ALIAS, session);
-	}
-
-	public CriteriaImpl(String entityOrClassName, String alias, SessionImplementor session) {
-		this.session = session;
-		this.entityOrClassName = entityOrClassName;
-		this.cacheable = false;
-		this.rootAlias = alias;
-	}
-
-	public String toString() {
-		return "CriteriaImpl(" +
-			entityOrClassName + ":" +
-			(rootAlias==null ? "" : rootAlias) +
-			subcriteriaList.toString() +
-			criterionEntries.toString() +
-			( projection==null ? "" : projection.toString() ) +
-			')';
-	}
-
-
-	// State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public SessionImplementor getSession() {
-		return session;
-	}
-
-	public void setSession(SessionImplementor session) {
-		this.session = session;
-	}
-
-	public String getEntityOrClassName() {
-		return entityOrClassName;
-	}
-
-	public Map getLockModes() {
-		return lockModes;
-	}
-
-	public Criteria getProjectionCriteria() {
-		return projectionCriteria;
-	}
-
-	public Iterator iterateSubcriteria() {
-		return subcriteriaList.iterator();
-	}
-
-	public Iterator iterateExpressionEntries() {
-		return criterionEntries.iterator();
-	}
-
-	public Iterator iterateOrderings() {
-		return orderEntries.iterator();
-	}
-
-	public Criteria add(Criteria criteriaInst, Criterion expression) {
-		criterionEntries.add( new CriterionEntry(expression, criteriaInst) );
-		return this;
-	}
-
-
-	// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public String getAlias() {
-		return rootAlias;
-	}
-
-	public Projection getProjection() {
-		return projection;
-	}
-
-	public Criteria setProjection(Projection projection) {
-		this.projection = projection;
-		this.projectionCriteria = this;
-		setResultTransformer( PROJECTION );
-		return this;
-	}
-
-	public Criteria add(Criterion expression) {
-		add( this, expression );
-		return this;
-	}
-
-	public Criteria addOrder(Order ordering) {
-		orderEntries.add( new OrderEntry( ordering, this ) );
-		return this;
-	}
-
-	public FetchMode getFetchMode(String path) {
-		return (FetchMode) fetchModes.get(path);
-	}
-
-	public Criteria setFetchMode(String associationPath, FetchMode mode) {
-		fetchModes.put( associationPath, mode );
-		return this;
-	}
-
-	public Criteria setLockMode(LockMode lockMode) {
-		return setLockMode( getAlias(), lockMode );
-	}
-
-	public Criteria setLockMode(String alias, LockMode lockMode) {
-		lockModes.put( alias, lockMode );
-		return this;
-	}
-
-	public Criteria createAlias(String associationPath, String alias) {
-		return createAlias( associationPath, alias, INNER_JOIN );
-	}
-
-	public Criteria createAlias(String associationPath, String alias, int joinType) {
-		new Subcriteria( this, associationPath, alias, joinType );
-		return this;
-	}
-
-	public Criteria createCriteria(String associationPath) {
-		return createCriteria( associationPath, INNER_JOIN );
-	}
-
-	public Criteria createCriteria(String associationPath, int joinType) {
-		return new Subcriteria( this, associationPath, joinType );
-	}
-
-	public Criteria createCriteria(String associationPath, String alias) {
-		return createCriteria( associationPath, alias, INNER_JOIN );
-	}
-
-	public Criteria createCriteria(String associationPath, String alias, int joinType) {
-		return new Subcriteria( this, associationPath, alias, joinType );
-	}
-
-	public ResultTransformer getResultTransformer() {
-		return resultTransformer;
-	}
-
-	public Criteria setResultTransformer(ResultTransformer tupleMapper) {
-		this.resultTransformer = tupleMapper;
-		return this;
-	}
-
-	public Integer getMaxResults() {
-		return maxResults;
-	}
-
-	public Criteria setMaxResults(int maxResults) {
-		this.maxResults = new Integer(maxResults);
-		return this;
-	}
-
-	public Integer getFirstResult() {
-		return firstResult;
-	}
-
-	public Criteria setFirstResult(int firstResult) {
-		this.firstResult = new Integer(firstResult);
-		return this;
-	}
-
-	public Integer getFetchSize() {
-		return fetchSize;
-	}
-
-	public Criteria setFetchSize(int fetchSize) {
-		this.fetchSize = new Integer(fetchSize);
-		return this;
-	}
-
-	public Integer getTimeout() {
-		return timeout;
-	}
-
-	public Criteria setTimeout(int timeout) {
-		this.timeout = new Integer(timeout);
-		return this;
-	}
-
-	public boolean getCacheable() {
-		return this.cacheable;
-	}
-
-	public Criteria setCacheable(boolean cacheable) {
-		this.cacheable = cacheable;
-		return this;
-	}
-
-	public String getCacheRegion() {
-		return this.cacheRegion;
-	}
-
-	public Criteria setCacheRegion(String cacheRegion) {
-		this.cacheRegion = cacheRegion.trim();
-		return this;
-	}
-
-	public String getComment() {
-		return comment;
-	}
-
-	public Criteria setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public Criteria setFlushMode(FlushMode flushMode) {
-		this.flushMode = flushMode;
-		return this;
-	}
-
-	public Criteria setCacheMode(CacheMode cacheMode) {
-		this.cacheMode = cacheMode;
-		return this;
-	}
-
-	public List list() throws HibernateException {
-		before();
-		try {
-			return session.list( this );
-		}
-		finally {
-			after();
-		}
-	}
-	
-	public ScrollableResults scroll() {
-		return scroll( ScrollMode.SCROLL_INSENSITIVE );
-	}
-
-	public ScrollableResults scroll(ScrollMode scrollMode) {
-		before();
-		try {
-			return session.scroll(this, scrollMode);
-		}
-		finally {
-			after();
-		}
-	}
-
-	public Object uniqueResult() throws HibernateException {
-		return AbstractQueryImpl.uniqueElement( list() );
-	}
-
-	protected void before() {
-		if ( flushMode != null ) {
-			sessionFlushMode = getSession().getFlushMode();
-			getSession().setFlushMode( flushMode );
-		}
-		if ( cacheMode != null ) {
-			sessionCacheMode = getSession().getCacheMode();
-			getSession().setCacheMode( cacheMode );
-		}
-	}
-	
-	protected void after() {
-		if ( sessionFlushMode != null ) {
-			getSession().setFlushMode( sessionFlushMode );
-			sessionFlushMode = null;
-		}
-		if ( sessionCacheMode != null ) {
-			getSession().setCacheMode( sessionCacheMode );
-			sessionCacheMode = null;
-		}
-	}
-	
-	public boolean isLookupByNaturalKey() {
-		if ( projection != null ) {
-			return false;
-		}
-		if ( subcriteriaList.size() > 0 ) {
-			return false;
-		}
-		if ( criterionEntries.size() != 1 ) {
-			return false;
-		}
-		CriterionEntry ce = (CriterionEntry) criterionEntries.get(0);
-		return ce.getCriterion() instanceof NaturalIdentifier;
-	}
-
-
-	// Inner classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public final class Subcriteria implements Criteria, Serializable {
-
-		private String alias;
-		private String path;
-		private Criteria parent;
-		private LockMode lockMode;
-		private int joinType;
-
-
-		// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		private Subcriteria(Criteria parent, String path, String alias, int joinType) {
-			this.alias = alias;
-			this.path = path;
-			this.parent = parent;
-			this.joinType = joinType;
-			CriteriaImpl.this.subcriteriaList.add(this);
-		}
-
-		private Subcriteria(Criteria parent, String path, int joinType) {
-			this( parent, path, null, joinType );
-		}
-
-		public String toString() {
-			return "Subcriteria(" +
-				path + ":" +
-				(alias==null ? "" : alias) +
-				')';
-		}
-
-
-		// State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		public String getAlias() {
-			return alias;
-		}
-
-		public void setAlias(String alias) {
-			this.alias = alias;
-		}
-
-		public String getPath() {
-			return path;
-		}
-
-		public Criteria getParent() {
-			return parent;
-		}
-
-		public LockMode getLockMode() {
-			return lockMode;
-		}
-
-		public Criteria setLockMode(LockMode lockMode) {
-			this.lockMode = lockMode;
-			return this;
-		}
-
-		public int getJoinType() {
-			return joinType;
-		}
-
-
-		// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		public Criteria add(Criterion expression) {
-			CriteriaImpl.this.add(this, expression);
-			return this;
-		}
-
-		public Criteria addOrder(Order order) {
-			CriteriaImpl.this.orderEntries.add( new OrderEntry(order, this) );
-			return this;
-		}
-
-		public Criteria createAlias(String associationPath, String alias) {
-			return createAlias( associationPath, alias, INNER_JOIN );
-		}
-
-		public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
-			new Subcriteria( this, associationPath, alias, joinType );
-			return this;
-		}
-
-		public Criteria createCriteria(String associationPath) {
-			return createCriteria( associationPath, INNER_JOIN );
-		}
-
-		public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
-			return new Subcriteria( Subcriteria.this, associationPath, joinType );
-		}
-
-		public Criteria createCriteria(String associationPath, String alias) {
-			return createCriteria( associationPath, alias, INNER_JOIN );
-		}
-
-		public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
-			return new Subcriteria( Subcriteria.this, associationPath, alias, joinType );
-		}
-
-		public Criteria setCacheable(boolean cacheable) {
-			CriteriaImpl.this.setCacheable(cacheable);
-			return this;
-		}
-
-		public Criteria setCacheRegion(String cacheRegion) {
-			CriteriaImpl.this.setCacheRegion(cacheRegion);
-			return this;
-		}
-
-		public List list() throws HibernateException {
-			return CriteriaImpl.this.list();
-		}
-
-		public ScrollableResults scroll() throws HibernateException {
-			return CriteriaImpl.this.scroll();
-		}
-
-		public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
-			return CriteriaImpl.this.scroll(scrollMode);
-		}
-
-		public Object uniqueResult() throws HibernateException {
-			return CriteriaImpl.this.uniqueResult();
-		}
-
-		public Criteria setFetchMode(String associationPath, FetchMode mode)
-			throws HibernateException {
-			CriteriaImpl.this.setFetchMode( StringHelper.qualify(path, associationPath), mode);
-			return this;
-		}
-
-		public Criteria setFlushMode(FlushMode flushMode) {
-			CriteriaImpl.this.setFlushMode(flushMode);
-			return this;
-		}
-
-		public Criteria setCacheMode(CacheMode cacheMode) {
-			CriteriaImpl.this.setCacheMode(cacheMode);
-			return this;
-		}
-
-		public Criteria setFirstResult(int firstResult) {
-			CriteriaImpl.this.setFirstResult(firstResult);
-			return this;
-		}
-
-		public Criteria setMaxResults(int maxResults) {
-			CriteriaImpl.this.setMaxResults(maxResults);
-			return this;
-		}
-
-		public Criteria setTimeout(int timeout) {
-			CriteriaImpl.this.setTimeout(timeout);
-			return this;
-		}
-
-		public Criteria setFetchSize(int fetchSize) {
-			CriteriaImpl.this.setFetchSize(fetchSize);
-			return this;
-		}
-
-		public Criteria setLockMode(String alias, LockMode lockMode) {
-			CriteriaImpl.this.setLockMode(alias, lockMode);
-			return this;
-		}
-
-		public Criteria setResultTransformer(ResultTransformer resultProcessor) {
-			CriteriaImpl.this.setResultTransformer(resultProcessor);
-			return this;
-		}
-
-		public Criteria setComment(String comment) {
-			CriteriaImpl.this.setComment(comment);
-			return this;
-		}
-
-		public Criteria setProjection(Projection projection) {
-			CriteriaImpl.this.projection = projection;
-			CriteriaImpl.this.projectionCriteria = this;
-			setResultTransformer(PROJECTION);
-			return this;
-		}
-	}
-
-	public static final class CriterionEntry implements Serializable {
-		private final Criterion criterion;
-		private final Criteria criteria;
-
-		private CriterionEntry(Criterion criterion, Criteria criteria) {
-			this.criteria = criteria;
-			this.criterion = criterion;
-		}
-
-		public Criterion getCriterion() {
-			return criterion;
-		}
-
-		public Criteria getCriteria() {
-			return criteria;
-		}
-
-		public String toString() {
-			return criterion.toString();
-		}
-	}
-
-	public static final class OrderEntry implements Serializable {
-		private final Order order;
-		private final Criteria criteria;
-
-		private OrderEntry(Order order, Criteria criteria) {
-			this.criteria = criteria;
-			this.order = order;
-		}
-
-		public Order getOrder() {
-			return order;
-		}
-
-		public Criteria getCriteria() {
-			return criteria;
-		}
-
-		public String toString() {
-			return order.toString();
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/CriteriaImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/CriteriaImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,598 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Criteria;
+import org.hibernate.FetchMode;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.criterion.Criterion;
+import org.hibernate.criterion.NaturalIdentifier;
+import org.hibernate.criterion.Order;
+import org.hibernate.criterion.Projection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Implementation of the <tt>Criteria</tt> interface
+ * @author Gavin King
+ */
+public class CriteriaImpl implements Criteria, Serializable {
+
+	private final String entityOrClassName;
+	private transient SessionImplementor session;
+	private final String rootAlias;
+
+	private List criterionEntries = new ArrayList();
+	private List orderEntries = new ArrayList();
+	private Projection projection;
+	private Criteria projectionCriteria;
+
+	private List subcriteriaList = new ArrayList();
+
+	private Map fetchModes = new HashMap();
+	private Map lockModes = new HashMap();
+
+	private Integer maxResults;
+	private Integer firstResult;
+	private Integer timeout;
+	private Integer fetchSize;
+
+	private boolean cacheable;
+	private String cacheRegion;
+	private String comment;
+
+	private FlushMode flushMode;
+	private CacheMode cacheMode;
+	private FlushMode sessionFlushMode;
+	private CacheMode sessionCacheMode;
+	
+	private ResultTransformer resultTransformer = Criteria.ROOT_ENTITY;
+
+
+	// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public CriteriaImpl(String entityOrClassName, SessionImplementor session) {
+		this(entityOrClassName, ROOT_ALIAS, session);
+	}
+
+	public CriteriaImpl(String entityOrClassName, String alias, SessionImplementor session) {
+		this.session = session;
+		this.entityOrClassName = entityOrClassName;
+		this.cacheable = false;
+		this.rootAlias = alias;
+	}
+
+	public String toString() {
+		return "CriteriaImpl(" +
+			entityOrClassName + ":" +
+			(rootAlias==null ? "" : rootAlias) +
+			subcriteriaList.toString() +
+			criterionEntries.toString() +
+			( projection==null ? "" : projection.toString() ) +
+			')';
+	}
+
+
+	// State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public SessionImplementor getSession() {
+		return session;
+	}
+
+	public void setSession(SessionImplementor session) {
+		this.session = session;
+	}
+
+	public String getEntityOrClassName() {
+		return entityOrClassName;
+	}
+
+	public Map getLockModes() {
+		return lockModes;
+	}
+
+	public Criteria getProjectionCriteria() {
+		return projectionCriteria;
+	}
+
+	public Iterator iterateSubcriteria() {
+		return subcriteriaList.iterator();
+	}
+
+	public Iterator iterateExpressionEntries() {
+		return criterionEntries.iterator();
+	}
+
+	public Iterator iterateOrderings() {
+		return orderEntries.iterator();
+	}
+
+	public Criteria add(Criteria criteriaInst, Criterion expression) {
+		criterionEntries.add( new CriterionEntry(expression, criteriaInst) );
+		return this;
+	}
+
+
+	// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public String getAlias() {
+		return rootAlias;
+	}
+
+	public Projection getProjection() {
+		return projection;
+	}
+
+	public Criteria setProjection(Projection projection) {
+		this.projection = projection;
+		this.projectionCriteria = this;
+		setResultTransformer( PROJECTION );
+		return this;
+	}
+
+	public Criteria add(Criterion expression) {
+		add( this, expression );
+		return this;
+	}
+
+	public Criteria addOrder(Order ordering) {
+		orderEntries.add( new OrderEntry( ordering, this ) );
+		return this;
+	}
+
+	public FetchMode getFetchMode(String path) {
+		return (FetchMode) fetchModes.get(path);
+	}
+
+	public Criteria setFetchMode(String associationPath, FetchMode mode) {
+		fetchModes.put( associationPath, mode );
+		return this;
+	}
+
+	public Criteria setLockMode(LockMode lockMode) {
+		return setLockMode( getAlias(), lockMode );
+	}
+
+	public Criteria setLockMode(String alias, LockMode lockMode) {
+		lockModes.put( alias, lockMode );
+		return this;
+	}
+
+	public Criteria createAlias(String associationPath, String alias) {
+		return createAlias( associationPath, alias, INNER_JOIN );
+	}
+
+	public Criteria createAlias(String associationPath, String alias, int joinType) {
+		new Subcriteria( this, associationPath, alias, joinType );
+		return this;
+	}
+
+	public Criteria createCriteria(String associationPath) {
+		return createCriteria( associationPath, INNER_JOIN );
+	}
+
+	public Criteria createCriteria(String associationPath, int joinType) {
+		return new Subcriteria( this, associationPath, joinType );
+	}
+
+	public Criteria createCriteria(String associationPath, String alias) {
+		return createCriteria( associationPath, alias, INNER_JOIN );
+	}
+
+	public Criteria createCriteria(String associationPath, String alias, int joinType) {
+		return new Subcriteria( this, associationPath, alias, joinType );
+	}
+
+	public ResultTransformer getResultTransformer() {
+		return resultTransformer;
+	}
+
+	public Criteria setResultTransformer(ResultTransformer tupleMapper) {
+		this.resultTransformer = tupleMapper;
+		return this;
+	}
+
+	public Integer getMaxResults() {
+		return maxResults;
+	}
+
+	public Criteria setMaxResults(int maxResults) {
+		this.maxResults = new Integer(maxResults);
+		return this;
+	}
+
+	public Integer getFirstResult() {
+		return firstResult;
+	}
+
+	public Criteria setFirstResult(int firstResult) {
+		this.firstResult = new Integer(firstResult);
+		return this;
+	}
+
+	public Integer getFetchSize() {
+		return fetchSize;
+	}
+
+	public Criteria setFetchSize(int fetchSize) {
+		this.fetchSize = new Integer(fetchSize);
+		return this;
+	}
+
+	public Integer getTimeout() {
+		return timeout;
+	}
+
+	public Criteria setTimeout(int timeout) {
+		this.timeout = new Integer(timeout);
+		return this;
+	}
+
+	public boolean getCacheable() {
+		return this.cacheable;
+	}
+
+	public Criteria setCacheable(boolean cacheable) {
+		this.cacheable = cacheable;
+		return this;
+	}
+
+	public String getCacheRegion() {
+		return this.cacheRegion;
+	}
+
+	public Criteria setCacheRegion(String cacheRegion) {
+		this.cacheRegion = cacheRegion.trim();
+		return this;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public Criteria setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public Criteria setFlushMode(FlushMode flushMode) {
+		this.flushMode = flushMode;
+		return this;
+	}
+
+	public Criteria setCacheMode(CacheMode cacheMode) {
+		this.cacheMode = cacheMode;
+		return this;
+	}
+
+	public List list() throws HibernateException {
+		before();
+		try {
+			return session.list( this );
+		}
+		finally {
+			after();
+		}
+	}
+	
+	public ScrollableResults scroll() {
+		return scroll( ScrollMode.SCROLL_INSENSITIVE );
+	}
+
+	public ScrollableResults scroll(ScrollMode scrollMode) {
+		before();
+		try {
+			return session.scroll(this, scrollMode);
+		}
+		finally {
+			after();
+		}
+	}
+
+	public Object uniqueResult() throws HibernateException {
+		return AbstractQueryImpl.uniqueElement( list() );
+	}
+
+	protected void before() {
+		if ( flushMode != null ) {
+			sessionFlushMode = getSession().getFlushMode();
+			getSession().setFlushMode( flushMode );
+		}
+		if ( cacheMode != null ) {
+			sessionCacheMode = getSession().getCacheMode();
+			getSession().setCacheMode( cacheMode );
+		}
+	}
+	
+	protected void after() {
+		if ( sessionFlushMode != null ) {
+			getSession().setFlushMode( sessionFlushMode );
+			sessionFlushMode = null;
+		}
+		if ( sessionCacheMode != null ) {
+			getSession().setCacheMode( sessionCacheMode );
+			sessionCacheMode = null;
+		}
+	}
+	
+	public boolean isLookupByNaturalKey() {
+		if ( projection != null ) {
+			return false;
+		}
+		if ( subcriteriaList.size() > 0 ) {
+			return false;
+		}
+		if ( criterionEntries.size() != 1 ) {
+			return false;
+		}
+		CriterionEntry ce = (CriterionEntry) criterionEntries.get(0);
+		return ce.getCriterion() instanceof NaturalIdentifier;
+	}
+
+
+	// Inner classes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public final class Subcriteria implements Criteria, Serializable {
+
+		private String alias;
+		private String path;
+		private Criteria parent;
+		private LockMode lockMode;
+		private int joinType;
+
+
+		// Constructors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		private Subcriteria(Criteria parent, String path, String alias, int joinType) {
+			this.alias = alias;
+			this.path = path;
+			this.parent = parent;
+			this.joinType = joinType;
+			CriteriaImpl.this.subcriteriaList.add(this);
+		}
+
+		private Subcriteria(Criteria parent, String path, int joinType) {
+			this( parent, path, null, joinType );
+		}
+
+		public String toString() {
+			return "Subcriteria(" +
+				path + ":" +
+				(alias==null ? "" : alias) +
+				')';
+		}
+
+
+		// State ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		public String getAlias() {
+			return alias;
+		}
+
+		public void setAlias(String alias) {
+			this.alias = alias;
+		}
+
+		public String getPath() {
+			return path;
+		}
+
+		public Criteria getParent() {
+			return parent;
+		}
+
+		public LockMode getLockMode() {
+			return lockMode;
+		}
+
+		public Criteria setLockMode(LockMode lockMode) {
+			this.lockMode = lockMode;
+			return this;
+		}
+
+		public int getJoinType() {
+			return joinType;
+		}
+
+
+		// Criteria impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		public Criteria add(Criterion expression) {
+			CriteriaImpl.this.add(this, expression);
+			return this;
+		}
+
+		public Criteria addOrder(Order order) {
+			CriteriaImpl.this.orderEntries.add( new OrderEntry(order, this) );
+			return this;
+		}
+
+		public Criteria createAlias(String associationPath, String alias) {
+			return createAlias( associationPath, alias, INNER_JOIN );
+		}
+
+		public Criteria createAlias(String associationPath, String alias, int joinType) throws HibernateException {
+			new Subcriteria( this, associationPath, alias, joinType );
+			return this;
+		}
+
+		public Criteria createCriteria(String associationPath) {
+			return createCriteria( associationPath, INNER_JOIN );
+		}
+
+		public Criteria createCriteria(String associationPath, int joinType) throws HibernateException {
+			return new Subcriteria( Subcriteria.this, associationPath, joinType );
+		}
+
+		public Criteria createCriteria(String associationPath, String alias) {
+			return createCriteria( associationPath, alias, INNER_JOIN );
+		}
+
+		public Criteria createCriteria(String associationPath, String alias, int joinType) throws HibernateException {
+			return new Subcriteria( Subcriteria.this, associationPath, alias, joinType );
+		}
+
+		public Criteria setCacheable(boolean cacheable) {
+			CriteriaImpl.this.setCacheable(cacheable);
+			return this;
+		}
+
+		public Criteria setCacheRegion(String cacheRegion) {
+			CriteriaImpl.this.setCacheRegion(cacheRegion);
+			return this;
+		}
+
+		public List list() throws HibernateException {
+			return CriteriaImpl.this.list();
+		}
+
+		public ScrollableResults scroll() throws HibernateException {
+			return CriteriaImpl.this.scroll();
+		}
+
+		public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
+			return CriteriaImpl.this.scroll(scrollMode);
+		}
+
+		public Object uniqueResult() throws HibernateException {
+			return CriteriaImpl.this.uniqueResult();
+		}
+
+		public Criteria setFetchMode(String associationPath, FetchMode mode)
+			throws HibernateException {
+			CriteriaImpl.this.setFetchMode( StringHelper.qualify(path, associationPath), mode);
+			return this;
+		}
+
+		public Criteria setFlushMode(FlushMode flushMode) {
+			CriteriaImpl.this.setFlushMode(flushMode);
+			return this;
+		}
+
+		public Criteria setCacheMode(CacheMode cacheMode) {
+			CriteriaImpl.this.setCacheMode(cacheMode);
+			return this;
+		}
+
+		public Criteria setFirstResult(int firstResult) {
+			CriteriaImpl.this.setFirstResult(firstResult);
+			return this;
+		}
+
+		public Criteria setMaxResults(int maxResults) {
+			CriteriaImpl.this.setMaxResults(maxResults);
+			return this;
+		}
+
+		public Criteria setTimeout(int timeout) {
+			CriteriaImpl.this.setTimeout(timeout);
+			return this;
+		}
+
+		public Criteria setFetchSize(int fetchSize) {
+			CriteriaImpl.this.setFetchSize(fetchSize);
+			return this;
+		}
+
+		public Criteria setLockMode(String alias, LockMode lockMode) {
+			CriteriaImpl.this.setLockMode(alias, lockMode);
+			return this;
+		}
+
+		public Criteria setResultTransformer(ResultTransformer resultProcessor) {
+			CriteriaImpl.this.setResultTransformer(resultProcessor);
+			return this;
+		}
+
+		public Criteria setComment(String comment) {
+			CriteriaImpl.this.setComment(comment);
+			return this;
+		}
+
+		public Criteria setProjection(Projection projection) {
+			CriteriaImpl.this.projection = projection;
+			CriteriaImpl.this.projectionCriteria = this;
+			setResultTransformer(PROJECTION);
+			return this;
+		}
+	}
+
+	public static final class CriterionEntry implements Serializable {
+		private final Criterion criterion;
+		private final Criteria criteria;
+
+		private CriterionEntry(Criterion criterion, Criteria criteria) {
+			this.criteria = criteria;
+			this.criterion = criterion;
+		}
+
+		public Criterion getCriterion() {
+			return criterion;
+		}
+
+		public Criteria getCriteria() {
+			return criteria;
+		}
+
+		public String toString() {
+			return criterion.toString();
+		}
+	}
+
+	public static final class OrderEntry implements Serializable {
+		private final Order order;
+		private final Criteria criteria;
+
+		private OrderEntry(Order order, Criteria criteria) {
+			this.criteria = criteria;
+			this.order = order;
+		}
+
+		public Order getOrder() {
+			return order;
+		}
+
+		public Criteria getCriteria() {
+			return criteria;
+		}
+
+		public String toString() {
+			return order.toString();
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,293 +0,0 @@
-// $Id: FetchingScrollableResultsImpl.java 7469 2005-07-14 13:12:19Z steveebersole $
-package org.hibernate.impl;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.type.Type;
-import org.hibernate.loader.Loader;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.QueryParameters;
-
-import java.sql.ResultSet;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Implementation of ScrollableResults which can handle collection fetches.
- *
- * @author Steve Ebersole
- */
-public class FetchingScrollableResultsImpl extends AbstractScrollableResults {
-
-	public FetchingScrollableResultsImpl(
-	        ResultSet rs,
-	        PreparedStatement ps,
-	        SessionImplementor sess,
-	        Loader loader,
-	        QueryParameters queryParameters,
-	        Type[] types,
-	        HolderInstantiator holderInstantiator) throws MappingException {
-		super( rs, ps, sess, loader, queryParameters, types, holderInstantiator );
-	}
-
-	private Object[] currentRow = null;
-	private int currentPosition = 0;
-	private Integer maxPosition = null;
-
-	protected Object[] getCurrentRow() {
-		return currentRow;
-	}
-
-	/**
-	 * Advance to the next result
-	 *
-	 * @return <tt>true</tt> if there is another result
-	 */
-	public boolean next() throws HibernateException {
-		if ( maxPosition != null && maxPosition.intValue() <= currentPosition ) {
-			currentRow = null;
-			currentPosition = maxPosition.intValue() + 1;
-			return false;
-		}
-
-		Object row = getLoader().loadSequentialRowsForward(
-				getResultSet(),
-				getSession(),
-				getQueryParameters(),
-				false
-		);
-
-
-		boolean afterLast;
-		try {
-			afterLast = getResultSet().isAfterLast();
-		}
-		catch( SQLException e ) {
-			throw JDBCExceptionHelper.convert(
-			        getSession().getFactory().getSQLExceptionConverter(),
-			        e,
-			        "exception calling isAfterLast()"
-				);
-		}
-
-		currentPosition++;
-		currentRow = new Object[] { row };
-
-		if ( afterLast ) {
-			if ( maxPosition == null ) {
-				// we just hit the last position
-				maxPosition = new Integer( currentPosition );
-			}
-		}
-
-		afterScrollOperation();
-
-		return true;
-	}
-
-	/**
-	 * Retreat to the previous result
-	 *
-	 * @return <tt>true</tt> if there is a previous result
-	 */
-	public boolean previous() throws HibernateException {
-		if ( currentPosition <= 1 ) {
-			currentPosition = 0;
-			currentRow = null;
-			return false;
-		}
-
-		Object loadResult = getLoader().loadSequentialRowsReverse(
-				getResultSet(),
-				getSession(),
-				getQueryParameters(),
-				false,
-		        ( maxPosition != null && currentPosition > maxPosition.intValue() )
-		);
-
-		currentRow = new Object[] { loadResult };
-		currentPosition--;
-
-		afterScrollOperation();
-
-		return true;
-
-	}
-
-	/**
-	 * Scroll an arbitrary number of locations
-	 *
-	 * @param positions a positive (forward) or negative (backward) number of rows
-	 *
-	 * @return <tt>true</tt> if there is a result at the new location
-	 */
-	public boolean scroll(int positions) throws HibernateException {
-		boolean more = false;
-		if ( positions > 0 ) {
-			// scroll ahead
-			for ( int i = 0; i < positions; i++ ) {
-				more = next();
-				if ( !more ) {
-					break;
-				}
-			}
-		}
-		else if ( positions < 0 ) {
-			// scroll backward
-			for ( int i = 0; i < ( 0 - positions ); i++ ) {
-				more = previous();
-				if ( !more ) {
-					break;
-				}
-			}
-		}
-		else {
-			throw new HibernateException( "scroll(0) not valid" );
-		}
-
-		afterScrollOperation();
-
-		return more;
-	}
-
-	/**
-	 * Go to the last result
-	 *
-	 * @return <tt>true</tt> if there are any results
-	 */
-	public boolean last() throws HibernateException {
-		boolean more = false;
-		if ( maxPosition != null ) {
-			for ( int i = currentPosition; i < maxPosition.intValue(); i++ ) {
-				more = next();
-			}
-		}
-		else {
-			try {
-				if ( getResultSet().isAfterLast() ) {
-					// should not be able to reach last without maxPosition being set
-					// unless there are no results
-					return false;
-				}
-
-				while ( !getResultSet().isAfterLast() ) {
-					more = next();
-				}
-			}
-			catch( SQLException e ) {
-				throw JDBCExceptionHelper.convert(
-						getSession().getFactory().getSQLExceptionConverter(),
-						e,
-						"exception calling isAfterLast()"
-					);
-			}
-		}
-
-		afterScrollOperation();
-
-		return more;
-	}
-
-	/**
-	 * Go to the first result
-	 *
-	 * @return <tt>true</tt> if there are any results
-	 */
-	public boolean first() throws HibernateException {
-		beforeFirst();
-		boolean more = next();
-
-		afterScrollOperation();
-
-		return more;
-	}
-
-	/**
-	 * Go to a location just before first result (this is the initial location)
-	 */
-	public void beforeFirst() throws HibernateException {
-		try {
-			getResultSet().beforeFirst();
-		}
-		catch( SQLException e ) {
-			throw JDBCExceptionHelper.convert(
-			        getSession().getFactory().getSQLExceptionConverter(),
-			        e,
-			        "exception calling beforeFirst()"
-				);
-		}
-		currentRow = null;
-		currentPosition = 0;
-	}
-
-	/**
-	 * Go to a location just after the last result
-	 */
-	public void afterLast() throws HibernateException {
-		// TODO : not sure the best way to handle this.
-		// The non-performant way :
-		last();
-		next();
-		afterScrollOperation();
-	}
-
-	/**
-	 * Is this the first result?
-	 *
-	 * @return <tt>true</tt> if this is the first row of results
-	 *
-	 * @throws org.hibernate.HibernateException
-	 */
-	public boolean isFirst() throws HibernateException {
-		return currentPosition == 1;
-	}
-
-	/**
-	 * Is this the last result?
-	 *
-	 * @return <tt>true</tt> if this is the last row of results
-	 *
-	 * @throws org.hibernate.HibernateException
-	 */
-	public boolean isLast() throws HibernateException {
-		if ( maxPosition == null ) {
-			// we have not yet hit the last result...
-			return false;
-		}
-		else {
-			return currentPosition == maxPosition.intValue();
-		}
-	}
-
-	/**
-	 * Get the current location in the result set. The first row is number <tt>0</tt>, contrary to JDBC.
-	 *
-	 * @return the row number, numbered from <tt>0</tt>, or <tt>-1</tt> if there is no current row
-	 */
-	public int getRowNumber() throws HibernateException {
-		return currentPosition;
-	}
-
-	/**
-	 * Set the current location in the result set, numbered from either the first row (row number <tt>0</tt>), or the last
-	 * row (row number <tt>-1</tt>).
-	 *
-	 * @param rowNumber the row number, numbered from the last row, in the case of a negative row number
-	 *
-	 * @return true if there is a row at that row number
-	 */
-	public boolean setRowNumber(int rowNumber) throws HibernateException {
-		if ( rowNumber == 1 ) {
-			return first();
-		}
-		else if ( rowNumber == -1 ) {
-			return last();
-		}
-		else if ( maxPosition != null && rowNumber == maxPosition.intValue() ) {
-			return last();
-		}
-		return scroll( rowNumber - currentPosition );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FetchingScrollableResultsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,316 @@
+/*
+ * 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.impl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.type.Type;
+import org.hibernate.loader.Loader;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.QueryParameters;
+
+import java.sql.ResultSet;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Implementation of ScrollableResults which can handle collection fetches.
+ *
+ * @author Steve Ebersole
+ */
+public class FetchingScrollableResultsImpl extends AbstractScrollableResults {
+
+	public FetchingScrollableResultsImpl(
+	        ResultSet rs,
+	        PreparedStatement ps,
+	        SessionImplementor sess,
+	        Loader loader,
+	        QueryParameters queryParameters,
+	        Type[] types,
+	        HolderInstantiator holderInstantiator) throws MappingException {
+		super( rs, ps, sess, loader, queryParameters, types, holderInstantiator );
+	}
+
+	private Object[] currentRow = null;
+	private int currentPosition = 0;
+	private Integer maxPosition = null;
+
+	protected Object[] getCurrentRow() {
+		return currentRow;
+	}
+
+	/**
+	 * Advance to the next result
+	 *
+	 * @return <tt>true</tt> if there is another result
+	 */
+	public boolean next() throws HibernateException {
+		if ( maxPosition != null && maxPosition.intValue() <= currentPosition ) {
+			currentRow = null;
+			currentPosition = maxPosition.intValue() + 1;
+			return false;
+		}
+
+		Object row = getLoader().loadSequentialRowsForward(
+				getResultSet(),
+				getSession(),
+				getQueryParameters(),
+				false
+		);
+
+
+		boolean afterLast;
+		try {
+			afterLast = getResultSet().isAfterLast();
+		}
+		catch( SQLException e ) {
+			throw JDBCExceptionHelper.convert(
+			        getSession().getFactory().getSQLExceptionConverter(),
+			        e,
+			        "exception calling isAfterLast()"
+				);
+		}
+
+		currentPosition++;
+		currentRow = new Object[] { row };
+
+		if ( afterLast ) {
+			if ( maxPosition == null ) {
+				// we just hit the last position
+				maxPosition = new Integer( currentPosition );
+			}
+		}
+
+		afterScrollOperation();
+
+		return true;
+	}
+
+	/**
+	 * Retreat to the previous result
+	 *
+	 * @return <tt>true</tt> if there is a previous result
+	 */
+	public boolean previous() throws HibernateException {
+		if ( currentPosition <= 1 ) {
+			currentPosition = 0;
+			currentRow = null;
+			return false;
+		}
+
+		Object loadResult = getLoader().loadSequentialRowsReverse(
+				getResultSet(),
+				getSession(),
+				getQueryParameters(),
+				false,
+		        ( maxPosition != null && currentPosition > maxPosition.intValue() )
+		);
+
+		currentRow = new Object[] { loadResult };
+		currentPosition--;
+
+		afterScrollOperation();
+
+		return true;
+
+	}
+
+	/**
+	 * Scroll an arbitrary number of locations
+	 *
+	 * @param positions a positive (forward) or negative (backward) number of rows
+	 *
+	 * @return <tt>true</tt> if there is a result at the new location
+	 */
+	public boolean scroll(int positions) throws HibernateException {
+		boolean more = false;
+		if ( positions > 0 ) {
+			// scroll ahead
+			for ( int i = 0; i < positions; i++ ) {
+				more = next();
+				if ( !more ) {
+					break;
+				}
+			}
+		}
+		else if ( positions < 0 ) {
+			// scroll backward
+			for ( int i = 0; i < ( 0 - positions ); i++ ) {
+				more = previous();
+				if ( !more ) {
+					break;
+				}
+			}
+		}
+		else {
+			throw new HibernateException( "scroll(0) not valid" );
+		}
+
+		afterScrollOperation();
+
+		return more;
+	}
+
+	/**
+	 * Go to the last result
+	 *
+	 * @return <tt>true</tt> if there are any results
+	 */
+	public boolean last() throws HibernateException {
+		boolean more = false;
+		if ( maxPosition != null ) {
+			for ( int i = currentPosition; i < maxPosition.intValue(); i++ ) {
+				more = next();
+			}
+		}
+		else {
+			try {
+				if ( getResultSet().isAfterLast() ) {
+					// should not be able to reach last without maxPosition being set
+					// unless there are no results
+					return false;
+				}
+
+				while ( !getResultSet().isAfterLast() ) {
+					more = next();
+				}
+			}
+			catch( SQLException e ) {
+				throw JDBCExceptionHelper.convert(
+						getSession().getFactory().getSQLExceptionConverter(),
+						e,
+						"exception calling isAfterLast()"
+					);
+			}
+		}
+
+		afterScrollOperation();
+
+		return more;
+	}
+
+	/**
+	 * Go to the first result
+	 *
+	 * @return <tt>true</tt> if there are any results
+	 */
+	public boolean first() throws HibernateException {
+		beforeFirst();
+		boolean more = next();
+
+		afterScrollOperation();
+
+		return more;
+	}
+
+	/**
+	 * Go to a location just before first result (this is the initial location)
+	 */
+	public void beforeFirst() throws HibernateException {
+		try {
+			getResultSet().beforeFirst();
+		}
+		catch( SQLException e ) {
+			throw JDBCExceptionHelper.convert(
+			        getSession().getFactory().getSQLExceptionConverter(),
+			        e,
+			        "exception calling beforeFirst()"
+				);
+		}
+		currentRow = null;
+		currentPosition = 0;
+	}
+
+	/**
+	 * Go to a location just after the last result
+	 */
+	public void afterLast() throws HibernateException {
+		// TODO : not sure the best way to handle this.
+		// The non-performant way :
+		last();
+		next();
+		afterScrollOperation();
+	}
+
+	/**
+	 * Is this the first result?
+	 *
+	 * @return <tt>true</tt> if this is the first row of results
+	 *
+	 * @throws org.hibernate.HibernateException
+	 */
+	public boolean isFirst() throws HibernateException {
+		return currentPosition == 1;
+	}
+
+	/**
+	 * Is this the last result?
+	 *
+	 * @return <tt>true</tt> if this is the last row of results
+	 *
+	 * @throws org.hibernate.HibernateException
+	 */
+	public boolean isLast() throws HibernateException {
+		if ( maxPosition == null ) {
+			// we have not yet hit the last result...
+			return false;
+		}
+		else {
+			return currentPosition == maxPosition.intValue();
+		}
+	}
+
+	/**
+	 * Get the current location in the result set. The first row is number <tt>0</tt>, contrary to JDBC.
+	 *
+	 * @return the row number, numbered from <tt>0</tt>, or <tt>-1</tt> if there is no current row
+	 */
+	public int getRowNumber() throws HibernateException {
+		return currentPosition;
+	}
+
+	/**
+	 * Set the current location in the result set, numbered from either the first row (row number <tt>0</tt>), or the last
+	 * row (row number <tt>-1</tt>).
+	 *
+	 * @param rowNumber the row number, numbered from the last row, in the case of a negative row number
+	 *
+	 * @return true if there is a row at that row number
+	 */
+	public boolean setRowNumber(int rowNumber) throws HibernateException {
+		if ( rowNumber == 1 ) {
+			return first();
+		}
+		else if ( rowNumber == -1 ) {
+			return last();
+		}
+		else if ( maxPosition != null && rowNumber == maxPosition.intValue() ) {
+			return last();
+		}
+		return scroll( rowNumber - currentPosition );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/FilterImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,151 +0,0 @@
-// $Id: FilterImpl.java 8754 2005-12-05 23:36:59Z steveebersole $
-package org.hibernate.impl;
-
-import java.io.Serializable;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.Filter;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.type.Type;
-
-/**
- * Implementation of FilterImpl.  FilterImpl implements the user's
- * view into enabled dynamic filters, allowing them to set filter parameter values.
- *
- * @author Steve Ebersole
- */
-public class FilterImpl implements Filter, Serializable {
-	public static final String MARKER = "$FILTER_PLACEHOLDER$";
-
-	private transient FilterDefinition definition;
-	private String filterName;
-	private Map parameters = new HashMap();
-	
-	void afterDeserialize(SessionFactoryImpl factory) {
-		definition = factory.getFilterDefinition(filterName);
-	}
-
-	/**
-	 * Constructs a new FilterImpl.
-	 *
-	 * @param configuration The filter's global configuration.
-	 */
-	public FilterImpl(FilterDefinition configuration) {
-		this.definition = configuration;
-		filterName = definition.getFilterName();
-	}
-
-	public FilterDefinition getFilterDefinition() {
-		return definition;
-	}
-
-	/**
-	 * Get the name of this filter.
-	 *
-	 * @return This filter's name.
-	 */
-	public String getName() {
-		return definition.getFilterName();
-	}
-	
-	public Map getParameters() {
-		return parameters;
-	}
-
-	/**
-	 * Set the named parameter's value for this filter.
-	 *
-	 * @param name The parameter's name.
-	 * @param value The value to be applied.
-	 * @return This FilterImpl instance (for method chaining).
-	 * @throws IllegalArgumentException Indicates that either the parameter was undefined or that the type
-	 * of the passed value did not match the configured type.
-	 */
-	public Filter setParameter(String name, Object value) throws IllegalArgumentException {
-		// Make sure this is a defined parameter and check the incoming value type
-		// TODO: what should be the actual exception type here?
-		Type type = definition.getParameterType( name );
-		if ( type == null ) {
-			throw new IllegalArgumentException( "Undefined filter parameter [" + name + "]" );
-		}
-		if ( value != null && !type.getReturnedClass().isAssignableFrom( value.getClass() ) ) {
-			throw new IllegalArgumentException( "Incorrect type for parameter [" + name + "]" );
-		}
-		parameters.put( name, value );
-		return this;
-	}
-
-	/**
-	 * Set the named parameter's value list for this filter.  Used
-	 * in conjunction with IN-style filter criteria.
-	 *
-	 * @param name   The parameter's name.
-	 * @param values The values to be expanded into an SQL IN list.
-	 * @return This FilterImpl instance (for method chaining).
-	 */
-	public Filter setParameterList(String name, Collection values) throws HibernateException  {
-		// Make sure this is a defined parameter and check the incoming value type
-		if ( values == null ) {
-			throw new IllegalArgumentException( "Collection must be not null!" );
-		}
-		Type type = definition.getParameterType( name );
-		if ( type == null ) {
-			throw new HibernateException( "Undefined filter parameter [" + name + "]" );
-		}
-		if ( values.size() > 0 ) {
-			Class elementClass = values.iterator().next().getClass();
-			if ( !type.getReturnedClass().isAssignableFrom( elementClass ) ) {
-				throw new HibernateException( "Incorrect type for parameter [" + name + "]" );
-			}
-		}
-		parameters.put( name, values );
-		return this;
-	}
-
-	/**
-	 * Set the named parameter's value list for this filter.  Used
-	 * in conjunction with IN-style filter criteria.
-	 *
-	 * @param name The parameter's name.
-	 * @param values The values to be expanded into an SQL IN list.
-	 * @return This FilterImpl instance (for method chaining).
-	 */
-	public Filter setParameterList(String name, Object[] values) throws IllegalArgumentException {
-		return setParameterList( name, Arrays.asList( values ) );
-	}
-
-	/**
-	 * Get the value of the named parameter for the current filter.
-	 *
-	 * @param name The name of the parameter for which to return the value.
-	 * @return The value of the named parameter.
-	 */
-	public Object getParameter(String name) {
-		return parameters.get( name );
-	}
-
-	/**
-	 * Perform validation of the filter state.  This is used to verify the
-	 * state of the filter after its enablement and before its use.
-	 *
-	 * @throws HibernateException If the state is not currently valid.
-	 */
-	public void validate() throws HibernateException {
-		// for each of the defined parameters, make sure its value
-		// has been set
-		Iterator itr = definition.getParameterNames().iterator();
-		while ( itr.hasNext() ) {
-			final String parameterName = (String) itr.next();
-			if ( parameters.get( parameterName ) == null ) {
-				throw new HibernateException(
-						"Filter [" + getName() + "] parameter [" + parameterName + "] value not set"
-				);
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/FilterImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/FilterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,174 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.Filter;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.type.Type;
+
+/**
+ * Implementation of FilterImpl.  FilterImpl implements the user's
+ * view into enabled dynamic filters, allowing them to set filter parameter values.
+ *
+ * @author Steve Ebersole
+ */
+public class FilterImpl implements Filter, Serializable {
+	public static final String MARKER = "$FILTER_PLACEHOLDER$";
+
+	private transient FilterDefinition definition;
+	private String filterName;
+	private Map parameters = new HashMap();
+	
+	void afterDeserialize(SessionFactoryImpl factory) {
+		definition = factory.getFilterDefinition(filterName);
+	}
+
+	/**
+	 * Constructs a new FilterImpl.
+	 *
+	 * @param configuration The filter's global configuration.
+	 */
+	public FilterImpl(FilterDefinition configuration) {
+		this.definition = configuration;
+		filterName = definition.getFilterName();
+	}
+
+	public FilterDefinition getFilterDefinition() {
+		return definition;
+	}
+
+	/**
+	 * Get the name of this filter.
+	 *
+	 * @return This filter's name.
+	 */
+	public String getName() {
+		return definition.getFilterName();
+	}
+	
+	public Map getParameters() {
+		return parameters;
+	}
+
+	/**
+	 * Set the named parameter's value for this filter.
+	 *
+	 * @param name The parameter's name.
+	 * @param value The value to be applied.
+	 * @return This FilterImpl instance (for method chaining).
+	 * @throws IllegalArgumentException Indicates that either the parameter was undefined or that the type
+	 * of the passed value did not match the configured type.
+	 */
+	public Filter setParameter(String name, Object value) throws IllegalArgumentException {
+		// Make sure this is a defined parameter and check the incoming value type
+		// TODO: what should be the actual exception type here?
+		Type type = definition.getParameterType( name );
+		if ( type == null ) {
+			throw new IllegalArgumentException( "Undefined filter parameter [" + name + "]" );
+		}
+		if ( value != null && !type.getReturnedClass().isAssignableFrom( value.getClass() ) ) {
+			throw new IllegalArgumentException( "Incorrect type for parameter [" + name + "]" );
+		}
+		parameters.put( name, value );
+		return this;
+	}
+
+	/**
+	 * Set the named parameter's value list for this filter.  Used
+	 * in conjunction with IN-style filter criteria.
+	 *
+	 * @param name   The parameter's name.
+	 * @param values The values to be expanded into an SQL IN list.
+	 * @return This FilterImpl instance (for method chaining).
+	 */
+	public Filter setParameterList(String name, Collection values) throws HibernateException  {
+		// Make sure this is a defined parameter and check the incoming value type
+		if ( values == null ) {
+			throw new IllegalArgumentException( "Collection must be not null!" );
+		}
+		Type type = definition.getParameterType( name );
+		if ( type == null ) {
+			throw new HibernateException( "Undefined filter parameter [" + name + "]" );
+		}
+		if ( values.size() > 0 ) {
+			Class elementClass = values.iterator().next().getClass();
+			if ( !type.getReturnedClass().isAssignableFrom( elementClass ) ) {
+				throw new HibernateException( "Incorrect type for parameter [" + name + "]" );
+			}
+		}
+		parameters.put( name, values );
+		return this;
+	}
+
+	/**
+	 * Set the named parameter's value list for this filter.  Used
+	 * in conjunction with IN-style filter criteria.
+	 *
+	 * @param name The parameter's name.
+	 * @param values The values to be expanded into an SQL IN list.
+	 * @return This FilterImpl instance (for method chaining).
+	 */
+	public Filter setParameterList(String name, Object[] values) throws IllegalArgumentException {
+		return setParameterList( name, Arrays.asList( values ) );
+	}
+
+	/**
+	 * Get the value of the named parameter for the current filter.
+	 *
+	 * @param name The name of the parameter for which to return the value.
+	 * @return The value of the named parameter.
+	 */
+	public Object getParameter(String name) {
+		return parameters.get( name );
+	}
+
+	/**
+	 * Perform validation of the filter state.  This is used to verify the
+	 * state of the filter after its enablement and before its use.
+	 *
+	 * @throws HibernateException If the state is not currently valid.
+	 */
+	public void validate() throws HibernateException {
+		// for each of the defined parameters, make sure its value
+		// has been set
+		Iterator itr = definition.getParameterNames().iterator();
+		while ( itr.hasNext() ) {
+			final String parameterName = (String) itr.next();
+			if ( parameters.get( parameterName ) == null ) {
+				throw new HibernateException(
+						"Filter [" + getName() + "] parameter [" + parameterName + "] value not set"
+				);
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,160 +0,0 @@
-//$Id: IteratorImpl.java 13956 2007-08-29 00:47:06Z gbadner $
-package org.hibernate.impl;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.NoSuchElementException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.engine.HibernateIterator;
-import org.hibernate.event.EventSource;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-
-/**
- * An implementation of <tt>java.util.Iterator</tt> that is
- * returned by <tt>iterate()</tt> query execution methods.
- * @author Gavin King
- */
-public final class IteratorImpl implements HibernateIterator {
-
-	private static final Logger log = LoggerFactory.getLogger(IteratorImpl.class);
-
-	private ResultSet rs;
-	private final EventSource session;
-	private final Type[] types;
-	private final boolean single;
-	private Object currentResult;
-	private boolean hasNext;
-	private final String[][] names;
-	private PreparedStatement ps;
-	private HolderInstantiator holderInstantiator;
-
-	public IteratorImpl(
-	        ResultSet rs,
-	        PreparedStatement ps,
-	        EventSource sess,
-	        Type[] types,
-	        String[][] columnNames,
-	        HolderInstantiator holderInstantiator)
-	throws HibernateException, SQLException {
-
-		this.rs=rs;
-		this.ps=ps;
-		this.session = sess;
-		this.types = types;
-		this.names = columnNames;
-		this.holderInstantiator = holderInstantiator;
-
-		single = types.length==1;
-
-		postNext();
-	}
-
-	public void close() throws JDBCException {
-		if (ps!=null) {
-			try {
-				log.debug("closing iterator");
-				session.getBatcher().closeQueryStatement(ps, rs);
-				ps = null;
-				rs = null;
-				hasNext = false;
-			}
-			catch (SQLException e) {
-				log.info( "Unable to close iterator", e );
-				throw JDBCExceptionHelper.convert(
-				        session.getFactory().getSQLExceptionConverter(),
-				        e,
-				        "Unable to close iterator"
-					);
-			}
-			finally {
-				try {
-					session.getPersistenceContext().getLoadContexts().cleanup( rs );
-				}
-				catch( Throwable ignore ) {
-					// ignore this error for now
-					log.trace( "exception trying to cleanup load context : " + ignore.getMessage() );
-				}
-			}
-		}
-	}
-
-	private void postNext() throws SQLException {
-		log.debug("attempting to retrieve next results");
-		this.hasNext = rs.next();
-		if (!hasNext) {
-			log.debug("exhausted results");
-			close();
-		}
-		else {
-			log.debug("retrieved next results");
-		}
-	}
-
-	public boolean hasNext() {
-		return hasNext;
-	}
-
-	public Object next() throws HibernateException {
-		if ( !hasNext ) throw new NoSuchElementException("No more results");
-		try {
-			boolean isHolder = holderInstantiator.isRequired();
-
-			log.debug("assembling results");
-			if ( single && !isHolder ) {
-				currentResult = types[0].nullSafeGet( rs, names[0], session, null );
-			}
-			else {
-				Object[] currentResults = new Object[types.length];
-				for (int i=0; i<types.length; i++) {
-					currentResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
-				}
-
-				if (isHolder) {
-					currentResult = holderInstantiator.instantiate(currentResults);
-				}
-				else {
-					currentResult = currentResults;
-				}
-			}
-
-			postNext();
-			log.debug("returning current results");
-			return currentResult;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					session.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not get next iterator result"
-				);
-		}
-	}
-
-	public void remove() {
-		if (!single) {
-			throw new UnsupportedOperationException("Not a single column hibernate query result set");
-		}
-		if (currentResult==null) {
-			throw new IllegalStateException("Called Iterator.remove() before next()");
-		}
-		if ( !( types[0] instanceof EntityType ) ) {
-			throw new UnsupportedOperationException("Not an entity");
-		}
-		
-		session.delete( 
-				( (EntityType) types[0] ).getAssociatedEntityName(), 
-				currentResult,
-				false,
-		        null
-			);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/IteratorImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/IteratorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,183 @@
+/*
+ * 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.impl;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.NoSuchElementException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.engine.HibernateIterator;
+import org.hibernate.event.EventSource;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * An implementation of <tt>java.util.Iterator</tt> that is
+ * returned by <tt>iterate()</tt> query execution methods.
+ * @author Gavin King
+ */
+public final class IteratorImpl implements HibernateIterator {
+
+	private static final Logger log = LoggerFactory.getLogger(IteratorImpl.class);
+
+	private ResultSet rs;
+	private final EventSource session;
+	private final Type[] types;
+	private final boolean single;
+	private Object currentResult;
+	private boolean hasNext;
+	private final String[][] names;
+	private PreparedStatement ps;
+	private HolderInstantiator holderInstantiator;
+
+	public IteratorImpl(
+	        ResultSet rs,
+	        PreparedStatement ps,
+	        EventSource sess,
+	        Type[] types,
+	        String[][] columnNames,
+	        HolderInstantiator holderInstantiator)
+	throws HibernateException, SQLException {
+
+		this.rs=rs;
+		this.ps=ps;
+		this.session = sess;
+		this.types = types;
+		this.names = columnNames;
+		this.holderInstantiator = holderInstantiator;
+
+		single = types.length==1;
+
+		postNext();
+	}
+
+	public void close() throws JDBCException {
+		if (ps!=null) {
+			try {
+				log.debug("closing iterator");
+				session.getBatcher().closeQueryStatement(ps, rs);
+				ps = null;
+				rs = null;
+				hasNext = false;
+			}
+			catch (SQLException e) {
+				log.info( "Unable to close iterator", e );
+				throw JDBCExceptionHelper.convert(
+				        session.getFactory().getSQLExceptionConverter(),
+				        e,
+				        "Unable to close iterator"
+					);
+			}
+			finally {
+				try {
+					session.getPersistenceContext().getLoadContexts().cleanup( rs );
+				}
+				catch( Throwable ignore ) {
+					// ignore this error for now
+					log.trace( "exception trying to cleanup load context : " + ignore.getMessage() );
+				}
+			}
+		}
+	}
+
+	private void postNext() throws SQLException {
+		log.debug("attempting to retrieve next results");
+		this.hasNext = rs.next();
+		if (!hasNext) {
+			log.debug("exhausted results");
+			close();
+		}
+		else {
+			log.debug("retrieved next results");
+		}
+	}
+
+	public boolean hasNext() {
+		return hasNext;
+	}
+
+	public Object next() throws HibernateException {
+		if ( !hasNext ) throw new NoSuchElementException("No more results");
+		try {
+			boolean isHolder = holderInstantiator.isRequired();
+
+			log.debug("assembling results");
+			if ( single && !isHolder ) {
+				currentResult = types[0].nullSafeGet( rs, names[0], session, null );
+			}
+			else {
+				Object[] currentResults = new Object[types.length];
+				for (int i=0; i<types.length; i++) {
+					currentResults[i] = types[i].nullSafeGet( rs, names[i], session, null );
+				}
+
+				if (isHolder) {
+					currentResult = holderInstantiator.instantiate(currentResults);
+				}
+				else {
+					currentResult = currentResults;
+				}
+			}
+
+			postNext();
+			log.debug("returning current results");
+			return currentResult;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					session.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not get next iterator result"
+				);
+		}
+	}
+
+	public void remove() {
+		if (!single) {
+			throw new UnsupportedOperationException("Not a single column hibernate query result set");
+		}
+		if (currentResult==null) {
+			throw new IllegalStateException("Called Iterator.remove() before next()");
+		}
+		if ( !( types[0] instanceof EntityType ) ) {
+			throw new UnsupportedOperationException("Not an entity");
+		}
+		
+		session.delete( 
+				( (EntityType) types[0] ).getAssociatedEntityName(), 
+				currentResult,
+				false,
+		        null
+			);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/QueryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,119 +0,0 @@
-//$Id: QueryImpl.java 8524 2005-11-04 21:28:49Z steveebersole $
-package org.hibernate.impl;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.query.ParameterMetadata;
-
-/**
- * default implementation of the <tt>Query</tt> interface,
- * for "ordinary" HQL queries (not collection filters)
- * @see CollectionFilterImpl
- * @author Gavin King
- */
-public class QueryImpl extends AbstractQueryImpl {
-
-	private Map lockModes = new HashMap(2);
-
-	public QueryImpl(
-			String queryString,
-	        FlushMode flushMode,
-	        SessionImplementor session,
-	        ParameterMetadata parameterMetadata) {
-		super( queryString, flushMode, session, parameterMetadata );
-	}
-
-	public QueryImpl(String queryString, SessionImplementor session, ParameterMetadata parameterMetadata) {
-		this( queryString, null, session, parameterMetadata );
-	}
-
-	public Iterator iterate() throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		before();
-		try {
-			return getSession().iterate(
-					expandParameterLists(namedParams),
-			        getQueryParameters(namedParams)
-				);
-		}
-		finally {
-			after();
-		}
-	}
-
-	public ScrollableResults scroll() throws HibernateException {
-		return scroll( ScrollMode.SCROLL_INSENSITIVE );
-	}
-
-	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		before();
-		QueryParameters qp = getQueryParameters(namedParams);
-		qp.setScrollMode(scrollMode);
-		try {
-			return getSession().scroll( expandParameterLists(namedParams), qp );
-		}
-		finally {
-			after();
-		}
-	}
-
-	public List list() throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		before();
-		try {
-			return getSession().list(
-					expandParameterLists(namedParams),
-			        getQueryParameters(namedParams)
-				);
-		}
-		finally {
-			after();
-		}
-	}
-
-	public int executeUpdate() throws HibernateException {
-		verifyParameters();
-		Map namedParams = getNamedParams();
-		before();
-		try {
-            return getSession().executeUpdate(
-                    expandParameterLists( namedParams ),
-                    getQueryParameters( namedParams )
-	            );
-		}
-		finally {
-			after();
-		}
-	}
-
-	public Query setLockMode(String alias, LockMode lockMode) {
-		lockModes.put(alias, lockMode);
-		return this;
-	}
-
-	protected Map getLockModes() {
-		return lockModes;
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/QueryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/QueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,142 @@
+/*
+ * 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.impl;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.ParameterMetadata;
+
+/**
+ * default implementation of the <tt>Query</tt> interface,
+ * for "ordinary" HQL queries (not collection filters)
+ * @see CollectionFilterImpl
+ * @author Gavin King
+ */
+public class QueryImpl extends AbstractQueryImpl {
+
+	private Map lockModes = new HashMap(2);
+
+	public QueryImpl(
+			String queryString,
+	        FlushMode flushMode,
+	        SessionImplementor session,
+	        ParameterMetadata parameterMetadata) {
+		super( queryString, flushMode, session, parameterMetadata );
+	}
+
+	public QueryImpl(String queryString, SessionImplementor session, ParameterMetadata parameterMetadata) {
+		this( queryString, null, session, parameterMetadata );
+	}
+
+	public Iterator iterate() throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		before();
+		try {
+			return getSession().iterate(
+					expandParameterLists(namedParams),
+			        getQueryParameters(namedParams)
+				);
+		}
+		finally {
+			after();
+		}
+	}
+
+	public ScrollableResults scroll() throws HibernateException {
+		return scroll( ScrollMode.SCROLL_INSENSITIVE );
+	}
+
+	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		before();
+		QueryParameters qp = getQueryParameters(namedParams);
+		qp.setScrollMode(scrollMode);
+		try {
+			return getSession().scroll( expandParameterLists(namedParams), qp );
+		}
+		finally {
+			after();
+		}
+	}
+
+	public List list() throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		before();
+		try {
+			return getSession().list(
+					expandParameterLists(namedParams),
+			        getQueryParameters(namedParams)
+				);
+		}
+		finally {
+			after();
+		}
+	}
+
+	public int executeUpdate() throws HibernateException {
+		verifyParameters();
+		Map namedParams = getNamedParams();
+		before();
+		try {
+            return getSession().executeUpdate(
+                    expandParameterLists( namedParams ),
+                    getQueryParameters( namedParams )
+	            );
+		}
+		finally {
+			after();
+		}
+	}
+
+	public Query setLockMode(String alias, LockMode lockMode) {
+		lockModes.put(alias, lockMode);
+		return this;
+	}
+
+	protected Map getLockModes() {
+		return lockModes;
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,344 +0,0 @@
-//$Id: SQLQueryImpl.java 10862 2006-11-22 00:11:35Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.io.Serializable;
-
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.Query;
-import org.hibernate.QueryException;
-import org.hibernate.SQLQuery;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.MappingException;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.query.ParameterMetadata;
-import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Implements SQL query passthrough.
- *
- * <pre>
- * <sql-query name="mySqlQuery">
- * <return alias="person" class="eg.Person"/>
- *   SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex}
- *   FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%'
- * </sql-query>
- * </pre>
- *
- * @author Max Andersen
- */
-public class SQLQueryImpl extends AbstractQueryImpl implements SQLQuery {
-
-	private final List queryReturns;
-	private Collection querySpaces;
-	private final boolean callable;
-	private boolean autodiscovertypes;
-
-	/**
-	 * Constructs a SQLQueryImpl given a sql query defined in the mappings.
-	 *
-	 * @param queryDef The representation of the defined <sql-query/>.
-	 * @param session The session to which this SQLQueryImpl belongs.
-	 * @param parameterMetadata Metadata about parameters found in the query.
-	 */
-	SQLQueryImpl(NamedSQLQueryDefinition queryDef, SessionImplementor session, ParameterMetadata parameterMetadata) {
-		super( queryDef.getQueryString(), queryDef.getFlushMode(), session, parameterMetadata );
-		if ( queryDef.getResultSetRef() != null ) {
-			ResultSetMappingDefinition definition = session.getFactory()
-					.getResultSetMapping( queryDef.getResultSetRef() );
-			if (definition == null) {
-				throw new MappingException(
-						"Unable to find resultset-ref definition: " +
-						queryDef.getResultSetRef()
-					);
-			}
-			this.queryReturns = Arrays.asList( definition.getQueryReturns() );
-		}
-		else {
-			this.queryReturns = Arrays.asList( queryDef.getQueryReturns() );
-		}
-
-		this.querySpaces = queryDef.getQuerySpaces();
-		this.callable = queryDef.isCallable();
-	}
-
-	SQLQueryImpl(
-			final String sql,
-	        final List queryReturns,
-	        final Collection querySpaces,
-	        final FlushMode flushMode,
-	        boolean callable,
-	        final SessionImplementor session,
-	        ParameterMetadata parameterMetadata) {
-		// TODO : absolutely no usages of this constructor form; can it go away?
-		super( sql, flushMode, session, parameterMetadata );
-		this.queryReturns = queryReturns;
-		this.querySpaces = querySpaces;
-		this.callable = callable;
-	}
-
-	SQLQueryImpl(
-			final String sql,
-	        final String returnAliases[],
-	        final Class returnClasses[],
-	        final LockMode[] lockModes,
-	        final SessionImplementor session,
-	        final Collection querySpaces,
-	        final FlushMode flushMode,
-	        ParameterMetadata parameterMetadata) {
-		// TODO : this constructor form is *only* used from constructor directly below us; can it go away?
-		super( sql, flushMode, session, parameterMetadata );
-		queryReturns = new ArrayList(returnAliases.length);
-		for ( int i=0; i<returnAliases.length; i++ ) {
-			NativeSQLQueryRootReturn ret = new NativeSQLQueryRootReturn(
-					returnAliases[i],
-					returnClasses[i].getName(),
-					lockModes==null ? LockMode.NONE : lockModes[i]
-			);
-			queryReturns.add(ret);
-		}
-		this.querySpaces = querySpaces;
-		this.callable = false;
-	}
-
-	SQLQueryImpl(
-			final String sql,
-	        final String returnAliases[],
-	        final Class returnClasses[],
-	        final SessionImplementor session,
-	        ParameterMetadata parameterMetadata) {
-		this( sql, returnAliases, returnClasses, null, session, null, null, parameterMetadata );
-	}
-
-	SQLQueryImpl(String sql, SessionImplementor session, ParameterMetadata parameterMetadata) {
-		super( sql, null, session, parameterMetadata );
-		queryReturns = new ArrayList();
-		querySpaces = null;
-		callable = false;
-	}
-
-	private static final NativeSQLQueryReturn[] NO_SQL_RETURNS = new NativeSQLQueryReturn[0];
-
-	private NativeSQLQueryReturn[] getQueryReturns() {
-		return ( NativeSQLQueryReturn[] ) queryReturns.toArray( NO_SQL_RETURNS );
-	}
-
-	public List list() throws HibernateException {
-		verifyParameters();
-		before();
-
-		Map namedParams = getNamedParams();
-		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
-
-		try {
-			return getSession().list( spec, getQueryParameters( namedParams ) );
-		}
-		finally {
-			after();
-		}
-	}
-
-	private NativeSQLQuerySpecification generateQuerySpecification(Map namedParams) {
-		return new NativeSQLQuerySpecification(
-		        expandParameterLists(namedParams),
-		        getQueryReturns(),
-		        querySpaces
-		);
-	}
-
-	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
-		verifyParameters();
-		before();
-
-		Map namedParams = getNamedParams();
-		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
-
-		QueryParameters qp = getQueryParameters( namedParams );
-		qp.setScrollMode( scrollMode );
-
-		try {
-			return getSession().scroll( spec, qp );
-		}
-		finally {
-			after();
-		}
-	}
-
-	public ScrollableResults scroll() throws HibernateException {
-		return scroll(ScrollMode.SCROLL_INSENSITIVE);
-	}
-
-	public Iterator iterate() throws HibernateException {
-		throw new UnsupportedOperationException("SQL queries do not currently support iteration");
-	}
-
-	public QueryParameters getQueryParameters(Map namedParams) {
-		QueryParameters qp = super.getQueryParameters(namedParams);
-		qp.setCallable(callable);
-		qp.setAutoDiscoverScalarTypes(autodiscovertypes);
-		return qp;
-	}
-
-	protected void verifyParameters() {
-		verifyParameters( callable );
-		boolean noReturns = queryReturns==null || queryReturns.isEmpty();
-		if ( noReturns ) {
-			this.autodiscovertypes = noReturns;
-		}
-		else {
-			Iterator itr = queryReturns.iterator();
-			while ( itr.hasNext() ) {
-				NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) itr.next();
-				if ( rtn instanceof NativeSQLQueryScalarReturn ) {
-					NativeSQLQueryScalarReturn scalar = ( NativeSQLQueryScalarReturn ) rtn;
-					if ( scalar.getType() == null ) {
-						autodiscovertypes = true;
-						break;
-					}
-				}
-			}
-		}
-	}
-
-	public String[] getReturnAliases() throws HibernateException {
-		throw new UnsupportedOperationException("SQL queries do not currently support returning aliases");
-	}
-
-	public Type[] getReturnTypes() throws HibernateException {
-		throw new UnsupportedOperationException("not yet implemented for SQL queries");
-	}
-
-	public Query setLockMode(String alias, LockMode lockMode) {
-		throw new UnsupportedOperationException("cannot set the lock mode for a native SQL query");
-	}
-
-	protected Map getLockModes() {
-		//we never need to apply locks to the SQL
-		return CollectionHelper.EMPTY_MAP;
-	}
-
-	public SQLQuery addScalar(String columnAlias, Type type) {
-		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, type ) );
-		return this;
-	}
-
-	public SQLQuery addScalar(String columnAlias) {
-		autodiscovertypes = true;
-		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, null ) );
-		return this;
-	}
-
-	public SQLQuery addJoin(String alias, String path) {
-		return addJoin(alias, path, LockMode.READ);
-	}
-
-	public SQLQuery addEntity(Class entityClass) {
-		return addEntity( StringHelper.unqualify( entityClass.getName() ), entityClass );
-	}
-
-	public SQLQuery addEntity(String entityName) {
-		return addEntity( StringHelper.unqualify( entityName ), entityName );
-	}
-
-	public SQLQuery addEntity(String alias, String entityName) {
-		return addEntity(alias, entityName, LockMode.READ);
-	}
-
-	public SQLQuery addEntity(String alias, Class entityClass) {
-		return addEntity( alias, entityClass.getName() );
-	}
-
-	public SQLQuery addJoin(String alias, String path, LockMode lockMode) {
-		int loc = path.indexOf('.');
-		if ( loc < 0 ) {
-			throw new QueryException( "not a property path: " + path );
-		}
-		String ownerAlias = path.substring(0, loc);
-		String role = path.substring(loc+1);
-		queryReturns.add( new NativeSQLQueryJoinReturn(alias, ownerAlias, role, CollectionHelper.EMPTY_MAP, lockMode) );
-		return this;
-	}
-
-	public SQLQuery addEntity(String alias, String entityName, LockMode lockMode) {
-		queryReturns.add( new NativeSQLQueryRootReturn(alias, entityName, lockMode) );
-		return this;
-	}
-
-	public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode) {
-		return addEntity( alias, entityClass.getName(), lockMode );
-	}
-
-	public SQLQuery setResultSetMapping(String name) {
-		ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( name );
-		if ( mapping == null ) {
-			throw new MappingException( "Unknown SqlResultSetMapping [" + name + "]" );
-		}
-		NativeSQLQueryReturn[] returns = mapping.getQueryReturns();
-		int length = returns.length;
-		for ( int index = 0 ; index < length ; index++ ) {
-			queryReturns.add( returns[index] );
-		}
-		return this;
-	}
-
-	public SQLQuery addSynchronizedQuerySpace(String querySpace) {
-		if ( querySpaces == null ) {
-			querySpaces = new ArrayList();
-		}
-		querySpaces.add( querySpace );
-		return this;
-	}
-
-	public SQLQuery addSynchronizedEntityName(String entityName) {
-		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityName ).getQuerySpaces() );
-	}
-
-	public SQLQuery addSynchronizedEntityClass(Class entityClass) {
-		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityClass.getName() ).getQuerySpaces() );
-	}
-
-	private SQLQuery addQuerySpaces(Serializable[] spaces) {
-		if ( spaces != null ) {
-			if ( querySpaces == null ) {
-				querySpaces = new ArrayList();
-			}
-			for ( int i = 0; i < spaces.length; i++ ) {
-				querySpaces.add( spaces[i] );
-			}
-		}
-		return this;
-	}
-
-	public int executeUpdate() throws HibernateException {
-		Map namedParams = getNamedParams();
-		before();
-		try {
-			return getSession().executeNativeUpdate(
-					generateQuerySpecification( namedParams ),
-					getQueryParameters( namedParams )
-			);
-		}
-		finally {
-			after();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SQLQueryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,367 @@
+/*
+ * 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.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.io.Serializable;
+
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.Query;
+import org.hibernate.QueryException;
+import org.hibernate.SQLQuery;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.MappingException;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.query.ParameterMetadata;
+import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Implements SQL query passthrough.
+ *
+ * <pre>
+ * <sql-query name="mySqlQuery">
+ * <return alias="person" class="eg.Person"/>
+ *   SELECT {person}.NAME AS {person.name}, {person}.AGE AS {person.age}, {person}.SEX AS {person.sex}
+ *   FROM PERSON {person} WHERE {person}.NAME LIKE 'Hiber%'
+ * </sql-query>
+ * </pre>
+ *
+ * @author Max Andersen
+ */
+public class SQLQueryImpl extends AbstractQueryImpl implements SQLQuery {
+
+	private final List queryReturns;
+	private Collection querySpaces;
+	private final boolean callable;
+	private boolean autodiscovertypes;
+
+	/**
+	 * Constructs a SQLQueryImpl given a sql query defined in the mappings.
+	 *
+	 * @param queryDef The representation of the defined <sql-query/>.
+	 * @param session The session to which this SQLQueryImpl belongs.
+	 * @param parameterMetadata Metadata about parameters found in the query.
+	 */
+	SQLQueryImpl(NamedSQLQueryDefinition queryDef, SessionImplementor session, ParameterMetadata parameterMetadata) {
+		super( queryDef.getQueryString(), queryDef.getFlushMode(), session, parameterMetadata );
+		if ( queryDef.getResultSetRef() != null ) {
+			ResultSetMappingDefinition definition = session.getFactory()
+					.getResultSetMapping( queryDef.getResultSetRef() );
+			if (definition == null) {
+				throw new MappingException(
+						"Unable to find resultset-ref definition: " +
+						queryDef.getResultSetRef()
+					);
+			}
+			this.queryReturns = Arrays.asList( definition.getQueryReturns() );
+		}
+		else {
+			this.queryReturns = Arrays.asList( queryDef.getQueryReturns() );
+		}
+
+		this.querySpaces = queryDef.getQuerySpaces();
+		this.callable = queryDef.isCallable();
+	}
+
+	SQLQueryImpl(
+			final String sql,
+	        final List queryReturns,
+	        final Collection querySpaces,
+	        final FlushMode flushMode,
+	        boolean callable,
+	        final SessionImplementor session,
+	        ParameterMetadata parameterMetadata) {
+		// TODO : absolutely no usages of this constructor form; can it go away?
+		super( sql, flushMode, session, parameterMetadata );
+		this.queryReturns = queryReturns;
+		this.querySpaces = querySpaces;
+		this.callable = callable;
+	}
+
+	SQLQueryImpl(
+			final String sql,
+	        final String returnAliases[],
+	        final Class returnClasses[],
+	        final LockMode[] lockModes,
+	        final SessionImplementor session,
+	        final Collection querySpaces,
+	        final FlushMode flushMode,
+	        ParameterMetadata parameterMetadata) {
+		// TODO : this constructor form is *only* used from constructor directly below us; can it go away?
+		super( sql, flushMode, session, parameterMetadata );
+		queryReturns = new ArrayList(returnAliases.length);
+		for ( int i=0; i<returnAliases.length; i++ ) {
+			NativeSQLQueryRootReturn ret = new NativeSQLQueryRootReturn(
+					returnAliases[i],
+					returnClasses[i].getName(),
+					lockModes==null ? LockMode.NONE : lockModes[i]
+			);
+			queryReturns.add(ret);
+		}
+		this.querySpaces = querySpaces;
+		this.callable = false;
+	}
+
+	SQLQueryImpl(
+			final String sql,
+	        final String returnAliases[],
+	        final Class returnClasses[],
+	        final SessionImplementor session,
+	        ParameterMetadata parameterMetadata) {
+		this( sql, returnAliases, returnClasses, null, session, null, null, parameterMetadata );
+	}
+
+	SQLQueryImpl(String sql, SessionImplementor session, ParameterMetadata parameterMetadata) {
+		super( sql, null, session, parameterMetadata );
+		queryReturns = new ArrayList();
+		querySpaces = null;
+		callable = false;
+	}
+
+	private static final NativeSQLQueryReturn[] NO_SQL_RETURNS = new NativeSQLQueryReturn[0];
+
+	private NativeSQLQueryReturn[] getQueryReturns() {
+		return ( NativeSQLQueryReturn[] ) queryReturns.toArray( NO_SQL_RETURNS );
+	}
+
+	public List list() throws HibernateException {
+		verifyParameters();
+		before();
+
+		Map namedParams = getNamedParams();
+		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
+
+		try {
+			return getSession().list( spec, getQueryParameters( namedParams ) );
+		}
+		finally {
+			after();
+		}
+	}
+
+	private NativeSQLQuerySpecification generateQuerySpecification(Map namedParams) {
+		return new NativeSQLQuerySpecification(
+		        expandParameterLists(namedParams),
+		        getQueryReturns(),
+		        querySpaces
+		);
+	}
+
+	public ScrollableResults scroll(ScrollMode scrollMode) throws HibernateException {
+		verifyParameters();
+		before();
+
+		Map namedParams = getNamedParams();
+		NativeSQLQuerySpecification spec = generateQuerySpecification( namedParams );
+
+		QueryParameters qp = getQueryParameters( namedParams );
+		qp.setScrollMode( scrollMode );
+
+		try {
+			return getSession().scroll( spec, qp );
+		}
+		finally {
+			after();
+		}
+	}
+
+	public ScrollableResults scroll() throws HibernateException {
+		return scroll(ScrollMode.SCROLL_INSENSITIVE);
+	}
+
+	public Iterator iterate() throws HibernateException {
+		throw new UnsupportedOperationException("SQL queries do not currently support iteration");
+	}
+
+	public QueryParameters getQueryParameters(Map namedParams) {
+		QueryParameters qp = super.getQueryParameters(namedParams);
+		qp.setCallable(callable);
+		qp.setAutoDiscoverScalarTypes(autodiscovertypes);
+		return qp;
+	}
+
+	protected void verifyParameters() {
+		verifyParameters( callable );
+		boolean noReturns = queryReturns==null || queryReturns.isEmpty();
+		if ( noReturns ) {
+			this.autodiscovertypes = noReturns;
+		}
+		else {
+			Iterator itr = queryReturns.iterator();
+			while ( itr.hasNext() ) {
+				NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) itr.next();
+				if ( rtn instanceof NativeSQLQueryScalarReturn ) {
+					NativeSQLQueryScalarReturn scalar = ( NativeSQLQueryScalarReturn ) rtn;
+					if ( scalar.getType() == null ) {
+						autodiscovertypes = true;
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	public String[] getReturnAliases() throws HibernateException {
+		throw new UnsupportedOperationException("SQL queries do not currently support returning aliases");
+	}
+
+	public Type[] getReturnTypes() throws HibernateException {
+		throw new UnsupportedOperationException("not yet implemented for SQL queries");
+	}
+
+	public Query setLockMode(String alias, LockMode lockMode) {
+		throw new UnsupportedOperationException("cannot set the lock mode for a native SQL query");
+	}
+
+	protected Map getLockModes() {
+		//we never need to apply locks to the SQL
+		return CollectionHelper.EMPTY_MAP;
+	}
+
+	public SQLQuery addScalar(String columnAlias, Type type) {
+		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, type ) );
+		return this;
+	}
+
+	public SQLQuery addScalar(String columnAlias) {
+		autodiscovertypes = true;
+		queryReturns.add( new NativeSQLQueryScalarReturn( columnAlias, null ) );
+		return this;
+	}
+
+	public SQLQuery addJoin(String alias, String path) {
+		return addJoin(alias, path, LockMode.READ);
+	}
+
+	public SQLQuery addEntity(Class entityClass) {
+		return addEntity( StringHelper.unqualify( entityClass.getName() ), entityClass );
+	}
+
+	public SQLQuery addEntity(String entityName) {
+		return addEntity( StringHelper.unqualify( entityName ), entityName );
+	}
+
+	public SQLQuery addEntity(String alias, String entityName) {
+		return addEntity(alias, entityName, LockMode.READ);
+	}
+
+	public SQLQuery addEntity(String alias, Class entityClass) {
+		return addEntity( alias, entityClass.getName() );
+	}
+
+	public SQLQuery addJoin(String alias, String path, LockMode lockMode) {
+		int loc = path.indexOf('.');
+		if ( loc < 0 ) {
+			throw new QueryException( "not a property path: " + path );
+		}
+		String ownerAlias = path.substring(0, loc);
+		String role = path.substring(loc+1);
+		queryReturns.add( new NativeSQLQueryJoinReturn(alias, ownerAlias, role, CollectionHelper.EMPTY_MAP, lockMode) );
+		return this;
+	}
+
+	public SQLQuery addEntity(String alias, String entityName, LockMode lockMode) {
+		queryReturns.add( new NativeSQLQueryRootReturn(alias, entityName, lockMode) );
+		return this;
+	}
+
+	public SQLQuery addEntity(String alias, Class entityClass, LockMode lockMode) {
+		return addEntity( alias, entityClass.getName(), lockMode );
+	}
+
+	public SQLQuery setResultSetMapping(String name) {
+		ResultSetMappingDefinition mapping = session.getFactory().getResultSetMapping( name );
+		if ( mapping == null ) {
+			throw new MappingException( "Unknown SqlResultSetMapping [" + name + "]" );
+		}
+		NativeSQLQueryReturn[] returns = mapping.getQueryReturns();
+		int length = returns.length;
+		for ( int index = 0 ; index < length ; index++ ) {
+			queryReturns.add( returns[index] );
+		}
+		return this;
+	}
+
+	public SQLQuery addSynchronizedQuerySpace(String querySpace) {
+		if ( querySpaces == null ) {
+			querySpaces = new ArrayList();
+		}
+		querySpaces.add( querySpace );
+		return this;
+	}
+
+	public SQLQuery addSynchronizedEntityName(String entityName) {
+		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityName ).getQuerySpaces() );
+	}
+
+	public SQLQuery addSynchronizedEntityClass(Class entityClass) {
+		return addQuerySpaces( getSession().getFactory().getEntityPersister( entityClass.getName() ).getQuerySpaces() );
+	}
+
+	private SQLQuery addQuerySpaces(Serializable[] spaces) {
+		if ( spaces != null ) {
+			if ( querySpaces == null ) {
+				querySpaces = new ArrayList();
+			}
+			for ( int i = 0; i < spaces.length; i++ ) {
+				querySpaces.add( spaces[i] );
+			}
+		}
+		return this;
+	}
+
+	public int executeUpdate() throws HibernateException {
+		Map namedParams = getNamedParams();
+		before();
+		try {
+			return getSession().executeNativeUpdate(
+					generateQuerySpecification( namedParams ),
+					getQueryParameters( namedParams )
+			);
+		}
+		finally {
+			after();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,251 +0,0 @@
-//$Id: ScrollableResultsImpl.java 7469 2005-07-14 13:12:19Z steveebersole $
-package org.hibernate.impl;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.loader.Loader;
-import org.hibernate.type.Type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/**
- * Implementation of the <tt>ScrollableResults</tt> interface
- * @author Gavin King
- */
-public class ScrollableResultsImpl extends AbstractScrollableResults implements ScrollableResults {
-
-	private Object[] currentRow;
-
-	public ScrollableResultsImpl(
-	        ResultSet rs,
-	        PreparedStatement ps,
-	        SessionImplementor sess,
-	        Loader loader,
-	        QueryParameters queryParameters,
-	        Type[] types, HolderInstantiator holderInstantiator) throws MappingException {
-		super( rs, ps, sess, loader, queryParameters, types, holderInstantiator );
-	}
-
-	protected Object[] getCurrentRow() {
-		return currentRow;
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#scroll(int)
-	 */
-	public boolean scroll(int i) throws HibernateException {
-		try {
-			boolean result = getResultSet().relative(i);
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using scroll()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#first()
-	 */
-	public boolean first() throws HibernateException {
-		try {
-			boolean result = getResultSet().first();
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using first()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#last()
-	 */
-	public boolean last() throws HibernateException {
-		try {
-			boolean result = getResultSet().last();
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using last()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#next()
-	 */
-	public boolean next() throws HibernateException {
-		try {
-			boolean result = getResultSet().next();
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using next()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#previous()
-	 */
-	public boolean previous() throws HibernateException {
-		try {
-			boolean result = getResultSet().previous();
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using previous()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#afterLast()
-	 */
-	public void afterLast() throws HibernateException {
-		try {
-			getResultSet().afterLast();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"exception calling afterLast()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#beforeFirst()
-	 */
-	public void beforeFirst() throws HibernateException {
-		try {
-			getResultSet().beforeFirst();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"exception calling beforeFirst()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#isFirst()
-	 */
-	public boolean isFirst() throws HibernateException {
-		try {
-			return getResultSet().isFirst();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"exception calling isFirst()"
-				);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.ScrollableResults#isLast()
-	 */
-	public boolean isLast() throws HibernateException {
-		try {
-			return getResultSet().isLast();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"exception calling isLast()"
-				);
-		}
-	}
-
-	public int getRowNumber() throws HibernateException {
-		try {
-			return getResultSet().getRow()-1;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"exception calling getRow()"
-				);
-		}
-	}
-
-	public boolean setRowNumber(int rowNumber) throws HibernateException {
-		if (rowNumber>=0) rowNumber++;
-		try {
-			boolean result = getResultSet().absolute(rowNumber);
-			prepareCurrentRow(result);
-			return result;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getSession().getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not advance using absolute()"
-				);
-		}
-	}
-
-	private void prepareCurrentRow(boolean underlyingScrollSuccessful) 
-	throws HibernateException {
-		
-		if (!underlyingScrollSuccessful) {
-			currentRow = null;
-			return;
-		}
-
-		Object result = getLoader().loadSingleRow(
-				getResultSet(),
-				getSession(),
-				getQueryParameters(),
-				false
-		);
-		if ( result != null && result.getClass().isArray() ) {
-			currentRow = (Object[]) result;
-		}
-		else {
-			currentRow = new Object[] { result };
-		}
-
-		if ( getHolderInstantiator() != null ) {
-			currentRow = new Object[] { getHolderInstantiator().instantiate(currentRow) };
-		}
-
-		afterScrollOperation();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/ScrollableResultsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,274 @@
+/*
+ * 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.impl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.loader.Loader;
+import org.hibernate.type.Type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Implementation of the <tt>ScrollableResults</tt> interface
+ * @author Gavin King
+ */
+public class ScrollableResultsImpl extends AbstractScrollableResults implements ScrollableResults {
+
+	private Object[] currentRow;
+
+	public ScrollableResultsImpl(
+	        ResultSet rs,
+	        PreparedStatement ps,
+	        SessionImplementor sess,
+	        Loader loader,
+	        QueryParameters queryParameters,
+	        Type[] types, HolderInstantiator holderInstantiator) throws MappingException {
+		super( rs, ps, sess, loader, queryParameters, types, holderInstantiator );
+	}
+
+	protected Object[] getCurrentRow() {
+		return currentRow;
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#scroll(int)
+	 */
+	public boolean scroll(int i) throws HibernateException {
+		try {
+			boolean result = getResultSet().relative(i);
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using scroll()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#first()
+	 */
+	public boolean first() throws HibernateException {
+		try {
+			boolean result = getResultSet().first();
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using first()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#last()
+	 */
+	public boolean last() throws HibernateException {
+		try {
+			boolean result = getResultSet().last();
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using last()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#next()
+	 */
+	public boolean next() throws HibernateException {
+		try {
+			boolean result = getResultSet().next();
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using next()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#previous()
+	 */
+	public boolean previous() throws HibernateException {
+		try {
+			boolean result = getResultSet().previous();
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using previous()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#afterLast()
+	 */
+	public void afterLast() throws HibernateException {
+		try {
+			getResultSet().afterLast();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"exception calling afterLast()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#beforeFirst()
+	 */
+	public void beforeFirst() throws HibernateException {
+		try {
+			getResultSet().beforeFirst();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"exception calling beforeFirst()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#isFirst()
+	 */
+	public boolean isFirst() throws HibernateException {
+		try {
+			return getResultSet().isFirst();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"exception calling isFirst()"
+				);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.ScrollableResults#isLast()
+	 */
+	public boolean isLast() throws HibernateException {
+		try {
+			return getResultSet().isLast();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"exception calling isLast()"
+				);
+		}
+	}
+
+	public int getRowNumber() throws HibernateException {
+		try {
+			return getResultSet().getRow()-1;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"exception calling getRow()"
+				);
+		}
+	}
+
+	public boolean setRowNumber(int rowNumber) throws HibernateException {
+		if (rowNumber>=0) rowNumber++;
+		try {
+			boolean result = getResultSet().absolute(rowNumber);
+			prepareCurrentRow(result);
+			return result;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getSession().getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not advance using absolute()"
+				);
+		}
+	}
+
+	private void prepareCurrentRow(boolean underlyingScrollSuccessful) 
+	throws HibernateException {
+		
+		if (!underlyingScrollSuccessful) {
+			currentRow = null;
+			return;
+		}
+
+		Object result = getLoader().loadSingleRow(
+				getResultSet(),
+				getSession(),
+				getQueryParameters(),
+				false
+		);
+		if ( result != null && result.getClass().isArray() ) {
+			currentRow = (Object[]) result;
+		}
+		else {
+			currentRow = new Object[] { result };
+		}
+
+		if ( getHolderInstantiator() != null ) {
+			currentRow = new Object[] { getHolderInstantiator().instantiate(currentRow) };
+		}
+
+		afterScrollOperation();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1086 +0,0 @@
-//$Id: SessionFactoryImpl.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import java.io.IOException;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.ObjectStreamException;
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.StringRefAddr;
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.MappingException;
-import org.hibernate.ObjectNotFoundException;
-import org.hibernate.QueryException;
-import org.hibernate.SessionFactory;
-import org.hibernate.StatelessSession;
-import org.hibernate.SessionFactoryObserver;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.CollectionRegion;
-import org.hibernate.cache.EntityRegion;
-import org.hibernate.cache.QueryCache;
-import org.hibernate.cache.Region;
-import org.hibernate.cache.UpdateTimestampsCache;
-import org.hibernate.cache.access.AccessType;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.impl.CacheDataDescriptionImpl;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.cfg.Settings;
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.context.CurrentSessionContext;
-import org.hibernate.context.JTASessionContext;
-import org.hibernate.context.ManagedSessionContext;
-import org.hibernate.context.ThreadLocalSessionContext;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.NamedQueryDefinition;
-import org.hibernate.engine.NamedSQLQueryDefinition;
-import org.hibernate.engine.ResultSetMappingDefinition;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.query.QueryPlanCache;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.event.EventListeners;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.UUIDHexGenerator;
-import org.hibernate.jdbc.BatcherFactory;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.RootClass;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.PersisterFactory;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.EntityNotFoundDelegate;
-import org.hibernate.stat.Statistics;
-import org.hibernate.stat.StatisticsImpl;
-import org.hibernate.stat.StatisticsImplementor;
-import org.hibernate.tool.hbm2ddl.SchemaExport;
-import org.hibernate.tool.hbm2ddl.SchemaUpdate;
-import org.hibernate.tool.hbm2ddl.SchemaValidator;
-import org.hibernate.transaction.TransactionFactory;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.ReflectHelper;
-
-
-/**
- * Concrete implementation of the <tt>SessionFactory</tt> interface. Has the following
- * responsibilites
- * <ul>
- * <li>caches configuration settings (immutably)
- * <li>caches "compiled" mappings ie. <tt>EntityPersister</tt>s and
- *     <tt>CollectionPersister</tt>s (immutable)
- * <li>caches "compiled" queries (memory sensitive cache)
- * <li>manages <tt>PreparedStatement</tt>s
- * <li> delegates JDBC <tt>Connection</tt> management to the <tt>ConnectionProvider</tt>
- * <li>factory for instances of <tt>SessionImpl</tt>
- * </ul>
- * This class must appear immutable to clients, even if it does all kinds of caching
- * and pooling under the covers. It is crucial that the class is not only thread
- * safe, but also highly concurrent. Synchronization must be used extremely sparingly.
- *
- * @see org.hibernate.connection.ConnectionProvider
- * @see org.hibernate.classic.Session
- * @see org.hibernate.hql.QueryTranslator
- * @see org.hibernate.persister.entity.EntityPersister
- * @see org.hibernate.persister.collection.CollectionPersister
- * @author Gavin King
- */
-public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor {
-
-	private static final Logger log = LoggerFactory.getLogger(SessionFactoryImpl.class);
-	private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator();
-
-	private final String name;
-	private final String uuid;
-
-	private final transient Map entityPersisters;
-	private final transient Map classMetadata;
-	private final transient Map collectionPersisters;
-	private final transient Map collectionMetadata;
-	private final transient Map collectionRolesByEntityParticipant;
-	private final transient Map identifierGenerators;
-	private final transient Map namedQueries;
-	private final transient Map namedSqlQueries;
-	private final transient Map sqlResultSetMappings;
-	private final transient Map filters;
-	private final transient Map imports;
-	private final transient Interceptor interceptor;
-	private final transient Settings settings;
-	private final transient Properties properties;
-	private transient SchemaExport schemaExport;
-	private final transient TransactionManager transactionManager;
-	private final transient QueryCache queryCache;
-	private final transient UpdateTimestampsCache updateTimestampsCache;
-	private final transient Map queryCaches;
-	private final transient Map allCacheRegions = new HashMap();
-	private final transient StatisticsImpl statistics = new StatisticsImpl(this);
-	private final transient EventListeners eventListeners;
-	private final transient CurrentSessionContext currentSessionContext;
-	private final transient EntityNotFoundDelegate entityNotFoundDelegate;
-	private final transient SQLFunctionRegistry sqlFunctionRegistry;
-	private final transient SessionFactoryObserver observer;
-
-	private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
-
-	private transient boolean isClosed = false;
-
-	public SessionFactoryImpl(
-			Configuration cfg,
-	        Mapping mapping,
-	        Settings settings,
-	        EventListeners listeners,
-			SessionFactoryObserver observer) throws HibernateException {
-
-		log.info("building session factory");
-
-		this.properties = new Properties();
-		this.properties.putAll( cfg.getProperties() );
-		this.interceptor = cfg.getInterceptor();
-		this.settings = settings;
-		this.sqlFunctionRegistry = new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions());
-        this.eventListeners = listeners;
-		this.observer = observer != null ? observer : new SessionFactoryObserver() {
-			public void sessionFactoryCreated(SessionFactory factory) {
-			}
-			public void sessionFactoryClosed(SessionFactory factory) {
-			}
-		};
-		this.filters = new HashMap();
-		this.filters.putAll( cfg.getFilterDefinitions() );
-
-		if ( log.isDebugEnabled() ) {
-			log.debug("Session factory constructed with filter configurations : " + filters);
-		}
-
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"instantiating session factory with properties: " + properties
-			);
-		}
-
-		// Caches
-		settings.getRegionFactory().start( settings, properties );
-
-		//Generators:
-
-		identifierGenerators = new HashMap();
-		Iterator classes = cfg.getClassMappings();
-		while ( classes.hasNext() ) {
-			PersistentClass model = (PersistentClass) classes.next();
-			if ( !model.isInherited() ) {
-				IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
-						settings.getDialect(),
-				        settings.getDefaultCatalogName(),
-				        settings.getDefaultSchemaName(),
-				        (RootClass) model
-					);
-				identifierGenerators.put( model.getEntityName(), generator );
-			}
-		}
-
-
-		///////////////////////////////////////////////////////////////////////
-		// Prepare persisters and link them up with their cache
-		// region/access-strategy
-
-		final String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";
-
-		entityPersisters = new HashMap();
-		Map entityAccessStrategies = new HashMap();
-		Map classMeta = new HashMap();
-		classes = cfg.getClassMappings();
-		while ( classes.hasNext() ) {
-			final PersistentClass model = (PersistentClass) classes.next();
-			model.prepareTemporaryTables( mapping, settings.getDialect() );
-			final String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();
-			// cache region is defined by the root-class in the hierarchy...
-			EntityRegionAccessStrategy accessStrategy = ( EntityRegionAccessStrategy ) entityAccessStrategies.get( cacheRegionName );
-			if ( accessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
-				final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
-				if ( accessType != null ) {
-					log.trace( "Building cache for entity data [" + model.getEntityName() + "]" );
-					EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
-					accessStrategy = entityRegion.buildAccessStrategy( accessType );
-					entityAccessStrategies.put( cacheRegionName, accessStrategy );
-					allCacheRegions.put( cacheRegionName, entityRegion );
-				}
-			}
-			EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, mapping );
-			entityPersisters.put( model.getEntityName(), cp );
-			classMeta.put( model.getEntityName(), cp.getClassMetadata() );
-		}
-		classMetadata = Collections.unmodifiableMap(classMeta);
-
-		Map tmpEntityToCollectionRoleMap = new HashMap();
-		collectionPersisters = new HashMap();
-		Iterator collections = cfg.getCollectionMappings();
-		while ( collections.hasNext() ) {
-			Collection model = (Collection) collections.next();
-			final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
-			final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
-			CollectionRegionAccessStrategy accessStrategy = null;
-			if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
-				log.trace( "Building cache for collection data [" + model.getRole() + "]" );
-				CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
-				accessStrategy = collectionRegion.buildAccessStrategy( accessType );
-				entityAccessStrategies.put( cacheRegionName, accessStrategy );
-				allCacheRegions.put( cacheRegionName, collectionRegion );
-			}
-			CollectionPersister persister = PersisterFactory.createCollectionPersister( cfg, model, accessStrategy, this) ;
-			collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
-			Type indexType = persister.getIndexType();
-			if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
-				String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
-				Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
-				if ( roles == null ) {
-					roles = new HashSet();
-					tmpEntityToCollectionRoleMap.put( entityName, roles );
-				}
-				roles.add( persister.getRole() );
-			}
-			Type elementType = persister.getElementType();
-			if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
-				String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
-				Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
-				if ( roles == null ) {
-					roles = new HashSet();
-					tmpEntityToCollectionRoleMap.put( entityName, roles );
-				}
-				roles.add( persister.getRole() );
-			}
-		}
-		collectionMetadata = Collections.unmodifiableMap(collectionPersisters);
-		Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
-		}
-		collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
-
-		//Named Queries:
-		namedQueries = new HashMap( cfg.getNamedQueries() );
-		namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
-		sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
-		imports = new HashMap( cfg.getImports() );
-
-		// after *all* persisters and named queries are registered
-		Iterator iter = entityPersisters.values().iterator();
-		while ( iter.hasNext() ) {
-			( (EntityPersister) iter.next() ).postInstantiate();
-		}
-		iter = collectionPersisters.values().iterator();
-		while ( iter.hasNext() ) {
-			( (CollectionPersister) iter.next() ).postInstantiate();
-		}
-
-		//JNDI + Serialization:
-
-		name = settings.getSessionFactoryName();
-		try {
-			uuid = (String) UUID_GENERATOR.generate(null, null);
-		}
-		catch (Exception e) {
-			throw new AssertionFailure("Could not generate UUID");
-		}
-		SessionFactoryObjectFactory.addInstance(uuid, name, this, properties);
-
-		log.debug("instantiated session factory");
-
-		if ( settings.isAutoCreateSchema() ) {
-			new SchemaExport( cfg, settings ).create( false, true );
-		}
-		if ( settings.isAutoUpdateSchema() ) {
-			new SchemaUpdate( cfg, settings ).execute( false, true );
-		}
-		if ( settings.isAutoValidateSchema() ) {
-			new SchemaValidator( cfg, settings ).validate();
-		}
-		if ( settings.isAutoDropSchema() ) {
-			schemaExport = new SchemaExport( cfg, settings );
-		}
-
-		if ( settings.getTransactionManagerLookup()!=null ) {
-			log.debug("obtaining JTA TransactionManager");
-			transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
-		}
-		else {
-			if ( settings.getTransactionFactory().isTransactionManagerRequired() ) {
-				throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");
-			}
-			transactionManager = null;
-		}
-
-		currentSessionContext = buildCurrentSessionContext();
-
-		if ( settings.isQueryCacheEnabled() ) {
-			updateTimestampsCache = new UpdateTimestampsCache(settings, properties);
-			queryCache = settings.getQueryCacheFactory()
-			        .getQueryCache(null, updateTimestampsCache, settings, properties);
-			queryCaches = new HashMap();
-			allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion() );
-			allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() );
-		}
-		else {
-			updateTimestampsCache = null;
-			queryCache = null;
-			queryCaches = null;
-		}
-
-		//checking for named queries
-		if ( settings.isNamedQueryStartupCheckingEnabled() ) {
-			Map errors = checkNamedQueries();
-			if ( !errors.isEmpty() ) {
-				Set keys = errors.keySet();
-				StringBuffer failingQueries = new StringBuffer( "Errors in named queries: " );
-				for ( Iterator iterator = keys.iterator() ; iterator.hasNext() ; ) {
-					String queryName = ( String ) iterator.next();
-					HibernateException e = ( HibernateException ) errors.get( queryName );
-					failingQueries.append( queryName );
-					if ( iterator.hasNext() ) {
-						failingQueries.append( ", " );
-					}
-					log.error( "Error in named query: " + queryName, e );
-				}
-				throw new HibernateException( failingQueries.toString() );
-			}
-		}
-
-		//stats
-		getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() );
-
-		// EntityNotFoundDelegate
-		EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
-		if ( entityNotFoundDelegate == null ) {
-			entityNotFoundDelegate = new EntityNotFoundDelegate() {
-				public void handleEntityNotFound(String entityName, Serializable id) {
-					throw new ObjectNotFoundException( id, entityName );
-				}
-			};
-		}
-		this.entityNotFoundDelegate = entityNotFoundDelegate;
-
-		this.observer.sessionFactoryCreated( this );
-	}
-
-	public QueryPlanCache getQueryPlanCache() {
-		return queryPlanCache;
-	}
-
-	private Map checkNamedQueries() throws HibernateException {
-		Map errors = new HashMap();
-
-		// Check named HQL queries
-		log.debug("Checking " + namedQueries.size() + " named HQL queries");
-		Iterator itr = namedQueries.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final String queryName = ( String ) entry.getKey();
-			final NamedQueryDefinition qd = ( NamedQueryDefinition ) entry.getValue();
-			// this will throw an error if there's something wrong.
-			try {
-				log.debug("Checking named query: " + queryName);
-				//TODO: BUG! this currently fails for named queries for non-POJO entities
-				queryPlanCache.getHQLQueryPlan( qd.getQueryString(), false, CollectionHelper.EMPTY_MAP );
-			}
-			catch ( QueryException e ) {
-				errors.put( queryName, e );
-			}
-			catch ( MappingException e ) {
-				errors.put( queryName, e );
-			}
-		}
-
-		log.debug("Checking " + namedSqlQueries.size() + " named SQL queries");
-		itr = namedSqlQueries.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final String queryName = ( String ) entry.getKey();
-			final NamedSQLQueryDefinition qd = ( NamedSQLQueryDefinition ) entry.getValue();
-			// this will throw an error if there's something wrong.
-			try {
-				log.debug("Checking named SQL query: " + queryName);
-				// TODO : would be really nice to cache the spec on the query-def so as to not have to re-calc the hash;
-				// currently not doable though because of the resultset-ref stuff...
-				NativeSQLQuerySpecification spec;
-				if ( qd.getResultSetRef() != null ) {
-					ResultSetMappingDefinition definition = ( ResultSetMappingDefinition ) sqlResultSetMappings.get( qd.getResultSetRef() );
-					if ( definition == null ) {
-						throw new MappingException( "Unable to find resultset-ref definition: " + qd.getResultSetRef() );
-					}
-					spec = new NativeSQLQuerySpecification(
-							qd.getQueryString(),
-					        definition.getQueryReturns(),
-					        qd.getQuerySpaces()
-					);
-				}
-				else {
-					spec =  new NativeSQLQuerySpecification(
-							qd.getQueryString(),
-					        qd.getQueryReturns(),
-					        qd.getQuerySpaces()
-					);
-				}
-				queryPlanCache.getNativeSQLQueryPlan( spec );
-			}
-			catch ( QueryException e ) {
-				errors.put( queryName, e );
-			}
-			catch ( MappingException e ) {
-				errors.put( queryName, e );
-			}
-		}
-
-		return errors;
-	}
-
-	public StatelessSession openStatelessSession() {
-		return new StatelessSessionImpl( null, this );
-	}
-
-	public StatelessSession openStatelessSession(Connection connection) {
-		return new StatelessSessionImpl( connection, this );
-	}
-
-	private SessionImpl openSession(
-		Connection connection,
-	    boolean autoClose,
-	    long timestamp,
-	    Interceptor sessionLocalInterceptor
-	) {
-		return new SessionImpl(
-		        connection,
-		        this,
-		        autoClose,
-		        timestamp,
-		        sessionLocalInterceptor == null ? interceptor : sessionLocalInterceptor,
-		        settings.getDefaultEntityMode(),
-		        settings.isFlushBeforeCompletionEnabled(),
-		        settings.isAutoCloseSessionEnabled(),
-		        settings.getConnectionReleaseMode()
-			);
-	}
-
-	public org.hibernate.classic.Session openSession(Connection connection, Interceptor sessionLocalInterceptor) {
-		return openSession(connection, false, Long.MIN_VALUE, sessionLocalInterceptor);
-	}
-
-	public org.hibernate.classic.Session openSession(Interceptor sessionLocalInterceptor)
-	throws HibernateException {
-		// note that this timestamp is not correct if the connection provider
-		// returns an older JDBC connection that was associated with a
-		// transaction that was already begun before openSession() was called
-		// (don't know any possible solution to this!)
-		long timestamp = settings.getRegionFactory().nextTimestamp();
-		return openSession( null, true, timestamp, sessionLocalInterceptor );
-	}
-
-	public org.hibernate.classic.Session openSession(Connection connection) {
-		return openSession(connection, interceptor); //prevents this session from adding things to cache
-	}
-
-	public org.hibernate.classic.Session openSession() throws HibernateException {
-		return openSession(interceptor);
-	}
-
-	public org.hibernate.classic.Session openTemporarySession() throws HibernateException {
-		return new SessionImpl(
-				null,
-		        this,
-		        true,
-		        settings.getRegionFactory().nextTimestamp(),
-		        interceptor,
-		        settings.getDefaultEntityMode(),
-		        false,
-		        false,
-		        ConnectionReleaseMode.AFTER_STATEMENT
-			);
-	}
-
-	public org.hibernate.classic.Session openSession(
-			final Connection connection,
-	        final boolean flushBeforeCompletionEnabled,
-	        final boolean autoCloseSessionEnabled,
-	        final ConnectionReleaseMode connectionReleaseMode) throws HibernateException {
-		return new SessionImpl(
-				connection,
-		        this,
-		        true,
-		        settings.getRegionFactory().nextTimestamp(),
-		        interceptor,
-		        settings.getDefaultEntityMode(),
-		        flushBeforeCompletionEnabled,
-		        autoCloseSessionEnabled,
-		        connectionReleaseMode
-			);
-	}
-
-	public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
-		if ( currentSessionContext == null ) {
-			throw new HibernateException( "No CurrentSessionContext configured!" );
-		}
-		return currentSessionContext.currentSession();
-	}
-
-	public EntityPersister getEntityPersister(String entityName) throws MappingException {
-		EntityPersister result = (EntityPersister) entityPersisters.get(entityName);
-		if (result==null) {
-			throw new MappingException( "Unknown entity: " + entityName );
-		}
-		return result;
-	}
-
-	public CollectionPersister getCollectionPersister(String role) throws MappingException {
-		CollectionPersister result = (CollectionPersister) collectionPersisters.get(role);
-		if (result==null) {
-			throw new MappingException( "Unknown collection role: " + role );
-		}
-		return result;
-	}
-
-	public Settings getSettings() {
-		return settings;
-	}
-
-	public Dialect getDialect() {
-		return settings.getDialect();
-	}
-
-	public Interceptor getInterceptor()
-	{
-		return interceptor;
-	}
-
-	public TransactionFactory getTransactionFactory() {
-		return settings.getTransactionFactory();
-	}
-
-	public TransactionManager getTransactionManager() {
-		return transactionManager;
-	}
-
-	public SQLExceptionConverter getSQLExceptionConverter() {
-		return settings.getSQLExceptionConverter();
-	}
-
-	public Set getCollectionRolesByEntityParticipant(String entityName) {
-		return ( Set ) collectionRolesByEntityParticipant.get( entityName );
-	}
-
-	// from javax.naming.Referenceable
-	public Reference getReference() throws NamingException {
-		log.debug("Returning a Reference to the SessionFactory");
-		return new Reference(
-			SessionFactoryImpl.class.getName(),
-		    new StringRefAddr("uuid", uuid),
-		    SessionFactoryObjectFactory.class.getName(),
-		    null
-		);
-	}
-
-	private Object readResolve() throws ObjectStreamException {
-		log.trace("Resolving serialized SessionFactory");
-		// look for the instance by uuid
-		Object result = SessionFactoryObjectFactory.getInstance(uuid);
-		if (result==null) {
-			// in case we were deserialized in a different JVM, look for an instance with the same name
-			// (alternatively we could do an actual JNDI lookup here....)
-			result = SessionFactoryObjectFactory.getNamedInstance(name);
-			if (result==null) {
-				throw new InvalidObjectException("Could not find a SessionFactory named: " + name);
-			}
-			else {
-				log.debug("resolved SessionFactory by name");
-			}
-		}
-		else {
-			log.debug("resolved SessionFactory by uid");
-		}
-		return result;
-	}
-
-	public NamedQueryDefinition getNamedQuery(String queryName) {
-		return (NamedQueryDefinition) namedQueries.get(queryName);
-	}
-
-	public NamedSQLQueryDefinition getNamedSQLQuery(String queryName) {
-		return (NamedSQLQueryDefinition) namedSqlQueries.get(queryName);
-	}
-
-	public ResultSetMappingDefinition getResultSetMapping(String resultSetName) {
-		return (ResultSetMappingDefinition) sqlResultSetMappings.get(resultSetName);
-	}
-
-	public Type getIdentifierType(String className) throws MappingException {
-		return getEntityPersister(className).getIdentifierType();
-	}
-	public String getIdentifierPropertyName(String className) throws MappingException {
-		return getEntityPersister(className).getIdentifierPropertyName();
-	}
-
-	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
-		log.trace("deserializing");
-		in.defaultReadObject();
-		log.debug("deserialized: " + uuid);
-	}
-
-	private void writeObject(ObjectOutputStream out) throws IOException {
-		log.debug("serializing: " + uuid);
-		out.defaultWriteObject();
-		log.trace("serialized");
-	}
-
-	public Type[] getReturnTypes(String queryString) throws HibernateException {
-		return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnTypes();
-	}
-
-	public String[] getReturnAliases(String queryString) throws HibernateException {
-		return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnAliases();
-	}
-
-	public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException {
-		return getClassMetadata( persistentClass.getName() );
-	}
-
-	public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException {
-		return (CollectionMetadata) collectionMetadata.get(roleName);
-	}
-
-	public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
-		return (ClassMetadata) classMetadata.get(entityName);
-	}
-
-	/**
-	 * Return the names of all persistent (mapped) classes that extend or implement the
-	 * given class or interface, accounting for implicit/explicit polymorphism settings
-	 * and excluding mapped subclasses/joined-subclasses of other classes in the result.
-	 */
-	public String[] getImplementors(String className) throws MappingException {
-
-		final Class clazz;
-		try {
-			clazz = ReflectHelper.classForName(className);
-		}
-		catch (ClassNotFoundException cnfe) {
-			return new String[] { className }; //for a dynamic-class
-		}
-
-		ArrayList results = new ArrayList();
-		Iterator iter = entityPersisters.values().iterator();
-		while ( iter.hasNext() ) {
-			//test this entity to see if we must query it
-			EntityPersister testPersister = (EntityPersister) iter.next();
-			if ( testPersister instanceof Queryable ) {
-				Queryable testQueryable = (Queryable) testPersister;
-				String testClassName = testQueryable.getEntityName();
-				boolean isMappedClass = className.equals(testClassName);
-				if ( testQueryable.isExplicitPolymorphism() ) {
-					if ( isMappedClass ) {
-						return new String[] {className}; //NOTE EARLY EXIT
-					}
-				}
-				else {
-					if (isMappedClass) {
-						results.add(testClassName);
-					}
-					else {
-						final Class mappedClass = testQueryable.getMappedClass( EntityMode.POJO );
-						if ( mappedClass!=null && clazz.isAssignableFrom( mappedClass ) ) {
-							final boolean assignableSuperclass;
-							if ( testQueryable.isInherited() ) {
-								Class mappedSuperclass = getEntityPersister( testQueryable.getMappedSuperclass() ).getMappedClass( EntityMode.POJO);
-								assignableSuperclass = clazz.isAssignableFrom(mappedSuperclass);
-							}
-							else {
-								assignableSuperclass = false;
-							}
-							if ( !assignableSuperclass ) {
-								results.add( testClassName );
-							}
-						}
-					}
-				}
-			}
-		}
-		return (String[]) results.toArray( new String[ results.size() ] );
-	}
-
-	public String getImportedClassName(String className) {
-		String result = (String) imports.get(className);
-		if (result==null) {
-			try {
-				ReflectHelper.classForName(className);
-				return className;
-			}
-			catch (ClassNotFoundException cnfe) {
-				return null;
-			}
-		}
-		else {
-			return result;
-		}
-	}
-
-	public Map getAllClassMetadata() throws HibernateException {
-		return classMetadata;
-	}
-
-	public Map getAllCollectionMetadata() throws HibernateException {
-		return collectionMetadata;
-	}
-
-	/**
-	 * Closes the session factory, releasing all held resources.
-	 *
-	 * <ol>
-	 * <li>cleans up used cache regions and "stops" the cache provider.
-	 * <li>close the JDBC connection
-	 * <li>remove the JNDI binding
-	 * </ol>
-	 *
-	 * Note: Be aware that the sessionfactory instance still can
-	 * be a "heavy" object memory wise after close() has been called.  Thus
-	 * it is important to not keep referencing the instance to let the garbage
-	 * collector release the memory.
-	 */
-	public void close() throws HibernateException {
-
-		if ( isClosed ) {
-			log.trace( "already closed" );
-			return;
-		}
-
-		log.info("closing");
-
-		isClosed = true;
-
-		Iterator iter = entityPersisters.values().iterator();
-		while ( iter.hasNext() ) {
-			EntityPersister p = (EntityPersister) iter.next();
-			if ( p.hasCache() ) {
-				p.getCacheAccessStrategy().getRegion().destroy();
-			}
-		}
-
-		iter = collectionPersisters.values().iterator();
-		while ( iter.hasNext() ) {
-			CollectionPersister p = (CollectionPersister) iter.next();
-			if ( p.hasCache() ) {
-				p.getCacheAccessStrategy().getRegion().destroy();
-			}
-		}
-
-		if ( settings.isQueryCacheEnabled() )  {
-			queryCache.destroy();
-
-			iter = queryCaches.values().iterator();
-			while ( iter.hasNext() ) {
-				QueryCache cache = (QueryCache) iter.next();
-				cache.destroy();
-			}
-			updateTimestampsCache.destroy();
-		}
-
-		settings.getRegionFactory().stop();
-
-		try {
-			settings.getConnectionProvider().close();
-		}
-		finally {
-			SessionFactoryObjectFactory.removeInstance(uuid, name, properties);
-		}
-
-		if ( settings.isAutoDropSchema() ) {
-			schemaExport.drop( false, true );
-		}
-
-		observer.sessionFactoryClosed( this );
-		eventListeners.destroyListeners();
-	}
-
-	public void evictEntity(String entityName, Serializable id) throws HibernateException {
-		EntityPersister p = getEntityPersister( entityName );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) );
-			}
-			CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this );
-			p.getCacheAccessStrategy().evict( cacheKey );
-		}
-	}
-
-	public void evictEntity(String entityName) throws HibernateException {
-		EntityPersister p = getEntityPersister( entityName );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + p.getEntityName() );
-			}
-			p.getCacheAccessStrategy().evictAll();
-		}
-	}
-
-	public void evict(Class persistentClass, Serializable id) throws HibernateException {
-		EntityPersister p = getEntityPersister( persistentClass.getName() );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) );
-			}
-			CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this );
-			p.getCacheAccessStrategy().evict( cacheKey );
-		}
-	}
-
-	public void evict(Class persistentClass) throws HibernateException {
-		EntityPersister p = getEntityPersister( persistentClass.getName() );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + p.getEntityName() );
-			}
-			p.getCacheAccessStrategy().evictAll();
-		}
-	}
-
-	public void evictCollection(String roleName, Serializable id) throws HibernateException {
-		CollectionPersister p = getCollectionPersister( roleName );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + MessageHelper.collectionInfoString(p, id, this) );
-			}
-			CacheKey cacheKey = new CacheKey( id, p.getKeyType(), p.getRole(), EntityMode.POJO, this );
-			p.getCacheAccessStrategy().evict( cacheKey );
-		}
-	}
-
-	public void evictCollection(String roleName) throws HibernateException {
-		CollectionPersister p = getCollectionPersister( roleName );
-		if ( p.hasCache() ) {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "evicting second-level cache: " + p.getRole() );
-			}
-			p.getCacheAccessStrategy().evictAll();
-		}
-	}
-
-	public Type getReferencedPropertyType(String className, String propertyName)
-		throws MappingException {
-		return getEntityPersister(className).getPropertyType(propertyName);
-	}
-
-	public ConnectionProvider getConnectionProvider() {
-		return settings.getConnectionProvider();
-	}
-
-	public UpdateTimestampsCache getUpdateTimestampsCache() {
-		return updateTimestampsCache;
-	}
-
-	public QueryCache getQueryCache() {
-		return queryCache;
-	}
-
-	public QueryCache getQueryCache(String regionName) throws HibernateException {
-		if ( regionName == null ) {
-			return getQueryCache();
-		}
-
-		if ( !settings.isQueryCacheEnabled() ) {
-			return null;
-		}
-
-		synchronized ( allCacheRegions ) {
-			QueryCache currentQueryCache = ( QueryCache ) queryCaches.get( regionName );
-			if ( currentQueryCache == null ) {
-				currentQueryCache = settings.getQueryCacheFactory().getQueryCache( regionName, updateTimestampsCache, settings, properties );
-				queryCaches.put( regionName, currentQueryCache );
-				allCacheRegions.put( currentQueryCache.getRegion().getName(), currentQueryCache.getRegion() );
-			}
-			return currentQueryCache;
-		}
-	}
-
-	public Region getSecondLevelCacheRegion(String regionName) {
-		synchronized ( allCacheRegions ) {
-			return ( Region ) allCacheRegions.get( regionName );
-		}
-	}
-
-	public Map getAllSecondLevelCacheRegions() {
-		synchronized ( allCacheRegions ) {
-			return new HashMap( allCacheRegions );
-		}
-	}
-
-	public boolean isClosed() {
-		return isClosed;
-	}
-
-	public Statistics getStatistics() {
-		return statistics;
-	}
-
-	public StatisticsImplementor getStatisticsImplementor() {
-		return statistics;
-	}
-
-	public void evictQueries() throws HibernateException {
-		if ( settings.isQueryCacheEnabled() ) {
-			queryCache.clear();
-		}
-	}
-
-	public void evictQueries(String cacheRegion) throws HibernateException {
-		if (cacheRegion==null) {
-			throw new NullPointerException("use the zero-argument form to evict the default query cache");
-		}
-		else {
-			synchronized (allCacheRegions) {
-				if ( settings.isQueryCacheEnabled() ) {
-					QueryCache currentQueryCache = (QueryCache) queryCaches.get(cacheRegion);
-					if ( currentQueryCache != null ) {
-						currentQueryCache.clear();
-					}
-				}
-			}
-		}
-	}
-
-	public FilterDefinition getFilterDefinition(String filterName) throws HibernateException {
-		FilterDefinition def = ( FilterDefinition ) filters.get( filterName );
-		if ( def == null ) {
-			throw new HibernateException( "No such filter configured [" + filterName + "]" );
-		}
-		return def;
-	}
-
-	public Set getDefinedFilterNames() {
-		return filters.keySet();
-	}
-
-	public BatcherFactory getBatcherFactory() {
-		return settings.getBatcherFactory();
-	}
-
-	public IdentifierGenerator getIdentifierGenerator(String rootEntityName) {
-		return (IdentifierGenerator) identifierGenerators.get(rootEntityName);
-	}
-
-	private CurrentSessionContext buildCurrentSessionContext() {
-		String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
-		// for backward-compatability
-		if ( impl == null && transactionManager != null ) {
-			impl = "jta";
-		}
-
-		if ( impl == null ) {
-			return null;
-		}
-		else if ( "jta".equals( impl ) ) {
-			if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
-				log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
-			}
-			return new JTASessionContext( this );
-		}
-		else if ( "thread".equals( impl ) ) {
-			return new ThreadLocalSessionContext( this );
-		}
-		else if ( "managed".equals( impl ) ) {
-			return new ManagedSessionContext( this );
-		}
-		else {
-			try {
-				Class implClass = ReflectHelper.classForName( impl );
-				return ( CurrentSessionContext ) implClass
-						.getConstructor( new Class[] { SessionFactoryImplementor.class } )
-						.newInstance( new Object[] { this } );
-			}
-			catch( Throwable t ) {
-				log.error( "Unable to construct current session context [" + impl + "]", t );
-				return null;
-			}
-		}
-	}
-
-	public EventListeners getEventListeners()
-	{
-		return eventListeners;
-	}
-
-	public EntityNotFoundDelegate getEntityNotFoundDelegate() {
-		return entityNotFoundDelegate;
-	}
-
-	/**
-	 * Custom serialization hook used during Session serialization.
-	 *
-	 * @param oos The stream to which to write the factory
-	 * @throws IOException Indicates problems writing out the serial data stream
-	 */
-	void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeUTF( uuid );
-		oos.writeBoolean( name != null );
-		if ( name != null ) {
-			oos.writeUTF( name );
-		}
-	}
-
-	/**
-	 * Custom deserialization hook used during Session deserialization.
-	 *
-	 * @param ois The stream from which to "read" the factory
-	 * @return The deserialized factory
-	 * @throws IOException indicates problems reading back serial data stream
-	 * @throws ClassNotFoundException indicates problems reading back serial data stream
-	 */
-	static SessionFactoryImpl deserialize(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		String uuid = ois.readUTF();
-		boolean isNamed = ois.readBoolean();
-		String name = null;
-		if ( isNamed ) {
-			name = ois.readUTF();
-		}
-		Object result = SessionFactoryObjectFactory.getInstance( uuid );
-		if ( result == null ) {
-			log.trace( "could not locate session factory by uuid [" + uuid + "] during session deserialization; trying name" );
-			if ( isNamed ) {
-				result = SessionFactoryObjectFactory.getNamedInstance( name );
-			}
-			if ( result == null ) {
-				throw new InvalidObjectException( "could not resolve session factory during session deserialization [uuid=" + uuid + ", name=" + name + "]" );
-			}
-		}
-		return ( SessionFactoryImpl ) result;
-	}
-
-	public SQLFunctionRegistry getSqlFunctionRegistry() {
-		return sqlFunctionRegistry;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1109 @@
+/*
+ * 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.impl;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.StringRefAddr;
+import javax.transaction.TransactionManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.MappingException;
+import org.hibernate.ObjectNotFoundException;
+import org.hibernate.QueryException;
+import org.hibernate.SessionFactory;
+import org.hibernate.StatelessSession;
+import org.hibernate.SessionFactoryObserver;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.CollectionRegion;
+import org.hibernate.cache.EntityRegion;
+import org.hibernate.cache.QueryCache;
+import org.hibernate.cache.Region;
+import org.hibernate.cache.UpdateTimestampsCache;
+import org.hibernate.cache.access.AccessType;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.impl.CacheDataDescriptionImpl;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.Settings;
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.context.CurrentSessionContext;
+import org.hibernate.context.JTASessionContext;
+import org.hibernate.context.ManagedSessionContext;
+import org.hibernate.context.ThreadLocalSessionContext;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.NamedQueryDefinition;
+import org.hibernate.engine.NamedSQLQueryDefinition;
+import org.hibernate.engine.ResultSetMappingDefinition;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.query.QueryPlanCache;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.event.EventListeners;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.UUIDHexGenerator;
+import org.hibernate.jdbc.BatcherFactory;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.RootClass;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.persister.PersisterFactory;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.EntityNotFoundDelegate;
+import org.hibernate.stat.Statistics;
+import org.hibernate.stat.StatisticsImpl;
+import org.hibernate.stat.StatisticsImplementor;
+import org.hibernate.tool.hbm2ddl.SchemaExport;
+import org.hibernate.tool.hbm2ddl.SchemaUpdate;
+import org.hibernate.tool.hbm2ddl.SchemaValidator;
+import org.hibernate.transaction.TransactionFactory;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.ReflectHelper;
+
+
+/**
+ * Concrete implementation of the <tt>SessionFactory</tt> interface. Has the following
+ * responsibilites
+ * <ul>
+ * <li>caches configuration settings (immutably)
+ * <li>caches "compiled" mappings ie. <tt>EntityPersister</tt>s and
+ *     <tt>CollectionPersister</tt>s (immutable)
+ * <li>caches "compiled" queries (memory sensitive cache)
+ * <li>manages <tt>PreparedStatement</tt>s
+ * <li> delegates JDBC <tt>Connection</tt> management to the <tt>ConnectionProvider</tt>
+ * <li>factory for instances of <tt>SessionImpl</tt>
+ * </ul>
+ * This class must appear immutable to clients, even if it does all kinds of caching
+ * and pooling under the covers. It is crucial that the class is not only thread
+ * safe, but also highly concurrent. Synchronization must be used extremely sparingly.
+ *
+ * @see org.hibernate.connection.ConnectionProvider
+ * @see org.hibernate.classic.Session
+ * @see org.hibernate.hql.QueryTranslator
+ * @see org.hibernate.persister.entity.EntityPersister
+ * @see org.hibernate.persister.collection.CollectionPersister
+ * @author Gavin King
+ */
+public final class SessionFactoryImpl implements SessionFactory, SessionFactoryImplementor {
+
+	private static final Logger log = LoggerFactory.getLogger(SessionFactoryImpl.class);
+	private static final IdentifierGenerator UUID_GENERATOR = new UUIDHexGenerator();
+
+	private final String name;
+	private final String uuid;
+
+	private final transient Map entityPersisters;
+	private final transient Map classMetadata;
+	private final transient Map collectionPersisters;
+	private final transient Map collectionMetadata;
+	private final transient Map collectionRolesByEntityParticipant;
+	private final transient Map identifierGenerators;
+	private final transient Map namedQueries;
+	private final transient Map namedSqlQueries;
+	private final transient Map sqlResultSetMappings;
+	private final transient Map filters;
+	private final transient Map imports;
+	private final transient Interceptor interceptor;
+	private final transient Settings settings;
+	private final transient Properties properties;
+	private transient SchemaExport schemaExport;
+	private final transient TransactionManager transactionManager;
+	private final transient QueryCache queryCache;
+	private final transient UpdateTimestampsCache updateTimestampsCache;
+	private final transient Map queryCaches;
+	private final transient Map allCacheRegions = new HashMap();
+	private final transient StatisticsImpl statistics = new StatisticsImpl(this);
+	private final transient EventListeners eventListeners;
+	private final transient CurrentSessionContext currentSessionContext;
+	private final transient EntityNotFoundDelegate entityNotFoundDelegate;
+	private final transient SQLFunctionRegistry sqlFunctionRegistry;
+	private final transient SessionFactoryObserver observer;
+
+	private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
+
+	private transient boolean isClosed = false;
+
+	public SessionFactoryImpl(
+			Configuration cfg,
+	        Mapping mapping,
+	        Settings settings,
+	        EventListeners listeners,
+			SessionFactoryObserver observer) throws HibernateException {
+
+		log.info("building session factory");
+
+		this.properties = new Properties();
+		this.properties.putAll( cfg.getProperties() );
+		this.interceptor = cfg.getInterceptor();
+		this.settings = settings;
+		this.sqlFunctionRegistry = new SQLFunctionRegistry(settings.getDialect(), cfg.getSqlFunctions());
+        this.eventListeners = listeners;
+		this.observer = observer != null ? observer : new SessionFactoryObserver() {
+			public void sessionFactoryCreated(SessionFactory factory) {
+			}
+			public void sessionFactoryClosed(SessionFactory factory) {
+			}
+		};
+		this.filters = new HashMap();
+		this.filters.putAll( cfg.getFilterDefinitions() );
+
+		if ( log.isDebugEnabled() ) {
+			log.debug("Session factory constructed with filter configurations : " + filters);
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"instantiating session factory with properties: " + properties
+			);
+		}
+
+		// Caches
+		settings.getRegionFactory().start( settings, properties );
+
+		//Generators:
+
+		identifierGenerators = new HashMap();
+		Iterator classes = cfg.getClassMappings();
+		while ( classes.hasNext() ) {
+			PersistentClass model = (PersistentClass) classes.next();
+			if ( !model.isInherited() ) {
+				IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
+						settings.getDialect(),
+				        settings.getDefaultCatalogName(),
+				        settings.getDefaultSchemaName(),
+				        (RootClass) model
+					);
+				identifierGenerators.put( model.getEntityName(), generator );
+			}
+		}
+
+
+		///////////////////////////////////////////////////////////////////////
+		// Prepare persisters and link them up with their cache
+		// region/access-strategy
+
+		final String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";
+
+		entityPersisters = new HashMap();
+		Map entityAccessStrategies = new HashMap();
+		Map classMeta = new HashMap();
+		classes = cfg.getClassMappings();
+		while ( classes.hasNext() ) {
+			final PersistentClass model = (PersistentClass) classes.next();
+			model.prepareTemporaryTables( mapping, settings.getDialect() );
+			final String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();
+			// cache region is defined by the root-class in the hierarchy...
+			EntityRegionAccessStrategy accessStrategy = ( EntityRegionAccessStrategy ) entityAccessStrategies.get( cacheRegionName );
+			if ( accessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
+				final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
+				if ( accessType != null ) {
+					log.trace( "Building cache for entity data [" + model.getEntityName() + "]" );
+					EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
+					accessStrategy = entityRegion.buildAccessStrategy( accessType );
+					entityAccessStrategies.put( cacheRegionName, accessStrategy );
+					allCacheRegions.put( cacheRegionName, entityRegion );
+				}
+			}
+			EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, mapping );
+			entityPersisters.put( model.getEntityName(), cp );
+			classMeta.put( model.getEntityName(), cp.getClassMetadata() );
+		}
+		classMetadata = Collections.unmodifiableMap(classMeta);
+
+		Map tmpEntityToCollectionRoleMap = new HashMap();
+		collectionPersisters = new HashMap();
+		Iterator collections = cfg.getCollectionMappings();
+		while ( collections.hasNext() ) {
+			Collection model = (Collection) collections.next();
+			final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
+			final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
+			CollectionRegionAccessStrategy accessStrategy = null;
+			if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
+				log.trace( "Building cache for collection data [" + model.getRole() + "]" );
+				CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
+				accessStrategy = collectionRegion.buildAccessStrategy( accessType );
+				entityAccessStrategies.put( cacheRegionName, accessStrategy );
+				allCacheRegions.put( cacheRegionName, collectionRegion );
+			}
+			CollectionPersister persister = PersisterFactory.createCollectionPersister( cfg, model, accessStrategy, this) ;
+			collectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
+			Type indexType = persister.getIndexType();
+			if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
+				String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
+				Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
+				if ( roles == null ) {
+					roles = new HashSet();
+					tmpEntityToCollectionRoleMap.put( entityName, roles );
+				}
+				roles.add( persister.getRole() );
+			}
+			Type elementType = persister.getElementType();
+			if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
+				String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
+				Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
+				if ( roles == null ) {
+					roles = new HashSet();
+					tmpEntityToCollectionRoleMap.put( entityName, roles );
+				}
+				roles.add( persister.getRole() );
+			}
+		}
+		collectionMetadata = Collections.unmodifiableMap(collectionPersisters);
+		Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
+		}
+		collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
+
+		//Named Queries:
+		namedQueries = new HashMap( cfg.getNamedQueries() );
+		namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
+		sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
+		imports = new HashMap( cfg.getImports() );
+
+		// after *all* persisters and named queries are registered
+		Iterator iter = entityPersisters.values().iterator();
+		while ( iter.hasNext() ) {
+			( (EntityPersister) iter.next() ).postInstantiate();
+		}
+		iter = collectionPersisters.values().iterator();
+		while ( iter.hasNext() ) {
+			( (CollectionPersister) iter.next() ).postInstantiate();
+		}
+
+		//JNDI + Serialization:
+
+		name = settings.getSessionFactoryName();
+		try {
+			uuid = (String) UUID_GENERATOR.generate(null, null);
+		}
+		catch (Exception e) {
+			throw new AssertionFailure("Could not generate UUID");
+		}
+		SessionFactoryObjectFactory.addInstance(uuid, name, this, properties);
+
+		log.debug("instantiated session factory");
+
+		if ( settings.isAutoCreateSchema() ) {
+			new SchemaExport( cfg, settings ).create( false, true );
+		}
+		if ( settings.isAutoUpdateSchema() ) {
+			new SchemaUpdate( cfg, settings ).execute( false, true );
+		}
+		if ( settings.isAutoValidateSchema() ) {
+			new SchemaValidator( cfg, settings ).validate();
+		}
+		if ( settings.isAutoDropSchema() ) {
+			schemaExport = new SchemaExport( cfg, settings );
+		}
+
+		if ( settings.getTransactionManagerLookup()!=null ) {
+			log.debug("obtaining JTA TransactionManager");
+			transactionManager = settings.getTransactionManagerLookup().getTransactionManager(properties);
+		}
+		else {
+			if ( settings.getTransactionFactory().isTransactionManagerRequired() ) {
+				throw new HibernateException("The chosen transaction strategy requires access to the JTA TransactionManager");
+			}
+			transactionManager = null;
+		}
+
+		currentSessionContext = buildCurrentSessionContext();
+
+		if ( settings.isQueryCacheEnabled() ) {
+			updateTimestampsCache = new UpdateTimestampsCache(settings, properties);
+			queryCache = settings.getQueryCacheFactory()
+			        .getQueryCache(null, updateTimestampsCache, settings, properties);
+			queryCaches = new HashMap();
+			allCacheRegions.put( updateTimestampsCache.getRegion().getName(), updateTimestampsCache.getRegion() );
+			allCacheRegions.put( queryCache.getRegion().getName(), queryCache.getRegion() );
+		}
+		else {
+			updateTimestampsCache = null;
+			queryCache = null;
+			queryCaches = null;
+		}
+
+		//checking for named queries
+		if ( settings.isNamedQueryStartupCheckingEnabled() ) {
+			Map errors = checkNamedQueries();
+			if ( !errors.isEmpty() ) {
+				Set keys = errors.keySet();
+				StringBuffer failingQueries = new StringBuffer( "Errors in named queries: " );
+				for ( Iterator iterator = keys.iterator() ; iterator.hasNext() ; ) {
+					String queryName = ( String ) iterator.next();
+					HibernateException e = ( HibernateException ) errors.get( queryName );
+					failingQueries.append( queryName );
+					if ( iterator.hasNext() ) {
+						failingQueries.append( ", " );
+					}
+					log.error( "Error in named query: " + queryName, e );
+				}
+				throw new HibernateException( failingQueries.toString() );
+			}
+		}
+
+		//stats
+		getStatistics().setStatisticsEnabled( settings.isStatisticsEnabled() );
+
+		// EntityNotFoundDelegate
+		EntityNotFoundDelegate entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
+		if ( entityNotFoundDelegate == null ) {
+			entityNotFoundDelegate = new EntityNotFoundDelegate() {
+				public void handleEntityNotFound(String entityName, Serializable id) {
+					throw new ObjectNotFoundException( id, entityName );
+				}
+			};
+		}
+		this.entityNotFoundDelegate = entityNotFoundDelegate;
+
+		this.observer.sessionFactoryCreated( this );
+	}
+
+	public QueryPlanCache getQueryPlanCache() {
+		return queryPlanCache;
+	}
+
+	private Map checkNamedQueries() throws HibernateException {
+		Map errors = new HashMap();
+
+		// Check named HQL queries
+		log.debug("Checking " + namedQueries.size() + " named HQL queries");
+		Iterator itr = namedQueries.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final String queryName = ( String ) entry.getKey();
+			final NamedQueryDefinition qd = ( NamedQueryDefinition ) entry.getValue();
+			// this will throw an error if there's something wrong.
+			try {
+				log.debug("Checking named query: " + queryName);
+				//TODO: BUG! this currently fails for named queries for non-POJO entities
+				queryPlanCache.getHQLQueryPlan( qd.getQueryString(), false, CollectionHelper.EMPTY_MAP );
+			}
+			catch ( QueryException e ) {
+				errors.put( queryName, e );
+			}
+			catch ( MappingException e ) {
+				errors.put( queryName, e );
+			}
+		}
+
+		log.debug("Checking " + namedSqlQueries.size() + " named SQL queries");
+		itr = namedSqlQueries.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final String queryName = ( String ) entry.getKey();
+			final NamedSQLQueryDefinition qd = ( NamedSQLQueryDefinition ) entry.getValue();
+			// this will throw an error if there's something wrong.
+			try {
+				log.debug("Checking named SQL query: " + queryName);
+				// TODO : would be really nice to cache the spec on the query-def so as to not have to re-calc the hash;
+				// currently not doable though because of the resultset-ref stuff...
+				NativeSQLQuerySpecification spec;
+				if ( qd.getResultSetRef() != null ) {
+					ResultSetMappingDefinition definition = ( ResultSetMappingDefinition ) sqlResultSetMappings.get( qd.getResultSetRef() );
+					if ( definition == null ) {
+						throw new MappingException( "Unable to find resultset-ref definition: " + qd.getResultSetRef() );
+					}
+					spec = new NativeSQLQuerySpecification(
+							qd.getQueryString(),
+					        definition.getQueryReturns(),
+					        qd.getQuerySpaces()
+					);
+				}
+				else {
+					spec =  new NativeSQLQuerySpecification(
+							qd.getQueryString(),
+					        qd.getQueryReturns(),
+					        qd.getQuerySpaces()
+					);
+				}
+				queryPlanCache.getNativeSQLQueryPlan( spec );
+			}
+			catch ( QueryException e ) {
+				errors.put( queryName, e );
+			}
+			catch ( MappingException e ) {
+				errors.put( queryName, e );
+			}
+		}
+
+		return errors;
+	}
+
+	public StatelessSession openStatelessSession() {
+		return new StatelessSessionImpl( null, this );
+	}
+
+	public StatelessSession openStatelessSession(Connection connection) {
+		return new StatelessSessionImpl( connection, this );
+	}
+
+	private SessionImpl openSession(
+		Connection connection,
+	    boolean autoClose,
+	    long timestamp,
+	    Interceptor sessionLocalInterceptor
+	) {
+		return new SessionImpl(
+		        connection,
+		        this,
+		        autoClose,
+		        timestamp,
+		        sessionLocalInterceptor == null ? interceptor : sessionLocalInterceptor,
+		        settings.getDefaultEntityMode(),
+		        settings.isFlushBeforeCompletionEnabled(),
+		        settings.isAutoCloseSessionEnabled(),
+		        settings.getConnectionReleaseMode()
+			);
+	}
+
+	public org.hibernate.classic.Session openSession(Connection connection, Interceptor sessionLocalInterceptor) {
+		return openSession(connection, false, Long.MIN_VALUE, sessionLocalInterceptor);
+	}
+
+	public org.hibernate.classic.Session openSession(Interceptor sessionLocalInterceptor)
+	throws HibernateException {
+		// note that this timestamp is not correct if the connection provider
+		// returns an older JDBC connection that was associated with a
+		// transaction that was already begun before openSession() was called
+		// (don't know any possible solution to this!)
+		long timestamp = settings.getRegionFactory().nextTimestamp();
+		return openSession( null, true, timestamp, sessionLocalInterceptor );
+	}
+
+	public org.hibernate.classic.Session openSession(Connection connection) {
+		return openSession(connection, interceptor); //prevents this session from adding things to cache
+	}
+
+	public org.hibernate.classic.Session openSession() throws HibernateException {
+		return openSession(interceptor);
+	}
+
+	public org.hibernate.classic.Session openTemporarySession() throws HibernateException {
+		return new SessionImpl(
+				null,
+		        this,
+		        true,
+		        settings.getRegionFactory().nextTimestamp(),
+		        interceptor,
+		        settings.getDefaultEntityMode(),
+		        false,
+		        false,
+		        ConnectionReleaseMode.AFTER_STATEMENT
+			);
+	}
+
+	public org.hibernate.classic.Session openSession(
+			final Connection connection,
+	        final boolean flushBeforeCompletionEnabled,
+	        final boolean autoCloseSessionEnabled,
+	        final ConnectionReleaseMode connectionReleaseMode) throws HibernateException {
+		return new SessionImpl(
+				connection,
+		        this,
+		        true,
+		        settings.getRegionFactory().nextTimestamp(),
+		        interceptor,
+		        settings.getDefaultEntityMode(),
+		        flushBeforeCompletionEnabled,
+		        autoCloseSessionEnabled,
+		        connectionReleaseMode
+			);
+	}
+
+	public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
+		if ( currentSessionContext == null ) {
+			throw new HibernateException( "No CurrentSessionContext configured!" );
+		}
+		return currentSessionContext.currentSession();
+	}
+
+	public EntityPersister getEntityPersister(String entityName) throws MappingException {
+		EntityPersister result = (EntityPersister) entityPersisters.get(entityName);
+		if (result==null) {
+			throw new MappingException( "Unknown entity: " + entityName );
+		}
+		return result;
+	}
+
+	public CollectionPersister getCollectionPersister(String role) throws MappingException {
+		CollectionPersister result = (CollectionPersister) collectionPersisters.get(role);
+		if (result==null) {
+			throw new MappingException( "Unknown collection role: " + role );
+		}
+		return result;
+	}
+
+	public Settings getSettings() {
+		return settings;
+	}
+
+	public Dialect getDialect() {
+		return settings.getDialect();
+	}
+
+	public Interceptor getInterceptor()
+	{
+		return interceptor;
+	}
+
+	public TransactionFactory getTransactionFactory() {
+		return settings.getTransactionFactory();
+	}
+
+	public TransactionManager getTransactionManager() {
+		return transactionManager;
+	}
+
+	public SQLExceptionConverter getSQLExceptionConverter() {
+		return settings.getSQLExceptionConverter();
+	}
+
+	public Set getCollectionRolesByEntityParticipant(String entityName) {
+		return ( Set ) collectionRolesByEntityParticipant.get( entityName );
+	}
+
+	// from javax.naming.Referenceable
+	public Reference getReference() throws NamingException {
+		log.debug("Returning a Reference to the SessionFactory");
+		return new Reference(
+			SessionFactoryImpl.class.getName(),
+		    new StringRefAddr("uuid", uuid),
+		    SessionFactoryObjectFactory.class.getName(),
+		    null
+		);
+	}
+
+	private Object readResolve() throws ObjectStreamException {
+		log.trace("Resolving serialized SessionFactory");
+		// look for the instance by uuid
+		Object result = SessionFactoryObjectFactory.getInstance(uuid);
+		if (result==null) {
+			// in case we were deserialized in a different JVM, look for an instance with the same name
+			// (alternatively we could do an actual JNDI lookup here....)
+			result = SessionFactoryObjectFactory.getNamedInstance(name);
+			if (result==null) {
+				throw new InvalidObjectException("Could not find a SessionFactory named: " + name);
+			}
+			else {
+				log.debug("resolved SessionFactory by name");
+			}
+		}
+		else {
+			log.debug("resolved SessionFactory by uid");
+		}
+		return result;
+	}
+
+	public NamedQueryDefinition getNamedQuery(String queryName) {
+		return (NamedQueryDefinition) namedQueries.get(queryName);
+	}
+
+	public NamedSQLQueryDefinition getNamedSQLQuery(String queryName) {
+		return (NamedSQLQueryDefinition) namedSqlQueries.get(queryName);
+	}
+
+	public ResultSetMappingDefinition getResultSetMapping(String resultSetName) {
+		return (ResultSetMappingDefinition) sqlResultSetMappings.get(resultSetName);
+	}
+
+	public Type getIdentifierType(String className) throws MappingException {
+		return getEntityPersister(className).getIdentifierType();
+	}
+	public String getIdentifierPropertyName(String className) throws MappingException {
+		return getEntityPersister(className).getIdentifierPropertyName();
+	}
+
+	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+		log.trace("deserializing");
+		in.defaultReadObject();
+		log.debug("deserialized: " + uuid);
+	}
+
+	private void writeObject(ObjectOutputStream out) throws IOException {
+		log.debug("serializing: " + uuid);
+		out.defaultWriteObject();
+		log.trace("serialized");
+	}
+
+	public Type[] getReturnTypes(String queryString) throws HibernateException {
+		return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnTypes();
+	}
+
+	public String[] getReturnAliases(String queryString) throws HibernateException {
+		return queryPlanCache.getHQLQueryPlan( queryString, false, CollectionHelper.EMPTY_MAP ).getReturnMetadata().getReturnAliases();
+	}
+
+	public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException {
+		return getClassMetadata( persistentClass.getName() );
+	}
+
+	public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException {
+		return (CollectionMetadata) collectionMetadata.get(roleName);
+	}
+
+	public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
+		return (ClassMetadata) classMetadata.get(entityName);
+	}
+
+	/**
+	 * Return the names of all persistent (mapped) classes that extend or implement the
+	 * given class or interface, accounting for implicit/explicit polymorphism settings
+	 * and excluding mapped subclasses/joined-subclasses of other classes in the result.
+	 */
+	public String[] getImplementors(String className) throws MappingException {
+
+		final Class clazz;
+		try {
+			clazz = ReflectHelper.classForName(className);
+		}
+		catch (ClassNotFoundException cnfe) {
+			return new String[] { className }; //for a dynamic-class
+		}
+
+		ArrayList results = new ArrayList();
+		Iterator iter = entityPersisters.values().iterator();
+		while ( iter.hasNext() ) {
+			//test this entity to see if we must query it
+			EntityPersister testPersister = (EntityPersister) iter.next();
+			if ( testPersister instanceof Queryable ) {
+				Queryable testQueryable = (Queryable) testPersister;
+				String testClassName = testQueryable.getEntityName();
+				boolean isMappedClass = className.equals(testClassName);
+				if ( testQueryable.isExplicitPolymorphism() ) {
+					if ( isMappedClass ) {
+						return new String[] {className}; //NOTE EARLY EXIT
+					}
+				}
+				else {
+					if (isMappedClass) {
+						results.add(testClassName);
+					}
+					else {
+						final Class mappedClass = testQueryable.getMappedClass( EntityMode.POJO );
+						if ( mappedClass!=null && clazz.isAssignableFrom( mappedClass ) ) {
+							final boolean assignableSuperclass;
+							if ( testQueryable.isInherited() ) {
+								Class mappedSuperclass = getEntityPersister( testQueryable.getMappedSuperclass() ).getMappedClass( EntityMode.POJO);
+								assignableSuperclass = clazz.isAssignableFrom(mappedSuperclass);
+							}
+							else {
+								assignableSuperclass = false;
+							}
+							if ( !assignableSuperclass ) {
+								results.add( testClassName );
+							}
+						}
+					}
+				}
+			}
+		}
+		return (String[]) results.toArray( new String[ results.size() ] );
+	}
+
+	public String getImportedClassName(String className) {
+		String result = (String) imports.get(className);
+		if (result==null) {
+			try {
+				ReflectHelper.classForName(className);
+				return className;
+			}
+			catch (ClassNotFoundException cnfe) {
+				return null;
+			}
+		}
+		else {
+			return result;
+		}
+	}
+
+	public Map getAllClassMetadata() throws HibernateException {
+		return classMetadata;
+	}
+
+	public Map getAllCollectionMetadata() throws HibernateException {
+		return collectionMetadata;
+	}
+
+	/**
+	 * Closes the session factory, releasing all held resources.
+	 *
+	 * <ol>
+	 * <li>cleans up used cache regions and "stops" the cache provider.
+	 * <li>close the JDBC connection
+	 * <li>remove the JNDI binding
+	 * </ol>
+	 *
+	 * Note: Be aware that the sessionfactory instance still can
+	 * be a "heavy" object memory wise after close() has been called.  Thus
+	 * it is important to not keep referencing the instance to let the garbage
+	 * collector release the memory.
+	 */
+	public void close() throws HibernateException {
+
+		if ( isClosed ) {
+			log.trace( "already closed" );
+			return;
+		}
+
+		log.info("closing");
+
+		isClosed = true;
+
+		Iterator iter = entityPersisters.values().iterator();
+		while ( iter.hasNext() ) {
+			EntityPersister p = (EntityPersister) iter.next();
+			if ( p.hasCache() ) {
+				p.getCacheAccessStrategy().getRegion().destroy();
+			}
+		}
+
+		iter = collectionPersisters.values().iterator();
+		while ( iter.hasNext() ) {
+			CollectionPersister p = (CollectionPersister) iter.next();
+			if ( p.hasCache() ) {
+				p.getCacheAccessStrategy().getRegion().destroy();
+			}
+		}
+
+		if ( settings.isQueryCacheEnabled() )  {
+			queryCache.destroy();
+
+			iter = queryCaches.values().iterator();
+			while ( iter.hasNext() ) {
+				QueryCache cache = (QueryCache) iter.next();
+				cache.destroy();
+			}
+			updateTimestampsCache.destroy();
+		}
+
+		settings.getRegionFactory().stop();
+
+		try {
+			settings.getConnectionProvider().close();
+		}
+		finally {
+			SessionFactoryObjectFactory.removeInstance(uuid, name, properties);
+		}
+
+		if ( settings.isAutoDropSchema() ) {
+			schemaExport.drop( false, true );
+		}
+
+		observer.sessionFactoryClosed( this );
+		eventListeners.destroyListeners();
+	}
+
+	public void evictEntity(String entityName, Serializable id) throws HibernateException {
+		EntityPersister p = getEntityPersister( entityName );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) );
+			}
+			CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this );
+			p.getCacheAccessStrategy().evict( cacheKey );
+		}
+	}
+
+	public void evictEntity(String entityName) throws HibernateException {
+		EntityPersister p = getEntityPersister( entityName );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + p.getEntityName() );
+			}
+			p.getCacheAccessStrategy().evictAll();
+		}
+	}
+
+	public void evict(Class persistentClass, Serializable id) throws HibernateException {
+		EntityPersister p = getEntityPersister( persistentClass.getName() );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + MessageHelper.infoString(p, id, this) );
+			}
+			CacheKey cacheKey = new CacheKey( id, p.getIdentifierType(), p.getRootEntityName(), EntityMode.POJO, this );
+			p.getCacheAccessStrategy().evict( cacheKey );
+		}
+	}
+
+	public void evict(Class persistentClass) throws HibernateException {
+		EntityPersister p = getEntityPersister( persistentClass.getName() );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + p.getEntityName() );
+			}
+			p.getCacheAccessStrategy().evictAll();
+		}
+	}
+
+	public void evictCollection(String roleName, Serializable id) throws HibernateException {
+		CollectionPersister p = getCollectionPersister( roleName );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + MessageHelper.collectionInfoString(p, id, this) );
+			}
+			CacheKey cacheKey = new CacheKey( id, p.getKeyType(), p.getRole(), EntityMode.POJO, this );
+			p.getCacheAccessStrategy().evict( cacheKey );
+		}
+	}
+
+	public void evictCollection(String roleName) throws HibernateException {
+		CollectionPersister p = getCollectionPersister( roleName );
+		if ( p.hasCache() ) {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "evicting second-level cache: " + p.getRole() );
+			}
+			p.getCacheAccessStrategy().evictAll();
+		}
+	}
+
+	public Type getReferencedPropertyType(String className, String propertyName)
+		throws MappingException {
+		return getEntityPersister(className).getPropertyType(propertyName);
+	}
+
+	public ConnectionProvider getConnectionProvider() {
+		return settings.getConnectionProvider();
+	}
+
+	public UpdateTimestampsCache getUpdateTimestampsCache() {
+		return updateTimestampsCache;
+	}
+
+	public QueryCache getQueryCache() {
+		return queryCache;
+	}
+
+	public QueryCache getQueryCache(String regionName) throws HibernateException {
+		if ( regionName == null ) {
+			return getQueryCache();
+		}
+
+		if ( !settings.isQueryCacheEnabled() ) {
+			return null;
+		}
+
+		synchronized ( allCacheRegions ) {
+			QueryCache currentQueryCache = ( QueryCache ) queryCaches.get( regionName );
+			if ( currentQueryCache == null ) {
+				currentQueryCache = settings.getQueryCacheFactory().getQueryCache( regionName, updateTimestampsCache, settings, properties );
+				queryCaches.put( regionName, currentQueryCache );
+				allCacheRegions.put( currentQueryCache.getRegion().getName(), currentQueryCache.getRegion() );
+			}
+			return currentQueryCache;
+		}
+	}
+
+	public Region getSecondLevelCacheRegion(String regionName) {
+		synchronized ( allCacheRegions ) {
+			return ( Region ) allCacheRegions.get( regionName );
+		}
+	}
+
+	public Map getAllSecondLevelCacheRegions() {
+		synchronized ( allCacheRegions ) {
+			return new HashMap( allCacheRegions );
+		}
+	}
+
+	public boolean isClosed() {
+		return isClosed;
+	}
+
+	public Statistics getStatistics() {
+		return statistics;
+	}
+
+	public StatisticsImplementor getStatisticsImplementor() {
+		return statistics;
+	}
+
+	public void evictQueries() throws HibernateException {
+		if ( settings.isQueryCacheEnabled() ) {
+			queryCache.clear();
+		}
+	}
+
+	public void evictQueries(String cacheRegion) throws HibernateException {
+		if (cacheRegion==null) {
+			throw new NullPointerException("use the zero-argument form to evict the default query cache");
+		}
+		else {
+			synchronized (allCacheRegions) {
+				if ( settings.isQueryCacheEnabled() ) {
+					QueryCache currentQueryCache = (QueryCache) queryCaches.get(cacheRegion);
+					if ( currentQueryCache != null ) {
+						currentQueryCache.clear();
+					}
+				}
+			}
+		}
+	}
+
+	public FilterDefinition getFilterDefinition(String filterName) throws HibernateException {
+		FilterDefinition def = ( FilterDefinition ) filters.get( filterName );
+		if ( def == null ) {
+			throw new HibernateException( "No such filter configured [" + filterName + "]" );
+		}
+		return def;
+	}
+
+	public Set getDefinedFilterNames() {
+		return filters.keySet();
+	}
+
+	public BatcherFactory getBatcherFactory() {
+		return settings.getBatcherFactory();
+	}
+
+	public IdentifierGenerator getIdentifierGenerator(String rootEntityName) {
+		return (IdentifierGenerator) identifierGenerators.get(rootEntityName);
+	}
+
+	private CurrentSessionContext buildCurrentSessionContext() {
+		String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
+		// for backward-compatability
+		if ( impl == null && transactionManager != null ) {
+			impl = "jta";
+		}
+
+		if ( impl == null ) {
+			return null;
+		}
+		else if ( "jta".equals( impl ) ) {
+			if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
+				log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
+			}
+			return new JTASessionContext( this );
+		}
+		else if ( "thread".equals( impl ) ) {
+			return new ThreadLocalSessionContext( this );
+		}
+		else if ( "managed".equals( impl ) ) {
+			return new ManagedSessionContext( this );
+		}
+		else {
+			try {
+				Class implClass = ReflectHelper.classForName( impl );
+				return ( CurrentSessionContext ) implClass
+						.getConstructor( new Class[] { SessionFactoryImplementor.class } )
+						.newInstance( new Object[] { this } );
+			}
+			catch( Throwable t ) {
+				log.error( "Unable to construct current session context [" + impl + "]", t );
+				return null;
+			}
+		}
+	}
+
+	public EventListeners getEventListeners()
+	{
+		return eventListeners;
+	}
+
+	public EntityNotFoundDelegate getEntityNotFoundDelegate() {
+		return entityNotFoundDelegate;
+	}
+
+	/**
+	 * Custom serialization hook used during Session serialization.
+	 *
+	 * @param oos The stream to which to write the factory
+	 * @throws IOException Indicates problems writing out the serial data stream
+	 */
+	void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeUTF( uuid );
+		oos.writeBoolean( name != null );
+		if ( name != null ) {
+			oos.writeUTF( name );
+		}
+	}
+
+	/**
+	 * Custom deserialization hook used during Session deserialization.
+	 *
+	 * @param ois The stream from which to "read" the factory
+	 * @return The deserialized factory
+	 * @throws IOException indicates problems reading back serial data stream
+	 * @throws ClassNotFoundException indicates problems reading back serial data stream
+	 */
+	static SessionFactoryImpl deserialize(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		String uuid = ois.readUTF();
+		boolean isNamed = ois.readBoolean();
+		String name = null;
+		if ( isNamed ) {
+			name = ois.readUTF();
+		}
+		Object result = SessionFactoryObjectFactory.getInstance( uuid );
+		if ( result == null ) {
+			log.trace( "could not locate session factory by uuid [" + uuid + "] during session deserialization; trying name" );
+			if ( isNamed ) {
+				result = SessionFactoryObjectFactory.getNamedInstance( name );
+			}
+			if ( result == null ) {
+				throw new InvalidObjectException( "could not resolve session factory during session deserialization [uuid=" + uuid + ", name=" + name + "]" );
+			}
+		}
+		return ( SessionFactoryImpl ) result;
+	}
+
+	public SQLFunctionRegistry getSqlFunctionRegistry() {
+		return sqlFunctionRegistry;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,161 +0,0 @@
-//$Id: SessionFactoryObjectFactory.java 11337 2007-03-22 22:42:58Z epbernard $
-package org.hibernate.impl;
-
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Properties;
-
-import javax.naming.Context;
-import javax.naming.InvalidNameException;
-import javax.naming.Name;
-import javax.naming.NamingException;
-import javax.naming.Reference;
-import javax.naming.event.EventContext;
-import javax.naming.event.NamespaceChangeListener;
-import javax.naming.event.NamingEvent;
-import javax.naming.event.NamingExceptionEvent;
-import javax.naming.event.NamingListener;
-import javax.naming.spi.ObjectFactory;
-
-import org.hibernate.SessionFactory;
-import org.hibernate.util.FastHashMap;
-import org.hibernate.util.NamingHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Resolves <tt>SessionFactory</tt> JNDI lookups and deserialization
- */
-public class SessionFactoryObjectFactory implements ObjectFactory {
-
-	private static final SessionFactoryObjectFactory INSTANCE; //to stop the class from being unloaded
-
-	private static final Logger log;
-
-	static {
-		log = LoggerFactory.getLogger( SessionFactoryObjectFactory.class );
-		INSTANCE = new SessionFactoryObjectFactory();
-		log.debug("initializing class SessionFactoryObjectFactory");
-	}
-
-	private static final FastHashMap INSTANCES = new FastHashMap();
-	private static final FastHashMap NAMED_INSTANCES = new FastHashMap();
-
-	private static final NamingListener LISTENER = new NamespaceChangeListener() {
-		public void objectAdded(NamingEvent evt) {
-			log.debug( "A factory was successfully bound to name: " + evt.getNewBinding().getName() );
-		}
-		public void objectRemoved(NamingEvent evt) {
-			String name = evt.getOldBinding().getName();
-			log.info("A factory was unbound from name: " + name);
-			Object instance = NAMED_INSTANCES.remove(name);
-			Iterator iter = INSTANCES.values().iterator();
-			while ( iter.hasNext() ) {
-				if ( iter.next()==instance ) iter.remove();
-			}
-		}
-		public void objectRenamed(NamingEvent evt) {
-			String name = evt.getOldBinding().getName();
-			log.info("A factory was renamed from name: " + name);
-			NAMED_INSTANCES.put( evt.getNewBinding().getName(), NAMED_INSTANCES.remove(name) );
-		}
-		public void namingExceptionThrown(NamingExceptionEvent evt) {
-			log.warn( "Naming exception occurred accessing factory: " + evt.getException() );
-		}
-	};
-
-	public Object getObjectInstance(Object reference, Name name, Context ctx, Hashtable env) throws Exception {
-		log.debug("JNDI lookup: " + name);
-		String uid = (String) ( (Reference) reference ).get(0).getContent();
-		return getInstance(uid);
-	}
-
-	public static void addInstance(String uid, String name, SessionFactory instance, Properties properties) {
-
-		log.debug("registered: " + uid + " (" + ( (name==null) ? "unnamed" : name ) + ')');
-		INSTANCES.put(uid, instance);
-		if (name!=null) NAMED_INSTANCES.put(name, instance);
-
-		//must add to JNDI _after_ adding to HashMaps, because some JNDI servers use serialization
-		if (name==null) {
-			log.info("Not binding factory to JNDI, no JNDI name configured");
-		}
-		else {
-
-			log.info("Factory name: " + name);
-
-			try {
-				Context ctx = NamingHelper.getInitialContext(properties);
-				NamingHelper.bind(ctx, name, instance);
-				log.info("Bound factory to JNDI name: " + name);
-				( (EventContext) ctx ).addNamingListener(name, EventContext.OBJECT_SCOPE, LISTENER);
-			}
-			catch (InvalidNameException ine) {
-				log.error("Invalid JNDI name: " + name, ine);
-			}
-			catch (NamingException ne) {
-				log.warn("Could not bind factory to JNDI", ne);
-			}
-			catch(ClassCastException cce) {
-				log.warn("InitialContext did not implement EventContext");
-			}
-
-		}
-
-	}
-
-	public static void removeInstance(String uid, String name, Properties properties) {
-		//TODO: theoretically non-threadsafe...
-
-		if (name!=null) {
-			log.info("Unbinding factory from JNDI name: " + name);
-
-			try {
-				Context ctx = NamingHelper.getInitialContext(properties);
-				ctx.unbind(name);
-				log.info("Unbound factory from JNDI name: " + name);
-			}
-			catch (InvalidNameException ine) {
-				log.error("Invalid JNDI name: " + name, ine);
-			}
-			catch (NamingException ne) {
-				log.warn("Could not unbind factory from JNDI", ne);
-			}
-
-			NAMED_INSTANCES.remove(name);
-
-		}
-
-		INSTANCES.remove(uid);
-
-	}
-
-	public static Object getNamedInstance(String name) {
-		log.debug("lookup: name=" + name);
-		Object result = NAMED_INSTANCES.get(name);
-		if (result==null) {
-			log.debug("Not found: " + name);
-			log.debug( NAMED_INSTANCES.toString() );
-		}
-		return result;
-	}
-
-	public static Object getInstance(String uid) {
-		log.debug("lookup: uid=" + uid);
-		Object result = INSTANCES.get(uid);
-		if (result==null) {
-			log.debug("Not found: " + uid);
-			log.debug( INSTANCES.toString() );
-		}
-		return result;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionFactoryObjectFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,184 @@
+/*
+ * 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.impl;
+
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InvalidNameException;
+import javax.naming.Name;
+import javax.naming.NamingException;
+import javax.naming.Reference;
+import javax.naming.event.EventContext;
+import javax.naming.event.NamespaceChangeListener;
+import javax.naming.event.NamingEvent;
+import javax.naming.event.NamingExceptionEvent;
+import javax.naming.event.NamingListener;
+import javax.naming.spi.ObjectFactory;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.util.FastHashMap;
+import org.hibernate.util.NamingHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Resolves <tt>SessionFactory</tt> JNDI lookups and deserialization
+ */
+public class SessionFactoryObjectFactory implements ObjectFactory {
+
+	private static final SessionFactoryObjectFactory INSTANCE; //to stop the class from being unloaded
+
+	private static final Logger log;
+
+	static {
+		log = LoggerFactory.getLogger( SessionFactoryObjectFactory.class );
+		INSTANCE = new SessionFactoryObjectFactory();
+		log.debug("initializing class SessionFactoryObjectFactory");
+	}
+
+	private static final FastHashMap INSTANCES = new FastHashMap();
+	private static final FastHashMap NAMED_INSTANCES = new FastHashMap();
+
+	private static final NamingListener LISTENER = new NamespaceChangeListener() {
+		public void objectAdded(NamingEvent evt) {
+			log.debug( "A factory was successfully bound to name: " + evt.getNewBinding().getName() );
+		}
+		public void objectRemoved(NamingEvent evt) {
+			String name = evt.getOldBinding().getName();
+			log.info("A factory was unbound from name: " + name);
+			Object instance = NAMED_INSTANCES.remove(name);
+			Iterator iter = INSTANCES.values().iterator();
+			while ( iter.hasNext() ) {
+				if ( iter.next()==instance ) iter.remove();
+			}
+		}
+		public void objectRenamed(NamingEvent evt) {
+			String name = evt.getOldBinding().getName();
+			log.info("A factory was renamed from name: " + name);
+			NAMED_INSTANCES.put( evt.getNewBinding().getName(), NAMED_INSTANCES.remove(name) );
+		}
+		public void namingExceptionThrown(NamingExceptionEvent evt) {
+			log.warn( "Naming exception occurred accessing factory: " + evt.getException() );
+		}
+	};
+
+	public Object getObjectInstance(Object reference, Name name, Context ctx, Hashtable env) throws Exception {
+		log.debug("JNDI lookup: " + name);
+		String uid = (String) ( (Reference) reference ).get(0).getContent();
+		return getInstance(uid);
+	}
+
+	public static void addInstance(String uid, String name, SessionFactory instance, Properties properties) {
+
+		log.debug("registered: " + uid + " (" + ( (name==null) ? "unnamed" : name ) + ')');
+		INSTANCES.put(uid, instance);
+		if (name!=null) NAMED_INSTANCES.put(name, instance);
+
+		//must add to JNDI _after_ adding to HashMaps, because some JNDI servers use serialization
+		if (name==null) {
+			log.info("Not binding factory to JNDI, no JNDI name configured");
+		}
+		else {
+
+			log.info("Factory name: " + name);
+
+			try {
+				Context ctx = NamingHelper.getInitialContext(properties);
+				NamingHelper.bind(ctx, name, instance);
+				log.info("Bound factory to JNDI name: " + name);
+				( (EventContext) ctx ).addNamingListener(name, EventContext.OBJECT_SCOPE, LISTENER);
+			}
+			catch (InvalidNameException ine) {
+				log.error("Invalid JNDI name: " + name, ine);
+			}
+			catch (NamingException ne) {
+				log.warn("Could not bind factory to JNDI", ne);
+			}
+			catch(ClassCastException cce) {
+				log.warn("InitialContext did not implement EventContext");
+			}
+
+		}
+
+	}
+
+	public static void removeInstance(String uid, String name, Properties properties) {
+		//TODO: theoretically non-threadsafe...
+
+		if (name!=null) {
+			log.info("Unbinding factory from JNDI name: " + name);
+
+			try {
+				Context ctx = NamingHelper.getInitialContext(properties);
+				ctx.unbind(name);
+				log.info("Unbound factory from JNDI name: " + name);
+			}
+			catch (InvalidNameException ine) {
+				log.error("Invalid JNDI name: " + name, ine);
+			}
+			catch (NamingException ne) {
+				log.warn("Could not unbind factory from JNDI", ne);
+			}
+
+			NAMED_INSTANCES.remove(name);
+
+		}
+
+		INSTANCES.remove(uid);
+
+	}
+
+	public static Object getNamedInstance(String name) {
+		log.debug("lookup: name=" + name);
+		Object result = NAMED_INSTANCES.get(name);
+		if (result==null) {
+			log.debug("Not found: " + name);
+			log.debug( NAMED_INSTANCES.toString() );
+		}
+		return result;
+	}
+
+	public static Object getInstance(String uid) {
+		log.debug("lookup: uid=" + uid);
+		Object result = INSTANCES.get(uid);
+		if (result==null) {
+			log.debug("Not found: " + uid);
+			log.debug( INSTANCES.toString() );
+		}
+		return result;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1972 +0,0 @@
-//$Id: SessionImpl.java 10688 2006-11-02 18:53:25Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.CacheMode;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.Filter;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.ObjectDeletedException;
-import org.hibernate.Query;
-import org.hibernate.QueryException;
-import org.hibernate.ReplicationMode;
-import org.hibernate.SQLQuery;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.Session;
-import org.hibernate.SessionException;
-import org.hibernate.SessionFactory;
-import org.hibernate.Transaction;
-import org.hibernate.TransientObjectException;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.ActionQueue;
-import org.hibernate.engine.CollectionEntry;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.FilterDefinition;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.StatefulPersistenceContext;
-import org.hibernate.engine.Status;
-import org.hibernate.engine.query.FilterQueryPlan;
-import org.hibernate.engine.query.HQLQueryPlan;
-import org.hibernate.engine.query.NativeSQLQueryPlan;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.event.AutoFlushEvent;
-import org.hibernate.event.AutoFlushEventListener;
-import org.hibernate.event.DeleteEvent;
-import org.hibernate.event.DeleteEventListener;
-import org.hibernate.event.DirtyCheckEvent;
-import org.hibernate.event.DirtyCheckEventListener;
-import org.hibernate.event.EventListeners;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.EvictEvent;
-import org.hibernate.event.EvictEventListener;
-import org.hibernate.event.FlushEvent;
-import org.hibernate.event.FlushEventListener;
-import org.hibernate.event.InitializeCollectionEvent;
-import org.hibernate.event.InitializeCollectionEventListener;
-import org.hibernate.event.LoadEvent;
-import org.hibernate.event.LoadEventListener;
-import org.hibernate.event.LoadEventListener.LoadType;
-import org.hibernate.event.LockEvent;
-import org.hibernate.event.LockEventListener;
-import org.hibernate.event.MergeEvent;
-import org.hibernate.event.MergeEventListener;
-import org.hibernate.event.PersistEvent;
-import org.hibernate.event.PersistEventListener;
-import org.hibernate.event.RefreshEvent;
-import org.hibernate.event.RefreshEventListener;
-import org.hibernate.event.ReplicateEvent;
-import org.hibernate.event.ReplicateEventListener;
-import org.hibernate.event.SaveOrUpdateEvent;
-import org.hibernate.event.SaveOrUpdateEventListener;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.jdbc.Batcher;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.jdbc.Work;
-import org.hibernate.loader.criteria.CriteriaLoader;
-import org.hibernate.loader.custom.CustomLoader;
-import org.hibernate.loader.custom.CustomQuery;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.stat.SessionStatistics;
-import org.hibernate.stat.SessionStatisticsImpl;
-import org.hibernate.tuple.DynamicMapInstantiator;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-
-/**
- * Concrete implementation of a Session, and also the central, organizing component
- * of Hibernate's internal implementation. As such, this class exposes two interfaces;
- * Session itself, to the application, and SessionImplementor, to other components
- * of Hibernate. This class is not threadsafe.
- *
- * @author Gavin King
- */
-public final class SessionImpl extends AbstractSessionImpl 
-		implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
-
-	// todo : need to find a clean way to handle the "event source" role
-	// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
-	// passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...
-
-	private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);
-
-	private transient EntityMode entityMode = EntityMode.POJO;
-	private transient boolean autoClear; //for EJB3
-	
-	private transient long timestamp;
-	private transient FlushMode flushMode = FlushMode.AUTO;
-	private transient CacheMode cacheMode = CacheMode.NORMAL;
-
-	private transient Interceptor interceptor;
-
-	private transient int dontFlushFromFind = 0;
-
-	private transient ActionQueue actionQueue;
-	private transient StatefulPersistenceContext persistenceContext;
-	private transient JDBCContext jdbcContext;
-	private transient EventListeners listeners;
-
-	private transient boolean flushBeforeCompletionEnabled;
-	private transient boolean autoCloseSessionEnabled;
-	private transient ConnectionReleaseMode connectionReleaseMode;
-	
-	private transient String fetchProfile;
-
-	private transient Map enabledFilters = new HashMap();
-
-	private transient Session rootSession;
-	private transient Map childSessionsByEntityMode;
-
-	/**
-	 * Constructor used in building "child sessions".
-	 *
-	 * @param parent The parent session
-	 * @param entityMode
-	 */
-	private SessionImpl(SessionImpl parent, EntityMode entityMode) {
-		super( parent.factory );
-		this.rootSession = parent;
-		this.timestamp = parent.timestamp;
-		this.jdbcContext = parent.jdbcContext;
-		this.interceptor = parent.interceptor;
-		this.listeners = parent.listeners;
-		this.actionQueue = new ActionQueue( this );
-		this.entityMode = entityMode;
-		this.persistenceContext = new StatefulPersistenceContext( this );
-		this.flushBeforeCompletionEnabled = false;
-		this.autoCloseSessionEnabled = false;
-		this.connectionReleaseMode = null;
-
-		if ( factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().openSession();
-		}
-
-		log.debug( "opened session [" + entityMode + "]" );
-	}
-
-	/**
-	 * Constructor used for openSession(...) processing, as well as construction
-	 * of sessions for getCurrentSession().
-	 *
-	 * @param connection The user-supplied connection to use for this session.
-	 * @param factory The factory from which this session was obtained
-	 * @param autoclose NOT USED
-	 * @param timestamp The timestamp for this session
-	 * @param interceptor The interceptor to be applied to this session
-	 * @param entityMode The entity-mode for this session
-	 * @param flushBeforeCompletionEnabled Should we auto flush before completion of transaction
-	 * @param autoCloseSessionEnabled Should we auto close after completion of transaction
-	 * @param connectionReleaseMode The mode by which we should release JDBC connections.
-	 */
-	SessionImpl(
-			final Connection connection,
-			final SessionFactoryImpl factory,
-			final boolean autoclose,
-			final long timestamp,
-			final Interceptor interceptor,
-			final EntityMode entityMode,
-			final boolean flushBeforeCompletionEnabled,
-			final boolean autoCloseSessionEnabled,
-			final ConnectionReleaseMode connectionReleaseMode) {
-		super( factory );
-		this.rootSession = null;
-		this.timestamp = timestamp;
-		this.entityMode = entityMode;
-		this.interceptor = interceptor;
-		this.listeners = factory.getEventListeners();
-		this.actionQueue = new ActionQueue( this );
-		this.persistenceContext = new StatefulPersistenceContext( this );
-		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
-		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
-		this.connectionReleaseMode = connectionReleaseMode;
-		this.jdbcContext = new JDBCContext( this, connection, interceptor );
-
-		if ( factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().openSession();
-		}
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( "opened session at timestamp: " + timestamp );
-		}
-	}
-
-	public Session getSession(EntityMode entityMode) {
-		if ( this.entityMode == entityMode ) {
-			return this;
-		}
-
-		if ( rootSession != null ) {
-			rootSession.getSession( entityMode );
-		}
-
-		errorIfClosed();
-		checkTransactionSynchStatus();
-
-		SessionImpl rtn = null;
-		if ( childSessionsByEntityMode == null ) {
-			childSessionsByEntityMode = new HashMap();
-		}
-		else {
-			rtn = (SessionImpl) childSessionsByEntityMode.get( entityMode );
-		}
-
-		if ( rtn == null ) {
-			rtn = new SessionImpl( this, entityMode );
-			childSessionsByEntityMode.put( entityMode, rtn );
-		}
-
-		return rtn;
-	}
-
-	public void clear() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		persistenceContext.clear();
-		actionQueue.clear();
-	}
-
-	public Batcher getBatcher() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		// TODO : should remove this exposure
-		//  and have all references to the session's batcher use the ConnectionManager.
-		return jdbcContext.getConnectionManager().getBatcher();
-	}
-
-	public long getTimestamp() {
-		checkTransactionSynchStatus();
-		return timestamp;
-	}
-
-	public Connection close() throws HibernateException {
-		log.trace( "closing session" );
-		if ( isClosed() ) {
-			throw new SessionException( "Session was already closed" );
-		}
-		
-
-		if ( factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().closeSession();
-		}
-
-		try {
-			try {
-				if ( childSessionsByEntityMode != null ) {
-					Iterator childSessions = childSessionsByEntityMode.values().iterator();
-					while ( childSessions.hasNext() ) {
-						final SessionImpl child = ( SessionImpl ) childSessions.next();
-						child.close();
-					}
-				}
-			}
-			catch( Throwable t ) {
-				// just ignore
-			}
-
-			if ( rootSession == null ) {
-				return jdbcContext.getConnectionManager().close();
-			}
-			else {
-				return null;
-			}
-		}
-		finally {
-			setClosed();
-			cleanup();
-		}
-	}
-
-	public ConnectionReleaseMode getConnectionReleaseMode() {
-		checkTransactionSynchStatus();
-		return connectionReleaseMode;
-	}
-
-	public boolean isAutoCloseSessionEnabled() {
-		return autoCloseSessionEnabled;
-	}
-
-	public boolean isOpen() {
-		checkTransactionSynchStatus();
-		return !isClosed();
-	}
-
-	public boolean isFlushModeNever() {
-		return FlushMode.isManualFlushMode( getFlushMode() );
-	}
-
-	public boolean isFlushBeforeCompletionEnabled() {
-		return flushBeforeCompletionEnabled;
-	}
-
-	public void managedFlush() {
-		if ( isClosed() ) {
-			log.trace( "skipping auto-flush due to session closed" );
-			return;
-		}
-		log.trace("automatically flushing session");
-		flush();
-		
-		if ( childSessionsByEntityMode != null ) {
-			Iterator iter = childSessionsByEntityMode.values().iterator();
-			while ( iter.hasNext() ) {
-				( (Session) iter.next() ).flush();
-			}
-		}
-	}
-
-	public boolean shouldAutoClose() {
-		return isAutoCloseSessionEnabled() && !isClosed();
-	}
-
-	public void managedClose() {
-		log.trace( "automatically closing session" );
-		close();
-	}
-
-	public Connection connection() throws HibernateException {
-		errorIfClosed();
-		return jdbcContext.borrowConnection();
-	}
-
-	public boolean isConnected() {
-		checkTransactionSynchStatus();
-		return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected();
-	}
-	
-	public boolean isTransactionInProgress() {
-		checkTransactionSynchStatus();
-		return !isClosed() && jdbcContext.isTransactionInProgress();
-	}
-
-	public Connection disconnect() throws HibernateException {
-		errorIfClosed();
-		log.debug( "disconnecting session" );
-		return jdbcContext.getConnectionManager().manualDisconnect();
-	}
-
-	public void reconnect() throws HibernateException {
-		errorIfClosed();
-		log.debug( "reconnecting session" );
-		checkTransactionSynchStatus();
-		jdbcContext.getConnectionManager().manualReconnect();
-	}
-
-	public void reconnect(Connection conn) throws HibernateException {
-		errorIfClosed();
-		log.debug( "reconnecting session" );
-		checkTransactionSynchStatus();
-		jdbcContext.getConnectionManager().manualReconnect( conn );
-	}
-
-	public void beforeTransactionCompletion(Transaction tx) {
-		log.trace( "before transaction completion" );
-		if ( rootSession == null ) {
-			try {
-				interceptor.beforeTransactionCompletion(tx);
-			}
-			catch (Throwable t) {
-				log.error("exception in interceptor beforeTransactionCompletion()", t);
-			}
-		}
-	}
-	
-	public void setAutoClear(boolean enabled) {
-		errorIfClosed();
-		autoClear = enabled;
-	}
-	
-	/**
-	 * Check if there is a Hibernate or JTA transaction in progress and, 
-	 * if there is not, flush if necessary, make sure the connection has 
-	 * been committed (if it is not in autocommit mode) and run the after 
-	 * completion processing
-	 */
-	public void afterOperation(boolean success) {
-		if ( !jdbcContext.isTransactionInProgress() ) {
-			jdbcContext.afterNontransactionalQuery( success );
-		}
-	}
-
-	public void afterTransactionCompletion(boolean success, Transaction tx) {
-		log.trace( "after transaction completion" );
-		persistenceContext.afterTransactionCompletion();
-		actionQueue.afterTransactionCompletion(success);
-		if ( rootSession == null && tx != null ) {
-			try {
-				interceptor.afterTransactionCompletion(tx);
-			}
-			catch (Throwable t) {
-				log.error("exception in interceptor afterTransactionCompletion()", t);
-			}
-		}
-		if ( autoClear ) {
-			clear();
-		}
-	}
-
-	/**
-	 * clear all the internal collections, just 
-	 * to help the garbage collector, does not
-	 * clear anything that is needed during the
-	 * afterTransactionCompletion() phase
-	 */
-	private void cleanup() {
-		persistenceContext.clear();
-	}
-
-	public LockMode getCurrentLockMode(Object object) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( object == null ) {
-			throw new NullPointerException( "null object passed to getCurrentLockMode()" );
-		}
-		if ( object instanceof HibernateProxy ) {
-			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this);
-			if ( object == null ) {
-				return LockMode.NONE;
-			}
-		}
-		EntityEntry e = persistenceContext.getEntry(object);
-		if ( e == null ) {
-			throw new TransientObjectException( "Given object not associated with the session" );
-		}
-		if ( e.getStatus() != Status.MANAGED ) {
-			throw new ObjectDeletedException( 
-					"The given object was deleted", 
-					e.getId(), 
-					e.getPersister().getEntityName() 
-				);
-		}
-		return e.getLockMode();
-	}
-
-	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
-		errorIfClosed();
-		// todo : should this get moved to PersistentContext?
-		// logically, is PersistentContext the "thing" to which an interceptor gets attached?
-		final Object result = persistenceContext.getEntity(key);
-		if ( result == null ) {
-			final Object newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );
-			if ( newObject != null ) {
-				lock( newObject, LockMode.NONE );
-			}
-			return newObject;
-		}
-		else {
-			return result;
-		}
-	}
-
-
-	// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void saveOrUpdate(Object object) throws HibernateException {
-		saveOrUpdate(null, object);
-	}
-
-	public void saveOrUpdate(String entityName, Object obj) throws HibernateException {
-		fireSaveOrUpdate( new SaveOrUpdateEvent(entityName, obj, this) );
-	}
-
-	private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners.getSaveOrUpdateEventListeners();
-		for ( int i = 0; i < saveOrUpdateEventListener.length; i++ ) {
-			saveOrUpdateEventListener[i].onSaveOrUpdate(event);
-		}
-	}
-
-
-	// save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void save(Object obj, Serializable id) throws HibernateException {
-		save(null, obj, id);
-	}
-
-	public Serializable save(Object obj) throws HibernateException {
-		return save(null, obj);
-	}
-
-	public Serializable save(String entityName, Object object) throws HibernateException {
-		return fireSave( new SaveOrUpdateEvent(entityName, object, this) );
-	}
-
-	public void save(String entityName, Object object, Serializable id) throws HibernateException {
-		fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
-	}
-
-	private Serializable fireSave(SaveOrUpdateEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
-		for ( int i = 0; i < saveEventListener.length; i++ ) {
-			saveEventListener[i].onSaveOrUpdate(event);
-		}
-		return event.getResultId();
-	}
-
-
-	// update() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void update(Object obj) throws HibernateException {
-		update(null, obj);
-	}
-
-	public void update(Object obj, Serializable id) throws HibernateException {
-		update(null, obj, id);
-	}
-
-	public void update(String entityName, Object object) throws HibernateException {
-		fireUpdate( new SaveOrUpdateEvent(entityName, object, this) );
-	}
-
-	public void update(String entityName, Object object, Serializable id) throws HibernateException {
-		fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this));
-	}
-
-	private void fireUpdate(SaveOrUpdateEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		SaveOrUpdateEventListener[] updateEventListener = listeners.getUpdateEventListeners();
-		for ( int i = 0; i < updateEventListener.length; i++ ) {
-			updateEventListener[i].onSaveOrUpdate(event);
-		}
-	}
-
-
-	// lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException {
-		fireLock( new LockEvent(entityName, object, lockMode, this) );
-	}
-
-	public void lock(Object object, LockMode lockMode) throws HibernateException {
-		fireLock( new LockEvent(object, lockMode, this) );
-	}
-
-	private void fireLock(LockEvent lockEvent) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		LockEventListener[] lockEventListener = listeners.getLockEventListeners();
-		for ( int i = 0; i < lockEventListener.length; i++ ) {
-			lockEventListener[i].onLock( lockEvent );
-		}
-	}
-
-
-	// persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void persist(String entityName, Object object) throws HibernateException {
-		firePersist( new PersistEvent(entityName, object, this) );
-	}
-
-	public void persist(Object object) throws HibernateException {
-		persist(null, object);
-	}
-
-	public void persist(String entityName, Object object, Map copiedAlready)
-	throws HibernateException {
-		firePersist( copiedAlready, new PersistEvent(entityName, object, this) );
-	}
-
-	private void firePersist(Map copiedAlready, PersistEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		PersistEventListener[] persistEventListener = listeners.getPersistEventListeners();
-		for ( int i = 0; i < persistEventListener.length; i++ ) {
-			persistEventListener[i].onPersist(event, copiedAlready);
-		}
-	}
-
-	private void firePersist(PersistEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		PersistEventListener[] createEventListener = listeners.getPersistEventListeners();
-		for ( int i = 0; i < createEventListener.length; i++ ) {
-			createEventListener[i].onPersist(event);
-		}
-	}
-
-
-	// persistOnFlush() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void persistOnFlush(String entityName, Object object)
-			throws HibernateException {
-		firePersistOnFlush( new PersistEvent(entityName, object, this) );
-	}
-
-	public void persistOnFlush(Object object) throws HibernateException {
-		persist(null, object);
-	}
-
-	public void persistOnFlush(String entityName, Object object, Map copiedAlready)
-			throws HibernateException {
-		firePersistOnFlush( copiedAlready, new PersistEvent(entityName, object, this) );
-	}
-
-	private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		PersistEventListener[] persistEventListener = listeners.getPersistOnFlushEventListeners();
-		for ( int i = 0; i < persistEventListener.length; i++ ) {
-			persistEventListener[i].onPersist(event, copiedAlready);
-		}
-	}
-
-	private void firePersistOnFlush(PersistEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		PersistEventListener[] createEventListener = listeners.getPersistOnFlushEventListeners();
-		for ( int i = 0; i < createEventListener.length; i++ ) {
-			createEventListener[i].onPersist(event);
-		}
-	}
-
-
-	// merge() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Object merge(String entityName, Object object) throws HibernateException {
-		return fireMerge( new MergeEvent(entityName, object, this) );
-	}
-
-	public Object merge(Object object) throws HibernateException {
-		return merge(null, object);
-	}
-
-	public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException {
-		fireMerge( copiedAlready, new MergeEvent(entityName, object, this) );
-	}
-
-	private Object fireMerge(MergeEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
-		for ( int i = 0; i < mergeEventListener.length; i++ ) {
-			mergeEventListener[i].onMerge(event);
-		}
-		return event.getResult();
-	}
-
-	private void fireMerge(Map copiedAlready, MergeEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
-		for ( int i = 0; i < mergeEventListener.length; i++ ) {
-			mergeEventListener[i].onMerge(event, copiedAlready);
-		}
-	}
-
-
-	// saveOrUpdateCopy() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Object saveOrUpdateCopy(String entityName, Object object)
-			throws HibernateException {
-		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, this) );
-	}
-
-	public Object saveOrUpdateCopy(Object object) throws HibernateException {
-		return saveOrUpdateCopy( null, object );
-	}
-
-	public Object saveOrUpdateCopy(String entityName, Object object, Serializable id)
-			throws HibernateException {
-		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, id, this) );
-	}
-
-	public Object saveOrUpdateCopy(Object object, Serializable id)
-			throws HibernateException {
-		return saveOrUpdateCopy( null, object, id );
-	}
-
-	public void saveOrUpdateCopy(String entityName, Object object, Map copiedAlready)
-			throws HibernateException {
-		fireSaveOrUpdateCopy( copiedAlready, new MergeEvent( entityName, object, this ) );
-	}
-
-	private void fireSaveOrUpdateCopy(Map copiedAlready, MergeEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
-		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
-			saveOrUpdateCopyEventListener[i].onMerge(event, copiedAlready);
-		}
-	}
-
-	private Object fireSaveOrUpdateCopy(MergeEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
-		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
-			saveOrUpdateCopyEventListener[i].onMerge(event);
-		}
-		return event.getResult();
-	}
-
-
-	// delete() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Delete a persistent object
-	 */
-	public void delete(Object object) throws HibernateException {
-		fireDelete( new DeleteEvent(object, this) );
-	}
-
-	/**
-	 * Delete a persistent object (by explicit entity name)
-	 */
-	public void delete(String entityName, Object object) throws HibernateException {
-		fireDelete( new DeleteEvent( entityName, object, this ) );
-	}
-
-	/**
-	 * Delete a persistent object
-	 */
-	public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, Set transientEntities) throws HibernateException {
-		fireDelete( new DeleteEvent( entityName, object, isCascadeDeleteEnabled, this ), transientEntities );
-	}
-
-	private void fireDelete(DeleteEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
-		for ( int i = 0; i < deleteEventListener.length; i++ ) {
-			deleteEventListener[i].onDelete( event );
-		}
-	}
-
-	private void fireDelete(DeleteEvent event, Set transientEntities) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
-		for ( int i = 0; i < deleteEventListener.length; i++ ) {
-			deleteEventListener[i].onDelete( event, transientEntities );
-		}
-	}
-
-
-	// load()/get() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void load(Object object, Serializable id) throws HibernateException {
-		LoadEvent event = new LoadEvent(id, object, this);
-		fireLoad( event, LoadEventListener.RELOAD );
-	}
-
-	public Object load(Class entityClass, Serializable id) throws HibernateException {
-		return load( entityClass.getName(), id );
-	}
-
-	public Object load(String entityName, Serializable id) throws HibernateException {
-		LoadEvent event = new LoadEvent(id, entityName, false, this);
-		boolean success = false;
-		try {
-			fireLoad( event, LoadEventListener.LOAD );
-			if ( event.getResult() == null ) {
-				getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
-			}
-			success = true;
-			return event.getResult();
-		}
-		finally {
-			afterOperation(success);
-		}
-	}
-
-	public Object get(Class entityClass, Serializable id) throws HibernateException {
-		return get( entityClass.getName(), id );
-	}
-
-	public Object get(String entityName, Serializable id) throws HibernateException {
-		LoadEvent event = new LoadEvent(id, entityName, false, this);
-		boolean success = false;
-		try {
-			fireLoad(event, LoadEventListener.GET);
-			success = true;
-			return event.getResult();
-		}
-		finally {
-			afterOperation(success);
-		}
-	}
-
-	/**
-	 * Load the data for the object with the specified id into a newly created object.
-	 * This is only called when lazily initializing a proxy.
-	 * Do NOT return a proxy.
-	 */
-	public Object immediateLoad(String entityName, Serializable id) throws HibernateException {
-		if ( log.isDebugEnabled() ) {
-			EntityPersister persister = getFactory().getEntityPersister(entityName);
-			log.debug( "initializing proxy: " + MessageHelper.infoString( persister, id, getFactory() ) );
-		}
-		
-		LoadEvent event = new LoadEvent(id, entityName, true, this);
-		fireLoad(event, LoadEventListener.IMMEDIATE_LOAD);
-		return event.getResult();
-	}
-
-	public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) throws HibernateException {
-		// todo : remove
-		LoadEventListener.LoadType type = nullable ? 
-				LoadEventListener.INTERNAL_LOAD_NULLABLE : 
-				eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY;
-		LoadEvent event = new LoadEvent(id, entityName, true, this);
-		fireLoad(event, type);
-		if ( !nullable ) {
-			UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName );
-		}
-		return event.getResult();
-	}
-
-	public Object load(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
-		return load( entityClass.getName(), id, lockMode );
-	}
-
-	public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
-		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
-		fireLoad( event, LoadEventListener.LOAD );
-		return event.getResult();
-	}
-
-	public Object get(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
-		return get( entityClass.getName(), id, lockMode );
-	}
-
-	public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
-		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
-	   	fireLoad(event, LoadEventListener.GET);
-		return event.getResult();
-	}
-
-	private void fireLoad(LoadEvent event, LoadType loadType) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
-		for ( int i = 0; i < loadEventListener.length; i++ ) {
-			loadEventListener[i].onLoad(event, loadType);
-		}
-	}
-
-
-	// refresh() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void refresh(Object object) throws HibernateException {
-		fireRefresh( new RefreshEvent(object, this) );
-	}
-
-	public void refresh(Object object, LockMode lockMode) throws HibernateException {
-		fireRefresh( new RefreshEvent(object, lockMode, this) );
-	}
-
-	public void refresh(Object object, Map refreshedAlready) throws HibernateException {
-		fireRefresh( refreshedAlready, new RefreshEvent(object, this) );
-	}
-
-	private void fireRefresh(RefreshEvent refreshEvent) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
-		for ( int i = 0; i < refreshEventListener.length; i++ ) {
-			refreshEventListener[i].onRefresh( refreshEvent );
-		}
-	}
-
-	private void fireRefresh(Map refreshedAlready, RefreshEvent refreshEvent) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
-		for ( int i = 0; i < refreshEventListener.length; i++ ) {
-			refreshEventListener[i].onRefresh( refreshEvent, refreshedAlready );
-		}
-	}
-
-
-	// replicate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void replicate(Object obj, ReplicationMode replicationMode) throws HibernateException {
-		fireReplicate( new ReplicateEvent(obj, replicationMode, this) );
-	}
-
-	public void replicate(String entityName, Object obj, ReplicationMode replicationMode)
-	throws HibernateException {
-		fireReplicate( new ReplicateEvent(entityName, obj, replicationMode, this) );
-	}
-
-	private void fireReplicate(ReplicateEvent event) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		ReplicateEventListener[] replicateEventListener = listeners.getReplicateEventListeners();
-		for ( int i = 0; i < replicateEventListener.length; i++ ) {
-			replicateEventListener[i].onReplicate(event);
-		}
-	}
-
-
-	// evict() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * remove any hard references to the entity that are held by the infrastructure
-	 * (references held by application or other persistant instances are okay)
-	 */
-	public void evict(Object object) throws HibernateException {
-		fireEvict( new EvictEvent(object, this) );
-	}
-
-	private void fireEvict(EvictEvent evictEvent) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		EvictEventListener[] evictEventListener = listeners.getEvictEventListeners();
-		for ( int i = 0; i < evictEventListener.length; i++ ) {
-			evictEventListener[i].onEvict( evictEvent );
-		}
-	}
-
-	/**
-	 * detect in-memory changes, determine if the changes are to tables
-	 * named in the query and, if so, complete execution the flush
-	 */
-	protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
-		errorIfClosed();
-		if ( ! isTransactionInProgress() ) {
-			// do not auto-flush while outside a transaction
-			return false;
-		}
-		AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
-		AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
-		for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
-			autoFlushEventListener[i].onAutoFlush(event);
-		}
-		return event.isFlushRequired();
-	}
-
-	public boolean isDirty() throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		log.debug("checking session dirtiness");
-		if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
-			log.debug("session dirty (scheduled updates and insertions)");
-			return true;
-		}
-		else {
-			DirtyCheckEvent event = new DirtyCheckEvent(this);
-			DirtyCheckEventListener[] dirtyCheckEventListener = listeners.getDirtyCheckEventListeners();
-			for ( int i = 0; i < dirtyCheckEventListener.length; i++ ) {
-				dirtyCheckEventListener[i].onDirtyCheck(event);
-			}
-			return event.isDirty();
-		}
-	}
-
-	public void flush() throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( persistenceContext.getCascadeLevel() > 0 ) {
-			throw new HibernateException("Flush during cascade is dangerous");
-		}
-		FlushEventListener[] flushEventListener = listeners.getFlushEventListeners();
-		for ( int i = 0; i < flushEventListener.length; i++ ) {
-			flushEventListener[i].onFlush( new FlushEvent(this) );
-		}
-	}
-
-	public void forceFlush(EntityEntry entityEntry) throws HibernateException {
-		errorIfClosed();
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-				"flushing to force deletion of re-saved object: " +
-				MessageHelper.infoString( entityEntry.getPersister(), entityEntry.getId(), getFactory() )
-			);
-		}
-
-		if ( persistenceContext.getCascadeLevel() > 0 ) {
-			throw new ObjectDeletedException(
-				"deleted object would be re-saved by cascade (remove deleted object from associations)",
-				entityEntry.getId(),
-				entityEntry.getPersister().getEntityName()
-			);
-		}
-
-		flush();
-	}
-
-	public Filter getEnabledFilter(String filterName) {
-		checkTransactionSynchStatus();
-		return (Filter) enabledFilters.get(filterName);
-	}
-
-	public Filter enableFilter(String filterName) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		FilterImpl filter = new FilterImpl( factory.getFilterDefinition(filterName) );
-		enabledFilters.put(filterName, filter);
-		return filter;
-	}
-
-	public void disableFilter(String filterName) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		enabledFilters.remove(filterName);
-	}
-
-	public Object getFilterParameterValue(String filterParameterName) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		String[] parsed = parseFilterParameterName(filterParameterName);
-		FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] );
-		if (filter == null) {
-			throw new IllegalArgumentException("Filter [" + parsed[0] + "] currently not enabled");
-		}
-		return filter.getParameter( parsed[1] );
-	}
-
-	public Type getFilterParameterType(String filterParameterName) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		String[] parsed = parseFilterParameterName(filterParameterName);
-		FilterDefinition filterDef = factory.getFilterDefinition( parsed[0] );
-		if (filterDef == null) {
-			throw new IllegalArgumentException("Filter [" + parsed[0] + "] not defined");
-		}
-		Type type = filterDef.getParameterType( parsed[1] );
-		if (type == null) {
-			// this is an internal error of some sort...
-			throw new InternalError("Unable to locate type for filter parameter");
-		}
-		return type;
-	}
-
-	public Map getEnabledFilters() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		// First, validate all the enabled filters...
-		//TODO: this implementation has bad performance
-		Iterator itr = enabledFilters.values().iterator();
-		while ( itr.hasNext() ) {
-			final Filter filter = (Filter) itr.next();
-			filter.validate();
-		}
-		return enabledFilters;
-	}
-
-	private String[] parseFilterParameterName(String filterParameterName) {
-		int dot = filterParameterName.indexOf('.');
-		if (dot <= 0) {
-			throw new IllegalArgumentException("Invalid filter-parameter name format"); // TODO: what type?
-		}
-		String filterName = filterParameterName.substring(0, dot);
-		String parameterName = filterParameterName.substring(dot+1);
-		return new String[] {filterName, parameterName};
-	}
-
-
-	/**
-	 * Retrieve a list of persistent objects using a hibernate query
-	 */
-	public List find(String query) throws HibernateException {
-		return list( query, new QueryParameters() );
-	}
-
-	public List find(String query, Object value, Type type) throws HibernateException {
-		return list( query, new QueryParameters(type, value) );
-	}
-
-	public List find(String query, Object[] values, Type[] types) throws HibernateException {
-		return list( query, new QueryParameters(types, values) );
-	}
-
-	public List list(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		queryParameters.validateParameters();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		autoFlushIfRequired( plan.getQuerySpaces() );
-
-		List results = CollectionHelper.EMPTY_LIST;
-		boolean success = false;
-
-		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
-		try {
-			results = plan.performList( queryParameters, this );
-			success = true;
-		}
-		finally {
-			dontFlushFromFind--;
-			afterOperation(success);
-		}
-		return results;
-	}
-
-	public int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		queryParameters.validateParameters();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		autoFlushIfRequired( plan.getQuerySpaces() );
-
-		boolean success = false;
-		int result = 0;
-		try {
-			result = plan.performExecuteUpdate( queryParameters, this );
-			success = true;
-		}
-		finally {
-			afterOperation(success);
-		}
-		return result;
-	}
-
-    public int executeNativeUpdate(NativeSQLQuerySpecification nativeQuerySpecification,
-            QueryParameters queryParameters) throws HibernateException {
-        errorIfClosed();
-        checkTransactionSynchStatus();
-        queryParameters.validateParameters();
-        NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);
-
-        
-        autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() );
-        
-        boolean success = false;
-        int result = 0;
-        try {
-            result = plan.performExecuteUpdate(queryParameters, this);
-            success = true;
-        } finally {
-            afterOperation(success);
-        }
-        return result;
-    }
-
-	public Iterator iterate(String query) throws HibernateException {
-		return iterate( query, new QueryParameters() );
-	}
-
-	public Iterator iterate(String query, Object value, Type type) throws HibernateException {
-		return iterate( query, new QueryParameters(type, value) );
-	}
-
-	public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException {
-		return iterate( query, new QueryParameters(types, values) );
-	}
-
-	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		queryParameters.validateParameters();
-		HQLQueryPlan plan = getHQLQueryPlan( query, true );
-		autoFlushIfRequired( plan.getQuerySpaces() );
-
-		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
-		try {
-			return plan.performIterate( queryParameters, this );
-		}
-		finally {
-			dontFlushFromFind--;
-		}
-	}
-
-	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		autoFlushIfRequired( plan.getQuerySpaces() );
-		dontFlushFromFind++;
-		try {
-			return plan.performScroll( queryParameters, this );
-		}
-		finally {
-			dontFlushFromFind--;
-		}
-	}
-
-	public int delete(String query) throws HibernateException {
-		return delete( query, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY );
-	}
-
-	public int delete(String query, Object value, Type type) throws HibernateException {
-		return delete( query, new Object[]{value}, new Type[]{type} );
-	}
-
-	public int delete(String query, Object[] values, Type[] types) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( query == null ) {
-			throw new IllegalArgumentException("attempt to perform delete-by-query with null query");
-		}
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "delete: " + query );
-			if ( values.length != 0 ) {
-				log.trace( "parameters: " + StringHelper.toString( values ) );
-			}
-		}
-
-		List list = find( query, values, types );
-		int deletionCount = list.size();
-		for ( int i = 0; i < deletionCount; i++ ) {
-			delete( list.get( i ) );
-		}
-
-		return deletionCount;
-	}
-
-	public Query createFilter(Object collection, String queryString) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		CollectionFilterImpl filter = new CollectionFilterImpl(
-				queryString,
-		        collection,
-		        this,
-		        getFilterQueryPlan( collection, queryString, null, false ).getParameterMetadata()
-		);
-		filter.setComment( queryString );
-		return filter;
-	}
-	
-	public Query getNamedQuery(String queryName) throws MappingException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return super.getNamedQuery(queryName);
-	}
-
-	public Object instantiate(String entityName, Serializable id) throws HibernateException {
-		return instantiate( factory.getEntityPersister(entityName), id );
-	}
-
-	/**
-	 * give the interceptor an opportunity to override the default instantiation
-	 */
-	public Object instantiate(EntityPersister persister, Serializable id) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		Object result = interceptor.instantiate( persister.getEntityName(), entityMode, id );
-		if ( result == null ) {
-			result = persister.instantiate( id, entityMode );
-		}
-		return result;
-	}
-
-	public EntityMode getEntityMode() {
-		checkTransactionSynchStatus();
-		return entityMode;
-	}
-
-	public void setFlushMode(FlushMode flushMode) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( log.isTraceEnabled() ) {
-			log.trace("setting flush mode to: " + flushMode);
-		}
-		this.flushMode = flushMode;
-	}
-	
-	public FlushMode getFlushMode() {
-		checkTransactionSynchStatus();
-		return flushMode;
-	}
-
-	public CacheMode getCacheMode() {
-		checkTransactionSynchStatus();
-		return cacheMode;
-	}
-	
-	public void setCacheMode(CacheMode cacheMode) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( log.isTraceEnabled() ) {
-			log.trace("setting cache mode to: " + cacheMode);
-		}
-		this.cacheMode= cacheMode; 
-	}
-
-	public Transaction getTransaction() throws HibernateException {
-		errorIfClosed();
-		return jdbcContext.getTransaction();
-	}
-	
-	public Transaction beginTransaction() throws HibernateException {
-		errorIfClosed();
-		if ( rootSession != null ) {
-			// todo : should seriously consider not allowing a txn to begin from a child session
-			//      can always route the request to the root session...
-			log.warn( "Transaction started on non-root session" );
-		}
-		Transaction result = getTransaction();
-		result.begin();
-		return result;
-	}
-	
-	public void afterTransactionBegin(Transaction tx) {
-		errorIfClosed();
-		interceptor.afterTransactionBegin(tx);
-	}
-
-	public EntityPersister getEntityPersister(final String entityName, final Object object) {
-		errorIfClosed();
-		if (entityName==null) {
-			return factory.getEntityPersister( guessEntityName( object ) );
-		}
-		else {
-			// try block is a hack around fact that currently tuplizers are not
-			// given the opportunity to resolve a subclass entity name.  this
-			// allows the (we assume custom) interceptor the ability to
-			// influence this decision if we were not able to based on the
-			// given entityName
-			try {
-				return factory.getEntityPersister( entityName )
-						.getSubclassEntityPersister( object, getFactory(), entityMode );
-			}
-			catch( HibernateException e ) {
-				try {
-					return getEntityPersister( null, object );
-				}
-				catch( HibernateException e2 ) {
-					throw e;
-				}
-			}
-		}
-	}
-
-	// not for internal use:
-	public Serializable getIdentifier(Object object) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( object instanceof HibernateProxy ) {
-			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
-			if ( li.getSession() != this ) {
-				throw new TransientObjectException( "The proxy was not associated with this session" );
-			}
-			return li.getIdentifier();
-		}
-		else {
-			EntityEntry entry = persistenceContext.getEntry(object);
-			if ( entry == null ) {
-				throw new TransientObjectException( "The instance was not associated with this session" );
-			}
-			return entry.getId();
-		}
-	}
-
-	/**
-	 * Get the id value for an object that is actually associated with the session. This
-	 * is a bit stricter than getEntityIdentifierIfNotUnsaved().
-	 */
-	public Serializable getContextEntityIdentifier(Object object) {
-		errorIfClosed();
-		if ( object instanceof HibernateProxy ) {
-			return getProxyIdentifier(object);
-		}
-		else {
-			EntityEntry entry = persistenceContext.getEntry(object);
-			return entry != null ? entry.getId() : null;
-		}
-	}
-	
-	private Serializable getProxyIdentifier(Object proxy) {
-		return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
-	}
-
-	public Collection filter(Object collection, String filter) throws HibernateException {
-		return listFilter( collection, filter, new QueryParameters( new Type[1], new Object[1] ) );
-	}
-
-	public Collection filter(Object collection, String filter, Object value, Type type) throws HibernateException {
-		return listFilter( collection, filter, new QueryParameters( new Type[]{null, type}, new Object[]{null, value} ) );
-	}
-
-	public Collection filter(Object collection, String filter, Object[] values, Type[] types) 
-	throws HibernateException {
-		Object[] vals = new Object[values.length + 1];
-		Type[] typs = new Type[types.length + 1];
-		System.arraycopy( values, 0, vals, 1, values.length );
-		System.arraycopy( types, 0, typs, 1, types.length );
-		return listFilter( collection, filter, new QueryParameters( typs, vals ) );
-	}
-
-	private FilterQueryPlan getFilterQueryPlan(
-			Object collection,
-			String filter,
-			QueryParameters parameters,
-			boolean shallow) throws HibernateException {
-		if ( collection == null ) {
-			throw new NullPointerException( "null collection passed to filter" );
-		}
-
-		CollectionEntry entry = persistenceContext.getCollectionEntryOrNull( collection );
-		final CollectionPersister roleBeforeFlush = (entry == null) ? null : entry.getLoadedPersister();
-
-		FilterQueryPlan plan = null;
-		if ( roleBeforeFlush == null ) {
-			// if it was previously unreferenced, we need to flush in order to
-			// get its state into the database in order to execute query
-			flush();
-			entry = persistenceContext.getCollectionEntryOrNull( collection );
-			CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
-			if ( roleAfterFlush == null ) {
-				throw new QueryException( "The collection was unreferenced" );
-			}
-			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
-		}
-		else {
-			// otherwise, we only need to flush if there are in-memory changes
-			// to the queried tables
-			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleBeforeFlush.getRole(), shallow, getEnabledFilters() );
-			if ( autoFlushIfRequired( plan.getQuerySpaces() ) ) {
-				// might need to run a different filter entirely after the flush
-				// because the collection role may have changed
-				entry = persistenceContext.getCollectionEntryOrNull( collection );
-				CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
-				if ( roleBeforeFlush != roleAfterFlush ) {
-					if ( roleAfterFlush == null ) {
-						throw new QueryException( "The collection was dereferenced" );
-					}
-					plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
-				}
-			}
-		}
-
-		if ( parameters != null ) {
-			parameters.getPositionalParameterValues()[0] = entry.getLoadedKey();
-			parameters.getPositionalParameterTypes()[0] = entry.getLoadedPersister().getKeyType();
-		}
-
-		return plan;
-	}
-
-	public List listFilter(Object collection, String filter, QueryParameters queryParameters) 
-	throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, false );
-		List results = CollectionHelper.EMPTY_LIST;
-
-		boolean success = false;
-		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
-		try {
-			results = plan.performList( queryParameters, this );
-			success = true;
-		}
-		finally {
-			dontFlushFromFind--;
-			afterOperation(success);
-		}
-		return results;
-	}
-
-	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) 
-	throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, true );
-		return plan.performIterate( queryParameters, this );
-	}
-
-	public Criteria createCriteria(Class persistentClass, String alias) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new CriteriaImpl( persistentClass.getName(), alias, this );
-	}
-
-	public Criteria createCriteria(String entityName, String alias) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new CriteriaImpl(entityName, alias, this);
-	}
-
-	public Criteria createCriteria(Class persistentClass) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new CriteriaImpl( persistentClass.getName(), this );
-	}
-
-	public Criteria createCriteria(String entityName) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new CriteriaImpl(entityName, this);
-	}
-
-	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		String entityName = criteria.getEntityOrClassName();
-		CriteriaLoader loader = new CriteriaLoader(
-				getOuterJoinLoadable(entityName),
-				factory,
-				criteria,
-				entityName,
-				getEnabledFilters()
-		);
-		autoFlushIfRequired( loader.getQuerySpaces() );
-		dontFlushFromFind++;
-		try {
-			return loader.scroll(this, scrollMode);
-		}
-		finally {
-			dontFlushFromFind--;
-		}
-	}
-
-	public List list(CriteriaImpl criteria) throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
-		int size = implementors.length;
-
-		CriteriaLoader[] loaders = new CriteriaLoader[size];
-		Set spaces = new HashSet();
-		for( int i=0; i <size; i++ ) {
-
-			loaders[i] = new CriteriaLoader(
-					getOuterJoinLoadable( implementors[i] ),
-					factory,
-					criteria,
-					implementors[i],
-					getEnabledFilters()
-				);
-
-			spaces.addAll( loaders[i].getQuerySpaces() );
-
-		}
-
-		autoFlushIfRequired(spaces);
-
-		List results = Collections.EMPTY_LIST;
-		dontFlushFromFind++;
-		boolean success = false;
-		try {
-			for( int i=0; i<size; i++ ) {
-				final List currentResults = loaders[i].list(this);
-				currentResults.addAll(results);
-				results = currentResults;
-			}
-			success = true;
-		}
-		finally {
-			dontFlushFromFind--;
-			afterOperation(success);
-		}
-
-		return results;
-	}
-
-	private OuterJoinLoadable getOuterJoinLoadable(String entityName) throws MappingException {
-		EntityPersister persister = factory.getEntityPersister(entityName);
-		if ( !(persister instanceof OuterJoinLoadable) ) {
-			throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
-		}
-		return ( OuterJoinLoadable ) persister;
-	}
-
-	public boolean contains(Object object) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if ( object instanceof HibernateProxy ) {
-			//do not use proxiesByKey, since not all
-			//proxies that point to this session's
-			//instances are in that collection!
-			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
-			if ( li.isUninitialized() ) {
-				//if it is an uninitialized proxy, pointing
-				//with this session, then when it is accessed,
-				//the underlying instance will be "contained"
-				return li.getSession()==this;
-			}
-			else {
-				//if it is initialized, see if the underlying
-				//instance is contained, since we need to 
-				//account for the fact that it might have been
-				//evicted
-				object = li.getImplementation();
-			}
-		}
-		// A session is considered to contain an entity only if the entity has
-		// an entry in the session's persistence context and the entry reports
-		// that the entity has not been removed
-		EntityEntry entry = persistenceContext.getEntry( object );
-		return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE;
-	}
-	
-	public Query createQuery(String queryString) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return super.createQuery(queryString);
-	}
-	
-	public SQLQuery createSQLQuery(String sql) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return super.createSQLQuery(sql);
-	}
-
-	public Query createSQLQuery(String sql, String returnAlias, Class returnClass) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new SQLQueryImpl(
-				sql,
-		        new String[] { returnAlias },
-		        new Class[] { returnClass },
-		        this,
-		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
-		);
-	}
-
-	public Query createSQLQuery(String sql, String returnAliases[], Class returnClasses[]) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return new SQLQueryImpl(
-				sql,
-		        returnAliases,
-		        returnClasses,
-		        this,
-		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
-		);
-	}
-
-	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
-	throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "scroll SQL query: " + customQuery.getSQL() );
-		}
-
-		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
-
-		autoFlushIfRequired( loader.getQuerySpaces() );
-
-		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
-		try {
-			return loader.scroll(queryParameters, this);
-		}
-		finally {
-			dontFlushFromFind--;
-		}
-	}
-
-	// basically just an adapted copy of find(CriteriaImpl)
-	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
-	throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "SQL query: " + customQuery.getSQL() );
-		}
-		
-		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
-
-		autoFlushIfRequired( loader.getQuerySpaces() );
-
-		dontFlushFromFind++;
-		boolean success = false;
-		try {
-			List results = loader.list(this, queryParameters);
-			success = true;
-			return results;
-		}
-		finally {
-			dontFlushFromFind--;
-			afterOperation(success);
-		}
-	}
-
-	public SessionFactory getSessionFactory() {
-		checkTransactionSynchStatus();
-		return factory;
-	}
-	
-	public void initializeCollection(PersistentCollection collection, boolean writing) 
-	throws HibernateException {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		InitializeCollectionEventListener[] listener = listeners.getInitializeCollectionEventListeners();
-		for ( int i = 0; i < listener.length; i++ ) {
-			listener[i].onInitializeCollection( new InitializeCollectionEvent(collection, this) );
-		}
-	}
-
-	public String bestGuessEntityName(Object object) {
-		if (object instanceof HibernateProxy) {
-			LazyInitializer initializer = ( ( HibernateProxy ) object ).getHibernateLazyInitializer();
-			// it is possible for this method to be called during flush processing,
-			// so make certain that we do not accidently initialize an uninitialized proxy
-			if ( initializer.isUninitialized() ) {
-				return initializer.getEntityName();
-			}
-			object = initializer.getImplementation();
-		}
-		EntityEntry entry = persistenceContext.getEntry(object);
-		if (entry==null) {
-			return guessEntityName(object);
-		}
-		else {
-			return entry.getPersister().getEntityName();
-		}
-	}
-	
-	public String getEntityName(Object object) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		if (object instanceof HibernateProxy) {
-			if ( !persistenceContext.containsProxy( object ) ) {
-				throw new TransientObjectException("proxy was not associated with the session");
-			}
-			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
-		}
-
-		EntityEntry entry = persistenceContext.getEntry(object);
-		if ( entry == null ) {
-			throwTransientObjectException( object );
-		}
-		return entry.getPersister().getEntityName();
-	}
-
-	private void throwTransientObjectException(Object object) throws HibernateException {
-		throw new TransientObjectException(
-				"object references an unsaved transient instance - save the transient instance before flushing: " +
-				guessEntityName(object)
-			);
-	}
-
-	public String guessEntityName(Object object) throws HibernateException {
-		errorIfClosed();
-		String entity = interceptor.getEntityName( object );
-		if ( entity == null ) {
-			if ( object instanceof Map ) {
-				entity = (String) ( (Map) object ).get( DynamicMapInstantiator.KEY );
-				if ( entity == null ) {
-					throw new HibernateException( "could not determine type of dynamic entity" );
-				}
-			}
-			else if ( object instanceof Element ) {
-				// TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
-				entity = ( (Element) object ).getName();
-			}
-			else {
-				entity = object.getClass().getName();
-			}
-		}
-		return entity;
-	}
-
-	public void cancelQuery() throws HibernateException {
-		errorIfClosed();
-		getBatcher().cancelLastQuery();
-	}
-
-	public Interceptor getInterceptor() {
-		checkTransactionSynchStatus();
-		return interceptor;
-	}
-
-	public int getDontFlushFromFind() {
-		return dontFlushFromFind;
-	}
-
-	public String toString() {
-		StringBuffer buf = new StringBuffer(500)
-			.append( "SessionImpl(" );
-		if ( !isClosed() ) {
-			buf.append(persistenceContext)
-				.append(";")
-				.append(actionQueue);
-		}
-		else {
-			buf.append("<closed>");
-		}
-		return buf.append(')').toString();
-	}
-
-	public EventListeners getListeners() {
-		return listeners;
-	}
-
-	public ActionQueue getActionQueue() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return actionQueue;
-	}
-	
-	public PersistenceContext getPersistenceContext() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return persistenceContext;
-	}
-	
-	public SessionStatistics getStatistics() {
-		checkTransactionSynchStatus();
-		return new SessionStatisticsImpl(this);
-	}
-
-	public boolean isEventSource() {
-		checkTransactionSynchStatus();
-		return true;
-	}
-
-	public void setReadOnly(Object entity, boolean readOnly) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		persistenceContext.setReadOnly(entity, readOnly);
-	}
-
-	public void doWork(Work work) throws HibernateException {
-		try {
-			work.execute( jdbcContext.getConnectionManager().getConnection() );
-			jdbcContext.getConnectionManager().afterStatement();
-		}
-		catch ( SQLException e ) {
-			throw JDBCExceptionHelper.convert( factory.getSettings().getSQLExceptionConverter(), e, "error executing work" );
-		}
-	}
-
-	public void afterScrollOperation() {
-		// nothing to do in a stateful session
-	}
-
-	public String getFetchProfile() {
-		checkTransactionSynchStatus();
-		return fetchProfile;
-	}
-
-	public JDBCContext getJDBCContext() {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		return jdbcContext;
-	}
-
-	public void setFetchProfile(String fetchProfile) {
-		errorIfClosed();
-		checkTransactionSynchStatus();
-		this.fetchProfile = fetchProfile;
-	}
-
-	private void checkTransactionSynchStatus() {
-		if ( jdbcContext != null && !isClosed() ) {
-			jdbcContext.registerSynchronizationIfPossible();
-		}
-	}
-
-	/**
-	 * Used by JDK serialization...
-	 *
-	 * @param ois The input stream from which we are being read...
-	 * @throws IOException Indicates a general IO stream exception
-	 * @throws ClassNotFoundException Indicates a class resolution issue
-	 */
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		log.trace( "deserializing session" );
-
-		boolean isRootSession = ois.readBoolean();
-		connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
-		entityMode = EntityMode.parse( ( String ) ois.readObject() );
-		autoClear = ois.readBoolean();
-		flushMode = FlushMode.parse( ( String ) ois.readObject() );
-		cacheMode = CacheMode.parse( ( String ) ois.readObject() );
-		flushBeforeCompletionEnabled = ois.readBoolean();
-		autoCloseSessionEnabled = ois.readBoolean();
-		fetchProfile = ( String ) ois.readObject();
-		interceptor = ( Interceptor ) ois.readObject();
-
-		factory = SessionFactoryImpl.deserialize( ois );
-		listeners = factory.getEventListeners();
-
-		if ( isRootSession ) {
-			jdbcContext = JDBCContext.deserialize( ois, this, interceptor );
-		}
-
-		persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
-		actionQueue = ActionQueue.deserialize( ois, this );
-
-		enabledFilters = ( Map ) ois.readObject();
-		childSessionsByEntityMode = ( Map ) ois.readObject();
-
-		Iterator iter = enabledFilters.values().iterator();
-		while ( iter.hasNext() ) {
-			( ( FilterImpl ) iter.next() ).afterDeserialize(factory);
-		}
-
-		if ( isRootSession && childSessionsByEntityMode != null ) {
-			iter = childSessionsByEntityMode.values().iterator();
-			while ( iter.hasNext() ) {
-				final SessionImpl child = ( ( SessionImpl ) iter.next() );
-				child.rootSession = this;
-				child.jdbcContext = this.jdbcContext;
-			}
-		}
-	}
-
-	/**
-	 * Used by JDK serialization...
-	 *
-	 * @param oos The output stream to which we are being written...
-	 * @throws IOException Indicates a general IO stream exception
-	 */
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		if ( !jdbcContext.getConnectionManager().isReadyForSerialization() ) {
-			throw new IllegalStateException( "Cannot serialize a session while connected" );
-		}
-
-		log.trace( "serializing session" );
-
-		oos.writeBoolean( rootSession == null );
-		oos.writeObject( connectionReleaseMode.toString() );
-		oos.writeObject( entityMode.toString() );
-		oos.writeBoolean( autoClear );
-		oos.writeObject( flushMode.toString() );
-		oos.writeObject( cacheMode.toString() );
-		oos.writeBoolean( flushBeforeCompletionEnabled );
-		oos.writeBoolean( autoCloseSessionEnabled );
-		oos.writeObject( fetchProfile );
-		// we need to writeObject() on this since interceptor is user defined
-		oos.writeObject( interceptor );
-
-		factory.serialize( oos );
-
-		if ( rootSession == null ) {
-			jdbcContext.serialize( oos );
-		}
-
-		persistenceContext.serialize( oos );
-		actionQueue.serialize( oos );
-
-		// todo : look at optimizing these...
-		oos.writeObject( enabledFilters );
-		oos.writeObject( childSessionsByEntityMode );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/SessionImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/SessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1995 @@
+/*
+ * 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.impl;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.dom4j.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.CacheMode;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.Filter;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.ObjectDeletedException;
+import org.hibernate.Query;
+import org.hibernate.QueryException;
+import org.hibernate.ReplicationMode;
+import org.hibernate.SQLQuery;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.Session;
+import org.hibernate.SessionException;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.TransientObjectException;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.ActionQueue;
+import org.hibernate.engine.CollectionEntry;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.FilterDefinition;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.StatefulPersistenceContext;
+import org.hibernate.engine.Status;
+import org.hibernate.engine.query.FilterQueryPlan;
+import org.hibernate.engine.query.HQLQueryPlan;
+import org.hibernate.engine.query.NativeSQLQueryPlan;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.event.AutoFlushEvent;
+import org.hibernate.event.AutoFlushEventListener;
+import org.hibernate.event.DeleteEvent;
+import org.hibernate.event.DeleteEventListener;
+import org.hibernate.event.DirtyCheckEvent;
+import org.hibernate.event.DirtyCheckEventListener;
+import org.hibernate.event.EventListeners;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.EvictEvent;
+import org.hibernate.event.EvictEventListener;
+import org.hibernate.event.FlushEvent;
+import org.hibernate.event.FlushEventListener;
+import org.hibernate.event.InitializeCollectionEvent;
+import org.hibernate.event.InitializeCollectionEventListener;
+import org.hibernate.event.LoadEvent;
+import org.hibernate.event.LoadEventListener;
+import org.hibernate.event.LoadEventListener.LoadType;
+import org.hibernate.event.LockEvent;
+import org.hibernate.event.LockEventListener;
+import org.hibernate.event.MergeEvent;
+import org.hibernate.event.MergeEventListener;
+import org.hibernate.event.PersistEvent;
+import org.hibernate.event.PersistEventListener;
+import org.hibernate.event.RefreshEvent;
+import org.hibernate.event.RefreshEventListener;
+import org.hibernate.event.ReplicateEvent;
+import org.hibernate.event.ReplicateEventListener;
+import org.hibernate.event.SaveOrUpdateEvent;
+import org.hibernate.event.SaveOrUpdateEventListener;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.jdbc.Batcher;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.jdbc.Work;
+import org.hibernate.loader.criteria.CriteriaLoader;
+import org.hibernate.loader.custom.CustomLoader;
+import org.hibernate.loader.custom.CustomQuery;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.stat.SessionStatistics;
+import org.hibernate.stat.SessionStatisticsImpl;
+import org.hibernate.tuple.DynamicMapInstantiator;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+
+/**
+ * Concrete implementation of a Session, and also the central, organizing component
+ * of Hibernate's internal implementation. As such, this class exposes two interfaces;
+ * Session itself, to the application, and SessionImplementor, to other components
+ * of Hibernate. This class is not threadsafe.
+ *
+ * @author Gavin King
+ */
+public final class SessionImpl extends AbstractSessionImpl 
+		implements EventSource, org.hibernate.classic.Session, JDBCContext.Context {
+
+	// todo : need to find a clean way to handle the "event source" role
+	// a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods...
+	// passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable...
+
+	private static final Logger log = LoggerFactory.getLogger(SessionImpl.class);
+
+	private transient EntityMode entityMode = EntityMode.POJO;
+	private transient boolean autoClear; //for EJB3
+	
+	private transient long timestamp;
+	private transient FlushMode flushMode = FlushMode.AUTO;
+	private transient CacheMode cacheMode = CacheMode.NORMAL;
+
+	private transient Interceptor interceptor;
+
+	private transient int dontFlushFromFind = 0;
+
+	private transient ActionQueue actionQueue;
+	private transient StatefulPersistenceContext persistenceContext;
+	private transient JDBCContext jdbcContext;
+	private transient EventListeners listeners;
+
+	private transient boolean flushBeforeCompletionEnabled;
+	private transient boolean autoCloseSessionEnabled;
+	private transient ConnectionReleaseMode connectionReleaseMode;
+	
+	private transient String fetchProfile;
+
+	private transient Map enabledFilters = new HashMap();
+
+	private transient Session rootSession;
+	private transient Map childSessionsByEntityMode;
+
+	/**
+	 * Constructor used in building "child sessions".
+	 *
+	 * @param parent The parent session
+	 * @param entityMode
+	 */
+	private SessionImpl(SessionImpl parent, EntityMode entityMode) {
+		super( parent.factory );
+		this.rootSession = parent;
+		this.timestamp = parent.timestamp;
+		this.jdbcContext = parent.jdbcContext;
+		this.interceptor = parent.interceptor;
+		this.listeners = parent.listeners;
+		this.actionQueue = new ActionQueue( this );
+		this.entityMode = entityMode;
+		this.persistenceContext = new StatefulPersistenceContext( this );
+		this.flushBeforeCompletionEnabled = false;
+		this.autoCloseSessionEnabled = false;
+		this.connectionReleaseMode = null;
+
+		if ( factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().openSession();
+		}
+
+		log.debug( "opened session [" + entityMode + "]" );
+	}
+
+	/**
+	 * Constructor used for openSession(...) processing, as well as construction
+	 * of sessions for getCurrentSession().
+	 *
+	 * @param connection The user-supplied connection to use for this session.
+	 * @param factory The factory from which this session was obtained
+	 * @param autoclose NOT USED
+	 * @param timestamp The timestamp for this session
+	 * @param interceptor The interceptor to be applied to this session
+	 * @param entityMode The entity-mode for this session
+	 * @param flushBeforeCompletionEnabled Should we auto flush before completion of transaction
+	 * @param autoCloseSessionEnabled Should we auto close after completion of transaction
+	 * @param connectionReleaseMode The mode by which we should release JDBC connections.
+	 */
+	SessionImpl(
+			final Connection connection,
+			final SessionFactoryImpl factory,
+			final boolean autoclose,
+			final long timestamp,
+			final Interceptor interceptor,
+			final EntityMode entityMode,
+			final boolean flushBeforeCompletionEnabled,
+			final boolean autoCloseSessionEnabled,
+			final ConnectionReleaseMode connectionReleaseMode) {
+		super( factory );
+		this.rootSession = null;
+		this.timestamp = timestamp;
+		this.entityMode = entityMode;
+		this.interceptor = interceptor;
+		this.listeners = factory.getEventListeners();
+		this.actionQueue = new ActionQueue( this );
+		this.persistenceContext = new StatefulPersistenceContext( this );
+		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
+		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
+		this.connectionReleaseMode = connectionReleaseMode;
+		this.jdbcContext = new JDBCContext( this, connection, interceptor );
+
+		if ( factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().openSession();
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "opened session at timestamp: " + timestamp );
+		}
+	}
+
+	public Session getSession(EntityMode entityMode) {
+		if ( this.entityMode == entityMode ) {
+			return this;
+		}
+
+		if ( rootSession != null ) {
+			rootSession.getSession( entityMode );
+		}
+
+		errorIfClosed();
+		checkTransactionSynchStatus();
+
+		SessionImpl rtn = null;
+		if ( childSessionsByEntityMode == null ) {
+			childSessionsByEntityMode = new HashMap();
+		}
+		else {
+			rtn = (SessionImpl) childSessionsByEntityMode.get( entityMode );
+		}
+
+		if ( rtn == null ) {
+			rtn = new SessionImpl( this, entityMode );
+			childSessionsByEntityMode.put( entityMode, rtn );
+		}
+
+		return rtn;
+	}
+
+	public void clear() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		persistenceContext.clear();
+		actionQueue.clear();
+	}
+
+	public Batcher getBatcher() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		// TODO : should remove this exposure
+		//  and have all references to the session's batcher use the ConnectionManager.
+		return jdbcContext.getConnectionManager().getBatcher();
+	}
+
+	public long getTimestamp() {
+		checkTransactionSynchStatus();
+		return timestamp;
+	}
+
+	public Connection close() throws HibernateException {
+		log.trace( "closing session" );
+		if ( isClosed() ) {
+			throw new SessionException( "Session was already closed" );
+		}
+		
+
+		if ( factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().closeSession();
+		}
+
+		try {
+			try {
+				if ( childSessionsByEntityMode != null ) {
+					Iterator childSessions = childSessionsByEntityMode.values().iterator();
+					while ( childSessions.hasNext() ) {
+						final SessionImpl child = ( SessionImpl ) childSessions.next();
+						child.close();
+					}
+				}
+			}
+			catch( Throwable t ) {
+				// just ignore
+			}
+
+			if ( rootSession == null ) {
+				return jdbcContext.getConnectionManager().close();
+			}
+			else {
+				return null;
+			}
+		}
+		finally {
+			setClosed();
+			cleanup();
+		}
+	}
+
+	public ConnectionReleaseMode getConnectionReleaseMode() {
+		checkTransactionSynchStatus();
+		return connectionReleaseMode;
+	}
+
+	public boolean isAutoCloseSessionEnabled() {
+		return autoCloseSessionEnabled;
+	}
+
+	public boolean isOpen() {
+		checkTransactionSynchStatus();
+		return !isClosed();
+	}
+
+	public boolean isFlushModeNever() {
+		return FlushMode.isManualFlushMode( getFlushMode() );
+	}
+
+	public boolean isFlushBeforeCompletionEnabled() {
+		return flushBeforeCompletionEnabled;
+	}
+
+	public void managedFlush() {
+		if ( isClosed() ) {
+			log.trace( "skipping auto-flush due to session closed" );
+			return;
+		}
+		log.trace("automatically flushing session");
+		flush();
+		
+		if ( childSessionsByEntityMode != null ) {
+			Iterator iter = childSessionsByEntityMode.values().iterator();
+			while ( iter.hasNext() ) {
+				( (Session) iter.next() ).flush();
+			}
+		}
+	}
+
+	public boolean shouldAutoClose() {
+		return isAutoCloseSessionEnabled() && !isClosed();
+	}
+
+	public void managedClose() {
+		log.trace( "automatically closing session" );
+		close();
+	}
+
+	public Connection connection() throws HibernateException {
+		errorIfClosed();
+		return jdbcContext.borrowConnection();
+	}
+
+	public boolean isConnected() {
+		checkTransactionSynchStatus();
+		return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected();
+	}
+	
+	public boolean isTransactionInProgress() {
+		checkTransactionSynchStatus();
+		return !isClosed() && jdbcContext.isTransactionInProgress();
+	}
+
+	public Connection disconnect() throws HibernateException {
+		errorIfClosed();
+		log.debug( "disconnecting session" );
+		return jdbcContext.getConnectionManager().manualDisconnect();
+	}
+
+	public void reconnect() throws HibernateException {
+		errorIfClosed();
+		log.debug( "reconnecting session" );
+		checkTransactionSynchStatus();
+		jdbcContext.getConnectionManager().manualReconnect();
+	}
+
+	public void reconnect(Connection conn) throws HibernateException {
+		errorIfClosed();
+		log.debug( "reconnecting session" );
+		checkTransactionSynchStatus();
+		jdbcContext.getConnectionManager().manualReconnect( conn );
+	}
+
+	public void beforeTransactionCompletion(Transaction tx) {
+		log.trace( "before transaction completion" );
+		if ( rootSession == null ) {
+			try {
+				interceptor.beforeTransactionCompletion(tx);
+			}
+			catch (Throwable t) {
+				log.error("exception in interceptor beforeTransactionCompletion()", t);
+			}
+		}
+	}
+	
+	public void setAutoClear(boolean enabled) {
+		errorIfClosed();
+		autoClear = enabled;
+	}
+	
+	/**
+	 * Check if there is a Hibernate or JTA transaction in progress and, 
+	 * if there is not, flush if necessary, make sure the connection has 
+	 * been committed (if it is not in autocommit mode) and run the after 
+	 * completion processing
+	 */
+	public void afterOperation(boolean success) {
+		if ( !jdbcContext.isTransactionInProgress() ) {
+			jdbcContext.afterNontransactionalQuery( success );
+		}
+	}
+
+	public void afterTransactionCompletion(boolean success, Transaction tx) {
+		log.trace( "after transaction completion" );
+		persistenceContext.afterTransactionCompletion();
+		actionQueue.afterTransactionCompletion(success);
+		if ( rootSession == null && tx != null ) {
+			try {
+				interceptor.afterTransactionCompletion(tx);
+			}
+			catch (Throwable t) {
+				log.error("exception in interceptor afterTransactionCompletion()", t);
+			}
+		}
+		if ( autoClear ) {
+			clear();
+		}
+	}
+
+	/**
+	 * clear all the internal collections, just 
+	 * to help the garbage collector, does not
+	 * clear anything that is needed during the
+	 * afterTransactionCompletion() phase
+	 */
+	private void cleanup() {
+		persistenceContext.clear();
+	}
+
+	public LockMode getCurrentLockMode(Object object) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( object == null ) {
+			throw new NullPointerException( "null object passed to getCurrentLockMode()" );
+		}
+		if ( object instanceof HibernateProxy ) {
+			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this);
+			if ( object == null ) {
+				return LockMode.NONE;
+			}
+		}
+		EntityEntry e = persistenceContext.getEntry(object);
+		if ( e == null ) {
+			throw new TransientObjectException( "Given object not associated with the session" );
+		}
+		if ( e.getStatus() != Status.MANAGED ) {
+			throw new ObjectDeletedException( 
+					"The given object was deleted", 
+					e.getId(), 
+					e.getPersister().getEntityName() 
+				);
+		}
+		return e.getLockMode();
+	}
+
+	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
+		errorIfClosed();
+		// todo : should this get moved to PersistentContext?
+		// logically, is PersistentContext the "thing" to which an interceptor gets attached?
+		final Object result = persistenceContext.getEntity(key);
+		if ( result == null ) {
+			final Object newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );
+			if ( newObject != null ) {
+				lock( newObject, LockMode.NONE );
+			}
+			return newObject;
+		}
+		else {
+			return result;
+		}
+	}
+
+
+	// saveOrUpdate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void saveOrUpdate(Object object) throws HibernateException {
+		saveOrUpdate(null, object);
+	}
+
+	public void saveOrUpdate(String entityName, Object obj) throws HibernateException {
+		fireSaveOrUpdate( new SaveOrUpdateEvent(entityName, obj, this) );
+	}
+
+	private void fireSaveOrUpdate(SaveOrUpdateEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners.getSaveOrUpdateEventListeners();
+		for ( int i = 0; i < saveOrUpdateEventListener.length; i++ ) {
+			saveOrUpdateEventListener[i].onSaveOrUpdate(event);
+		}
+	}
+
+
+	// save() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void save(Object obj, Serializable id) throws HibernateException {
+		save(null, obj, id);
+	}
+
+	public Serializable save(Object obj) throws HibernateException {
+		return save(null, obj);
+	}
+
+	public Serializable save(String entityName, Object object) throws HibernateException {
+		return fireSave( new SaveOrUpdateEvent(entityName, object, this) );
+	}
+
+	public void save(String entityName, Object object, Serializable id) throws HibernateException {
+		fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
+	}
+
+	private Serializable fireSave(SaveOrUpdateEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
+		for ( int i = 0; i < saveEventListener.length; i++ ) {
+			saveEventListener[i].onSaveOrUpdate(event);
+		}
+		return event.getResultId();
+	}
+
+
+	// update() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void update(Object obj) throws HibernateException {
+		update(null, obj);
+	}
+
+	public void update(Object obj, Serializable id) throws HibernateException {
+		update(null, obj, id);
+	}
+
+	public void update(String entityName, Object object) throws HibernateException {
+		fireUpdate( new SaveOrUpdateEvent(entityName, object, this) );
+	}
+
+	public void update(String entityName, Object object, Serializable id) throws HibernateException {
+		fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this));
+	}
+
+	private void fireUpdate(SaveOrUpdateEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		SaveOrUpdateEventListener[] updateEventListener = listeners.getUpdateEventListeners();
+		for ( int i = 0; i < updateEventListener.length; i++ ) {
+			updateEventListener[i].onSaveOrUpdate(event);
+		}
+	}
+
+
+	// lock() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void lock(String entityName, Object object, LockMode lockMode) throws HibernateException {
+		fireLock( new LockEvent(entityName, object, lockMode, this) );
+	}
+
+	public void lock(Object object, LockMode lockMode) throws HibernateException {
+		fireLock( new LockEvent(object, lockMode, this) );
+	}
+
+	private void fireLock(LockEvent lockEvent) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		LockEventListener[] lockEventListener = listeners.getLockEventListeners();
+		for ( int i = 0; i < lockEventListener.length; i++ ) {
+			lockEventListener[i].onLock( lockEvent );
+		}
+	}
+
+
+	// persist() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void persist(String entityName, Object object) throws HibernateException {
+		firePersist( new PersistEvent(entityName, object, this) );
+	}
+
+	public void persist(Object object) throws HibernateException {
+		persist(null, object);
+	}
+
+	public void persist(String entityName, Object object, Map copiedAlready)
+	throws HibernateException {
+		firePersist( copiedAlready, new PersistEvent(entityName, object, this) );
+	}
+
+	private void firePersist(Map copiedAlready, PersistEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		PersistEventListener[] persistEventListener = listeners.getPersistEventListeners();
+		for ( int i = 0; i < persistEventListener.length; i++ ) {
+			persistEventListener[i].onPersist(event, copiedAlready);
+		}
+	}
+
+	private void firePersist(PersistEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		PersistEventListener[] createEventListener = listeners.getPersistEventListeners();
+		for ( int i = 0; i < createEventListener.length; i++ ) {
+			createEventListener[i].onPersist(event);
+		}
+	}
+
+
+	// persistOnFlush() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void persistOnFlush(String entityName, Object object)
+			throws HibernateException {
+		firePersistOnFlush( new PersistEvent(entityName, object, this) );
+	}
+
+	public void persistOnFlush(Object object) throws HibernateException {
+		persist(null, object);
+	}
+
+	public void persistOnFlush(String entityName, Object object, Map copiedAlready)
+			throws HibernateException {
+		firePersistOnFlush( copiedAlready, new PersistEvent(entityName, object, this) );
+	}
+
+	private void firePersistOnFlush(Map copiedAlready, PersistEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		PersistEventListener[] persistEventListener = listeners.getPersistOnFlushEventListeners();
+		for ( int i = 0; i < persistEventListener.length; i++ ) {
+			persistEventListener[i].onPersist(event, copiedAlready);
+		}
+	}
+
+	private void firePersistOnFlush(PersistEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		PersistEventListener[] createEventListener = listeners.getPersistOnFlushEventListeners();
+		for ( int i = 0; i < createEventListener.length; i++ ) {
+			createEventListener[i].onPersist(event);
+		}
+	}
+
+
+	// merge() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Object merge(String entityName, Object object) throws HibernateException {
+		return fireMerge( new MergeEvent(entityName, object, this) );
+	}
+
+	public Object merge(Object object) throws HibernateException {
+		return merge(null, object);
+	}
+
+	public void merge(String entityName, Object object, Map copiedAlready) throws HibernateException {
+		fireMerge( copiedAlready, new MergeEvent(entityName, object, this) );
+	}
+
+	private Object fireMerge(MergeEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
+		for ( int i = 0; i < mergeEventListener.length; i++ ) {
+			mergeEventListener[i].onMerge(event);
+		}
+		return event.getResult();
+	}
+
+	private void fireMerge(Map copiedAlready, MergeEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
+		for ( int i = 0; i < mergeEventListener.length; i++ ) {
+			mergeEventListener[i].onMerge(event, copiedAlready);
+		}
+	}
+
+
+	// saveOrUpdateCopy() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Object saveOrUpdateCopy(String entityName, Object object)
+			throws HibernateException {
+		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, this) );
+	}
+
+	public Object saveOrUpdateCopy(Object object) throws HibernateException {
+		return saveOrUpdateCopy( null, object );
+	}
+
+	public Object saveOrUpdateCopy(String entityName, Object object, Serializable id)
+			throws HibernateException {
+		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, id, this) );
+	}
+
+	public Object saveOrUpdateCopy(Object object, Serializable id)
+			throws HibernateException {
+		return saveOrUpdateCopy( null, object, id );
+	}
+
+	public void saveOrUpdateCopy(String entityName, Object object, Map copiedAlready)
+			throws HibernateException {
+		fireSaveOrUpdateCopy( copiedAlready, new MergeEvent( entityName, object, this ) );
+	}
+
+	private void fireSaveOrUpdateCopy(Map copiedAlready, MergeEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
+		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
+			saveOrUpdateCopyEventListener[i].onMerge(event, copiedAlready);
+		}
+	}
+
+	private Object fireSaveOrUpdateCopy(MergeEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
+		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
+			saveOrUpdateCopyEventListener[i].onMerge(event);
+		}
+		return event.getResult();
+	}
+
+
+	// delete() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Delete a persistent object
+	 */
+	public void delete(Object object) throws HibernateException {
+		fireDelete( new DeleteEvent(object, this) );
+	}
+
+	/**
+	 * Delete a persistent object (by explicit entity name)
+	 */
+	public void delete(String entityName, Object object) throws HibernateException {
+		fireDelete( new DeleteEvent( entityName, object, this ) );
+	}
+
+	/**
+	 * Delete a persistent object
+	 */
+	public void delete(String entityName, Object object, boolean isCascadeDeleteEnabled, Set transientEntities) throws HibernateException {
+		fireDelete( new DeleteEvent( entityName, object, isCascadeDeleteEnabled, this ), transientEntities );
+	}
+
+	private void fireDelete(DeleteEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
+		for ( int i = 0; i < deleteEventListener.length; i++ ) {
+			deleteEventListener[i].onDelete( event );
+		}
+	}
+
+	private void fireDelete(DeleteEvent event, Set transientEntities) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
+		for ( int i = 0; i < deleteEventListener.length; i++ ) {
+			deleteEventListener[i].onDelete( event, transientEntities );
+		}
+	}
+
+
+	// load()/get() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void load(Object object, Serializable id) throws HibernateException {
+		LoadEvent event = new LoadEvent(id, object, this);
+		fireLoad( event, LoadEventListener.RELOAD );
+	}
+
+	public Object load(Class entityClass, Serializable id) throws HibernateException {
+		return load( entityClass.getName(), id );
+	}
+
+	public Object load(String entityName, Serializable id) throws HibernateException {
+		LoadEvent event = new LoadEvent(id, entityName, false, this);
+		boolean success = false;
+		try {
+			fireLoad( event, LoadEventListener.LOAD );
+			if ( event.getResult() == null ) {
+				getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
+			}
+			success = true;
+			return event.getResult();
+		}
+		finally {
+			afterOperation(success);
+		}
+	}
+
+	public Object get(Class entityClass, Serializable id) throws HibernateException {
+		return get( entityClass.getName(), id );
+	}
+
+	public Object get(String entityName, Serializable id) throws HibernateException {
+		LoadEvent event = new LoadEvent(id, entityName, false, this);
+		boolean success = false;
+		try {
+			fireLoad(event, LoadEventListener.GET);
+			success = true;
+			return event.getResult();
+		}
+		finally {
+			afterOperation(success);
+		}
+	}
+
+	/**
+	 * Load the data for the object with the specified id into a newly created object.
+	 * This is only called when lazily initializing a proxy.
+	 * Do NOT return a proxy.
+	 */
+	public Object immediateLoad(String entityName, Serializable id) throws HibernateException {
+		if ( log.isDebugEnabled() ) {
+			EntityPersister persister = getFactory().getEntityPersister(entityName);
+			log.debug( "initializing proxy: " + MessageHelper.infoString( persister, id, getFactory() ) );
+		}
+		
+		LoadEvent event = new LoadEvent(id, entityName, true, this);
+		fireLoad(event, LoadEventListener.IMMEDIATE_LOAD);
+		return event.getResult();
+	}
+
+	public Object internalLoad(String entityName, Serializable id, boolean eager, boolean nullable) throws HibernateException {
+		// todo : remove
+		LoadEventListener.LoadType type = nullable ? 
+				LoadEventListener.INTERNAL_LOAD_NULLABLE : 
+				eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY;
+		LoadEvent event = new LoadEvent(id, entityName, true, this);
+		fireLoad(event, type);
+		if ( !nullable ) {
+			UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName );
+		}
+		return event.getResult();
+	}
+
+	public Object load(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
+		return load( entityClass.getName(), id, lockMode );
+	}
+
+	public Object load(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
+		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
+		fireLoad( event, LoadEventListener.LOAD );
+		return event.getResult();
+	}
+
+	public Object get(Class entityClass, Serializable id, LockMode lockMode) throws HibernateException {
+		return get( entityClass.getName(), id, lockMode );
+	}
+
+	public Object get(String entityName, Serializable id, LockMode lockMode) throws HibernateException {
+		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
+	   	fireLoad(event, LoadEventListener.GET);
+		return event.getResult();
+	}
+
+	private void fireLoad(LoadEvent event, LoadType loadType) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
+		for ( int i = 0; i < loadEventListener.length; i++ ) {
+			loadEventListener[i].onLoad(event, loadType);
+		}
+	}
+
+
+	// refresh() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void refresh(Object object) throws HibernateException {
+		fireRefresh( new RefreshEvent(object, this) );
+	}
+
+	public void refresh(Object object, LockMode lockMode) throws HibernateException {
+		fireRefresh( new RefreshEvent(object, lockMode, this) );
+	}
+
+	public void refresh(Object object, Map refreshedAlready) throws HibernateException {
+		fireRefresh( refreshedAlready, new RefreshEvent(object, this) );
+	}
+
+	private void fireRefresh(RefreshEvent refreshEvent) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
+		for ( int i = 0; i < refreshEventListener.length; i++ ) {
+			refreshEventListener[i].onRefresh( refreshEvent );
+		}
+	}
+
+	private void fireRefresh(Map refreshedAlready, RefreshEvent refreshEvent) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
+		for ( int i = 0; i < refreshEventListener.length; i++ ) {
+			refreshEventListener[i].onRefresh( refreshEvent, refreshedAlready );
+		}
+	}
+
+
+	// replicate() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void replicate(Object obj, ReplicationMode replicationMode) throws HibernateException {
+		fireReplicate( new ReplicateEvent(obj, replicationMode, this) );
+	}
+
+	public void replicate(String entityName, Object obj, ReplicationMode replicationMode)
+	throws HibernateException {
+		fireReplicate( new ReplicateEvent(entityName, obj, replicationMode, this) );
+	}
+
+	private void fireReplicate(ReplicateEvent event) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		ReplicateEventListener[] replicateEventListener = listeners.getReplicateEventListeners();
+		for ( int i = 0; i < replicateEventListener.length; i++ ) {
+			replicateEventListener[i].onReplicate(event);
+		}
+	}
+
+
+	// evict() operations ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * remove any hard references to the entity that are held by the infrastructure
+	 * (references held by application or other persistant instances are okay)
+	 */
+	public void evict(Object object) throws HibernateException {
+		fireEvict( new EvictEvent(object, this) );
+	}
+
+	private void fireEvict(EvictEvent evictEvent) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		EvictEventListener[] evictEventListener = listeners.getEvictEventListeners();
+		for ( int i = 0; i < evictEventListener.length; i++ ) {
+			evictEventListener[i].onEvict( evictEvent );
+		}
+	}
+
+	/**
+	 * detect in-memory changes, determine if the changes are to tables
+	 * named in the query and, if so, complete execution the flush
+	 */
+	protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
+		errorIfClosed();
+		if ( ! isTransactionInProgress() ) {
+			// do not auto-flush while outside a transaction
+			return false;
+		}
+		AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
+		AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
+		for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
+			autoFlushEventListener[i].onAutoFlush(event);
+		}
+		return event.isFlushRequired();
+	}
+
+	public boolean isDirty() throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		log.debug("checking session dirtiness");
+		if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
+			log.debug("session dirty (scheduled updates and insertions)");
+			return true;
+		}
+		else {
+			DirtyCheckEvent event = new DirtyCheckEvent(this);
+			DirtyCheckEventListener[] dirtyCheckEventListener = listeners.getDirtyCheckEventListeners();
+			for ( int i = 0; i < dirtyCheckEventListener.length; i++ ) {
+				dirtyCheckEventListener[i].onDirtyCheck(event);
+			}
+			return event.isDirty();
+		}
+	}
+
+	public void flush() throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( persistenceContext.getCascadeLevel() > 0 ) {
+			throw new HibernateException("Flush during cascade is dangerous");
+		}
+		FlushEventListener[] flushEventListener = listeners.getFlushEventListeners();
+		for ( int i = 0; i < flushEventListener.length; i++ ) {
+			flushEventListener[i].onFlush( new FlushEvent(this) );
+		}
+	}
+
+	public void forceFlush(EntityEntry entityEntry) throws HibernateException {
+		errorIfClosed();
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+				"flushing to force deletion of re-saved object: " +
+				MessageHelper.infoString( entityEntry.getPersister(), entityEntry.getId(), getFactory() )
+			);
+		}
+
+		if ( persistenceContext.getCascadeLevel() > 0 ) {
+			throw new ObjectDeletedException(
+				"deleted object would be re-saved by cascade (remove deleted object from associations)",
+				entityEntry.getId(),
+				entityEntry.getPersister().getEntityName()
+			);
+		}
+
+		flush();
+	}
+
+	public Filter getEnabledFilter(String filterName) {
+		checkTransactionSynchStatus();
+		return (Filter) enabledFilters.get(filterName);
+	}
+
+	public Filter enableFilter(String filterName) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		FilterImpl filter = new FilterImpl( factory.getFilterDefinition(filterName) );
+		enabledFilters.put(filterName, filter);
+		return filter;
+	}
+
+	public void disableFilter(String filterName) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		enabledFilters.remove(filterName);
+	}
+
+	public Object getFilterParameterValue(String filterParameterName) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		String[] parsed = parseFilterParameterName(filterParameterName);
+		FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] );
+		if (filter == null) {
+			throw new IllegalArgumentException("Filter [" + parsed[0] + "] currently not enabled");
+		}
+		return filter.getParameter( parsed[1] );
+	}
+
+	public Type getFilterParameterType(String filterParameterName) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		String[] parsed = parseFilterParameterName(filterParameterName);
+		FilterDefinition filterDef = factory.getFilterDefinition( parsed[0] );
+		if (filterDef == null) {
+			throw new IllegalArgumentException("Filter [" + parsed[0] + "] not defined");
+		}
+		Type type = filterDef.getParameterType( parsed[1] );
+		if (type == null) {
+			// this is an internal error of some sort...
+			throw new InternalError("Unable to locate type for filter parameter");
+		}
+		return type;
+	}
+
+	public Map getEnabledFilters() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		// First, validate all the enabled filters...
+		//TODO: this implementation has bad performance
+		Iterator itr = enabledFilters.values().iterator();
+		while ( itr.hasNext() ) {
+			final Filter filter = (Filter) itr.next();
+			filter.validate();
+		}
+		return enabledFilters;
+	}
+
+	private String[] parseFilterParameterName(String filterParameterName) {
+		int dot = filterParameterName.indexOf('.');
+		if (dot <= 0) {
+			throw new IllegalArgumentException("Invalid filter-parameter name format"); // TODO: what type?
+		}
+		String filterName = filterParameterName.substring(0, dot);
+		String parameterName = filterParameterName.substring(dot+1);
+		return new String[] {filterName, parameterName};
+	}
+
+
+	/**
+	 * Retrieve a list of persistent objects using a hibernate query
+	 */
+	public List find(String query) throws HibernateException {
+		return list( query, new QueryParameters() );
+	}
+
+	public List find(String query, Object value, Type type) throws HibernateException {
+		return list( query, new QueryParameters(type, value) );
+	}
+
+	public List find(String query, Object[] values, Type[] types) throws HibernateException {
+		return list( query, new QueryParameters(types, values) );
+	}
+
+	public List list(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		queryParameters.validateParameters();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		autoFlushIfRequired( plan.getQuerySpaces() );
+
+		List results = CollectionHelper.EMPTY_LIST;
+		boolean success = false;
+
+		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
+		try {
+			results = plan.performList( queryParameters, this );
+			success = true;
+		}
+		finally {
+			dontFlushFromFind--;
+			afterOperation(success);
+		}
+		return results;
+	}
+
+	public int executeUpdate(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		queryParameters.validateParameters();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		autoFlushIfRequired( plan.getQuerySpaces() );
+
+		boolean success = false;
+		int result = 0;
+		try {
+			result = plan.performExecuteUpdate( queryParameters, this );
+			success = true;
+		}
+		finally {
+			afterOperation(success);
+		}
+		return result;
+	}
+
+    public int executeNativeUpdate(NativeSQLQuerySpecification nativeQuerySpecification,
+            QueryParameters queryParameters) throws HibernateException {
+        errorIfClosed();
+        checkTransactionSynchStatus();
+        queryParameters.validateParameters();
+        NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);
+
+        
+        autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() );
+        
+        boolean success = false;
+        int result = 0;
+        try {
+            result = plan.performExecuteUpdate(queryParameters, this);
+            success = true;
+        } finally {
+            afterOperation(success);
+        }
+        return result;
+    }
+
+	public Iterator iterate(String query) throws HibernateException {
+		return iterate( query, new QueryParameters() );
+	}
+
+	public Iterator iterate(String query, Object value, Type type) throws HibernateException {
+		return iterate( query, new QueryParameters(type, value) );
+	}
+
+	public Iterator iterate(String query, Object[] values, Type[] types) throws HibernateException {
+		return iterate( query, new QueryParameters(types, values) );
+	}
+
+	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		queryParameters.validateParameters();
+		HQLQueryPlan plan = getHQLQueryPlan( query, true );
+		autoFlushIfRequired( plan.getQuerySpaces() );
+
+		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
+		try {
+			return plan.performIterate( queryParameters, this );
+		}
+		finally {
+			dontFlushFromFind--;
+		}
+	}
+
+	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		autoFlushIfRequired( plan.getQuerySpaces() );
+		dontFlushFromFind++;
+		try {
+			return plan.performScroll( queryParameters, this );
+		}
+		finally {
+			dontFlushFromFind--;
+		}
+	}
+
+	public int delete(String query) throws HibernateException {
+		return delete( query, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY );
+	}
+
+	public int delete(String query, Object value, Type type) throws HibernateException {
+		return delete( query, new Object[]{value}, new Type[]{type} );
+	}
+
+	public int delete(String query, Object[] values, Type[] types) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( query == null ) {
+			throw new IllegalArgumentException("attempt to perform delete-by-query with null query");
+		}
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "delete: " + query );
+			if ( values.length != 0 ) {
+				log.trace( "parameters: " + StringHelper.toString( values ) );
+			}
+		}
+
+		List list = find( query, values, types );
+		int deletionCount = list.size();
+		for ( int i = 0; i < deletionCount; i++ ) {
+			delete( list.get( i ) );
+		}
+
+		return deletionCount;
+	}
+
+	public Query createFilter(Object collection, String queryString) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		CollectionFilterImpl filter = new CollectionFilterImpl(
+				queryString,
+		        collection,
+		        this,
+		        getFilterQueryPlan( collection, queryString, null, false ).getParameterMetadata()
+		);
+		filter.setComment( queryString );
+		return filter;
+	}
+	
+	public Query getNamedQuery(String queryName) throws MappingException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return super.getNamedQuery(queryName);
+	}
+
+	public Object instantiate(String entityName, Serializable id) throws HibernateException {
+		return instantiate( factory.getEntityPersister(entityName), id );
+	}
+
+	/**
+	 * give the interceptor an opportunity to override the default instantiation
+	 */
+	public Object instantiate(EntityPersister persister, Serializable id) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		Object result = interceptor.instantiate( persister.getEntityName(), entityMode, id );
+		if ( result == null ) {
+			result = persister.instantiate( id, entityMode );
+		}
+		return result;
+	}
+
+	public EntityMode getEntityMode() {
+		checkTransactionSynchStatus();
+		return entityMode;
+	}
+
+	public void setFlushMode(FlushMode flushMode) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( log.isTraceEnabled() ) {
+			log.trace("setting flush mode to: " + flushMode);
+		}
+		this.flushMode = flushMode;
+	}
+	
+	public FlushMode getFlushMode() {
+		checkTransactionSynchStatus();
+		return flushMode;
+	}
+
+	public CacheMode getCacheMode() {
+		checkTransactionSynchStatus();
+		return cacheMode;
+	}
+	
+	public void setCacheMode(CacheMode cacheMode) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( log.isTraceEnabled() ) {
+			log.trace("setting cache mode to: " + cacheMode);
+		}
+		this.cacheMode= cacheMode; 
+	}
+
+	public Transaction getTransaction() throws HibernateException {
+		errorIfClosed();
+		return jdbcContext.getTransaction();
+	}
+	
+	public Transaction beginTransaction() throws HibernateException {
+		errorIfClosed();
+		if ( rootSession != null ) {
+			// todo : should seriously consider not allowing a txn to begin from a child session
+			//      can always route the request to the root session...
+			log.warn( "Transaction started on non-root session" );
+		}
+		Transaction result = getTransaction();
+		result.begin();
+		return result;
+	}
+	
+	public void afterTransactionBegin(Transaction tx) {
+		errorIfClosed();
+		interceptor.afterTransactionBegin(tx);
+	}
+
+	public EntityPersister getEntityPersister(final String entityName, final Object object) {
+		errorIfClosed();
+		if (entityName==null) {
+			return factory.getEntityPersister( guessEntityName( object ) );
+		}
+		else {
+			// try block is a hack around fact that currently tuplizers are not
+			// given the opportunity to resolve a subclass entity name.  this
+			// allows the (we assume custom) interceptor the ability to
+			// influence this decision if we were not able to based on the
+			// given entityName
+			try {
+				return factory.getEntityPersister( entityName )
+						.getSubclassEntityPersister( object, getFactory(), entityMode );
+			}
+			catch( HibernateException e ) {
+				try {
+					return getEntityPersister( null, object );
+				}
+				catch( HibernateException e2 ) {
+					throw e;
+				}
+			}
+		}
+	}
+
+	// not for internal use:
+	public Serializable getIdentifier(Object object) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( object instanceof HibernateProxy ) {
+			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
+			if ( li.getSession() != this ) {
+				throw new TransientObjectException( "The proxy was not associated with this session" );
+			}
+			return li.getIdentifier();
+		}
+		else {
+			EntityEntry entry = persistenceContext.getEntry(object);
+			if ( entry == null ) {
+				throw new TransientObjectException( "The instance was not associated with this session" );
+			}
+			return entry.getId();
+		}
+	}
+
+	/**
+	 * Get the id value for an object that is actually associated with the session. This
+	 * is a bit stricter than getEntityIdentifierIfNotUnsaved().
+	 */
+	public Serializable getContextEntityIdentifier(Object object) {
+		errorIfClosed();
+		if ( object instanceof HibernateProxy ) {
+			return getProxyIdentifier(object);
+		}
+		else {
+			EntityEntry entry = persistenceContext.getEntry(object);
+			return entry != null ? entry.getId() : null;
+		}
+	}
+	
+	private Serializable getProxyIdentifier(Object proxy) {
+		return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
+	}
+
+	public Collection filter(Object collection, String filter) throws HibernateException {
+		return listFilter( collection, filter, new QueryParameters( new Type[1], new Object[1] ) );
+	}
+
+	public Collection filter(Object collection, String filter, Object value, Type type) throws HibernateException {
+		return listFilter( collection, filter, new QueryParameters( new Type[]{null, type}, new Object[]{null, value} ) );
+	}
+
+	public Collection filter(Object collection, String filter, Object[] values, Type[] types) 
+	throws HibernateException {
+		Object[] vals = new Object[values.length + 1];
+		Type[] typs = new Type[types.length + 1];
+		System.arraycopy( values, 0, vals, 1, values.length );
+		System.arraycopy( types, 0, typs, 1, types.length );
+		return listFilter( collection, filter, new QueryParameters( typs, vals ) );
+	}
+
+	private FilterQueryPlan getFilterQueryPlan(
+			Object collection,
+			String filter,
+			QueryParameters parameters,
+			boolean shallow) throws HibernateException {
+		if ( collection == null ) {
+			throw new NullPointerException( "null collection passed to filter" );
+		}
+
+		CollectionEntry entry = persistenceContext.getCollectionEntryOrNull( collection );
+		final CollectionPersister roleBeforeFlush = (entry == null) ? null : entry.getLoadedPersister();
+
+		FilterQueryPlan plan = null;
+		if ( roleBeforeFlush == null ) {
+			// if it was previously unreferenced, we need to flush in order to
+			// get its state into the database in order to execute query
+			flush();
+			entry = persistenceContext.getCollectionEntryOrNull( collection );
+			CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
+			if ( roleAfterFlush == null ) {
+				throw new QueryException( "The collection was unreferenced" );
+			}
+			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
+		}
+		else {
+			// otherwise, we only need to flush if there are in-memory changes
+			// to the queried tables
+			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleBeforeFlush.getRole(), shallow, getEnabledFilters() );
+			if ( autoFlushIfRequired( plan.getQuerySpaces() ) ) {
+				// might need to run a different filter entirely after the flush
+				// because the collection role may have changed
+				entry = persistenceContext.getCollectionEntryOrNull( collection );
+				CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
+				if ( roleBeforeFlush != roleAfterFlush ) {
+					if ( roleAfterFlush == null ) {
+						throw new QueryException( "The collection was dereferenced" );
+					}
+					plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
+				}
+			}
+		}
+
+		if ( parameters != null ) {
+			parameters.getPositionalParameterValues()[0] = entry.getLoadedKey();
+			parameters.getPositionalParameterTypes()[0] = entry.getLoadedPersister().getKeyType();
+		}
+
+		return plan;
+	}
+
+	public List listFilter(Object collection, String filter, QueryParameters queryParameters) 
+	throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, false );
+		List results = CollectionHelper.EMPTY_LIST;
+
+		boolean success = false;
+		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
+		try {
+			results = plan.performList( queryParameters, this );
+			success = true;
+		}
+		finally {
+			dontFlushFromFind--;
+			afterOperation(success);
+		}
+		return results;
+	}
+
+	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters) 
+	throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, true );
+		return plan.performIterate( queryParameters, this );
+	}
+
+	public Criteria createCriteria(Class persistentClass, String alias) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new CriteriaImpl( persistentClass.getName(), alias, this );
+	}
+
+	public Criteria createCriteria(String entityName, String alias) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new CriteriaImpl(entityName, alias, this);
+	}
+
+	public Criteria createCriteria(Class persistentClass) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new CriteriaImpl( persistentClass.getName(), this );
+	}
+
+	public Criteria createCriteria(String entityName) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new CriteriaImpl(entityName, this);
+	}
+
+	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		String entityName = criteria.getEntityOrClassName();
+		CriteriaLoader loader = new CriteriaLoader(
+				getOuterJoinLoadable(entityName),
+				factory,
+				criteria,
+				entityName,
+				getEnabledFilters()
+		);
+		autoFlushIfRequired( loader.getQuerySpaces() );
+		dontFlushFromFind++;
+		try {
+			return loader.scroll(this, scrollMode);
+		}
+		finally {
+			dontFlushFromFind--;
+		}
+	}
+
+	public List list(CriteriaImpl criteria) throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
+		int size = implementors.length;
+
+		CriteriaLoader[] loaders = new CriteriaLoader[size];
+		Set spaces = new HashSet();
+		for( int i=0; i <size; i++ ) {
+
+			loaders[i] = new CriteriaLoader(
+					getOuterJoinLoadable( implementors[i] ),
+					factory,
+					criteria,
+					implementors[i],
+					getEnabledFilters()
+				);
+
+			spaces.addAll( loaders[i].getQuerySpaces() );
+
+		}
+
+		autoFlushIfRequired(spaces);
+
+		List results = Collections.EMPTY_LIST;
+		dontFlushFromFind++;
+		boolean success = false;
+		try {
+			for( int i=0; i<size; i++ ) {
+				final List currentResults = loaders[i].list(this);
+				currentResults.addAll(results);
+				results = currentResults;
+			}
+			success = true;
+		}
+		finally {
+			dontFlushFromFind--;
+			afterOperation(success);
+		}
+
+		return results;
+	}
+
+	private OuterJoinLoadable getOuterJoinLoadable(String entityName) throws MappingException {
+		EntityPersister persister = factory.getEntityPersister(entityName);
+		if ( !(persister instanceof OuterJoinLoadable) ) {
+			throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
+		}
+		return ( OuterJoinLoadable ) persister;
+	}
+
+	public boolean contains(Object object) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if ( object instanceof HibernateProxy ) {
+			//do not use proxiesByKey, since not all
+			//proxies that point to this session's
+			//instances are in that collection!
+			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
+			if ( li.isUninitialized() ) {
+				//if it is an uninitialized proxy, pointing
+				//with this session, then when it is accessed,
+				//the underlying instance will be "contained"
+				return li.getSession()==this;
+			}
+			else {
+				//if it is initialized, see if the underlying
+				//instance is contained, since we need to 
+				//account for the fact that it might have been
+				//evicted
+				object = li.getImplementation();
+			}
+		}
+		// A session is considered to contain an entity only if the entity has
+		// an entry in the session's persistence context and the entry reports
+		// that the entity has not been removed
+		EntityEntry entry = persistenceContext.getEntry( object );
+		return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE;
+	}
+	
+	public Query createQuery(String queryString) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return super.createQuery(queryString);
+	}
+	
+	public SQLQuery createSQLQuery(String sql) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return super.createSQLQuery(sql);
+	}
+
+	public Query createSQLQuery(String sql, String returnAlias, Class returnClass) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new SQLQueryImpl(
+				sql,
+		        new String[] { returnAlias },
+		        new Class[] { returnClass },
+		        this,
+		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
+		);
+	}
+
+	public Query createSQLQuery(String sql, String returnAliases[], Class returnClasses[]) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return new SQLQueryImpl(
+				sql,
+		        returnAliases,
+		        returnClasses,
+		        this,
+		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
+		);
+	}
+
+	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
+	throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "scroll SQL query: " + customQuery.getSQL() );
+		}
+
+		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
+
+		autoFlushIfRequired( loader.getQuerySpaces() );
+
+		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
+		try {
+			return loader.scroll(queryParameters, this);
+		}
+		finally {
+			dontFlushFromFind--;
+		}
+	}
+
+	// basically just an adapted copy of find(CriteriaImpl)
+	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters) 
+	throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "SQL query: " + customQuery.getSQL() );
+		}
+		
+		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
+
+		autoFlushIfRequired( loader.getQuerySpaces() );
+
+		dontFlushFromFind++;
+		boolean success = false;
+		try {
+			List results = loader.list(this, queryParameters);
+			success = true;
+			return results;
+		}
+		finally {
+			dontFlushFromFind--;
+			afterOperation(success);
+		}
+	}
+
+	public SessionFactory getSessionFactory() {
+		checkTransactionSynchStatus();
+		return factory;
+	}
+	
+	public void initializeCollection(PersistentCollection collection, boolean writing) 
+	throws HibernateException {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		InitializeCollectionEventListener[] listener = listeners.getInitializeCollectionEventListeners();
+		for ( int i = 0; i < listener.length; i++ ) {
+			listener[i].onInitializeCollection( new InitializeCollectionEvent(collection, this) );
+		}
+	}
+
+	public String bestGuessEntityName(Object object) {
+		if (object instanceof HibernateProxy) {
+			LazyInitializer initializer = ( ( HibernateProxy ) object ).getHibernateLazyInitializer();
+			// it is possible for this method to be called during flush processing,
+			// so make certain that we do not accidently initialize an uninitialized proxy
+			if ( initializer.isUninitialized() ) {
+				return initializer.getEntityName();
+			}
+			object = initializer.getImplementation();
+		}
+		EntityEntry entry = persistenceContext.getEntry(object);
+		if (entry==null) {
+			return guessEntityName(object);
+		}
+		else {
+			return entry.getPersister().getEntityName();
+		}
+	}
+	
+	public String getEntityName(Object object) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		if (object instanceof HibernateProxy) {
+			if ( !persistenceContext.containsProxy( object ) ) {
+				throw new TransientObjectException("proxy was not associated with the session");
+			}
+			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
+		}
+
+		EntityEntry entry = persistenceContext.getEntry(object);
+		if ( entry == null ) {
+			throwTransientObjectException( object );
+		}
+		return entry.getPersister().getEntityName();
+	}
+
+	private void throwTransientObjectException(Object object) throws HibernateException {
+		throw new TransientObjectException(
+				"object references an unsaved transient instance - save the transient instance before flushing: " +
+				guessEntityName(object)
+			);
+	}
+
+	public String guessEntityName(Object object) throws HibernateException {
+		errorIfClosed();
+		String entity = interceptor.getEntityName( object );
+		if ( entity == null ) {
+			if ( object instanceof Map ) {
+				entity = (String) ( (Map) object ).get( DynamicMapInstantiator.KEY );
+				if ( entity == null ) {
+					throw new HibernateException( "could not determine type of dynamic entity" );
+				}
+			}
+			else if ( object instanceof Element ) {
+				// TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
+				entity = ( (Element) object ).getName();
+			}
+			else {
+				entity = object.getClass().getName();
+			}
+		}
+		return entity;
+	}
+
+	public void cancelQuery() throws HibernateException {
+		errorIfClosed();
+		getBatcher().cancelLastQuery();
+	}
+
+	public Interceptor getInterceptor() {
+		checkTransactionSynchStatus();
+		return interceptor;
+	}
+
+	public int getDontFlushFromFind() {
+		return dontFlushFromFind;
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer(500)
+			.append( "SessionImpl(" );
+		if ( !isClosed() ) {
+			buf.append(persistenceContext)
+				.append(";")
+				.append(actionQueue);
+		}
+		else {
+			buf.append("<closed>");
+		}
+		return buf.append(')').toString();
+	}
+
+	public EventListeners getListeners() {
+		return listeners;
+	}
+
+	public ActionQueue getActionQueue() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return actionQueue;
+	}
+	
+	public PersistenceContext getPersistenceContext() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return persistenceContext;
+	}
+	
+	public SessionStatistics getStatistics() {
+		checkTransactionSynchStatus();
+		return new SessionStatisticsImpl(this);
+	}
+
+	public boolean isEventSource() {
+		checkTransactionSynchStatus();
+		return true;
+	}
+
+	public void setReadOnly(Object entity, boolean readOnly) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		persistenceContext.setReadOnly(entity, readOnly);
+	}
+
+	public void doWork(Work work) throws HibernateException {
+		try {
+			work.execute( jdbcContext.getConnectionManager().getConnection() );
+			jdbcContext.getConnectionManager().afterStatement();
+		}
+		catch ( SQLException e ) {
+			throw JDBCExceptionHelper.convert( factory.getSettings().getSQLExceptionConverter(), e, "error executing work" );
+		}
+	}
+
+	public void afterScrollOperation() {
+		// nothing to do in a stateful session
+	}
+
+	public String getFetchProfile() {
+		checkTransactionSynchStatus();
+		return fetchProfile;
+	}
+
+	public JDBCContext getJDBCContext() {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		return jdbcContext;
+	}
+
+	public void setFetchProfile(String fetchProfile) {
+		errorIfClosed();
+		checkTransactionSynchStatus();
+		this.fetchProfile = fetchProfile;
+	}
+
+	private void checkTransactionSynchStatus() {
+		if ( jdbcContext != null && !isClosed() ) {
+			jdbcContext.registerSynchronizationIfPossible();
+		}
+	}
+
+	/**
+	 * Used by JDK serialization...
+	 *
+	 * @param ois The input stream from which we are being read...
+	 * @throws IOException Indicates a general IO stream exception
+	 * @throws ClassNotFoundException Indicates a class resolution issue
+	 */
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		log.trace( "deserializing session" );
+
+		boolean isRootSession = ois.readBoolean();
+		connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
+		entityMode = EntityMode.parse( ( String ) ois.readObject() );
+		autoClear = ois.readBoolean();
+		flushMode = FlushMode.parse( ( String ) ois.readObject() );
+		cacheMode = CacheMode.parse( ( String ) ois.readObject() );
+		flushBeforeCompletionEnabled = ois.readBoolean();
+		autoCloseSessionEnabled = ois.readBoolean();
+		fetchProfile = ( String ) ois.readObject();
+		interceptor = ( Interceptor ) ois.readObject();
+
+		factory = SessionFactoryImpl.deserialize( ois );
+		listeners = factory.getEventListeners();
+
+		if ( isRootSession ) {
+			jdbcContext = JDBCContext.deserialize( ois, this, interceptor );
+		}
+
+		persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
+		actionQueue = ActionQueue.deserialize( ois, this );
+
+		enabledFilters = ( Map ) ois.readObject();
+		childSessionsByEntityMode = ( Map ) ois.readObject();
+
+		Iterator iter = enabledFilters.values().iterator();
+		while ( iter.hasNext() ) {
+			( ( FilterImpl ) iter.next() ).afterDeserialize(factory);
+		}
+
+		if ( isRootSession && childSessionsByEntityMode != null ) {
+			iter = childSessionsByEntityMode.values().iterator();
+			while ( iter.hasNext() ) {
+				final SessionImpl child = ( ( SessionImpl ) iter.next() );
+				child.rootSession = this;
+				child.jdbcContext = this.jdbcContext;
+			}
+		}
+	}
+
+	/**
+	 * Used by JDK serialization...
+	 *
+	 * @param oos The output stream to which we are being written...
+	 * @throws IOException Indicates a general IO stream exception
+	 */
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		if ( !jdbcContext.getConnectionManager().isReadyForSerialization() ) {
+			throw new IllegalStateException( "Cannot serialize a session while connected" );
+		}
+
+		log.trace( "serializing session" );
+
+		oos.writeBoolean( rootSession == null );
+		oos.writeObject( connectionReleaseMode.toString() );
+		oos.writeObject( entityMode.toString() );
+		oos.writeBoolean( autoClear );
+		oos.writeObject( flushMode.toString() );
+		oos.writeObject( cacheMode.toString() );
+		oos.writeBoolean( flushBeforeCompletionEnabled );
+		oos.writeBoolean( autoCloseSessionEnabled );
+		oos.writeObject( fetchProfile );
+		// we need to writeObject() on this since interceptor is user defined
+		oos.writeObject( interceptor );
+
+		factory.serialize( oos );
+
+		if ( rootSession == null ) {
+			jdbcContext.serialize( oos );
+		}
+
+		persistenceContext.serialize( oos );
+		actionQueue.serialize( oos );
+
+		// todo : look at optimizing these...
+		oos.writeObject( enabledFilters );
+		oos.writeObject( childSessionsByEntityMode );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,630 +0,0 @@
-//$Id: StatelessSessionImpl.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.impl;
-
-import java.io.Serializable;
-import java.sql.Connection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.CacheMode;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.Criteria;
-import org.hibernate.EmptyInterceptor;
-import org.hibernate.EntityMode;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.SessionException;
-import org.hibernate.StatelessSession;
-import org.hibernate.Transaction;
-import org.hibernate.UnresolvableObjectException;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.StatefulPersistenceContext;
-import org.hibernate.engine.Versioning;
-import org.hibernate.engine.query.HQLQueryPlan;
-import org.hibernate.engine.query.NativeSQLQueryPlan;
-import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
-import org.hibernate.event.EventListeners;
-import org.hibernate.id.IdentifierGeneratorFactory;
-import org.hibernate.jdbc.Batcher;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.loader.criteria.CriteriaLoader;
-import org.hibernate.loader.custom.CustomLoader;
-import org.hibernate.loader.custom.CustomQuery;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.type.Type;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * @author Gavin King
- */
-public class StatelessSessionImpl extends AbstractSessionImpl
-		implements JDBCContext.Context, StatelessSession {
-
-	private static final Logger log = LoggerFactory.getLogger( StatelessSessionImpl.class );
-
-	private JDBCContext jdbcContext;
-	private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this );
-
-	StatelessSessionImpl(Connection connection, SessionFactoryImpl factory) {
-		super( factory );
-		this.jdbcContext = new JDBCContext( this, connection, EmptyInterceptor.INSTANCE );
-	}
-
-
-	// inserts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Serializable insert(Object entity) {
-		errorIfClosed();
-		return insert(null, entity);
-	}
-
-	public Serializable insert(String entityName, Object entity) {
-		errorIfClosed();
-		EntityPersister persister = getEntityPersister(entityName, entity);
-		Serializable id = persister.getIdentifierGenerator().generate(this, entity);
-		Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
-		if ( persister.isVersioned() ) {
-			boolean substitute = Versioning.seedVersion(state, persister.getVersionProperty(), persister.getVersionType(), this);
-			if ( substitute ) {
-				persister.setPropertyValues( entity, state, EntityMode.POJO );
-			}
-		}
-		if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
-			id = persister.insert(state, entity, this);
-		}
-		else {
-			persister.insert(id, state, entity, this);
-		}
-		persister.setIdentifier(entity, id, EntityMode.POJO);
-		return id;
-	}
-
-
-	// deletes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void delete(Object entity) {
-		errorIfClosed();
-		delete(null, entity);
-	}
-
-	public void delete(String entityName, Object entity) {
-		errorIfClosed();
-		EntityPersister persister = getEntityPersister(entityName, entity);
-		Serializable id = persister.getIdentifier(entity, EntityMode.POJO);
-		Object version = persister.getVersion(entity, EntityMode.POJO);
-		persister.delete(id, version, entity, this);
-	}
-
-
-	// updates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void update(Object entity) {
-		errorIfClosed();
-		update(null, entity);
-	}
-
-	public void update(String entityName, Object entity) {
-		errorIfClosed();
-		EntityPersister persister = getEntityPersister(entityName, entity);
-		Serializable id = persister.getIdentifier(entity, EntityMode.POJO);
-		Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
-		Object oldVersion;
-		if ( persister.isVersioned() ) {
-			oldVersion = persister.getVersion(entity, EntityMode.POJO);
-			Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this );
-			Versioning.setVersion(state, newVersion, persister);
-			persister.setPropertyValues(entity, state, EntityMode.POJO);
-		}
-		else {
-			oldVersion = null;
-		}
-		persister.update(id, state, null, false, null, oldVersion, entity, null, this);
-	}
-
-
-	// loading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public Object get(Class entityClass, Serializable id) {
-		return get( entityClass.getName(), id );
-	}
-
-	public Object get(Class entityClass, Serializable id, LockMode lockMode) {
-		return get( entityClass.getName(), id, lockMode );
-	}
-
-	public Object get(String entityName, Serializable id) {
-		return get(entityName, id, LockMode.NONE);
-	}
-
-	public Object get(String entityName, Serializable id, LockMode lockMode) {
-		errorIfClosed();
-		Object result = getFactory().getEntityPersister(entityName)
-				.load(id, null, lockMode, this);
-		temporaryPersistenceContext.clear();
-		return result;
-	}
-
-	public void refresh(Object entity) {
-		refresh( bestGuessEntityName( entity ), entity, LockMode.NONE );
-	}
-
-	public void refresh(String entityName, Object entity) {
-		refresh( entityName, entity, LockMode.NONE );
-	}
-
-	public void refresh(Object entity, LockMode lockMode) {
-		refresh( bestGuessEntityName( entity ), entity, lockMode );
-	}
-
-	public void refresh(String entityName, Object entity, LockMode lockMode) {
-		final EntityPersister persister = this.getEntityPersister( entityName, entity );
-		final Serializable id = persister.getIdentifier( entity, getEntityMode() );
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"refreshing transient " +
-					MessageHelper.infoString( persister, id, this.getFactory() )
-			);
-		}
-		// TODO : can this ever happen???
-//		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
-//		if ( source.getPersistenceContext().getEntry( key ) != null ) {
-//			throw new PersistentObjectException(
-//					"attempted to refresh transient instance when persistent " +
-//					"instance was already associated with the Session: " +
-//					MessageHelper.infoString( persister, id, source.getFactory() )
-//			);
-//		}
-
-		if ( persister.hasCache() ) {
-			final CacheKey ck = new CacheKey(
-					id,
-			        persister.getIdentifierType(),
-			        persister.getRootEntityName(),
-			        this.getEntityMode(),
-			        this.getFactory()
-			);
-			persister.getCacheAccessStrategy().evict( ck );
-		}
-
-		String previousFetchProfile = this.getFetchProfile();
-		Object result = null;
-		try {
-			this.setFetchProfile( "refresh" );
-			result = persister.load( id, entity, lockMode, this );
-		}
-		finally {
-			this.setFetchProfile( previousFetchProfile );
-		}
-		UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
-	}
-
-	public Object immediateLoad(String entityName, Serializable id)
-			throws HibernateException {
-		throw new SessionException("proxies cannot be fetched by a stateless session");
-	}
-
-	public void initializeCollection(
-			PersistentCollection collection,
-	        boolean writing) throws HibernateException {
-		throw new SessionException("collections cannot be fetched by a stateless session");
-	}
-
-	public Object instantiate(
-			String entityName,
-	        Serializable id) throws HibernateException {
-		errorIfClosed();
-		return getFactory().getEntityPersister( entityName )
-				.instantiate( id, EntityMode.POJO );
-	}
-
-	public Object internalLoad(
-			String entityName,
-	        Serializable id,
-	        boolean eager,
-	        boolean nullable) throws HibernateException {
-		errorIfClosed();
-		EntityPersister persister = getFactory().getEntityPersister(entityName);
-		if ( !eager && persister.hasProxy() ) {
-			return persister.createProxy(id, this);
-		}
-		Object loaded = temporaryPersistenceContext.getEntity( new EntityKey(id, persister, EntityMode.POJO) );
-		//TODO: if not loaded, throw an exception
-		return loaded==null ? get( entityName, id ) : loaded;
-	}
-
-	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
-		throw new UnsupportedOperationException();
-	}
-
-	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters)
-	throws HibernateException {
-		throw new UnsupportedOperationException();
-	}
-
-	public List listFilter(Object collection, String filter, QueryParameters queryParameters)
-	throws HibernateException {
-		throw new UnsupportedOperationException();
-	}
-
-
-	public boolean isOpen() {
-		return !isClosed();
-	}
-
-	public void close() {
-		managedClose();
-	}
-
-	public ConnectionReleaseMode getConnectionReleaseMode() {
-		return factory.getSettings().getConnectionReleaseMode();
-	}
-
-	public boolean isAutoCloseSessionEnabled() {
-		return factory.getSettings().isAutoCloseSessionEnabled();
-	}
-
-	public boolean isFlushBeforeCompletionEnabled() {
-		return true;
-	}
-
-	public boolean isFlushModeNever() {
-		return false;
-	}
-
-	public void managedClose() {
-		if ( isClosed() ) {
-			throw new SessionException( "Session was already closed!" );
-		}
-		jdbcContext.getConnectionManager().close();
-		setClosed();
-	}
-
-	public void managedFlush() {
-		errorIfClosed();
-		getBatcher().executeBatch();
-	}
-
-	public boolean shouldAutoClose() {
-		return isAutoCloseSessionEnabled() && !isClosed();
-	}
-
-	public void afterTransactionCompletion(boolean successful, Transaction tx) {}
-
-	public void beforeTransactionCompletion(Transaction tx) {}
-
-	public String bestGuessEntityName(Object object) {
-		if (object instanceof HibernateProxy) {
-			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
-		}
-		return guessEntityName(object);
-	}
-
-	public Connection connection() {
-		errorIfClosed();
-		return jdbcContext.borrowConnection();
-	}
-
-	public int executeUpdate(String query, QueryParameters queryParameters)
-			throws HibernateException {
-		errorIfClosed();
-		queryParameters.validateParameters();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		boolean success = false;
-		int result = 0;
-		try {
-			result = plan.performExecuteUpdate( queryParameters, this );
-			success = true;
-		}
-		finally {
-			afterOperation(success);
-		}
-		temporaryPersistenceContext.clear();
-		return result;
-	}
-
-	public Batcher getBatcher() {
-		errorIfClosed();
-		return jdbcContext.getConnectionManager()
-				.getBatcher();
-	}
-
-	public CacheMode getCacheMode() {
-		return CacheMode.IGNORE;
-	}
-
-	public int getDontFlushFromFind() {
-		return 0;
-	}
-
-	public Map getEnabledFilters() {
-		return CollectionHelper.EMPTY_MAP;
-	}
-
-	public Serializable getContextEntityIdentifier(Object object) {
-		errorIfClosed();
-		return null;
-	}
-
-	public EntityMode getEntityMode() {
-		return EntityMode.POJO;
-	}
-
-	public EntityPersister getEntityPersister(String entityName, Object object)
-			throws HibernateException {
-		errorIfClosed();
-		if ( entityName==null ) {
-			return factory.getEntityPersister( guessEntityName( object ) );
-		}
-		else {
-			return factory.getEntityPersister( entityName )
-					.getSubclassEntityPersister( object, getFactory(), EntityMode.POJO );
-		}
-	}
-
-	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
-		errorIfClosed();
-		return null;
-	}
-
-	public Type getFilterParameterType(String filterParameterName) {
-		throw new UnsupportedOperationException();
-	}
-
-	public Object getFilterParameterValue(String filterParameterName) {
-		throw new UnsupportedOperationException();
-	}
-
-	public FlushMode getFlushMode() {
-		return FlushMode.COMMIT;
-	}
-
-	public Interceptor getInterceptor() {
-		return EmptyInterceptor.INSTANCE;
-	}
-
-	public EventListeners getListeners() {
-		throw new UnsupportedOperationException();
-	}
-
-	public PersistenceContext getPersistenceContext() {
-		return temporaryPersistenceContext;
-	}
-
-	public long getTimestamp() {
-		throw new UnsupportedOperationException();
-	}
-
-	public String guessEntityName(Object entity) throws HibernateException {
-		errorIfClosed();
-		return entity.getClass().getName();
-	}
-
-
-	public boolean isConnected() {
-		return jdbcContext.getConnectionManager().isCurrentlyConnected();
-	}
-
-	public boolean isTransactionInProgress() {
-		return jdbcContext.isTransactionInProgress();
-	}
-
-	public void setAutoClear(boolean enabled) {
-		throw new UnsupportedOperationException();
-	}
-
-	public void setCacheMode(CacheMode cm) {
-		throw new UnsupportedOperationException();
-	}
-
-	public void setFlushMode(FlushMode fm) {
-		throw new UnsupportedOperationException();
-	}
-
-	public Transaction getTransaction() throws HibernateException {
-		errorIfClosed();
-		return jdbcContext.getTransaction();
-	}
-
-	public Transaction beginTransaction() throws HibernateException {
-		errorIfClosed();
-		Transaction result = getTransaction();
-		result.begin();
-		return result;
-	}
-
-	public boolean isEventSource() {
-		return false;
-	}
-
-/////////////////////////////////////////////////////////////////////////////////////////////////////
-
-	//TODO: COPY/PASTE FROM SessionImpl, pull up!
-
-	public List list(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		queryParameters.validateParameters();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		boolean success = false;
-		List results = CollectionHelper.EMPTY_LIST;
-		try {
-			results = plan.performList( queryParameters, this );
-			success = true;
-		}
-		finally {
-			afterOperation(success);
-		}
-		temporaryPersistenceContext.clear();
-		return results;
-	}
-
-	public void afterOperation(boolean success) {
-		if ( !jdbcContext.isTransactionInProgress() ) {
-			jdbcContext.afterNontransactionalQuery(success);
-		}
-	}
-
-	public Criteria createCriteria(Class persistentClass, String alias) {
-		errorIfClosed();
-		return new CriteriaImpl( persistentClass.getName(), alias, this );
-	}
-
-	public Criteria createCriteria(String entityName, String alias) {
-		errorIfClosed();
-		return new CriteriaImpl(entityName, alias, this);
-	}
-
-	public Criteria createCriteria(Class persistentClass) {
-		errorIfClosed();
-		return new CriteriaImpl( persistentClass.getName(), this );
-	}
-
-	public Criteria createCriteria(String entityName) {
-		errorIfClosed();
-		return new CriteriaImpl(entityName, this);
-	}
-
-	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
-		errorIfClosed();
-		String entityName = criteria.getEntityOrClassName();
-		CriteriaLoader loader = new CriteriaLoader(
-				getOuterJoinLoadable(entityName),
-		        factory,
-		        criteria,
-		        entityName,
-		        getEnabledFilters()
-			);
-		return loader.scroll(this, scrollMode);
-	}
-
-	public List list(CriteriaImpl criteria) throws HibernateException {
-		errorIfClosed();
-		String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
-		int size = implementors.length;
-
-		CriteriaLoader[] loaders = new CriteriaLoader[size];
-		for( int i=0; i <size; i++ ) {
-			loaders[i] = new CriteriaLoader(
-					getOuterJoinLoadable( implementors[i] ),
-			        factory,
-			        criteria,
-			        implementors[i],
-			        getEnabledFilters()
-			);
-		}
-
-
-		List results = Collections.EMPTY_LIST;
-		boolean success = false;
-		try {
-			for( int i=0; i<size; i++ ) {
-				final List currentResults = loaders[i].list(this);
-				currentResults.addAll(results);
-				results = currentResults;
-			}
-			success = true;
-		}
-		finally {
-			afterOperation(success);
-		}
-		temporaryPersistenceContext.clear();
-		return results;
-	}
-
-	private OuterJoinLoadable getOuterJoinLoadable(String entityName) throws MappingException {
-		EntityPersister persister = factory.getEntityPersister(entityName);
-		if ( !(persister instanceof OuterJoinLoadable) ) {
-			throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
-		}
-		return ( OuterJoinLoadable ) persister;
-	}
-
-	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
-	throws HibernateException {
-		errorIfClosed();
-		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
-
-		boolean success = false;
-		List results;
-		try {
-			results = loader.list(this, queryParameters);
-			success = true;
-		}
-		finally {
-			afterOperation(success);
-		}
-		temporaryPersistenceContext.clear();
-		return results;
-	}
-
-	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
-	throws HibernateException {
-		errorIfClosed();
-		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
-		return loader.scroll(queryParameters, this);
-	}
-
-	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		HQLQueryPlan plan = getHQLQueryPlan( query, false );
-		return plan.performScroll( queryParameters, this );
-	}
-
-	public void afterScrollOperation() {
-		temporaryPersistenceContext.clear();
-	}
-
-	public void flush() {}
-
-	public String getFetchProfile() {
-		return null;
-	}
-
-	public JDBCContext getJDBCContext() {
-		return jdbcContext;
-	}
-
-	public void setFetchProfile(String name) {}
-
-	public void afterTransactionBegin(Transaction tx) {}
-
-	protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
-		// no auto-flushing to support in stateless session
-		return false;
-	}
-	
-	public int executeNativeUpdate(NativeSQLQuerySpecification nativeSQLQuerySpecification,
-			QueryParameters queryParameters) throws HibernateException {
-		errorIfClosed();
-		queryParameters.validateParameters();
-		NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeSQLQuerySpecification);
-
-		boolean success = false;
-		int result = 0;
-		try {
-			result = plan.performExecuteUpdate(queryParameters, this);
-			success = true;
-		} finally {
-			afterOperation(success);
-		}
-		temporaryPersistenceContext.clear();
-		return result;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/StatelessSessionImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,653 @@
+/*
+ * 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.impl;
+
+import java.io.Serializable;
+import java.sql.Connection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.CacheMode;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.Criteria;
+import org.hibernate.EmptyInterceptor;
+import org.hibernate.EntityMode;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.SessionException;
+import org.hibernate.StatelessSession;
+import org.hibernate.Transaction;
+import org.hibernate.UnresolvableObjectException;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.StatefulPersistenceContext;
+import org.hibernate.engine.Versioning;
+import org.hibernate.engine.query.HQLQueryPlan;
+import org.hibernate.engine.query.NativeSQLQueryPlan;
+import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;
+import org.hibernate.event.EventListeners;
+import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.jdbc.Batcher;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.loader.criteria.CriteriaLoader;
+import org.hibernate.loader.custom.CustomLoader;
+import org.hibernate.loader.custom.CustomQuery;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.type.Type;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * @author Gavin King
+ */
+public class StatelessSessionImpl extends AbstractSessionImpl
+		implements JDBCContext.Context, StatelessSession {
+
+	private static final Logger log = LoggerFactory.getLogger( StatelessSessionImpl.class );
+
+	private JDBCContext jdbcContext;
+	private PersistenceContext temporaryPersistenceContext = new StatefulPersistenceContext( this );
+
+	StatelessSessionImpl(Connection connection, SessionFactoryImpl factory) {
+		super( factory );
+		this.jdbcContext = new JDBCContext( this, connection, EmptyInterceptor.INSTANCE );
+	}
+
+
+	// inserts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Serializable insert(Object entity) {
+		errorIfClosed();
+		return insert(null, entity);
+	}
+
+	public Serializable insert(String entityName, Object entity) {
+		errorIfClosed();
+		EntityPersister persister = getEntityPersister(entityName, entity);
+		Serializable id = persister.getIdentifierGenerator().generate(this, entity);
+		Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
+		if ( persister.isVersioned() ) {
+			boolean substitute = Versioning.seedVersion(state, persister.getVersionProperty(), persister.getVersionType(), this);
+			if ( substitute ) {
+				persister.setPropertyValues( entity, state, EntityMode.POJO );
+			}
+		}
+		if ( id == IdentifierGeneratorFactory.POST_INSERT_INDICATOR ) {
+			id = persister.insert(state, entity, this);
+		}
+		else {
+			persister.insert(id, state, entity, this);
+		}
+		persister.setIdentifier(entity, id, EntityMode.POJO);
+		return id;
+	}
+
+
+	// deletes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void delete(Object entity) {
+		errorIfClosed();
+		delete(null, entity);
+	}
+
+	public void delete(String entityName, Object entity) {
+		errorIfClosed();
+		EntityPersister persister = getEntityPersister(entityName, entity);
+		Serializable id = persister.getIdentifier(entity, EntityMode.POJO);
+		Object version = persister.getVersion(entity, EntityMode.POJO);
+		persister.delete(id, version, entity, this);
+	}
+
+
+	// updates ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void update(Object entity) {
+		errorIfClosed();
+		update(null, entity);
+	}
+
+	public void update(String entityName, Object entity) {
+		errorIfClosed();
+		EntityPersister persister = getEntityPersister(entityName, entity);
+		Serializable id = persister.getIdentifier(entity, EntityMode.POJO);
+		Object[] state = persister.getPropertyValues(entity, EntityMode.POJO);
+		Object oldVersion;
+		if ( persister.isVersioned() ) {
+			oldVersion = persister.getVersion(entity, EntityMode.POJO);
+			Object newVersion = Versioning.increment( oldVersion, persister.getVersionType(), this );
+			Versioning.setVersion(state, newVersion, persister);
+			persister.setPropertyValues(entity, state, EntityMode.POJO);
+		}
+		else {
+			oldVersion = null;
+		}
+		persister.update(id, state, null, false, null, oldVersion, entity, null, this);
+	}
+
+
+	// loading ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public Object get(Class entityClass, Serializable id) {
+		return get( entityClass.getName(), id );
+	}
+
+	public Object get(Class entityClass, Serializable id, LockMode lockMode) {
+		return get( entityClass.getName(), id, lockMode );
+	}
+
+	public Object get(String entityName, Serializable id) {
+		return get(entityName, id, LockMode.NONE);
+	}
+
+	public Object get(String entityName, Serializable id, LockMode lockMode) {
+		errorIfClosed();
+		Object result = getFactory().getEntityPersister(entityName)
+				.load(id, null, lockMode, this);
+		temporaryPersistenceContext.clear();
+		return result;
+	}
+
+	public void refresh(Object entity) {
+		refresh( bestGuessEntityName( entity ), entity, LockMode.NONE );
+	}
+
+	public void refresh(String entityName, Object entity) {
+		refresh( entityName, entity, LockMode.NONE );
+	}
+
+	public void refresh(Object entity, LockMode lockMode) {
+		refresh( bestGuessEntityName( entity ), entity, lockMode );
+	}
+
+	public void refresh(String entityName, Object entity, LockMode lockMode) {
+		final EntityPersister persister = this.getEntityPersister( entityName, entity );
+		final Serializable id = persister.getIdentifier( entity, getEntityMode() );
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"refreshing transient " +
+					MessageHelper.infoString( persister, id, this.getFactory() )
+			);
+		}
+		// TODO : can this ever happen???
+//		EntityKey key = new EntityKey( id, persister, source.getEntityMode() );
+//		if ( source.getPersistenceContext().getEntry( key ) != null ) {
+//			throw new PersistentObjectException(
+//					"attempted to refresh transient instance when persistent " +
+//					"instance was already associated with the Session: " +
+//					MessageHelper.infoString( persister, id, source.getFactory() )
+//			);
+//		}
+
+		if ( persister.hasCache() ) {
+			final CacheKey ck = new CacheKey(
+					id,
+			        persister.getIdentifierType(),
+			        persister.getRootEntityName(),
+			        this.getEntityMode(),
+			        this.getFactory()
+			);
+			persister.getCacheAccessStrategy().evict( ck );
+		}
+
+		String previousFetchProfile = this.getFetchProfile();
+		Object result = null;
+		try {
+			this.setFetchProfile( "refresh" );
+			result = persister.load( id, entity, lockMode, this );
+		}
+		finally {
+			this.setFetchProfile( previousFetchProfile );
+		}
+		UnresolvableObjectException.throwIfNull( result, id, persister.getEntityName() );
+	}
+
+	public Object immediateLoad(String entityName, Serializable id)
+			throws HibernateException {
+		throw new SessionException("proxies cannot be fetched by a stateless session");
+	}
+
+	public void initializeCollection(
+			PersistentCollection collection,
+	        boolean writing) throws HibernateException {
+		throw new SessionException("collections cannot be fetched by a stateless session");
+	}
+
+	public Object instantiate(
+			String entityName,
+	        Serializable id) throws HibernateException {
+		errorIfClosed();
+		return getFactory().getEntityPersister( entityName )
+				.instantiate( id, EntityMode.POJO );
+	}
+
+	public Object internalLoad(
+			String entityName,
+	        Serializable id,
+	        boolean eager,
+	        boolean nullable) throws HibernateException {
+		errorIfClosed();
+		EntityPersister persister = getFactory().getEntityPersister(entityName);
+		if ( !eager && persister.hasProxy() ) {
+			return persister.createProxy(id, this);
+		}
+		Object loaded = temporaryPersistenceContext.getEntity( new EntityKey(id, persister, EntityMode.POJO) );
+		//TODO: if not loaded, throw an exception
+		return loaded==null ? get( entityName, id ) : loaded;
+	}
+
+	public Iterator iterate(String query, QueryParameters queryParameters) throws HibernateException {
+		throw new UnsupportedOperationException();
+	}
+
+	public Iterator iterateFilter(Object collection, String filter, QueryParameters queryParameters)
+	throws HibernateException {
+		throw new UnsupportedOperationException();
+	}
+
+	public List listFilter(Object collection, String filter, QueryParameters queryParameters)
+	throws HibernateException {
+		throw new UnsupportedOperationException();
+	}
+
+
+	public boolean isOpen() {
+		return !isClosed();
+	}
+
+	public void close() {
+		managedClose();
+	}
+
+	public ConnectionReleaseMode getConnectionReleaseMode() {
+		return factory.getSettings().getConnectionReleaseMode();
+	}
+
+	public boolean isAutoCloseSessionEnabled() {
+		return factory.getSettings().isAutoCloseSessionEnabled();
+	}
+
+	public boolean isFlushBeforeCompletionEnabled() {
+		return true;
+	}
+
+	public boolean isFlushModeNever() {
+		return false;
+	}
+
+	public void managedClose() {
+		if ( isClosed() ) {
+			throw new SessionException( "Session was already closed!" );
+		}
+		jdbcContext.getConnectionManager().close();
+		setClosed();
+	}
+
+	public void managedFlush() {
+		errorIfClosed();
+		getBatcher().executeBatch();
+	}
+
+	public boolean shouldAutoClose() {
+		return isAutoCloseSessionEnabled() && !isClosed();
+	}
+
+	public void afterTransactionCompletion(boolean successful, Transaction tx) {}
+
+	public void beforeTransactionCompletion(Transaction tx) {}
+
+	public String bestGuessEntityName(Object object) {
+		if (object instanceof HibernateProxy) {
+			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
+		}
+		return guessEntityName(object);
+	}
+
+	public Connection connection() {
+		errorIfClosed();
+		return jdbcContext.borrowConnection();
+	}
+
+	public int executeUpdate(String query, QueryParameters queryParameters)
+			throws HibernateException {
+		errorIfClosed();
+		queryParameters.validateParameters();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		boolean success = false;
+		int result = 0;
+		try {
+			result = plan.performExecuteUpdate( queryParameters, this );
+			success = true;
+		}
+		finally {
+			afterOperation(success);
+		}
+		temporaryPersistenceContext.clear();
+		return result;
+	}
+
+	public Batcher getBatcher() {
+		errorIfClosed();
+		return jdbcContext.getConnectionManager()
+				.getBatcher();
+	}
+
+	public CacheMode getCacheMode() {
+		return CacheMode.IGNORE;
+	}
+
+	public int getDontFlushFromFind() {
+		return 0;
+	}
+
+	public Map getEnabledFilters() {
+		return CollectionHelper.EMPTY_MAP;
+	}
+
+	public Serializable getContextEntityIdentifier(Object object) {
+		errorIfClosed();
+		return null;
+	}
+
+	public EntityMode getEntityMode() {
+		return EntityMode.POJO;
+	}
+
+	public EntityPersister getEntityPersister(String entityName, Object object)
+			throws HibernateException {
+		errorIfClosed();
+		if ( entityName==null ) {
+			return factory.getEntityPersister( guessEntityName( object ) );
+		}
+		else {
+			return factory.getEntityPersister( entityName )
+					.getSubclassEntityPersister( object, getFactory(), EntityMode.POJO );
+		}
+	}
+
+	public Object getEntityUsingInterceptor(EntityKey key) throws HibernateException {
+		errorIfClosed();
+		return null;
+	}
+
+	public Type getFilterParameterType(String filterParameterName) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Object getFilterParameterValue(String filterParameterName) {
+		throw new UnsupportedOperationException();
+	}
+
+	public FlushMode getFlushMode() {
+		return FlushMode.COMMIT;
+	}
+
+	public Interceptor getInterceptor() {
+		return EmptyInterceptor.INSTANCE;
+	}
+
+	public EventListeners getListeners() {
+		throw new UnsupportedOperationException();
+	}
+
+	public PersistenceContext getPersistenceContext() {
+		return temporaryPersistenceContext;
+	}
+
+	public long getTimestamp() {
+		throw new UnsupportedOperationException();
+	}
+
+	public String guessEntityName(Object entity) throws HibernateException {
+		errorIfClosed();
+		return entity.getClass().getName();
+	}
+
+
+	public boolean isConnected() {
+		return jdbcContext.getConnectionManager().isCurrentlyConnected();
+	}
+
+	public boolean isTransactionInProgress() {
+		return jdbcContext.isTransactionInProgress();
+	}
+
+	public void setAutoClear(boolean enabled) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setCacheMode(CacheMode cm) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void setFlushMode(FlushMode fm) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Transaction getTransaction() throws HibernateException {
+		errorIfClosed();
+		return jdbcContext.getTransaction();
+	}
+
+	public Transaction beginTransaction() throws HibernateException {
+		errorIfClosed();
+		Transaction result = getTransaction();
+		result.begin();
+		return result;
+	}
+
+	public boolean isEventSource() {
+		return false;
+	}
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+
+	//TODO: COPY/PASTE FROM SessionImpl, pull up!
+
+	public List list(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		queryParameters.validateParameters();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		boolean success = false;
+		List results = CollectionHelper.EMPTY_LIST;
+		try {
+			results = plan.performList( queryParameters, this );
+			success = true;
+		}
+		finally {
+			afterOperation(success);
+		}
+		temporaryPersistenceContext.clear();
+		return results;
+	}
+
+	public void afterOperation(boolean success) {
+		if ( !jdbcContext.isTransactionInProgress() ) {
+			jdbcContext.afterNontransactionalQuery(success);
+		}
+	}
+
+	public Criteria createCriteria(Class persistentClass, String alias) {
+		errorIfClosed();
+		return new CriteriaImpl( persistentClass.getName(), alias, this );
+	}
+
+	public Criteria createCriteria(String entityName, String alias) {
+		errorIfClosed();
+		return new CriteriaImpl(entityName, alias, this);
+	}
+
+	public Criteria createCriteria(Class persistentClass) {
+		errorIfClosed();
+		return new CriteriaImpl( persistentClass.getName(), this );
+	}
+
+	public Criteria createCriteria(String entityName) {
+		errorIfClosed();
+		return new CriteriaImpl(entityName, this);
+	}
+
+	public ScrollableResults scroll(CriteriaImpl criteria, ScrollMode scrollMode) {
+		errorIfClosed();
+		String entityName = criteria.getEntityOrClassName();
+		CriteriaLoader loader = new CriteriaLoader(
+				getOuterJoinLoadable(entityName),
+		        factory,
+		        criteria,
+		        entityName,
+		        getEnabledFilters()
+			);
+		return loader.scroll(this, scrollMode);
+	}
+
+	public List list(CriteriaImpl criteria) throws HibernateException {
+		errorIfClosed();
+		String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
+		int size = implementors.length;
+
+		CriteriaLoader[] loaders = new CriteriaLoader[size];
+		for( int i=0; i <size; i++ ) {
+			loaders[i] = new CriteriaLoader(
+					getOuterJoinLoadable( implementors[i] ),
+			        factory,
+			        criteria,
+			        implementors[i],
+			        getEnabledFilters()
+			);
+		}
+
+
+		List results = Collections.EMPTY_LIST;
+		boolean success = false;
+		try {
+			for( int i=0; i<size; i++ ) {
+				final List currentResults = loaders[i].list(this);
+				currentResults.addAll(results);
+				results = currentResults;
+			}
+			success = true;
+		}
+		finally {
+			afterOperation(success);
+		}
+		temporaryPersistenceContext.clear();
+		return results;
+	}
+
+	private OuterJoinLoadable getOuterJoinLoadable(String entityName) throws MappingException {
+		EntityPersister persister = factory.getEntityPersister(entityName);
+		if ( !(persister instanceof OuterJoinLoadable) ) {
+			throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
+		}
+		return ( OuterJoinLoadable ) persister;
+	}
+
+	public List listCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
+	throws HibernateException {
+		errorIfClosed();
+		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
+
+		boolean success = false;
+		List results;
+		try {
+			results = loader.list(this, queryParameters);
+			success = true;
+		}
+		finally {
+			afterOperation(success);
+		}
+		temporaryPersistenceContext.clear();
+		return results;
+	}
+
+	public ScrollableResults scrollCustomQuery(CustomQuery customQuery, QueryParameters queryParameters)
+	throws HibernateException {
+		errorIfClosed();
+		CustomLoader loader = new CustomLoader( customQuery, getFactory() );
+		return loader.scroll(queryParameters, this);
+	}
+
+	public ScrollableResults scroll(String query, QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		HQLQueryPlan plan = getHQLQueryPlan( query, false );
+		return plan.performScroll( queryParameters, this );
+	}
+
+	public void afterScrollOperation() {
+		temporaryPersistenceContext.clear();
+	}
+
+	public void flush() {}
+
+	public String getFetchProfile() {
+		return null;
+	}
+
+	public JDBCContext getJDBCContext() {
+		return jdbcContext;
+	}
+
+	public void setFetchProfile(String name) {}
+
+	public void afterTransactionBegin(Transaction tx) {}
+
+	protected boolean autoFlushIfRequired(Set querySpaces) throws HibernateException {
+		// no auto-flushing to support in stateless session
+		return false;
+	}
+	
+	public int executeNativeUpdate(NativeSQLQuerySpecification nativeSQLQuerySpecification,
+			QueryParameters queryParameters) throws HibernateException {
+		errorIfClosed();
+		queryParameters.validateParameters();
+		NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeSQLQuerySpecification);
+
+		boolean success = false;
+		int result = 0;
+		try {
+			result = plan.performExecuteUpdate(queryParameters, this);
+			success = true;
+		} finally {
+			afterOperation(success);
+		}
+		temporaryPersistenceContext.clear();
+		return result;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/impl/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package contains implementations of the
-	central Hibernate APIs, especially the
-	Hibernate session.
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/impl/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/impl/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package contains implementations of the
+	central Hibernate APIs, especially the
+	Hibernate session.
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,103 +0,0 @@
-package org.hibernate.intercept;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.LazyInitializationException;
-
-import java.util.Set;
-import java.io.Serializable;
-
-/**
- * @author Steve Ebersole
- */
-public abstract class AbstractFieldInterceptor implements FieldInterceptor, Serializable {
-
-	private transient SessionImplementor session;
-	private Set uninitializedFields;
-	private final String entityName;
-
-	private transient boolean initializing;
-	private boolean dirty;
-
-	protected AbstractFieldInterceptor(SessionImplementor session, Set uninitializedFields, String entityName) {
-		this.session = session;
-		this.uninitializedFields = uninitializedFields;
-		this.entityName = entityName;
-	}
-
-
-	// FieldInterceptor impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public final void setSession(SessionImplementor session) {
-		this.session = session;
-	}
-
-	public final boolean isInitialized() {
-		return uninitializedFields == null || uninitializedFields.size() == 0;
-	}
-
-	public final boolean isInitialized(String field) {
-		return uninitializedFields == null || !uninitializedFields.contains( field );
-	}
-
-	public final void dirty() {
-		dirty = true;
-	}
-
-	public final boolean isDirty() {
-		return dirty;
-	}
-
-	public final void clearDirty() {
-		dirty = false;
-	}
-
-
-	// subclass accesses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	protected final Object intercept(Object target, String fieldName, Object value) {
-		if ( initializing ) {
-			return value;
-		}
-
-		if ( uninitializedFields != null && uninitializedFields.contains( fieldName ) ) {
-			if ( session == null ) {
-				throw new LazyInitializationException( "entity with lazy properties is not associated with a session" );
-			}
-			else if ( !session.isOpen() || !session.isConnected() ) {
-				throw new LazyInitializationException( "session is not connected" );
-			}
-
-			final Object result;
-			initializing = true;
-			try {
-				result = ( ( LazyPropertyInitializer ) session.getFactory()
-						.getEntityPersister( entityName ) )
-						.initializeLazyProperty( fieldName, target, session );
-			}
-			finally {
-				initializing = false;
-			}
-			uninitializedFields = null; //let's assume that there is only one lazy fetch group, for now!
-			return result;
-		}
-		else {
-			return value;
-		}
-	}
-
-	public final SessionImplementor getSession() {
-		return session;
-	}
-
-	public final Set getUninitializedFields() {
-		return uninitializedFields;
-	}
-
-	public final String getEntityName() {
-		return entityName;
-	}
-
-	public final boolean isInitializing() {
-		return initializing;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/AbstractFieldInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,127 @@
+/*
+ * 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.intercept;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.LazyInitializationException;
+
+import java.util.Set;
+import java.io.Serializable;
+
+/**
+ * @author Steve Ebersole
+ */
+public abstract class AbstractFieldInterceptor implements FieldInterceptor, Serializable {
+
+	private transient SessionImplementor session;
+	private Set uninitializedFields;
+	private final String entityName;
+
+	private transient boolean initializing;
+	private boolean dirty;
+
+	protected AbstractFieldInterceptor(SessionImplementor session, Set uninitializedFields, String entityName) {
+		this.session = session;
+		this.uninitializedFields = uninitializedFields;
+		this.entityName = entityName;
+	}
+
+
+	// FieldInterceptor impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public final void setSession(SessionImplementor session) {
+		this.session = session;
+	}
+
+	public final boolean isInitialized() {
+		return uninitializedFields == null || uninitializedFields.size() == 0;
+	}
+
+	public final boolean isInitialized(String field) {
+		return uninitializedFields == null || !uninitializedFields.contains( field );
+	}
+
+	public final void dirty() {
+		dirty = true;
+	}
+
+	public final boolean isDirty() {
+		return dirty;
+	}
+
+	public final void clearDirty() {
+		dirty = false;
+	}
+
+
+	// subclass accesses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	protected final Object intercept(Object target, String fieldName, Object value) {
+		if ( initializing ) {
+			return value;
+		}
+
+		if ( uninitializedFields != null && uninitializedFields.contains( fieldName ) ) {
+			if ( session == null ) {
+				throw new LazyInitializationException( "entity with lazy properties is not associated with a session" );
+			}
+			else if ( !session.isOpen() || !session.isConnected() ) {
+				throw new LazyInitializationException( "session is not connected" );
+			}
+
+			final Object result;
+			initializing = true;
+			try {
+				result = ( ( LazyPropertyInitializer ) session.getFactory()
+						.getEntityPersister( entityName ) )
+						.initializeLazyProperty( fieldName, target, session );
+			}
+			finally {
+				initializing = false;
+			}
+			uninitializedFields = null; //let's assume that there is only one lazy fetch group, for now!
+			return result;
+		}
+		else {
+			return value;
+		}
+	}
+
+	public final SessionImplementor getSession() {
+		return session;
+	}
+
+	public final Set getUninitializedFields() {
+		return uninitializedFields;
+	}
+
+	public final String getEntityName() {
+		return entityName;
+	}
+
+	public final boolean isInitializing() {
+		return initializing;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-package org.hibernate.intercept;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.intercept.cglib.CGLIBHelper;
-import org.hibernate.intercept.javassist.JavassistHelper;
-
-import java.util.Set;
-
-/**
- * Helper class for dealing with enhanced entity classes.
- *
- * @author Steve Ebersole
- */
-public class FieldInterceptionHelper {
-
-	// VERY IMPORTANT!!!! - This class needs to be free of any static references
-	// to any CGLIB or Javassist classes.  Otherwise, users will always need both
-	// on their classpaths no matter which (if either) they use.
-	//
-	// Another option here would be to remove the Hibernate.isPropertyInitialized()
-	// method and have the users go through the SessionFactory to get this information.
-
-	private FieldInterceptionHelper() {
-	}
-
-	public static boolean isInstrumented(Class entityClass) {
-		Class[] definedInterfaces = entityClass.getInterfaces();
-		for ( int i = 0; i < definedInterfaces.length; i++ ) {
-			if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() )
-			     || "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public static boolean isInstrumented(Object entity) {
-		return entity != null && isInstrumented( entity.getClass() );
-	}
-
-	public static FieldInterceptor extractFieldInterceptor(Object entity) {
-		if ( entity == null ) {
-			return null;
-		}
-		Class[] definedInterfaces = entity.getClass().getInterfaces();
-		for ( int i = 0; i < definedInterfaces.length; i++ ) {
-			if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
-				// we have a CGLIB enhanced entity
-				return CGLIBHelper.extractFieldInterceptor( entity );
-			}
-			else if ( "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
-				// we have a Javassist enhanced entity
-				return JavassistHelper.extractFieldInterceptor( entity );
-			}
-		}
-		return null;
-	}
-
-	public static FieldInterceptor injectFieldInterceptor(
-			Object entity,
-	        String entityName,
-	        Set uninitializedFieldNames,
-	        SessionImplementor session) {
-		if ( entity != null ) {
-			Class[] definedInterfaces = entity.getClass().getInterfaces();
-			for ( int i = 0; i < definedInterfaces.length; i++ ) {
-				if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
-					// we have a CGLIB enhanced entity
-					return CGLIBHelper.injectFieldInterceptor( entity, entityName, uninitializedFieldNames, session );
-				}
-				else if ( "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
-					// we have a Javassist enhanced entity
-					return JavassistHelper.injectFieldInterceptor( entity, entityName, uninitializedFieldNames, session );
-				}
-			}
-		}
-		return null;
-	}
-
-	public static void clearDirty(Object entity) {
-		FieldInterceptor interceptor = extractFieldInterceptor( entity );
-		if ( interceptor != null ) {
-			interceptor.clearDirty();
-		}
-	}
-
-	public static void markDirty(Object entity) {
-		FieldInterceptor interceptor = extractFieldInterceptor( entity );
-		if ( interceptor != null ) {
-			interceptor.dirty();
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.intercept;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.intercept.cglib.CGLIBHelper;
+import org.hibernate.intercept.javassist.JavassistHelper;
+
+import java.util.Set;
+
+/**
+ * Helper class for dealing with enhanced entity classes.
+ *
+ * @author Steve Ebersole
+ */
+public class FieldInterceptionHelper {
+
+	// VERY IMPORTANT!!!! - This class needs to be free of any static references
+	// to any CGLIB or Javassist classes.  Otherwise, users will always need both
+	// on their classpaths no matter which (if either) they use.
+	//
+	// Another option here would be to remove the Hibernate.isPropertyInitialized()
+	// method and have the users go through the SessionFactory to get this information.
+
+	private FieldInterceptionHelper() {
+	}
+
+	public static boolean isInstrumented(Class entityClass) {
+		Class[] definedInterfaces = entityClass.getInterfaces();
+		for ( int i = 0; i < definedInterfaces.length; i++ ) {
+			if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() )
+			     || "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public static boolean isInstrumented(Object entity) {
+		return entity != null && isInstrumented( entity.getClass() );
+	}
+
+	public static FieldInterceptor extractFieldInterceptor(Object entity) {
+		if ( entity == null ) {
+			return null;
+		}
+		Class[] definedInterfaces = entity.getClass().getInterfaces();
+		for ( int i = 0; i < definedInterfaces.length; i++ ) {
+			if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
+				// we have a CGLIB enhanced entity
+				return CGLIBHelper.extractFieldInterceptor( entity );
+			}
+			else if ( "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
+				// we have a Javassist enhanced entity
+				return JavassistHelper.extractFieldInterceptor( entity );
+			}
+		}
+		return null;
+	}
+
+	public static FieldInterceptor injectFieldInterceptor(
+			Object entity,
+	        String entityName,
+	        Set uninitializedFieldNames,
+	        SessionImplementor session) {
+		if ( entity != null ) {
+			Class[] definedInterfaces = entity.getClass().getInterfaces();
+			for ( int i = 0; i < definedInterfaces.length; i++ ) {
+				if ( "org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled".equals( definedInterfaces[i].getName() ) ) {
+					// we have a CGLIB enhanced entity
+					return CGLIBHelper.injectFieldInterceptor( entity, entityName, uninitializedFieldNames, session );
+				}
+				else if ( "org.hibernate.bytecode.javassist.FieldHandled".equals( definedInterfaces[i].getName() ) ) {
+					// we have a Javassist enhanced entity
+					return JavassistHelper.injectFieldInterceptor( entity, entityName, uninitializedFieldNames, session );
+				}
+			}
+		}
+		return null;
+	}
+
+	public static void clearDirty(Object entity) {
+		FieldInterceptor interceptor = extractFieldInterceptor( entity );
+		if ( interceptor != null ) {
+			interceptor.clearDirty();
+		}
+	}
+
+	public static void markDirty(Object entity) {
+		FieldInterceptor interceptor = extractFieldInterceptor( entity );
+		if ( interceptor != null ) {
+			interceptor.dirty();
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-package org.hibernate.intercept;
-
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Contract for field interception handlers.
- *
- * @author Steve Ebersole
- */
-public interface FieldInterceptor {
-
-	/**
-	 * Use to associate the entity to which we are bound to the given session.
-	 *
-	 * @param session The session to which we are now associated.
-	 */
-	public void setSession(SessionImplementor session);
-
-	/**
-	 * Is the entity to which we are bound completely initialized?
-	 *
-	 * @return True if the entity is initialized; otherwise false.
-	 */
-	public boolean isInitialized();
-
-	/**
-	 * The the given field initialized for the entity to which we are bound?
-	 *
-	 * @param field The name of the field to check
-	 * @return True if the given field is initialized; otherwise false.
-	 */
-	public boolean isInitialized(String field);
-
-	/**
-	 * Forcefully mark the entity as being dirty.
-	 */
-	public void dirty();
-
-	/**
-	 * Is the entity considered dirty?
-	 *
-	 * @return True if the entity is dirty; otherwise false.
-	 */
-	public boolean isDirty();
-
-	/**
-	 * Clear the internal dirty flag.
-	 */
-	public void clearDirty();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/FieldInterceptor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.intercept;
+
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Contract for field interception handlers.
+ *
+ * @author Steve Ebersole
+ */
+public interface FieldInterceptor {
+
+	/**
+	 * Use to associate the entity to which we are bound to the given session.
+	 *
+	 * @param session The session to which we are now associated.
+	 */
+	public void setSession(SessionImplementor session);
+
+	/**
+	 * Is the entity to which we are bound completely initialized?
+	 *
+	 * @return True if the entity is initialized; otherwise false.
+	 */
+	public boolean isInitialized();
+
+	/**
+	 * The the given field initialized for the entity to which we are bound?
+	 *
+	 * @param field The name of the field to check
+	 * @return True if the given field is initialized; otherwise false.
+	 */
+	public boolean isInitialized(String field);
+
+	/**
+	 * Forcefully mark the entity as being dirty.
+	 */
+	public void dirty();
+
+	/**
+	 * Is the entity considered dirty?
+	 *
+	 * @return True if the entity is dirty; otherwise false.
+	 */
+	public boolean isDirty();
+
+	/**
+	 * Clear the internal dirty flag.
+	 */
+	public void clearDirty();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-//$Id: LazyPropertyInitializer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.intercept;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Contract for controlling how lazy properties get initialized.
- * 
- * @author Gavin King
- */
-public interface LazyPropertyInitializer {
-
-	/**
-	 * Marker value for uninitialized properties
-	 */
-	public static final Serializable UNFETCHED_PROPERTY = new Serializable() {
-		public String toString() {
-			return "<lazy>";
-		}
-		public Object readResolve() {
-			return UNFETCHED_PROPERTY;
-		}
-	};
-
-	/**
-	 * Initialize the property, and return its new value
-	 */
-	public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
-	throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/LazyPropertyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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.intercept;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Contract for controlling how lazy properties get initialized.
+ * 
+ * @author Gavin King
+ */
+public interface LazyPropertyInitializer {
+
+	/**
+	 * Marker value for uninitialized properties
+	 */
+	public static final Serializable UNFETCHED_PROPERTY = new Serializable() {
+		public String toString() {
+			return "<lazy>";
+		}
+		public Object readResolve() {
+			return UNFETCHED_PROPERTY;
+		}
+	};
+
+	/**
+	 * Initialize the property, and return its new value
+	 */
+	public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
+	throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.intercept.cglib;
-
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
-
-import java.util.Set;
-
-/**
- * @author Steve Ebersole
- */
-public class CGLIBHelper {
-	private CGLIBHelper() {
-	}
-
-	public static FieldInterceptor extractFieldInterceptor(Object entity) {
-		return ( FieldInterceptor ) ( ( InterceptFieldEnabled ) entity ).getInterceptFieldCallback();
-	}
-
-	public static FieldInterceptor injectFieldInterceptor(
-			Object entity,
-	        String entityName,
-	        Set uninitializedFieldNames,
-	        SessionImplementor session) {
-		FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl(
-				session, uninitializedFieldNames, entityName
-		);
-		( ( InterceptFieldEnabled ) entity ).setInterceptFieldCallback( fieldInterceptor );
-		return fieldInterceptor;
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/CGLIBHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.intercept.cglib;
+
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+
+import java.util.Set;
+
+/**
+ * @author Steve Ebersole
+ */
+public class CGLIBHelper {
+	private CGLIBHelper() {
+	}
+
+	public static FieldInterceptor extractFieldInterceptor(Object entity) {
+		return ( FieldInterceptor ) ( ( InterceptFieldEnabled ) entity ).getInterceptFieldCallback();
+	}
+
+	public static FieldInterceptor injectFieldInterceptor(
+			Object entity,
+	        String entityName,
+	        Set uninitializedFieldNames,
+	        SessionImplementor session) {
+		FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl(
+				session, uninitializedFieldNames, entityName
+		);
+		( ( InterceptFieldEnabled ) entity ).setInterceptFieldCallback( fieldInterceptor );
+		return fieldInterceptor;
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,147 +0,0 @@
-//$Id: FieldInterceptorImpl.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.intercept.cglib;
-
-import java.io.Serializable;
-import java.util.Set;
-
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback;
-
-import org.hibernate.intercept.AbstractFieldInterceptor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-
-/**
- * A field-level interceptor that initializes lazily fetched properties.
- * This interceptor can be attached to classes instrumented by CGLIB.
- * Note that this implementation assumes that the instance variable
- * name is the same as the name of the persistent property that must
- * be loaded.
- *
- * @author Gavin King
- */
-public final class FieldInterceptorImpl extends AbstractFieldInterceptor implements InterceptFieldCallback, Serializable {
-
-	/**
-	 * Package-protected constructor
-	 *
-	 * @param session The Hibernate session
-	 * @param uninitializedFields Names of the fields we need to initialize on load
-	 * @param entityName The entity name to which we are being bound
-	 */
-	FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) {
-		super( session, uninitializedFields, entityName );
-	}
-
-	public boolean readBoolean(Object target, String name, boolean oldValue) {
-		return ( ( Boolean ) intercept( target, name, oldValue  ? Boolean.TRUE : Boolean.FALSE ) )
-				.booleanValue();
-	}
-
-	public byte readByte(Object target, String name, byte oldValue) {
-		return ( ( Byte ) intercept( target, name, new Byte( oldValue ) ) ).byteValue();
-	}
-
-	public char readChar(Object target, String name, char oldValue) {
-		return ( ( Character ) intercept( target, name, new Character( oldValue ) ) )
-				.charValue();
-	}
-
-	public double readDouble(Object target, String name, double oldValue) {
-		return ( ( Double ) intercept( target, name, new Double( oldValue ) ) )
-				.doubleValue();
-	}
-
-	public float readFloat(Object target, String name, float oldValue) {
-		return ( ( Float ) intercept( target, name, new Float( oldValue ) ) )
-				.floatValue();
-	}
-
-	public int readInt(Object target, String name, int oldValue) {
-		return ( ( Integer ) intercept( target, name, new Integer( oldValue ) ) )
-				.intValue();
-	}
-
-	public long readLong(Object target, String name, long oldValue) {
-		return ( ( Long ) intercept( target, name, new Long( oldValue ) ) ).longValue();
-	}
-
-	public short readShort(Object target, String name, short oldValue) {
-		return ( ( Short ) intercept( target, name, new Short( oldValue ) ) )
-				.shortValue();
-	}
-
-	public Object readObject(Object target, String name, Object oldValue) {
-		Object value = intercept( target, name, oldValue );
-		if (value instanceof HibernateProxy) {
-			LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer();
-			if ( li.isUnwrap() ) {
-				value = li.getImplementation();
-			}
-		}
-		return value;
-	}
-
-	public boolean writeBoolean(Object target, String name, boolean oldValue, boolean newValue) {
-		dirty();
-		intercept( target, name, oldValue ? Boolean.TRUE : Boolean.FALSE );
-		return newValue;
-	}
-
-	public byte writeByte(Object target, String name, byte oldValue, byte newValue) {
-		dirty();
-		intercept( target, name, new Byte( oldValue ) );
-		return newValue;
-	}
-
-	public char writeChar(Object target, String name, char oldValue, char newValue) {
-		dirty();
-		intercept( target, name, new Character( oldValue ) );
-		return newValue;
-	}
-
-	public double writeDouble(Object target, String name, double oldValue, double newValue) {
-		dirty();
-		intercept( target, name, new Double( oldValue ) );
-		return newValue;
-	}
-
-	public float writeFloat(Object target, String name, float oldValue, float newValue) {
-		dirty();
-		intercept( target, name, new Float( oldValue ) );
-		return newValue;
-	}
-
-	public int writeInt(Object target, String name, int oldValue, int newValue) {
-		dirty();
-		intercept( target, name, new Integer( oldValue ) );
-		return newValue;
-	}
-
-	public long writeLong(Object target, String name, long oldValue, long newValue) {
-		dirty();
-		intercept( target, name, new Long( oldValue ) );
-		return newValue;
-	}
-
-	public short writeShort(Object target, String name, short oldValue, short newValue) {
-		dirty();
-		intercept( target, name, new Short( oldValue ) );
-		return newValue;
-	}
-
-	public Object writeObject(Object target, String name, Object oldValue, Object newValue) {
-		dirty();
-		intercept( target, name, oldValue );
-		return newValue;
-	}
-
-	public String toString() {
-		return "FieldInterceptorImpl(" +
-			"entityName=" + getEntityName() +
-			",dirty=" + isDirty() +
-			",uninitializedFields=" + getUninitializedFields() +
-			')';
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/cglib/FieldInterceptorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,170 @@
+/*
+ * 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.intercept.cglib;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldCallback;
+
+import org.hibernate.intercept.AbstractFieldInterceptor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+
+/**
+ * A field-level interceptor that initializes lazily fetched properties.
+ * This interceptor can be attached to classes instrumented by CGLIB.
+ * Note that this implementation assumes that the instance variable
+ * name is the same as the name of the persistent property that must
+ * be loaded.
+ *
+ * @author Gavin King
+ */
+public final class FieldInterceptorImpl extends AbstractFieldInterceptor implements InterceptFieldCallback, Serializable {
+
+	/**
+	 * Package-protected constructor
+	 *
+	 * @param session The Hibernate session
+	 * @param uninitializedFields Names of the fields we need to initialize on load
+	 * @param entityName The entity name to which we are being bound
+	 */
+	FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) {
+		super( session, uninitializedFields, entityName );
+	}
+
+	public boolean readBoolean(Object target, String name, boolean oldValue) {
+		return ( ( Boolean ) intercept( target, name, oldValue  ? Boolean.TRUE : Boolean.FALSE ) )
+				.booleanValue();
+	}
+
+	public byte readByte(Object target, String name, byte oldValue) {
+		return ( ( Byte ) intercept( target, name, new Byte( oldValue ) ) ).byteValue();
+	}
+
+	public char readChar(Object target, String name, char oldValue) {
+		return ( ( Character ) intercept( target, name, new Character( oldValue ) ) )
+				.charValue();
+	}
+
+	public double readDouble(Object target, String name, double oldValue) {
+		return ( ( Double ) intercept( target, name, new Double( oldValue ) ) )
+				.doubleValue();
+	}
+
+	public float readFloat(Object target, String name, float oldValue) {
+		return ( ( Float ) intercept( target, name, new Float( oldValue ) ) )
+				.floatValue();
+	}
+
+	public int readInt(Object target, String name, int oldValue) {
+		return ( ( Integer ) intercept( target, name, new Integer( oldValue ) ) )
+				.intValue();
+	}
+
+	public long readLong(Object target, String name, long oldValue) {
+		return ( ( Long ) intercept( target, name, new Long( oldValue ) ) ).longValue();
+	}
+
+	public short readShort(Object target, String name, short oldValue) {
+		return ( ( Short ) intercept( target, name, new Short( oldValue ) ) )
+				.shortValue();
+	}
+
+	public Object readObject(Object target, String name, Object oldValue) {
+		Object value = intercept( target, name, oldValue );
+		if (value instanceof HibernateProxy) {
+			LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer();
+			if ( li.isUnwrap() ) {
+				value = li.getImplementation();
+			}
+		}
+		return value;
+	}
+
+	public boolean writeBoolean(Object target, String name, boolean oldValue, boolean newValue) {
+		dirty();
+		intercept( target, name, oldValue ? Boolean.TRUE : Boolean.FALSE );
+		return newValue;
+	}
+
+	public byte writeByte(Object target, String name, byte oldValue, byte newValue) {
+		dirty();
+		intercept( target, name, new Byte( oldValue ) );
+		return newValue;
+	}
+
+	public char writeChar(Object target, String name, char oldValue, char newValue) {
+		dirty();
+		intercept( target, name, new Character( oldValue ) );
+		return newValue;
+	}
+
+	public double writeDouble(Object target, String name, double oldValue, double newValue) {
+		dirty();
+		intercept( target, name, new Double( oldValue ) );
+		return newValue;
+	}
+
+	public float writeFloat(Object target, String name, float oldValue, float newValue) {
+		dirty();
+		intercept( target, name, new Float( oldValue ) );
+		return newValue;
+	}
+
+	public int writeInt(Object target, String name, int oldValue, int newValue) {
+		dirty();
+		intercept( target, name, new Integer( oldValue ) );
+		return newValue;
+	}
+
+	public long writeLong(Object target, String name, long oldValue, long newValue) {
+		dirty();
+		intercept( target, name, new Long( oldValue ) );
+		return newValue;
+	}
+
+	public short writeShort(Object target, String name, short oldValue, short newValue) {
+		dirty();
+		intercept( target, name, new Short( oldValue ) );
+		return newValue;
+	}
+
+	public Object writeObject(Object target, String name, Object oldValue, Object newValue) {
+		dirty();
+		intercept( target, name, oldValue );
+		return newValue;
+	}
+
+	public String toString() {
+		return "FieldInterceptorImpl(" +
+			"entityName=" + getEntityName() +
+			",dirty=" + isDirty() +
+			",uninitializedFields=" + getUninitializedFields() +
+			')';
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,154 +0,0 @@
-//$Id: FieldInterceptorImpl.java 10206 2006-08-03 19:59:42Z steve.ebersole at jboss.com $
-package org.hibernate.intercept.javassist;
-
-import java.io.Serializable;
-import java.util.Set;
-
-import org.hibernate.bytecode.javassist.FieldHandler;
-import org.hibernate.intercept.AbstractFieldInterceptor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-
-/**
- * A field-level interceptor that initializes lazily fetched properties.
- * This interceptor can be attached to classes instrumented by Javassist.
- * Note that this implementation assumes that the instance variable
- * name is the same as the name of the persistent property that must
- * be loaded.
- * </p>
- * Note: most of the interesting functionality here is farmed off
- * to the super-class.  The stuff here mainly acts as an adapter to the
- * Javassist-specific functionality, routing interception through
- * the super-class's intercept() method
- *
- * @author Steve Ebersole
- */
-public final class FieldInterceptorImpl extends AbstractFieldInterceptor implements FieldHandler, Serializable {
-
-	/**
-	 * Package-protected constructor.
-	 *
-	 * @param session
-	 * @param uninitializedFields
-	 * @param entityName
-	 */
-	FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) {
-		super( session, uninitializedFields, entityName );
-	}
-
-
-	// FieldHandler impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean readBoolean(Object target, String name, boolean oldValue) {
-		return ( ( Boolean ) intercept( target, name, oldValue  ? Boolean.TRUE : Boolean.FALSE ) )
-				.booleanValue();
-	}
-
-	public byte readByte(Object target, String name, byte oldValue) {
-		return ( ( Byte ) intercept( target, name, new Byte( oldValue ) ) ).byteValue();
-	}
-
-	public char readChar(Object target, String name, char oldValue) {
-		return ( ( Character ) intercept( target, name, new Character( oldValue ) ) )
-				.charValue();
-	}
-
-	public double readDouble(Object target, String name, double oldValue) {
-		return ( ( Double ) intercept( target, name, new Double( oldValue ) ) )
-				.doubleValue();
-	}
-
-	public float readFloat(Object target, String name, float oldValue) {
-		return ( ( Float ) intercept( target, name, new Float( oldValue ) ) )
-				.floatValue();
-	}
-
-	public int readInt(Object target, String name, int oldValue) {
-		return ( ( Integer ) intercept( target, name, new Integer( oldValue ) ) )
-				.intValue();
-	}
-
-	public long readLong(Object target, String name, long oldValue) {
-		return ( ( Long ) intercept( target, name, new Long( oldValue ) ) ).longValue();
-	}
-
-	public short readShort(Object target, String name, short oldValue) {
-		return ( ( Short ) intercept( target, name, new Short( oldValue ) ) )
-				.shortValue();
-	}
-
-	public Object readObject(Object target, String name, Object oldValue) {
-		Object value = intercept( target, name, oldValue );
-		if (value instanceof HibernateProxy) {
-			LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer();
-			if ( li.isUnwrap() ) {
-				value = li.getImplementation();
-			}
-		}
-		return value;
-	}
-
-	public boolean writeBoolean(Object target, String name, boolean oldValue, boolean newValue) {
-		dirty();
-		intercept( target, name, oldValue ? Boolean.TRUE : Boolean.FALSE );
-		return newValue;
-	}
-
-	public byte writeByte(Object target, String name, byte oldValue, byte newValue) {
-		dirty();
-		intercept( target, name, new Byte( oldValue ) );
-		return newValue;
-	}
-
-	public char writeChar(Object target, String name, char oldValue, char newValue) {
-		dirty();
-		intercept( target, name, new Character( oldValue ) );
-		return newValue;
-	}
-
-	public double writeDouble(Object target, String name, double oldValue, double newValue) {
-		dirty();
-		intercept( target, name, new Double( oldValue ) );
-		return newValue;
-	}
-
-	public float writeFloat(Object target, String name, float oldValue, float newValue) {
-		dirty();
-		intercept( target, name, new Float( oldValue ) );
-		return newValue;
-	}
-
-	public int writeInt(Object target, String name, int oldValue, int newValue) {
-		dirty();
-		intercept( target, name, new Integer( oldValue ) );
-		return newValue;
-	}
-
-	public long writeLong(Object target, String name, long oldValue, long newValue) {
-		dirty();
-		intercept( target, name, new Long( oldValue ) );
-		return newValue;
-	}
-
-	public short writeShort(Object target, String name, short oldValue, short newValue) {
-		dirty();
-		intercept( target, name, new Short( oldValue ) );
-		return newValue;
-	}
-
-	public Object writeObject(Object target, String name, Object oldValue, Object newValue) {
-		dirty();
-		intercept( target, name, oldValue );
-		return newValue;
-	}
-
-	public String toString() {
-		return "FieldInterceptorImpl(" +
-		       "entityName=" + getEntityName() +
-		       ",dirty=" + isDirty() +
-		       ",uninitializedFields=" + getUninitializedFields() +
-		       ')';
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/FieldInterceptorImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,177 @@
+/*
+ * 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.intercept.javassist;
+
+import java.io.Serializable;
+import java.util.Set;
+
+import org.hibernate.bytecode.javassist.FieldHandler;
+import org.hibernate.intercept.AbstractFieldInterceptor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+
+/**
+ * A field-level interceptor that initializes lazily fetched properties.
+ * This interceptor can be attached to classes instrumented by Javassist.
+ * Note that this implementation assumes that the instance variable
+ * name is the same as the name of the persistent property that must
+ * be loaded.
+ * </p>
+ * Note: most of the interesting functionality here is farmed off
+ * to the super-class.  The stuff here mainly acts as an adapter to the
+ * Javassist-specific functionality, routing interception through
+ * the super-class's intercept() method
+ *
+ * @author Steve Ebersole
+ */
+public final class FieldInterceptorImpl extends AbstractFieldInterceptor implements FieldHandler, Serializable {
+
+	/**
+	 * Package-protected constructor.
+	 *
+	 * @param session
+	 * @param uninitializedFields
+	 * @param entityName
+	 */
+	FieldInterceptorImpl(SessionImplementor session, Set uninitializedFields, String entityName) {
+		super( session, uninitializedFields, entityName );
+	}
+
+
+	// FieldHandler impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean readBoolean(Object target, String name, boolean oldValue) {
+		return ( ( Boolean ) intercept( target, name, oldValue  ? Boolean.TRUE : Boolean.FALSE ) )
+				.booleanValue();
+	}
+
+	public byte readByte(Object target, String name, byte oldValue) {
+		return ( ( Byte ) intercept( target, name, new Byte( oldValue ) ) ).byteValue();
+	}
+
+	public char readChar(Object target, String name, char oldValue) {
+		return ( ( Character ) intercept( target, name, new Character( oldValue ) ) )
+				.charValue();
+	}
+
+	public double readDouble(Object target, String name, double oldValue) {
+		return ( ( Double ) intercept( target, name, new Double( oldValue ) ) )
+				.doubleValue();
+	}
+
+	public float readFloat(Object target, String name, float oldValue) {
+		return ( ( Float ) intercept( target, name, new Float( oldValue ) ) )
+				.floatValue();
+	}
+
+	public int readInt(Object target, String name, int oldValue) {
+		return ( ( Integer ) intercept( target, name, new Integer( oldValue ) ) )
+				.intValue();
+	}
+
+	public long readLong(Object target, String name, long oldValue) {
+		return ( ( Long ) intercept( target, name, new Long( oldValue ) ) ).longValue();
+	}
+
+	public short readShort(Object target, String name, short oldValue) {
+		return ( ( Short ) intercept( target, name, new Short( oldValue ) ) )
+				.shortValue();
+	}
+
+	public Object readObject(Object target, String name, Object oldValue) {
+		Object value = intercept( target, name, oldValue );
+		if (value instanceof HibernateProxy) {
+			LazyInitializer li = ( (HibernateProxy) value ).getHibernateLazyInitializer();
+			if ( li.isUnwrap() ) {
+				value = li.getImplementation();
+			}
+		}
+		return value;
+	}
+
+	public boolean writeBoolean(Object target, String name, boolean oldValue, boolean newValue) {
+		dirty();
+		intercept( target, name, oldValue ? Boolean.TRUE : Boolean.FALSE );
+		return newValue;
+	}
+
+	public byte writeByte(Object target, String name, byte oldValue, byte newValue) {
+		dirty();
+		intercept( target, name, new Byte( oldValue ) );
+		return newValue;
+	}
+
+	public char writeChar(Object target, String name, char oldValue, char newValue) {
+		dirty();
+		intercept( target, name, new Character( oldValue ) );
+		return newValue;
+	}
+
+	public double writeDouble(Object target, String name, double oldValue, double newValue) {
+		dirty();
+		intercept( target, name, new Double( oldValue ) );
+		return newValue;
+	}
+
+	public float writeFloat(Object target, String name, float oldValue, float newValue) {
+		dirty();
+		intercept( target, name, new Float( oldValue ) );
+		return newValue;
+	}
+
+	public int writeInt(Object target, String name, int oldValue, int newValue) {
+		dirty();
+		intercept( target, name, new Integer( oldValue ) );
+		return newValue;
+	}
+
+	public long writeLong(Object target, String name, long oldValue, long newValue) {
+		dirty();
+		intercept( target, name, new Long( oldValue ) );
+		return newValue;
+	}
+
+	public short writeShort(Object target, String name, short oldValue, short newValue) {
+		dirty();
+		intercept( target, name, new Short( oldValue ) );
+		return newValue;
+	}
+
+	public Object writeObject(Object target, String name, Object oldValue, Object newValue) {
+		dirty();
+		intercept( target, name, oldValue );
+		return newValue;
+	}
+
+	public String toString() {
+		return "FieldInterceptorImpl(" +
+		       "entityName=" + getEntityName() +
+		       ",dirty=" + isDirty() +
+		       ",uninitializedFields=" + getUninitializedFields() +
+		       ')';
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-package org.hibernate.intercept.javassist;
-
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.bytecode.javassist.FieldHandled;
-
-import java.util.Set;
-
-/**
- * @author Steve Ebersole
- */
-public class JavassistHelper {
-	private JavassistHelper() {
-	}
-
-	public static FieldInterceptor extractFieldInterceptor(Object entity) {
-		return ( FieldInterceptor ) ( ( FieldHandled ) entity ).getFieldHandler();
-	}
-
-	public static FieldInterceptor injectFieldInterceptor(
-			Object entity,
-	        String entityName,
-	        Set uninitializedFieldNames,
-	        SessionImplementor session) {
-		FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl( session, uninitializedFieldNames, entityName );
-		( ( FieldHandled ) entity ).setFieldHandler( fieldInterceptor );
-		return fieldInterceptor;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/javassist/JavassistHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.intercept.javassist;
+
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.bytecode.javassist.FieldHandled;
+
+import java.util.Set;
+
+/**
+ * @author Steve Ebersole
+ */
+public class JavassistHelper {
+	private JavassistHelper() {
+	}
+
+	public static FieldInterceptor extractFieldInterceptor(Object entity) {
+		return ( FieldInterceptor ) ( ( FieldHandled ) entity ).getFieldHandler();
+	}
+
+	public static FieldInterceptor injectFieldInterceptor(
+			Object entity,
+	        String entityName,
+	        Set uninitializedFieldNames,
+	        SessionImplementor session) {
+		FieldInterceptorImpl fieldInterceptor = new FieldInterceptorImpl( session, uninitializedFieldNames, entityName );
+		( ( FieldHandled ) entity ).setFieldHandler( fieldInterceptor );
+		return fieldInterceptor;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/intercept/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package implements an interception
-	mechanism for lazy property fetching,
-	based on CGLIB bytecode instrumentation.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/intercept/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/intercept/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package implements an interception
+	mechanism for lazy property fetching,
+	based on CGLIB bytecode instrumentation.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,626 +0,0 @@
-//$Id: AbstractBatcher.java 11332 2007-03-22 17:34:55Z steve.ebersole at jboss.com $
-package org.hibernate.jdbc;
-
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.ConcurrentModificationException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.ScrollMode;
-import org.hibernate.TransactionException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.util.JDBCExceptionReporter;
-
-/**
- * Manages prepared statements and batching.
- *
- * @author Gavin King
- */
-public abstract class AbstractBatcher implements Batcher {
-
-	private static int globalOpenPreparedStatementCount;
-	private static int globalOpenResultSetCount;
-
-	private int openPreparedStatementCount;
-	private int openResultSetCount;
-
-	protected static final Logger log = LoggerFactory.getLogger( AbstractBatcher.class );
-
-	private final ConnectionManager connectionManager;
-	private final SessionFactoryImplementor factory;
-
-	private PreparedStatement batchUpdate;
-	private String batchUpdateSQL;
-
-	private HashSet statementsToClose = new HashSet();
-	private HashSet resultSetsToClose = new HashSet();
-	private PreparedStatement lastQuery;
-
-	private boolean releasing = false;
-	private final Interceptor interceptor;
-
-	private long transactionTimeout = -1;
-	boolean isTransactionTimeoutSet;
-
-	public AbstractBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
-		this.connectionManager = connectionManager;
-		this.interceptor = interceptor;
-		this.factory = connectionManager.getFactory();
-	}
-
-	public void setTransactionTimeout(int seconds) {
-		isTransactionTimeoutSet = true;
-		transactionTimeout = System.currentTimeMillis() / 1000 + seconds;
-	}
-
-	public void unsetTransactionTimeout() {
-		isTransactionTimeoutSet = false;
-	}
-
-	protected PreparedStatement getStatement() {
-		return batchUpdate;
-	}
-
-	public CallableStatement prepareCallableStatement(String sql)
-	throws SQLException, HibernateException {
-		executeBatch();
-		logOpenPreparedStatement();
-		return getCallableStatement( connectionManager.getConnection(), sql, false);
-	}
-
-	public PreparedStatement prepareStatement(String sql)
-	throws SQLException, HibernateException {
-		return prepareStatement( sql, false );
-	}
-
-	public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys)
-			throws SQLException, HibernateException {
-		executeBatch();
-		logOpenPreparedStatement();
-		return getPreparedStatement(
-				connectionManager.getConnection(),
-		        sql,
-		        false,
-		        getGeneratedKeys,
-		        null,
-		        null,
-		        false
-		);
-	}
-
-	public PreparedStatement prepareStatement(String sql, String[] columnNames)
-			throws SQLException, HibernateException {
-		executeBatch();
-		logOpenPreparedStatement();
-		return getPreparedStatement(
-				connectionManager.getConnection(),
-		        sql,
-		        false,
-		        false,
-		        columnNames,
-		        null,
-		        false
-		);
-	}
-
-	public PreparedStatement prepareSelectStatement(String sql)
-			throws SQLException, HibernateException {
-		logOpenPreparedStatement();
-		return getPreparedStatement(
-				connectionManager.getConnection(),
-		        sql,
-		        false,
-		        false,
-		        null,
-		        null,
-		        false
-		);
-	}
-
-	public PreparedStatement prepareQueryStatement(
-			String sql,
-	        boolean scrollable,
-	        ScrollMode scrollMode) throws SQLException, HibernateException {
-		logOpenPreparedStatement();
-		PreparedStatement ps = getPreparedStatement(
-				connectionManager.getConnection(),
-		        sql,
-		        scrollable,
-		        scrollMode
-		);
-		setStatementFetchSize( ps );
-		statementsToClose.add( ps );
-		lastQuery = ps;
-		return ps;
-	}
-
-	public CallableStatement prepareCallableQueryStatement(
-			String sql,
-	        boolean scrollable,
-	        ScrollMode scrollMode) throws SQLException, HibernateException {
-		logOpenPreparedStatement();
-		CallableStatement ps = ( CallableStatement ) getPreparedStatement(
-				connectionManager.getConnection(),
-		        sql,
-		        scrollable,
-		        false,
-		        null,
-		        scrollMode,
-		        true
-		);
-		setStatementFetchSize( ps );
-		statementsToClose.add( ps );
-		lastQuery = ps;
-		return ps;
-	}
-
-	public void abortBatch(SQLException sqle) {
-		try {
-			if (batchUpdate!=null) closeStatement(batchUpdate);
-		}
-		catch (SQLException e) {
-			//noncritical, swallow and let the other propagate!
-			JDBCExceptionReporter.logExceptions(e);
-		}
-		finally {
-			batchUpdate=null;
-			batchUpdateSQL=null;
-		}
-	}
-
-	public ResultSet getResultSet(PreparedStatement ps) throws SQLException {
-		ResultSet rs = ps.executeQuery();
-		resultSetsToClose.add(rs);
-		logOpenResults();
-		return rs;
-	}
-
-	public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException {
-		ResultSet rs = dialect.getResultSet(ps);
-		resultSetsToClose.add(rs);
-		logOpenResults();
-		return rs;
-
-	}
-
-	public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException {
-		boolean psStillThere = statementsToClose.remove( ps );
-		try {
-			if ( rs != null ) {
-				if ( resultSetsToClose.remove( rs ) ) {
-					logCloseResults();
-					rs.close();
-				}
-			}
-		}
-		finally {
-			if ( psStillThere ) {
-				closeQueryStatement( ps );
-			}
-		}
-	}
-
-	public PreparedStatement prepareBatchStatement(String sql)
-			throws SQLException, HibernateException {
-		sql = getSQL( sql );
-
-		if ( !sql.equals(batchUpdateSQL) ) {
-			batchUpdate=prepareStatement(sql); // calls executeBatch()
-			batchUpdateSQL=sql;
-		}
-		else {
-			log.debug("reusing prepared statement");
-			log(sql);
-		}
-		return batchUpdate;
-	}
-
-	public CallableStatement prepareBatchCallableStatement(String sql)
-			throws SQLException, HibernateException {
-		if ( !sql.equals(batchUpdateSQL) ) { // TODO: what if batchUpdate is a callablestatement ?
-			batchUpdate=prepareCallableStatement(sql); // calls executeBatch()
-			batchUpdateSQL=sql;
-		}
-		return (CallableStatement)batchUpdate;
-	}
-
-
-	public void executeBatch() throws HibernateException {
-		if (batchUpdate!=null) {
-			try {
-				try {
-					doExecuteBatch(batchUpdate);
-				}
-				finally {
-					closeStatement(batchUpdate);
-				}
-			}
-			catch (SQLException sqle) {
-				throw JDBCExceptionHelper.convert(
-				        factory.getSQLExceptionConverter(),
-				        sqle,
-				        "Could not execute JDBC batch update",
-				        batchUpdateSQL
-					);
-			}
-			finally {
-				batchUpdate=null;
-				batchUpdateSQL=null;
-			}
-		}
-	}
-
-	public void closeStatement(PreparedStatement ps) throws SQLException {
-		logClosePreparedStatement();
-		closePreparedStatement(ps);
-	}
-
-	private void closeQueryStatement(PreparedStatement ps) throws SQLException {
-
-		try {
-			//work around a bug in all known connection pools....
-			if ( ps.getMaxRows()!=0 ) ps.setMaxRows(0);
-			if ( ps.getQueryTimeout()!=0 ) ps.setQueryTimeout(0);
-		}
-		catch (Exception e) {
-			log.warn("exception clearing maxRows/queryTimeout", e);
-//			ps.close(); //just close it; do NOT try to return it to the pool!
-			return; //NOTE: early exit!
-		}
-		finally {
-			closeStatement(ps);
-		}
-
-		if ( lastQuery==ps ) lastQuery = null;
-
-	}
-
-	/**
-	 * Actually releases the batcher, allowing it to cleanup internally held
-	 * resources.
-	 */
-	public void closeStatements() {
-		try {
-			releasing = true;
-
-			try {
-				if ( batchUpdate != null ) {
-					batchUpdate.close();
-				}
-			}
-			catch ( SQLException sqle ) {
-				//no big deal
-				log.warn( "Could not close a JDBC prepared statement", sqle );
-			}
-			batchUpdate = null;
-			batchUpdateSQL = null;
-
-			Iterator iter = resultSetsToClose.iterator();
-			while ( iter.hasNext() ) {
-				try {
-					logCloseResults();
-					( ( ResultSet ) iter.next() ).close();
-				}
-				catch ( SQLException e ) {
-					// no big deal
-					log.warn( "Could not close a JDBC result set", e );
-				}
-				catch ( ConcurrentModificationException e ) {
-					// this has been shown to happen occasionally in rare cases
-					// when using a transaction manager + transaction-timeout
-					// where the timeout calls back through Hibernate's
-					// registered transaction synchronization on a separate
-					// "reaping" thread.  In cases where that reaping thread
-					// executes through this block at the same time the main
-					// application thread does we can get into situations where
-					// these CMEs occur.  And though it is not "allowed" per-se,
-					// the end result without handling it specifically is infinite
-					// looping.  So here, we simply break the loop
-					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
-					break;
-				}
-				catch ( Throwable e ) {
-					// sybase driver (jConnect) throwing NPE here in certain
-					// cases, but we'll just handle the general "unexpected" case
-					log.warn( "Could not close a JDBC result set", e );
-				}
-			}
-			resultSetsToClose.clear();
-
-			iter = statementsToClose.iterator();
-			while ( iter.hasNext() ) {
-				try {
-					closeQueryStatement( ( PreparedStatement ) iter.next() );
-				}
-				catch ( ConcurrentModificationException e ) {
-					// see explanation above...
-					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
-					break;
-				}
-				catch ( SQLException e ) {
-					// no big deal
-					log.warn( "Could not close a JDBC statement", e );
-				}
-			}
-			statementsToClose.clear();
-		}
-		finally {
-			releasing = false;
-		}
-	}
-
-	protected abstract void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException;
-
-	private String preparedStatementCountsToString() {
-		return
-				" (open PreparedStatements: " +
-				openPreparedStatementCount +
-				", globally: " +
-				globalOpenPreparedStatementCount +
-				")";
-	}
-
-	private String resultSetCountsToString() {
-		return
-				" (open ResultSets: " +
-				openResultSetCount +
-				", globally: " +
-				globalOpenResultSetCount +
-				")";
-	}
-
-	private void logOpenPreparedStatement() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "about to open PreparedStatement" + preparedStatementCountsToString() );
-			openPreparedStatementCount++;
-			globalOpenPreparedStatementCount++;
-		}
-	}
-
-	private void logClosePreparedStatement() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "about to close PreparedStatement" + preparedStatementCountsToString() );
-			openPreparedStatementCount--;
-			globalOpenPreparedStatementCount--;
-		}
-	}
-
-	private void logOpenResults() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "about to open ResultSet" + resultSetCountsToString() );
-			openResultSetCount++;
-			globalOpenResultSetCount++;
-		}
-	}
-	private void logCloseResults() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "about to close ResultSet" + resultSetCountsToString() );
-			openResultSetCount--;
-			globalOpenResultSetCount--;
-		}
-	}
-
-	protected SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	private void log(String sql) {
-		factory.getSettings().getSqlStatementLogger().logStatement( sql, FormatStyle.BASIC );
-	}
-
-	private PreparedStatement getPreparedStatement(
-			final Connection conn,
-	        final String sql,
-	        final boolean scrollable,
-	        final ScrollMode scrollMode) throws SQLException {
-		return getPreparedStatement(
-				conn,
-		        sql,
-		        scrollable,
-		        false,
-		        null,
-		        scrollMode,
-		        false
-		);
-	}
-
-	private CallableStatement getCallableStatement(
-			final Connection conn,
-	        String sql,
-	        boolean scrollable) throws SQLException {
-		if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
-			throw new AssertionFailure("scrollable result sets are not enabled");
-		}
-
-		sql = getSQL( sql );
-		log( sql );
-
-		log.trace("preparing callable statement");
-		if ( scrollable ) {
-			return conn.prepareCall(
-					sql,
-			        ResultSet.TYPE_SCROLL_INSENSITIVE,
-			        ResultSet.CONCUR_READ_ONLY
-			);
-		}
-		else {
-			return conn.prepareCall( sql );
-		}
-	}
-
-	private String getSQL(String sql) {
-		sql = interceptor.onPrepareStatement( sql );
-		if ( sql==null || sql.length() == 0 ) {
-			throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
-		}
-		return sql;
-	}
-
-	private PreparedStatement getPreparedStatement(
-			final Connection conn,
-	        String sql,
-	        boolean scrollable,
-	        final boolean useGetGeneratedKeys,
-	        final String[] namedGeneratedKeys,
-	        final ScrollMode scrollMode,
-	        final boolean callable) throws SQLException {
-		if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
-			throw new AssertionFailure("scrollable result sets are not enabled");
-		}
-		if ( useGetGeneratedKeys && !factory.getSettings().isGetGeneratedKeysEnabled() ) {
-			throw new AssertionFailure("getGeneratedKeys() support is not enabled");
-		}
-
-		sql = getSQL( sql );
-		log( sql );
-
-		log.trace( "preparing statement" );
-		PreparedStatement result;
-		if ( scrollable ) {
-			if ( callable ) {
-				result = conn.prepareCall( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
-			}
-			else {
-				result = conn.prepareStatement( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
-			}
-		}
-		else if ( useGetGeneratedKeys ) {
-			result = conn.prepareStatement( sql, PreparedStatement.RETURN_GENERATED_KEYS );
-		}
-		else if ( namedGeneratedKeys != null ) {
-			result = conn.prepareStatement( sql, namedGeneratedKeys );
-		}
-		else {
-			if ( callable ) {
-				result = conn.prepareCall( sql );
-			}
-			else {
-				result = conn.prepareStatement( sql );
-			}
-		}
-
-		setTimeout( result );
-
-		if ( factory.getStatistics().isStatisticsEnabled() ) {
-			factory.getStatisticsImplementor().prepareStatement();
-		}
-
-		return result;
-
-	}
-
-	private void setTimeout(PreparedStatement result) throws SQLException {
-		if ( isTransactionTimeoutSet ) {
-			int timeout = (int) ( transactionTimeout - ( System.currentTimeMillis() / 1000 ) );
-			if (timeout<=0) {
-				throw new TransactionException("transaction timeout expired");
-			}
-			else {
-				result.setQueryTimeout(timeout);
-			}
-		}
-	}
-
-	private void closePreparedStatement(PreparedStatement ps) throws SQLException {
-		try {
-			log.trace("closing statement");
-			ps.close();
-			if ( factory.getStatistics().isStatisticsEnabled() ) {
-				factory.getStatisticsImplementor().closeStatement();
-			}
-		}
-		finally {
-			if ( !releasing ) {
-				// If we are in the process of releasing, no sense
-				// checking for aggressive-release possibility.
-				connectionManager.afterStatement();
-			}
-		}
-	}
-
-	private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
-		Integer statementFetchSize = factory.getSettings().getJdbcFetchSize();
-		if ( statementFetchSize!=null ) {
-			statement.setFetchSize( statementFetchSize.intValue() );
-		}
-	}
-
-	public Connection openConnection() throws HibernateException {
-		log.debug("opening JDBC connection");
-		try {
-			return factory.getConnectionProvider().getConnection();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					factory.getSQLExceptionConverter(),
-			        sqle,
-			        "Cannot open connection"
-				);
-		}
-	}
-
-	public void closeConnection(Connection conn) throws HibernateException {
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"closing JDBC connection" +
-					preparedStatementCountsToString() +
-					resultSetCountsToString()
-				);
-		}
-
-		try {
-			if ( !conn.isClosed() ) {
-				JDBCExceptionReporter.logAndClearWarnings(conn);
-			}
-			factory.getConnectionProvider().closeConnection(conn);
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					factory.getSQLExceptionConverter(),
-			        sqle,
-			        "Cannot close connection"
-				);
-		}
-	}
-
-	public void cancelLastQuery() throws HibernateException {
-		try {
-			if (lastQuery!=null) lastQuery.cancel();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					factory.getSQLExceptionConverter(),
-			        sqle,
-			        "Cannot cancel query"
-				);
-		}
-	}
-
-	public boolean hasOpenResources() {
-		return resultSetsToClose.size() > 0 || statementsToClose.size() > 0;
-	}
-
-	public String openResourceStatsAsString() {
-		return preparedStatementCountsToString() + resultSetCountsToString();
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java (from rev 14998, core/trunk/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/AbstractBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,647 @@
+/*
+ * 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.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.ConcurrentModificationException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.ScrollMode;
+import org.hibernate.TransactionException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.util.JDBCExceptionReporter;
+
+/**
+ * Manages prepared statements and batching.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractBatcher implements Batcher {
+
+	private static int globalOpenPreparedStatementCount;
+	private static int globalOpenResultSetCount;
+
+	private int openPreparedStatementCount;
+	private int openResultSetCount;
+
+	protected static final Logger log = LoggerFactory.getLogger( AbstractBatcher.class );
+
+	private final ConnectionManager connectionManager;
+	private final SessionFactoryImplementor factory;
+
+	private PreparedStatement batchUpdate;
+	private String batchUpdateSQL;
+
+	private HashSet statementsToClose = new HashSet();
+	private HashSet resultSetsToClose = new HashSet();
+	private PreparedStatement lastQuery;
+
+	private boolean releasing = false;
+	private final Interceptor interceptor;
+
+	private long transactionTimeout = -1;
+	boolean isTransactionTimeoutSet;
+
+	public AbstractBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
+		this.connectionManager = connectionManager;
+		this.interceptor = interceptor;
+		this.factory = connectionManager.getFactory();
+	}
+
+	public void setTransactionTimeout(int seconds) {
+		isTransactionTimeoutSet = true;
+		transactionTimeout = System.currentTimeMillis() / 1000 + seconds;
+	}
+
+	public void unsetTransactionTimeout() {
+		isTransactionTimeoutSet = false;
+	}
+
+	protected PreparedStatement getStatement() {
+		return batchUpdate;
+	}
+
+	public CallableStatement prepareCallableStatement(String sql)
+	throws SQLException, HibernateException {
+		executeBatch();
+		logOpenPreparedStatement();
+		return getCallableStatement( connectionManager.getConnection(), sql, false);
+	}
+
+	public PreparedStatement prepareStatement(String sql)
+	throws SQLException, HibernateException {
+		return prepareStatement( sql, false );
+	}
+
+	public PreparedStatement prepareStatement(String sql, boolean getGeneratedKeys)
+			throws SQLException, HibernateException {
+		executeBatch();
+		logOpenPreparedStatement();
+		return getPreparedStatement(
+				connectionManager.getConnection(),
+		        sql,
+		        false,
+		        getGeneratedKeys,
+		        null,
+		        null,
+		        false
+		);
+	}
+
+	public PreparedStatement prepareStatement(String sql, String[] columnNames)
+			throws SQLException, HibernateException {
+		executeBatch();
+		logOpenPreparedStatement();
+		return getPreparedStatement(
+				connectionManager.getConnection(),
+		        sql,
+		        false,
+		        false,
+		        columnNames,
+		        null,
+		        false
+		);
+	}
+
+	public PreparedStatement prepareSelectStatement(String sql)
+			throws SQLException, HibernateException {
+		logOpenPreparedStatement();
+		return getPreparedStatement(
+				connectionManager.getConnection(),
+		        sql,
+		        false,
+		        false,
+		        null,
+		        null,
+		        false
+		);
+	}
+
+	public PreparedStatement prepareQueryStatement(
+			String sql,
+	        boolean scrollable,
+	        ScrollMode scrollMode) throws SQLException, HibernateException {
+		logOpenPreparedStatement();
+		PreparedStatement ps = getPreparedStatement(
+				connectionManager.getConnection(),
+		        sql,
+		        scrollable,
+		        scrollMode
+		);
+		setStatementFetchSize( ps );
+		statementsToClose.add( ps );
+		lastQuery = ps;
+		return ps;
+	}
+
+	public CallableStatement prepareCallableQueryStatement(
+			String sql,
+	        boolean scrollable,
+	        ScrollMode scrollMode) throws SQLException, HibernateException {
+		logOpenPreparedStatement();
+		CallableStatement ps = ( CallableStatement ) getPreparedStatement(
+				connectionManager.getConnection(),
+		        sql,
+		        scrollable,
+		        false,
+		        null,
+		        scrollMode,
+		        true
+		);
+		setStatementFetchSize( ps );
+		statementsToClose.add( ps );
+		lastQuery = ps;
+		return ps;
+	}
+
+	public void abortBatch(SQLException sqle) {
+		try {
+			if (batchUpdate!=null) closeStatement(batchUpdate);
+		}
+		catch (SQLException e) {
+			//noncritical, swallow and let the other propagate!
+			JDBCExceptionReporter.logExceptions(e);
+		}
+		finally {
+			batchUpdate=null;
+			batchUpdateSQL=null;
+		}
+	}
+
+	public ResultSet getResultSet(PreparedStatement ps) throws SQLException {
+		ResultSet rs = ps.executeQuery();
+		resultSetsToClose.add(rs);
+		logOpenResults();
+		return rs;
+	}
+
+	public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException {
+		ResultSet rs = dialect.getResultSet(ps);
+		resultSetsToClose.add(rs);
+		logOpenResults();
+		return rs;
+
+	}
+
+	public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException {
+		boolean psStillThere = statementsToClose.remove( ps );
+		try {
+			if ( rs != null ) {
+				if ( resultSetsToClose.remove( rs ) ) {
+					logCloseResults();
+					rs.close();
+				}
+			}
+		}
+		finally {
+			if ( psStillThere ) {
+				closeQueryStatement( ps );
+			}
+		}
+	}
+
+	public PreparedStatement prepareBatchStatement(String sql)
+			throws SQLException, HibernateException {
+		sql = getSQL( sql );
+
+		if ( !sql.equals(batchUpdateSQL) ) {
+			batchUpdate=prepareStatement(sql); // calls executeBatch()
+			batchUpdateSQL=sql;
+		}
+		else {
+			log.debug("reusing prepared statement");
+			log(sql);
+		}
+		return batchUpdate;
+	}
+
+	public CallableStatement prepareBatchCallableStatement(String sql)
+			throws SQLException, HibernateException {
+		if ( !sql.equals(batchUpdateSQL) ) { // TODO: what if batchUpdate is a callablestatement ?
+			batchUpdate=prepareCallableStatement(sql); // calls executeBatch()
+			batchUpdateSQL=sql;
+		}
+		return (CallableStatement)batchUpdate;
+	}
+
+
+	public void executeBatch() throws HibernateException {
+		if (batchUpdate!=null) {
+			try {
+				try {
+					doExecuteBatch(batchUpdate);
+				}
+				finally {
+					closeStatement(batchUpdate);
+				}
+			}
+			catch (SQLException sqle) {
+				throw JDBCExceptionHelper.convert(
+				        factory.getSQLExceptionConverter(),
+				        sqle,
+				        "Could not execute JDBC batch update",
+				        batchUpdateSQL
+					);
+			}
+			finally {
+				batchUpdate=null;
+				batchUpdateSQL=null;
+			}
+		}
+	}
+
+	public void closeStatement(PreparedStatement ps) throws SQLException {
+		logClosePreparedStatement();
+		closePreparedStatement(ps);
+	}
+
+	private void closeQueryStatement(PreparedStatement ps) throws SQLException {
+
+		try {
+			//work around a bug in all known connection pools....
+			if ( ps.getMaxRows()!=0 ) ps.setMaxRows(0);
+			if ( ps.getQueryTimeout()!=0 ) ps.setQueryTimeout(0);
+		}
+		catch (Exception e) {
+			log.warn("exception clearing maxRows/queryTimeout", e);
+//			ps.close(); //just close it; do NOT try to return it to the pool!
+			return; //NOTE: early exit!
+		}
+		finally {
+			closeStatement(ps);
+		}
+
+		if ( lastQuery==ps ) lastQuery = null;
+
+	}
+
+	/**
+	 * Actually releases the batcher, allowing it to cleanup internally held
+	 * resources.
+	 */
+	public void closeStatements() {
+		try {
+			releasing = true;
+
+			try {
+				if ( batchUpdate != null ) {
+					batchUpdate.close();
+				}
+			}
+			catch ( SQLException sqle ) {
+				//no big deal
+				log.warn( "Could not close a JDBC prepared statement", sqle );
+			}
+			batchUpdate = null;
+			batchUpdateSQL = null;
+
+			Iterator iter = resultSetsToClose.iterator();
+			while ( iter.hasNext() ) {
+				try {
+					logCloseResults();
+					( ( ResultSet ) iter.next() ).close();
+				}
+				catch ( SQLException e ) {
+					// no big deal
+					log.warn( "Could not close a JDBC result set", e );
+				}
+				catch ( ConcurrentModificationException e ) {
+					// this has been shown to happen occasionally in rare cases
+					// when using a transaction manager + transaction-timeout
+					// where the timeout calls back through Hibernate's
+					// registered transaction synchronization on a separate
+					// "reaping" thread.  In cases where that reaping thread
+					// executes through this block at the same time the main
+					// application thread does we can get into situations where
+					// these CMEs occur.  And though it is not "allowed" per-se,
+					// the end result without handling it specifically is infinite
+					// looping.  So here, we simply break the loop
+					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
+					break;
+				}
+				catch ( Throwable e ) {
+					// sybase driver (jConnect) throwing NPE here in certain
+					// cases, but we'll just handle the general "unexpected" case
+					log.warn( "Could not close a JDBC result set", e );
+				}
+			}
+			resultSetsToClose.clear();
+
+			iter = statementsToClose.iterator();
+			while ( iter.hasNext() ) {
+				try {
+					closeQueryStatement( ( PreparedStatement ) iter.next() );
+				}
+				catch ( ConcurrentModificationException e ) {
+					// see explanation above...
+					log.info( "encountered CME attempting to release batcher; assuming cause is tx-timeout scenario and ignoring" );
+					break;
+				}
+				catch ( SQLException e ) {
+					// no big deal
+					log.warn( "Could not close a JDBC statement", e );
+				}
+			}
+			statementsToClose.clear();
+		}
+		finally {
+			releasing = false;
+		}
+	}
+
+	protected abstract void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException;
+
+	private String preparedStatementCountsToString() {
+		return
+				" (open PreparedStatements: " +
+				openPreparedStatementCount +
+				", globally: " +
+				globalOpenPreparedStatementCount +
+				")";
+	}
+
+	private String resultSetCountsToString() {
+		return
+				" (open ResultSets: " +
+				openResultSetCount +
+				", globally: " +
+				globalOpenResultSetCount +
+				")";
+	}
+
+	private void logOpenPreparedStatement() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "about to open PreparedStatement" + preparedStatementCountsToString() );
+			openPreparedStatementCount++;
+			globalOpenPreparedStatementCount++;
+		}
+	}
+
+	private void logClosePreparedStatement() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "about to close PreparedStatement" + preparedStatementCountsToString() );
+			openPreparedStatementCount--;
+			globalOpenPreparedStatementCount--;
+		}
+	}
+
+	private void logOpenResults() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "about to open ResultSet" + resultSetCountsToString() );
+			openResultSetCount++;
+			globalOpenResultSetCount++;
+		}
+	}
+	private void logCloseResults() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "about to close ResultSet" + resultSetCountsToString() );
+			openResultSetCount--;
+			globalOpenResultSetCount--;
+		}
+	}
+
+	protected SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	private void log(String sql) {
+		factory.getSettings().getSqlStatementLogger().logStatement( sql, FormatStyle.BASIC );
+	}
+
+	private PreparedStatement getPreparedStatement(
+			final Connection conn,
+	        final String sql,
+	        final boolean scrollable,
+	        final ScrollMode scrollMode) throws SQLException {
+		return getPreparedStatement(
+				conn,
+		        sql,
+		        scrollable,
+		        false,
+		        null,
+		        scrollMode,
+		        false
+		);
+	}
+
+	private CallableStatement getCallableStatement(
+			final Connection conn,
+	        String sql,
+	        boolean scrollable) throws SQLException {
+		if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
+			throw new AssertionFailure("scrollable result sets are not enabled");
+		}
+
+		sql = getSQL( sql );
+		log( sql );
+
+		log.trace("preparing callable statement");
+		if ( scrollable ) {
+			return conn.prepareCall(
+					sql,
+			        ResultSet.TYPE_SCROLL_INSENSITIVE,
+			        ResultSet.CONCUR_READ_ONLY
+			);
+		}
+		else {
+			return conn.prepareCall( sql );
+		}
+	}
+
+	private String getSQL(String sql) {
+		sql = interceptor.onPrepareStatement( sql );
+		if ( sql==null || sql.length() == 0 ) {
+			throw new AssertionFailure( "Interceptor.onPrepareStatement() returned null or empty string." );
+		}
+		return sql;
+	}
+
+	private PreparedStatement getPreparedStatement(
+			final Connection conn,
+	        String sql,
+	        boolean scrollable,
+	        final boolean useGetGeneratedKeys,
+	        final String[] namedGeneratedKeys,
+	        final ScrollMode scrollMode,
+	        final boolean callable) throws SQLException {
+		if ( scrollable && !factory.getSettings().isScrollableResultSetsEnabled() ) {
+			throw new AssertionFailure("scrollable result sets are not enabled");
+		}
+		if ( useGetGeneratedKeys && !factory.getSettings().isGetGeneratedKeysEnabled() ) {
+			throw new AssertionFailure("getGeneratedKeys() support is not enabled");
+		}
+
+		sql = getSQL( sql );
+		log( sql );
+
+		log.trace( "preparing statement" );
+		PreparedStatement result;
+		if ( scrollable ) {
+			if ( callable ) {
+				result = conn.prepareCall( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
+			}
+			else {
+				result = conn.prepareStatement( sql, scrollMode.toResultSetType(), ResultSet.CONCUR_READ_ONLY );
+			}
+		}
+		else if ( useGetGeneratedKeys ) {
+			result = conn.prepareStatement( sql, PreparedStatement.RETURN_GENERATED_KEYS );
+		}
+		else if ( namedGeneratedKeys != null ) {
+			result = conn.prepareStatement( sql, namedGeneratedKeys );
+		}
+		else {
+			if ( callable ) {
+				result = conn.prepareCall( sql );
+			}
+			else {
+				result = conn.prepareStatement( sql );
+			}
+		}
+
+		setTimeout( result );
+
+		if ( factory.getStatistics().isStatisticsEnabled() ) {
+			factory.getStatisticsImplementor().prepareStatement();
+		}
+
+		return result;
+
+	}
+
+	private void setTimeout(PreparedStatement result) throws SQLException {
+		if ( isTransactionTimeoutSet ) {
+			int timeout = (int) ( transactionTimeout - ( System.currentTimeMillis() / 1000 ) );
+			if (timeout<=0) {
+				throw new TransactionException("transaction timeout expired");
+			}
+			else {
+				result.setQueryTimeout(timeout);
+			}
+		}
+	}
+
+	private void closePreparedStatement(PreparedStatement ps) throws SQLException {
+		try {
+			log.trace("closing statement");
+			ps.close();
+			if ( factory.getStatistics().isStatisticsEnabled() ) {
+				factory.getStatisticsImplementor().closeStatement();
+			}
+		}
+		finally {
+			if ( !releasing ) {
+				// If we are in the process of releasing, no sense
+				// checking for aggressive-release possibility.
+				connectionManager.afterStatement();
+			}
+		}
+	}
+
+	private void setStatementFetchSize(PreparedStatement statement) throws SQLException {
+		Integer statementFetchSize = factory.getSettings().getJdbcFetchSize();
+		if ( statementFetchSize!=null ) {
+			statement.setFetchSize( statementFetchSize.intValue() );
+		}
+	}
+
+	public Connection openConnection() throws HibernateException {
+		log.debug("opening JDBC connection");
+		try {
+			return factory.getConnectionProvider().getConnection();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					factory.getSQLExceptionConverter(),
+			        sqle,
+			        "Cannot open connection"
+				);
+		}
+	}
+
+	public void closeConnection(Connection conn) throws HibernateException {
+		if ( conn == null ) {
+			log.debug( "found null connection on AbstractBatcher#closeConnection" );
+			// EARLY EXIT!!!!
+			return;
+		}
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( "closing JDBC connection" + preparedStatementCountsToString() + resultSetCountsToString() );
+		}
+
+		try {
+			if ( !conn.isClosed() ) {
+				JDBCExceptionReporter.logAndClearWarnings( conn );
+			}
+			factory.getConnectionProvider().closeConnection( conn );
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert( factory.getSQLExceptionConverter(), sqle, "Cannot close connection" );
+		}
+	}
+
+	public void cancelLastQuery() throws HibernateException {
+		try {
+			if (lastQuery!=null) lastQuery.cancel();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					factory.getSQLExceptionConverter(),
+			        sqle,
+			        "Cannot cancel query"
+				);
+		}
+	}
+
+	public boolean hasOpenResources() {
+		return resultSetsToClose.size() > 0 || statementsToClose.size() > 0;
+	}
+
+	public String openResourceStatsAsString() {
+		return preparedStatementCountsToString() + resultSetCountsToString();
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-package org.hibernate.jdbc;
-
-import org.hibernate.HibernateException;
-
-/**
- * Indicates a failed batch entry (-3 return).
- *
- * @author Steve Ebersole
- */
-public class BatchFailedException extends HibernateException {
-	public BatchFailedException(String s) {
-		super( s );
-	}
-
-	public BatchFailedException(String string, Throwable root) {
-		super( string, root );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchFailedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.jdbc;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates a failed batch entry (-3 return).
+ *
+ * @author Steve Ebersole
+ */
+public class BatchFailedException extends HibernateException {
+	public BatchFailedException(String s) {
+		super( s );
+	}
+
+	public BatchFailedException(String string, Throwable root) {
+		super( string, root );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-package org.hibernate.jdbc;
-
-/**
- * Much like {@link TooManyRowsAffectedException}, indicates that more
- * rows than what we were expcecting were affected.  Additionally, this form
- * occurs from a batch and carries along the batch positon that failed.
- *
- * @author Steve Ebersole
- */
-public class BatchedTooManyRowsAffectedException extends TooManyRowsAffectedException {
-	private final int batchPosition;
-
-	public BatchedTooManyRowsAffectedException(String message, int expectedRowCount, int actualRowCount, int batchPosition) {
-		super( message, expectedRowCount, actualRowCount );
-		this.batchPosition = batchPosition;
-	}
-
-	public int getBatchPosition() {
-		return batchPosition;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchedTooManyRowsAffectedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+/**
+ * Much like {@link TooManyRowsAffectedException}, indicates that more
+ * rows than what we were expcecting were affected.  Additionally, this form
+ * occurs from a batch and carries along the batch positon that failed.
+ *
+ * @author Steve Ebersole
+ */
+public class BatchedTooManyRowsAffectedException extends TooManyRowsAffectedException {
+	private final int batchPosition;
+
+	public BatchedTooManyRowsAffectedException(String message, int expectedRowCount, int actualRowCount, int batchPosition) {
+		super( message, expectedRowCount, actualRowCount );
+		this.batchPosition = batchPosition;
+	}
+
+	public int getBatchPosition() {
+		return batchPosition;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/Batcher.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,163 +0,0 @@
-//$Id: Batcher.java 10040 2006-06-22 19:51:43Z steve.ebersole at jboss.com $
-package org.hibernate.jdbc;
-
-import java.sql.CallableStatement;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.ScrollMode;
-import org.hibernate.dialect.Dialect;
-
-/**
- * Manages <tt>PreparedStatement</tt>s for a session. Abstracts JDBC
- * batching to maintain the illusion that a single logical batch
- * exists for the whole session, even when batching is disabled.
- * Provides transparent <tt>PreparedStatement</tt> caching.
- *
- * @see java.sql.PreparedStatement
- * @see org.hibernate.impl.SessionImpl
- * @author Gavin King
- */
-public interface Batcher {
-	/**
-	 * Get a prepared statement for use in loading / querying. If not explicitly
-	 * released by <tt>closeQueryStatement()</tt>, it will be released when the
-	 * session is closed or disconnected.
-	 */
-	public PreparedStatement prepareQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
-	/**
-	 * Close a prepared statement opened with <tt>prepareQueryStatement()</tt>
-	 */
-	public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException;
-	/**
-	 * Get a prepared statement for use in loading / querying. If not explicitly
-	 * released by <tt>closeQueryStatement()</tt>, it will be released when the
-	 * session is closed or disconnected.
-	 */
-	public CallableStatement prepareCallableQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
-	
-	
-	/**
-	 * Get a non-batchable prepared statement to use for selecting. Does not
-	 * result in execution of the current batch.
-	 */
-	public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException;
-
-	/**
-	 * Get a non-batchable prepared statement to use for inserting / deleting / updating,
-	 * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, int)}).
-	 * <p/>
-	 * Must be explicitly released by {@link #closeStatement} after use.
-	 */
-	public PreparedStatement prepareStatement(String sql, boolean useGetGeneratedKeys) throws SQLException, HibernateException;
-
-	/**
-	 * Get a non-batchable prepared statement to use for inserting / deleting / updating.
-	 * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, String[])}).
-	 * <p/>
-	 * Must be explicitly released by {@link #closeStatement} after use.
-	 */
-	public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException, HibernateException;
-
-	/**
-	 * Get a non-batchable prepared statement to use for inserting / deleting / updating.
-	 * <p/>
-	 * Must be explicitly released by {@link #closeStatement} after use.
-	 */
-	public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException;
-
-	/**
-	 * Get a non-batchable callable statement to use for inserting / deleting / updating.
-	 * <p/>
-	 * Must be explicitly released by {@link #closeStatement} after use.
-	 */
-	public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException;
-
-	/**
-	 * Close a prepared or callable statement opened using <tt>prepareStatement()</tt> or <tt>prepareCallableStatement()</tt>
-	 */
-	public void closeStatement(PreparedStatement ps) throws SQLException;
-
-	/**
-	 * Get a batchable prepared statement to use for inserting / deleting / updating
-	 * (might be called many times before a single call to <tt>executeBatch()</tt>).
-	 * After setting parameters, call <tt>addToBatch</tt> - do not execute the
-	 * statement explicitly.
-	 * @see Batcher#addToBatch
-	 */
-	public PreparedStatement prepareBatchStatement(String sql) throws SQLException, HibernateException;
-
-	/**
-	 * Get a batchable callable statement to use for inserting / deleting / updating
-	 * (might be called many times before a single call to <tt>executeBatch()</tt>).
-	 * After setting parameters, call <tt>addToBatch</tt> - do not execute the
-	 * statement explicitly.
-	 * @see Batcher#addToBatch
-	 */
-	public CallableStatement prepareBatchCallableStatement(String sql) throws SQLException, HibernateException;
-
-	/**
-	 * Add an insert / delete / update to the current batch (might be called multiple times
-	 * for single <tt>prepareBatchStatement()</tt>)
-	 */
-	public void addToBatch(Expectation expectation) throws SQLException, HibernateException;
-
-	/**
-	 * Execute the batch
-	 */
-	public void executeBatch() throws HibernateException;
-
-	/**
-	 * Close any query statements that were left lying around
-	 */
-	public void closeStatements();
-	/**
-	 * Execute the statement and return the result set
-	 */
-	public ResultSet getResultSet(PreparedStatement ps) throws SQLException;
-	/**
-	 * Execute the statement and return the result set from a callable statement
-	 */
-	public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException;
-
-	/**
-	 * Must be called when an exception occurs
-	 * @param sqle the (not null) exception that is the reason for aborting
-	 */
-	public void abortBatch(SQLException sqle);
-
-	/**
-	 * Cancel the current query statement
-	 */
-	public void cancelLastQuery() throws HibernateException;
-
-	public boolean hasOpenResources();
-
-	public String openResourceStatsAsString();
-
-	// TODO : remove these last two as batcher is no longer managing connections
-
-	/**
-	 * Obtain a JDBC connection
-	 */
-	public Connection openConnection() throws HibernateException;
-	/**
-	 * Dispose of the JDBC connection
-	 */
-	public void closeConnection(Connection conn) throws HibernateException;
-	
-	/**
-	 * Set the transaction timeout to <tt>seconds</tt> later
-	 * than the current system time.
-	 */
-	public void setTransactionTimeout(int seconds);
-	/**
-	 * Unset the transaction timeout, called after the end of a 
-	 * transaction.
-	 */
-	public void unsetTransactionTimeout();
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/Batcher.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Batcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,186 @@
+/*
+ * 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.jdbc;
+
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.ScrollMode;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Manages <tt>PreparedStatement</tt>s for a session. Abstracts JDBC
+ * batching to maintain the illusion that a single logical batch
+ * exists for the whole session, even when batching is disabled.
+ * Provides transparent <tt>PreparedStatement</tt> caching.
+ *
+ * @see java.sql.PreparedStatement
+ * @see org.hibernate.impl.SessionImpl
+ * @author Gavin King
+ */
+public interface Batcher {
+	/**
+	 * Get a prepared statement for use in loading / querying. If not explicitly
+	 * released by <tt>closeQueryStatement()</tt>, it will be released when the
+	 * session is closed or disconnected.
+	 */
+	public PreparedStatement prepareQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
+	/**
+	 * Close a prepared statement opened with <tt>prepareQueryStatement()</tt>
+	 */
+	public void closeQueryStatement(PreparedStatement ps, ResultSet rs) throws SQLException;
+	/**
+	 * Get a prepared statement for use in loading / querying. If not explicitly
+	 * released by <tt>closeQueryStatement()</tt>, it will be released when the
+	 * session is closed or disconnected.
+	 */
+	public CallableStatement prepareCallableQueryStatement(String sql, boolean scrollable, ScrollMode scrollMode) throws SQLException, HibernateException;
+	
+	
+	/**
+	 * Get a non-batchable prepared statement to use for selecting. Does not
+	 * result in execution of the current batch.
+	 */
+	public PreparedStatement prepareSelectStatement(String sql) throws SQLException, HibernateException;
+
+	/**
+	 * Get a non-batchable prepared statement to use for inserting / deleting / updating,
+	 * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, int)}).
+	 * <p/>
+	 * Must be explicitly released by {@link #closeStatement} after use.
+	 */
+	public PreparedStatement prepareStatement(String sql, boolean useGetGeneratedKeys) throws SQLException, HibernateException;
+
+	/**
+	 * Get a non-batchable prepared statement to use for inserting / deleting / updating.
+	 * using JDBC3 getGeneratedKeys ({@link Connection#prepareStatement(String, String[])}).
+	 * <p/>
+	 * Must be explicitly released by {@link #closeStatement} after use.
+	 */
+	public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException, HibernateException;
+
+	/**
+	 * Get a non-batchable prepared statement to use for inserting / deleting / updating.
+	 * <p/>
+	 * Must be explicitly released by {@link #closeStatement} after use.
+	 */
+	public PreparedStatement prepareStatement(String sql) throws SQLException, HibernateException;
+
+	/**
+	 * Get a non-batchable callable statement to use for inserting / deleting / updating.
+	 * <p/>
+	 * Must be explicitly released by {@link #closeStatement} after use.
+	 */
+	public CallableStatement prepareCallableStatement(String sql) throws SQLException, HibernateException;
+
+	/**
+	 * Close a prepared or callable statement opened using <tt>prepareStatement()</tt> or <tt>prepareCallableStatement()</tt>
+	 */
+	public void closeStatement(PreparedStatement ps) throws SQLException;
+
+	/**
+	 * Get a batchable prepared statement to use for inserting / deleting / updating
+	 * (might be called many times before a single call to <tt>executeBatch()</tt>).
+	 * After setting parameters, call <tt>addToBatch</tt> - do not execute the
+	 * statement explicitly.
+	 * @see Batcher#addToBatch
+	 */
+	public PreparedStatement prepareBatchStatement(String sql) throws SQLException, HibernateException;
+
+	/**
+	 * Get a batchable callable statement to use for inserting / deleting / updating
+	 * (might be called many times before a single call to <tt>executeBatch()</tt>).
+	 * After setting parameters, call <tt>addToBatch</tt> - do not execute the
+	 * statement explicitly.
+	 * @see Batcher#addToBatch
+	 */
+	public CallableStatement prepareBatchCallableStatement(String sql) throws SQLException, HibernateException;
+
+	/**
+	 * Add an insert / delete / update to the current batch (might be called multiple times
+	 * for single <tt>prepareBatchStatement()</tt>)
+	 */
+	public void addToBatch(Expectation expectation) throws SQLException, HibernateException;
+
+	/**
+	 * Execute the batch
+	 */
+	public void executeBatch() throws HibernateException;
+
+	/**
+	 * Close any query statements that were left lying around
+	 */
+	public void closeStatements();
+	/**
+	 * Execute the statement and return the result set
+	 */
+	public ResultSet getResultSet(PreparedStatement ps) throws SQLException;
+	/**
+	 * Execute the statement and return the result set from a callable statement
+	 */
+	public ResultSet getResultSet(CallableStatement ps, Dialect dialect) throws SQLException;
+
+	/**
+	 * Must be called when an exception occurs
+	 * @param sqle the (not null) exception that is the reason for aborting
+	 */
+	public void abortBatch(SQLException sqle);
+
+	/**
+	 * Cancel the current query statement
+	 */
+	public void cancelLastQuery() throws HibernateException;
+
+	public boolean hasOpenResources();
+
+	public String openResourceStatsAsString();
+
+	// TODO : remove these last two as batcher is no longer managing connections
+
+	/**
+	 * Obtain a JDBC connection
+	 */
+	public Connection openConnection() throws HibernateException;
+	/**
+	 * Dispose of the JDBC connection
+	 */
+	public void closeConnection(Connection conn) throws HibernateException;
+	
+	/**
+	 * Set the transaction timeout to <tt>seconds</tt> later
+	 * than the current system time.
+	 */
+	public void setTransactionTimeout(int seconds);
+	/**
+	 * Unset the transaction timeout, called after the end of a 
+	 * transaction.
+	 */
+	public void unsetTransactionTimeout();
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: BatcherFactory.java 7683 2005-07-29 19:10:20Z maxcsaucdk $
-package org.hibernate.jdbc;
-
-import org.hibernate.Interceptor;
-
-
-/**
- * Factory for <tt>Batcher</tt> instances.
- * @author Gavin King
- */
-public interface BatcherFactory {
-	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import org.hibernate.Interceptor;
+
+
+/**
+ * Factory for <tt>Batcher</tt> instances.
+ * @author Gavin King
+ */
+public interface BatcherFactory {
+	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: BatchingBatcher.java 10040 2006-06-22 19:51:43Z steve.ebersole at jboss.com $
-package org.hibernate.jdbc;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.StaleStateException;
-
-/**
- * An implementation of the <tt>Batcher</tt> interface that
- * actually uses batching
- * @author Gavin King
- */
-public class BatchingBatcher extends AbstractBatcher {
-
-	private int batchSize;
-	private Expectation[] expectations;
-	
-	public BatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
-		super( connectionManager, interceptor );
-		expectations = new Expectation[ getFactory().getSettings().getJdbcBatchSize() ];
-	}
-
-	public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
-		if ( !expectation.canBeBatched() ) {
-			throw new HibernateException( "attempting to batch an operation which cannot be batched" );
-		}
-		PreparedStatement batchUpdate = getStatement();
-		batchUpdate.addBatch();
-		expectations[ batchSize++ ] = expectation;
-		if ( batchSize == getFactory().getSettings().getJdbcBatchSize() ) {
-			doExecuteBatch( batchUpdate );
-		}
-	}
-
-	protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
-		if ( batchSize == 0 ) {
-			log.debug( "no batched statements to execute" );
-		}
-		else {
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Executing batch size: " + batchSize );
-			}
-
-			try {
-				checkRowCounts( ps.executeBatch(), ps );
-			}
-			catch (RuntimeException re) {
-				log.error( "Exception executing batch: ", re );
-				throw re;
-			}
-			finally {
-				batchSize = 0;
-			}
-
-		}
-
-	}
-
-	private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
-		int numberOfRowCounts = rowCounts.length;
-		if ( numberOfRowCounts != batchSize ) {
-			log.warn( "JDBC driver did not return the expected number of row counts" );
-		}
-		for ( int i = 0; i < numberOfRowCounts; i++ ) {
-			expectations[i].verifyOutcome( rowCounts[i], ps, i );
-		}
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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.jdbc;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+
+/**
+ * An implementation of the <tt>Batcher</tt> interface that
+ * actually uses batching
+ * @author Gavin King
+ */
+public class BatchingBatcher extends AbstractBatcher {
+
+	private int batchSize;
+	private Expectation[] expectations;
+	
+	public BatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
+		super( connectionManager, interceptor );
+		expectations = new Expectation[ getFactory().getSettings().getJdbcBatchSize() ];
+	}
+
+	public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
+		if ( !expectation.canBeBatched() ) {
+			throw new HibernateException( "attempting to batch an operation which cannot be batched" );
+		}
+		PreparedStatement batchUpdate = getStatement();
+		batchUpdate.addBatch();
+		expectations[ batchSize++ ] = expectation;
+		if ( batchSize == getFactory().getSettings().getJdbcBatchSize() ) {
+			doExecuteBatch( batchUpdate );
+		}
+	}
+
+	protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
+		if ( batchSize == 0 ) {
+			log.debug( "no batched statements to execute" );
+		}
+		else {
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Executing batch size: " + batchSize );
+			}
+
+			try {
+				checkRowCounts( ps.executeBatch(), ps );
+			}
+			catch (RuntimeException re) {
+				log.error( "Exception executing batch: ", re );
+				throw re;
+			}
+			finally {
+				batchSize = 0;
+			}
+
+		}
+
+	}
+
+	private void checkRowCounts(int[] rowCounts, PreparedStatement ps) throws SQLException, HibernateException {
+		int numberOfRowCounts = rowCounts.length;
+		if ( numberOfRowCounts != batchSize ) {
+			log.warn( "JDBC driver did not return the expected number of row counts" );
+		}
+		for ( int i = 0; i < numberOfRowCounts; i++ ) {
+			expectations[i].verifyOutcome( rowCounts[i], ps, i );
+		}
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,19 +0,0 @@
-//$Id: BatchingBatcherFactory.java 7683 2005-07-29 19:10:20Z maxcsaucdk $
-package org.hibernate.jdbc;
-
-import org.hibernate.Interceptor;
-
-
-/**
- * A BatcherFactory implementation which constructs Batcher instances
- * capable of actually performing batch operations.
- * 
- * @author Gavin King
- */
-public class BatchingBatcherFactory implements BatcherFactory {
-
-	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
-		return new BatchingBatcher( connectionManager, interceptor );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BatchingBatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.jdbc;
+
+import org.hibernate.Interceptor;
+
+
+/**
+ * A BatcherFactory implementation which constructs Batcher instances
+ * capable of actually performing batch operations.
+ * 
+ * @author Gavin King
+ */
+public class BatchingBatcherFactory implements BatcherFactory {
+
+	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
+		return new BatchingBatcher( connectionManager, interceptor );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,117 +0,0 @@
-package org.hibernate.jdbc;
-
-import org.hibernate.HibernateException;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.lang.reflect.InvocationTargetException;
-import java.sql.Connection;
-
-/**
- * A proxy for <i>borrowed</i> connections which funnels all requests back
- * into the ConnectionManager from which it was borrowed to be properly
- * handled (in terms of connection release modes).
- * <p/>
- * Note: the term borrowed here refers to connection references obtained
- * via {@link org.hibernate.Session#connection()} for application usage.
- *
- * @author Steve Ebersole
- */
-public class BorrowedConnectionProxy implements InvocationHandler {
-
-	private static final Class[] PROXY_INTERFACES = new Class[] { Connection.class, ConnectionWrapper.class };
-
-	private final ConnectionManager connectionManager;
-	private boolean useable = true;
-
-	public BorrowedConnectionProxy(ConnectionManager connectionManager) {
-		this.connectionManager = connectionManager;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-		if ( "close".equals( method.getName() ) ) {
-			connectionManager.releaseBorrowedConnection();
-			return null;
-		}
-		// should probably no-op commit/rollback here, at least in JTA scenarios
-		if ( !useable ) {
-			throw new HibernateException( "connnection proxy not usable after transaction completion" );
-		}
-
-		if ( "getWrappedConnection".equals( method.getName() ) ) {
-			return connectionManager.getConnection();
-		}
-
-		try {
-			return method.invoke( connectionManager.getConnection(), args );
-		}
-		catch( InvocationTargetException e ) {
-			throw e.getTargetException();
-		}
-	}
-
-	/**
-	 * Generates a Connection proxy wrapping the connection managed by the passed
-	 * connection manager.
-	 *
-	 * @param connectionManager The connection manager to wrap with the
-	 * connection proxy.
-	 * @return The generated proxy.
-	 */
-	public static Connection generateProxy(ConnectionManager connectionManager) {
-		BorrowedConnectionProxy handler = new BorrowedConnectionProxy( connectionManager );
-		return ( Connection ) Proxy.newProxyInstance(
-				getProxyClassLoader(),
-		        PROXY_INTERFACES,
-		        handler
-		);
-	}
-
-	/**
-	 * Marks a borrowed connection as no longer usable.
-	 *
-	 * @param connection The connection (proxy) to be marked.
-	 */
-	public static void renderUnuseable(Connection connection) {
-		if ( connection != null && Proxy.isProxyClass( connection.getClass() ) ) {
-			InvocationHandler handler = Proxy.getInvocationHandler( connection );
-			if ( BorrowedConnectionProxy.class.isAssignableFrom( handler.getClass() ) ) {
-				( ( BorrowedConnectionProxy ) handler ).useable = false;
-			}
-		}
-	}
-
-	/**
-	 * Convience method for unwrapping a connection proxy and getting a
-	 * handle to an underlying connection.
-	 *
-	 * @param connection The connection (proxy) to be unwrapped.
-	 * @return The unwrapped connection.
-	 */
-	public static Connection getWrappedConnection(Connection connection) {
-		if ( connection != null && connection instanceof ConnectionWrapper ) {
-			return ( ( ConnectionWrapper ) connection ).getWrappedConnection();
-		}
-		else {
-			return connection;
-		}
-	}
-
-	/**
-	 * Determines the appropriate class loader to which the generated proxy
-	 * should be scoped.
-	 *
-	 * @return The class loader appropriate for proxy construction.
-	 */
-	public static ClassLoader getProxyClassLoader() {
-		ClassLoader cl = Thread.currentThread().getContextClassLoader();
-		if ( cl == null ) {
-			cl = BorrowedConnectionProxy.class.getClassLoader();
-		}
-		return cl;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/BorrowedConnectionProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,141 @@
+/*
+ * 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.jdbc;
+
+import org.hibernate.HibernateException;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationTargetException;
+import java.sql.Connection;
+
+/**
+ * A proxy for <i>borrowed</i> connections which funnels all requests back
+ * into the ConnectionManager from which it was borrowed to be properly
+ * handled (in terms of connection release modes).
+ * <p/>
+ * Note: the term borrowed here refers to connection references obtained
+ * via {@link org.hibernate.Session#connection()} for application usage.
+ *
+ * @author Steve Ebersole
+ */
+public class BorrowedConnectionProxy implements InvocationHandler {
+
+	private static final Class[] PROXY_INTERFACES = new Class[] { Connection.class, ConnectionWrapper.class };
+
+	private final ConnectionManager connectionManager;
+	private boolean useable = true;
+
+	public BorrowedConnectionProxy(ConnectionManager connectionManager) {
+		this.connectionManager = connectionManager;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+		if ( "close".equals( method.getName() ) ) {
+			connectionManager.releaseBorrowedConnection();
+			return null;
+		}
+		// should probably no-op commit/rollback here, at least in JTA scenarios
+		if ( !useable ) {
+			throw new HibernateException( "connnection proxy not usable after transaction completion" );
+		}
+
+		if ( "getWrappedConnection".equals( method.getName() ) ) {
+			return connectionManager.getConnection();
+		}
+
+		try {
+			return method.invoke( connectionManager.getConnection(), args );
+		}
+		catch( InvocationTargetException e ) {
+			throw e.getTargetException();
+		}
+	}
+
+	/**
+	 * Generates a Connection proxy wrapping the connection managed by the passed
+	 * connection manager.
+	 *
+	 * @param connectionManager The connection manager to wrap with the
+	 * connection proxy.
+	 * @return The generated proxy.
+	 */
+	public static Connection generateProxy(ConnectionManager connectionManager) {
+		BorrowedConnectionProxy handler = new BorrowedConnectionProxy( connectionManager );
+		return ( Connection ) Proxy.newProxyInstance(
+				getProxyClassLoader(),
+		        PROXY_INTERFACES,
+		        handler
+		);
+	}
+
+	/**
+	 * Marks a borrowed connection as no longer usable.
+	 *
+	 * @param connection The connection (proxy) to be marked.
+	 */
+	public static void renderUnuseable(Connection connection) {
+		if ( connection != null && Proxy.isProxyClass( connection.getClass() ) ) {
+			InvocationHandler handler = Proxy.getInvocationHandler( connection );
+			if ( BorrowedConnectionProxy.class.isAssignableFrom( handler.getClass() ) ) {
+				( ( BorrowedConnectionProxy ) handler ).useable = false;
+			}
+		}
+	}
+
+	/**
+	 * Convience method for unwrapping a connection proxy and getting a
+	 * handle to an underlying connection.
+	 *
+	 * @param connection The connection (proxy) to be unwrapped.
+	 * @return The unwrapped connection.
+	 */
+	public static Connection getWrappedConnection(Connection connection) {
+		if ( connection != null && connection instanceof ConnectionWrapper ) {
+			return ( ( ConnectionWrapper ) connection ).getWrappedConnection();
+		}
+		else {
+			return connection;
+		}
+	}
+
+	/**
+	 * Determines the appropriate class loader to which the generated proxy
+	 * should be scoped.
+	 *
+	 * @return The class loader appropriate for proxy construction.
+	 */
+	public static ClassLoader getProxyClassLoader() {
+		ClassLoader cl = Thread.currentThread().getContextClassLoader();
+		if ( cl == null ) {
+			cl = BorrowedConnectionProxy.class.getClassLoader();
+		}
+		return cl;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-// $Id: ColumnNameCache.java 5811 2005-02-20 23:02:37Z oneovthafew $
-package org.hibernate.jdbc;
-
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * Implementation of ColumnNameCache.
- *
- * @author Steve Ebersole
- */
-public class ColumnNameCache {
-
-	private final Map columnNameToIndexCache;
-
-	public ColumnNameCache(int columnCount) {
-		// should *not* need to grow beyond the size of the total number of columns in the rs
-		this.columnNameToIndexCache = new HashMap( columnCount );
-	}
-
-	public int getIndexForColumnName(String columnName, ResultSetWrapper rs)throws SQLException {
-		Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
-		if ( cached != null ) {
-			return cached.intValue();
-		}
-		else {
-			int index = rs.getTarget().findColumn( columnName );
-			columnNameToIndexCache.put( columnName, new Integer(index) );
-			return index;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ColumnNameCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Implementation of ColumnNameCache.
+ *
+ * @author Steve Ebersole
+ */
+public class ColumnNameCache {
+
+	private final Map columnNameToIndexCache;
+
+	public ColumnNameCache(int columnCount) {
+		// should *not* need to grow beyond the size of the total number of columns in the rs
+		this.columnNameToIndexCache = new HashMap( columnCount );
+	}
+
+	public int getIndexForColumnName(String columnName, ResultSetWrapper rs)throws SQLException {
+		Integer cached = ( Integer ) columnNameToIndexCache.get( columnName );
+		if ( cached != null ) {
+			return cached.intValue();
+		}
+		else {
+			int index = rs.getTarget().findColumn( columnName );
+			columnNameToIndexCache.put( columnName, new Integer(index) );
+			return index;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,539 +0,0 @@
-// $Id: ConnectionManager.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.jdbc;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.util.JDBCExceptionReporter;
-
-/**
- * Encapsulates JDBC Connection management logic needed by Hibernate.
- * <p/>
- * The lifecycle is intended to span a logical series of interactions with the
- * database.  Internally, this means the the lifecycle of the Session.
- *
- * @author Steve Ebersole
- */
-public class ConnectionManager implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger( ConnectionManager.class );
-
-	public static interface Callback {
-		public void connectionOpened();
-		public void connectionCleanedUp();
-		public boolean isTransactionInProgress();
-	}
-
-	private transient SessionFactoryImplementor factory;
-	private final Callback callback;
-
-	private final ConnectionReleaseMode releaseMode;
-	private transient Connection connection;
-	private transient Connection borrowedConnection;
-
-	private final boolean wasConnectionSupplied;
-	private transient Batcher batcher;
-	private transient Interceptor interceptor;
-	private boolean isClosed;
-	private transient boolean isFlushing;
- 
-	/**
-	 * Constructs a ConnectionManager.
-	 * <p/>
-	 * This is the form used internally.
-	 * 
-	 * @param factory The SessionFactory.
-	 * @param callback An observer for internal state change.
-	 * @param releaseMode The mode by which to release JDBC connections.
-	 * @param connection An externally supplied connection.
-	 */ 
-	public ConnectionManager(
-	        SessionFactoryImplementor factory,
-	        Callback callback,
-	        ConnectionReleaseMode releaseMode,
-	        Connection connection,
-	        Interceptor interceptor) {
-		this.factory = factory;
-		this.callback = callback;
-
-		this.interceptor = interceptor;
-		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
-
-		this.connection = connection;
-		wasConnectionSupplied = ( connection != null );
-
-		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
-	}
-
-	/**
-	 * Private constructor used exclusively from custom serialization
-	 */
-	private ConnectionManager(
-	        SessionFactoryImplementor factory,
-	        Callback callback,
-	        ConnectionReleaseMode releaseMode,
-	        Interceptor interceptor,
-	        boolean wasConnectionSupplied,
-	        boolean isClosed) {
-		this.factory = factory;
-		this.callback = callback;
-
-		this.interceptor = interceptor;
-		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
-
-		this.wasConnectionSupplied = wasConnectionSupplied;
-		this.isClosed = isClosed;
-		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
-	}
-
-	/**
-	 * The session factory.
-	 *
-	 * @return the session factory.
-	 */
-	public SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	/**
-	 * The batcher managed by this ConnectionManager.
-	 *
-	 * @return The batcher.
-	 */
-	public Batcher getBatcher() {
-		return batcher;
-	}
-
-	/**
-	 * Was the connection being used here supplied by the user?
-	 *
-	 * @return True if the user supplied the JDBC connection; false otherwise
-	 */
-	public boolean isSuppliedConnection() {
-		return wasConnectionSupplied;
-	}
-
-	/**
-	 * Retrieves the connection currently managed by this ConnectionManager.
-	 * <p/>
-	 * Note, that we may need to obtain a connection to return here if a
-	 * connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
-	 * or has previously been aggressively released (if supported in this environment).
-	 *
-	 * @return The current Connection.
-	 *
-	 * @throws HibernateException Indicates a connection is currently not
-	 * available (we are currently manually disconnected).
-	 */
-	public Connection getConnection() throws HibernateException {
-		if ( isClosed ) {
-			throw new HibernateException( "connection manager has been closed" );
-		}
-		if ( connection == null  ) {
-			openConnection();
-		}
-		return connection;
-	}
-
-	public boolean hasBorrowedConnection() {
-		// used from testsuite
-		return borrowedConnection != null;
-	}
-
-	public Connection borrowConnection() {
-		if ( isClosed ) {
-			throw new HibernateException( "connection manager has been closed" );
-		}
-		if ( isSuppliedConnection() ) {
-			return connection;
-		}
-		else {
-			if ( borrowedConnection == null ) {
-				borrowedConnection = BorrowedConnectionProxy.generateProxy( this );
-			}
-			return borrowedConnection;
-		}
-	}
-
-	public void releaseBorrowedConnection() {
-		if ( borrowedConnection != null ) {
-			try {
-				BorrowedConnectionProxy.renderUnuseable( borrowedConnection );
-			}
-			finally {
-				borrowedConnection = null;
-			}
-		}
-	}
-
-	/**
-	 * Is the connection considered "auto-commit"?
-	 *
-	 * @return True if we either do not have a connection, or the connection
-	 * really is in auto-commit mode.
-	 *
-	 * @throws SQLException Can be thrown by the Connection.isAutoCommit() check.
-	 */
-	public boolean isAutoCommit() throws SQLException {
-		return connection == null 
-			|| connection.isClosed()
-			|| connection.getAutoCommit();
-	}
-
-	/**
-	 * Will connections be released after each statement execution?
-	 * <p/>
-	 * Connections will be released after each statement if either:<ul>
-	 * <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_STATEMENT}; or
-	 * <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_TRANSACTION} but
-	 * we are in auto-commit mode.
-	 * <p/>
-	 * release-mode = {@link ConnectionReleaseMode#ON_CLOSE} should [b]never[/b] release
-	 * a connection.
-	 *
-	 * @return True if the connections will be released after each statement; false otherwise.
-	 */
-	public boolean isAggressiveRelease() {
-		if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
-			return true;
-		}
-		else if ( releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ) {
-			boolean inAutoCommitState;
-			try {
-				inAutoCommitState = isAutoCommit()&& !callback.isTransactionInProgress();
-			}
-			catch( SQLException e ) {
-				// assume we are in an auto-commit state
-				inAutoCommitState = true;
-			}
-			return inAutoCommitState;
-		}
-		return false;
-	}
-
-	/**
-	 * Modified version of {@link #isAggressiveRelease} which does not force a
-	 * transaction check.  This is solely used from our {@link #afterTransaction}
-	 * callback, so no need to do the check; plus it seems to cause problems on
-	 * websphere (god i love websphere ;)
-	 * </p>
-	 * It uses this information to decide if an aggressive release was skipped
-	 * do to open resources, and if so forces a release.
-	 *
-	 * @return True if the connections will be released after each statement; false otherwise.
-	 */
-	private boolean isAggressiveReleaseNoTransactionCheck() {
-		if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
-			return true;
-		}
-		else {
-			boolean inAutoCommitState;
-			try {
-				inAutoCommitState = isAutoCommit();
-			}
-			catch( SQLException e ) {
-				// assume we are in an auto-commit state
-				inAutoCommitState = true;
-			}
-			return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
-		}
-	}
-
-	/**
-	 * Is this ConnectionManager instance "logically" connected.  Meaning
-	 * do we either have a cached connection available or do we have the
-	 * ability to obtain a connection on demand.
-	 *
-	 * @return True if logically connected; false otherwise.
-	 */
-	public boolean isCurrentlyConnected() {
-		return wasConnectionSupplied ? connection != null : !isClosed;
-	}
-
-	/**
-	 * To be called after execution of each JDBC statement.  Used to
-	 * conditionally release the JDBC connection aggressively if
-	 * the configured release mode indicates.
-	 */
-	public void afterStatement() {
-		if ( isAggressiveRelease() ) {
-			if ( isFlushing ) {
-				log.debug( "skipping aggressive-release due to flush cycle" );
-			}
-			else if ( batcher.hasOpenResources() ) {
-				log.debug( "skipping aggresive-release due to open resources on batcher" );
-			}
-			else if ( borrowedConnection != null ) {
-				log.debug( "skipping aggresive-release due to borrowed connection" );
-			}
-			else {
-				aggressiveRelease();
-			}
-		}
-	}
-
-	/**
-	 * To be called after local transaction completion.  Used to conditionally
-	 * release the JDBC connection aggressively if the configured release mode
-	 * indicates.
-	 */
-	public void afterTransaction() {
-		if ( isAfterTransactionRelease() ) {
-			aggressiveRelease();
-		}
-		else if ( isAggressiveReleaseNoTransactionCheck() && batcher.hasOpenResources() ) {
-			log.info( "forcing batcher resource cleanup on transaction completion; forgot to close ScrollableResults/Iterator?" );
-			batcher.closeStatements();
-			aggressiveRelease();
-		}
-		else if ( isOnCloseRelease() ) {
-			// log a message about potential connection leaks
-			log.debug( "transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!" );
-		}
-		batcher.unsetTransactionTimeout();
-	}
-
-	private boolean isAfterTransactionRelease() {
-		return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION;
-	}
-
-	private boolean isOnCloseRelease() {
-		return releaseMode == ConnectionReleaseMode.ON_CLOSE;
-	}
-
-	/**
-	 * To be called after Session completion.  Used to release the JDBC
-	 * connection.
-	 *
-	 * @return The connection mantained here at time of close.  Null if
-	 * there was no connection cached internally.
-	 */
-	public Connection close() {
-		try {
-			return cleanup();
-		}
-		finally {
-			isClosed = true;
-		}
-	}
-
-	/**
-	 * Manually disconnect the underlying JDBC Connection.  The assumption here
-	 * is that the manager will be reconnected at a later point in time.
-	 *
-	 * @return The connection mantained here at time of disconnect.  Null if
-	 * there was no connection cached internally.
-	 */
-	public Connection manualDisconnect() {
-		return cleanup();
-	}
-
-	/**
-	 * Manually reconnect the underlying JDBC Connection.  Should be called at
-	 * some point after manualDisconnect().
-	 * <p/>
-	 * This form is used for ConnectionProvider-supplied connections.
-	 */
-	public void manualReconnect() {
-	}
-
-	/**
-	 * Manually reconnect the underlying JDBC Connection.  Should be called at
-	 * some point after manualDisconnect().
-	 * <p/>
-	 * This form is used for user-supplied connections.
-	 */
-	public void manualReconnect(Connection suppliedConnection) {
-		this.connection = suppliedConnection;
-	}
-
-	/**
-	 * Releases the Connection and cleans up any resources associated with
-	 * that Connection.  This is intended for use:
-	 * 1) at the end of the session
-	 * 2) on a manual disconnect of the session
-	 * 3) from afterTransaction(), in the case of skipped aggressive releasing
-	 *
-	 * @return The released connection.
-	 * @throws HibernateException
-	 */
-	private Connection cleanup() throws HibernateException {
-		releaseBorrowedConnection();
-
-		if ( connection == null ) {
-			log.trace( "connection already null in cleanup : no action");
-			return null;
-		}
-
-		try {
-			log.trace( "performing cleanup" );
-
-			batcher.closeStatements();
-			Connection c = null;
-			if ( !wasConnectionSupplied ) {
-				closeConnection();
-			}
-			else {
-				c = connection;
-			}
-			connection = null;
-			return c;
-		}
-		finally {
-			callback.connectionCleanedUp();
-		}
-	}
-
-	/**
-	 * Performs actions required to perform an aggressive release of the
-	 * JDBC Connection.
-	 */
-	private void aggressiveRelease() {
-		if ( !wasConnectionSupplied ) {
-			log.debug( "aggressively releasing JDBC connection" );
-			if ( connection != null ) {
-				closeConnection();
-			}
-		}
-	}
-
-	/**
-	 * Pysically opens a JDBC Connection.
-	 *
-	 * @throws HibernateException
-	 */
-	private void openConnection() throws HibernateException {
-		if ( connection != null ) {
-			return;
-		}
-
-		log.debug("opening JDBC connection");
-		try {
-			connection = factory.getConnectionProvider().getConnection();
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					factory.getSQLExceptionConverter(),
-					sqle,
-					"Cannot open connection"
-				);
-		}
-
-		callback.connectionOpened(); // register synch; stats.connect()
-	}
-
-	/**
-	 * Physically closes the JDBC Connection.
-	 */
-	private void closeConnection() {
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"releasing JDBC connection [" +
-					batcher.openResourceStatsAsString() + "]"
-				);
-		}
-
-		try {
-			if ( !connection.isClosed() ) {
-				JDBCExceptionReporter.logAndClearWarnings( connection );
-			}
-			factory.getConnectionProvider().closeConnection( connection );
-			connection = null;
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert( 
-					factory.getSQLExceptionConverter(), 
-					sqle, 
-					"Cannot release connection"
-				);
-		}
-	}
-
-	/**
-	 * Callback to let us know that a flush is beginning.  We use this fact
-	 * to temporarily circumvent aggressive connection releasing until after
-	 * the flush cycle is complete {@link #flushEnding()}
-	 */
-	public void flushBeginning() {
-		log.trace( "registering flush begin" );
-		isFlushing = true;
-	}
-
-	/**
-	 * Callback to let us know that a flush is ending.  We use this fact to
-	 * stop circumventing aggressive releasing connections.
-	 */
-	public void flushEnding() {
-		log.trace( "registering flush end" );
-		isFlushing = false;
-		afterStatement();
-	}
-
-	public boolean isReadyForSerialization() {
-		return wasConnectionSupplied ? connection == null : !batcher.hasOpenResources();
-	}
-
-	/**
-	 * Used during serialization.
-	 *
-	 * @param oos The stream to which we are being written.
-	 * @throws IOException Indicates an I/O error writing to the stream
-	 */
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		if ( !isReadyForSerialization() ) {
-			throw new IllegalStateException( "Cannot serialize a ConnectionManager while connected" );
-		}
-
-		oos.writeObject( factory );
-		oos.writeObject( interceptor );
-		oos.defaultWriteObject();
-	}
-
-	/**
-	 * Used during deserialization.
-	 *
-	 * @param ois The stream from which we are being read.
-	 * @throws IOException Indicates an I/O error reading the stream
-	 * @throws ClassNotFoundException Indicates resource class resolution.
-	 */
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		factory = (SessionFactoryImplementor) ois.readObject();
-		interceptor = (Interceptor) ois.readObject();
-		ois.defaultReadObject();
-
-		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
-	}
-
-	public void serialize(ObjectOutputStream oos) throws IOException {
-		oos.writeBoolean( wasConnectionSupplied );
-		oos.writeBoolean( isClosed );
-	}
-
-	public static ConnectionManager deserialize(
-			ObjectInputStream ois,
-	        SessionFactoryImplementor factory,
-	        Interceptor interceptor,
-	        ConnectionReleaseMode connectionReleaseMode,
-	        JDBCContext jdbcContext) throws IOException {
-		return new ConnectionManager(
-				factory,
-		        jdbcContext,
-		        connectionReleaseMode,
-		        interceptor,
-		        ois.readBoolean(),
-		        ois.readBoolean()
-		);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionManager.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,562 @@
+/*
+ * 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.jdbc;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.util.JDBCExceptionReporter;
+
+/**
+ * Encapsulates JDBC Connection management logic needed by Hibernate.
+ * <p/>
+ * The lifecycle is intended to span a logical series of interactions with the
+ * database.  Internally, this means the the lifecycle of the Session.
+ *
+ * @author Steve Ebersole
+ */
+public class ConnectionManager implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger( ConnectionManager.class );
+
+	public static interface Callback {
+		public void connectionOpened();
+		public void connectionCleanedUp();
+		public boolean isTransactionInProgress();
+	}
+
+	private transient SessionFactoryImplementor factory;
+	private final Callback callback;
+
+	private final ConnectionReleaseMode releaseMode;
+	private transient Connection connection;
+	private transient Connection borrowedConnection;
+
+	private final boolean wasConnectionSupplied;
+	private transient Batcher batcher;
+	private transient Interceptor interceptor;
+	private boolean isClosed;
+	private transient boolean isFlushing;
+ 
+	/**
+	 * Constructs a ConnectionManager.
+	 * <p/>
+	 * This is the form used internally.
+	 * 
+	 * @param factory The SessionFactory.
+	 * @param callback An observer for internal state change.
+	 * @param releaseMode The mode by which to release JDBC connections.
+	 * @param connection An externally supplied connection.
+	 */ 
+	public ConnectionManager(
+	        SessionFactoryImplementor factory,
+	        Callback callback,
+	        ConnectionReleaseMode releaseMode,
+	        Connection connection,
+	        Interceptor interceptor) {
+		this.factory = factory;
+		this.callback = callback;
+
+		this.interceptor = interceptor;
+		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
+
+		this.connection = connection;
+		wasConnectionSupplied = ( connection != null );
+
+		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
+	}
+
+	/**
+	 * Private constructor used exclusively from custom serialization
+	 */
+	private ConnectionManager(
+	        SessionFactoryImplementor factory,
+	        Callback callback,
+	        ConnectionReleaseMode releaseMode,
+	        Interceptor interceptor,
+	        boolean wasConnectionSupplied,
+	        boolean isClosed) {
+		this.factory = factory;
+		this.callback = callback;
+
+		this.interceptor = interceptor;
+		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
+
+		this.wasConnectionSupplied = wasConnectionSupplied;
+		this.isClosed = isClosed;
+		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
+	}
+
+	/**
+	 * The session factory.
+	 *
+	 * @return the session factory.
+	 */
+	public SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	/**
+	 * The batcher managed by this ConnectionManager.
+	 *
+	 * @return The batcher.
+	 */
+	public Batcher getBatcher() {
+		return batcher;
+	}
+
+	/**
+	 * Was the connection being used here supplied by the user?
+	 *
+	 * @return True if the user supplied the JDBC connection; false otherwise
+	 */
+	public boolean isSuppliedConnection() {
+		return wasConnectionSupplied;
+	}
+
+	/**
+	 * Retrieves the connection currently managed by this ConnectionManager.
+	 * <p/>
+	 * Note, that we may need to obtain a connection to return here if a
+	 * connection has either not yet been obtained (non-UserSuppliedConnectionProvider)
+	 * or has previously been aggressively released (if supported in this environment).
+	 *
+	 * @return The current Connection.
+	 *
+	 * @throws HibernateException Indicates a connection is currently not
+	 * available (we are currently manually disconnected).
+	 */
+	public Connection getConnection() throws HibernateException {
+		if ( isClosed ) {
+			throw new HibernateException( "connection manager has been closed" );
+		}
+		if ( connection == null  ) {
+			openConnection();
+		}
+		return connection;
+	}
+
+	public boolean hasBorrowedConnection() {
+		// used from testsuite
+		return borrowedConnection != null;
+	}
+
+	public Connection borrowConnection() {
+		if ( isClosed ) {
+			throw new HibernateException( "connection manager has been closed" );
+		}
+		if ( isSuppliedConnection() ) {
+			return connection;
+		}
+		else {
+			if ( borrowedConnection == null ) {
+				borrowedConnection = BorrowedConnectionProxy.generateProxy( this );
+			}
+			return borrowedConnection;
+		}
+	}
+
+	public void releaseBorrowedConnection() {
+		if ( borrowedConnection != null ) {
+			try {
+				BorrowedConnectionProxy.renderUnuseable( borrowedConnection );
+			}
+			finally {
+				borrowedConnection = null;
+			}
+		}
+	}
+
+	/**
+	 * Is the connection considered "auto-commit"?
+	 *
+	 * @return True if we either do not have a connection, or the connection
+	 * really is in auto-commit mode.
+	 *
+	 * @throws SQLException Can be thrown by the Connection.isAutoCommit() check.
+	 */
+	public boolean isAutoCommit() throws SQLException {
+		return connection == null 
+			|| connection.isClosed()
+			|| connection.getAutoCommit();
+	}
+
+	/**
+	 * Will connections be released after each statement execution?
+	 * <p/>
+	 * Connections will be released after each statement if either:<ul>
+	 * <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_STATEMENT}; or
+	 * <li>the defined release-mode is {@link ConnectionReleaseMode#AFTER_TRANSACTION} but
+	 * we are in auto-commit mode.
+	 * <p/>
+	 * release-mode = {@link ConnectionReleaseMode#ON_CLOSE} should [b]never[/b] release
+	 * a connection.
+	 *
+	 * @return True if the connections will be released after each statement; false otherwise.
+	 */
+	public boolean isAggressiveRelease() {
+		if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
+			return true;
+		}
+		else if ( releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION ) {
+			boolean inAutoCommitState;
+			try {
+				inAutoCommitState = isAutoCommit()&& !callback.isTransactionInProgress();
+			}
+			catch( SQLException e ) {
+				// assume we are in an auto-commit state
+				inAutoCommitState = true;
+			}
+			return inAutoCommitState;
+		}
+		return false;
+	}
+
+	/**
+	 * Modified version of {@link #isAggressiveRelease} which does not force a
+	 * transaction check.  This is solely used from our {@link #afterTransaction}
+	 * callback, so no need to do the check; plus it seems to cause problems on
+	 * websphere (god i love websphere ;)
+	 * </p>
+	 * It uses this information to decide if an aggressive release was skipped
+	 * do to open resources, and if so forces a release.
+	 *
+	 * @return True if the connections will be released after each statement; false otherwise.
+	 */
+	private boolean isAggressiveReleaseNoTransactionCheck() {
+		if ( releaseMode == ConnectionReleaseMode.AFTER_STATEMENT ) {
+			return true;
+		}
+		else {
+			boolean inAutoCommitState;
+			try {
+				inAutoCommitState = isAutoCommit();
+			}
+			catch( SQLException e ) {
+				// assume we are in an auto-commit state
+				inAutoCommitState = true;
+			}
+			return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;
+		}
+	}
+
+	/**
+	 * Is this ConnectionManager instance "logically" connected.  Meaning
+	 * do we either have a cached connection available or do we have the
+	 * ability to obtain a connection on demand.
+	 *
+	 * @return True if logically connected; false otherwise.
+	 */
+	public boolean isCurrentlyConnected() {
+		return wasConnectionSupplied ? connection != null : !isClosed;
+	}
+
+	/**
+	 * To be called after execution of each JDBC statement.  Used to
+	 * conditionally release the JDBC connection aggressively if
+	 * the configured release mode indicates.
+	 */
+	public void afterStatement() {
+		if ( isAggressiveRelease() ) {
+			if ( isFlushing ) {
+				log.debug( "skipping aggressive-release due to flush cycle" );
+			}
+			else if ( batcher.hasOpenResources() ) {
+				log.debug( "skipping aggresive-release due to open resources on batcher" );
+			}
+			else if ( borrowedConnection != null ) {
+				log.debug( "skipping aggresive-release due to borrowed connection" );
+			}
+			else {
+				aggressiveRelease();
+			}
+		}
+	}
+
+	/**
+	 * To be called after local transaction completion.  Used to conditionally
+	 * release the JDBC connection aggressively if the configured release mode
+	 * indicates.
+	 */
+	public void afterTransaction() {
+		if ( isAfterTransactionRelease() ) {
+			aggressiveRelease();
+		}
+		else if ( isAggressiveReleaseNoTransactionCheck() && batcher.hasOpenResources() ) {
+			log.info( "forcing batcher resource cleanup on transaction completion; forgot to close ScrollableResults/Iterator?" );
+			batcher.closeStatements();
+			aggressiveRelease();
+		}
+		else if ( isOnCloseRelease() ) {
+			// log a message about potential connection leaks
+			log.debug( "transaction completed on session with on_close connection release mode; be sure to close the session to release JDBC resources!" );
+		}
+		batcher.unsetTransactionTimeout();
+	}
+
+	private boolean isAfterTransactionRelease() {
+		return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION;
+	}
+
+	private boolean isOnCloseRelease() {
+		return releaseMode == ConnectionReleaseMode.ON_CLOSE;
+	}
+
+	/**
+	 * To be called after Session completion.  Used to release the JDBC
+	 * connection.
+	 *
+	 * @return The connection mantained here at time of close.  Null if
+	 * there was no connection cached internally.
+	 */
+	public Connection close() {
+		try {
+			return cleanup();
+		}
+		finally {
+			isClosed = true;
+		}
+	}
+
+	/**
+	 * Manually disconnect the underlying JDBC Connection.  The assumption here
+	 * is that the manager will be reconnected at a later point in time.
+	 *
+	 * @return The connection mantained here at time of disconnect.  Null if
+	 * there was no connection cached internally.
+	 */
+	public Connection manualDisconnect() {
+		return cleanup();
+	}
+
+	/**
+	 * Manually reconnect the underlying JDBC Connection.  Should be called at
+	 * some point after manualDisconnect().
+	 * <p/>
+	 * This form is used for ConnectionProvider-supplied connections.
+	 */
+	public void manualReconnect() {
+	}
+
+	/**
+	 * Manually reconnect the underlying JDBC Connection.  Should be called at
+	 * some point after manualDisconnect().
+	 * <p/>
+	 * This form is used for user-supplied connections.
+	 */
+	public void manualReconnect(Connection suppliedConnection) {
+		this.connection = suppliedConnection;
+	}
+
+	/**
+	 * Releases the Connection and cleans up any resources associated with
+	 * that Connection.  This is intended for use:
+	 * 1) at the end of the session
+	 * 2) on a manual disconnect of the session
+	 * 3) from afterTransaction(), in the case of skipped aggressive releasing
+	 *
+	 * @return The released connection.
+	 * @throws HibernateException
+	 */
+	private Connection cleanup() throws HibernateException {
+		releaseBorrowedConnection();
+
+		if ( connection == null ) {
+			log.trace( "connection already null in cleanup : no action");
+			return null;
+		}
+
+		try {
+			log.trace( "performing cleanup" );
+
+			batcher.closeStatements();
+			Connection c = null;
+			if ( !wasConnectionSupplied ) {
+				closeConnection();
+			}
+			else {
+				c = connection;
+			}
+			connection = null;
+			return c;
+		}
+		finally {
+			callback.connectionCleanedUp();
+		}
+	}
+
+	/**
+	 * Performs actions required to perform an aggressive release of the
+	 * JDBC Connection.
+	 */
+	private void aggressiveRelease() {
+		if ( !wasConnectionSupplied ) {
+			log.debug( "aggressively releasing JDBC connection" );
+			if ( connection != null ) {
+				closeConnection();
+			}
+		}
+	}
+
+	/**
+	 * Pysically opens a JDBC Connection.
+	 *
+	 * @throws HibernateException
+	 */
+	private void openConnection() throws HibernateException {
+		if ( connection != null ) {
+			return;
+		}
+
+		log.debug("opening JDBC connection");
+		try {
+			connection = factory.getConnectionProvider().getConnection();
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					factory.getSQLExceptionConverter(),
+					sqle,
+					"Cannot open connection"
+				);
+		}
+
+		callback.connectionOpened(); // register synch; stats.connect()
+	}
+
+	/**
+	 * Physically closes the JDBC Connection.
+	 */
+	private void closeConnection() {
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"releasing JDBC connection [" +
+					batcher.openResourceStatsAsString() + "]"
+				);
+		}
+
+		try {
+			if ( !connection.isClosed() ) {
+				JDBCExceptionReporter.logAndClearWarnings( connection );
+			}
+			factory.getConnectionProvider().closeConnection( connection );
+			connection = null;
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert( 
+					factory.getSQLExceptionConverter(), 
+					sqle, 
+					"Cannot release connection"
+				);
+		}
+	}
+
+	/**
+	 * Callback to let us know that a flush is beginning.  We use this fact
+	 * to temporarily circumvent aggressive connection releasing until after
+	 * the flush cycle is complete {@link #flushEnding()}
+	 */
+	public void flushBeginning() {
+		log.trace( "registering flush begin" );
+		isFlushing = true;
+	}
+
+	/**
+	 * Callback to let us know that a flush is ending.  We use this fact to
+	 * stop circumventing aggressive releasing connections.
+	 */
+	public void flushEnding() {
+		log.trace( "registering flush end" );
+		isFlushing = false;
+		afterStatement();
+	}
+
+	public boolean isReadyForSerialization() {
+		return wasConnectionSupplied ? connection == null : !batcher.hasOpenResources();
+	}
+
+	/**
+	 * Used during serialization.
+	 *
+	 * @param oos The stream to which we are being written.
+	 * @throws IOException Indicates an I/O error writing to the stream
+	 */
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		if ( !isReadyForSerialization() ) {
+			throw new IllegalStateException( "Cannot serialize a ConnectionManager while connected" );
+		}
+
+		oos.writeObject( factory );
+		oos.writeObject( interceptor );
+		oos.defaultWriteObject();
+	}
+
+	/**
+	 * Used during deserialization.
+	 *
+	 * @param ois The stream from which we are being read.
+	 * @throws IOException Indicates an I/O error reading the stream
+	 * @throws ClassNotFoundException Indicates resource class resolution.
+	 */
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		factory = (SessionFactoryImplementor) ois.readObject();
+		interceptor = (Interceptor) ois.readObject();
+		ois.defaultReadObject();
+
+		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );
+	}
+
+	public void serialize(ObjectOutputStream oos) throws IOException {
+		oos.writeBoolean( wasConnectionSupplied );
+		oos.writeBoolean( isClosed );
+	}
+
+	public static ConnectionManager deserialize(
+			ObjectInputStream ois,
+	        SessionFactoryImplementor factory,
+	        Interceptor interceptor,
+	        ConnectionReleaseMode connectionReleaseMode,
+	        JDBCContext jdbcContext) throws IOException {
+		return new ConnectionManager(
+				factory,
+		        jdbcContext,
+		        connectionReleaseMode,
+		        interceptor,
+		        ois.readBoolean(),
+		        ois.readBoolean()
+		);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-package org.hibernate.jdbc;
-
-import java.sql.Connection;
-
-/**
- * Interface implemented by JDBC connection wrappers in order to give
- * access to the underlying wrapped connection.
- *
- * @author Steve Ebersole
- */
-public interface ConnectionWrapper {
-	/**
-	 * Get a reference to the wrapped connection.
-	 *
-	 * @return The wrapped connection.
-	 */
-	public Connection getWrappedConnection();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ConnectionWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.jdbc;
+
+import java.sql.Connection;
+
+/**
+ * Interface implemented by JDBC connection wrappers in order to give
+ * access to the underlying wrapped connection.
+ *
+ * @author Steve Ebersole
+ */
+public interface ConnectionWrapper {
+	/**
+	 * Get a reference to the wrapped connection.
+	 *
+	 * @return The wrapped connection.
+	 */
+	public Connection getWrappedConnection();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/Expectation.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,17 +0,0 @@
-package org.hibernate.jdbc;
-
-import org.hibernate.HibernateException;
-
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-
-/**
- * Defines an expected DML operation outcome.
- *
- * @author Steve Ebersole
- */
-public interface Expectation {
-	public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) throws SQLException, HibernateException;
-	public int prepare(PreparedStatement statement) throws SQLException, HibernateException;
-	public boolean canBeBatched();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/Expectation.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectation.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import org.hibernate.HibernateException;
+
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+
+/**
+ * Defines an expected DML operation outcome.
+ *
+ * @author Steve Ebersole
+ */
+public interface Expectation {
+	/**
+	 * Perform verification of the outcome of the RDBMS operation based on
+	 * the type of expectation defined.
+	 *
+	 * @param rowCount The RDBMS reported "number of rows affected".
+	 * @param statement The statement representing the operation
+	 * @param batchPosition The position in the batch (if batching)
+	 * @throws SQLException Exception from the JDBC driver
+	 * @throws HibernateException Problem processing the outcome.
+	 */
+	public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) throws SQLException, HibernateException;
+
+	/**
+	 * Perform any special statement preparation.
+	 *
+	 * @param statement The statement to be prepared
+	 * @return The number of bind positions consumed (if any)
+	 * @throws SQLException Exception from the JDBC driver
+	 * @throws HibernateException Problem performing preparation.
+	 */
+	public int prepare(PreparedStatement statement) throws SQLException, HibernateException;
+
+	/**
+	 * Is it acceptable to combiner this expectation with statement batching?
+	 *
+	 * @return True if batching can be combined with this expectation; false otherwise.
+	 */
+	public boolean canBeBatched();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/Expectations.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,174 +0,0 @@
-package org.hibernate.jdbc;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.StaleStateException;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.util.JDBCExceptionReporter;
-import org.hibernate.exception.GenericJDBCException;
-
-import java.sql.CallableStatement;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-import java.sql.Types;
-
-/**
- * Holds various often used {@link Expectation} definitions.
- *
- * @author Steve Ebersole
- */
-public class Expectations {
-	private static final Logger log = LoggerFactory.getLogger( Expectations.class );
-
-	public static final int USUAL_EXPECTED_COUNT = 1;
-	public static final int USUAL_PARAM_POSITION = 1;
-
-
-	// Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public static class BasicExpectation implements Expectation {
-		private final int expectedRowCount;
-
-		protected BasicExpectation(int expectedRowCount) {
-			this.expectedRowCount = expectedRowCount;
-			if ( expectedRowCount < 0 ) {
-				throw new IllegalArgumentException( "Expected row count must be greater than zero" );
-			}
-		}
-
-		public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
-			rowCount = determineRowCount( rowCount, statement );
-			if ( batchPosition < 0 ) {
-				checkNonBatched( rowCount );
-			}
-			else {
-				checkBatched( rowCount, batchPosition );
-			}
-		}
-
-		private void checkBatched(int rowCount, int batchPosition) {
-			if ( rowCount == -2 ) {
-				if ( log.isDebugEnabled() ) {
-					log.debug( "success of batch update unknown: " + batchPosition );
-				}
-			}
-			else if ( rowCount == -3 ) {
-				throw new BatchFailedException( "Batch update failed: " + batchPosition );
-			}
-			else {
-				if ( expectedRowCount > rowCount ) {
-					throw new StaleStateException(
-							"Batch update returned unexpected row count from update [" + batchPosition +
-							"]; actual row count: " + rowCount +
-							"; expected: " + expectedRowCount
-					);
-				}
-				if ( expectedRowCount < rowCount ) {
-					String msg = "Batch update returned unexpected row count from update [" +
-					             batchPosition + "]; actual row count: " + rowCount +
-					             "; expected: " + expectedRowCount;
-					throw new BatchedTooManyRowsAffectedException( msg, expectedRowCount, rowCount, batchPosition );
-				}
-			}
-		}
-
-		private void checkNonBatched(int rowCount) {
-			if ( expectedRowCount > rowCount ) {
-				throw new StaleStateException(
-						"Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
-				);
-			}
-			if ( expectedRowCount < rowCount ) {
-				String msg = "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount;
-				throw new TooManyRowsAffectedException( msg, expectedRowCount, rowCount );
-			}
-		}
-
-		public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
-			return 0;
-		}
-
-		public boolean canBeBatched() {
-			return true;
-		}
-
-		protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
-			return reportedRowCount;
-		}
-	}
-
-	public static class BasicParamExpectation extends BasicExpectation {
-		private final int parameterPosition;
-		protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
-			super( expectedRowCount );
-			this.parameterPosition = parameterPosition;
-		}
-
-		public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
-			toCallableStatement( statement ).registerOutParameter( parameterPosition, Types.NUMERIC );
-			return 1;
-		}
-
-		public boolean canBeBatched() {
-			return false;
-		}
-
-		protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
-			try {
-				return toCallableStatement( statement ).getInt( parameterPosition );
-			}
-			catch( SQLException sqle ) {
-				JDBCExceptionReporter.logExceptions( sqle, "could not extract row counts from CallableStatement" );
-				throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
-			}
-		}
-
-		private CallableStatement toCallableStatement(PreparedStatement statement) {
-			if ( ! CallableStatement.class.isInstance( statement ) ) {
-				throw new HibernateException( "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass() );
-			}
-			return ( CallableStatement ) statement;
-		}
-	}
-
-
-	// Various Expectation instances ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public static final Expectation NONE = new Expectation() {
-		public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
-			// explicitly perform no checking...
-		}
-
-		public int prepare(PreparedStatement statement) {
-			return 0;
-		}
-
-		public boolean canBeBatched() {
-			return true;
-		}
-	};
-
-	public static final Expectation BASIC = new BasicExpectation( USUAL_EXPECTED_COUNT );
-
-	public static final Expectation PARAM = new BasicParamExpectation( USUAL_EXPECTED_COUNT, USUAL_PARAM_POSITION );
-
-
-	public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
-		if ( style == ExecuteUpdateResultCheckStyle.NONE ) {
-			return NONE;
-		}
-		else if ( style == ExecuteUpdateResultCheckStyle.COUNT ) {
-			return BASIC;
-		}
-		else if ( style == ExecuteUpdateResultCheckStyle.PARAM ) {
-			return PARAM;
-		}
-		else {
-			throw new HibernateException( "unknown check style : " + style );
-		}
-	}
-
-	private Expectations() {
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/Expectations.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Expectations.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,198 @@
+/*
+ * 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.jdbc;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.StaleStateException;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.util.JDBCExceptionReporter;
+import org.hibernate.exception.GenericJDBCException;
+
+import java.sql.CallableStatement;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+
+/**
+ * Holds various often used {@link Expectation} definitions.
+ *
+ * @author Steve Ebersole
+ */
+public class Expectations {
+	private static final Logger log = LoggerFactory.getLogger( Expectations.class );
+
+	public static final int USUAL_EXPECTED_COUNT = 1;
+	public static final int USUAL_PARAM_POSITION = 1;
+
+
+	// Base Expectation impls ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public static class BasicExpectation implements Expectation {
+		private final int expectedRowCount;
+
+		protected BasicExpectation(int expectedRowCount) {
+			this.expectedRowCount = expectedRowCount;
+			if ( expectedRowCount < 0 ) {
+				throw new IllegalArgumentException( "Expected row count must be greater than zero" );
+			}
+		}
+
+		public final void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
+			rowCount = determineRowCount( rowCount, statement );
+			if ( batchPosition < 0 ) {
+				checkNonBatched( rowCount );
+			}
+			else {
+				checkBatched( rowCount, batchPosition );
+			}
+		}
+
+		private void checkBatched(int rowCount, int batchPosition) {
+			if ( rowCount == -2 ) {
+				if ( log.isDebugEnabled() ) {
+					log.debug( "success of batch update unknown: " + batchPosition );
+				}
+			}
+			else if ( rowCount == -3 ) {
+				throw new BatchFailedException( "Batch update failed: " + batchPosition );
+			}
+			else {
+				if ( expectedRowCount > rowCount ) {
+					throw new StaleStateException(
+							"Batch update returned unexpected row count from update [" + batchPosition +
+							"]; actual row count: " + rowCount +
+							"; expected: " + expectedRowCount
+					);
+				}
+				if ( expectedRowCount < rowCount ) {
+					String msg = "Batch update returned unexpected row count from update [" +
+					             batchPosition + "]; actual row count: " + rowCount +
+					             "; expected: " + expectedRowCount;
+					throw new BatchedTooManyRowsAffectedException( msg, expectedRowCount, rowCount, batchPosition );
+				}
+			}
+		}
+
+		private void checkNonBatched(int rowCount) {
+			if ( expectedRowCount > rowCount ) {
+				throw new StaleStateException(
+						"Unexpected row count: " + rowCount + "; expected: " + expectedRowCount
+				);
+			}
+			if ( expectedRowCount < rowCount ) {
+				String msg = "Unexpected row count: " + rowCount + "; expected: " + expectedRowCount;
+				throw new TooManyRowsAffectedException( msg, expectedRowCount, rowCount );
+			}
+		}
+
+		public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
+			return 0;
+		}
+
+		public boolean canBeBatched() {
+			return true;
+		}
+
+		protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
+			return reportedRowCount;
+		}
+	}
+
+	public static class BasicParamExpectation extends BasicExpectation {
+		private final int parameterPosition;
+		protected BasicParamExpectation(int expectedRowCount, int parameterPosition) {
+			super( expectedRowCount );
+			this.parameterPosition = parameterPosition;
+		}
+
+		public int prepare(PreparedStatement statement) throws SQLException, HibernateException {
+			toCallableStatement( statement ).registerOutParameter( parameterPosition, Types.NUMERIC );
+			return 1;
+		}
+
+		public boolean canBeBatched() {
+			return false;
+		}
+
+		protected int determineRowCount(int reportedRowCount, PreparedStatement statement) {
+			try {
+				return toCallableStatement( statement ).getInt( parameterPosition );
+			}
+			catch( SQLException sqle ) {
+				JDBCExceptionReporter.logExceptions( sqle, "could not extract row counts from CallableStatement" );
+				throw new GenericJDBCException( "could not extract row counts from CallableStatement", sqle );
+			}
+		}
+
+		private CallableStatement toCallableStatement(PreparedStatement statement) {
+			if ( ! CallableStatement.class.isInstance( statement ) ) {
+				throw new HibernateException( "BasicParamExpectation operates exclusively on CallableStatements : " + statement.getClass() );
+			}
+			return ( CallableStatement ) statement;
+		}
+	}
+
+
+	// Various Expectation instances ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public static final Expectation NONE = new Expectation() {
+		public void verifyOutcome(int rowCount, PreparedStatement statement, int batchPosition) {
+			// explicitly perform no checking...
+		}
+
+		public int prepare(PreparedStatement statement) {
+			return 0;
+		}
+
+		public boolean canBeBatched() {
+			return true;
+		}
+	};
+
+	public static final Expectation BASIC = new BasicExpectation( USUAL_EXPECTED_COUNT );
+
+	public static final Expectation PARAM = new BasicParamExpectation( USUAL_EXPECTED_COUNT, USUAL_PARAM_POSITION );
+
+
+	public static Expectation appropriateExpectation(ExecuteUpdateResultCheckStyle style) {
+		if ( style == ExecuteUpdateResultCheckStyle.NONE ) {
+			return NONE;
+		}
+		else if ( style == ExecuteUpdateResultCheckStyle.COUNT ) {
+			return BASIC;
+		}
+		else if ( style == ExecuteUpdateResultCheckStyle.PARAM ) {
+			return PARAM;
+		}
+		else {
+			throw new HibernateException( "unknown check style : " + style );
+		}
+	}
+
+	private Expectations() {
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/JDBCContext.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,317 +0,0 @@
-// $Id: JDBCContext.java 10476 2006-09-08 21:00:48Z epbernard $
-package org.hibernate.jdbc;
-
-import java.io.Serializable;
-import java.io.ObjectOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-import org.hibernate.SessionException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.util.JTAHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.transaction.CacheSynchronization;
-import org.hibernate.transaction.TransactionFactory;
-
-/**
- * Acts as the mediary between "entity-mode related" sessions in terms of
- * their interaction with the JDBC data store.
- *
- * @author Steve Ebersole
- */
-public class JDBCContext implements Serializable, ConnectionManager.Callback {
-
-	// TODO : make this the factory for "entity mode related" sessions;
-	// also means making this the target of transaction-synch and the
-	// thing that knows how to cascade things between related sessions
-	//
-	// At that point, perhaps this thing is a "SessionContext", and
-	// ConnectionManager is a "JDBCContext"?  A "SessionContext" should
-	// live in the impl package...
-
-	private static final Logger log = LoggerFactory.getLogger( JDBCContext.class );
-
-	public static interface Context extends TransactionFactory.Context {
-		/**
-		 * We cannot rely upon this method being called! It is only
-		 * called if we are using Hibernate Transaction API.
-		 */
-		public void afterTransactionBegin(Transaction tx);
-		public void beforeTransactionCompletion(Transaction tx);
-		public void afterTransactionCompletion(boolean success, Transaction tx);
-		public ConnectionReleaseMode getConnectionReleaseMode();
-		public boolean isAutoCloseSessionEnabled();
-	}
-
-	private Context owner;
-	private ConnectionManager connectionManager;
-	private transient boolean isTransactionCallbackRegistered;
-	private transient Transaction hibernateTransaction;
-
-	public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
-		this.owner = owner;
-		this.connectionManager = new ConnectionManager(
-		        owner.getFactory(),
-		        this,
-		        owner.getConnectionReleaseMode(),
-		        connection,
-		        interceptor
-			);
-
-		final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
-		        || owner.isFlushBeforeCompletionEnabled()
-		        || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
-		if ( registerSynchronization ) {
-			registerSynchronizationIfPossible();
-		}
-	}
-
-	/**
-	 * Private constructor used exclusively for custom serialization...
-	 *
-	 */
-	private JDBCContext() {
-	}
-
-	// ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public void connectionOpened() {
-		if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
-			owner.getFactory().getStatisticsImplementor().connect();
-		}
-	}
-
-	public void connectionCleanedUp() {
-		if ( !isTransactionCallbackRegistered ) {
-			afterTransactionCompletion( false, null );
-			// Note : success = false, because we don't know the outcome of the transaction
-		}
-	}
-
-	public SessionFactoryImplementor getFactory() {
-		return owner.getFactory();
-	}
-
-	public ConnectionManager getConnectionManager() {
-		return connectionManager;
-	}
-
-	public Connection borrowConnection() {
-		return connectionManager.borrowConnection();
-	}
-	
-	public Connection connection() throws HibernateException {
-		if ( owner.isClosed() ) {
-			throw new SessionException( "Session is closed" );
-		}
-
-		return connectionManager.getConnection();
-	}
-
-	public boolean registerCallbackIfNecessary() {
-		if ( isTransactionCallbackRegistered ) {
-			return false;
-		}
-		else {
-			isTransactionCallbackRegistered = true;
-			return true;
-		}
-
-	}
-
-	public boolean registerSynchronizationIfPossible() {
-		if ( isTransactionCallbackRegistered ) {
-			// we already have a callback registered; either a local
-			// (org.hibernate.Transaction) transaction has accepted
-			// callback responsibilities, or we have previously
-			// registered a transaction synch.
-			return true;
-		}
-		boolean localCallbacksOnly = owner.getFactory().getSettings()
-				.getTransactionFactory()
-				.areCallbacksLocalToHibernateTransactions();
-		if ( localCallbacksOnly ) {
-			// the configured transaction-factory says it only supports
-			// local callback mode, so no sense attempting to register a
-			// JTA Synchronization
-			return false;
-		}
-		TransactionManager tm = owner.getFactory().getTransactionManager();
-		if ( tm == null ) {
-			// if there is no TM configured, we will not be able to access
-			// the javax.transaction.Transaction object in order to
-			// register a synch anyway.
-			return false;
-		}
-		else {
-			try {
-				if ( !isTransactionInProgress() ) {
-					log.trace( "TransactionFactory reported no active transaction; Synchronization not registered" );
-					return false;
-				}
-				else {
-					javax.transaction.Transaction tx = tm.getTransaction();
-					if ( JTAHelper.isMarkedForRollback( tx ) ) {
-						// transactions marked for rollback-only cause some TM impls to throw exceptions
-						log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
-						return false;
-					}
-					else {
-						if ( hibernateTransaction == null ) {
-							hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
-						}
-						tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
-						isTransactionCallbackRegistered = true;
-						log.debug("successfully registered Synchronization");
-						return true;
-					}
-				}
-			}
-			catch( HibernateException e ) {
-				throw e;
-			}
-			catch (Exception e) {
-				throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
-			}
-		}
-	}
-	
-	public boolean isTransactionInProgress() {
-		return owner.getFactory().getSettings().getTransactionFactory()
-				.isTransactionInProgress( this, owner, hibernateTransaction );
-	}
-
-	public Transaction getTransaction() throws HibernateException {
-		if (hibernateTransaction==null) {
-			hibernateTransaction = owner.getFactory().getSettings()
-					.getTransactionFactory()
-					.createTransaction( this, owner );
-		}
-		return hibernateTransaction;
-	}
-	
-	public void beforeTransactionCompletion(Transaction tx) {
-		log.trace( "before transaction completion" );
-		owner.beforeTransactionCompletion(tx);
-	}
-	
-	/**
-	 * We cannot rely upon this method being called! It is only
-	 * called if we are using Hibernate Transaction API.
-	 */
-	public void afterTransactionBegin(Transaction tx) {
-		log.trace( "after transaction begin" );
-		owner.afterTransactionBegin(tx);
-	}
-
-	public void afterTransactionCompletion(boolean success, Transaction tx) {
-		log.trace( "after transaction completion" );
-
-		if ( getFactory().getStatistics().isStatisticsEnabled() ) {
-			getFactory().getStatisticsImplementor().endTransaction(success);
-		}
-
-		connectionManager.afterTransaction();
-
-		isTransactionCallbackRegistered = false;
-		hibernateTransaction = null;
-		owner.afterTransactionCompletion(success, tx);
-	}
-	
-	/**
-	 * Called after executing a query outside the scope of
-	 * a Hibernate or JTA transaction
-	 */
-	public void afterNontransactionalQuery(boolean success) {
-		log.trace( "after autocommit" );
-		try {
-			// check to see if the connection is in auto-commit 
-			// mode (no connection means aggressive connection
-			// release outside a JTA transaction context, so MUST
-			// be autocommit mode)
-			boolean isAutocommit = connectionManager.isAutoCommit();
-
-			connectionManager.afterTransaction();
-			
-			if ( isAutocommit ) {
-				owner.afterTransactionCompletion(success, null);
-			}
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert( 
-					owner.getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not inspect JDBC autocommit mode"
-				);
-		}
-	}
-
-
-	// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	private void writeObject(ObjectOutputStream oos) throws IOException {
-		// isTransactionCallbackRegistered denotes whether any Hibernate
-		// Transaction has registered as a callback against this
-		// JDBCContext; only one such callback is allowed.  Directly
-		// serializing this value causes problems with JDBCTransaction,
-		// or really any Transaction impl where the callback is local
-		// to the Transaction instance itself, since that Transaction
-		// is not serialized along with the JDBCContext.  Thus we
-		// handle that fact here explicitly...
-		oos.defaultWriteObject();
-		boolean deserHasCallbackRegistered = isTransactionCallbackRegistered
-				&& ! owner.getFactory().getSettings().getTransactionFactory()
-				.areCallbacksLocalToHibernateTransactions();
-		oos.writeBoolean( deserHasCallbackRegistered );
-	}
-
-	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
-		ois.defaultReadObject();
-		isTransactionCallbackRegistered = ois.readBoolean();
-	}
-
-	/**
-	 * Custom serialization routine used during serialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param oos The stream to which we should write the serial data.
-	 * @throws IOException
-	 */
-	public void serialize(ObjectOutputStream oos) throws IOException {
-		connectionManager.serialize( oos );
-	}
-
-	/**
-	 * Custom deserialization routine used during deserialization of a
-	 * Session/PersistenceContext for increased performance.
-	 *
-	 * @param ois The stream from which to read the entry.
-	 * @throws IOException
-	 */
-	public static JDBCContext deserialize(
-			ObjectInputStream ois,
-	        Context context,
-	        Interceptor interceptor) throws IOException {
-		JDBCContext jdbcContext = new JDBCContext();
-		jdbcContext.owner = context;
-		jdbcContext.connectionManager = ConnectionManager.deserialize(
-				ois,
-				context.getFactory(),
-		        interceptor,
-		        context.getConnectionReleaseMode(),
-		        jdbcContext
-		);
-		return jdbcContext;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/JDBCContext.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/JDBCContext.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,340 @@
+/*
+ * 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.jdbc;
+
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import javax.transaction.TransactionManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+import org.hibernate.SessionException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.util.JTAHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.transaction.CacheSynchronization;
+import org.hibernate.transaction.TransactionFactory;
+
+/**
+ * Acts as the mediary between "entity-mode related" sessions in terms of
+ * their interaction with the JDBC data store.
+ *
+ * @author Steve Ebersole
+ */
+public class JDBCContext implements Serializable, ConnectionManager.Callback {
+
+	// TODO : make this the factory for "entity mode related" sessions;
+	// also means making this the target of transaction-synch and the
+	// thing that knows how to cascade things between related sessions
+	//
+	// At that point, perhaps this thing is a "SessionContext", and
+	// ConnectionManager is a "JDBCContext"?  A "SessionContext" should
+	// live in the impl package...
+
+	private static final Logger log = LoggerFactory.getLogger( JDBCContext.class );
+
+	public static interface Context extends TransactionFactory.Context {
+		/**
+		 * We cannot rely upon this method being called! It is only
+		 * called if we are using Hibernate Transaction API.
+		 */
+		public void afterTransactionBegin(Transaction tx);
+		public void beforeTransactionCompletion(Transaction tx);
+		public void afterTransactionCompletion(boolean success, Transaction tx);
+		public ConnectionReleaseMode getConnectionReleaseMode();
+		public boolean isAutoCloseSessionEnabled();
+	}
+
+	private Context owner;
+	private ConnectionManager connectionManager;
+	private transient boolean isTransactionCallbackRegistered;
+	private transient Transaction hibernateTransaction;
+
+	public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
+		this.owner = owner;
+		this.connectionManager = new ConnectionManager(
+		        owner.getFactory(),
+		        this,
+		        owner.getConnectionReleaseMode(),
+		        connection,
+		        interceptor
+			);
+
+		final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
+		        || owner.isFlushBeforeCompletionEnabled()
+		        || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
+		if ( registerSynchronization ) {
+			registerSynchronizationIfPossible();
+		}
+	}
+
+	/**
+	 * Private constructor used exclusively for custom serialization...
+	 *
+	 */
+	private JDBCContext() {
+	}
+
+	// ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public void connectionOpened() {
+		if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) {
+			owner.getFactory().getStatisticsImplementor().connect();
+		}
+	}
+
+	public void connectionCleanedUp() {
+		if ( !isTransactionCallbackRegistered ) {
+			afterTransactionCompletion( false, null );
+			// Note : success = false, because we don't know the outcome of the transaction
+		}
+	}
+
+	public SessionFactoryImplementor getFactory() {
+		return owner.getFactory();
+	}
+
+	public ConnectionManager getConnectionManager() {
+		return connectionManager;
+	}
+
+	public Connection borrowConnection() {
+		return connectionManager.borrowConnection();
+	}
+	
+	public Connection connection() throws HibernateException {
+		if ( owner.isClosed() ) {
+			throw new SessionException( "Session is closed" );
+		}
+
+		return connectionManager.getConnection();
+	}
+
+	public boolean registerCallbackIfNecessary() {
+		if ( isTransactionCallbackRegistered ) {
+			return false;
+		}
+		else {
+			isTransactionCallbackRegistered = true;
+			return true;
+		}
+
+	}
+
+	public boolean registerSynchronizationIfPossible() {
+		if ( isTransactionCallbackRegistered ) {
+			// we already have a callback registered; either a local
+			// (org.hibernate.Transaction) transaction has accepted
+			// callback responsibilities, or we have previously
+			// registered a transaction synch.
+			return true;
+		}
+		boolean localCallbacksOnly = owner.getFactory().getSettings()
+				.getTransactionFactory()
+				.areCallbacksLocalToHibernateTransactions();
+		if ( localCallbacksOnly ) {
+			// the configured transaction-factory says it only supports
+			// local callback mode, so no sense attempting to register a
+			// JTA Synchronization
+			return false;
+		}
+		TransactionManager tm = owner.getFactory().getTransactionManager();
+		if ( tm == null ) {
+			// if there is no TM configured, we will not be able to access
+			// the javax.transaction.Transaction object in order to
+			// register a synch anyway.
+			return false;
+		}
+		else {
+			try {
+				if ( !isTransactionInProgress() ) {
+					log.trace( "TransactionFactory reported no active transaction; Synchronization not registered" );
+					return false;
+				}
+				else {
+					javax.transaction.Transaction tx = tm.getTransaction();
+					if ( JTAHelper.isMarkedForRollback( tx ) ) {
+						// transactions marked for rollback-only cause some TM impls to throw exceptions
+						log.debug( "Transaction is marked for rollback; skipping Synchronization registration" );
+						return false;
+					}
+					else {
+						if ( hibernateTransaction == null ) {
+							hibernateTransaction = owner.getFactory().getSettings().getTransactionFactory().createTransaction( this, owner );
+						}
+						tx.registerSynchronization( new CacheSynchronization(owner, this, tx, hibernateTransaction) );
+						isTransactionCallbackRegistered = true;
+						log.debug("successfully registered Synchronization");
+						return true;
+					}
+				}
+			}
+			catch( HibernateException e ) {
+				throw e;
+			}
+			catch (Exception e) {
+				throw new TransactionException( "could not register synchronization with JTA TransactionManager", e );
+			}
+		}
+	}
+	
+	public boolean isTransactionInProgress() {
+		return owner.getFactory().getSettings().getTransactionFactory()
+				.isTransactionInProgress( this, owner, hibernateTransaction );
+	}
+
+	public Transaction getTransaction() throws HibernateException {
+		if (hibernateTransaction==null) {
+			hibernateTransaction = owner.getFactory().getSettings()
+					.getTransactionFactory()
+					.createTransaction( this, owner );
+		}
+		return hibernateTransaction;
+	}
+	
+	public void beforeTransactionCompletion(Transaction tx) {
+		log.trace( "before transaction completion" );
+		owner.beforeTransactionCompletion(tx);
+	}
+	
+	/**
+	 * We cannot rely upon this method being called! It is only
+	 * called if we are using Hibernate Transaction API.
+	 */
+	public void afterTransactionBegin(Transaction tx) {
+		log.trace( "after transaction begin" );
+		owner.afterTransactionBegin(tx);
+	}
+
+	public void afterTransactionCompletion(boolean success, Transaction tx) {
+		log.trace( "after transaction completion" );
+
+		if ( getFactory().getStatistics().isStatisticsEnabled() ) {
+			getFactory().getStatisticsImplementor().endTransaction(success);
+		}
+
+		connectionManager.afterTransaction();
+
+		isTransactionCallbackRegistered = false;
+		hibernateTransaction = null;
+		owner.afterTransactionCompletion(success, tx);
+	}
+	
+	/**
+	 * Called after executing a query outside the scope of
+	 * a Hibernate or JTA transaction
+	 */
+	public void afterNontransactionalQuery(boolean success) {
+		log.trace( "after autocommit" );
+		try {
+			// check to see if the connection is in auto-commit 
+			// mode (no connection means aggressive connection
+			// release outside a JTA transaction context, so MUST
+			// be autocommit mode)
+			boolean isAutocommit = connectionManager.isAutoCommit();
+
+			connectionManager.afterTransaction();
+			
+			if ( isAutocommit ) {
+				owner.afterTransactionCompletion(success, null);
+			}
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert( 
+					owner.getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not inspect JDBC autocommit mode"
+				);
+		}
+	}
+
+
+	// serialization ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private void writeObject(ObjectOutputStream oos) throws IOException {
+		// isTransactionCallbackRegistered denotes whether any Hibernate
+		// Transaction has registered as a callback against this
+		// JDBCContext; only one such callback is allowed.  Directly
+		// serializing this value causes problems with JDBCTransaction,
+		// or really any Transaction impl where the callback is local
+		// to the Transaction instance itself, since that Transaction
+		// is not serialized along with the JDBCContext.  Thus we
+		// handle that fact here explicitly...
+		oos.defaultWriteObject();
+		boolean deserHasCallbackRegistered = isTransactionCallbackRegistered
+				&& ! owner.getFactory().getSettings().getTransactionFactory()
+				.areCallbacksLocalToHibernateTransactions();
+		oos.writeBoolean( deserHasCallbackRegistered );
+	}
+
+	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
+		ois.defaultReadObject();
+		isTransactionCallbackRegistered = ois.readBoolean();
+	}
+
+	/**
+	 * Custom serialization routine used during serialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param oos The stream to which we should write the serial data.
+	 * @throws IOException
+	 */
+	public void serialize(ObjectOutputStream oos) throws IOException {
+		connectionManager.serialize( oos );
+	}
+
+	/**
+	 * Custom deserialization routine used during deserialization of a
+	 * Session/PersistenceContext for increased performance.
+	 *
+	 * @param ois The stream from which to read the entry.
+	 * @throws IOException
+	 */
+	public static JDBCContext deserialize(
+			ObjectInputStream ois,
+	        Context context,
+	        Interceptor interceptor) throws IOException {
+		JDBCContext jdbcContext = new JDBCContext();
+		jdbcContext.owner = context;
+		jdbcContext.connectionManager = ConnectionManager.deserialize(
+				ois,
+				context.getFactory(),
+		        interceptor,
+		        context.getConnectionReleaseMode(),
+		        jdbcContext
+		);
+		return jdbcContext;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,30 +0,0 @@
-//$Id: NonBatchingBatcher.java 10040 2006-06-22 19:51:43Z steve.ebersole at jboss.com $
-package org.hibernate.jdbc;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Interceptor;
-
-/**
- * An implementation of the <tt>Batcher</tt> interface that does no batching
- *
- * @author Gavin King
- */
-public class NonBatchingBatcher extends AbstractBatcher {
-
-	public NonBatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
-		super( connectionManager, interceptor );
-	}
-
-	public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
-		PreparedStatement statement = getStatement();
-		final int rowCount = statement.executeUpdate();
-		expectation.verifyOutcome( rowCount, statement, 0 );
-	}
-
-	protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcher.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Interceptor;
+
+/**
+ * An implementation of the <tt>Batcher</tt> interface that does no batching
+ *
+ * @author Gavin King
+ */
+public class NonBatchingBatcher extends AbstractBatcher {
+
+	public NonBatchingBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
+		super( connectionManager, interceptor );
+	}
+
+	public void addToBatch(Expectation expectation) throws SQLException, HibernateException {
+		PreparedStatement statement = getStatement();
+		final int rowCount = statement.executeUpdate();
+		expectation.verifyOutcome( rowCount, statement, 0 );
+	}
+
+	protected void doExecuteBatch(PreparedStatement ps) throws SQLException, HibernateException {
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,19 +0,0 @@
-//$Id: NonBatchingBatcherFactory.java 7683 2005-07-29 19:10:20Z maxcsaucdk $
-package org.hibernate.jdbc;
-
-import org.hibernate.Interceptor;
-
-
-/**
- * A BatcherFactory implementation which constructs Batcher instances
- * that do not perform batch operations.
- *
- * @author Gavin King
- */
-public class NonBatchingBatcherFactory implements BatcherFactory {
-
-	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
-		return new NonBatchingBatcher( connectionManager, interceptor );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/NonBatchingBatcherFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.jdbc;
+
+import org.hibernate.Interceptor;
+
+
+/**
+ * A BatcherFactory implementation which constructs Batcher instances
+ * that do not perform batch operations.
+ *
+ * @author Gavin King
+ */
+public class NonBatchingBatcherFactory implements BatcherFactory {
+
+	public Batcher createBatcher(ConnectionManager connectionManager, Interceptor interceptor) {
+		return new NonBatchingBatcher( connectionManager, interceptor );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,619 +0,0 @@
-// $Id: ResultSetWrapper.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.jdbc;
-
-import java.io.InputStream;
-import java.io.Reader;
-import java.math.BigDecimal;
-import java.net.URL;
-import java.sql.Array;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Date;
-import java.sql.Ref;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Map;
-
-/**
- * A ResultSet delegate, responsible for locally caching the columnName-to-columnIndex
- * resolution that has been found to be inefficient in a few vendor's drivers (i.e., Oracle
- * and Postgres).
- *
- * @author Steve Ebersole
- */
-public class ResultSetWrapper implements ResultSet {
-
-	private ResultSet rs;
-	private ColumnNameCache columnNameCache;
-
-	public ResultSetWrapper(ResultSet resultSet, ColumnNameCache columnNameCache) {
-		this.rs = resultSet;
-		this.columnNameCache = columnNameCache;
-	}
-
-	/*package*/ ResultSet getTarget() {
-		return rs;
-	}
-
-
-	// ResultSet impl ("overridden") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Overridden version to utilize local caching of the column indexes by name
-	 * to improve performance for those drivers which are known to not support
-	 * such caching by themselves.
-	 * <p/>
-	 * This implementation performs the caching based on the upper case version
-	 * of the given column name.
-	 *
-	 * @param columnName The column name to resolve into an index.
-	 * @return The column index corresponding to the given column name.
-	 * @throws SQLException - if the ResultSet object does not contain
-	 * columnName or a database access error occurs
-	 */
-	public int findColumn(String columnName) throws SQLException {
-		return columnNameCache.getIndexForColumnName( columnName, this );
-	}
-
-	public Array getArray(String colName) throws SQLException {
-		return rs.getArray( findColumn(colName) );
-	}
-
-	public void updateArray(String columnName, Array x) throws SQLException {
-		rs.updateArray( findColumn(columnName), x );
-	}
-
-	public InputStream getAsciiStream(String columnName) throws SQLException {
-		return rs.getAsciiStream( findColumn(columnName) );
-	}
-
-	public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException {
-		rs.updateAsciiStream( findColumn(columnName), x, length );
-	}
-
-	public BigDecimal getBigDecimal(String columnName) throws SQLException {
-		return rs.getBigDecimal( findColumn(columnName) );
-	}
-
-	public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
-		return rs.getBigDecimal( findColumn(columnName), scale );
-	}
-
-	public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
-		rs.updateBigDecimal( findColumn(columnName), x );
-	}
-
-	public InputStream getBinaryStream(String columnName) throws SQLException {
-		return rs.getBinaryStream( findColumn(columnName) );
-	}
-
-	public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException {
-		rs.updateBinaryStream( findColumn(columnName), x, length );
-	}
-
-	public Blob getBlob(String columnName) throws SQLException {
-		return rs.getBlob( findColumn(columnName) );
-	}
-
-	public void updateBlob(String columnName, Blob x) throws SQLException {
-		rs.updateBlob( findColumn(columnName), x );
-	}
-
-	public boolean getBoolean(String columnName) throws SQLException {
-		return rs.getBoolean( findColumn(columnName) );
-	}
-
-	public void updateBoolean(String columnName, boolean x) throws SQLException {
-		rs.updateBoolean( findColumn(columnName), x );
-	}
-
-	public byte getByte(String columnName) throws SQLException {
-		return rs.getByte( findColumn(columnName) );
-	}
-
-	public void updateByte(String columnName, byte x) throws SQLException {
-		rs.updateByte( findColumn(columnName), x );
-	}
-
-	public byte[] getBytes(String columnName) throws SQLException {
-		return rs.getBytes( findColumn(columnName) );
-	}
-
-	public void updateBytes(String columnName, byte[] x) throws SQLException {
-		rs.updateBytes( findColumn(columnName), x );
-	}
-
-	public Reader getCharacterStream(String columnName) throws SQLException {
-		return rs.getCharacterStream( findColumn(columnName) );
-	}
-
-	public void updateCharacterStream(String columnName, Reader x, int length) throws SQLException {
-		rs.updateCharacterStream( findColumn(columnName), x, length );
-	}
-
-	public Clob getClob(String columnName) throws SQLException {
-		return rs.getClob( findColumn(columnName) );
-	}
-
-	public void updateClob(String columnName, Clob x) throws SQLException {
-		rs.updateClob( findColumn(columnName), x );
-	}
-
-	public Date getDate(String columnName) throws SQLException {
-		return rs.getDate( findColumn(columnName) );
-	}
-
-	public Date getDate(String columnName, Calendar cal) throws SQLException {
-		return rs.getDate( findColumn(columnName), cal );
-	}
-
-	public void updateDate(String columnName, Date x) throws SQLException {
-		rs.updateDate( findColumn(columnName), x );
-	}
-
-	public double getDouble(String columnName) throws SQLException {
-		return rs.getDouble( findColumn(columnName) );
-	}
-
-	public void updateDouble(String columnName, double x) throws SQLException {
-		rs.updateDouble( findColumn(columnName), x );
-	}
-
-	public float getFloat(String columnName) throws SQLException {
-		return rs.getFloat( findColumn(columnName) );
-	}
-
-	public void updateFloat(String columnName, float x) throws SQLException {
-		rs.updateFloat( findColumn(columnName), x );
-	}
-
-	public int getInt(String columnName) throws SQLException {
-		return rs.getInt( findColumn(columnName) );
-	}
-
-	public void updateInt(String columnName, int x) throws SQLException {
-		rs.updateInt( findColumn(columnName), x );
-	}
-
-	public long getLong(String columnName) throws SQLException {
-		return rs.getLong( findColumn(columnName) );
-	}
-
-	public void updateLong(String columnName, long x) throws SQLException {
-		rs.updateLong( findColumn(columnName), x );
-	}
-
-	public Object getObject(String columnName) throws SQLException {
-		return rs.getObject( findColumn(columnName) );
-	}
-
-	public Object getObject(String columnName, Map map) throws SQLException {
-		return rs.getObject( findColumn(columnName), map );
-	}
-
-	public void updateObject(String columnName, Object x) throws SQLException {
-		rs.updateObject( findColumn(columnName), x );
-	}
-
-	public void updateObject(String columnName, Object x, int scale) throws SQLException {
-		rs.updateObject( findColumn(columnName), x, scale );
-	}
-
-	public Ref getRef(String columnName) throws SQLException {
-		return rs.getRef( findColumn(columnName) );
-	}
-
-	public void updateRef(String columnName, Ref x) throws SQLException {
-		rs.updateRef( findColumn(columnName), x );
-	}
-
-	public short getShort(String columnName) throws SQLException {
-		return rs.getShort( findColumn(columnName) );
-	}
-
-	public void updateShort(String columnName, short x) throws SQLException {
-		rs.updateShort( findColumn(columnName), x );
-	}
-
-	public String getString(String columnName) throws SQLException {
-		return rs.getString( findColumn(columnName) );
-	}
-
-	public void updateString(String columnName, String x) throws SQLException {
-		rs.updateString( findColumn(columnName), x );
-	}
-
-	public Time getTime(String columnName) throws SQLException {
-		return rs.getTime( findColumn(columnName) );
-	}
-
-	public Time getTime(String columnName, Calendar cal) throws SQLException {
-		return rs.getTime( findColumn(columnName), cal );
-	}
-
-	public void updateTime(String columnName, Time x) throws SQLException {
-		rs.updateTime( findColumn(columnName), x );
-	}
-
-	public Timestamp getTimestamp(String columnName) throws SQLException {
-		return rs.getTimestamp( findColumn(columnName) );
-	}
-
-	public void updateTimestamp(String columnName, Timestamp x) throws SQLException {
-		rs.updateTimestamp( findColumn(columnName), x );
-	}
-
-	public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
-		return rs.getTimestamp( findColumn(columnName), cal );
-	}
-
-	public InputStream getUnicodeStream(String columnName) throws SQLException {
-		return rs.getUnicodeStream( findColumn(columnName) );
-	}
-
-	public URL getURL(String columnName) throws SQLException {
-		return rs.getURL( findColumn(columnName) );
-	}
-
-	public void updateNull(String columnName) throws SQLException {
-		rs.updateNull( findColumn(columnName) );
-	}
-
-
-	// ResultSet impl (delegated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public int getConcurrency() throws SQLException {
-		return rs.getConcurrency();
-	}
-
-	public int getFetchDirection() throws SQLException {
-		return rs.getFetchDirection();
-	}
-
-	public int getFetchSize() throws SQLException {
-		return rs.getFetchSize();
-	}
-
-	public int getRow() throws SQLException {
-		return rs.getRow();
-	}
-
-	public int getType() throws SQLException {
-		return rs.getType();
-	}
-
-	public void afterLast() throws SQLException {
-		rs.afterLast();
-	}
-
-	public void beforeFirst() throws SQLException {
-		rs.beforeFirst();
-	}
-
-	public void cancelRowUpdates() throws SQLException {
-		rs.cancelRowUpdates();
-	}
-
-	public void clearWarnings() throws SQLException {
-		rs.clearWarnings();
-	}
-
-	public void close() throws SQLException {
-		rs.close();
-	}
-
-	public void deleteRow() throws SQLException {
-		rs.deleteRow();
-	}
-
-	public void insertRow() throws SQLException {
-		rs.insertRow();
-	}
-
-	public void moveToCurrentRow() throws SQLException {
-		rs.moveToCurrentRow();
-	}
-
-	public void moveToInsertRow() throws SQLException {
-		rs.moveToInsertRow();
-	}
-
-	public void refreshRow() throws SQLException {
-		rs.refreshRow();
-	}
-
-	public void updateRow() throws SQLException {
-		rs.updateRow();
-	}
-
-	public boolean first() throws SQLException {
-		return rs.first();
-	}
-
-	public boolean isAfterLast() throws SQLException {
-		return rs.isAfterLast();
-	}
-
-	public boolean isBeforeFirst() throws SQLException {
-		return rs.isBeforeFirst();
-	}
-
-	public boolean isFirst() throws SQLException {
-		return rs.isFirst();
-	}
-
-	public boolean isLast() throws SQLException {
-		return rs.isLast();
-	}
-
-	public boolean last() throws SQLException {
-		return rs.last();
-	}
-
-	public boolean next() throws SQLException {
-		return rs.next();
-	}
-
-	public boolean previous() throws SQLException {
-		return rs.previous();
-	}
-
-	public boolean rowDeleted() throws SQLException {
-		return rs.rowDeleted();
-	}
-
-	public boolean rowInserted() throws SQLException {
-		return rs.rowInserted();
-	}
-
-	public boolean rowUpdated() throws SQLException {
-		return rs.rowUpdated();
-	}
-
-	public boolean wasNull() throws SQLException {
-		return rs.wasNull();
-	}
-
-	public byte getByte(int columnIndex) throws SQLException {
-		return rs.getByte(columnIndex);
-	}
-
-	public double getDouble(int columnIndex) throws SQLException {
-		return rs.getDouble(columnIndex);
-	}
-
-	public float getFloat(int columnIndex) throws SQLException {
-		return rs.getFloat(columnIndex);
-	}
-
-	public int getInt(int columnIndex) throws SQLException {
-		return rs.getInt(columnIndex);
-	}
-
-	public long getLong(int columnIndex) throws SQLException {
-		return rs.getLong(columnIndex);
-	}
-
-	public short getShort(int columnIndex) throws SQLException {
-		return rs.getShort(columnIndex);
-	}
-
-	public void setFetchDirection(int direction) throws SQLException {
-		rs.setFetchDirection(direction);
-	}
-
-	public void setFetchSize(int rows) throws SQLException {
-		rs.setFetchSize(rows);
-	}
-
-	public void updateNull(int columnIndex) throws SQLException {
-		rs.updateNull(columnIndex);
-	}
-
-	public boolean absolute(int row) throws SQLException {
-		return rs.absolute(row);
-	}
-
-	public boolean getBoolean(int columnIndex) throws SQLException {
-		return rs.getBoolean(columnIndex);
-	}
-
-	public boolean relative(int rows) throws SQLException {
-		return rs.relative(rows);
-	}
-
-	public byte[] getBytes(int columnIndex) throws SQLException {
-		return rs.getBytes(columnIndex);
-	}
-
-	public void updateByte(int columnIndex, byte x) throws SQLException {
-		rs.updateByte(columnIndex, x);
-	}
-
-	public void updateDouble(int columnIndex, double x) throws SQLException {
-		rs.updateDouble(columnIndex, x);
-	}
-
-	public void updateFloat(int columnIndex, float x) throws SQLException {
-		rs.updateFloat(columnIndex, x);
-	}
-
-	public void updateInt(int columnIndex, int x) throws SQLException {
-		rs.updateInt(columnIndex, x);
-	}
-
-	public void updateLong(int columnIndex, long x) throws SQLException {
-		rs.updateLong(columnIndex, x);
-	}
-
-	public void updateShort(int columnIndex, short x) throws SQLException {
-		rs.updateShort(columnIndex, x);
-	}
-
-	public void updateBoolean(int columnIndex, boolean x) throws SQLException {
-		rs.updateBoolean(columnIndex, x);
-	}
-
-	public void updateBytes(int columnIndex, byte[] x) throws SQLException {
-		rs.updateBytes(columnIndex, x);
-	}
-
-	public InputStream getAsciiStream(int columnIndex) throws SQLException {
-		return rs.getAsciiStream(columnIndex);
-	}
-
-	public InputStream getBinaryStream(int columnIndex) throws SQLException {
-		return rs.getBinaryStream(columnIndex);
-	}
-
-	public InputStream getUnicodeStream(int columnIndex) throws SQLException {
-		return rs.getUnicodeStream(columnIndex);
-	}
-
-	public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
-		rs.updateAsciiStream(columnIndex, x, length);
-	}
-
-	public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
-		rs.updateBinaryStream(columnIndex, x, length);
-	}
-
-	public Reader getCharacterStream(int columnIndex) throws SQLException {
-		return rs.getCharacterStream(columnIndex);
-	}
-
-	public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
-		rs.updateCharacterStream(columnIndex, x, length);
-	}
-
-	public Object getObject(int columnIndex) throws SQLException {
-		return rs.getObject(columnIndex);
-	}
-
-	public void updateObject(int columnIndex, Object x) throws SQLException {
-		rs.updateObject(columnIndex, x);
-	}
-
-	public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
-		rs.updateObject(columnIndex, x, scale);
-	}
-
-	public String getCursorName() throws SQLException {
-		return rs.getCursorName();
-	}
-
-	public String getString(int columnIndex) throws SQLException {
-		return rs.getString(columnIndex);
-	}
-
-	public void updateString(int columnIndex, String x) throws SQLException {
-		rs.updateString(columnIndex, x);
-	}
-
-	public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
-		return rs.getBigDecimal(columnIndex);
-	}
-
-	public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
-		return rs.getBigDecimal(columnIndex, scale);
-	}
-
-	public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
-		rs.updateBigDecimal(columnIndex, x);
-	}
-
-	public URL getURL(int columnIndex) throws SQLException {
-		return rs.getURL(columnIndex);
-	}
-
-	public Array getArray(int columnIndex) throws SQLException {
-		return rs.getArray(columnIndex);
-	}
-
-	public void updateArray(int columnIndex, Array x) throws SQLException {
-		rs.updateArray(columnIndex, x);
-	}
-
-	public Blob getBlob(int columnIndex) throws SQLException {
-		return rs.getBlob(columnIndex);
-	}
-
-	public void updateBlob(int columnIndex, Blob x) throws SQLException {
-		rs.updateBlob(columnIndex, x);
-	}
-
-	public Clob getClob(int columnIndex) throws SQLException {
-		return rs.getClob(columnIndex);
-	}
-
-	public void updateClob(int columnIndex, Clob x) throws SQLException {
-		rs.updateClob(columnIndex, x);
-	}
-
-	public Date getDate(int columnIndex) throws SQLException {
-		return rs.getDate(columnIndex);
-	}
-
-	public void updateDate(int columnIndex, Date x) throws SQLException {
-		rs.updateDate(columnIndex, x);
-	}
-
-	public Ref getRef(int columnIndex) throws SQLException {
-		return rs.getRef(columnIndex);
-	}
-
-	public void updateRef(int columnIndex, Ref x) throws SQLException {
-		rs.updateRef(columnIndex, x);
-	}
-
-	public ResultSetMetaData getMetaData() throws SQLException {
-		return rs.getMetaData();
-	}
-
-	public SQLWarning getWarnings() throws SQLException {
-		return rs.getWarnings();
-	}
-
-	public Statement getStatement() throws SQLException {
-		return rs.getStatement();
-	}
-
-	public Time getTime(int columnIndex) throws SQLException {
-		return rs.getTime(columnIndex);
-	}
-
-	public void updateTime(int columnIndex, Time x) throws SQLException {
-		rs.updateTime(columnIndex, x);
-	}
-
-	public Timestamp getTimestamp(int columnIndex) throws SQLException {
-		return rs.getTimestamp(columnIndex);
-	}
-
-	public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
-		rs.updateTimestamp(columnIndex, x);
-	}
-
-	public Object getObject(int columnIndex, Map map) throws SQLException {
-		return rs.getObject( columnIndex, map );
-	}
-
-	public Date getDate(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getDate(columnIndex, cal);
-	}
-
-	public Time getTime(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getTime(columnIndex, cal);
-	}
-
-	public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
-		return rs.getTimestamp(columnIndex, cal);
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/ResultSetWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,642 @@
+/*
+ * 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.jdbc;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Map;
+
+/**
+ * A ResultSet delegate, responsible for locally caching the columnName-to-columnIndex
+ * resolution that has been found to be inefficient in a few vendor's drivers (i.e., Oracle
+ * and Postgres).
+ *
+ * @author Steve Ebersole
+ */
+public class ResultSetWrapper implements ResultSet {
+
+	private ResultSet rs;
+	private ColumnNameCache columnNameCache;
+
+	public ResultSetWrapper(ResultSet resultSet, ColumnNameCache columnNameCache) {
+		this.rs = resultSet;
+		this.columnNameCache = columnNameCache;
+	}
+
+	/*package*/ ResultSet getTarget() {
+		return rs;
+	}
+
+
+	// ResultSet impl ("overridden") ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Overridden version to utilize local caching of the column indexes by name
+	 * to improve performance for those drivers which are known to not support
+	 * such caching by themselves.
+	 * <p/>
+	 * This implementation performs the caching based on the upper case version
+	 * of the given column name.
+	 *
+	 * @param columnName The column name to resolve into an index.
+	 * @return The column index corresponding to the given column name.
+	 * @throws SQLException - if the ResultSet object does not contain
+	 * columnName or a database access error occurs
+	 */
+	public int findColumn(String columnName) throws SQLException {
+		return columnNameCache.getIndexForColumnName( columnName, this );
+	}
+
+	public Array getArray(String colName) throws SQLException {
+		return rs.getArray( findColumn(colName) );
+	}
+
+	public void updateArray(String columnName, Array x) throws SQLException {
+		rs.updateArray( findColumn(columnName), x );
+	}
+
+	public InputStream getAsciiStream(String columnName) throws SQLException {
+		return rs.getAsciiStream( findColumn(columnName) );
+	}
+
+	public void updateAsciiStream(String columnName, InputStream x, int length) throws SQLException {
+		rs.updateAsciiStream( findColumn(columnName), x, length );
+	}
+
+	public BigDecimal getBigDecimal(String columnName) throws SQLException {
+		return rs.getBigDecimal( findColumn(columnName) );
+	}
+
+	public BigDecimal getBigDecimal(String columnName, int scale) throws SQLException {
+		return rs.getBigDecimal( findColumn(columnName), scale );
+	}
+
+	public void updateBigDecimal(String columnName, BigDecimal x) throws SQLException {
+		rs.updateBigDecimal( findColumn(columnName), x );
+	}
+
+	public InputStream getBinaryStream(String columnName) throws SQLException {
+		return rs.getBinaryStream( findColumn(columnName) );
+	}
+
+	public void updateBinaryStream(String columnName, InputStream x, int length) throws SQLException {
+		rs.updateBinaryStream( findColumn(columnName), x, length );
+	}
+
+	public Blob getBlob(String columnName) throws SQLException {
+		return rs.getBlob( findColumn(columnName) );
+	}
+
+	public void updateBlob(String columnName, Blob x) throws SQLException {
+		rs.updateBlob( findColumn(columnName), x );
+	}
+
+	public boolean getBoolean(String columnName) throws SQLException {
+		return rs.getBoolean( findColumn(columnName) );
+	}
+
+	public void updateBoolean(String columnName, boolean x) throws SQLException {
+		rs.updateBoolean( findColumn(columnName), x );
+	}
+
+	public byte getByte(String columnName) throws SQLException {
+		return rs.getByte( findColumn(columnName) );
+	}
+
+	public void updateByte(String columnName, byte x) throws SQLException {
+		rs.updateByte( findColumn(columnName), x );
+	}
+
+	public byte[] getBytes(String columnName) throws SQLException {
+		return rs.getBytes( findColumn(columnName) );
+	}
+
+	public void updateBytes(String columnName, byte[] x) throws SQLException {
+		rs.updateBytes( findColumn(columnName), x );
+	}
+
+	public Reader getCharacterStream(String columnName) throws SQLException {
+		return rs.getCharacterStream( findColumn(columnName) );
+	}
+
+	public void updateCharacterStream(String columnName, Reader x, int length) throws SQLException {
+		rs.updateCharacterStream( findColumn(columnName), x, length );
+	}
+
+	public Clob getClob(String columnName) throws SQLException {
+		return rs.getClob( findColumn(columnName) );
+	}
+
+	public void updateClob(String columnName, Clob x) throws SQLException {
+		rs.updateClob( findColumn(columnName), x );
+	}
+
+	public Date getDate(String columnName) throws SQLException {
+		return rs.getDate( findColumn(columnName) );
+	}
+
+	public Date getDate(String columnName, Calendar cal) throws SQLException {
+		return rs.getDate( findColumn(columnName), cal );
+	}
+
+	public void updateDate(String columnName, Date x) throws SQLException {
+		rs.updateDate( findColumn(columnName), x );
+	}
+
+	public double getDouble(String columnName) throws SQLException {
+		return rs.getDouble( findColumn(columnName) );
+	}
+
+	public void updateDouble(String columnName, double x) throws SQLException {
+		rs.updateDouble( findColumn(columnName), x );
+	}
+
+	public float getFloat(String columnName) throws SQLException {
+		return rs.getFloat( findColumn(columnName) );
+	}
+
+	public void updateFloat(String columnName, float x) throws SQLException {
+		rs.updateFloat( findColumn(columnName), x );
+	}
+
+	public int getInt(String columnName) throws SQLException {
+		return rs.getInt( findColumn(columnName) );
+	}
+
+	public void updateInt(String columnName, int x) throws SQLException {
+		rs.updateInt( findColumn(columnName), x );
+	}
+
+	public long getLong(String columnName) throws SQLException {
+		return rs.getLong( findColumn(columnName) );
+	}
+
+	public void updateLong(String columnName, long x) throws SQLException {
+		rs.updateLong( findColumn(columnName), x );
+	}
+
+	public Object getObject(String columnName) throws SQLException {
+		return rs.getObject( findColumn(columnName) );
+	}
+
+	public Object getObject(String columnName, Map map) throws SQLException {
+		return rs.getObject( findColumn(columnName), map );
+	}
+
+	public void updateObject(String columnName, Object x) throws SQLException {
+		rs.updateObject( findColumn(columnName), x );
+	}
+
+	public void updateObject(String columnName, Object x, int scale) throws SQLException {
+		rs.updateObject( findColumn(columnName), x, scale );
+	}
+
+	public Ref getRef(String columnName) throws SQLException {
+		return rs.getRef( findColumn(columnName) );
+	}
+
+	public void updateRef(String columnName, Ref x) throws SQLException {
+		rs.updateRef( findColumn(columnName), x );
+	}
+
+	public short getShort(String columnName) throws SQLException {
+		return rs.getShort( findColumn(columnName) );
+	}
+
+	public void updateShort(String columnName, short x) throws SQLException {
+		rs.updateShort( findColumn(columnName), x );
+	}
+
+	public String getString(String columnName) throws SQLException {
+		return rs.getString( findColumn(columnName) );
+	}
+
+	public void updateString(String columnName, String x) throws SQLException {
+		rs.updateString( findColumn(columnName), x );
+	}
+
+	public Time getTime(String columnName) throws SQLException {
+		return rs.getTime( findColumn(columnName) );
+	}
+
+	public Time getTime(String columnName, Calendar cal) throws SQLException {
+		return rs.getTime( findColumn(columnName), cal );
+	}
+
+	public void updateTime(String columnName, Time x) throws SQLException {
+		rs.updateTime( findColumn(columnName), x );
+	}
+
+	public Timestamp getTimestamp(String columnName) throws SQLException {
+		return rs.getTimestamp( findColumn(columnName) );
+	}
+
+	public void updateTimestamp(String columnName, Timestamp x) throws SQLException {
+		rs.updateTimestamp( findColumn(columnName), x );
+	}
+
+	public Timestamp getTimestamp(String columnName, Calendar cal) throws SQLException {
+		return rs.getTimestamp( findColumn(columnName), cal );
+	}
+
+	public InputStream getUnicodeStream(String columnName) throws SQLException {
+		return rs.getUnicodeStream( findColumn(columnName) );
+	}
+
+	public URL getURL(String columnName) throws SQLException {
+		return rs.getURL( findColumn(columnName) );
+	}
+
+	public void updateNull(String columnName) throws SQLException {
+		rs.updateNull( findColumn(columnName) );
+	}
+
+
+	// ResultSet impl (delegated) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public int getConcurrency() throws SQLException {
+		return rs.getConcurrency();
+	}
+
+	public int getFetchDirection() throws SQLException {
+		return rs.getFetchDirection();
+	}
+
+	public int getFetchSize() throws SQLException {
+		return rs.getFetchSize();
+	}
+
+	public int getRow() throws SQLException {
+		return rs.getRow();
+	}
+
+	public int getType() throws SQLException {
+		return rs.getType();
+	}
+
+	public void afterLast() throws SQLException {
+		rs.afterLast();
+	}
+
+	public void beforeFirst() throws SQLException {
+		rs.beforeFirst();
+	}
+
+	public void cancelRowUpdates() throws SQLException {
+		rs.cancelRowUpdates();
+	}
+
+	public void clearWarnings() throws SQLException {
+		rs.clearWarnings();
+	}
+
+	public void close() throws SQLException {
+		rs.close();
+	}
+
+	public void deleteRow() throws SQLException {
+		rs.deleteRow();
+	}
+
+	public void insertRow() throws SQLException {
+		rs.insertRow();
+	}
+
+	public void moveToCurrentRow() throws SQLException {
+		rs.moveToCurrentRow();
+	}
+
+	public void moveToInsertRow() throws SQLException {
+		rs.moveToInsertRow();
+	}
+
+	public void refreshRow() throws SQLException {
+		rs.refreshRow();
+	}
+
+	public void updateRow() throws SQLException {
+		rs.updateRow();
+	}
+
+	public boolean first() throws SQLException {
+		return rs.first();
+	}
+
+	public boolean isAfterLast() throws SQLException {
+		return rs.isAfterLast();
+	}
+
+	public boolean isBeforeFirst() throws SQLException {
+		return rs.isBeforeFirst();
+	}
+
+	public boolean isFirst() throws SQLException {
+		return rs.isFirst();
+	}
+
+	public boolean isLast() throws SQLException {
+		return rs.isLast();
+	}
+
+	public boolean last() throws SQLException {
+		return rs.last();
+	}
+
+	public boolean next() throws SQLException {
+		return rs.next();
+	}
+
+	public boolean previous() throws SQLException {
+		return rs.previous();
+	}
+
+	public boolean rowDeleted() throws SQLException {
+		return rs.rowDeleted();
+	}
+
+	public boolean rowInserted() throws SQLException {
+		return rs.rowInserted();
+	}
+
+	public boolean rowUpdated() throws SQLException {
+		return rs.rowUpdated();
+	}
+
+	public boolean wasNull() throws SQLException {
+		return rs.wasNull();
+	}
+
+	public byte getByte(int columnIndex) throws SQLException {
+		return rs.getByte(columnIndex);
+	}
+
+	public double getDouble(int columnIndex) throws SQLException {
+		return rs.getDouble(columnIndex);
+	}
+
+	public float getFloat(int columnIndex) throws SQLException {
+		return rs.getFloat(columnIndex);
+	}
+
+	public int getInt(int columnIndex) throws SQLException {
+		return rs.getInt(columnIndex);
+	}
+
+	public long getLong(int columnIndex) throws SQLException {
+		return rs.getLong(columnIndex);
+	}
+
+	public short getShort(int columnIndex) throws SQLException {
+		return rs.getShort(columnIndex);
+	}
+
+	public void setFetchDirection(int direction) throws SQLException {
+		rs.setFetchDirection(direction);
+	}
+
+	public void setFetchSize(int rows) throws SQLException {
+		rs.setFetchSize(rows);
+	}
+
+	public void updateNull(int columnIndex) throws SQLException {
+		rs.updateNull(columnIndex);
+	}
+
+	public boolean absolute(int row) throws SQLException {
+		return rs.absolute(row);
+	}
+
+	public boolean getBoolean(int columnIndex) throws SQLException {
+		return rs.getBoolean(columnIndex);
+	}
+
+	public boolean relative(int rows) throws SQLException {
+		return rs.relative(rows);
+	}
+
+	public byte[] getBytes(int columnIndex) throws SQLException {
+		return rs.getBytes(columnIndex);
+	}
+
+	public void updateByte(int columnIndex, byte x) throws SQLException {
+		rs.updateByte(columnIndex, x);
+	}
+
+	public void updateDouble(int columnIndex, double x) throws SQLException {
+		rs.updateDouble(columnIndex, x);
+	}
+
+	public void updateFloat(int columnIndex, float x) throws SQLException {
+		rs.updateFloat(columnIndex, x);
+	}
+
+	public void updateInt(int columnIndex, int x) throws SQLException {
+		rs.updateInt(columnIndex, x);
+	}
+
+	public void updateLong(int columnIndex, long x) throws SQLException {
+		rs.updateLong(columnIndex, x);
+	}
+
+	public void updateShort(int columnIndex, short x) throws SQLException {
+		rs.updateShort(columnIndex, x);
+	}
+
+	public void updateBoolean(int columnIndex, boolean x) throws SQLException {
+		rs.updateBoolean(columnIndex, x);
+	}
+
+	public void updateBytes(int columnIndex, byte[] x) throws SQLException {
+		rs.updateBytes(columnIndex, x);
+	}
+
+	public InputStream getAsciiStream(int columnIndex) throws SQLException {
+		return rs.getAsciiStream(columnIndex);
+	}
+
+	public InputStream getBinaryStream(int columnIndex) throws SQLException {
+		return rs.getBinaryStream(columnIndex);
+	}
+
+	public InputStream getUnicodeStream(int columnIndex) throws SQLException {
+		return rs.getUnicodeStream(columnIndex);
+	}
+
+	public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException {
+		rs.updateAsciiStream(columnIndex, x, length);
+	}
+
+	public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException {
+		rs.updateBinaryStream(columnIndex, x, length);
+	}
+
+	public Reader getCharacterStream(int columnIndex) throws SQLException {
+		return rs.getCharacterStream(columnIndex);
+	}
+
+	public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException {
+		rs.updateCharacterStream(columnIndex, x, length);
+	}
+
+	public Object getObject(int columnIndex) throws SQLException {
+		return rs.getObject(columnIndex);
+	}
+
+	public void updateObject(int columnIndex, Object x) throws SQLException {
+		rs.updateObject(columnIndex, x);
+	}
+
+	public void updateObject(int columnIndex, Object x, int scale) throws SQLException {
+		rs.updateObject(columnIndex, x, scale);
+	}
+
+	public String getCursorName() throws SQLException {
+		return rs.getCursorName();
+	}
+
+	public String getString(int columnIndex) throws SQLException {
+		return rs.getString(columnIndex);
+	}
+
+	public void updateString(int columnIndex, String x) throws SQLException {
+		rs.updateString(columnIndex, x);
+	}
+
+	public BigDecimal getBigDecimal(int columnIndex) throws SQLException {
+		return rs.getBigDecimal(columnIndex);
+	}
+
+	public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException {
+		return rs.getBigDecimal(columnIndex, scale);
+	}
+
+	public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException {
+		rs.updateBigDecimal(columnIndex, x);
+	}
+
+	public URL getURL(int columnIndex) throws SQLException {
+		return rs.getURL(columnIndex);
+	}
+
+	public Array getArray(int columnIndex) throws SQLException {
+		return rs.getArray(columnIndex);
+	}
+
+	public void updateArray(int columnIndex, Array x) throws SQLException {
+		rs.updateArray(columnIndex, x);
+	}
+
+	public Blob getBlob(int columnIndex) throws SQLException {
+		return rs.getBlob(columnIndex);
+	}
+
+	public void updateBlob(int columnIndex, Blob x) throws SQLException {
+		rs.updateBlob(columnIndex, x);
+	}
+
+	public Clob getClob(int columnIndex) throws SQLException {
+		return rs.getClob(columnIndex);
+	}
+
+	public void updateClob(int columnIndex, Clob x) throws SQLException {
+		rs.updateClob(columnIndex, x);
+	}
+
+	public Date getDate(int columnIndex) throws SQLException {
+		return rs.getDate(columnIndex);
+	}
+
+	public void updateDate(int columnIndex, Date x) throws SQLException {
+		rs.updateDate(columnIndex, x);
+	}
+
+	public Ref getRef(int columnIndex) throws SQLException {
+		return rs.getRef(columnIndex);
+	}
+
+	public void updateRef(int columnIndex, Ref x) throws SQLException {
+		rs.updateRef(columnIndex, x);
+	}
+
+	public ResultSetMetaData getMetaData() throws SQLException {
+		return rs.getMetaData();
+	}
+
+	public SQLWarning getWarnings() throws SQLException {
+		return rs.getWarnings();
+	}
+
+	public Statement getStatement() throws SQLException {
+		return rs.getStatement();
+	}
+
+	public Time getTime(int columnIndex) throws SQLException {
+		return rs.getTime(columnIndex);
+	}
+
+	public void updateTime(int columnIndex, Time x) throws SQLException {
+		rs.updateTime(columnIndex, x);
+	}
+
+	public Timestamp getTimestamp(int columnIndex) throws SQLException {
+		return rs.getTimestamp(columnIndex);
+	}
+
+	public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException {
+		rs.updateTimestamp(columnIndex, x);
+	}
+
+	public Object getObject(int columnIndex, Map map) throws SQLException {
+		return rs.getObject( columnIndex, map );
+	}
+
+	public Date getDate(int columnIndex, Calendar cal) throws SQLException {
+		return rs.getDate(columnIndex, cal);
+	}
+
+	public Time getTime(int columnIndex, Calendar cal) throws SQLException {
+		return rs.getTime(columnIndex, cal);
+	}
+
+	public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException {
+		return rs.getTimestamp(columnIndex, cal);
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-package org.hibernate.jdbc;
-
-import org.hibernate.HibernateException;
-
-/**
- * Indicates that more rows were affected then we were expecting to be.
- * Typically indicates presence of duplicate "PK" values in the
- * given table.
- *
- * @author Steve Ebersole
- */
-public class TooManyRowsAffectedException extends HibernateException {
-	private final int expectedRowCount;
-	private final int actualRowCount;
-
-	public TooManyRowsAffectedException(String message, int expectedRowCount, int actualRowCount) {
-		super( message );
-		this.expectedRowCount = expectedRowCount;
-		this.actualRowCount = actualRowCount;
-	}
-
-	public int getExpectedRowCount() {
-		return expectedRowCount;
-	}
-
-	public int getActualRowCount() {
-		return actualRowCount;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/TooManyRowsAffectedException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Indicates that more rows were affected then we were expecting to be.
+ * Typically indicates presence of duplicate "PK" values in the
+ * given table.
+ *
+ * @author Steve Ebersole
+ */
+public class TooManyRowsAffectedException extends HibernateException {
+	private final int expectedRowCount;
+	private final int actualRowCount;
+
+	public TooManyRowsAffectedException(String message, int expectedRowCount, int actualRowCount) {
+		super( message );
+		this.expectedRowCount = expectedRowCount;
+		this.actualRowCount = actualRowCount;
+	}
+
+	public int getExpectedRowCount() {
+		return expectedRowCount;
+	}
+
+	public int getActualRowCount() {
+		return actualRowCount;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.jdbc;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-
-/**
- * Contract for performing a discrete piece of JDBC work.
- *
- * @author Steve Ebersole
- */
-public interface Work {
-	/**
-	 * Execute the discrete work encapsulated by this work instance using the supplied connection.
-	 *
-	 * @param connection The connection on which to perform the work.
-	 * @throws SQLException Thrown during execution of the underlying JDBC interaction.
-	 * @throws HibernateException Generally indicates a wrapped SQLException.
-	 */
-	public void execute(Connection connection) throws SQLException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/Work.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/Work.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.jdbc;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for performing a discrete piece of JDBC work.
+ *
+ * @author Steve Ebersole
+ */
+public interface Work {
+	/**
+	 * Execute the discrete work encapsulated by this work instance using the supplied connection.
+	 *
+	 * @param connection The connection on which to perform the work.
+	 * @throws SQLException Thrown during execution of the underlying JDBC interaction.
+	 * @throws HibernateException Generally indicates a wrapped SQLException.
+	 */
+	public void execute(Connection connection) throws SQLException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the mechanism for dispatching SQL statements 
-	to the database, and implements interaction with JDBC.
-</p>
-<p>
-	Concrete implementations of the <tt>Batcher</tt> interface may be 
-	selected by specifying <tt>hibernate.jdbc.factory_class</tt>.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the mechanism for dispatching SQL statements 
+	to the database, and implements interaction with JDBC.
+</p>
+<p>
+	Concrete implementations of the <tt>Batcher</tt> interface may be 
+	selected by specifying <tt>hibernate.jdbc.factory_class</tt>.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,388 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Gavin King, Steve Ebersole
- */
-package org.hibernate.jdbc.util;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * Performs formatting of basic SQL statements (DML + query).
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class BasicFormatterImpl implements Formatter {
-
-	private static final Set BEGIN_CLAUSES = new HashSet();
-	private static final Set END_CLAUSES = new HashSet();
-	private static final Set LOGICAL = new HashSet();
-	private static final Set QUANTIFIERS = new HashSet();
-	private static final Set DML = new HashSet();
-	private static final Set MISC = new HashSet();
-
-	static {
-		BEGIN_CLAUSES.add( "left" );
-		BEGIN_CLAUSES.add( "right" );
-		BEGIN_CLAUSES.add( "inner" );
-		BEGIN_CLAUSES.add( "outer" );
-		BEGIN_CLAUSES.add( "group" );
-		BEGIN_CLAUSES.add( "order" );
-
-		END_CLAUSES.add( "where" );
-		END_CLAUSES.add( "set" );
-		END_CLAUSES.add( "having" );
-		END_CLAUSES.add( "join" );
-		END_CLAUSES.add( "from" );
-		END_CLAUSES.add( "by" );
-		END_CLAUSES.add( "join" );
-		END_CLAUSES.add( "into" );
-		END_CLAUSES.add( "union" );
-
-		LOGICAL.add( "and" );
-		LOGICAL.add( "or" );
-		LOGICAL.add( "when" );
-		LOGICAL.add( "else" );
-		LOGICAL.add( "end" );
-
-		QUANTIFIERS.add( "in" );
-		QUANTIFIERS.add( "all" );
-		QUANTIFIERS.add( "exists" );
-		QUANTIFIERS.add( "some" );
-		QUANTIFIERS.add( "any" );
-
-		DML.add( "insert" );
-		DML.add( "update" );
-		DML.add( "delete" );
-
-		MISC.add( "select" );
-		MISC.add( "on" );
-	}
-
-	static final String indentString = "    ";
-	static final String initial = "\n    ";
-
-	public String format(String source) {
-		return new FormatProcess( source ).perform();
-	}
-
-	private static class FormatProcess {
-		boolean beginLine = true;
-		boolean afterBeginBeforeEnd = false;
-		boolean afterByOrSetOrFromOrSelect = false;
-		boolean afterValues = false;
-		boolean afterOn = false;
-		boolean afterBetween = false;
-		boolean afterInsert = false;
-		int inFunction = 0;
-		int parensSinceSelect = 0;
-		private LinkedList parenCounts = new LinkedList();
-		private LinkedList afterByOrFromOrSelects = new LinkedList();
-
-		int indent = 1;
-
-		StringBuffer result = new StringBuffer();
-		StringTokenizer tokens;
-		String lastToken;
-		String token;
-		String lcToken;
-
-		public FormatProcess(String sql) {
-			tokens = new StringTokenizer(
-					sql,
-					"()+*/-=<>'`\"[]," + StringHelper.WHITESPACE,
-					true
-			);
-		}
-
-		public String perform() {
-
-			result.append( initial );
-
-			while ( tokens.hasMoreTokens() ) {
-				token = tokens.nextToken();
-				lcToken = token.toLowerCase();
-
-				if ( "'".equals( token ) ) {
-					String t;
-					do {
-						t = tokens.nextToken();
-						token += t;
-					}
-					while ( !"'".equals( t ) && tokens.hasMoreTokens() ); // cannot handle single quotes
-				}
-				else if ( "\"".equals( token ) ) {
-					String t;
-					do {
-						t = tokens.nextToken();
-						token += t;
-					}
-					while ( !"\"".equals( t ) );
-				}
-
-				if ( afterByOrSetOrFromOrSelect && ",".equals( token ) ) {
-					commaAfterByOrFromOrSelect();
-				}
-				else if ( afterOn && ",".equals( token ) ) {
-					commaAfterOn();
-				}
-
-				else if ( "(".equals( token ) ) {
-					openParen();
-				}
-				else if ( ")".equals( token ) ) {
-					closeParen();
-				}
-
-				else if ( BEGIN_CLAUSES.contains( lcToken ) ) {
-					beginNewClause();
-				}
-
-				else if ( END_CLAUSES.contains( lcToken ) ) {
-					endNewClause();
-				}
-
-				else if ( "select".equals( lcToken ) ) {
-					select();
-				}
-
-				else if ( DML.contains( lcToken ) ) {
-					updateOrInsertOrDelete();
-				}
-
-				else if ( "values".equals( lcToken ) ) {
-					values();
-				}
-
-				else if ( "on".equals( lcToken ) ) {
-					on();
-				}
-
-				else if ( afterBetween && lcToken.equals( "and" ) ) {
-					misc();
-					afterBetween = false;
-				}
-
-				else if ( LOGICAL.contains( lcToken ) ) {
-					logical();
-				}
-
-				else if ( isWhitespace( token ) ) {
-					white();
-				}
-
-				else {
-					misc();
-				}
-
-				if ( !isWhitespace( token ) ) {
-					lastToken = lcToken;
-				}
-
-			}
-			return result.toString();
-		}
-
-		private void commaAfterOn() {
-			out();
-			indent--;
-			newline();
-			afterOn = false;
-			afterByOrSetOrFromOrSelect = true;
-		}
-
-		private void commaAfterByOrFromOrSelect() {
-			out();
-			newline();
-		}
-
-		private void logical() {
-			if ( "end".equals( lcToken ) ) {
-				indent--;
-			}
-			newline();
-			out();
-			beginLine = false;
-		}
-
-		private void on() {
-			indent++;
-			afterOn = true;
-			newline();
-			out();
-			beginLine = false;
-		}
-
-		private void misc() {
-			out();
-			if ( "between".equals( lcToken ) ) {
-				afterBetween = true;
-			}
-			if ( afterInsert ) {
-				newline();
-				afterInsert = false;
-			}
-			else {
-				beginLine = false;
-				if ( "case".equals( lcToken ) ) {
-					indent++;
-				}
-			}
-		}
-
-		private void white() {
-			if ( !beginLine ) {
-				result.append( " " );
-			}
-		}
-
-		private void updateOrInsertOrDelete() {
-			out();
-			indent++;
-			beginLine = false;
-			if ( "update".equals( lcToken ) ) {
-				newline();
-			}
-			if ( "insert".equals( lcToken ) ) {
-				afterInsert = true;
-			}
-		}
-
-		private void select() {
-			out();
-			indent++;
-			newline();
-			parenCounts.addLast( new Integer( parensSinceSelect ) );
-			afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) );
-			parensSinceSelect = 0;
-			afterByOrSetOrFromOrSelect = true;
-		}
-
-		private void out() {
-			result.append( token );
-		}
-
-		private void endNewClause() {
-			if ( !afterBeginBeforeEnd ) {
-				indent--;
-				if ( afterOn ) {
-					indent--;
-					afterOn = false;
-				}
-				newline();
-			}
-			out();
-			if ( !"union".equals( lcToken ) ) {
-				indent++;
-			}
-			newline();
-			afterBeginBeforeEnd = false;
-			afterByOrSetOrFromOrSelect = "by".equals( lcToken )
-					|| "set".equals( lcToken )
-					|| "from".equals( lcToken );
-		}
-
-		private void beginNewClause() {
-			if ( !afterBeginBeforeEnd ) {
-				if ( afterOn ) {
-					indent--;
-					afterOn = false;
-				}
-				indent--;
-				newline();
-			}
-			out();
-			beginLine = false;
-			afterBeginBeforeEnd = true;
-		}
-
-		private void values() {
-			indent--;
-			newline();
-			out();
-			indent++;
-			newline();
-			afterValues = true;
-		}
-
-		private void closeParen() {
-			parensSinceSelect--;
-			if ( parensSinceSelect < 0 ) {
-				indent--;
-				parensSinceSelect = ( ( Integer ) parenCounts.removeLast() ).intValue();
-				afterByOrSetOrFromOrSelect = ( ( Boolean ) afterByOrFromOrSelects.removeLast() ).booleanValue();
-			}
-			if ( inFunction > 0 ) {
-				inFunction--;
-				out();
-			}
-			else {
-				if ( !afterByOrSetOrFromOrSelect ) {
-					indent--;
-					newline();
-				}
-				out();
-			}
-			beginLine = false;
-		}
-
-		private void openParen() {
-			if ( isFunctionName( lastToken ) || inFunction > 0 ) {
-				inFunction++;
-			}
-			beginLine = false;
-			if ( inFunction > 0 ) {
-				out();
-			}
-			else {
-				out();
-				if ( !afterByOrSetOrFromOrSelect ) {
-					indent++;
-					newline();
-					beginLine = true;
-				}
-			}
-			parensSinceSelect++;
-		}
-
-		private static boolean isFunctionName(String tok) {
-			final char begin = tok.charAt( 0 );
-			final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"' == begin;
-			return isIdentifier &&
-					!LOGICAL.contains( tok ) &&
-					!END_CLAUSES.contains( tok ) &&
-					!QUANTIFIERS.contains( tok ) &&
-					!DML.contains( tok ) &&
-					!MISC.contains( tok );
-		}
-
-		private static boolean isWhitespace(String token) {
-			return StringHelper.WHITESPACE.indexOf( token ) >= 0;
-		}
-
-		private void newline() {
-			result.append( "\n" );
-			for ( int i = 0; i < indent; i++ ) {
-				result.append( indentString );
-			}
-			beginLine = true;
-		}
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/BasicFormatterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,397 @@
+/*
+ * 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.jdbc.util;
+
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * Performs formatting of basic SQL statements (DML + query).
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class BasicFormatterImpl implements Formatter {
+
+	private static final Set BEGIN_CLAUSES = new HashSet();
+	private static final Set END_CLAUSES = new HashSet();
+	private static final Set LOGICAL = new HashSet();
+	private static final Set QUANTIFIERS = new HashSet();
+	private static final Set DML = new HashSet();
+	private static final Set MISC = new HashSet();
+
+	static {
+		BEGIN_CLAUSES.add( "left" );
+		BEGIN_CLAUSES.add( "right" );
+		BEGIN_CLAUSES.add( "inner" );
+		BEGIN_CLAUSES.add( "outer" );
+		BEGIN_CLAUSES.add( "group" );
+		BEGIN_CLAUSES.add( "order" );
+
+		END_CLAUSES.add( "where" );
+		END_CLAUSES.add( "set" );
+		END_CLAUSES.add( "having" );
+		END_CLAUSES.add( "join" );
+		END_CLAUSES.add( "from" );
+		END_CLAUSES.add( "by" );
+		END_CLAUSES.add( "join" );
+		END_CLAUSES.add( "into" );
+		END_CLAUSES.add( "union" );
+
+		LOGICAL.add( "and" );
+		LOGICAL.add( "or" );
+		LOGICAL.add( "when" );
+		LOGICAL.add( "else" );
+		LOGICAL.add( "end" );
+
+		QUANTIFIERS.add( "in" );
+		QUANTIFIERS.add( "all" );
+		QUANTIFIERS.add( "exists" );
+		QUANTIFIERS.add( "some" );
+		QUANTIFIERS.add( "any" );
+
+		DML.add( "insert" );
+		DML.add( "update" );
+		DML.add( "delete" );
+
+		MISC.add( "select" );
+		MISC.add( "on" );
+	}
+
+	static final String indentString = "    ";
+	static final String initial = "\n    ";
+
+	public String format(String source) {
+		return new FormatProcess( source ).perform();
+	}
+
+	private static class FormatProcess {
+		boolean beginLine = true;
+		boolean afterBeginBeforeEnd = false;
+		boolean afterByOrSetOrFromOrSelect = false;
+		boolean afterValues = false;
+		boolean afterOn = false;
+		boolean afterBetween = false;
+		boolean afterInsert = false;
+		int inFunction = 0;
+		int parensSinceSelect = 0;
+		private LinkedList parenCounts = new LinkedList();
+		private LinkedList afterByOrFromOrSelects = new LinkedList();
+
+		int indent = 1;
+
+		StringBuffer result = new StringBuffer();
+		StringTokenizer tokens;
+		String lastToken;
+		String token;
+		String lcToken;
+
+		public FormatProcess(String sql) {
+			tokens = new StringTokenizer(
+					sql,
+					"()+*/-=<>'`\"[]," + StringHelper.WHITESPACE,
+					true
+			);
+		}
+
+		public String perform() {
+
+			result.append( initial );
+
+			while ( tokens.hasMoreTokens() ) {
+				token = tokens.nextToken();
+				lcToken = token.toLowerCase();
+
+				if ( "'".equals( token ) ) {
+					String t;
+					do {
+						t = tokens.nextToken();
+						token += t;
+					}
+					while ( !"'".equals( t ) && tokens.hasMoreTokens() ); // cannot handle single quotes
+				}
+				else if ( "\"".equals( token ) ) {
+					String t;
+					do {
+						t = tokens.nextToken();
+						token += t;
+					}
+					while ( !"\"".equals( t ) );
+				}
+
+				if ( afterByOrSetOrFromOrSelect && ",".equals( token ) ) {
+					commaAfterByOrFromOrSelect();
+				}
+				else if ( afterOn && ",".equals( token ) ) {
+					commaAfterOn();
+				}
+
+				else if ( "(".equals( token ) ) {
+					openParen();
+				}
+				else if ( ")".equals( token ) ) {
+					closeParen();
+				}
+
+				else if ( BEGIN_CLAUSES.contains( lcToken ) ) {
+					beginNewClause();
+				}
+
+				else if ( END_CLAUSES.contains( lcToken ) ) {
+					endNewClause();
+				}
+
+				else if ( "select".equals( lcToken ) ) {
+					select();
+				}
+
+				else if ( DML.contains( lcToken ) ) {
+					updateOrInsertOrDelete();
+				}
+
+				else if ( "values".equals( lcToken ) ) {
+					values();
+				}
+
+				else if ( "on".equals( lcToken ) ) {
+					on();
+				}
+
+				else if ( afterBetween && lcToken.equals( "and" ) ) {
+					misc();
+					afterBetween = false;
+				}
+
+				else if ( LOGICAL.contains( lcToken ) ) {
+					logical();
+				}
+
+				else if ( isWhitespace( token ) ) {
+					white();
+				}
+
+				else {
+					misc();
+				}
+
+				if ( !isWhitespace( token ) ) {
+					lastToken = lcToken;
+				}
+
+			}
+			return result.toString();
+		}
+
+		private void commaAfterOn() {
+			out();
+			indent--;
+			newline();
+			afterOn = false;
+			afterByOrSetOrFromOrSelect = true;
+		}
+
+		private void commaAfterByOrFromOrSelect() {
+			out();
+			newline();
+		}
+
+		private void logical() {
+			if ( "end".equals( lcToken ) ) {
+				indent--;
+			}
+			newline();
+			out();
+			beginLine = false;
+		}
+
+		private void on() {
+			indent++;
+			afterOn = true;
+			newline();
+			out();
+			beginLine = false;
+		}
+
+		private void misc() {
+			out();
+			if ( "between".equals( lcToken ) ) {
+				afterBetween = true;
+			}
+			if ( afterInsert ) {
+				newline();
+				afterInsert = false;
+			}
+			else {
+				beginLine = false;
+				if ( "case".equals( lcToken ) ) {
+					indent++;
+				}
+			}
+		}
+
+		private void white() {
+			if ( !beginLine ) {
+				result.append( " " );
+			}
+		}
+
+		private void updateOrInsertOrDelete() {
+			out();
+			indent++;
+			beginLine = false;
+			if ( "update".equals( lcToken ) ) {
+				newline();
+			}
+			if ( "insert".equals( lcToken ) ) {
+				afterInsert = true;
+			}
+		}
+
+		private void select() {
+			out();
+			indent++;
+			newline();
+			parenCounts.addLast( new Integer( parensSinceSelect ) );
+			afterByOrFromOrSelects.addLast( Boolean.valueOf( afterByOrSetOrFromOrSelect ) );
+			parensSinceSelect = 0;
+			afterByOrSetOrFromOrSelect = true;
+		}
+
+		private void out() {
+			result.append( token );
+		}
+
+		private void endNewClause() {
+			if ( !afterBeginBeforeEnd ) {
+				indent--;
+				if ( afterOn ) {
+					indent--;
+					afterOn = false;
+				}
+				newline();
+			}
+			out();
+			if ( !"union".equals( lcToken ) ) {
+				indent++;
+			}
+			newline();
+			afterBeginBeforeEnd = false;
+			afterByOrSetOrFromOrSelect = "by".equals( lcToken )
+					|| "set".equals( lcToken )
+					|| "from".equals( lcToken );
+		}
+
+		private void beginNewClause() {
+			if ( !afterBeginBeforeEnd ) {
+				if ( afterOn ) {
+					indent--;
+					afterOn = false;
+				}
+				indent--;
+				newline();
+			}
+			out();
+			beginLine = false;
+			afterBeginBeforeEnd = true;
+		}
+
+		private void values() {
+			indent--;
+			newline();
+			out();
+			indent++;
+			newline();
+			afterValues = true;
+		}
+
+		private void closeParen() {
+			parensSinceSelect--;
+			if ( parensSinceSelect < 0 ) {
+				indent--;
+				parensSinceSelect = ( ( Integer ) parenCounts.removeLast() ).intValue();
+				afterByOrSetOrFromOrSelect = ( ( Boolean ) afterByOrFromOrSelects.removeLast() ).booleanValue();
+			}
+			if ( inFunction > 0 ) {
+				inFunction--;
+				out();
+			}
+			else {
+				if ( !afterByOrSetOrFromOrSelect ) {
+					indent--;
+					newline();
+				}
+				out();
+			}
+			beginLine = false;
+		}
+
+		private void openParen() {
+			if ( isFunctionName( lastToken ) || inFunction > 0 ) {
+				inFunction++;
+			}
+			beginLine = false;
+			if ( inFunction > 0 ) {
+				out();
+			}
+			else {
+				out();
+				if ( !afterByOrSetOrFromOrSelect ) {
+					indent++;
+					newline();
+					beginLine = true;
+				}
+			}
+			parensSinceSelect++;
+		}
+
+		private static boolean isFunctionName(String tok) {
+			final char begin = tok.charAt( 0 );
+			final boolean isIdentifier = Character.isJavaIdentifierStart( begin ) || '"' == begin;
+			return isIdentifier &&
+					!LOGICAL.contains( tok ) &&
+					!END_CLAUSES.contains( tok ) &&
+					!QUANTIFIERS.contains( tok ) &&
+					!DML.contains( tok ) &&
+					!MISC.contains( tok );
+		}
+
+		private static boolean isWhitespace(String token) {
+			return StringHelper.WHITESPACE.indexOf( token ) >= 0;
+		}
+
+		private void newline() {
+			result.append( "\n" );
+			for ( int i = 0; i < indent; i++ ) {
+				result.append( indentString );
+			}
+			beginLine = true;
+		}
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Gavin King, Steve Ebersole
- */
-package org.hibernate.jdbc.util;
-
-import java.util.StringTokenizer;
-
-/**
- * Performs formatting of DDL SQL statements.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class DDLFormatterImpl implements Formatter {
-	/**
-	 * Format an SQL statement using simple rules<ul>
-	 * <li>Insert newline after each comma</li>
-	 * <li>Indent three spaces after each inserted newline</li>
-	 * </ul>
-	 * If the statement contains single/double quotes return unchanged,
-	 * it is too complex and could be broken by simple formatting.
-	 * 
-	 * @param sql The statement to be fornmatted.
-	 */
-	public String format(String sql) {
-		if ( sql.toLowerCase().startsWith( "create table" ) ) {
-			return formatCreateTable( sql );
-		}
-		else if ( sql.toLowerCase().startsWith( "alter table" ) ) {
-			return formatAlterTable( sql );
-		}
-		else if ( sql.toLowerCase().startsWith( "comment on" ) ) {
-			return formatCommentOn( sql );
-		}
-		else {
-			return "\n    " + sql;
-		}
-	}
-
-	private String formatCommentOn(String sql) {
-		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
-		StringTokenizer tokens = new StringTokenizer( sql, " '[]\"", true );
-
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			result.append( token );
-			if ( isQuote( token ) ) {
-				quoted = !quoted;
-			}
-			else if ( !quoted ) {
-				if ( "is".equals( token ) ) {
-					result.append( "\n       " );
-				}
-			}
-		}
-
-		return result.toString();
-	}
-
-	private String formatAlterTable(String sql) {
-		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
-		StringTokenizer tokens = new StringTokenizer( sql, " (,)'[]\"", true );
-
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			if ( isQuote( token ) ) {
-				quoted = !quoted;
-			}
-			else if ( !quoted ) {
-				if ( isBreak( token ) ) {
-					result.append( "\n        " );
-				}
-			}
-			result.append( token );
-		}
-
-		return result.toString();
-	}
-
-	private String formatCreateTable(String sql) {
-		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
-		StringTokenizer tokens = new StringTokenizer( sql, "(,)'[]\"", true );
-
-		int depth = 0;
-		boolean quoted = false;
-		while ( tokens.hasMoreTokens() ) {
-			String token = tokens.nextToken();
-			if ( isQuote( token ) ) {
-				quoted = !quoted;
-				result.append( token );
-			}
-			else if ( quoted ) {
-				result.append( token );
-			}
-			else {
-				if ( ")".equals( token ) ) {
-					depth--;
-					if ( depth == 0 ) {
-						result.append( "\n    " );
-					}
-				}
-				result.append( token );
-				if ( ",".equals( token ) && depth == 1 ) {
-					result.append( "\n       " );
-				}
-				if ( "(".equals( token ) ) {
-					depth++;
-					if ( depth == 1 ) {
-						result.append( "\n        " );
-					}
-				}
-			}
-		}
-
-		return result.toString();
-	}
-
-	private static boolean isBreak(String token) {
-		return "drop".equals( token ) ||
-				"add".equals( token ) ||
-				"references".equals( token ) ||
-				"foreign".equals( token ) ||
-				"on".equals( token );
-	}
-
-	private static boolean isQuote(String tok) {
-		return "\"".equals( tok ) ||
-				"`".equals( tok ) ||
-				"]".equals( tok ) ||
-				"[".equals( tok ) ||
-				"'".equals( tok );
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/DDLFormatterImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,157 @@
+/*
+ * 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.jdbc.util;
+
+import java.util.StringTokenizer;
+
+/**
+ * Performs formatting of DDL SQL statements.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class DDLFormatterImpl implements Formatter {
+	/**
+	 * Format an SQL statement using simple rules<ul>
+	 * <li>Insert newline after each comma</li>
+	 * <li>Indent three spaces after each inserted newline</li>
+	 * </ul>
+	 * If the statement contains single/double quotes return unchanged,
+	 * it is too complex and could be broken by simple formatting.
+	 * 
+	 * @param sql The statement to be fornmatted.
+	 */
+	public String format(String sql) {
+		if ( sql.toLowerCase().startsWith( "create table" ) ) {
+			return formatCreateTable( sql );
+		}
+		else if ( sql.toLowerCase().startsWith( "alter table" ) ) {
+			return formatAlterTable( sql );
+		}
+		else if ( sql.toLowerCase().startsWith( "comment on" ) ) {
+			return formatCommentOn( sql );
+		}
+		else {
+			return "\n    " + sql;
+		}
+	}
+
+	private String formatCommentOn(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, " '[]\"", true );
+
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			result.append( token );
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+			}
+			else if ( !quoted ) {
+				if ( "is".equals( token ) ) {
+					result.append( "\n       " );
+				}
+			}
+		}
+
+		return result.toString();
+	}
+
+	private String formatAlterTable(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, " (,)'[]\"", true );
+
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+			}
+			else if ( !quoted ) {
+				if ( isBreak( token ) ) {
+					result.append( "\n        " );
+				}
+			}
+			result.append( token );
+		}
+
+		return result.toString();
+	}
+
+	private String formatCreateTable(String sql) {
+		StringBuffer result = new StringBuffer( 60 ).append( "\n    " );
+		StringTokenizer tokens = new StringTokenizer( sql, "(,)'[]\"", true );
+
+		int depth = 0;
+		boolean quoted = false;
+		while ( tokens.hasMoreTokens() ) {
+			String token = tokens.nextToken();
+			if ( isQuote( token ) ) {
+				quoted = !quoted;
+				result.append( token );
+			}
+			else if ( quoted ) {
+				result.append( token );
+			}
+			else {
+				if ( ")".equals( token ) ) {
+					depth--;
+					if ( depth == 0 ) {
+						result.append( "\n    " );
+					}
+				}
+				result.append( token );
+				if ( ",".equals( token ) && depth == 1 ) {
+					result.append( "\n       " );
+				}
+				if ( "(".equals( token ) ) {
+					depth++;
+					if ( depth == 1 ) {
+						result.append( "\n        " );
+					}
+				}
+			}
+		}
+
+		return result.toString();
+	}
+
+	private static boolean isBreak(String token) {
+		return "drop".equals( token ) ||
+				"add".equals( token ) ||
+				"references".equals( token ) ||
+				"foreign".equals( token ) ||
+				"on".equals( token );
+	}
+
+	private static boolean isQuote(String tok) {
+		return "\"".equals( tok ) ||
+				"`".equals( tok ) ||
+				"]".equals( tok ) ||
+				"[".equals( tok ) ||
+				"'".equals( tok );
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.jdbc.util;
-
-/**
- * Represents the the understood types or styles of formatting. 
- *
- * @author Steve Ebersole
- */
-public class FormatStyle {
-	public static final FormatStyle BASIC = new FormatStyle( "basic", new BasicFormatterImpl() );
-	public static final FormatStyle DDL = new FormatStyle( "ddl", new DDLFormatterImpl() );
-	public static final FormatStyle NONE = new FormatStyle( "none", new NoFormatImpl() );
-
-	private final String name;
-	private final Formatter formatter;
-
-	private FormatStyle(String name, Formatter formatter) {
-		this.name = name;
-		this.formatter = formatter;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Formatter getFormatter() {
-		return formatter;
-	}
-
-	public boolean equals(Object o) {
-		if ( this == o ) {
-			return true;
-		}
-		if ( o == null || getClass() != o.getClass() ) {
-			return false;
-		}
-
-		FormatStyle that = ( FormatStyle ) o;
-
-		return name.equals( that.name );
-
-	}
-
-	public int hashCode() {
-		return name.hashCode();
-	}
-
-	private static class NoFormatImpl implements Formatter {
-		public String format(String source) {
-			return source;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/FormatStyle.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.jdbc.util;
+
+/**
+ * Represents the the understood types or styles of formatting. 
+ *
+ * @author Steve Ebersole
+ */
+public class FormatStyle {
+	public static final FormatStyle BASIC = new FormatStyle( "basic", new BasicFormatterImpl() );
+	public static final FormatStyle DDL = new FormatStyle( "ddl", new DDLFormatterImpl() );
+	public static final FormatStyle NONE = new FormatStyle( "none", new NoFormatImpl() );
+
+	private final String name;
+	private final Formatter formatter;
+
+	private FormatStyle(String name, Formatter formatter) {
+		this.name = name;
+		this.formatter = formatter;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Formatter getFormatter() {
+		return formatter;
+	}
+
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+
+		FormatStyle that = ( FormatStyle ) o;
+
+		return name.equals( that.name );
+
+	}
+
+	public int hashCode() {
+		return name.hashCode();
+	}
+
+	private static class NoFormatImpl implements Formatter {
+		public String format(String source) {
+			return source;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.jdbc.util;
-
-/**
- * Formatter contract
- *
- * @author Steve Ebersole
- */
-public interface Formatter {
-	public String format(String source);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/util/Formatter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/Formatter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+/*
+ * 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.jdbc.util;
+
+/**
+ * Formatter contract
+ *
+ * @author Steve Ebersole
+ */
+public interface Formatter {
+	public String format(String source);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Steve Ebersole
- */
-package org.hibernate.jdbc.util;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Centralize logging handling for SQL statements.
- *
- * @author Steve Ebersole
- */
-public class SQLStatementLogger {
-	// todo : for 4.0
-//	private static final Logger log = LoggerFactory.getLogger( SQLStatementLogger.class );
-	// this is the legacy logging 'category'...
-	private static final Logger log = LoggerFactory.getLogger( "org.hibernate.SQL" );
-
-	private boolean logToStdout;
-	private boolean formatSql;
-
-	/**
-	 * Constructs a new SQLStatementLogger instance.
-	 */
-	public SQLStatementLogger() {
-		this( false, false );
-	}
-
-	/**
-	 * Constructs a new SQLStatementLogger instance.
-	 *
-	 * @param logToStdout Should we log to STDOUT in addition to our internal logger.
-	 * @param formatSql Should we format SQL ('prettify') prior to logging.
-	 */
-	public SQLStatementLogger(boolean logToStdout, boolean formatSql) {
-		this.logToStdout = logToStdout;
-		this.formatSql = formatSql;
-	}
-
-	/**
-	 * Getter for property 'logToStdout'.
-	 * @see #setLogToStdout
-	 *
-	 * @return Value for property 'logToStdout'.
-	 */
-	public boolean isLogToStdout() {
-		return logToStdout;
-	}
-
-	/**
-	 * Setter for property 'logToStdout'.
-	 *
-	 * @param logToStdout Value to set for property 'logToStdout'.
-	 */
-	public void setLogToStdout(boolean logToStdout) {
-		this.logToStdout = logToStdout;
-	}
-
-	/**
-	 * Getter for property 'formatSql'.
-	 * @see #setFormatSql
-	 *
-	 * @return Value for property 'formatSql'.
-	 */
-	public boolean isFormatSql() {
-		return formatSql;
-	}
-
-	/**
-	 * Setter for property 'formatSql'.
-	 *
-	 * @param formatSql Value to set for property 'formatSql'.
-	 */
-	public void setFormatSql(boolean formatSql) {
-		this.formatSql = formatSql;
-	}
-
-	/**
-	 * Log a SQL statement string.
-	 *
-	 * @param statement The SQL statement.
-	 * @param style The requested formatting style.
-	 */
-	public void logStatement(String statement, FormatStyle style) {
-		if ( log.isDebugEnabled() || logToStdout ) {
-			style = determineActualStyle( style );
-			statement = style.getFormatter().format( statement );
-		}
-		log.debug( statement );
-		if ( logToStdout ) {
-			System.out.println( "Hibernate: " + statement );
-		}
-	}
-
-	private FormatStyle determineActualStyle(FormatStyle style) {
-		return formatSql ? style : FormatStyle.NONE;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/jdbc/util/SQLStatementLogger.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,120 @@
+/*
+ * 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.jdbc.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Centralize logging handling for SQL statements.
+ *
+ * @author Steve Ebersole
+ */
+public class SQLStatementLogger {
+	// todo : for 4.0
+//	private static final Logger log = LoggerFactory.getLogger( SQLStatementLogger.class );
+	// this is the legacy logging 'category'...
+	private static final Logger log = LoggerFactory.getLogger( "org.hibernate.SQL" );
+
+	private boolean logToStdout;
+	private boolean formatSql;
+
+	/**
+	 * Constructs a new SQLStatementLogger instance.
+	 */
+	public SQLStatementLogger() {
+		this( false, false );
+	}
+
+	/**
+	 * Constructs a new SQLStatementLogger instance.
+	 *
+	 * @param logToStdout Should we log to STDOUT in addition to our internal logger.
+	 * @param formatSql Should we format SQL ('prettify') prior to logging.
+	 */
+	public SQLStatementLogger(boolean logToStdout, boolean formatSql) {
+		this.logToStdout = logToStdout;
+		this.formatSql = formatSql;
+	}
+
+	/**
+	 * Getter for property 'logToStdout'.
+	 * @see #setLogToStdout
+	 *
+	 * @return Value for property 'logToStdout'.
+	 */
+	public boolean isLogToStdout() {
+		return logToStdout;
+	}
+
+	/**
+	 * Setter for property 'logToStdout'.
+	 *
+	 * @param logToStdout Value to set for property 'logToStdout'.
+	 */
+	public void setLogToStdout(boolean logToStdout) {
+		this.logToStdout = logToStdout;
+	}
+
+	/**
+	 * Getter for property 'formatSql'.
+	 * @see #setFormatSql
+	 *
+	 * @return Value for property 'formatSql'.
+	 */
+	public boolean isFormatSql() {
+		return formatSql;
+	}
+
+	/**
+	 * Setter for property 'formatSql'.
+	 *
+	 * @param formatSql Value to set for property 'formatSql'.
+	 */
+	public void setFormatSql(boolean formatSql) {
+		this.formatSql = formatSql;
+	}
+
+	/**
+	 * Log a SQL statement string.
+	 *
+	 * @param statement The SQL statement.
+	 * @param style The requested formatting style.
+	 */
+	public void logStatement(String statement, FormatStyle style) {
+		if ( log.isDebugEnabled() || logToStdout ) {
+			style = determineActualStyle( style );
+			statement = style.getFormatter().format( statement );
+		}
+		log.debug( statement );
+		if ( logToStdout ) {
+			System.out.println( "Hibernate: " + statement );
+		}
+	}
+
+	private FormatStyle determineActualStyle(FormatStyle style) {
+		return formatSql ? style : FormatStyle.NONE;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,145 +0,0 @@
-//$Id: AbstractEntityJoinWalker.java 11081 2007-01-23 16:31:13Z steve.ebersole at jboss.com $
-package org.hibernate.loader;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.Select;
-import org.hibernate.type.AssociationType;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * Abstract walker for walkers which begin at an entity (criteria
- * queries and entity loaders).
- *
- * @author Gavin King
- */
-public abstract class AbstractEntityJoinWalker extends JoinWalker {
-
-	private final OuterJoinLoadable persister;
-	private final String alias;
-
-	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters) {
-		this( persister, factory, enabledFilters, null );
-	}
-
-	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters, String alias) {
-		super( factory, enabledFilters );
-		this.persister = persister;
-		this.alias = ( alias == null ) ? generateRootAlias( persister.getEntityName() ) : alias;
-	}
-
-	protected final void initAll(
-		final String whereString,
-		final String orderByString,
-		final LockMode lockMode)
-	throws MappingException {
-		walkEntityTree( persister, getAlias() );
-		List allAssociations = new ArrayList();
-		allAssociations.addAll(associations);
-		allAssociations.add( new OuterJoinableAssociation(
-				persister.getEntityType(),
-				null,
-				null,
-				alias,
-				JoinFragment.LEFT_OUTER_JOIN,
-				getFactory(),
-				CollectionHelper.EMPTY_MAP
-			) );
-
-		initPersisters(allAssociations, lockMode);
-		initStatementString( whereString, orderByString, lockMode);
-	}
-
-	protected final void initProjection(
-		final String projectionString,
-		final String whereString,
-		final String orderByString,
-		final String groupByString,
-		final LockMode lockMode)
-	throws MappingException {
-		walkEntityTree( persister, getAlias() );
-		persisters = new Loadable[0];
-		initStatementString(projectionString, whereString, orderByString, groupByString, lockMode);
-	}
-
-	private void initStatementString(
-		final String condition,
-		final String orderBy,
-		final LockMode lockMode)
-	throws MappingException {
-		initStatementString(null, condition, orderBy, "", lockMode);
-	}
-
-	private void initStatementString(
-			final String projection,
-			final String condition,
-			final String orderBy,
-			final String groupBy,
-			final LockMode lockMode) throws MappingException {
-
-		final int joins = countEntityPersisters( associations );
-		suffixes = BasicLoader.generateSuffixes( joins + 1 );
-
-		JoinFragment ojf = mergeOuterJoins( associations );
-
-		Select select = new Select( getDialect() )
-				.setLockMode( lockMode )
-				.setSelectClause(
-						projection == null ?
-								persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
-								projection
-				)
-				.setFromClause(
-						getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) +
-								persister.fromJoinFragment( alias, true, true )
-				)
-				.setWhereClause( condition )
-				.setOuterJoins(
-						ojf.toFromFragmentString(),
-						ojf.toWhereFragmentString() + getWhereFragment()
-				)
-				.setOrderByClause( orderBy( associations, orderBy ) )
-				.setGroupByClause( groupBy );
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( getComment() );
-		}
-		sql = select.toStatementString();
-	}
-
-	protected String getWhereFragment() throws MappingException {
-		// here we do not bother with the discriminator.
-		return persister.whereJoinFragment(alias, true, true);
-	}
-
-	/**
-	 * The superclass deliberately excludes collections
-	 */
-	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
-		return isJoinedFetchEnabledInMapping(config, type);
-	}
-
-	public abstract String getComment();
-
-	protected final Loadable getPersister() {
-		return persister;
-	}
-
-	protected final String getAlias() {
-		return alias;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getPersister().getEntityName() + ')';
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/AbstractEntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,168 @@
+/*
+ * 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.loader;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.Select;
+import org.hibernate.type.AssociationType;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * Abstract walker for walkers which begin at an entity (criteria
+ * queries and entity loaders).
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractEntityJoinWalker extends JoinWalker {
+
+	private final OuterJoinLoadable persister;
+	private final String alias;
+
+	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters) {
+		this( persister, factory, enabledFilters, null );
+	}
+
+	public AbstractEntityJoinWalker(OuterJoinLoadable persister, SessionFactoryImplementor factory, Map enabledFilters, String alias) {
+		super( factory, enabledFilters );
+		this.persister = persister;
+		this.alias = ( alias == null ) ? generateRootAlias( persister.getEntityName() ) : alias;
+	}
+
+	protected final void initAll(
+		final String whereString,
+		final String orderByString,
+		final LockMode lockMode)
+	throws MappingException {
+		walkEntityTree( persister, getAlias() );
+		List allAssociations = new ArrayList();
+		allAssociations.addAll(associations);
+		allAssociations.add( new OuterJoinableAssociation(
+				persister.getEntityType(),
+				null,
+				null,
+				alias,
+				JoinFragment.LEFT_OUTER_JOIN,
+				getFactory(),
+				CollectionHelper.EMPTY_MAP
+			) );
+
+		initPersisters(allAssociations, lockMode);
+		initStatementString( whereString, orderByString, lockMode);
+	}
+
+	protected final void initProjection(
+		final String projectionString,
+		final String whereString,
+		final String orderByString,
+		final String groupByString,
+		final LockMode lockMode)
+	throws MappingException {
+		walkEntityTree( persister, getAlias() );
+		persisters = new Loadable[0];
+		initStatementString(projectionString, whereString, orderByString, groupByString, lockMode);
+	}
+
+	private void initStatementString(
+		final String condition,
+		final String orderBy,
+		final LockMode lockMode)
+	throws MappingException {
+		initStatementString(null, condition, orderBy, "", lockMode);
+	}
+
+	private void initStatementString(
+			final String projection,
+			final String condition,
+			final String orderBy,
+			final String groupBy,
+			final LockMode lockMode) throws MappingException {
+
+		final int joins = countEntityPersisters( associations );
+		suffixes = BasicLoader.generateSuffixes( joins + 1 );
+
+		JoinFragment ojf = mergeOuterJoins( associations );
+
+		Select select = new Select( getDialect() )
+				.setLockMode( lockMode )
+				.setSelectClause(
+						projection == null ?
+								persister.selectFragment( alias, suffixes[joins] ) + selectString( associations ) :
+								projection
+				)
+				.setFromClause(
+						getDialect().appendLockHint( lockMode, persister.fromTableFragment( alias ) ) +
+								persister.fromJoinFragment( alias, true, true )
+				)
+				.setWhereClause( condition )
+				.setOuterJoins(
+						ojf.toFromFragmentString(),
+						ojf.toWhereFragmentString() + getWhereFragment()
+				)
+				.setOrderByClause( orderBy( associations, orderBy ) )
+				.setGroupByClause( groupBy );
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( getComment() );
+		}
+		sql = select.toStatementString();
+	}
+
+	protected String getWhereFragment() throws MappingException {
+		// here we do not bother with the discriminator.
+		return persister.whereJoinFragment(alias, true, true);
+	}
+
+	/**
+	 * The superclass deliberately excludes collections
+	 */
+	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
+		return isJoinedFetchEnabledInMapping(config, type);
+	}
+
+	public abstract String getComment();
+
+	protected final Loadable getPersister() {
+		return persister;
+	}
+
+	protected final String getAlias() {
+		return alias;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getPersister().getEntityName() + ')';
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/BasicLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-//$Id: BasicLoader.java 9870 2006-05-04 11:57:58Z steve.ebersole at jboss.com $
-package org.hibernate.loader;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.type.BagType;
-import org.hibernate.HibernateException;
-
-/**
- * Uses the default mapping from property to result set column 
- * alias defined by the entities' persisters. Used when Hibernate
- * is generating result set column aliases.
- * 
- * @author Gavin King
- */
-public abstract class BasicLoader extends Loader {
-
-	protected static final String[] NO_SUFFIX = {""};
-
-	private EntityAliases[] descriptors;
-	private CollectionAliases[] collectionDescriptors;
-
-	public BasicLoader(SessionFactoryImplementor factory) {
-		super(factory);
-	}
-
-	protected final EntityAliases[] getEntityAliases() {
-		return descriptors;
-	}
-
-	protected final CollectionAliases[] getCollectionAliases() {
-		return collectionDescriptors;
-	}
-
-	protected abstract String[] getSuffixes();
-	protected abstract String[] getCollectionSuffixes();
-
-	protected void postInstantiate() {
-		Loadable[] persisters = getEntityPersisters();
-		String[] suffixes = getSuffixes();
-		descriptors = new EntityAliases[persisters.length];
-		for ( int i=0; i<descriptors.length; i++ ) {
-			descriptors[i] = new DefaultEntityAliases( persisters[i], suffixes[i] );
-		}
-
-		CollectionPersister[] collectionPersisters = getCollectionPersisters();
-		int bagCount = 0;
-		if ( collectionPersisters != null ) {
-			String[] collectionSuffixes = getCollectionSuffixes();
-			collectionDescriptors = new CollectionAliases[collectionPersisters.length];
-			for ( int i = 0; i < collectionPersisters.length; i++ ) {
-				if ( isBag( collectionPersisters[i] ) ) {
-					bagCount++;
-				}
-				collectionDescriptors[i] = new GeneratedCollectionAliases(
-						collectionPersisters[i],
-						collectionSuffixes[i]
-					);
-			}
-		}
-		else {
-			collectionDescriptors = null;
-		}
-		if ( bagCount > 1 ) {
-			throw new HibernateException( "cannot simultaneously fetch multiple bags" );
-		}
-	}
-
-	private boolean isBag(CollectionPersister collectionPersister) {
-		return collectionPersister.getCollectionType().getClass().isAssignableFrom( BagType.class );
-	}
-
-	/**
-	 * Utility method that generates 0_, 1_ suffixes. Subclasses don't
-	 * necessarily need to use this algorithm, but it is intended that
-	 * they will in most cases.
-	 */
-	public static String[] generateSuffixes(int length) {
-		return generateSuffixes( 0, length );
-	}
-
-	public static String[] generateSuffixes(int seed, int length) {
-		if ( length == 0 ) return NO_SUFFIX;
-
-		String[] suffixes = new String[length];
-		for ( int i = 0; i < length; i++ ) {
-			suffixes[i] = Integer.toString( i + seed ) + "_";
-		}
-		return suffixes;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/BasicLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/BasicLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.type.BagType;
+import org.hibernate.HibernateException;
+
+/**
+ * Uses the default mapping from property to result set column 
+ * alias defined by the entities' persisters. Used when Hibernate
+ * is generating result set column aliases.
+ * 
+ * @author Gavin King
+ */
+public abstract class BasicLoader extends Loader {
+
+	protected static final String[] NO_SUFFIX = {""};
+
+	private EntityAliases[] descriptors;
+	private CollectionAliases[] collectionDescriptors;
+
+	public BasicLoader(SessionFactoryImplementor factory) {
+		super(factory);
+	}
+
+	protected final EntityAliases[] getEntityAliases() {
+		return descriptors;
+	}
+
+	protected final CollectionAliases[] getCollectionAliases() {
+		return collectionDescriptors;
+	}
+
+	protected abstract String[] getSuffixes();
+	protected abstract String[] getCollectionSuffixes();
+
+	protected void postInstantiate() {
+		Loadable[] persisters = getEntityPersisters();
+		String[] suffixes = getSuffixes();
+		descriptors = new EntityAliases[persisters.length];
+		for ( int i=0; i<descriptors.length; i++ ) {
+			descriptors[i] = new DefaultEntityAliases( persisters[i], suffixes[i] );
+		}
+
+		CollectionPersister[] collectionPersisters = getCollectionPersisters();
+		int bagCount = 0;
+		if ( collectionPersisters != null ) {
+			String[] collectionSuffixes = getCollectionSuffixes();
+			collectionDescriptors = new CollectionAliases[collectionPersisters.length];
+			for ( int i = 0; i < collectionPersisters.length; i++ ) {
+				if ( isBag( collectionPersisters[i] ) ) {
+					bagCount++;
+				}
+				collectionDescriptors[i] = new GeneratedCollectionAliases(
+						collectionPersisters[i],
+						collectionSuffixes[i]
+					);
+			}
+		}
+		else {
+			collectionDescriptors = null;
+		}
+		if ( bagCount > 1 ) {
+			throw new HibernateException( "cannot simultaneously fetch multiple bags" );
+		}
+	}
+
+	private boolean isBag(CollectionPersister collectionPersister) {
+		return collectionPersister.getCollectionType().getClass().isAssignableFrom( BagType.class );
+	}
+
+	/**
+	 * Utility method that generates 0_, 1_ suffixes. Subclasses don't
+	 * necessarily need to use this algorithm, but it is intended that
+	 * they will in most cases.
+	 */
+	public static String[] generateSuffixes(int length) {
+		return generateSuffixes( 0, length );
+	}
+
+	public static String[] generateSuffixes(int seed, int length) {
+		if ( length == 0 ) return NO_SUFFIX;
+
+		String[] suffixes = new String[length];
+		for ( int i = 0; i < length; i++ ) {
+			suffixes[i] = Integer.toString( i + seed ) + "_";
+		}
+		return suffixes;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/CollectionAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-// $Id: CollectionAliases.java 6828 2005-05-19 07:28:59Z steveebersole $
-package org.hibernate.loader;
-
-/**
- * Type definition of CollectionAliases.
- *
- * @author Steve Ebersole
- */
-public interface CollectionAliases {
-	/**
-	 * Returns the suffixed result-set column-aliases for columns making
-	 * up the key for this collection (i.e., its FK to its owner).
-	 *
-	 * @return The key result-set column aliases.
-	 */
-	public String[] getSuffixedKeyAliases();
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the collumns
-	 * making up the collection's index (map or list).
-	 *
-	 * @return The index result-set column aliases.
-	 */
-	public String[] getSuffixedIndexAliases();
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the columns
-	 * making up the collection's elements.
-	 *
-	 * @return The element result-set column aliases.
-	 */
-	public String[] getSuffixedElementAliases();
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the column
-	 * defining the collection's identifier (if any).
-	 *
-	 * @return The identifier result-set column aliases.
-	 */
-	public String getSuffixedIdentifierAlias();
-
-	/**
-	 * Returns the suffix used to unique the column aliases for this
-	 * particular alias set.
-	 *
-	 * @return The uniqued column alias suffix.
-	 */
-	public String getSuffix();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/CollectionAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/CollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader;
+
+/**
+ * Type definition of CollectionAliases.
+ *
+ * @author Steve Ebersole
+ */
+public interface CollectionAliases {
+	/**
+	 * Returns the suffixed result-set column-aliases for columns making
+	 * up the key for this collection (i.e., its FK to its owner).
+	 *
+	 * @return The key result-set column aliases.
+	 */
+	public String[] getSuffixedKeyAliases();
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the collumns
+	 * making up the collection's index (map or list).
+	 *
+	 * @return The index result-set column aliases.
+	 */
+	public String[] getSuffixedIndexAliases();
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the columns
+	 * making up the collection's elements.
+	 *
+	 * @return The element result-set column aliases.
+	 */
+	public String[] getSuffixedElementAliases();
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the column
+	 * defining the collection's identifier (if any).
+	 *
+	 * @return The identifier result-set column aliases.
+	 */
+	public String getSuffixedIdentifierAlias();
+
+	/**
+	 * Returns the suffix used to unique the column aliases for this
+	 * particular alias set.
+	 *
+	 * @return The uniqued column alias suffix.
+	 */
+	public String getSuffix();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-package org.hibernate.loader;
-
-import java.util.Map;
-
-import org.hibernate.persister.entity.Loadable;
-
-/**
- * EntityAliases that chooses the column names over the alias names.
- * 
- * @author max
- *
- */
-public class ColumnEntityAliases extends DefaultEntityAliases {
-
-	public ColumnEntityAliases(Map returnProperties, Loadable persister, String suffix) {
-		super(returnProperties, persister, suffix);
-	}
-	
-	protected String[] getIdentifierAliases(Loadable persister, String suffix) {
-		return persister.getIdentifierColumnNames();
-	}
-	
-	protected String getDiscriminatorAlias(Loadable persister, String suffix) {
-		return persister.getDiscriminatorColumnName();
-	}
-	
-	protected String[] getPropertyAliases(Loadable persister, int j) {
-		return persister.getPropertyColumnNames(j);
-	}
-	 
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/ColumnEntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader;
+
+import java.util.Map;
+
+import org.hibernate.persister.entity.Loadable;
+
+/**
+ * EntityAliases that chooses the column names over the alias names.
+ * 
+ * @author max
+ *
+ */
+public class ColumnEntityAliases extends DefaultEntityAliases {
+
+	public ColumnEntityAliases(Map returnProperties, Loadable persister, String suffix) {
+		super(returnProperties, persister, suffix);
+	}
+	
+	protected String[] getIdentifierAliases(Loadable persister, String suffix) {
+		return persister.getIdentifierColumnNames();
+	}
+	
+	protected String getDiscriminatorAlias(Loadable persister, String suffix) {
+		return persister.getDiscriminatorColumnName();
+	}
+	
+	protected String[] getPropertyAliases(Loadable persister, int j) {
+		return persister.getPropertyColumnNames(j);
+	}
+	 
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,137 +0,0 @@
-package org.hibernate.loader;
-
-import java.util.Map;
-
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * EntityAliases which handles the logic of selecting user provided aliases (via return-property),
- * before using the default aliases. 
- *
- * @author max
- *
- */
-public class DefaultEntityAliases implements EntityAliases {
-
-	private final String[] suffixedKeyColumns;
-	private final String[] suffixedVersionColumn;
-	private final String[][] suffixedPropertyColumns;
-	private final String suffixedDiscriminatorColumn;
-	private final String suffix;
-	private final String rowIdAlias;
-	private final Map userProvidedAliases;	
-
-	public DefaultEntityAliases(Loadable persister, String suffix) {
-		this(CollectionHelper.EMPTY_MAP, persister, suffix);
-	}
-	
-	/**
-	 * Calculate and cache select-clause suffixes.
-	 * @param map 
-	 */
-	public DefaultEntityAliases(Map userProvidedAliases, Loadable persister, String suffix) {
-		this.suffix = suffix;
-		this.userProvidedAliases = userProvidedAliases;
-		
-		String[] keyColumnsCandidates = getUserProvidedAliases(
-				persister.getIdentifierPropertyName(), 
-				(String[]) null
-			); 
-		if (keyColumnsCandidates==null) {
-			suffixedKeyColumns = getUserProvidedAliases(
-					"id", 
-					getIdentifierAliases(persister, suffix)
-				);
-		} 
-		else {
-			suffixedKeyColumns = keyColumnsCandidates;
-		}
-		intern(suffixedKeyColumns);
-		
-		suffixedPropertyColumns = getSuffixedPropertyAliases(persister);
-		suffixedDiscriminatorColumn = getUserProvidedAlias(
-				"class", 
-				getDiscriminatorAlias(persister, suffix)
-			);
-		if ( persister.isVersioned() ) { 
-			suffixedVersionColumn = suffixedPropertyColumns[ persister.getVersionProperty() ];
-		}
-		else {
-			suffixedVersionColumn = null;
-		}
-		rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user!
-	}
-
-	protected String getDiscriminatorAlias(Loadable persister, String suffix) {
-		return persister.getDiscriminatorAlias(suffix);
-	}
-
-	protected String[] getIdentifierAliases(Loadable persister, String suffix) {
-		return persister.getIdentifierAliases(suffix);
-	}
-	
-	protected String[] getPropertyAliases(Loadable persister, int j) {
-		return persister.getPropertyAliases(suffix, j);
-	}
-	
-	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
-		String[] result = (String[]) userProvidedAliases.get(propertyPath);
-		if (result==null) {
-			return defaultAliases;			
-		} 
-		else {
-			return result;
-		}
-	}
-
-	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
-		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
-		if (columns==null) {
-			return defaultAlias;
-		} 
-		else {
-			return columns[0];
-		}
-	}
-	
-	public String[][] getSuffixedPropertyAliases(Loadable persister) {
-		int size = persister.getPropertyNames().length;
-		String[][] suffixedPropertyAliases = new String[size][];
-		for ( int j = 0; j < size; j++ ) {
-			suffixedPropertyAliases[j] = getUserProvidedAliases(
-					persister.getPropertyNames()[j],
-					getPropertyAliases(persister, j)
-				);
-			intern( suffixedPropertyAliases[j] );
-		}			
-		return suffixedPropertyAliases;
-	}
-
-	public String[] getSuffixedVersionAliases() {
-		return suffixedVersionColumn;
-	}
-
-	public String[][] getSuffixedPropertyAliases() {
-		return suffixedPropertyColumns;
-	}
-
-	public String getSuffixedDiscriminatorAlias() {
-		return suffixedDiscriminatorColumn;
-	}
-
-	public String[] getSuffixedKeyAliases() {
-		return suffixedKeyColumns;
-	}
-
-	public String getRowIdAlias() {
-		return rowIdAlias;
-	}
-	
-	private static void intern(String[] strings) {
-		for (int i=0; i<strings.length; i++ ) {
-			strings[i] = strings[i].intern();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/DefaultEntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,161 @@
+/*
+ * 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.loader;
+
+import java.util.Map;
+
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * EntityAliases which handles the logic of selecting user provided aliases (via return-property),
+ * before using the default aliases. 
+ *
+ * @author max
+ *
+ */
+public class DefaultEntityAliases implements EntityAliases {
+
+	private final String[] suffixedKeyColumns;
+	private final String[] suffixedVersionColumn;
+	private final String[][] suffixedPropertyColumns;
+	private final String suffixedDiscriminatorColumn;
+	private final String suffix;
+	private final String rowIdAlias;
+	private final Map userProvidedAliases;	
+
+	public DefaultEntityAliases(Loadable persister, String suffix) {
+		this(CollectionHelper.EMPTY_MAP, persister, suffix);
+	}
+	
+	/**
+	 * Calculate and cache select-clause suffixes.
+	 * @param map 
+	 */
+	public DefaultEntityAliases(Map userProvidedAliases, Loadable persister, String suffix) {
+		this.suffix = suffix;
+		this.userProvidedAliases = userProvidedAliases;
+		
+		String[] keyColumnsCandidates = getUserProvidedAliases(
+				persister.getIdentifierPropertyName(), 
+				(String[]) null
+			); 
+		if (keyColumnsCandidates==null) {
+			suffixedKeyColumns = getUserProvidedAliases(
+					"id", 
+					getIdentifierAliases(persister, suffix)
+				);
+		} 
+		else {
+			suffixedKeyColumns = keyColumnsCandidates;
+		}
+		intern(suffixedKeyColumns);
+		
+		suffixedPropertyColumns = getSuffixedPropertyAliases(persister);
+		suffixedDiscriminatorColumn = getUserProvidedAlias(
+				"class", 
+				getDiscriminatorAlias(persister, suffix)
+			);
+		if ( persister.isVersioned() ) { 
+			suffixedVersionColumn = suffixedPropertyColumns[ persister.getVersionProperty() ];
+		}
+		else {
+			suffixedVersionColumn = null;
+		}
+		rowIdAlias = Loadable.ROWID_ALIAS + suffix; // TODO: not visible to the user!
+	}
+
+	protected String getDiscriminatorAlias(Loadable persister, String suffix) {
+		return persister.getDiscriminatorAlias(suffix);
+	}
+
+	protected String[] getIdentifierAliases(Loadable persister, String suffix) {
+		return persister.getIdentifierAliases(suffix);
+	}
+	
+	protected String[] getPropertyAliases(Loadable persister, int j) {
+		return persister.getPropertyAliases(suffix, j);
+	}
+	
+	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
+		String[] result = (String[]) userProvidedAliases.get(propertyPath);
+		if (result==null) {
+			return defaultAliases;			
+		} 
+		else {
+			return result;
+		}
+	}
+
+	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
+		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
+		if (columns==null) {
+			return defaultAlias;
+		} 
+		else {
+			return columns[0];
+		}
+	}
+	
+	public String[][] getSuffixedPropertyAliases(Loadable persister) {
+		int size = persister.getPropertyNames().length;
+		String[][] suffixedPropertyAliases = new String[size][];
+		for ( int j = 0; j < size; j++ ) {
+			suffixedPropertyAliases[j] = getUserProvidedAliases(
+					persister.getPropertyNames()[j],
+					getPropertyAliases(persister, j)
+				);
+			intern( suffixedPropertyAliases[j] );
+		}			
+		return suffixedPropertyAliases;
+	}
+
+	public String[] getSuffixedVersionAliases() {
+		return suffixedVersionColumn;
+	}
+
+	public String[][] getSuffixedPropertyAliases() {
+		return suffixedPropertyColumns;
+	}
+
+	public String getSuffixedDiscriminatorAlias() {
+		return suffixedDiscriminatorColumn;
+	}
+
+	public String[] getSuffixedKeyAliases() {
+		return suffixedKeyColumns;
+	}
+
+	public String getRowIdAlias() {
+		return rowIdAlias;
+	}
+	
+	private static void intern(String[] strings) {
+		for (int i=0; i<strings.length; i++ ) {
+			strings[i] = strings[i].intern();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/EntityAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: EntityAliases.java 5699 2005-02-13 11:50:11Z oneovthafew $
-package org.hibernate.loader;
-
-import org.hibernate.persister.entity.Loadable;
-
-/**
- * Metadata describing the SQL result set column aliases
- * for a particular entity.
- * 
- * @author Gavin King
- */
-public interface EntityAliases {
-	/**
-	 * The result set column aliases for the primary key columns
-	 */
-	public String[] getSuffixedKeyAliases();
-	/**
-	 * The result set column aliases for the discriminator columns
-	 */
-	public String getSuffixedDiscriminatorAlias();
-	/**
-	 * The result set column aliases for the version columns
-	 */
-	public String[] getSuffixedVersionAliases();
-	/**
-	 * The result set column aliases for the property columns
-	 */
-	public String[][] getSuffixedPropertyAliases();
-	/**
-	 * The result set column aliases for the property columns of a subclass
-	 */
-	public String[][] getSuffixedPropertyAliases(Loadable persister);
-	/**
-	 * The result set column alias for the Oracle row id
-	 */
-	public String getRowIdAlias();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/EntityAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/EntityAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader;
+
+import org.hibernate.persister.entity.Loadable;
+
+/**
+ * Metadata describing the SQL result set column aliases
+ * for a particular entity.
+ * 
+ * @author Gavin King
+ */
+public interface EntityAliases {
+	/**
+	 * The result set column aliases for the primary key columns
+	 */
+	public String[] getSuffixedKeyAliases();
+	/**
+	 * The result set column aliases for the discriminator columns
+	 */
+	public String getSuffixedDiscriminatorAlias();
+	/**
+	 * The result set column aliases for the version columns
+	 */
+	public String[] getSuffixedVersionAliases();
+	/**
+	 * The result set column aliases for the property columns
+	 */
+	public String[][] getSuffixedPropertyAliases();
+	/**
+	 * The result set column aliases for the property columns of a subclass
+	 */
+	public String[][] getSuffixedPropertyAliases(Loadable persister);
+	/**
+	 * The result set column alias for the Oracle row id
+	 */
+	public String getRowIdAlias();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,131 +0,0 @@
-// $Id: GeneratedCollectionAliases.java 8410 2005-10-14 22:43:44Z maxcsaucdk $
-package org.hibernate.loader;
-
-import java.util.Map;
-
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * CollectionAliases which handles the logic of selecting user provided aliases (via return-property),
- * before using the default aliases. 
- *
- * @author Steve Ebersole and Max Rydahl Andersen
- */
-public class GeneratedCollectionAliases implements CollectionAliases {
-	private final String suffix;
-	private final String[] keyAliases;
-	private final String[] indexAliases;
-	private final String[] elementAliases;
-	private final String identifierAlias;
-	private Map userProvidedAliases;
-	
-	public GeneratedCollectionAliases(Map userProvidedAliases, CollectionPersister persister, String suffix) {
-		this.suffix = suffix;
-		this.userProvidedAliases = userProvidedAliases;
-
-		this.keyAliases = getUserProvidedAliases(
-				"key", 
-				persister.getKeyColumnAliases( suffix )
-			);
-
-		this.indexAliases = getUserProvidedAliases(
-				"index",
-				persister.getIndexColumnAliases( suffix )
-				);
-		
-		this.elementAliases = getUserProvidedAliases( "element", 
-				persister.getElementColumnAliases( suffix )
-				);
-				
-		this.identifierAlias = getUserProvidedAlias( "id", 
-				persister.getIdentifierColumnAlias( suffix )
-				);
-	}
-
-	public GeneratedCollectionAliases(CollectionPersister persister, String string) {
-		this(CollectionHelper.EMPTY_MAP, persister, string);
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for columns making up the key for this collection (i.e., its FK to
-	 * its owner).
-	 *
-	 * @return The key result-set column aliases.
-	 */
-	public String[] getSuffixedKeyAliases() {
-		return keyAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the collumns making up the collection's index (map or list).
-	 *
-	 * @return The index result-set column aliases.
-	 */
-	public String[] getSuffixedIndexAliases() {
-		return indexAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the columns making up the collection's elements.
-	 *
-	 * @return The element result-set column aliases.
-	 */
-	public String[] getSuffixedElementAliases() {
-		return elementAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the column defining the collection's identifier (if any).
-	 *
-	 * @return The identifier result-set column aliases.
-	 */
-	public String getSuffixedIdentifierAlias() {
-		return identifierAlias;
-	}
-
-	/**
-	 * Returns the suffix used to unique the column aliases for this particular alias set.
-	 *
-	 * @return The uniqued column alias suffix.
-	 */
-	public String getSuffix() {
-		return suffix;
-	}
-
-	public String toString() {
-		return super.toString() + " [suffix=" + suffix +
-		        ", suffixedKeyAliases=[" + join( keyAliases ) +
-		        "], suffixedIndexAliases=[" + join( indexAliases ) +
-		        "], suffixedElementAliases=[" + join( elementAliases ) +
-		        "], suffixedIdentifierAlias=[" + identifierAlias + "]]";
-	}
-
-	private String join(String[] aliases) {
-		if ( aliases == null) return null;
-
-		return StringHelper.join( ", ", aliases );
-	}
-	
-	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
-		String[] result = (String[]) userProvidedAliases.get(propertyPath);
-		if (result==null) {
-			return defaultAliases;			
-		} 
-		else {
-			return result;
-		}
-	}
-
-	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
-		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
-		if (columns==null) {
-			return defaultAlias;
-		} 
-		else {
-			return columns[0];
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/GeneratedCollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,155 @@
+/*
+ * 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.loader;
+
+import java.util.Map;
+
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * CollectionAliases which handles the logic of selecting user provided aliases (via return-property),
+ * before using the default aliases. 
+ *
+ * @author Steve Ebersole
+ * @author Max Rydahl Andersen
+ */
+public class GeneratedCollectionAliases implements CollectionAliases {
+	private final String suffix;
+	private final String[] keyAliases;
+	private final String[] indexAliases;
+	private final String[] elementAliases;
+	private final String identifierAlias;
+	private Map userProvidedAliases;
+	
+	public GeneratedCollectionAliases(Map userProvidedAliases, CollectionPersister persister, String suffix) {
+		this.suffix = suffix;
+		this.userProvidedAliases = userProvidedAliases;
+
+		this.keyAliases = getUserProvidedAliases(
+				"key", 
+				persister.getKeyColumnAliases( suffix )
+			);
+
+		this.indexAliases = getUserProvidedAliases(
+				"index",
+				persister.getIndexColumnAliases( suffix )
+				);
+		
+		this.elementAliases = getUserProvidedAliases( "element", 
+				persister.getElementColumnAliases( suffix )
+				);
+				
+		this.identifierAlias = getUserProvidedAlias( "id", 
+				persister.getIdentifierColumnAlias( suffix )
+				);
+	}
+
+	public GeneratedCollectionAliases(CollectionPersister persister, String string) {
+		this(CollectionHelper.EMPTY_MAP, persister, string);
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for columns making up the key for this collection (i.e., its FK to
+	 * its owner).
+	 *
+	 * @return The key result-set column aliases.
+	 */
+	public String[] getSuffixedKeyAliases() {
+		return keyAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the collumns making up the collection's index (map or list).
+	 *
+	 * @return The index result-set column aliases.
+	 */
+	public String[] getSuffixedIndexAliases() {
+		return indexAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the columns making up the collection's elements.
+	 *
+	 * @return The element result-set column aliases.
+	 */
+	public String[] getSuffixedElementAliases() {
+		return elementAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the column defining the collection's identifier (if any).
+	 *
+	 * @return The identifier result-set column aliases.
+	 */
+	public String getSuffixedIdentifierAlias() {
+		return identifierAlias;
+	}
+
+	/**
+	 * Returns the suffix used to unique the column aliases for this particular alias set.
+	 *
+	 * @return The uniqued column alias suffix.
+	 */
+	public String getSuffix() {
+		return suffix;
+	}
+
+	public String toString() {
+		return super.toString() + " [suffix=" + suffix +
+		        ", suffixedKeyAliases=[" + join( keyAliases ) +
+		        "], suffixedIndexAliases=[" + join( indexAliases ) +
+		        "], suffixedElementAliases=[" + join( elementAliases ) +
+		        "], suffixedIdentifierAlias=[" + identifierAlias + "]]";
+	}
+
+	private String join(String[] aliases) {
+		if ( aliases == null) return null;
+
+		return StringHelper.join( ", ", aliases );
+	}
+	
+	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
+		String[] result = (String[]) userProvidedAliases.get(propertyPath);
+		if (result==null) {
+			return defaultAliases;			
+		} 
+		else {
+			return result;
+		}
+	}
+
+	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
+		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
+		if (columns==null) {
+			return defaultAlias;
+		} 
+		else {
+			return columns[0];
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,967 +0,0 @@
-//$Id: JoinWalker.java 9889 2006-05-05 01:24:12Z steve.ebersole at jboss.com $
-package org.hibernate.loader;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.JoinHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.ConditionFragment;
-import org.hibernate.sql.DisjunctionFragment;
-import org.hibernate.sql.InFragment;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.ForeignKeyDirection;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Walks the metamodel, searching for joins, and collecting
- * together information needed by <tt>OuterJoinLoader</tt>.
- * 
- * @see OuterJoinLoader
- * @author Gavin King, Jon Lipsky
- */
-public class JoinWalker {
-	
-	private final SessionFactoryImplementor factory;
-	protected final List associations = new ArrayList();
-	private final Set visitedAssociationKeys = new HashSet();
-	private final Map enabledFilters;
-
-	protected String[] suffixes;
-	protected String[] collectionSuffixes;
-	protected Loadable[] persisters;
-	protected int[] owners;
-	protected EntityType[] ownerAssociationTypes;
-	protected CollectionPersister[] collectionPersisters;
-	protected int[] collectionOwners;
-	protected String[] aliases;
-	protected LockMode[] lockModeArray;
-	protected String sql;
-	
-	public String[] getCollectionSuffixes() {
-		return collectionSuffixes;
-	}
-
-	public void setCollectionSuffixes(String[] collectionSuffixes) {
-		this.collectionSuffixes = collectionSuffixes;
-	}
-
-	public LockMode[] getLockModeArray() {
-		return lockModeArray;
-	}
-
-	public void setLockModeArray(LockMode[] lockModeArray) {
-		this.lockModeArray = lockModeArray;
-	}
-
-	public String[] getSuffixes() {
-		return suffixes;
-	}
-
-	public void setSuffixes(String[] suffixes) {
-		this.suffixes = suffixes;
-	}
-
-	public String[] getAliases() {
-		return aliases;
-	}
-
-	public void setAliases(String[] aliases) {
-		this.aliases = aliases;
-	}
-
-	public int[] getCollectionOwners() {
-		return collectionOwners;
-	}
-
-	public void setCollectionOwners(int[] collectionOwners) {
-		this.collectionOwners = collectionOwners;
-	}
-
-	public CollectionPersister[] getCollectionPersisters() {
-		return collectionPersisters;
-	}
-
-	public void setCollectionPersisters(CollectionPersister[] collectionPersisters) {
-		this.collectionPersisters = collectionPersisters;
-	}
-
-	public EntityType[] getOwnerAssociationTypes() {
-		return ownerAssociationTypes;
-	}
-
-	public void setOwnerAssociationTypes(EntityType[] ownerAssociationType) {
-		this.ownerAssociationTypes = ownerAssociationType;
-	}
-
-	public int[] getOwners() {
-		return owners;
-	}
-
-	public void setOwners(int[] owners) {
-		this.owners = owners;
-	}
-
-	public Loadable[] getPersisters() {
-		return persisters;
-	}
-
-	public void setPersisters(Loadable[] persisters) {
-		this.persisters = persisters;
-	}
-
-	public String getSQLString() {
-		return sql;
-	}
-
-	public void setSql(String sql) {
-		this.sql = sql;
-	}
-
-	protected SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	protected Dialect getDialect() {
-		return factory.getDialect();
-	}
-	
-	protected Map getEnabledFilters() {
-		return enabledFilters;
-	}
-
-	protected JoinWalker(SessionFactoryImplementor factory, Map enabledFilters) {
-		this.factory = factory;
-		this.enabledFilters = enabledFilters;
-	}
-
-	/**
-	 * Add on association (one-to-one, many-to-one, or a collection) to a list 
-	 * of associations to be fetched by outerjoin (if necessary)
-	 */
-	private void addAssociationToJoinTreeIfNecessary(
-		final AssociationType type,
-		final String[] aliasedLhsColumns,
-		final String alias,
-		final String path,
-		int currentDepth,
-		final int joinType)
-	throws MappingException {
-		
-		if (joinType>=0) {	
-			addAssociationToJoinTree(
-					type, 
-					aliasedLhsColumns, 
-					alias, 
-					path,
-					currentDepth,
-					joinType
-				);
-		}
-
-	}
-
-	/**
-	 * Add on association (one-to-one, many-to-one, or a collection) to a list 
-	 * of associations to be fetched by outerjoin 
-	 */
-	private void addAssociationToJoinTree(
-		final AssociationType type,
-		final String[] aliasedLhsColumns,
-		final String alias,
-		final String path,
-		final int currentDepth,
-		final int joinType)
-	throws MappingException {
-
-		Joinable joinable = type.getAssociatedJoinable( getFactory() );
-
-		String subalias = generateTableAlias(
-				associations.size()+1, //before adding to collection!
-				path, 
-				joinable
-			);
-
-		OuterJoinableAssociation assoc = new OuterJoinableAssociation(
-				type, 
-				alias, 
-				aliasedLhsColumns, 
-				subalias, 
-				joinType, 
-				getFactory(), 
-				enabledFilters
-			);
-		assoc.validateJoin(path);
-		associations.add(assoc);
-
-		int nextDepth = currentDepth+1;
-		if ( !joinable.isCollection() ) {
-			if (joinable instanceof OuterJoinLoadable) {
-				walkEntityTree(
-					(OuterJoinLoadable) joinable, 
-					subalias,
-					path, 
-					nextDepth
-				);
-			}
-		}
-		else {
-			if (joinable instanceof QueryableCollection) {
-				walkCollectionTree(
-					(QueryableCollection) joinable, 
-					subalias, 
-					path, 
-					nextDepth
-				);
-			}
-		}
-
-	}
-
-	/**
-	 * For an entity class, return a list of associations to be fetched by outerjoin
-	 */
-	protected final void walkEntityTree(OuterJoinLoadable persister, String alias)
-	throws MappingException {
-		walkEntityTree(persister, alias, "", 0);
-	}
-
-	/**
-	 * For a collection role, return a list of associations to be fetched by outerjoin
-	 */
-	protected final void walkCollectionTree(QueryableCollection persister, String alias)
-	throws MappingException {
-		walkCollectionTree(persister, alias, "", 0);
-		//TODO: when this is the entry point, we should use an INNER_JOIN for fetching the many-to-many elements!
-	}
-
-	/**
-	 * For a collection role, return a list of associations to be fetched by outerjoin
-	 */
-	private void walkCollectionTree(
-		final QueryableCollection persister,
-		final String alias,
-		final String path,
-		final int currentDepth)
-	throws MappingException {
-
-		if ( persister.isOneToMany() ) {
-			walkEntityTree(
-					(OuterJoinLoadable) persister.getElementPersister(),
-					alias,
-					path,
-					currentDepth
-				);
-		}
-		else {
-			Type type = persister.getElementType();
-			if ( type.isAssociationType() ) {
-				// a many-to-many;
-				// decrement currentDepth here to allow join across the association table
-				// without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit)
-				AssociationType associationType = (AssociationType) type;
-				String[] aliasedLhsColumns = persister.getElementColumnNames(alias);
-				String[] lhsColumns = persister.getElementColumnNames();
-				// if the current depth is 0, the root thing being loaded is the
-				// many-to-many collection itself.  Here, it is alright to use
-				// an inner join...
-				boolean useInnerJoin = currentDepth == 0;
-				final int joinType = getJoinType(
-						associationType,
-						persister.getFetchMode(),
-						path,
-						persister.getTableName(),
-						lhsColumns,
-						!useInnerJoin,
-						currentDepth - 1, 
-						null //operations which cascade as far as the collection also cascade to collection elements
-					);
-				addAssociationToJoinTreeIfNecessary(
-						associationType,
-						aliasedLhsColumns,
-						alias,
-						path,
-						currentDepth - 1,
-						joinType
-					);
-			}
-			else if ( type.isComponentType() ) {
-				walkCompositeElementTree(
-						(AbstractComponentType) type,
-						persister.getElementColumnNames(),
-						persister,
-						alias,
-						path,
-						currentDepth
-					);
-			}
-		}
-
-	}
-	
-	/**
-	 * Walk the tree for a particular entity association
-	 */
-	private final void walkEntityAssociationTree(
-		final AssociationType associationType,
-		final OuterJoinLoadable persister,
-		final int propertyNumber,
-		final String alias,
-		final String path,
-		final boolean nullable,
-		final int currentDepth)
-	throws MappingException {
-
-		String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames(
-				associationType, alias, propertyNumber, persister, getFactory()
-			);
-
-		String[] lhsColumns = JoinHelper.getLHSColumnNames(
-				associationType, propertyNumber, persister, getFactory()
-			);
-		String lhsTable = JoinHelper.getLHSTableName(associationType, propertyNumber, persister);
-
-		String subpath = subPath( path, persister.getSubclassPropertyName(propertyNumber) );
-		int joinType = getJoinType(
-				associationType,
-				persister.getFetchMode(propertyNumber),
-				subpath,
-				lhsTable,
-				lhsColumns,
-				nullable,
-				currentDepth, 
-				persister.getCascadeStyle(propertyNumber)
-			);
-		addAssociationToJoinTreeIfNecessary(
-				associationType,
-				aliasedLhsColumns,
-				alias,
-				subpath,
-				currentDepth,
-				joinType
-			);
-
-	}
-
-	/**
-	 * For an entity class, add to a list of associations to be fetched 
-	 * by outerjoin
-	 */
-	private final void walkEntityTree(
-		final OuterJoinLoadable persister,
-		final String alias,
-		final String path,
-		final int currentDepth) 
-	throws MappingException {
-
-		int n = persister.countSubclassProperties();
-		for ( int i=0; i<n; i++ ) {
-			Type type = persister.getSubclassPropertyType(i);
-			if ( type.isAssociationType() ) {
-				walkEntityAssociationTree(
-					(AssociationType) type,
-					persister,
-					i,
-					alias,
-					path,
-					persister.isSubclassPropertyNullable(i),
-					currentDepth
-				);
-			}
-			else if ( type.isComponentType() ) {
-				walkComponentTree(
-					(AbstractComponentType) type,
-					i,
-					0,
-					persister,
-					alias,
-					subPath( path, persister.getSubclassPropertyName(i) ),
-					currentDepth
-				);
-			}
-		}
-	}
-
-	/**
-	 * For a component, add to a list of associations to be fetched by outerjoin
-	 */
-	private void walkComponentTree(
-		final AbstractComponentType componentType,
-		final int propertyNumber,
-		int begin,
-		final OuterJoinLoadable persister,
-		final String alias,
-		final String path,
-		final int currentDepth
-	) throws MappingException {
-
-		Type[] types = componentType.getSubtypes();
-		String[] propertyNames = componentType.getPropertyNames();
-		for ( int i=0; i <types.length; i++ ) {
-
-			if ( types[i].isAssociationType() ) {
-				AssociationType associationType = (AssociationType) types[i];
-
-				String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames(
-					associationType, alias, propertyNumber, begin, persister, getFactory()
-				);
-
-				String[] lhsColumns = JoinHelper.getLHSColumnNames(
-					associationType, propertyNumber, begin, persister, getFactory()
-				);
-				String lhsTable = JoinHelper.getLHSTableName(associationType, propertyNumber, persister);
-
-				String subpath = subPath( path, propertyNames[i] );
-				final boolean[] propertyNullability = componentType.getPropertyNullability();
-				final int joinType = getJoinType(
-						associationType,
-						componentType.getFetchMode(i),
-						subpath,
-						lhsTable,
-						lhsColumns,
-						propertyNullability==null || propertyNullability[i],
-						currentDepth, 
-						componentType.getCascadeStyle(i)
-					);
-				addAssociationToJoinTreeIfNecessary(			
-						associationType,
-						aliasedLhsColumns,
-						alias,
-						subpath,
-						currentDepth,
-						joinType
-					);
-
-			}
-			else if ( types[i].isComponentType() ) {
-				String subpath = subPath( path, propertyNames[i] );
-				walkComponentTree(
-						(AbstractComponentType) types[i],
-						propertyNumber,
-						begin,
-						persister,
-						alias,
-						subpath,
-						currentDepth
-					);
-			}
-			
-			begin+=types[i].getColumnSpan( getFactory() );
-		}
-
-	}
-
-	/**
-	 * For a composite element, add to a list of associations to be fetched by outerjoin
-	 */
-	private void walkCompositeElementTree(
-		final AbstractComponentType compositeType,
-		final String[] cols,
-		final QueryableCollection persister,
-		final String alias,
-		final String path,
-		final int currentDepth) 
-	throws MappingException {
-
-		Type[] types = compositeType.getSubtypes();
-		String[] propertyNames = compositeType.getPropertyNames();
-		int begin = 0;
-		for ( int i=0; i <types.length; i++ ) {
-			int length = types[i].getColumnSpan( getFactory() );
-			String[] lhsColumns = ArrayHelper.slice(cols, begin, length);
-
-			if ( types[i].isAssociationType() ) {
-				AssociationType associationType = (AssociationType) types[i];
-
-				// simple, because we can't have a one-to-one or a collection 
-				// (or even a property-ref) in a composite-element:
-				String[] aliasedLhsColumns = StringHelper.qualify(alias, lhsColumns);
-
-				String subpath = subPath( path, propertyNames[i] );
-				final boolean[] propertyNullability = compositeType.getPropertyNullability();
-				final int joinType = getJoinType(
-						associationType,
-						compositeType.getFetchMode(i),
-						subpath,
-						persister.getTableName(),
-						lhsColumns,
-						propertyNullability==null || propertyNullability[i],
-						currentDepth, 
-						compositeType.getCascadeStyle(i)
-					);
-				addAssociationToJoinTreeIfNecessary(
-						associationType,
-						aliasedLhsColumns,
-						alias,
-						subpath,
-						currentDepth,
-						joinType
-					);
-			}
-			else if ( types[i].isComponentType() ) {
-				String subpath = subPath( path, propertyNames[i] );
-				walkCompositeElementTree(
-						(AbstractComponentType) types[i],
-						lhsColumns,
-						persister,
-						alias,
-						subpath,
-						currentDepth
-					);
-			}
-			begin+=length;
-		}
-
-	}
-
-	/**
-	 * Extend the path by the given property name
-	 */
-	private static String subPath(String path, String property) {
-		if ( path==null || path.length()==0) {
-			return property;
-		}
-		else {
-			return StringHelper.qualify(path, property);
-		}
-	}
-
-	/**
-	 * Get the join type (inner, outer, etc) or -1 if the
-	 * association should not be joined. Override on
-	 * subclasses.
-	 */
-	protected int getJoinType(
-			AssociationType type, 
-			FetchMode config, 
-			String path, 
-			String lhsTable,
-			String[] lhsColumns,
-			boolean nullable,
-			int currentDepth, 
-			CascadeStyle cascadeStyle)
-	throws MappingException {
-		
-		if  ( !isJoinedFetchEnabled(type, config, cascadeStyle) ) return -1;
-		
-		if ( isTooDeep(currentDepth) || ( type.isCollectionType() && isTooManyCollections() ) ) return -1;
-		
-		final boolean dupe = isDuplicateAssociation(lhsTable,  lhsColumns, type);
-		if (dupe) return -1;
-		
-		return getJoinType(nullable, currentDepth);
-		
-	}
-	
-	/**
-	 * Use an inner join if it is a non-null association and this
-	 * is the "first" join in a series
-	 */
-	protected int getJoinType(boolean nullable, int currentDepth) {
-		//TODO: this is too conservative; if all preceding joins were 
-		//      also inner joins, we could use an inner join here
-		return !nullable && currentDepth==0 ? 
-					JoinFragment.INNER_JOIN : 
-					JoinFragment.LEFT_OUTER_JOIN;
-	}
-
-	protected boolean isTooDeep(int currentDepth) {
-		Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();
-		return maxFetchDepth!=null && currentDepth >= maxFetchDepth.intValue();
-	}
-	
-	protected boolean isTooManyCollections() {
-		return false;
-	}
-	
-	/**
-	 * Does the mapping, and Hibernate default semantics, specify that
-	 * this association should be fetched by outer joining
-	 */
-	protected boolean isJoinedFetchEnabledInMapping(FetchMode config, AssociationType type) 
-	throws MappingException {
-		if ( !type.isEntityType() && !type.isCollectionType() ) {
-			return false;
-		}
-		else {
-			if (config==FetchMode.JOIN) return true;
-			if (config==FetchMode.SELECT) return false;
-			if ( type.isEntityType() ) {
-				//TODO: look at the owning property and check that it 
-				//      isn't lazy (by instrumentation)
-				EntityType entityType =(EntityType) type;
-				EntityPersister persister = getFactory().getEntityPersister( entityType.getAssociatedEntityName() );
-				return !persister.hasProxy();
-			}
-			else {
-				return false;
-			}
-		}
-	}
-
-	/**
-	 * Override on subclasses to enable or suppress joining 
-	 * of certain association types
-	 */
-	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
-		return type.isEntityType() && isJoinedFetchEnabledInMapping(config, type) ;
-	}
-	
-	protected String generateTableAlias(
-			final int n,
-			final String path,
-			final Joinable joinable
-	) {
-		return StringHelper.generateAlias( joinable.getName(), n );
-	}
-
-	protected String generateRootAlias(final String description) {
-		return StringHelper.generateAlias(description, 0);
-	}
-
-	/**
-	 * Used to detect circularities in the joined graph, note that 
-	 * this method is side-effecty
-	 */
-	protected boolean isDuplicateAssociation(
-		final String foreignKeyTable, 
-		final String[] foreignKeyColumns
-	) {
-		AssociationKey associationKey = new AssociationKey(foreignKeyColumns, foreignKeyTable);
-		return !visitedAssociationKeys.add( associationKey );
-	}
-	
-	/**
-	 * Used to detect circularities in the joined graph, note that 
-	 * this method is side-effecty
-	 */
-	protected boolean isDuplicateAssociation(
-		final String lhsTable,
-		final String[] lhsColumnNames,
-		final AssociationType type
-	) {
-		final String foreignKeyTable;
-		final String[] foreignKeyColumns;
-		if ( type.getForeignKeyDirection()==ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) {
-			foreignKeyTable = lhsTable;
-			foreignKeyColumns = lhsColumnNames;
-		}
-		else {
-			foreignKeyTable = type.getAssociatedJoinable( getFactory() ).getTableName();
-			foreignKeyColumns = JoinHelper.getRHSColumnNames( type, getFactory() );
-		}
-		return isDuplicateAssociation(foreignKeyTable, foreignKeyColumns);
-	}
-	
-	/**
-	 * Uniquely identifier a foreign key, so that we don't
-	 * join it more than once, and create circularities
-	 */
-	private static final class AssociationKey {
-		private String[] columns;
-		private String table;
-		private AssociationKey(String[] columns, String table) {
-			this.columns = columns;
-			this.table = table;
-		}
-		public boolean equals(Object other) {
-			AssociationKey that = (AssociationKey) other;
-			return that.table.equals(table) && Arrays.equals(columns, that.columns);
-		}
-		public int hashCode() {
-			return table.hashCode(); //TODO: inefficient
-		}
-	}
-	
-	/**
-	 * Should we join this association?
-	 */
-	protected boolean isJoinable(
-		final int joinType,
-		final Set visitedAssociationKeys, 
-		final String lhsTable,
-		final String[] lhsColumnNames,
-		final AssociationType type,
-		final int depth
-	) {
-		if (joinType<0) return false;
-		
-		if (joinType==JoinFragment.INNER_JOIN) return true;
-		
-		Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();
-		final boolean tooDeep = maxFetchDepth!=null && 
-			depth >= maxFetchDepth.intValue();
-		
-		return !tooDeep && !isDuplicateAssociation(lhsTable, lhsColumnNames, type);
-	}
-	
-	protected String orderBy(final List associations, final String orderBy) {
-		return mergeOrderings( orderBy( associations ), orderBy );
-	}
-
-	protected static String mergeOrderings(String ordering1, String ordering2) {
-		if ( ordering1.length() == 0 ) {
-			return ordering2;
-		}
-		else if ( ordering2.length() == 0 ) {
-			return ordering1;
-		}
-		else {
-			return ordering1 + ", " + ordering2;
-		}
-	}
-	
-	/**
-	 * Generate a sequence of <tt>LEFT OUTER JOIN</tt> clauses for the given associations.
-	 */
-	protected final JoinFragment mergeOuterJoins(List associations)
-	throws MappingException {
-		JoinFragment outerjoin = getDialect().createOuterJoinFragment();
-		Iterator iter = associations.iterator();
-		OuterJoinableAssociation last = null;
-		while ( iter.hasNext() ) {
-			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
-			if ( last != null && last.isManyToManyWith( oj ) ) {
-				oj.addManyToManyJoin( outerjoin, ( QueryableCollection ) last.getJoinable() );
-			}
-			else {
-				oj.addJoins(outerjoin);
-			}
-			last = oj;
-		}
-		last = null;
-		return outerjoin;
-	}
-
-	/**
-	 * Count the number of instances of Joinable which are actually
-	 * also instances of Loadable, or are one-to-many associations
-	 */
-	protected static final int countEntityPersisters(List associations)
-	throws MappingException {
-		int result = 0;
-		Iterator iter = associations.iterator();
-		while ( iter.hasNext() ) {
-			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
-			if ( oj.getJoinable().consumesEntityAlias() ) {
-				result++;
-			}
-		}
-		return result;
-	}
-	
-	/**
-	 * Count the number of instances of Joinable which are actually
-	 * also instances of PersistentCollection which are being fetched
-	 * by outer join
-	 */
-	protected static final int countCollectionPersisters(List associations)
-	throws MappingException {
-		int result = 0;
-		Iterator iter = associations.iterator();
-		while ( iter.hasNext() ) {
-			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
-			if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) {
-				result++;
-			}
-		}
-		return result;
-	}
-	
-	/**
-	 * Get the order by string required for collection fetching
-	 */
-	protected static final String orderBy(List associations)
-	throws MappingException {
-		StringBuffer buf = new StringBuffer();
-		Iterator iter = associations.iterator();
-		OuterJoinableAssociation last = null;
-		while ( iter.hasNext() ) {
-			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
-			if ( oj.getJoinType() == JoinFragment.LEFT_OUTER_JOIN ) { // why does this matter?
-				if ( oj.getJoinable().isCollection() ) {
-					final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable();
-					if ( queryableCollection.hasOrdering() ) {
-						final String orderByString = queryableCollection.getSQLOrderByString( oj.getRHSAlias() );
-						buf.append( orderByString ).append(", ");
-					}
-				}
-				else {
-					// it might still need to apply a collection ordering based on a
-					// many-to-many defined order-by...
-					if ( last != null && last.getJoinable().isCollection() ) {
-						final QueryableCollection queryableCollection = (QueryableCollection) last.getJoinable();
-						if ( queryableCollection.isManyToMany() && last.isManyToManyWith( oj ) ) {
-							if ( queryableCollection.hasManyToManyOrdering() ) {
-								final String orderByString = queryableCollection.getManyToManyOrderByString( oj.getRHSAlias() );
-								buf.append( orderByString ).append(", ");
-							}
-						}
-					}
-				}
-			}
-			last = oj;
-		}
-		if ( buf.length()>0 ) buf.setLength( buf.length()-2 );
-		return buf.toString();
-	}
-	
-	/**
-	 * Render the where condition for a (batch) load by identifier / collection key
-	 */
-	protected StringBuffer whereString(String alias, String[] columnNames, int batchSize) {
-		if ( columnNames.length==1 ) {
-			// if not a composite key, use "foo in (?, ?, ?)" for batching
-			// if no batch, and not a composite key, use "foo = ?"
-			InFragment in = new InFragment().setColumn( alias, columnNames[0] );
-			for ( int i=0; i<batchSize; i++ ) in.addValue("?");
-			return new StringBuffer( in.toFragmentString() );
-		}
-		else {
-			//a composite key
-			ConditionFragment byId = new ConditionFragment()
-					.setTableAlias(alias)
-					.setCondition( columnNames, "?" );
-	
-			StringBuffer whereString = new StringBuffer();
-			if ( batchSize==1 ) {
-				// if no batch, use "foo = ? and bar = ?"
-				whereString.append( byId.toFragmentString() );
-			}
-			else {
-				// if a composite key, use "( (foo = ? and bar = ?) or (foo = ? and bar = ?) )" for batching
-				whereString.append('('); //TODO: unnecessary for databases with ANSI-style joins
-				DisjunctionFragment df = new DisjunctionFragment();
-				for ( int i=0; i<batchSize; i++ ) {
-					df.addCondition(byId);
-				}
-				whereString.append( df.toFragmentString() );
-				whereString.append(')'); //TODO: unnecessary for databases with ANSI-style joins
-			}
-			return whereString;
-		}
-	}
-
-	protected void initPersisters(final List associations, final LockMode lockMode) throws MappingException {
-		
-		final int joins = countEntityPersisters(associations);
-		final int collections = countCollectionPersisters(associations);
-
-		collectionOwners = collections==0 ? null : new int[collections];
-		collectionPersisters = collections==0 ? null : new CollectionPersister[collections];
-		collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collections );
-
-		persisters = new Loadable[joins];
-		aliases = new String[joins];
-		owners = new int[joins];
-		ownerAssociationTypes = new EntityType[joins];
-		lockModeArray = ArrayHelper.fillArray(lockMode, joins);
-		
-		int i=0;
-		int j=0;
-		Iterator iter = associations.iterator();
-		while ( iter.hasNext() ) {
-			final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
-			if ( !oj.isCollection() ) {
-				
-				persisters[i] = (Loadable) oj.getJoinable();
-				aliases[i] = oj.getRHSAlias();
-				owners[i] = oj.getOwner(associations);
-				ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();
-				i++;
-				
-			}
-			else {
-				
-				QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
-				if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) {
-					//it must be a collection fetch
-					collectionPersisters[j] = collPersister;
-					collectionOwners[j] = oj.getOwner(associations);
-					j++;
-				}
-	
-				if ( collPersister.isOneToMany() ) {
-					persisters[i] = (Loadable) collPersister.getElementPersister();
-					aliases[i] = oj.getRHSAlias();
-					i++;
-				}
-			}
-		}
-	
-		if ( ArrayHelper.isAllNegative(owners) ) owners = null;
-		if ( collectionOwners!=null && ArrayHelper.isAllNegative(collectionOwners) ) {
-			collectionOwners = null;
-		}
-	}
-
-	/**
-	 * Generate a select list of columns containing all properties of the entity classes
-	 */
-	protected final String selectString(List associations)
-	throws MappingException {
-
-		if ( associations.size()==0 ) {
-			return "";
-		}
-		else {
-			StringBuffer buf = new StringBuffer( associations.size() * 100 )
-				.append(", ");
-			int entityAliasCount=0;
-			int collectionAliasCount=0;
-			for ( int i=0; i<associations.size(); i++ ) {
-				OuterJoinableAssociation join = (OuterJoinableAssociation) associations.get(i);
-				OuterJoinableAssociation next = (i == associations.size() - 1)
-				        ? null
-				        : ( OuterJoinableAssociation ) associations.get( i + 1 );
-				final Joinable joinable = join.getJoinable();
-				final String entitySuffix = ( suffixes == null || entityAliasCount >= suffixes.length )
-				        ? null
-				        : suffixes[entityAliasCount];
-				final String collectionSuffix = ( collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length )
-				        ? null
-				        : collectionSuffixes[collectionAliasCount];
-				final String selectFragment = joinable.selectFragment(
-						next == null ? null : next.getJoinable(),
-						next == null ? null : next.getRHSAlias(),
-						join.getRHSAlias(),
-						entitySuffix,
-				        collectionSuffix,
-						join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN
-				);
-				buf.append(selectFragment);
-				if ( joinable.consumesEntityAlias() ) entityAliasCount++;
-				if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) collectionAliasCount++;
-				if (
-					i<associations.size()-1 &&
-					selectFragment.trim().length()>0
-				) {
-					buf.append(", ");
-				}
-			}
-			return buf.toString();
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/JoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/JoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,990 @@
+/*
+ * 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.loader;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.JoinHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.sql.ConditionFragment;
+import org.hibernate.sql.DisjunctionFragment;
+import org.hibernate.sql.InFragment;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Walks the metamodel, searching for joins, and collecting
+ * together information needed by <tt>OuterJoinLoader</tt>.
+ * 
+ * @see OuterJoinLoader
+ * @author Gavin King, Jon Lipsky
+ */
+public class JoinWalker {
+	
+	private final SessionFactoryImplementor factory;
+	protected final List associations = new ArrayList();
+	private final Set visitedAssociationKeys = new HashSet();
+	private final Map enabledFilters;
+
+	protected String[] suffixes;
+	protected String[] collectionSuffixes;
+	protected Loadable[] persisters;
+	protected int[] owners;
+	protected EntityType[] ownerAssociationTypes;
+	protected CollectionPersister[] collectionPersisters;
+	protected int[] collectionOwners;
+	protected String[] aliases;
+	protected LockMode[] lockModeArray;
+	protected String sql;
+	
+	public String[] getCollectionSuffixes() {
+		return collectionSuffixes;
+	}
+
+	public void setCollectionSuffixes(String[] collectionSuffixes) {
+		this.collectionSuffixes = collectionSuffixes;
+	}
+
+	public LockMode[] getLockModeArray() {
+		return lockModeArray;
+	}
+
+	public void setLockModeArray(LockMode[] lockModeArray) {
+		this.lockModeArray = lockModeArray;
+	}
+
+	public String[] getSuffixes() {
+		return suffixes;
+	}
+
+	public void setSuffixes(String[] suffixes) {
+		this.suffixes = suffixes;
+	}
+
+	public String[] getAliases() {
+		return aliases;
+	}
+
+	public void setAliases(String[] aliases) {
+		this.aliases = aliases;
+	}
+
+	public int[] getCollectionOwners() {
+		return collectionOwners;
+	}
+
+	public void setCollectionOwners(int[] collectionOwners) {
+		this.collectionOwners = collectionOwners;
+	}
+
+	public CollectionPersister[] getCollectionPersisters() {
+		return collectionPersisters;
+	}
+
+	public void setCollectionPersisters(CollectionPersister[] collectionPersisters) {
+		this.collectionPersisters = collectionPersisters;
+	}
+
+	public EntityType[] getOwnerAssociationTypes() {
+		return ownerAssociationTypes;
+	}
+
+	public void setOwnerAssociationTypes(EntityType[] ownerAssociationType) {
+		this.ownerAssociationTypes = ownerAssociationType;
+	}
+
+	public int[] getOwners() {
+		return owners;
+	}
+
+	public void setOwners(int[] owners) {
+		this.owners = owners;
+	}
+
+	public Loadable[] getPersisters() {
+		return persisters;
+	}
+
+	public void setPersisters(Loadable[] persisters) {
+		this.persisters = persisters;
+	}
+
+	public String getSQLString() {
+		return sql;
+	}
+
+	public void setSql(String sql) {
+		this.sql = sql;
+	}
+
+	protected SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	protected Dialect getDialect() {
+		return factory.getDialect();
+	}
+	
+	protected Map getEnabledFilters() {
+		return enabledFilters;
+	}
+
+	protected JoinWalker(SessionFactoryImplementor factory, Map enabledFilters) {
+		this.factory = factory;
+		this.enabledFilters = enabledFilters;
+	}
+
+	/**
+	 * Add on association (one-to-one, many-to-one, or a collection) to a list 
+	 * of associations to be fetched by outerjoin (if necessary)
+	 */
+	private void addAssociationToJoinTreeIfNecessary(
+		final AssociationType type,
+		final String[] aliasedLhsColumns,
+		final String alias,
+		final String path,
+		int currentDepth,
+		final int joinType)
+	throws MappingException {
+		
+		if (joinType>=0) {	
+			addAssociationToJoinTree(
+					type, 
+					aliasedLhsColumns, 
+					alias, 
+					path,
+					currentDepth,
+					joinType
+				);
+		}
+
+	}
+
+	/**
+	 * Add on association (one-to-one, many-to-one, or a collection) to a list 
+	 * of associations to be fetched by outerjoin 
+	 */
+	private void addAssociationToJoinTree(
+		final AssociationType type,
+		final String[] aliasedLhsColumns,
+		final String alias,
+		final String path,
+		final int currentDepth,
+		final int joinType)
+	throws MappingException {
+
+		Joinable joinable = type.getAssociatedJoinable( getFactory() );
+
+		String subalias = generateTableAlias(
+				associations.size()+1, //before adding to collection!
+				path, 
+				joinable
+			);
+
+		OuterJoinableAssociation assoc = new OuterJoinableAssociation(
+				type, 
+				alias, 
+				aliasedLhsColumns, 
+				subalias, 
+				joinType, 
+				getFactory(), 
+				enabledFilters
+			);
+		assoc.validateJoin(path);
+		associations.add(assoc);
+
+		int nextDepth = currentDepth+1;
+		if ( !joinable.isCollection() ) {
+			if (joinable instanceof OuterJoinLoadable) {
+				walkEntityTree(
+					(OuterJoinLoadable) joinable, 
+					subalias,
+					path, 
+					nextDepth
+				);
+			}
+		}
+		else {
+			if (joinable instanceof QueryableCollection) {
+				walkCollectionTree(
+					(QueryableCollection) joinable, 
+					subalias, 
+					path, 
+					nextDepth
+				);
+			}
+		}
+
+	}
+
+	/**
+	 * For an entity class, return a list of associations to be fetched by outerjoin
+	 */
+	protected final void walkEntityTree(OuterJoinLoadable persister, String alias)
+	throws MappingException {
+		walkEntityTree(persister, alias, "", 0);
+	}
+
+	/**
+	 * For a collection role, return a list of associations to be fetched by outerjoin
+	 */
+	protected final void walkCollectionTree(QueryableCollection persister, String alias)
+	throws MappingException {
+		walkCollectionTree(persister, alias, "", 0);
+		//TODO: when this is the entry point, we should use an INNER_JOIN for fetching the many-to-many elements!
+	}
+
+	/**
+	 * For a collection role, return a list of associations to be fetched by outerjoin
+	 */
+	private void walkCollectionTree(
+		final QueryableCollection persister,
+		final String alias,
+		final String path,
+		final int currentDepth)
+	throws MappingException {
+
+		if ( persister.isOneToMany() ) {
+			walkEntityTree(
+					(OuterJoinLoadable) persister.getElementPersister(),
+					alias,
+					path,
+					currentDepth
+				);
+		}
+		else {
+			Type type = persister.getElementType();
+			if ( type.isAssociationType() ) {
+				// a many-to-many;
+				// decrement currentDepth here to allow join across the association table
+				// without exceeding MAX_FETCH_DEPTH (i.e. the "currentDepth - 1" bit)
+				AssociationType associationType = (AssociationType) type;
+				String[] aliasedLhsColumns = persister.getElementColumnNames(alias);
+				String[] lhsColumns = persister.getElementColumnNames();
+				// if the current depth is 0, the root thing being loaded is the
+				// many-to-many collection itself.  Here, it is alright to use
+				// an inner join...
+				boolean useInnerJoin = currentDepth == 0;
+				final int joinType = getJoinType(
+						associationType,
+						persister.getFetchMode(),
+						path,
+						persister.getTableName(),
+						lhsColumns,
+						!useInnerJoin,
+						currentDepth - 1, 
+						null //operations which cascade as far as the collection also cascade to collection elements
+					);
+				addAssociationToJoinTreeIfNecessary(
+						associationType,
+						aliasedLhsColumns,
+						alias,
+						path,
+						currentDepth - 1,
+						joinType
+					);
+			}
+			else if ( type.isComponentType() ) {
+				walkCompositeElementTree(
+						(AbstractComponentType) type,
+						persister.getElementColumnNames(),
+						persister,
+						alias,
+						path,
+						currentDepth
+					);
+			}
+		}
+
+	}
+	
+	/**
+	 * Walk the tree for a particular entity association
+	 */
+	private final void walkEntityAssociationTree(
+		final AssociationType associationType,
+		final OuterJoinLoadable persister,
+		final int propertyNumber,
+		final String alias,
+		final String path,
+		final boolean nullable,
+		final int currentDepth)
+	throws MappingException {
+
+		String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames(
+				associationType, alias, propertyNumber, persister, getFactory()
+			);
+
+		String[] lhsColumns = JoinHelper.getLHSColumnNames(
+				associationType, propertyNumber, persister, getFactory()
+			);
+		String lhsTable = JoinHelper.getLHSTableName(associationType, propertyNumber, persister);
+
+		String subpath = subPath( path, persister.getSubclassPropertyName(propertyNumber) );
+		int joinType = getJoinType(
+				associationType,
+				persister.getFetchMode(propertyNumber),
+				subpath,
+				lhsTable,
+				lhsColumns,
+				nullable,
+				currentDepth, 
+				persister.getCascadeStyle(propertyNumber)
+			);
+		addAssociationToJoinTreeIfNecessary(
+				associationType,
+				aliasedLhsColumns,
+				alias,
+				subpath,
+				currentDepth,
+				joinType
+			);
+
+	}
+
+	/**
+	 * For an entity class, add to a list of associations to be fetched 
+	 * by outerjoin
+	 */
+	private final void walkEntityTree(
+		final OuterJoinLoadable persister,
+		final String alias,
+		final String path,
+		final int currentDepth) 
+	throws MappingException {
+
+		int n = persister.countSubclassProperties();
+		for ( int i=0; i<n; i++ ) {
+			Type type = persister.getSubclassPropertyType(i);
+			if ( type.isAssociationType() ) {
+				walkEntityAssociationTree(
+					(AssociationType) type,
+					persister,
+					i,
+					alias,
+					path,
+					persister.isSubclassPropertyNullable(i),
+					currentDepth
+				);
+			}
+			else if ( type.isComponentType() ) {
+				walkComponentTree(
+					(AbstractComponentType) type,
+					i,
+					0,
+					persister,
+					alias,
+					subPath( path, persister.getSubclassPropertyName(i) ),
+					currentDepth
+				);
+			}
+		}
+	}
+
+	/**
+	 * For a component, add to a list of associations to be fetched by outerjoin
+	 */
+	private void walkComponentTree(
+		final AbstractComponentType componentType,
+		final int propertyNumber,
+		int begin,
+		final OuterJoinLoadable persister,
+		final String alias,
+		final String path,
+		final int currentDepth
+	) throws MappingException {
+
+		Type[] types = componentType.getSubtypes();
+		String[] propertyNames = componentType.getPropertyNames();
+		for ( int i=0; i <types.length; i++ ) {
+
+			if ( types[i].isAssociationType() ) {
+				AssociationType associationType = (AssociationType) types[i];
+
+				String[] aliasedLhsColumns = JoinHelper.getAliasedLHSColumnNames(
+					associationType, alias, propertyNumber, begin, persister, getFactory()
+				);
+
+				String[] lhsColumns = JoinHelper.getLHSColumnNames(
+					associationType, propertyNumber, begin, persister, getFactory()
+				);
+				String lhsTable = JoinHelper.getLHSTableName(associationType, propertyNumber, persister);
+
+				String subpath = subPath( path, propertyNames[i] );
+				final boolean[] propertyNullability = componentType.getPropertyNullability();
+				final int joinType = getJoinType(
+						associationType,
+						componentType.getFetchMode(i),
+						subpath,
+						lhsTable,
+						lhsColumns,
+						propertyNullability==null || propertyNullability[i],
+						currentDepth, 
+						componentType.getCascadeStyle(i)
+					);
+				addAssociationToJoinTreeIfNecessary(			
+						associationType,
+						aliasedLhsColumns,
+						alias,
+						subpath,
+						currentDepth,
+						joinType
+					);
+
+			}
+			else if ( types[i].isComponentType() ) {
+				String subpath = subPath( path, propertyNames[i] );
+				walkComponentTree(
+						(AbstractComponentType) types[i],
+						propertyNumber,
+						begin,
+						persister,
+						alias,
+						subpath,
+						currentDepth
+					);
+			}
+			
+			begin+=types[i].getColumnSpan( getFactory() );
+		}
+
+	}
+
+	/**
+	 * For a composite element, add to a list of associations to be fetched by outerjoin
+	 */
+	private void walkCompositeElementTree(
+		final AbstractComponentType compositeType,
+		final String[] cols,
+		final QueryableCollection persister,
+		final String alias,
+		final String path,
+		final int currentDepth) 
+	throws MappingException {
+
+		Type[] types = compositeType.getSubtypes();
+		String[] propertyNames = compositeType.getPropertyNames();
+		int begin = 0;
+		for ( int i=0; i <types.length; i++ ) {
+			int length = types[i].getColumnSpan( getFactory() );
+			String[] lhsColumns = ArrayHelper.slice(cols, begin, length);
+
+			if ( types[i].isAssociationType() ) {
+				AssociationType associationType = (AssociationType) types[i];
+
+				// simple, because we can't have a one-to-one or a collection 
+				// (or even a property-ref) in a composite-element:
+				String[] aliasedLhsColumns = StringHelper.qualify(alias, lhsColumns);
+
+				String subpath = subPath( path, propertyNames[i] );
+				final boolean[] propertyNullability = compositeType.getPropertyNullability();
+				final int joinType = getJoinType(
+						associationType,
+						compositeType.getFetchMode(i),
+						subpath,
+						persister.getTableName(),
+						lhsColumns,
+						propertyNullability==null || propertyNullability[i],
+						currentDepth, 
+						compositeType.getCascadeStyle(i)
+					);
+				addAssociationToJoinTreeIfNecessary(
+						associationType,
+						aliasedLhsColumns,
+						alias,
+						subpath,
+						currentDepth,
+						joinType
+					);
+			}
+			else if ( types[i].isComponentType() ) {
+				String subpath = subPath( path, propertyNames[i] );
+				walkCompositeElementTree(
+						(AbstractComponentType) types[i],
+						lhsColumns,
+						persister,
+						alias,
+						subpath,
+						currentDepth
+					);
+			}
+			begin+=length;
+		}
+
+	}
+
+	/**
+	 * Extend the path by the given property name
+	 */
+	private static String subPath(String path, String property) {
+		if ( path==null || path.length()==0) {
+			return property;
+		}
+		else {
+			return StringHelper.qualify(path, property);
+		}
+	}
+
+	/**
+	 * Get the join type (inner, outer, etc) or -1 if the
+	 * association should not be joined. Override on
+	 * subclasses.
+	 */
+	protected int getJoinType(
+			AssociationType type, 
+			FetchMode config, 
+			String path, 
+			String lhsTable,
+			String[] lhsColumns,
+			boolean nullable,
+			int currentDepth, 
+			CascadeStyle cascadeStyle)
+	throws MappingException {
+		
+		if  ( !isJoinedFetchEnabled(type, config, cascadeStyle) ) return -1;
+		
+		if ( isTooDeep(currentDepth) || ( type.isCollectionType() && isTooManyCollections() ) ) return -1;
+		
+		final boolean dupe = isDuplicateAssociation(lhsTable,  lhsColumns, type);
+		if (dupe) return -1;
+		
+		return getJoinType(nullable, currentDepth);
+		
+	}
+	
+	/**
+	 * Use an inner join if it is a non-null association and this
+	 * is the "first" join in a series
+	 */
+	protected int getJoinType(boolean nullable, int currentDepth) {
+		//TODO: this is too conservative; if all preceding joins were 
+		//      also inner joins, we could use an inner join here
+		return !nullable && currentDepth==0 ? 
+					JoinFragment.INNER_JOIN : 
+					JoinFragment.LEFT_OUTER_JOIN;
+	}
+
+	protected boolean isTooDeep(int currentDepth) {
+		Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();
+		return maxFetchDepth!=null && currentDepth >= maxFetchDepth.intValue();
+	}
+	
+	protected boolean isTooManyCollections() {
+		return false;
+	}
+	
+	/**
+	 * Does the mapping, and Hibernate default semantics, specify that
+	 * this association should be fetched by outer joining
+	 */
+	protected boolean isJoinedFetchEnabledInMapping(FetchMode config, AssociationType type) 
+	throws MappingException {
+		if ( !type.isEntityType() && !type.isCollectionType() ) {
+			return false;
+		}
+		else {
+			if (config==FetchMode.JOIN) return true;
+			if (config==FetchMode.SELECT) return false;
+			if ( type.isEntityType() ) {
+				//TODO: look at the owning property and check that it 
+				//      isn't lazy (by instrumentation)
+				EntityType entityType =(EntityType) type;
+				EntityPersister persister = getFactory().getEntityPersister( entityType.getAssociatedEntityName() );
+				return !persister.hasProxy();
+			}
+			else {
+				return false;
+			}
+		}
+	}
+
+	/**
+	 * Override on subclasses to enable or suppress joining 
+	 * of certain association types
+	 */
+	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
+		return type.isEntityType() && isJoinedFetchEnabledInMapping(config, type) ;
+	}
+	
+	protected String generateTableAlias(
+			final int n,
+			final String path,
+			final Joinable joinable
+	) {
+		return StringHelper.generateAlias( joinable.getName(), n );
+	}
+
+	protected String generateRootAlias(final String description) {
+		return StringHelper.generateAlias(description, 0);
+	}
+
+	/**
+	 * Used to detect circularities in the joined graph, note that 
+	 * this method is side-effecty
+	 */
+	protected boolean isDuplicateAssociation(
+		final String foreignKeyTable, 
+		final String[] foreignKeyColumns
+	) {
+		AssociationKey associationKey = new AssociationKey(foreignKeyColumns, foreignKeyTable);
+		return !visitedAssociationKeys.add( associationKey );
+	}
+	
+	/**
+	 * Used to detect circularities in the joined graph, note that 
+	 * this method is side-effecty
+	 */
+	protected boolean isDuplicateAssociation(
+		final String lhsTable,
+		final String[] lhsColumnNames,
+		final AssociationType type
+	) {
+		final String foreignKeyTable;
+		final String[] foreignKeyColumns;
+		if ( type.getForeignKeyDirection()==ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT ) {
+			foreignKeyTable = lhsTable;
+			foreignKeyColumns = lhsColumnNames;
+		}
+		else {
+			foreignKeyTable = type.getAssociatedJoinable( getFactory() ).getTableName();
+			foreignKeyColumns = JoinHelper.getRHSColumnNames( type, getFactory() );
+		}
+		return isDuplicateAssociation(foreignKeyTable, foreignKeyColumns);
+	}
+	
+	/**
+	 * Uniquely identifier a foreign key, so that we don't
+	 * join it more than once, and create circularities
+	 */
+	private static final class AssociationKey {
+		private String[] columns;
+		private String table;
+		private AssociationKey(String[] columns, String table) {
+			this.columns = columns;
+			this.table = table;
+		}
+		public boolean equals(Object other) {
+			AssociationKey that = (AssociationKey) other;
+			return that.table.equals(table) && Arrays.equals(columns, that.columns);
+		}
+		public int hashCode() {
+			return table.hashCode(); //TODO: inefficient
+		}
+	}
+	
+	/**
+	 * Should we join this association?
+	 */
+	protected boolean isJoinable(
+		final int joinType,
+		final Set visitedAssociationKeys, 
+		final String lhsTable,
+		final String[] lhsColumnNames,
+		final AssociationType type,
+		final int depth
+	) {
+		if (joinType<0) return false;
+		
+		if (joinType==JoinFragment.INNER_JOIN) return true;
+		
+		Integer maxFetchDepth = getFactory().getSettings().getMaximumFetchDepth();
+		final boolean tooDeep = maxFetchDepth!=null && 
+			depth >= maxFetchDepth.intValue();
+		
+		return !tooDeep && !isDuplicateAssociation(lhsTable, lhsColumnNames, type);
+	}
+	
+	protected String orderBy(final List associations, final String orderBy) {
+		return mergeOrderings( orderBy( associations ), orderBy );
+	}
+
+	protected static String mergeOrderings(String ordering1, String ordering2) {
+		if ( ordering1.length() == 0 ) {
+			return ordering2;
+		}
+		else if ( ordering2.length() == 0 ) {
+			return ordering1;
+		}
+		else {
+			return ordering1 + ", " + ordering2;
+		}
+	}
+	
+	/**
+	 * Generate a sequence of <tt>LEFT OUTER JOIN</tt> clauses for the given associations.
+	 */
+	protected final JoinFragment mergeOuterJoins(List associations)
+	throws MappingException {
+		JoinFragment outerjoin = getDialect().createOuterJoinFragment();
+		Iterator iter = associations.iterator();
+		OuterJoinableAssociation last = null;
+		while ( iter.hasNext() ) {
+			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
+			if ( last != null && last.isManyToManyWith( oj ) ) {
+				oj.addManyToManyJoin( outerjoin, ( QueryableCollection ) last.getJoinable() );
+			}
+			else {
+				oj.addJoins(outerjoin);
+			}
+			last = oj;
+		}
+		last = null;
+		return outerjoin;
+	}
+
+	/**
+	 * Count the number of instances of Joinable which are actually
+	 * also instances of Loadable, or are one-to-many associations
+	 */
+	protected static final int countEntityPersisters(List associations)
+	throws MappingException {
+		int result = 0;
+		Iterator iter = associations.iterator();
+		while ( iter.hasNext() ) {
+			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
+			if ( oj.getJoinable().consumesEntityAlias() ) {
+				result++;
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Count the number of instances of Joinable which are actually
+	 * also instances of PersistentCollection which are being fetched
+	 * by outer join
+	 */
+	protected static final int countCollectionPersisters(List associations)
+	throws MappingException {
+		int result = 0;
+		Iterator iter = associations.iterator();
+		while ( iter.hasNext() ) {
+			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
+			if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN && oj.getJoinable().isCollection() ) {
+				result++;
+			}
+		}
+		return result;
+	}
+	
+	/**
+	 * Get the order by string required for collection fetching
+	 */
+	protected static final String orderBy(List associations)
+	throws MappingException {
+		StringBuffer buf = new StringBuffer();
+		Iterator iter = associations.iterator();
+		OuterJoinableAssociation last = null;
+		while ( iter.hasNext() ) {
+			OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
+			if ( oj.getJoinType() == JoinFragment.LEFT_OUTER_JOIN ) { // why does this matter?
+				if ( oj.getJoinable().isCollection() ) {
+					final QueryableCollection queryableCollection = (QueryableCollection) oj.getJoinable();
+					if ( queryableCollection.hasOrdering() ) {
+						final String orderByString = queryableCollection.getSQLOrderByString( oj.getRHSAlias() );
+						buf.append( orderByString ).append(", ");
+					}
+				}
+				else {
+					// it might still need to apply a collection ordering based on a
+					// many-to-many defined order-by...
+					if ( last != null && last.getJoinable().isCollection() ) {
+						final QueryableCollection queryableCollection = (QueryableCollection) last.getJoinable();
+						if ( queryableCollection.isManyToMany() && last.isManyToManyWith( oj ) ) {
+							if ( queryableCollection.hasManyToManyOrdering() ) {
+								final String orderByString = queryableCollection.getManyToManyOrderByString( oj.getRHSAlias() );
+								buf.append( orderByString ).append(", ");
+							}
+						}
+					}
+				}
+			}
+			last = oj;
+		}
+		if ( buf.length()>0 ) buf.setLength( buf.length()-2 );
+		return buf.toString();
+	}
+	
+	/**
+	 * Render the where condition for a (batch) load by identifier / collection key
+	 */
+	protected StringBuffer whereString(String alias, String[] columnNames, int batchSize) {
+		if ( columnNames.length==1 ) {
+			// if not a composite key, use "foo in (?, ?, ?)" for batching
+			// if no batch, and not a composite key, use "foo = ?"
+			InFragment in = new InFragment().setColumn( alias, columnNames[0] );
+			for ( int i=0; i<batchSize; i++ ) in.addValue("?");
+			return new StringBuffer( in.toFragmentString() );
+		}
+		else {
+			//a composite key
+			ConditionFragment byId = new ConditionFragment()
+					.setTableAlias(alias)
+					.setCondition( columnNames, "?" );
+	
+			StringBuffer whereString = new StringBuffer();
+			if ( batchSize==1 ) {
+				// if no batch, use "foo = ? and bar = ?"
+				whereString.append( byId.toFragmentString() );
+			}
+			else {
+				// if a composite key, use "( (foo = ? and bar = ?) or (foo = ? and bar = ?) )" for batching
+				whereString.append('('); //TODO: unnecessary for databases with ANSI-style joins
+				DisjunctionFragment df = new DisjunctionFragment();
+				for ( int i=0; i<batchSize; i++ ) {
+					df.addCondition(byId);
+				}
+				whereString.append( df.toFragmentString() );
+				whereString.append(')'); //TODO: unnecessary for databases with ANSI-style joins
+			}
+			return whereString;
+		}
+	}
+
+	protected void initPersisters(final List associations, final LockMode lockMode) throws MappingException {
+		
+		final int joins = countEntityPersisters(associations);
+		final int collections = countCollectionPersisters(associations);
+
+		collectionOwners = collections==0 ? null : new int[collections];
+		collectionPersisters = collections==0 ? null : new CollectionPersister[collections];
+		collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collections );
+
+		persisters = new Loadable[joins];
+		aliases = new String[joins];
+		owners = new int[joins];
+		ownerAssociationTypes = new EntityType[joins];
+		lockModeArray = ArrayHelper.fillArray(lockMode, joins);
+		
+		int i=0;
+		int j=0;
+		Iterator iter = associations.iterator();
+		while ( iter.hasNext() ) {
+			final OuterJoinableAssociation oj = (OuterJoinableAssociation) iter.next();
+			if ( !oj.isCollection() ) {
+				
+				persisters[i] = (Loadable) oj.getJoinable();
+				aliases[i] = oj.getRHSAlias();
+				owners[i] = oj.getOwner(associations);
+				ownerAssociationTypes[i] = (EntityType) oj.getJoinableType();
+				i++;
+				
+			}
+			else {
+				
+				QueryableCollection collPersister = (QueryableCollection) oj.getJoinable();
+				if ( oj.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) {
+					//it must be a collection fetch
+					collectionPersisters[j] = collPersister;
+					collectionOwners[j] = oj.getOwner(associations);
+					j++;
+				}
+	
+				if ( collPersister.isOneToMany() ) {
+					persisters[i] = (Loadable) collPersister.getElementPersister();
+					aliases[i] = oj.getRHSAlias();
+					i++;
+				}
+			}
+		}
+	
+		if ( ArrayHelper.isAllNegative(owners) ) owners = null;
+		if ( collectionOwners!=null && ArrayHelper.isAllNegative(collectionOwners) ) {
+			collectionOwners = null;
+		}
+	}
+
+	/**
+	 * Generate a select list of columns containing all properties of the entity classes
+	 */
+	protected final String selectString(List associations)
+	throws MappingException {
+
+		if ( associations.size()==0 ) {
+			return "";
+		}
+		else {
+			StringBuffer buf = new StringBuffer( associations.size() * 100 )
+				.append(", ");
+			int entityAliasCount=0;
+			int collectionAliasCount=0;
+			for ( int i=0; i<associations.size(); i++ ) {
+				OuterJoinableAssociation join = (OuterJoinableAssociation) associations.get(i);
+				OuterJoinableAssociation next = (i == associations.size() - 1)
+				        ? null
+				        : ( OuterJoinableAssociation ) associations.get( i + 1 );
+				final Joinable joinable = join.getJoinable();
+				final String entitySuffix = ( suffixes == null || entityAliasCount >= suffixes.length )
+				        ? null
+				        : suffixes[entityAliasCount];
+				final String collectionSuffix = ( collectionSuffixes == null || collectionAliasCount >= collectionSuffixes.length )
+				        ? null
+				        : collectionSuffixes[collectionAliasCount];
+				final String selectFragment = joinable.selectFragment(
+						next == null ? null : next.getJoinable(),
+						next == null ? null : next.getRHSAlias(),
+						join.getRHSAlias(),
+						entitySuffix,
+				        collectionSuffix,
+						join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN
+				);
+				buf.append(selectFragment);
+				if ( joinable.consumesEntityAlias() ) entityAliasCount++;
+				if ( joinable.consumesCollectionAlias() && join.getJoinType()==JoinFragment.LEFT_OUTER_JOIN ) collectionAliasCount++;
+				if (
+					i<associations.size()-1 &&
+					selectFragment.trim().length()>0
+				) {
+					buf.append(", ");
+				}
+			}
+			return buf.toString();
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/Loader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,2352 +0,0 @@
-//$Id: Loader.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.loader;
-
-import java.io.Serializable;
-import java.sql.CallableStatement;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.WrongClassException;
-import org.hibernate.cache.FilterKey;
-import org.hibernate.cache.QueryCache;
-import org.hibernate.cache.QueryKey;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.EntityUniqueKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SubselectFetch;
-import org.hibernate.engine.TwoPhaseLoad;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.event.EventSource;
-import org.hibernate.event.PostLoadEvent;
-import org.hibernate.event.PreLoadEvent;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.impl.FetchingScrollableResultsImpl;
-import org.hibernate.impl.ScrollableResultsImpl;
-import org.hibernate.jdbc.ColumnNameCache;
-import org.hibernate.jdbc.ResultSetWrapper;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.UniqueKeyLoadable;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.VersionType;
-import org.hibernate.util.StringHelper;
-
-/**
- * Abstract superclass of object loading (and querying) strategies. This class implements
- * useful common functionality that concrete loaders delegate to. It is not intended that this
- * functionality would be directly accessed by client code. (Hence, all methods of this class
- * are declared <tt>protected</tt> or <tt>private</tt>.) This class relies heavily upon the
- * <tt>Loadable</tt> interface, which is the contract between this class and
- * <tt>EntityPersister</tt>s that may be loaded by it.<br>
- * <br>
- * The present implementation is able to load any number of columns of entities and at most
- * one collection role per query.
- *
- * @author Gavin King
- * @see org.hibernate.persister.entity.Loadable
- */
-public abstract class Loader {
-
-	private static final Logger log = LoggerFactory.getLogger( Loader.class );
-
-	private final SessionFactoryImplementor factory;
-	private ColumnNameCache columnNameCache;
-
-	public Loader(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-	/**
-	 * The SQL query string to be called; implemented by all subclasses
-	 *
-	 * @return The sql command this loader should use to get its {@link ResultSet}.
-	 */
-	protected abstract String getSQLString();
-
-	/**
-	 * An array of persisters of entity classes contained in each row of results;
-	 * implemented by all subclasses
-	 *
-	 * @return The entity persisters.
-	 */
-	protected abstract Loadable[] getEntityPersisters();
-	
-	/**
-	 * An array indicating whether the entities have eager property fetching
-	 * enabled.
-	 *
-	 * @return Eager property fetching indicators.
-	 */
-	protected boolean[] getEntityEagerPropertyFetches() {
-		return null;
-	}
-
-	/**
-	 * An array of indexes of the entity that owns a one-to-one association
-	 * to the entity at the given index (-1 if there is no "owner").  The
-	 * indexes contained here are relative to the result of
-	 * {@link #getEntityPersisters}.
-	 *
-	 * @return The owner indicators (see discussion above).
-	 */
-	protected int[] getOwners() {
-		return null;
-	}
-
-	/**
-	 * An array of the owner types corresponding to the {@link #getOwners()}
-	 * returns.  Indices indicating no owner would be null here.
-	 *
-	 * @return The types for the owners.
-	 */
-	protected EntityType[] getOwnerAssociationTypes() {
-		return null;
-	}
-
-	/**
-	 * An (optional) persister for a collection to be initialized; only 
-	 * collection loaders return a non-null value
-	 */
-	protected CollectionPersister[] getCollectionPersisters() {
-		return null;
-	}
-
-	/**
-	 * Get the index of the entity that owns the collection, or -1
-	 * if there is no owner in the query results (ie. in the case of a
-	 * collection initializer) or no collection.
-	 */
-	protected int[] getCollectionOwners() {
-		return null;
-	}
-
-	/**
-	 * What lock mode does this load entities with?
-	 *
-	 * @param lockModes a collection of lock modes specified dynamically via the Query interface
-	 */
-	protected abstract LockMode[] getLockModes(Map lockModes);
-
-	/**
-	 * Append <tt>FOR UPDATE OF</tt> clause, if necessary. This
-	 * empty superclass implementation merely returns its first
-	 * argument.
-	 */
-	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws HibernateException {
-		return sql;
-	}
-
-	/**
-	 * Does this query return objects that might be already cached
-	 * by the session, whose lock mode may need upgrading
-	 */
-	protected boolean upgradeLocks() {
-		return false;
-	}
-
-	/**
-	 * Return false is this loader is a batch entity loader
-	 */
-	protected boolean isSingleRowLoader() {
-		return false;
-	}
-
-	/**
-	 * Get the SQL table aliases of entities whose
-	 * associations are subselect-loadable, returning
-	 * null if this loader does not support subselect
-	 * loading
-	 */
-	protected String[] getAliases() {
-		return null;
-	}
-
-	/**
-	 * Modify the SQL, adding lock hints and comments, if necessary
-	 */
-	protected String preprocessSQL(String sql, QueryParameters parameters, Dialect dialect)
-			throws HibernateException {
-		
-		sql = applyLocks( sql, parameters.getLockModes(), dialect );
-		
-		return getFactory().getSettings().isCommentsEnabled() ?
-				prependComment( sql, parameters ) : sql;
-	}
-
-	private String prependComment(String sql, QueryParameters parameters) {
-		String comment = parameters.getComment();
-		if ( comment == null ) {
-			return sql;
-		}
-		else {
-			return new StringBuffer( comment.length() + sql.length() + 5 )
-					.append( "/* " )
-					.append( comment )
-					.append( " */ " )
-					.append( sql )
-					.toString();
-		}
-	}
-
-	/**
-	 * Execute an SQL query and attempt to instantiate instances of the class mapped by the given
-	 * persister from each row of the <tt>ResultSet</tt>. If an object is supplied, will attempt to
-	 * initialize that object. If a collection is supplied, attempt to initialize that collection.
-	 */
-	private List doQueryAndInitializeNonLazyCollections(final SessionImplementor session,
-														final QueryParameters queryParameters,
-														final boolean returnProxies) 
-		throws HibernateException, SQLException {
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		persistenceContext.beforeLoad();
-		List result;
-		try {
-			result = doQuery( session, queryParameters, returnProxies );
-		}
-		finally {
-			persistenceContext.afterLoad();
-		}
-		persistenceContext.initializeNonLazyCollections();
-		return result;
-	}
-
-	/**
-	 * Loads a single row from the result set.  This is the processing used from the
-	 * ScrollableResults where no collection fetches were encountered.
-	 *
-	 * @param resultSet The result set from which to do the load.
-	 * @param session The session from which the request originated.
-	 * @param queryParameters The query parameters specified by the user.
-	 * @param returnProxies Should proxies be generated
-	 * @return The loaded "row".
-	 * @throws HibernateException
-	 */
-	public Object loadSingleRow(
-	        final ResultSet resultSet,
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final boolean returnProxies) throws HibernateException {
-
-		final int entitySpan = getEntityPersisters().length;
-		final List hydratedObjects = entitySpan == 0 ? 
-				null : new ArrayList( entitySpan );
-
-		final Object result;
-		try {
-			result = getRowFromResultSet(
-			        resultSet,
-					session,
-					queryParameters,
-					getLockModes( queryParameters.getLockModes() ),
-					null,
-					hydratedObjects,
-					new EntityKey[entitySpan],
-					returnProxies
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not read next row of results",
-			        getSQLString()
-				);
-		}
-
-		initializeEntitiesAndCollections( 
-				hydratedObjects, 
-				resultSet, 
-				session, 
-				queryParameters.isReadOnly() 
-			);
-		session.getPersistenceContext().initializeNonLazyCollections();
-		return result;
-	}
-
-	private Object sequentialLoad(
-	        final ResultSet resultSet,
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final boolean returnProxies,
-	        final EntityKey keyToRead) throws HibernateException {
-
-		final int entitySpan = getEntityPersisters().length;
-		final List hydratedObjects = entitySpan == 0 ? 
-				null : new ArrayList( entitySpan );
-
-		Object result = null;
-		final EntityKey[] loadedKeys = new EntityKey[entitySpan];
-
-		try {
-			do {
-				Object loaded = getRowFromResultSet(
-						resultSet,
-						session,
-						queryParameters,
-						getLockModes( queryParameters.getLockModes() ),
-						null,
-						hydratedObjects,
-						loadedKeys,
-						returnProxies
-					);
-				if ( result == null ) {
-					result = loaded;
-				}
-			} 
-			while ( keyToRead.equals( loadedKeys[0] ) && resultSet.next() );
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not perform sequential read of results (forward)",
-			        getSQLString()
-				);
-		}
-
-		initializeEntitiesAndCollections( 
-				hydratedObjects, 
-				resultSet, 
-				session, 
-				queryParameters.isReadOnly() 
-			);
-		session.getPersistenceContext().initializeNonLazyCollections();
-		return result;
-	}
-
-	/**
-	 * Loads a single logical row from the result set moving forward.  This is the
-	 * processing used from the ScrollableResults where there were collection fetches
-	 * encountered; thus a single logical row may have multiple rows in the underlying
-	 * result set.
-	 *
-	 * @param resultSet The result set from which to do the load.
-	 * @param session The session from which the request originated.
-	 * @param queryParameters The query parameters specified by the user.
-	 * @param returnProxies Should proxies be generated
-	 * @return The loaded "row".
-	 * @throws HibernateException
-	 */
-	public Object loadSequentialRowsForward(
-	        final ResultSet resultSet,
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final boolean returnProxies) throws HibernateException {
-
-		// note that for sequential scrolling, we make the assumption that
-		// the first persister element is the "root entity"
-
-		try {
-			if ( resultSet.isAfterLast() ) {
-				// don't even bother trying to read further
-				return null;
-			}
-
-			if ( resultSet.isBeforeFirst() ) {
-				resultSet.next();
-			}
-
-			// We call getKeyFromResultSet() here so that we can know the
-			// key value upon which to perform the breaking logic.  However,
-			// it is also then called from getRowFromResultSet() which is certainly
-			// not the most efficient.  But the call here is needed, and there
-			// currently is no other way without refactoring of the doQuery()/getRowFromResultSet()
-			// methods
-			final EntityKey currentKey = getKeyFromResultSet(
-					0,
-					getEntityPersisters()[0],
-					null,
-					resultSet,
-					session
-				);
-
-			return sequentialLoad( resultSet, session, queryParameters, returnProxies, currentKey );
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not perform sequential read of results (forward)",
-			        getSQLString()
-				);
-		}
-	}
-
-	/**
-	 * Loads a single logical row from the result set moving forward.  This is the
-	 * processing used from the ScrollableResults where there were collection fetches
-	 * encountered; thus a single logical row may have multiple rows in the underlying
-	 * result set.
-	 *
-	 * @param resultSet The result set from which to do the load.
-	 * @param session The session from which the request originated.
-	 * @param queryParameters The query parameters specified by the user.
-	 * @param returnProxies Should proxies be generated
-	 * @return The loaded "row".
-	 * @throws HibernateException
-	 */
-	public Object loadSequentialRowsReverse(
-	        final ResultSet resultSet,
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final boolean returnProxies,
-	        final boolean isLogicallyAfterLast) throws HibernateException {
-
-		// note that for sequential scrolling, we make the assumption that
-		// the first persister element is the "root entity"
-
-		try {
-			if ( resultSet.isFirst() ) {
-				// don't even bother trying to read any further
-				return null;
-			}
-
-			EntityKey keyToRead = null;
-			// This check is needed since processing leaves the cursor
-			// after the last physical row for the current logical row;
-			// thus if we are after the last physical row, this might be
-			// caused by either:
-			//      1) scrolling to the last logical row
-			//      2) scrolling past the last logical row
-			// In the latter scenario, the previous logical row
-			// really is the last logical row.
-			//
-			// In all other cases, we should process back two
-			// logical records (the current logic row, plus the
-			// previous logical row).
-			if ( resultSet.isAfterLast() && isLogicallyAfterLast ) {
-				// position cursor to the last row
-				resultSet.last();
-				keyToRead = getKeyFromResultSet(
-						0,
-						getEntityPersisters()[0],
-						null,
-						resultSet,
-						session
-					);
-			}
-			else {
-				// Since the result set cursor is always left at the first
-				// physical row after the "last processed", we need to jump
-				// back one position to get the key value we are interested
-				// in skipping
-				resultSet.previous();
-
-				// sequentially read the result set in reverse until we recognize
-				// a change in the key value.  At that point, we are pointed at
-				// the last physical sequential row for the logical row in which
-				// we are interested in processing
-				boolean firstPass = true;
-				final EntityKey lastKey = getKeyFromResultSet(
-						0,
-						getEntityPersisters()[0],
-						null,
-						resultSet,
-						session
-					);
-				while ( resultSet.previous() ) {
-					EntityKey checkKey = getKeyFromResultSet(
-							0,
-							getEntityPersisters()[0],
-							null,
-							resultSet,
-							session
-						);
-
-					if ( firstPass ) {
-						firstPass = false;
-						keyToRead = checkKey;
-					}
-
-					if ( !lastKey.equals( checkKey ) ) {
-						break;
-					}
-				}
-
-			}
-
-			// Read backwards until we read past the first physical sequential
-			// row with the key we are interested in loading
-			while ( resultSet.previous() ) {
-				EntityKey checkKey = getKeyFromResultSet(
-						0,
-						getEntityPersisters()[0],
-						null,
-						resultSet,
-						session
-					);
-
-				if ( !keyToRead.equals( checkKey ) ) {
-					break;
-				}
-			}
-
-			// Finally, read ahead one row to position result set cursor
-			// at the first physical row we are interested in loading
-			resultSet.next();
-
-			// and perform the load
-			return sequentialLoad( resultSet, session, queryParameters, returnProxies, keyToRead );
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not perform sequential read of results (forward)",
-			        getSQLString()
-				);
-		}
-	}
-
-	private static EntityKey getOptionalObjectKey(QueryParameters queryParameters, SessionImplementor session) {
-		final Object optionalObject = queryParameters.getOptionalObject();
-		final Serializable optionalId = queryParameters.getOptionalId();
-		final String optionalEntityName = queryParameters.getOptionalEntityName();
-
-		if ( optionalObject != null && optionalEntityName != null ) {
-			return new EntityKey( 
-					optionalId,
-					session.getEntityPersister( optionalEntityName, optionalObject ), 
-					session.getEntityMode()
-				);
-		}
-		else {
-			return null;
-		}
-
-	}
-
-	private Object getRowFromResultSet(
-	        final ResultSet resultSet,
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final LockMode[] lockModeArray,
-	        final EntityKey optionalObjectKey,
-	        final List hydratedObjects,
-	        final EntityKey[] keys,
-	        boolean returnProxies) throws SQLException, HibernateException {
-
-		final Loadable[] persisters = getEntityPersisters();
-		final int entitySpan = persisters.length;
-
-		for ( int i = 0; i < entitySpan; i++ ) {
-			keys[i] = getKeyFromResultSet(
-			        i,
-					persisters[i],
-					i == entitySpan - 1 ?
-							queryParameters.getOptionalId() :
-							null,
-					resultSet,
-					session
-				);
-			//TODO: the i==entitySpan-1 bit depends upon subclass implementation (very bad)
-		}
-
-		registerNonExists( keys, persisters, session );
-
-		// this call is side-effecty
-		Object[] row = getRow(
-		        resultSet,
-				persisters,
-				keys,
-				queryParameters.getOptionalObject(),
-				optionalObjectKey,
-				lockModeArray,
-				hydratedObjects,
-				session
-		);
-
-		readCollectionElements( row, resultSet, session );
-
-		if ( returnProxies ) {
-			// now get an existing proxy for each row element (if there is one)
-			for ( int i = 0; i < entitySpan; i++ ) {
-				Object entity = row[i];
-				Object proxy = session.getPersistenceContext().proxyFor( persisters[i], keys[i], entity );
-				if ( entity != proxy ) {
-					// force the proxy to resolve itself
-					( (HibernateProxy) proxy ).getHibernateLazyInitializer().setImplementation(entity);
-					row[i] = proxy;
-				}
-			}
-		}
-
-		return getResultColumnOrRow( row, queryParameters.getResultTransformer(), resultSet, session );
-
-	}
-
-	/**
-	 * Read any collection elements contained in a single row of the result set
-	 */
-	private void readCollectionElements(Object[] row, ResultSet resultSet, SessionImplementor session)
-			throws SQLException, HibernateException {
-
-		//TODO: make this handle multiple collection roles!
-
-		final CollectionPersister[] collectionPersisters = getCollectionPersisters();
-		if ( collectionPersisters != null ) {
-
-			final CollectionAliases[] descriptors = getCollectionAliases();
-			final int[] collectionOwners = getCollectionOwners();
-
-			for ( int i=0; i<collectionPersisters.length; i++ ) {
-
-				final boolean hasCollectionOwners = collectionOwners !=null && 
-						collectionOwners[i] > -1;
-				//true if this is a query and we are loading multiple instances of the same collection role
-				//otherwise this is a CollectionInitializer and we are loading up a single collection or batch
-				
-				final Object owner = hasCollectionOwners ?
-						row[ collectionOwners[i] ] :
-						null; //if null, owner will be retrieved from session
-
-				final CollectionPersister collectionPersister = collectionPersisters[i];
-				final Serializable key;
-				if ( owner == null ) {
-					key = null;
-				}
-				else {
-					key = collectionPersister.getCollectionType().getKeyOfOwner( owner, session );
-					//TODO: old version did not require hashmap lookup:
-					//keys[collectionOwner].getIdentifier()
-				}
-	
-				readCollectionElement( 
-						owner, 
-						key, 
-						collectionPersister, 
-						descriptors[i], 
-						resultSet, 
-						session 
-					);
-				
-			}
-
-		}
-	}
-
-	private List doQuery(
-			final SessionImplementor session,
-			final QueryParameters queryParameters,
-			final boolean returnProxies) throws SQLException, HibernateException {
-
-		final RowSelection selection = queryParameters.getRowSelection();
-		final int maxRows = hasMaxRows( selection ) ?
-				selection.getMaxRows().intValue() :
-				Integer.MAX_VALUE;
-
-		final int entitySpan = getEntityPersisters().length;
-
-		final ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan * 10 );
-		final PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
-		final ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), selection, session );
-
-// would be great to move all this below here into another method that could also be used
-// from the new scrolling stuff.
-//
-// Would need to change the way the max-row stuff is handled (i.e. behind an interface) so
-// that I could do the control breaking at the means to know when to stop
-		final LockMode[] lockModeArray = getLockModes( queryParameters.getLockModes() );
-		final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session );
-
-		final boolean createSubselects = isSubselectLoadingEnabled();
-		final List subselectResultKeys = createSubselects ? new ArrayList() : null;
-		final List results = new ArrayList();
-
-		try {
-
-			handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );
-
-			EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row
-
-			if ( log.isTraceEnabled() ) log.trace( "processing result set" );
-
-			int count;
-			for ( count = 0; count < maxRows && rs.next(); count++ ) {
-				
-				if ( log.isTraceEnabled() ) log.debug("result set row: " + count);
-
-				Object result = getRowFromResultSet( 
-						rs,
-						session,
-						queryParameters,
-						lockModeArray,
-						optionalObjectKey,
-						hydratedObjects,
-						keys,
-						returnProxies 
-				);
-				results.add( result );
-
-				if ( createSubselects ) {
-					subselectResultKeys.add(keys);
-					keys = new EntityKey[entitySpan]; //can't reuse in this case
-				}
-				
-			}
-
-			if ( log.isTraceEnabled() ) {
-				log.trace( "done processing result set (" + count + " rows)" );
-			}
-
-		}
-		finally {
-			session.getBatcher().closeQueryStatement( st, rs );
-		}
-
-		initializeEntitiesAndCollections( hydratedObjects, rs, session, queryParameters.isReadOnly() );
-
-		if ( createSubselects ) createSubselects( subselectResultKeys, queryParameters, session );
-
-		return results; //getResultList(results);
-
-	}
-
-	protected boolean isSubselectLoadingEnabled() {
-		return false;
-	}
-	
-	protected boolean hasSubselectLoadableCollections() {
-		final Loadable[] loadables = getEntityPersisters();
-		for (int i=0; i<loadables.length; i++ ) {
-			if ( loadables[i].hasSubselectLoadableCollections() ) return true;
-		}
-		return false;
-	}
-	
-	private static Set[] transpose( List keys ) {
-		Set[] result = new Set[ ( ( EntityKey[] ) keys.get(0) ).length ];
-		for ( int j=0; j<result.length; j++ ) {
-			result[j] = new HashSet( keys.size() );
-			for ( int i=0; i<keys.size(); i++ ) {
-				result[j].add( ( ( EntityKey[] ) keys.get(i) ) [j] );
-			}
-		}
-		return result;
-	}
-
-	private void createSubselects(List keys, QueryParameters queryParameters, SessionImplementor session) {
-		if ( keys.size() > 1 ) { //if we only returned one entity, query by key is more efficient
-			
-			Set[] keySets = transpose(keys);
-			
-			Map namedParameterLocMap = buildNamedParameterLocMap( queryParameters );
-			
-			final Loadable[] loadables = getEntityPersisters();
-			final String[] aliases = getAliases();
-			final Iterator iter = keys.iterator();
-			while ( iter.hasNext() ) {
-				
-				final EntityKey[] rowKeys = (EntityKey[]) iter.next();
-				for ( int i=0; i<rowKeys.length; i++ ) {
-					
-					if ( rowKeys[i]!=null && loadables[i].hasSubselectLoadableCollections() ) {
-						
-						SubselectFetch subselectFetch = new SubselectFetch( 
-								//getSQLString(), 
-								aliases[i], 
-								loadables[i], 
-								queryParameters, 
-								keySets[i],
-								namedParameterLocMap
-							);
-						
-						session.getPersistenceContext()
-								.getBatchFetchQueue()
-								.addSubselect( rowKeys[i], subselectFetch );
-					}
-					
-				}
-				
-			}
-		}
-	}
-
-	private Map buildNamedParameterLocMap(QueryParameters queryParameters) {
-		if ( queryParameters.getNamedParameters()!=null ) {
-			final Map namedParameterLocMap = new HashMap();
-			Iterator piter = queryParameters.getNamedParameters().keySet().iterator();
-			while ( piter.hasNext() ) {
-				String name = (String) piter.next();
-				namedParameterLocMap.put(
-						name,
-						getNamedParameterLocs(name)
-					);
-			}
-			return namedParameterLocMap;
-		}
-		else {
-			return null;
-		}
-	}
-
-	private void initializeEntitiesAndCollections(
-			final List hydratedObjects,
-			final Object resultSetId,
-			final SessionImplementor session,
-			final boolean readOnly) 
-	throws HibernateException {
-		
-		final CollectionPersister[] collectionPersisters = getCollectionPersisters();
-		if ( collectionPersisters != null ) {
-			for ( int i=0; i<collectionPersisters.length; i++ ) {
-				if ( collectionPersisters[i].isArray() ) {
-					//for arrays, we should end the collection load before resolving
-					//the entities, since the actual array instances are not instantiated
-					//during loading
-					//TODO: or we could do this polymorphically, and have two
-					//      different operations implemented differently for arrays
-					endCollectionLoad( resultSetId, session, collectionPersisters[i] );
-				}
-			}
-		}
-
-		//important: reuse the same event instances for performance!
-		final PreLoadEvent pre;
-		final PostLoadEvent post;
-		if ( session.isEventSource() ) {
-			pre = new PreLoadEvent( (EventSource) session );
-			post = new PostLoadEvent( (EventSource) session );
-		}
-		else {
-			pre = null;
-			post = null;
-		}
-		
-		if ( hydratedObjects!=null ) {
-			int hydratedObjectsSize = hydratedObjects.size();
-			if ( log.isTraceEnabled() ) {
-				log.trace( "total objects hydrated: " + hydratedObjectsSize );
-			}
-			for ( int i = 0; i < hydratedObjectsSize; i++ ) {
-				TwoPhaseLoad.initializeEntity( hydratedObjects.get(i), readOnly, session, pre, post );
-			}
-		}
-		
-		if ( collectionPersisters != null ) {
-			for ( int i=0; i<collectionPersisters.length; i++ ) {
-				if ( !collectionPersisters[i].isArray() ) {
-					//for sets, we should end the collection load after resolving
-					//the entities, since we might call hashCode() on the elements
-					//TODO: or we could do this polymorphically, and have two
-					//      different operations implemented differently for arrays
-					endCollectionLoad( resultSetId, session, collectionPersisters[i] );
-				}
-			}
-		}
-		
-	}
-
-	private void endCollectionLoad(
-			final Object resultSetId, 
-			final SessionImplementor session, 
-			final CollectionPersister collectionPersister) {
-		//this is a query and we are loading multiple instances of the same collection role
-		session.getPersistenceContext()
-				.getLoadContexts()
-				.getCollectionLoadContext( ( ResultSet ) resultSetId )
-				.endLoadingCollections( collectionPersister );
-	}
-
-	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
-		return results;
-	}
-
-	/**
-	 * Get the actual object that is returned in the user-visible result list.
-	 * This empty implementation merely returns its first argument. This is
-	 * overridden by some subclasses.
-	 */
-	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
-			throws SQLException, HibernateException {
-		return row;
-	}
-
-	/**
-	 * For missing objects associated by one-to-one with another object in the
-	 * result set, register the fact that the the object is missing with the
-	 * session.
-	 */
-	private void registerNonExists(
-	        final EntityKey[] keys,
-	        final Loadable[] persisters,
-	        final SessionImplementor session) {
-		
-		final int[] owners = getOwners();
-		if ( owners != null ) {
-			
-			EntityType[] ownerAssociationTypes = getOwnerAssociationTypes();
-			for ( int i = 0; i < keys.length; i++ ) {
-				
-				int owner = owners[i];
-				if ( owner > -1 ) {
-					EntityKey ownerKey = keys[owner];
-					if ( keys[i] == null && ownerKey != null ) {
-						
-						final PersistenceContext persistenceContext = session.getPersistenceContext();
-						
-						/*final boolean isPrimaryKey;
-						final boolean isSpecialOneToOne;
-						if ( ownerAssociationTypes == null || ownerAssociationTypes[i] == null ) {
-							isPrimaryKey = true;
-							isSpecialOneToOne = false;
-						}
-						else {
-							isPrimaryKey = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName()==null;
-							isSpecialOneToOne = ownerAssociationTypes[i].getLHSPropertyName()!=null;
-						}*/
-						
-						//TODO: can we *always* use the "null property" approach for everything?
-						/*if ( isPrimaryKey && !isSpecialOneToOne ) {
-							persistenceContext.addNonExistantEntityKey( 
-									new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) 
-							);
-						}
-						else if ( isSpecialOneToOne ) {*/
-						boolean isOneToOneAssociation = ownerAssociationTypes!=null && 
-								ownerAssociationTypes[i]!=null && 
-								ownerAssociationTypes[i].isOneToOne();
-						if ( isOneToOneAssociation ) {
-							persistenceContext.addNullProperty( ownerKey, 
-									ownerAssociationTypes[i].getPropertyName() );
-						}
-						/*}
-						else {
-							persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( 
-									persisters[i].getEntityName(),
-									ownerAssociationTypes[i].getRHSUniqueKeyPropertyName(),
-									ownerKey.getIdentifier(),
-									persisters[owner].getIdentifierType(),
-									session.getEntityMode()
-							) );
-						}*/
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Read one collection element from the current row of the JDBC result set
-	 */
-	private void readCollectionElement(
-	        final Object optionalOwner,
-	        final Serializable optionalKey,
-	        final CollectionPersister persister,
-	        final CollectionAliases descriptor,
-	        final ResultSet rs,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-
-		final Serializable collectionRowKey = (Serializable) persister.readKey( 
-				rs, 
-				descriptor.getSuffixedKeyAliases(), 
-				session 
-			);
-		
-		if ( collectionRowKey != null ) {
-			// we found a collection element in the result set
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"found row of collection: " +
-						MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) 
-					);
-			}
-
-			Object owner = optionalOwner;
-			if ( owner == null ) {
-				owner = persistenceContext.getCollectionOwner( collectionRowKey, persister );
-				if ( owner == null ) {
-					//TODO: This is assertion is disabled because there is a bug that means the
-					//	  original owner of a transient, uninitialized collection is not known
-					//	  if the collection is re-referenced by a different object associated
-					//	  with the current Session
-					//throw new AssertionFailure("bug loading unowned collection");
-				}
-			}
-
-			PersistentCollection rowCollection = persistenceContext.getLoadContexts()
-					.getCollectionLoadContext( rs )
-					.getLoadingCollection( persister, collectionRowKey );
-
-			if ( rowCollection != null ) {
-				rowCollection.readFrom( rs, persister, descriptor, owner );
-			}
-
-		}
-		else if ( optionalKey != null ) {
-			// we did not find a collection element in the result set, so we
-			// ensure that a collection is created with the owner's identifier,
-			// since what we have is an empty collection
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"result set contains (possibly empty) collection: " +
-						MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) 
-					);
-			}
-
-			persistenceContext.getLoadContexts()
-					.getCollectionLoadContext( rs )
-					.getLoadingCollection( persister, optionalKey ); // handle empty collection
-
-		}
-
-		// else no collection element, but also no owner
-
-	}
-
-	/**
-	 * If this is a collection initializer, we need to tell the session that a collection
-	 * is being initilized, to account for the possibility of the collection having
-	 * no elements (hence no rows in the result set).
-	 */
-	private void handleEmptyCollections(
-	        final Serializable[] keys,
-	        final Object resultSetId,
-	        final SessionImplementor session) {
-
-		if ( keys != null ) {
-			// this is a collection initializer, so we must create a collection
-			// for each of the passed-in keys, to account for the possibility
-			// that the collection is empty and has no rows in the result set
-
-			CollectionPersister[] collectionPersisters = getCollectionPersisters();
-			for ( int j=0; j<collectionPersisters.length; j++ ) {
-				for ( int i = 0; i < keys.length; i++ ) {
-					//handle empty collections
-	
-					if ( log.isDebugEnabled() ) {
-						log.debug( 
-								"result set contains (possibly empty) collection: " +
-								MessageHelper.collectionInfoString( collectionPersisters[j], keys[i], getFactory() ) 
-							);
-					}
-
-					session.getPersistenceContext()
-							.getLoadContexts()
-							.getCollectionLoadContext( ( ResultSet ) resultSetId )
-							.getLoadingCollection( collectionPersisters[j], keys[i] );
-				}
-			}
-		}
-
-		// else this is not a collection initializer (and empty collections will
-		// be detected by looking for the owner's identifier in the result set)
-	}
-
-	/**
-	 * Read a row of <tt>Key</tt>s from the <tt>ResultSet</tt> into the given array.
-	 * Warning: this method is side-effecty.
-	 * <p/>
-	 * If an <tt>id</tt> is given, don't bother going to the <tt>ResultSet</tt>.
-	 */
-	private EntityKey getKeyFromResultSet(
-	        final int i,
-	        final Loadable persister,
-	        final Serializable id,
-	        final ResultSet rs,
-	        final SessionImplementor session) throws HibernateException, SQLException {
-
-		Serializable resultId;
-
-		// if we know there is exactly 1 row, we can skip.
-		// it would be great if we could _always_ skip this;
-		// it is a problem for <key-many-to-one>
-
-		if ( isSingleRowLoader() && id != null ) {
-			resultId = id;
-		}
-		else {
-			
-			Type idType = persister.getIdentifierType();
-			resultId = (Serializable) idType.nullSafeGet(
-					rs,
-					getEntityAliases()[i].getSuffixedKeyAliases(),
-					session,
-					null //problematic for <key-many-to-one>!
-				);
-			
-			final boolean idIsResultId = id != null && 
-					resultId != null && 
-					idType.isEqual( id, resultId, session.getEntityMode(), factory );
-			
-			if ( idIsResultId ) resultId = id; //use the id passed in
-		}
-
-		return resultId == null ?
-				null :
-				new EntityKey( resultId, persister, session.getEntityMode() );
-	}
-
-	/**
-	 * Check the version of the object in the <tt>ResultSet</tt> against
-	 * the object version in the session cache, throwing an exception
-	 * if the version numbers are different
-	 */
-	private void checkVersion(
-	        final int i,
-	        final Loadable persister,
-	        final Serializable id,
-	        final Object entity,
-	        final ResultSet rs,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		Object version = session.getPersistenceContext().getEntry( entity ).getVersion();
-
-		if ( version != null ) { //null version means the object is in the process of being loaded somewhere else in the ResultSet
-			VersionType versionType = persister.getVersionType();
-			Object currentVersion = versionType.nullSafeGet(
-					rs,
-					getEntityAliases()[i].getSuffixedVersionAliases(),
-					session,
-					null
-				);
-			if ( !versionType.isEqual(version, currentVersion) ) {
-				if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
-					session.getFactory().getStatisticsImplementor()
-							.optimisticFailure( persister.getEntityName() );
-				}
-				throw new StaleObjectStateException( persister.getEntityName(), id );
-			}
-		}
-
-	}
-
-	/**
-	 * Resolve any ids for currently loaded objects, duplications within the
-	 * <tt>ResultSet</tt>, etc. Instantiate empty objects to be initialized from the
-	 * <tt>ResultSet</tt>. Return an array of objects (a row of results) and an
-	 * array of booleans (by side-effect) that determine whether the corresponding
-	 * object should be initialized.
-	 */
-	private Object[] getRow(
-	        final ResultSet rs,
-	        final Loadable[] persisters,
-	        final EntityKey[] keys,
-	        final Object optionalObject,
-	        final EntityKey optionalObjectKey,
-	        final LockMode[] lockModes,
-	        final List hydratedObjects,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		final int cols = persisters.length;
-		final EntityAliases[] descriptors = getEntityAliases();
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( 
-					"result row: " + 
-					StringHelper.toString( keys ) 
-				);
-		}
-
-		final Object[] rowResults = new Object[cols];
-
-		for ( int i = 0; i < cols; i++ ) {
-
-			Object object = null;
-			EntityKey key = keys[i];
-
-			if ( keys[i] == null ) {
-				//do nothing
-			}
-			else {
-
-				//If the object is already loaded, return the loaded one
-				object = session.getEntityUsingInterceptor( key );
-				if ( object != null ) {
-					//its already loaded so don't need to hydrate it
-					instanceAlreadyLoaded( 
-							rs,
-							i,
-							persisters[i],
-							key,
-							object,
-							lockModes[i],
-							session 
-						);
-				}
-				else {
-					object = instanceNotYetLoaded( 
-							rs,
-							i,
-							persisters[i],
-							descriptors[i].getRowIdAlias(),
-							key,
-							lockModes[i],
-							optionalObjectKey,
-							optionalObject,
-							hydratedObjects,
-							session 
-						);
-				}
-
-			}
-
-			rowResults[i] = object;
-
-		}
-
-		return rowResults;
-	}
-
-	/**
-	 * The entity instance is already in the session cache
-	 */
-	private void instanceAlreadyLoaded(
-	        final ResultSet rs,
-	        final int i,
-	        final Loadable persister,
-	        final EntityKey key,
-	        final Object object,
-	        final LockMode lockMode,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		if ( !persister.isInstance( object, session.getEntityMode() ) ) {
-			throw new WrongClassException( 
-					"loaded object was of wrong class " + object.getClass(), 
-					key.getIdentifier(), 
-					persister.getEntityName() 
-				);
-		}
-
-		if ( LockMode.NONE != lockMode && upgradeLocks() ) { //no point doing this if NONE was requested
-
-			final boolean isVersionCheckNeeded = persister.isVersioned() &&
-					session.getPersistenceContext().getEntry(object)
-							.getLockMode().lessThan( lockMode );
-			// we don't need to worry about existing version being uninitialized
-			// because this block isn't called by a re-entrant load (re-entrant
-			// loads _always_ have lock mode NONE)
-			if (isVersionCheckNeeded) {
-				//we only check the version when _upgrading_ lock modes
-				checkVersion( i, persister, key.getIdentifier(), object, rs, session );
-				//we need to upgrade the lock mode to the mode requested
-				session.getPersistenceContext().getEntry(object)
-						.setLockMode(lockMode);
-			}
-		}
-	}
-
-	/**
-	 * The entity instance is not in the session cache
-	 */
-	private Object instanceNotYetLoaded(
-	        final ResultSet rs,
-	        final int i,
-	        final Loadable persister,
-	        final String rowIdAlias,
-	        final EntityKey key,
-	        final LockMode lockMode,
-	        final EntityKey optionalObjectKey,
-	        final Object optionalObject,
-	        final List hydratedObjects,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		final String instanceClass = getInstanceClass( 
-				rs, 
-				i, 
-				persister, 
-				key.getIdentifier(), 
-				session 
-			);
-
-		final Object object;
-		if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) {
-			//its the given optional object
-			object = optionalObject;
-		}
-		else {
-			// instantiate a new instance
-			object = session.instantiate( instanceClass, key.getIdentifier() );
-		}
-
-		//need to hydrate it.
-
-		// grab its state from the ResultSet and keep it in the Session
-		// (but don't yet initialize the object itself)
-		// note that we acquire LockMode.READ even if it was not requested
-		LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode;
-		loadFromResultSet( 
-				rs, 
-				i, 
-				object, 
-				instanceClass, 
-				key, 
-				rowIdAlias, 
-				acquiredLockMode, 
-				persister, 
-				session 
-			);
-
-		//materialize associations (and initialize the object) later
-		hydratedObjects.add( object );
-
-		return object;
-	}
-	
-	private boolean isEagerPropertyFetchEnabled(int i) {
-		boolean[] array = getEntityEagerPropertyFetches();
-		return array!=null && array[i];
-	}
-
-
-	/**
-	 * Hydrate the state an object from the SQL <tt>ResultSet</tt>, into
-	 * an array or "hydrated" values (do not resolve associations yet),
-	 * and pass the hydrates state to the session.
-	 */
-	private void loadFromResultSet(
-	        final ResultSet rs,
-	        final int i,
-	        final Object object,
-	        final String instanceEntityName,
-	        final EntityKey key,
-	        final String rowIdAlias,
-	        final LockMode lockMode,
-	        final Loadable rootPersister,
-	        final SessionImplementor session) 
-	throws SQLException, HibernateException {
-
-		final Serializable id = key.getIdentifier();
-
-		// Get the persister for the _subclass_
-		final Loadable persister = (Loadable) getFactory().getEntityPersister( instanceEntityName );
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( 
-					"Initializing object from ResultSet: " + 
-					MessageHelper.infoString( persister, id, getFactory() ) 
-				);
-		}
-		
-		boolean eagerPropertyFetch = isEagerPropertyFetchEnabled(i);
-
-		// add temp entry so that the next step is circular-reference
-		// safe - only needed because some types don't take proper
-		// advantage of two-phase-load (esp. components)
-		TwoPhaseLoad.addUninitializedEntity( 
-				key, 
-				object, 
-				persister, 
-				lockMode, 
-				!eagerPropertyFetch, 
-				session 
-			);
-
-		//This is not very nice (and quite slow):
-		final String[][] cols = persister == rootPersister ?
-				getEntityAliases()[i].getSuffixedPropertyAliases() :
-				getEntityAliases()[i].getSuffixedPropertyAliases(persister);
-
-		final Object[] values = persister.hydrate( 
-				rs, 
-				id, 
-				object, 
-				rootPersister, 
-				cols, 
-				eagerPropertyFetch, 
-				session 
-			);
-
-		final Object rowId = persister.hasRowId() ? rs.getObject(rowIdAlias) : null;
-
-		final AssociationType[] ownerAssociationTypes = getOwnerAssociationTypes();
-		if ( ownerAssociationTypes != null && ownerAssociationTypes[i] != null ) {
-			String ukName = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName();
-			if (ukName!=null) {
-				final int index = ( (UniqueKeyLoadable) persister ).getPropertyIndex(ukName);
-				final Type type = persister.getPropertyTypes()[index];
-	
-				// polymorphism not really handled completely correctly,
-				// perhaps...well, actually its ok, assuming that the
-				// entity name used in the lookup is the same as the
-				// the one used here, which it will be
-	
-				EntityUniqueKey euk = new EntityUniqueKey( 
-						rootPersister.getEntityName(), //polymorphism comment above
-						ukName,
-						type.semiResolve( values[index], session, object ),
-						type,
-						session.getEntityMode(), session.getFactory()
-					);
-				session.getPersistenceContext().addEntity( euk, object );
-			}
-		}
-
-		TwoPhaseLoad.postHydrate( 
-				persister, 
-				id, 
-				values, 
-				rowId, 
-				object, 
-				lockMode, 
-				!eagerPropertyFetch, 
-				session 
-			);
-
-	}
-
-	/**
-	 * Determine the concrete class of an instance in the <tt>ResultSet</tt>
-	 */
-	private String getInstanceClass(
-	        final ResultSet rs,
-	        final int i,
-	        final Loadable persister,
-	        final Serializable id,
-	        final SessionImplementor session) 
-	throws HibernateException, SQLException {
-
-		if ( persister.hasSubclasses() ) {
-
-			// Code to handle subclasses of topClass
-			Object discriminatorValue = persister.getDiscriminatorType().nullSafeGet(
-					rs,
-					getEntityAliases()[i].getSuffixedDiscriminatorAlias(),
-					session,
-					null
-				);
-
-			final String result = persister.getSubclassForDiscriminatorValue( discriminatorValue );
-
-			if ( result == null ) {
-				//woops we got an instance of another class hierarchy branch
-				throw new WrongClassException( 
-						"Discriminator: " + discriminatorValue,
-						id,
-						persister.getEntityName() 
-					);
-			}
-
-			return result;
-
-		}
-		else {
-			return persister.getEntityName();
-		}
-	}
-
-	/**
-	 * Advance the cursor to the first required row of the <tt>ResultSet</tt>
-	 */
-	private void advance(final ResultSet rs, final RowSelection selection)
-			throws SQLException {
-
-		final int firstRow = getFirstRow( selection );
-		if ( firstRow != 0 ) {
-			if ( getFactory().getSettings().isScrollableResultSetsEnabled() ) {
-				// we can go straight to the first required row
-				rs.absolute( firstRow );
-			}
-			else {
-				// we need to step through the rows one row at a time (slow)
-				for ( int m = 0; m < firstRow; m++ ) rs.next();
-			}
-		}
-	}
-
-	private static boolean hasMaxRows(RowSelection selection) {
-		return selection != null && selection.getMaxRows() != null;
-	}
-
-	private static int getFirstRow(RowSelection selection) {
-		if ( selection == null || selection.getFirstRow() == null ) {
-			return 0;
-		}
-		else {
-			return selection.getFirstRow().intValue();
-		}
-	}
-
-	/**
-	 * Should we pre-process the SQL string, adding a dialect-specific
-	 * LIMIT clause.
-	 */
-	private static boolean useLimit(final RowSelection selection, final Dialect dialect) {
-		return dialect.supportsLimit() && hasMaxRows( selection );
-	}
-
-	/**
-	 * Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
-	 * Bind JDBC-style <tt>?</tt> parameters, named parameters, and
-	 * limit parameters.
-	 */
-	protected final PreparedStatement prepareQueryStatement(
-	        final QueryParameters queryParameters,
-	        final boolean scroll,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-
-		queryParameters.processFilters( getSQLString(), session );
-		String sql = queryParameters.getFilteredSQL();
-		final Dialect dialect = getFactory().getDialect();
-		final RowSelection selection = queryParameters.getRowSelection();
-		boolean useLimit = useLimit( selection, dialect );
-		boolean hasFirstRow = getFirstRow( selection ) > 0;
-		boolean useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
-		boolean callable = queryParameters.isCallable();
-		
-		boolean useScrollableResultSetToSkip = hasFirstRow &&
-				!useOffset &&
-				getFactory().getSettings().isScrollableResultSetsEnabled();
-		ScrollMode scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE;
-
-		if ( useLimit ) {
-			sql = dialect.getLimitString( 
-					sql.trim(), //use of trim() here is ugly?
-					useOffset ? getFirstRow(selection) : 0, 
-					getMaxOrLimit(selection, dialect) 
-				);
-		}
-
-		sql = preprocessSQL( sql, queryParameters, dialect );
-		
-		PreparedStatement st = null;
-		
-		if (callable) {
-			st = session.getBatcher()
-				.prepareCallableQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
-		} 
-		else {
-			st = session.getBatcher()
-				.prepareQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
-		}
-				
-
-		try {
-
-			int col = 1;
-			//TODO: can we limit stored procedures ?!
-			if ( useLimit && dialect.bindLimitParametersFirst() ) {
-				col += bindLimitParameters( st, col, selection );
-			}
-			if (callable) {
-				col = dialect.registerResultSetOutParameter( (CallableStatement)st, col );
-			}
-
-			col += bindParameterValues( st, queryParameters, col, session );
-
-			if ( useLimit && !dialect.bindLimitParametersFirst() ) {
-				col += bindLimitParameters( st, col, selection );
-			}
-
-			if ( !useLimit ) {
-				setMaxRows( st, selection );
-			}
-
-			if ( selection != null ) {
-				if ( selection.getTimeout() != null ) {
-					st.setQueryTimeout( selection.getTimeout().intValue() );
-				}
-				if ( selection.getFetchSize() != null ) {
-					st.setFetchSize( selection.getFetchSize().intValue() );
-				}
-			}
-		}
-		catch ( SQLException sqle ) {
-			session.getBatcher().closeQueryStatement( st, null );
-			throw sqle;
-		}
-		catch ( HibernateException he ) {
-			session.getBatcher().closeQueryStatement( st, null );
-			throw he;
-		}
-
-		return st;
-	}
-
-	/**
-	 * Some dialect-specific LIMIT clauses require the maximium last row number
-	 * (aka, first_row_number + total_row_count), while others require the maximum
-	 * returned row count (the total maximum number of rows to return).
-	 *
-	 * @param selection The selection criteria
-	 * @param dialect The dialect
-	 * @return The appropriate value to bind into the limit clause.
-	 */
-	private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
-		final int firstRow = getFirstRow( selection );
-		final int lastRow = selection.getMaxRows().intValue();
-		if ( dialect.useMaxForLimit() ) {
-			return lastRow + firstRow;
-		}
-		else {
-			return lastRow;
-		}
-	}
-
-	/**
-	 * Bind parameter values needed by the dialect-specific LIMIT clause.
-	 *
-	 * @param statement The statement to which to bind limit param values.
-	 * @param index The bind position from which to start binding
-	 * @param selection The selection object containing the limit information.
-	 * @return The number of parameter values bound.
-	 * @throws java.sql.SQLException Indicates problems binding parameter values.
-	 */
-	private int bindLimitParameters(
-			final PreparedStatement statement,
-			final int index,
-			final RowSelection selection) throws SQLException {
-		Dialect dialect = getFactory().getDialect();
-		if ( !dialect.supportsVariableLimit() ) {
-			return 0;
-		}
-		if ( !hasMaxRows( selection ) ) {
-			throw new AssertionFailure( "no max results set" );
-		}
-		int firstRow = getFirstRow( selection );
-		int lastRow = getMaxOrLimit( selection, dialect );
-		boolean hasFirstRow = firstRow > 0 && dialect.supportsLimitOffset();
-		boolean reverse = dialect.bindLimitParametersInReverseOrder();
-		if ( hasFirstRow ) {
-			statement.setInt( index + ( reverse ? 1 : 0 ), firstRow );
-		}
-		statement.setInt( index + ( reverse || !hasFirstRow ? 0 : 1 ), lastRow );
-		return hasFirstRow ? 2 : 1;
-	}
-
-	/**
-	 * Use JDBC API to limit the number of rows returned by the SQL query if necessary
-	 */
-	private void setMaxRows(
-			final PreparedStatement st,
-			final RowSelection selection) throws SQLException {
-		if ( hasMaxRows( selection ) ) {
-			st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
-		}
-	}
-
-	/**
-	 * Bind all parameter values into the prepared statement in preparation
-	 * for execution.
-	 *
-	 * @param statement The JDBC prepared statement
-	 * @param queryParameters The encapsulation of the parameter values to be bound.
-	 * @param startIndex The position from which to start binding parameter values.
-	 * @param session The originating session.
-	 * @return The number of JDBC bind positions actually bound during this method execution.
-	 * @throws SQLException Indicates problems performing the binding.
-	 */
-	protected int bindParameterValues(
-			PreparedStatement statement,
-			QueryParameters queryParameters,
-			int startIndex,
-			SessionImplementor session) throws SQLException {
-		int span = 0;
-		span += bindPositionalParameters( statement, queryParameters, startIndex, session );
-		span += bindNamedParameters( statement, queryParameters.getNamedParameters(), startIndex + span, session );
-		return span;
-	}
-
-	/**
-	 * Bind positional parameter values to the JDBC prepared statement.
-	 * <p/>
-	 * Postional parameters are those specified by JDBC-style ? parameters
-	 * in the source query.  It is (currently) expected that these come
-	 * before any named parameters in the source query.
-	 *
-	 * @param statement The JDBC prepared statement
-	 * @param queryParameters The encapsulation of the parameter values to be bound.
-	 * @param startIndex The position from which to start binding parameter values.
-	 * @param session The originating session.
-	 * @return The number of JDBC bind positions actually bound during this method execution.
-	 * @throws SQLException Indicates problems performing the binding.
-	 * @throws org.hibernate.HibernateException Indicates problems delegating binding to the types.
-	 */
-	protected int bindPositionalParameters(
-	        final PreparedStatement statement,
-	        final QueryParameters queryParameters,
-	        final int startIndex,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-		final Object[] values = queryParameters.getFilteredPositionalParameterValues();
-		final Type[] types = queryParameters.getFilteredPositionalParameterTypes();
-		int span = 0;
-		for ( int i = 0; i < values.length; i++ ) {
-			types[i].nullSafeSet( statement, values[i], startIndex + span, session );
-			span += types[i].getColumnSpan( getFactory() );
-		}
-		return span;
-	}
-
-	/**
-	 * Bind named parameters to the JDBC prepared statement.
-	 * <p/>
-	 * This is a generic implementation, the problem being that in the
-	 * general case we do not know enough information about the named
-	 * parameters to perform this in a complete manner here.  Thus this
-	 * is generally overridden on subclasses allowing named parameters to
-	 * apply the specific behavior.  The most usual limitation here is that
-	 * we need to assume the type span is always one...
-	 *
-	 * @param statement The JDBC prepared statement
-	 * @param namedParams A map of parameter names to values
-	 * @param startIndex The position from which to start binding parameter values.
-	 * @param session The originating session.
-	 * @return The number of JDBC bind positions actually bound during this method execution.
-	 * @throws SQLException Indicates problems performing the binding.
-	 * @throws org.hibernate.HibernateException Indicates problems delegating binding to the types.
-	 */
-	protected int bindNamedParameters(
-			final PreparedStatement statement,
-			final Map namedParams,
-			final int startIndex,
-			final SessionImplementor session) throws SQLException, HibernateException {
-		if ( namedParams != null ) {
-			// assumes that types are all of span 1
-			Iterator iter = namedParams.entrySet().iterator();
-			int result = 0;
-			while ( iter.hasNext() ) {
-				Map.Entry e = ( Map.Entry ) iter.next();
-				String name = ( String ) e.getKey();
-				TypedValue typedval = ( TypedValue ) e.getValue();
-				int[] locs = getNamedParameterLocs( name );
-				for ( int i = 0; i < locs.length; i++ ) {
-					if ( log.isDebugEnabled() ) {
-						log.debug(
-								"bindNamedParameters() " +
-								typedval.getValue() + " -> " + name +
-								" [" + ( locs[i] + startIndex ) + "]"
-							);
-					}
-					typedval.getType().nullSafeSet( statement, typedval.getValue(), locs[i] + startIndex, session );
-				}
-				result += locs.length;
-			}
-			return result;
-		}
-		else {
-			return 0;
-		}
-	}
-
-	public int[] getNamedParameterLocs(String name) {
-		throw new AssertionFailure("no named parameters");
-	}
-
-	/**
-	 * Fetch a <tt>PreparedStatement</tt>, call <tt>setMaxRows</tt> and then execute it,
-	 * advance to the first result and return an SQL <tt>ResultSet</tt>
-	 */
-	protected final ResultSet getResultSet(
-	        final PreparedStatement st,
-	        final boolean autodiscovertypes,
-	        final boolean callable,
-	        final RowSelection selection,
-	        final SessionImplementor session) 
-	throws SQLException, HibernateException {
-	
-		ResultSet rs = null;
-		try {
-			Dialect dialect = getFactory().getDialect();
-			if (callable) {
-				rs = session.getBatcher().getResultSet( (CallableStatement) st, dialect );
-			} 
-			else {
-				rs = session.getBatcher().getResultSet( st );
-			}
-			rs = wrapResultSetIfEnabled( rs , session );
-			
-			if ( !dialect.supportsLimitOffset() || !useLimit( selection, dialect ) ) {
-				advance( rs, selection );
-			}
-			
-			if ( autodiscovertypes ) {
-				autoDiscoverTypes( rs );
-			}
-			return rs;
-		}
-		catch ( SQLException sqle ) {
-			session.getBatcher().closeQueryStatement( st, rs );
-			throw sqle;
-		}
-	}
-
-	protected void autoDiscoverTypes(ResultSet rs) {
-		throw new AssertionFailure("Auto discover types not supported in this loader");
-		
-	}
-
-	private synchronized ResultSet wrapResultSetIfEnabled(final ResultSet rs, final SessionImplementor session) {
-		// synchronized to avoid multi-thread access issues; defined as method synch to avoid
-		// potential deadlock issues due to nature of code.
-		if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) {
-			try {
-				log.debug("Wrapping result set [" + rs + "]");
-				return new ResultSetWrapper( rs, retreiveColumnNameToIndexCache( rs ) );
-			}
-			catch(SQLException e) {
-				log.info("Error wrapping result set", e);
-				return rs;
-			}
-		}
-		else {
-			return rs;
-		}
-	}
-
-	private ColumnNameCache retreiveColumnNameToIndexCache(ResultSet rs) throws SQLException {
-		if ( columnNameCache == null ) {
-			log.trace("Building columnName->columnIndex cache");
-			columnNameCache = new ColumnNameCache( rs.getMetaData().getColumnCount() );
-		}
-
-		return columnNameCache;
-	}
-
-	/**
-	 * Called by subclasses that load entities
-	 * @param persister only needed for logging
-	 */
-	protected final List loadEntity(
-	        final SessionImplementor session,
-	        final Object id,
-	        final Type identifierType,
-	        final Object optionalObject,
-	        final String optionalEntityName,
-	        final Serializable optionalIdentifier,
-	        final EntityPersister persister) throws HibernateException {
-		
-		if ( log.isDebugEnabled() ) {
-			log.debug( 
-					"loading entity: " + 
-					MessageHelper.infoString( persister, id, identifierType, getFactory() ) 
-				);
-		}
-
-		List result;
-		try {
-			result = doQueryAndInitializeNonLazyCollections( 
-					session,
-					new QueryParameters( 
-							new Type[] { identifierType },
-							new Object[] { id },
-							optionalObject,
-							optionalEntityName,
-							optionalIdentifier 
-						),
-					false 
-				);
-		}
-		catch ( SQLException sqle ) {
-			final Loadable[] persisters = getEntityPersisters();
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not load an entity: " + 
-			        MessageHelper.infoString( persisters[persisters.length-1], id, identifierType, getFactory() ),
-			        getSQLString()
-				);
-		}
-
-		log.debug("done entity load");
-		
-		return result;
-		
-	}
-
-	/**
-	 * Called by subclasses that load entities
-	 * @param persister only needed for logging
-	 */
-	protected final List loadEntity(
-	        final SessionImplementor session,
-	        final Object key,
-	        final Object index,
-	        final Type keyType,
-	        final Type indexType,
-	        final EntityPersister persister) throws HibernateException {
-		
-		if ( log.isDebugEnabled() ) {
-			log.debug( "loading collection element by index" );
-		}
-
-		List result;
-		try {
-			result = doQueryAndInitializeNonLazyCollections( 
-					session,
-					new QueryParameters( 
-							new Type[] { keyType, indexType },
-							new Object[] { key, index }
-						),
-					false 
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not collection element by index",
-			        getSQLString()
-				);
-		}
-
-		log.debug("done entity load");
-		
-		return result;
-		
-	}
-
-	/**
-	 * Called by wrappers that batch load entities
-	 * @param persister only needed for logging
-	 */
-	public final List loadEntityBatch(
-	        final SessionImplementor session,
-	        final Serializable[] ids,
-	        final Type idType,
-	        final Object optionalObject,
-	        final String optionalEntityName,
-	        final Serializable optionalId,
-	        final EntityPersister persister) throws HibernateException {
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( 
-					"batch loading entity: " + 
-					MessageHelper.infoString(persister, ids, getFactory() ) 
-				);
-		}
-
-		Type[] types = new Type[ids.length];
-		Arrays.fill( types, idType );
-		List result;
-		try {
-			result = doQueryAndInitializeNonLazyCollections( 
-					session,
-					new QueryParameters( types, ids, optionalObject, optionalEntityName, optionalId ),
-					false 
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not load an entity batch: " + 
-			        MessageHelper.infoString( getEntityPersisters()[0], ids, getFactory() ),
-			        getSQLString()
-				);
-		}
-
-		log.debug("done entity batch load");
-		
-		return result;
-
-	}
-
-	/**
-	 * Called by subclasses that initialize collections
-	 */
-	public final void loadCollection(
-	        final SessionImplementor session,
-	        final Serializable id,
-	        final Type type) throws HibernateException {
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( 
-					"loading collection: "+ 
-					MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() )
-				);
-		}
-
-		Serializable[] ids = new Serializable[]{id};
-		try {
-			doQueryAndInitializeNonLazyCollections( 
-					session,
-					new QueryParameters( new Type[]{type}, ids, ids ),
-					true 
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					factory.getSQLExceptionConverter(),
-					sqle,
-					"could not initialize a collection: " + 
-					MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() ),
-					getSQLString()
-				);
-		}
-	
-		log.debug("done loading collection");
-
-	}
-
-	/**
-	 * Called by wrappers that batch initialize collections
-	 */
-	public final void loadCollectionBatch(
-	        final SessionImplementor session,
-	        final Serializable[] ids,
-	        final Type type) throws HibernateException {
-
-		if ( log.isDebugEnabled() ) {
-			log.debug( 
-					"batch loading collection: "+ 
-					MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() )
-				);
-		}
-
-		Type[] idTypes = new Type[ids.length];
-		Arrays.fill( idTypes, type );
-		try {
-			doQueryAndInitializeNonLazyCollections( 
-					session,
-					new QueryParameters( idTypes, ids, ids ),
-					true 
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not initialize a collection batch: " + 
-			        MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ),
-			        getSQLString()
-				);
-		}
-		
-		log.debug("done batch load");
-
-	}
-
-	/**
-	 * Called by subclasses that batch initialize collections
-	 */
-	protected final void loadCollectionSubselect(
-	        final SessionImplementor session,
-	        final Serializable[] ids,
-	        final Object[] parameterValues,
-	        final Type[] parameterTypes,
-	        final Map namedParameters,
-	        final Type type) throws HibernateException {
-
-		Type[] idTypes = new Type[ids.length];
-		Arrays.fill( idTypes, type );
-		try {
-			doQueryAndInitializeNonLazyCollections( session,
-					new QueryParameters( parameterTypes, parameterValues, namedParameters, ids ),
-					true 
-				);
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not load collection by subselect: " + 
-			        MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ),
-			        getSQLString()
-				);
-		}
-	}
-
-	/**
-	 * Return the query results, using the query cache, called
-	 * by subclasses that implement cacheable queries
-	 */
-	protected List list(
-	        final SessionImplementor session,
-	        final QueryParameters queryParameters,
-	        final Set querySpaces,
-	        final Type[] resultTypes) throws HibernateException {
-
-		final boolean cacheable = factory.getSettings().isQueryCacheEnabled() && 
-			queryParameters.isCacheable();
-
-		if ( cacheable ) {
-			return listUsingQueryCache( session, queryParameters, querySpaces, resultTypes );
-		}
-		else {
-			return listIgnoreQueryCache( session, queryParameters );
-		}
-	}
-
-	private List listIgnoreQueryCache(SessionImplementor session, QueryParameters queryParameters) {
-		return getResultList( doList( session, queryParameters ), queryParameters.getResultTransformer() );
-	}
-
-	private List listUsingQueryCache(
-			final SessionImplementor session, 
-			final QueryParameters queryParameters, 
-			final Set querySpaces, 
-			final Type[] resultTypes) {
-	
-		QueryCache queryCache = factory.getQueryCache( queryParameters.getCacheRegion() );
-		
-		Set filterKeys = FilterKey.createFilterKeys( 
-				session.getEnabledFilters(), 
-				session.getEntityMode() 
-			);
-		QueryKey key = new QueryKey( 
-				getSQLString(), 
-				queryParameters, 
-				filterKeys, 
-				session.getEntityMode() 
-			);
-		
-		List result = getResultFromQueryCache( 
-				session, 
-				queryParameters, 
-				querySpaces, 
-				resultTypes, 
-				queryCache, 
-				key 
-			);
-
-		if ( result == null ) {
-			result = doList( session, queryParameters );
-
-			putResultInQueryCache( 
-					session, 
-					queryParameters, 
-					resultTypes,
-					queryCache, 
-					key, 
-					result 
-				);
-		}
-
-		return getResultList( result, queryParameters.getResultTransformer() );
-	}
-
-	private List getResultFromQueryCache(
-			final SessionImplementor session,
-			final QueryParameters queryParameters,
-			final Set querySpaces,
-			final Type[] resultTypes,
-			final QueryCache queryCache,
-			final QueryKey key) {
-		List result = null;
-
-		if ( session.getCacheMode().isGetEnabled() ) {
-			boolean isImmutableNaturalKeyLookup = queryParameters.isNaturalKeyLookup()
-					&& getEntityPersisters()[0].getEntityMetamodel().hasImmutableNaturalId();
-			result = queryCache.get( key, resultTypes, isImmutableNaturalKeyLookup, querySpaces, session );
-			if ( factory.getStatistics().isStatisticsEnabled() ) {
-				if ( result == null ) {
-					factory.getStatisticsImplementor()
-							.queryCacheMiss( getQueryIdentifier(), queryCache.getRegion().getName() );
-				}
-				else {
-					factory.getStatisticsImplementor()
-							.queryCacheHit( getQueryIdentifier(), queryCache.getRegion().getName() );
-				}
-			}
-		}
-
-		return result;
-	}
-
-	private void putResultInQueryCache(
-			final SessionImplementor session,
-			final QueryParameters queryParameters,
-			final Type[] resultTypes,
-			final QueryCache queryCache,
-			final QueryKey key,
-			final List result) {
-		if ( session.getCacheMode().isPutEnabled() ) {
-			boolean put = queryCache.put( key, resultTypes, result, queryParameters.isNaturalKeyLookup(), session );
-			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
-				factory.getStatisticsImplementor()
-						.queryCachePut( getQueryIdentifier(), queryCache.getRegion().getName() );
-			}
-		}
-	}
-
-	/**
-	 * Actually execute a query, ignoring the query cache
-	 */
-	protected List doList(final SessionImplementor session, final QueryParameters queryParameters)
-			throws HibernateException {
-
-		final boolean stats = getFactory().getStatistics().isStatisticsEnabled();
-		long startTime = 0;
-		if ( stats ) startTime = System.currentTimeMillis();
-
-		List result;
-		try {
-			result = doQueryAndInitializeNonLazyCollections( session, queryParameters, true );
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not execute query",
-			        getSQLString()
-				);
-		}
-
-		if ( stats ) {
-			getFactory().getStatisticsImplementor().queryExecuted(
-					getQueryIdentifier(),
-					result.size(),
-					System.currentTimeMillis() - startTime
-				);
-		}
-
-		return result;
-	}
-
-	/**
-	 * Check whether the current loader can support returning ScrollableResults.
-	 *
-	 * @throws HibernateException
-	 */
-	protected void checkScrollability() throws HibernateException {
-		// Allows various loaders (ok mainly the QueryLoader :) to check
-		// whether scrolling of their result set should be allowed.
-		//
-		// By default it is allowed.
-		return;
-	}
-
-	/**
-	 * Does the result set to be scrolled contain collection fetches?
-	 *
-	 * @return True if it does, and thus needs the special fetching scroll
-	 * functionality; false otherwise.
-	 */
-	protected boolean needsFetchingScroll() {
-		return false;
-	}
-
-	/**
-	 * Return the query results, as an instance of <tt>ScrollableResults</tt>
-	 *
-	 * @param queryParameters The parameters with which the query should be executed.
-	 * @param returnTypes The expected return types of the query
-	 * @param holderInstantiator If the return values are expected to be wrapped
-	 * in a holder, this is the thing that knows how to wrap them.
-	 * @param session The session from which the scroll request originated.
-	 * @return The ScrollableResults instance.
-	 * @throws HibernateException Indicates an error executing the query, or constructing
-	 * the ScrollableResults.
-	 */
-	protected ScrollableResults scroll(
-	        final QueryParameters queryParameters,
-	        final Type[] returnTypes,
-	        final HolderInstantiator holderInstantiator,
-	        final SessionImplementor session) throws HibernateException {
-
-		checkScrollability();
-
-		final boolean stats = getQueryIdentifier() != null &&
-				getFactory().getStatistics().isStatisticsEnabled();
-		long startTime = 0;
-		if ( stats ) startTime = System.currentTimeMillis();
-
-		try {
-
-			PreparedStatement st = prepareQueryStatement( queryParameters, true, session );
-			ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), queryParameters.getRowSelection(), session);
-
-			if ( stats ) {
-				getFactory().getStatisticsImplementor().queryExecuted(
-						getQueryIdentifier(),
-						0,
-						System.currentTimeMillis() - startTime
-					);
-			}
-
-			if ( needsFetchingScroll() ) {
-				return new FetchingScrollableResultsImpl(
-						rs,
-						st,
-						session,
-						this,
-						queryParameters,
-						returnTypes,
-						holderInstantiator
-					);
-			}
-			else {
-				return new ScrollableResultsImpl(
-						rs,
-						st,
-						session,
-						this,
-						queryParameters,
-						returnTypes,
-						holderInstantiator
-					);
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        factory.getSQLExceptionConverter(),
-			        sqle,
-			        "could not execute query using scroll",
-			        getSQLString()
-				);
-		}
-
-	}
-
-	/**
-	 * Calculate and cache select-clause suffixes. Must be
-	 * called by subclasses after instantiation.
-	 */
-	protected void postInstantiate() {}
-
-	/**
-	 * Get the result set descriptor
-	 */
-	protected abstract EntityAliases[] getEntityAliases();
-
-	protected abstract CollectionAliases[] getCollectionAliases();
-
-	/**
-	 * Identifies the query for statistics reporting, if null,
-	 * no statistics will be reported
-	 */
-	protected String getQueryIdentifier() {
-		return null;
-	}
-
-	public final SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getSQLString() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/Loader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/Loader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,2375 @@
+/*
+ * 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.loader;
+
+import java.io.Serializable;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.WrongClassException;
+import org.hibernate.cache.FilterKey;
+import org.hibernate.cache.QueryCache;
+import org.hibernate.cache.QueryKey;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.EntityUniqueKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SubselectFetch;
+import org.hibernate.engine.TwoPhaseLoad;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.event.EventSource;
+import org.hibernate.event.PostLoadEvent;
+import org.hibernate.event.PreLoadEvent;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.impl.FetchingScrollableResultsImpl;
+import org.hibernate.impl.ScrollableResultsImpl;
+import org.hibernate.jdbc.ColumnNameCache;
+import org.hibernate.jdbc.ResultSetWrapper;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.UniqueKeyLoadable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.VersionType;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Abstract superclass of object loading (and querying) strategies. This class implements
+ * useful common functionality that concrete loaders delegate to. It is not intended that this
+ * functionality would be directly accessed by client code. (Hence, all methods of this class
+ * are declared <tt>protected</tt> or <tt>private</tt>.) This class relies heavily upon the
+ * <tt>Loadable</tt> interface, which is the contract between this class and
+ * <tt>EntityPersister</tt>s that may be loaded by it.<br>
+ * <br>
+ * The present implementation is able to load any number of columns of entities and at most
+ * one collection role per query.
+ *
+ * @author Gavin King
+ * @see org.hibernate.persister.entity.Loadable
+ */
+public abstract class Loader {
+
+	private static final Logger log = LoggerFactory.getLogger( Loader.class );
+
+	private final SessionFactoryImplementor factory;
+	private ColumnNameCache columnNameCache;
+
+	public Loader(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+	/**
+	 * The SQL query string to be called; implemented by all subclasses
+	 *
+	 * @return The sql command this loader should use to get its {@link ResultSet}.
+	 */
+	protected abstract String getSQLString();
+
+	/**
+	 * An array of persisters of entity classes contained in each row of results;
+	 * implemented by all subclasses
+	 *
+	 * @return The entity persisters.
+	 */
+	protected abstract Loadable[] getEntityPersisters();
+	
+	/**
+	 * An array indicating whether the entities have eager property fetching
+	 * enabled.
+	 *
+	 * @return Eager property fetching indicators.
+	 */
+	protected boolean[] getEntityEagerPropertyFetches() {
+		return null;
+	}
+
+	/**
+	 * An array of indexes of the entity that owns a one-to-one association
+	 * to the entity at the given index (-1 if there is no "owner").  The
+	 * indexes contained here are relative to the result of
+	 * {@link #getEntityPersisters}.
+	 *
+	 * @return The owner indicators (see discussion above).
+	 */
+	protected int[] getOwners() {
+		return null;
+	}
+
+	/**
+	 * An array of the owner types corresponding to the {@link #getOwners()}
+	 * returns.  Indices indicating no owner would be null here.
+	 *
+	 * @return The types for the owners.
+	 */
+	protected EntityType[] getOwnerAssociationTypes() {
+		return null;
+	}
+
+	/**
+	 * An (optional) persister for a collection to be initialized; only 
+	 * collection loaders return a non-null value
+	 */
+	protected CollectionPersister[] getCollectionPersisters() {
+		return null;
+	}
+
+	/**
+	 * Get the index of the entity that owns the collection, or -1
+	 * if there is no owner in the query results (ie. in the case of a
+	 * collection initializer) or no collection.
+	 */
+	protected int[] getCollectionOwners() {
+		return null;
+	}
+
+	/**
+	 * What lock mode does this load entities with?
+	 *
+	 * @param lockModes a collection of lock modes specified dynamically via the Query interface
+	 */
+	protected abstract LockMode[] getLockModes(Map lockModes);
+
+	/**
+	 * Append <tt>FOR UPDATE OF</tt> clause, if necessary. This
+	 * empty superclass implementation merely returns its first
+	 * argument.
+	 */
+	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws HibernateException {
+		return sql;
+	}
+
+	/**
+	 * Does this query return objects that might be already cached
+	 * by the session, whose lock mode may need upgrading
+	 */
+	protected boolean upgradeLocks() {
+		return false;
+	}
+
+	/**
+	 * Return false is this loader is a batch entity loader
+	 */
+	protected boolean isSingleRowLoader() {
+		return false;
+	}
+
+	/**
+	 * Get the SQL table aliases of entities whose
+	 * associations are subselect-loadable, returning
+	 * null if this loader does not support subselect
+	 * loading
+	 */
+	protected String[] getAliases() {
+		return null;
+	}
+
+	/**
+	 * Modify the SQL, adding lock hints and comments, if necessary
+	 */
+	protected String preprocessSQL(String sql, QueryParameters parameters, Dialect dialect)
+			throws HibernateException {
+		
+		sql = applyLocks( sql, parameters.getLockModes(), dialect );
+		
+		return getFactory().getSettings().isCommentsEnabled() ?
+				prependComment( sql, parameters ) : sql;
+	}
+
+	private String prependComment(String sql, QueryParameters parameters) {
+		String comment = parameters.getComment();
+		if ( comment == null ) {
+			return sql;
+		}
+		else {
+			return new StringBuffer( comment.length() + sql.length() + 5 )
+					.append( "/* " )
+					.append( comment )
+					.append( " */ " )
+					.append( sql )
+					.toString();
+		}
+	}
+
+	/**
+	 * Execute an SQL query and attempt to instantiate instances of the class mapped by the given
+	 * persister from each row of the <tt>ResultSet</tt>. If an object is supplied, will attempt to
+	 * initialize that object. If a collection is supplied, attempt to initialize that collection.
+	 */
+	private List doQueryAndInitializeNonLazyCollections(final SessionImplementor session,
+														final QueryParameters queryParameters,
+														final boolean returnProxies) 
+		throws HibernateException, SQLException {
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		persistenceContext.beforeLoad();
+		List result;
+		try {
+			result = doQuery( session, queryParameters, returnProxies );
+		}
+		finally {
+			persistenceContext.afterLoad();
+		}
+		persistenceContext.initializeNonLazyCollections();
+		return result;
+	}
+
+	/**
+	 * Loads a single row from the result set.  This is the processing used from the
+	 * ScrollableResults where no collection fetches were encountered.
+	 *
+	 * @param resultSet The result set from which to do the load.
+	 * @param session The session from which the request originated.
+	 * @param queryParameters The query parameters specified by the user.
+	 * @param returnProxies Should proxies be generated
+	 * @return The loaded "row".
+	 * @throws HibernateException
+	 */
+	public Object loadSingleRow(
+	        final ResultSet resultSet,
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final boolean returnProxies) throws HibernateException {
+
+		final int entitySpan = getEntityPersisters().length;
+		final List hydratedObjects = entitySpan == 0 ? 
+				null : new ArrayList( entitySpan );
+
+		final Object result;
+		try {
+			result = getRowFromResultSet(
+			        resultSet,
+					session,
+					queryParameters,
+					getLockModes( queryParameters.getLockModes() ),
+					null,
+					hydratedObjects,
+					new EntityKey[entitySpan],
+					returnProxies
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not read next row of results",
+			        getSQLString()
+				);
+		}
+
+		initializeEntitiesAndCollections( 
+				hydratedObjects, 
+				resultSet, 
+				session, 
+				queryParameters.isReadOnly() 
+			);
+		session.getPersistenceContext().initializeNonLazyCollections();
+		return result;
+	}
+
+	private Object sequentialLoad(
+	        final ResultSet resultSet,
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final boolean returnProxies,
+	        final EntityKey keyToRead) throws HibernateException {
+
+		final int entitySpan = getEntityPersisters().length;
+		final List hydratedObjects = entitySpan == 0 ? 
+				null : new ArrayList( entitySpan );
+
+		Object result = null;
+		final EntityKey[] loadedKeys = new EntityKey[entitySpan];
+
+		try {
+			do {
+				Object loaded = getRowFromResultSet(
+						resultSet,
+						session,
+						queryParameters,
+						getLockModes( queryParameters.getLockModes() ),
+						null,
+						hydratedObjects,
+						loadedKeys,
+						returnProxies
+					);
+				if ( result == null ) {
+					result = loaded;
+				}
+			} 
+			while ( keyToRead.equals( loadedKeys[0] ) && resultSet.next() );
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not perform sequential read of results (forward)",
+			        getSQLString()
+				);
+		}
+
+		initializeEntitiesAndCollections( 
+				hydratedObjects, 
+				resultSet, 
+				session, 
+				queryParameters.isReadOnly() 
+			);
+		session.getPersistenceContext().initializeNonLazyCollections();
+		return result;
+	}
+
+	/**
+	 * Loads a single logical row from the result set moving forward.  This is the
+	 * processing used from the ScrollableResults where there were collection fetches
+	 * encountered; thus a single logical row may have multiple rows in the underlying
+	 * result set.
+	 *
+	 * @param resultSet The result set from which to do the load.
+	 * @param session The session from which the request originated.
+	 * @param queryParameters The query parameters specified by the user.
+	 * @param returnProxies Should proxies be generated
+	 * @return The loaded "row".
+	 * @throws HibernateException
+	 */
+	public Object loadSequentialRowsForward(
+	        final ResultSet resultSet,
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final boolean returnProxies) throws HibernateException {
+
+		// note that for sequential scrolling, we make the assumption that
+		// the first persister element is the "root entity"
+
+		try {
+			if ( resultSet.isAfterLast() ) {
+				// don't even bother trying to read further
+				return null;
+			}
+
+			if ( resultSet.isBeforeFirst() ) {
+				resultSet.next();
+			}
+
+			// We call getKeyFromResultSet() here so that we can know the
+			// key value upon which to perform the breaking logic.  However,
+			// it is also then called from getRowFromResultSet() which is certainly
+			// not the most efficient.  But the call here is needed, and there
+			// currently is no other way without refactoring of the doQuery()/getRowFromResultSet()
+			// methods
+			final EntityKey currentKey = getKeyFromResultSet(
+					0,
+					getEntityPersisters()[0],
+					null,
+					resultSet,
+					session
+				);
+
+			return sequentialLoad( resultSet, session, queryParameters, returnProxies, currentKey );
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not perform sequential read of results (forward)",
+			        getSQLString()
+				);
+		}
+	}
+
+	/**
+	 * Loads a single logical row from the result set moving forward.  This is the
+	 * processing used from the ScrollableResults where there were collection fetches
+	 * encountered; thus a single logical row may have multiple rows in the underlying
+	 * result set.
+	 *
+	 * @param resultSet The result set from which to do the load.
+	 * @param session The session from which the request originated.
+	 * @param queryParameters The query parameters specified by the user.
+	 * @param returnProxies Should proxies be generated
+	 * @return The loaded "row".
+	 * @throws HibernateException
+	 */
+	public Object loadSequentialRowsReverse(
+	        final ResultSet resultSet,
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final boolean returnProxies,
+	        final boolean isLogicallyAfterLast) throws HibernateException {
+
+		// note that for sequential scrolling, we make the assumption that
+		// the first persister element is the "root entity"
+
+		try {
+			if ( resultSet.isFirst() ) {
+				// don't even bother trying to read any further
+				return null;
+			}
+
+			EntityKey keyToRead = null;
+			// This check is needed since processing leaves the cursor
+			// after the last physical row for the current logical row;
+			// thus if we are after the last physical row, this might be
+			// caused by either:
+			//      1) scrolling to the last logical row
+			//      2) scrolling past the last logical row
+			// In the latter scenario, the previous logical row
+			// really is the last logical row.
+			//
+			// In all other cases, we should process back two
+			// logical records (the current logic row, plus the
+			// previous logical row).
+			if ( resultSet.isAfterLast() && isLogicallyAfterLast ) {
+				// position cursor to the last row
+				resultSet.last();
+				keyToRead = getKeyFromResultSet(
+						0,
+						getEntityPersisters()[0],
+						null,
+						resultSet,
+						session
+					);
+			}
+			else {
+				// Since the result set cursor is always left at the first
+				// physical row after the "last processed", we need to jump
+				// back one position to get the key value we are interested
+				// in skipping
+				resultSet.previous();
+
+				// sequentially read the result set in reverse until we recognize
+				// a change in the key value.  At that point, we are pointed at
+				// the last physical sequential row for the logical row in which
+				// we are interested in processing
+				boolean firstPass = true;
+				final EntityKey lastKey = getKeyFromResultSet(
+						0,
+						getEntityPersisters()[0],
+						null,
+						resultSet,
+						session
+					);
+				while ( resultSet.previous() ) {
+					EntityKey checkKey = getKeyFromResultSet(
+							0,
+							getEntityPersisters()[0],
+							null,
+							resultSet,
+							session
+						);
+
+					if ( firstPass ) {
+						firstPass = false;
+						keyToRead = checkKey;
+					}
+
+					if ( !lastKey.equals( checkKey ) ) {
+						break;
+					}
+				}
+
+			}
+
+			// Read backwards until we read past the first physical sequential
+			// row with the key we are interested in loading
+			while ( resultSet.previous() ) {
+				EntityKey checkKey = getKeyFromResultSet(
+						0,
+						getEntityPersisters()[0],
+						null,
+						resultSet,
+						session
+					);
+
+				if ( !keyToRead.equals( checkKey ) ) {
+					break;
+				}
+			}
+
+			// Finally, read ahead one row to position result set cursor
+			// at the first physical row we are interested in loading
+			resultSet.next();
+
+			// and perform the load
+			return sequentialLoad( resultSet, session, queryParameters, returnProxies, keyToRead );
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not perform sequential read of results (forward)",
+			        getSQLString()
+				);
+		}
+	}
+
+	private static EntityKey getOptionalObjectKey(QueryParameters queryParameters, SessionImplementor session) {
+		final Object optionalObject = queryParameters.getOptionalObject();
+		final Serializable optionalId = queryParameters.getOptionalId();
+		final String optionalEntityName = queryParameters.getOptionalEntityName();
+
+		if ( optionalObject != null && optionalEntityName != null ) {
+			return new EntityKey( 
+					optionalId,
+					session.getEntityPersister( optionalEntityName, optionalObject ), 
+					session.getEntityMode()
+				);
+		}
+		else {
+			return null;
+		}
+
+	}
+
+	private Object getRowFromResultSet(
+	        final ResultSet resultSet,
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final LockMode[] lockModeArray,
+	        final EntityKey optionalObjectKey,
+	        final List hydratedObjects,
+	        final EntityKey[] keys,
+	        boolean returnProxies) throws SQLException, HibernateException {
+
+		final Loadable[] persisters = getEntityPersisters();
+		final int entitySpan = persisters.length;
+
+		for ( int i = 0; i < entitySpan; i++ ) {
+			keys[i] = getKeyFromResultSet(
+			        i,
+					persisters[i],
+					i == entitySpan - 1 ?
+							queryParameters.getOptionalId() :
+							null,
+					resultSet,
+					session
+				);
+			//TODO: the i==entitySpan-1 bit depends upon subclass implementation (very bad)
+		}
+
+		registerNonExists( keys, persisters, session );
+
+		// this call is side-effecty
+		Object[] row = getRow(
+		        resultSet,
+				persisters,
+				keys,
+				queryParameters.getOptionalObject(),
+				optionalObjectKey,
+				lockModeArray,
+				hydratedObjects,
+				session
+		);
+
+		readCollectionElements( row, resultSet, session );
+
+		if ( returnProxies ) {
+			// now get an existing proxy for each row element (if there is one)
+			for ( int i = 0; i < entitySpan; i++ ) {
+				Object entity = row[i];
+				Object proxy = session.getPersistenceContext().proxyFor( persisters[i], keys[i], entity );
+				if ( entity != proxy ) {
+					// force the proxy to resolve itself
+					( (HibernateProxy) proxy ).getHibernateLazyInitializer().setImplementation(entity);
+					row[i] = proxy;
+				}
+			}
+		}
+
+		return getResultColumnOrRow( row, queryParameters.getResultTransformer(), resultSet, session );
+
+	}
+
+	/**
+	 * Read any collection elements contained in a single row of the result set
+	 */
+	private void readCollectionElements(Object[] row, ResultSet resultSet, SessionImplementor session)
+			throws SQLException, HibernateException {
+
+		//TODO: make this handle multiple collection roles!
+
+		final CollectionPersister[] collectionPersisters = getCollectionPersisters();
+		if ( collectionPersisters != null ) {
+
+			final CollectionAliases[] descriptors = getCollectionAliases();
+			final int[] collectionOwners = getCollectionOwners();
+
+			for ( int i=0; i<collectionPersisters.length; i++ ) {
+
+				final boolean hasCollectionOwners = collectionOwners !=null && 
+						collectionOwners[i] > -1;
+				//true if this is a query and we are loading multiple instances of the same collection role
+				//otherwise this is a CollectionInitializer and we are loading up a single collection or batch
+				
+				final Object owner = hasCollectionOwners ?
+						row[ collectionOwners[i] ] :
+						null; //if null, owner will be retrieved from session
+
+				final CollectionPersister collectionPersister = collectionPersisters[i];
+				final Serializable key;
+				if ( owner == null ) {
+					key = null;
+				}
+				else {
+					key = collectionPersister.getCollectionType().getKeyOfOwner( owner, session );
+					//TODO: old version did not require hashmap lookup:
+					//keys[collectionOwner].getIdentifier()
+				}
+	
+				readCollectionElement( 
+						owner, 
+						key, 
+						collectionPersister, 
+						descriptors[i], 
+						resultSet, 
+						session 
+					);
+				
+			}
+
+		}
+	}
+
+	private List doQuery(
+			final SessionImplementor session,
+			final QueryParameters queryParameters,
+			final boolean returnProxies) throws SQLException, HibernateException {
+
+		final RowSelection selection = queryParameters.getRowSelection();
+		final int maxRows = hasMaxRows( selection ) ?
+				selection.getMaxRows().intValue() :
+				Integer.MAX_VALUE;
+
+		final int entitySpan = getEntityPersisters().length;
+
+		final ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList( entitySpan * 10 );
+		final PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
+		final ResultSet rs = getResultSet( st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), selection, session );
+
+// would be great to move all this below here into another method that could also be used
+// from the new scrolling stuff.
+//
+// Would need to change the way the max-row stuff is handled (i.e. behind an interface) so
+// that I could do the control breaking at the means to know when to stop
+		final LockMode[] lockModeArray = getLockModes( queryParameters.getLockModes() );
+		final EntityKey optionalObjectKey = getOptionalObjectKey( queryParameters, session );
+
+		final boolean createSubselects = isSubselectLoadingEnabled();
+		final List subselectResultKeys = createSubselects ? new ArrayList() : null;
+		final List results = new ArrayList();
+
+		try {
+
+			handleEmptyCollections( queryParameters.getCollectionKeys(), rs, session );
+
+			EntityKey[] keys = new EntityKey[entitySpan]; //we can reuse it for each row
+
+			if ( log.isTraceEnabled() ) log.trace( "processing result set" );
+
+			int count;
+			for ( count = 0; count < maxRows && rs.next(); count++ ) {
+				
+				if ( log.isTraceEnabled() ) log.debug("result set row: " + count);
+
+				Object result = getRowFromResultSet( 
+						rs,
+						session,
+						queryParameters,
+						lockModeArray,
+						optionalObjectKey,
+						hydratedObjects,
+						keys,
+						returnProxies 
+				);
+				results.add( result );
+
+				if ( createSubselects ) {
+					subselectResultKeys.add(keys);
+					keys = new EntityKey[entitySpan]; //can't reuse in this case
+				}
+				
+			}
+
+			if ( log.isTraceEnabled() ) {
+				log.trace( "done processing result set (" + count + " rows)" );
+			}
+
+		}
+		finally {
+			session.getBatcher().closeQueryStatement( st, rs );
+		}
+
+		initializeEntitiesAndCollections( hydratedObjects, rs, session, queryParameters.isReadOnly() );
+
+		if ( createSubselects ) createSubselects( subselectResultKeys, queryParameters, session );
+
+		return results; //getResultList(results);
+
+	}
+
+	protected boolean isSubselectLoadingEnabled() {
+		return false;
+	}
+	
+	protected boolean hasSubselectLoadableCollections() {
+		final Loadable[] loadables = getEntityPersisters();
+		for (int i=0; i<loadables.length; i++ ) {
+			if ( loadables[i].hasSubselectLoadableCollections() ) return true;
+		}
+		return false;
+	}
+	
+	private static Set[] transpose( List keys ) {
+		Set[] result = new Set[ ( ( EntityKey[] ) keys.get(0) ).length ];
+		for ( int j=0; j<result.length; j++ ) {
+			result[j] = new HashSet( keys.size() );
+			for ( int i=0; i<keys.size(); i++ ) {
+				result[j].add( ( ( EntityKey[] ) keys.get(i) ) [j] );
+			}
+		}
+		return result;
+	}
+
+	private void createSubselects(List keys, QueryParameters queryParameters, SessionImplementor session) {
+		if ( keys.size() > 1 ) { //if we only returned one entity, query by key is more efficient
+			
+			Set[] keySets = transpose(keys);
+			
+			Map namedParameterLocMap = buildNamedParameterLocMap( queryParameters );
+			
+			final Loadable[] loadables = getEntityPersisters();
+			final String[] aliases = getAliases();
+			final Iterator iter = keys.iterator();
+			while ( iter.hasNext() ) {
+				
+				final EntityKey[] rowKeys = (EntityKey[]) iter.next();
+				for ( int i=0; i<rowKeys.length; i++ ) {
+					
+					if ( rowKeys[i]!=null && loadables[i].hasSubselectLoadableCollections() ) {
+						
+						SubselectFetch subselectFetch = new SubselectFetch( 
+								//getSQLString(), 
+								aliases[i], 
+								loadables[i], 
+								queryParameters, 
+								keySets[i],
+								namedParameterLocMap
+							);
+						
+						session.getPersistenceContext()
+								.getBatchFetchQueue()
+								.addSubselect( rowKeys[i], subselectFetch );
+					}
+					
+				}
+				
+			}
+		}
+	}
+
+	private Map buildNamedParameterLocMap(QueryParameters queryParameters) {
+		if ( queryParameters.getNamedParameters()!=null ) {
+			final Map namedParameterLocMap = new HashMap();
+			Iterator piter = queryParameters.getNamedParameters().keySet().iterator();
+			while ( piter.hasNext() ) {
+				String name = (String) piter.next();
+				namedParameterLocMap.put(
+						name,
+						getNamedParameterLocs(name)
+					);
+			}
+			return namedParameterLocMap;
+		}
+		else {
+			return null;
+		}
+	}
+
+	private void initializeEntitiesAndCollections(
+			final List hydratedObjects,
+			final Object resultSetId,
+			final SessionImplementor session,
+			final boolean readOnly) 
+	throws HibernateException {
+		
+		final CollectionPersister[] collectionPersisters = getCollectionPersisters();
+		if ( collectionPersisters != null ) {
+			for ( int i=0; i<collectionPersisters.length; i++ ) {
+				if ( collectionPersisters[i].isArray() ) {
+					//for arrays, we should end the collection load before resolving
+					//the entities, since the actual array instances are not instantiated
+					//during loading
+					//TODO: or we could do this polymorphically, and have two
+					//      different operations implemented differently for arrays
+					endCollectionLoad( resultSetId, session, collectionPersisters[i] );
+				}
+			}
+		}
+
+		//important: reuse the same event instances for performance!
+		final PreLoadEvent pre;
+		final PostLoadEvent post;
+		if ( session.isEventSource() ) {
+			pre = new PreLoadEvent( (EventSource) session );
+			post = new PostLoadEvent( (EventSource) session );
+		}
+		else {
+			pre = null;
+			post = null;
+		}
+		
+		if ( hydratedObjects!=null ) {
+			int hydratedObjectsSize = hydratedObjects.size();
+			if ( log.isTraceEnabled() ) {
+				log.trace( "total objects hydrated: " + hydratedObjectsSize );
+			}
+			for ( int i = 0; i < hydratedObjectsSize; i++ ) {
+				TwoPhaseLoad.initializeEntity( hydratedObjects.get(i), readOnly, session, pre, post );
+			}
+		}
+		
+		if ( collectionPersisters != null ) {
+			for ( int i=0; i<collectionPersisters.length; i++ ) {
+				if ( !collectionPersisters[i].isArray() ) {
+					//for sets, we should end the collection load after resolving
+					//the entities, since we might call hashCode() on the elements
+					//TODO: or we could do this polymorphically, and have two
+					//      different operations implemented differently for arrays
+					endCollectionLoad( resultSetId, session, collectionPersisters[i] );
+				}
+			}
+		}
+		
+	}
+
+	private void endCollectionLoad(
+			final Object resultSetId, 
+			final SessionImplementor session, 
+			final CollectionPersister collectionPersister) {
+		//this is a query and we are loading multiple instances of the same collection role
+		session.getPersistenceContext()
+				.getLoadContexts()
+				.getCollectionLoadContext( ( ResultSet ) resultSetId )
+				.endLoadingCollections( collectionPersister );
+	}
+
+	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
+		return results;
+	}
+
+	/**
+	 * Get the actual object that is returned in the user-visible result list.
+	 * This empty implementation merely returns its first argument. This is
+	 * overridden by some subclasses.
+	 */
+	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
+			throws SQLException, HibernateException {
+		return row;
+	}
+
+	/**
+	 * For missing objects associated by one-to-one with another object in the
+	 * result set, register the fact that the the object is missing with the
+	 * session.
+	 */
+	private void registerNonExists(
+	        final EntityKey[] keys,
+	        final Loadable[] persisters,
+	        final SessionImplementor session) {
+		
+		final int[] owners = getOwners();
+		if ( owners != null ) {
+			
+			EntityType[] ownerAssociationTypes = getOwnerAssociationTypes();
+			for ( int i = 0; i < keys.length; i++ ) {
+				
+				int owner = owners[i];
+				if ( owner > -1 ) {
+					EntityKey ownerKey = keys[owner];
+					if ( keys[i] == null && ownerKey != null ) {
+						
+						final PersistenceContext persistenceContext = session.getPersistenceContext();
+						
+						/*final boolean isPrimaryKey;
+						final boolean isSpecialOneToOne;
+						if ( ownerAssociationTypes == null || ownerAssociationTypes[i] == null ) {
+							isPrimaryKey = true;
+							isSpecialOneToOne = false;
+						}
+						else {
+							isPrimaryKey = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName()==null;
+							isSpecialOneToOne = ownerAssociationTypes[i].getLHSPropertyName()!=null;
+						}*/
+						
+						//TODO: can we *always* use the "null property" approach for everything?
+						/*if ( isPrimaryKey && !isSpecialOneToOne ) {
+							persistenceContext.addNonExistantEntityKey( 
+									new EntityKey( ownerKey.getIdentifier(), persisters[i], session.getEntityMode() ) 
+							);
+						}
+						else if ( isSpecialOneToOne ) {*/
+						boolean isOneToOneAssociation = ownerAssociationTypes!=null && 
+								ownerAssociationTypes[i]!=null && 
+								ownerAssociationTypes[i].isOneToOne();
+						if ( isOneToOneAssociation ) {
+							persistenceContext.addNullProperty( ownerKey, 
+									ownerAssociationTypes[i].getPropertyName() );
+						}
+						/*}
+						else {
+							persistenceContext.addNonExistantEntityUniqueKey( new EntityUniqueKey( 
+									persisters[i].getEntityName(),
+									ownerAssociationTypes[i].getRHSUniqueKeyPropertyName(),
+									ownerKey.getIdentifier(),
+									persisters[owner].getIdentifierType(),
+									session.getEntityMode()
+							) );
+						}*/
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Read one collection element from the current row of the JDBC result set
+	 */
+	private void readCollectionElement(
+	        final Object optionalOwner,
+	        final Serializable optionalKey,
+	        final CollectionPersister persister,
+	        final CollectionAliases descriptor,
+	        final ResultSet rs,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+
+		final Serializable collectionRowKey = (Serializable) persister.readKey( 
+				rs, 
+				descriptor.getSuffixedKeyAliases(), 
+				session 
+			);
+		
+		if ( collectionRowKey != null ) {
+			// we found a collection element in the result set
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"found row of collection: " +
+						MessageHelper.collectionInfoString( persister, collectionRowKey, getFactory() ) 
+					);
+			}
+
+			Object owner = optionalOwner;
+			if ( owner == null ) {
+				owner = persistenceContext.getCollectionOwner( collectionRowKey, persister );
+				if ( owner == null ) {
+					//TODO: This is assertion is disabled because there is a bug that means the
+					//	  original owner of a transient, uninitialized collection is not known
+					//	  if the collection is re-referenced by a different object associated
+					//	  with the current Session
+					//throw new AssertionFailure("bug loading unowned collection");
+				}
+			}
+
+			PersistentCollection rowCollection = persistenceContext.getLoadContexts()
+					.getCollectionLoadContext( rs )
+					.getLoadingCollection( persister, collectionRowKey );
+
+			if ( rowCollection != null ) {
+				rowCollection.readFrom( rs, persister, descriptor, owner );
+			}
+
+		}
+		else if ( optionalKey != null ) {
+			// we did not find a collection element in the result set, so we
+			// ensure that a collection is created with the owner's identifier,
+			// since what we have is an empty collection
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"result set contains (possibly empty) collection: " +
+						MessageHelper.collectionInfoString( persister, optionalKey, getFactory() ) 
+					);
+			}
+
+			persistenceContext.getLoadContexts()
+					.getCollectionLoadContext( rs )
+					.getLoadingCollection( persister, optionalKey ); // handle empty collection
+
+		}
+
+		// else no collection element, but also no owner
+
+	}
+
+	/**
+	 * If this is a collection initializer, we need to tell the session that a collection
+	 * is being initilized, to account for the possibility of the collection having
+	 * no elements (hence no rows in the result set).
+	 */
+	private void handleEmptyCollections(
+	        final Serializable[] keys,
+	        final Object resultSetId,
+	        final SessionImplementor session) {
+
+		if ( keys != null ) {
+			// this is a collection initializer, so we must create a collection
+			// for each of the passed-in keys, to account for the possibility
+			// that the collection is empty and has no rows in the result set
+
+			CollectionPersister[] collectionPersisters = getCollectionPersisters();
+			for ( int j=0; j<collectionPersisters.length; j++ ) {
+				for ( int i = 0; i < keys.length; i++ ) {
+					//handle empty collections
+	
+					if ( log.isDebugEnabled() ) {
+						log.debug( 
+								"result set contains (possibly empty) collection: " +
+								MessageHelper.collectionInfoString( collectionPersisters[j], keys[i], getFactory() ) 
+							);
+					}
+
+					session.getPersistenceContext()
+							.getLoadContexts()
+							.getCollectionLoadContext( ( ResultSet ) resultSetId )
+							.getLoadingCollection( collectionPersisters[j], keys[i] );
+				}
+			}
+		}
+
+		// else this is not a collection initializer (and empty collections will
+		// be detected by looking for the owner's identifier in the result set)
+	}
+
+	/**
+	 * Read a row of <tt>Key</tt>s from the <tt>ResultSet</tt> into the given array.
+	 * Warning: this method is side-effecty.
+	 * <p/>
+	 * If an <tt>id</tt> is given, don't bother going to the <tt>ResultSet</tt>.
+	 */
+	private EntityKey getKeyFromResultSet(
+	        final int i,
+	        final Loadable persister,
+	        final Serializable id,
+	        final ResultSet rs,
+	        final SessionImplementor session) throws HibernateException, SQLException {
+
+		Serializable resultId;
+
+		// if we know there is exactly 1 row, we can skip.
+		// it would be great if we could _always_ skip this;
+		// it is a problem for <key-many-to-one>
+
+		if ( isSingleRowLoader() && id != null ) {
+			resultId = id;
+		}
+		else {
+			
+			Type idType = persister.getIdentifierType();
+			resultId = (Serializable) idType.nullSafeGet(
+					rs,
+					getEntityAliases()[i].getSuffixedKeyAliases(),
+					session,
+					null //problematic for <key-many-to-one>!
+				);
+			
+			final boolean idIsResultId = id != null && 
+					resultId != null && 
+					idType.isEqual( id, resultId, session.getEntityMode(), factory );
+			
+			if ( idIsResultId ) resultId = id; //use the id passed in
+		}
+
+		return resultId == null ?
+				null :
+				new EntityKey( resultId, persister, session.getEntityMode() );
+	}
+
+	/**
+	 * Check the version of the object in the <tt>ResultSet</tt> against
+	 * the object version in the session cache, throwing an exception
+	 * if the version numbers are different
+	 */
+	private void checkVersion(
+	        final int i,
+	        final Loadable persister,
+	        final Serializable id,
+	        final Object entity,
+	        final ResultSet rs,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		Object version = session.getPersistenceContext().getEntry( entity ).getVersion();
+
+		if ( version != null ) { //null version means the object is in the process of being loaded somewhere else in the ResultSet
+			VersionType versionType = persister.getVersionType();
+			Object currentVersion = versionType.nullSafeGet(
+					rs,
+					getEntityAliases()[i].getSuffixedVersionAliases(),
+					session,
+					null
+				);
+			if ( !versionType.isEqual(version, currentVersion) ) {
+				if ( session.getFactory().getStatistics().isStatisticsEnabled() ) {
+					session.getFactory().getStatisticsImplementor()
+							.optimisticFailure( persister.getEntityName() );
+				}
+				throw new StaleObjectStateException( persister.getEntityName(), id );
+			}
+		}
+
+	}
+
+	/**
+	 * Resolve any ids for currently loaded objects, duplications within the
+	 * <tt>ResultSet</tt>, etc. Instantiate empty objects to be initialized from the
+	 * <tt>ResultSet</tt>. Return an array of objects (a row of results) and an
+	 * array of booleans (by side-effect) that determine whether the corresponding
+	 * object should be initialized.
+	 */
+	private Object[] getRow(
+	        final ResultSet rs,
+	        final Loadable[] persisters,
+	        final EntityKey[] keys,
+	        final Object optionalObject,
+	        final EntityKey optionalObjectKey,
+	        final LockMode[] lockModes,
+	        final List hydratedObjects,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		final int cols = persisters.length;
+		final EntityAliases[] descriptors = getEntityAliases();
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( 
+					"result row: " + 
+					StringHelper.toString( keys ) 
+				);
+		}
+
+		final Object[] rowResults = new Object[cols];
+
+		for ( int i = 0; i < cols; i++ ) {
+
+			Object object = null;
+			EntityKey key = keys[i];
+
+			if ( keys[i] == null ) {
+				//do nothing
+			}
+			else {
+
+				//If the object is already loaded, return the loaded one
+				object = session.getEntityUsingInterceptor( key );
+				if ( object != null ) {
+					//its already loaded so don't need to hydrate it
+					instanceAlreadyLoaded( 
+							rs,
+							i,
+							persisters[i],
+							key,
+							object,
+							lockModes[i],
+							session 
+						);
+				}
+				else {
+					object = instanceNotYetLoaded( 
+							rs,
+							i,
+							persisters[i],
+							descriptors[i].getRowIdAlias(),
+							key,
+							lockModes[i],
+							optionalObjectKey,
+							optionalObject,
+							hydratedObjects,
+							session 
+						);
+				}
+
+			}
+
+			rowResults[i] = object;
+
+		}
+
+		return rowResults;
+	}
+
+	/**
+	 * The entity instance is already in the session cache
+	 */
+	private void instanceAlreadyLoaded(
+	        final ResultSet rs,
+	        final int i,
+	        final Loadable persister,
+	        final EntityKey key,
+	        final Object object,
+	        final LockMode lockMode,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		if ( !persister.isInstance( object, session.getEntityMode() ) ) {
+			throw new WrongClassException( 
+					"loaded object was of wrong class " + object.getClass(), 
+					key.getIdentifier(), 
+					persister.getEntityName() 
+				);
+		}
+
+		if ( LockMode.NONE != lockMode && upgradeLocks() ) { //no point doing this if NONE was requested
+
+			final boolean isVersionCheckNeeded = persister.isVersioned() &&
+					session.getPersistenceContext().getEntry(object)
+							.getLockMode().lessThan( lockMode );
+			// we don't need to worry about existing version being uninitialized
+			// because this block isn't called by a re-entrant load (re-entrant
+			// loads _always_ have lock mode NONE)
+			if (isVersionCheckNeeded) {
+				//we only check the version when _upgrading_ lock modes
+				checkVersion( i, persister, key.getIdentifier(), object, rs, session );
+				//we need to upgrade the lock mode to the mode requested
+				session.getPersistenceContext().getEntry(object)
+						.setLockMode(lockMode);
+			}
+		}
+	}
+
+	/**
+	 * The entity instance is not in the session cache
+	 */
+	private Object instanceNotYetLoaded(
+	        final ResultSet rs,
+	        final int i,
+	        final Loadable persister,
+	        final String rowIdAlias,
+	        final EntityKey key,
+	        final LockMode lockMode,
+	        final EntityKey optionalObjectKey,
+	        final Object optionalObject,
+	        final List hydratedObjects,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		final String instanceClass = getInstanceClass( 
+				rs, 
+				i, 
+				persister, 
+				key.getIdentifier(), 
+				session 
+			);
+
+		final Object object;
+		if ( optionalObjectKey != null && key.equals( optionalObjectKey ) ) {
+			//its the given optional object
+			object = optionalObject;
+		}
+		else {
+			// instantiate a new instance
+			object = session.instantiate( instanceClass, key.getIdentifier() );
+		}
+
+		//need to hydrate it.
+
+		// grab its state from the ResultSet and keep it in the Session
+		// (but don't yet initialize the object itself)
+		// note that we acquire LockMode.READ even if it was not requested
+		LockMode acquiredLockMode = lockMode == LockMode.NONE ? LockMode.READ : lockMode;
+		loadFromResultSet( 
+				rs, 
+				i, 
+				object, 
+				instanceClass, 
+				key, 
+				rowIdAlias, 
+				acquiredLockMode, 
+				persister, 
+				session 
+			);
+
+		//materialize associations (and initialize the object) later
+		hydratedObjects.add( object );
+
+		return object;
+	}
+	
+	private boolean isEagerPropertyFetchEnabled(int i) {
+		boolean[] array = getEntityEagerPropertyFetches();
+		return array!=null && array[i];
+	}
+
+
+	/**
+	 * Hydrate the state an object from the SQL <tt>ResultSet</tt>, into
+	 * an array or "hydrated" values (do not resolve associations yet),
+	 * and pass the hydrates state to the session.
+	 */
+	private void loadFromResultSet(
+	        final ResultSet rs,
+	        final int i,
+	        final Object object,
+	        final String instanceEntityName,
+	        final EntityKey key,
+	        final String rowIdAlias,
+	        final LockMode lockMode,
+	        final Loadable rootPersister,
+	        final SessionImplementor session) 
+	throws SQLException, HibernateException {
+
+		final Serializable id = key.getIdentifier();
+
+		// Get the persister for the _subclass_
+		final Loadable persister = (Loadable) getFactory().getEntityPersister( instanceEntityName );
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( 
+					"Initializing object from ResultSet: " + 
+					MessageHelper.infoString( persister, id, getFactory() ) 
+				);
+		}
+		
+		boolean eagerPropertyFetch = isEagerPropertyFetchEnabled(i);
+
+		// add temp entry so that the next step is circular-reference
+		// safe - only needed because some types don't take proper
+		// advantage of two-phase-load (esp. components)
+		TwoPhaseLoad.addUninitializedEntity( 
+				key, 
+				object, 
+				persister, 
+				lockMode, 
+				!eagerPropertyFetch, 
+				session 
+			);
+
+		//This is not very nice (and quite slow):
+		final String[][] cols = persister == rootPersister ?
+				getEntityAliases()[i].getSuffixedPropertyAliases() :
+				getEntityAliases()[i].getSuffixedPropertyAliases(persister);
+
+		final Object[] values = persister.hydrate( 
+				rs, 
+				id, 
+				object, 
+				rootPersister, 
+				cols, 
+				eagerPropertyFetch, 
+				session 
+			);
+
+		final Object rowId = persister.hasRowId() ? rs.getObject(rowIdAlias) : null;
+
+		final AssociationType[] ownerAssociationTypes = getOwnerAssociationTypes();
+		if ( ownerAssociationTypes != null && ownerAssociationTypes[i] != null ) {
+			String ukName = ownerAssociationTypes[i].getRHSUniqueKeyPropertyName();
+			if (ukName!=null) {
+				final int index = ( (UniqueKeyLoadable) persister ).getPropertyIndex(ukName);
+				final Type type = persister.getPropertyTypes()[index];
+	
+				// polymorphism not really handled completely correctly,
+				// perhaps...well, actually its ok, assuming that the
+				// entity name used in the lookup is the same as the
+				// the one used here, which it will be
+	
+				EntityUniqueKey euk = new EntityUniqueKey( 
+						rootPersister.getEntityName(), //polymorphism comment above
+						ukName,
+						type.semiResolve( values[index], session, object ),
+						type,
+						session.getEntityMode(), session.getFactory()
+					);
+				session.getPersistenceContext().addEntity( euk, object );
+			}
+		}
+
+		TwoPhaseLoad.postHydrate( 
+				persister, 
+				id, 
+				values, 
+				rowId, 
+				object, 
+				lockMode, 
+				!eagerPropertyFetch, 
+				session 
+			);
+
+	}
+
+	/**
+	 * Determine the concrete class of an instance in the <tt>ResultSet</tt>
+	 */
+	private String getInstanceClass(
+	        final ResultSet rs,
+	        final int i,
+	        final Loadable persister,
+	        final Serializable id,
+	        final SessionImplementor session) 
+	throws HibernateException, SQLException {
+
+		if ( persister.hasSubclasses() ) {
+
+			// Code to handle subclasses of topClass
+			Object discriminatorValue = persister.getDiscriminatorType().nullSafeGet(
+					rs,
+					getEntityAliases()[i].getSuffixedDiscriminatorAlias(),
+					session,
+					null
+				);
+
+			final String result = persister.getSubclassForDiscriminatorValue( discriminatorValue );
+
+			if ( result == null ) {
+				//woops we got an instance of another class hierarchy branch
+				throw new WrongClassException( 
+						"Discriminator: " + discriminatorValue,
+						id,
+						persister.getEntityName() 
+					);
+			}
+
+			return result;
+
+		}
+		else {
+			return persister.getEntityName();
+		}
+	}
+
+	/**
+	 * Advance the cursor to the first required row of the <tt>ResultSet</tt>
+	 */
+	private void advance(final ResultSet rs, final RowSelection selection)
+			throws SQLException {
+
+		final int firstRow = getFirstRow( selection );
+		if ( firstRow != 0 ) {
+			if ( getFactory().getSettings().isScrollableResultSetsEnabled() ) {
+				// we can go straight to the first required row
+				rs.absolute( firstRow );
+			}
+			else {
+				// we need to step through the rows one row at a time (slow)
+				for ( int m = 0; m < firstRow; m++ ) rs.next();
+			}
+		}
+	}
+
+	private static boolean hasMaxRows(RowSelection selection) {
+		return selection != null && selection.getMaxRows() != null;
+	}
+
+	private static int getFirstRow(RowSelection selection) {
+		if ( selection == null || selection.getFirstRow() == null ) {
+			return 0;
+		}
+		else {
+			return selection.getFirstRow().intValue();
+		}
+	}
+
+	/**
+	 * Should we pre-process the SQL string, adding a dialect-specific
+	 * LIMIT clause.
+	 */
+	private static boolean useLimit(final RowSelection selection, final Dialect dialect) {
+		return dialect.supportsLimit() && hasMaxRows( selection );
+	}
+
+	/**
+	 * Obtain a <tt>PreparedStatement</tt> with all parameters pre-bound.
+	 * Bind JDBC-style <tt>?</tt> parameters, named parameters, and
+	 * limit parameters.
+	 */
+	protected final PreparedStatement prepareQueryStatement(
+	        final QueryParameters queryParameters,
+	        final boolean scroll,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+
+		queryParameters.processFilters( getSQLString(), session );
+		String sql = queryParameters.getFilteredSQL();
+		final Dialect dialect = getFactory().getDialect();
+		final RowSelection selection = queryParameters.getRowSelection();
+		boolean useLimit = useLimit( selection, dialect );
+		boolean hasFirstRow = getFirstRow( selection ) > 0;
+		boolean useOffset = hasFirstRow && useLimit && dialect.supportsLimitOffset();
+		boolean callable = queryParameters.isCallable();
+		
+		boolean useScrollableResultSetToSkip = hasFirstRow &&
+				!useOffset &&
+				getFactory().getSettings().isScrollableResultSetsEnabled();
+		ScrollMode scrollMode = scroll ? queryParameters.getScrollMode() : ScrollMode.SCROLL_INSENSITIVE;
+
+		if ( useLimit ) {
+			sql = dialect.getLimitString( 
+					sql.trim(), //use of trim() here is ugly?
+					useOffset ? getFirstRow(selection) : 0, 
+					getMaxOrLimit(selection, dialect) 
+				);
+		}
+
+		sql = preprocessSQL( sql, queryParameters, dialect );
+		
+		PreparedStatement st = null;
+		
+		if (callable) {
+			st = session.getBatcher()
+				.prepareCallableQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
+		} 
+		else {
+			st = session.getBatcher()
+				.prepareQueryStatement( sql, scroll || useScrollableResultSetToSkip, scrollMode );
+		}
+				
+
+		try {
+
+			int col = 1;
+			//TODO: can we limit stored procedures ?!
+			if ( useLimit && dialect.bindLimitParametersFirst() ) {
+				col += bindLimitParameters( st, col, selection );
+			}
+			if (callable) {
+				col = dialect.registerResultSetOutParameter( (CallableStatement)st, col );
+			}
+
+			col += bindParameterValues( st, queryParameters, col, session );
+
+			if ( useLimit && !dialect.bindLimitParametersFirst() ) {
+				col += bindLimitParameters( st, col, selection );
+			}
+
+			if ( !useLimit ) {
+				setMaxRows( st, selection );
+			}
+
+			if ( selection != null ) {
+				if ( selection.getTimeout() != null ) {
+					st.setQueryTimeout( selection.getTimeout().intValue() );
+				}
+				if ( selection.getFetchSize() != null ) {
+					st.setFetchSize( selection.getFetchSize().intValue() );
+				}
+			}
+		}
+		catch ( SQLException sqle ) {
+			session.getBatcher().closeQueryStatement( st, null );
+			throw sqle;
+		}
+		catch ( HibernateException he ) {
+			session.getBatcher().closeQueryStatement( st, null );
+			throw he;
+		}
+
+		return st;
+	}
+
+	/**
+	 * Some dialect-specific LIMIT clauses require the maximium last row number
+	 * (aka, first_row_number + total_row_count), while others require the maximum
+	 * returned row count (the total maximum number of rows to return).
+	 *
+	 * @param selection The selection criteria
+	 * @param dialect The dialect
+	 * @return The appropriate value to bind into the limit clause.
+	 */
+	private static int getMaxOrLimit(final RowSelection selection, final Dialect dialect) {
+		final int firstRow = getFirstRow( selection );
+		final int lastRow = selection.getMaxRows().intValue();
+		if ( dialect.useMaxForLimit() ) {
+			return lastRow + firstRow;
+		}
+		else {
+			return lastRow;
+		}
+	}
+
+	/**
+	 * Bind parameter values needed by the dialect-specific LIMIT clause.
+	 *
+	 * @param statement The statement to which to bind limit param values.
+	 * @param index The bind position from which to start binding
+	 * @param selection The selection object containing the limit information.
+	 * @return The number of parameter values bound.
+	 * @throws java.sql.SQLException Indicates problems binding parameter values.
+	 */
+	private int bindLimitParameters(
+			final PreparedStatement statement,
+			final int index,
+			final RowSelection selection) throws SQLException {
+		Dialect dialect = getFactory().getDialect();
+		if ( !dialect.supportsVariableLimit() ) {
+			return 0;
+		}
+		if ( !hasMaxRows( selection ) ) {
+			throw new AssertionFailure( "no max results set" );
+		}
+		int firstRow = getFirstRow( selection );
+		int lastRow = getMaxOrLimit( selection, dialect );
+		boolean hasFirstRow = firstRow > 0 && dialect.supportsLimitOffset();
+		boolean reverse = dialect.bindLimitParametersInReverseOrder();
+		if ( hasFirstRow ) {
+			statement.setInt( index + ( reverse ? 1 : 0 ), firstRow );
+		}
+		statement.setInt( index + ( reverse || !hasFirstRow ? 0 : 1 ), lastRow );
+		return hasFirstRow ? 2 : 1;
+	}
+
+	/**
+	 * Use JDBC API to limit the number of rows returned by the SQL query if necessary
+	 */
+	private void setMaxRows(
+			final PreparedStatement st,
+			final RowSelection selection) throws SQLException {
+		if ( hasMaxRows( selection ) ) {
+			st.setMaxRows( selection.getMaxRows().intValue() + getFirstRow( selection ) );
+		}
+	}
+
+	/**
+	 * Bind all parameter values into the prepared statement in preparation
+	 * for execution.
+	 *
+	 * @param statement The JDBC prepared statement
+	 * @param queryParameters The encapsulation of the parameter values to be bound.
+	 * @param startIndex The position from which to start binding parameter values.
+	 * @param session The originating session.
+	 * @return The number of JDBC bind positions actually bound during this method execution.
+	 * @throws SQLException Indicates problems performing the binding.
+	 */
+	protected int bindParameterValues(
+			PreparedStatement statement,
+			QueryParameters queryParameters,
+			int startIndex,
+			SessionImplementor session) throws SQLException {
+		int span = 0;
+		span += bindPositionalParameters( statement, queryParameters, startIndex, session );
+		span += bindNamedParameters( statement, queryParameters.getNamedParameters(), startIndex + span, session );
+		return span;
+	}
+
+	/**
+	 * Bind positional parameter values to the JDBC prepared statement.
+	 * <p/>
+	 * Postional parameters are those specified by JDBC-style ? parameters
+	 * in the source query.  It is (currently) expected that these come
+	 * before any named parameters in the source query.
+	 *
+	 * @param statement The JDBC prepared statement
+	 * @param queryParameters The encapsulation of the parameter values to be bound.
+	 * @param startIndex The position from which to start binding parameter values.
+	 * @param session The originating session.
+	 * @return The number of JDBC bind positions actually bound during this method execution.
+	 * @throws SQLException Indicates problems performing the binding.
+	 * @throws org.hibernate.HibernateException Indicates problems delegating binding to the types.
+	 */
+	protected int bindPositionalParameters(
+	        final PreparedStatement statement,
+	        final QueryParameters queryParameters,
+	        final int startIndex,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+		final Object[] values = queryParameters.getFilteredPositionalParameterValues();
+		final Type[] types = queryParameters.getFilteredPositionalParameterTypes();
+		int span = 0;
+		for ( int i = 0; i < values.length; i++ ) {
+			types[i].nullSafeSet( statement, values[i], startIndex + span, session );
+			span += types[i].getColumnSpan( getFactory() );
+		}
+		return span;
+	}
+
+	/**
+	 * Bind named parameters to the JDBC prepared statement.
+	 * <p/>
+	 * This is a generic implementation, the problem being that in the
+	 * general case we do not know enough information about the named
+	 * parameters to perform this in a complete manner here.  Thus this
+	 * is generally overridden on subclasses allowing named parameters to
+	 * apply the specific behavior.  The most usual limitation here is that
+	 * we need to assume the type span is always one...
+	 *
+	 * @param statement The JDBC prepared statement
+	 * @param namedParams A map of parameter names to values
+	 * @param startIndex The position from which to start binding parameter values.
+	 * @param session The originating session.
+	 * @return The number of JDBC bind positions actually bound during this method execution.
+	 * @throws SQLException Indicates problems performing the binding.
+	 * @throws org.hibernate.HibernateException Indicates problems delegating binding to the types.
+	 */
+	protected int bindNamedParameters(
+			final PreparedStatement statement,
+			final Map namedParams,
+			final int startIndex,
+			final SessionImplementor session) throws SQLException, HibernateException {
+		if ( namedParams != null ) {
+			// assumes that types are all of span 1
+			Iterator iter = namedParams.entrySet().iterator();
+			int result = 0;
+			while ( iter.hasNext() ) {
+				Map.Entry e = ( Map.Entry ) iter.next();
+				String name = ( String ) e.getKey();
+				TypedValue typedval = ( TypedValue ) e.getValue();
+				int[] locs = getNamedParameterLocs( name );
+				for ( int i = 0; i < locs.length; i++ ) {
+					if ( log.isDebugEnabled() ) {
+						log.debug(
+								"bindNamedParameters() " +
+								typedval.getValue() + " -> " + name +
+								" [" + ( locs[i] + startIndex ) + "]"
+							);
+					}
+					typedval.getType().nullSafeSet( statement, typedval.getValue(), locs[i] + startIndex, session );
+				}
+				result += locs.length;
+			}
+			return result;
+		}
+		else {
+			return 0;
+		}
+	}
+
+	public int[] getNamedParameterLocs(String name) {
+		throw new AssertionFailure("no named parameters");
+	}
+
+	/**
+	 * Fetch a <tt>PreparedStatement</tt>, call <tt>setMaxRows</tt> and then execute it,
+	 * advance to the first result and return an SQL <tt>ResultSet</tt>
+	 */
+	protected final ResultSet getResultSet(
+	        final PreparedStatement st,
+	        final boolean autodiscovertypes,
+	        final boolean callable,
+	        final RowSelection selection,
+	        final SessionImplementor session) 
+	throws SQLException, HibernateException {
+	
+		ResultSet rs = null;
+		try {
+			Dialect dialect = getFactory().getDialect();
+			if (callable) {
+				rs = session.getBatcher().getResultSet( (CallableStatement) st, dialect );
+			} 
+			else {
+				rs = session.getBatcher().getResultSet( st );
+			}
+			rs = wrapResultSetIfEnabled( rs , session );
+			
+			if ( !dialect.supportsLimitOffset() || !useLimit( selection, dialect ) ) {
+				advance( rs, selection );
+			}
+			
+			if ( autodiscovertypes ) {
+				autoDiscoverTypes( rs );
+			}
+			return rs;
+		}
+		catch ( SQLException sqle ) {
+			session.getBatcher().closeQueryStatement( st, rs );
+			throw sqle;
+		}
+	}
+
+	protected void autoDiscoverTypes(ResultSet rs) {
+		throw new AssertionFailure("Auto discover types not supported in this loader");
+		
+	}
+
+	private synchronized ResultSet wrapResultSetIfEnabled(final ResultSet rs, final SessionImplementor session) {
+		// synchronized to avoid multi-thread access issues; defined as method synch to avoid
+		// potential deadlock issues due to nature of code.
+		if ( session.getFactory().getSettings().isWrapResultSetsEnabled() ) {
+			try {
+				log.debug("Wrapping result set [" + rs + "]");
+				return new ResultSetWrapper( rs, retreiveColumnNameToIndexCache( rs ) );
+			}
+			catch(SQLException e) {
+				log.info("Error wrapping result set", e);
+				return rs;
+			}
+		}
+		else {
+			return rs;
+		}
+	}
+
+	private ColumnNameCache retreiveColumnNameToIndexCache(ResultSet rs) throws SQLException {
+		if ( columnNameCache == null ) {
+			log.trace("Building columnName->columnIndex cache");
+			columnNameCache = new ColumnNameCache( rs.getMetaData().getColumnCount() );
+		}
+
+		return columnNameCache;
+	}
+
+	/**
+	 * Called by subclasses that load entities
+	 * @param persister only needed for logging
+	 */
+	protected final List loadEntity(
+	        final SessionImplementor session,
+	        final Object id,
+	        final Type identifierType,
+	        final Object optionalObject,
+	        final String optionalEntityName,
+	        final Serializable optionalIdentifier,
+	        final EntityPersister persister) throws HibernateException {
+		
+		if ( log.isDebugEnabled() ) {
+			log.debug( 
+					"loading entity: " + 
+					MessageHelper.infoString( persister, id, identifierType, getFactory() ) 
+				);
+		}
+
+		List result;
+		try {
+			result = doQueryAndInitializeNonLazyCollections( 
+					session,
+					new QueryParameters( 
+							new Type[] { identifierType },
+							new Object[] { id },
+							optionalObject,
+							optionalEntityName,
+							optionalIdentifier 
+						),
+					false 
+				);
+		}
+		catch ( SQLException sqle ) {
+			final Loadable[] persisters = getEntityPersisters();
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not load an entity: " + 
+			        MessageHelper.infoString( persisters[persisters.length-1], id, identifierType, getFactory() ),
+			        getSQLString()
+				);
+		}
+
+		log.debug("done entity load");
+		
+		return result;
+		
+	}
+
+	/**
+	 * Called by subclasses that load entities
+	 * @param persister only needed for logging
+	 */
+	protected final List loadEntity(
+	        final SessionImplementor session,
+	        final Object key,
+	        final Object index,
+	        final Type keyType,
+	        final Type indexType,
+	        final EntityPersister persister) throws HibernateException {
+		
+		if ( log.isDebugEnabled() ) {
+			log.debug( "loading collection element by index" );
+		}
+
+		List result;
+		try {
+			result = doQueryAndInitializeNonLazyCollections( 
+					session,
+					new QueryParameters( 
+							new Type[] { keyType, indexType },
+							new Object[] { key, index }
+						),
+					false 
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not collection element by index",
+			        getSQLString()
+				);
+		}
+
+		log.debug("done entity load");
+		
+		return result;
+		
+	}
+
+	/**
+	 * Called by wrappers that batch load entities
+	 * @param persister only needed for logging
+	 */
+	public final List loadEntityBatch(
+	        final SessionImplementor session,
+	        final Serializable[] ids,
+	        final Type idType,
+	        final Object optionalObject,
+	        final String optionalEntityName,
+	        final Serializable optionalId,
+	        final EntityPersister persister) throws HibernateException {
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( 
+					"batch loading entity: " + 
+					MessageHelper.infoString(persister, ids, getFactory() ) 
+				);
+		}
+
+		Type[] types = new Type[ids.length];
+		Arrays.fill( types, idType );
+		List result;
+		try {
+			result = doQueryAndInitializeNonLazyCollections( 
+					session,
+					new QueryParameters( types, ids, optionalObject, optionalEntityName, optionalId ),
+					false 
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not load an entity batch: " + 
+			        MessageHelper.infoString( getEntityPersisters()[0], ids, getFactory() ),
+			        getSQLString()
+				);
+		}
+
+		log.debug("done entity batch load");
+		
+		return result;
+
+	}
+
+	/**
+	 * Called by subclasses that initialize collections
+	 */
+	public final void loadCollection(
+	        final SessionImplementor session,
+	        final Serializable id,
+	        final Type type) throws HibernateException {
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( 
+					"loading collection: "+ 
+					MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() )
+				);
+		}
+
+		Serializable[] ids = new Serializable[]{id};
+		try {
+			doQueryAndInitializeNonLazyCollections( 
+					session,
+					new QueryParameters( new Type[]{type}, ids, ids ),
+					true 
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					factory.getSQLExceptionConverter(),
+					sqle,
+					"could not initialize a collection: " + 
+					MessageHelper.collectionInfoString( getCollectionPersisters()[0], id, getFactory() ),
+					getSQLString()
+				);
+		}
+	
+		log.debug("done loading collection");
+
+	}
+
+	/**
+	 * Called by wrappers that batch initialize collections
+	 */
+	public final void loadCollectionBatch(
+	        final SessionImplementor session,
+	        final Serializable[] ids,
+	        final Type type) throws HibernateException {
+
+		if ( log.isDebugEnabled() ) {
+			log.debug( 
+					"batch loading collection: "+ 
+					MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() )
+				);
+		}
+
+		Type[] idTypes = new Type[ids.length];
+		Arrays.fill( idTypes, type );
+		try {
+			doQueryAndInitializeNonLazyCollections( 
+					session,
+					new QueryParameters( idTypes, ids, ids ),
+					true 
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not initialize a collection batch: " + 
+			        MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ),
+			        getSQLString()
+				);
+		}
+		
+		log.debug("done batch load");
+
+	}
+
+	/**
+	 * Called by subclasses that batch initialize collections
+	 */
+	protected final void loadCollectionSubselect(
+	        final SessionImplementor session,
+	        final Serializable[] ids,
+	        final Object[] parameterValues,
+	        final Type[] parameterTypes,
+	        final Map namedParameters,
+	        final Type type) throws HibernateException {
+
+		Type[] idTypes = new Type[ids.length];
+		Arrays.fill( idTypes, type );
+		try {
+			doQueryAndInitializeNonLazyCollections( session,
+					new QueryParameters( parameterTypes, parameterValues, namedParameters, ids ),
+					true 
+				);
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not load collection by subselect: " + 
+			        MessageHelper.collectionInfoString( getCollectionPersisters()[0], ids, getFactory() ),
+			        getSQLString()
+				);
+		}
+	}
+
+	/**
+	 * Return the query results, using the query cache, called
+	 * by subclasses that implement cacheable queries
+	 */
+	protected List list(
+	        final SessionImplementor session,
+	        final QueryParameters queryParameters,
+	        final Set querySpaces,
+	        final Type[] resultTypes) throws HibernateException {
+
+		final boolean cacheable = factory.getSettings().isQueryCacheEnabled() && 
+			queryParameters.isCacheable();
+
+		if ( cacheable ) {
+			return listUsingQueryCache( session, queryParameters, querySpaces, resultTypes );
+		}
+		else {
+			return listIgnoreQueryCache( session, queryParameters );
+		}
+	}
+
+	private List listIgnoreQueryCache(SessionImplementor session, QueryParameters queryParameters) {
+		return getResultList( doList( session, queryParameters ), queryParameters.getResultTransformer() );
+	}
+
+	private List listUsingQueryCache(
+			final SessionImplementor session, 
+			final QueryParameters queryParameters, 
+			final Set querySpaces, 
+			final Type[] resultTypes) {
+	
+		QueryCache queryCache = factory.getQueryCache( queryParameters.getCacheRegion() );
+		
+		Set filterKeys = FilterKey.createFilterKeys( 
+				session.getEnabledFilters(), 
+				session.getEntityMode() 
+			);
+		QueryKey key = new QueryKey( 
+				getSQLString(), 
+				queryParameters, 
+				filterKeys, 
+				session.getEntityMode() 
+			);
+		
+		List result = getResultFromQueryCache( 
+				session, 
+				queryParameters, 
+				querySpaces, 
+				resultTypes, 
+				queryCache, 
+				key 
+			);
+
+		if ( result == null ) {
+			result = doList( session, queryParameters );
+
+			putResultInQueryCache( 
+					session, 
+					queryParameters, 
+					resultTypes,
+					queryCache, 
+					key, 
+					result 
+				);
+		}
+
+		return getResultList( result, queryParameters.getResultTransformer() );
+	}
+
+	private List getResultFromQueryCache(
+			final SessionImplementor session,
+			final QueryParameters queryParameters,
+			final Set querySpaces,
+			final Type[] resultTypes,
+			final QueryCache queryCache,
+			final QueryKey key) {
+		List result = null;
+
+		if ( session.getCacheMode().isGetEnabled() ) {
+			boolean isImmutableNaturalKeyLookup = queryParameters.isNaturalKeyLookup()
+					&& getEntityPersisters()[0].getEntityMetamodel().hasImmutableNaturalId();
+			result = queryCache.get( key, resultTypes, isImmutableNaturalKeyLookup, querySpaces, session );
+			if ( factory.getStatistics().isStatisticsEnabled() ) {
+				if ( result == null ) {
+					factory.getStatisticsImplementor()
+							.queryCacheMiss( getQueryIdentifier(), queryCache.getRegion().getName() );
+				}
+				else {
+					factory.getStatisticsImplementor()
+							.queryCacheHit( getQueryIdentifier(), queryCache.getRegion().getName() );
+				}
+			}
+		}
+
+		return result;
+	}
+
+	private void putResultInQueryCache(
+			final SessionImplementor session,
+			final QueryParameters queryParameters,
+			final Type[] resultTypes,
+			final QueryCache queryCache,
+			final QueryKey key,
+			final List result) {
+		if ( session.getCacheMode().isPutEnabled() ) {
+			boolean put = queryCache.put( key, resultTypes, result, queryParameters.isNaturalKeyLookup(), session );
+			if ( put && factory.getStatistics().isStatisticsEnabled() ) {
+				factory.getStatisticsImplementor()
+						.queryCachePut( getQueryIdentifier(), queryCache.getRegion().getName() );
+			}
+		}
+	}
+
+	/**
+	 * Actually execute a query, ignoring the query cache
+	 */
+	protected List doList(final SessionImplementor session, final QueryParameters queryParameters)
+			throws HibernateException {
+
+		final boolean stats = getFactory().getStatistics().isStatisticsEnabled();
+		long startTime = 0;
+		if ( stats ) startTime = System.currentTimeMillis();
+
+		List result;
+		try {
+			result = doQueryAndInitializeNonLazyCollections( session, queryParameters, true );
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not execute query",
+			        getSQLString()
+				);
+		}
+
+		if ( stats ) {
+			getFactory().getStatisticsImplementor().queryExecuted(
+					getQueryIdentifier(),
+					result.size(),
+					System.currentTimeMillis() - startTime
+				);
+		}
+
+		return result;
+	}
+
+	/**
+	 * Check whether the current loader can support returning ScrollableResults.
+	 *
+	 * @throws HibernateException
+	 */
+	protected void checkScrollability() throws HibernateException {
+		// Allows various loaders (ok mainly the QueryLoader :) to check
+		// whether scrolling of their result set should be allowed.
+		//
+		// By default it is allowed.
+		return;
+	}
+
+	/**
+	 * Does the result set to be scrolled contain collection fetches?
+	 *
+	 * @return True if it does, and thus needs the special fetching scroll
+	 * functionality; false otherwise.
+	 */
+	protected boolean needsFetchingScroll() {
+		return false;
+	}
+
+	/**
+	 * Return the query results, as an instance of <tt>ScrollableResults</tt>
+	 *
+	 * @param queryParameters The parameters with which the query should be executed.
+	 * @param returnTypes The expected return types of the query
+	 * @param holderInstantiator If the return values are expected to be wrapped
+	 * in a holder, this is the thing that knows how to wrap them.
+	 * @param session The session from which the scroll request originated.
+	 * @return The ScrollableResults instance.
+	 * @throws HibernateException Indicates an error executing the query, or constructing
+	 * the ScrollableResults.
+	 */
+	protected ScrollableResults scroll(
+	        final QueryParameters queryParameters,
+	        final Type[] returnTypes,
+	        final HolderInstantiator holderInstantiator,
+	        final SessionImplementor session) throws HibernateException {
+
+		checkScrollability();
+
+		final boolean stats = getQueryIdentifier() != null &&
+				getFactory().getStatistics().isStatisticsEnabled();
+		long startTime = 0;
+		if ( stats ) startTime = System.currentTimeMillis();
+
+		try {
+
+			PreparedStatement st = prepareQueryStatement( queryParameters, true, session );
+			ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), queryParameters.getRowSelection(), session);
+
+			if ( stats ) {
+				getFactory().getStatisticsImplementor().queryExecuted(
+						getQueryIdentifier(),
+						0,
+						System.currentTimeMillis() - startTime
+					);
+			}
+
+			if ( needsFetchingScroll() ) {
+				return new FetchingScrollableResultsImpl(
+						rs,
+						st,
+						session,
+						this,
+						queryParameters,
+						returnTypes,
+						holderInstantiator
+					);
+			}
+			else {
+				return new ScrollableResultsImpl(
+						rs,
+						st,
+						session,
+						this,
+						queryParameters,
+						returnTypes,
+						holderInstantiator
+					);
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        factory.getSQLExceptionConverter(),
+			        sqle,
+			        "could not execute query using scroll",
+			        getSQLString()
+				);
+		}
+
+	}
+
+	/**
+	 * Calculate and cache select-clause suffixes. Must be
+	 * called by subclasses after instantiation.
+	 */
+	protected void postInstantiate() {}
+
+	/**
+	 * Get the result set descriptor
+	 */
+	protected abstract EntityAliases[] getEntityAliases();
+
+	protected abstract CollectionAliases[] getCollectionAliases();
+
+	/**
+	 * Identifies the query for statistics reporting, if null,
+	 * no statistics will be reported
+	 */
+	protected String getQueryIdentifier() {
+		return null;
+	}
+
+	public final SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getSQLString() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,102 +0,0 @@
-//$Id: OuterJoinLoader.java 7124 2005-06-13 20:27:16Z oneovthafew $
-package org.hibernate.loader;
-
-import java.util.Map;
-
-import org.hibernate.LockMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.type.EntityType;
-
-/**
- * Implements logic for walking a tree of associated classes.
- *
- * Generates an SQL select string containing all properties of those classes.
- * Tables are joined using an ANSI-style left outer join.
- *
- * @author Gavin King
- */
-public abstract class OuterJoinLoader extends BasicLoader {
-
-	protected Loadable[] persisters;
-	protected CollectionPersister[] collectionPersisters;
-	protected int[] collectionOwners;
-	protected String[] aliases;
-	protected LockMode[] lockModeArray;
-	protected int[] owners;
-	protected EntityType[] ownerAssociationTypes;
-	protected String sql;
-	protected String[] suffixes;
-	protected String[] collectionSuffixes;
-
-    private Map enabledFilters;
-    
-    protected final Dialect getDialect() {
-    	return getFactory().getDialect();
-    }
-
-	public OuterJoinLoader(SessionFactoryImplementor factory, Map enabledFilters) {
-		super(factory);
-		this.enabledFilters = enabledFilters;
-	}
-
-	protected String[] getSuffixes() {
-		return suffixes;
-	}
-
-	protected String[] getCollectionSuffixes() {
-		return collectionSuffixes;
-	}
-
-	protected final String getSQLString() {
-		return sql;
-	}
-
-	protected final Loadable[] getEntityPersisters() {
-		return persisters;
-	}
-
-	protected int[] getOwners() {
-		return owners;
-	}
-
-	protected EntityType[] getOwnerAssociationTypes() {
-		return ownerAssociationTypes;
-	}
-
-	protected LockMode[] getLockModes(Map lockModes) {
-		return lockModeArray;
-	}
-	
-	public Map getEnabledFilters() {
-		return enabledFilters;
-	}
-
-	protected final String[] getAliases() {
-		return aliases;
-	}
-
-	protected final CollectionPersister[] getCollectionPersisters() {
-		return collectionPersisters;
-	}
-
-	protected final int[] getCollectionOwners() {
-		return collectionOwners;
-	}
-
-	protected void initFromWalker(JoinWalker walker) {
-		persisters = walker.getPersisters();
-		collectionPersisters = walker.getCollectionPersisters();
-		ownerAssociationTypes = walker.getOwnerAssociationTypes();
-		lockModeArray = walker.getLockModeArray();
-		suffixes = walker.getSuffixes();
-		collectionSuffixes = walker.getCollectionSuffixes();
-		owners = walker.getOwners();
-		collectionOwners = walker.getCollectionOwners();
-		sql = walker.getSQLString();
-		aliases = walker.getAliases();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,125 @@
+/*
+ * 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.loader;
+
+import java.util.Map;
+
+import org.hibernate.LockMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.type.EntityType;
+
+/**
+ * Implements logic for walking a tree of associated classes.
+ *
+ * Generates an SQL select string containing all properties of those classes.
+ * Tables are joined using an ANSI-style left outer join.
+ *
+ * @author Gavin King
+ */
+public abstract class OuterJoinLoader extends BasicLoader {
+
+	protected Loadable[] persisters;
+	protected CollectionPersister[] collectionPersisters;
+	protected int[] collectionOwners;
+	protected String[] aliases;
+	protected LockMode[] lockModeArray;
+	protected int[] owners;
+	protected EntityType[] ownerAssociationTypes;
+	protected String sql;
+	protected String[] suffixes;
+	protected String[] collectionSuffixes;
+
+    private Map enabledFilters;
+    
+    protected final Dialect getDialect() {
+    	return getFactory().getDialect();
+    }
+
+	public OuterJoinLoader(SessionFactoryImplementor factory, Map enabledFilters) {
+		super(factory);
+		this.enabledFilters = enabledFilters;
+	}
+
+	protected String[] getSuffixes() {
+		return suffixes;
+	}
+
+	protected String[] getCollectionSuffixes() {
+		return collectionSuffixes;
+	}
+
+	protected final String getSQLString() {
+		return sql;
+	}
+
+	protected final Loadable[] getEntityPersisters() {
+		return persisters;
+	}
+
+	protected int[] getOwners() {
+		return owners;
+	}
+
+	protected EntityType[] getOwnerAssociationTypes() {
+		return ownerAssociationTypes;
+	}
+
+	protected LockMode[] getLockModes(Map lockModes) {
+		return lockModeArray;
+	}
+	
+	public Map getEnabledFilters() {
+		return enabledFilters;
+	}
+
+	protected final String[] getAliases() {
+		return aliases;
+	}
+
+	protected final CollectionPersister[] getCollectionPersisters() {
+		return collectionPersisters;
+	}
+
+	protected final int[] getCollectionOwners() {
+		return collectionOwners;
+	}
+
+	protected void initFromWalker(JoinWalker walker) {
+		persisters = walker.getPersisters();
+		collectionPersisters = walker.getCollectionPersisters();
+		ownerAssociationTypes = walker.getOwnerAssociationTypes();
+		lockModeArray = walker.getLockModeArray();
+		suffixes = walker.getSuffixes();
+		collectionSuffixes = walker.getCollectionSuffixes();
+		owners = walker.getOwners();
+		collectionOwners = walker.getCollectionOwners();
+		sql = walker.getSQLString();
+		aliases = walker.getAliases();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,163 +0,0 @@
-//$Id: OuterJoinableAssociation.java 6828 2005-05-19 07:28:59Z steveebersole $
-package org.hibernate.loader;
-
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.JoinHelper;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-
-public final class OuterJoinableAssociation {
-	private final AssociationType joinableType;
-	private final Joinable joinable;
-	private final String lhsAlias; // belong to other persister
-	private final String[] lhsColumns; // belong to other persister
-	private final String rhsAlias;
-	private final String[] rhsColumns;
-	private final int joinType;
-	private final String on;
-	private final Map enabledFilters;
-
-	public OuterJoinableAssociation(
-		AssociationType joinableType,
-		String lhsAlias,
-		String[] lhsColumns,
-		String rhsAlias,
-		int joinType,
-		SessionFactoryImplementor factory,
-		Map enabledFilters)
-	throws MappingException {
-		this.joinableType = joinableType;
-		this.lhsAlias = lhsAlias;
-		this.lhsColumns = lhsColumns;
-		this.rhsAlias = rhsAlias;
-		this.joinType = joinType;
-		this.joinable = joinableType.getAssociatedJoinable(factory);
-		this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory);
-		this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters);
-		this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
-	}
-
-	public int getJoinType() {
-		return joinType;
-	}
-
-	public String getRHSAlias() {
-		return rhsAlias;
-	}
-
-	private boolean isOneToOne() {
-		if ( joinableType.isEntityType() )  {
-			EntityType etype = (EntityType) joinableType;
-			return etype.isOneToOne() /*&& etype.isReferenceToPrimaryKey()*/;
-		}
-		else {
-			return false;
-		}
-			
-	}
-	
-	public AssociationType getJoinableType() {
-		return joinableType;
-	}
-	
-	public String getRHSUniqueKeyName() {
-		return joinableType.getRHSUniqueKeyPropertyName();
-	}
-
-	public boolean isCollection() {
-		return joinableType.isCollectionType();
-	}
-
-	public Joinable getJoinable() {
-		return joinable;
-	}
-
-	public int getOwner(final List associations) {
-		if ( isOneToOne() || isCollection() ) {
-			return getPosition(lhsAlias, associations);
-		}
-		else {
-			return -1;
-		}
-	}
-
-	/**
-	 * Get the position of the join with the given alias in the
-	 * list of joins
-	 */
-	private static int getPosition(String lhsAlias, List associations) {
-		int result = 0;
-		for ( int i=0; i<associations.size(); i++ ) {
-			OuterJoinableAssociation oj = (OuterJoinableAssociation) associations.get(i);
-			if ( oj.getJoinable().consumesEntityAlias() /*|| oj.getJoinable().consumesCollectionAlias() */ ) {
-				if ( oj.rhsAlias.equals(lhsAlias) ) return result;
-				result++;
-			}
-		}
-		return -1;
-	}
-
-	public void addJoins(JoinFragment outerjoin) throws MappingException {
-		outerjoin.addJoin(
-			joinable.getTableName(),
-			rhsAlias,
-			lhsColumns,
-			rhsColumns,
-			joinType,
-			on
-		);
-		outerjoin.addJoins(
-			joinable.fromJoinFragment(rhsAlias, false, true),
-			joinable.whereJoinFragment(rhsAlias, false, true)
-		);
-	}
-
-	public void validateJoin(String path) throws MappingException {
-		if (
-			rhsColumns==null || 
-			lhsColumns==null ||
-			lhsColumns.length!=rhsColumns.length ||
-			lhsColumns.length==0
-		) {
-			throw new MappingException("invalid join columns for association: " + path);
-		}
-	}
-
-	public boolean isManyToManyWith(OuterJoinableAssociation other) {
-		if ( joinable.isCollection() ) {
-			QueryableCollection persister = ( QueryableCollection ) joinable;
-			if ( persister.isManyToMany() ) {
-				return persister.getElementType() == other.getJoinableType();
-			}
-		}
-		return false;
-	}
-
-	public void addManyToManyJoin(JoinFragment outerjoin, QueryableCollection collection) throws MappingException {
-		String manyToManyFilter = collection.getManyToManyFilterFragment( rhsAlias, enabledFilters );
-		String condition = "".equals( manyToManyFilter )
-				? on
-				: "".equals( on )
-						? manyToManyFilter
-						: on + " and " + manyToManyFilter;
-		outerjoin.addJoin(
-		        joinable.getTableName(),
-		        rhsAlias,
-		        lhsColumns,
-		        rhsColumns,
-		        joinType,
-		        condition
-		);
-		outerjoin.addJoins(
-			joinable.fromJoinFragment(rhsAlias, false, true),
-			joinable.whereJoinFragment(rhsAlias, false, true)
-		);
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/OuterJoinableAssociation.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,186 @@
+/*
+ * 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.loader;
+
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.JoinHelper;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+
+public final class OuterJoinableAssociation {
+	private final AssociationType joinableType;
+	private final Joinable joinable;
+	private final String lhsAlias; // belong to other persister
+	private final String[] lhsColumns; // belong to other persister
+	private final String rhsAlias;
+	private final String[] rhsColumns;
+	private final int joinType;
+	private final String on;
+	private final Map enabledFilters;
+
+	public OuterJoinableAssociation(
+		AssociationType joinableType,
+		String lhsAlias,
+		String[] lhsColumns,
+		String rhsAlias,
+		int joinType,
+		SessionFactoryImplementor factory,
+		Map enabledFilters)
+	throws MappingException {
+		this.joinableType = joinableType;
+		this.lhsAlias = lhsAlias;
+		this.lhsColumns = lhsColumns;
+		this.rhsAlias = rhsAlias;
+		this.joinType = joinType;
+		this.joinable = joinableType.getAssociatedJoinable(factory);
+		this.rhsColumns = JoinHelper.getRHSColumnNames(joinableType, factory);
+		this.on = joinableType.getOnCondition(rhsAlias, factory, enabledFilters);
+		this.enabledFilters = enabledFilters; // needed later for many-to-many/filter application
+	}
+
+	public int getJoinType() {
+		return joinType;
+	}
+
+	public String getRHSAlias() {
+		return rhsAlias;
+	}
+
+	private boolean isOneToOne() {
+		if ( joinableType.isEntityType() )  {
+			EntityType etype = (EntityType) joinableType;
+			return etype.isOneToOne() /*&& etype.isReferenceToPrimaryKey()*/;
+		}
+		else {
+			return false;
+		}
+			
+	}
+	
+	public AssociationType getJoinableType() {
+		return joinableType;
+	}
+	
+	public String getRHSUniqueKeyName() {
+		return joinableType.getRHSUniqueKeyPropertyName();
+	}
+
+	public boolean isCollection() {
+		return joinableType.isCollectionType();
+	}
+
+	public Joinable getJoinable() {
+		return joinable;
+	}
+
+	public int getOwner(final List associations) {
+		if ( isOneToOne() || isCollection() ) {
+			return getPosition(lhsAlias, associations);
+		}
+		else {
+			return -1;
+		}
+	}
+
+	/**
+	 * Get the position of the join with the given alias in the
+	 * list of joins
+	 */
+	private static int getPosition(String lhsAlias, List associations) {
+		int result = 0;
+		for ( int i=0; i<associations.size(); i++ ) {
+			OuterJoinableAssociation oj = (OuterJoinableAssociation) associations.get(i);
+			if ( oj.getJoinable().consumesEntityAlias() /*|| oj.getJoinable().consumesCollectionAlias() */ ) {
+				if ( oj.rhsAlias.equals(lhsAlias) ) return result;
+				result++;
+			}
+		}
+		return -1;
+	}
+
+	public void addJoins(JoinFragment outerjoin) throws MappingException {
+		outerjoin.addJoin(
+			joinable.getTableName(),
+			rhsAlias,
+			lhsColumns,
+			rhsColumns,
+			joinType,
+			on
+		);
+		outerjoin.addJoins(
+			joinable.fromJoinFragment(rhsAlias, false, true),
+			joinable.whereJoinFragment(rhsAlias, false, true)
+		);
+	}
+
+	public void validateJoin(String path) throws MappingException {
+		if (
+			rhsColumns==null || 
+			lhsColumns==null ||
+			lhsColumns.length!=rhsColumns.length ||
+			lhsColumns.length==0
+		) {
+			throw new MappingException("invalid join columns for association: " + path);
+		}
+	}
+
+	public boolean isManyToManyWith(OuterJoinableAssociation other) {
+		if ( joinable.isCollection() ) {
+			QueryableCollection persister = ( QueryableCollection ) joinable;
+			if ( persister.isManyToMany() ) {
+				return persister.getElementType() == other.getJoinableType();
+			}
+		}
+		return false;
+	}
+
+	public void addManyToManyJoin(JoinFragment outerjoin, QueryableCollection collection) throws MappingException {
+		String manyToManyFilter = collection.getManyToManyFilterFragment( rhsAlias, enabledFilters );
+		String condition = "".equals( manyToManyFilter )
+				? on
+				: "".equals( on )
+						? manyToManyFilter
+						: on + " and " + manyToManyFilter;
+		outerjoin.addJoin(
+		        joinable.getTableName(),
+		        rhsAlias,
+		        lhsColumns,
+		        rhsColumns,
+		        joinType,
+		        condition
+		);
+		outerjoin.addJoins(
+			joinable.fromJoinFragment(rhsAlias, false, true),
+			joinable.whereJoinFragment(rhsAlias, false, true)
+		);
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,167 +0,0 @@
-//$Id: BasicCollectionJoinWalker.java 9875 2006-05-04 16:23:44Z steve.ebersole at jboss.com $
-package org.hibernate.loader.collection;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.BasicLoader;
-import org.hibernate.loader.OuterJoinableAssociation;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.Select;
-import org.hibernate.type.AssociationType;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Walker for collections of values and many-to-many associations
- * 
- * @see BasicCollectionLoader
- * @author Gavin King
- */
-public class BasicCollectionJoinWalker extends CollectionJoinWalker {
-	
-	private final QueryableCollection collectionPersister;
-
-	public BasicCollectionJoinWalker(
-			QueryableCollection collectionPersister, 
-			int batchSize, 
-			String subquery, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-
-		super(factory, enabledFilters);
-
-		this.collectionPersister = collectionPersister;
-
-		String alias = generateRootAlias( collectionPersister.getRole() );
-
-		walkCollectionTree(collectionPersister, alias);
-
-		List allAssociations = new ArrayList();
-		allAssociations.addAll(associations);
-		allAssociations.add( new OuterJoinableAssociation( 
-				collectionPersister.getCollectionType(),
-				null, 
-				null, 
-				alias, 
-				JoinFragment.LEFT_OUTER_JOIN, 
-				getFactory(), 
-				CollectionHelper.EMPTY_MAP 
-			) );
-
-		initPersisters(allAssociations, LockMode.NONE);
-		initStatementString(alias, batchSize, subquery);
-
-	}
-
-	private void initStatementString(
-		final String alias,
-		final int batchSize,
-		final String subquery)
-	throws MappingException {
-
-		final int joins = countEntityPersisters( associations );
-		final int collectionJoins = countCollectionPersisters( associations ) + 1;
-
-		suffixes = BasicLoader.generateSuffixes( joins );
-		collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
-
-		StringBuffer whereString = whereString(
-				alias, 
-				collectionPersister.getKeyColumnNames(), 
-				subquery,
-				batchSize
-			);
-
-		String manyToManyOrderBy = "";
-		String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
-		if ( collectionPersister.isManyToMany() ) {
-			// from the collection of associations, locate OJA for the
-			// ManyToOne corresponding to this persister to fully
-			// define the many-to-many; we need that OJA so that we can
-			// use its alias here
-			// TODO : is there a better way here?
-			Iterator itr = associations.iterator();
-			AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
-			while ( itr.hasNext() ) {
-				OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
-				if ( oja.getJoinableType() == associationType ) {
-					// we found it
-					filter += collectionPersister.getManyToManyFilterFragment( 
-							oja.getRHSAlias(), 
-							getEnabledFilters() 
-						);
-						manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
-				}
-			}
-		}
-		whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
-
-		JoinFragment ojf = mergeOuterJoins(associations);
-		Select select = new Select( getDialect() )
-			.setSelectClause(
-				collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
-				selectString(associations)
-			)
-			.setFromClause( collectionPersister.getTableName(), alias )
-			.setWhereClause( whereString.toString()	)
-			.setOuterJoins(
-				ojf.toFromFragmentString(),
-				ojf.toWhereFragmentString()
-			);
-
-		select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "load collection " + collectionPersister.getRole() );
-		}
-
-		sql = select.toStatementString();
-	}
-
-	/**
-	 * We can use an inner join for first many-to-many association
-	 */
-	protected int getJoinType(
-			AssociationType type, 
-			FetchMode config, 
-			String path, 
-			Set visitedAssociations,
-			String lhsTable,
-			String[] lhsColumns,
-			boolean nullable,
-			int currentDepth)
-	throws MappingException {
-
-		int joinType = super.getJoinType(
-				type, 
-				config, 
-				path, 
-				lhsTable, 
-				lhsColumns, 
-				nullable, 
-				currentDepth,
-				null
-			);
-		//we can use an inner join for the many-to-many
-		if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {
-			joinType=JoinFragment.INNER_JOIN;
-		}
-		return joinType;
-	}
-	
-	public String toString() {
-		return getClass().getName() + '(' + collectionPersister.getRole() + ')';
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,190 @@
+/*
+ * 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.loader.collection;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.BasicLoader;
+import org.hibernate.loader.OuterJoinableAssociation;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.Select;
+import org.hibernate.type.AssociationType;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Walker for collections of values and many-to-many associations
+ * 
+ * @see BasicCollectionLoader
+ * @author Gavin King
+ */
+public class BasicCollectionJoinWalker extends CollectionJoinWalker {
+	
+	private final QueryableCollection collectionPersister;
+
+	public BasicCollectionJoinWalker(
+			QueryableCollection collectionPersister, 
+			int batchSize, 
+			String subquery, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+
+		super(factory, enabledFilters);
+
+		this.collectionPersister = collectionPersister;
+
+		String alias = generateRootAlias( collectionPersister.getRole() );
+
+		walkCollectionTree(collectionPersister, alias);
+
+		List allAssociations = new ArrayList();
+		allAssociations.addAll(associations);
+		allAssociations.add( new OuterJoinableAssociation( 
+				collectionPersister.getCollectionType(),
+				null, 
+				null, 
+				alias, 
+				JoinFragment.LEFT_OUTER_JOIN, 
+				getFactory(), 
+				CollectionHelper.EMPTY_MAP 
+			) );
+
+		initPersisters(allAssociations, LockMode.NONE);
+		initStatementString(alias, batchSize, subquery);
+
+	}
+
+	private void initStatementString(
+		final String alias,
+		final int batchSize,
+		final String subquery)
+	throws MappingException {
+
+		final int joins = countEntityPersisters( associations );
+		final int collectionJoins = countCollectionPersisters( associations ) + 1;
+
+		suffixes = BasicLoader.generateSuffixes( joins );
+		collectionSuffixes = BasicLoader.generateSuffixes( joins, collectionJoins );
+
+		StringBuffer whereString = whereString(
+				alias, 
+				collectionPersister.getKeyColumnNames(), 
+				subquery,
+				batchSize
+			);
+
+		String manyToManyOrderBy = "";
+		String filter = collectionPersister.filterFragment( alias, getEnabledFilters() );
+		if ( collectionPersister.isManyToMany() ) {
+			// from the collection of associations, locate OJA for the
+			// ManyToOne corresponding to this persister to fully
+			// define the many-to-many; we need that OJA so that we can
+			// use its alias here
+			// TODO : is there a better way here?
+			Iterator itr = associations.iterator();
+			AssociationType associationType = ( AssociationType ) collectionPersister.getElementType();
+			while ( itr.hasNext() ) {
+				OuterJoinableAssociation oja = ( OuterJoinableAssociation ) itr.next();
+				if ( oja.getJoinableType() == associationType ) {
+					// we found it
+					filter += collectionPersister.getManyToManyFilterFragment( 
+							oja.getRHSAlias(), 
+							getEnabledFilters() 
+						);
+						manyToManyOrderBy += collectionPersister.getManyToManyOrderByString( oja.getRHSAlias() );
+				}
+			}
+		}
+		whereString.insert( 0, StringHelper.moveAndToBeginning( filter ) );
+
+		JoinFragment ojf = mergeOuterJoins(associations);
+		Select select = new Select( getDialect() )
+			.setSelectClause(
+				collectionPersister.selectFragment(alias, collectionSuffixes[0] ) +
+				selectString(associations)
+			)
+			.setFromClause( collectionPersister.getTableName(), alias )
+			.setWhereClause( whereString.toString()	)
+			.setOuterJoins(
+				ojf.toFromFragmentString(),
+				ojf.toWhereFragmentString()
+			);
+
+		select.setOrderByClause( orderBy( associations, mergeOrderings( collectionPersister.getSQLOrderByString(alias), manyToManyOrderBy ) ) );
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "load collection " + collectionPersister.getRole() );
+		}
+
+		sql = select.toStatementString();
+	}
+
+	/**
+	 * We can use an inner join for first many-to-many association
+	 */
+	protected int getJoinType(
+			AssociationType type, 
+			FetchMode config, 
+			String path, 
+			Set visitedAssociations,
+			String lhsTable,
+			String[] lhsColumns,
+			boolean nullable,
+			int currentDepth)
+	throws MappingException {
+
+		int joinType = super.getJoinType(
+				type, 
+				config, 
+				path, 
+				lhsTable, 
+				lhsColumns, 
+				nullable, 
+				currentDepth,
+				null
+			);
+		//we can use an inner join for the many-to-many
+		if ( joinType==JoinFragment.LEFT_OUTER_JOIN && "".equals(path) ) {
+			joinType=JoinFragment.INNER_JOIN;
+		}
+		return joinType;
+	}
+	
+	public String toString() {
+		return getClass().getName() + '(' + collectionPersister.getRole() + ')';
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,67 +0,0 @@
-//$Id: BasicCollectionLoader.java 7123 2005-06-13 20:10:20Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.persister.collection.QueryableCollection;
-
-/**
- * Loads a collection of values or a many-to-many association.
- * <br>
- * The collection persister must implement <tt>QueryableCOllection<tt>. For
- * other collections, create a customized subclass of <tt>Loader</tt>.
- *
- * @see OneToManyLoader
- * @author Gavin King
- */
-public class BasicCollectionLoader extends CollectionLoader {
-
-	private static final Logger log = LoggerFactory.getLogger(BasicCollectionLoader.class);
-
-	public BasicCollectionLoader(
-			QueryableCollection collectionPersister, 
-			SessionFactoryImplementor session, 
-			Map enabledFilters)
-	throws MappingException {
-		this(collectionPersister, 1, session, enabledFilters);
-	}
-
-	public BasicCollectionLoader(
-			QueryableCollection collectionPersister, 
-			int batchSize, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-		this(collectionPersister, batchSize, null, factory, enabledFilters);
-	}
-	
-	protected BasicCollectionLoader(
-			QueryableCollection collectionPersister, 
-			int batchSize, 
-			String subquery, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-		
-		super(collectionPersister, factory, enabledFilters);
-		
-		JoinWalker walker = new BasicCollectionJoinWalker(
-				collectionPersister, 
-				batchSize, 
-				subquery, 
-				factory, 
-				enabledFilters
-			);
-		initFromWalker( walker );
-
-		postInstantiate();
-
-		log.debug( "Static select for collection " + collectionPersister.getRole() + ": " + getSQLString() );
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BasicCollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,90 @@
+/*
+ * 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.loader.collection;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.persister.collection.QueryableCollection;
+
+/**
+ * Loads a collection of values or a many-to-many association.
+ * <br>
+ * The collection persister must implement <tt>QueryableCOllection<tt>. For
+ * other collections, create a customized subclass of <tt>Loader</tt>.
+ *
+ * @see OneToManyLoader
+ * @author Gavin King
+ */
+public class BasicCollectionLoader extends CollectionLoader {
+
+	private static final Logger log = LoggerFactory.getLogger(BasicCollectionLoader.class);
+
+	public BasicCollectionLoader(
+			QueryableCollection collectionPersister, 
+			SessionFactoryImplementor session, 
+			Map enabledFilters)
+	throws MappingException {
+		this(collectionPersister, 1, session, enabledFilters);
+	}
+
+	public BasicCollectionLoader(
+			QueryableCollection collectionPersister, 
+			int batchSize, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+		this(collectionPersister, batchSize, null, factory, enabledFilters);
+	}
+	
+	protected BasicCollectionLoader(
+			QueryableCollection collectionPersister, 
+			int batchSize, 
+			String subquery, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+		
+		super(collectionPersister, factory, enabledFilters);
+		
+		JoinWalker walker = new BasicCollectionJoinWalker(
+				collectionPersister, 
+				batchSize, 
+				subquery, 
+				factory, 
+				enabledFilters
+			);
+		initFromWalker( walker );
+
+		postInstantiate();
+
+		log.debug( "Static select for collection " + collectionPersister.getRole() + ": " + getSQLString() );
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,96 +0,0 @@
-//$Id: BatchingCollectionInitializer.java 7123 2005-06-13 20:10:20Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.Loader;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * "Batch" loads collections, using multiple foreign key values in the
- * SQL <tt>where</tt> clause.
- *
- * @see BasicCollectionLoader
- * @see OneToManyLoader
- * @author Gavin King
- */
-public class BatchingCollectionInitializer implements CollectionInitializer {
-
-	private final Loader[] loaders;
-	private final int[] batchSizes;
-	private final CollectionPersister collectionPersister;
-
-	public BatchingCollectionInitializer(CollectionPersister collPersister, int[] batchSizes, Loader[] loaders) {
-		this.loaders = loaders;
-		this.batchSizes = batchSizes;
-		this.collectionPersister = collPersister;
-	}
-
-	public void initialize(Serializable id, SessionImplementor session)
-	throws HibernateException {
-		
-		Serializable[] batch = session.getPersistenceContext().getBatchFetchQueue()
-			.getCollectionBatch( collectionPersister, id, batchSizes[0], session.getEntityMode() );
-		
-		for ( int i=0; i<batchSizes.length-1; i++) {
-			final int smallBatchSize = batchSizes[i];
-			if ( batch[smallBatchSize-1]!=null ) {
-				Serializable[] smallBatch = new Serializable[smallBatchSize];
-				System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize);
-				loaders[i].loadCollectionBatch( session, smallBatch, collectionPersister.getKeyType() );
-				return; //EARLY EXIT!
-			}
-		}
-		
-		loaders[batchSizes.length-1].loadCollection( session, id, collectionPersister.getKeyType() );
-
-	}
-
-	public static CollectionInitializer createBatchingOneToManyInitializer(
-		final QueryableCollection persister,
-		final int maxBatchSize,
-		final SessionFactoryImplementor factory,
-		final Map enabledFilters)
-	throws MappingException {
-
-		if ( maxBatchSize>1 ) {
-			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
-			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
-			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
-				loadersToCreate[i] = new OneToManyLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
-			}
-			return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
-		}
-		else {
-			return new OneToManyLoader(persister, factory, enabledFilters);
-		}
-	}
-
-	public static CollectionInitializer createBatchingCollectionInitializer(
-		final QueryableCollection persister,
-		final int maxBatchSize,
-		final SessionFactoryImplementor factory,
-		final Map enabledFilters)
-	throws MappingException {
-
-		if ( maxBatchSize>1 ) {
-			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
-			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
-			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
-				loadersToCreate[i] = new BasicCollectionLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
-			}
-			return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
-		}
-		else {
-			return new BasicCollectionLoader(persister, factory, enabledFilters);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/BatchingCollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,119 @@
+/*
+ * 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.loader.collection;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.Loader;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * "Batch" loads collections, using multiple foreign key values in the
+ * SQL <tt>where</tt> clause.
+ *
+ * @see BasicCollectionLoader
+ * @see OneToManyLoader
+ * @author Gavin King
+ */
+public class BatchingCollectionInitializer implements CollectionInitializer {
+
+	private final Loader[] loaders;
+	private final int[] batchSizes;
+	private final CollectionPersister collectionPersister;
+
+	public BatchingCollectionInitializer(CollectionPersister collPersister, int[] batchSizes, Loader[] loaders) {
+		this.loaders = loaders;
+		this.batchSizes = batchSizes;
+		this.collectionPersister = collPersister;
+	}
+
+	public void initialize(Serializable id, SessionImplementor session)
+	throws HibernateException {
+		
+		Serializable[] batch = session.getPersistenceContext().getBatchFetchQueue()
+			.getCollectionBatch( collectionPersister, id, batchSizes[0], session.getEntityMode() );
+		
+		for ( int i=0; i<batchSizes.length-1; i++) {
+			final int smallBatchSize = batchSizes[i];
+			if ( batch[smallBatchSize-1]!=null ) {
+				Serializable[] smallBatch = new Serializable[smallBatchSize];
+				System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize);
+				loaders[i].loadCollectionBatch( session, smallBatch, collectionPersister.getKeyType() );
+				return; //EARLY EXIT!
+			}
+		}
+		
+		loaders[batchSizes.length-1].loadCollection( session, id, collectionPersister.getKeyType() );
+
+	}
+
+	public static CollectionInitializer createBatchingOneToManyInitializer(
+		final QueryableCollection persister,
+		final int maxBatchSize,
+		final SessionFactoryImplementor factory,
+		final Map enabledFilters)
+	throws MappingException {
+
+		if ( maxBatchSize>1 ) {
+			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
+			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
+			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
+				loadersToCreate[i] = new OneToManyLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
+			}
+			return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
+		}
+		else {
+			return new OneToManyLoader(persister, factory, enabledFilters);
+		}
+	}
+
+	public static CollectionInitializer createBatchingCollectionInitializer(
+		final QueryableCollection persister,
+		final int maxBatchSize,
+		final SessionFactoryImplementor factory,
+		final Map enabledFilters)
+	throws MappingException {
+
+		if ( maxBatchSize>1 ) {
+			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
+			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
+			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
+				loadersToCreate[i] = new BasicCollectionLoader(persister, batchSizesToCreate[i], factory, enabledFilters);
+			}
+			return new BatchingCollectionInitializer(persister, batchSizesToCreate, loadersToCreate);
+		}
+		else {
+			return new BasicCollectionLoader(persister, factory, enabledFilters);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-//$Id: CollectionInitializer.java 7123 2005-06-13 20:10:20Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * An interface for collection loaders
- * @see BasicCollectionLoader
- * @see OneToManyLoader
- * @author Gavin King
- */
-public interface CollectionInitializer {
-	/**
-	 * Initialize the given collection
-	 */
-	public void initialize(Serializable id, SessionImplementor session) throws HibernateException;
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,49 @@
+/*
+ * 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.loader.collection;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * An interface for collection loaders
+ * @see BasicCollectionLoader
+ * @see OneToManyLoader
+ * @author Gavin King
+ */
+public interface CollectionInitializer {
+	/**
+	 * Initialize the given collection
+	 */
+	public void initialize(Serializable id, SessionImplementor session) throws HibernateException;
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-//$Id: CollectionJoinWalker.java 7627 2005-07-24 06:53:06Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.util.Map;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.util.StringHelper;
-
-/**
- * Superclass of walkers for collection initializers
- * 
- * @see CollectionLoader
- * @see OneToManyJoinWalker
- * @see BasicCollectionJoinWalker
- * @author Gavin King
- */
-public abstract class CollectionJoinWalker extends JoinWalker {
-	
-	public CollectionJoinWalker(SessionFactoryImplementor factory, Map enabledFilters) {
-		super( factory, enabledFilters );
-	}
-
-	protected StringBuffer whereString(String alias, String[] columnNames, String subselect, int batchSize) {
-		if (subselect==null) {
-			return super.whereString(alias, columnNames, batchSize);
-		}
-		else {
-			StringBuffer buf = new StringBuffer();
-			if (columnNames.length>1) buf.append('(');
-			buf.append( StringHelper.join(", ", StringHelper.qualify(alias, columnNames) ) );
-			if (columnNames.length>1) buf.append(')');
-			buf.append(" in ")
-				.append('(')
-				.append(subselect) 
-				.append(')');
-			return buf;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.loader.collection;
+
+import java.util.Map;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Superclass of walkers for collection initializers
+ * 
+ * @see CollectionLoader
+ * @see OneToManyJoinWalker
+ * @see BasicCollectionJoinWalker
+ * @author Gavin King
+ */
+public abstract class CollectionJoinWalker extends JoinWalker {
+	
+	public CollectionJoinWalker(SessionFactoryImplementor factory, Map enabledFilters) {
+		super( factory, enabledFilters );
+	}
+
+	protected StringBuffer whereString(String alias, String[] columnNames, String subselect, int batchSize) {
+		if (subselect==null) {
+			return super.whereString(alias, columnNames, batchSize);
+		}
+		else {
+			StringBuffer buf = new StringBuffer();
+			if (columnNames.length>1) buf.append('(');
+			buf.append( StringHelper.join(", ", StringHelper.qualify(alias, columnNames) ) );
+			if (columnNames.length>1) buf.append(')');
+			buf.append(" in ")
+				.append('(')
+				.append(subselect) 
+				.append(')');
+			return buf;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: CollectionLoader.java 7124 2005-06-13 20:27:16Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.OuterJoinLoader;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.type.Type;
-
-/**
- * Superclass for loaders that initialize collections
- * 
- * @see OneToManyLoader
- * @see BasicCollectionLoader
- * @author Gavin King
- */
-public class CollectionLoader extends OuterJoinLoader implements CollectionInitializer {
-
-	private final QueryableCollection collectionPersister;
-
-	public CollectionLoader(QueryableCollection collectionPersister, SessionFactoryImplementor factory, Map enabledFilters) {
-		super( factory, enabledFilters );
-		this.collectionPersister = collectionPersister;
-	}
-
-	protected boolean isSubselectLoadingEnabled() {
-		return hasSubselectLoadableCollections();
-	}
-
-	public void initialize(Serializable id, SessionImplementor session)
-	throws HibernateException {
-		loadCollection( session, id, getKeyType() );
-	}
-
-	protected Type getKeyType() {
-		return collectionPersister.getKeyType();
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + collectionPersister.getRole() + ')';
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/CollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.collection;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.OuterJoinLoader;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.Type;
+
+/**
+ * Superclass for loaders that initialize collections
+ * 
+ * @see OneToManyLoader
+ * @see BasicCollectionLoader
+ * @author Gavin King
+ */
+public class CollectionLoader extends OuterJoinLoader implements CollectionInitializer {
+
+	private final QueryableCollection collectionPersister;
+
+	public CollectionLoader(QueryableCollection collectionPersister, SessionFactoryImplementor factory, Map enabledFilters) {
+		super( factory, enabledFilters );
+		this.collectionPersister = collectionPersister;
+	}
+
+	protected boolean isSubselectLoadingEnabled() {
+		return hasSubselectLoadableCollections();
+	}
+
+	public void initialize(Serializable id, SessionImplementor session)
+	throws HibernateException {
+		loadCollection( session, id, getKeyType() );
+	}
+
+	protected Type getKeyType() {
+		return collectionPersister.getKeyType();
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + collectionPersister.getRole() + ')';
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,128 +0,0 @@
-//$Id: OneToManyJoinWalker.java 7627 2005-07-24 06:53:06Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.BasicLoader;
-import org.hibernate.loader.OuterJoinableAssociation;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.Select;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Walker for one-to-many associations
- *
- * @see OneToManyLoader
- * @author Gavin King
- */
-public class OneToManyJoinWalker extends CollectionJoinWalker {
-
-	private final QueryableCollection oneToManyPersister;
-
-	protected boolean isDuplicateAssociation(
-		final String foreignKeyTable, 
-		final String[] foreignKeyColumns
-	) {
-		//disable a join back to this same association
-		final boolean isSameJoin = oneToManyPersister.getTableName().equals(foreignKeyTable) &&
-			Arrays.equals( foreignKeyColumns, oneToManyPersister.getKeyColumnNames() );
-		return isSameJoin || 
-			super.isDuplicateAssociation(foreignKeyTable, foreignKeyColumns);
-	}
-
-	public OneToManyJoinWalker(
-			QueryableCollection oneToManyPersister, 
-			int batchSize, 
-			String subquery, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-
-		super(factory, enabledFilters);
-
-		this.oneToManyPersister = oneToManyPersister;
-
-		final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister.getElementPersister();
-		final String alias = generateRootAlias( oneToManyPersister.getRole() );
-
-		walkEntityTree(elementPersister, alias);
-
-		List allAssociations = new ArrayList();
-		allAssociations.addAll(associations);
-		allAssociations.add( new OuterJoinableAssociation( 
-				oneToManyPersister.getCollectionType(),
-				null, 
-				null, 
-				alias, 
-				JoinFragment.LEFT_OUTER_JOIN, 
-				getFactory(), 
-				CollectionHelper.EMPTY_MAP 
-			) );
-		
-		initPersisters(allAssociations, LockMode.NONE);
-		initStatementString(elementPersister, alias, batchSize, subquery);
-
-	}
-
-	private void initStatementString(
-		final OuterJoinLoadable elementPersister,
-		final String alias,
-		final int batchSize,
-		final String subquery)
-	throws MappingException {
-
-		final int joins = countEntityPersisters( associations );
-		suffixes = BasicLoader.generateSuffixes( joins + 1 );
-
-		final int collectionJoins = countCollectionPersisters( associations ) + 1;
-		collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins );
-
-		StringBuffer whereString = whereString(
-				alias, 
-				oneToManyPersister.getKeyColumnNames(), 
-				subquery,
-				batchSize
-			);
-		String filter = oneToManyPersister.filterFragment( alias, getEnabledFilters() );
-		whereString.insert( 0, StringHelper.moveAndToBeginning(filter) );
-
-		JoinFragment ojf = mergeOuterJoins(associations);
-		Select select = new Select( getDialect() )
-			.setSelectClause(
-				oneToManyPersister.selectFragment(null, null, alias, suffixes[joins], collectionSuffixes[0], true) +
-				selectString(associations)
-			)
-			.setFromClause(
-				elementPersister.fromTableFragment(alias) +
-				elementPersister.fromJoinFragment(alias, true, true)
-			)
-			.setWhereClause( whereString.toString() )
-			.setOuterJoins(
-				ojf.toFromFragmentString(),
-				ojf.toWhereFragmentString() +
-				elementPersister.whereJoinFragment(alias, true, true)
-			);
-
-		select.setOrderByClause( orderBy( associations, oneToManyPersister.getSQLOrderByString(alias) ) );
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "load one-to-many " + oneToManyPersister.getRole() );
-		}
-
-		sql = select.toStatementString();
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + oneToManyPersister.getRole() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.collection;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.BasicLoader;
+import org.hibernate.loader.OuterJoinableAssociation;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.Select;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Walker for one-to-many associations
+ *
+ * @see OneToManyLoader
+ * @author Gavin King
+ */
+public class OneToManyJoinWalker extends CollectionJoinWalker {
+
+	private final QueryableCollection oneToManyPersister;
+
+	protected boolean isDuplicateAssociation(
+		final String foreignKeyTable, 
+		final String[] foreignKeyColumns
+	) {
+		//disable a join back to this same association
+		final boolean isSameJoin = oneToManyPersister.getTableName().equals(foreignKeyTable) &&
+			Arrays.equals( foreignKeyColumns, oneToManyPersister.getKeyColumnNames() );
+		return isSameJoin || 
+			super.isDuplicateAssociation(foreignKeyTable, foreignKeyColumns);
+	}
+
+	public OneToManyJoinWalker(
+			QueryableCollection oneToManyPersister, 
+			int batchSize, 
+			String subquery, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+
+		super(factory, enabledFilters);
+
+		this.oneToManyPersister = oneToManyPersister;
+
+		final OuterJoinLoadable elementPersister = (OuterJoinLoadable) oneToManyPersister.getElementPersister();
+		final String alias = generateRootAlias( oneToManyPersister.getRole() );
+
+		walkEntityTree(elementPersister, alias);
+
+		List allAssociations = new ArrayList();
+		allAssociations.addAll(associations);
+		allAssociations.add( new OuterJoinableAssociation( 
+				oneToManyPersister.getCollectionType(),
+				null, 
+				null, 
+				alias, 
+				JoinFragment.LEFT_OUTER_JOIN, 
+				getFactory(), 
+				CollectionHelper.EMPTY_MAP 
+			) );
+		
+		initPersisters(allAssociations, LockMode.NONE);
+		initStatementString(elementPersister, alias, batchSize, subquery);
+
+	}
+
+	private void initStatementString(
+		final OuterJoinLoadable elementPersister,
+		final String alias,
+		final int batchSize,
+		final String subquery)
+	throws MappingException {
+
+		final int joins = countEntityPersisters( associations );
+		suffixes = BasicLoader.generateSuffixes( joins + 1 );
+
+		final int collectionJoins = countCollectionPersisters( associations ) + 1;
+		collectionSuffixes = BasicLoader.generateSuffixes( joins + 1, collectionJoins );
+
+		StringBuffer whereString = whereString(
+				alias, 
+				oneToManyPersister.getKeyColumnNames(), 
+				subquery,
+				batchSize
+			);
+		String filter = oneToManyPersister.filterFragment( alias, getEnabledFilters() );
+		whereString.insert( 0, StringHelper.moveAndToBeginning(filter) );
+
+		JoinFragment ojf = mergeOuterJoins(associations);
+		Select select = new Select( getDialect() )
+			.setSelectClause(
+				oneToManyPersister.selectFragment(null, null, alias, suffixes[joins], collectionSuffixes[0], true) +
+				selectString(associations)
+			)
+			.setFromClause(
+				elementPersister.fromTableFragment(alias) +
+				elementPersister.fromJoinFragment(alias, true, true)
+			)
+			.setWhereClause( whereString.toString() )
+			.setOuterJoins(
+				ojf.toFromFragmentString(),
+				ojf.toWhereFragmentString() +
+				elementPersister.whereJoinFragment(alias, true, true)
+			);
+
+		select.setOrderByClause( orderBy( associations, oneToManyPersister.getSQLOrderByString(alias) ) );
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "load one-to-many " + oneToManyPersister.getRole() );
+		}
+
+		sql = select.toStatementString();
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + oneToManyPersister.getRole() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,67 +0,0 @@
-//$Id: OneToManyLoader.java 7123 2005-06-13 20:10:20Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.persister.collection.QueryableCollection;
-
-/**
- * Loads one-to-many associations<br>
- * <br>
- * The collection persister must implement <tt>QueryableCOllection<tt>. For
- * other collections, create a customized subclass of <tt>Loader</tt>.
- *
- * @see BasicCollectionLoader
- * @author Gavin King
- */
-public class OneToManyLoader extends CollectionLoader {
-
-	private static final Logger log = LoggerFactory.getLogger(OneToManyLoader.class);
-
-	public OneToManyLoader(
-			QueryableCollection oneToManyPersister, 
-			SessionFactoryImplementor session, 
-			Map enabledFilters)
-	throws MappingException {
-		this(oneToManyPersister, 1, session, enabledFilters);
-	}
-
-	public OneToManyLoader(
-			QueryableCollection oneToManyPersister, 
-			int batchSize, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-		this(oneToManyPersister, batchSize, null, factory, enabledFilters);
-	}
-
-	public OneToManyLoader(
-			QueryableCollection oneToManyPersister, 
-			int batchSize, 
-			String subquery, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-
-		super(oneToManyPersister, factory, enabledFilters);
-		
-		JoinWalker walker = new OneToManyJoinWalker(
-				oneToManyPersister, 
-				batchSize, 
-				subquery, 
-				factory, 
-				enabledFilters
-			);
-		initFromWalker( walker );
-
-		postInstantiate();
-
-		log.debug( "Static select for one-to-many " + oneToManyPersister.getRole() + ": " + getSQLString() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/OneToManyLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,90 @@
+/*
+ * 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.loader.collection;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.persister.collection.QueryableCollection;
+
+/**
+ * Loads one-to-many associations<br>
+ * <br>
+ * The collection persister must implement <tt>QueryableCOllection<tt>. For
+ * other collections, create a customized subclass of <tt>Loader</tt>.
+ *
+ * @see BasicCollectionLoader
+ * @author Gavin King
+ */
+public class OneToManyLoader extends CollectionLoader {
+
+	private static final Logger log = LoggerFactory.getLogger(OneToManyLoader.class);
+
+	public OneToManyLoader(
+			QueryableCollection oneToManyPersister, 
+			SessionFactoryImplementor session, 
+			Map enabledFilters)
+	throws MappingException {
+		this(oneToManyPersister, 1, session, enabledFilters);
+	}
+
+	public OneToManyLoader(
+			QueryableCollection oneToManyPersister, 
+			int batchSize, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+		this(oneToManyPersister, batchSize, null, factory, enabledFilters);
+	}
+
+	public OneToManyLoader(
+			QueryableCollection oneToManyPersister, 
+			int batchSize, 
+			String subquery, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+
+		super(oneToManyPersister, factory, enabledFilters);
+		
+		JoinWalker walker = new OneToManyJoinWalker(
+				oneToManyPersister, 
+				batchSize, 
+				subquery, 
+				factory, 
+				enabledFilters
+			);
+		initFromWalker( walker );
+
+		postInstantiate();
+
+		log.debug( "Static select for one-to-many " + oneToManyPersister.getRole() + ": " + getSQLString() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-//$Id: SubselectCollectionLoader.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.type.Type;
-
-/**
- * Implements subselect fetching for a collection
- * @author Gavin King
- */
-public class SubselectCollectionLoader extends BasicCollectionLoader {
-	
-	private final Serializable[] keys;
-	private final Type[] types;
-	private final Object[] values;
-	private final Map namedParameters;
-	private final Map namedParameterLocMap;
-
-	public SubselectCollectionLoader(
-			QueryableCollection persister, 
-			String subquery,
-			Collection entityKeys,
-			QueryParameters queryParameters,
-			Map namedParameterLocMap,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-		
-		super(persister, 1, subquery, factory, enabledFilters);
-
-		keys = new Serializable[ entityKeys.size() ];
-		Iterator iter = entityKeys.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
-		}
-		
-		this.namedParameters = queryParameters.getNamedParameters();
-		this.types = queryParameters.getFilteredPositionalParameterTypes();
-		this.values = queryParameters.getFilteredPositionalParameterValues();
-		this.namedParameterLocMap = namedParameterLocMap;
-		
-	}
-
-	public void initialize(Serializable id, SessionImplementor session)
-	throws HibernateException {
-		loadCollectionSubselect( 
-				session, 
-				keys, 
-				values,
-				types,
-				namedParameters,
-				getKeyType() 
-			);
-	}
-
-	public int[] getNamedParameterLocs(String name) {
-		return (int[]) namedParameterLocMap.get( name );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectCollectionLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+/*
+ * 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.loader.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.Type;
+
+/**
+ * Implements subselect fetching for a collection
+ * @author Gavin King
+ */
+public class SubselectCollectionLoader extends BasicCollectionLoader {
+	
+	private final Serializable[] keys;
+	private final Type[] types;
+	private final Object[] values;
+	private final Map namedParameters;
+	private final Map namedParameterLocMap;
+
+	public SubselectCollectionLoader(
+			QueryableCollection persister, 
+			String subquery,
+			Collection entityKeys,
+			QueryParameters queryParameters,
+			Map namedParameterLocMap,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+		
+		super(persister, 1, subquery, factory, enabledFilters);
+
+		keys = new Serializable[ entityKeys.size() ];
+		Iterator iter = entityKeys.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
+		}
+		
+		this.namedParameters = queryParameters.getNamedParameters();
+		this.types = queryParameters.getFilteredPositionalParameterTypes();
+		this.values = queryParameters.getFilteredPositionalParameterValues();
+		this.namedParameterLocMap = namedParameterLocMap;
+		
+	}
+
+	public void initialize(Serializable id, SessionImplementor session)
+	throws HibernateException {
+		loadCollectionSubselect( 
+				session, 
+				keys, 
+				values,
+				types,
+				namedParameters,
+				getKeyType() 
+			);
+	}
+
+	public int[] getNamedParameterLocs(String name) {
+		return (int[]) namedParameterLocMap.get( name );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +0,0 @@
-//$Id: SubselectOneToManyLoader.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.loader.collection;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.type.Type;
-
-/**
- * Implements subselect fetching for a one to many association
- * @author Gavin King
- */
-public class SubselectOneToManyLoader extends OneToManyLoader {
-	
-	private final Serializable[] keys;
-	private final Type[] types;
-	private final Object[] values;
-	private final Map namedParameters;
-	private final Map namedParameterLocMap;
-
-	public SubselectOneToManyLoader(
-			QueryableCollection persister, 
-			String subquery,
-			Collection entityKeys,
-			QueryParameters queryParameters,
-			Map namedParameterLocMap,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters)
-	throws MappingException {
-		
-		super(persister, 1, subquery, factory, enabledFilters);
-
-		keys = new Serializable[ entityKeys.size() ];
-		Iterator iter = entityKeys.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
-		}
-		
-		this.namedParameters = queryParameters.getNamedParameters();
-		this.types = queryParameters.getFilteredPositionalParameterTypes();
-		this.values = queryParameters.getFilteredPositionalParameterValues();
-		this.namedParameterLocMap = namedParameterLocMap;
-		
-	}
-
-	public void initialize(Serializable id, SessionImplementor session)
-	throws HibernateException {
-		loadCollectionSubselect( 
-				session, 
-				keys, 
-				values,
-				types,
-				namedParameters,
-				getKeyType() 
-			);
-	}
-
-	public int[] getNamedParameterLocs(String name) {
-		return (int[]) namedParameterLocMap.get( name );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/SubselectOneToManyLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+/*
+ * 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.loader.collection;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.type.Type;
+
+/**
+ * Implements subselect fetching for a one to many association
+ * @author Gavin King
+ */
+public class SubselectOneToManyLoader extends OneToManyLoader {
+	
+	private final Serializable[] keys;
+	private final Type[] types;
+	private final Object[] values;
+	private final Map namedParameters;
+	private final Map namedParameterLocMap;
+
+	public SubselectOneToManyLoader(
+			QueryableCollection persister, 
+			String subquery,
+			Collection entityKeys,
+			QueryParameters queryParameters,
+			Map namedParameterLocMap,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters)
+	throws MappingException {
+		
+		super(persister, 1, subquery, factory, enabledFilters);
+
+		keys = new Serializable[ entityKeys.size() ];
+		Iterator iter = entityKeys.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			keys[i++] = ( (EntityKey) iter.next() ).getIdentifier();
+		}
+		
+		this.namedParameters = queryParameters.getNamedParameters();
+		this.types = queryParameters.getFilteredPositionalParameterTypes();
+		this.values = queryParameters.getFilteredPositionalParameterValues();
+		this.namedParameterLocMap = namedParameterLocMap;
+		
+	}
+
+	public void initialize(Serializable id, SessionImplementor session)
+	throws HibernateException {
+		loadCollectionSubselect( 
+				session, 
+				keys, 
+				values,
+				types,
+				namedParameters,
+				getKeyType() 
+			);
+	}
+
+	public int[] getNamedParameterLocs(String name) {
+		return (int[]) namedParameterLocMap.get( name );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/collection/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines collection initializers
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/collection/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines collection initializers
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,182 +0,0 @@
-//$Id: CriteriaJoinWalker.java 9116 2006-01-23 21:21:01Z steveebersole $
-package org.hibernate.loader.criteria;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.Criteria;
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.loader.AbstractEntityJoinWalker;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * A <tt>JoinWalker</tt> for <tt>Criteria</tt> queries.
- *
- * @see CriteriaLoader
- * @author Gavin King
- */
-public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
-
-	//TODO: add a CriteriaImplementor interface
-	//      this class depends directly upon CriteriaImpl in the impl package...
-
-	private final CriteriaQueryTranslator translator;
-	private final Set querySpaces;
-	private final Type[] resultTypes;
-	//the user visible aliases, which are unknown to the superclass,
-	//these are not the actual "physical" SQL aliases
-	private final String[] userAliases;
-	private final List userAliasList = new ArrayList();
-
-	public Type[] getResultTypes() {
-		return resultTypes;
-	}
-
-	public String[] getUserAliases() {
-		return userAliases;
-	}
-
-	public CriteriaJoinWalker(
-			final OuterJoinLoadable persister, 
-			final CriteriaQueryTranslator translator,
-			final SessionFactoryImplementor factory, 
-			final CriteriaImpl criteria, 
-			final String rootEntityName,
-			final Map enabledFilters) {
-		this(persister, translator, factory, criteria, rootEntityName, enabledFilters, null);
-	}
-
-	public CriteriaJoinWalker(
-			final OuterJoinLoadable persister,
-			final CriteriaQueryTranslator translator,
-			final SessionFactoryImplementor factory,
-			final CriteriaImpl criteria,
-			final String rootEntityName,
-			final Map enabledFilters,
-			final String alias) {
-		super(persister, factory, enabledFilters, alias);
-
-		this.translator = translator;
-
-		querySpaces = translator.getQuerySpaces();
-
-		if ( translator.hasProjection() ) {
-			resultTypes = translator.getProjectedTypes();
-			
-			initProjection( 
-					translator.getSelect(), 
-					translator.getWhereCondition(), 
-					translator.getOrderBy(),
-					translator.getGroupBy(),
-					LockMode.NONE 
-				);
-		}
-		else {
-			resultTypes = new Type[] { TypeFactory.manyToOne( persister.getEntityName() ) };
-
-			initAll( translator.getWhereCondition(), translator.getOrderBy(), LockMode.NONE );
-		}
-		
-		userAliasList.add( criteria.getAlias() ); //root entity comes *last*
-		userAliases = ArrayHelper.toStringArray(userAliasList);
-
-	}
-
-	protected int getJoinType(
-			AssociationType type, 
-			FetchMode config, 
-			String path,
-			String lhsTable,
-			String[] lhsColumns,
-			boolean nullable,
-			int currentDepth, CascadeStyle cascadeStyle)
-	throws MappingException {
-
-		if ( translator.isJoin(path) ) {
-			return translator.getJoinType( path );
-		}
-		else {
-			if ( translator.hasProjection() ) {
-				return -1;
-			}
-			else {
-				FetchMode fetchMode = translator.getRootCriteria()
-					.getFetchMode(path);
-				if ( isDefaultFetchMode(fetchMode) ) {
-					return super.getJoinType(
-							type, 
-							config, 
-							path, 
-							lhsTable, 
-							lhsColumns, 
-							nullable,
-							currentDepth, cascadeStyle
-						);
-				}
-				else {
-					if ( fetchMode==FetchMode.JOIN ) {
-						isDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value!
-						return getJoinType(nullable, currentDepth);
-					}
-					else {
-						return -1;
-					}
-				}
-			}
-		}
-	}
-	
-	private static boolean isDefaultFetchMode(FetchMode fetchMode) {
-		return fetchMode==null || fetchMode==FetchMode.DEFAULT;
-	}
-
-	/**
-	 * Use the discriminator, to narrow the select to instances
-	 * of the queried subclass, also applying any filters.
-	 */
-	protected String getWhereFragment() throws MappingException {
-		return super.getWhereFragment() +
-			( (Queryable) getPersister() ).filterFragment( getAlias(), getEnabledFilters() );
-	}
-	
-	protected String generateTableAlias(int n, String path, Joinable joinable) {
-		if ( joinable.consumesEntityAlias() ) {
-			final Criteria subcriteria = translator.getCriteria(path);
-			String sqlAlias = subcriteria==null ? null : translator.getSQLAlias(subcriteria);
-			if (sqlAlias!=null) {
-				userAliasList.add( subcriteria.getAlias() ); //alias may be null
-				return sqlAlias; //EARLY EXIT
-			}
-			else {
-				userAliasList.add(null);
-			}
-		}
-		return super.generateTableAlias( n + translator.getSQLAliasCount(), path, joinable );
-	}
-
-	protected String generateRootAlias(String tableName) {
-		return CriteriaQueryTranslator.ROOT_SQL_ALIAS;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-	
-	public String getComment() {
-		return "criteria query";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,205 @@
+/*
+ * 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.loader.criteria;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.Criteria;
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.loader.AbstractEntityJoinWalker;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * A <tt>JoinWalker</tt> for <tt>Criteria</tt> queries.
+ *
+ * @see CriteriaLoader
+ * @author Gavin King
+ */
+public class CriteriaJoinWalker extends AbstractEntityJoinWalker {
+
+	//TODO: add a CriteriaImplementor interface
+	//      this class depends directly upon CriteriaImpl in the impl package...
+
+	private final CriteriaQueryTranslator translator;
+	private final Set querySpaces;
+	private final Type[] resultTypes;
+	//the user visible aliases, which are unknown to the superclass,
+	//these are not the actual "physical" SQL aliases
+	private final String[] userAliases;
+	private final List userAliasList = new ArrayList();
+
+	public Type[] getResultTypes() {
+		return resultTypes;
+	}
+
+	public String[] getUserAliases() {
+		return userAliases;
+	}
+
+	public CriteriaJoinWalker(
+			final OuterJoinLoadable persister, 
+			final CriteriaQueryTranslator translator,
+			final SessionFactoryImplementor factory, 
+			final CriteriaImpl criteria, 
+			final String rootEntityName,
+			final Map enabledFilters) {
+		this(persister, translator, factory, criteria, rootEntityName, enabledFilters, null);
+	}
+
+	public CriteriaJoinWalker(
+			final OuterJoinLoadable persister,
+			final CriteriaQueryTranslator translator,
+			final SessionFactoryImplementor factory,
+			final CriteriaImpl criteria,
+			final String rootEntityName,
+			final Map enabledFilters,
+			final String alias) {
+		super(persister, factory, enabledFilters, alias);
+
+		this.translator = translator;
+
+		querySpaces = translator.getQuerySpaces();
+
+		if ( translator.hasProjection() ) {
+			resultTypes = translator.getProjectedTypes();
+			
+			initProjection( 
+					translator.getSelect(), 
+					translator.getWhereCondition(), 
+					translator.getOrderBy(),
+					translator.getGroupBy(),
+					LockMode.NONE 
+				);
+		}
+		else {
+			resultTypes = new Type[] { TypeFactory.manyToOne( persister.getEntityName() ) };
+
+			initAll( translator.getWhereCondition(), translator.getOrderBy(), LockMode.NONE );
+		}
+		
+		userAliasList.add( criteria.getAlias() ); //root entity comes *last*
+		userAliases = ArrayHelper.toStringArray(userAliasList);
+
+	}
+
+	protected int getJoinType(
+			AssociationType type, 
+			FetchMode config, 
+			String path,
+			String lhsTable,
+			String[] lhsColumns,
+			boolean nullable,
+			int currentDepth, CascadeStyle cascadeStyle)
+	throws MappingException {
+
+		if ( translator.isJoin(path) ) {
+			return translator.getJoinType( path );
+		}
+		else {
+			if ( translator.hasProjection() ) {
+				return -1;
+			}
+			else {
+				FetchMode fetchMode = translator.getRootCriteria()
+					.getFetchMode(path);
+				if ( isDefaultFetchMode(fetchMode) ) {
+					return super.getJoinType(
+							type, 
+							config, 
+							path, 
+							lhsTable, 
+							lhsColumns, 
+							nullable,
+							currentDepth, cascadeStyle
+						);
+				}
+				else {
+					if ( fetchMode==FetchMode.JOIN ) {
+						isDuplicateAssociation(lhsTable, lhsColumns, type); //deliberately ignore return value!
+						return getJoinType(nullable, currentDepth);
+					}
+					else {
+						return -1;
+					}
+				}
+			}
+		}
+	}
+	
+	private static boolean isDefaultFetchMode(FetchMode fetchMode) {
+		return fetchMode==null || fetchMode==FetchMode.DEFAULT;
+	}
+
+	/**
+	 * Use the discriminator, to narrow the select to instances
+	 * of the queried subclass, also applying any filters.
+	 */
+	protected String getWhereFragment() throws MappingException {
+		return super.getWhereFragment() +
+			( (Queryable) getPersister() ).filterFragment( getAlias(), getEnabledFilters() );
+	}
+	
+	protected String generateTableAlias(int n, String path, Joinable joinable) {
+		if ( joinable.consumesEntityAlias() ) {
+			final Criteria subcriteria = translator.getCriteria(path);
+			String sqlAlias = subcriteria==null ? null : translator.getSQLAlias(subcriteria);
+			if (sqlAlias!=null) {
+				userAliasList.add( subcriteria.getAlias() ); //alias may be null
+				return sqlAlias; //EARLY EXIT
+			}
+			else {
+				userAliasList.add(null);
+			}
+		}
+		return super.generateTableAlias( n + translator.getSQLAliasCount(), path, joinable );
+	}
+
+	protected String generateRootAlias(String tableName) {
+		return CriteriaQueryTranslator.ROOT_SQL_ALIAS;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+	
+	public String getComment() {
+		return "criteria query";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,169 +0,0 @@
-//$Id: CriteriaLoader.java 11320 2007-03-20 11:50:53Z steve.ebersole at jboss.com $
-package org.hibernate.loader.criteria;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollMode;
-import org.hibernate.ScrollableResults;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.loader.OuterJoinLoader;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-
-/**
- * A <tt>Loader</tt> for <tt>Criteria</tt> queries. Note that criteria queries are
- * more like multi-object <tt>load()</tt>s than like HQL queries.
- *
- * @author Gavin King
- */
-public class CriteriaLoader extends OuterJoinLoader {
-
-	//TODO: this class depends directly upon CriteriaImpl, 
-	//      in the impl package ... add a CriteriaImplementor 
-	//      interface
-
-	//NOTE: unlike all other Loaders, this one is NOT
-	//      multithreaded, or cacheable!!
-
-	private final CriteriaQueryTranslator translator;
-	private final Set querySpaces;
-	private final Type[] resultTypes;
-	//the user visible aliases, which are unknown to the superclass,
-	//these are not the actual "physical" SQL aliases
-	private final String[] userAliases;
-
-	public CriteriaLoader(
-			final OuterJoinLoadable persister, 
-			final SessionFactoryImplementor factory, 
-			final CriteriaImpl criteria, 
-			final String rootEntityName,
-			final Map enabledFilters)
-	throws HibernateException {
-		super(factory, enabledFilters);
-
-		translator = new CriteriaQueryTranslator(
-				factory, 
-				criteria, 
-				rootEntityName, 
-				CriteriaQueryTranslator.ROOT_SQL_ALIAS
-			);
-
-		querySpaces = translator.getQuerySpaces();
-		
-		CriteriaJoinWalker walker = new CriteriaJoinWalker(
-				persister, 
-				translator,
-				factory, 
-				criteria, 
-				rootEntityName, 
-				enabledFilters
-			);
-
-		initFromWalker(walker);
-		
-		userAliases = walker.getUserAliases();
-		resultTypes = walker.getResultTypes();
-
-		postInstantiate();
-
-	}
-	
-	public ScrollableResults scroll(SessionImplementor session, ScrollMode scrollMode) 
-	throws HibernateException {
-		QueryParameters qp = translator.getQueryParameters();
-		qp.setScrollMode(scrollMode);
-		return scroll(qp, resultTypes, null, session);
-	}
-
-	public List list(SessionImplementor session) 
-	throws HibernateException {
-		return list( session, translator.getQueryParameters(), querySpaces, resultTypes );
-
-	}
-
-	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
-	throws SQLException, HibernateException {
-		final Object[] result;
-		final String[] aliases;
-		if ( translator.hasProjection() ) {
-			Type[] types = translator.getProjectedTypes();
-			result = new Object[types.length];
-			String[] columnAliases = translator.getProjectedColumnAliases();
-			for ( int i=0; i<result.length; i++ ) {
-				result[i] = types[i].nullSafeGet(rs, columnAliases[i], session, null);
-			}
-			aliases = translator.getProjectedAliases();
-		}
-		else {
-			result = row;
-			aliases = userAliases;
-		}
-		return translator.getRootCriteria().getResultTransformer()
-				.transformTuple(result, aliases);
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	protected String applyLocks(String sqlSelectString, Map lockModes, Dialect dialect) throws QueryException {
-		if ( lockModes == null || lockModes.isEmpty() ) {
-			return sqlSelectString;
-		}
-
-		final Map aliasedLockModes = new HashMap();
-		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
-		final String[] drivingSqlAliases = getAliases();
-		for ( int i = 0; i < drivingSqlAliases.length; i++ ) {
-			final LockMode lockMode = ( LockMode ) lockModes.get( drivingSqlAliases[i] );
-			if ( lockMode != null ) {
-				final Lockable drivingPersister = ( Lockable ) getEntityPersisters()[i];
-				final String rootSqlAlias = drivingPersister.getRootTableAlias( drivingSqlAliases[i] );
-				aliasedLockModes.put( rootSqlAlias, lockMode );
-				if ( keyColumnNames != null ) {
-					keyColumnNames.put( rootSqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
-				}
-			}
-		}
-		return dialect.applyLocksToSql( sqlSelectString, aliasedLockModes, keyColumnNames );
-	}
-
-	protected LockMode[] getLockModes(Map lockModes) {
-		final String[] entityAliases = getAliases();
-		if ( entityAliases == null ) {
-			return null;
-		}
-		final int size = entityAliases.length;
-		LockMode[] lockModesArray = new LockMode[size];
-		for ( int i=0; i<size; i++ ) {
-			LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] );
-			lockModesArray[i] = lockMode==null ? LockMode.NONE : lockMode;
-		}
-		return lockModesArray;
-	}
-
-	protected boolean isSubselectLoadingEnabled() {
-		return hasSubselectLoadableCollections();
-	}
-	
-	protected List getResultList(List results, ResultTransformer resultTransformer) {
-		return translator.getRootCriteria().getResultTransformer().transformList( results );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,191 @@
+/*
+ * 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.loader.criteria;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollMode;
+import org.hibernate.ScrollableResults;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.loader.OuterJoinLoader;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+
+/**
+ * A <tt>Loader</tt> for <tt>Criteria</tt> queries. Note that criteria queries are
+ * more like multi-object <tt>load()</tt>s than like HQL queries.
+ *
+ * @author Gavin King
+ */
+public class CriteriaLoader extends OuterJoinLoader {
+
+	//TODO: this class depends directly upon CriteriaImpl, 
+	//      in the impl package ... add a CriteriaImplementor 
+	//      interface
+
+	//NOTE: unlike all other Loaders, this one is NOT
+	//      multithreaded, or cacheable!!
+
+	private final CriteriaQueryTranslator translator;
+	private final Set querySpaces;
+	private final Type[] resultTypes;
+	//the user visible aliases, which are unknown to the superclass,
+	//these are not the actual "physical" SQL aliases
+	private final String[] userAliases;
+
+	public CriteriaLoader(
+			final OuterJoinLoadable persister, 
+			final SessionFactoryImplementor factory, 
+			final CriteriaImpl criteria, 
+			final String rootEntityName,
+			final Map enabledFilters)
+	throws HibernateException {
+		super(factory, enabledFilters);
+
+		translator = new CriteriaQueryTranslator(
+				factory, 
+				criteria, 
+				rootEntityName, 
+				CriteriaQueryTranslator.ROOT_SQL_ALIAS
+			);
+
+		querySpaces = translator.getQuerySpaces();
+		
+		CriteriaJoinWalker walker = new CriteriaJoinWalker(
+				persister, 
+				translator,
+				factory, 
+				criteria, 
+				rootEntityName, 
+				enabledFilters
+			);
+
+		initFromWalker(walker);
+		
+		userAliases = walker.getUserAliases();
+		resultTypes = walker.getResultTypes();
+
+		postInstantiate();
+
+	}
+	
+	public ScrollableResults scroll(SessionImplementor session, ScrollMode scrollMode) 
+	throws HibernateException {
+		QueryParameters qp = translator.getQueryParameters();
+		qp.setScrollMode(scrollMode);
+		return scroll(qp, resultTypes, null, session);
+	}
+
+	public List list(SessionImplementor session) 
+	throws HibernateException {
+		return list( session, translator.getQueryParameters(), querySpaces, resultTypes );
+
+	}
+
+	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
+	throws SQLException, HibernateException {
+		final Object[] result;
+		final String[] aliases;
+		if ( translator.hasProjection() ) {
+			Type[] types = translator.getProjectedTypes();
+			result = new Object[types.length];
+			String[] columnAliases = translator.getProjectedColumnAliases();
+			for ( int i=0; i<result.length; i++ ) {
+				result[i] = types[i].nullSafeGet(rs, columnAliases[i], session, null);
+			}
+			aliases = translator.getProjectedAliases();
+		}
+		else {
+			result = row;
+			aliases = userAliases;
+		}
+		return translator.getRootCriteria().getResultTransformer()
+				.transformTuple(result, aliases);
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	protected String applyLocks(String sqlSelectString, Map lockModes, Dialect dialect) throws QueryException {
+		if ( lockModes == null || lockModes.isEmpty() ) {
+			return sqlSelectString;
+		}
+
+		final Map aliasedLockModes = new HashMap();
+		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
+		final String[] drivingSqlAliases = getAliases();
+		for ( int i = 0; i < drivingSqlAliases.length; i++ ) {
+			final LockMode lockMode = ( LockMode ) lockModes.get( drivingSqlAliases[i] );
+			if ( lockMode != null ) {
+				final Lockable drivingPersister = ( Lockable ) getEntityPersisters()[i];
+				final String rootSqlAlias = drivingPersister.getRootTableAlias( drivingSqlAliases[i] );
+				aliasedLockModes.put( rootSqlAlias, lockMode );
+				if ( keyColumnNames != null ) {
+					keyColumnNames.put( rootSqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
+				}
+			}
+		}
+		return dialect.applyLocksToSql( sqlSelectString, aliasedLockModes, keyColumnNames );
+	}
+
+	protected LockMode[] getLockModes(Map lockModes) {
+		final String[] entityAliases = getAliases();
+		if ( entityAliases == null ) {
+			return null;
+		}
+		final int size = entityAliases.length;
+		LockMode[] lockModesArray = new LockMode[size];
+		for ( int i=0; i<size; i++ ) {
+			LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] );
+			lockModesArray[i] = lockMode==null ? LockMode.NONE : lockMode;
+		}
+		return lockModesArray;
+	}
+
+	protected boolean isSubselectLoadingEnabled() {
+		return hasSubselectLoadableCollections();
+	}
+	
+	protected List getResultList(List results, ResultTransformer resultTransformer) {
+		return translator.getRootCriteria().getResultTransformer().transformList( results );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,556 +0,0 @@
-//$Id: CriteriaQueryTranslator.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.loader.criteria;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.StringTokenizer;
-import java.util.LinkedHashMap;
-
-import org.hibernate.Criteria;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.hql.ast.util.SessionFactoryHelper;
-import org.hibernate.criterion.CriteriaQuery;
-import org.hibernate.criterion.Projection;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.RowSelection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.impl.CriteriaImpl;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.type.NullableType;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Gavin King
- */
-public class CriteriaQueryTranslator implements CriteriaQuery {
-
-	public static final String ROOT_SQL_ALIAS = Criteria.ROOT_ALIAS + '_';
-
-	private CriteriaQuery outerQueryTranslator;
-
-	private final CriteriaImpl rootCriteria;
-	private final String rootEntityName;
-	private final String rootSQLAlias;
-	private int aliasCount = 0;
-
-	private final Map criteriaEntityNames = new LinkedHashMap();
-	private final Map criteriaSQLAliasMap = new HashMap();
-	private final Map aliasCriteriaMap = new HashMap();
-	private final Map associationPathCriteriaMap = new LinkedHashMap();
-	private final Map associationPathJoinTypesMap = new LinkedHashMap();
-
-	private final SessionFactoryImplementor sessionFactory;
-
-	public CriteriaQueryTranslator(
-			final SessionFactoryImplementor factory,
-	        final CriteriaImpl criteria,
-	        final String rootEntityName,
-	        final String rootSQLAlias,
-	        CriteriaQuery outerQuery) throws HibernateException {
-		this( factory, criteria, rootEntityName, rootSQLAlias );
-		outerQueryTranslator = outerQuery;
-	}
-
-	public CriteriaQueryTranslator(
-			final SessionFactoryImplementor factory,
-	        final CriteriaImpl criteria,
-	        final String rootEntityName,
-	        final String rootSQLAlias) throws HibernateException {
-		this.rootCriteria = criteria;
-		this.rootEntityName = rootEntityName;
-		this.sessionFactory = factory;
-		this.rootSQLAlias = rootSQLAlias;
-		createAliasCriteriaMap();
-		createAssociationPathCriteriaMap();
-		createCriteriaEntityNameMap();
-		createCriteriaSQLAliasMap();
-	}
-
-	public String generateSQLAlias() {
-		return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_';
-	}
-
-	public String getRootSQLALias() {
-		return rootSQLAlias;
-	}
-
-	private Criteria getAliasedCriteria(String alias) {
-		return ( Criteria ) aliasCriteriaMap.get( alias );
-	}
-
-	public boolean isJoin(String path) {
-		return associationPathCriteriaMap.containsKey( path );
-	}
-
-	public int getJoinType(String path) {
-		Integer result = ( Integer ) associationPathJoinTypesMap.get( path );
-		return ( result == null ? Criteria.INNER_JOIN : result.intValue() );
-	}
-
-	public Criteria getCriteria(String path) {
-		return ( Criteria ) associationPathCriteriaMap.get( path );
-	}
-
-	public Set getQuerySpaces() {
-		Set result = new HashSet();
-		Iterator iter = criteriaEntityNames.values().iterator();
-		while ( iter.hasNext() ) {
-			String entityName = ( String ) iter.next();
-			result.addAll( Arrays.asList( getFactory().getEntityPersister( entityName ).getQuerySpaces() ) );
-		}
-		return result;
-	}
-
-	private void createAliasCriteriaMap() {
-		aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria );
-		Iterator iter = rootCriteria.iterateSubcriteria();
-		while ( iter.hasNext() ) {
-			Criteria subcriteria = ( Criteria ) iter.next();
-			if ( subcriteria.getAlias() != null ) {
-				Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria );
-				if ( old != null ) {
-					throw new QueryException( "duplicate alias: " + subcriteria.getAlias() );
-				}
-			}
-		}
-	}
-
-	private void createAssociationPathCriteriaMap() {
-		Iterator iter = rootCriteria.iterateSubcriteria();
-		while ( iter.hasNext() ) {
-			CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next();
-			String wholeAssociationPath = getWholeAssociationPath( crit );
-			Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit );
-			if ( old != null ) {
-				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
-			}
-			int joinType = crit.getJoinType();
-			old = associationPathJoinTypesMap.put( wholeAssociationPath, new Integer( joinType ) );
-			if ( old != null ) {
-				// TODO : not so sure this is needed...
-				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
-			}
-		}
-	}
-
-	private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) {
-		String path = subcriteria.getPath();
-
-		// some messy, complex stuff here, since createCriteria() can take an
-		// aliased path, or a path rooted at the creating criteria instance
-		Criteria parent = null;
-		if ( path.indexOf( '.' ) > 0 ) {
-			// if it is a compound path
-			String testAlias = StringHelper.root( path );
-			if ( !testAlias.equals( subcriteria.getAlias() ) ) {
-				// and the qualifier is not the alias of this criteria
-				//      -> check to see if we belong to some criteria other
-				//          than the one that created us
-				parent = ( Criteria ) aliasCriteriaMap.get( testAlias );
-			}
-		}
-		if ( parent == null ) {
-			// otherwise assume the parent is the the criteria that created us
-			parent = subcriteria.getParent();
-		}
-		else {
-			path = StringHelper.unroot( path );
-		}
-
-		if ( parent.equals( rootCriteria ) ) {
-			// if its the root criteria, we are done
-			return path;
-		}
-		else {
-			// otherwise, recurse
-			return getWholeAssociationPath( ( CriteriaImpl.Subcriteria ) parent ) + '.' + path;
-		}
-	}
-
-	private void createCriteriaEntityNameMap() {
-		criteriaEntityNames.put( rootCriteria, rootEntityName );
-		Iterator iter = associationPathCriteriaMap.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) iter.next();
-			criteriaEntityNames.put(
-					me.getValue(), //the criteria instance
-			        getPathEntityName( ( String ) me.getKey() )
-			);
-		}
-	}
-
-	private String getPathEntityName(String path) {
-		Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName );
-		StringTokenizer tokens = new StringTokenizer( path, "." );
-		String componentPath = "";
-		while ( tokens.hasMoreTokens() ) {
-			componentPath += tokens.nextToken();
-			Type type = persister.toType( componentPath );
-			if ( type.isAssociationType() ) {
-				AssociationType atype = ( AssociationType ) type;
-				persister = ( Queryable ) sessionFactory.getEntityPersister(
-						atype.getAssociatedEntityName( sessionFactory )
-				);
-				componentPath = "";
-			}
-			else if ( type.isComponentType() ) {
-				componentPath += '.';
-			}
-			else {
-				throw new QueryException( "not an association: " + componentPath );
-			}
-		}
-		return persister.getEntityName();
-	}
-
-	public int getSQLAliasCount() {
-		return criteriaSQLAliasMap.size();
-	}
-
-	private void createCriteriaSQLAliasMap() {
-		int i = 0;
-		Iterator criteriaIterator = criteriaEntityNames.entrySet().iterator();
-		while ( criteriaIterator.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) criteriaIterator.next();
-			Criteria crit = ( Criteria ) me.getKey();
-			String alias = crit.getAlias();
-			if ( alias == null ) {
-				alias = ( String ) me.getValue(); // the entity name
-			}
-			criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) );
-		}
-		criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias );
-	}
-
-	public CriteriaImpl getRootCriteria() {
-		return rootCriteria;
-	}
-
-	public QueryParameters getQueryParameters() {
-		List values = new ArrayList();
-		List types = new ArrayList();
-		Iterator iter = rootCriteria.iterateExpressionEntries();
-		while ( iter.hasNext() ) {
-			CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next();
-			TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
-			for ( int i = 0; i < tv.length; i++ ) {
-				values.add( tv[i].getValue() );
-				types.add( tv[i].getType() );
-			}
-		}
-		Object[] valueArray = values.toArray();
-		Type[] typeArray = ArrayHelper.toTypeArray( types );
-
-		RowSelection selection = new RowSelection();
-		selection.setFirstRow( rootCriteria.getFirstResult() );
-		selection.setMaxRows( rootCriteria.getMaxResults() );
-		selection.setTimeout( rootCriteria.getTimeout() );
-		selection.setFetchSize( rootCriteria.getFetchSize() );
-
-		Map lockModes = new HashMap();
-		iter = rootCriteria.getLockModes().entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) iter.next();
-			final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() );
-			lockModes.put( getSQLAlias( subcriteria ), me.getValue() );
-		}
-		iter = rootCriteria.iterateSubcriteria();
-		while ( iter.hasNext() ) {
-			CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next();
-			LockMode lm = subcriteria.getLockMode();
-			if ( lm != null ) {
-				lockModes.put( getSQLAlias( subcriteria ), lm );
-			}
-		}
-
-		return new QueryParameters(
-				typeArray,
-		        valueArray,
-		        lockModes,
-		        selection,
-		        rootCriteria.getCacheable(),
-		        rootCriteria.getCacheRegion(),
-		        rootCriteria.getComment(),
-		        rootCriteria.isLookupByNaturalKey(),
-		        rootCriteria.getResultTransformer()
-		);
-	}
-
-	public boolean hasProjection() {
-		return rootCriteria.getProjection() != null;
-	}
-
-	public String getGroupBy() {
-		if ( rootCriteria.getProjection().isGrouped() ) {
-			return rootCriteria.getProjection()
-					.toGroupSqlString( rootCriteria.getProjectionCriteria(), this );
-		}
-		else {
-			return "";
-		}
-	}
-
-	public String getSelect() {
-		return rootCriteria.getProjection().toSqlString(
-				rootCriteria.getProjectionCriteria(),
-		        0,
-		        this
-		);
-	}
-
-	public Type[] getProjectedTypes() {
-		return rootCriteria.getProjection().getTypes( rootCriteria, this );
-	}
-
-	public String[] getProjectedColumnAliases() {
-		return rootCriteria.getProjection().getColumnAliases( 0 );
-	}
-
-	public String[] getProjectedAliases() {
-		return rootCriteria.getProjection().getAliases();
-	}
-
-	public String getWhereCondition() {
-		StringBuffer condition = new StringBuffer( 30 );
-		Iterator criterionIterator = rootCriteria.iterateExpressionEntries();
-		while ( criterionIterator.hasNext() ) {
-			CriteriaImpl.CriterionEntry entry = ( CriteriaImpl.CriterionEntry ) criterionIterator.next();
-			String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this );
-			condition.append( sqlString );
-			if ( criterionIterator.hasNext() ) {
-				condition.append( " and " );
-			}
-		}
-		return condition.toString();
-	}
-
-	public String getOrderBy() {
-		StringBuffer orderBy = new StringBuffer( 30 );
-		Iterator criterionIterator = rootCriteria.iterateOrderings();
-		while ( criterionIterator.hasNext() ) {
-			CriteriaImpl.OrderEntry oe = ( CriteriaImpl.OrderEntry ) criterionIterator.next();
-			orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) );
-			if ( criterionIterator.hasNext() ) {
-				orderBy.append( ", " );
-			}
-		}
-		return orderBy.toString();
-	}
-
-	public SessionFactoryImplementor getFactory() {
-		return sessionFactory;
-	}
-
-	public String getSQLAlias(Criteria criteria) {
-		return ( String ) criteriaSQLAliasMap.get( criteria );
-	}
-
-	public String getEntityName(Criteria criteria) {
-		return ( String ) criteriaEntityNames.get( criteria );
-	}
-
-	public String getColumn(Criteria criteria, String propertyName) {
-		String[] cols = getColumns( propertyName, criteria );
-		if ( cols.length != 1 ) {
-			throw new QueryException( "property does not map to a single column: " + propertyName );
-		}
-		return cols[0];
-	}
-
-	/**
-	 * Get the names of the columns constrained
-	 * by this criterion.
-	 */
-	public String[] getColumnsUsingProjection(
-			Criteria subcriteria,
-	        String propertyName) throws HibernateException {
-
-		//first look for a reference to a projection alias
-		final Projection projection = rootCriteria.getProjection();
-		String[] projectionColumns = projection == null ?
-		                             null :
-		                             projection.getColumnAliases( propertyName, 0 );
-
-		if ( projectionColumns == null ) {
-			//it does not refer to an alias of a projection,
-			//look for a property
-			try {
-				return getColumns( propertyName, subcriteria );
-			}
-			catch ( HibernateException he ) {
-				//not found in inner query , try the outer query
-				if ( outerQueryTranslator != null ) {
-					return outerQueryTranslator.getColumnsUsingProjection( subcriteria, propertyName );
-				}
-				else {
-					throw he;
-				}
-			}
-		}
-		else {
-			//it refers to an alias of a projection
-			return projectionColumns;
-		}
-	}
-
-	public String[] getIdentifierColumns(Criteria subcriteria) {
-		String[] idcols =
-				( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierColumnNames();
-		return StringHelper.qualify( getSQLAlias( subcriteria ), idcols );
-	}
-
-	public Type getIdentifierType(Criteria subcriteria) {
-		return ( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierType();
-	}
-
-	public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value) {
-		final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) );
-		return new TypedValue(
-				loadable.getIdentifierType(),
-		        value,
-		        EntityMode.POJO
-		);
-	}
-
-	private String[] getColumns(
-			String propertyName,
-	        Criteria subcriteria) throws HibernateException {
-		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
-				.toColumns(
-						getSQLAlias( subcriteria, propertyName ),
-				        getPropertyName( propertyName )
-				);
-	}
-
-	public Type getTypeUsingProjection(Criteria subcriteria, String propertyName)
-			throws HibernateException {
-
-		//first look for a reference to a projection alias
-		final Projection projection = rootCriteria.getProjection();
-		Type[] projectionTypes = projection == null ?
-		                         null :
-		                         projection.getTypes( propertyName, subcriteria, this );
-
-		if ( projectionTypes == null ) {
-			try {
-				//it does not refer to an alias of a projection,
-				//look for a property
-				return getType( subcriteria, propertyName );
-			}
-			catch ( HibernateException he ) {
-				//not found in inner query , try the outer query
-				if ( outerQueryTranslator != null ) {
-					return outerQueryTranslator.getType( subcriteria, propertyName );
-				}
-				else {
-					throw he;
-				}
-			}
-		}
-		else {
-			if ( projectionTypes.length != 1 ) {
-				//should never happen, i think
-				throw new QueryException( "not a single-length projection: " + propertyName );
-			}
-			return projectionTypes[0];
-		}
-	}
-
-	public Type getType(Criteria subcriteria, String propertyName)
-			throws HibernateException {
-		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
-				.toType( getPropertyName( propertyName ) );
-	}
-
-	/**
-	 * Get the a typed value for the given property value.
-	 */
-	public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value)
-			throws HibernateException {
-		// Detect discriminator values...
-		if ( value instanceof Class ) {
-			Class entityClass = ( Class ) value;
-			Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() );
-			if ( q != null ) {
-				Type type = q.getDiscriminatorType();
-				String stringValue = q.getDiscriminatorSQLValue();
-				// Convert the string value into the proper type.
-				if ( type instanceof NullableType ) {
-					NullableType nullableType = ( NullableType ) type;
-					value = nullableType.fromStringValue( stringValue );
-				}
-				else {
-					throw new QueryException( "Unsupported discriminator type " + type );
-				}
-				return new TypedValue(
-						type,
-				        value,
-				        EntityMode.POJO
-				);
-			}
-		}
-		// Otherwise, this is an ordinary value.
-		return new TypedValue(
-				getTypeUsingProjection( subcriteria, propertyName ),
-		        value,
-		        EntityMode.POJO
-		);
-	}
-
-	private PropertyMapping getPropertyMapping(String entityName)
-			throws MappingException {
-		return ( PropertyMapping ) sessionFactory.getEntityPersister( entityName );
-	}
-
-	//TODO: use these in methods above
-
-	public String getEntityName(Criteria subcriteria, String propertyName) {
-		if ( propertyName.indexOf( '.' ) > 0 ) {
-			String root = StringHelper.root( propertyName );
-			Criteria crit = getAliasedCriteria( root );
-			if ( crit != null ) {
-				return getEntityName( crit );
-			}
-		}
-		return getEntityName( subcriteria );
-	}
-
-	public String getSQLAlias(Criteria criteria, String propertyName) {
-		if ( propertyName.indexOf( '.' ) > 0 ) {
-			String root = StringHelper.root( propertyName );
-			Criteria subcriteria = getAliasedCriteria( root );
-			if ( subcriteria != null ) {
-				return getSQLAlias( subcriteria );
-			}
-		}
-		return getSQLAlias( criteria );
-	}
-
-	public String getPropertyName(String propertyName) {
-		if ( propertyName.indexOf( '.' ) > 0 ) {
-			String root = StringHelper.root( propertyName );
-			Criteria crit = getAliasedCriteria( root );
-			if ( crit != null ) {
-				return propertyName.substring( root.length() + 1 );
-			}
-		}
-		return propertyName;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/CriteriaQueryTranslator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,579 @@
+/*
+ * 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.loader.criteria;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.LinkedHashMap;
+
+import org.hibernate.Criteria;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.hql.ast.util.SessionFactoryHelper;
+import org.hibernate.criterion.CriteriaQuery;
+import org.hibernate.criterion.Projection;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.RowSelection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.impl.CriteriaImpl;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.NullableType;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Gavin King
+ */
+public class CriteriaQueryTranslator implements CriteriaQuery {
+
+	public static final String ROOT_SQL_ALIAS = Criteria.ROOT_ALIAS + '_';
+
+	private CriteriaQuery outerQueryTranslator;
+
+	private final CriteriaImpl rootCriteria;
+	private final String rootEntityName;
+	private final String rootSQLAlias;
+	private int aliasCount = 0;
+
+	private final Map criteriaEntityNames = new LinkedHashMap();
+	private final Map criteriaSQLAliasMap = new HashMap();
+	private final Map aliasCriteriaMap = new HashMap();
+	private final Map associationPathCriteriaMap = new LinkedHashMap();
+	private final Map associationPathJoinTypesMap = new LinkedHashMap();
+
+	private final SessionFactoryImplementor sessionFactory;
+
+	public CriteriaQueryTranslator(
+			final SessionFactoryImplementor factory,
+	        final CriteriaImpl criteria,
+	        final String rootEntityName,
+	        final String rootSQLAlias,
+	        CriteriaQuery outerQuery) throws HibernateException {
+		this( factory, criteria, rootEntityName, rootSQLAlias );
+		outerQueryTranslator = outerQuery;
+	}
+
+	public CriteriaQueryTranslator(
+			final SessionFactoryImplementor factory,
+	        final CriteriaImpl criteria,
+	        final String rootEntityName,
+	        final String rootSQLAlias) throws HibernateException {
+		this.rootCriteria = criteria;
+		this.rootEntityName = rootEntityName;
+		this.sessionFactory = factory;
+		this.rootSQLAlias = rootSQLAlias;
+		createAliasCriteriaMap();
+		createAssociationPathCriteriaMap();
+		createCriteriaEntityNameMap();
+		createCriteriaSQLAliasMap();
+	}
+
+	public String generateSQLAlias() {
+		return StringHelper.generateAlias( Criteria.ROOT_ALIAS, aliasCount ) + '_';
+	}
+
+	public String getRootSQLALias() {
+		return rootSQLAlias;
+	}
+
+	private Criteria getAliasedCriteria(String alias) {
+		return ( Criteria ) aliasCriteriaMap.get( alias );
+	}
+
+	public boolean isJoin(String path) {
+		return associationPathCriteriaMap.containsKey( path );
+	}
+
+	public int getJoinType(String path) {
+		Integer result = ( Integer ) associationPathJoinTypesMap.get( path );
+		return ( result == null ? Criteria.INNER_JOIN : result.intValue() );
+	}
+
+	public Criteria getCriteria(String path) {
+		return ( Criteria ) associationPathCriteriaMap.get( path );
+	}
+
+	public Set getQuerySpaces() {
+		Set result = new HashSet();
+		Iterator iter = criteriaEntityNames.values().iterator();
+		while ( iter.hasNext() ) {
+			String entityName = ( String ) iter.next();
+			result.addAll( Arrays.asList( getFactory().getEntityPersister( entityName ).getQuerySpaces() ) );
+		}
+		return result;
+	}
+
+	private void createAliasCriteriaMap() {
+		aliasCriteriaMap.put( rootCriteria.getAlias(), rootCriteria );
+		Iterator iter = rootCriteria.iterateSubcriteria();
+		while ( iter.hasNext() ) {
+			Criteria subcriteria = ( Criteria ) iter.next();
+			if ( subcriteria.getAlias() != null ) {
+				Object old = aliasCriteriaMap.put( subcriteria.getAlias(), subcriteria );
+				if ( old != null ) {
+					throw new QueryException( "duplicate alias: " + subcriteria.getAlias() );
+				}
+			}
+		}
+	}
+
+	private void createAssociationPathCriteriaMap() {
+		Iterator iter = rootCriteria.iterateSubcriteria();
+		while ( iter.hasNext() ) {
+			CriteriaImpl.Subcriteria crit = ( CriteriaImpl.Subcriteria ) iter.next();
+			String wholeAssociationPath = getWholeAssociationPath( crit );
+			Object old = associationPathCriteriaMap.put( wholeAssociationPath, crit );
+			if ( old != null ) {
+				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
+			}
+			int joinType = crit.getJoinType();
+			old = associationPathJoinTypesMap.put( wholeAssociationPath, new Integer( joinType ) );
+			if ( old != null ) {
+				// TODO : not so sure this is needed...
+				throw new QueryException( "duplicate association path: " + wholeAssociationPath );
+			}
+		}
+	}
+
+	private String getWholeAssociationPath(CriteriaImpl.Subcriteria subcriteria) {
+		String path = subcriteria.getPath();
+
+		// some messy, complex stuff here, since createCriteria() can take an
+		// aliased path, or a path rooted at the creating criteria instance
+		Criteria parent = null;
+		if ( path.indexOf( '.' ) > 0 ) {
+			// if it is a compound path
+			String testAlias = StringHelper.root( path );
+			if ( !testAlias.equals( subcriteria.getAlias() ) ) {
+				// and the qualifier is not the alias of this criteria
+				//      -> check to see if we belong to some criteria other
+				//          than the one that created us
+				parent = ( Criteria ) aliasCriteriaMap.get( testAlias );
+			}
+		}
+		if ( parent == null ) {
+			// otherwise assume the parent is the the criteria that created us
+			parent = subcriteria.getParent();
+		}
+		else {
+			path = StringHelper.unroot( path );
+		}
+
+		if ( parent.equals( rootCriteria ) ) {
+			// if its the root criteria, we are done
+			return path;
+		}
+		else {
+			// otherwise, recurse
+			return getWholeAssociationPath( ( CriteriaImpl.Subcriteria ) parent ) + '.' + path;
+		}
+	}
+
+	private void createCriteriaEntityNameMap() {
+		criteriaEntityNames.put( rootCriteria, rootEntityName );
+		Iterator iter = associationPathCriteriaMap.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			criteriaEntityNames.put(
+					me.getValue(), //the criteria instance
+			        getPathEntityName( ( String ) me.getKey() )
+			);
+		}
+	}
+
+	private String getPathEntityName(String path) {
+		Queryable persister = ( Queryable ) sessionFactory.getEntityPersister( rootEntityName );
+		StringTokenizer tokens = new StringTokenizer( path, "." );
+		String componentPath = "";
+		while ( tokens.hasMoreTokens() ) {
+			componentPath += tokens.nextToken();
+			Type type = persister.toType( componentPath );
+			if ( type.isAssociationType() ) {
+				AssociationType atype = ( AssociationType ) type;
+				persister = ( Queryable ) sessionFactory.getEntityPersister(
+						atype.getAssociatedEntityName( sessionFactory )
+				);
+				componentPath = "";
+			}
+			else if ( type.isComponentType() ) {
+				componentPath += '.';
+			}
+			else {
+				throw new QueryException( "not an association: " + componentPath );
+			}
+		}
+		return persister.getEntityName();
+	}
+
+	public int getSQLAliasCount() {
+		return criteriaSQLAliasMap.size();
+	}
+
+	private void createCriteriaSQLAliasMap() {
+		int i = 0;
+		Iterator criteriaIterator = criteriaEntityNames.entrySet().iterator();
+		while ( criteriaIterator.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) criteriaIterator.next();
+			Criteria crit = ( Criteria ) me.getKey();
+			String alias = crit.getAlias();
+			if ( alias == null ) {
+				alias = ( String ) me.getValue(); // the entity name
+			}
+			criteriaSQLAliasMap.put( crit, StringHelper.generateAlias( alias, i++ ) );
+		}
+		criteriaSQLAliasMap.put( rootCriteria, rootSQLAlias );
+	}
+
+	public CriteriaImpl getRootCriteria() {
+		return rootCriteria;
+	}
+
+	public QueryParameters getQueryParameters() {
+		List values = new ArrayList();
+		List types = new ArrayList();
+		Iterator iter = rootCriteria.iterateExpressionEntries();
+		while ( iter.hasNext() ) {
+			CriteriaImpl.CriterionEntry ce = ( CriteriaImpl.CriterionEntry ) iter.next();
+			TypedValue[] tv = ce.getCriterion().getTypedValues( ce.getCriteria(), this );
+			for ( int i = 0; i < tv.length; i++ ) {
+				values.add( tv[i].getValue() );
+				types.add( tv[i].getType() );
+			}
+		}
+		Object[] valueArray = values.toArray();
+		Type[] typeArray = ArrayHelper.toTypeArray( types );
+
+		RowSelection selection = new RowSelection();
+		selection.setFirstRow( rootCriteria.getFirstResult() );
+		selection.setMaxRows( rootCriteria.getMaxResults() );
+		selection.setTimeout( rootCriteria.getTimeout() );
+		selection.setFetchSize( rootCriteria.getFetchSize() );
+
+		Map lockModes = new HashMap();
+		iter = rootCriteria.getLockModes().entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			final Criteria subcriteria = getAliasedCriteria( ( String ) me.getKey() );
+			lockModes.put( getSQLAlias( subcriteria ), me.getValue() );
+		}
+		iter = rootCriteria.iterateSubcriteria();
+		while ( iter.hasNext() ) {
+			CriteriaImpl.Subcriteria subcriteria = ( CriteriaImpl.Subcriteria ) iter.next();
+			LockMode lm = subcriteria.getLockMode();
+			if ( lm != null ) {
+				lockModes.put( getSQLAlias( subcriteria ), lm );
+			}
+		}
+
+		return new QueryParameters(
+				typeArray,
+		        valueArray,
+		        lockModes,
+		        selection,
+		        rootCriteria.getCacheable(),
+		        rootCriteria.getCacheRegion(),
+		        rootCriteria.getComment(),
+		        rootCriteria.isLookupByNaturalKey(),
+		        rootCriteria.getResultTransformer()
+		);
+	}
+
+	public boolean hasProjection() {
+		return rootCriteria.getProjection() != null;
+	}
+
+	public String getGroupBy() {
+		if ( rootCriteria.getProjection().isGrouped() ) {
+			return rootCriteria.getProjection()
+					.toGroupSqlString( rootCriteria.getProjectionCriteria(), this );
+		}
+		else {
+			return "";
+		}
+	}
+
+	public String getSelect() {
+		return rootCriteria.getProjection().toSqlString(
+				rootCriteria.getProjectionCriteria(),
+		        0,
+		        this
+		);
+	}
+
+	public Type[] getProjectedTypes() {
+		return rootCriteria.getProjection().getTypes( rootCriteria, this );
+	}
+
+	public String[] getProjectedColumnAliases() {
+		return rootCriteria.getProjection().getColumnAliases( 0 );
+	}
+
+	public String[] getProjectedAliases() {
+		return rootCriteria.getProjection().getAliases();
+	}
+
+	public String getWhereCondition() {
+		StringBuffer condition = new StringBuffer( 30 );
+		Iterator criterionIterator = rootCriteria.iterateExpressionEntries();
+		while ( criterionIterator.hasNext() ) {
+			CriteriaImpl.CriterionEntry entry = ( CriteriaImpl.CriterionEntry ) criterionIterator.next();
+			String sqlString = entry.getCriterion().toSqlString( entry.getCriteria(), this );
+			condition.append( sqlString );
+			if ( criterionIterator.hasNext() ) {
+				condition.append( " and " );
+			}
+		}
+		return condition.toString();
+	}
+
+	public String getOrderBy() {
+		StringBuffer orderBy = new StringBuffer( 30 );
+		Iterator criterionIterator = rootCriteria.iterateOrderings();
+		while ( criterionIterator.hasNext() ) {
+			CriteriaImpl.OrderEntry oe = ( CriteriaImpl.OrderEntry ) criterionIterator.next();
+			orderBy.append( oe.getOrder().toSqlString( oe.getCriteria(), this ) );
+			if ( criterionIterator.hasNext() ) {
+				orderBy.append( ", " );
+			}
+		}
+		return orderBy.toString();
+	}
+
+	public SessionFactoryImplementor getFactory() {
+		return sessionFactory;
+	}
+
+	public String getSQLAlias(Criteria criteria) {
+		return ( String ) criteriaSQLAliasMap.get( criteria );
+	}
+
+	public String getEntityName(Criteria criteria) {
+		return ( String ) criteriaEntityNames.get( criteria );
+	}
+
+	public String getColumn(Criteria criteria, String propertyName) {
+		String[] cols = getColumns( propertyName, criteria );
+		if ( cols.length != 1 ) {
+			throw new QueryException( "property does not map to a single column: " + propertyName );
+		}
+		return cols[0];
+	}
+
+	/**
+	 * Get the names of the columns constrained
+	 * by this criterion.
+	 */
+	public String[] getColumnsUsingProjection(
+			Criteria subcriteria,
+	        String propertyName) throws HibernateException {
+
+		//first look for a reference to a projection alias
+		final Projection projection = rootCriteria.getProjection();
+		String[] projectionColumns = projection == null ?
+		                             null :
+		                             projection.getColumnAliases( propertyName, 0 );
+
+		if ( projectionColumns == null ) {
+			//it does not refer to an alias of a projection,
+			//look for a property
+			try {
+				return getColumns( propertyName, subcriteria );
+			}
+			catch ( HibernateException he ) {
+				//not found in inner query , try the outer query
+				if ( outerQueryTranslator != null ) {
+					return outerQueryTranslator.getColumnsUsingProjection( subcriteria, propertyName );
+				}
+				else {
+					throw he;
+				}
+			}
+		}
+		else {
+			//it refers to an alias of a projection
+			return projectionColumns;
+		}
+	}
+
+	public String[] getIdentifierColumns(Criteria subcriteria) {
+		String[] idcols =
+				( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierColumnNames();
+		return StringHelper.qualify( getSQLAlias( subcriteria ), idcols );
+	}
+
+	public Type getIdentifierType(Criteria subcriteria) {
+		return ( ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) ) ).getIdentifierType();
+	}
+
+	public TypedValue getTypedIdentifierValue(Criteria subcriteria, Object value) {
+		final Loadable loadable = ( Loadable ) getPropertyMapping( getEntityName( subcriteria ) );
+		return new TypedValue(
+				loadable.getIdentifierType(),
+		        value,
+		        EntityMode.POJO
+		);
+	}
+
+	private String[] getColumns(
+			String propertyName,
+	        Criteria subcriteria) throws HibernateException {
+		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
+				.toColumns(
+						getSQLAlias( subcriteria, propertyName ),
+				        getPropertyName( propertyName )
+				);
+	}
+
+	public Type getTypeUsingProjection(Criteria subcriteria, String propertyName)
+			throws HibernateException {
+
+		//first look for a reference to a projection alias
+		final Projection projection = rootCriteria.getProjection();
+		Type[] projectionTypes = projection == null ?
+		                         null :
+		                         projection.getTypes( propertyName, subcriteria, this );
+
+		if ( projectionTypes == null ) {
+			try {
+				//it does not refer to an alias of a projection,
+				//look for a property
+				return getType( subcriteria, propertyName );
+			}
+			catch ( HibernateException he ) {
+				//not found in inner query , try the outer query
+				if ( outerQueryTranslator != null ) {
+					return outerQueryTranslator.getType( subcriteria, propertyName );
+				}
+				else {
+					throw he;
+				}
+			}
+		}
+		else {
+			if ( projectionTypes.length != 1 ) {
+				//should never happen, i think
+				throw new QueryException( "not a single-length projection: " + propertyName );
+			}
+			return projectionTypes[0];
+		}
+	}
+
+	public Type getType(Criteria subcriteria, String propertyName)
+			throws HibernateException {
+		return getPropertyMapping( getEntityName( subcriteria, propertyName ) )
+				.toType( getPropertyName( propertyName ) );
+	}
+
+	/**
+	 * Get the a typed value for the given property value.
+	 */
+	public TypedValue getTypedValue(Criteria subcriteria, String propertyName, Object value)
+			throws HibernateException {
+		// Detect discriminator values...
+		if ( value instanceof Class ) {
+			Class entityClass = ( Class ) value;
+			Queryable q = SessionFactoryHelper.findQueryableUsingImports( sessionFactory, entityClass.getName() );
+			if ( q != null ) {
+				Type type = q.getDiscriminatorType();
+				String stringValue = q.getDiscriminatorSQLValue();
+				// Convert the string value into the proper type.
+				if ( type instanceof NullableType ) {
+					NullableType nullableType = ( NullableType ) type;
+					value = nullableType.fromStringValue( stringValue );
+				}
+				else {
+					throw new QueryException( "Unsupported discriminator type " + type );
+				}
+				return new TypedValue(
+						type,
+				        value,
+				        EntityMode.POJO
+				);
+			}
+		}
+		// Otherwise, this is an ordinary value.
+		return new TypedValue(
+				getTypeUsingProjection( subcriteria, propertyName ),
+		        value,
+		        EntityMode.POJO
+		);
+	}
+
+	private PropertyMapping getPropertyMapping(String entityName)
+			throws MappingException {
+		return ( PropertyMapping ) sessionFactory.getEntityPersister( entityName );
+	}
+
+	//TODO: use these in methods above
+
+	public String getEntityName(Criteria subcriteria, String propertyName) {
+		if ( propertyName.indexOf( '.' ) > 0 ) {
+			String root = StringHelper.root( propertyName );
+			Criteria crit = getAliasedCriteria( root );
+			if ( crit != null ) {
+				return getEntityName( crit );
+			}
+		}
+		return getEntityName( subcriteria );
+	}
+
+	public String getSQLAlias(Criteria criteria, String propertyName) {
+		if ( propertyName.indexOf( '.' ) > 0 ) {
+			String root = StringHelper.root( propertyName );
+			Criteria subcriteria = getAliasedCriteria( root );
+			if ( subcriteria != null ) {
+				return getSQLAlias( subcriteria );
+			}
+		}
+		return getSQLAlias( criteria );
+	}
+
+	public String getPropertyName(String propertyName) {
+		if ( propertyName.indexOf( '.' ) > 0 ) {
+			String root = StringHelper.root( propertyName );
+			Criteria crit = getAliasedCriteria( root );
+			if ( crit != null ) {
+				return propertyName.substring( root.length() + 1 );
+			}
+		}
+		return propertyName;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/criteria/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines the criteria query compiler and loader
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/criteria/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/criteria/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines the criteria query compiler and loader
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.loader.EntityAliases;
-import org.hibernate.LockMode;
-
-/**
- * Spefically a fetch return that refers to a collection association.
- *
- * @author Steve Ebersole
- */
-public class CollectionFetchReturn extends FetchReturn {
-	private final CollectionAliases collectionAliases;
-	private final EntityAliases elementEntityAliases;
-
-	public CollectionFetchReturn(
-			String alias,
-			NonScalarReturn owner,
-			String ownerProperty,
-			CollectionAliases collectionAliases,
-	        EntityAliases elementEntityAliases,
-			LockMode lockMode) {
-		super( owner, ownerProperty, alias, lockMode );
-		this.collectionAliases = collectionAliases;
-		this.elementEntityAliases = elementEntityAliases;
-	}
-
-	public CollectionAliases getCollectionAliases() {
-		return collectionAliases;
-	}
-
-	public EntityAliases getElementEntityAliases() {
-		return elementEntityAliases;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionFetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.custom;
+
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.loader.EntityAliases;
+import org.hibernate.LockMode;
+
+/**
+ * Spefically a fetch return that refers to a collection association.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionFetchReturn extends FetchReturn {
+	private final CollectionAliases collectionAliases;
+	private final EntityAliases elementEntityAliases;
+
+	public CollectionFetchReturn(
+			String alias,
+			NonScalarReturn owner,
+			String ownerProperty,
+			CollectionAliases collectionAliases,
+	        EntityAliases elementEntityAliases,
+			LockMode lockMode) {
+		super( owner, ownerProperty, alias, lockMode );
+		this.collectionAliases = collectionAliases;
+		this.elementEntityAliases = elementEntityAliases;
+	}
+
+	public CollectionAliases getCollectionAliases() {
+		return collectionAliases;
+	}
+
+	public EntityAliases getElementEntityAliases() {
+		return elementEntityAliases;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.LockMode;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.loader.EntityAliases;
-
-/**
- * Represents a return which names a collection role; it
- * is used in defining a custom query for loading an entity's
- * collection in non-fetching scenarios (i.e., loading the collection
- * itself as the "root" of the result).
- *
- * @author Steve Ebersole
- */
-public class CollectionReturn extends NonScalarReturn {
-	private final String ownerEntityName;
-	private final String ownerProperty;
-	private final CollectionAliases collectionAliases;
-	private final EntityAliases elementEntityAliases;
-
-	public CollectionReturn(
-			String alias,
-			String ownerEntityName,
-			String ownerProperty,
-			CollectionAliases collectionAliases,
-	        EntityAliases elementEntityAliases,
-			LockMode lockMode) {
-		super( alias, lockMode );
-		this.ownerEntityName = ownerEntityName;
-		this.ownerProperty = ownerProperty;
-		this.collectionAliases = collectionAliases;
-		this.elementEntityAliases = elementEntityAliases;
-	}
-
-	/**
-	 * Returns the class owning the collection.
-	 *
-	 * @return The class owning the collection.
-	 */
-	public String getOwnerEntityName() {
-		return ownerEntityName;
-	}
-
-	/**
-	 * Returns the name of the property representing the collection from the {@link #getOwnerEntityName}.
-	 *
-	 * @return The name of the property representing the collection on the owner class.
-	 */
-	public String getOwnerProperty() {
-		return ownerProperty;
-	}
-
-	public CollectionAliases getCollectionAliases() {
-		return collectionAliases;
-	}
-
-	public EntityAliases getElementEntityAliases() {
-		return elementEntityAliases;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CollectionReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.loader.custom;
+
+import org.hibernate.LockMode;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.loader.EntityAliases;
+
+/**
+ * Represents a return which names a collection role; it
+ * is used in defining a custom query for loading an entity's
+ * collection in non-fetching scenarios (i.e., loading the collection
+ * itself as the "root" of the result).
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionReturn extends NonScalarReturn {
+	private final String ownerEntityName;
+	private final String ownerProperty;
+	private final CollectionAliases collectionAliases;
+	private final EntityAliases elementEntityAliases;
+
+	public CollectionReturn(
+			String alias,
+			String ownerEntityName,
+			String ownerProperty,
+			CollectionAliases collectionAliases,
+	        EntityAliases elementEntityAliases,
+			LockMode lockMode) {
+		super( alias, lockMode );
+		this.ownerEntityName = ownerEntityName;
+		this.ownerProperty = ownerProperty;
+		this.collectionAliases = collectionAliases;
+		this.elementEntityAliases = elementEntityAliases;
+	}
+
+	/**
+	 * Returns the class owning the collection.
+	 *
+	 * @return The class owning the collection.
+	 */
+	public String getOwnerEntityName() {
+		return ownerEntityName;
+	}
+
+	/**
+	 * Returns the name of the property representing the collection from the {@link #getOwnerEntityName}.
+	 *
+	 * @return The name of the property representing the collection on the owner class.
+	 */
+	public String getOwnerProperty() {
+		return ownerProperty;
+	}
+
+	public CollectionAliases getCollectionAliases() {
+		return collectionAliases;
+	}
+
+	public EntityAliases getElementEntityAliases() {
+		return elementEntityAliases;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,127 +0,0 @@
-package org.hibernate.loader.custom;
-
-import java.util.Map;
-
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.persister.collection.SQLLoadableCollection;
-import org.hibernate.util.StringHelper;
-
-/**
- * CollectionAliases that uses columnnames instead of generated aliases.
- * Aliases can still be overwritten via <return-property>
- *  
- * @author Max Rydahl Andersen
- *
- */
-public class ColumnCollectionAliases implements CollectionAliases {
-	private final String[] keyAliases;
-	private final String[] indexAliases;
-	private final String[] elementAliases;
-	private final String identifierAlias;
-	private Map userProvidedAliases;
-	
-	
-	public ColumnCollectionAliases(Map userProvidedAliases, SQLLoadableCollection persister) {
-		this.userProvidedAliases = userProvidedAliases;
-
-		this.keyAliases = getUserProvidedAliases(
-				"key", 
-				persister.getKeyColumnNames()
-			);
-
-		this.indexAliases = getUserProvidedAliases(
-				"index",
-				persister.getIndexColumnNames()
-				);
-		
-		this.elementAliases = getUserProvidedAliases( "element", 
-				persister.getElementColumnNames()
-				);
-				
-		this.identifierAlias = getUserProvidedAlias( "id", 
-				persister.getIdentifierColumnName()
-				);
-	
-	}
-
-
-	/**
-	 * Returns the suffixed result-set column-aliases for columns making up the key for this collection (i.e., its FK to
-	 * its owner).
-	 *
-	 * @return The key result-set column aliases.
-	 */
-	public String[] getSuffixedKeyAliases() {
-		return keyAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the collumns making up the collection's index (map or list).
-	 *
-	 * @return The index result-set column aliases.
-	 */
-	public String[] getSuffixedIndexAliases() {
-		return indexAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the columns making up the collection's elements.
-	 *
-	 * @return The element result-set column aliases.
-	 */
-	public String[] getSuffixedElementAliases() {
-		return elementAliases;
-	}
-
-	/**
-	 * Returns the suffixed result-set column-aliases for the column defining the collection's identifier (if any).
-	 *
-	 * @return The identifier result-set column aliases.
-	 */
-	public String getSuffixedIdentifierAlias() {
-		return identifierAlias;
-	}
-
-	/**
-	 * Returns the suffix used to unique the column aliases for this particular alias set.
-	 *
-	 * @return The uniqued column alias suffix.
-	 */
-	public String getSuffix() {
-		return "";
-	}
-
-	public String toString() {
-		return super.toString() + " [ suffixedKeyAliases=[" + join( keyAliases ) +
-		        "], suffixedIndexAliases=[" + join( indexAliases ) +
-		        "], suffixedElementAliases=[" + join( elementAliases ) +
-		        "], suffixedIdentifierAlias=[" + identifierAlias + "]]";
-	}
-
-	private String join(String[] aliases) {
-		if ( aliases == null) return null;
-
-		return StringHelper.join( ", ", aliases );
-	}
-	
-	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
-		String[] result = (String[]) userProvidedAliases.get(propertyPath);
-		if (result==null) {
-			return defaultAliases;			
-		} 
-		else {
-			return result;
-		}
-	}
-
-	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
-		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
-		if (columns==null) {
-			return defaultAlias;
-		} 
-		else {
-			return columns[0];
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ColumnCollectionAliases.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.custom;
+
+import java.util.Map;
+
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.persister.collection.SQLLoadableCollection;
+import org.hibernate.util.StringHelper;
+
+/**
+ * CollectionAliases that uses columnnames instead of generated aliases.
+ * Aliases can still be overwritten via <return-property>
+ *  
+ * @author Max Rydahl Andersen
+ *
+ */
+public class ColumnCollectionAliases implements CollectionAliases {
+	private final String[] keyAliases;
+	private final String[] indexAliases;
+	private final String[] elementAliases;
+	private final String identifierAlias;
+	private Map userProvidedAliases;
+	
+	
+	public ColumnCollectionAliases(Map userProvidedAliases, SQLLoadableCollection persister) {
+		this.userProvidedAliases = userProvidedAliases;
+
+		this.keyAliases = getUserProvidedAliases(
+				"key", 
+				persister.getKeyColumnNames()
+			);
+
+		this.indexAliases = getUserProvidedAliases(
+				"index",
+				persister.getIndexColumnNames()
+				);
+		
+		this.elementAliases = getUserProvidedAliases( "element", 
+				persister.getElementColumnNames()
+				);
+				
+		this.identifierAlias = getUserProvidedAlias( "id", 
+				persister.getIdentifierColumnName()
+				);
+	
+	}
+
+
+	/**
+	 * Returns the suffixed result-set column-aliases for columns making up the key for this collection (i.e., its FK to
+	 * its owner).
+	 *
+	 * @return The key result-set column aliases.
+	 */
+	public String[] getSuffixedKeyAliases() {
+		return keyAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the collumns making up the collection's index (map or list).
+	 *
+	 * @return The index result-set column aliases.
+	 */
+	public String[] getSuffixedIndexAliases() {
+		return indexAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the columns making up the collection's elements.
+	 *
+	 * @return The element result-set column aliases.
+	 */
+	public String[] getSuffixedElementAliases() {
+		return elementAliases;
+	}
+
+	/**
+	 * Returns the suffixed result-set column-aliases for the column defining the collection's identifier (if any).
+	 *
+	 * @return The identifier result-set column aliases.
+	 */
+	public String getSuffixedIdentifierAlias() {
+		return identifierAlias;
+	}
+
+	/**
+	 * Returns the suffix used to unique the column aliases for this particular alias set.
+	 *
+	 * @return The uniqued column alias suffix.
+	 */
+	public String getSuffix() {
+		return "";
+	}
+
+	public String toString() {
+		return super.toString() + " [ suffixedKeyAliases=[" + join( keyAliases ) +
+		        "], suffixedIndexAliases=[" + join( indexAliases ) +
+		        "], suffixedElementAliases=[" + join( elementAliases ) +
+		        "], suffixedIdentifierAlias=[" + identifierAlias + "]]";
+	}
+
+	private String join(String[] aliases) {
+		if ( aliases == null) return null;
+
+		return StringHelper.join( ", ", aliases );
+	}
+	
+	private String[] getUserProvidedAliases(String propertyPath, String[] defaultAliases) {
+		String[] result = (String[]) userProvidedAliases.get(propertyPath);
+		if (result==null) {
+			return defaultAliases;			
+		} 
+		else {
+			return result;
+		}
+	}
+
+	private String getUserProvidedAlias(String propertyPath, String defaultAlias) {
+		String[] columns = (String[]) userProvidedAliases.get(propertyPath);
+		if (columns==null) {
+			return defaultAlias;
+		} 
+		else {
+			return columns[0];
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,569 +0,0 @@
-//$Id: CustomLoader.java 10087 2006-07-06 12:21:30Z steve.ebersole at jboss.com $
-package org.hibernate.loader.custom;
-
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.HashSet;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.loader.EntityAliases;
-import org.hibernate.loader.Loader;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Extension point for loaders which use a SQL result set with "unexpected" column aliases.
- * 
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class CustomLoader extends Loader {
-	
-	// Currently *not* cachable if autodiscover types is in effect (e.g. "select * ...")
-
-	private final String sql;
-	private final Set querySpaces = new HashSet();
-	private final Map namedParameterBindPoints;
-
-	private final Queryable[] entityPersisters;
-	private final int[] entiytOwners;
-	private final EntityAliases[] entityAliases;
-
-	private final QueryableCollection[] collectionPersisters;
-	private final int[] collectionOwners;
-	private final CollectionAliases[] collectionAliases;
-
-	private final LockMode[] lockModes;
-//	private final String[] sqlAliases;
-//	private final String[] sqlAliasSuffixes;
-	private final ResultRowProcessor rowProcessor;
-
-	// this is only needed (afaict) for processing results from the query cache;
-	// however, this cannot possibly work in the case of discovered types...
-	private Type[] resultTypes;
-
-	// this is only needed (afaict) for ResultTransformer processing...
-	private String[] transformerAliases;
-
-
-	public CustomLoader(CustomQuery customQuery, SessionFactoryImplementor factory) {
-		super( factory );
-
-		this.sql = customQuery.getSQL();
-		this.querySpaces.addAll( customQuery.getQuerySpaces() );
-		this.namedParameterBindPoints = customQuery.getNamedParameterBindPoints();
-
-		List entityPersisters = new ArrayList();
-		List entityOwners = new ArrayList();
-		List entityAliases = new ArrayList();
-
-		List collectionPersisters = new ArrayList();
-		List collectionOwners = new ArrayList();
-		List collectionAliases = new ArrayList();
-
-		List lockModes = new ArrayList();
-		List resultColumnProcessors = new ArrayList();
-		List nonScalarReturnList = new ArrayList();
-		List resultTypes = new ArrayList();
-		List specifiedAliases = new ArrayList();
-		int returnableCounter = 0;
-		boolean hasScalars = false;
-
-		Iterator itr = customQuery.getCustomQueryReturns().iterator();
-		while ( itr.hasNext() ) {
-			final Return rtn = ( Return ) itr.next();
-			if ( rtn instanceof ScalarReturn ) {
-				ScalarReturn scalarRtn = ( ScalarReturn ) rtn;
-				resultTypes.add( scalarRtn.getType() );
-				specifiedAliases.add( scalarRtn.getColumnAlias() );
-				resultColumnProcessors.add(
-						new ScalarResultColumnProcessor(
-								scalarRtn.getColumnAlias(),
-								scalarRtn.getType()
-						)
-				);
-				hasScalars = true;
-			}
-			else if ( rtn instanceof RootReturn ) {
-				RootReturn rootRtn = ( RootReturn ) rtn;
-				Queryable persister = ( Queryable ) factory.getEntityPersister( rootRtn.getEntityName() );
-				entityPersisters.add( persister );
-				lockModes.add( rootRtn.getLockMode() );
-				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
-				nonScalarReturnList.add( rtn );
-				entityOwners.add( new Integer( -1 ) );
-				resultTypes.add( persister.getType() );
-				specifiedAliases.add( rootRtn.getAlias() );
-				entityAliases.add( rootRtn.getEntityAliases() );
-				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
-			}
-			else if ( rtn instanceof CollectionReturn ) {
-				CollectionReturn collRtn = ( CollectionReturn ) rtn;
-				String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
-				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
-				collectionPersisters.add( persister );
-				lockModes.add( collRtn.getLockMode() );
-				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
-				nonScalarReturnList.add( rtn );
-				collectionOwners.add( new Integer( -1 ) );
-				resultTypes.add( persister.getType() );
-				specifiedAliases.add( collRtn.getAlias() );
-				collectionAliases.add( collRtn.getCollectionAliases() );
-				// determine if the collection elements are entities...
-				Type elementType = persister.getElementType();
-				if ( elementType.isEntityType() ) {
-					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
-					entityPersisters.add( elementPersister );
-					entityOwners.add( new Integer( -1 ) );
-					entityAliases.add( collRtn.getElementEntityAliases() );
-					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
-				}
-			}
-			else if ( rtn instanceof EntityFetchReturn ) {
-				EntityFetchReturn fetchRtn = ( EntityFetchReturn ) rtn;
-				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
-				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
-				entityOwners.add( new Integer( ownerIndex ) );
-				lockModes.add( fetchRtn.getLockMode() );
-				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
-				EntityType fetchedType = ( EntityType ) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() );
-				String entityName = fetchedType.getAssociatedEntityName( getFactory() );
-				Queryable persister = ( Queryable ) factory.getEntityPersister( entityName );
-				entityPersisters.add( persister );
-				nonScalarReturnList.add( rtn );
-				specifiedAliases.add( fetchRtn.getAlias() );
-				entityAliases.add( fetchRtn.getEntityAliases() );
-				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
-			}
-			else if ( rtn instanceof CollectionFetchReturn ) {
-				CollectionFetchReturn fetchRtn = ( CollectionFetchReturn ) rtn;
-				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
-				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
-				collectionOwners.add( new Integer( ownerIndex ) );
-				lockModes.add( fetchRtn.getLockMode() );
-				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
-				String role = ownerPersister.getEntityName() + '.' + fetchRtn.getOwnerProperty();
-				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
-				collectionPersisters.add( persister );
-				nonScalarReturnList.add( rtn );
-				specifiedAliases.add( fetchRtn.getAlias() );
-				collectionAliases.add( fetchRtn.getCollectionAliases() );
-				// determine if the collection elements are entities...
-				Type elementType = persister.getElementType();
-				if ( elementType.isEntityType() ) {
-					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
-					entityPersisters.add( elementPersister );
-					entityOwners.add( new Integer( ownerIndex ) );
-					entityAliases.add( fetchRtn.getElementEntityAliases() );
-					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
-				}
-			}
-			else {
-				throw new HibernateException( "unexpected custom query return type : " + rtn.getClass().getName() );
-			}
-		}
-
-		this.entityPersisters = new Queryable[ entityPersisters.size() ];
-		for ( int i = 0; i < entityPersisters.size(); i++ ) {
-			this.entityPersisters[i] = ( Queryable ) entityPersisters.get( i );
-		}
-		this.entiytOwners = ArrayHelper.toIntArray( entityOwners );
-		this.entityAliases = new EntityAliases[ entityAliases.size() ];
-		for ( int i = 0; i < entityAliases.size(); i++ ) {
-			this.entityAliases[i] = ( EntityAliases ) entityAliases.get( i );
-		}
-
-		this.collectionPersisters = new QueryableCollection[ collectionPersisters.size() ];
-		for ( int i = 0; i < collectionPersisters.size(); i++ ) {
-			this.collectionPersisters[i] = ( QueryableCollection ) collectionPersisters.get( i );
-		}
-		this.collectionOwners = ArrayHelper.toIntArray( collectionOwners );
-		this.collectionAliases = new CollectionAliases[ collectionAliases.size() ];
-		for ( int i = 0; i < collectionAliases.size(); i++ ) {
-			this.collectionAliases[i] = ( CollectionAliases ) collectionAliases.get( i );
-		}
-
-		this.lockModes = new LockMode[ lockModes.size() ];
-		for ( int i = 0; i < lockModes.size(); i++ ) {
-			this.lockModes[i] = ( LockMode ) lockModes.get( i );
-		}
-
-		this.resultTypes = ArrayHelper.toTypeArray( resultTypes );
-		this.transformerAliases = ArrayHelper.toStringArray( specifiedAliases );
-
-		this.rowProcessor = new ResultRowProcessor(
-				hasScalars,
-		        ( ResultColumnProcessor[] ) resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] )
-		);
-	}
-
-	private Queryable determineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor) {
-		String entityName = null;
-		if ( ownerDescriptor instanceof RootReturn ) {
-			entityName = ( ( RootReturn ) ownerDescriptor ).getEntityName();
-		}
-		else if ( ownerDescriptor instanceof CollectionReturn ) {
-			CollectionReturn collRtn = ( CollectionReturn ) ownerDescriptor;
-			String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
-			CollectionPersister persister = getFactory().getCollectionPersister( role );
-			EntityType ownerType = ( EntityType ) persister.getElementType();
-			entityName = ownerType.getAssociatedEntityName( getFactory() );
-		}
-		else if ( ownerDescriptor instanceof FetchReturn ) {
-			FetchReturn fetchRtn = ( FetchReturn ) ownerDescriptor;
-			Queryable persister = determineAppropriateOwnerPersister( fetchRtn.getOwner() );
-			Type ownerType = persister.getPropertyType( fetchRtn.getOwnerProperty() );
-			if ( ownerType.isEntityType() ) {
-				entityName = ( ( EntityType ) ownerType ).getAssociatedEntityName( getFactory() );
-			}
-			else if ( ownerType.isCollectionType() ) {
-				Type ownerCollectionElementType = ( ( CollectionType ) ownerType ).getElementType( getFactory() );
-				if ( ownerCollectionElementType.isEntityType() ) {
-					entityName = ( ( EntityType ) ownerCollectionElementType ).getAssociatedEntityName( getFactory() );
-				}
-			}
-		}
-
-		if ( entityName == null ) {
-			throw new HibernateException( "Could not determine fetch owner : " + ownerDescriptor );
-		}
-
-		return ( Queryable ) getFactory().getEntityPersister( entityName );
-	}
-
-	protected String getQueryIdentifier() {
-		return sql;
-	}
-
-	protected String getSQLString() {
-		return sql;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	protected LockMode[] getLockModes(Map lockModesMap) {
-		return lockModes;
-	}
-
-	protected Loadable[] getEntityPersisters() {
-		return entityPersisters;
-	}
-
-	protected CollectionPersister[] getCollectionPersisters() {
-		return collectionPersisters;
-	}
-
-	protected int[] getCollectionOwners() {
-		return collectionOwners;
-	}
-	
-	protected int[] getOwners() {
-		return entiytOwners;
-	}
-
-	public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException {
-		return list( session, queryParameters, querySpaces, resultTypes );
-	}
-
-	public ScrollableResults scroll(
-			final QueryParameters queryParameters,
-			final SessionImplementor session) throws HibernateException {		
-		return scroll(
-				queryParameters,
-				resultTypes,
-				getHolderInstantiator( queryParameters.getResultTransformer(), getReturnAliasesForTransformer() ),
-				session
-		);
-	}
-	
-	static private HolderInstantiator getHolderInstantiator(ResultTransformer resultTransformer, String[] queryReturnAliases) {
-		if ( resultTransformer != null ) {
-			return HolderInstantiator.NOOP_INSTANTIATOR;
-		}
-		else {
-			return new HolderInstantiator(resultTransformer, queryReturnAliases);
-		}
-	}
-	
-	protected Object getResultColumnOrRow(
-			Object[] row,
-	        ResultTransformer transformer,
-	        ResultSet rs,
-	        SessionImplementor session) throws SQLException, HibernateException {
-		return rowProcessor.buildResultRow( row, rs, transformer != null, session );
-	}
-
-	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
-		// meant to handle dynamic instantiation queries...(Copy from QueryLoader)
-		HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(
-				null,
-				resultTransformer,
-				getReturnAliasesForTransformer()
-		);
-		if ( holderInstantiator.isRequired() ) {
-			for ( int i = 0; i < results.size(); i++ ) {
-				Object[] row = ( Object[] ) results.get( i );
-				Object result = holderInstantiator.instantiate(row);
-				results.set( i, result );
-			}
-			
-			return resultTransformer.transformList(results);
-		}
-		else {
-			return results;
-		}
-	}
-
-	private String[] getReturnAliasesForTransformer() {
-		return transformerAliases;
-	}
-	
-	protected EntityAliases[] getEntityAliases() {
-		return entityAliases;
-	}
-
-	protected CollectionAliases[] getCollectionAliases() {
-		return collectionAliases;
-	}
-	
-	public int[] getNamedParameterLocs(String name) throws QueryException {
-		Object loc = namedParameterBindPoints.get( name );
-		if ( loc == null ) {
-			throw new QueryException(
-					"Named parameter does not appear in Query: " + name,
-					sql
-			);
-		}
-		if ( loc instanceof Integer ) {
-			return new int[] { ( ( Integer ) loc ).intValue() };
-		}
-		else {
-			return ArrayHelper.toIntArray( ( List ) loc );
-		}
-	}
-
-
-	public class ResultRowProcessor {
-		private final boolean hasScalars;
-		private ResultColumnProcessor[] columnProcessors;
-
-		public ResultRowProcessor(boolean hasScalars, ResultColumnProcessor[] columnProcessors) {
-			this.hasScalars = hasScalars || ( columnProcessors == null || columnProcessors.length == 0 );
-			this.columnProcessors = columnProcessors;
-		}
-
-		public void prepareForAutoDiscovery(Metadata metadata) throws SQLException {
-			if ( columnProcessors == null || columnProcessors.length == 0 ) {
-				int columns = metadata.getColumnCount();
-				columnProcessors = new ResultColumnProcessor[ columns ];
-				for ( int i = 1; i <= columns; i++ ) {
-					columnProcessors[ i - 1 ] = new ScalarResultColumnProcessor( i );
-				}
-
-			}
-		}
-
-		/**
-		 * Build a logical result row.
-		 * <p/>
-		 * At this point, Loader has already processed all non-scalar result data.  We
-		 * just need to account for scalar result data here...
-		 *
-		 * @param data Entity data defined as "root returns" and already handled by the
-		 * normal Loader mechanism.
-		 * @param resultSet The JDBC result set (positioned at the row currently being processed).
-		 * @param hasTransformer Does this query have an associated {@link ResultTransformer}
-		 * @param session The session from which the query request originated.
-		 * @return The logical result row
-		 * @throws SQLException
-		 * @throws HibernateException
-		 */
-		public Object buildResultRow(
-				Object[] data,
-				ResultSet resultSet,
-				boolean hasTransformer,
-				SessionImplementor session) throws SQLException, HibernateException {
-			Object[] resultRow;
-			if ( !hasScalars ) {
-				resultRow = data;
-			}
-			else {
-				// build an array with indices equal to the total number
-				// of actual returns in the result Hibernate will return
-				// for this query (scalars + non-scalars)
-				resultRow = new Object[ columnProcessors.length ];
-				for ( int i = 0; i < columnProcessors.length; i++ ) {
-					resultRow[i] = columnProcessors[i].extract( data, resultSet, session );
-				}
-			}
-
-			return ( hasTransformer )
-			       ? resultRow
-			       : ( resultRow.length == 1 )
-			         ? resultRow[0]
-			         : resultRow;
-		}
-	}
-
-	private static interface ResultColumnProcessor {
-		public Object extract(Object[] data, ResultSet resultSet, SessionImplementor session) throws SQLException, HibernateException;
-		public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException, HibernateException;
-	}
-
-	public class NonScalarResultColumnProcessor implements ResultColumnProcessor {
-		private final int position;
-
-		public NonScalarResultColumnProcessor(int position) {
-			this.position = position;
-		}
-
-		public Object extract(
-				Object[] data,
-				ResultSet resultSet,
-				SessionImplementor session) throws SQLException, HibernateException {
-			return data[ position ];
-		}
-
-		public void performDiscovery(Metadata metadata, List types, List aliases) {
-		}
-
-	}
-
-	public class ScalarResultColumnProcessor implements ResultColumnProcessor {
-		private int position = -1;
-		private String alias;
-		private Type type;
-
-		public ScalarResultColumnProcessor(int position) {
-			this.position = position;
-		}
-
-		public ScalarResultColumnProcessor(String alias, Type type) {
-			this.alias = alias;
-			this.type = type;
-		}
-
-		public Object extract(
-				Object[] data,
-				ResultSet resultSet,
-				SessionImplementor session) throws SQLException, HibernateException {
-			return type.nullSafeGet( resultSet, alias, session, null );
-		}
-
-		public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException {
-			if ( alias == null ) {
-				alias = metadata.getColumnName( position );
-			}
-			else if ( position < 0 ) {
-				position = metadata.resolveColumnPosition( alias );
-			}
-			if ( type == null ) {
-				type = metadata.getHibernateType( position );
-			}
-			types.add( type );
-			aliases.add( alias );
-		}
-	}
-
-	protected void autoDiscoverTypes(ResultSet rs) {
-		try {
-			Metadata metadata = new Metadata( getFactory(), rs );
-			List aliases = new ArrayList();
-			List types = new ArrayList();
-
-			rowProcessor.prepareForAutoDiscovery( metadata );
-
-			for ( int i = 0; i < rowProcessor.columnProcessors.length; i++ ) {
-				rowProcessor.columnProcessors[i].performDiscovery( metadata, types, aliases );
-			}
-
-			resultTypes = ArrayHelper.toTypeArray( types );
-			transformerAliases = ArrayHelper.toStringArray( aliases );
-		}
-		catch ( SQLException e ) {
-			throw new HibernateException( "Exception while trying to autodiscover types.", e );
-		}
-	}
-
-	private static class Metadata {
-		private final SessionFactoryImplementor factory;
-		private final ResultSet resultSet;
-		private final ResultSetMetaData resultSetMetaData;
-
-		public Metadata(SessionFactoryImplementor factory, ResultSet resultSet) throws HibernateException {
-			try {
-				this.factory = factory;
-				this.resultSet = resultSet;
-				this.resultSetMetaData = resultSet.getMetaData();
-			}
-			catch( SQLException e ) {
-				throw new HibernateException( "Could not extract result set metadata", e );
-			}
-		}
-
-		public int getColumnCount() throws HibernateException {
-			try {
-				return resultSetMetaData.getColumnCount();
-			}
-			catch( SQLException e ) {
-				throw new HibernateException( "Could not determine result set column count", e );
-			}
-		}
-
-		public int resolveColumnPosition(String columnName) throws HibernateException {
-			try {
-				return resultSet.findColumn( columnName );
-			}
-			catch( SQLException e ) {
-				throw new HibernateException( "Could not resolve column name in result set [" + columnName + "]", e );
-			}
-		}
-
-		public String getColumnName(int position) throws HibernateException {
-			try {
-				return resultSetMetaData.getColumnName( position );
-			}
-			catch( SQLException e ) {
-				throw new HibernateException( "Could not resolve column name [" + position + "]", e );
-			}
-		}
-
-		public Type getHibernateType(int columnPos) throws SQLException {
-			int columnType = resultSetMetaData.getColumnType( columnPos );
-			int scale = resultSetMetaData.getScale( columnPos );
-			int precision = resultSetMetaData.getPrecision( columnPos );
-			return TypeFactory.heuristicType(
-					factory.getDialect().getHibernateTypeName(
-							columnType,
-							precision,
-							precision,
-							scale
-					)
-			);
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,592 @@
+/*
+ * 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.loader.custom;
+
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.HashSet;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.loader.EntityAliases;
+import org.hibernate.loader.Loader;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Extension point for loaders which use a SQL result set with "unexpected" column aliases.
+ * 
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class CustomLoader extends Loader {
+	
+	// Currently *not* cachable if autodiscover types is in effect (e.g. "select * ...")
+
+	private final String sql;
+	private final Set querySpaces = new HashSet();
+	private final Map namedParameterBindPoints;
+
+	private final Queryable[] entityPersisters;
+	private final int[] entiytOwners;
+	private final EntityAliases[] entityAliases;
+
+	private final QueryableCollection[] collectionPersisters;
+	private final int[] collectionOwners;
+	private final CollectionAliases[] collectionAliases;
+
+	private final LockMode[] lockModes;
+//	private final String[] sqlAliases;
+//	private final String[] sqlAliasSuffixes;
+	private final ResultRowProcessor rowProcessor;
+
+	// this is only needed (afaict) for processing results from the query cache;
+	// however, this cannot possibly work in the case of discovered types...
+	private Type[] resultTypes;
+
+	// this is only needed (afaict) for ResultTransformer processing...
+	private String[] transformerAliases;
+
+
+	public CustomLoader(CustomQuery customQuery, SessionFactoryImplementor factory) {
+		super( factory );
+
+		this.sql = customQuery.getSQL();
+		this.querySpaces.addAll( customQuery.getQuerySpaces() );
+		this.namedParameterBindPoints = customQuery.getNamedParameterBindPoints();
+
+		List entityPersisters = new ArrayList();
+		List entityOwners = new ArrayList();
+		List entityAliases = new ArrayList();
+
+		List collectionPersisters = new ArrayList();
+		List collectionOwners = new ArrayList();
+		List collectionAliases = new ArrayList();
+
+		List lockModes = new ArrayList();
+		List resultColumnProcessors = new ArrayList();
+		List nonScalarReturnList = new ArrayList();
+		List resultTypes = new ArrayList();
+		List specifiedAliases = new ArrayList();
+		int returnableCounter = 0;
+		boolean hasScalars = false;
+
+		Iterator itr = customQuery.getCustomQueryReturns().iterator();
+		while ( itr.hasNext() ) {
+			final Return rtn = ( Return ) itr.next();
+			if ( rtn instanceof ScalarReturn ) {
+				ScalarReturn scalarRtn = ( ScalarReturn ) rtn;
+				resultTypes.add( scalarRtn.getType() );
+				specifiedAliases.add( scalarRtn.getColumnAlias() );
+				resultColumnProcessors.add(
+						new ScalarResultColumnProcessor(
+								scalarRtn.getColumnAlias(),
+								scalarRtn.getType()
+						)
+				);
+				hasScalars = true;
+			}
+			else if ( rtn instanceof RootReturn ) {
+				RootReturn rootRtn = ( RootReturn ) rtn;
+				Queryable persister = ( Queryable ) factory.getEntityPersister( rootRtn.getEntityName() );
+				entityPersisters.add( persister );
+				lockModes.add( rootRtn.getLockMode() );
+				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
+				nonScalarReturnList.add( rtn );
+				entityOwners.add( new Integer( -1 ) );
+				resultTypes.add( persister.getType() );
+				specifiedAliases.add( rootRtn.getAlias() );
+				entityAliases.add( rootRtn.getEntityAliases() );
+				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
+			}
+			else if ( rtn instanceof CollectionReturn ) {
+				CollectionReturn collRtn = ( CollectionReturn ) rtn;
+				String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
+				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
+				collectionPersisters.add( persister );
+				lockModes.add( collRtn.getLockMode() );
+				resultColumnProcessors.add( new NonScalarResultColumnProcessor( returnableCounter++ ) );
+				nonScalarReturnList.add( rtn );
+				collectionOwners.add( new Integer( -1 ) );
+				resultTypes.add( persister.getType() );
+				specifiedAliases.add( collRtn.getAlias() );
+				collectionAliases.add( collRtn.getCollectionAliases() );
+				// determine if the collection elements are entities...
+				Type elementType = persister.getElementType();
+				if ( elementType.isEntityType() ) {
+					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
+					entityPersisters.add( elementPersister );
+					entityOwners.add( new Integer( -1 ) );
+					entityAliases.add( collRtn.getElementEntityAliases() );
+					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
+				}
+			}
+			else if ( rtn instanceof EntityFetchReturn ) {
+				EntityFetchReturn fetchRtn = ( EntityFetchReturn ) rtn;
+				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
+				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
+				entityOwners.add( new Integer( ownerIndex ) );
+				lockModes.add( fetchRtn.getLockMode() );
+				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
+				EntityType fetchedType = ( EntityType ) ownerPersister.getPropertyType( fetchRtn.getOwnerProperty() );
+				String entityName = fetchedType.getAssociatedEntityName( getFactory() );
+				Queryable persister = ( Queryable ) factory.getEntityPersister( entityName );
+				entityPersisters.add( persister );
+				nonScalarReturnList.add( rtn );
+				specifiedAliases.add( fetchRtn.getAlias() );
+				entityAliases.add( fetchRtn.getEntityAliases() );
+				ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
+			}
+			else if ( rtn instanceof CollectionFetchReturn ) {
+				CollectionFetchReturn fetchRtn = ( CollectionFetchReturn ) rtn;
+				NonScalarReturn ownerDescriptor = fetchRtn.getOwner();
+				int ownerIndex = nonScalarReturnList.indexOf( ownerDescriptor );
+				collectionOwners.add( new Integer( ownerIndex ) );
+				lockModes.add( fetchRtn.getLockMode() );
+				Queryable ownerPersister = determineAppropriateOwnerPersister( ownerDescriptor );
+				String role = ownerPersister.getEntityName() + '.' + fetchRtn.getOwnerProperty();
+				QueryableCollection persister = ( QueryableCollection ) factory.getCollectionPersister( role );
+				collectionPersisters.add( persister );
+				nonScalarReturnList.add( rtn );
+				specifiedAliases.add( fetchRtn.getAlias() );
+				collectionAliases.add( fetchRtn.getCollectionAliases() );
+				// determine if the collection elements are entities...
+				Type elementType = persister.getElementType();
+				if ( elementType.isEntityType() ) {
+					Queryable elementPersister = ( Queryable ) ( ( EntityType ) elementType ).getAssociatedJoinable( factory );
+					entityPersisters.add( elementPersister );
+					entityOwners.add( new Integer( ownerIndex ) );
+					entityAliases.add( fetchRtn.getElementEntityAliases() );
+					ArrayHelper.addAll( querySpaces, elementPersister.getQuerySpaces() );
+				}
+			}
+			else {
+				throw new HibernateException( "unexpected custom query return type : " + rtn.getClass().getName() );
+			}
+		}
+
+		this.entityPersisters = new Queryable[ entityPersisters.size() ];
+		for ( int i = 0; i < entityPersisters.size(); i++ ) {
+			this.entityPersisters[i] = ( Queryable ) entityPersisters.get( i );
+		}
+		this.entiytOwners = ArrayHelper.toIntArray( entityOwners );
+		this.entityAliases = new EntityAliases[ entityAliases.size() ];
+		for ( int i = 0; i < entityAliases.size(); i++ ) {
+			this.entityAliases[i] = ( EntityAliases ) entityAliases.get( i );
+		}
+
+		this.collectionPersisters = new QueryableCollection[ collectionPersisters.size() ];
+		for ( int i = 0; i < collectionPersisters.size(); i++ ) {
+			this.collectionPersisters[i] = ( QueryableCollection ) collectionPersisters.get( i );
+		}
+		this.collectionOwners = ArrayHelper.toIntArray( collectionOwners );
+		this.collectionAliases = new CollectionAliases[ collectionAliases.size() ];
+		for ( int i = 0; i < collectionAliases.size(); i++ ) {
+			this.collectionAliases[i] = ( CollectionAliases ) collectionAliases.get( i );
+		}
+
+		this.lockModes = new LockMode[ lockModes.size() ];
+		for ( int i = 0; i < lockModes.size(); i++ ) {
+			this.lockModes[i] = ( LockMode ) lockModes.get( i );
+		}
+
+		this.resultTypes = ArrayHelper.toTypeArray( resultTypes );
+		this.transformerAliases = ArrayHelper.toStringArray( specifiedAliases );
+
+		this.rowProcessor = new ResultRowProcessor(
+				hasScalars,
+		        ( ResultColumnProcessor[] ) resultColumnProcessors.toArray( new ResultColumnProcessor[ resultColumnProcessors.size() ] )
+		);
+	}
+
+	private Queryable determineAppropriateOwnerPersister(NonScalarReturn ownerDescriptor) {
+		String entityName = null;
+		if ( ownerDescriptor instanceof RootReturn ) {
+			entityName = ( ( RootReturn ) ownerDescriptor ).getEntityName();
+		}
+		else if ( ownerDescriptor instanceof CollectionReturn ) {
+			CollectionReturn collRtn = ( CollectionReturn ) ownerDescriptor;
+			String role = collRtn.getOwnerEntityName() + "." + collRtn.getOwnerProperty();
+			CollectionPersister persister = getFactory().getCollectionPersister( role );
+			EntityType ownerType = ( EntityType ) persister.getElementType();
+			entityName = ownerType.getAssociatedEntityName( getFactory() );
+		}
+		else if ( ownerDescriptor instanceof FetchReturn ) {
+			FetchReturn fetchRtn = ( FetchReturn ) ownerDescriptor;
+			Queryable persister = determineAppropriateOwnerPersister( fetchRtn.getOwner() );
+			Type ownerType = persister.getPropertyType( fetchRtn.getOwnerProperty() );
+			if ( ownerType.isEntityType() ) {
+				entityName = ( ( EntityType ) ownerType ).getAssociatedEntityName( getFactory() );
+			}
+			else if ( ownerType.isCollectionType() ) {
+				Type ownerCollectionElementType = ( ( CollectionType ) ownerType ).getElementType( getFactory() );
+				if ( ownerCollectionElementType.isEntityType() ) {
+					entityName = ( ( EntityType ) ownerCollectionElementType ).getAssociatedEntityName( getFactory() );
+				}
+			}
+		}
+
+		if ( entityName == null ) {
+			throw new HibernateException( "Could not determine fetch owner : " + ownerDescriptor );
+		}
+
+		return ( Queryable ) getFactory().getEntityPersister( entityName );
+	}
+
+	protected String getQueryIdentifier() {
+		return sql;
+	}
+
+	protected String getSQLString() {
+		return sql;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	protected LockMode[] getLockModes(Map lockModesMap) {
+		return lockModes;
+	}
+
+	protected Loadable[] getEntityPersisters() {
+		return entityPersisters;
+	}
+
+	protected CollectionPersister[] getCollectionPersisters() {
+		return collectionPersisters;
+	}
+
+	protected int[] getCollectionOwners() {
+		return collectionOwners;
+	}
+	
+	protected int[] getOwners() {
+		return entiytOwners;
+	}
+
+	public List list(SessionImplementor session, QueryParameters queryParameters) throws HibernateException {
+		return list( session, queryParameters, querySpaces, resultTypes );
+	}
+
+	public ScrollableResults scroll(
+			final QueryParameters queryParameters,
+			final SessionImplementor session) throws HibernateException {		
+		return scroll(
+				queryParameters,
+				resultTypes,
+				getHolderInstantiator( queryParameters.getResultTransformer(), getReturnAliasesForTransformer() ),
+				session
+		);
+	}
+	
+	static private HolderInstantiator getHolderInstantiator(ResultTransformer resultTransformer, String[] queryReturnAliases) {
+		if ( resultTransformer != null ) {
+			return HolderInstantiator.NOOP_INSTANTIATOR;
+		}
+		else {
+			return new HolderInstantiator(resultTransformer, queryReturnAliases);
+		}
+	}
+	
+	protected Object getResultColumnOrRow(
+			Object[] row,
+	        ResultTransformer transformer,
+	        ResultSet rs,
+	        SessionImplementor session) throws SQLException, HibernateException {
+		return rowProcessor.buildResultRow( row, rs, transformer != null, session );
+	}
+
+	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
+		// meant to handle dynamic instantiation queries...(Copy from QueryLoader)
+		HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(
+				null,
+				resultTransformer,
+				getReturnAliasesForTransformer()
+		);
+		if ( holderInstantiator.isRequired() ) {
+			for ( int i = 0; i < results.size(); i++ ) {
+				Object[] row = ( Object[] ) results.get( i );
+				Object result = holderInstantiator.instantiate(row);
+				results.set( i, result );
+			}
+			
+			return resultTransformer.transformList(results);
+		}
+		else {
+			return results;
+		}
+	}
+
+	private String[] getReturnAliasesForTransformer() {
+		return transformerAliases;
+	}
+	
+	protected EntityAliases[] getEntityAliases() {
+		return entityAliases;
+	}
+
+	protected CollectionAliases[] getCollectionAliases() {
+		return collectionAliases;
+	}
+	
+	public int[] getNamedParameterLocs(String name) throws QueryException {
+		Object loc = namedParameterBindPoints.get( name );
+		if ( loc == null ) {
+			throw new QueryException(
+					"Named parameter does not appear in Query: " + name,
+					sql
+			);
+		}
+		if ( loc instanceof Integer ) {
+			return new int[] { ( ( Integer ) loc ).intValue() };
+		}
+		else {
+			return ArrayHelper.toIntArray( ( List ) loc );
+		}
+	}
+
+
+	public class ResultRowProcessor {
+		private final boolean hasScalars;
+		private ResultColumnProcessor[] columnProcessors;
+
+		public ResultRowProcessor(boolean hasScalars, ResultColumnProcessor[] columnProcessors) {
+			this.hasScalars = hasScalars || ( columnProcessors == null || columnProcessors.length == 0 );
+			this.columnProcessors = columnProcessors;
+		}
+
+		public void prepareForAutoDiscovery(Metadata metadata) throws SQLException {
+			if ( columnProcessors == null || columnProcessors.length == 0 ) {
+				int columns = metadata.getColumnCount();
+				columnProcessors = new ResultColumnProcessor[ columns ];
+				for ( int i = 1; i <= columns; i++ ) {
+					columnProcessors[ i - 1 ] = new ScalarResultColumnProcessor( i );
+				}
+
+			}
+		}
+
+		/**
+		 * Build a logical result row.
+		 * <p/>
+		 * At this point, Loader has already processed all non-scalar result data.  We
+		 * just need to account for scalar result data here...
+		 *
+		 * @param data Entity data defined as "root returns" and already handled by the
+		 * normal Loader mechanism.
+		 * @param resultSet The JDBC result set (positioned at the row currently being processed).
+		 * @param hasTransformer Does this query have an associated {@link ResultTransformer}
+		 * @param session The session from which the query request originated.
+		 * @return The logical result row
+		 * @throws SQLException
+		 * @throws HibernateException
+		 */
+		public Object buildResultRow(
+				Object[] data,
+				ResultSet resultSet,
+				boolean hasTransformer,
+				SessionImplementor session) throws SQLException, HibernateException {
+			Object[] resultRow;
+			if ( !hasScalars ) {
+				resultRow = data;
+			}
+			else {
+				// build an array with indices equal to the total number
+				// of actual returns in the result Hibernate will return
+				// for this query (scalars + non-scalars)
+				resultRow = new Object[ columnProcessors.length ];
+				for ( int i = 0; i < columnProcessors.length; i++ ) {
+					resultRow[i] = columnProcessors[i].extract( data, resultSet, session );
+				}
+			}
+
+			return ( hasTransformer )
+			       ? resultRow
+			       : ( resultRow.length == 1 )
+			         ? resultRow[0]
+			         : resultRow;
+		}
+	}
+
+	private static interface ResultColumnProcessor {
+		public Object extract(Object[] data, ResultSet resultSet, SessionImplementor session) throws SQLException, HibernateException;
+		public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException, HibernateException;
+	}
+
+	public class NonScalarResultColumnProcessor implements ResultColumnProcessor {
+		private final int position;
+
+		public NonScalarResultColumnProcessor(int position) {
+			this.position = position;
+		}
+
+		public Object extract(
+				Object[] data,
+				ResultSet resultSet,
+				SessionImplementor session) throws SQLException, HibernateException {
+			return data[ position ];
+		}
+
+		public void performDiscovery(Metadata metadata, List types, List aliases) {
+		}
+
+	}
+
+	public class ScalarResultColumnProcessor implements ResultColumnProcessor {
+		private int position = -1;
+		private String alias;
+		private Type type;
+
+		public ScalarResultColumnProcessor(int position) {
+			this.position = position;
+		}
+
+		public ScalarResultColumnProcessor(String alias, Type type) {
+			this.alias = alias;
+			this.type = type;
+		}
+
+		public Object extract(
+				Object[] data,
+				ResultSet resultSet,
+				SessionImplementor session) throws SQLException, HibernateException {
+			return type.nullSafeGet( resultSet, alias, session, null );
+		}
+
+		public void performDiscovery(Metadata metadata, List types, List aliases) throws SQLException {
+			if ( alias == null ) {
+				alias = metadata.getColumnName( position );
+			}
+			else if ( position < 0 ) {
+				position = metadata.resolveColumnPosition( alias );
+			}
+			if ( type == null ) {
+				type = metadata.getHibernateType( position );
+			}
+			types.add( type );
+			aliases.add( alias );
+		}
+	}
+
+	protected void autoDiscoverTypes(ResultSet rs) {
+		try {
+			Metadata metadata = new Metadata( getFactory(), rs );
+			List aliases = new ArrayList();
+			List types = new ArrayList();
+
+			rowProcessor.prepareForAutoDiscovery( metadata );
+
+			for ( int i = 0; i < rowProcessor.columnProcessors.length; i++ ) {
+				rowProcessor.columnProcessors[i].performDiscovery( metadata, types, aliases );
+			}
+
+			resultTypes = ArrayHelper.toTypeArray( types );
+			transformerAliases = ArrayHelper.toStringArray( aliases );
+		}
+		catch ( SQLException e ) {
+			throw new HibernateException( "Exception while trying to autodiscover types.", e );
+		}
+	}
+
+	private static class Metadata {
+		private final SessionFactoryImplementor factory;
+		private final ResultSet resultSet;
+		private final ResultSetMetaData resultSetMetaData;
+
+		public Metadata(SessionFactoryImplementor factory, ResultSet resultSet) throws HibernateException {
+			try {
+				this.factory = factory;
+				this.resultSet = resultSet;
+				this.resultSetMetaData = resultSet.getMetaData();
+			}
+			catch( SQLException e ) {
+				throw new HibernateException( "Could not extract result set metadata", e );
+			}
+		}
+
+		public int getColumnCount() throws HibernateException {
+			try {
+				return resultSetMetaData.getColumnCount();
+			}
+			catch( SQLException e ) {
+				throw new HibernateException( "Could not determine result set column count", e );
+			}
+		}
+
+		public int resolveColumnPosition(String columnName) throws HibernateException {
+			try {
+				return resultSet.findColumn( columnName );
+			}
+			catch( SQLException e ) {
+				throw new HibernateException( "Could not resolve column name in result set [" + columnName + "]", e );
+			}
+		}
+
+		public String getColumnName(int position) throws HibernateException {
+			try {
+				return resultSetMetaData.getColumnName( position );
+			}
+			catch( SQLException e ) {
+				throw new HibernateException( "Could not resolve column name [" + position + "]", e );
+			}
+		}
+
+		public Type getHibernateType(int columnPos) throws SQLException {
+			int columnType = resultSetMetaData.getColumnType( columnPos );
+			int scale = resultSetMetaData.getScale( columnPos );
+			int precision = resultSetMetaData.getPrecision( columnPos );
+			return TypeFactory.heuristicType(
+					factory.getDialect().getHibernateTypeName(
+							columnType,
+							precision,
+							precision,
+							scale
+					)
+			);
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: CustomQuery.java 10018 2006-06-15 05:21:06Z steve.ebersole at jboss.com $
-package org.hibernate.loader.custom;
-
-import java.util.Map;
-import java.util.Set;
-import java.util.List;
-
-/**
- * Extension point allowing any SQL query with named and positional parameters
- * to be executed by Hibernate, returning managed entities, collections and
- * simple scalar values.
- * 
- * @author Gavin King
- * @author Steve Ebersole
- */
-public interface CustomQuery {
-	/**
-	 * The SQL query string to be performed.
-	 *
-	 * @return The SQL statement string.
-	 */
-	public String getSQL();
-
-	/**
-	 * Any query spaces to apply to the query execution.  Query spaces are
-	 * used in Hibernate's auto-flushing mechanism to determine which
-	 * entities need to be checked for pending changes.
-	 *
-	 * @return The query spaces
-	 */
-	public Set getQuerySpaces();
-
-	/**
-	 * A map representing positions within the supplied {@link #getSQL query} to
-	 * which we need to bind named parameters.
-	 * <p/>
-	 * Optional, may return null if no named parameters.
-	 * <p/>
-	 * The structure of the returned map (if one) as follows:<ol>
-	 * <li>The keys into the map are the named parameter names</li>
-	 * <li>The corresponding value is either an {@link Integer} if the
-	 * parameter occurs only once in the query; or a List of Integers if the
-	 * parameter occurs more than once</li>
-	 * </ol>
-	 */
-	public Map getNamedParameterBindPoints();
-
-	/**
-	 * A collection of {@link Return descriptors} describing the
-	 * JDBC result set to be expected and how to map this result set.
-	 *
-	 * @return List of return descriptors.
-	 */
-	public List getCustomQueryReturns();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/CustomQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.loader.custom;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.List;
+
+/**
+ * Extension point allowing any SQL query with named and positional parameters
+ * to be executed by Hibernate, returning managed entities, collections and
+ * simple scalar values.
+ * 
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public interface CustomQuery {
+	/**
+	 * The SQL query string to be performed.
+	 *
+	 * @return The SQL statement string.
+	 */
+	public String getSQL();
+
+	/**
+	 * Any query spaces to apply to the query execution.  Query spaces are
+	 * used in Hibernate's auto-flushing mechanism to determine which
+	 * entities need to be checked for pending changes.
+	 *
+	 * @return The query spaces
+	 */
+	public Set getQuerySpaces();
+
+	/**
+	 * A map representing positions within the supplied {@link #getSQL query} to
+	 * which we need to bind named parameters.
+	 * <p/>
+	 * Optional, may return null if no named parameters.
+	 * <p/>
+	 * The structure of the returned map (if one) as follows:<ol>
+	 * <li>The keys into the map are the named parameter names</li>
+	 * <li>The corresponding value is either an {@link Integer} if the
+	 * parameter occurs only once in the query; or a List of Integers if the
+	 * parameter occurs more than once</li>
+	 * </ol>
+	 */
+	public Map getNamedParameterBindPoints();
+
+	/**
+	 * A collection of {@link Return descriptors} describing the
+	 * JDBC result set to be expected and how to map this result set.
+	 *
+	 * @return List of return descriptors.
+	 */
+	public List getCustomQueryReturns();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.loader.EntityAliases;
-import org.hibernate.LockMode;
-
-/**
- * Spefically a fetch return that refers to an entity association.
- *
- * @author Steve Ebersole
- */
-public class EntityFetchReturn extends FetchReturn {
-	private final EntityAliases entityAliases;
-
-	public EntityFetchReturn(
-			String alias,
-			EntityAliases entityAliases,
-			NonScalarReturn owner,
-			String ownerProperty,
-			LockMode lockMode) {
-		super( owner, ownerProperty, alias, lockMode );
-		this.entityAliases = entityAliases;
-	}
-
-	public EntityAliases getEntityAliases() {
-		return entityAliases;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/EntityFetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.loader.custom;
+
+import org.hibernate.loader.EntityAliases;
+import org.hibernate.LockMode;
+
+/**
+ * Spefically a fetch return that refers to an entity association.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityFetchReturn extends FetchReturn {
+	private final EntityAliases entityAliases;
+
+	public EntityFetchReturn(
+			String alias,
+			EntityAliases entityAliases,
+			NonScalarReturn owner,
+			String ownerProperty,
+			LockMode lockMode) {
+		super( owner, ownerProperty, alias, lockMode );
+		this.entityAliases = entityAliases;
+	}
+
+	public EntityAliases getEntityAliases() {
+		return entityAliases;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.LockMode;
-
-/**
- * Represents a return which names a fetched association.
- *
- * @author Steve Ebersole
- */
-public abstract class FetchReturn extends NonScalarReturn {
-	private final NonScalarReturn owner;
-	private final String ownerProperty;
-
-	/**
-	 * Creates a return descriptor for an association fetch.
-	 *
-	 * @param owner The return descriptor for the owner of the fetch
-	 * @param ownerProperty The name of the property represernting the association being fetched
-	 * @param alias The alias for the fetch
-	 * @param lockMode The lock mode to apply to the fetched association.
-	 */
-	public FetchReturn(
-			NonScalarReturn owner,
-			String ownerProperty,
-			String alias,
-			LockMode lockMode) {
-		super( alias, lockMode );
-		this.owner = owner;
-		this.ownerProperty = ownerProperty;
-	}
-
-	/**
-	 * Retrieves the return descriptor for the owner of this fetch.
-	 *
-	 * @return The owner
-	 */
-	public NonScalarReturn getOwner() {
-		return owner;
-	}
-
-	/**
-	 * The name of the property on the owner which represents this association.
-	 *
-	 * @return The property name.
-	 */
-	public String getOwnerProperty() {
-		return ownerProperty;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/FetchReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.loader.custom;
+
+import org.hibernate.LockMode;
+
+/**
+ * Represents a return which names a fetched association.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class FetchReturn extends NonScalarReturn {
+	private final NonScalarReturn owner;
+	private final String ownerProperty;
+
+	/**
+	 * Creates a return descriptor for an association fetch.
+	 *
+	 * @param owner The return descriptor for the owner of the fetch
+	 * @param ownerProperty The name of the property represernting the association being fetched
+	 * @param alias The alias for the fetch
+	 * @param lockMode The lock mode to apply to the fetched association.
+	 */
+	public FetchReturn(
+			NonScalarReturn owner,
+			String ownerProperty,
+			String alias,
+			LockMode lockMode) {
+		super( alias, lockMode );
+		this.owner = owner;
+		this.ownerProperty = ownerProperty;
+	}
+
+	/**
+	 * Retrieves the return descriptor for the owner of this fetch.
+	 *
+	 * @return The owner
+	 */
+	public NonScalarReturn getOwner() {
+		return owner;
+	}
+
+	/**
+	 * The name of the property on the owner which represents this association.
+	 *
+	 * @return The property name.
+	 */
+	public String getOwnerProperty() {
+		return ownerProperty;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,30 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.LockMode;
-import org.hibernate.HibernateException;
-
-/**
- * Represents some non-scalar (entity/collection) return within the query result.
- *
- * @author Steve Ebersole
- */
-public abstract class NonScalarReturn implements Return {
-	private final String alias;
-	private final LockMode lockMode;
-
-	public NonScalarReturn(String alias, LockMode lockMode) {
-		this.alias = alias;
-		if ( alias == null ) {
-			throw new HibernateException("alias must be specified");
-		}
-		this.lockMode = lockMode;
-	}
-
-	public String getAlias() {
-		return alias;
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/NonScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.loader.custom;
+
+import org.hibernate.LockMode;
+import org.hibernate.HibernateException;
+
+/**
+ * Represents some non-scalar (entity/collection) return within the query result.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class NonScalarReturn implements Return {
+	private final String alias;
+	private final LockMode lockMode;
+
+	public NonScalarReturn(String alias, LockMode lockMode) {
+		this.alias = alias;
+		if ( alias == null ) {
+			throw new HibernateException("alias must be specified");
+		}
+		this.lockMode = lockMode;
+	}
+
+	public String getAlias() {
+		return alias;
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/Return.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-package org.hibernate.loader.custom;
-
-/**
- * Represents a return in a custom query.
- *
- * @author Steve Ebersole
- */
-public interface Return {
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/Return.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/Return.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+/*
+ * 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.loader.custom;
+
+/**
+ * Represents a return in a custom query.
+ *
+ * @author Steve Ebersole
+ */
+public interface Return {
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/RootReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.LockMode;
-import org.hibernate.loader.EntityAliases;
-
-/**
- * Represents a return which names a "root" entity.
- * <p/>
- * A root entity means it is explicitly a "column" in the result, as opposed to
- * a fetched association.
- *
- * @author Steve Ebersole
- */
-public class RootReturn extends NonScalarReturn {
-	private final String entityName;
-	private final EntityAliases entityAliases;
-
-	public RootReturn(
-			String alias,
-			String entityName,
-			EntityAliases entityAliases,
-			LockMode lockMode) {
-		super( alias, lockMode );
-		this.entityName = entityName;
-		this.entityAliases = entityAliases;
-	}
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public EntityAliases getEntityAliases() {
-		return entityAliases;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/RootReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/RootReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.custom;
+
+import org.hibernate.LockMode;
+import org.hibernate.loader.EntityAliases;
+
+/**
+ * Represents a return which names a "root" entity.
+ * <p/>
+ * A root entity means it is explicitly a "column" in the result, as opposed to
+ * a fetched association.
+ *
+ * @author Steve Ebersole
+ */
+public class RootReturn extends NonScalarReturn {
+	private final String entityName;
+	private final EntityAliases entityAliases;
+
+	public RootReturn(
+			String alias,
+			String entityName,
+			EntityAliases entityAliases,
+			LockMode lockMode) {
+		super( alias, lockMode );
+		this.entityName = entityName;
+		this.entityAliases = entityAliases;
+	}
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public EntityAliases getEntityAliases() {
+		return entityAliases;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-package org.hibernate.loader.custom;
-
-import org.hibernate.type.Type;
-
-/**
- * Represent a scalar (aka simple value) return within a query result.
- *
- * @author Steve Ebersole
- */
-public class ScalarReturn implements Return {
-	private final Type type;
-	private final String columnAlias;
-
-	public ScalarReturn(Type type, String columnAlias) {
-		this.type = type;
-		this.columnAlias = columnAlias;
-	}
-
-	public Type getType() {
-		return type;
-	}
-
-	public String getColumnAlias() {
-		return columnAlias;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/ScalarReturn.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.loader.custom;
+
+import org.hibernate.type.Type;
+
+/**
+ * Represent a scalar (aka simple value) return within a query result.
+ *
+ * @author Steve Ebersole
+ */
+public class ScalarReturn implements Return {
+	private final Type type;
+	private final String columnAlias;
+
+	public ScalarReturn(Type type, String columnAlias) {
+		this.type = type;
+		this.columnAlias = columnAlias;
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+	public String getColumnAlias() {
+		return columnAlias;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a framework for custom loaders that accept 
-	handwritten SQL
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a framework for custom loaders that accept 
+	handwritten SQL
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,232 +0,0 @@
-//$Id: SQLCustomQuery.java 10018 2006-06-15 05:21:06Z steve.ebersole at jboss.com $
-package org.hibernate.loader.custom.sql;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashMap;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.custom.CustomQuery;
-import org.hibernate.persister.collection.SQLLoadableCollection;
-import org.hibernate.persister.entity.SQLLoadable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Implements Hibernate's built-in support for native SQL queries.
- * <p/>
- * This support is built on top of the notion of "custom queries"...
- * 
- * @author Gavin King
- * @author Max Andersen
- * @author Steve Ebersole
- */
-public class SQLCustomQuery implements CustomQuery {
-
-	public static final Logger log = LoggerFactory.getLogger( SQLCustomQuery.class );
-
-	private final String sql;
-	private final Set querySpaces = new HashSet();
-	private final Map namedParameterBindPoints = new HashMap();
-	private final List customQueryReturns = new ArrayList();
-
-
-	public String getSQL() {
-		return sql;
-	}
-
-	public Set getQuerySpaces() {
-		return querySpaces;
-	}
-
-	public Map getNamedParameterBindPoints() {
-		return namedParameterBindPoints;
-	}
-
-	public List getCustomQueryReturns() {
-		return customQueryReturns;
-	}
-
-	public SQLCustomQuery(
-			final String sqlQuery,
-			final NativeSQLQueryReturn[] queryReturns,
-			final Collection additionalQuerySpaces,
-			final SessionFactoryImplementor factory) throws HibernateException {
-
-		log.trace( "starting processing of sql query [" + sqlQuery + "]" );
-		SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory);
-		SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.process();
-
-
-//		Map[] propertyResultMaps =  (Map[]) processor.getPropertyResults().toArray( new Map[0] );
-//		Map[] collectionResultMaps =  (Map[]) processor.getCollectionPropertyResults().toArray( new Map[0] );
-//
-//		List collectionSuffixes = new ArrayList();
-//		List collectionOwnerAliases = processor.getCollectionOwnerAliases();
-//		List collectionPersisters = processor.getCollectionPersisters();
-//		int size = collectionPersisters.size();
-//		if (size!=0) {
-//			collectionOwners = new int[size];
-//			collectionRoles = new String[size];
-//			//collectionDescriptors = new CollectionAliases[size];
-//			for ( int i=0; i<size; i++ ) {
-//				CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
-//				collectionRoles[i] = ( collectionPersister ).getRole();
-//				collectionOwners[i] = processor.getAliases().indexOf( collectionOwnerAliases.get(i) );
-//				String suffix = i + "__";
-//				collectionSuffixes.add(suffix);
-//				//collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
-//			}
-//		}
-//		else {
-//			collectionRoles = null;
-//			//collectionDescriptors = null;
-//			collectionOwners = null;
-//		}
-//
-//		String[] aliases = ArrayHelper.toStringArray( processor.getAliases() );
-//		String[] collAliases = ArrayHelper.toStringArray( processor.getCollectionAliases() );
-//		String[] collSuffixes = ArrayHelper.toStringArray(collectionSuffixes);
-//
-//		SQLLoadable[] entityPersisters = (SQLLoadable[]) processor.getPersisters().toArray( new SQLLoadable[0] );
-//		SQLLoadableCollection[] collPersisters = (SQLLoadableCollection[]) collectionPersisters.toArray( new SQLLoadableCollection[0] );
-//        lockModes = (LockMode[]) processor.getLockModes().toArray( new LockMode[0] );
-//
-//        scalarColumnAliases = ArrayHelper.toStringArray( processor.getScalarColumnAliases() );
-//		scalarTypes = ArrayHelper.toTypeArray( processor.getScalarTypes() );
-//
-//		// need to match the "sequence" of what we return. scalar first, entity last.
-//		returnAliases = ArrayHelper.join(scalarColumnAliases, aliases);
-//
-//		String[] suffixes = BasicLoader.generateSuffixes(entityPersisters.length);
-
-		SQLQueryParser parser = new SQLQueryParser( sqlQuery, new ParserContext( aliasContext ) );
-		this.sql = parser.process();
-		this.namedParameterBindPoints.putAll( parser.getNamedParameters() );
-
-//		SQLQueryParser parser = new SQLQueryParser(
-//				sqlQuery,
-//				processor.getAlias2Persister(),
-//				processor.getAlias2Return(),
-//				aliases,
-//				collAliases,
-//				collPersisters,
-//				suffixes,
-//				collSuffixes
-//		);
-//
-//		sql = parser.process();
-//
-//		namedParameterBindPoints = parser.getNamedParameters();
-
-
-		customQueryReturns.addAll( processor.generateCustomReturns( parser.queryHasAliases() ) );
-
-//		// Populate entityNames, entityDescrptors and querySpaces
-//		entityNames = new String[entityPersisters.length];
-//		entityDescriptors = new EntityAliases[entityPersisters.length];
-//		for (int i = 0; i < entityPersisters.length; i++) {
-//			SQLLoadable persister = entityPersisters[i];
-//			//alias2Persister.put( aliases[i], persister );
-//			//TODO: Does not consider any other tables referenced in the query
-//			ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
-//			entityNames[i] = persister.getEntityName();
-//			if ( parser.queryHasAliases() ) {
-//				entityDescriptors[i] = new DefaultEntityAliases(
-//						propertyResultMaps[i],
-//						entityPersisters[i],
-//						suffixes[i]
-//					);
-//			}
-//			else {
-//				entityDescriptors[i] = new ColumnEntityAliases(
-//						propertyResultMaps[i],
-//						entityPersisters[i],
-//						suffixes[i]
-//					);
-//			}
-//		}
-		if ( additionalQuerySpaces != null ) {
-			querySpaces.addAll( additionalQuerySpaces );
-		}
-
-//		if (size!=0) {
-//			collectionDescriptors = new CollectionAliases[size];
-//			for ( int i=0; i<size; i++ ) {
-//				CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
-//				String suffix = i + "__";
-//				if( parser.queryHasAliases() ) {
-//					collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
-//				} else {
-//					collectionDescriptors[i] = new ColumnCollectionAliases( collectionResultMaps[i], (SQLLoadableCollection) collectionPersister );
-//				}
-//			}
-//		}
-//		else {
-//			collectionDescriptors = null;
-//		}
-//
-//
-//		// Resolve owners
-//		Map alias2OwnerAlias = processor.getAlias2OwnerAlias();
-//		int[] ownersArray = new int[entityPersisters.length];
-//		for ( int j=0; j < aliases.length; j++ ) {
-//			String ownerAlias = (String) alias2OwnerAlias.get( aliases[j] );
-//			if ( StringHelper.isNotEmpty(ownerAlias) ) {
-//				ownersArray[j] =  processor.getAliases().indexOf( ownerAlias );
-//			}
-//			else {
-//				ownersArray[j] = -1;
-//			}
-//		}
-//		if ( ArrayHelper.isAllNegative(ownersArray) ) {
-//			ownersArray = null;
-//		}
-//		this.entityOwners = ownersArray;
-
-	}
-
-
-	private static class ParserContext implements SQLQueryParser.ParserContext {
-
-		private final SQLQueryReturnProcessor.ResultAliasContext aliasContext;
-
-		public ParserContext(SQLQueryReturnProcessor.ResultAliasContext aliasContext) {
-			this.aliasContext = aliasContext;
-		}
-
-		public boolean isEntityAlias(String alias) {
-			return getEntityPersisterByAlias( alias ) != null;
-		}
-
-		public SQLLoadable getEntityPersisterByAlias(String alias) {
-			return aliasContext.getEntityPersister( alias );
-		}
-
-		public String getEntitySuffixByAlias(String alias) {
-			return aliasContext.getEntitySuffix( alias );
-		}
-
-		public boolean isCollectionAlias(String alias) {
-			return getCollectionPersisterByAlias( alias ) != null;
-		}
-
-		public SQLLoadableCollection getCollectionPersisterByAlias(String alias) {
-			return aliasContext.getCollectionPersister( alias );
-		}
-
-		public String getCollectionSuffixByAlias(String alias) {
-			return aliasContext.getCollectionSuffix( alias );
-		}
-
-		public Map getPropertyResultsMapByAlias(String alias) {
-			return aliasContext.getPropertyResultsMap( alias );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLCustomQuery.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,255 @@
+/*
+ * 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.loader.custom.sql;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.custom.CustomQuery;
+import org.hibernate.persister.collection.SQLLoadableCollection;
+import org.hibernate.persister.entity.SQLLoadable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements Hibernate's built-in support for native SQL queries.
+ * <p/>
+ * This support is built on top of the notion of "custom queries"...
+ * 
+ * @author Gavin King
+ * @author Max Andersen
+ * @author Steve Ebersole
+ */
+public class SQLCustomQuery implements CustomQuery {
+
+	public static final Logger log = LoggerFactory.getLogger( SQLCustomQuery.class );
+
+	private final String sql;
+	private final Set querySpaces = new HashSet();
+	private final Map namedParameterBindPoints = new HashMap();
+	private final List customQueryReturns = new ArrayList();
+
+
+	public String getSQL() {
+		return sql;
+	}
+
+	public Set getQuerySpaces() {
+		return querySpaces;
+	}
+
+	public Map getNamedParameterBindPoints() {
+		return namedParameterBindPoints;
+	}
+
+	public List getCustomQueryReturns() {
+		return customQueryReturns;
+	}
+
+	public SQLCustomQuery(
+			final String sqlQuery,
+			final NativeSQLQueryReturn[] queryReturns,
+			final Collection additionalQuerySpaces,
+			final SessionFactoryImplementor factory) throws HibernateException {
+
+		log.trace( "starting processing of sql query [" + sqlQuery + "]" );
+		SQLQueryReturnProcessor processor = new SQLQueryReturnProcessor(queryReturns, factory);
+		SQLQueryReturnProcessor.ResultAliasContext aliasContext = processor.process();
+
+
+//		Map[] propertyResultMaps =  (Map[]) processor.getPropertyResults().toArray( new Map[0] );
+//		Map[] collectionResultMaps =  (Map[]) processor.getCollectionPropertyResults().toArray( new Map[0] );
+//
+//		List collectionSuffixes = new ArrayList();
+//		List collectionOwnerAliases = processor.getCollectionOwnerAliases();
+//		List collectionPersisters = processor.getCollectionPersisters();
+//		int size = collectionPersisters.size();
+//		if (size!=0) {
+//			collectionOwners = new int[size];
+//			collectionRoles = new String[size];
+//			//collectionDescriptors = new CollectionAliases[size];
+//			for ( int i=0; i<size; i++ ) {
+//				CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
+//				collectionRoles[i] = ( collectionPersister ).getRole();
+//				collectionOwners[i] = processor.getAliases().indexOf( collectionOwnerAliases.get(i) );
+//				String suffix = i + "__";
+//				collectionSuffixes.add(suffix);
+//				//collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
+//			}
+//		}
+//		else {
+//			collectionRoles = null;
+//			//collectionDescriptors = null;
+//			collectionOwners = null;
+//		}
+//
+//		String[] aliases = ArrayHelper.toStringArray( processor.getAliases() );
+//		String[] collAliases = ArrayHelper.toStringArray( processor.getCollectionAliases() );
+//		String[] collSuffixes = ArrayHelper.toStringArray(collectionSuffixes);
+//
+//		SQLLoadable[] entityPersisters = (SQLLoadable[]) processor.getPersisters().toArray( new SQLLoadable[0] );
+//		SQLLoadableCollection[] collPersisters = (SQLLoadableCollection[]) collectionPersisters.toArray( new SQLLoadableCollection[0] );
+//        lockModes = (LockMode[]) processor.getLockModes().toArray( new LockMode[0] );
+//
+//        scalarColumnAliases = ArrayHelper.toStringArray( processor.getScalarColumnAliases() );
+//		scalarTypes = ArrayHelper.toTypeArray( processor.getScalarTypes() );
+//
+//		// need to match the "sequence" of what we return. scalar first, entity last.
+//		returnAliases = ArrayHelper.join(scalarColumnAliases, aliases);
+//
+//		String[] suffixes = BasicLoader.generateSuffixes(entityPersisters.length);
+
+		SQLQueryParser parser = new SQLQueryParser( sqlQuery, new ParserContext( aliasContext ) );
+		this.sql = parser.process();
+		this.namedParameterBindPoints.putAll( parser.getNamedParameters() );
+
+//		SQLQueryParser parser = new SQLQueryParser(
+//				sqlQuery,
+//				processor.getAlias2Persister(),
+//				processor.getAlias2Return(),
+//				aliases,
+//				collAliases,
+//				collPersisters,
+//				suffixes,
+//				collSuffixes
+//		);
+//
+//		sql = parser.process();
+//
+//		namedParameterBindPoints = parser.getNamedParameters();
+
+
+		customQueryReturns.addAll( processor.generateCustomReturns( parser.queryHasAliases() ) );
+
+//		// Populate entityNames, entityDescrptors and querySpaces
+//		entityNames = new String[entityPersisters.length];
+//		entityDescriptors = new EntityAliases[entityPersisters.length];
+//		for (int i = 0; i < entityPersisters.length; i++) {
+//			SQLLoadable persister = entityPersisters[i];
+//			//alias2Persister.put( aliases[i], persister );
+//			//TODO: Does not consider any other tables referenced in the query
+//			ArrayHelper.addAll( querySpaces, persister.getQuerySpaces() );
+//			entityNames[i] = persister.getEntityName();
+//			if ( parser.queryHasAliases() ) {
+//				entityDescriptors[i] = new DefaultEntityAliases(
+//						propertyResultMaps[i],
+//						entityPersisters[i],
+//						suffixes[i]
+//					);
+//			}
+//			else {
+//				entityDescriptors[i] = new ColumnEntityAliases(
+//						propertyResultMaps[i],
+//						entityPersisters[i],
+//						suffixes[i]
+//					);
+//			}
+//		}
+		if ( additionalQuerySpaces != null ) {
+			querySpaces.addAll( additionalQuerySpaces );
+		}
+
+//		if (size!=0) {
+//			collectionDescriptors = new CollectionAliases[size];
+//			for ( int i=0; i<size; i++ ) {
+//				CollectionPersister collectionPersister = (CollectionPersister) collectionPersisters.get(i);
+//				String suffix = i + "__";
+//				if( parser.queryHasAliases() ) {
+//					collectionDescriptors[i] = new GeneratedCollectionAliases( collectionResultMaps[i], collectionPersister, suffix );
+//				} else {
+//					collectionDescriptors[i] = new ColumnCollectionAliases( collectionResultMaps[i], (SQLLoadableCollection) collectionPersister );
+//				}
+//			}
+//		}
+//		else {
+//			collectionDescriptors = null;
+//		}
+//
+//
+//		// Resolve owners
+//		Map alias2OwnerAlias = processor.getAlias2OwnerAlias();
+//		int[] ownersArray = new int[entityPersisters.length];
+//		for ( int j=0; j < aliases.length; j++ ) {
+//			String ownerAlias = (String) alias2OwnerAlias.get( aliases[j] );
+//			if ( StringHelper.isNotEmpty(ownerAlias) ) {
+//				ownersArray[j] =  processor.getAliases().indexOf( ownerAlias );
+//			}
+//			else {
+//				ownersArray[j] = -1;
+//			}
+//		}
+//		if ( ArrayHelper.isAllNegative(ownersArray) ) {
+//			ownersArray = null;
+//		}
+//		this.entityOwners = ownersArray;
+
+	}
+
+
+	private static class ParserContext implements SQLQueryParser.ParserContext {
+
+		private final SQLQueryReturnProcessor.ResultAliasContext aliasContext;
+
+		public ParserContext(SQLQueryReturnProcessor.ResultAliasContext aliasContext) {
+			this.aliasContext = aliasContext;
+		}
+
+		public boolean isEntityAlias(String alias) {
+			return getEntityPersisterByAlias( alias ) != null;
+		}
+
+		public SQLLoadable getEntityPersisterByAlias(String alias) {
+			return aliasContext.getEntityPersister( alias );
+		}
+
+		public String getEntitySuffixByAlias(String alias) {
+			return aliasContext.getEntitySuffix( alias );
+		}
+
+		public boolean isCollectionAlias(String alias) {
+			return getCollectionPersisterByAlias( alias ) != null;
+		}
+
+		public SQLLoadableCollection getCollectionPersisterByAlias(String alias) {
+			return aliasContext.getCollectionPersister( alias );
+		}
+
+		public String getCollectionSuffixByAlias(String alias) {
+			return aliasContext.getCollectionSuffix( alias );
+		}
+
+		public Map getPropertyResultsMapByAlias(String alias) {
+			return aliasContext.getPropertyResultsMap( alias );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,274 +0,0 @@
-//$Id: SQLQueryParser.java 10067 2006-06-28 13:24:59Z steve.ebersole at jboss.com $
-package org.hibernate.loader.custom.sql;
-
-import org.hibernate.QueryException;
-import org.hibernate.engine.query.ParameterParser;
-import org.hibernate.persister.collection.SQLLoadableCollection;
-import org.hibernate.persister.entity.SQLLoadable;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Gavin King
- * @author Max Andersen
- * @author Steve Ebersole
- */
-public class SQLQueryParser {
-
-	private final String originalQueryString;
-	private final ParserContext context;
-
-	private final Map namedParameters = new HashMap();
-	private long aliasesFound = 0;
-
-	static interface ParserContext {
-		boolean isEntityAlias(String aliasName);
-		SQLLoadable getEntityPersisterByAlias(String alias);
-		String getEntitySuffixByAlias(String alias);
-		boolean isCollectionAlias(String aliasName);
-		SQLLoadableCollection getCollectionPersisterByAlias(String alias);
-		String getCollectionSuffixByAlias(String alias);
-		Map getPropertyResultsMapByAlias(String alias);
-	}
-
-	public SQLQueryParser(String queryString, ParserContext context) {
-		this.originalQueryString = queryString;
-		this.context = context;
-	}
-
-	public Map getNamedParameters() {
-		return namedParameters;
-	}
-
-	public boolean queryHasAliases() {
-		return aliasesFound>0;
-	}
-
-	public String process() {
-		return substituteParams( substituteBrackets( originalQueryString ) );
-	}
-
-	// TODO: should "record" how many properties we have reffered to - and if we 
-	//       don't get'em'all we throw an exception! Way better than trial and error ;)
-	private String substituteBrackets(String sqlQuery) throws QueryException {
-
-		StringBuffer result = new StringBuffer( sqlQuery.length() + 20 );
-		int left, right;
-
-		// replace {....} with corresponding column aliases
-		for ( int curr = 0; curr < sqlQuery.length(); curr = right + 1 ) {
-			if ( ( left = sqlQuery.indexOf( '{', curr ) ) < 0 ) {
-				// No additional open braces found in the string, append the
-				// rest of the string in its entirty and quit this loop
-				result.append( sqlQuery.substring( curr ) );
-				break;
-			}
-
-			// apend everything up until the next encountered open brace
-			result.append( sqlQuery.substring( curr, left ) );
-
-			if ( ( right = sqlQuery.indexOf( '}', left + 1 ) ) < 0 ) {
-				throw new QueryException( "Unmatched braces for alias path", sqlQuery );
-			}
-
-			String aliasPath = sqlQuery.substring( left + 1, right );
-			int firstDot = aliasPath.indexOf( '.' );
-			if ( firstDot == -1 ) {
-				if ( context.isEntityAlias( aliasPath ) ) {
-					// it is a simple table alias {foo}
-					result.append( aliasPath );
-					aliasesFound++;
-				} 
-				else {
-					// passing through anything we do not know : to support jdbc escape sequences HB-898
-					result.append( '{' ).append(aliasPath).append( '}' );					
-				}
-			}
-			else {
-				String aliasName = aliasPath.substring(0, firstDot);
-				boolean isCollection = context.isCollectionAlias( aliasName );
-				boolean isEntity = context.isEntityAlias( aliasName );
-				
-				if ( isCollection ) {
-					// The current alias is referencing the collection to be eagerly fetched
-					String propertyName = aliasPath.substring( firstDot + 1 );
-					result.append( resolveCollectionProperties( aliasName, propertyName ) );
-					aliasesFound++;
-				} 
-				else if ( isEntity ) {
-					// it is a property reference {foo.bar}
-					String propertyName = aliasPath.substring( firstDot + 1 );
-					result.append( resolveProperties( aliasName, propertyName ) );
-					aliasesFound++;
-				}
-				else {
-					// passing through anything we do not know : to support jdbc escape sequences HB-898
-					result.append( '{' ).append(aliasPath).append( '}' );
-				}
-	
-			}
-		}
-
-		// Possibly handle :something parameters for the query ?
-
-		return result.toString();
-	}	
-
-	private String resolveCollectionProperties(
-			String aliasName,
-			String propertyName) {
-
-		Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
-		SQLLoadableCollection collectionPersister = context.getCollectionPersisterByAlias( aliasName );
-		String collectionSuffix = context.getCollectionSuffixByAlias( aliasName );
-
-		if ( "*".equals( propertyName ) ) {
-			if( !fieldResults.isEmpty() ) {
-				throw new QueryException("Using return-propertys together with * syntax is not supported.");
-			}
-			
-			String selectFragment = collectionPersister.selectFragment( aliasName, collectionSuffix );
-			aliasesFound++;
-			return selectFragment 
-						+ ", " 
-						+ resolveProperties( aliasName, propertyName );
-		}
-		else if ( "element.*".equals( propertyName ) ) {
-			return resolveProperties( aliasName, "*" );
-		}
-		else {
-			String[] columnAliases;
-
-			// Let return-propertys override whatever the persister has for aliases.
-			columnAliases = ( String[] ) fieldResults.get(propertyName);
-			if ( columnAliases==null ) {
-				columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix );
-			}
-			
-			if ( columnAliases == null || columnAliases.length == 0 ) {
-				throw new QueryException(
-						"No column name found for property [" + propertyName + "] for alias [" + aliasName + "]",
-						originalQueryString
-				);
-			}
-			if ( columnAliases.length != 1 ) {
-				// TODO: better error message since we actually support composites if names are explicitly listed.
-				throw new QueryException(
-						"SQL queries only support properties mapped to a single column - property [" +
-						propertyName + "] is mapped to " + columnAliases.length + " columns.",
-						originalQueryString
-				);
-			}
-			aliasesFound++;
-			return columnAliases[0];
-		
-		}
-	}
-	private String resolveProperties(
-			String aliasName,
-	        String propertyName) {
-		Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
-		SQLLoadable persister = context.getEntityPersisterByAlias( aliasName );
-		String suffix = context.getEntitySuffixByAlias( aliasName );
-
-		if ( "*".equals( propertyName ) ) {
-			if( !fieldResults.isEmpty() ) {
-				throw new QueryException("Using return-propertys together with * syntax is not supported.");
-			}			
-			aliasesFound++;
-			return persister.selectFragment( aliasName, suffix ) ;
-		}
-		else {
-
-			String[] columnAliases;
-
-			// Let return-propertys override whatever the persister has for aliases.
-			columnAliases = (String[]) fieldResults.get( propertyName );
-			if ( columnAliases == null ) {
-				columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix );
-			}
-
-			if ( columnAliases == null || columnAliases.length == 0 ) {
-				throw new QueryException(
-						"No column name found for property [" + propertyName + "] for alias [" + aliasName + "]",
-						originalQueryString
-				);
-			}
-			if ( columnAliases.length != 1 ) {
-				// TODO: better error message since we actually support composites if names are explicitly listed.
-				throw new QueryException(
-						"SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.length + " columns.",
-						originalQueryString
-				);
-			}			
-			aliasesFound++;
-			return columnAliases[0];
-		}
-	}
-
-	/**
-	 * Substitues JDBC parameter placeholders (?) for all encountered
-	 * parameter specifications.  It also tracks the positions of these
-	 * parameter specifications within the query string.  This accounts for
-	 * ordinal-params, named-params, and ejb3-positional-params.
-	 *
-	 * @param sqlString The query string.
-	 * @return The SQL query with parameter substitution complete.
-	 */
-	private String substituteParams(String sqlString) {
-		ParameterSubstitutionRecognizer recognizer = new ParameterSubstitutionRecognizer();
-		ParameterParser.parse( sqlString, recognizer );
-
-		namedParameters.clear();
-		namedParameters.putAll( recognizer.namedParameterBindPoints );
-
-		return recognizer.result.toString();
-	}
-
-	public static class ParameterSubstitutionRecognizer implements ParameterParser.Recognizer {
-		StringBuffer result = new StringBuffer();
-		Map namedParameterBindPoints = new HashMap();
-		int parameterCount = 0;
-
-		public void outParameter(int position) {
-			result.append( '?' );
-		}
-
-		public void ordinalParameter(int position) {
-			result.append( '?' );
-		}
-
-		public void namedParameter(String name, int position) {
-			addNamedParameter( name );
-			result.append( '?' );
-		}
-
-		public void jpaPositionalParameter(String name, int position) {
-			namedParameter( name, position );
-		}
-
-		public void other(char character) {
-			result.append( character );
-		}
-
-		private void addNamedParameter(String name) {
-			Integer loc = new Integer( parameterCount++ );
-			Object o = namedParameterBindPoints.get( name );
-			if ( o == null ) {
-				namedParameterBindPoints.put( name, loc );
-			}
-			else if ( o instanceof Integer ) {
-				ArrayList list = new ArrayList( 4 );
-				list.add( o );
-				list.add( loc );
-				namedParameterBindPoints.put( name, list );
-			}
-			else {
-				( ( List ) o ).add( loc );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryParser.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,297 @@
+/*
+ * 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.loader.custom.sql;
+
+import org.hibernate.QueryException;
+import org.hibernate.engine.query.ParameterParser;
+import org.hibernate.persister.collection.SQLLoadableCollection;
+import org.hibernate.persister.entity.SQLLoadable;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Gavin King
+ * @author Max Andersen
+ * @author Steve Ebersole
+ */
+public class SQLQueryParser {
+
+	private final String originalQueryString;
+	private final ParserContext context;
+
+	private final Map namedParameters = new HashMap();
+	private long aliasesFound = 0;
+
+	static interface ParserContext {
+		boolean isEntityAlias(String aliasName);
+		SQLLoadable getEntityPersisterByAlias(String alias);
+		String getEntitySuffixByAlias(String alias);
+		boolean isCollectionAlias(String aliasName);
+		SQLLoadableCollection getCollectionPersisterByAlias(String alias);
+		String getCollectionSuffixByAlias(String alias);
+		Map getPropertyResultsMapByAlias(String alias);
+	}
+
+	public SQLQueryParser(String queryString, ParserContext context) {
+		this.originalQueryString = queryString;
+		this.context = context;
+	}
+
+	public Map getNamedParameters() {
+		return namedParameters;
+	}
+
+	public boolean queryHasAliases() {
+		return aliasesFound>0;
+	}
+
+	public String process() {
+		return substituteParams( substituteBrackets( originalQueryString ) );
+	}
+
+	// TODO: should "record" how many properties we have reffered to - and if we 
+	//       don't get'em'all we throw an exception! Way better than trial and error ;)
+	private String substituteBrackets(String sqlQuery) throws QueryException {
+
+		StringBuffer result = new StringBuffer( sqlQuery.length() + 20 );
+		int left, right;
+
+		// replace {....} with corresponding column aliases
+		for ( int curr = 0; curr < sqlQuery.length(); curr = right + 1 ) {
+			if ( ( left = sqlQuery.indexOf( '{', curr ) ) < 0 ) {
+				// No additional open braces found in the string, append the
+				// rest of the string in its entirty and quit this loop
+				result.append( sqlQuery.substring( curr ) );
+				break;
+			}
+
+			// apend everything up until the next encountered open brace
+			result.append( sqlQuery.substring( curr, left ) );
+
+			if ( ( right = sqlQuery.indexOf( '}', left + 1 ) ) < 0 ) {
+				throw new QueryException( "Unmatched braces for alias path", sqlQuery );
+			}
+
+			String aliasPath = sqlQuery.substring( left + 1, right );
+			int firstDot = aliasPath.indexOf( '.' );
+			if ( firstDot == -1 ) {
+				if ( context.isEntityAlias( aliasPath ) ) {
+					// it is a simple table alias {foo}
+					result.append( aliasPath );
+					aliasesFound++;
+				} 
+				else {
+					// passing through anything we do not know : to support jdbc escape sequences HB-898
+					result.append( '{' ).append(aliasPath).append( '}' );					
+				}
+			}
+			else {
+				String aliasName = aliasPath.substring(0, firstDot);
+				boolean isCollection = context.isCollectionAlias( aliasName );
+				boolean isEntity = context.isEntityAlias( aliasName );
+				
+				if ( isCollection ) {
+					// The current alias is referencing the collection to be eagerly fetched
+					String propertyName = aliasPath.substring( firstDot + 1 );
+					result.append( resolveCollectionProperties( aliasName, propertyName ) );
+					aliasesFound++;
+				} 
+				else if ( isEntity ) {
+					// it is a property reference {foo.bar}
+					String propertyName = aliasPath.substring( firstDot + 1 );
+					result.append( resolveProperties( aliasName, propertyName ) );
+					aliasesFound++;
+				}
+				else {
+					// passing through anything we do not know : to support jdbc escape sequences HB-898
+					result.append( '{' ).append(aliasPath).append( '}' );
+				}
+	
+			}
+		}
+
+		// Possibly handle :something parameters for the query ?
+
+		return result.toString();
+	}	
+
+	private String resolveCollectionProperties(
+			String aliasName,
+			String propertyName) {
+
+		Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
+		SQLLoadableCollection collectionPersister = context.getCollectionPersisterByAlias( aliasName );
+		String collectionSuffix = context.getCollectionSuffixByAlias( aliasName );
+
+		if ( "*".equals( propertyName ) ) {
+			if( !fieldResults.isEmpty() ) {
+				throw new QueryException("Using return-propertys together with * syntax is not supported.");
+			}
+			
+			String selectFragment = collectionPersister.selectFragment( aliasName, collectionSuffix );
+			aliasesFound++;
+			return selectFragment 
+						+ ", " 
+						+ resolveProperties( aliasName, propertyName );
+		}
+		else if ( "element.*".equals( propertyName ) ) {
+			return resolveProperties( aliasName, "*" );
+		}
+		else {
+			String[] columnAliases;
+
+			// Let return-propertys override whatever the persister has for aliases.
+			columnAliases = ( String[] ) fieldResults.get(propertyName);
+			if ( columnAliases==null ) {
+				columnAliases = collectionPersister.getCollectionPropertyColumnAliases( propertyName, collectionSuffix );
+			}
+			
+			if ( columnAliases == null || columnAliases.length == 0 ) {
+				throw new QueryException(
+						"No column name found for property [" + propertyName + "] for alias [" + aliasName + "]",
+						originalQueryString
+				);
+			}
+			if ( columnAliases.length != 1 ) {
+				// TODO: better error message since we actually support composites if names are explicitly listed.
+				throw new QueryException(
+						"SQL queries only support properties mapped to a single column - property [" +
+						propertyName + "] is mapped to " + columnAliases.length + " columns.",
+						originalQueryString
+				);
+			}
+			aliasesFound++;
+			return columnAliases[0];
+		
+		}
+	}
+	private String resolveProperties(
+			String aliasName,
+	        String propertyName) {
+		Map fieldResults = context.getPropertyResultsMapByAlias( aliasName );
+		SQLLoadable persister = context.getEntityPersisterByAlias( aliasName );
+		String suffix = context.getEntitySuffixByAlias( aliasName );
+
+		if ( "*".equals( propertyName ) ) {
+			if( !fieldResults.isEmpty() ) {
+				throw new QueryException("Using return-propertys together with * syntax is not supported.");
+			}			
+			aliasesFound++;
+			return persister.selectFragment( aliasName, suffix ) ;
+		}
+		else {
+
+			String[] columnAliases;
+
+			// Let return-propertys override whatever the persister has for aliases.
+			columnAliases = (String[]) fieldResults.get( propertyName );
+			if ( columnAliases == null ) {
+				columnAliases = persister.getSubclassPropertyColumnAliases( propertyName, suffix );
+			}
+
+			if ( columnAliases == null || columnAliases.length == 0 ) {
+				throw new QueryException(
+						"No column name found for property [" + propertyName + "] for alias [" + aliasName + "]",
+						originalQueryString
+				);
+			}
+			if ( columnAliases.length != 1 ) {
+				// TODO: better error message since we actually support composites if names are explicitly listed.
+				throw new QueryException(
+						"SQL queries only support properties mapped to a single column - property [" + propertyName + "] is mapped to " + columnAliases.length + " columns.",
+						originalQueryString
+				);
+			}			
+			aliasesFound++;
+			return columnAliases[0];
+		}
+	}
+
+	/**
+	 * Substitues JDBC parameter placeholders (?) for all encountered
+	 * parameter specifications.  It also tracks the positions of these
+	 * parameter specifications within the query string.  This accounts for
+	 * ordinal-params, named-params, and ejb3-positional-params.
+	 *
+	 * @param sqlString The query string.
+	 * @return The SQL query with parameter substitution complete.
+	 */
+	private String substituteParams(String sqlString) {
+		ParameterSubstitutionRecognizer recognizer = new ParameterSubstitutionRecognizer();
+		ParameterParser.parse( sqlString, recognizer );
+
+		namedParameters.clear();
+		namedParameters.putAll( recognizer.namedParameterBindPoints );
+
+		return recognizer.result.toString();
+	}
+
+	public static class ParameterSubstitutionRecognizer implements ParameterParser.Recognizer {
+		StringBuffer result = new StringBuffer();
+		Map namedParameterBindPoints = new HashMap();
+		int parameterCount = 0;
+
+		public void outParameter(int position) {
+			result.append( '?' );
+		}
+
+		public void ordinalParameter(int position) {
+			result.append( '?' );
+		}
+
+		public void namedParameter(String name, int position) {
+			addNamedParameter( name );
+			result.append( '?' );
+		}
+
+		public void jpaPositionalParameter(String name, int position) {
+			namedParameter( name, position );
+		}
+
+		public void other(char character) {
+			result.append( character );
+		}
+
+		private void addNamedParameter(String name) {
+			Integer loc = new Integer( parameterCount++ );
+			Object o = namedParameterBindPoints.get( name );
+			if ( o == null ) {
+				namedParameterBindPoints.put( name, loc );
+			}
+			else if ( o instanceof Integer ) {
+				ArrayList list = new ArrayList( 4 );
+				list.add( o );
+				list.add( loc );
+				namedParameterBindPoints.put( name, list );
+			}
+			else {
+				( ( List ) o ).add( loc );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,502 +0,0 @@
-//$Id: SQLQueryReturnProcessor.java 7370 2005-07-04 11:17:33Z maxcsaucdk $
-package org.hibernate.loader.custom.sql;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.loader.custom.Return;
-import org.hibernate.loader.custom.ScalarReturn;
-import org.hibernate.loader.custom.RootReturn;
-import org.hibernate.loader.custom.CollectionReturn;
-import org.hibernate.loader.custom.ColumnCollectionAliases;
-import org.hibernate.loader.custom.FetchReturn;
-import org.hibernate.loader.custom.CollectionFetchReturn;
-import org.hibernate.loader.custom.NonScalarReturn;
-import org.hibernate.loader.custom.EntityFetchReturn;
-import org.hibernate.loader.BasicLoader;
-import org.hibernate.loader.EntityAliases;
-import org.hibernate.loader.DefaultEntityAliases;
-import org.hibernate.loader.ColumnEntityAliases;
-import org.hibernate.loader.CollectionAliases;
-import org.hibernate.loader.GeneratedCollectionAliases;
-import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryNonScalarReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
-import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.SQLLoadableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.SQLLoadable;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Responsible for processing the series of {@link org.hibernate.engine.query.sql.NativeSQLQueryReturn returns}
- * defined by a {@link org.hibernate.engine.query.sql.NativeSQLQuerySpecification} and
- * breaking them down into a series of {@link Return returns} for use within the
- * {@link org.hibernate.loader.custom.CustomLoader}.
- *
- * @author Gavin King
- * @author Max Andersen
- * @author Steve Ebersole
- */
-public class SQLQueryReturnProcessor {
-
-	public static final Logger log = LoggerFactory.getLogger( SQLQueryReturnProcessor.class );
-
-	private NativeSQLQueryReturn[] queryReturns;
-
-//	private final List persisters = new ArrayList();
-
-	private final Map alias2Return = new HashMap();
-	private final Map alias2OwnerAlias = new HashMap();
-
-	private final Map alias2Persister = new HashMap();
-	private final Map alias2Suffix = new HashMap();
-
-	private final Map alias2CollectionPersister = new HashMap();
-	private final Map alias2CollectionSuffix = new HashMap();
-
-	private final Map entityPropertyResultMaps = new HashMap();
-	private final Map collectionPropertyResultMaps = new HashMap();
-
-//	private final List scalarTypes = new ArrayList();
-//	private final List scalarColumnAliases = new ArrayList();
-
-	private final SessionFactoryImplementor factory;
-
-//	private List collectionOwnerAliases = new ArrayList();
-//	private List collectionAliases = new ArrayList();
-//	private List collectionPersisters = new ArrayList();
-//	private List collectionResults = new ArrayList();
-
-	private int entitySuffixSeed = 0;
-	private int collectionSuffixSeed = 0;
-
-
-	public SQLQueryReturnProcessor(NativeSQLQueryReturn[] queryReturns, SessionFactoryImplementor factory) {
-		this.queryReturns = queryReturns;
-		this.factory = factory;
-	}
-
-	/*package*/ class ResultAliasContext {
-		public SQLLoadable getEntityPersister(String alias) {
-			return ( SQLLoadable ) alias2Persister.get( alias );
-		}
-
-		public SQLLoadableCollection getCollectionPersister(String alias) {
-			return ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
-		}
-
-		public String getEntitySuffix(String alias) {
-			return ( String ) alias2Suffix.get( alias );
-		}
-
-		public String getCollectionSuffix(String alias) {
-			return ( String ) alias2CollectionSuffix.get ( alias );
-		}
-
-		public String getOwnerAlias(String alias) {
-			return ( String ) alias2OwnerAlias.get( alias );
-		}
-
-		public Map getPropertyResultsMap(String alias) {
-			return internalGetPropertyResultsMap( alias );
-		}
-	}
-
-	private Map internalGetPropertyResultsMap(String alias) {
-		NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) alias2Return.get( alias );
-		if ( rtn instanceof NativeSQLQueryNonScalarReturn ) {
-			return ( ( NativeSQLQueryNonScalarReturn ) rtn ).getPropertyResultsMap();
-		}
-		else {
-			return null;
-		}
-	}
-
-	private boolean hasPropertyResultMap(String alias) {
-		Map propertyMaps = internalGetPropertyResultsMap( alias );
-		return propertyMaps != null && ! propertyMaps.isEmpty();
-	}
-
-	public ResultAliasContext process() {
-		// first, break down the returns into maps keyed by alias
-		// so that role returns can be more easily resolved to their owners
-		for ( int i = 0; i < queryReturns.length; i++ ) {
-			if ( queryReturns[i] instanceof NativeSQLQueryNonScalarReturn ) {
-				NativeSQLQueryNonScalarReturn rtn = ( NativeSQLQueryNonScalarReturn ) queryReturns[i];
-				alias2Return.put( rtn.getAlias(), rtn );
-				if ( rtn instanceof NativeSQLQueryJoinReturn ) {
-					NativeSQLQueryJoinReturn fetchReturn = ( NativeSQLQueryJoinReturn ) rtn;
-					alias2OwnerAlias.put( fetchReturn.getAlias(), fetchReturn.getOwnerAlias() );
-				}
-			}
-		}
-
-		// Now, process the returns
-		for ( int i = 0; i < queryReturns.length; i++ ) {
-			processReturn( queryReturns[i] );
-		}
-
-		return new ResultAliasContext();
-	}
-
-	public List generateCustomReturns(boolean queryHadAliases) {
-		List customReturns = new ArrayList();
-		Map customReturnsByAlias = new HashMap();
-		for ( int i = 0; i < queryReturns.length; i++ ) {
-			if ( queryReturns[i] instanceof NativeSQLQueryScalarReturn ) {
-				NativeSQLQueryScalarReturn rtn = ( NativeSQLQueryScalarReturn ) queryReturns[i];
-				customReturns.add( new ScalarReturn( rtn.getType(), rtn.getColumnAlias() ) );
-			}
-			else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) {
-				NativeSQLQueryRootReturn rtn = ( NativeSQLQueryRootReturn ) queryReturns[i];
-				String alias = rtn.getAlias();
-				EntityAliases entityAliases;
-				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
-					entityAliases = new DefaultEntityAliases(
-							( Map ) entityPropertyResultMaps.get( alias ),
-							( SQLLoadable ) alias2Persister.get( alias ),
-							( String ) alias2Suffix.get( alias )
-					);
-				}
-				else {
-					entityAliases = new ColumnEntityAliases(
-							( Map ) entityPropertyResultMaps.get( alias ),
-							( SQLLoadable ) alias2Persister.get( alias ),
-							( String ) alias2Suffix.get( alias )
-					);
-				}
-				RootReturn customReturn = new RootReturn(
-						alias,
-						rtn.getReturnEntityName(),
-						entityAliases,
-						rtn.getLockMode()
-				);
-				customReturns.add( customReturn );
-				customReturnsByAlias.put( rtn.getAlias(), customReturn );
-			}
-			else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) {
-				NativeSQLQueryCollectionReturn rtn = ( NativeSQLQueryCollectionReturn ) queryReturns[i];
-				String alias = rtn.getAlias();
-				SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
-				boolean isEntityElements = persister.getElementType().isEntityType();
-				CollectionAliases collectionAliases;
-				EntityAliases elementEntityAliases = null;
-				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
-					collectionAliases = new GeneratedCollectionAliases(
-							( Map ) collectionPropertyResultMaps.get( alias ),
-							( SQLLoadableCollection ) alias2CollectionPersister.get( alias ),
-							( String ) alias2CollectionSuffix.get( alias )
-					);
-					if ( isEntityElements ) {
-						elementEntityAliases = new DefaultEntityAliases(
-								( Map ) entityPropertyResultMaps.get( alias ),
-								( SQLLoadable ) alias2Persister.get( alias ),
-								( String ) alias2Suffix.get( alias )
-						);
-					}
-				}
-				else {
-					collectionAliases = new ColumnCollectionAliases(
-							( Map ) collectionPropertyResultMaps.get( alias ),
-							( SQLLoadableCollection ) alias2CollectionPersister.get( alias )
-					);
-					if ( isEntityElements ) {
-						elementEntityAliases = new ColumnEntityAliases(
-								( Map ) entityPropertyResultMaps.get( alias ),
-								( SQLLoadable ) alias2Persister.get( alias ),
-								( String ) alias2Suffix.get( alias )
-						);
-					}
-				}
-				CollectionReturn customReturn = new CollectionReturn(
-						alias,
-						rtn.getOwnerEntityName(),
-						rtn.getOwnerProperty(),
-						collectionAliases,
-				        elementEntityAliases,
-						rtn.getLockMode()
-				);
-				customReturns.add( customReturn );
-				customReturnsByAlias.put( rtn.getAlias(), customReturn );
-			}
-			else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
-				NativeSQLQueryJoinReturn rtn = ( NativeSQLQueryJoinReturn ) queryReturns[i];
-				String alias = rtn.getAlias();
-				FetchReturn customReturn;
-				NonScalarReturn ownerCustomReturn = ( NonScalarReturn ) customReturnsByAlias.get( rtn.getOwnerAlias() );
-				if ( alias2CollectionPersister.containsKey( alias ) ) {
-					SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
-					boolean isEntityElements = persister.getElementType().isEntityType();
-					CollectionAliases collectionAliases;
-					EntityAliases elementEntityAliases = null;
-					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
-						collectionAliases = new GeneratedCollectionAliases(
-								( Map ) collectionPropertyResultMaps.get( alias ),
-								persister,
-								( String ) alias2CollectionSuffix.get( alias )
-						);
-						if ( isEntityElements ) {
-							elementEntityAliases = new DefaultEntityAliases(
-									( Map ) entityPropertyResultMaps.get( alias ),
-									( SQLLoadable ) alias2Persister.get( alias ),
-									( String ) alias2Suffix.get( alias )
-							);
-						}
-					}
-					else {
-						collectionAliases = new ColumnCollectionAliases(
-								( Map ) collectionPropertyResultMaps.get( alias ),
-								persister
-						);
-						if ( isEntityElements ) {
-							elementEntityAliases = new ColumnEntityAliases(
-									( Map ) entityPropertyResultMaps.get( alias ),
-									( SQLLoadable ) alias2Persister.get( alias ),
-									( String ) alias2Suffix.get( alias )
-							);
-						}
-					}
-					customReturn = new CollectionFetchReturn(
-							alias,
-							ownerCustomReturn,
-							rtn.getOwnerProperty(),
-							collectionAliases,
-					        elementEntityAliases,
-							rtn.getLockMode()
-					);
-				}
-				else {
-					EntityAliases entityAliases;
-					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
-						entityAliases = new DefaultEntityAliases(
-								( Map ) entityPropertyResultMaps.get( alias ),
-								( SQLLoadable ) alias2Persister.get( alias ),
-								( String ) alias2Suffix.get( alias )
-						);
-					}
-					else {
-						entityAliases = new ColumnEntityAliases(
-								( Map ) entityPropertyResultMaps.get( alias ),
-								( SQLLoadable ) alias2Persister.get( alias ),
-								( String ) alias2Suffix.get( alias )
-						);
-					}
-					customReturn = new EntityFetchReturn(
-							alias,
-							entityAliases,
-							ownerCustomReturn,
-							rtn.getOwnerProperty(),
-							rtn.getLockMode()
-					);
-				}
-				customReturns.add( customReturn );
-				customReturnsByAlias.put( alias, customReturn );
-			}
-		}
-		return customReturns;
-	}
-
-	private SQLLoadable getSQLLoadable(String entityName) throws MappingException {
-		EntityPersister persister = factory.getEntityPersister( entityName );
-		if ( !(persister instanceof SQLLoadable) ) {
-			throw new MappingException( "class persister is not SQLLoadable: " + entityName );
-		}
-		return (SQLLoadable) persister;
-	}
-
-	private String generateEntitySuffix() {
-		return BasicLoader.generateSuffixes( entitySuffixSeed++, 1 )[0];
-	}
-
-	private String generateCollectionSuffix() {
-		return collectionSuffixSeed++ + "__";
-	}
-
-	private void processReturn(NativeSQLQueryReturn rtn) {
-		if ( rtn instanceof NativeSQLQueryScalarReturn ) {
-			processScalarReturn( ( NativeSQLQueryScalarReturn ) rtn );
-		}
-		else if ( rtn instanceof NativeSQLQueryRootReturn ) {
-			processRootReturn( ( NativeSQLQueryRootReturn ) rtn );
-		}
-		else if ( rtn instanceof NativeSQLQueryCollectionReturn ) {
-			processCollectionReturn( ( NativeSQLQueryCollectionReturn ) rtn );
-		}
-		else {
-			processJoinReturn( ( NativeSQLQueryJoinReturn ) rtn );
-		}
-	}
-
-	private void processScalarReturn(NativeSQLQueryScalarReturn typeReturn) {
-//		scalarColumnAliases.add( typeReturn.getColumnAlias() );
-//		scalarTypes.add( typeReturn.getType() );
-	}
-
-	private void processRootReturn(NativeSQLQueryRootReturn rootReturn) {
-		if ( alias2Persister.containsKey( rootReturn.getAlias() ) ) {
-			// already been processed...
-			return;
-		}
-
-		SQLLoadable persister = getSQLLoadable( rootReturn.getReturnEntityName() );
-		addPersister( rootReturn.getAlias(), rootReturn.getPropertyResultsMap(), persister );
-	}
-
-	/**
-	 * @param propertyResult
-	 * @param persister
-	 */
-	private void addPersister(String alias, Map propertyResult, SQLLoadable persister) {
-		alias2Persister.put( alias, persister );
-		String suffix = generateEntitySuffix();
-		log.trace( "mapping alias [" + alias + "] to entity-suffix [" + suffix + "]" );
-		alias2Suffix.put( alias, suffix );
-		entityPropertyResultMaps.put( alias, propertyResult );
-	}
-
-	private void addCollection(String role, String alias, Map propertyResults) {
-		SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role );
-		alias2CollectionPersister.put( alias, collectionPersister );
-		String suffix = generateCollectionSuffix();
-		log.trace( "mapping alias [" + alias + "] to collection-suffix [" + suffix + "]" );
-		alias2CollectionSuffix.put( alias, suffix );
-		collectionPropertyResultMaps.put( alias, propertyResults );
-
-		if ( collectionPersister.isOneToMany() ) {
-			SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister();
-			addPersister( alias, filter( propertyResults ), persister );
-		}
-	}
-
-	private Map filter(Map propertyResults) {
-		Map result = new HashMap( propertyResults.size() );
-
-		String keyPrefix = "element.";
-
-		Iterator iter = propertyResults.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry element = ( Map.Entry ) iter.next();
-			String path = ( String ) element.getKey();
-			if ( path.startsWith( keyPrefix ) ) {
-				result.put( path.substring( keyPrefix.length() ), element.getValue() );
-			}
-		}
-
-		return result;
-	}
-
-	private void processCollectionReturn(NativeSQLQueryCollectionReturn collectionReturn) {
-		// we are initializing an owned collection
-		//collectionOwners.add( new Integer(-1) );
-//		collectionOwnerAliases.add( null );
-		String role = collectionReturn.getOwnerEntityName() + '.' + collectionReturn.getOwnerProperty();
-		addCollection(
-				role,
-				collectionReturn.getAlias(),
-				collectionReturn.getPropertyResultsMap()
-		);
-	}
-
-	private void processJoinReturn(NativeSQLQueryJoinReturn fetchReturn) {
-		String alias = fetchReturn.getAlias();
-//		if ( alias2Persister.containsKey( alias ) || collectionAliases.contains( alias ) ) {
-		if ( alias2Persister.containsKey( alias ) || alias2CollectionPersister.containsKey( alias ) ) {
-			// already been processed...
-			return;
-		}
-
-		String ownerAlias = fetchReturn.getOwnerAlias();
-
-		// Make sure the owner alias is known...
-		if ( !alias2Return.containsKey( ownerAlias ) ) {
-			throw new HibernateException( "Owner alias [" + ownerAlias + "] is unknown for alias [" + alias + "]" );
-		}
-
-		// If this return's alias has not been processed yet, do so b4 further processing of this return
-		if ( !alias2Persister.containsKey( ownerAlias ) ) {
-			NativeSQLQueryNonScalarReturn ownerReturn = ( NativeSQLQueryNonScalarReturn ) alias2Return.get(ownerAlias);
-			processReturn( ownerReturn );
-		}
-
-		SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias );
-		Type returnType = ownerPersister.getPropertyType( fetchReturn.getOwnerProperty() );
-
-		if ( returnType.isCollectionType() ) {
-			String role = ownerPersister.getEntityName() + '.' + fetchReturn.getOwnerProperty();
-			addCollection( role, alias, fetchReturn.getPropertyResultsMap() );
-//			collectionOwnerAliases.add( ownerAlias );
-		}
-		else if ( returnType.isEntityType() ) {
-			EntityType eType = ( EntityType ) returnType;
-			String returnEntityName = eType.getAssociatedEntityName();
-			SQLLoadable persister = getSQLLoadable( returnEntityName );
-			addPersister( alias, fetchReturn.getPropertyResultsMap(), persister );
-		}
-
-	}
-
-//	public List getCollectionAliases() {
-//		return collectionAliases;
-//	}
-//
-//	/*public List getCollectionOwners() {
-//		return collectionOwners;
-//	}*/
-//
-//	public List getCollectionOwnerAliases() {
-//		return collectionOwnerAliases;
-//	}
-//
-//	public List getCollectionPersisters() {
-//		return collectionPersisters;
-//	}
-//
-//	public Map getAlias2Persister() {
-//		return alias2Persister;
-//	}
-//
-//	/*public boolean isCollectionInitializer() {
-//		return isCollectionInitializer;
-//	}*/
-//
-////	public List getPersisters() {
-////		return persisters;
-////	}
-//
-//	public Map getAlias2OwnerAlias() {
-//		return alias2OwnerAlias;
-//	}
-//
-//	public List getScalarTypes() {
-//		return scalarTypes;
-//	}
-//	public List getScalarColumnAliases() {
-//		return scalarColumnAliases;
-//	}
-//
-//	public List getPropertyResults() {
-//		return propertyResults;
-//	}
-//
-//	public List getCollectionPropertyResults() {
-//		return collectionResults;
-//	}
-//
-//
-//	public Map getAlias2Return() {
-//		return alias2Return;
-//	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/custom/sql/SQLQueryReturnProcessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,525 @@
+/*
+ * 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.loader.custom.sql;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.loader.custom.Return;
+import org.hibernate.loader.custom.ScalarReturn;
+import org.hibernate.loader.custom.RootReturn;
+import org.hibernate.loader.custom.CollectionReturn;
+import org.hibernate.loader.custom.ColumnCollectionAliases;
+import org.hibernate.loader.custom.FetchReturn;
+import org.hibernate.loader.custom.CollectionFetchReturn;
+import org.hibernate.loader.custom.NonScalarReturn;
+import org.hibernate.loader.custom.EntityFetchReturn;
+import org.hibernate.loader.BasicLoader;
+import org.hibernate.loader.EntityAliases;
+import org.hibernate.loader.DefaultEntityAliases;
+import org.hibernate.loader.ColumnEntityAliases;
+import org.hibernate.loader.CollectionAliases;
+import org.hibernate.loader.GeneratedCollectionAliases;
+import org.hibernate.engine.query.sql.NativeSQLQueryReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryCollectionReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryScalarReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryNonScalarReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryJoinReturn;
+import org.hibernate.engine.query.sql.NativeSQLQueryRootReturn;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.SQLLoadableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.SQLLoadable;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for processing the series of {@link org.hibernate.engine.query.sql.NativeSQLQueryReturn returns}
+ * defined by a {@link org.hibernate.engine.query.sql.NativeSQLQuerySpecification} and
+ * breaking them down into a series of {@link Return returns} for use within the
+ * {@link org.hibernate.loader.custom.CustomLoader}.
+ *
+ * @author Gavin King
+ * @author Max Andersen
+ * @author Steve Ebersole
+ */
+public class SQLQueryReturnProcessor {
+
+	public static final Logger log = LoggerFactory.getLogger( SQLQueryReturnProcessor.class );
+
+	private NativeSQLQueryReturn[] queryReturns;
+
+//	private final List persisters = new ArrayList();
+
+	private final Map alias2Return = new HashMap();
+	private final Map alias2OwnerAlias = new HashMap();
+
+	private final Map alias2Persister = new HashMap();
+	private final Map alias2Suffix = new HashMap();
+
+	private final Map alias2CollectionPersister = new HashMap();
+	private final Map alias2CollectionSuffix = new HashMap();
+
+	private final Map entityPropertyResultMaps = new HashMap();
+	private final Map collectionPropertyResultMaps = new HashMap();
+
+//	private final List scalarTypes = new ArrayList();
+//	private final List scalarColumnAliases = new ArrayList();
+
+	private final SessionFactoryImplementor factory;
+
+//	private List collectionOwnerAliases = new ArrayList();
+//	private List collectionAliases = new ArrayList();
+//	private List collectionPersisters = new ArrayList();
+//	private List collectionResults = new ArrayList();
+
+	private int entitySuffixSeed = 0;
+	private int collectionSuffixSeed = 0;
+
+
+	public SQLQueryReturnProcessor(NativeSQLQueryReturn[] queryReturns, SessionFactoryImplementor factory) {
+		this.queryReturns = queryReturns;
+		this.factory = factory;
+	}
+
+	/*package*/ class ResultAliasContext {
+		public SQLLoadable getEntityPersister(String alias) {
+			return ( SQLLoadable ) alias2Persister.get( alias );
+		}
+
+		public SQLLoadableCollection getCollectionPersister(String alias) {
+			return ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
+		}
+
+		public String getEntitySuffix(String alias) {
+			return ( String ) alias2Suffix.get( alias );
+		}
+
+		public String getCollectionSuffix(String alias) {
+			return ( String ) alias2CollectionSuffix.get ( alias );
+		}
+
+		public String getOwnerAlias(String alias) {
+			return ( String ) alias2OwnerAlias.get( alias );
+		}
+
+		public Map getPropertyResultsMap(String alias) {
+			return internalGetPropertyResultsMap( alias );
+		}
+	}
+
+	private Map internalGetPropertyResultsMap(String alias) {
+		NativeSQLQueryReturn rtn = ( NativeSQLQueryReturn ) alias2Return.get( alias );
+		if ( rtn instanceof NativeSQLQueryNonScalarReturn ) {
+			return ( ( NativeSQLQueryNonScalarReturn ) rtn ).getPropertyResultsMap();
+		}
+		else {
+			return null;
+		}
+	}
+
+	private boolean hasPropertyResultMap(String alias) {
+		Map propertyMaps = internalGetPropertyResultsMap( alias );
+		return propertyMaps != null && ! propertyMaps.isEmpty();
+	}
+
+	public ResultAliasContext process() {
+		// first, break down the returns into maps keyed by alias
+		// so that role returns can be more easily resolved to their owners
+		for ( int i = 0; i < queryReturns.length; i++ ) {
+			if ( queryReturns[i] instanceof NativeSQLQueryNonScalarReturn ) {
+				NativeSQLQueryNonScalarReturn rtn = ( NativeSQLQueryNonScalarReturn ) queryReturns[i];
+				alias2Return.put( rtn.getAlias(), rtn );
+				if ( rtn instanceof NativeSQLQueryJoinReturn ) {
+					NativeSQLQueryJoinReturn fetchReturn = ( NativeSQLQueryJoinReturn ) rtn;
+					alias2OwnerAlias.put( fetchReturn.getAlias(), fetchReturn.getOwnerAlias() );
+				}
+			}
+		}
+
+		// Now, process the returns
+		for ( int i = 0; i < queryReturns.length; i++ ) {
+			processReturn( queryReturns[i] );
+		}
+
+		return new ResultAliasContext();
+	}
+
+	public List generateCustomReturns(boolean queryHadAliases) {
+		List customReturns = new ArrayList();
+		Map customReturnsByAlias = new HashMap();
+		for ( int i = 0; i < queryReturns.length; i++ ) {
+			if ( queryReturns[i] instanceof NativeSQLQueryScalarReturn ) {
+				NativeSQLQueryScalarReturn rtn = ( NativeSQLQueryScalarReturn ) queryReturns[i];
+				customReturns.add( new ScalarReturn( rtn.getType(), rtn.getColumnAlias() ) );
+			}
+			else if ( queryReturns[i] instanceof NativeSQLQueryRootReturn ) {
+				NativeSQLQueryRootReturn rtn = ( NativeSQLQueryRootReturn ) queryReturns[i];
+				String alias = rtn.getAlias();
+				EntityAliases entityAliases;
+				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
+					entityAliases = new DefaultEntityAliases(
+							( Map ) entityPropertyResultMaps.get( alias ),
+							( SQLLoadable ) alias2Persister.get( alias ),
+							( String ) alias2Suffix.get( alias )
+					);
+				}
+				else {
+					entityAliases = new ColumnEntityAliases(
+							( Map ) entityPropertyResultMaps.get( alias ),
+							( SQLLoadable ) alias2Persister.get( alias ),
+							( String ) alias2Suffix.get( alias )
+					);
+				}
+				RootReturn customReturn = new RootReturn(
+						alias,
+						rtn.getReturnEntityName(),
+						entityAliases,
+						rtn.getLockMode()
+				);
+				customReturns.add( customReturn );
+				customReturnsByAlias.put( rtn.getAlias(), customReturn );
+			}
+			else if ( queryReturns[i] instanceof NativeSQLQueryCollectionReturn ) {
+				NativeSQLQueryCollectionReturn rtn = ( NativeSQLQueryCollectionReturn ) queryReturns[i];
+				String alias = rtn.getAlias();
+				SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
+				boolean isEntityElements = persister.getElementType().isEntityType();
+				CollectionAliases collectionAliases;
+				EntityAliases elementEntityAliases = null;
+				if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
+					collectionAliases = new GeneratedCollectionAliases(
+							( Map ) collectionPropertyResultMaps.get( alias ),
+							( SQLLoadableCollection ) alias2CollectionPersister.get( alias ),
+							( String ) alias2CollectionSuffix.get( alias )
+					);
+					if ( isEntityElements ) {
+						elementEntityAliases = new DefaultEntityAliases(
+								( Map ) entityPropertyResultMaps.get( alias ),
+								( SQLLoadable ) alias2Persister.get( alias ),
+								( String ) alias2Suffix.get( alias )
+						);
+					}
+				}
+				else {
+					collectionAliases = new ColumnCollectionAliases(
+							( Map ) collectionPropertyResultMaps.get( alias ),
+							( SQLLoadableCollection ) alias2CollectionPersister.get( alias )
+					);
+					if ( isEntityElements ) {
+						elementEntityAliases = new ColumnEntityAliases(
+								( Map ) entityPropertyResultMaps.get( alias ),
+								( SQLLoadable ) alias2Persister.get( alias ),
+								( String ) alias2Suffix.get( alias )
+						);
+					}
+				}
+				CollectionReturn customReturn = new CollectionReturn(
+						alias,
+						rtn.getOwnerEntityName(),
+						rtn.getOwnerProperty(),
+						collectionAliases,
+				        elementEntityAliases,
+						rtn.getLockMode()
+				);
+				customReturns.add( customReturn );
+				customReturnsByAlias.put( rtn.getAlias(), customReturn );
+			}
+			else if ( queryReturns[i] instanceof NativeSQLQueryJoinReturn ) {
+				NativeSQLQueryJoinReturn rtn = ( NativeSQLQueryJoinReturn ) queryReturns[i];
+				String alias = rtn.getAlias();
+				FetchReturn customReturn;
+				NonScalarReturn ownerCustomReturn = ( NonScalarReturn ) customReturnsByAlias.get( rtn.getOwnerAlias() );
+				if ( alias2CollectionPersister.containsKey( alias ) ) {
+					SQLLoadableCollection persister = ( SQLLoadableCollection ) alias2CollectionPersister.get( alias );
+					boolean isEntityElements = persister.getElementType().isEntityType();
+					CollectionAliases collectionAliases;
+					EntityAliases elementEntityAliases = null;
+					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
+						collectionAliases = new GeneratedCollectionAliases(
+								( Map ) collectionPropertyResultMaps.get( alias ),
+								persister,
+								( String ) alias2CollectionSuffix.get( alias )
+						);
+						if ( isEntityElements ) {
+							elementEntityAliases = new DefaultEntityAliases(
+									( Map ) entityPropertyResultMaps.get( alias ),
+									( SQLLoadable ) alias2Persister.get( alias ),
+									( String ) alias2Suffix.get( alias )
+							);
+						}
+					}
+					else {
+						collectionAliases = new ColumnCollectionAliases(
+								( Map ) collectionPropertyResultMaps.get( alias ),
+								persister
+						);
+						if ( isEntityElements ) {
+							elementEntityAliases = new ColumnEntityAliases(
+									( Map ) entityPropertyResultMaps.get( alias ),
+									( SQLLoadable ) alias2Persister.get( alias ),
+									( String ) alias2Suffix.get( alias )
+							);
+						}
+					}
+					customReturn = new CollectionFetchReturn(
+							alias,
+							ownerCustomReturn,
+							rtn.getOwnerProperty(),
+							collectionAliases,
+					        elementEntityAliases,
+							rtn.getLockMode()
+					);
+				}
+				else {
+					EntityAliases entityAliases;
+					if ( queryHadAliases || hasPropertyResultMap( alias ) ) {
+						entityAliases = new DefaultEntityAliases(
+								( Map ) entityPropertyResultMaps.get( alias ),
+								( SQLLoadable ) alias2Persister.get( alias ),
+								( String ) alias2Suffix.get( alias )
+						);
+					}
+					else {
+						entityAliases = new ColumnEntityAliases(
+								( Map ) entityPropertyResultMaps.get( alias ),
+								( SQLLoadable ) alias2Persister.get( alias ),
+								( String ) alias2Suffix.get( alias )
+						);
+					}
+					customReturn = new EntityFetchReturn(
+							alias,
+							entityAliases,
+							ownerCustomReturn,
+							rtn.getOwnerProperty(),
+							rtn.getLockMode()
+					);
+				}
+				customReturns.add( customReturn );
+				customReturnsByAlias.put( alias, customReturn );
+			}
+		}
+		return customReturns;
+	}
+
+	private SQLLoadable getSQLLoadable(String entityName) throws MappingException {
+		EntityPersister persister = factory.getEntityPersister( entityName );
+		if ( !(persister instanceof SQLLoadable) ) {
+			throw new MappingException( "class persister is not SQLLoadable: " + entityName );
+		}
+		return (SQLLoadable) persister;
+	}
+
+	private String generateEntitySuffix() {
+		return BasicLoader.generateSuffixes( entitySuffixSeed++, 1 )[0];
+	}
+
+	private String generateCollectionSuffix() {
+		return collectionSuffixSeed++ + "__";
+	}
+
+	private void processReturn(NativeSQLQueryReturn rtn) {
+		if ( rtn instanceof NativeSQLQueryScalarReturn ) {
+			processScalarReturn( ( NativeSQLQueryScalarReturn ) rtn );
+		}
+		else if ( rtn instanceof NativeSQLQueryRootReturn ) {
+			processRootReturn( ( NativeSQLQueryRootReturn ) rtn );
+		}
+		else if ( rtn instanceof NativeSQLQueryCollectionReturn ) {
+			processCollectionReturn( ( NativeSQLQueryCollectionReturn ) rtn );
+		}
+		else {
+			processJoinReturn( ( NativeSQLQueryJoinReturn ) rtn );
+		}
+	}
+
+	private void processScalarReturn(NativeSQLQueryScalarReturn typeReturn) {
+//		scalarColumnAliases.add( typeReturn.getColumnAlias() );
+//		scalarTypes.add( typeReturn.getType() );
+	}
+
+	private void processRootReturn(NativeSQLQueryRootReturn rootReturn) {
+		if ( alias2Persister.containsKey( rootReturn.getAlias() ) ) {
+			// already been processed...
+			return;
+		}
+
+		SQLLoadable persister = getSQLLoadable( rootReturn.getReturnEntityName() );
+		addPersister( rootReturn.getAlias(), rootReturn.getPropertyResultsMap(), persister );
+	}
+
+	/**
+	 * @param propertyResult
+	 * @param persister
+	 */
+	private void addPersister(String alias, Map propertyResult, SQLLoadable persister) {
+		alias2Persister.put( alias, persister );
+		String suffix = generateEntitySuffix();
+		log.trace( "mapping alias [" + alias + "] to entity-suffix [" + suffix + "]" );
+		alias2Suffix.put( alias, suffix );
+		entityPropertyResultMaps.put( alias, propertyResult );
+	}
+
+	private void addCollection(String role, String alias, Map propertyResults) {
+		SQLLoadableCollection collectionPersister = ( SQLLoadableCollection ) factory.getCollectionPersister( role );
+		alias2CollectionPersister.put( alias, collectionPersister );
+		String suffix = generateCollectionSuffix();
+		log.trace( "mapping alias [" + alias + "] to collection-suffix [" + suffix + "]" );
+		alias2CollectionSuffix.put( alias, suffix );
+		collectionPropertyResultMaps.put( alias, propertyResults );
+
+		if ( collectionPersister.isOneToMany() ) {
+			SQLLoadable persister = ( SQLLoadable ) collectionPersister.getElementPersister();
+			addPersister( alias, filter( propertyResults ), persister );
+		}
+	}
+
+	private Map filter(Map propertyResults) {
+		Map result = new HashMap( propertyResults.size() );
+
+		String keyPrefix = "element.";
+
+		Iterator iter = propertyResults.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry element = ( Map.Entry ) iter.next();
+			String path = ( String ) element.getKey();
+			if ( path.startsWith( keyPrefix ) ) {
+				result.put( path.substring( keyPrefix.length() ), element.getValue() );
+			}
+		}
+
+		return result;
+	}
+
+	private void processCollectionReturn(NativeSQLQueryCollectionReturn collectionReturn) {
+		// we are initializing an owned collection
+		//collectionOwners.add( new Integer(-1) );
+//		collectionOwnerAliases.add( null );
+		String role = collectionReturn.getOwnerEntityName() + '.' + collectionReturn.getOwnerProperty();
+		addCollection(
+				role,
+				collectionReturn.getAlias(),
+				collectionReturn.getPropertyResultsMap()
+		);
+	}
+
+	private void processJoinReturn(NativeSQLQueryJoinReturn fetchReturn) {
+		String alias = fetchReturn.getAlias();
+//		if ( alias2Persister.containsKey( alias ) || collectionAliases.contains( alias ) ) {
+		if ( alias2Persister.containsKey( alias ) || alias2CollectionPersister.containsKey( alias ) ) {
+			// already been processed...
+			return;
+		}
+
+		String ownerAlias = fetchReturn.getOwnerAlias();
+
+		// Make sure the owner alias is known...
+		if ( !alias2Return.containsKey( ownerAlias ) ) {
+			throw new HibernateException( "Owner alias [" + ownerAlias + "] is unknown for alias [" + alias + "]" );
+		}
+
+		// If this return's alias has not been processed yet, do so b4 further processing of this return
+		if ( !alias2Persister.containsKey( ownerAlias ) ) {
+			NativeSQLQueryNonScalarReturn ownerReturn = ( NativeSQLQueryNonScalarReturn ) alias2Return.get(ownerAlias);
+			processReturn( ownerReturn );
+		}
+
+		SQLLoadable ownerPersister = ( SQLLoadable ) alias2Persister.get( ownerAlias );
+		Type returnType = ownerPersister.getPropertyType( fetchReturn.getOwnerProperty() );
+
+		if ( returnType.isCollectionType() ) {
+			String role = ownerPersister.getEntityName() + '.' + fetchReturn.getOwnerProperty();
+			addCollection( role, alias, fetchReturn.getPropertyResultsMap() );
+//			collectionOwnerAliases.add( ownerAlias );
+		}
+		else if ( returnType.isEntityType() ) {
+			EntityType eType = ( EntityType ) returnType;
+			String returnEntityName = eType.getAssociatedEntityName();
+			SQLLoadable persister = getSQLLoadable( returnEntityName );
+			addPersister( alias, fetchReturn.getPropertyResultsMap(), persister );
+		}
+
+	}
+
+//	public List getCollectionAliases() {
+//		return collectionAliases;
+//	}
+//
+//	/*public List getCollectionOwners() {
+//		return collectionOwners;
+//	}*/
+//
+//	public List getCollectionOwnerAliases() {
+//		return collectionOwnerAliases;
+//	}
+//
+//	public List getCollectionPersisters() {
+//		return collectionPersisters;
+//	}
+//
+//	public Map getAlias2Persister() {
+//		return alias2Persister;
+//	}
+//
+//	/*public boolean isCollectionInitializer() {
+//		return isCollectionInitializer;
+//	}*/
+//
+////	public List getPersisters() {
+////		return persisters;
+////	}
+//
+//	public Map getAlias2OwnerAlias() {
+//		return alias2OwnerAlias;
+//	}
+//
+//	public List getScalarTypes() {
+//		return scalarTypes;
+//	}
+//	public List getScalarColumnAliases() {
+//		return scalarColumnAliases;
+//	}
+//
+//	public List getPropertyResults() {
+//		return propertyResults;
+//	}
+//
+//	public List getCollectionPropertyResults() {
+//		return collectionResults;
+//	}
+//
+//
+//	public Map getAlias2Return() {
+//		return alias2Return;
+//	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,89 +0,0 @@
-//$Id: AbstractEntityLoader.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.loader.entity;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.OuterJoinLoader;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-
-public abstract class AbstractEntityLoader extends OuterJoinLoader 
-		implements UniqueEntityLoader {
-
-	protected static final Logger log = LoggerFactory.getLogger(EntityLoader.class);
-	protected final OuterJoinLoadable persister;
-	protected final Type uniqueKeyType;
-	protected final String entityName;
-
-	public AbstractEntityLoader(
-			OuterJoinLoadable persister, 
-			Type uniqueKeyType, 
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) {
-		super( factory, enabledFilters );
-		this.uniqueKeyType = uniqueKeyType;
-		this.entityName = persister.getEntityName();
-		this.persister = persister;
-		
-	}
-
-	public Object load(Serializable id, Object optionalObject, SessionImplementor session) 
-	throws HibernateException {
-		return load(session, id, optionalObject, id);
-	}
-
-	protected Object load(SessionImplementor session, Object id, Object optionalObject, Serializable optionalId) 
-	throws HibernateException {
-		
-		List list = loadEntity(
-				session, 
-				id, 
-				uniqueKeyType, 
-				optionalObject, 
-				entityName, 
-				optionalId, 
-				persister
-			);
-		
-		if ( list.size()==1 ) {
-			return list.get(0);
-		}
-		else if ( list.size()==0 ) {
-			return null;
-		}
-		else {
-			if ( getCollectionOwners()!=null ) {
-				return list.get(0);
-			}
-			else {
-				throw new HibernateException(
-						"More than one row with the given identifier was found: " +
-						id +
-						", for class: " +
-						persister.getEntityName()
-					);
-			}
-		}
-		
-	}
-
-	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) 
-	throws SQLException, HibernateException {
-		return row[row.length-1];
-	}
-
-	protected boolean isSingleRowLoader() {
-		return true;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/AbstractEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,112 @@
+/*
+ * 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.loader.entity;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.OuterJoinLoader;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+
+public abstract class AbstractEntityLoader extends OuterJoinLoader 
+		implements UniqueEntityLoader {
+
+	protected static final Logger log = LoggerFactory.getLogger(EntityLoader.class);
+	protected final OuterJoinLoadable persister;
+	protected final Type uniqueKeyType;
+	protected final String entityName;
+
+	public AbstractEntityLoader(
+			OuterJoinLoadable persister, 
+			Type uniqueKeyType, 
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) {
+		super( factory, enabledFilters );
+		this.uniqueKeyType = uniqueKeyType;
+		this.entityName = persister.getEntityName();
+		this.persister = persister;
+		
+	}
+
+	public Object load(Serializable id, Object optionalObject, SessionImplementor session) 
+	throws HibernateException {
+		return load(session, id, optionalObject, id);
+	}
+
+	protected Object load(SessionImplementor session, Object id, Object optionalObject, Serializable optionalId) 
+	throws HibernateException {
+		
+		List list = loadEntity(
+				session, 
+				id, 
+				uniqueKeyType, 
+				optionalObject, 
+				entityName, 
+				optionalId, 
+				persister
+			);
+		
+		if ( list.size()==1 ) {
+			return list.get(0);
+		}
+		else if ( list.size()==0 ) {
+			return null;
+		}
+		else {
+			if ( getCollectionOwners()!=null ) {
+				return list.get(0);
+			}
+			else {
+				throw new HibernateException(
+						"More than one row with the given identifier was found: " +
+						id +
+						", for class: " +
+						persister.getEntityName()
+					);
+			}
+		}
+		
+	}
+
+	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session) 
+	throws SQLException, HibernateException {
+		return row[row.length-1];
+	}
+
+	protected boolean isSingleRowLoader() {
+		return true;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: BatchingEntityLoader.java 6929 2005-05-27 03:54:08Z oneovthafew $
-package org.hibernate.loader.entity;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.Loader;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * "Batch" loads entities, using multiple primary key values in the
- * SQL <tt>where</tt> clause.
- *
- * @see EntityLoader
- * @author Gavin King
- */
-public class BatchingEntityLoader implements UniqueEntityLoader {
-
-	private final Loader[] loaders;
-	private final int[] batchSizes;
-	private final EntityPersister persister;
-	private final Type idType;
-
-	public BatchingEntityLoader(EntityPersister persister, int[] batchSizes, Loader[] loaders) {
-		this.batchSizes = batchSizes;
-		this.loaders = loaders;
-		this.persister = persister;
-		idType = persister.getIdentifierType();
-	}
-
-	private Object getObjectFromList(List results, Serializable id, SessionImplementor session) {
-		// get the right object from the list ... would it be easier to just call getEntity() ??
-		Iterator iter = results.iterator();
-		while ( iter.hasNext() ) {
-			Object obj = iter.next();
-			final boolean equal = idType.isEqual( 
-					id, 
-					session.getContextEntityIdentifier(obj), 
-					session.getEntityMode(), 
-					session.getFactory() 
-			);
-			if ( equal ) return obj;
-		}
-		return null;
-	}
-
-	public Object load(Serializable id, Object optionalObject, SessionImplementor session)
-	throws HibernateException {
-		
-		Serializable[] batch = session.getPersistenceContext()
-			.getBatchFetchQueue()
-			.getEntityBatch( persister, id, batchSizes[0], session.getEntityMode() );
-		
-		for ( int i=0; i<batchSizes.length-1; i++) {
-			final int smallBatchSize = batchSizes[i];
-			if ( batch[smallBatchSize-1]!=null ) {
-				Serializable[] smallBatch = new Serializable[smallBatchSize];
-				System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize);
-				final List results = loaders[i].loadEntityBatch(
-						session, 
-						smallBatch, 
-						idType, 
-						optionalObject, 
-						persister.getEntityName(), 
-						id, 
-						persister
-				);
-				return getObjectFromList(results, id, session); //EARLY EXIT
-			}
-		}
-		
-		return ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load(id, optionalObject, session);
-
-	}
-
-	public static UniqueEntityLoader createBatchingEntityLoader(
-		final OuterJoinLoadable persister,
-		final int maxBatchSize,
-		final LockMode lockMode,
-		final SessionFactoryImplementor factory,
-		final Map enabledFilters)
-	throws MappingException {
-
-		if ( maxBatchSize>1 ) {
-			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
-			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
-			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
-				loadersToCreate[i] = new EntityLoader(persister, batchSizesToCreate[i], lockMode, factory, enabledFilters);
-			}
-			return new BatchingEntityLoader(persister, batchSizesToCreate, loadersToCreate);
-		}
-		else {
-			return new EntityLoader(persister, lockMode, factory, enabledFilters);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/BatchingEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.loader.entity;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.Loader;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * "Batch" loads entities, using multiple primary key values in the
+ * SQL <tt>where</tt> clause.
+ *
+ * @see EntityLoader
+ * @author Gavin King
+ */
+public class BatchingEntityLoader implements UniqueEntityLoader {
+
+	private final Loader[] loaders;
+	private final int[] batchSizes;
+	private final EntityPersister persister;
+	private final Type idType;
+
+	public BatchingEntityLoader(EntityPersister persister, int[] batchSizes, Loader[] loaders) {
+		this.batchSizes = batchSizes;
+		this.loaders = loaders;
+		this.persister = persister;
+		idType = persister.getIdentifierType();
+	}
+
+	private Object getObjectFromList(List results, Serializable id, SessionImplementor session) {
+		// get the right object from the list ... would it be easier to just call getEntity() ??
+		Iterator iter = results.iterator();
+		while ( iter.hasNext() ) {
+			Object obj = iter.next();
+			final boolean equal = idType.isEqual( 
+					id, 
+					session.getContextEntityIdentifier(obj), 
+					session.getEntityMode(), 
+					session.getFactory() 
+			);
+			if ( equal ) return obj;
+		}
+		return null;
+	}
+
+	public Object load(Serializable id, Object optionalObject, SessionImplementor session)
+	throws HibernateException {
+		
+		Serializable[] batch = session.getPersistenceContext()
+			.getBatchFetchQueue()
+			.getEntityBatch( persister, id, batchSizes[0], session.getEntityMode() );
+		
+		for ( int i=0; i<batchSizes.length-1; i++) {
+			final int smallBatchSize = batchSizes[i];
+			if ( batch[smallBatchSize-1]!=null ) {
+				Serializable[] smallBatch = new Serializable[smallBatchSize];
+				System.arraycopy(batch, 0, smallBatch, 0, smallBatchSize);
+				final List results = loaders[i].loadEntityBatch(
+						session, 
+						smallBatch, 
+						idType, 
+						optionalObject, 
+						persister.getEntityName(), 
+						id, 
+						persister
+				);
+				return getObjectFromList(results, id, session); //EARLY EXIT
+			}
+		}
+		
+		return ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load(id, optionalObject, session);
+
+	}
+
+	public static UniqueEntityLoader createBatchingEntityLoader(
+		final OuterJoinLoadable persister,
+		final int maxBatchSize,
+		final LockMode lockMode,
+		final SessionFactoryImplementor factory,
+		final Map enabledFilters)
+	throws MappingException {
+
+		if ( maxBatchSize>1 ) {
+			int[] batchSizesToCreate = ArrayHelper.getBatchSizes(maxBatchSize);
+			Loader[] loadersToCreate = new Loader[ batchSizesToCreate.length ];
+			for ( int i=0; i<batchSizesToCreate.length; i++ ) {
+				loadersToCreate[i] = new EntityLoader(persister, batchSizesToCreate[i], lockMode, factory, enabledFilters);
+			}
+			return new BatchingEntityLoader(persister, batchSizesToCreate, loadersToCreate);
+		}
+		else {
+			return new EntityLoader(persister, lockMode, factory, enabledFilters);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-//$Id: CascadeEntityJoinWalker.java 9889 2006-05-05 01:24:12Z steve.ebersole at jboss.com $
-package org.hibernate.loader.entity;
-
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.AbstractEntityJoinWalker;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.type.AssociationType;
-import org.hibernate.util.CollectionHelper;
-
-public class CascadeEntityJoinWalker extends AbstractEntityJoinWalker {
-	
-	private final CascadingAction cascadeAction;
-
-	public CascadeEntityJoinWalker(OuterJoinLoadable persister, CascadingAction action, SessionFactoryImplementor factory) 
-	throws MappingException {
-		super( persister, factory, CollectionHelper.EMPTY_MAP );
-		this.cascadeAction = action;
-		StringBuffer whereCondition = whereString( getAlias(), persister.getIdentifierColumnNames(), 1 )
-				//include the discriminator and class-level where, but not filters
-				.append( persister.filterFragment( getAlias(), CollectionHelper.EMPTY_MAP ) );
-	
-		initAll( whereCondition.toString(), "", LockMode.READ );
-	}
-
-	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
-		return ( type.isEntityType() || type.isCollectionType() ) &&
-				( cascadeStyle==null || cascadeStyle.doCascade(cascadeAction) );
-	}
-
-	protected boolean isTooManyCollections() {
-		return countCollectionPersisters(associations)>0;
-	}
-
-	public String getComment() {
-		return "load " + getPersister().getEntityName();
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.entity;
+
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.AbstractEntityJoinWalker;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.type.AssociationType;
+import org.hibernate.util.CollectionHelper;
+
+public class CascadeEntityJoinWalker extends AbstractEntityJoinWalker {
+	
+	private final CascadingAction cascadeAction;
+
+	public CascadeEntityJoinWalker(OuterJoinLoadable persister, CascadingAction action, SessionFactoryImplementor factory) 
+	throws MappingException {
+		super( persister, factory, CollectionHelper.EMPTY_MAP );
+		this.cascadeAction = action;
+		StringBuffer whereCondition = whereString( getAlias(), persister.getIdentifierColumnNames(), 1 )
+				//include the discriminator and class-level where, but not filters
+				.append( persister.filterFragment( getAlias(), CollectionHelper.EMPTY_MAP ) );
+	
+		initAll( whereCondition.toString(), "", LockMode.READ );
+	}
+
+	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
+		return ( type.isEntityType() || type.isCollectionType() ) &&
+				( cascadeStyle==null || cascadeStyle.doCascade(cascadeAction) );
+	}
+
+	protected boolean isTooManyCollections() {
+		return countCollectionPersisters(associations)>0;
+	}
+
+	public String getComment() {
+		return "load " + getPersister().getEntityName();
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: CascadeEntityLoader.java 7652 2005-07-26 05:51:47Z oneovthafew $
-package org.hibernate.loader.entity;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.util.CollectionHelper;
-
-public class CascadeEntityLoader extends AbstractEntityLoader {
-	
-	public CascadeEntityLoader(
-			OuterJoinLoadable persister,
-			CascadingAction action,
-			SessionFactoryImplementor factory) 
-	throws MappingException {
-		super(
-				persister, 
-				persister.getIdentifierType(), 
-				factory, 
-				CollectionHelper.EMPTY_MAP
-			);
-
-		JoinWalker walker = new CascadeEntityJoinWalker(
-				persister, 
-				action,
-				factory
-			);
-		initFromWalker( walker );
-
-		postInstantiate();
-		
-		log.debug( "Static select for action " + action + " on entity " + entityName + ": " + getSQLString() );
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CascadeEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.loader.entity;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.util.CollectionHelper;
+
+public class CascadeEntityLoader extends AbstractEntityLoader {
+	
+	public CascadeEntityLoader(
+			OuterJoinLoadable persister,
+			CascadingAction action,
+			SessionFactoryImplementor factory) 
+	throws MappingException {
+		super(
+				persister, 
+				persister.getIdentifierType(), 
+				factory, 
+				CollectionHelper.EMPTY_MAP
+			);
+
+		JoinWalker walker = new CascadeEntityJoinWalker(
+				persister, 
+				action,
+				factory
+			);
+		initFromWalker( walker );
+
+		postInstantiate();
+		
+		log.debug( "Static select for action " + action + " on entity " + entityName + ": " + getSQLString() );
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,111 +0,0 @@
-//$Id: CollectionElementLoader.java 9636 2006-03-16 14:14:48Z max.andersen at jboss.com $
-package org.hibernate.loader.entity;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.loader.OuterJoinLoader;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * 
- *
- * @author Gavin King
- */
-public class CollectionElementLoader extends OuterJoinLoader {
-	
-	private static final Logger log = LoggerFactory.getLogger(CollectionElementLoader.class);
-
-	private final OuterJoinLoadable persister;
-	private final Type keyType;
-	private final Type indexType;
-	private final String entityName;
-
-	public CollectionElementLoader(
-			QueryableCollection collectionPersister,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) 
-	throws MappingException {
-		super(factory, enabledFilters);
-
-		this.keyType = collectionPersister.getKeyType();
-		this.indexType = collectionPersister.getIndexType();
-		this.persister = (OuterJoinLoadable) collectionPersister.getElementPersister();
-		this.entityName = persister.getEntityName();
-		
-		JoinWalker walker = new EntityJoinWalker(
-				persister, 
-				ArrayHelper.join( 
-						collectionPersister.getKeyColumnNames(), 
-						collectionPersister.getIndexColumnNames()
-					),
-				1, 
-				LockMode.NONE, 
-				factory, 
-				enabledFilters
-			);
-		initFromWalker( walker );
-
-		postInstantiate();
-		
-		log.debug( "Static select for entity " + entityName + ": " + getSQLString() );
-
-	}
-
-	public Object loadElement(SessionImplementor session, Object key, Object index) 
-	throws HibernateException {
-		
-		List list = loadEntity(
-				session, 
-				key,
-				index,
-				keyType, 
-				indexType,
-				persister
-			);
-		
-		if ( list.size()==1 ) {
-			return list.get(0);
-		}
-		else if ( list.size()==0 ) {
-			return null;
-		}
-		else {
-			if ( getCollectionOwners()!=null ) {
-				return list.get(0);
-			}
-			else {
-				throw new HibernateException("More than one row was found");
-			}
-		}
-		
-	}
-
-	protected Object getResultColumnOrRow(
-		Object[] row,
-		ResultTransformer transformer,
-		ResultSet rs, SessionImplementor session)
-	throws SQLException, HibernateException {
-		return row[row.length-1];
-	}
-
-	protected boolean isSingleRowLoader() {
-		return true;
-	}
-
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/CollectionElementLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.loader.entity;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.loader.OuterJoinLoader;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * 
+ *
+ * @author Gavin King
+ */
+public class CollectionElementLoader extends OuterJoinLoader {
+	
+	private static final Logger log = LoggerFactory.getLogger(CollectionElementLoader.class);
+
+	private final OuterJoinLoadable persister;
+	private final Type keyType;
+	private final Type indexType;
+	private final String entityName;
+
+	public CollectionElementLoader(
+			QueryableCollection collectionPersister,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) 
+	throws MappingException {
+		super(factory, enabledFilters);
+
+		this.keyType = collectionPersister.getKeyType();
+		this.indexType = collectionPersister.getIndexType();
+		this.persister = (OuterJoinLoadable) collectionPersister.getElementPersister();
+		this.entityName = persister.getEntityName();
+		
+		JoinWalker walker = new EntityJoinWalker(
+				persister, 
+				ArrayHelper.join( 
+						collectionPersister.getKeyColumnNames(), 
+						collectionPersister.getIndexColumnNames()
+					),
+				1, 
+				LockMode.NONE, 
+				factory, 
+				enabledFilters
+			);
+		initFromWalker( walker );
+
+		postInstantiate();
+		
+		log.debug( "Static select for entity " + entityName + ": " + getSQLString() );
+
+	}
+
+	public Object loadElement(SessionImplementor session, Object key, Object index) 
+	throws HibernateException {
+		
+		List list = loadEntity(
+				session, 
+				key,
+				index,
+				keyType, 
+				indexType,
+				persister
+			);
+		
+		if ( list.size()==1 ) {
+			return list.get(0);
+		}
+		else if ( list.size()==0 ) {
+			return null;
+		}
+		else {
+			if ( getCollectionOwners()!=null ) {
+				return list.get(0);
+			}
+			else {
+				throw new HibernateException("More than one row was found");
+			}
+		}
+		
+	}
+
+	protected Object getResultColumnOrRow(
+		Object[] row,
+		ResultTransformer transformer,
+		ResultSet rs, SessionImplementor session)
+	throws SQLException, HibernateException {
+		return row[row.length-1];
+	}
+
+	protected boolean isSingleRowLoader() {
+		return true;
+	}
+
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-//$Id: EntityJoinWalker.java 7652 2005-07-26 05:51:47Z oneovthafew $
-package org.hibernate.loader.entity;
-
-import java.util.Collections;
-import java.util.Map;
-
-import org.hibernate.FetchMode;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.loader.AbstractEntityJoinWalker;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.type.AssociationType;
-
-/**
- * A walker for loaders that fetch entities
- *
- * @see EntityLoader
- * @author Gavin King
- */
-public class EntityJoinWalker extends AbstractEntityJoinWalker {
-	
-	private final LockMode lockMode;
-
-	public EntityJoinWalker(
-			OuterJoinLoadable persister, 
-			String[] uniqueKey, 
-			int batchSize, 
-			LockMode lockMode,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) 
-	throws MappingException {
-		super(persister, factory, enabledFilters);
-
-		this.lockMode = lockMode;
-		
-		StringBuffer whereCondition = whereString( getAlias(), uniqueKey, batchSize )
-			//include the discriminator and class-level where, but not filters
-			.append( persister.filterFragment( getAlias(), Collections.EMPTY_MAP ) );
-
-		initAll( whereCondition.toString(), "", lockMode );
-		
-	}
-
-	/**
-	 * Disable outer join fetching if this loader obtains an
-	 * upgrade lock mode
-	 */
-	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
-		return lockMode.greaterThan(LockMode.READ) ?
-			false :
-			super.isJoinedFetchEnabled(type, config, cascadeStyle);
-	}
-
-	public String getComment() {
-		return "load " + getPersister().getEntityName();
-	}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityJoinWalker.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.loader.entity;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.hibernate.FetchMode;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.loader.AbstractEntityJoinWalker;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.type.AssociationType;
+
+/**
+ * A walker for loaders that fetch entities
+ *
+ * @see EntityLoader
+ * @author Gavin King
+ */
+public class EntityJoinWalker extends AbstractEntityJoinWalker {
+	
+	private final LockMode lockMode;
+
+	public EntityJoinWalker(
+			OuterJoinLoadable persister, 
+			String[] uniqueKey, 
+			int batchSize, 
+			LockMode lockMode,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) 
+	throws MappingException {
+		super(persister, factory, enabledFilters);
+
+		this.lockMode = lockMode;
+		
+		StringBuffer whereCondition = whereString( getAlias(), uniqueKey, batchSize )
+			//include the discriminator and class-level where, but not filters
+			.append( persister.filterFragment( getAlias(), Collections.EMPTY_MAP ) );
+
+		initAll( whereCondition.toString(), "", lockMode );
+		
+	}
+
+	/**
+	 * Disable outer join fetching if this loader obtains an
+	 * upgrade lock mode
+	 */
+	protected boolean isJoinedFetchEnabled(AssociationType type, FetchMode config, CascadeStyle cascadeStyle) {
+		return lockMode.greaterThan(LockMode.READ) ?
+			false :
+			super.isJoinedFetchEnabled(type, config, cascadeStyle);
+	}
+
+	public String getComment() {
+		return "load " + getPersister().getEntityName();
+	}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,92 +0,0 @@
-//$Id: EntityLoader.java 7652 2005-07-26 05:51:47Z oneovthafew $
-package org.hibernate.loader.entity;
-
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.loader.JoinWalker;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.type.Type;
-
-/**
- * Loads an entity instance using outerjoin fetching to fetch associated entities.
- * <br>
- * The <tt>EntityPersister</tt> must implement <tt>Loadable</tt>. For other entities,
- * create a customized subclass of <tt>Loader</tt>.
- *
- * @author Gavin King
- */
-public class EntityLoader extends AbstractEntityLoader {
-	
-	private final boolean batchLoader;
-	
-	public EntityLoader(
-			OuterJoinLoadable persister, 
-			LockMode lockMode,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) 
-	throws MappingException {
-		this(persister, 1, lockMode, factory, enabledFilters);
-	}
-	
-	public EntityLoader(
-			OuterJoinLoadable persister, 
-			int batchSize, 
-			LockMode lockMode,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) 
-	throws MappingException {
-		this( 
-				persister, 
-				persister.getIdentifierColumnNames(), 
-				persister.getIdentifierType(), 
-				batchSize,
-				lockMode,
-				factory, 
-				enabledFilters 
-			);
-	}
-
-	public EntityLoader(
-			OuterJoinLoadable persister, 
-			String[] uniqueKey, 
-			Type uniqueKeyType, 
-			int batchSize, 
-			LockMode lockMode,
-			SessionFactoryImplementor factory, 
-			Map enabledFilters) 
-	throws MappingException {
-		super(persister, uniqueKeyType, factory, enabledFilters);
-
-		JoinWalker walker = new EntityJoinWalker(
-				persister, 
-				uniqueKey, 
-				batchSize, 
-				lockMode, 
-				factory, 
-				enabledFilters
-			);
-		initFromWalker( walker );
-
-		postInstantiate();
-
-		batchLoader = batchSize > 1;
-		
-		log.debug( "Static select for entity " + entityName + ": " + getSQLString() );
-
-	}
-
-	public Object loadByUniqueKey(SessionImplementor session, Object key) 
-	throws HibernateException {
-		return load(session, key, null, null);
-	}
-
-	protected boolean isSingleRowLoader() {
-		return !batchLoader;
-	}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/EntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.loader.entity;
+
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.loader.JoinWalker;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.type.Type;
+
+/**
+ * Loads an entity instance using outerjoin fetching to fetch associated entities.
+ * <br>
+ * The <tt>EntityPersister</tt> must implement <tt>Loadable</tt>. For other entities,
+ * create a customized subclass of <tt>Loader</tt>.
+ *
+ * @author Gavin King
+ */
+public class EntityLoader extends AbstractEntityLoader {
+	
+	private final boolean batchLoader;
+	
+	public EntityLoader(
+			OuterJoinLoadable persister, 
+			LockMode lockMode,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) 
+	throws MappingException {
+		this(persister, 1, lockMode, factory, enabledFilters);
+	}
+	
+	public EntityLoader(
+			OuterJoinLoadable persister, 
+			int batchSize, 
+			LockMode lockMode,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) 
+	throws MappingException {
+		this( 
+				persister, 
+				persister.getIdentifierColumnNames(), 
+				persister.getIdentifierType(), 
+				batchSize,
+				lockMode,
+				factory, 
+				enabledFilters 
+			);
+	}
+
+	public EntityLoader(
+			OuterJoinLoadable persister, 
+			String[] uniqueKey, 
+			Type uniqueKeyType, 
+			int batchSize, 
+			LockMode lockMode,
+			SessionFactoryImplementor factory, 
+			Map enabledFilters) 
+	throws MappingException {
+		super(persister, uniqueKeyType, factory, enabledFilters);
+
+		JoinWalker walker = new EntityJoinWalker(
+				persister, 
+				uniqueKey, 
+				batchSize, 
+				lockMode, 
+				factory, 
+				enabledFilters
+			);
+		initFromWalker( walker );
+
+		postInstantiate();
+
+		batchLoader = batchSize > 1;
+		
+		log.debug( "Static select for entity " + entityName + ": " + getSQLString() );
+
+	}
+
+	public Object loadByUniqueKey(SessionImplementor session, Object key) 
+	throws HibernateException {
+		return load(session, key, null, null);
+	}
+
+	protected boolean isSingleRowLoader() {
+		return !batchLoader;
+	}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: UniqueEntityLoader.java 5699 2005-02-13 11:50:11Z oneovthafew $
-package org.hibernate.loader.entity;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Loads entities for a <tt>EntityPersister</tt>
- * @author Gavin King
- */
-public interface UniqueEntityLoader {
-	/**
-	 * Load an entity instance. If <tt>optionalObject</tt> is supplied,
-	 * load the entity state into the given (uninitialized) object.
-	 */
-	public Object load(Serializable id, Object optionalObject, SessionImplementor session) throws HibernateException;
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/UniqueEntityLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.loader.entity;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Loads entities for a <tt>EntityPersister</tt>
+ * @author Gavin King
+ */
+public interface UniqueEntityLoader {
+	/**
+	 * Load an entity instance. If <tt>optionalObject</tt> is supplied,
+	 * load the entity state into the given (uninitialized) object.
+	 */
+	public Object load(Serializable id, Object optionalObject, SessionImplementor session) throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/entity/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines entity loaders
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/entity/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/entity/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines entity loaders
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,520 +0,0 @@
-// $Id: QueryLoader.java 11116 2007-01-30 14:30:55Z steve.ebersole at jboss.com $
-package org.hibernate.loader.hql;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.ScrollableResults;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.event.EventSource;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.hql.HolderInstantiator;
-import org.hibernate.hql.ast.QueryTranslatorImpl;
-import org.hibernate.hql.ast.tree.FromElement;
-import org.hibernate.hql.ast.tree.SelectClause;
-import org.hibernate.hql.ast.tree.QueryNode;
-import org.hibernate.impl.IteratorImpl;
-import org.hibernate.loader.BasicLoader;
-import org.hibernate.param.ParameterSpecification;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.Queryable;
-import org.hibernate.persister.entity.Lockable;
-import org.hibernate.transform.ResultTransformer;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * A delegate that implements the Loader part of QueryTranslator.
- *
- * @author josh
- */
-public class QueryLoader extends BasicLoader {
-
-	/**
-	 * The query translator that is delegating to this object.
-	 */
-	private QueryTranslatorImpl queryTranslator;
-
-	private Queryable[] entityPersisters;
-	private String[] entityAliases;
-	private String[] sqlAliases;
-	private String[] sqlAliasSuffixes;
-	private boolean[] includeInSelect;
-
-	private String[] collectionSuffixes;
-
-	private boolean hasScalars;
-	private String[][] scalarColumnNames;
-	//private Type[] sqlResultTypes;
-	private Type[] queryReturnTypes;
-
-	private final Map sqlAliasByEntityAlias = new HashMap(8);
-
-	private EntityType[] ownerAssociationTypes;
-	private int[] owners;
-	private boolean[] entityEagerPropertyFetches;
-
-	private int[] collectionOwners;
-	private QueryableCollection[] collectionPersisters;
-
-	private int selectLength;
-
-	private ResultTransformer selectNewTransformer;
-	private String[] queryReturnAliases;
-
-	private LockMode[] defaultLockModes;
-
-
-	/**
-	 * Creates a new Loader implementation.
-	 *
-	 * @param queryTranslator The query translator that is the delegator.
-	 * @param factory The factory from which this loader is being created.
-	 * @param selectClause The AST representing the select clause for loading.
-	 */
-	public QueryLoader(
-			final QueryTranslatorImpl queryTranslator,
-	        final SessionFactoryImplementor factory,
-	        final SelectClause selectClause) {
-		super( factory );
-		this.queryTranslator = queryTranslator;
-		initialize( selectClause );
-		postInstantiate();
-	}
-
-	private void initialize(SelectClause selectClause) {
-
-		List fromElementList = selectClause.getFromElementsForLoad();
-
-		hasScalars = selectClause.isScalarSelect();
-		scalarColumnNames = selectClause.getColumnNames();
-		//sqlResultTypes = selectClause.getSqlResultTypes();
-		queryReturnTypes = selectClause.getQueryReturnTypes();
-
-		selectNewTransformer = HolderInstantiator.createSelectNewTransformer(
-				selectClause.getConstructor(),
-				selectClause.isMap(),
-				selectClause.isList());
-		queryReturnAliases = selectClause.getQueryReturnAliases();
-
-		List collectionFromElements = selectClause.getCollectionFromElements();
-		if ( collectionFromElements != null && collectionFromElements.size()!=0 ) {
-			int length = collectionFromElements.size();
-			collectionPersisters = new QueryableCollection[length];
-			collectionOwners = new int[length];
-			collectionSuffixes = new String[length];
-			for ( int i=0; i<length; i++ ) {
-				FromElement collectionFromElement = (FromElement) collectionFromElements.get(i);
-				collectionPersisters[i] = collectionFromElement.getQueryableCollection();
-				collectionOwners[i] = fromElementList.indexOf( collectionFromElement.getOrigin() );
-//				collectionSuffixes[i] = collectionFromElement.getColumnAliasSuffix();
-//				collectionSuffixes[i] = Integer.toString( i ) + "_";
-				collectionSuffixes[i] = collectionFromElement.getCollectionSuffix();
-			}
-		}
-
-		int size = fromElementList.size();
-		entityPersisters = new Queryable[size];
-		entityEagerPropertyFetches = new boolean[size];
-		entityAliases = new String[size];
-		sqlAliases = new String[size];
-		sqlAliasSuffixes = new String[size];
-		includeInSelect = new boolean[size];
-		owners = new int[size];
-		ownerAssociationTypes = new EntityType[size];
-
-		for ( int i = 0; i < size; i++ ) {
-			final FromElement element = ( FromElement ) fromElementList.get( i );
-			entityPersisters[i] = ( Queryable ) element.getEntityPersister();
-
-			if ( entityPersisters[i] == null ) {
-				throw new IllegalStateException( "No entity persister for " + element.toString() );
-			}
-
-			entityEagerPropertyFetches[i] = element.isAllPropertyFetch();
-			sqlAliases[i] = element.getTableAlias();
-			entityAliases[i] = element.getClassAlias();
-			sqlAliasByEntityAlias.put( entityAliases[i], sqlAliases[i] );
-			// TODO should we just collect these like with the collections above?
-			sqlAliasSuffixes[i] = ( size == 1 ) ? "" : Integer.toString( i ) + "_";
-//			sqlAliasSuffixes[i] = element.getColumnAliasSuffix();
-			includeInSelect[i] = !element.isFetch();
-			if ( includeInSelect[i] ) {
-				selectLength++;
-			}
-
-			owners[i] = -1; //by default
-			if ( element.isFetch() ) {
-				if ( element.isCollectionJoin() || element.getQueryableCollection() != null ) {
-					// This is now handled earlier in this method.
-				}
-				else if ( element.getDataType().isEntityType() ) {
-					EntityType entityType = ( EntityType ) element.getDataType();
-					if ( entityType.isOneToOne() ) {
-						owners[i] = fromElementList.indexOf( element.getOrigin() );
-					}
-					ownerAssociationTypes[i] = entityType;
-				}
-			}
-		}
-
-		//NONE, because its the requested lock mode, not the actual! 
-		defaultLockModes = ArrayHelper.fillArray(LockMode.NONE, size);
-
-	}
-
-	// -- Loader implementation --
-
-	public final void validateScrollability() throws HibernateException {
-		queryTranslator.validateScrollability();
-	}
-
-	protected boolean needsFetchingScroll() {
-		return queryTranslator.containsCollectionFetches();
-	}
-
-	public Loadable[] getEntityPersisters() {
-		return entityPersisters;
-	}
-
-	public String[] getAliases() {
-		return sqlAliases;
-	}
-
-	public String[] getSqlAliasSuffixes() {
-		return sqlAliasSuffixes;
-	}
-
-	public String[] getSuffixes() {
-		return getSqlAliasSuffixes();
-	}
-
-	public String[] getCollectionSuffixes() {
-		return collectionSuffixes;
-	}
-
-	protected String getQueryIdentifier() {
-		return queryTranslator.getQueryIdentifier();
-	}
-
-	/**
-	 * The SQL query string to be called.
-	 */
-	protected String getSQLString() {
-		return queryTranslator.getSQLString();
-	}
-
-	/**
-	 * An (optional) persister for a collection to be initialized; only collection loaders
-	 * return a non-null value
-	 */
-	protected CollectionPersister[] getCollectionPersisters() {
-		return collectionPersisters;
-	}
-
-	protected int[] getCollectionOwners() {
-		return collectionOwners;
-	}
-
-	protected boolean[] getEntityEagerPropertyFetches() {
-		return entityEagerPropertyFetches;
-	}
-
-	/**
-	 * An array of indexes of the entity that owns a one-to-one association
-	 * to the entity at the given index (-1 if there is no "owner")
-	 */
-	protected int[] getOwners() {
-		return owners;
-	}
-
-	protected EntityType[] getOwnerAssociationTypes() {
-		return ownerAssociationTypes;
-	}
-
-	// -- Loader overrides --
-
-	protected boolean isSubselectLoadingEnabled() {
-		return hasSubselectLoadableCollections();
-	}
-
-	/**
-	 * @param lockModes a collection of lock modes specified dynamically via the Query interface
-	 */
-	protected LockMode[] getLockModes(Map lockModes) {
-
-		if ( lockModes==null || lockModes.size()==0 ) {
-			return defaultLockModes;
-		}
-		else {
-			// unfortunately this stuff can't be cached because
-			// it is per-invocation, not constant for the
-			// QueryTranslator instance
-
-			LockMode[] lockModeArray = new LockMode[entityAliases.length];
-			for ( int i = 0; i < entityAliases.length; i++ ) {
-				LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] );
-				if ( lockMode == null ) {
-					//NONE, because its the requested lock mode, not the actual! 
-					lockMode = LockMode.NONE;
-				}
-				lockModeArray[i] = lockMode;
-			}
-			return lockModeArray;
-		}
-	}
-
-	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException {
-		if ( lockModes == null || lockModes.size() == 0 ) {
-			return sql;
-		}
-
-		// can't cache this stuff either (per-invocation)
-		// we are given a map of user-alias -> lock mode
-		// create a new map of sql-alias -> lock mode
-		final Map aliasedLockModes = new HashMap();
-		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
-		final Iterator iter = lockModes.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) iter.next();
-			final String userAlias = ( String ) me.getKey();
-			final String drivingSqlAlias = ( String ) sqlAliasByEntityAlias.get( userAlias );
-			if ( drivingSqlAlias == null ) {
-				throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias );
-			}
-			// at this point we have (drivingSqlAlias) the SQL alias of the driving table
-			// corresponding to the given user alias.  However, the driving table is not
-			// (necessarily) the table against which we want to apply locks.  Mainly,
-			// the exception case here is joined-subclass hierarchies where we instead
-			// want to apply the lock against the root table (for all other strategies,
-			// it just happens that driving and root are the same).
-			final QueryNode select = ( QueryNode ) queryTranslator.getSqlAST();
-			final Lockable drivingPersister = ( Lockable ) select.getFromClause().getFromElement( userAlias ).getQueryable();
-			final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias );
-			aliasedLockModes.put( sqlAlias, me.getValue() );
-			if ( keyColumnNames != null ) {
-				keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
-			}
-		}
-		return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
-	}
-
-	protected boolean upgradeLocks() {
-		return true;
-	}
-
-	private boolean hasSelectNew() {
-		return selectNewTransformer!=null;
-	}
-
-	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
-			throws SQLException, HibernateException {
-
-		row = toResultRow( row );
-		boolean hasTransform = hasSelectNew() || transformer!=null;
-		if ( hasScalars ) {
-			String[][] scalarColumns = scalarColumnNames;
-			int queryCols = queryReturnTypes.length;
-			if ( !hasTransform && queryCols == 1 ) {
-				return queryReturnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null );
-			}
-			else {
-				row = new Object[queryCols];
-				for ( int i = 0; i < queryCols; i++ ) {
-					row[i] = queryReturnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null );
-				}
-				return row;
-			}
-		}
-		else if ( !hasTransform ) {
-			return row.length == 1 ? row[0] : row;
-		}
-		else {
-			return row;
-		}
-
-	}
-
-	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
-		// meant to handle dynamic instantiation queries...
-		HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(selectNewTransformer, resultTransformer, queryReturnAliases);
-		if ( holderInstantiator.isRequired() ) {
-			for ( int i = 0; i < results.size(); i++ ) {
-				Object[] row = ( Object[] ) results.get( i );
-				Object result = holderInstantiator.instantiate(row);
-				results.set( i, result );
-			}
-
-			if(!hasSelectNew() && resultTransformer!=null) {
-				return resultTransformer.transformList(results);
-			} else {
-				return results;
-			}
-		} else {
-			return results;
-		}
-	}
-
-	// --- Query translator methods ---
-
-	public List list(
-			SessionImplementor session,
-			QueryParameters queryParameters) throws HibernateException {
-		checkQuery( queryParameters );
-		return list( session, queryParameters, queryTranslator.getQuerySpaces(), queryReturnTypes );
-	}
-
-	private void checkQuery(QueryParameters queryParameters) {
-		if ( hasSelectNew() && queryParameters.getResultTransformer() != null ) {
-			throw new QueryException( "ResultTransformer is not allowed for 'select new' queries." );
-		}
-	}
-
-	public Iterator iterate(
-			QueryParameters queryParameters,
-			EventSource session) throws HibernateException {
-		checkQuery( queryParameters );
-		final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
-		long startTime = 0;
-		if ( stats ) {
-			startTime = System.currentTimeMillis();
-		}
-
-		try {
-
-			final PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
-
-			if(queryParameters.isCallable()) {
-				throw new QueryException("iterate() not supported for callable statements");
-			}
-			final ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session);
-			final Iterator result = new IteratorImpl(
-					rs,
-			        st,
-			        session,
-			        queryReturnTypes,
-			        queryTranslator.getColumnNames(),
-			        HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases)
-				);
-
-			if ( stats ) {
-				session.getFactory().getStatisticsImplementor().queryExecuted(
-//						"HQL: " + queryTranslator.getQueryString(),
-						getQueryIdentifier(),
-						0,
-						System.currentTimeMillis() - startTime
-				);
-			}
-
-			return result;
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not execute query using iterate",
-			        getSQLString()
-				);
-		}
-
-	}
-
-	public ScrollableResults scroll(
-			final QueryParameters queryParameters,
-	        final SessionImplementor session) throws HibernateException {
-		checkQuery( queryParameters );
-		return scroll( queryParameters, queryReturnTypes, HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases), session );
-	}
-
-	// -- Implementation private methods --
-
-	private Object[] toResultRow(Object[] row) {
-		if ( selectLength == row.length ) {
-			return row;
-		}
-		else {
-			Object[] result = new Object[selectLength];
-			int j = 0;
-			for ( int i = 0; i < row.length; i++ ) {
-				if ( includeInSelect[i] ) {
-					result[j++] = row[i];
-				}
-			}
-			return result;
-		}
-	}
-
-	/**
-	 * Returns the locations of all occurrences of the named parameter.
-	 */
-	public int[] getNamedParameterLocs(String name) throws QueryException {
-		return queryTranslator.getParameterTranslations().getNamedParameterSqlLocations( name );
-	}
-
-	/**
-	 * We specifically override this method here, because in general we know much more
-	 * about the parameters and their appropriate bind positions here then we do in
-	 * our super because we track them explciitly here through the ParameterSpecification
-	 * interface.
-	 *
-	 * @param queryParameters The encapsulation of the parameter values to be bound.
-	 * @param startIndex The position from which to start binding parameter values.
-	 * @param session The originating session.
-	 * @return The number of JDBC bind positions actually bound during this method execution.
-	 * @throws SQLException Indicates problems performing the binding.
-	 */
-	protected int bindParameterValues(
-			final PreparedStatement statement,
-			final QueryParameters queryParameters,
-			final int startIndex,
-			final SessionImplementor session) throws SQLException {
-		int position = bindFilterParameterValues( statement, queryParameters, startIndex, session );
-		List parameterSpecs = queryTranslator.getSqlAST().getWalker().getParameters();
-		Iterator itr = parameterSpecs.iterator();
-		while ( itr.hasNext() ) {
-			ParameterSpecification spec = ( ParameterSpecification ) itr.next();
-			position += spec.bind( statement, queryParameters, session, position );
-		}
-		return position - startIndex;
-	}
-
-	private int bindFilterParameterValues(
-			PreparedStatement st,
-			QueryParameters queryParameters,
-			int position,
-			SessionImplementor session) throws SQLException {
-		// todo : better to handle dynamic filters through implicit DynamicFilterParameterSpecification
-		// see the discussion there in DynamicFilterParameterSpecification's javadocs as to why
-		// it is currently not done that way.
-		int filteredParamCount = queryParameters.getFilteredPositionalParameterTypes() == null
-				? 0
-				: queryParameters.getFilteredPositionalParameterTypes().length;
-		int nonfilteredParamCount = queryParameters.getPositionalParameterTypes() == null
-				? 0
-				: queryParameters.getPositionalParameterTypes().length;
-		int filterParamCount = filteredParamCount - nonfilteredParamCount;
-		for ( int i = 0; i < filterParamCount; i++ ) {
-			Type type = queryParameters.getFilteredPositionalParameterTypes()[i];
-			Object value = queryParameters.getFilteredPositionalParameterValues()[i];
-			type.nullSafeSet( st, value, position, session );
-			position += type.getColumnSpan( getFactory() );
-		}
-
-		return position;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/QueryLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,543 @@
+/*
+ * 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.loader.hql;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.QueryException;
+import org.hibernate.ScrollableResults;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.event.EventSource;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.hql.HolderInstantiator;
+import org.hibernate.hql.ast.QueryTranslatorImpl;
+import org.hibernate.hql.ast.tree.FromElement;
+import org.hibernate.hql.ast.tree.SelectClause;
+import org.hibernate.hql.ast.tree.QueryNode;
+import org.hibernate.impl.IteratorImpl;
+import org.hibernate.loader.BasicLoader;
+import org.hibernate.param.ParameterSpecification;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.Queryable;
+import org.hibernate.persister.entity.Lockable;
+import org.hibernate.transform.ResultTransformer;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * A delegate that implements the Loader part of QueryTranslator.
+ *
+ * @author josh
+ */
+public class QueryLoader extends BasicLoader {
+
+	/**
+	 * The query translator that is delegating to this object.
+	 */
+	private QueryTranslatorImpl queryTranslator;
+
+	private Queryable[] entityPersisters;
+	private String[] entityAliases;
+	private String[] sqlAliases;
+	private String[] sqlAliasSuffixes;
+	private boolean[] includeInSelect;
+
+	private String[] collectionSuffixes;
+
+	private boolean hasScalars;
+	private String[][] scalarColumnNames;
+	//private Type[] sqlResultTypes;
+	private Type[] queryReturnTypes;
+
+	private final Map sqlAliasByEntityAlias = new HashMap(8);
+
+	private EntityType[] ownerAssociationTypes;
+	private int[] owners;
+	private boolean[] entityEagerPropertyFetches;
+
+	private int[] collectionOwners;
+	private QueryableCollection[] collectionPersisters;
+
+	private int selectLength;
+
+	private ResultTransformer selectNewTransformer;
+	private String[] queryReturnAliases;
+
+	private LockMode[] defaultLockModes;
+
+
+	/**
+	 * Creates a new Loader implementation.
+	 *
+	 * @param queryTranslator The query translator that is the delegator.
+	 * @param factory The factory from which this loader is being created.
+	 * @param selectClause The AST representing the select clause for loading.
+	 */
+	public QueryLoader(
+			final QueryTranslatorImpl queryTranslator,
+	        final SessionFactoryImplementor factory,
+	        final SelectClause selectClause) {
+		super( factory );
+		this.queryTranslator = queryTranslator;
+		initialize( selectClause );
+		postInstantiate();
+	}
+
+	private void initialize(SelectClause selectClause) {
+
+		List fromElementList = selectClause.getFromElementsForLoad();
+
+		hasScalars = selectClause.isScalarSelect();
+		scalarColumnNames = selectClause.getColumnNames();
+		//sqlResultTypes = selectClause.getSqlResultTypes();
+		queryReturnTypes = selectClause.getQueryReturnTypes();
+
+		selectNewTransformer = HolderInstantiator.createSelectNewTransformer(
+				selectClause.getConstructor(),
+				selectClause.isMap(),
+				selectClause.isList());
+		queryReturnAliases = selectClause.getQueryReturnAliases();
+
+		List collectionFromElements = selectClause.getCollectionFromElements();
+		if ( collectionFromElements != null && collectionFromElements.size()!=0 ) {
+			int length = collectionFromElements.size();
+			collectionPersisters = new QueryableCollection[length];
+			collectionOwners = new int[length];
+			collectionSuffixes = new String[length];
+			for ( int i=0; i<length; i++ ) {
+				FromElement collectionFromElement = (FromElement) collectionFromElements.get(i);
+				collectionPersisters[i] = collectionFromElement.getQueryableCollection();
+				collectionOwners[i] = fromElementList.indexOf( collectionFromElement.getOrigin() );
+//				collectionSuffixes[i] = collectionFromElement.getColumnAliasSuffix();
+//				collectionSuffixes[i] = Integer.toString( i ) + "_";
+				collectionSuffixes[i] = collectionFromElement.getCollectionSuffix();
+			}
+		}
+
+		int size = fromElementList.size();
+		entityPersisters = new Queryable[size];
+		entityEagerPropertyFetches = new boolean[size];
+		entityAliases = new String[size];
+		sqlAliases = new String[size];
+		sqlAliasSuffixes = new String[size];
+		includeInSelect = new boolean[size];
+		owners = new int[size];
+		ownerAssociationTypes = new EntityType[size];
+
+		for ( int i = 0; i < size; i++ ) {
+			final FromElement element = ( FromElement ) fromElementList.get( i );
+			entityPersisters[i] = ( Queryable ) element.getEntityPersister();
+
+			if ( entityPersisters[i] == null ) {
+				throw new IllegalStateException( "No entity persister for " + element.toString() );
+			}
+
+			entityEagerPropertyFetches[i] = element.isAllPropertyFetch();
+			sqlAliases[i] = element.getTableAlias();
+			entityAliases[i] = element.getClassAlias();
+			sqlAliasByEntityAlias.put( entityAliases[i], sqlAliases[i] );
+			// TODO should we just collect these like with the collections above?
+			sqlAliasSuffixes[i] = ( size == 1 ) ? "" : Integer.toString( i ) + "_";
+//			sqlAliasSuffixes[i] = element.getColumnAliasSuffix();
+			includeInSelect[i] = !element.isFetch();
+			if ( includeInSelect[i] ) {
+				selectLength++;
+			}
+
+			owners[i] = -1; //by default
+			if ( element.isFetch() ) {
+				if ( element.isCollectionJoin() || element.getQueryableCollection() != null ) {
+					// This is now handled earlier in this method.
+				}
+				else if ( element.getDataType().isEntityType() ) {
+					EntityType entityType = ( EntityType ) element.getDataType();
+					if ( entityType.isOneToOne() ) {
+						owners[i] = fromElementList.indexOf( element.getOrigin() );
+					}
+					ownerAssociationTypes[i] = entityType;
+				}
+			}
+		}
+
+		//NONE, because its the requested lock mode, not the actual! 
+		defaultLockModes = ArrayHelper.fillArray(LockMode.NONE, size);
+
+	}
+
+	// -- Loader implementation --
+
+	public final void validateScrollability() throws HibernateException {
+		queryTranslator.validateScrollability();
+	}
+
+	protected boolean needsFetchingScroll() {
+		return queryTranslator.containsCollectionFetches();
+	}
+
+	public Loadable[] getEntityPersisters() {
+		return entityPersisters;
+	}
+
+	public String[] getAliases() {
+		return sqlAliases;
+	}
+
+	public String[] getSqlAliasSuffixes() {
+		return sqlAliasSuffixes;
+	}
+
+	public String[] getSuffixes() {
+		return getSqlAliasSuffixes();
+	}
+
+	public String[] getCollectionSuffixes() {
+		return collectionSuffixes;
+	}
+
+	protected String getQueryIdentifier() {
+		return queryTranslator.getQueryIdentifier();
+	}
+
+	/**
+	 * The SQL query string to be called.
+	 */
+	protected String getSQLString() {
+		return queryTranslator.getSQLString();
+	}
+
+	/**
+	 * An (optional) persister for a collection to be initialized; only collection loaders
+	 * return a non-null value
+	 */
+	protected CollectionPersister[] getCollectionPersisters() {
+		return collectionPersisters;
+	}
+
+	protected int[] getCollectionOwners() {
+		return collectionOwners;
+	}
+
+	protected boolean[] getEntityEagerPropertyFetches() {
+		return entityEagerPropertyFetches;
+	}
+
+	/**
+	 * An array of indexes of the entity that owns a one-to-one association
+	 * to the entity at the given index (-1 if there is no "owner")
+	 */
+	protected int[] getOwners() {
+		return owners;
+	}
+
+	protected EntityType[] getOwnerAssociationTypes() {
+		return ownerAssociationTypes;
+	}
+
+	// -- Loader overrides --
+
+	protected boolean isSubselectLoadingEnabled() {
+		return hasSubselectLoadableCollections();
+	}
+
+	/**
+	 * @param lockModes a collection of lock modes specified dynamically via the Query interface
+	 */
+	protected LockMode[] getLockModes(Map lockModes) {
+
+		if ( lockModes==null || lockModes.size()==0 ) {
+			return defaultLockModes;
+		}
+		else {
+			// unfortunately this stuff can't be cached because
+			// it is per-invocation, not constant for the
+			// QueryTranslator instance
+
+			LockMode[] lockModeArray = new LockMode[entityAliases.length];
+			for ( int i = 0; i < entityAliases.length; i++ ) {
+				LockMode lockMode = (LockMode) lockModes.get( entityAliases[i] );
+				if ( lockMode == null ) {
+					//NONE, because its the requested lock mode, not the actual! 
+					lockMode = LockMode.NONE;
+				}
+				lockModeArray[i] = lockMode;
+			}
+			return lockModeArray;
+		}
+	}
+
+	protected String applyLocks(String sql, Map lockModes, Dialect dialect) throws QueryException {
+		if ( lockModes == null || lockModes.size() == 0 ) {
+			return sql;
+		}
+
+		// can't cache this stuff either (per-invocation)
+		// we are given a map of user-alias -> lock mode
+		// create a new map of sql-alias -> lock mode
+		final Map aliasedLockModes = new HashMap();
+		final Map keyColumnNames = dialect.forUpdateOfColumns() ? new HashMap() : null;
+		final Iterator iter = lockModes.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			final String userAlias = ( String ) me.getKey();
+			final String drivingSqlAlias = ( String ) sqlAliasByEntityAlias.get( userAlias );
+			if ( drivingSqlAlias == null ) {
+				throw new IllegalArgumentException( "could not locate alias to apply lock mode : " + userAlias );
+			}
+			// at this point we have (drivingSqlAlias) the SQL alias of the driving table
+			// corresponding to the given user alias.  However, the driving table is not
+			// (necessarily) the table against which we want to apply locks.  Mainly,
+			// the exception case here is joined-subclass hierarchies where we instead
+			// want to apply the lock against the root table (for all other strategies,
+			// it just happens that driving and root are the same).
+			final QueryNode select = ( QueryNode ) queryTranslator.getSqlAST();
+			final Lockable drivingPersister = ( Lockable ) select.getFromClause().getFromElement( userAlias ).getQueryable();
+			final String sqlAlias = drivingPersister.getRootTableAlias( drivingSqlAlias );
+			aliasedLockModes.put( sqlAlias, me.getValue() );
+			if ( keyColumnNames != null ) {
+				keyColumnNames.put( sqlAlias, drivingPersister.getRootTableIdentifierColumnNames() );
+			}
+		}
+		return dialect.applyLocksToSql( sql, aliasedLockModes, keyColumnNames );
+	}
+
+	protected boolean upgradeLocks() {
+		return true;
+	}
+
+	private boolean hasSelectNew() {
+		return selectNewTransformer!=null;
+	}
+
+	protected Object getResultColumnOrRow(Object[] row, ResultTransformer transformer, ResultSet rs, SessionImplementor session)
+			throws SQLException, HibernateException {
+
+		row = toResultRow( row );
+		boolean hasTransform = hasSelectNew() || transformer!=null;
+		if ( hasScalars ) {
+			String[][] scalarColumns = scalarColumnNames;
+			int queryCols = queryReturnTypes.length;
+			if ( !hasTransform && queryCols == 1 ) {
+				return queryReturnTypes[0].nullSafeGet( rs, scalarColumns[0], session, null );
+			}
+			else {
+				row = new Object[queryCols];
+				for ( int i = 0; i < queryCols; i++ ) {
+					row[i] = queryReturnTypes[i].nullSafeGet( rs, scalarColumns[i], session, null );
+				}
+				return row;
+			}
+		}
+		else if ( !hasTransform ) {
+			return row.length == 1 ? row[0] : row;
+		}
+		else {
+			return row;
+		}
+
+	}
+
+	protected List getResultList(List results, ResultTransformer resultTransformer) throws QueryException {
+		// meant to handle dynamic instantiation queries...
+		HolderInstantiator holderInstantiator = HolderInstantiator.getHolderInstantiator(selectNewTransformer, resultTransformer, queryReturnAliases);
+		if ( holderInstantiator.isRequired() ) {
+			for ( int i = 0; i < results.size(); i++ ) {
+				Object[] row = ( Object[] ) results.get( i );
+				Object result = holderInstantiator.instantiate(row);
+				results.set( i, result );
+			}
+
+			if(!hasSelectNew() && resultTransformer!=null) {
+				return resultTransformer.transformList(results);
+			} else {
+				return results;
+			}
+		} else {
+			return results;
+		}
+	}
+
+	// --- Query translator methods ---
+
+	public List list(
+			SessionImplementor session,
+			QueryParameters queryParameters) throws HibernateException {
+		checkQuery( queryParameters );
+		return list( session, queryParameters, queryTranslator.getQuerySpaces(), queryReturnTypes );
+	}
+
+	private void checkQuery(QueryParameters queryParameters) {
+		if ( hasSelectNew() && queryParameters.getResultTransformer() != null ) {
+			throw new QueryException( "ResultTransformer is not allowed for 'select new' queries." );
+		}
+	}
+
+	public Iterator iterate(
+			QueryParameters queryParameters,
+			EventSource session) throws HibernateException {
+		checkQuery( queryParameters );
+		final boolean stats = session.getFactory().getStatistics().isStatisticsEnabled();
+		long startTime = 0;
+		if ( stats ) {
+			startTime = System.currentTimeMillis();
+		}
+
+		try {
+
+			final PreparedStatement st = prepareQueryStatement( queryParameters, false, session );
+
+			if(queryParameters.isCallable()) {
+				throw new QueryException("iterate() not supported for callable statements");
+			}
+			final ResultSet rs = getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), false, queryParameters.getRowSelection(), session);
+			final Iterator result = new IteratorImpl(
+					rs,
+			        st,
+			        session,
+			        queryReturnTypes,
+			        queryTranslator.getColumnNames(),
+			        HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases)
+				);
+
+			if ( stats ) {
+				session.getFactory().getStatisticsImplementor().queryExecuted(
+//						"HQL: " + queryTranslator.getQueryString(),
+						getQueryIdentifier(),
+						0,
+						System.currentTimeMillis() - startTime
+				);
+			}
+
+			return result;
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not execute query using iterate",
+			        getSQLString()
+				);
+		}
+
+	}
+
+	public ScrollableResults scroll(
+			final QueryParameters queryParameters,
+	        final SessionImplementor session) throws HibernateException {
+		checkQuery( queryParameters );
+		return scroll( queryParameters, queryReturnTypes, HolderInstantiator.getHolderInstantiator(selectNewTransformer, queryParameters.getResultTransformer(), queryReturnAliases), session );
+	}
+
+	// -- Implementation private methods --
+
+	private Object[] toResultRow(Object[] row) {
+		if ( selectLength == row.length ) {
+			return row;
+		}
+		else {
+			Object[] result = new Object[selectLength];
+			int j = 0;
+			for ( int i = 0; i < row.length; i++ ) {
+				if ( includeInSelect[i] ) {
+					result[j++] = row[i];
+				}
+			}
+			return result;
+		}
+	}
+
+	/**
+	 * Returns the locations of all occurrences of the named parameter.
+	 */
+	public int[] getNamedParameterLocs(String name) throws QueryException {
+		return queryTranslator.getParameterTranslations().getNamedParameterSqlLocations( name );
+	}
+
+	/**
+	 * We specifically override this method here, because in general we know much more
+	 * about the parameters and their appropriate bind positions here then we do in
+	 * our super because we track them explciitly here through the ParameterSpecification
+	 * interface.
+	 *
+	 * @param queryParameters The encapsulation of the parameter values to be bound.
+	 * @param startIndex The position from which to start binding parameter values.
+	 * @param session The originating session.
+	 * @return The number of JDBC bind positions actually bound during this method execution.
+	 * @throws SQLException Indicates problems performing the binding.
+	 */
+	protected int bindParameterValues(
+			final PreparedStatement statement,
+			final QueryParameters queryParameters,
+			final int startIndex,
+			final SessionImplementor session) throws SQLException {
+		int position = bindFilterParameterValues( statement, queryParameters, startIndex, session );
+		List parameterSpecs = queryTranslator.getSqlAST().getWalker().getParameters();
+		Iterator itr = parameterSpecs.iterator();
+		while ( itr.hasNext() ) {
+			ParameterSpecification spec = ( ParameterSpecification ) itr.next();
+			position += spec.bind( statement, queryParameters, session, position );
+		}
+		return position - startIndex;
+	}
+
+	private int bindFilterParameterValues(
+			PreparedStatement st,
+			QueryParameters queryParameters,
+			int position,
+			SessionImplementor session) throws SQLException {
+		// todo : better to handle dynamic filters through implicit DynamicFilterParameterSpecification
+		// see the discussion there in DynamicFilterParameterSpecification's javadocs as to why
+		// it is currently not done that way.
+		int filteredParamCount = queryParameters.getFilteredPositionalParameterTypes() == null
+				? 0
+				: queryParameters.getFilteredPositionalParameterTypes().length;
+		int nonfilteredParamCount = queryParameters.getPositionalParameterTypes() == null
+				? 0
+				: queryParameters.getPositionalParameterTypes().length;
+		int filterParamCount = filteredParamCount - nonfilteredParamCount;
+		for ( int i = 0; i < filterParamCount; i++ ) {
+			Type type = queryParameters.getFilteredPositionalParameterTypes()[i];
+			Object value = queryParameters.getFilteredPositionalParameterValues()[i];
+			type.nullSafeSet( st, value, position, session );
+			position += type.getColumnSpan( getFactory() );
+		}
+
+		return position;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/hql/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a loader for the AST-based query parser
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/hql/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/hql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a loader for the AST-based query parser
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/loader/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines functionality for processing JDBC
-	result sets and returning complex graphs of persistent
-	objects.
-</p>
-<p>
-	Subclasses of <tt>Loader</tt> define a particular
-	query mechanism.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/loader/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/loader/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines functionality for processing JDBC
+	result sets and returning complex graphs of persistent
+	objects.
+</p>
+<p>
+	Subclasses of <tt>Loader</tt> define a particular
+	query mechanism.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/BlobImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,113 +0,0 @@
-//$Id: BlobImpl.java 4997 2004-12-18 18:48:20Z oneovthafew $
-package org.hibernate.lob;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.sql.Blob;
-import java.sql.SQLException;
-
-/**
- * A dummy implementation of <tt>java.sql.Blob</tt> that
- * may be used to insert new data into a BLOB.
- * @author Gavin King
- */
-public class BlobImpl implements Blob {
-
-	private InputStream stream;
-	private int length;
-	private boolean needsReset = false;
-
-	public BlobImpl(byte[] bytes) {
-		this.stream = new ByteArrayInputStream(bytes);
-		this.length = bytes.length;
-	}
-
-	public BlobImpl(InputStream stream, int length) {
-		this.stream = stream;
-		this.length = length;
-	}
-
-	/**
-	 * @see java.sql.Blob#length()
-	 */
-	public long length() throws SQLException {
-		return length;
-	}
-
-	/**
-	 * @see java.sql.Blob#truncate(long)
-	 */
-	public void truncate(long pos) throws SQLException {
-		excep();
-	}
-
-	/**
-	 * @see java.sql.Blob#getBytes(long, int)
-	 */
-	public byte[] getBytes(long pos, int len) throws SQLException {
-		excep(); return null;
-	}
-
-	/**
-	 * @see java.sql.Blob#setBytes(long, byte[])
-	 */
-	public int setBytes(long pos, byte[] bytes) throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Blob#setBytes(long, byte[], int, int)
-	 */
-	public int setBytes(long pos, byte[] bytes, int i, int j)
-	throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Blob#position(byte[], long)
-	 */
-	public long position(byte[] bytes, long pos) throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Blob#getBinaryStream()
-	 */
-	public InputStream getBinaryStream() throws SQLException {
-		try {
-			if (needsReset) stream.reset();
-		}
-		catch (IOException ioe) {
-			throw new SQLException("could not reset reader");
-		}
-		needsReset = true;
-		return stream;
-	}
-
-	/**
-	 * @see java.sql.Blob#setBinaryStream(long)
-	 */
-	public OutputStream setBinaryStream(long pos) throws SQLException {
-		excep(); return null;
-	}
-
-	/**
-	 * @see java.sql.Blob#position(Blob, long)
-	 */
-	public long position(Blob blob, long pos) throws SQLException {
-		excep(); return 0;
-	}
-
-	private static void excep() {
-		throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/BlobImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/BlobImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,136 @@
+/*
+ * 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.lob;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+/**
+ * A dummy implementation of <tt>java.sql.Blob</tt> that
+ * may be used to insert new data into a BLOB.
+ * @author Gavin King
+ */
+public class BlobImpl implements Blob {
+
+	private InputStream stream;
+	private int length;
+	private boolean needsReset = false;
+
+	public BlobImpl(byte[] bytes) {
+		this.stream = new ByteArrayInputStream(bytes);
+		this.length = bytes.length;
+	}
+
+	public BlobImpl(InputStream stream, int length) {
+		this.stream = stream;
+		this.length = length;
+	}
+
+	/**
+	 * @see java.sql.Blob#length()
+	 */
+	public long length() throws SQLException {
+		return length;
+	}
+
+	/**
+	 * @see java.sql.Blob#truncate(long)
+	 */
+	public void truncate(long pos) throws SQLException {
+		excep();
+	}
+
+	/**
+	 * @see java.sql.Blob#getBytes(long, int)
+	 */
+	public byte[] getBytes(long pos, int len) throws SQLException {
+		excep(); return null;
+	}
+
+	/**
+	 * @see java.sql.Blob#setBytes(long, byte[])
+	 */
+	public int setBytes(long pos, byte[] bytes) throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Blob#setBytes(long, byte[], int, int)
+	 */
+	public int setBytes(long pos, byte[] bytes, int i, int j)
+	throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Blob#position(byte[], long)
+	 */
+	public long position(byte[] bytes, long pos) throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Blob#getBinaryStream()
+	 */
+	public InputStream getBinaryStream() throws SQLException {
+		try {
+			if (needsReset) stream.reset();
+		}
+		catch (IOException ioe) {
+			throw new SQLException("could not reset reader");
+		}
+		needsReset = true;
+		return stream;
+	}
+
+	/**
+	 * @see java.sql.Blob#setBinaryStream(long)
+	 */
+	public OutputStream setBinaryStream(long pos) throws SQLException {
+		excep(); return null;
+	}
+
+	/**
+	 * @see java.sql.Blob#position(Blob, long)
+	 */
+	public long position(Blob blob, long pos) throws SQLException {
+		excep(); return 0;
+	}
+
+	private static void excep() {
+		throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/ClobImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,137 +0,0 @@
-//$Id: ClobImpl.java 5683 2005-02-12 03:09:22Z oneovthafew $
-package org.hibernate.lob;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.sql.Clob;
-import java.sql.SQLException;
-
-/**
- * A dummy implementation of <tt>java.sql.Clob</tt> that
- * may be used to insert new data into a CLOB.
- * @author Gavin King
- */
-public class ClobImpl implements Clob {
-
-	private Reader reader;
-	private int length;
-	private boolean needsReset = false;
-
-	public ClobImpl(String string) {
-		reader = new StringReader(string);
-		length = string.length();
-	}
-
-	public ClobImpl(Reader reader, int length) {
-		this.reader = reader;
-		this.length = length;
-	}
-
-	/**
-	 * @see java.sql.Clob#length()
-	 */
-	public long length() throws SQLException {
-		return length;
-	}
-
-	/**
-	 * @see java.sql.Clob#truncate(long)
-	 */
-	public void truncate(long pos) throws SQLException {
-		excep();
-	}
-
-	/**
-	 * @see java.sql.Clob#getAsciiStream()
-	 */
-	public InputStream getAsciiStream() throws SQLException {
-		try {
-			if (needsReset) reader.reset();
-		}
-		catch (IOException ioe) {
-			throw new SQLException("could not reset reader");
-		}
-		needsReset = true;
-		return new ReaderInputStream(reader);
-	}
-
-	/**
-	 * @see java.sql.Clob#setAsciiStream(long)
-	 */
-	public OutputStream setAsciiStream(long pos) throws SQLException {
-		excep(); return null;
-	}
-
-	/**
-	 * @see java.sql.Clob#getCharacterStream()
-	 */
-	public Reader getCharacterStream() throws SQLException {
-		try {
-			if (needsReset) reader.reset();
-		}
-		catch (IOException ioe) {
-			throw new SQLException("could not reset reader");
-		}
-		needsReset = true;
-		return reader;
-	}
-
-	/**
-	 * @see java.sql.Clob#setCharacterStream(long)
-	 */
-	public Writer setCharacterStream(long pos) throws SQLException {
-		excep(); return null;
-	}
-
-	/**
-	 * @see java.sql.Clob#getSubString(long, int)
-	 */
-	public String getSubString(long pos, int len) throws SQLException {
-		excep(); return null;
-	}
-
-	/**
-	 * @see java.sql.Clob#setString(long, String)
-	 */
-	public int setString(long pos, String string) throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Clob#setString(long, String, int, int)
-	 */
-	public int setString(long pos, String string, int i, int j)
-	throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Clob#position(String, long)
-	 */
-	public long position(String string, long pos) throws SQLException {
-		excep(); return 0;
-	}
-
-	/**
-	 * @see java.sql.Clob#position(Clob, long)
-	 */
-	public long position(Clob colb, long pos) throws SQLException {
-		excep(); return 0;
-	}
-
-
-	private static void excep() {
-		throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/ClobImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ClobImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,160 @@
+/*
+ * 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.lob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+/**
+ * A dummy implementation of <tt>java.sql.Clob</tt> that
+ * may be used to insert new data into a CLOB.
+ * @author Gavin King
+ */
+public class ClobImpl implements Clob {
+
+	private Reader reader;
+	private int length;
+	private boolean needsReset = false;
+
+	public ClobImpl(String string) {
+		reader = new StringReader(string);
+		length = string.length();
+	}
+
+	public ClobImpl(Reader reader, int length) {
+		this.reader = reader;
+		this.length = length;
+	}
+
+	/**
+	 * @see java.sql.Clob#length()
+	 */
+	public long length() throws SQLException {
+		return length;
+	}
+
+	/**
+	 * @see java.sql.Clob#truncate(long)
+	 */
+	public void truncate(long pos) throws SQLException {
+		excep();
+	}
+
+	/**
+	 * @see java.sql.Clob#getAsciiStream()
+	 */
+	public InputStream getAsciiStream() throws SQLException {
+		try {
+			if (needsReset) reader.reset();
+		}
+		catch (IOException ioe) {
+			throw new SQLException("could not reset reader");
+		}
+		needsReset = true;
+		return new ReaderInputStream(reader);
+	}
+
+	/**
+	 * @see java.sql.Clob#setAsciiStream(long)
+	 */
+	public OutputStream setAsciiStream(long pos) throws SQLException {
+		excep(); return null;
+	}
+
+	/**
+	 * @see java.sql.Clob#getCharacterStream()
+	 */
+	public Reader getCharacterStream() throws SQLException {
+		try {
+			if (needsReset) reader.reset();
+		}
+		catch (IOException ioe) {
+			throw new SQLException("could not reset reader");
+		}
+		needsReset = true;
+		return reader;
+	}
+
+	/**
+	 * @see java.sql.Clob#setCharacterStream(long)
+	 */
+	public Writer setCharacterStream(long pos) throws SQLException {
+		excep(); return null;
+	}
+
+	/**
+	 * @see java.sql.Clob#getSubString(long, int)
+	 */
+	public String getSubString(long pos, int len) throws SQLException {
+		excep(); return null;
+	}
+
+	/**
+	 * @see java.sql.Clob#setString(long, String)
+	 */
+	public int setString(long pos, String string) throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Clob#setString(long, String, int, int)
+	 */
+	public int setString(long pos, String string, int i, int j)
+	throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Clob#position(String, long)
+	 */
+	public long position(String string, long pos) throws SQLException {
+		excep(); return 0;
+	}
+
+	/**
+	 * @see java.sql.Clob#position(Clob, long)
+	 */
+	public long position(Clob colb, long pos) throws SQLException {
+		excep(); return 0;
+	}
+
+
+	private static void excep() {
+		throw new UnsupportedOperationException("Blob may not be manipulated from creating session");
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: ReaderInputStream.java 5683 2005-02-12 03:09:22Z oneovthafew $
-package org.hibernate.lob;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * Exposes a <tt>Reader</tt> as an <tt>InputStream</tt>
- * @author Gavin King
- */
-public class ReaderInputStream extends InputStream {
-	
-	private Reader reader;
-	
-	public ReaderInputStream(Reader reader) {
-		this.reader = reader;
-	}
-	
-	public int read() throws IOException {
-		return reader.read();
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/ReaderInputStream.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/ReaderInputStream.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.lob;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+
+/**
+ * Exposes a <tt>Reader</tt> as an <tt>InputStream</tt>
+ * @author Gavin King
+ */
+public class ReaderInputStream extends InputStream {
+	
+	private Reader reader;
+	
+	public ReaderInputStream(Reader reader) {
+		this.reader = reader;
+	}
+	
+	public int read() throws IOException {
+		return reader.read();
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/SerializableBlob.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-//$Id: SerializableBlob.java 5986 2005-03-02 11:43:36Z oneovthafew $
-package org.hibernate.lob;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.sql.Blob;
-import java.sql.SQLException;
-
-/**
- * @author Gavin King
- */
-public class SerializableBlob implements Serializable, Blob {
-	
-	private transient final Blob blob;
-	
-	public SerializableBlob(Blob blob) {
-		this.blob = blob;
-	}
-
-	public Blob getWrappedBlob() {
-		if ( blob==null ) {
-			throw new IllegalStateException("Blobs may not be accessed after serialization");
-		}
-		else {
-			return blob;
-		}
-	}
-	
-	public long length() throws SQLException {
-		return getWrappedBlob().length();
-	}
-
-	public byte[] getBytes(long pos, int length) throws SQLException {
-		return getWrappedBlob().getBytes(pos, length);
-	}
-
-	public InputStream getBinaryStream() throws SQLException {
-		return getWrappedBlob().getBinaryStream();
-	}
-
-	public long position(byte[] pattern, long start) throws SQLException {
-		return getWrappedBlob().position(pattern, start);
-	}
-
-	public long position(Blob pattern, long start) throws SQLException {
-		return getWrappedBlob().position(pattern, start);
-	}
-
-	public int setBytes(long pos, byte[] bytes) throws SQLException {
-		return getWrappedBlob().setBytes(pos, bytes);
-	}
-
-	public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
-		return getWrappedBlob().setBytes(pos, bytes, offset, len);
-	}
-
-	public OutputStream setBinaryStream(long pos) throws SQLException {
-		return getWrappedBlob().setBinaryStream(pos);
-	}
-
-	public void truncate(long len) throws SQLException {
-		getWrappedBlob().truncate(len);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/SerializableBlob.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableBlob.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,89 @@
+/*
+ * 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.lob;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.SQLException;
+
+/**
+ * @author Gavin King
+ */
+public class SerializableBlob implements Serializable, Blob {
+	
+	private transient final Blob blob;
+	
+	public SerializableBlob(Blob blob) {
+		this.blob = blob;
+	}
+
+	public Blob getWrappedBlob() {
+		if ( blob==null ) {
+			throw new IllegalStateException("Blobs may not be accessed after serialization");
+		}
+		else {
+			return blob;
+		}
+	}
+	
+	public long length() throws SQLException {
+		return getWrappedBlob().length();
+	}
+
+	public byte[] getBytes(long pos, int length) throws SQLException {
+		return getWrappedBlob().getBytes(pos, length);
+	}
+
+	public InputStream getBinaryStream() throws SQLException {
+		return getWrappedBlob().getBinaryStream();
+	}
+
+	public long position(byte[] pattern, long start) throws SQLException {
+		return getWrappedBlob().position(pattern, start);
+	}
+
+	public long position(Blob pattern, long start) throws SQLException {
+		return getWrappedBlob().position(pattern, start);
+	}
+
+	public int setBytes(long pos, byte[] bytes) throws SQLException {
+		return getWrappedBlob().setBytes(pos, bytes);
+	}
+
+	public int setBytes(long pos, byte[] bytes, int offset, int len) throws SQLException {
+		return getWrappedBlob().setBytes(pos, bytes, offset, len);
+	}
+
+	public OutputStream setBinaryStream(long pos) throws SQLException {
+		return getWrappedBlob().setBinaryStream(pos);
+	}
+
+	public void truncate(long len) throws SQLException {
+		getWrappedBlob().truncate(len);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/SerializableClob.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,76 +0,0 @@
-//$Id: SerializableClob.java 5986 2005-03-02 11:43:36Z oneovthafew $
-package org.hibernate.lob;
-
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.Serializable;
-import java.io.Writer;
-import java.sql.Clob;
-import java.sql.SQLException;
-
-/**
- * @author Gavin King
- */
-public class SerializableClob implements Serializable, Clob {
-
-	private transient final Clob clob;
-	
-	public SerializableClob(Clob blob) {
-		this.clob = blob;
-	}
-
-	public Clob getWrappedClob() {
-		if ( clob==null ) {
-			throw new IllegalStateException("Clobs may not be accessed after serialization");
-		}
-		else {
-			return clob;
-		}
-	}
-	
-	public long length() throws SQLException {
-		return getWrappedClob().length();
-	}
-
-	public String getSubString(long pos, int length) throws SQLException {
-		return getWrappedClob().getSubString(pos, length);
-	}
-
-	public Reader getCharacterStream() throws SQLException {
-		return getWrappedClob().getCharacterStream();
-	}
-
-	public InputStream getAsciiStream() throws SQLException {
-		return getWrappedClob().getAsciiStream();
-	}
-
-	public long position(String searchstr, long start) throws SQLException {
-		return getWrappedClob().position(searchstr, start);
-	}
-
-	public long position(Clob searchstr, long start) throws SQLException {
-		return getWrappedClob().position(searchstr, start);
-	}
-
-	public int setString(long pos, String str) throws SQLException {
-		return getWrappedClob().setString(pos, str);
-	}
-
-	public int setString(long pos, String str, int offset, int len) throws SQLException {
-		return getWrappedClob().setString(pos, str, offset, len);
-	}
-
-	public OutputStream setAsciiStream(long pos) throws SQLException {
-		return getWrappedClob().setAsciiStream(pos);
-	}
-
-	public Writer setCharacterStream(long pos) throws SQLException {
-		return getWrappedClob().setCharacterStream(pos);
-	}
-
-	public void truncate(long len) throws SQLException {
-		getWrappedClob().truncate(len);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/SerializableClob.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/SerializableClob.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,99 @@
+/*
+ * 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.lob;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.io.Writer;
+import java.sql.Clob;
+import java.sql.SQLException;
+
+/**
+ * @author Gavin King
+ */
+public class SerializableClob implements Serializable, Clob {
+
+	private transient final Clob clob;
+	
+	public SerializableClob(Clob blob) {
+		this.clob = blob;
+	}
+
+	public Clob getWrappedClob() {
+		if ( clob==null ) {
+			throw new IllegalStateException("Clobs may not be accessed after serialization");
+		}
+		else {
+			return clob;
+		}
+	}
+	
+	public long length() throws SQLException {
+		return getWrappedClob().length();
+	}
+
+	public String getSubString(long pos, int length) throws SQLException {
+		return getWrappedClob().getSubString(pos, length);
+	}
+
+	public Reader getCharacterStream() throws SQLException {
+		return getWrappedClob().getCharacterStream();
+	}
+
+	public InputStream getAsciiStream() throws SQLException {
+		return getWrappedClob().getAsciiStream();
+	}
+
+	public long position(String searchstr, long start) throws SQLException {
+		return getWrappedClob().position(searchstr, start);
+	}
+
+	public long position(Clob searchstr, long start) throws SQLException {
+		return getWrappedClob().position(searchstr, start);
+	}
+
+	public int setString(long pos, String str) throws SQLException {
+		return getWrappedClob().setString(pos, str);
+	}
+
+	public int setString(long pos, String str, int offset, int len) throws SQLException {
+		return getWrappedClob().setString(pos, str, offset, len);
+	}
+
+	public OutputStream setAsciiStream(long pos) throws SQLException {
+		return getWrappedClob().setAsciiStream(pos);
+	}
+
+	public Writer setCharacterStream(long pos) throws SQLException {
+		return getWrappedClob().setCharacterStream(pos);
+	}
+
+	public void truncate(long len) throws SQLException {
+		getWrappedClob().truncate(len);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/lob/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines dummy and wrapper implementations 
-	of <tt>java.sql.Clob</tt> and <tt>java.sql.Blob</tt>.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/lob/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/lob/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines dummy and wrapper implementations 
+	of <tt>java.sql.Clob</tt> and <tt>java.sql.Blob</tt>.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-// $Id: AbstractAuxiliaryDatabaseObject.java 7801 2005-08-10 12:16:55Z steveebersole $
-package org.hibernate.mapping;
-
-import java.util.HashSet;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * Convenience base class for {@link AuxiliaryDatabaseObject}s.
- * <p/>
- * This implementation performs dialect scoping checks strictly based on
- * dialect name comparisons.  Custom implementations might want to do
- * instanceof-type checks.
- *
- * @author Steve Ebersole
- */
-public abstract class AbstractAuxiliaryDatabaseObject implements AuxiliaryDatabaseObject {
-
-	private final HashSet dialectScopes;
-
-	protected AbstractAuxiliaryDatabaseObject() {
-		this.dialectScopes = new HashSet();
-	}
-
-	protected AbstractAuxiliaryDatabaseObject(HashSet dialectScopes) {
-		this.dialectScopes = dialectScopes;
-	}
-
-	public void addDialectScope(String dialectName) {
-		dialectScopes.add( dialectName );
-	}
-
-	public HashSet getDialectScopes() {
-		return dialectScopes;
-	}
-
-	public boolean appliesToDialect(Dialect dialect) {
-		// empty means no scoping
-		return dialectScopes.isEmpty() || dialectScopes.contains( dialect.getClass().getName() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AbstractAuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.util.HashSet;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Convenience base class for {@link AuxiliaryDatabaseObject}s.
+ * <p/>
+ * This implementation performs dialect scoping checks strictly based on
+ * dialect name comparisons.  Custom implementations might want to do
+ * instanceof-type checks.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractAuxiliaryDatabaseObject implements AuxiliaryDatabaseObject {
+
+	private final HashSet dialectScopes;
+
+	protected AbstractAuxiliaryDatabaseObject() {
+		this.dialectScopes = new HashSet();
+	}
+
+	protected AbstractAuxiliaryDatabaseObject(HashSet dialectScopes) {
+		this.dialectScopes = dialectScopes;
+	}
+
+	public void addDialectScope(String dialectName) {
+		dialectScopes.add( dialectName );
+	}
+
+	public HashSet getDialectScopes() {
+		return dialectScopes;
+	}
+
+	public boolean appliesToDialect(Dialect dialect) {
+		// empty means no scoping
+		return dialectScopes.isEmpty() || dialectScopes.contains( dialect.getClass().getName() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Any.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-//$Id: Any.java 4905 2004-12-07 09:59:56Z maxcsaucdk $
-package org.hibernate.mapping;
-
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.MetaType;
-import org.hibernate.type.AnyType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A Hibernate "any" type (ie. polymorphic association to
- * one-of-several tables).
- * @author Gavin King
- */
-public class Any extends SimpleValue {
-
-	private String identifierTypeName;
-	private String metaTypeName = "string";
-	private Map metaValues;
-
-	public Any(Table table) {
-		super(table);
-	}
-
-	public String getIdentifierType() {
-		return identifierTypeName;
-	}
-
-	public void setIdentifierType(String identifierType) {
-		this.identifierTypeName = identifierType;
-	}
-
-	public Type getType() throws MappingException {
-		return new AnyType(
-			metaValues==null ?
-				TypeFactory.heuristicType(metaTypeName) :
-				new MetaType( metaValues, TypeFactory.heuristicType(metaTypeName) ),
-				TypeFactory.heuristicType(identifierTypeName)
-		);
-	}
-
-	public void setTypeByReflection(String propertyClass, String propertyName) {}
-
-	public String getMetaType() {
-		return metaTypeName;
-	}
-
-	public void setMetaType(String type) {
-		metaTypeName = type;
-	}
-
-	public Map getMetaValues() {
-		return metaValues;
-	}
-
-	public void setMetaValues(Map metaValues) {
-		this.metaValues = metaValues;
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName)
-		throws MappingException {
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Any.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Any.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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.mapping;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.MetaType;
+import org.hibernate.type.AnyType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A Hibernate "any" type (ie. polymorphic association to
+ * one-of-several tables).
+ * @author Gavin King
+ */
+public class Any extends SimpleValue {
+
+	private String identifierTypeName;
+	private String metaTypeName = "string";
+	private Map metaValues;
+
+	public Any(Table table) {
+		super(table);
+	}
+
+	public String getIdentifierType() {
+		return identifierTypeName;
+	}
+
+	public void setIdentifierType(String identifierType) {
+		this.identifierTypeName = identifierType;
+	}
+
+	public Type getType() throws MappingException {
+		return new AnyType(
+			metaValues==null ?
+				TypeFactory.heuristicType(metaTypeName) :
+				new MetaType( metaValues, TypeFactory.heuristicType(metaTypeName) ),
+				TypeFactory.heuristicType(identifierTypeName)
+		);
+	}
+
+	public void setTypeByReflection(String propertyClass, String propertyName) {}
+
+	public String getMetaType() {
+		return metaTypeName;
+	}
+
+	public void setMetaType(String type) {
+		metaTypeName = type;
+	}
+
+	public Map getMetaValues() {
+		return metaValues;
+	}
+
+	public void setMetaValues(Map metaValues) {
+		this.metaValues = metaValues;
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName)
+		throws MappingException {
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Array.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-//$Id: Array.java 5793 2005-02-20 03:34:50Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.PrimitiveType;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * An array mapping has a primary key consisting of
- * the key columns + index column.
- * @author Gavin King
- */
-public class Array extends List {
-
-	private String elementClassName;
-
-	/**
-	 * Constructor for Array.
-	 * @param owner
-	 */
-	public Array(PersistentClass owner) {
-		super(owner);
-	}
-
-	public Class getElementClass() throws MappingException {
-		if (elementClassName==null) {
-			org.hibernate.type.Type elementType = getElement().getType();
-			return isPrimitiveArray() ?
-				( (PrimitiveType) elementType ).getPrimitiveClass() :
-				elementType.getReturnedClass();
-		}
-		else {
-			try {
-				return ReflectHelper.classForName(elementClassName);
-			}
-			catch (ClassNotFoundException cnfe) {
-				throw new MappingException(cnfe);
-			}
-		}
-	}
-
-	public CollectionType getDefaultCollectionType() throws MappingException {
-		return TypeFactory.array( getRole(), getReferencedPropertyName(), isEmbedded(), getElementClass() );
-	}
-
-	public boolean isArray() {
-		return true;
-	}
-
-	/**
-	 * @return Returns the elementClassName.
-	 */
-	public String getElementClassName() {
-		return elementClassName;
-	}
-	/**
-	 * @param elementClassName The elementClassName to set.
-	 */
-	public void setElementClassName(String elementClassName) {
-		this.elementClassName = elementClassName;
-	}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Array.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Array.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.PrimitiveType;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * An array mapping has a primary key consisting of
+ * the key columns + index column.
+ * @author Gavin King
+ */
+public class Array extends List {
+
+	private String elementClassName;
+
+	/**
+	 * Constructor for Array.
+	 * @param owner
+	 */
+	public Array(PersistentClass owner) {
+		super(owner);
+	}
+
+	public Class getElementClass() throws MappingException {
+		if (elementClassName==null) {
+			org.hibernate.type.Type elementType = getElement().getType();
+			return isPrimitiveArray() ?
+				( (PrimitiveType) elementType ).getPrimitiveClass() :
+				elementType.getReturnedClass();
+		}
+		else {
+			try {
+				return ReflectHelper.classForName(elementClassName);
+			}
+			catch (ClassNotFoundException cnfe) {
+				throw new MappingException(cnfe);
+			}
+		}
+	}
+
+	public CollectionType getDefaultCollectionType() throws MappingException {
+		return TypeFactory.array( getRole(), getReferencedPropertyName(), isEmbedded(), getElementClass() );
+	}
+
+	public boolean isArray() {
+		return true;
+	}
+
+	/**
+	 * @return Returns the elementClassName.
+	 */
+	public String getElementClassName() {
+		return elementClassName;
+	}
+	/**
+	 * @param elementClassName The elementClassName to set.
+	 */
+	public void setElementClassName(String elementClassName) {
+		this.elementClassName = elementClassName;
+	}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-// $Id: AuxiliaryDatabaseObject.java 7800 2005-08-10 12:13:00Z steveebersole $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * Auxiliary database objects (i.e., triggers, stored procedures, etc) defined
- * in the mappings.  Allows Hibernate to manage their lifecycle as part of
- * creating/dropping the schema.
- *
- * @author Steve Ebersole
- */
-public interface AuxiliaryDatabaseObject extends RelationalModel, Serializable {
-	/**
-	 * Add the given dialect name to the scope of dialects to which
-	 * this database object applies.
-	 *
-	 * @param dialectName The name of a dialect.
-	 */
-	void addDialectScope(String dialectName);
-
-	/**
-	 * Does this database object apply to the given dialect?
-	 *
-	 * @param dialect The dialect to check against.
-	 * @return True if this database object does apply to the given dialect.
-	 */
-	boolean appliesToDialect(Dialect dialect);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/AuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Auxiliary database objects (i.e., triggers, stored procedures, etc) defined
+ * in the mappings.  Allows Hibernate to manage their lifecycle as part of
+ * creating/dropping the schema.
+ *
+ * @author Steve Ebersole
+ */
+public interface AuxiliaryDatabaseObject extends RelationalModel, Serializable {
+	/**
+	 * Add the given dialect name to the scope of dialects to which
+	 * this database object applies.
+	 *
+	 * @param dialectName The name of a dialect.
+	 */
+	void addDialectScope(String dialectName);
+
+	/**
+	 * Does this database object apply to the given dialect?
+	 *
+	 * @param dialect The dialect to check against.
+	 * @return True if this database object does apply to the given dialect.
+	 */
+	boolean appliesToDialect(Dialect dialect);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Backref.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: Backref.java 6924 2005-05-27 01:30:18Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.property.BackrefPropertyAccessor;
-import org.hibernate.property.PropertyAccessor;
-
-/**
- * @author Gavin King
- */
-public class Backref extends Property {
-	private String collectionRole;
-	private String entityName;
-	
-	public boolean isBackRef() {
-		return true;
-	}
-	public String getCollectionRole() {
-		return collectionRole;
-	}
-	public void setCollectionRole(String collectionRole) {
-		this.collectionRole = collectionRole;
-	}
-
-	public boolean isBasicPropertyAccessor() {
-		return false;
-	}
-
-	public PropertyAccessor getPropertyAccessor(Class clazz) {
-		return new BackrefPropertyAccessor(collectionRole, entityName);
-	}
-	
-	public String getEntityName() {
-		return entityName;
-	}
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Backref.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Backref.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.property.BackrefPropertyAccessor;
+import org.hibernate.property.PropertyAccessor;
+
+/**
+ * @author Gavin King
+ */
+public class Backref extends Property {
+	private String collectionRole;
+	private String entityName;
+	
+	public boolean isBackRef() {
+		return true;
+	}
+	public String getCollectionRole() {
+		return collectionRole;
+	}
+	public void setCollectionRole(String collectionRole) {
+		this.collectionRole = collectionRole;
+	}
+
+	public boolean isBasicPropertyAccessor() {
+		return false;
+	}
+
+	public PropertyAccessor getPropertyAccessor(Class clazz) {
+		return new BackrefPropertyAccessor(collectionRole, entityName);
+	}
+	
+	public String getEntityName() {
+		return entityName;
+	}
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Bag.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: Bag.java 5793 2005-02-20 03:34:50Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A bag permits duplicates, so it has no primary key
- * @author Gavin King
- */
-public class Bag extends Collection {
-
-	public Bag(PersistentClass owner) {
-		super(owner);
-	}
-
-	public CollectionType getDefaultCollectionType() {
-		return TypeFactory.bag( getRole(), getReferencedPropertyName(), isEmbedded() );
-	}
-
-	void createPrimaryKey() {
-		//create an index on the key columns??
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Bag.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Bag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A bag permits duplicates, so it has no primary key
+ * 
+ * @author Gavin King
+ */
+public class Bag extends Collection {
+
+	public Bag(PersistentClass owner) {
+		super(owner);
+	}
+
+	public CollectionType getDefaultCollectionType() {
+		return TypeFactory.bag( getRole(), getReferencedPropertyName(), isEmbedded() );
+	}
+
+	void createPrimaryKey() {
+		//create an index on the key columns??
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Collection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,622 +0,0 @@
-// $Id: Collection.java 11496 2007-05-09 03:54:06Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Properties;
-
-import org.hibernate.FetchMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.EmptyIterator;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Mapping for a collection. Subclasses specialize to particular collection styles.
- * 
- * @author Gavin King
- */
-public abstract class Collection implements Fetchable, Value, Filterable {
-
-	public static final String DEFAULT_ELEMENT_COLUMN_NAME = "elt";
-	public static final String DEFAULT_KEY_COLUMN_NAME = "id";
-
-	private KeyValue key;
-	private Value element;
-	private Table collectionTable;
-	private String role;
-	private boolean lazy;
-	private boolean extraLazy;
-	private boolean inverse;
-	private boolean mutable = true;
-	private boolean subselectLoadable;
-	private String cacheConcurrencyStrategy;
-	private String cacheRegionName;
-	private String orderBy;
-	private String where;
-	private String manyToManyWhere;
-	private String manyToManyOrderBy;
-	private PersistentClass owner;
-	private String referencedPropertyName;
-	private String nodeName;
-	private String elementNodeName;
-	private boolean sorted;
-	private Comparator comparator;
-	private String comparatorClassName;
-	private boolean orphanDelete;
-	private int batchSize = -1;
-	private FetchMode fetchMode;
-	private boolean embedded = true;
-	private boolean optimisticLocked = true;
-	private Class collectionPersisterClass;
-	private String typeName;
-	private Properties typeParameters;
-	private final java.util.Map filters = new HashMap();
-	private final java.util.Map manyToManyFilters = new HashMap();
-	private final java.util.Set synchronizedTables = new HashSet();
-
-	private String customSQLInsert;
-	private boolean customInsertCallable;
-	private ExecuteUpdateResultCheckStyle insertCheckStyle;
-	private String customSQLUpdate;
-	private boolean customUpdateCallable;
-	private ExecuteUpdateResultCheckStyle updateCheckStyle;
-	private String customSQLDelete;
-	private boolean customDeleteCallable;
-	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
-	private String customSQLDeleteAll;
-	private boolean customDeleteAllCallable;
-	private ExecuteUpdateResultCheckStyle deleteAllCheckStyle;
-
-	private String loaderName;
-
-	protected Collection(PersistentClass owner) {
-		this.owner = owner;
-	}
-
-	public boolean isSet() {
-		return false;
-	}
-
-	public KeyValue getKey() {
-		return key;
-	}
-
-	public Value getElement() {
-		return element;
-	}
-
-	public boolean isIndexed() {
-		return false;
-	}
-
-	public Table getCollectionTable() {
-		return collectionTable;
-	}
-
-	public void setCollectionTable(Table table) {
-		this.collectionTable = table;
-	}
-
-	public boolean isSorted() {
-		return sorted;
-	}
-
-	public Comparator getComparator() {
-		if ( comparator == null && comparatorClassName != null ) {
-			try {
-				setComparator( (Comparator) ReflectHelper.classForName( comparatorClassName ).newInstance() );
-			}
-			catch ( Exception e ) {
-				throw new MappingException(
-						"Could not instantiate comparator class [" + comparatorClassName
-						+ "] for collection " + getRole()  
-				);
-			}
-		}
-		return comparator;
-	}
-
-	public boolean isLazy() {
-		return lazy;
-	}
-
-	public void setLazy(boolean lazy) {
-		this.lazy = lazy;
-	}
-
-	public String getRole() {
-		return role;
-	}
-
-	public abstract CollectionType getDefaultCollectionType() throws MappingException;
-
-	public boolean isPrimitiveArray() {
-		return false;
-	}
-
-	public boolean isArray() {
-		return false;
-	}
-
-	public boolean hasFormula() {
-		return false;
-	}
-
-	public boolean isOneToMany() {
-		return element instanceof OneToMany;
-	}
-
-	public boolean isInverse() {
-		return inverse;
-	}
-
-	public String getOwnerEntityName() {
-		return owner.getEntityName();
-	}
-
-	public String getOrderBy() {
-		return orderBy;
-	}
-
-	public void setComparator(Comparator comparator) {
-		this.comparator = comparator;
-	}
-
-	public void setElement(Value element) {
-		this.element = element;
-	}
-
-	public void setKey(KeyValue key) {
-		this.key = key;
-	}
-
-	public void setOrderBy(String orderBy) {
-		this.orderBy = orderBy;
-	}
-
-	public void setRole(String role) {
-		this.role = role==null ? null : role.intern();
-	}
-
-	public void setSorted(boolean sorted) {
-		this.sorted = sorted;
-	}
-
-	public void setInverse(boolean inverse) {
-		this.inverse = inverse;
-	}
-
-	public PersistentClass getOwner() {
-		return owner;
-	}
-
-	public void setOwner(PersistentClass owner) {
-		this.owner = owner;
-	}
-
-	public String getWhere() {
-		return where;
-	}
-
-	public void setWhere(String where) {
-		this.where = where;
-	}
-
-	public String getManyToManyWhere() {
-		return manyToManyWhere;
-	}
-
-	public void setManyToManyWhere(String manyToManyWhere) {
-		this.manyToManyWhere = manyToManyWhere;
-	}
-
-	public String getManyToManyOrdering() {
-		return manyToManyOrderBy;
-	}
-
-	public void setManyToManyOrdering(String orderFragment) {
-		this.manyToManyOrderBy = orderFragment;
-	}
-
-	public boolean isIdentified() {
-		return false;
-	}
-
-	public boolean hasOrphanDelete() {
-		return orphanDelete;
-	}
-
-	public void setOrphanDelete(boolean orphanDelete) {
-		this.orphanDelete = orphanDelete;
-	}
-
-	public int getBatchSize() {
-		return batchSize;
-	}
-
-	public void setBatchSize(int i) {
-		batchSize = i;
-	}
-
-	public FetchMode getFetchMode() {
-		return fetchMode;
-	}
-
-	public void setFetchMode(FetchMode fetchMode) {
-		this.fetchMode = fetchMode;
-	}
-
-	public void setCollectionPersisterClass(Class persister) {
-		this.collectionPersisterClass = persister;
-	}
-
-	public Class getCollectionPersisterClass() {
-		return collectionPersisterClass;
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		if ( getKey().isCascadeDeleteEnabled() && ( !isInverse() || !isOneToMany() ) ) {
-			throw new MappingException(
-				"only inverse one-to-many associations may use on-delete=\"cascade\": " 
-				+ getRole() );
-		}
-		if ( !getKey().isValid( mapping ) ) {
-			throw new MappingException(
-				"collection foreign key mapping has wrong number of columns: "
-				+ getRole()
-				+ " type: "
-				+ getKey().getType().getName() );
-		}
-		if ( !getElement().isValid( mapping ) ) {
-			throw new MappingException( 
-				"collection element mapping has wrong number of columns: "
-				+ getRole()
-				+ " type: "
-				+ getElement().getType().getName() );
-		}
-
-		checkColumnDuplication();
-		
-		if ( elementNodeName!=null && elementNodeName.startsWith("@") ) {
-			throw new MappingException("element node must not be an attribute: " + elementNodeName );
-		}
-		if ( elementNodeName!=null && elementNodeName.equals(".") ) {
-			throw new MappingException("element node must not be the parent: " + elementNodeName );
-		}
-		if ( nodeName!=null && nodeName.indexOf('@')>-1 ) {
-			throw new MappingException("collection node must not be an attribute: " + elementNodeName );
-		}
-	}
-
-	private void checkColumnDuplication(java.util.Set distinctColumns, Iterator columns)
-			throws MappingException {
-		while ( columns.hasNext() ) {
-			Selectable s = (Selectable) columns.next();
-			if ( !s.isFormula() ) {
-				Column col = (Column) s;
-				if ( !distinctColumns.add( col.getName() ) ) {
-					throw new MappingException( "Repeated column in mapping for collection: "
-						+ getRole()
-						+ " column: "
-						+ col.getName() );
-				}
-			}
-		}
-	}
-
-	private void checkColumnDuplication() throws MappingException {
-		HashSet cols = new HashSet();
-		checkColumnDuplication( cols, getKey().getColumnIterator() );
-		if ( isIndexed() ) {
-			checkColumnDuplication( cols, ( (IndexedCollection) this )
-				.getIndex()
-				.getColumnIterator() );
-		}
-		if ( isIdentified() ) {
-			checkColumnDuplication( cols, ( (IdentifierCollection) this )
-				.getIdentifier()
-				.getColumnIterator() );
-		}
-		if ( !isOneToMany() ) {
-			checkColumnDuplication( cols, getElement().getColumnIterator() );
-		}
-	}
-
-	public Iterator getColumnIterator() {
-		return EmptyIterator.INSTANCE;
-	}
-
-	public int getColumnSpan() {
-		return 0;
-	}
-
-	public Type getType() throws MappingException {
-		return getCollectionType();
-	}
-
-	public CollectionType getCollectionType() {
-		if ( typeName == null ) {
-			return getDefaultCollectionType();
-		}
-		else {
-			return TypeFactory.customCollection( typeName, typeParameters, role, referencedPropertyName, isEmbedded() );
-		}
-	}
-
-	public boolean isNullable() {
-		return true;
-	}
-
-	public boolean isAlternateUniqueKey() {
-		return false;
-	}
-
-	public Table getTable() {
-		return owner.getTable();
-	}
-
-	public void createForeignKey() {
-	}
-
-	public boolean isSimpleValue() {
-		return false;
-	}
-
-	public boolean isValid(Mapping mapping) throws MappingException {
-		return true;
-	}
-
-	private void createForeignKeys() throws MappingException {
-		// if ( !isInverse() ) { // for inverse collections, let the "other end" handle it
-		if ( referencedPropertyName == null ) {
-			getElement().createForeignKey();
-			key.createForeignKeyOfEntity( getOwner().getEntityName() );
-		}
-		// }
-	}
-
-	abstract void createPrimaryKey();
-
-	public void createAllKeys() throws MappingException {
-		createForeignKeys();
-		if ( !isInverse() ) createPrimaryKey();
-	}
-
-	public String getCacheConcurrencyStrategy() {
-		return cacheConcurrencyStrategy;
-	}
-
-	public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
-		this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName) {
-	}
-
-	public String getCacheRegionName() {
-		return cacheRegionName == null ? role : cacheRegionName;
-	}
-
-	public void setCacheRegionName(String cacheRegionName) {
-		this.cacheRegionName = cacheRegionName;
-	}
-
-
-
-	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLInsert = customSQLInsert;
-		this.customInsertCallable = callable;
-		this.insertCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLInsert() {
-		return customSQLInsert;
-	}
-
-	public boolean isCustomInsertCallable() {
-		return customInsertCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
-		return insertCheckStyle;
-	}
-
-	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLUpdate = customSQLUpdate;
-		this.customUpdateCallable = callable;
-		this.updateCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLUpdate() {
-		return customSQLUpdate;
-	}
-
-	public boolean isCustomUpdateCallable() {
-		return customUpdateCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
-		return updateCheckStyle;
-	}
-
-	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLDelete = customSQLDelete;
-		this.customDeleteCallable = callable;
-		this.deleteCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLDelete() {
-		return customSQLDelete;
-	}
-
-	public boolean isCustomDeleteCallable() {
-		return customDeleteCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
-		return deleteCheckStyle;
-	}
-
-	public void setCustomSQLDeleteAll(String customSQLDeleteAll, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLDeleteAll = customSQLDeleteAll;
-		this.customDeleteAllCallable = callable;
-		this.deleteAllCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLDeleteAll() {
-		return customSQLDeleteAll;
-	}
-
-	public boolean isCustomDeleteAllCallable() {
-		return customDeleteAllCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteAllCheckStyle() {
-		return deleteAllCheckStyle;
-	}
-
-	public void addFilter(String name, String condition) {
-		filters.put( name, condition );
-	}
-
-	public java.util.Map getFilterMap() {
-		return filters;
-	}
-
-	public void addManyToManyFilter(String name, String condition) {
-		manyToManyFilters.put( name, condition );
-	}
-
-	public java.util.Map getManyToManyFilterMap() {
-		return manyToManyFilters;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getRole() + ')';
-	}
-
-	public java.util.Set getSynchronizedTables() {
-		return synchronizedTables;
-	}
-
-	public String getLoaderName() {
-		return loaderName;
-	}
-
-	public void setLoaderName(String name) {
-		this.loaderName = name==null ? null : name.intern();
-	}
-
-	public String getReferencedPropertyName() {
-		return referencedPropertyName;
-	}
-
-	public void setReferencedPropertyName(String propertyRef) {
-		this.referencedPropertyName = propertyRef==null ? null : propertyRef.intern();
-	}
-
-	public boolean isOptimisticLocked() {
-		return optimisticLocked;
-	}
-
-	public void setOptimisticLocked(boolean optimisticLocked) {
-		this.optimisticLocked = optimisticLocked;
-	}
-
-	public boolean isMap() {
-		return false;
-	}
-
-	public String getTypeName() {
-		return typeName;
-	}
-
-	public void setTypeName(String typeName) {
-		this.typeName = typeName;
-	}
-
-	public Properties getTypeParameters() {
-		return typeParameters;
-	}
-
-	public void setTypeParameters(Properties parameterMap) {
-		this.typeParameters = parameterMap;
-	}
-
-	public boolean[] getColumnInsertability() {
-		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
-	}
-
-	public boolean[] getColumnUpdateability() {
-		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
-	}
-
-	public String getNodeName() {
-		return nodeName;
-	}
-
-	public void setNodeName(String nodeName) {
-		this.nodeName = nodeName;
-	}
-
-	public String getElementNodeName() {
-		return elementNodeName;
-	}
-
-	public void setElementNodeName(String elementNodeName) {
-		this.elementNodeName = elementNodeName;
-	}
-
-	public boolean isEmbedded() {
-		return embedded;
-	}
-
-	public void setEmbedded(boolean embedded) {
-		this.embedded = embedded;
-	}
-
-	public boolean isSubselectLoadable() {
-		return subselectLoadable;
-	}
-	
-
-	public void setSubselectLoadable(boolean subqueryLoadable) {
-		this.subselectLoadable = subqueryLoadable;
-	}
-
-	public boolean isMutable() {
-		return mutable;
-	}
-
-	public void setMutable(boolean mutable) {
-		this.mutable = mutable;
-	}
-
-	public boolean isExtraLazy() {
-		return extraLazy;
-	}
-
-	public void setExtraLazy(boolean extraLazy) {
-		this.extraLazy = extraLazy;
-	}
-	
-	public boolean hasOrder() {
-		return orderBy!=null || manyToManyOrderBy!=null;
-	}
-
-	public void setComparatorClassName(String comparatorClassName) {
-		this.comparatorClassName = comparatorClassName;		
-	}
-	
-	public String getComparatorClassName() {
-		return comparatorClassName;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Collection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Collection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,645 @@
+/*
+ * 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.mapping;
+
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Properties;
+
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Mapping for a collection. Subclasses specialize to particular collection styles.
+ * 
+ * @author Gavin King
+ */
+public abstract class Collection implements Fetchable, Value, Filterable {
+
+	public static final String DEFAULT_ELEMENT_COLUMN_NAME = "elt";
+	public static final String DEFAULT_KEY_COLUMN_NAME = "id";
+
+	private KeyValue key;
+	private Value element;
+	private Table collectionTable;
+	private String role;
+	private boolean lazy;
+	private boolean extraLazy;
+	private boolean inverse;
+	private boolean mutable = true;
+	private boolean subselectLoadable;
+	private String cacheConcurrencyStrategy;
+	private String cacheRegionName;
+	private String orderBy;
+	private String where;
+	private String manyToManyWhere;
+	private String manyToManyOrderBy;
+	private PersistentClass owner;
+	private String referencedPropertyName;
+	private String nodeName;
+	private String elementNodeName;
+	private boolean sorted;
+	private Comparator comparator;
+	private String comparatorClassName;
+	private boolean orphanDelete;
+	private int batchSize = -1;
+	private FetchMode fetchMode;
+	private boolean embedded = true;
+	private boolean optimisticLocked = true;
+	private Class collectionPersisterClass;
+	private String typeName;
+	private Properties typeParameters;
+	private final java.util.Map filters = new HashMap();
+	private final java.util.Map manyToManyFilters = new HashMap();
+	private final java.util.Set synchronizedTables = new HashSet();
+
+	private String customSQLInsert;
+	private boolean customInsertCallable;
+	private ExecuteUpdateResultCheckStyle insertCheckStyle;
+	private String customSQLUpdate;
+	private boolean customUpdateCallable;
+	private ExecuteUpdateResultCheckStyle updateCheckStyle;
+	private String customSQLDelete;
+	private boolean customDeleteCallable;
+	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
+	private String customSQLDeleteAll;
+	private boolean customDeleteAllCallable;
+	private ExecuteUpdateResultCheckStyle deleteAllCheckStyle;
+
+	private String loaderName;
+
+	protected Collection(PersistentClass owner) {
+		this.owner = owner;
+	}
+
+	public boolean isSet() {
+		return false;
+	}
+
+	public KeyValue getKey() {
+		return key;
+	}
+
+	public Value getElement() {
+		return element;
+	}
+
+	public boolean isIndexed() {
+		return false;
+	}
+
+	public Table getCollectionTable() {
+		return collectionTable;
+	}
+
+	public void setCollectionTable(Table table) {
+		this.collectionTable = table;
+	}
+
+	public boolean isSorted() {
+		return sorted;
+	}
+
+	public Comparator getComparator() {
+		if ( comparator == null && comparatorClassName != null ) {
+			try {
+				setComparator( (Comparator) ReflectHelper.classForName( comparatorClassName ).newInstance() );
+			}
+			catch ( Exception e ) {
+				throw new MappingException(
+						"Could not instantiate comparator class [" + comparatorClassName
+						+ "] for collection " + getRole()  
+				);
+			}
+		}
+		return comparator;
+	}
+
+	public boolean isLazy() {
+		return lazy;
+	}
+
+	public void setLazy(boolean lazy) {
+		this.lazy = lazy;
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public abstract CollectionType getDefaultCollectionType() throws MappingException;
+
+	public boolean isPrimitiveArray() {
+		return false;
+	}
+
+	public boolean isArray() {
+		return false;
+	}
+
+	public boolean hasFormula() {
+		return false;
+	}
+
+	public boolean isOneToMany() {
+		return element instanceof OneToMany;
+	}
+
+	public boolean isInverse() {
+		return inverse;
+	}
+
+	public String getOwnerEntityName() {
+		return owner.getEntityName();
+	}
+
+	public String getOrderBy() {
+		return orderBy;
+	}
+
+	public void setComparator(Comparator comparator) {
+		this.comparator = comparator;
+	}
+
+	public void setElement(Value element) {
+		this.element = element;
+	}
+
+	public void setKey(KeyValue key) {
+		this.key = key;
+	}
+
+	public void setOrderBy(String orderBy) {
+		this.orderBy = orderBy;
+	}
+
+	public void setRole(String role) {
+		this.role = role==null ? null : role.intern();
+	}
+
+	public void setSorted(boolean sorted) {
+		this.sorted = sorted;
+	}
+
+	public void setInverse(boolean inverse) {
+		this.inverse = inverse;
+	}
+
+	public PersistentClass getOwner() {
+		return owner;
+	}
+
+	public void setOwner(PersistentClass owner) {
+		this.owner = owner;
+	}
+
+	public String getWhere() {
+		return where;
+	}
+
+	public void setWhere(String where) {
+		this.where = where;
+	}
+
+	public String getManyToManyWhere() {
+		return manyToManyWhere;
+	}
+
+	public void setManyToManyWhere(String manyToManyWhere) {
+		this.manyToManyWhere = manyToManyWhere;
+	}
+
+	public String getManyToManyOrdering() {
+		return manyToManyOrderBy;
+	}
+
+	public void setManyToManyOrdering(String orderFragment) {
+		this.manyToManyOrderBy = orderFragment;
+	}
+
+	public boolean isIdentified() {
+		return false;
+	}
+
+	public boolean hasOrphanDelete() {
+		return orphanDelete;
+	}
+
+	public void setOrphanDelete(boolean orphanDelete) {
+		this.orphanDelete = orphanDelete;
+	}
+
+	public int getBatchSize() {
+		return batchSize;
+	}
+
+	public void setBatchSize(int i) {
+		batchSize = i;
+	}
+
+	public FetchMode getFetchMode() {
+		return fetchMode;
+	}
+
+	public void setFetchMode(FetchMode fetchMode) {
+		this.fetchMode = fetchMode;
+	}
+
+	public void setCollectionPersisterClass(Class persister) {
+		this.collectionPersisterClass = persister;
+	}
+
+	public Class getCollectionPersisterClass() {
+		return collectionPersisterClass;
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		if ( getKey().isCascadeDeleteEnabled() && ( !isInverse() || !isOneToMany() ) ) {
+			throw new MappingException(
+				"only inverse one-to-many associations may use on-delete=\"cascade\": " 
+				+ getRole() );
+		}
+		if ( !getKey().isValid( mapping ) ) {
+			throw new MappingException(
+				"collection foreign key mapping has wrong number of columns: "
+				+ getRole()
+				+ " type: "
+				+ getKey().getType().getName() );
+		}
+		if ( !getElement().isValid( mapping ) ) {
+			throw new MappingException( 
+				"collection element mapping has wrong number of columns: "
+				+ getRole()
+				+ " type: "
+				+ getElement().getType().getName() );
+		}
+
+		checkColumnDuplication();
+		
+		if ( elementNodeName!=null && elementNodeName.startsWith("@") ) {
+			throw new MappingException("element node must not be an attribute: " + elementNodeName );
+		}
+		if ( elementNodeName!=null && elementNodeName.equals(".") ) {
+			throw new MappingException("element node must not be the parent: " + elementNodeName );
+		}
+		if ( nodeName!=null && nodeName.indexOf('@')>-1 ) {
+			throw new MappingException("collection node must not be an attribute: " + elementNodeName );
+		}
+	}
+
+	private void checkColumnDuplication(java.util.Set distinctColumns, Iterator columns)
+			throws MappingException {
+		while ( columns.hasNext() ) {
+			Selectable s = (Selectable) columns.next();
+			if ( !s.isFormula() ) {
+				Column col = (Column) s;
+				if ( !distinctColumns.add( col.getName() ) ) {
+					throw new MappingException( "Repeated column in mapping for collection: "
+						+ getRole()
+						+ " column: "
+						+ col.getName() );
+				}
+			}
+		}
+	}
+
+	private void checkColumnDuplication() throws MappingException {
+		HashSet cols = new HashSet();
+		checkColumnDuplication( cols, getKey().getColumnIterator() );
+		if ( isIndexed() ) {
+			checkColumnDuplication( cols, ( (IndexedCollection) this )
+				.getIndex()
+				.getColumnIterator() );
+		}
+		if ( isIdentified() ) {
+			checkColumnDuplication( cols, ( (IdentifierCollection) this )
+				.getIdentifier()
+				.getColumnIterator() );
+		}
+		if ( !isOneToMany() ) {
+			checkColumnDuplication( cols, getElement().getColumnIterator() );
+		}
+	}
+
+	public Iterator getColumnIterator() {
+		return EmptyIterator.INSTANCE;
+	}
+
+	public int getColumnSpan() {
+		return 0;
+	}
+
+	public Type getType() throws MappingException {
+		return getCollectionType();
+	}
+
+	public CollectionType getCollectionType() {
+		if ( typeName == null ) {
+			return getDefaultCollectionType();
+		}
+		else {
+			return TypeFactory.customCollection( typeName, typeParameters, role, referencedPropertyName, isEmbedded() );
+		}
+	}
+
+	public boolean isNullable() {
+		return true;
+	}
+
+	public boolean isAlternateUniqueKey() {
+		return false;
+	}
+
+	public Table getTable() {
+		return owner.getTable();
+	}
+
+	public void createForeignKey() {
+	}
+
+	public boolean isSimpleValue() {
+		return false;
+	}
+
+	public boolean isValid(Mapping mapping) throws MappingException {
+		return true;
+	}
+
+	private void createForeignKeys() throws MappingException {
+		// if ( !isInverse() ) { // for inverse collections, let the "other end" handle it
+		if ( referencedPropertyName == null ) {
+			getElement().createForeignKey();
+			key.createForeignKeyOfEntity( getOwner().getEntityName() );
+		}
+		// }
+	}
+
+	abstract void createPrimaryKey();
+
+	public void createAllKeys() throws MappingException {
+		createForeignKeys();
+		if ( !isInverse() ) createPrimaryKey();
+	}
+
+	public String getCacheConcurrencyStrategy() {
+		return cacheConcurrencyStrategy;
+	}
+
+	public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
+		this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName) {
+	}
+
+	public String getCacheRegionName() {
+		return cacheRegionName == null ? role : cacheRegionName;
+	}
+
+	public void setCacheRegionName(String cacheRegionName) {
+		this.cacheRegionName = cacheRegionName;
+	}
+
+
+
+	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLInsert = customSQLInsert;
+		this.customInsertCallable = callable;
+		this.insertCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLInsert() {
+		return customSQLInsert;
+	}
+
+	public boolean isCustomInsertCallable() {
+		return customInsertCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
+		return insertCheckStyle;
+	}
+
+	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLUpdate = customSQLUpdate;
+		this.customUpdateCallable = callable;
+		this.updateCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLUpdate() {
+		return customSQLUpdate;
+	}
+
+	public boolean isCustomUpdateCallable() {
+		return customUpdateCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
+		return updateCheckStyle;
+	}
+
+	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLDelete = customSQLDelete;
+		this.customDeleteCallable = callable;
+		this.deleteCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLDelete() {
+		return customSQLDelete;
+	}
+
+	public boolean isCustomDeleteCallable() {
+		return customDeleteCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
+		return deleteCheckStyle;
+	}
+
+	public void setCustomSQLDeleteAll(String customSQLDeleteAll, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLDeleteAll = customSQLDeleteAll;
+		this.customDeleteAllCallable = callable;
+		this.deleteAllCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLDeleteAll() {
+		return customSQLDeleteAll;
+	}
+
+	public boolean isCustomDeleteAllCallable() {
+		return customDeleteAllCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteAllCheckStyle() {
+		return deleteAllCheckStyle;
+	}
+
+	public void addFilter(String name, String condition) {
+		filters.put( name, condition );
+	}
+
+	public java.util.Map getFilterMap() {
+		return filters;
+	}
+
+	public void addManyToManyFilter(String name, String condition) {
+		manyToManyFilters.put( name, condition );
+	}
+
+	public java.util.Map getManyToManyFilterMap() {
+		return manyToManyFilters;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getRole() + ')';
+	}
+
+	public java.util.Set getSynchronizedTables() {
+		return synchronizedTables;
+	}
+
+	public String getLoaderName() {
+		return loaderName;
+	}
+
+	public void setLoaderName(String name) {
+		this.loaderName = name==null ? null : name.intern();
+	}
+
+	public String getReferencedPropertyName() {
+		return referencedPropertyName;
+	}
+
+	public void setReferencedPropertyName(String propertyRef) {
+		this.referencedPropertyName = propertyRef==null ? null : propertyRef.intern();
+	}
+
+	public boolean isOptimisticLocked() {
+		return optimisticLocked;
+	}
+
+	public void setOptimisticLocked(boolean optimisticLocked) {
+		this.optimisticLocked = optimisticLocked;
+	}
+
+	public boolean isMap() {
+		return false;
+	}
+
+	public String getTypeName() {
+		return typeName;
+	}
+
+	public void setTypeName(String typeName) {
+		this.typeName = typeName;
+	}
+
+	public Properties getTypeParameters() {
+		return typeParameters;
+	}
+
+	public void setTypeParameters(Properties parameterMap) {
+		this.typeParameters = parameterMap;
+	}
+
+	public boolean[] getColumnInsertability() {
+		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+	}
+
+	public boolean[] getColumnUpdateability() {
+		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+	}
+
+	public String getNodeName() {
+		return nodeName;
+	}
+
+	public void setNodeName(String nodeName) {
+		this.nodeName = nodeName;
+	}
+
+	public String getElementNodeName() {
+		return elementNodeName;
+	}
+
+	public void setElementNodeName(String elementNodeName) {
+		this.elementNodeName = elementNodeName;
+	}
+
+	public boolean isEmbedded() {
+		return embedded;
+	}
+
+	public void setEmbedded(boolean embedded) {
+		this.embedded = embedded;
+	}
+
+	public boolean isSubselectLoadable() {
+		return subselectLoadable;
+	}
+	
+
+	public void setSubselectLoadable(boolean subqueryLoadable) {
+		this.subselectLoadable = subqueryLoadable;
+	}
+
+	public boolean isMutable() {
+		return mutable;
+	}
+
+	public void setMutable(boolean mutable) {
+		this.mutable = mutable;
+	}
+
+	public boolean isExtraLazy() {
+		return extraLazy;
+	}
+
+	public void setExtraLazy(boolean extraLazy) {
+		this.extraLazy = extraLazy;
+	}
+	
+	public boolean hasOrder() {
+		return orderBy!=null || manyToManyOrderBy!=null;
+	}
+
+	public void setComparatorClassName(String comparatorClassName) {
+		this.comparatorClassName = comparatorClassName;		
+	}
+	
+	public String getComparatorClassName() {
+		return comparatorClassName;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Column.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,310 +0,0 @@
-//$Id: Column.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-import org.hibernate.engine.Mapping;
-import org.hibernate.util.StringHelper;
-
-/**
- * A column of a relational database table
- * @author Gavin King
- */
-public class Column implements Selectable, Serializable, Cloneable {
-
-	public static final int DEFAULT_LENGTH = 255;
-	public static final int DEFAULT_PRECISION = 19;
-	public static final int DEFAULT_SCALE = 2;
-
-	private int length=DEFAULT_LENGTH;
-	private int precision=DEFAULT_PRECISION;
-	private int scale=DEFAULT_SCALE;
-	private Value value;
-	private int typeIndex = 0;
-	private String name;
-	private boolean nullable=true;
-	private boolean unique=false;
-	private String sqlType;
-	private Integer sqlTypeCode;
-	private boolean quoted=false;
-	int uniqueInteger;
-	private String checkConstraint;
-	private String comment;
-	private String defaultValue;
-
-	public Column() { };
-
-	public Column(String columnName) {
-		setName(columnName);
-	}
-
-	public int getLength() {
-		return length;
-	}
-	public void setLength(int length) {
-		this.length = length;
-	}
-	public Value getValue() {
-		return value;
-	}
-	public void setValue(Value value) {
-		this.value= value;
-	}
-	public String getName() {
-		return name;
-	}
-	public void setName(String name) {
-		if (
-			name.charAt(0)=='`' ||
-			Dialect.QUOTE.indexOf( name.charAt(0) ) > -1 //TODO: deprecated, remove eventually
-		) {
-			quoted=true;
-			this.name=name.substring( 1, name.length()-1 );
-		}
-		else {
-			this.name = name;
-		}
-	}
-
-	/** returns quoted name as it would be in the mapping file. */
-	public String getQuotedName() {
-		return quoted ?
-				"`" + name + "`" :
-				name;
-	}
-
-	public String getQuotedName(Dialect d) {
-		return quoted ?
-			d.openQuote() + name + d.closeQuote() :
-			name;
-	}
-	
-	/**
-	 * For any column name, generate an alias that is unique
-	 * to that column name, and also 10 characters or less
-	 * in length.
-	 */
-	public String getAlias(Dialect dialect) {
-		String alias = name;
-		String unique = Integer.toString(uniqueInteger) + '_';
-		int lastLetter = StringHelper.lastIndexOfLetter(name);
-		if ( lastLetter == -1 ) {
-			alias = "column";
-		}
-		else if ( lastLetter < name.length()-1 ) {
-			alias = name.substring(0, lastLetter+1);
-		}
-		if ( alias.length() > dialect.getMaxAliasLength() ) {
-			alias = alias.substring( 0, dialect.getMaxAliasLength() - unique.length() );
-		}
-		boolean useRawName = name.equals(alias) && 
-			!quoted && 
-			!name.toLowerCase().equals("rowid");
-		if ( useRawName ) {
-			return alias;
-		}
-		else {
-			return alias + unique;
-		}
-	}
-	
-	/**
-	 * Generate a column alias that is unique across multiple tables
-	 */
-	public String getAlias(Dialect dialect, Table table) {
-		return getAlias(dialect) + table.getUniqueInteger() + '_';
-	}
-
-	public boolean isNullable() {
-		return nullable;
-	}
-
-	public void setNullable(boolean nullable) {
-		this.nullable=nullable;
-	}
-
-	public int getTypeIndex() {
-		return typeIndex;
-	}
-	public void setTypeIndex(int typeIndex) {
-		this.typeIndex = typeIndex;
-	}
-
-	public int getSqlTypeCode(Mapping mapping) throws MappingException {
-		org.hibernate.type.Type type = getValue().getType();
-		try {
-			int sqlTypeCode = type.sqlTypes(mapping)[ getTypeIndex() ];
-			if(getSqlTypeCode()!=null && getSqlTypeCode().intValue()!=sqlTypeCode) {
-				throw new MappingException("SQLType code's does not match. mapped as " + sqlTypeCode + " but is " + getSqlTypeCode() );
-			}
-			return sqlTypeCode;
-		}
-		catch (Exception e) {
-			throw new MappingException(
-					"Could not determine type for column " +
-					name +
-					" of type " +
-					type.getClass().getName() +
-					": " +
-					e.getClass().getName(),
-					e
-				);
-		}
-	}
-
-	/**
-	 * Returns the underlying columns sqltypecode.
-	 * If null, it is because the sqltype code is unknown.
-	 * 
-	 * Use #getSqlTypeCode(Mapping) to retreive the sqltypecode used
-	 * for the columns associated Value/Type.
-	 * 
-	 * @return sqltypecode if it is set, otherwise null.
-	 */
-	public Integer getSqlTypeCode() {
-		return sqlTypeCode;
-	}
-	
-	public void setSqlTypeCode(Integer typecode) {
-		sqlTypeCode=typecode;
-	}
-	
-	public boolean isUnique() {
-		return unique;
-	}
-
-
-	public String getSqlType(Dialect dialect, Mapping mapping) throws HibernateException {
-		return sqlType==null ?
-			dialect.getTypeName( getSqlTypeCode(mapping), getLength(), getPrecision(), getScale() ) :
-			sqlType;
-	}
-
-	public boolean equals(Object object) {
-		return object instanceof Column && equals( (Column) object );
-	}
-
-	public boolean equals(Column column) {
-		if (null == column) return false;
-		if (this == column) return true;
-
-		return isQuoted() ? 
-			name.equals(column.name) :
-			name.equalsIgnoreCase(column.name);
-	}
-
-	//used also for generation of FK names!
-	public int hashCode() {
-		return isQuoted() ? 
-			name.hashCode() : 
-			name.toLowerCase().hashCode();
-	}
-
-	public String getSqlType() {
-		return sqlType;
-	}
-
-	public void setSqlType(String sqlType) {
-		this.sqlType = sqlType;
-	}
-
-	public void setUnique(boolean unique) {
-		this.unique = unique;
-	}
-
-	public boolean isQuoted() {
-		return quoted;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getName() + ')';
-	}
-
-	public String getCheckConstraint() {
-		return checkConstraint;
-	}
-
-	public void setCheckConstraint(String checkConstraint) {
-		this.checkConstraint = checkConstraint;
-	}
-
-	public boolean hasCheckConstraint() {
-		return checkConstraint!=null;
-	}
-
-	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		return getQuotedName(dialect);
-	}
-
-	public boolean isFormula() {
-		return false;
-	}
-
-	public String getText(Dialect d) {
-		return getQuotedName(d);
-	}
-	public String getText() {
-		return getName();
-	}
-	
-	public int getPrecision() {
-		return precision;
-	}
-	public void setPrecision(int scale) {
-		this.precision = scale;
-	}
-
-	public int getScale() {
-		return scale;
-	}
-	public void setScale(int scale) {
-		this.scale = scale;
-	}
-
-	public String getComment() {
-		return comment;
-	}
-
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-
-	public String getDefaultValue() {
-		return defaultValue;
-	}
-
-	public void setDefaultValue(String defaultValue) {
-		this.defaultValue = defaultValue;
-	}
-
-	public String getCanonicalName() {
-		return quoted ? name : name.toLowerCase();
-	}
-
-	/**
-	 * Shallow copy, the value is not copied
-	 */
-	protected Object clone() {
-		Column copy = new Column();
-		copy.setLength( length );
-		copy.setScale( scale );
-		copy.setValue( value );
-		copy.setTypeIndex( typeIndex );
-		copy.setName( getQuotedName() );
-		copy.setNullable( nullable );
-		copy.setPrecision( precision );
-		copy.setUnique( unique );
-		copy.setSqlType( sqlType );
-		copy.setSqlTypeCode( sqlTypeCode );
-		copy.uniqueInteger = uniqueInteger; //usually useless
-		copy.setCheckConstraint( checkConstraint );
-		copy.setComment( comment );
-		copy.setDefaultValue( defaultValue );
-		return copy;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Column.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Column.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,333 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+import org.hibernate.engine.Mapping;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A column of a relational database table
+ * @author Gavin King
+ */
+public class Column implements Selectable, Serializable, Cloneable {
+
+	public static final int DEFAULT_LENGTH = 255;
+	public static final int DEFAULT_PRECISION = 19;
+	public static final int DEFAULT_SCALE = 2;
+
+	private int length=DEFAULT_LENGTH;
+	private int precision=DEFAULT_PRECISION;
+	private int scale=DEFAULT_SCALE;
+	private Value value;
+	private int typeIndex = 0;
+	private String name;
+	private boolean nullable=true;
+	private boolean unique=false;
+	private String sqlType;
+	private Integer sqlTypeCode;
+	private boolean quoted=false;
+	int uniqueInteger;
+	private String checkConstraint;
+	private String comment;
+	private String defaultValue;
+
+	public Column() { };
+
+	public Column(String columnName) {
+		setName(columnName);
+	}
+
+	public int getLength() {
+		return length;
+	}
+	public void setLength(int length) {
+		this.length = length;
+	}
+	public Value getValue() {
+		return value;
+	}
+	public void setValue(Value value) {
+		this.value= value;
+	}
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		if (
+			name.charAt(0)=='`' ||
+			Dialect.QUOTE.indexOf( name.charAt(0) ) > -1 //TODO: deprecated, remove eventually
+		) {
+			quoted=true;
+			this.name=name.substring( 1, name.length()-1 );
+		}
+		else {
+			this.name = name;
+		}
+	}
+
+	/** returns quoted name as it would be in the mapping file. */
+	public String getQuotedName() {
+		return quoted ?
+				"`" + name + "`" :
+				name;
+	}
+
+	public String getQuotedName(Dialect d) {
+		return quoted ?
+			d.openQuote() + name + d.closeQuote() :
+			name;
+	}
+	
+	/**
+	 * For any column name, generate an alias that is unique
+	 * to that column name, and also 10 characters or less
+	 * in length.
+	 */
+	public String getAlias(Dialect dialect) {
+		String alias = name;
+		String unique = Integer.toString(uniqueInteger) + '_';
+		int lastLetter = StringHelper.lastIndexOfLetter(name);
+		if ( lastLetter == -1 ) {
+			alias = "column";
+		}
+		else if ( lastLetter < name.length()-1 ) {
+			alias = name.substring(0, lastLetter+1);
+		}
+		if ( alias.length() > dialect.getMaxAliasLength() ) {
+			alias = alias.substring( 0, dialect.getMaxAliasLength() - unique.length() );
+		}
+		boolean useRawName = name.equals(alias) && 
+			!quoted && 
+			!name.toLowerCase().equals("rowid");
+		if ( useRawName ) {
+			return alias;
+		}
+		else {
+			return alias + unique;
+		}
+	}
+	
+	/**
+	 * Generate a column alias that is unique across multiple tables
+	 */
+	public String getAlias(Dialect dialect, Table table) {
+		return getAlias(dialect) + table.getUniqueInteger() + '_';
+	}
+
+	public boolean isNullable() {
+		return nullable;
+	}
+
+	public void setNullable(boolean nullable) {
+		this.nullable=nullable;
+	}
+
+	public int getTypeIndex() {
+		return typeIndex;
+	}
+	public void setTypeIndex(int typeIndex) {
+		this.typeIndex = typeIndex;
+	}
+
+	public int getSqlTypeCode(Mapping mapping) throws MappingException {
+		org.hibernate.type.Type type = getValue().getType();
+		try {
+			int sqlTypeCode = type.sqlTypes(mapping)[ getTypeIndex() ];
+			if(getSqlTypeCode()!=null && getSqlTypeCode().intValue()!=sqlTypeCode) {
+				throw new MappingException("SQLType code's does not match. mapped as " + sqlTypeCode + " but is " + getSqlTypeCode() );
+			}
+			return sqlTypeCode;
+		}
+		catch (Exception e) {
+			throw new MappingException(
+					"Could not determine type for column " +
+					name +
+					" of type " +
+					type.getClass().getName() +
+					": " +
+					e.getClass().getName(),
+					e
+				);
+		}
+	}
+
+	/**
+	 * Returns the underlying columns sqltypecode.
+	 * If null, it is because the sqltype code is unknown.
+	 * 
+	 * Use #getSqlTypeCode(Mapping) to retreive the sqltypecode used
+	 * for the columns associated Value/Type.
+	 * 
+	 * @return sqltypecode if it is set, otherwise null.
+	 */
+	public Integer getSqlTypeCode() {
+		return sqlTypeCode;
+	}
+	
+	public void setSqlTypeCode(Integer typecode) {
+		sqlTypeCode=typecode;
+	}
+	
+	public boolean isUnique() {
+		return unique;
+	}
+
+
+	public String getSqlType(Dialect dialect, Mapping mapping) throws HibernateException {
+		return sqlType==null ?
+			dialect.getTypeName( getSqlTypeCode(mapping), getLength(), getPrecision(), getScale() ) :
+			sqlType;
+	}
+
+	public boolean equals(Object object) {
+		return object instanceof Column && equals( (Column) object );
+	}
+
+	public boolean equals(Column column) {
+		if (null == column) return false;
+		if (this == column) return true;
+
+		return isQuoted() ? 
+			name.equals(column.name) :
+			name.equalsIgnoreCase(column.name);
+	}
+
+	//used also for generation of FK names!
+	public int hashCode() {
+		return isQuoted() ? 
+			name.hashCode() : 
+			name.toLowerCase().hashCode();
+	}
+
+	public String getSqlType() {
+		return sqlType;
+	}
+
+	public void setSqlType(String sqlType) {
+		this.sqlType = sqlType;
+	}
+
+	public void setUnique(boolean unique) {
+		this.unique = unique;
+	}
+
+	public boolean isQuoted() {
+		return quoted;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getName() + ')';
+	}
+
+	public String getCheckConstraint() {
+		return checkConstraint;
+	}
+
+	public void setCheckConstraint(String checkConstraint) {
+		this.checkConstraint = checkConstraint;
+	}
+
+	public boolean hasCheckConstraint() {
+		return checkConstraint!=null;
+	}
+
+	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		return getQuotedName(dialect);
+	}
+
+	public boolean isFormula() {
+		return false;
+	}
+
+	public String getText(Dialect d) {
+		return getQuotedName(d);
+	}
+	public String getText() {
+		return getName();
+	}
+	
+	public int getPrecision() {
+		return precision;
+	}
+	public void setPrecision(int scale) {
+		this.precision = scale;
+	}
+
+	public int getScale() {
+		return scale;
+	}
+	public void setScale(int scale) {
+		this.scale = scale;
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public String getDefaultValue() {
+		return defaultValue;
+	}
+
+	public void setDefaultValue(String defaultValue) {
+		this.defaultValue = defaultValue;
+	}
+
+	public String getCanonicalName() {
+		return quoted ? name : name.toLowerCase();
+	}
+
+	/**
+	 * Shallow copy, the value is not copied
+	 */
+	protected Object clone() {
+		Column copy = new Column();
+		copy.setLength( length );
+		copy.setScale( scale );
+		copy.setValue( value );
+		copy.setTypeIndex( typeIndex );
+		copy.setName( getQuotedName() );
+		copy.setNullable( nullable );
+		copy.setPrecision( precision );
+		copy.setUnique( unique );
+		copy.setSqlType( sqlType );
+		copy.setSqlTypeCode( sqlTypeCode );
+		copy.uniqueInteger = uniqueInteger; //usually useless
+		copy.setCheckConstraint( checkConstraint );
+		copy.setComment( comment );
+		copy.setDefaultValue( defaultValue );
+		return copy;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Component.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,275 +0,0 @@
-//$Id: Component.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.MappingException;
-import org.hibernate.tuple.component.ComponentMetamodel;
-import org.hibernate.type.ComponentType;
-import org.hibernate.type.EmbeddedComponentType;
-import org.hibernate.type.Type;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * The mapping for a component, composite element,
- * composite identifier, etc.
- * @author Gavin King
- */
-public class Component extends SimpleValue implements MetaAttributable {
-
-	private ArrayList properties = new ArrayList();
-	private String componentClassName;
-	private boolean embedded;
-	private String parentProperty;
-	private PersistentClass owner;
-	private boolean dynamic;
-	private Map metaAttributes;
-	private String nodeName;
-	private boolean isKey;
-	private String roleName;
-
-	private java.util.Map tuplizerImpls;
-
-	public Component(PersistentClass owner) throws MappingException {
-		super( owner.getTable() );
-		this.owner = owner;
-	}
-
-	public Component(Component component) throws MappingException {
-		super( component.getTable() );
-		this.owner = component.getOwner();
-	}
-
-	public Component(Join join) throws MappingException {
-		super( join.getTable() );
-		this.owner = join.getPersistentClass();
-	}
-
-	public Component(Collection collection) throws MappingException {
-		super( collection.getCollectionTable() );
-		this.owner = collection.getOwner();
-	}
-
-	public int getPropertySpan() {
-		return properties.size();
-	}
-	public Iterator getPropertyIterator() {
-		return properties.iterator();
-	}
-	public void addProperty(Property p) {
-		properties.add(p);
-	}
-	public void addColumn(Column column) {
-		throw new UnsupportedOperationException("Cant add a column to a component");
-	}
-	public int getColumnSpan() {
-		int n=0;
-		Iterator iter = getPropertyIterator();
-		while ( iter.hasNext() ) {
-			Property p = (Property) iter.next();
-			n+= p.getColumnSpan();
-		}
-		return n;
-	}
-	public Iterator getColumnIterator() {
-		Iterator[] iters = new Iterator[ getPropertySpan() ];
-		Iterator iter = getPropertyIterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			iters[i++] = ( (Property) iter.next() ).getColumnIterator();
-		}
-		return new JoinedIterator(iters);
-	}
-
-	public void setTypeByReflection(String propertyClass, String propertyName) {}
-
-	public boolean isEmbedded() {
-		return embedded;
-	}
-
-	public String getComponentClassName() {
-		return componentClassName;
-	}
-
-	public Class getComponentClass() throws MappingException {
-		try {
-			return ReflectHelper.classForName(componentClassName);
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new MappingException("component class not found: " + componentClassName, cnfe);
-		}
-	}
-
-	public PersistentClass getOwner() {
-		return owner;
-	}
-
-	public String getParentProperty() {
-		return parentProperty;
-	}
-
-	public void setComponentClassName(String componentClass) {
-		this.componentClassName = componentClass;
-	}
-
-	public void setEmbedded(boolean embedded) {
-		this.embedded = embedded;
-	}
-
-	public void setOwner(PersistentClass owner) {
-		this.owner = owner;
-	}
-
-	public void setParentProperty(String parentProperty) {
-		this.parentProperty = parentProperty;
-	}
-
-	public boolean isDynamic() {
-		return dynamic;
-	}
-
-	public void setDynamic(boolean dynamic) {
-		this.dynamic = dynamic;
-	}
-
-	private Type type;
-
-	public Type getType() throws MappingException {
-		// added this caching as I noticed that getType() is being called multiple times...
-		if ( type == null ) {
-			type = buildType();
-		}
-		return type;
-	}
-
-	private Type buildType() {
-		// TODO : temporary initial step towards HHH-1907
-		ComponentMetamodel metamodel = new ComponentMetamodel( this );
-		if ( isEmbedded() ) {
-			return new EmbeddedComponentType( metamodel );
-		}
-		else {
-			return new ComponentType( metamodel );
-		}
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName)
-		throws MappingException {
-	}
-	
-	public java.util.Map getMetaAttributes() {
-		return metaAttributes;
-	}
-	public MetaAttribute getMetaAttribute(String attributeName) {
-		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
-	}
-
-	public void setMetaAttributes(java.util.Map metas) {
-		this.metaAttributes = metas;
-	}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-	
-	public boolean[] getColumnInsertability() {
-		boolean[] result = new boolean[ getColumnSpan() ];
-		Iterator iter = getPropertyIterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			boolean[] chunk = prop.getValue().getColumnInsertability();
-			if ( prop.isInsertable() ) {
-				System.arraycopy(chunk, 0, result, i, chunk.length);
-			}
-			i+=chunk.length;
-		}
-		return result;
-	}
-
-	public boolean[] getColumnUpdateability() {
-		boolean[] result = new boolean[ getColumnSpan() ];
-		Iterator iter = getPropertyIterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			boolean[] chunk = prop.getValue().getColumnUpdateability();
-			if ( prop.isUpdateable() ) {
-				System.arraycopy(chunk, 0, result, i, chunk.length);
-			}
-			i+=chunk.length;
-		}
-		return result;
-	}
-	
-	public String getNodeName() {
-		return nodeName;
-	}
-	
-	public void setNodeName(String nodeName) {
-		this.nodeName = nodeName;
-	}
-	
-	public boolean isKey() {
-		return isKey;
-	}
-	
-	public void setKey(boolean isKey) {
-		this.isKey = isKey;
-	}
-	
-	public boolean hasPojoRepresentation() {
-		return componentClassName!=null;
-	}
-
-	public void addTuplizer(EntityMode entityMode, String implClassName) {
-		if ( tuplizerImpls == null ) {
-			tuplizerImpls = new HashMap();
-		}
-		tuplizerImpls.put( entityMode, implClassName );
-	}
-
-	public String getTuplizerImplClassName(EntityMode mode) {
-		// todo : remove this once ComponentMetamodel is complete and merged
-		if ( tuplizerImpls == null ) {
-			return null;
-		}
-		return ( String ) tuplizerImpls.get( mode );
-	}
-
-	public Map getTuplizerMap() {
-		if ( tuplizerImpls == null ) {
-			return null;
-		}
-		return java.util.Collections.unmodifiableMap( tuplizerImpls );
-	}
-
-	public Property getProperty(String propertyName) throws MappingException {
-		Iterator iter = getPropertyIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			if ( prop.getName().equals(propertyName) ) {
-				return prop;
-			}
-		}
-		throw new MappingException("component property not found: " + propertyName);
-	}
-
-	public String getRoleName() {
-		return roleName;
-	}
-
-	public void setRoleName(String roleName) {
-		this.roleName = roleName;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + properties.toString() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Component.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Component.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,298 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.MappingException;
+import org.hibernate.tuple.component.ComponentMetamodel;
+import org.hibernate.type.ComponentType;
+import org.hibernate.type.EmbeddedComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * The mapping for a component, composite element,
+ * composite identifier, etc.
+ * @author Gavin King
+ */
+public class Component extends SimpleValue implements MetaAttributable {
+
+	private ArrayList properties = new ArrayList();
+	private String componentClassName;
+	private boolean embedded;
+	private String parentProperty;
+	private PersistentClass owner;
+	private boolean dynamic;
+	private Map metaAttributes;
+	private String nodeName;
+	private boolean isKey;
+	private String roleName;
+
+	private java.util.Map tuplizerImpls;
+
+	public Component(PersistentClass owner) throws MappingException {
+		super( owner.getTable() );
+		this.owner = owner;
+	}
+
+	public Component(Component component) throws MappingException {
+		super( component.getTable() );
+		this.owner = component.getOwner();
+	}
+
+	public Component(Join join) throws MappingException {
+		super( join.getTable() );
+		this.owner = join.getPersistentClass();
+	}
+
+	public Component(Collection collection) throws MappingException {
+		super( collection.getCollectionTable() );
+		this.owner = collection.getOwner();
+	}
+
+	public int getPropertySpan() {
+		return properties.size();
+	}
+	public Iterator getPropertyIterator() {
+		return properties.iterator();
+	}
+	public void addProperty(Property p) {
+		properties.add(p);
+	}
+	public void addColumn(Column column) {
+		throw new UnsupportedOperationException("Cant add a column to a component");
+	}
+	public int getColumnSpan() {
+		int n=0;
+		Iterator iter = getPropertyIterator();
+		while ( iter.hasNext() ) {
+			Property p = (Property) iter.next();
+			n+= p.getColumnSpan();
+		}
+		return n;
+	}
+	public Iterator getColumnIterator() {
+		Iterator[] iters = new Iterator[ getPropertySpan() ];
+		Iterator iter = getPropertyIterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			iters[i++] = ( (Property) iter.next() ).getColumnIterator();
+		}
+		return new JoinedIterator(iters);
+	}
+
+	public void setTypeByReflection(String propertyClass, String propertyName) {}
+
+	public boolean isEmbedded() {
+		return embedded;
+	}
+
+	public String getComponentClassName() {
+		return componentClassName;
+	}
+
+	public Class getComponentClass() throws MappingException {
+		try {
+			return ReflectHelper.classForName(componentClassName);
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new MappingException("component class not found: " + componentClassName, cnfe);
+		}
+	}
+
+	public PersistentClass getOwner() {
+		return owner;
+	}
+
+	public String getParentProperty() {
+		return parentProperty;
+	}
+
+	public void setComponentClassName(String componentClass) {
+		this.componentClassName = componentClass;
+	}
+
+	public void setEmbedded(boolean embedded) {
+		this.embedded = embedded;
+	}
+
+	public void setOwner(PersistentClass owner) {
+		this.owner = owner;
+	}
+
+	public void setParentProperty(String parentProperty) {
+		this.parentProperty = parentProperty;
+	}
+
+	public boolean isDynamic() {
+		return dynamic;
+	}
+
+	public void setDynamic(boolean dynamic) {
+		this.dynamic = dynamic;
+	}
+
+	private Type type;
+
+	public Type getType() throws MappingException {
+		// added this caching as I noticed that getType() is being called multiple times...
+		if ( type == null ) {
+			type = buildType();
+		}
+		return type;
+	}
+
+	private Type buildType() {
+		// TODO : temporary initial step towards HHH-1907
+		ComponentMetamodel metamodel = new ComponentMetamodel( this );
+		if ( isEmbedded() ) {
+			return new EmbeddedComponentType( metamodel );
+		}
+		else {
+			return new ComponentType( metamodel );
+		}
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName)
+		throws MappingException {
+	}
+	
+	public java.util.Map getMetaAttributes() {
+		return metaAttributes;
+	}
+	public MetaAttribute getMetaAttribute(String attributeName) {
+		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
+	}
+
+	public void setMetaAttributes(java.util.Map metas) {
+		this.metaAttributes = metas;
+	}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+	
+	public boolean[] getColumnInsertability() {
+		boolean[] result = new boolean[ getColumnSpan() ];
+		Iterator iter = getPropertyIterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			boolean[] chunk = prop.getValue().getColumnInsertability();
+			if ( prop.isInsertable() ) {
+				System.arraycopy(chunk, 0, result, i, chunk.length);
+			}
+			i+=chunk.length;
+		}
+		return result;
+	}
+
+	public boolean[] getColumnUpdateability() {
+		boolean[] result = new boolean[ getColumnSpan() ];
+		Iterator iter = getPropertyIterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			boolean[] chunk = prop.getValue().getColumnUpdateability();
+			if ( prop.isUpdateable() ) {
+				System.arraycopy(chunk, 0, result, i, chunk.length);
+			}
+			i+=chunk.length;
+		}
+		return result;
+	}
+	
+	public String getNodeName() {
+		return nodeName;
+	}
+	
+	public void setNodeName(String nodeName) {
+		this.nodeName = nodeName;
+	}
+	
+	public boolean isKey() {
+		return isKey;
+	}
+	
+	public void setKey(boolean isKey) {
+		this.isKey = isKey;
+	}
+	
+	public boolean hasPojoRepresentation() {
+		return componentClassName!=null;
+	}
+
+	public void addTuplizer(EntityMode entityMode, String implClassName) {
+		if ( tuplizerImpls == null ) {
+			tuplizerImpls = new HashMap();
+		}
+		tuplizerImpls.put( entityMode, implClassName );
+	}
+
+	public String getTuplizerImplClassName(EntityMode mode) {
+		// todo : remove this once ComponentMetamodel is complete and merged
+		if ( tuplizerImpls == null ) {
+			return null;
+		}
+		return ( String ) tuplizerImpls.get( mode );
+	}
+
+	public Map getTuplizerMap() {
+		if ( tuplizerImpls == null ) {
+			return null;
+		}
+		return java.util.Collections.unmodifiableMap( tuplizerImpls );
+	}
+
+	public Property getProperty(String propertyName) throws MappingException {
+		Iterator iter = getPropertyIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			if ( prop.getName().equals(propertyName) ) {
+				return prop;
+			}
+		}
+		throw new MappingException("component property not found: " + propertyName);
+	}
+
+	public String getRoleName() {
+		return roleName;
+	}
+
+	public void setRoleName(String roleName) {
+		this.roleName = roleName;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + properties.toString() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,111 +0,0 @@
-//$Id: Constraint.java 10661 2006-10-31 02:19:13Z epbernard $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-
-/**
- * A relational constraint.
- *
- * @author Gavin King
- */
-public abstract class Constraint implements RelationalModel, Serializable {
-
-	private String name;
-	private final List columns = new ArrayList();
-	private Table table;
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public Iterator getColumnIterator() {
-		return columns.iterator();
-	}
-
-	public void addColumn(Column column) {
-		if ( !columns.contains( column ) ) columns.add( column );
-	}
-
-	public void addColumns(Iterator columnIterator) {
-		while ( columnIterator.hasNext() ) {
-			Selectable col = (Selectable) columnIterator.next();
-			if ( !col.isFormula() ) addColumn( (Column) col );
-		}
-	}
-
-	/**
-	 * @param column
-	 * @return true if this constraint already contains a column with same name.
-	 */
-	public boolean containsColumn(Column column) {
-		return columns.contains( column );
-	}
-
-	public int getColumnSpan() {
-		return columns.size();
-	}
-
-	public Column getColumn(int i) {
-		return (Column) columns.get( i );
-	}
-
-	public Iterator columnIterator() {
-		return columns.iterator();
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	public void setTable(Table table) {
-		this.table = table;
-	}
-
-	public boolean isGenerated(Dialect dialect) {
-		return true;
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		if ( isGenerated( dialect ) ) {
-			return "alter table " + getTable()
-					.getQualifiedName( dialect, defaultCatalog, defaultSchema ) + " drop constraint " + getName();
-		}
-		else {
-			return null;
-		}
-	}
-
-	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
-		if ( isGenerated( dialect ) ) {
-			String constraintString = sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema );
-			StringBuffer buf = new StringBuffer( "alter table " )
-					.append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
-					.append( constraintString );
-			return buf.toString();
-		}
-		else {
-			return null;
-		}
-	}
-
-	public List getColumns() {
-		return columns;
-	}
-
-	public abstract String sqlConstraintString(Dialect d, String constraintName, String defaultCatalog,
-											   String defaultSchema);
-
-	public String toString() {
-		return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Constraint.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Constraint.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+
+/**
+ * A relational constraint.
+ *
+ * @author Gavin King
+ */
+public abstract class Constraint implements RelationalModel, Serializable {
+
+	private String name;
+	private final List columns = new ArrayList();
+	private Table table;
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Iterator getColumnIterator() {
+		return columns.iterator();
+	}
+
+	public void addColumn(Column column) {
+		if ( !columns.contains( column ) ) columns.add( column );
+	}
+
+	public void addColumns(Iterator columnIterator) {
+		while ( columnIterator.hasNext() ) {
+			Selectable col = (Selectable) columnIterator.next();
+			if ( !col.isFormula() ) addColumn( (Column) col );
+		}
+	}
+
+	/**
+	 * @param column
+	 * @return true if this constraint already contains a column with same name.
+	 */
+	public boolean containsColumn(Column column) {
+		return columns.contains( column );
+	}
+
+	public int getColumnSpan() {
+		return columns.size();
+	}
+
+	public Column getColumn(int i) {
+		return (Column) columns.get( i );
+	}
+
+	public Iterator columnIterator() {
+		return columns.iterator();
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	public void setTable(Table table) {
+		this.table = table;
+	}
+
+	public boolean isGenerated(Dialect dialect) {
+		return true;
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		if ( isGenerated( dialect ) ) {
+			return "alter table " + getTable()
+					.getQualifiedName( dialect, defaultCatalog, defaultSchema ) + " drop constraint " + getName();
+		}
+		else {
+			return null;
+		}
+	}
+
+	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
+		if ( isGenerated( dialect ) ) {
+			String constraintString = sqlConstraintString( dialect, getName(), defaultCatalog, defaultSchema );
+			StringBuffer buf = new StringBuffer( "alter table " )
+					.append( getTable().getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+					.append( constraintString );
+			return buf.toString();
+		}
+		else {
+			return null;
+		}
+	}
+
+	public List getColumns() {
+		return columns;
+	}
+
+	public abstract String sqlConstraintString(Dialect d, String constraintName, String defaultCatalog,
+											   String defaultSchema);
+
+	public String toString() {
+		return getClass().getName() + '(' + getTable().getName() + getColumns() + ") as " + name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,90 +0,0 @@
-//$Id: DenormalizedTable.java 10880 2006-11-29 15:18:34Z epbernard $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.util.JoinedIterator;
-
-/**
- * @author Gavin King
- */
-public class DenormalizedTable extends Table {
-	
-	private final Table includedTable;
-	
-	public DenormalizedTable(Table includedTable) {
-		this.includedTable = includedTable;
-		includedTable.setHasDenormalizedTables();
-	}
-	
-	public void createForeignKeys() {
-		includedTable.createForeignKeys();
-		Iterator iter = includedTable.getForeignKeyIterator();
-		while ( iter.hasNext() ) {
-			ForeignKey fk = (ForeignKey) iter.next();
-			createForeignKey( 
-					fk.getName() + Integer.toHexString( getName().hashCode() ), 
-					fk.getColumns(), 
-					fk.getReferencedEntityName() 
-				);
-		}
-	}
-
-	public Column getColumn(Column column) {
-		Column superColumn = super.getColumn( column );
-		if (superColumn != null) {
-			return superColumn;
-		}
-		else {
-			return includedTable.getColumn( column );
-		}
-	}
-
-	public Iterator getColumnIterator() {
-		return new JoinedIterator(
-				includedTable.getColumnIterator(),
-				super.getColumnIterator()
-			);
-	}
-
-	public boolean containsColumn(Column column) {
-		return super.containsColumn(column) || includedTable.containsColumn(column);
-	}
-
-	public PrimaryKey getPrimaryKey() {
-		return includedTable.getPrimaryKey();
-	}
-
-	public Iterator getUniqueKeyIterator() {
-		//wierd implementation because of hacky behavior
-		//of Table.sqlCreateString() which modifies the
-		//list of unique keys by side-effect on some
-		//dialects
-		Map uks = new HashMap();
-		uks.putAll( getUniqueKeys() );
-		uks.putAll( includedTable.getUniqueKeys() );
-		return uks.values().iterator();
-	}
-
-	public Iterator getIndexIterator() {
-		List indexes = new ArrayList();
-		Iterator iter = includedTable.getIndexIterator();
-		while ( iter.hasNext() ) {
-			Index parentIndex = (Index) iter.next();
-			Index index = new Index();
-			index.setName( getName() + parentIndex.getName() );
-			index.setTable(this);
-			index.addColumns( parentIndex.getColumnIterator() );
-			indexes.add( index );
-		}
-		return new JoinedIterator(
-				indexes.iterator(),
-				super.getIndexIterator()
-			);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DenormalizedTable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.util.JoinedIterator;
+
+/**
+ * @author Gavin King
+ */
+public class DenormalizedTable extends Table {
+	
+	private final Table includedTable;
+	
+	public DenormalizedTable(Table includedTable) {
+		this.includedTable = includedTable;
+		includedTable.setHasDenormalizedTables();
+	}
+	
+	public void createForeignKeys() {
+		includedTable.createForeignKeys();
+		Iterator iter = includedTable.getForeignKeyIterator();
+		while ( iter.hasNext() ) {
+			ForeignKey fk = (ForeignKey) iter.next();
+			createForeignKey( 
+					fk.getName() + Integer.toHexString( getName().hashCode() ), 
+					fk.getColumns(), 
+					fk.getReferencedEntityName() 
+				);
+		}
+	}
+
+	public Column getColumn(Column column) {
+		Column superColumn = super.getColumn( column );
+		if (superColumn != null) {
+			return superColumn;
+		}
+		else {
+			return includedTable.getColumn( column );
+		}
+	}
+
+	public Iterator getColumnIterator() {
+		return new JoinedIterator(
+				includedTable.getColumnIterator(),
+				super.getColumnIterator()
+			);
+	}
+
+	public boolean containsColumn(Column column) {
+		return super.containsColumn(column) || includedTable.containsColumn(column);
+	}
+
+	public PrimaryKey getPrimaryKey() {
+		return includedTable.getPrimaryKey();
+	}
+
+	public Iterator getUniqueKeyIterator() {
+		//wierd implementation because of hacky behavior
+		//of Table.sqlCreateString() which modifies the
+		//list of unique keys by side-effect on some
+		//dialects
+		Map uks = new HashMap();
+		uks.putAll( getUniqueKeys() );
+		uks.putAll( includedTable.getUniqueKeys() );
+		return uks.values().iterator();
+	}
+
+	public Iterator getIndexIterator() {
+		List indexes = new ArrayList();
+		Iterator iter = includedTable.getIndexIterator();
+		while ( iter.hasNext() ) {
+			Index parentIndex = (Index) iter.next();
+			Index index = new Index();
+			index.setName( getName() + parentIndex.getName() );
+			index.setTable(this);
+			index.addColumns( parentIndex.getColumnIterator() );
+			indexes.add( index );
+		}
+		return new JoinedIterator(
+				indexes.iterator(),
+				super.getIndexIterator()
+			);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/DependantValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: DependantValue.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.Type;
-
-/**
- * A value which is "typed" by reference to some other
- * value (for example, a foreign key is typed by the
- * referenced primary key).
- *
- * @author Gavin King
- */
-public class DependantValue extends SimpleValue {
-	private KeyValue wrappedValue;
-	private boolean nullable;
-	private boolean updateable;
-
-	public DependantValue(Table table, KeyValue prototype) {
-		super(table);
-		this.wrappedValue = prototype;
-	}
-
-	public Type getType() throws MappingException {
-		return wrappedValue.getType();
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName) {}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-
-	public boolean isNullable() {
-		return nullable;
-	
-	}
-	
-	public void setNullable(boolean nullable) {
-		this.nullable = nullable;
-	}
-	
-	public boolean isUpdateable() {
-		return updateable;
-	}
-	
-	public void setUpdateable(boolean updateable) {
-		this.updateable = updateable;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/DependantValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/DependantValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.Type;
+
+/**
+ * A value which is "typed" by reference to some other
+ * value (for example, a foreign key is typed by the
+ * referenced primary key).
+ *
+ * @author Gavin King
+ */
+public class DependantValue extends SimpleValue {
+	private KeyValue wrappedValue;
+	private boolean nullable;
+	private boolean updateable;
+
+	public DependantValue(Table table, KeyValue prototype) {
+		super(table);
+		this.wrappedValue = prototype;
+	}
+
+	public Type getType() throws MappingException {
+		return wrappedValue.getType();
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName) {}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+
+	public boolean isNullable() {
+		return nullable;
+	
+	}
+	
+	public void setNullable(boolean nullable) {
+		this.nullable = nullable;
+	}
+	
+	public boolean isUpdateable() {
+		return updateable;
+	}
+	
+	public void setUpdateable(boolean updateable) {
+		this.updateable = updateable;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Fetchable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: Fetchable.java 6586 2005-04-28 08:35:10Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.FetchMode;
-
-/**
- * Any mapping with an outer-join attribute
- * @author Gavin King
- */
-public interface Fetchable {
-	public FetchMode getFetchMode();
-	public void setFetchMode(FetchMode joinedFetch);
-	public boolean isLazy();
-	public void setLazy(boolean lazy);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Fetchable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Fetchable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.FetchMode;
+
+/**
+ * Any mapping with an outer-join attribute
+ * @author Gavin King
+ */
+public interface Fetchable {
+	public FetchMode getFetchMode();
+	public void setFetchMode(FetchMode joinedFetch);
+	public boolean isLazy();
+	public void setLazy(boolean lazy);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Filterable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-// $Id: Filterable.java 4219 2004-08-10 05:11:47Z steveebersole $
-package org.hibernate.mapping;
-
-/**
- * Defines mapping elements to which filters may be applied.
- *
- * @author Steve Ebersole
- */
-public interface Filterable {
-	public void addFilter(String name, String condition);
-
-	public java.util.Map getFilterMap();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Filterable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Filterable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+/**
+ * Defines mapping elements to which filters may be applied.
+ *
+ * @author Steve Ebersole
+ */
+public interface Filterable {
+	public void addFilter(String name, String condition);
+
+	public java.util.Map getFilterMap();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/ForeignKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,163 +0,0 @@
-//$Id: ForeignKey.java 7360 2005-07-01 16:38:03Z maxcsaucdk $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * A foreign key constraint
- * @author Gavin King
- */
-public class ForeignKey extends Constraint {
-
-	private Table referencedTable;
-	private String referencedEntityName;
-	private boolean cascadeDeleteEnabled;
-	private List referencedColumns = new ArrayList();    
-    
-	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) {
-		String[] cols = new String[ getColumnSpan() ];
-		String[] refcols = new String[ getColumnSpan() ];
-		int i=0;
-		Iterator refiter = null;
-		if(isReferenceToPrimaryKey() ) {
-			refiter = referencedTable.getPrimaryKey().getColumnIterator();
-		} 
-		else {
-			refiter = referencedColumns.iterator();
-		}
-		
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			cols[i] = ( (Column) iter.next() ).getQuotedName(dialect);
-			refcols[i] = ( (Column) refiter.next() ).getQuotedName(dialect);
-			i++;
-		}
-		String result = dialect.getAddForeignKeyConstraintString(
-			constraintName, cols, referencedTable.getQualifiedName(dialect, defaultCatalog, defaultSchema), refcols, isReferenceToPrimaryKey()
-		);
-		return cascadeDeleteEnabled && dialect.supportsCascadeDelete() ? 
-			result + " on delete cascade" : 
-			result;
-	}
-
-	public Table getReferencedTable() {
-		return referencedTable;
-	}
-
-	private void appendColumns(StringBuffer buf, Iterator columns) {
-		while( columns.hasNext() ) {
-			Column column = (Column) columns.next();
-			buf.append( column.getName() );
-			if ( columns.hasNext() ) buf.append(",");
-		}
-	}
-
-	public void setReferencedTable(Table referencedTable) throws MappingException {
-		//if( isReferenceToPrimaryKey() ) alignColumns(referencedTable); // TODO: possibly remove to allow more piecemal building of a foreignkey.  
-		
-		this.referencedTable = referencedTable;
-	}
-
-	/**
-	 * Validates that columnspan of the foreignkey and the primarykey is the same.
-	 * 
-	 * Furthermore it aligns the length of the underlying tables columns.
-	 * @param referencedTable
-	 */
-	public void alignColumns() {
-		if ( isReferenceToPrimaryKey() ) alignColumns(referencedTable);
-	}
-	
-	private void alignColumns(Table referencedTable) {
-		if ( referencedTable.getPrimaryKey().getColumnSpan()!=getColumnSpan() ) {
-			StringBuffer sb = new StringBuffer();
-			sb.append("Foreign key (")
-                .append( getName() + ":")
-				.append( getTable().getName() )
-				.append(" [");
-			appendColumns( sb, getColumnIterator() );
-			sb.append("])")
-				.append(") must have same number of columns as the referenced primary key (")
-				.append( referencedTable.getName() )
-				.append(" [");
-			appendColumns( sb, referencedTable.getPrimaryKey().getColumnIterator() );
-			sb.append("])");
-			throw new MappingException( sb.toString() );
-		}
-		
-		Iterator fkCols = getColumnIterator();
-		Iterator pkCols = referencedTable.getPrimaryKey().getColumnIterator();
-		while ( pkCols.hasNext() ) {
-			( (Column) fkCols.next() ).setLength( ( (Column) pkCols.next() ).getLength() );
-		}
-
-	}
-
-	public String getReferencedEntityName() {
-		return referencedEntityName;
-	}
-
-	public void setReferencedEntityName(String referencedEntityName) {
-		this.referencedEntityName = referencedEntityName;
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		return "alter table " + 
-			getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) + 
-			dialect.getDropForeignKeyString() + 
-			getName();
-	}
-
-	public boolean isCascadeDeleteEnabled() {
-		return cascadeDeleteEnabled;
-	}
-
-	public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
-		this.cascadeDeleteEnabled = cascadeDeleteEnabled;
-	}
-	
-	public boolean isPhysicalConstraint() {
-		return referencedTable.isPhysicalTable() && 
-				getTable().isPhysicalTable() && 
-				!referencedTable.hasDenormalizedTables();
-	}
-
-	/** Returns the referenced columns if the foreignkey does not refer to the primary key */
-	public List getReferencedColumns() {
-		return referencedColumns;		
-	}
-
-	/** Does this foreignkey reference the primary key of the reference table */ 
-	public boolean isReferenceToPrimaryKey() {
-		return referencedColumns.isEmpty();
-	}
-
-	public void addReferencedColumns(Iterator referencedColumnsIterator) {
-		while ( referencedColumnsIterator.hasNext() ) {
-			Selectable col = (Selectable) referencedColumnsIterator.next();
-			if ( !col.isFormula() ) addReferencedColumn( (Column) col );
-		}
-	}
-
-	private void addReferencedColumn(Column column) {
-		if ( !referencedColumns.contains(column) ) referencedColumns.add(column);		
-	}
-	
-	public String toString() {
-		if(!isReferenceToPrimaryKey() ) {
-			StringBuffer result = new StringBuffer(getClass().getName() + '(' + getTable().getName() + getColumns() );
-			result.append( " ref-columns:" + '(' + getReferencedColumns() );
-			result.append( ") as " + getName() );
-			return result.toString();
-		} 
-		else {
-			return super.toString();
-		}
-		
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/ForeignKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ForeignKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,186 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A foreign key constraint
+ * @author Gavin King
+ */
+public class ForeignKey extends Constraint {
+
+	private Table referencedTable;
+	private String referencedEntityName;
+	private boolean cascadeDeleteEnabled;
+	private List referencedColumns = new ArrayList();    
+    
+	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) {
+		String[] cols = new String[ getColumnSpan() ];
+		String[] refcols = new String[ getColumnSpan() ];
+		int i=0;
+		Iterator refiter = null;
+		if(isReferenceToPrimaryKey() ) {
+			refiter = referencedTable.getPrimaryKey().getColumnIterator();
+		} 
+		else {
+			refiter = referencedColumns.iterator();
+		}
+		
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			cols[i] = ( (Column) iter.next() ).getQuotedName(dialect);
+			refcols[i] = ( (Column) refiter.next() ).getQuotedName(dialect);
+			i++;
+		}
+		String result = dialect.getAddForeignKeyConstraintString(
+			constraintName, cols, referencedTable.getQualifiedName(dialect, defaultCatalog, defaultSchema), refcols, isReferenceToPrimaryKey()
+		);
+		return cascadeDeleteEnabled && dialect.supportsCascadeDelete() ? 
+			result + " on delete cascade" : 
+			result;
+	}
+
+	public Table getReferencedTable() {
+		return referencedTable;
+	}
+
+	private void appendColumns(StringBuffer buf, Iterator columns) {
+		while( columns.hasNext() ) {
+			Column column = (Column) columns.next();
+			buf.append( column.getName() );
+			if ( columns.hasNext() ) buf.append(",");
+		}
+	}
+
+	public void setReferencedTable(Table referencedTable) throws MappingException {
+		//if( isReferenceToPrimaryKey() ) alignColumns(referencedTable); // TODO: possibly remove to allow more piecemal building of a foreignkey.  
+		
+		this.referencedTable = referencedTable;
+	}
+
+	/**
+	 * Validates that columnspan of the foreignkey and the primarykey is the same.
+	 * 
+	 * Furthermore it aligns the length of the underlying tables columns.
+	 * @param referencedTable
+	 */
+	public void alignColumns() {
+		if ( isReferenceToPrimaryKey() ) alignColumns(referencedTable);
+	}
+	
+	private void alignColumns(Table referencedTable) {
+		if ( referencedTable.getPrimaryKey().getColumnSpan()!=getColumnSpan() ) {
+			StringBuffer sb = new StringBuffer();
+			sb.append("Foreign key (")
+                .append( getName() + ":")
+				.append( getTable().getName() )
+				.append(" [");
+			appendColumns( sb, getColumnIterator() );
+			sb.append("])")
+				.append(") must have same number of columns as the referenced primary key (")
+				.append( referencedTable.getName() )
+				.append(" [");
+			appendColumns( sb, referencedTable.getPrimaryKey().getColumnIterator() );
+			sb.append("])");
+			throw new MappingException( sb.toString() );
+		}
+		
+		Iterator fkCols = getColumnIterator();
+		Iterator pkCols = referencedTable.getPrimaryKey().getColumnIterator();
+		while ( pkCols.hasNext() ) {
+			( (Column) fkCols.next() ).setLength( ( (Column) pkCols.next() ).getLength() );
+		}
+
+	}
+
+	public String getReferencedEntityName() {
+		return referencedEntityName;
+	}
+
+	public void setReferencedEntityName(String referencedEntityName) {
+		this.referencedEntityName = referencedEntityName;
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		return "alter table " + 
+			getTable().getQualifiedName(dialect, defaultCatalog, defaultSchema) + 
+			dialect.getDropForeignKeyString() + 
+			getName();
+	}
+
+	public boolean isCascadeDeleteEnabled() {
+		return cascadeDeleteEnabled;
+	}
+
+	public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
+		this.cascadeDeleteEnabled = cascadeDeleteEnabled;
+	}
+	
+	public boolean isPhysicalConstraint() {
+		return referencedTable.isPhysicalTable() && 
+				getTable().isPhysicalTable() && 
+				!referencedTable.hasDenormalizedTables();
+	}
+
+	/** Returns the referenced columns if the foreignkey does not refer to the primary key */
+	public List getReferencedColumns() {
+		return referencedColumns;		
+	}
+
+	/** Does this foreignkey reference the primary key of the reference table */ 
+	public boolean isReferenceToPrimaryKey() {
+		return referencedColumns.isEmpty();
+	}
+
+	public void addReferencedColumns(Iterator referencedColumnsIterator) {
+		while ( referencedColumnsIterator.hasNext() ) {
+			Selectable col = (Selectable) referencedColumnsIterator.next();
+			if ( !col.isFormula() ) addReferencedColumn( (Column) col );
+		}
+	}
+
+	private void addReferencedColumn(Column column) {
+		if ( !referencedColumns.contains(column) ) referencedColumns.add(column);		
+	}
+	
+	public String toString() {
+		if(!isReferenceToPrimaryKey() ) {
+			StringBuffer result = new StringBuffer(getClass().getName() + '(' + getTable().getName() + getColumns() );
+			result.append( " ref-columns:" + '(' + getReferencedColumns() );
+			result.append( ") as " + getName() );
+			return result.toString();
+		} 
+		else {
+			return super.toString();
+		}
+		
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Formula.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-//$Id: Formula.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-import org.hibernate.sql.Template;
-
-/**
- * A formula is a derived column value
- * @author Gavin King
- */
-public class Formula implements Selectable, Serializable {
-	private static int formulaUniqueInteger=0;
-
-	private String formula;
-	private int uniqueInteger;
-
-	public Formula() {
-		uniqueInteger = formulaUniqueInteger++;
-	}
-
-	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		return Template.renderWhereStringTemplate(formula, dialect, functionRegistry);
-	}
-	public String getText(Dialect dialect) {
-		return getFormula();
-	}
-	public String getText() {
-		return getFormula();
-	}
-	public String getAlias(Dialect dialect) {
-		return "formula" + Integer.toString(uniqueInteger) + '_';
-	}
-	public String getAlias(Dialect dialect, Table table) {
-		return getAlias(dialect);
-	}
-	public String getFormula() {
-		return formula;
-	}
-	public void setFormula(String string) {
-		formula = string;
-	}
-	public boolean isFormula() {
-		return true;
-	}
-
-	public String toString() {
-		return this.getClass().getName() + "( " + formula + " )";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Formula.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Formula.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+import org.hibernate.sql.Template;
+
+/**
+ * A formula is a derived column value
+ * @author Gavin King
+ */
+public class Formula implements Selectable, Serializable {
+	private static int formulaUniqueInteger=0;
+
+	private String formula;
+	private int uniqueInteger;
+
+	public Formula() {
+		uniqueInteger = formulaUniqueInteger++;
+	}
+
+	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		return Template.renderWhereStringTemplate(formula, dialect, functionRegistry);
+	}
+	public String getText(Dialect dialect) {
+		return getFormula();
+	}
+	public String getText() {
+		return getFormula();
+	}
+	public String getAlias(Dialect dialect) {
+		return "formula" + Integer.toString(uniqueInteger) + '_';
+	}
+	public String getAlias(Dialect dialect, Table table) {
+		return getAlias(dialect);
+	}
+	public String getFormula() {
+		return formula;
+	}
+	public void setFormula(String string) {
+		formula = string;
+	}
+	public boolean isFormula() {
+		return true;
+	}
+
+	public String toString() {
+		return this.getClass().getName() + "( " + formula + " )";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/IdentifierBag.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: IdentifierBag.java 5793 2005-02-20 03:34:50Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.TypeFactory;
-
-/**
- * An <tt>IdentifierBag</tt> has a primary key consisting of
- * just the identifier column
- */
-public class IdentifierBag extends IdentifierCollection {
-
-	public IdentifierBag(PersistentClass owner) {
-		super(owner);
-	}
-
-	public CollectionType getDefaultCollectionType() {
-		return TypeFactory.idbag( getRole(), getReferencedPropertyName(), isEmbedded() );
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/IdentifierBag.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierBag.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * An <tt>IdentifierBag</tt> has a primary key consisting of
+ * just the identifier column
+ */
+public class IdentifierBag extends IdentifierCollection {
+
+	public IdentifierBag(PersistentClass owner) {
+		super(owner);
+	}
+
+	public CollectionType getDefaultCollectionType() {
+		return TypeFactory.idbag( getRole(), getReferencedPropertyName(), isEmbedded() );
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,64 +0,0 @@
-//$Id: IdentifierCollection.java 4173 2004-08-08 04:56:01Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-
-/**
- * A collection with a synthetic "identifier" column
- */
-public abstract class IdentifierCollection extends Collection {
-
-	public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
-
-	private KeyValue identifier;
-
-	public IdentifierCollection(PersistentClass owner) {
-		super(owner);
-	}
-
-	public KeyValue getIdentifier() {
-		return identifier;
-	}
-	public void setIdentifier(KeyValue identifier) {
-		this.identifier = identifier;
-	}
-	public final boolean isIdentified() {
-		return true;
-	}
-
-	void createPrimaryKey() {
-		if ( !isOneToMany() ) {
-			PrimaryKey pk = new PrimaryKey();
-			pk.addColumns( getIdentifier().getColumnIterator() );
-			getCollectionTable().setPrimaryKey(pk);
-		}
-		else {
-			// don't create a unique key, 'cos some
-			// databases don't like a UK on nullable
-			// columns
-			//getCollectionTable().createUniqueKey( getIdentifier().getConstraintColumns() );
-		}
-		// create an index on the key columns??
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate(mapping);
-		if ( !getIdentifier().isValid(mapping) ) {
-			throw new MappingException(
-				"collection id mapping has wrong number of columns: " +
-				getRole() +
-				" type: " +
-				getIdentifier().getType().getName()
-			);
-		}
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IdentifierCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+
+/**
+ * A collection with a synthetic "identifier" column
+ */
+public abstract class IdentifierCollection extends Collection {
+
+	public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
+
+	private KeyValue identifier;
+
+	public IdentifierCollection(PersistentClass owner) {
+		super(owner);
+	}
+
+	public KeyValue getIdentifier() {
+		return identifier;
+	}
+	public void setIdentifier(KeyValue identifier) {
+		this.identifier = identifier;
+	}
+	public final boolean isIdentified() {
+		return true;
+	}
+
+	void createPrimaryKey() {
+		if ( !isOneToMany() ) {
+			PrimaryKey pk = new PrimaryKey();
+			pk.addColumns( getIdentifier().getColumnIterator() );
+			getCollectionTable().setPrimaryKey(pk);
+		}
+		else {
+			// don't create a unique key, 'cos some
+			// databases don't like a UK on nullable
+			// columns
+			//getCollectionTable().createUniqueKey( getIdentifier().getConstraintColumns() );
+		}
+		// create an index on the key columns??
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate(mapping);
+		if ( !getIdentifier().isValid(mapping) ) {
+			throw new MappingException(
+				"collection id mapping has wrong number of columns: " +
+				getRole() +
+				" type: " +
+				getIdentifier().getType().getName()
+			);
+		}
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Index.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,145 +0,0 @@
-//$Id: Index.java 10661 2006-10-31 02:19:13Z epbernard $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.util.StringHelper;
-
-/**
- * A relational table index
- *
- * @author Gavin King
- */
-public class Index implements RelationalModel, Serializable {
-
-	private Table table;
-	private List columns = new ArrayList();
-	private String name;
-
-	public String sqlCreateString(Dialect dialect, Mapping mapping, String defaultCatalog, String defaultSchema)
-			throws HibernateException {
-		return buildSqlCreateIndexString(
-				dialect,
-				getName(),
-				getTable(),
-				getColumnIterator(),
-				false,
-				defaultCatalog,
-				defaultSchema
-		);
-	}
-
-	public static String buildSqlDropIndexString(
-			Dialect dialect,
-			Table table,
-			String name,
-			String defaultCatalog,
-			String defaultSchema
-	) {
-		return "drop index " +
-				StringHelper.qualify(
-						table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
-						name
-				);
-	}
-
-	public static String buildSqlCreateIndexString(
-			Dialect dialect,
-			String name,
-			Table table,
-			Iterator columns,
-			boolean unique,
-			String defaultCatalog,
-			String defaultSchema
-	) {
-		//TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far
-		StringBuffer buf = new StringBuffer( "create" )
-				.append( unique ?
-						" unique" :
-						"" )
-				.append( " index " )
-				.append( dialect.qualifyIndexName() ?
-						name :
-						StringHelper.unqualify( name ) )
-				.append( " on " )
-				.append( table.getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
-				.append( " (" );
-		Iterator iter = columns;
-		while ( iter.hasNext() ) {
-			buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
-			if ( iter.hasNext() ) buf.append( ", " );
-		}
-		buf.append( ")" );
-		return buf.toString();
-	}
-
-
-	// Used only in Table for sqlCreateString (but commented out at the moment)
-	public String sqlConstraintString(Dialect dialect) {
-		StringBuffer buf = new StringBuffer( " index (" );
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
-			if ( iter.hasNext() ) buf.append( ", " );
-		}
-		return buf.append( ')' ).toString();
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		return "drop index " +
-				StringHelper.qualify(
-						table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
-						name
-				);
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	public void setTable(Table table) {
-		this.table = table;
-	}
-
-	public int getColumnSpan() {
-		return columns.size();
-	}
-
-	public Iterator getColumnIterator() {
-		return columns.iterator();
-	}
-
-	public void addColumn(Column column) {
-		if ( !columns.contains( column ) ) columns.add( column );
-	}
-
-	public void addColumns(Iterator extraColumns) {
-		while ( extraColumns.hasNext() ) addColumn( (Column) extraColumns.next() );
-	}
-
-	/**
-	 * @param column
-	 * @return true if this constraint already contains a column with same name.
-	 */
-	public boolean containsColumn(Column column) {
-		return columns.contains( column );
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-	public String toString() {
-		return getClass().getName() + "(" + getName() + ")";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Index.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Index.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,168 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A relational table index
+ *
+ * @author Gavin King
+ */
+public class Index implements RelationalModel, Serializable {
+
+	private Table table;
+	private List columns = new ArrayList();
+	private String name;
+
+	public String sqlCreateString(Dialect dialect, Mapping mapping, String defaultCatalog, String defaultSchema)
+			throws HibernateException {
+		return buildSqlCreateIndexString(
+				dialect,
+				getName(),
+				getTable(),
+				getColumnIterator(),
+				false,
+				defaultCatalog,
+				defaultSchema
+		);
+	}
+
+	public static String buildSqlDropIndexString(
+			Dialect dialect,
+			Table table,
+			String name,
+			String defaultCatalog,
+			String defaultSchema
+	) {
+		return "drop index " +
+				StringHelper.qualify(
+						table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
+						name
+				);
+	}
+
+	public static String buildSqlCreateIndexString(
+			Dialect dialect,
+			String name,
+			Table table,
+			Iterator columns,
+			boolean unique,
+			String defaultCatalog,
+			String defaultSchema
+	) {
+		//TODO handle supportsNotNullUnique=false, but such a case does not exist in the wild so far
+		StringBuffer buf = new StringBuffer( "create" )
+				.append( unique ?
+						" unique" :
+						"" )
+				.append( " index " )
+				.append( dialect.qualifyIndexName() ?
+						name :
+						StringHelper.unqualify( name ) )
+				.append( " on " )
+				.append( table.getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+				.append( " (" );
+		Iterator iter = columns;
+		while ( iter.hasNext() ) {
+			buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
+			if ( iter.hasNext() ) buf.append( ", " );
+		}
+		buf.append( ")" );
+		return buf.toString();
+	}
+
+
+	// Used only in Table for sqlCreateString (but commented out at the moment)
+	public String sqlConstraintString(Dialect dialect) {
+		StringBuffer buf = new StringBuffer( " index (" );
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			buf.append( ( (Column) iter.next() ).getQuotedName( dialect ) );
+			if ( iter.hasNext() ) buf.append( ", " );
+		}
+		return buf.append( ')' ).toString();
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		return "drop index " +
+				StringHelper.qualify(
+						table.getQualifiedName( dialect, defaultCatalog, defaultSchema ),
+						name
+				);
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	public void setTable(Table table) {
+		this.table = table;
+	}
+
+	public int getColumnSpan() {
+		return columns.size();
+	}
+
+	public Iterator getColumnIterator() {
+		return columns.iterator();
+	}
+
+	public void addColumn(Column column) {
+		if ( !columns.contains( column ) ) columns.add( column );
+	}
+
+	public void addColumns(Iterator extraColumns) {
+		while ( extraColumns.hasNext() ) addColumn( (Column) extraColumns.next() );
+	}
+
+	/**
+	 * @param column
+	 * @return true if this constraint already contains a column with same name.
+	 */
+	public boolean containsColumn(Column column) {
+		return columns.contains( column );
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String toString() {
+		return getClass().getName() + "(" + getName() + ")";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/IndexBackref.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: IndexBackref.java 6924 2005-05-27 01:30:18Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.property.IndexPropertyAccessor;
-import org.hibernate.property.PropertyAccessor;
-
-/**
- * @author Gavin King
- */
-public class IndexBackref extends Property {
-	private String collectionRole;
-	private String entityName;
-	
-	public boolean isBackRef() {
-		return true;
-	}
-	public String getCollectionRole() {
-		return collectionRole;
-	}
-	public void setCollectionRole(String collectionRole) {
-		this.collectionRole = collectionRole;
-	}
-
-	public boolean isBasicPropertyAccessor() {
-		return false;
-	}
-
-	public PropertyAccessor getPropertyAccessor(Class clazz) {
-		return new IndexPropertyAccessor(collectionRole, entityName);
-	}
-	
-	public String getEntityName() {
-		return entityName;
-	}
-	public void setEntityName(String entityName) {
-		this.entityName = entityName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/IndexBackref.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexBackref.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.property.IndexPropertyAccessor;
+import org.hibernate.property.PropertyAccessor;
+
+/**
+ * @author Gavin King
+ */
+public class IndexBackref extends Property {
+	private String collectionRole;
+	private String entityName;
+	
+	public boolean isBackRef() {
+		return true;
+	}
+	public String getCollectionRole() {
+		return collectionRole;
+	}
+	public void setCollectionRole(String collectionRole) {
+		this.collectionRole = collectionRole;
+	}
+
+	public boolean isBasicPropertyAccessor() {
+		return false;
+	}
+
+	public PropertyAccessor getPropertyAccessor(Class clazz) {
+		return new IndexPropertyAccessor(collectionRole, entityName);
+	}
+	
+	public String getEntityName() {
+		return entityName;
+	}
+	public void setEntityName(String entityName) {
+		this.entityName = entityName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/IndexedCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-//$Id: IndexedCollection.java 5797 2005-02-20 08:37:56Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-
-/**
- * Indexed collections include Lists, Maps, arrays and
- * primitive arrays.
- * @author Gavin King
- */
-public abstract class IndexedCollection extends Collection {
-
-	public static final String DEFAULT_INDEX_COLUMN_NAME = "idx";
-
-	private Value index;
-	private String indexNodeName;
-
-	public IndexedCollection(PersistentClass owner) {
-		super(owner);
-	}
-
-	public Value getIndex() {
-		return index;
-	}
-	public void setIndex(Value index) {
-		this.index = index;
-	}
-	public final boolean isIndexed() {
-		return true;
-	}
-
-	void createPrimaryKey() {
-		if ( !isOneToMany() ) {
-			PrimaryKey pk = new PrimaryKey();
-			pk.addColumns( getKey().getColumnIterator() );
-			
-			// index should be last column listed
-			boolean isFormula = false;
-			Iterator iter = getIndex().getColumnIterator();
-			while ( iter.hasNext() ) {
-				if ( ( (Selectable) iter.next() ).isFormula() ) isFormula=true;
-			}
-			if (isFormula) {
-				//if it is a formula index, use the element columns in the PK
-				pk.addColumns( getElement().getColumnIterator() );
-			}
-			else {
-				pk.addColumns( getIndex().getColumnIterator() ); 
-			}
-			getCollectionTable().setPrimaryKey(pk);
-		}
-		else {
-			// don't create a unique key, 'cos some
-			// databases don't like a UK on nullable
-			// columns
-			/*ArrayList list = new ArrayList();
-			list.addAll( getKey().getConstraintColumns() );
-			list.addAll( getIndex().getConstraintColumns() );
-			getCollectionTable().createUniqueKey(list);*/
-		}
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate(mapping);
-		if ( !getIndex().isValid(mapping) ) {
-			throw new MappingException(
-				"collection index mapping has wrong number of columns: " +
-				getRole() +
-				" type: " +
-				getIndex().getType().getName()
-			);
-		}
-		if ( indexNodeName!=null && !indexNodeName.startsWith("@") ) {
-			throw new MappingException("index node must be an attribute: " + indexNodeName );
-		}
-	}
-	
-	public boolean isList() {
-		return false;
-	}
-
-	public String getIndexNodeName() {
-		return indexNodeName;
-	}
-
-	public void setIndexNodeName(String indexNodeName) {
-		this.indexNodeName = indexNodeName;
-	}
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/IndexedCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/IndexedCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+
+/**
+ * Indexed collections include Lists, Maps, arrays and
+ * primitive arrays.
+ * @author Gavin King
+ */
+public abstract class IndexedCollection extends Collection {
+
+	public static final String DEFAULT_INDEX_COLUMN_NAME = "idx";
+
+	private Value index;
+	private String indexNodeName;
+
+	public IndexedCollection(PersistentClass owner) {
+		super(owner);
+	}
+
+	public Value getIndex() {
+		return index;
+	}
+	public void setIndex(Value index) {
+		this.index = index;
+	}
+	public final boolean isIndexed() {
+		return true;
+	}
+
+	void createPrimaryKey() {
+		if ( !isOneToMany() ) {
+			PrimaryKey pk = new PrimaryKey();
+			pk.addColumns( getKey().getColumnIterator() );
+			
+			// index should be last column listed
+			boolean isFormula = false;
+			Iterator iter = getIndex().getColumnIterator();
+			while ( iter.hasNext() ) {
+				if ( ( (Selectable) iter.next() ).isFormula() ) isFormula=true;
+			}
+			if (isFormula) {
+				//if it is a formula index, use the element columns in the PK
+				pk.addColumns( getElement().getColumnIterator() );
+			}
+			else {
+				pk.addColumns( getIndex().getColumnIterator() ); 
+			}
+			getCollectionTable().setPrimaryKey(pk);
+		}
+		else {
+			// don't create a unique key, 'cos some
+			// databases don't like a UK on nullable
+			// columns
+			/*ArrayList list = new ArrayList();
+			list.addAll( getKey().getConstraintColumns() );
+			list.addAll( getIndex().getConstraintColumns() );
+			getCollectionTable().createUniqueKey(list);*/
+		}
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate(mapping);
+		if ( !getIndex().isValid(mapping) ) {
+			throw new MappingException(
+				"collection index mapping has wrong number of columns: " +
+				getRole() +
+				" type: " +
+				getIndex().getType().getName()
+			);
+		}
+		if ( indexNodeName!=null && !indexNodeName.startsWith("@") ) {
+			throw new MappingException("index node must be an attribute: " + indexNodeName );
+		}
+	}
+	
+	public boolean isList() {
+		return false;
+	}
+
+	public String getIndexNodeName() {
+		return indexNodeName;
+	}
+
+	public void setIndexNodeName(String indexNodeName) {
+		this.indexNodeName = indexNodeName;
+	}
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Join.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,176 +0,0 @@
-//$Id: Join.java 10040 2006-06-22 19:51:43Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.hibernate.sql.Alias;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-
-/**
- * @author Gavin King
- */
-public class Join implements Serializable {
-
-	private static final Alias PK_ALIAS = new Alias(15, "PK");
-
-	private ArrayList properties = new ArrayList();
-	private Table table;
-	private KeyValue key;
-	private PersistentClass persistentClass;
-	private boolean sequentialSelect;
-	private boolean inverse;
-	private boolean optional;
-
-	// Custom SQL
-	private String customSQLInsert;
-	private boolean customInsertCallable;
-	private ExecuteUpdateResultCheckStyle insertCheckStyle;
-	private String customSQLUpdate;
-	private boolean customUpdateCallable;
-	private ExecuteUpdateResultCheckStyle updateCheckStyle;
-	private String customSQLDelete;
-	private boolean customDeleteCallable;
-	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
-
-	public void addProperty(Property prop) {
-		properties.add(prop);
-		prop.setPersistentClass( getPersistentClass() );
-	}
-	public boolean containsProperty(Property prop) {
-		return properties.contains(prop);
-	}
-	public Iterator getPropertyIterator() {
-		return properties.iterator();
-	}
-
-	public Table getTable() {
-		return table;
-	}
-	public void setTable(Table table) {
-		this.table = table;
-	}
-
-	public KeyValue getKey() {
-		return key;
-	}
-	public void setKey(KeyValue key) {
-		this.key = key;
-	}
-
-	public PersistentClass getPersistentClass() {
-		return persistentClass;
-	}
-
-	public void setPersistentClass(PersistentClass persistentClass) {
-		this.persistentClass = persistentClass;
-	}
-
-	public void createForeignKey() {
-		getKey().createForeignKeyOfEntity( persistentClass.getEntityName() );
-	}
-
-	public void createPrimaryKey() {
-		//Primary key constraint
-		PrimaryKey pk = new PrimaryKey();
-		pk.setTable(table);
-		pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
-		table.setPrimaryKey(pk);
-
-		pk.addColumns( getKey().getColumnIterator() );
-	}
-
-	public int getPropertySpan() {
-		return properties.size();
-	}
-
-	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLInsert = customSQLInsert;
-		this.customInsertCallable = callable;
-		this.insertCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLInsert() {
-		return customSQLInsert;
-	}
-
-	public boolean isCustomInsertCallable() {
-		return customInsertCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
-		return insertCheckStyle;
-	}
-
-	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLUpdate = customSQLUpdate;
-		this.customUpdateCallable = callable;
-		this.updateCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLUpdate() {
-		return customSQLUpdate;
-	}
-
-	public boolean isCustomUpdateCallable() {
-		return customUpdateCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
-		return updateCheckStyle;
-	}
-
-	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLDelete = customSQLDelete;
-		this.customDeleteCallable = callable;
-		this.deleteCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLDelete() {
-		return customSQLDelete;
-	}
-
-	public boolean isCustomDeleteCallable() {
-		return customDeleteCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
-		return deleteCheckStyle;
-	}
-
-	public boolean isSequentialSelect() {
-		return sequentialSelect;
-	}
-	public void setSequentialSelect(boolean deferred) {
-		this.sequentialSelect = deferred;
-	}
-
-	public boolean isInverse() {
-		return inverse;
-	}
-
-	public void setInverse(boolean leftJoin) {
-		this.inverse = leftJoin;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + table.toString() + ')';
-	}
-
-	public boolean isLazy() {
-		Iterator iter = getPropertyIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			if ( !prop.isLazy() ) return false;
-		}
-		return true;
-	}
-
-	public boolean isOptional() {
-		return optional;
-	}
-	public void setOptional(boolean nullable) {
-		this.optional = nullable;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Join.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Join.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,199 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.hibernate.sql.Alias;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+
+/**
+ * @author Gavin King
+ */
+public class Join implements Serializable {
+
+	private static final Alias PK_ALIAS = new Alias(15, "PK");
+
+	private ArrayList properties = new ArrayList();
+	private Table table;
+	private KeyValue key;
+	private PersistentClass persistentClass;
+	private boolean sequentialSelect;
+	private boolean inverse;
+	private boolean optional;
+
+	// Custom SQL
+	private String customSQLInsert;
+	private boolean customInsertCallable;
+	private ExecuteUpdateResultCheckStyle insertCheckStyle;
+	private String customSQLUpdate;
+	private boolean customUpdateCallable;
+	private ExecuteUpdateResultCheckStyle updateCheckStyle;
+	private String customSQLDelete;
+	private boolean customDeleteCallable;
+	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
+
+	public void addProperty(Property prop) {
+		properties.add(prop);
+		prop.setPersistentClass( getPersistentClass() );
+	}
+	public boolean containsProperty(Property prop) {
+		return properties.contains(prop);
+	}
+	public Iterator getPropertyIterator() {
+		return properties.iterator();
+	}
+
+	public Table getTable() {
+		return table;
+	}
+	public void setTable(Table table) {
+		this.table = table;
+	}
+
+	public KeyValue getKey() {
+		return key;
+	}
+	public void setKey(KeyValue key) {
+		this.key = key;
+	}
+
+	public PersistentClass getPersistentClass() {
+		return persistentClass;
+	}
+
+	public void setPersistentClass(PersistentClass persistentClass) {
+		this.persistentClass = persistentClass;
+	}
+
+	public void createForeignKey() {
+		getKey().createForeignKeyOfEntity( persistentClass.getEntityName() );
+	}
+
+	public void createPrimaryKey() {
+		//Primary key constraint
+		PrimaryKey pk = new PrimaryKey();
+		pk.setTable(table);
+		pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
+		table.setPrimaryKey(pk);
+
+		pk.addColumns( getKey().getColumnIterator() );
+	}
+
+	public int getPropertySpan() {
+		return properties.size();
+	}
+
+	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLInsert = customSQLInsert;
+		this.customInsertCallable = callable;
+		this.insertCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLInsert() {
+		return customSQLInsert;
+	}
+
+	public boolean isCustomInsertCallable() {
+		return customInsertCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
+		return insertCheckStyle;
+	}
+
+	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLUpdate = customSQLUpdate;
+		this.customUpdateCallable = callable;
+		this.updateCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLUpdate() {
+		return customSQLUpdate;
+	}
+
+	public boolean isCustomUpdateCallable() {
+		return customUpdateCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
+		return updateCheckStyle;
+	}
+
+	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLDelete = customSQLDelete;
+		this.customDeleteCallable = callable;
+		this.deleteCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLDelete() {
+		return customSQLDelete;
+	}
+
+	public boolean isCustomDeleteCallable() {
+		return customDeleteCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
+		return deleteCheckStyle;
+	}
+
+	public boolean isSequentialSelect() {
+		return sequentialSelect;
+	}
+	public void setSequentialSelect(boolean deferred) {
+		this.sequentialSelect = deferred;
+	}
+
+	public boolean isInverse() {
+		return inverse;
+	}
+
+	public void setInverse(boolean leftJoin) {
+		this.inverse = leftJoin;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + table.toString() + ')';
+	}
+
+	public boolean isLazy() {
+		Iterator iter = getPropertyIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			if ( !prop.isLazy() ) return false;
+		}
+		return true;
+	}
+
+	public boolean isOptional() {
+		return optional;
+	}
+	public void setOptional(boolean nullable) {
+		this.optional = nullable;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: JoinedSubclass.java 7586 2005-07-21 01:11:52Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-
-/**
- * A subclass in a table-per-subclass mapping
- * @author Gavin King
- */
-public class JoinedSubclass extends Subclass implements TableOwner {
-
-	private Table table;
-	private KeyValue key;
-
-	public JoinedSubclass(PersistentClass superclass) {
-		super(superclass);
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	public void setTable(Table table) {
-		this.table=table;
-		getSuperclass().addSubclassTable(table);
-	}
-
-	public KeyValue getKey() {
-		return key;
-	}
-
-	public void setKey(KeyValue key) {
-		this.key = key;
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate(mapping);
-		if ( key!=null && !key.isValid(mapping) ) {
-			throw new MappingException(
-					"subclass key mapping has wrong number of columns: " +
-					getEntityName() +
-					" type: " +
-					key.getType().getName()
-				);
-		}
-	}
-
-	public Iterator getReferenceablePropertyIterator() {
-		return getPropertyIterator();
-	}
-	
-	public Object accept(PersistentClassVisitor mv) {
-		return mv.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/JoinedSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+
+/**
+ * A subclass in a table-per-subclass mapping
+ * @author Gavin King
+ */
+public class JoinedSubclass extends Subclass implements TableOwner {
+
+	private Table table;
+	private KeyValue key;
+
+	public JoinedSubclass(PersistentClass superclass) {
+		super(superclass);
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	public void setTable(Table table) {
+		this.table=table;
+		getSuperclass().addSubclassTable(table);
+	}
+
+	public KeyValue getKey() {
+		return key;
+	}
+
+	public void setKey(KeyValue key) {
+		this.key = key;
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate(mapping);
+		if ( key!=null && !key.isValid(mapping) ) {
+			throw new MappingException(
+					"subclass key mapping has wrong number of columns: " +
+					getEntityName() +
+					" type: " +
+					key.getType().getName()
+				);
+		}
+	}
+
+	public Iterator getReferenceablePropertyIterator() {
+		return getPropertyIterator();
+	}
+	
+	public Object accept(PersistentClassVisitor mv) {
+		return mv.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-//$Id: KeyValue.java 6514 2005-04-26 06:37:54Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.id.IdentifierGenerator;
-
-/**
- * Represents an identifying key of a table: the value for primary key
- * of an entity, or a foreign key of a collection or join table or
- * joined subclass table.
- * @author Gavin King
- */
-public interface KeyValue extends Value {
-	
-	public void createForeignKeyOfEntity(String entityName);
-	
-	public boolean isCascadeDeleteEnabled();
-	
-	public boolean isIdentityColumn(Dialect dialect);
-	
-	public String getNullValue();
-	
-	public boolean isUpdateable();
-
-	public IdentifierGenerator createIdentifierGenerator(
-			Dialect dialect, 
-			String defaultCatalog, 
-			String defaultSchema, 
-			RootClass rootClass) throws MappingException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/KeyValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/KeyValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.id.IdentifierGenerator;
+
+/**
+ * Represents an identifying key of a table: the value for primary key
+ * of an entity, or a foreign key of a collection or join table or
+ * joined subclass table.
+ * @author Gavin King
+ */
+public interface KeyValue extends Value {
+	
+	public void createForeignKeyOfEntity(String entityName);
+	
+	public boolean isCascadeDeleteEnabled();
+	
+	public boolean isIdentityColumn(Dialect dialect);
+	
+	public String getNullValue();
+	
+	public boolean isUpdateable();
+
+	public IdentifierGenerator createIdentifierGenerator(
+			Dialect dialect, 
+			String defaultCatalog, 
+			String defaultSchema, 
+			RootClass rootClass) throws MappingException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/List.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-//$Id: List.java 5793 2005-02-20 03:34:50Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A list mapping has a primary key consisting of
- * the key columns + index column.
- * @author Gavin King
- */
-public class List extends IndexedCollection {
-	
-	private int baseIndex;
-
-	public boolean isList() {
-		return true;
-	}
-
-	public List(PersistentClass owner) {
-		super(owner);
-	}
-
-	public CollectionType getDefaultCollectionType() throws MappingException {
-		return TypeFactory.list( getRole(), getReferencedPropertyName(), isEmbedded() );
-	}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-
-	public int getBaseIndex() {
-		return baseIndex;
-	}
-	
-	public void setBaseIndex(int baseIndex) {
-		this.baseIndex = baseIndex;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/List.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/List.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A list mapping has a primary key consisting of
+ * the key columns + index column.
+ * @author Gavin King
+ */
+public class List extends IndexedCollection {
+	
+	private int baseIndex;
+
+	public boolean isList() {
+		return true;
+	}
+
+	public List(PersistentClass owner) {
+		super(owner);
+	}
+
+	public CollectionType getDefaultCollectionType() throws MappingException {
+		return TypeFactory.list( getRole(), getReferencedPropertyName(), isEmbedded() );
+	}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+
+	public int getBaseIndex() {
+		return baseIndex;
+	}
+	
+	public void setBaseIndex(int baseIndex) {
+		this.baseIndex = baseIndex;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/ManyToOne.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,91 +0,0 @@
-//$Id: ManyToOne.java 7586 2005-07-21 01:11:52Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A many-to-one association mapping
- * @author Gavin King
- */
-public class ManyToOne extends ToOne {
-	
-	private boolean ignoreNotFound;
-	
-	public ManyToOne(Table table) {
-		super(table);
-	}
-
-	public Type getType() throws MappingException {
-		return TypeFactory.manyToOne( 
-				getReferencedEntityName(), 
-				getReferencedPropertyName(),
-				isLazy(),
-				isUnwrapProxy(),
-				isEmbedded(),
-				isIgnoreNotFound()
-			);
-	}
-
-	public void createForeignKey() throws MappingException {
-		// the case of a foreign key to something other than the pk is handled in createPropertyRefConstraints
-		if (referencedPropertyName==null && !hasFormula() ) {
-			createForeignKeyOfEntity( ( (EntityType) getType() ).getAssociatedEntityName() );
-		} 
-	}
-
-	public void createPropertyRefConstraints(Map persistentClasses) {
-		if (referencedPropertyName!=null) {
-			PersistentClass pc = (PersistentClass) persistentClasses.get(getReferencedEntityName() );
-			
-			Property property = pc.getReferencedProperty( getReferencedPropertyName() );
-			
-			if (property==null) {
-				throw new MappingException(
-						"Could not find property " + 
-						getReferencedPropertyName() + 
-						" on " + 
-						getReferencedEntityName() 
-					);
-			} 
-			else {
-				if ( !hasFormula() && !"none".equals( getForeignKeyName() ) ) {
-					java.util.List refColumns = new ArrayList();
-					Iterator iter = property.getColumnIterator();
-					while ( iter.hasNext() ) {
-						Column col = (Column) iter.next();
-						refColumns.add( col );							
-					}
-					
-					ForeignKey fk = getTable().createForeignKey( 
-							getForeignKeyName(), 
-							getConstraintColumns(), 
-							( (EntityType) getType() ).getAssociatedEntityName(), 
-							refColumns 
-						);
-					fk.setCascadeDeleteEnabled(isCascadeDeleteEnabled() );
-				}
-			}
-		}
-	}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-
-	public boolean isIgnoreNotFound() {
-		return ignoreNotFound;
-	}
-
-	public void setIgnoreNotFound(boolean ignoreNotFound) {
-		this.ignoreNotFound = ignoreNotFound;
-	}
-
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/ManyToOne.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ManyToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,114 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A many-to-one association mapping
+ * @author Gavin King
+ */
+public class ManyToOne extends ToOne {
+	
+	private boolean ignoreNotFound;
+	
+	public ManyToOne(Table table) {
+		super(table);
+	}
+
+	public Type getType() throws MappingException {
+		return TypeFactory.manyToOne( 
+				getReferencedEntityName(), 
+				getReferencedPropertyName(),
+				isLazy(),
+				isUnwrapProxy(),
+				isEmbedded(),
+				isIgnoreNotFound()
+			);
+	}
+
+	public void createForeignKey() throws MappingException {
+		// the case of a foreign key to something other than the pk is handled in createPropertyRefConstraints
+		if (referencedPropertyName==null && !hasFormula() ) {
+			createForeignKeyOfEntity( ( (EntityType) getType() ).getAssociatedEntityName() );
+		} 
+	}
+
+	public void createPropertyRefConstraints(Map persistentClasses) {
+		if (referencedPropertyName!=null) {
+			PersistentClass pc = (PersistentClass) persistentClasses.get(getReferencedEntityName() );
+			
+			Property property = pc.getReferencedProperty( getReferencedPropertyName() );
+			
+			if (property==null) {
+				throw new MappingException(
+						"Could not find property " + 
+						getReferencedPropertyName() + 
+						" on " + 
+						getReferencedEntityName() 
+					);
+			} 
+			else {
+				if ( !hasFormula() && !"none".equals( getForeignKeyName() ) ) {
+					java.util.List refColumns = new ArrayList();
+					Iterator iter = property.getColumnIterator();
+					while ( iter.hasNext() ) {
+						Column col = (Column) iter.next();
+						refColumns.add( col );							
+					}
+					
+					ForeignKey fk = getTable().createForeignKey( 
+							getForeignKeyName(), 
+							getConstraintColumns(), 
+							( (EntityType) getType() ).getAssociatedEntityName(), 
+							refColumns 
+						);
+					fk.setCascadeDeleteEnabled(isCascadeDeleteEnabled() );
+				}
+			}
+		}
+	}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+
+	public boolean isIgnoreNotFound() {
+		return ignoreNotFound;
+	}
+
+	public void setIgnoreNotFound(boolean ignoreNotFound) {
+		this.ignoreNotFound = ignoreNotFound;
+	}
+
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Map.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-//$Id: Map.java 7714 2005-08-01 16:29:33Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A map has a primary key consisting of
- * the key columns + index columns.
- */
-public class Map extends IndexedCollection {
-
-	public Map(PersistentClass owner) {
-		super(owner);
-	}
-	
-	public boolean isMap() {
-		return true;
-	}
-
-	public CollectionType getDefaultCollectionType() {
-		if ( isSorted() ) {
-			return TypeFactory.sortedMap( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() );
-		}
-		else if ( hasOrder() ) {
-			return TypeFactory.orderedMap( getRole(), getReferencedPropertyName(), isEmbedded() );
-		}
-		else {
-			return TypeFactory.map( getRole(), getReferencedPropertyName(), isEmbedded() );
-		}
-	}
-
-
-	public void createAllKeys() throws MappingException {
-		super.createAllKeys();
-		if ( !isInverse() ) getIndex().createForeignKey();
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Map.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Map.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A map has a primary key consisting of
+ * the key columns + index columns.
+ */
+public class Map extends IndexedCollection {
+
+	public Map(PersistentClass owner) {
+		super(owner);
+	}
+	
+	public boolean isMap() {
+		return true;
+	}
+
+	public CollectionType getDefaultCollectionType() {
+		if ( isSorted() ) {
+			return TypeFactory.sortedMap( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() );
+		}
+		else if ( hasOrder() ) {
+			return TypeFactory.orderedMap( getRole(), getReferencedPropertyName(), isEmbedded() );
+		}
+		else {
+			return TypeFactory.map( getRole(), getReferencedPropertyName(), isEmbedded() );
+		}
+	}
+
+
+	public void createAllKeys() throws MappingException {
+		super.createAllKeys();
+		if ( !isInverse() ) getIndex().createForeignKey();
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/MetaAttributable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-package org.hibernate.mapping;
-
-/**
- * Common interface for things that can handle meta attributes.
- * 
- * @since 3.0.1
- */
-public interface MetaAttributable {
-
-	public java.util.Map getMetaAttributes();
-
-	public void setMetaAttributes(java.util.Map metas);
-		
-	public MetaAttribute getMetaAttribute(String name);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/MetaAttributable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttributable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.mapping;
+
+/**
+ * Common interface for things that can handle meta attributes.
+ * 
+ * @since 3.0.1
+ */
+public interface MetaAttributable {
+
+	public java.util.Map getMetaAttributes();
+
+	public void setMetaAttributes(java.util.Map metas);
+		
+	public MetaAttribute getMetaAttribute(String name);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/MetaAttribute.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-//$Id: MetaAttribute.java 10659 2006-10-30 16:19:10Z max.andersen at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * A meta attribute is a named value or values.
- * @author Gavin King
- */
-public class MetaAttribute implements Serializable {
-	private String name;
-	private java.util.List values = new ArrayList();
-
-	public MetaAttribute(String name) {
-		this.name = name;
-	}
-	
-	public String getName() {
-		return name;
-	}	
-
-	public java.util.List getValues() {
-		return Collections.unmodifiableList(values);
-	}
-
-	public void addValue(String value) {
-		values.add(value);
-	}
-
-	public String getValue() {
-		if ( values.size()!=1 ) {
-			throw new IllegalStateException("no unique value");
-		}
-		return (String) values.get(0);
-	}
-
-	public boolean isMultiValued() {
-		return values.size()>1;
-	}
-
-	public String toString() {
-		return "[" + name + "=" + values + "]";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/MetaAttribute.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/MetaAttribute.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * A meta attribute is a named value or values.
+ * @author Gavin King
+ */
+public class MetaAttribute implements Serializable {
+	private String name;
+	private java.util.List values = new ArrayList();
+
+	public MetaAttribute(String name) {
+		this.name = name;
+	}
+	
+	public String getName() {
+		return name;
+	}	
+
+	public java.util.List getValues() {
+		return Collections.unmodifiableList(values);
+	}
+
+	public void addValue(String value) {
+		values.add(value);
+	}
+
+	public String getValue() {
+		if ( values.size()!=1 ) {
+			throw new IllegalStateException("no unique value");
+		}
+		return (String) values.get(0);
+	}
+
+	public boolean isMultiValued() {
+		return values.size()>1;
+	}
+
+	public String toString() {
+		return "[" + name + "=" + values + "]";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/OneToMany.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,145 +0,0 @@
-//$Id: OneToMany.java 7246 2005-06-20 20:32:36Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.FetchMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A mapping for a one-to-many association
- * @author Gavin King
- */
-public class OneToMany implements Value {
-
-	private String referencedEntityName;
-	private Table referencingTable;
-	private PersistentClass associatedClass;
-	private boolean embedded;
-	private boolean ignoreNotFound;
-
-	private EntityType getEntityType() {
-		return TypeFactory.manyToOne(
-				getReferencedEntityName(), 
-				null, 
-				false,
-				false,
-				isEmbedded(),
-				isIgnoreNotFound()
-			);
-	}
-
-	public OneToMany(PersistentClass owner) throws MappingException {
-		this.referencingTable = (owner==null) ? null : owner.getTable();
-	}
-
-	public PersistentClass getAssociatedClass() {
-		return associatedClass;
-	}
-
-    /**
-     * Associated entity on the many side
-     */
-	public void setAssociatedClass(PersistentClass associatedClass) {
-		this.associatedClass = associatedClass;
-	}
-
-	public void createForeignKey() {
-		// no foreign key element of for a one-to-many
-	}
-
-	public Iterator getColumnIterator() {
-		return associatedClass.getKey().getColumnIterator();
-	}
-
-	public int getColumnSpan() {
-		return associatedClass.getKey().getColumnSpan();
-	}
-
-	public FetchMode getFetchMode() {
-		return FetchMode.JOIN;
-	}
-
-    /** 
-     * Table of the owner entity (the "one" side)
-     */
-	public Table getTable() {
-		return referencingTable;
-	}
-
-	public Type getType() {
-		return getEntityType();
-	}
-
-	public boolean isNullable() {
-		return false;
-	}
-
-	public boolean isSimpleValue() {
-		return false;
-	}
-
-	public boolean isAlternateUniqueKey() {
-		return false;
-	}
-
-	public boolean hasFormula() {
-		return false;
-	}
-	
-	public boolean isValid(Mapping mapping) throws MappingException {
-		if (referencedEntityName==null) {
-			throw new MappingException("one to many association must specify the referenced entity");
-		}
-		return true;
-	}
-
-    public String getReferencedEntityName() {
-		return referencedEntityName;
-	}
-
-    /** 
-     * Associated entity on the "many" side
-     */    
-	public void setReferencedEntityName(String referencedEntityName) {
-		this.referencedEntityName = referencedEntityName==null ? null : referencedEntityName.intern();
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName) {}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-	
-	
-	public boolean[] getColumnInsertability() {
-		//TODO: we could just return all false...
-		throw new UnsupportedOperationException();
-	}
-	
-	public boolean[] getColumnUpdateability() {
-		//TODO: we could just return all false...
-		throw new UnsupportedOperationException();
-	}
-	
-	public boolean isEmbedded() {
-		return embedded;
-	}
-	
-	public void setEmbedded(boolean embedded) {
-		this.embedded = embedded;
-	}
-
-	public boolean isIgnoreNotFound() {
-		return ignoreNotFound;
-	}
-
-	public void setIgnoreNotFound(boolean ignoreNotFound) {
-		this.ignoreNotFound = ignoreNotFound;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/OneToMany.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToMany.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,168 @@
+/*
+ * 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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A mapping for a one-to-many association
+ * @author Gavin King
+ */
+public class OneToMany implements Value {
+
+	private String referencedEntityName;
+	private Table referencingTable;
+	private PersistentClass associatedClass;
+	private boolean embedded;
+	private boolean ignoreNotFound;
+
+	private EntityType getEntityType() {
+		return TypeFactory.manyToOne(
+				getReferencedEntityName(), 
+				null, 
+				false,
+				false,
+				isEmbedded(),
+				isIgnoreNotFound()
+			);
+	}
+
+	public OneToMany(PersistentClass owner) throws MappingException {
+		this.referencingTable = (owner==null) ? null : owner.getTable();
+	}
+
+	public PersistentClass getAssociatedClass() {
+		return associatedClass;
+	}
+
+    /**
+     * Associated entity on the many side
+     */
+	public void setAssociatedClass(PersistentClass associatedClass) {
+		this.associatedClass = associatedClass;
+	}
+
+	public void createForeignKey() {
+		// no foreign key element of for a one-to-many
+	}
+
+	public Iterator getColumnIterator() {
+		return associatedClass.getKey().getColumnIterator();
+	}
+
+	public int getColumnSpan() {
+		return associatedClass.getKey().getColumnSpan();
+	}
+
+	public FetchMode getFetchMode() {
+		return FetchMode.JOIN;
+	}
+
+    /** 
+     * Table of the owner entity (the "one" side)
+     */
+	public Table getTable() {
+		return referencingTable;
+	}
+
+	public Type getType() {
+		return getEntityType();
+	}
+
+	public boolean isNullable() {
+		return false;
+	}
+
+	public boolean isSimpleValue() {
+		return false;
+	}
+
+	public boolean isAlternateUniqueKey() {
+		return false;
+	}
+
+	public boolean hasFormula() {
+		return false;
+	}
+	
+	public boolean isValid(Mapping mapping) throws MappingException {
+		if (referencedEntityName==null) {
+			throw new MappingException("one to many association must specify the referenced entity");
+		}
+		return true;
+	}
+
+    public String getReferencedEntityName() {
+		return referencedEntityName;
+	}
+
+    /** 
+     * Associated entity on the "many" side
+     */    
+	public void setReferencedEntityName(String referencedEntityName) {
+		this.referencedEntityName = referencedEntityName==null ? null : referencedEntityName.intern();
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName) {}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+	
+	
+	public boolean[] getColumnInsertability() {
+		//TODO: we could just return all false...
+		throw new UnsupportedOperationException();
+	}
+	
+	public boolean[] getColumnUpdateability() {
+		//TODO: we could just return all false...
+		throw new UnsupportedOperationException();
+	}
+	
+	public boolean isEmbedded() {
+		return embedded;
+	}
+	
+	public void setEmbedded(boolean embedded) {
+		this.embedded = embedded;
+	}
+
+	public boolean isIgnoreNotFound() {
+		return ignoreNotFound;
+	}
+
+	public void setIgnoreNotFound(boolean ignoreNotFound) {
+		this.ignoreNotFound = ignoreNotFound;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/OneToOne.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,143 +0,0 @@
-//$Id: OneToOne.java 7246 2005-06-20 20:32:36Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.ForeignKeyDirection;
-import org.hibernate.type.SpecialOneToOneType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A one-to-one association mapping
- * @author Gavin King
- */
-public class OneToOne extends ToOne {
-
-	private boolean constrained;
-	private ForeignKeyDirection foreignKeyType;
-	private KeyValue identifier;
-	private String propertyName;
-	private String entityName;
-
-	public OneToOne(Table table, PersistentClass owner) throws MappingException {
-		super(table);
-		this.identifier = owner.getKey();
-		this.entityName = owner.getEntityName();
-	}
-
-	public String getPropertyName() {
-		return propertyName;
-	}
-
-	public void setPropertyName(String propertyName) {
-		this.propertyName = propertyName==null ? null : propertyName.intern();
-	}
-	
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public void setEntityName(String propertyName) {
-		this.entityName = entityName==null ? null : entityName.intern();
-	}
-	
-	public Type getType() throws MappingException {
-		if ( getColumnIterator().hasNext() ) {
-			return new SpecialOneToOneType(
-					getReferencedEntityName(), 
-					foreignKeyType, 
-					referencedPropertyName,
-					isLazy(),
-					isUnwrapProxy(),
-					entityName,
-					propertyName
-				);
-		}
-		else {
-			return TypeFactory.oneToOne( 
-					getReferencedEntityName(), 
-					foreignKeyType, 
-					referencedPropertyName,
-					isLazy(),
-					isUnwrapProxy(),
-					isEmbedded(),
-					entityName,
-					propertyName
-				);
-		}
-	}
-
-	public void createForeignKey() throws MappingException {
-		if ( constrained && referencedPropertyName==null) {
-			//TODO: handle the case of a foreign key to something other than the pk
-			createForeignKeyOfEntity( ( (EntityType) getType() ).getAssociatedEntityName() );
-		}
-	}
-
-	public java.util.List getConstraintColumns() {
-		ArrayList list = new ArrayList();
-		Iterator iter = identifier.getColumnIterator();
-		while ( iter.hasNext() ) list.add( iter.next() );
-		return list;
-	}
-	/**
-	 * Returns the constrained.
-	 * @return boolean
-	 */
-	public boolean isConstrained() {
-		return constrained;
-	}
-
-	/**
-	 * Returns the foreignKeyType.
-	 * @return AssociationType.ForeignKeyType
-	 */
-	public ForeignKeyDirection getForeignKeyType() {
-		return foreignKeyType;
-	}
-
-	/**
-	 * Returns the identifier.
-	 * @return Value
-	 */
-	public KeyValue getIdentifier() {
-		return identifier;
-	}
-
-	/**
-	 * Sets the constrained.
-	 * @param constrained The constrained to set
-	 */
-	public void setConstrained(boolean constrained) {
-		this.constrained = constrained;
-	}
-
-	/**
-	 * Sets the foreignKeyType.
-	 * @param foreignKeyType The foreignKeyType to set
-	 */
-	public void setForeignKeyType(ForeignKeyDirection foreignKeyType) {
-		this.foreignKeyType = foreignKeyType;
-	}
-
-	/**
-	 * Sets the identifier.
-	 * @param identifier The identifier to set
-	 */
-	public void setIdentifier(KeyValue identifier) {
-		this.identifier = identifier;
-	}
-
-	public boolean isNullable() {
-		return !constrained;
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/OneToOne.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/OneToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,166 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.ForeignKeyDirection;
+import org.hibernate.type.SpecialOneToOneType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A one-to-one association mapping
+ * @author Gavin King
+ */
+public class OneToOne extends ToOne {
+
+	private boolean constrained;
+	private ForeignKeyDirection foreignKeyType;
+	private KeyValue identifier;
+	private String propertyName;
+	private String entityName;
+
+	public OneToOne(Table table, PersistentClass owner) throws MappingException {
+		super(table);
+		this.identifier = owner.getKey();
+		this.entityName = owner.getEntityName();
+	}
+
+	public String getPropertyName() {
+		return propertyName;
+	}
+
+	public void setPropertyName(String propertyName) {
+		this.propertyName = propertyName==null ? null : propertyName.intern();
+	}
+	
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public void setEntityName(String propertyName) {
+		this.entityName = entityName==null ? null : entityName.intern();
+	}
+	
+	public Type getType() throws MappingException {
+		if ( getColumnIterator().hasNext() ) {
+			return new SpecialOneToOneType(
+					getReferencedEntityName(), 
+					foreignKeyType, 
+					referencedPropertyName,
+					isLazy(),
+					isUnwrapProxy(),
+					entityName,
+					propertyName
+				);
+		}
+		else {
+			return TypeFactory.oneToOne( 
+					getReferencedEntityName(), 
+					foreignKeyType, 
+					referencedPropertyName,
+					isLazy(),
+					isUnwrapProxy(),
+					isEmbedded(),
+					entityName,
+					propertyName
+				);
+		}
+	}
+
+	public void createForeignKey() throws MappingException {
+		if ( constrained && referencedPropertyName==null) {
+			//TODO: handle the case of a foreign key to something other than the pk
+			createForeignKeyOfEntity( ( (EntityType) getType() ).getAssociatedEntityName() );
+		}
+	}
+
+	public java.util.List getConstraintColumns() {
+		ArrayList list = new ArrayList();
+		Iterator iter = identifier.getColumnIterator();
+		while ( iter.hasNext() ) list.add( iter.next() );
+		return list;
+	}
+	/**
+	 * Returns the constrained.
+	 * @return boolean
+	 */
+	public boolean isConstrained() {
+		return constrained;
+	}
+
+	/**
+	 * Returns the foreignKeyType.
+	 * @return AssociationType.ForeignKeyType
+	 */
+	public ForeignKeyDirection getForeignKeyType() {
+		return foreignKeyType;
+	}
+
+	/**
+	 * Returns the identifier.
+	 * @return Value
+	 */
+	public KeyValue getIdentifier() {
+		return identifier;
+	}
+
+	/**
+	 * Sets the constrained.
+	 * @param constrained The constrained to set
+	 */
+	public void setConstrained(boolean constrained) {
+		this.constrained = constrained;
+	}
+
+	/**
+	 * Sets the foreignKeyType.
+	 * @param foreignKeyType The foreignKeyType to set
+	 */
+	public void setForeignKeyType(ForeignKeyDirection foreignKeyType) {
+		this.foreignKeyType = foreignKeyType;
+	}
+
+	/**
+	 * Sets the identifier.
+	 * @param identifier The identifier to set
+	 */
+	public void setIdentifier(KeyValue identifier) {
+		this.identifier = identifier;
+	}
+
+	public boolean isNullable() {
+		return !constrained;
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,791 +0,0 @@
-//$Id: PersistentClass.java 10927 2006-12-05 18:48:50Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.*;
-import java.util.Set;
-
-import org.hibernate.MappingException;
-import org.hibernate.EntityMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.sql.Alias;
-import org.hibernate.util.EmptyIterator;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.SingletonIterator;
-import org.hibernate.util.StringHelper;
-
-/**
- * Mapping for an entity.
- *
- * @author Gavin King
- */
-public abstract class PersistentClass implements Serializable, Filterable, MetaAttributable {
-
-	private static final Alias PK_ALIAS = new Alias(15, "PK");
-
-	public static final String NULL_DISCRIMINATOR_MAPPING = "null";
-	public static final String NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
-
-	private String entityName;
-
-	private String className;
-	private String proxyInterfaceName;
-	
-	private String nodeName;
-
-	private String discriminatorValue;
-	private boolean lazy;
-	private ArrayList properties = new ArrayList();
-	private final ArrayList subclasses = new ArrayList();
-	private final ArrayList subclassProperties = new ArrayList();
-	private final ArrayList subclassTables = new ArrayList();
-	private boolean dynamicInsert;
-	private boolean dynamicUpdate;
-	private int batchSize=-1;
-	private boolean selectBeforeUpdate;
-	private java.util.Map metaAttributes;
-	private ArrayList joins = new ArrayList();
-	private final ArrayList subclassJoins = new ArrayList();
-	private final java.util.Map filters = new HashMap();
-	protected final java.util.Set synchronizedTables = new HashSet();
-	private String loaderName;
-	private Boolean isAbstract;
-	private boolean hasSubselectLoadableCollections;
-	private Component identifierMapper;
-
-	// Custom SQL
-	private String customSQLInsert;
-	private boolean customInsertCallable;
-	private ExecuteUpdateResultCheckStyle insertCheckStyle;
-	private String customSQLUpdate;
-	private boolean customUpdateCallable;
-	private ExecuteUpdateResultCheckStyle updateCheckStyle;
-	private String customSQLDelete;
-	private boolean customDeleteCallable;
-	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
-
-	private String temporaryIdTableName;
-	private String temporaryIdTableDDL;
-
-	private java.util.Map tuplizerImpls;
-
-	protected int optimisticLockMode;
-
-	public String getClassName() {
-		return className;
-	}
-
-	public void setClassName(String className) {
-		this.className = className==null ? null : className.intern();
-	}
-
-	public String getProxyInterfaceName() {
-		return proxyInterfaceName;
-	}
-
-	public void setProxyInterfaceName(String proxyInterfaceName) {
-		this.proxyInterfaceName = proxyInterfaceName;
-	}
-
-	public Class getMappedClass() throws MappingException {
-		if (className==null) return null;
-		try {
-			return ReflectHelper.classForName(className);
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new MappingException("entity class not found: " + className, cnfe);
-		}
-	}
-
-	public Class getProxyInterface() {
-		if (proxyInterfaceName==null) return null;
-		try {
-			return ReflectHelper.classForName(proxyInterfaceName);
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe);
-		}
-	}
-	public boolean useDynamicInsert() {
-		return dynamicInsert;
-	}
-
-	abstract int nextSubclassId();
-	public abstract int getSubclassId();
-	
-	public boolean useDynamicUpdate() {
-		return dynamicUpdate;
-	}
-
-	public void setDynamicInsert(boolean dynamicInsert) {
-		this.dynamicInsert = dynamicInsert;
-	}
-
-	public void setDynamicUpdate(boolean dynamicUpdate) {
-		this.dynamicUpdate = dynamicUpdate;
-	}
-
-
-	public String getDiscriminatorValue() {
-		return discriminatorValue;
-	}
-
-	public void addSubclass(Subclass subclass) throws MappingException {
-		// inheritance cycle detection (paranoid check)
-		PersistentClass superclass = getSuperclass();
-		while (superclass!=null) {
-			if( subclass.getEntityName().equals( superclass.getEntityName() ) ) {
-				throw new MappingException(
-					"Circular inheritance mapping detected: " +
-					subclass.getEntityName() +
-					" will have it self as superclass when extending " +
-					getEntityName()
-				);
-			}
-			superclass = superclass.getSuperclass();
-		}
-		subclasses.add(subclass);
-	}
-
-	public boolean hasSubclasses() {
-		return subclasses.size() > 0;
-	}
-
-	public int getSubclassSpan() {
-		int n = subclasses.size();
-		Iterator iter = subclasses.iterator();
-		while ( iter.hasNext() ) {
-			n += ( (Subclass) iter.next() ).getSubclassSpan();
-		}
-		return n;
-	}
-	/**
-	 * Iterate over subclasses in a special 'order', most derived subclasses
-	 * first.
-	 */
-	public Iterator getSubclassIterator() {
-		Iterator[] iters = new Iterator[ subclasses.size() + 1 ];
-		Iterator iter = subclasses.iterator();
-		int i=0;
-		while ( iter.hasNext() ) {
-			iters[i++] = ( (Subclass) iter.next() ).getSubclassIterator();
-		}
-		iters[i] = subclasses.iterator();
-		return new JoinedIterator(iters);
-	}
-
-	public Iterator getSubclassClosureIterator() {
-		ArrayList iters = new ArrayList();
-		iters.add( new SingletonIterator(this) );
-		Iterator iter = getSubclassIterator();
-		while ( iter.hasNext() ) {
-			PersistentClass clazz = (PersistentClass)  iter.next();
-			iters.add( clazz.getSubclassClosureIterator() );
-		}
-		return new JoinedIterator(iters);
-	}
-	
-	public Table getIdentityTable() {
-		return getRootTable();
-	}
-	
-	public Iterator getDirectSubclasses() {
-		return subclasses.iterator();
-	}
-
-	public void addProperty(Property p) {
-		properties.add(p);
-		p.setPersistentClass(this);
-	}
-
-	public abstract Table getTable();
-
-	public String getEntityName() {
-		return entityName;
-	}
-
-	public abstract boolean isMutable();
-	public abstract boolean hasIdentifierProperty();
-	public abstract Property getIdentifierProperty();
-	public abstract KeyValue getIdentifier();
-	public abstract Property getVersion();
-	public abstract Value getDiscriminator();
-	public abstract boolean isInherited();
-	public abstract boolean isPolymorphic();
-	public abstract boolean isVersioned();
-	public abstract String getCacheConcurrencyStrategy();
-	public abstract PersistentClass getSuperclass();
-	public abstract boolean isExplicitPolymorphism();
-	public abstract boolean isDiscriminatorInsertable();
-
-	public abstract Iterator getPropertyClosureIterator();
-	public abstract Iterator getTableClosureIterator();
-	public abstract Iterator getKeyClosureIterator();
-
-	protected void addSubclassProperty(Property prop) {
-		subclassProperties.add(prop);
-	}
-	protected void addSubclassJoin(Join join) {
-		subclassJoins.add(join);
-	}
-	protected void addSubclassTable(Table subclassTable) {
-		subclassTables.add(subclassTable);
-	}
-	public Iterator getSubclassPropertyClosureIterator() {
-		ArrayList iters = new ArrayList();
-		iters.add( getPropertyClosureIterator() );
-		iters.add( subclassProperties.iterator() );
-		for ( int i=0; i<subclassJoins.size(); i++ ) {
-			Join join = (Join) subclassJoins.get(i);
-			iters.add( join.getPropertyIterator() );
-		}
-		return new JoinedIterator(iters);
-	}
-	public Iterator getSubclassJoinClosureIterator() {
-		return new JoinedIterator( getJoinClosureIterator(), subclassJoins.iterator() );
-	}
-	public Iterator getSubclassTableClosureIterator() {
-		return new JoinedIterator( getTableClosureIterator(), subclassTables.iterator() );
-	}
-
-	public boolean isClassOrSuperclassJoin(Join join) {
-		return joins.contains(join);
-	}
-
-	public boolean isClassOrSuperclassTable(Table closureTable) {
-		return getTable()==closureTable;
-	}
-
-	public boolean isLazy() {
-		return lazy;
-	}
-
-	public void setLazy(boolean lazy) {
-		this.lazy = lazy;
-	}
-
-	public abstract boolean hasEmbeddedIdentifier();
-	public abstract Class getEntityPersisterClass();
-	public abstract void setEntityPersisterClass(Class classPersisterClass);
-	public abstract Table getRootTable();
-	public abstract RootClass getRootClass();
-	public abstract KeyValue getKey();
-
-	public void setDiscriminatorValue(String discriminatorValue) {
-		this.discriminatorValue = discriminatorValue;
-	}
-
-	public void setEntityName(String entityName) {
-		this.entityName = entityName==null ? null : entityName.intern();
-	}
-
-	public void createPrimaryKey() {
-		//Primary key constraint
-		PrimaryKey pk = new PrimaryKey();
-		Table table = getTable();
-		pk.setTable(table);
-		pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
-		table.setPrimaryKey(pk);
-
-		pk.addColumns( getKey().getColumnIterator() );
-	}
-
-	public abstract String getWhere();
-
-	public int getBatchSize() {
-		return batchSize;
-	}
-
-	public void setBatchSize(int batchSize) {
-		this.batchSize = batchSize;
-	}
-
-	public boolean hasSelectBeforeUpdate() {
-		return selectBeforeUpdate;
-	}
-
-	public void setSelectBeforeUpdate(boolean selectBeforeUpdate) {
-		this.selectBeforeUpdate = selectBeforeUpdate;
-	}
-
-	/**
-	 * Build an iterator of properties which are "referenceable".
-	 *
-	 * @see #getReferencedProperty for a discussion of "referenceable"
-	 * @return The property iterator.
-	 */
-	public Iterator getReferenceablePropertyIterator() {
-		return getPropertyClosureIterator();
-	}
-
-	/**
-	 * Given a property path, locate the appropriate referenceable property reference.
-	 * <p/>
-	 * A referenceable property is a property  which can be a target of a foreign-key
-	 * mapping (an identifier or explcitly named in a property-ref).
-	 *
-	 * @param propertyPath The property path to resolve into a property reference.
-	 * @return The property reference (never null).
-	 * @throws MappingException If the property could not be found.
-	 */
-	public Property getReferencedProperty(String propertyPath) throws MappingException {
-		try {
-			return getRecursiveProperty( propertyPath, getReferenceablePropertyIterator() );
-		}
-		catch ( MappingException e ) {
-			throw new MappingException(
-					"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
-			);
-		}
-	}
-
-	public Property getRecursiveProperty(String propertyPath) throws MappingException {
-		try {
-			return getRecursiveProperty( propertyPath, getPropertyIterator() );
-		}
-		catch ( MappingException e ) {
-			throw new MappingException(
-					"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
-			);
-		}
-	}
-
-	private Property getRecursiveProperty(String propertyPath, Iterator iter) throws MappingException {
-		Property property = null;
-		StringTokenizer st = new StringTokenizer( propertyPath, ".", false );
-		try {
-			while ( st.hasMoreElements() ) {
-				final String element = ( String ) st.nextElement();
-				if ( property == null ) {
-					Property identifierProperty = getIdentifierProperty();
-					if ( identifierProperty != null && identifierProperty.getName().equals( element ) ) {
-						// we have a mapped identifier property and the root of
-						// the incoming property path matched that identifier
-						// property
-						property = identifierProperty;
-					}
-					else if ( identifierProperty == null && getIdentifierMapper() != null ) {
-						// we have an embedded composite identifier
-						try {
-							identifierProperty = getProperty( element, getIdentifierMapper().getPropertyIterator() );
-							if ( identifierProperty != null ) {
-								// the root of the incoming property path matched one
-								// of the embedded composite identifier properties
-								property = identifierProperty;
-							}
-						}
-						catch( MappingException ignore ) {
-							// ignore it...
-						}
-					}
-
-					if ( property == null ) {
-						property = getProperty( element, iter );
-					}
-				}
-				else {
-					//flat recursive algorithm
-					property = ( ( Component ) property.getValue() ).getProperty( element );
-				}
-			}
-		}
-		catch ( MappingException e ) {
-			throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
-		}
-
-		return property;
-	}
-
-	private Property getProperty(String propertyName, Iterator iterator) throws MappingException {
-		while ( iterator.hasNext() ) {
-			Property prop = (Property) iterator.next();
-			if ( prop.getName().equals( StringHelper.root(propertyName) ) ) {
-				return prop;
-			}
-		}
-		throw new MappingException( "property [" + propertyName + "] not found on entity [" + getEntityName() + "]" );
-	}
-
-	public Property getProperty(String propertyName) throws MappingException {
-		Iterator iter = getPropertyClosureIterator();
-		Property identifierProperty = getIdentifierProperty();
-		if ( identifierProperty != null
-				&& identifierProperty.getName().equals( StringHelper.root(propertyName) )
-				) {
-			return identifierProperty;
-		}
-		else {
-			return getProperty( propertyName, iter );
-		}
-	}
-
-	abstract public int getOptimisticLockMode();
-
-	public void setOptimisticLockMode(int optimisticLockMode) {
-		this.optimisticLockMode = optimisticLockMode;
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		Iterator iter = getPropertyIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			if ( !prop.isValid(mapping) ) {
-				throw new MappingException(
-						"property mapping has wrong number of columns: " +
-						StringHelper.qualify( getEntityName(), prop.getName() ) +
-						" type: " +
-						prop.getType().getName()
-					);
-			}
-		}
-		checkPropertyDuplication();
-		checkColumnDuplication();
-	}
-	
-	private void checkPropertyDuplication() throws MappingException {
-		HashSet names = new HashSet();
-		Iterator iter = getPropertyIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			if ( !names.add( prop.getName() ) ) {
-				throw new MappingException( "Duplicate property mapping of " + prop.getName() + " found in " + getEntityName());
-			}
-		}
-	}
-
-	public boolean isDiscriminatorValueNotNull() {
-		return NOT_NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
-	}
-	public boolean isDiscriminatorValueNull() {
-		return NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
-	}
-
-	public java.util.Map getMetaAttributes() {
-		return metaAttributes;
-	}
-
-	public void setMetaAttributes(java.util.Map metas) {
-		this.metaAttributes = metas;
-	}
-
-	public MetaAttribute getMetaAttribute(String name) {
-		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(name);
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getEntityName() + ')';
-	}
-	
-	public Iterator getJoinIterator() {
-		return joins.iterator();
-	}
-
-	public Iterator getJoinClosureIterator() {
-		return joins.iterator();
-	}
-
-	public void addJoin(Join join) {
-		joins.add(join);
-		join.setPersistentClass(this);
-	}
-
-	public int getJoinClosureSpan() {
-		return joins.size();
-	}
-
-	public int getPropertyClosureSpan() {
-		int span = properties.size();
-		for ( int i=0; i<joins.size(); i++ ) {
-			Join join = (Join) joins.get(i);
-			span += join.getPropertySpan();
-		}
-		return span;
-	}
-
-	public int getJoinNumber(Property prop) {
-		int result=1;
-		Iterator iter = getSubclassJoinClosureIterator();
-		while ( iter.hasNext() ) {
-			Join join = (Join) iter.next();
-			if ( join.containsProperty(prop) ) return result;
-			result++;
-		}
-		return 0;
-	}
-
-	/**
-	 * Build an iterator over the properties defined on this class.  The returned
-	 * iterator only accounts for "normal" properties (i.e. non-identifier
-	 * properties).
-	 * <p/>
-	 * Differs from {@link #getUnjoinedPropertyIterator} in that the iterator
-	 * we return here will include properties defined as part of a join.
-	 *
-	 * @return An iterator over the "normal" properties.
-	 */
-	public Iterator getPropertyIterator() {
-		ArrayList iterators = new ArrayList();
-		iterators.add( properties.iterator() );
-		for ( int i = 0; i < joins.size(); i++ ) {
-			Join join = ( Join ) joins.get( i );
-			iterators.add( join.getPropertyIterator() );
-		}
-		return new JoinedIterator( iterators );
-	}
-
-	/**
-	 * Build an iterator over the properties defined on this class <b>which
-	 * are not defined as part of a join</b>.  As with {@link #getPropertyIterator},
-	 * the returned iterator only accounts for non-identifier properties.
-	 *
-	 * @return An iterator over the non-joined "normal" properties.
-	 */
-	public Iterator getUnjoinedPropertyIterator() {
-		return properties.iterator();
-	}
-
-	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLInsert = customSQLInsert;
-		this.customInsertCallable = callable;
-		this.insertCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLInsert() {
-		return customSQLInsert;
-	}
-
-	public boolean isCustomInsertCallable() {
-		return customInsertCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
-		return insertCheckStyle;
-	}
-
-	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLUpdate = customSQLUpdate;
-		this.customUpdateCallable = callable;
-		this.updateCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLUpdate() {
-		return customSQLUpdate;
-	}
-
-	public boolean isCustomUpdateCallable() {
-		return customUpdateCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
-		return updateCheckStyle;
-	}
-
-	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
-		this.customSQLDelete = customSQLDelete;
-		this.customDeleteCallable = callable;
-		this.deleteCheckStyle = checkStyle;
-	}
-
-	public String getCustomSQLDelete() {
-		return customSQLDelete;
-	}
-
-	public boolean isCustomDeleteCallable() {
-		return customDeleteCallable;
-	}
-
-	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
-		return deleteCheckStyle;
-	}
-
-	public void addFilter(String name, String condition) {
-		filters.put(name, condition);
-	}
-
-	public java.util.Map getFilterMap() {
-		return filters;
-	}
-
-	public boolean isForceDiscriminator() {
-		return false;
-	}
-
-	public abstract boolean isJoinedSubclass();
-
-	public String getLoaderName() {
-		return loaderName;
-	}
-
-	public void setLoaderName(String loaderName) {
-		this.loaderName = loaderName==null ? null : loaderName.intern();
-	}
-
-	public abstract java.util.Set getSynchronizedTables();
-	
-	public void addSynchronizedTable(String table) {
-		synchronizedTables.add(table);
-	}
-
-	public Boolean isAbstract() {
-		return isAbstract;
-	}
-
-	public void setAbstract(Boolean isAbstract) {
-		this.isAbstract = isAbstract;
-	}
-
-	protected void checkColumnDuplication(Set distinctColumns, Iterator columns) 
-	throws MappingException {
-		while ( columns.hasNext() ) {
-			Selectable columnOrFormula = (Selectable) columns.next();
-			if ( !columnOrFormula.isFormula() ) {
-				Column col = (Column) columnOrFormula;
-				if ( !distinctColumns.add( col.getName() ) ) {
-					throw new MappingException( 
-							"Repeated column in mapping for entity: " +
-							getEntityName() +
-							" column: " +
-							col.getName() + 
-							" (should be mapped with insert=\"false\" update=\"false\")"
-						);
-				}
-			}
-		}
-	}
-	
-	protected void checkPropertyColumnDuplication(Set distinctColumns, Iterator properties) 
-	throws MappingException {
-		while ( properties.hasNext() ) {
-			Property prop = (Property) properties.next();
-			if ( prop.getValue() instanceof Component ) { //TODO: remove use of instanceof!
-				Component component = (Component) prop.getValue();
-				checkPropertyColumnDuplication( distinctColumns, component.getPropertyIterator() );
-			}
-			else {
-				if ( prop.isUpdateable() || prop.isInsertable() ) {
-					checkColumnDuplication( distinctColumns, prop.getColumnIterator() );
-				}
-			}
-		}
-	}
-	
-	protected Iterator getNonDuplicatedPropertyIterator() {
-		return getUnjoinedPropertyIterator();
-	}
-	
-	protected Iterator getDiscriminatorColumnIterator() {
-		return EmptyIterator.INSTANCE;
-	}
-	
-	protected void checkColumnDuplication() {
-		HashSet cols = new HashSet();
-		if (getIdentifierMapper() == null ) {
-			//an identifier mapper => getKey will be included in the getNonDuplicatedPropertyIterator()
-			//and checked later, so it needs to be excluded
-			checkColumnDuplication( cols, getKey().getColumnIterator() );
-		}
-		checkColumnDuplication( cols, getDiscriminatorColumnIterator() );
-		checkPropertyColumnDuplication( cols, getNonDuplicatedPropertyIterator() );
-		Iterator iter = getJoinIterator();
-		while ( iter.hasNext() ) {
-			cols.clear();
-			Join join = (Join) iter.next();
-			checkColumnDuplication( cols, join.getKey().getColumnIterator() );
-			checkPropertyColumnDuplication( cols, join.getPropertyIterator() );
-		}
-	}
-	
-	public abstract Object accept(PersistentClassVisitor mv);
-	
-	public String getNodeName() {
-		return nodeName;
-	}
-	
-	public void setNodeName(String nodeName) {
-		this.nodeName = nodeName;
-	}
-	
-	public boolean hasPojoRepresentation() {
-		return getClassName()!=null;
-	}
-
-	public boolean hasDom4jRepresentation() {
-		return getNodeName()!=null;
-	}
-
-	public boolean hasSubselectLoadableCollections() {
-		return hasSubselectLoadableCollections;
-	}
-	
-	public void setSubselectLoadableCollections(boolean hasSubselectCollections) {
-		this.hasSubselectLoadableCollections = hasSubselectCollections;
-	}
-
-	public void prepareTemporaryTables(Mapping mapping, Dialect dialect) {
-		if ( dialect.supportsTemporaryTables() ) {
-			temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() );
-			Table table = new Table();
-			table.setName( temporaryIdTableName );
-			Iterator itr = getTable().getPrimaryKey().getColumnIterator();
-			while( itr.hasNext() ) {
-				Column column = (Column) itr.next();
-				table.addColumn( (Column) column.clone()  );
-			}
-			temporaryIdTableDDL = table.sqlTemporaryTableCreateString( dialect, mapping );
-		}
-	}
-
-	public String getTemporaryIdTableName() {
-		return temporaryIdTableName;
-	}
-
-	public String getTemporaryIdTableDDL() {
-		return temporaryIdTableDDL;
-	}
-
-	public Component getIdentifierMapper() {
-		return identifierMapper;
-	}
-
-	public boolean hasIdentifierMapper() {
-		return identifierMapper != null;
-	}
-
-	public void setIdentifierMapper(Component handle) {
-		this.identifierMapper = handle;
-	}
-
-	public void addTuplizer(EntityMode entityMode, String implClassName) {
-		if ( tuplizerImpls == null ) {
-			tuplizerImpls = new HashMap();
-		}
-		tuplizerImpls.put( entityMode, implClassName );
-	}
-
-	public String getTuplizerImplClassName(EntityMode mode) {
-		if ( tuplizerImpls == null ) return null;
-		return ( String ) tuplizerImpls.get( mode );
-	}
-
-	public java.util.Map getTuplizerMap() {
-		if ( tuplizerImpls == null ) {
-			return null;
-		}
-		return java.util.Collections.unmodifiableMap( tuplizerImpls );
-	}
-
-	public boolean hasNaturalId() {
-		Iterator props = getRootClass().getPropertyIterator();
-		while ( props.hasNext() ) {
-			if ( ( (Property) props.next() ).isNaturalIdentifier() ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public abstract boolean isLazyPropertiesCacheable();
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,814 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.*;
+import java.util.Set;
+
+import org.hibernate.MappingException;
+import org.hibernate.EntityMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.sql.Alias;
+import org.hibernate.util.EmptyIterator;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.SingletonIterator;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Mapping for an entity.
+ *
+ * @author Gavin King
+ */
+public abstract class PersistentClass implements Serializable, Filterable, MetaAttributable {
+
+	private static final Alias PK_ALIAS = new Alias(15, "PK");
+
+	public static final String NULL_DISCRIMINATOR_MAPPING = "null";
+	public static final String NOT_NULL_DISCRIMINATOR_MAPPING = "not null";
+
+	private String entityName;
+
+	private String className;
+	private String proxyInterfaceName;
+	
+	private String nodeName;
+
+	private String discriminatorValue;
+	private boolean lazy;
+	private ArrayList properties = new ArrayList();
+	private final ArrayList subclasses = new ArrayList();
+	private final ArrayList subclassProperties = new ArrayList();
+	private final ArrayList subclassTables = new ArrayList();
+	private boolean dynamicInsert;
+	private boolean dynamicUpdate;
+	private int batchSize=-1;
+	private boolean selectBeforeUpdate;
+	private java.util.Map metaAttributes;
+	private ArrayList joins = new ArrayList();
+	private final ArrayList subclassJoins = new ArrayList();
+	private final java.util.Map filters = new HashMap();
+	protected final java.util.Set synchronizedTables = new HashSet();
+	private String loaderName;
+	private Boolean isAbstract;
+	private boolean hasSubselectLoadableCollections;
+	private Component identifierMapper;
+
+	// Custom SQL
+	private String customSQLInsert;
+	private boolean customInsertCallable;
+	private ExecuteUpdateResultCheckStyle insertCheckStyle;
+	private String customSQLUpdate;
+	private boolean customUpdateCallable;
+	private ExecuteUpdateResultCheckStyle updateCheckStyle;
+	private String customSQLDelete;
+	private boolean customDeleteCallable;
+	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
+
+	private String temporaryIdTableName;
+	private String temporaryIdTableDDL;
+
+	private java.util.Map tuplizerImpls;
+
+	protected int optimisticLockMode;
+
+	public String getClassName() {
+		return className;
+	}
+
+	public void setClassName(String className) {
+		this.className = className==null ? null : className.intern();
+	}
+
+	public String getProxyInterfaceName() {
+		return proxyInterfaceName;
+	}
+
+	public void setProxyInterfaceName(String proxyInterfaceName) {
+		this.proxyInterfaceName = proxyInterfaceName;
+	}
+
+	public Class getMappedClass() throws MappingException {
+		if (className==null) return null;
+		try {
+			return ReflectHelper.classForName(className);
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new MappingException("entity class not found: " + className, cnfe);
+		}
+	}
+
+	public Class getProxyInterface() {
+		if (proxyInterfaceName==null) return null;
+		try {
+			return ReflectHelper.classForName(proxyInterfaceName);
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new MappingException("proxy class not found: " + proxyInterfaceName, cnfe);
+		}
+	}
+	public boolean useDynamicInsert() {
+		return dynamicInsert;
+	}
+
+	abstract int nextSubclassId();
+	public abstract int getSubclassId();
+	
+	public boolean useDynamicUpdate() {
+		return dynamicUpdate;
+	}
+
+	public void setDynamicInsert(boolean dynamicInsert) {
+		this.dynamicInsert = dynamicInsert;
+	}
+
+	public void setDynamicUpdate(boolean dynamicUpdate) {
+		this.dynamicUpdate = dynamicUpdate;
+	}
+
+
+	public String getDiscriminatorValue() {
+		return discriminatorValue;
+	}
+
+	public void addSubclass(Subclass subclass) throws MappingException {
+		// inheritance cycle detection (paranoid check)
+		PersistentClass superclass = getSuperclass();
+		while (superclass!=null) {
+			if( subclass.getEntityName().equals( superclass.getEntityName() ) ) {
+				throw new MappingException(
+					"Circular inheritance mapping detected: " +
+					subclass.getEntityName() +
+					" will have it self as superclass when extending " +
+					getEntityName()
+				);
+			}
+			superclass = superclass.getSuperclass();
+		}
+		subclasses.add(subclass);
+	}
+
+	public boolean hasSubclasses() {
+		return subclasses.size() > 0;
+	}
+
+	public int getSubclassSpan() {
+		int n = subclasses.size();
+		Iterator iter = subclasses.iterator();
+		while ( iter.hasNext() ) {
+			n += ( (Subclass) iter.next() ).getSubclassSpan();
+		}
+		return n;
+	}
+	/**
+	 * Iterate over subclasses in a special 'order', most derived subclasses
+	 * first.
+	 */
+	public Iterator getSubclassIterator() {
+		Iterator[] iters = new Iterator[ subclasses.size() + 1 ];
+		Iterator iter = subclasses.iterator();
+		int i=0;
+		while ( iter.hasNext() ) {
+			iters[i++] = ( (Subclass) iter.next() ).getSubclassIterator();
+		}
+		iters[i] = subclasses.iterator();
+		return new JoinedIterator(iters);
+	}
+
+	public Iterator getSubclassClosureIterator() {
+		ArrayList iters = new ArrayList();
+		iters.add( new SingletonIterator(this) );
+		Iterator iter = getSubclassIterator();
+		while ( iter.hasNext() ) {
+			PersistentClass clazz = (PersistentClass)  iter.next();
+			iters.add( clazz.getSubclassClosureIterator() );
+		}
+		return new JoinedIterator(iters);
+	}
+	
+	public Table getIdentityTable() {
+		return getRootTable();
+	}
+	
+	public Iterator getDirectSubclasses() {
+		return subclasses.iterator();
+	}
+
+	public void addProperty(Property p) {
+		properties.add(p);
+		p.setPersistentClass(this);
+	}
+
+	public abstract Table getTable();
+
+	public String getEntityName() {
+		return entityName;
+	}
+
+	public abstract boolean isMutable();
+	public abstract boolean hasIdentifierProperty();
+	public abstract Property getIdentifierProperty();
+	public abstract KeyValue getIdentifier();
+	public abstract Property getVersion();
+	public abstract Value getDiscriminator();
+	public abstract boolean isInherited();
+	public abstract boolean isPolymorphic();
+	public abstract boolean isVersioned();
+	public abstract String getCacheConcurrencyStrategy();
+	public abstract PersistentClass getSuperclass();
+	public abstract boolean isExplicitPolymorphism();
+	public abstract boolean isDiscriminatorInsertable();
+
+	public abstract Iterator getPropertyClosureIterator();
+	public abstract Iterator getTableClosureIterator();
+	public abstract Iterator getKeyClosureIterator();
+
+	protected void addSubclassProperty(Property prop) {
+		subclassProperties.add(prop);
+	}
+	protected void addSubclassJoin(Join join) {
+		subclassJoins.add(join);
+	}
+	protected void addSubclassTable(Table subclassTable) {
+		subclassTables.add(subclassTable);
+	}
+	public Iterator getSubclassPropertyClosureIterator() {
+		ArrayList iters = new ArrayList();
+		iters.add( getPropertyClosureIterator() );
+		iters.add( subclassProperties.iterator() );
+		for ( int i=0; i<subclassJoins.size(); i++ ) {
+			Join join = (Join) subclassJoins.get(i);
+			iters.add( join.getPropertyIterator() );
+		}
+		return new JoinedIterator(iters);
+	}
+	public Iterator getSubclassJoinClosureIterator() {
+		return new JoinedIterator( getJoinClosureIterator(), subclassJoins.iterator() );
+	}
+	public Iterator getSubclassTableClosureIterator() {
+		return new JoinedIterator( getTableClosureIterator(), subclassTables.iterator() );
+	}
+
+	public boolean isClassOrSuperclassJoin(Join join) {
+		return joins.contains(join);
+	}
+
+	public boolean isClassOrSuperclassTable(Table closureTable) {
+		return getTable()==closureTable;
+	}
+
+	public boolean isLazy() {
+		return lazy;
+	}
+
+	public void setLazy(boolean lazy) {
+		this.lazy = lazy;
+	}
+
+	public abstract boolean hasEmbeddedIdentifier();
+	public abstract Class getEntityPersisterClass();
+	public abstract void setEntityPersisterClass(Class classPersisterClass);
+	public abstract Table getRootTable();
+	public abstract RootClass getRootClass();
+	public abstract KeyValue getKey();
+
+	public void setDiscriminatorValue(String discriminatorValue) {
+		this.discriminatorValue = discriminatorValue;
+	}
+
+	public void setEntityName(String entityName) {
+		this.entityName = entityName==null ? null : entityName.intern();
+	}
+
+	public void createPrimaryKey() {
+		//Primary key constraint
+		PrimaryKey pk = new PrimaryKey();
+		Table table = getTable();
+		pk.setTable(table);
+		pk.setName( PK_ALIAS.toAliasString( table.getName() ) );
+		table.setPrimaryKey(pk);
+
+		pk.addColumns( getKey().getColumnIterator() );
+	}
+
+	public abstract String getWhere();
+
+	public int getBatchSize() {
+		return batchSize;
+	}
+
+	public void setBatchSize(int batchSize) {
+		this.batchSize = batchSize;
+	}
+
+	public boolean hasSelectBeforeUpdate() {
+		return selectBeforeUpdate;
+	}
+
+	public void setSelectBeforeUpdate(boolean selectBeforeUpdate) {
+		this.selectBeforeUpdate = selectBeforeUpdate;
+	}
+
+	/**
+	 * Build an iterator of properties which are "referenceable".
+	 *
+	 * @see #getReferencedProperty for a discussion of "referenceable"
+	 * @return The property iterator.
+	 */
+	public Iterator getReferenceablePropertyIterator() {
+		return getPropertyClosureIterator();
+	}
+
+	/**
+	 * Given a property path, locate the appropriate referenceable property reference.
+	 * <p/>
+	 * A referenceable property is a property  which can be a target of a foreign-key
+	 * mapping (an identifier or explcitly named in a property-ref).
+	 *
+	 * @param propertyPath The property path to resolve into a property reference.
+	 * @return The property reference (never null).
+	 * @throws MappingException If the property could not be found.
+	 */
+	public Property getReferencedProperty(String propertyPath) throws MappingException {
+		try {
+			return getRecursiveProperty( propertyPath, getReferenceablePropertyIterator() );
+		}
+		catch ( MappingException e ) {
+			throw new MappingException(
+					"property-ref [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
+			);
+		}
+	}
+
+	public Property getRecursiveProperty(String propertyPath) throws MappingException {
+		try {
+			return getRecursiveProperty( propertyPath, getPropertyIterator() );
+		}
+		catch ( MappingException e ) {
+			throw new MappingException(
+					"property [" + propertyPath + "] not found on entity [" + getEntityName() + "]", e
+			);
+		}
+	}
+
+	private Property getRecursiveProperty(String propertyPath, Iterator iter) throws MappingException {
+		Property property = null;
+		StringTokenizer st = new StringTokenizer( propertyPath, ".", false );
+		try {
+			while ( st.hasMoreElements() ) {
+				final String element = ( String ) st.nextElement();
+				if ( property == null ) {
+					Property identifierProperty = getIdentifierProperty();
+					if ( identifierProperty != null && identifierProperty.getName().equals( element ) ) {
+						// we have a mapped identifier property and the root of
+						// the incoming property path matched that identifier
+						// property
+						property = identifierProperty;
+					}
+					else if ( identifierProperty == null && getIdentifierMapper() != null ) {
+						// we have an embedded composite identifier
+						try {
+							identifierProperty = getProperty( element, getIdentifierMapper().getPropertyIterator() );
+							if ( identifierProperty != null ) {
+								// the root of the incoming property path matched one
+								// of the embedded composite identifier properties
+								property = identifierProperty;
+							}
+						}
+						catch( MappingException ignore ) {
+							// ignore it...
+						}
+					}
+
+					if ( property == null ) {
+						property = getProperty( element, iter );
+					}
+				}
+				else {
+					//flat recursive algorithm
+					property = ( ( Component ) property.getValue() ).getProperty( element );
+				}
+			}
+		}
+		catch ( MappingException e ) {
+			throw new MappingException( "property [" + propertyPath + "] not found on entity [" + getEntityName() + "]" );
+		}
+
+		return property;
+	}
+
+	private Property getProperty(String propertyName, Iterator iterator) throws MappingException {
+		while ( iterator.hasNext() ) {
+			Property prop = (Property) iterator.next();
+			if ( prop.getName().equals( StringHelper.root(propertyName) ) ) {
+				return prop;
+			}
+		}
+		throw new MappingException( "property [" + propertyName + "] not found on entity [" + getEntityName() + "]" );
+	}
+
+	public Property getProperty(String propertyName) throws MappingException {
+		Iterator iter = getPropertyClosureIterator();
+		Property identifierProperty = getIdentifierProperty();
+		if ( identifierProperty != null
+				&& identifierProperty.getName().equals( StringHelper.root(propertyName) )
+				) {
+			return identifierProperty;
+		}
+		else {
+			return getProperty( propertyName, iter );
+		}
+	}
+
+	abstract public int getOptimisticLockMode();
+
+	public void setOptimisticLockMode(int optimisticLockMode) {
+		this.optimisticLockMode = optimisticLockMode;
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		Iterator iter = getPropertyIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			if ( !prop.isValid(mapping) ) {
+				throw new MappingException(
+						"property mapping has wrong number of columns: " +
+						StringHelper.qualify( getEntityName(), prop.getName() ) +
+						" type: " +
+						prop.getType().getName()
+					);
+			}
+		}
+		checkPropertyDuplication();
+		checkColumnDuplication();
+	}
+	
+	private void checkPropertyDuplication() throws MappingException {
+		HashSet names = new HashSet();
+		Iterator iter = getPropertyIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			if ( !names.add( prop.getName() ) ) {
+				throw new MappingException( "Duplicate property mapping of " + prop.getName() + " found in " + getEntityName());
+			}
+		}
+	}
+
+	public boolean isDiscriminatorValueNotNull() {
+		return NOT_NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
+	}
+	public boolean isDiscriminatorValueNull() {
+		return NULL_DISCRIMINATOR_MAPPING.equals( getDiscriminatorValue() );
+	}
+
+	public java.util.Map getMetaAttributes() {
+		return metaAttributes;
+	}
+
+	public void setMetaAttributes(java.util.Map metas) {
+		this.metaAttributes = metas;
+	}
+
+	public MetaAttribute getMetaAttribute(String name) {
+		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(name);
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getEntityName() + ')';
+	}
+	
+	public Iterator getJoinIterator() {
+		return joins.iterator();
+	}
+
+	public Iterator getJoinClosureIterator() {
+		return joins.iterator();
+	}
+
+	public void addJoin(Join join) {
+		joins.add(join);
+		join.setPersistentClass(this);
+	}
+
+	public int getJoinClosureSpan() {
+		return joins.size();
+	}
+
+	public int getPropertyClosureSpan() {
+		int span = properties.size();
+		for ( int i=0; i<joins.size(); i++ ) {
+			Join join = (Join) joins.get(i);
+			span += join.getPropertySpan();
+		}
+		return span;
+	}
+
+	public int getJoinNumber(Property prop) {
+		int result=1;
+		Iterator iter = getSubclassJoinClosureIterator();
+		while ( iter.hasNext() ) {
+			Join join = (Join) iter.next();
+			if ( join.containsProperty(prop) ) return result;
+			result++;
+		}
+		return 0;
+	}
+
+	/**
+	 * Build an iterator over the properties defined on this class.  The returned
+	 * iterator only accounts for "normal" properties (i.e. non-identifier
+	 * properties).
+	 * <p/>
+	 * Differs from {@link #getUnjoinedPropertyIterator} in that the iterator
+	 * we return here will include properties defined as part of a join.
+	 *
+	 * @return An iterator over the "normal" properties.
+	 */
+	public Iterator getPropertyIterator() {
+		ArrayList iterators = new ArrayList();
+		iterators.add( properties.iterator() );
+		for ( int i = 0; i < joins.size(); i++ ) {
+			Join join = ( Join ) joins.get( i );
+			iterators.add( join.getPropertyIterator() );
+		}
+		return new JoinedIterator( iterators );
+	}
+
+	/**
+	 * Build an iterator over the properties defined on this class <b>which
+	 * are not defined as part of a join</b>.  As with {@link #getPropertyIterator},
+	 * the returned iterator only accounts for non-identifier properties.
+	 *
+	 * @return An iterator over the non-joined "normal" properties.
+	 */
+	public Iterator getUnjoinedPropertyIterator() {
+		return properties.iterator();
+	}
+
+	public void setCustomSQLInsert(String customSQLInsert, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLInsert = customSQLInsert;
+		this.customInsertCallable = callable;
+		this.insertCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLInsert() {
+		return customSQLInsert;
+	}
+
+	public boolean isCustomInsertCallable() {
+		return customInsertCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLInsertCheckStyle() {
+		return insertCheckStyle;
+	}
+
+	public void setCustomSQLUpdate(String customSQLUpdate, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLUpdate = customSQLUpdate;
+		this.customUpdateCallable = callable;
+		this.updateCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLUpdate() {
+		return customSQLUpdate;
+	}
+
+	public boolean isCustomUpdateCallable() {
+		return customUpdateCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLUpdateCheckStyle() {
+		return updateCheckStyle;
+	}
+
+	public void setCustomSQLDelete(String customSQLDelete, boolean callable, ExecuteUpdateResultCheckStyle checkStyle) {
+		this.customSQLDelete = customSQLDelete;
+		this.customDeleteCallable = callable;
+		this.deleteCheckStyle = checkStyle;
+	}
+
+	public String getCustomSQLDelete() {
+		return customSQLDelete;
+	}
+
+	public boolean isCustomDeleteCallable() {
+		return customDeleteCallable;
+	}
+
+	public ExecuteUpdateResultCheckStyle getCustomSQLDeleteCheckStyle() {
+		return deleteCheckStyle;
+	}
+
+	public void addFilter(String name, String condition) {
+		filters.put(name, condition);
+	}
+
+	public java.util.Map getFilterMap() {
+		return filters;
+	}
+
+	public boolean isForceDiscriminator() {
+		return false;
+	}
+
+	public abstract boolean isJoinedSubclass();
+
+	public String getLoaderName() {
+		return loaderName;
+	}
+
+	public void setLoaderName(String loaderName) {
+		this.loaderName = loaderName==null ? null : loaderName.intern();
+	}
+
+	public abstract java.util.Set getSynchronizedTables();
+	
+	public void addSynchronizedTable(String table) {
+		synchronizedTables.add(table);
+	}
+
+	public Boolean isAbstract() {
+		return isAbstract;
+	}
+
+	public void setAbstract(Boolean isAbstract) {
+		this.isAbstract = isAbstract;
+	}
+
+	protected void checkColumnDuplication(Set distinctColumns, Iterator columns) 
+	throws MappingException {
+		while ( columns.hasNext() ) {
+			Selectable columnOrFormula = (Selectable) columns.next();
+			if ( !columnOrFormula.isFormula() ) {
+				Column col = (Column) columnOrFormula;
+				if ( !distinctColumns.add( col.getName() ) ) {
+					throw new MappingException( 
+							"Repeated column in mapping for entity: " +
+							getEntityName() +
+							" column: " +
+							col.getName() + 
+							" (should be mapped with insert=\"false\" update=\"false\")"
+						);
+				}
+			}
+		}
+	}
+	
+	protected void checkPropertyColumnDuplication(Set distinctColumns, Iterator properties) 
+	throws MappingException {
+		while ( properties.hasNext() ) {
+			Property prop = (Property) properties.next();
+			if ( prop.getValue() instanceof Component ) { //TODO: remove use of instanceof!
+				Component component = (Component) prop.getValue();
+				checkPropertyColumnDuplication( distinctColumns, component.getPropertyIterator() );
+			}
+			else {
+				if ( prop.isUpdateable() || prop.isInsertable() ) {
+					checkColumnDuplication( distinctColumns, prop.getColumnIterator() );
+				}
+			}
+		}
+	}
+	
+	protected Iterator getNonDuplicatedPropertyIterator() {
+		return getUnjoinedPropertyIterator();
+	}
+	
+	protected Iterator getDiscriminatorColumnIterator() {
+		return EmptyIterator.INSTANCE;
+	}
+	
+	protected void checkColumnDuplication() {
+		HashSet cols = new HashSet();
+		if (getIdentifierMapper() == null ) {
+			//an identifier mapper => getKey will be included in the getNonDuplicatedPropertyIterator()
+			//and checked later, so it needs to be excluded
+			checkColumnDuplication( cols, getKey().getColumnIterator() );
+		}
+		checkColumnDuplication( cols, getDiscriminatorColumnIterator() );
+		checkPropertyColumnDuplication( cols, getNonDuplicatedPropertyIterator() );
+		Iterator iter = getJoinIterator();
+		while ( iter.hasNext() ) {
+			cols.clear();
+			Join join = (Join) iter.next();
+			checkColumnDuplication( cols, join.getKey().getColumnIterator() );
+			checkPropertyColumnDuplication( cols, join.getPropertyIterator() );
+		}
+	}
+	
+	public abstract Object accept(PersistentClassVisitor mv);
+	
+	public String getNodeName() {
+		return nodeName;
+	}
+	
+	public void setNodeName(String nodeName) {
+		this.nodeName = nodeName;
+	}
+	
+	public boolean hasPojoRepresentation() {
+		return getClassName()!=null;
+	}
+
+	public boolean hasDom4jRepresentation() {
+		return getNodeName()!=null;
+	}
+
+	public boolean hasSubselectLoadableCollections() {
+		return hasSubselectLoadableCollections;
+	}
+	
+	public void setSubselectLoadableCollections(boolean hasSubselectCollections) {
+		this.hasSubselectLoadableCollections = hasSubselectCollections;
+	}
+
+	public void prepareTemporaryTables(Mapping mapping, Dialect dialect) {
+		if ( dialect.supportsTemporaryTables() ) {
+			temporaryIdTableName = dialect.generateTemporaryTableName( getTable().getName() );
+			Table table = new Table();
+			table.setName( temporaryIdTableName );
+			Iterator itr = getTable().getPrimaryKey().getColumnIterator();
+			while( itr.hasNext() ) {
+				Column column = (Column) itr.next();
+				table.addColumn( (Column) column.clone()  );
+			}
+			temporaryIdTableDDL = table.sqlTemporaryTableCreateString( dialect, mapping );
+		}
+	}
+
+	public String getTemporaryIdTableName() {
+		return temporaryIdTableName;
+	}
+
+	public String getTemporaryIdTableDDL() {
+		return temporaryIdTableDDL;
+	}
+
+	public Component getIdentifierMapper() {
+		return identifierMapper;
+	}
+
+	public boolean hasIdentifierMapper() {
+		return identifierMapper != null;
+	}
+
+	public void setIdentifierMapper(Component handle) {
+		this.identifierMapper = handle;
+	}
+
+	public void addTuplizer(EntityMode entityMode, String implClassName) {
+		if ( tuplizerImpls == null ) {
+			tuplizerImpls = new HashMap();
+		}
+		tuplizerImpls.put( entityMode, implClassName );
+	}
+
+	public String getTuplizerImplClassName(EntityMode mode) {
+		if ( tuplizerImpls == null ) return null;
+		return ( String ) tuplizerImpls.get( mode );
+	}
+
+	public java.util.Map getTuplizerMap() {
+		if ( tuplizerImpls == null ) {
+			return null;
+		}
+		return java.util.Collections.unmodifiableMap( tuplizerImpls );
+	}
+
+	public boolean hasNaturalId() {
+		Iterator props = getRootClass().getPropertyIterator();
+		while ( props.hasNext() ) {
+			if ( ( (Property) props.next() ).isNaturalIdentifier() ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public abstract boolean isLazyPropertiesCacheable();
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-/*
- * Created on 07-Dec-2004
- *
- */
-package org.hibernate.mapping;
-
-/**
- * @author max
- *
- */
-public interface PersistentClassVisitor {
-
-	/**
-	 * @param class1
-	 * @return
-	 */
-	Object accept(RootClass class1);
-
-	/**
-	 * @param subclass
-	 * @return
-	 */
-	Object accept(UnionSubclass subclass);
-
-	/**
-	 * @param subclass
-	 * @return
-	 */
-	Object accept(SingleTableSubclass subclass);
-
-	/**
-	 * @param subclass
-	 * @return
-	 */
-	Object accept(JoinedSubclass subclass);
-
-	/**
-	 * @param subclass
-	 * @return
-	 */
-	Object accept(Subclass subclass);
-
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PersistentClassVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+/**
+ * @author max
+ *
+ */
+public interface PersistentClassVisitor {
+
+	/**
+	 * @param class1
+	 * @return
+	 */
+	Object accept(RootClass class1);
+
+	/**
+	 * @param subclass
+	 * @return
+	 */
+	Object accept(UnionSubclass subclass);
+
+	/**
+	 * @param subclass
+	 * @return
+	 */
+	Object accept(SingleTableSubclass subclass);
+
+	/**
+	 * @param subclass
+	 * @return
+	 */
+	Object accept(JoinedSubclass subclass);
+
+	/**
+	 * @param subclass
+	 * @return
+	 */
+	Object accept(Subclass subclass);
+
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PrimaryKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: PrimaryKey.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * A primary key constraint
- * @author Gavin King
- */
-public class PrimaryKey extends Constraint {
-
-	public String sqlConstraintString(Dialect dialect) {
-		StringBuffer buf = new StringBuffer("primary key (");
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
-			if ( iter.hasNext() ) buf.append(", ");
-		}
-		return buf.append(')').toString();
-	}
-
-	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) {
-		StringBuffer buf = new StringBuffer(
-			dialect.getAddPrimaryKeyConstraintString(constraintName)
-		).append('(');
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
-			if ( iter.hasNext() ) buf.append(", ");
-		}
-		return buf.append(')').toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/PrimaryKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimaryKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A primary key constraint
+ * @author Gavin King
+ */
+public class PrimaryKey extends Constraint {
+
+	public String sqlConstraintString(Dialect dialect) {
+		StringBuffer buf = new StringBuffer("primary key (");
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
+			if ( iter.hasNext() ) buf.append(", ");
+		}
+		return buf.append(')').toString();
+	}
+
+	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog, String defaultSchema) {
+		StringBuffer buf = new StringBuffer(
+			dialect.getAddPrimaryKeyConstraintString(constraintName)
+		).append('(');
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			buf.append( ( (Column) iter.next() ).getQuotedName(dialect) );
+			if ( iter.hasNext() ) buf.append(", ");
+		}
+		return buf.append(')').toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: PrimitiveArray.java 4905 2004-12-07 09:59:56Z maxcsaucdk $
-package org.hibernate.mapping;
-
-/**
- * A primitive array has a primary key consisting
- * of the key columns + index column.
- */
-public class PrimitiveArray extends Array {
-
-	public PrimitiveArray(PersistentClass owner) {
-		super(owner);
-	}
-
-	public boolean isPrimitiveArray() {
-		return true;
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PrimitiveArray.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,51 @@
+/*
+ * 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.mapping;
+
+/**
+ * A primitive array has a primary key consisting
+ * of the key columns + index column.
+ */
+public class PrimitiveArray extends Array {
+
+	public PrimitiveArray(PersistentClass owner) {
+		super(owner);
+	}
+
+	public boolean isPrimitiveArray() {
+		return true;
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Property.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,292 +0,0 @@
-//$Id: Property.java 10245 2006-08-11 18:38:39Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.StringTokenizer;
-
-import org.hibernate.MappingException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.EntityMode;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.Mapping;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Represents a property as part of an entity or a component.
- *
- * @author Gavin King
- */
-public class Property implements Serializable, MetaAttributable {
-
-	private String name;
-	private Value value;
-	private String cascade;
-	private boolean updateable = true;
-	private boolean insertable = true;
-	private boolean selectable = true;
-	private boolean optimisticLocked = true;
-	private PropertyGeneration generation = PropertyGeneration.NEVER;
-	private String propertyAccessorName;
-	private boolean lazy;
-	private boolean optional;
-	private String nodeName;
-	private java.util.Map metaAttributes;
-	private PersistentClass persistentClass;
-	private boolean naturalIdentifier;
-	
-	public boolean isBackRef() {
-		return false;
-	}
-
-	public Type getType() throws MappingException {
-		return value.getType();
-	}
-	
-	public int getColumnSpan() {
-		return value.getColumnSpan();
-	}
-	
-	public Iterator getColumnIterator() {
-		return value.getColumnIterator();
-	}
-	
-	public String getName() {
-		return name;
-	}
-	
-	public boolean isComposite() {
-		return value instanceof Component;
-	}
-
-	public Value getValue() {
-		return value;
-	}
-	
-	public boolean isPrimitive(Class clazz) {
-		return getGetter(clazz).getReturnType().isPrimitive();
-	}
-
-	public CascadeStyle getCascadeStyle() throws MappingException {
-		Type type = value.getType();
-		if ( type.isComponentType() && !type.isAnyType() ) {
-			AbstractComponentType actype = (AbstractComponentType) type;
-			int length = actype.getSubtypes().length;
-			for ( int i=0; i<length; i++ ) {
-				if ( actype.getCascadeStyle(i)!=CascadeStyle.NONE ) return CascadeStyle.ALL;
-			}
-			return CascadeStyle.NONE;
-		}
-		else if ( cascade==null || cascade.equals("none") ) {
-			return CascadeStyle.NONE;
-		}
-		else {
-			StringTokenizer tokens = new StringTokenizer(cascade, ", ");
-			CascadeStyle[] styles = new CascadeStyle[ tokens.countTokens() ] ;
-			int i=0;
-			while ( tokens.hasMoreTokens() ) {
-				styles[i++] = CascadeStyle.getCascadeStyle( tokens.nextToken() );
-			}
-			return new CascadeStyle.MultipleCascadeStyle(styles);
-		}
-	}
-
-	public String getCascade() {
-		return cascade;
-	}
-
-	public void setCascade(String cascade) {
-		this.cascade = cascade;
-	}
-
-	public void setName(String name) {
-		this.name = name==null ? null : name.intern();
-	}
-
-	public void setValue(Value value) {
-		this.value = value;
-	}
-
-	public boolean isUpdateable() {
-		// if the property mapping consists of all formulas, 
-		// make it non-updateable
-		final boolean[] columnUpdateability = value.getColumnUpdateability();
-		return updateable && ( 
-				//columnUpdateability.length==0 ||
-				!ArrayHelper.isAllFalse(columnUpdateability)
-			);
-	}
-
-	public boolean isInsertable() {
-		// if the property mapping consists of all formulas, 
-		// make it insertable
-		final boolean[] columnInsertability = value.getColumnInsertability();
-		return insertable && (
-				columnInsertability.length==0 ||
-				!ArrayHelper.isAllFalse(columnInsertability)
-			);
-	}
-
-    public PropertyGeneration getGeneration() {
-        return generation;
-    }
-
-    public void setGeneration(PropertyGeneration generation) {
-        this.generation = generation;
-    }
-
-    public void setUpdateable(boolean mutable) {
-		this.updateable = mutable;
-	}
-
-	public void setInsertable(boolean insertable) {
-		this.insertable = insertable;
-	}
-
-	public String getPropertyAccessorName() {
-		return propertyAccessorName;
-	}
-
-	public void setPropertyAccessorName(String string) {
-		propertyAccessorName = string;
-	}
-
-	/**
-	 * Approximate!
-	 */
-	boolean isNullable() {
-		return value==null || value.isNullable();
-	}
-
-	public boolean isBasicPropertyAccessor() {
-		return propertyAccessorName==null || "property".equals(propertyAccessorName);
-	}
-
-	public java.util.Map getMetaAttributes() {
-		return metaAttributes;
-	}
-
-	public MetaAttribute getMetaAttribute(String attributeName) {
-		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
-	}
-
-	public void setMetaAttributes(java.util.Map metas) {
-		this.metaAttributes = metas;
-	}
-
-	public boolean isValid(Mapping mapping) throws MappingException {
-		return getValue().isValid(mapping);
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + name + ')';
-	}
-	
-	public void setLazy(boolean lazy) {
-		this.lazy=lazy;
-	}
-	
-	public boolean isLazy() {
-		if ( value instanceof ToOne ) {
-			// both many-to-one and one-to-one are represented as a
-			// Property.  EntityPersister is relying on this value to
-			// determine "lazy fetch groups" in terms of field-level
-			// interception.  So we need to make sure that we return
-			// true here for the case of many-to-one and one-to-one
-			// with lazy="no-proxy"
-			//
-			// * impl note - lazy="no-proxy" currently forces both
-			// lazy and unwrap to be set to true.  The other case we
-			// are extremely interested in here is that of lazy="proxy"
-			// where lazy is set to true, but unwrap is set to false.
-			// thus we use both here under the assumption that this
-			// return is really only ever used during persister
-			// construction to determine the lazy property/field fetch
-			// groupings.  If that assertion changes then this check
-			// needs to change as well.  Partially, this is an issue with
-			// the overloading of the term "lazy" here...
-			ToOne toOneValue = ( ToOne ) value;
-			return toOneValue.isLazy() && toOneValue.isUnwrapProxy();
-		}
-		return lazy;
-	}
-	
-	public boolean isOptimisticLocked() {
-		return optimisticLocked;
-	}
-
-	public void setOptimisticLocked(boolean optimisticLocked) {
-		this.optimisticLocked = optimisticLocked;
-	}
-	
-	public boolean isOptional() {
-		return optional || isNullable();
-	}
-	
-	public void setOptional(boolean optional) {
-		this.optional = optional;
-	}
-
-	public PersistentClass getPersistentClass() {
-		return persistentClass;
-	}
-
-	public void setPersistentClass(PersistentClass persistentClass) {
-		this.persistentClass = persistentClass;
-	}
-
-	public boolean isSelectable() {
-		return selectable;
-	}
-	
-	public void setSelectable(boolean selectable) {
-		this.selectable = selectable;
-	}
-
-	public String getNodeName() {
-		return nodeName;
-	}
-
-	public void setNodeName(String nodeName) {
-		this.nodeName = nodeName;
-	}
-
-	public String getAccessorPropertyName( EntityMode mode ) {
-		if ( mode == EntityMode.DOM4J ) {
-			return nodeName;
-		}
-		else {
-			return getName();
-		}
-	}
-
-	// todo : remove
-	public Getter getGetter(Class clazz) throws PropertyNotFoundException, MappingException {
-		return getPropertyAccessor(clazz).getGetter(clazz, name);
-	}
-
-	// todo : remove
-	public Setter getSetter(Class clazz) throws PropertyNotFoundException, MappingException {
-		return getPropertyAccessor(clazz).getSetter(clazz, name);
-	}
-
-	// todo : remove
-	public PropertyAccessor getPropertyAccessor(Class clazz) throws MappingException {
-		return PropertyAccessorFactory.getPropertyAccessor( clazz, getPropertyAccessorName() );
-	}
-
-	public boolean isNaturalIdentifier() {
-		return naturalIdentifier;
-	}
-
-	public void setNaturalIdentifier(boolean naturalIdentifier) {
-		this.naturalIdentifier = naturalIdentifier;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Property.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,314 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.StringTokenizer;
+
+import org.hibernate.MappingException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.Mapping;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Represents a property as part of an entity or a component.
+ *
+ * @author Gavin King
+ */
+public class Property implements Serializable, MetaAttributable {
+
+	private String name;
+	private Value value;
+	private String cascade;
+	private boolean updateable = true;
+	private boolean insertable = true;
+	private boolean selectable = true;
+	private boolean optimisticLocked = true;
+	private PropertyGeneration generation = PropertyGeneration.NEVER;
+	private String propertyAccessorName;
+	private boolean lazy;
+	private boolean optional;
+	private String nodeName;
+	private java.util.Map metaAttributes;
+	private PersistentClass persistentClass;
+	private boolean naturalIdentifier;
+	
+	public boolean isBackRef() {
+		return false;
+	}
+
+	public Type getType() throws MappingException {
+		return value.getType();
+	}
+	
+	public int getColumnSpan() {
+		return value.getColumnSpan();
+	}
+	
+	public Iterator getColumnIterator() {
+		return value.getColumnIterator();
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public boolean isComposite() {
+		return value instanceof Component;
+	}
+
+	public Value getValue() {
+		return value;
+	}
+	
+	public boolean isPrimitive(Class clazz) {
+		return getGetter(clazz).getReturnType().isPrimitive();
+	}
+
+	public CascadeStyle getCascadeStyle() throws MappingException {
+		Type type = value.getType();
+		if ( type.isComponentType() && !type.isAnyType() ) {
+			AbstractComponentType actype = (AbstractComponentType) type;
+			int length = actype.getSubtypes().length;
+			for ( int i=0; i<length; i++ ) {
+				if ( actype.getCascadeStyle(i)!=CascadeStyle.NONE ) return CascadeStyle.ALL;
+			}
+			return CascadeStyle.NONE;
+		}
+		else if ( cascade==null || cascade.equals("none") ) {
+			return CascadeStyle.NONE;
+		}
+		else {
+			StringTokenizer tokens = new StringTokenizer(cascade, ", ");
+			CascadeStyle[] styles = new CascadeStyle[ tokens.countTokens() ] ;
+			int i=0;
+			while ( tokens.hasMoreTokens() ) {
+				styles[i++] = CascadeStyle.getCascadeStyle( tokens.nextToken() );
+			}
+			return new CascadeStyle.MultipleCascadeStyle(styles);
+		}
+	}
+
+	public String getCascade() {
+		return cascade;
+	}
+
+	public void setCascade(String cascade) {
+		this.cascade = cascade;
+	}
+
+	public void setName(String name) {
+		this.name = name==null ? null : name.intern();
+	}
+
+	public void setValue(Value value) {
+		this.value = value;
+	}
+
+	public boolean isUpdateable() {
+		// if the property mapping consists of all formulas, 
+		// make it non-updateable
+		final boolean[] columnUpdateability = value.getColumnUpdateability();
+		return updateable && ( 
+				//columnUpdateability.length==0 ||
+				!ArrayHelper.isAllFalse(columnUpdateability)
+			);
+	}
+
+	public boolean isInsertable() {
+		// if the property mapping consists of all formulas, 
+		// make it insertable
+		final boolean[] columnInsertability = value.getColumnInsertability();
+		return insertable && (
+				columnInsertability.length==0 ||
+				!ArrayHelper.isAllFalse(columnInsertability)
+			);
+	}
+
+    public PropertyGeneration getGeneration() {
+        return generation;
+    }
+
+    public void setGeneration(PropertyGeneration generation) {
+        this.generation = generation;
+    }
+
+    public void setUpdateable(boolean mutable) {
+		this.updateable = mutable;
+	}
+
+	public void setInsertable(boolean insertable) {
+		this.insertable = insertable;
+	}
+
+	public String getPropertyAccessorName() {
+		return propertyAccessorName;
+	}
+
+	public void setPropertyAccessorName(String string) {
+		propertyAccessorName = string;
+	}
+
+	/**
+	 * Approximate!
+	 */
+	boolean isNullable() {
+		return value==null || value.isNullable();
+	}
+
+	public boolean isBasicPropertyAccessor() {
+		return propertyAccessorName==null || "property".equals(propertyAccessorName);
+	}
+
+	public java.util.Map getMetaAttributes() {
+		return metaAttributes;
+	}
+
+	public MetaAttribute getMetaAttribute(String attributeName) {
+		return metaAttributes==null?null:(MetaAttribute) metaAttributes.get(attributeName);
+	}
+
+	public void setMetaAttributes(java.util.Map metas) {
+		this.metaAttributes = metas;
+	}
+
+	public boolean isValid(Mapping mapping) throws MappingException {
+		return getValue().isValid(mapping);
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + name + ')';
+	}
+	
+	public void setLazy(boolean lazy) {
+		this.lazy=lazy;
+	}
+	
+	public boolean isLazy() {
+		if ( value instanceof ToOne ) {
+			// both many-to-one and one-to-one are represented as a
+			// Property.  EntityPersister is relying on this value to
+			// determine "lazy fetch groups" in terms of field-level
+			// interception.  So we need to make sure that we return
+			// true here for the case of many-to-one and one-to-one
+			// with lazy="no-proxy"
+			//
+			// * impl note - lazy="no-proxy" currently forces both
+			// lazy and unwrap to be set to true.  The other case we
+			// are extremely interested in here is that of lazy="proxy"
+			// where lazy is set to true, but unwrap is set to false.
+			// thus we use both here under the assumption that this
+			// return is really only ever used during persister
+			// construction to determine the lazy property/field fetch
+			// groupings.  If that assertion changes then this check
+			// needs to change as well.  Partially, this is an issue with
+			// the overloading of the term "lazy" here...
+			ToOne toOneValue = ( ToOne ) value;
+			return toOneValue.isLazy() && toOneValue.isUnwrapProxy();
+		}
+		return lazy;
+	}
+	
+	public boolean isOptimisticLocked() {
+		return optimisticLocked;
+	}
+
+	public void setOptimisticLocked(boolean optimisticLocked) {
+		this.optimisticLocked = optimisticLocked;
+	}
+	
+	public boolean isOptional() {
+		return optional || isNullable();
+	}
+	
+	public void setOptional(boolean optional) {
+		this.optional = optional;
+	}
+
+	public PersistentClass getPersistentClass() {
+		return persistentClass;
+	}
+
+	public void setPersistentClass(PersistentClass persistentClass) {
+		this.persistentClass = persistentClass;
+	}
+
+	public boolean isSelectable() {
+		return selectable;
+	}
+	
+	public void setSelectable(boolean selectable) {
+		this.selectable = selectable;
+	}
+
+	public String getNodeName() {
+		return nodeName;
+	}
+
+	public void setNodeName(String nodeName) {
+		this.nodeName = nodeName;
+	}
+
+	public String getAccessorPropertyName( EntityMode mode ) {
+		if ( mode == EntityMode.DOM4J ) {
+			return nodeName;
+		}
+		else {
+			return getName();
+		}
+	}
+
+	// todo : remove
+	public Getter getGetter(Class clazz) throws PropertyNotFoundException, MappingException {
+		return getPropertyAccessor(clazz).getGetter(clazz, name);
+	}
+
+	// todo : remove
+	public Setter getSetter(Class clazz) throws PropertyNotFoundException, MappingException {
+		return getPropertyAccessor(clazz).getSetter(clazz, name);
+	}
+
+	// todo : remove
+	public PropertyAccessor getPropertyAccessor(Class clazz) throws MappingException {
+		return PropertyAccessorFactory.getPropertyAccessor( clazz, getPropertyAccessorName() );
+	}
+
+	public boolean isNaturalIdentifier() {
+		return naturalIdentifier;
+	}
+
+	public void setNaturalIdentifier(boolean naturalIdentifier) {
+		this.naturalIdentifier = naturalIdentifier;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-
-/**
- * Indicates whether given properties are generated by the database and, if
- * so, at what time(s) they are generated.
- *
- * @author Steve Ebersole
- */
-public class PropertyGeneration implements Serializable {
-
-	/**
-	 * Values for this property are never generated by the database.
-	 */
-	public static final PropertyGeneration NEVER = new PropertyGeneration( "never" );
-	/**
-	 * Values for this property are generated by the database on insert.
-	 */
-	public static final PropertyGeneration INSERT = new PropertyGeneration( "insert" );
-	/**
-	 * Values for this property are generated by the database on both insert and update.
-	 */
-	public static final PropertyGeneration ALWAYS = new PropertyGeneration( "always" );
-
-	private final String name;
-
-	private PropertyGeneration(String name) {
-		this.name = name;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public static PropertyGeneration parse(String name) {
-		if ( "insert".equalsIgnoreCase( name ) ) {
-			return INSERT;
-		}
-		else if ( "always".equalsIgnoreCase( name ) ) {
-			return ALWAYS;
-		}
-		else {
-			return NEVER;
-		}
-	}
-
-	private Object readResolve() {
-		return parse( name );
-	}
-	
-	public String toString() {
-		return getClass().getName() + "(" + getName() + ")";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/PropertyGeneration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.io.Serializable;
+
+/**
+ * Indicates whether given properties are generated by the database and, if
+ * so, at what time(s) they are generated.
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyGeneration implements Serializable {
+
+	/**
+	 * Values for this property are never generated by the database.
+	 */
+	public static final PropertyGeneration NEVER = new PropertyGeneration( "never" );
+	/**
+	 * Values for this property are generated by the database on insert.
+	 */
+	public static final PropertyGeneration INSERT = new PropertyGeneration( "insert" );
+	/**
+	 * Values for this property are generated by the database on both insert and update.
+	 */
+	public static final PropertyGeneration ALWAYS = new PropertyGeneration( "always" );
+
+	private final String name;
+
+	private PropertyGeneration(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public static PropertyGeneration parse(String name) {
+		if ( "insert".equalsIgnoreCase( name ) ) {
+			return INSERT;
+		}
+		else if ( "always".equalsIgnoreCase( name ) ) {
+			return ALWAYS;
+		}
+		else {
+			return NEVER;
+		}
+	}
+
+	private Object readResolve() {
+		return parse( name );
+	}
+	
+	public String toString() {
+		return getClass().getName() + "(" + getName() + ")";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/RelationalModel.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: RelationalModel.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.mapping;
-
-import org.hibernate.engine.Mapping;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * A relational object which may be created using DDL
- * @author Gavin King
- */
-public interface RelationalModel {
-	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) throws HibernateException;
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/RelationalModel.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RelationalModel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.engine.Mapping;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A relational object which may be created using DDL
+ * @author Gavin King
+ */
+public interface RelationalModel {
+	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) throws HibernateException;
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,276 +0,0 @@
-//$Id: RootClass.java 8698 2005-11-29 14:34:11Z steveebersole $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import org.slf4j.LoggerFactory;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.SingletonIterator;
-
-/**
- * The root class of an inheritance hierarchy
- * @author Gavin King
- */
-public class RootClass extends PersistentClass implements TableOwner {
-
-	public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
-	public static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "class";
-
-	private Property identifierProperty; //may be final
-	private KeyValue identifier; //may be final
-	private Property version; //may be final
-	private boolean polymorphic;
-	private String cacheConcurrencyStrategy;
-	private String cacheRegionName;
-	private boolean lazyPropertiesCacheable = true;
-	private Value discriminator; //may be final
-	private boolean mutable = true;
-	private boolean embeddedIdentifier = false; // may be final
-	private boolean explicitPolymorphism;
-	private Class entityPersisterClass;
-	private boolean forceDiscriminator = false;
-	private String where;
-	private Table table;
-	private boolean discriminatorInsertable = true;
-	private int nextSubclassId = 0;
-		
-	int nextSubclassId() {
-		return ++nextSubclassId;
-	}
-
-	public int getSubclassId() {
-		return 0;
-	}
-	
-	public void setTable(Table table) {
-		this.table=table;
-	}
-	public Table getTable() {
-		return table;
-	}
-
-	public Property getIdentifierProperty() {
-		return identifierProperty;
-	}
-	public KeyValue getIdentifier() {
-		return identifier;
-	}
-	public boolean hasIdentifierProperty() {
-		return identifierProperty!=null;
-	}
-
-	public Value getDiscriminator() {
-		return discriminator;
-	}
-
-	public boolean isInherited() {
-		return false;
-	}
-	public boolean isPolymorphic() {
-		return polymorphic;
-	}
-
-	public void setPolymorphic(boolean polymorphic) {
-		this.polymorphic = polymorphic;
-	}
-
-	public RootClass getRootClass() {
-		return this;
-	}
-
-	public Iterator getPropertyClosureIterator() {
-		return getPropertyIterator();
-	}
-	public Iterator getTableClosureIterator() {
-		return new SingletonIterator( getTable() );
-	}
-	public Iterator getKeyClosureIterator() {
-		return new SingletonIterator( getKey() );
-	}
-
-	public void addSubclass(Subclass subclass) throws MappingException {
-		super.addSubclass(subclass);
-		setPolymorphic(true);
-	}
-
-	public boolean isExplicitPolymorphism() {
-		return explicitPolymorphism;
-	}
-
-	public Property getVersion() {
-		return version;
-	}
-	public void setVersion(Property version) {
-		this.version = version;
-	}
-	public boolean isVersioned() {
-		return version!=null;
-	}
-
-	public boolean isMutable() {
-		return mutable;
-	}
-	public boolean hasEmbeddedIdentifier() {
-		return embeddedIdentifier;
-	}
-
-	public Class getEntityPersisterClass() {
-		return entityPersisterClass;
-	}
-
-	public Table getRootTable() {
-		return getTable();
-	}
-
-	public void setEntityPersisterClass(Class persister) {
-		this.entityPersisterClass = persister;
-	}
-
-	public PersistentClass getSuperclass() {
-		return null;
-	}
-
-	public KeyValue getKey() {
-		return getIdentifier();
-	}
-
-	public void setDiscriminator(Value discriminator) {
-		this.discriminator = discriminator;
-	}
-
-	public void setEmbeddedIdentifier(boolean embeddedIdentifier) {
-		this.embeddedIdentifier = embeddedIdentifier;
-	}
-
-	public void setExplicitPolymorphism(boolean explicitPolymorphism) {
-		this.explicitPolymorphism = explicitPolymorphism;
-	}
-
-	public void setIdentifier(KeyValue identifier) {
-		this.identifier = identifier;
-	}
-
-	public void setIdentifierProperty(Property identifierProperty) {
-		this.identifierProperty = identifierProperty;
-		identifierProperty.setPersistentClass(this);
-	}
-
-	public void setMutable(boolean mutable) {
-		this.mutable = mutable;
-	}
-
-	public boolean isDiscriminatorInsertable() {
-		return discriminatorInsertable;
-	}
-	
-	public void setDiscriminatorInsertable(boolean insertable) {
-		this.discriminatorInsertable = insertable;
-	}
-
-	public boolean isForceDiscriminator() {
-		return forceDiscriminator;
-	}
-
-	public void setForceDiscriminator(boolean forceDiscriminator) {
-		this.forceDiscriminator = forceDiscriminator;
-	}
-
-	public String getWhere() {
-		return where;
-	}
-
-	public void setWhere(String string) {
-		where = string;
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate(mapping);
-		if ( !getIdentifier().isValid(mapping) ) {
-			throw new MappingException(
-				"identifier mapping has wrong number of columns: " +
-				getEntityName() +
-				" type: " +
-				getIdentifier().getType().getName()
-			);
-		}
-		checkCompositeIdentifier();
-	}
-
-	private void checkCompositeIdentifier() {
-		if ( getIdentifier() instanceof Component ) {
-			Component id = (Component) getIdentifier();
-			if ( !id.isDynamic() ) {
-				Class idClass = id.getComponentClass();
-				if ( idClass != null && !ReflectHelper.overridesEquals( idClass ) ) {
-					LoggerFactory.getLogger( RootClass.class )
-						.warn( "composite-id class does not override equals(): "
-							+ id.getComponentClass().getName() );
-				}
-				if ( !ReflectHelper.overridesHashCode( idClass ) ) {
-					LoggerFactory.getLogger( RootClass.class )
-						.warn( "composite-id class does not override hashCode(): "
-							+ id.getComponentClass().getName() );
-				}
-				if ( !Serializable.class.isAssignableFrom( idClass ) ) {
-					throw new MappingException( "composite-id class must implement Serializable: "
-						+ id.getComponentClass().getName() );
-				}
-			}
-		}
-	}
-	
-	public String getCacheConcurrencyStrategy() {
-		return cacheConcurrencyStrategy;
-	}
-
-	public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
-		this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
-	}
-
-	public String getCacheRegionName() {
-		return cacheRegionName==null ? getEntityName() : cacheRegionName;
-	}
-	public void setCacheRegionName(String cacheRegionName) {
-		this.cacheRegionName = cacheRegionName;
-	}
-
-	public boolean isLazyPropertiesCacheable() {
-		return lazyPropertiesCacheable;
-	}
-
-	public void setLazyPropertiesCacheable(boolean lazyPropertiesCacheable) {
-		this.lazyPropertiesCacheable = lazyPropertiesCacheable;
-	}
-	
-	public boolean isJoinedSubclass() {
-		return false;
-	}
-
-	public java.util.Set getSynchronizedTables() {
-		return synchronizedTables;
-	}
-	
-	public Set getIdentityTables() {
-		Set tables = new HashSet();
-		Iterator iter = getSubclassClosureIterator();
-		while ( iter.hasNext() ) {
-			PersistentClass clazz = (PersistentClass) iter.next();
-			if ( clazz.isAbstract() == null || !clazz.isAbstract().booleanValue() ) tables.add( clazz.getIdentityTable() );
-		}
-		return tables;
-	}
-	
-	public Object accept(PersistentClassVisitor mv) {
-		return mv.accept(this);
-	}
-	
-	public int getOptimisticLockMode() {
-		return optimisticLockMode;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/RootClass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/RootClass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,299 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.slf4j.LoggerFactory;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.SingletonIterator;
+
+/**
+ * The root class of an inheritance hierarchy
+ * @author Gavin King
+ */
+public class RootClass extends PersistentClass implements TableOwner {
+
+	public static final String DEFAULT_IDENTIFIER_COLUMN_NAME = "id";
+	public static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "class";
+
+	private Property identifierProperty; //may be final
+	private KeyValue identifier; //may be final
+	private Property version; //may be final
+	private boolean polymorphic;
+	private String cacheConcurrencyStrategy;
+	private String cacheRegionName;
+	private boolean lazyPropertiesCacheable = true;
+	private Value discriminator; //may be final
+	private boolean mutable = true;
+	private boolean embeddedIdentifier = false; // may be final
+	private boolean explicitPolymorphism;
+	private Class entityPersisterClass;
+	private boolean forceDiscriminator = false;
+	private String where;
+	private Table table;
+	private boolean discriminatorInsertable = true;
+	private int nextSubclassId = 0;
+		
+	int nextSubclassId() {
+		return ++nextSubclassId;
+	}
+
+	public int getSubclassId() {
+		return 0;
+	}
+	
+	public void setTable(Table table) {
+		this.table=table;
+	}
+	public Table getTable() {
+		return table;
+	}
+
+	public Property getIdentifierProperty() {
+		return identifierProperty;
+	}
+	public KeyValue getIdentifier() {
+		return identifier;
+	}
+	public boolean hasIdentifierProperty() {
+		return identifierProperty!=null;
+	}
+
+	public Value getDiscriminator() {
+		return discriminator;
+	}
+
+	public boolean isInherited() {
+		return false;
+	}
+	public boolean isPolymorphic() {
+		return polymorphic;
+	}
+
+	public void setPolymorphic(boolean polymorphic) {
+		this.polymorphic = polymorphic;
+	}
+
+	public RootClass getRootClass() {
+		return this;
+	}
+
+	public Iterator getPropertyClosureIterator() {
+		return getPropertyIterator();
+	}
+	public Iterator getTableClosureIterator() {
+		return new SingletonIterator( getTable() );
+	}
+	public Iterator getKeyClosureIterator() {
+		return new SingletonIterator( getKey() );
+	}
+
+	public void addSubclass(Subclass subclass) throws MappingException {
+		super.addSubclass(subclass);
+		setPolymorphic(true);
+	}
+
+	public boolean isExplicitPolymorphism() {
+		return explicitPolymorphism;
+	}
+
+	public Property getVersion() {
+		return version;
+	}
+	public void setVersion(Property version) {
+		this.version = version;
+	}
+	public boolean isVersioned() {
+		return version!=null;
+	}
+
+	public boolean isMutable() {
+		return mutable;
+	}
+	public boolean hasEmbeddedIdentifier() {
+		return embeddedIdentifier;
+	}
+
+	public Class getEntityPersisterClass() {
+		return entityPersisterClass;
+	}
+
+	public Table getRootTable() {
+		return getTable();
+	}
+
+	public void setEntityPersisterClass(Class persister) {
+		this.entityPersisterClass = persister;
+	}
+
+	public PersistentClass getSuperclass() {
+		return null;
+	}
+
+	public KeyValue getKey() {
+		return getIdentifier();
+	}
+
+	public void setDiscriminator(Value discriminator) {
+		this.discriminator = discriminator;
+	}
+
+	public void setEmbeddedIdentifier(boolean embeddedIdentifier) {
+		this.embeddedIdentifier = embeddedIdentifier;
+	}
+
+	public void setExplicitPolymorphism(boolean explicitPolymorphism) {
+		this.explicitPolymorphism = explicitPolymorphism;
+	}
+
+	public void setIdentifier(KeyValue identifier) {
+		this.identifier = identifier;
+	}
+
+	public void setIdentifierProperty(Property identifierProperty) {
+		this.identifierProperty = identifierProperty;
+		identifierProperty.setPersistentClass(this);
+	}
+
+	public void setMutable(boolean mutable) {
+		this.mutable = mutable;
+	}
+
+	public boolean isDiscriminatorInsertable() {
+		return discriminatorInsertable;
+	}
+	
+	public void setDiscriminatorInsertable(boolean insertable) {
+		this.discriminatorInsertable = insertable;
+	}
+
+	public boolean isForceDiscriminator() {
+		return forceDiscriminator;
+	}
+
+	public void setForceDiscriminator(boolean forceDiscriminator) {
+		this.forceDiscriminator = forceDiscriminator;
+	}
+
+	public String getWhere() {
+		return where;
+	}
+
+	public void setWhere(String string) {
+		where = string;
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate(mapping);
+		if ( !getIdentifier().isValid(mapping) ) {
+			throw new MappingException(
+				"identifier mapping has wrong number of columns: " +
+				getEntityName() +
+				" type: " +
+				getIdentifier().getType().getName()
+			);
+		}
+		checkCompositeIdentifier();
+	}
+
+	private void checkCompositeIdentifier() {
+		if ( getIdentifier() instanceof Component ) {
+			Component id = (Component) getIdentifier();
+			if ( !id.isDynamic() ) {
+				Class idClass = id.getComponentClass();
+				if ( idClass != null && !ReflectHelper.overridesEquals( idClass ) ) {
+					LoggerFactory.getLogger( RootClass.class )
+						.warn( "composite-id class does not override equals(): "
+							+ id.getComponentClass().getName() );
+				}
+				if ( !ReflectHelper.overridesHashCode( idClass ) ) {
+					LoggerFactory.getLogger( RootClass.class )
+						.warn( "composite-id class does not override hashCode(): "
+							+ id.getComponentClass().getName() );
+				}
+				if ( !Serializable.class.isAssignableFrom( idClass ) ) {
+					throw new MappingException( "composite-id class must implement Serializable: "
+						+ id.getComponentClass().getName() );
+				}
+			}
+		}
+	}
+	
+	public String getCacheConcurrencyStrategy() {
+		return cacheConcurrencyStrategy;
+	}
+
+	public void setCacheConcurrencyStrategy(String cacheConcurrencyStrategy) {
+		this.cacheConcurrencyStrategy = cacheConcurrencyStrategy;
+	}
+
+	public String getCacheRegionName() {
+		return cacheRegionName==null ? getEntityName() : cacheRegionName;
+	}
+	public void setCacheRegionName(String cacheRegionName) {
+		this.cacheRegionName = cacheRegionName;
+	}
+
+	public boolean isLazyPropertiesCacheable() {
+		return lazyPropertiesCacheable;
+	}
+
+	public void setLazyPropertiesCacheable(boolean lazyPropertiesCacheable) {
+		this.lazyPropertiesCacheable = lazyPropertiesCacheable;
+	}
+	
+	public boolean isJoinedSubclass() {
+		return false;
+	}
+
+	public java.util.Set getSynchronizedTables() {
+		return synchronizedTables;
+	}
+	
+	public Set getIdentityTables() {
+		Set tables = new HashSet();
+		Iterator iter = getSubclassClosureIterator();
+		while ( iter.hasNext() ) {
+			PersistentClass clazz = (PersistentClass) iter.next();
+			if ( clazz.isAbstract() == null || !clazz.isAbstract().booleanValue() ) tables.add( clazz.getIdentityTable() );
+		}
+		return tables;
+	}
+	
+	public Object accept(PersistentClassVisitor mv) {
+		return mv.accept(this);
+	}
+	
+	public int getOptimisticLockMode() {
+		return optimisticLockMode;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Selectable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,14 +0,0 @@
-//$Id: Selectable.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.mapping;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-
-public interface Selectable {
-	public String getAlias(Dialect dialect);
-	public String getAlias(Dialect dialect, Table table);
-	public boolean isFormula();
-	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry);
-	public String getText(Dialect dialect);
-	public String getText();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Selectable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Selectable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+public interface Selectable {
+	public String getAlias(Dialect dialect);
+	public String getAlias(Dialect dialect, Table table);
+	public boolean isFormula();
+	public String getTemplate(Dialect dialect, SQLFunctionRegistry functionRegistry);
+	public String getText(Dialect dialect);
+	public String getText();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Set.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,86 +0,0 @@
-//$Id: Set.java 7714 2005-08-01 16:29:33Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.TypeFactory;
-
-/**
- * A set with no nullable element columns. It will have a primary key
- * consisting of all table columns (ie. key columns + element columns).
- * @author Gavin King
- */
-public class Set extends Collection {
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate( mapping );
-		//for backward compatibility, disable this:
-		/*Iterator iter = getElement().getColumnIterator();
-		while ( iter.hasNext() ) {
-			Column col = (Column) iter.next();
-			if ( !col.isNullable() ) {
-				return;
-			}
-		}
-		throw new MappingException("set element mappings must have at least one non-nullable column: " + getRole() );*/
-	}
-
-	/**
-	 * Constructor for Set.
-	 * @param owner
-	 */
-	public Set(PersistentClass owner) {
-		super(owner);
-	}
-
-	public boolean isSet() {
-		return true;
-	}
-
-	public CollectionType getDefaultCollectionType() {
-		if ( isSorted() ) {
-			return TypeFactory.sortedSet( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() );
-		}
-		else if ( hasOrder() ) {
-			return TypeFactory.orderedSet( getRole(), getReferencedPropertyName(), isEmbedded() );
-		}
-		else {
-			return TypeFactory.set( getRole(), getReferencedPropertyName(), isEmbedded() );
-		}
-	}
-
-	void createPrimaryKey() {
-		if ( !isOneToMany() ) {
-			PrimaryKey pk = new PrimaryKey();
-			pk.addColumns( getKey().getColumnIterator() );
-			Iterator iter = getElement().getColumnIterator();
-			while ( iter.hasNext() ) {
-				Object selectable = iter.next();
-				if ( selectable instanceof Column ) {
-					Column col = (Column) selectable;
-					if ( !col.isNullable() ) {
-						pk.addColumn(col);
-					}
-				}
-			}
-			if ( pk.getColumnSpan()==getKey().getColumnSpan() ) { 
-				//for backward compatibility, allow a set with no not-null 
-				//element columns, using all columns in the row locater SQL
-				//TODO: create an implicit not null constraint on all cols?
-			}
-			else {
-				getCollectionTable().setPrimaryKey(pk);
-			}
-		}
-		else {
-			//create an index on the key columns??
-		}
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Set.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Set.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,109 @@
+/*
+ * 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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.TypeFactory;
+
+/**
+ * A set with no nullable element columns. It will have a primary key
+ * consisting of all table columns (ie. key columns + element columns).
+ * @author Gavin King
+ */
+public class Set extends Collection {
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate( mapping );
+		//for backward compatibility, disable this:
+		/*Iterator iter = getElement().getColumnIterator();
+		while ( iter.hasNext() ) {
+			Column col = (Column) iter.next();
+			if ( !col.isNullable() ) {
+				return;
+			}
+		}
+		throw new MappingException("set element mappings must have at least one non-nullable column: " + getRole() );*/
+	}
+
+	/**
+	 * Constructor for Set.
+	 * @param owner
+	 */
+	public Set(PersistentClass owner) {
+		super(owner);
+	}
+
+	public boolean isSet() {
+		return true;
+	}
+
+	public CollectionType getDefaultCollectionType() {
+		if ( isSorted() ) {
+			return TypeFactory.sortedSet( getRole(), getReferencedPropertyName(), isEmbedded(), getComparator() );
+		}
+		else if ( hasOrder() ) {
+			return TypeFactory.orderedSet( getRole(), getReferencedPropertyName(), isEmbedded() );
+		}
+		else {
+			return TypeFactory.set( getRole(), getReferencedPropertyName(), isEmbedded() );
+		}
+	}
+
+	void createPrimaryKey() {
+		if ( !isOneToMany() ) {
+			PrimaryKey pk = new PrimaryKey();
+			pk.addColumns( getKey().getColumnIterator() );
+			Iterator iter = getElement().getColumnIterator();
+			while ( iter.hasNext() ) {
+				Object selectable = iter.next();
+				if ( selectable instanceof Column ) {
+					Column col = (Column) selectable;
+					if ( !col.isNullable() ) {
+						pk.addColumn(col);
+					}
+				}
+			}
+			if ( pk.getColumnSpan()==getKey().getColumnSpan() ) { 
+				//for backward compatibility, allow a set with no not-null 
+				//element columns, using all columns in the row locater SQL
+				//TODO: create an implicit not null constraint on all cols?
+			}
+			else {
+				getCollectionTable().setPrimaryKey(pk);
+			}
+		}
+		else {
+			//create an index on the key columns??
+		}
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-// $Id: SimpleAuxiliaryDatabaseObject.java 7800 2005-08-10 12:13:00Z steveebersole $
-package org.hibernate.mapping;
-
-import java.util.HashSet;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.HibernateException;
-import org.hibernate.util.StringHelper;
-
-/**
- * A simple implementation of AbstractAuxiliaryDatabaseObject in which the CREATE and DROP strings are
- * provided up front.  Contains simple facilities for templating the catalog and schema
- * names into the provided strings.
- * <p/>
- * This is the form created when the mapping documents use &lt;create/&gt; and
- * &lt;drop/&gt;.
- *
- * @author Steve Ebersole
- */
-public class SimpleAuxiliaryDatabaseObject extends AbstractAuxiliaryDatabaseObject {
-
-	private final String sqlCreateString;
-	private final String sqlDropString;
-
-	public SimpleAuxiliaryDatabaseObject(String sqlCreateString, String sqlDropString) {
-		this.sqlCreateString = sqlCreateString;
-		this.sqlDropString = sqlDropString;
-	}
-
-	public SimpleAuxiliaryDatabaseObject(String sqlCreateString, String sqlDropString, HashSet dialectScopes) {
-		super( dialectScopes );
-		this.sqlCreateString = sqlCreateString;
-		this.sqlDropString = sqlDropString;
-	}
-
-	public String sqlCreateString(
-	        Dialect dialect,
-	        Mapping p,
-	        String defaultCatalog,
-	        String defaultSchema) throws HibernateException {
-		return injectCatalogAndSchema( sqlCreateString, defaultCatalog, defaultSchema );
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		return injectCatalogAndSchema( sqlDropString, defaultCatalog, defaultSchema );
-	}
-
-	private String injectCatalogAndSchema(String ddlString, String defaultCatalog, String defaultSchema) {
-		String rtn = StringHelper.replace( ddlString, "${catalog}", defaultCatalog );
-		rtn = StringHelper.replace( rtn, "${schema}", defaultSchema );
-		return rtn;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleAuxiliaryDatabaseObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.util.HashSet;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.HibernateException;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A simple implementation of AbstractAuxiliaryDatabaseObject in which the CREATE and DROP strings are
+ * provided up front.  Contains simple facilities for templating the catalog and schema
+ * names into the provided strings.
+ * <p/>
+ * This is the form created when the mapping documents use &lt;create/&gt; and
+ * &lt;drop/&gt;.
+ *
+ * @author Steve Ebersole
+ */
+public class SimpleAuxiliaryDatabaseObject extends AbstractAuxiliaryDatabaseObject {
+
+	private final String sqlCreateString;
+	private final String sqlDropString;
+
+	public SimpleAuxiliaryDatabaseObject(String sqlCreateString, String sqlDropString) {
+		this.sqlCreateString = sqlCreateString;
+		this.sqlDropString = sqlDropString;
+	}
+
+	public SimpleAuxiliaryDatabaseObject(String sqlCreateString, String sqlDropString, HashSet dialectScopes) {
+		super( dialectScopes );
+		this.sqlCreateString = sqlCreateString;
+		this.sqlDropString = sqlDropString;
+	}
+
+	public String sqlCreateString(
+	        Dialect dialect,
+	        Mapping p,
+	        String defaultCatalog,
+	        String defaultSchema) throws HibernateException {
+		return injectCatalogAndSchema( sqlCreateString, defaultCatalog, defaultSchema );
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		return injectCatalogAndSchema( sqlDropString, defaultCatalog, defaultSchema );
+	}
+
+	private String injectCatalogAndSchema(String ddlString, String defaultCatalog, String defaultSchema) {
+		String rtn = StringHelper.replace( ddlString, "${catalog}", defaultCatalog );
+		rtn = StringHelper.replace( rtn, "${schema}", defaultSchema );
+		return rtn;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,317 +0,0 @@
-//$Id: SimpleValue.java 8046 2005-08-30 20:11:43Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Properties;
-
-import org.hibernate.FetchMode;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.IdentifierGeneratorFactory;
-import org.hibernate.id.IdentityGenerator;
-import org.hibernate.id.PersistentIdentifierGenerator;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Any value that maps to columns.
- * @author Gavin King
- */
-public class SimpleValue implements KeyValue {
-
-	private final List columns = new ArrayList();
-	private String typeName;
-	private Properties identifierGeneratorProperties;
-	private String identifierGeneratorStrategy = "assigned";
-	private String nullValue;
-	private Table table;
-	private String foreignKeyName;
-	private boolean alternateUniqueKey;
-	private Properties typeParameters;
-	private boolean cascadeDeleteEnabled;
-
-	public boolean isCascadeDeleteEnabled() {
-		return cascadeDeleteEnabled;
-	}
-
-	public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
-		this.cascadeDeleteEnabled = cascadeDeleteEnabled;
-	}
-	
-	public void addColumn(Column column) {
-		if ( !columns.contains(column) ) columns.add(column);
-		column.setValue(this);
-		column.setTypeIndex( columns.size()-1 );
-	}
-	
-	public void addFormula(Formula formula) {
-		columns.add(formula);
-	}
-	
-	public boolean hasFormula() {
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			Object o = iter.next();
-			if (o instanceof Formula) return true;
-		}
-		return false;
-	}
-
-	public int getColumnSpan() {
-		return columns.size();
-	}
-	public Iterator getColumnIterator() {
-		return columns.iterator();
-	}
-	public List getConstraintColumns() {
-		return columns;
-	}
-	public String getTypeName() {
-		return typeName;
-	}
-	public void setTypeName(String type) {
-		this.typeName = type;
-	}
-	public void setTable(Table table) {
-		this.table = table;
-	}
-	
-	public SimpleValue(Table table) {
-		this.table = table;
-	}
-
-	public SimpleValue() {}
-
-	public void createForeignKey() throws MappingException {}
-
-	public void createForeignKeyOfEntity(String entityName) {
-		if ( !hasFormula() && !"none".equals(getForeignKeyName())) {
-			ForeignKey fk = table.createForeignKey( getForeignKeyName(), getConstraintColumns(), entityName );
-			fk.setCascadeDeleteEnabled(cascadeDeleteEnabled);
-		}
-	}
-
-	public IdentifierGenerator createIdentifierGenerator(
-			Dialect dialect, 
-			String defaultCatalog, 
-			String defaultSchema, 
-			RootClass rootClass) 
-	throws MappingException {
-		
-		Properties params = new Properties();
-		
-		//if the hibernate-mapping did not specify a schema/catalog, use the defaults
-		//specified by properties - but note that if the schema/catalog were specified
-		//in hibernate-mapping, or as params, they will already be initialized and
-		//will override the values set here (they are in identifierGeneratorProperties)
-		if ( defaultSchema!=null ) {
-			params.setProperty(PersistentIdentifierGenerator.SCHEMA, defaultSchema);
-		}
-		if ( defaultCatalog!=null ) {
-			params.setProperty(PersistentIdentifierGenerator.CATALOG, defaultCatalog);
-		}
-		
-		//pass the entity-name, if not a collection-id
-		if (rootClass!=null) {
-			params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
-		}
-		
-		//init the table here instead of earlier, so that we can get a quoted table name
-		//TODO: would it be better to simply pass the qualified table name, instead of
-		//      splitting it up into schema/catalog/table names
-		String tableName = getTable().getQuotedName(dialect);
-		params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
-		
-		//pass the column name (a generated id almost always has a single column)
-		String columnName = ( (Column) getColumnIterator().next() ).getQuotedName(dialect);
-		params.setProperty( PersistentIdentifierGenerator.PK, columnName );
-		
-		if (rootClass!=null) {
-			StringBuffer tables = new StringBuffer();
-			Iterator iter = rootClass.getIdentityTables().iterator();
-			while ( iter.hasNext() ) {
-				Table table= (Table) iter.next();
-				tables.append( table.getQuotedName(dialect) );
-				if ( iter.hasNext() ) tables.append(", ");
-			}
-			params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
-		}
-		else {
-			params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
-		}
-
-		if (identifierGeneratorProperties!=null) {
-			params.putAll(identifierGeneratorProperties);
-		}
-		
-		return IdentifierGeneratorFactory.create(
-				identifierGeneratorStrategy,
-				getType(),
-				params,
-				dialect
-			);
-		
-	}
-
-	public boolean isUpdateable() {
-		//needed to satisfy KeyValue
-		return true;
-	}
-	
-	public FetchMode getFetchMode() {
-		return FetchMode.SELECT;
-	}
-
-	public Properties getIdentifierGeneratorProperties() {
-		return identifierGeneratorProperties;
-	}
-
-	public String getNullValue() {
-		return nullValue;
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	/**
-	 * Returns the identifierGeneratorStrategy.
-	 * @return String
-	 */
-	public String getIdentifierGeneratorStrategy() {
-		return identifierGeneratorStrategy;
-	}
-	
-	public boolean isIdentityColumn(Dialect dialect) {
-		return IdentifierGeneratorFactory.getIdentifierGeneratorClass(identifierGeneratorStrategy, dialect)
-				.equals(IdentityGenerator.class);
-	}
-
-	/**
-	 * Sets the identifierGeneratorProperties.
-	 * @param identifierGeneratorProperties The identifierGeneratorProperties to set
-	 */
-	public void setIdentifierGeneratorProperties(Properties identifierGeneratorProperties) {
-		this.identifierGeneratorProperties = identifierGeneratorProperties;
-	}
-
-	/**
-	 * Sets the identifierGeneratorStrategy.
-	 * @param identifierGeneratorStrategy The identifierGeneratorStrategy to set
-	 */
-	public void setIdentifierGeneratorStrategy(String identifierGeneratorStrategy) {
-		this.identifierGeneratorStrategy = identifierGeneratorStrategy;
-	}
-
-	/**
-	 * Sets the nullValue.
-	 * @param nullValue The nullValue to set
-	 */
-	public void setNullValue(String nullValue) {
-		this.nullValue = nullValue;
-	}
-
-	public String getForeignKeyName() {
-		return foreignKeyName;
-	}
-
-	public void setForeignKeyName(String foreignKeyName) {
-		this.foreignKeyName = foreignKeyName;
-	}
-
-	public boolean isAlternateUniqueKey() {
-		return alternateUniqueKey;
-	}
-
-	public void setAlternateUniqueKey(boolean unique) {
-		this.alternateUniqueKey = unique;
-	}
-
-	public boolean isNullable() {
-		if ( hasFormula() ) return true;
-		boolean nullable = true;
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			if ( !( (Column) iter.next() ).isNullable() ) {
-				nullable = false;
-				return nullable; //shortcut
-			}
-		}
-		return nullable;
-	}
-
-	public boolean isSimpleValue() {
-		return true;
-	}
-
-	public boolean isValid(Mapping mapping) throws MappingException {
-		return getColumnSpan()==getType().getColumnSpan(mapping);
-	}
-
-	public Type getType() throws MappingException {
-		if (typeName==null) {
-			throw new MappingException("No type name");
-		}
-		Type result = TypeFactory.heuristicType(typeName, typeParameters);
-		if (result==null) {
-			String msg = "Could not determine type for: " + typeName;
-			if(table != null){
-				msg += ", at table: " + table.getName();
-			}
-			if(columns!=null && columns.size()>0) {
-				msg += ", for columns: " + columns;
-			}
-			throw new MappingException(msg);
-		}
-		return result;
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName) throws MappingException {
-		if (typeName==null) {
-			if (className==null) {
-				throw new MappingException("you must specify types for a dynamic entity: " + propertyName);
-			}
-			typeName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName();
-		}
-	}
-
-	public boolean isTypeSpecified() {
-		return typeName!=null;
-	}
-
-	public void setTypeParameters(Properties parameterMap) {
-		this.typeParameters = parameterMap;
-	}
-	
-	public Properties getTypeParameters() {
-		return typeParameters;
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + columns.toString() + ')';
-	}
-
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-	
-	public boolean[] getColumnInsertability() {
-		boolean[] result = new boolean[ getColumnSpan() ];
-		int i = 0;
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			Selectable s = (Selectable) iter.next();
-			result[i++] = !s.isFormula();
-		}
-		return result;
-	}
-	
-	public boolean[] getColumnUpdateability() {
-		return getColumnInsertability();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/SimpleValue.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SimpleValue.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,340 @@
+/*
+ * 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.mapping;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.IdentifierGeneratorFactory;
+import org.hibernate.id.IdentityGenerator;
+import org.hibernate.id.PersistentIdentifierGenerator;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Any value that maps to columns.
+ * @author Gavin King
+ */
+public class SimpleValue implements KeyValue {
+
+	private final List columns = new ArrayList();
+	private String typeName;
+	private Properties identifierGeneratorProperties;
+	private String identifierGeneratorStrategy = "assigned";
+	private String nullValue;
+	private Table table;
+	private String foreignKeyName;
+	private boolean alternateUniqueKey;
+	private Properties typeParameters;
+	private boolean cascadeDeleteEnabled;
+
+	public boolean isCascadeDeleteEnabled() {
+		return cascadeDeleteEnabled;
+	}
+
+	public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
+		this.cascadeDeleteEnabled = cascadeDeleteEnabled;
+	}
+	
+	public void addColumn(Column column) {
+		if ( !columns.contains(column) ) columns.add(column);
+		column.setValue(this);
+		column.setTypeIndex( columns.size()-1 );
+	}
+	
+	public void addFormula(Formula formula) {
+		columns.add(formula);
+	}
+	
+	public boolean hasFormula() {
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			Object o = iter.next();
+			if (o instanceof Formula) return true;
+		}
+		return false;
+	}
+
+	public int getColumnSpan() {
+		return columns.size();
+	}
+	public Iterator getColumnIterator() {
+		return columns.iterator();
+	}
+	public List getConstraintColumns() {
+		return columns;
+	}
+	public String getTypeName() {
+		return typeName;
+	}
+	public void setTypeName(String type) {
+		this.typeName = type;
+	}
+	public void setTable(Table table) {
+		this.table = table;
+	}
+	
+	public SimpleValue(Table table) {
+		this.table = table;
+	}
+
+	public SimpleValue() {}
+
+	public void createForeignKey() throws MappingException {}
+
+	public void createForeignKeyOfEntity(String entityName) {
+		if ( !hasFormula() && !"none".equals(getForeignKeyName())) {
+			ForeignKey fk = table.createForeignKey( getForeignKeyName(), getConstraintColumns(), entityName );
+			fk.setCascadeDeleteEnabled(cascadeDeleteEnabled);
+		}
+	}
+
+	public IdentifierGenerator createIdentifierGenerator(
+			Dialect dialect, 
+			String defaultCatalog, 
+			String defaultSchema, 
+			RootClass rootClass) 
+	throws MappingException {
+		
+		Properties params = new Properties();
+		
+		//if the hibernate-mapping did not specify a schema/catalog, use the defaults
+		//specified by properties - but note that if the schema/catalog were specified
+		//in hibernate-mapping, or as params, they will already be initialized and
+		//will override the values set here (they are in identifierGeneratorProperties)
+		if ( defaultSchema!=null ) {
+			params.setProperty(PersistentIdentifierGenerator.SCHEMA, defaultSchema);
+		}
+		if ( defaultCatalog!=null ) {
+			params.setProperty(PersistentIdentifierGenerator.CATALOG, defaultCatalog);
+		}
+		
+		//pass the entity-name, if not a collection-id
+		if (rootClass!=null) {
+			params.setProperty( IdentifierGenerator.ENTITY_NAME, rootClass.getEntityName() );
+		}
+		
+		//init the table here instead of earlier, so that we can get a quoted table name
+		//TODO: would it be better to simply pass the qualified table name, instead of
+		//      splitting it up into schema/catalog/table names
+		String tableName = getTable().getQuotedName(dialect);
+		params.setProperty( PersistentIdentifierGenerator.TABLE, tableName );
+		
+		//pass the column name (a generated id almost always has a single column)
+		String columnName = ( (Column) getColumnIterator().next() ).getQuotedName(dialect);
+		params.setProperty( PersistentIdentifierGenerator.PK, columnName );
+		
+		if (rootClass!=null) {
+			StringBuffer tables = new StringBuffer();
+			Iterator iter = rootClass.getIdentityTables().iterator();
+			while ( iter.hasNext() ) {
+				Table table= (Table) iter.next();
+				tables.append( table.getQuotedName(dialect) );
+				if ( iter.hasNext() ) tables.append(", ");
+			}
+			params.setProperty( PersistentIdentifierGenerator.TABLES, tables.toString() );
+		}
+		else {
+			params.setProperty( PersistentIdentifierGenerator.TABLES, tableName );
+		}
+
+		if (identifierGeneratorProperties!=null) {
+			params.putAll(identifierGeneratorProperties);
+		}
+		
+		return IdentifierGeneratorFactory.create(
+				identifierGeneratorStrategy,
+				getType(),
+				params,
+				dialect
+			);
+		
+	}
+
+	public boolean isUpdateable() {
+		//needed to satisfy KeyValue
+		return true;
+	}
+	
+	public FetchMode getFetchMode() {
+		return FetchMode.SELECT;
+	}
+
+	public Properties getIdentifierGeneratorProperties() {
+		return identifierGeneratorProperties;
+	}
+
+	public String getNullValue() {
+		return nullValue;
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	/**
+	 * Returns the identifierGeneratorStrategy.
+	 * @return String
+	 */
+	public String getIdentifierGeneratorStrategy() {
+		return identifierGeneratorStrategy;
+	}
+	
+	public boolean isIdentityColumn(Dialect dialect) {
+		return IdentifierGeneratorFactory.getIdentifierGeneratorClass(identifierGeneratorStrategy, dialect)
+				.equals(IdentityGenerator.class);
+	}
+
+	/**
+	 * Sets the identifierGeneratorProperties.
+	 * @param identifierGeneratorProperties The identifierGeneratorProperties to set
+	 */
+	public void setIdentifierGeneratorProperties(Properties identifierGeneratorProperties) {
+		this.identifierGeneratorProperties = identifierGeneratorProperties;
+	}
+
+	/**
+	 * Sets the identifierGeneratorStrategy.
+	 * @param identifierGeneratorStrategy The identifierGeneratorStrategy to set
+	 */
+	public void setIdentifierGeneratorStrategy(String identifierGeneratorStrategy) {
+		this.identifierGeneratorStrategy = identifierGeneratorStrategy;
+	}
+
+	/**
+	 * Sets the nullValue.
+	 * @param nullValue The nullValue to set
+	 */
+	public void setNullValue(String nullValue) {
+		this.nullValue = nullValue;
+	}
+
+	public String getForeignKeyName() {
+		return foreignKeyName;
+	}
+
+	public void setForeignKeyName(String foreignKeyName) {
+		this.foreignKeyName = foreignKeyName;
+	}
+
+	public boolean isAlternateUniqueKey() {
+		return alternateUniqueKey;
+	}
+
+	public void setAlternateUniqueKey(boolean unique) {
+		this.alternateUniqueKey = unique;
+	}
+
+	public boolean isNullable() {
+		if ( hasFormula() ) return true;
+		boolean nullable = true;
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			if ( !( (Column) iter.next() ).isNullable() ) {
+				nullable = false;
+				return nullable; //shortcut
+			}
+		}
+		return nullable;
+	}
+
+	public boolean isSimpleValue() {
+		return true;
+	}
+
+	public boolean isValid(Mapping mapping) throws MappingException {
+		return getColumnSpan()==getType().getColumnSpan(mapping);
+	}
+
+	public Type getType() throws MappingException {
+		if (typeName==null) {
+			throw new MappingException("No type name");
+		}
+		Type result = TypeFactory.heuristicType(typeName, typeParameters);
+		if (result==null) {
+			String msg = "Could not determine type for: " + typeName;
+			if(table != null){
+				msg += ", at table: " + table.getName();
+			}
+			if(columns!=null && columns.size()>0) {
+				msg += ", for columns: " + columns;
+			}
+			throw new MappingException(msg);
+		}
+		return result;
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName) throws MappingException {
+		if (typeName==null) {
+			if (className==null) {
+				throw new MappingException("you must specify types for a dynamic entity: " + propertyName);
+			}
+			typeName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName();
+		}
+	}
+
+	public boolean isTypeSpecified() {
+		return typeName!=null;
+	}
+
+	public void setTypeParameters(Properties parameterMap) {
+		this.typeParameters = parameterMap;
+	}
+	
+	public Properties getTypeParameters() {
+		return typeParameters;
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + columns.toString() + ')';
+	}
+
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+	
+	public boolean[] getColumnInsertability() {
+		boolean[] result = new boolean[ getColumnSpan() ];
+		int i = 0;
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			Selectable s = (Selectable) iter.next();
+			result[i++] = !s.isFormula();
+		}
+		return result;
+	}
+	
+	public boolean[] getColumnUpdateability() {
+		return getColumnInsertability();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: SingleTableSubclass.java 7270 2005-06-22 17:02:26Z turin42 $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.util.JoinedIterator;
-
-/**
- * @author Gavin King
- */
-public class SingleTableSubclass extends Subclass {
-	
-	public SingleTableSubclass(PersistentClass superclass) {
-		super(superclass);
-	}
-	
-	protected Iterator getNonDuplicatedPropertyIterator() {
-		return new JoinedIterator( 
-				getSuperclass().getUnjoinedPropertyIterator(),
-				getUnjoinedPropertyIterator()
-		);
-	}
-	
-	protected Iterator getDiscriminatorColumnIterator() {
-		if ( isDiscriminatorInsertable() && !getDiscriminator().hasFormula() ) {
-			return getDiscriminator().getColumnIterator();
-		}
-		else {
-			return super.getDiscriminatorColumnIterator();
-		}
-	}
-
-	public Object accept(PersistentClassVisitor mv) {
-		return mv.accept(this);
-	}
-    
-    public void validate(Mapping mapping) throws MappingException {
-        if(getDiscriminator()==null) {
-            throw new MappingException("No discriminator found for " + getEntityName() + ". Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses");
-        }
-        super.validate(mapping);
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/SingleTableSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.util.JoinedIterator;
+
+/**
+ * @author Gavin King
+ */
+public class SingleTableSubclass extends Subclass {
+	
+	public SingleTableSubclass(PersistentClass superclass) {
+		super(superclass);
+	}
+	
+	protected Iterator getNonDuplicatedPropertyIterator() {
+		return new JoinedIterator( 
+				getSuperclass().getUnjoinedPropertyIterator(),
+				getUnjoinedPropertyIterator()
+		);
+	}
+	
+	protected Iterator getDiscriminatorColumnIterator() {
+		if ( isDiscriminatorInsertable() && !getDiscriminator().hasFormula() ) {
+			return getDiscriminator().getColumnIterator();
+		}
+		else {
+			return super.getDiscriminatorColumnIterator();
+		}
+	}
+
+	public Object accept(PersistentClassVisitor mv) {
+		return mv.accept(this);
+	}
+    
+    public void validate(Mapping mapping) throws MappingException {
+        if(getDiscriminator()==null) {
+            throw new MappingException("No discriminator found for " + getEntityName() + ". Discriminator is needed when 'single-table-per-hierarchy' is used and a class has subclasses");
+        }
+        super.validate(mapping);
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,257 +0,0 @@
-//$Id: Subclass.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.util.*;
-import java.util.Map;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.SingletonIterator;
-
-/**
- * A sublass in a table-per-class-hierarchy mapping
- * @author Gavin King
- */
-public class Subclass extends PersistentClass {
-
-	private PersistentClass superclass;
-	private Class classPersisterClass;
-	private final int subclassId;
-	
-	public Subclass(PersistentClass superclass) {
-		this.superclass = superclass;
-		this.subclassId = superclass.nextSubclassId();
-	}
-
-	int nextSubclassId() {
-		return getSuperclass().nextSubclassId();
-	}
-	
-	public int getSubclassId() {
-		return subclassId;
-	}
-	
-	public String getCacheConcurrencyStrategy() {
-		return getSuperclass().getCacheConcurrencyStrategy();
-	}
-
-	public RootClass getRootClass() {
-		return getSuperclass().getRootClass();
-	}
-
-	public PersistentClass getSuperclass() {
-		return superclass;
-	}
-
-	public Property getIdentifierProperty() {
-		return getSuperclass().getIdentifierProperty();
-	}
-	public KeyValue getIdentifier() {
-		return getSuperclass().getIdentifier();
-	}
-	public boolean hasIdentifierProperty() {
-		return getSuperclass().hasIdentifierProperty();
-	}
-	public Value getDiscriminator() {
-		return getSuperclass().getDiscriminator();
-	}
-	public boolean isMutable() {
-		return getSuperclass().isMutable();
-	}
-	public boolean isInherited() {
-		return true;
-	}
-	public boolean isPolymorphic() {
-		return true;
-	}
-
-	public void addProperty(Property p) {
-		super.addProperty(p);
-		getSuperclass().addSubclassProperty(p);
-	}
-	public void addJoin(Join j) {
-		super.addJoin(j);
-		getSuperclass().addSubclassJoin(j);
-	}
-
-	public Iterator getPropertyClosureIterator() {
-		return new JoinedIterator(
-				getSuperclass().getPropertyClosureIterator(),
-				getPropertyIterator()
-			);
-	}
-	public Iterator getTableClosureIterator() {
-		return new JoinedIterator(
-				getSuperclass().getTableClosureIterator(),
-				new SingletonIterator( getTable() )
-			);
-	}
-	public Iterator getKeyClosureIterator() {
-		return new JoinedIterator(
-				getSuperclass().getKeyClosureIterator(),
-				new SingletonIterator( getKey() )
-			);
-	}
-	protected void addSubclassProperty(Property p) {
-		super.addSubclassProperty(p);
-		getSuperclass().addSubclassProperty(p);
-	}
-	protected void addSubclassJoin(Join j) {
-		super.addSubclassJoin(j);
-		getSuperclass().addSubclassJoin(j);
-	}
-
-	protected void addSubclassTable(Table table) {
-		super.addSubclassTable(table);
-		getSuperclass().addSubclassTable(table);
-	}
-
-	public boolean isVersioned() {
-		return getSuperclass().isVersioned();
-	}
-	public Property getVersion() {
-		return getSuperclass().getVersion();
-	}
-
-	public boolean hasEmbeddedIdentifier() {
-		return getSuperclass().hasEmbeddedIdentifier();
-	}
-	public Class getEntityPersisterClass() {
-		if (classPersisterClass==null) {
-			return getSuperclass().getEntityPersisterClass();
-		}
-		else {
-			return classPersisterClass;
-		}
-	}
-
-	public Table getRootTable() {
-		return getSuperclass().getRootTable();
-	}
-
-	public KeyValue getKey() {
-		return getSuperclass().getIdentifier();
-	}
-
-	public boolean isExplicitPolymorphism() {
-		return getSuperclass().isExplicitPolymorphism();
-	}
-
-	public void setSuperclass(PersistentClass superclass) {
-		this.superclass = superclass;
-	}
-
-	public String getWhere() {
-		return getSuperclass().getWhere();
-	}
-
-	public boolean isJoinedSubclass() {
-		return getTable()!=getRootTable();
-	}
-
-	public void createForeignKey() {
-		if ( !isJoinedSubclass() ) {
-			throw new AssertionFailure( "not a joined-subclass" );
-		}
-		getKey().createForeignKeyOfEntity( getSuperclass().getEntityName() );
-	}
-
-	public void setEntityPersisterClass(Class classPersisterClass) {
-		this.classPersisterClass = classPersisterClass;
-	}
-
-	public boolean isLazyPropertiesCacheable() {
-		return getSuperclass().isLazyPropertiesCacheable();
-	}
-
-	public int getJoinClosureSpan() {
-		return getSuperclass().getJoinClosureSpan() + super.getJoinClosureSpan();
-	}
-
-	public int getPropertyClosureSpan() {
-		return getSuperclass().getPropertyClosureSpan() + super.getPropertyClosureSpan();
-	}
-
-	public Iterator getJoinClosureIterator() {
-		return new JoinedIterator(
-			getSuperclass().getJoinClosureIterator(),
-			super.getJoinClosureIterator()
-		);
-	}
-
-	public boolean isClassOrSuperclassJoin(Join join) {
-		return super.isClassOrSuperclassJoin(join) || getSuperclass().isClassOrSuperclassJoin(join);
-	}
-
-	public boolean isClassOrSuperclassTable(Table table) {
-		return super.isClassOrSuperclassTable(table) || getSuperclass().isClassOrSuperclassTable(table);
-	}
-
-	public Table getTable() {
-		return getSuperclass().getTable();
-	}
-
-	public boolean isForceDiscriminator() {
-		return getSuperclass().isForceDiscriminator();
-	}
-
-	public boolean isDiscriminatorInsertable() {
-		return getSuperclass().isDiscriminatorInsertable();
-	}
-
-	public java.util.Set getSynchronizedTables() {
-		HashSet result = new HashSet();
-		result.addAll(synchronizedTables);
-		result.addAll( getSuperclass().getSynchronizedTables() );
-		return result;
-	}
-
-	public Object accept(PersistentClassVisitor mv) {
-		return mv.accept(this);
-	}
-
-	public Map getFilterMap() {
-		return getSuperclass().getFilterMap();
-	}
-
-	public boolean hasSubselectLoadableCollections() {
-		return super.hasSubselectLoadableCollections() || 
-			getSuperclass().hasSubselectLoadableCollections();
-	}
-
-	public String getTuplizerImplClassName(EntityMode mode) {
-		String impl = super.getTuplizerImplClassName( mode );
-		if ( impl == null ) {
-			impl = getSuperclass().getTuplizerImplClassName( mode );
-		}
-		return impl;
-	}
-
-	public Map getTuplizerMap() {
-		Map specificTuplizerDefs = super.getTuplizerMap();
-		Map superclassTuplizerDefs = getSuperclass().getTuplizerMap();
-		if ( specificTuplizerDefs == null && superclassTuplizerDefs == null ) {
-			return null;
-		}
-		else {
-			Map combined = new HashMap();
-			if ( superclassTuplizerDefs != null ) {
-				combined.putAll( superclassTuplizerDefs );
-			}
-			if ( specificTuplizerDefs != null ) {
-				combined.putAll( specificTuplizerDefs );
-			}
-			return java.util.Collections.unmodifiableMap( combined );
-		}
-	}
-
-	public Component getIdentifierMapper() {
-		return superclass.getIdentifierMapper();
-	}
-	
-	public int getOptimisticLockMode() {
-		return superclass.getOptimisticLockMode();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Subclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,280 @@
+/*
+ * 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.mapping;
+
+import java.util.*;
+import java.util.Map;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.SingletonIterator;
+
+/**
+ * A sublass in a table-per-class-hierarchy mapping
+ * @author Gavin King
+ */
+public class Subclass extends PersistentClass {
+
+	private PersistentClass superclass;
+	private Class classPersisterClass;
+	private final int subclassId;
+	
+	public Subclass(PersistentClass superclass) {
+		this.superclass = superclass;
+		this.subclassId = superclass.nextSubclassId();
+	}
+
+	int nextSubclassId() {
+		return getSuperclass().nextSubclassId();
+	}
+	
+	public int getSubclassId() {
+		return subclassId;
+	}
+	
+	public String getCacheConcurrencyStrategy() {
+		return getSuperclass().getCacheConcurrencyStrategy();
+	}
+
+	public RootClass getRootClass() {
+		return getSuperclass().getRootClass();
+	}
+
+	public PersistentClass getSuperclass() {
+		return superclass;
+	}
+
+	public Property getIdentifierProperty() {
+		return getSuperclass().getIdentifierProperty();
+	}
+	public KeyValue getIdentifier() {
+		return getSuperclass().getIdentifier();
+	}
+	public boolean hasIdentifierProperty() {
+		return getSuperclass().hasIdentifierProperty();
+	}
+	public Value getDiscriminator() {
+		return getSuperclass().getDiscriminator();
+	}
+	public boolean isMutable() {
+		return getSuperclass().isMutable();
+	}
+	public boolean isInherited() {
+		return true;
+	}
+	public boolean isPolymorphic() {
+		return true;
+	}
+
+	public void addProperty(Property p) {
+		super.addProperty(p);
+		getSuperclass().addSubclassProperty(p);
+	}
+	public void addJoin(Join j) {
+		super.addJoin(j);
+		getSuperclass().addSubclassJoin(j);
+	}
+
+	public Iterator getPropertyClosureIterator() {
+		return new JoinedIterator(
+				getSuperclass().getPropertyClosureIterator(),
+				getPropertyIterator()
+			);
+	}
+	public Iterator getTableClosureIterator() {
+		return new JoinedIterator(
+				getSuperclass().getTableClosureIterator(),
+				new SingletonIterator( getTable() )
+			);
+	}
+	public Iterator getKeyClosureIterator() {
+		return new JoinedIterator(
+				getSuperclass().getKeyClosureIterator(),
+				new SingletonIterator( getKey() )
+			);
+	}
+	protected void addSubclassProperty(Property p) {
+		super.addSubclassProperty(p);
+		getSuperclass().addSubclassProperty(p);
+	}
+	protected void addSubclassJoin(Join j) {
+		super.addSubclassJoin(j);
+		getSuperclass().addSubclassJoin(j);
+	}
+
+	protected void addSubclassTable(Table table) {
+		super.addSubclassTable(table);
+		getSuperclass().addSubclassTable(table);
+	}
+
+	public boolean isVersioned() {
+		return getSuperclass().isVersioned();
+	}
+	public Property getVersion() {
+		return getSuperclass().getVersion();
+	}
+
+	public boolean hasEmbeddedIdentifier() {
+		return getSuperclass().hasEmbeddedIdentifier();
+	}
+	public Class getEntityPersisterClass() {
+		if (classPersisterClass==null) {
+			return getSuperclass().getEntityPersisterClass();
+		}
+		else {
+			return classPersisterClass;
+		}
+	}
+
+	public Table getRootTable() {
+		return getSuperclass().getRootTable();
+	}
+
+	public KeyValue getKey() {
+		return getSuperclass().getIdentifier();
+	}
+
+	public boolean isExplicitPolymorphism() {
+		return getSuperclass().isExplicitPolymorphism();
+	}
+
+	public void setSuperclass(PersistentClass superclass) {
+		this.superclass = superclass;
+	}
+
+	public String getWhere() {
+		return getSuperclass().getWhere();
+	}
+
+	public boolean isJoinedSubclass() {
+		return getTable()!=getRootTable();
+	}
+
+	public void createForeignKey() {
+		if ( !isJoinedSubclass() ) {
+			throw new AssertionFailure( "not a joined-subclass" );
+		}
+		getKey().createForeignKeyOfEntity( getSuperclass().getEntityName() );
+	}
+
+	public void setEntityPersisterClass(Class classPersisterClass) {
+		this.classPersisterClass = classPersisterClass;
+	}
+
+	public boolean isLazyPropertiesCacheable() {
+		return getSuperclass().isLazyPropertiesCacheable();
+	}
+
+	public int getJoinClosureSpan() {
+		return getSuperclass().getJoinClosureSpan() + super.getJoinClosureSpan();
+	}
+
+	public int getPropertyClosureSpan() {
+		return getSuperclass().getPropertyClosureSpan() + super.getPropertyClosureSpan();
+	}
+
+	public Iterator getJoinClosureIterator() {
+		return new JoinedIterator(
+			getSuperclass().getJoinClosureIterator(),
+			super.getJoinClosureIterator()
+		);
+	}
+
+	public boolean isClassOrSuperclassJoin(Join join) {
+		return super.isClassOrSuperclassJoin(join) || getSuperclass().isClassOrSuperclassJoin(join);
+	}
+
+	public boolean isClassOrSuperclassTable(Table table) {
+		return super.isClassOrSuperclassTable(table) || getSuperclass().isClassOrSuperclassTable(table);
+	}
+
+	public Table getTable() {
+		return getSuperclass().getTable();
+	}
+
+	public boolean isForceDiscriminator() {
+		return getSuperclass().isForceDiscriminator();
+	}
+
+	public boolean isDiscriminatorInsertable() {
+		return getSuperclass().isDiscriminatorInsertable();
+	}
+
+	public java.util.Set getSynchronizedTables() {
+		HashSet result = new HashSet();
+		result.addAll(synchronizedTables);
+		result.addAll( getSuperclass().getSynchronizedTables() );
+		return result;
+	}
+
+	public Object accept(PersistentClassVisitor mv) {
+		return mv.accept(this);
+	}
+
+	public Map getFilterMap() {
+		return getSuperclass().getFilterMap();
+	}
+
+	public boolean hasSubselectLoadableCollections() {
+		return super.hasSubselectLoadableCollections() || 
+			getSuperclass().hasSubselectLoadableCollections();
+	}
+
+	public String getTuplizerImplClassName(EntityMode mode) {
+		String impl = super.getTuplizerImplClassName( mode );
+		if ( impl == null ) {
+			impl = getSuperclass().getTuplizerImplClassName( mode );
+		}
+		return impl;
+	}
+
+	public Map getTuplizerMap() {
+		Map specificTuplizerDefs = super.getTuplizerMap();
+		Map superclassTuplizerDefs = getSuperclass().getTuplizerMap();
+		if ( specificTuplizerDefs == null && superclassTuplizerDefs == null ) {
+			return null;
+		}
+		else {
+			Map combined = new HashMap();
+			if ( superclassTuplizerDefs != null ) {
+				combined.putAll( superclassTuplizerDefs );
+			}
+			if ( specificTuplizerDefs != null ) {
+				combined.putAll( specificTuplizerDefs );
+			}
+			return java.util.Collections.unmodifiableMap( combined );
+		}
+	}
+
+	public Component getIdentifierMapper() {
+		return superclass.getIdentifierMapper();
+	}
+	
+	public int getOptimisticLockMode() {
+		return superclass.getOptimisticLockMode();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Table.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,771 +0,0 @@
-//$Id: Table.java 11303 2007-03-19 22:06:14Z steve.ebersole at jboss.com $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.LinkedHashMap;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.tool.hbm2ddl.ColumnMetadata;
-import org.hibernate.tool.hbm2ddl.TableMetadata;
-import org.hibernate.util.CollectionHelper;
-
-/**
- * A relational table
- *
- * @author Gavin King
- */
-public class Table implements RelationalModel, Serializable {
-
-	private String name;
-	private String schema;
-	private String catalog;
-	/**
-	 * contains all columns, including the primary key
-	 */
-	private Map columns = new LinkedHashMap();
-	private KeyValue idValue;
-	private PrimaryKey primaryKey;
-	private Map indexes = new HashMap();
-	private Map foreignKeys = new HashMap();
-	private Map uniqueKeys = new HashMap();
-	private final int uniqueInteger;
-	private boolean quoted;
-	private boolean schemaQuoted;
-	private static int tableCounter = 0;
-	private List checkConstraints = new ArrayList();
-	private String rowId;
-	private String subselect;
-	private boolean isAbstract;
-	private boolean hasDenormalizedTables = false;
-	private String comment;
-
-	static class ForeignKeyKey implements Serializable {
-		String referencedClassName;
-		List columns;
-		List referencedColumns;
-
-		ForeignKeyKey(List columns, String referencedClassName, List referencedColumns) {
-			this.referencedClassName = referencedClassName;
-			this.columns = new ArrayList();
-			this.columns.addAll( columns );
-			if ( referencedColumns != null ) {
-				this.referencedColumns = new ArrayList();
-				this.referencedColumns.addAll( referencedColumns );
-			}
-			else {
-				this.referencedColumns = CollectionHelper.EMPTY_LIST;
-			}
-		}
-
-		public int hashCode() {
-			return columns.hashCode() + referencedColumns.hashCode();
-		}
-
-		public boolean equals(Object other) {
-			ForeignKeyKey fkk = (ForeignKeyKey) other;
-			return fkk.columns.equals( columns ) &&
-					fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns
-					.equals( referencedColumns );
-		}
-	}
-
-	public Table() {
-		uniqueInteger = tableCounter++;
-	}
-
-	public Table(String name) {
-		this();
-		setName( name );
-	}
-
-	public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		if ( subselect != null ) {
-			return "( " + subselect + " )";
-		}
-		String quotedName = getQuotedName( dialect );
-		String usedSchema = schema == null ?
-				defaultSchema :
-				getQuotedSchema( dialect );
-		String usedCatalog = catalog == null ?
-				defaultCatalog :
-				catalog;
-		return qualify( usedCatalog, usedSchema, quotedName );
-	}
-
-	public static String qualify(String catalog, String schema, String table) {
-		StringBuffer qualifiedName = new StringBuffer();
-		if ( catalog != null ) {
-			qualifiedName.append( catalog ).append( '.' );
-		}
-		if ( schema != null ) {
-			qualifiedName.append( schema ).append( '.' );
-		}
-		return qualifiedName.append( table ).toString();
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	/**
-	 * returns quoted name as it would be in the mapping file.
-	 */
-	public String getQuotedName() {
-		return quoted ?
-				"`" + name + "`" :
-				name;
-	}
-
-	public String getQuotedName(Dialect dialect) {
-		return quoted ?
-				dialect.openQuote() + name + dialect.closeQuote() :
-				name;
-	}
-
-	/**
-	 * returns quoted name as it is in the mapping file.
-	 */
-	public String getQuotedSchema() {
-		return schemaQuoted ?
-				"`" + schema + "`" :
-				schema;
-	}
-
-	public String getQuotedSchema(Dialect dialect) {
-		return schemaQuoted ?
-				dialect.openQuote() + schema + dialect.closeQuote() :
-				schema;
-	}
-
-	public void setName(String name) {
-		if ( name.charAt( 0 ) == '`' ) {
-			quoted = true;
-			this.name = name.substring( 1, name.length() - 1 );
-		}
-		else {
-			this.name = name;
-		}
-	}
-
-	/**
-	 * Return the column which is identified by column provided as argument.
-	 *
-	 * @param column column with atleast a name.
-	 * @return the underlying column or null if not inside this table. Note: the instance *can* be different than the input parameter, but the name will be the same.
-	 */
-	public Column getColumn(Column column) {
-		if ( column == null ) {
-			return null;
-		}
-
-		Column myColumn = (Column) columns.get( column.getCanonicalName() );
-
-		return column.equals( myColumn ) ?
-				myColumn :
-				null;
-	}
-
-	public Column getColumn(int n) {
-		Iterator iter = columns.values().iterator();
-		for ( int i = 0; i < n - 1; i++ ) {
-			iter.next();
-		}
-		return (Column) iter.next();
-	}
-
-	public void addColumn(Column column) {
-		Column old = (Column) getColumn( column );
-		if ( old == null ) {
-			columns.put( column.getCanonicalName(), column );
-			column.uniqueInteger = columns.size();
-		}
-		else {
-			column.uniqueInteger = old.uniqueInteger;
-		}
-	}
-
-	public int getColumnSpan() {
-		return columns.size();
-	}
-
-	public Iterator getColumnIterator() {
-		return columns.values().iterator();
-	}
-
-	public Iterator getIndexIterator() {
-		return indexes.values().iterator();
-	}
-
-	public Iterator getForeignKeyIterator() {
-		return foreignKeys.values().iterator();
-	}
-
-	public Iterator getUniqueKeyIterator() {
-		return getUniqueKeys().values().iterator();
-	}
-
-	Map getUniqueKeys() {
-		if ( uniqueKeys.size() > 1 ) {
-			//deduplicate unique constraints sharing the same columns
-			//this is needed by Hibernate Annotations since it creates automagically
-			// unique constraints for the user
-			Iterator it = uniqueKeys.entrySet().iterator();
-			Map finalUniqueKeys = new HashMap( uniqueKeys.size() );
-			while ( it.hasNext() ) {
-				Map.Entry entry = (Map.Entry) it.next();
-				UniqueKey uk = (UniqueKey) entry.getValue();
-				List columns = uk.getColumns();
-				int size = finalUniqueKeys.size();
-				boolean skip = false;
-				Iterator tempUks = finalUniqueKeys.entrySet().iterator();
-				while ( tempUks.hasNext() ) {
-					final UniqueKey currentUk = (UniqueKey) ( (Map.Entry) tempUks.next() ).getValue();
-					if ( currentUk.getColumns().containsAll( columns ) && columns
-							.containsAll( currentUk.getColumns() ) ) {
-						skip = true;
-						break;
-					}
-				}
-				if ( !skip ) finalUniqueKeys.put( entry.getKey(), uk );
-			}
-			return finalUniqueKeys;
-		}
-		else {
-			return uniqueKeys;
-		}
-	}
-
-	public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) {
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			Column col = (Column) iter.next();
-
-			ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );
-
-			if ( columnInfo == null ) {
-				throw new HibernateException( "Missing column: " + col.getName() + " in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()));
-			}
-			else {
-				final boolean typesMatch = col.getSqlType( dialect, mapping ).toLowerCase()
-						.startsWith( columnInfo.getTypeName().toLowerCase() )
-						|| columnInfo.getTypeCode() == col.getSqlTypeCode( mapping );
-				if ( !typesMatch ) {
-					throw new HibernateException(
-							"Wrong column type in " +
-							Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()) +
-							" for column " + col.getName() +
-							". Found: " + columnInfo.getTypeName().toLowerCase() +
-							", expected: " + col.getSqlType( dialect, mapping )
-					);
-				}
-			}
-		}
-
-	}
-
-	public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog,
-									String defaultSchema)
-			throws HibernateException {
-
-		StringBuffer root = new StringBuffer( "alter table " )
-				.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
-				.append( ' ' )
-				.append( dialect.getAddColumnString() );
-
-		Iterator iter = getColumnIterator();
-		List results = new ArrayList();
-		while ( iter.hasNext() ) {
-			Column column = (Column) iter.next();
-
-			ColumnMetadata columnInfo = tableInfo.getColumnMetadata( column.getName() );
-
-			if ( columnInfo == null ) {
-				// the column doesnt exist at all.
-				StringBuffer alter = new StringBuffer( root.toString() )
-						.append( ' ' )
-						.append( column.getQuotedName( dialect ) )
-						.append( ' ' )
-						.append( column.getSqlType( dialect, p ) );
-
-				String defaultValue = column.getDefaultValue();
-				if ( defaultValue != null ) {
-					alter.append( " default " ).append( defaultValue );
-
-					if ( column.isNullable() ) {
-						alter.append( dialect.getNullColumnString() );
-					}
-					else {
-						alter.append( " not null" );
-					}
-
-				}
-
-				boolean useUniqueConstraint = column.isUnique() &&
-						dialect.supportsUnique() &&
-						( !column.isNullable() || dialect.supportsNotNullUnique() );
-				if ( useUniqueConstraint ) {
-					alter.append( " unique" );
-				}
-
-				if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
-					alter.append( " check(" )
-							.append( column.getCheckConstraint() )
-							.append( ")" );
-				}
-
-				String columnComment = column.getComment();
-				if ( columnComment != null ) {
-					alter.append( dialect.getColumnComment( columnComment ) );
-				}
-
-				results.add( alter.toString() );
-			}
-
-		}
-
-		return results.iterator();
-	}
-
-	public boolean hasPrimaryKey() {
-		return getPrimaryKey() != null;
-	}
-
-	public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException {
-		StringBuffer buffer = new StringBuffer( dialect.getCreateTemporaryTableString() )
-				.append( ' ' )
-				.append( name )
-				.append( " (" );
-		Iterator itr = getColumnIterator();
-		while ( itr.hasNext() ) {
-			final Column column = (Column) itr.next();
-			buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
-			buffer.append( column.getSqlType( dialect, mapping ) );
-			if ( column.isNullable() ) {
-				buffer.append( dialect.getNullColumnString() );
-			}
-			else {
-				buffer.append( " not null" );
-			}
-			if ( itr.hasNext() ) {
-				buffer.append( ", " );
-			}
-		}
-		buffer.append( ") " );
-		buffer.append( dialect.getCreateTemporaryTablePostfix() );
-		return buffer.toString();
-	}
-
-	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
-		StringBuffer buf = new StringBuffer( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() )
-				.append( ' ' )
-				.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
-				.append( " (" );
-
-		boolean identityColumn = idValue != null && idValue.isIdentityColumn( dialect );
-
-		// Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
-		String pkname = null;
-		if ( hasPrimaryKey() && identityColumn ) {
-			pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
-		}
-
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			Column col = (Column) iter.next();
-
-			buf.append( col.getQuotedName( dialect ) )
-					.append( ' ' );
-
-			if ( identityColumn && col.getQuotedName( dialect ).equals( pkname ) ) {
-				// to support dialects that have their own identity data type
-				if ( dialect.hasDataTypeInIdentityColumn() ) {
-					buf.append( col.getSqlType( dialect, p ) );
-				}
-				buf.append( ' ' )
-						.append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
-			}
-			else {
-
-				buf.append( col.getSqlType( dialect, p ) );
-
-				String defaultValue = col.getDefaultValue();
-				if ( defaultValue != null ) {
-					buf.append( " default " ).append( defaultValue );
-				}
-
-				if ( col.isNullable() ) {
-					buf.append( dialect.getNullColumnString() );
-				}
-				else {
-					buf.append( " not null" );
-				}
-
-			}
-
-			boolean useUniqueConstraint = col.isUnique() &&
-					( !col.isNullable() || dialect.supportsNotNullUnique() );
-			if ( useUniqueConstraint ) {
-				if ( dialect.supportsUnique() ) {
-					buf.append( " unique" );
-				}
-				else {
-					UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
-					uk.addColumn( col );
-				}
-			}
-
-			if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
-				buf.append( " check (" )
-						.append( col.getCheckConstraint() )
-						.append( ")" );
-			}
-
-			String columnComment = col.getComment();
-			if ( columnComment != null ) {
-				buf.append( dialect.getColumnComment( columnComment ) );
-			}
-
-			if ( iter.hasNext() ) {
-				buf.append( ", " );
-			}
-
-		}
-		if ( hasPrimaryKey() ) {
-			buf.append( ", " )
-					.append( getPrimaryKey().sqlConstraintString( dialect ) );
-		}
-
-		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
-			Iterator ukiter = getUniqueKeyIterator();
-			while ( ukiter.hasNext() ) {
-				UniqueKey uk = (UniqueKey) ukiter.next();
-				String constraint = uk.sqlConstraintString( dialect );
-				if ( constraint != null ) {
-					buf.append( ", " ).append( constraint );
-				}
-			}
-		}
-		/*Iterator idxiter = getIndexIterator();
-		while ( idxiter.hasNext() ) {
-			Index idx = (Index) idxiter.next();
-			buf.append(',').append( idx.sqlConstraintString(dialect) );
-		}*/
-
-		if ( dialect.supportsTableCheck() ) {
-			Iterator chiter = checkConstraints.iterator();
-			while ( chiter.hasNext() ) {
-				buf.append( ", check (" )
-						.append( chiter.next() )
-						.append( ')' );
-			}
-		}
-
-		buf.append( ')' );
-
-		if ( comment != null ) {
-			buf.append( dialect.getTableComment( comment ) );
-		}
-
-		return buf.append( dialect.getTableTypeString() ).toString();
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		StringBuffer buf = new StringBuffer( "drop table " );
-		if ( dialect.supportsIfExistsBeforeTableName() ) {
-			buf.append( "if exists " );
-		}
-		buf.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
-				.append( dialect.getCascadeConstraintsString() );
-		if ( dialect.supportsIfExistsAfterTableName() ) {
-			buf.append( " if exists" );
-		}
-		return buf.toString();
-	}
-
-	public PrimaryKey getPrimaryKey() {
-		return primaryKey;
-	}
-
-	public void setPrimaryKey(PrimaryKey primaryKey) {
-		this.primaryKey = primaryKey;
-	}
-
-	public Index getOrCreateIndex(String indexName) {
-
-		Index index = (Index) indexes.get( indexName );
-
-		if ( index == null ) {
-			index = new Index();
-			index.setName( indexName );
-			index.setTable( this );
-			indexes.put( indexName, index );
-		}
-
-		return index;
-	}
-
-	public Index getIndex(String indexName) {
-		return (Index) indexes.get( indexName );
-	}
-
-	public Index addIndex(Index index) {
-		Index current = (Index) indexes.get( index.getName() );
-		if ( current != null ) {
-			throw new MappingException( "Index " + index.getName() + " already exists!" );
-		}
-		indexes.put( index.getName(), index );
-		return index;
-	}
-
-	public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
-		UniqueKey current = (UniqueKey) uniqueKeys.get( uniqueKey.getName() );
-		if ( current != null ) {
-			throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" );
-		}
-		uniqueKeys.put( uniqueKey.getName(), uniqueKey );
-		return uniqueKey;
-	}
-
-	public UniqueKey createUniqueKey(List keyColumns) {
-		String keyName = "UK" + uniqueColumnString( keyColumns.iterator() );
-		UniqueKey uk = getOrCreateUniqueKey( keyName );
-		uk.addColumns( keyColumns.iterator() );
-		return uk;
-	}
-
-	public UniqueKey getUniqueKey(String keyName) {
-		return (UniqueKey) uniqueKeys.get( keyName );
-	}
-
-	public UniqueKey getOrCreateUniqueKey(String keyName) {
-		UniqueKey uk = (UniqueKey) uniqueKeys.get( keyName );
-
-		if ( uk == null ) {
-			uk = new UniqueKey();
-			uk.setName( keyName );
-			uk.setTable( this );
-			uniqueKeys.put( keyName, uk );
-		}
-		return uk;
-	}
-
-	public void createForeignKeys() {
-	}
-
-	public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName) {
-		return createForeignKey( keyName, keyColumns, referencedEntityName, null );
-	}
-
-	public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName,
-									   List referencedColumns) {
-		Object key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns );
-
-		ForeignKey fk = (ForeignKey) foreignKeys.get( key );
-		if ( fk == null ) {
-			fk = new ForeignKey();
-			if ( keyName != null ) {
-				fk.setName( keyName );
-			}
-			else {
-				fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) );
-				//TODO: add referencedClass to disambiguate to FKs on the same
-				//      columns, pointing to different tables
-			}
-			fk.setTable( this );
-			foreignKeys.put( key, fk );
-			fk.setReferencedEntityName( referencedEntityName );
-			fk.addColumns( keyColumns.iterator() );
-			if ( referencedColumns != null ) {
-				fk.addReferencedColumns( referencedColumns.iterator() );
-			}
-		}
-
-		if ( keyName != null ) {
-			fk.setName( keyName );
-		}
-
-		return fk;
-	}
-
-
-	public String uniqueColumnString(Iterator iterator) {
-		return uniqueColumnString( iterator, null );
-	}
-
-	public String uniqueColumnString(Iterator iterator, String referencedEntityName) {
-		int result = 0;
-		if ( referencedEntityName != null ) {
-			result += referencedEntityName.hashCode();
-		}
-		while ( iterator.hasNext() ) {
-			result += iterator.next().hashCode();
-		}
-		return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase();
-	}
-
-
-	public String getSchema() {
-		return schema;
-	}
-
-	public void setSchema(String schema) {
-		if ( schema != null && schema.charAt( 0 ) == '`' ) {
-			schemaQuoted = true;
-			this.schema = schema.substring( 1, schema.length() - 1 );
-		}
-		else {
-			this.schema = schema;
-		}
-	}
-
-	public String getCatalog() {
-		return catalog;
-	}
-
-	public void setCatalog(String catalog) {
-		this.catalog = catalog;
-	}
-
-	public int getUniqueInteger() {
-		return uniqueInteger;
-	}
-
-	public void setIdentifierValue(KeyValue idValue) {
-		this.idValue = idValue;
-	}
-
-	public KeyValue getIdentifierValue() {
-		return idValue;
-	}
-
-	public boolean isSchemaQuoted() {
-		return schemaQuoted;
-	}
-
-	public boolean isQuoted() {
-		return quoted;
-	}
-
-	public void setQuoted(boolean quoted) {
-		this.quoted = quoted;
-	}
-
-	public void addCheckConstraint(String constraint) {
-		checkConstraints.add( constraint );
-	}
-
-	public boolean containsColumn(Column column) {
-		return columns.containsValue( column );
-	}
-
-	public String getRowId() {
-		return rowId;
-	}
-
-	public void setRowId(String rowId) {
-		this.rowId = rowId;
-	}
-
-	public String toString() {
-		StringBuffer buf = new StringBuffer().append( getClass().getName() )
-				.append( '(' );
-		if ( getCatalog() != null ) {
-			buf.append( getCatalog() + "." );
-		}
-		if ( getSchema() != null ) {
-			buf.append( getSchema() + "." );
-		}
-		buf.append( getName() ).append( ')' );
-		return buf.toString();
-	}
-
-	public String getSubselect() {
-		return subselect;
-	}
-
-	public void setSubselect(String subselect) {
-		this.subselect = subselect;
-	}
-
-	public boolean isSubselect() {
-		return subselect != null;
-	}
-
-	public boolean isAbstractUnionTable() {
-		return hasDenormalizedTables() && isAbstract;
-	}
-
-	public boolean hasDenormalizedTables() {
-		return hasDenormalizedTables;
-	}
-
-	void setHasDenormalizedTables() {
-		hasDenormalizedTables = true;
-	}
-
-	public void setAbstract(boolean isAbstract) {
-		this.isAbstract = isAbstract;
-	}
-
-	public boolean isAbstract() {
-		return isAbstract;
-	}
-
-	public boolean isPhysicalTable() {
-		return !isSubselect() && !isAbstractUnionTable();
-	}
-
-	public String getComment() {
-		return comment;
-	}
-
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-
-	public Iterator getCheckConstraintsIterator() {
-		return checkConstraints.iterator();
-	}
-
-	public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		List comments = new ArrayList();
-		if ( dialect.supportsCommentOn() ) {
-			String tableName = getQualifiedName( dialect, defaultCatalog, defaultSchema );
-			if ( comment != null ) {
-				StringBuffer buf = new StringBuffer()
-						.append( "comment on table " )
-						.append( tableName )
-						.append( " is '" )
-						.append( comment )
-						.append( "'" );
-				comments.add( buf.toString() );
-			}
-			Iterator iter = getColumnIterator();
-			while ( iter.hasNext() ) {
-				Column column = (Column) iter.next();
-				String columnComment = column.getComment();
-				if ( columnComment != null ) {
-					StringBuffer buf = new StringBuffer()
-							.append( "comment on column " )
-							.append( tableName )
-							.append( '.' )
-							.append( column.getQuotedName( dialect ) )
-							.append( " is '" )
-							.append( columnComment )
-							.append( "'" );
-					comments.add( buf.toString() );
-				}
-			}
-		}
-		return comments.iterator();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Table.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Table.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,794 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.tool.hbm2ddl.ColumnMetadata;
+import org.hibernate.tool.hbm2ddl.TableMetadata;
+import org.hibernate.util.CollectionHelper;
+
+/**
+ * A relational table
+ *
+ * @author Gavin King
+ */
+public class Table implements RelationalModel, Serializable {
+
+	private String name;
+	private String schema;
+	private String catalog;
+	/**
+	 * contains all columns, including the primary key
+	 */
+	private Map columns = new LinkedHashMap();
+	private KeyValue idValue;
+	private PrimaryKey primaryKey;
+	private Map indexes = new HashMap();
+	private Map foreignKeys = new HashMap();
+	private Map uniqueKeys = new HashMap();
+	private final int uniqueInteger;
+	private boolean quoted;
+	private boolean schemaQuoted;
+	private static int tableCounter = 0;
+	private List checkConstraints = new ArrayList();
+	private String rowId;
+	private String subselect;
+	private boolean isAbstract;
+	private boolean hasDenormalizedTables = false;
+	private String comment;
+
+	static class ForeignKeyKey implements Serializable {
+		String referencedClassName;
+		List columns;
+		List referencedColumns;
+
+		ForeignKeyKey(List columns, String referencedClassName, List referencedColumns) {
+			this.referencedClassName = referencedClassName;
+			this.columns = new ArrayList();
+			this.columns.addAll( columns );
+			if ( referencedColumns != null ) {
+				this.referencedColumns = new ArrayList();
+				this.referencedColumns.addAll( referencedColumns );
+			}
+			else {
+				this.referencedColumns = CollectionHelper.EMPTY_LIST;
+			}
+		}
+
+		public int hashCode() {
+			return columns.hashCode() + referencedColumns.hashCode();
+		}
+
+		public boolean equals(Object other) {
+			ForeignKeyKey fkk = (ForeignKeyKey) other;
+			return fkk.columns.equals( columns ) &&
+					fkk.referencedClassName.equals( referencedClassName ) && fkk.referencedColumns
+					.equals( referencedColumns );
+		}
+	}
+
+	public Table() {
+		uniqueInteger = tableCounter++;
+	}
+
+	public Table(String name) {
+		this();
+		setName( name );
+	}
+
+	public String getQualifiedName(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		if ( subselect != null ) {
+			return "( " + subselect + " )";
+		}
+		String quotedName = getQuotedName( dialect );
+		String usedSchema = schema == null ?
+				defaultSchema :
+				getQuotedSchema( dialect );
+		String usedCatalog = catalog == null ?
+				defaultCatalog :
+				catalog;
+		return qualify( usedCatalog, usedSchema, quotedName );
+	}
+
+	public static String qualify(String catalog, String schema, String table) {
+		StringBuffer qualifiedName = new StringBuffer();
+		if ( catalog != null ) {
+			qualifiedName.append( catalog ).append( '.' );
+		}
+		if ( schema != null ) {
+			qualifiedName.append( schema ).append( '.' );
+		}
+		return qualifiedName.append( table ).toString();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * returns quoted name as it would be in the mapping file.
+	 */
+	public String getQuotedName() {
+		return quoted ?
+				"`" + name + "`" :
+				name;
+	}
+
+	public String getQuotedName(Dialect dialect) {
+		return quoted ?
+				dialect.openQuote() + name + dialect.closeQuote() :
+				name;
+	}
+
+	/**
+	 * returns quoted name as it is in the mapping file.
+	 */
+	public String getQuotedSchema() {
+		return schemaQuoted ?
+				"`" + schema + "`" :
+				schema;
+	}
+
+	public String getQuotedSchema(Dialect dialect) {
+		return schemaQuoted ?
+				dialect.openQuote() + schema + dialect.closeQuote() :
+				schema;
+	}
+
+	public void setName(String name) {
+		if ( name.charAt( 0 ) == '`' ) {
+			quoted = true;
+			this.name = name.substring( 1, name.length() - 1 );
+		}
+		else {
+			this.name = name;
+		}
+	}
+
+	/**
+	 * Return the column which is identified by column provided as argument.
+	 *
+	 * @param column column with atleast a name.
+	 * @return the underlying column or null if not inside this table. Note: the instance *can* be different than the input parameter, but the name will be the same.
+	 */
+	public Column getColumn(Column column) {
+		if ( column == null ) {
+			return null;
+		}
+
+		Column myColumn = (Column) columns.get( column.getCanonicalName() );
+
+		return column.equals( myColumn ) ?
+				myColumn :
+				null;
+	}
+
+	public Column getColumn(int n) {
+		Iterator iter = columns.values().iterator();
+		for ( int i = 0; i < n - 1; i++ ) {
+			iter.next();
+		}
+		return (Column) iter.next();
+	}
+
+	public void addColumn(Column column) {
+		Column old = (Column) getColumn( column );
+		if ( old == null ) {
+			columns.put( column.getCanonicalName(), column );
+			column.uniqueInteger = columns.size();
+		}
+		else {
+			column.uniqueInteger = old.uniqueInteger;
+		}
+	}
+
+	public int getColumnSpan() {
+		return columns.size();
+	}
+
+	public Iterator getColumnIterator() {
+		return columns.values().iterator();
+	}
+
+	public Iterator getIndexIterator() {
+		return indexes.values().iterator();
+	}
+
+	public Iterator getForeignKeyIterator() {
+		return foreignKeys.values().iterator();
+	}
+
+	public Iterator getUniqueKeyIterator() {
+		return getUniqueKeys().values().iterator();
+	}
+
+	Map getUniqueKeys() {
+		if ( uniqueKeys.size() > 1 ) {
+			//deduplicate unique constraints sharing the same columns
+			//this is needed by Hibernate Annotations since it creates automagically
+			// unique constraints for the user
+			Iterator it = uniqueKeys.entrySet().iterator();
+			Map finalUniqueKeys = new HashMap( uniqueKeys.size() );
+			while ( it.hasNext() ) {
+				Map.Entry entry = (Map.Entry) it.next();
+				UniqueKey uk = (UniqueKey) entry.getValue();
+				List columns = uk.getColumns();
+				int size = finalUniqueKeys.size();
+				boolean skip = false;
+				Iterator tempUks = finalUniqueKeys.entrySet().iterator();
+				while ( tempUks.hasNext() ) {
+					final UniqueKey currentUk = (UniqueKey) ( (Map.Entry) tempUks.next() ).getValue();
+					if ( currentUk.getColumns().containsAll( columns ) && columns
+							.containsAll( currentUk.getColumns() ) ) {
+						skip = true;
+						break;
+					}
+				}
+				if ( !skip ) finalUniqueKeys.put( entry.getKey(), uk );
+			}
+			return finalUniqueKeys;
+		}
+		else {
+			return uniqueKeys;
+		}
+	}
+
+	public void validateColumns(Dialect dialect, Mapping mapping, TableMetadata tableInfo) {
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			Column col = (Column) iter.next();
+
+			ColumnMetadata columnInfo = tableInfo.getColumnMetadata( col.getName() );
+
+			if ( columnInfo == null ) {
+				throw new HibernateException( "Missing column: " + col.getName() + " in " + Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()));
+			}
+			else {
+				final boolean typesMatch = col.getSqlType( dialect, mapping ).toLowerCase()
+						.startsWith( columnInfo.getTypeName().toLowerCase() )
+						|| columnInfo.getTypeCode() == col.getSqlTypeCode( mapping );
+				if ( !typesMatch ) {
+					throw new HibernateException(
+							"Wrong column type in " +
+							Table.qualify( tableInfo.getCatalog(), tableInfo.getSchema(), tableInfo.getName()) +
+							" for column " + col.getName() +
+							". Found: " + columnInfo.getTypeName().toLowerCase() +
+							", expected: " + col.getSqlType( dialect, mapping )
+					);
+				}
+			}
+		}
+
+	}
+
+	public Iterator sqlAlterStrings(Dialect dialect, Mapping p, TableMetadata tableInfo, String defaultCatalog,
+									String defaultSchema)
+			throws HibernateException {
+
+		StringBuffer root = new StringBuffer( "alter table " )
+				.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+				.append( ' ' )
+				.append( dialect.getAddColumnString() );
+
+		Iterator iter = getColumnIterator();
+		List results = new ArrayList();
+		while ( iter.hasNext() ) {
+			Column column = (Column) iter.next();
+
+			ColumnMetadata columnInfo = tableInfo.getColumnMetadata( column.getName() );
+
+			if ( columnInfo == null ) {
+				// the column doesnt exist at all.
+				StringBuffer alter = new StringBuffer( root.toString() )
+						.append( ' ' )
+						.append( column.getQuotedName( dialect ) )
+						.append( ' ' )
+						.append( column.getSqlType( dialect, p ) );
+
+				String defaultValue = column.getDefaultValue();
+				if ( defaultValue != null ) {
+					alter.append( " default " ).append( defaultValue );
+
+					if ( column.isNullable() ) {
+						alter.append( dialect.getNullColumnString() );
+					}
+					else {
+						alter.append( " not null" );
+					}
+
+				}
+
+				boolean useUniqueConstraint = column.isUnique() &&
+						dialect.supportsUnique() &&
+						( !column.isNullable() || dialect.supportsNotNullUnique() );
+				if ( useUniqueConstraint ) {
+					alter.append( " unique" );
+				}
+
+				if ( column.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
+					alter.append( " check(" )
+							.append( column.getCheckConstraint() )
+							.append( ")" );
+				}
+
+				String columnComment = column.getComment();
+				if ( columnComment != null ) {
+					alter.append( dialect.getColumnComment( columnComment ) );
+				}
+
+				results.add( alter.toString() );
+			}
+
+		}
+
+		return results.iterator();
+	}
+
+	public boolean hasPrimaryKey() {
+		return getPrimaryKey() != null;
+	}
+
+	public String sqlTemporaryTableCreateString(Dialect dialect, Mapping mapping) throws HibernateException {
+		StringBuffer buffer = new StringBuffer( dialect.getCreateTemporaryTableString() )
+				.append( ' ' )
+				.append( name )
+				.append( " (" );
+		Iterator itr = getColumnIterator();
+		while ( itr.hasNext() ) {
+			final Column column = (Column) itr.next();
+			buffer.append( column.getQuotedName( dialect ) ).append( ' ' );
+			buffer.append( column.getSqlType( dialect, mapping ) );
+			if ( column.isNullable() ) {
+				buffer.append( dialect.getNullColumnString() );
+			}
+			else {
+				buffer.append( " not null" );
+			}
+			if ( itr.hasNext() ) {
+				buffer.append( ", " );
+			}
+		}
+		buffer.append( ") " );
+		buffer.append( dialect.getCreateTemporaryTablePostfix() );
+		return buffer.toString();
+	}
+
+	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
+		StringBuffer buf = new StringBuffer( hasPrimaryKey() ? dialect.getCreateTableString() : dialect.getCreateMultisetTableString() )
+				.append( ' ' )
+				.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+				.append( " (" );
+
+		boolean identityColumn = idValue != null && idValue.isIdentityColumn( dialect );
+
+		// Try to find out the name of the primary key to create it as identity if the IdentityGenerator is used
+		String pkname = null;
+		if ( hasPrimaryKey() && identityColumn ) {
+			pkname = ( (Column) getPrimaryKey().getColumnIterator().next() ).getQuotedName( dialect );
+		}
+
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			Column col = (Column) iter.next();
+
+			buf.append( col.getQuotedName( dialect ) )
+					.append( ' ' );
+
+			if ( identityColumn && col.getQuotedName( dialect ).equals( pkname ) ) {
+				// to support dialects that have their own identity data type
+				if ( dialect.hasDataTypeInIdentityColumn() ) {
+					buf.append( col.getSqlType( dialect, p ) );
+				}
+				buf.append( ' ' )
+						.append( dialect.getIdentityColumnString( col.getSqlTypeCode( p ) ) );
+			}
+			else {
+
+				buf.append( col.getSqlType( dialect, p ) );
+
+				String defaultValue = col.getDefaultValue();
+				if ( defaultValue != null ) {
+					buf.append( " default " ).append( defaultValue );
+				}
+
+				if ( col.isNullable() ) {
+					buf.append( dialect.getNullColumnString() );
+				}
+				else {
+					buf.append( " not null" );
+				}
+
+			}
+
+			boolean useUniqueConstraint = col.isUnique() &&
+					( !col.isNullable() || dialect.supportsNotNullUnique() );
+			if ( useUniqueConstraint ) {
+				if ( dialect.supportsUnique() ) {
+					buf.append( " unique" );
+				}
+				else {
+					UniqueKey uk = getOrCreateUniqueKey( col.getQuotedName( dialect ) + '_' );
+					uk.addColumn( col );
+				}
+			}
+
+			if ( col.hasCheckConstraint() && dialect.supportsColumnCheck() ) {
+				buf.append( " check (" )
+						.append( col.getCheckConstraint() )
+						.append( ")" );
+			}
+
+			String columnComment = col.getComment();
+			if ( columnComment != null ) {
+				buf.append( dialect.getColumnComment( columnComment ) );
+			}
+
+			if ( iter.hasNext() ) {
+				buf.append( ", " );
+			}
+
+		}
+		if ( hasPrimaryKey() ) {
+			buf.append( ", " )
+					.append( getPrimaryKey().sqlConstraintString( dialect ) );
+		}
+
+		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+			Iterator ukiter = getUniqueKeyIterator();
+			while ( ukiter.hasNext() ) {
+				UniqueKey uk = (UniqueKey) ukiter.next();
+				String constraint = uk.sqlConstraintString( dialect );
+				if ( constraint != null ) {
+					buf.append( ", " ).append( constraint );
+				}
+			}
+		}
+		/*Iterator idxiter = getIndexIterator();
+		while ( idxiter.hasNext() ) {
+			Index idx = (Index) idxiter.next();
+			buf.append(',').append( idx.sqlConstraintString(dialect) );
+		}*/
+
+		if ( dialect.supportsTableCheck() ) {
+			Iterator chiter = checkConstraints.iterator();
+			while ( chiter.hasNext() ) {
+				buf.append( ", check (" )
+						.append( chiter.next() )
+						.append( ')' );
+			}
+		}
+
+		buf.append( ')' );
+
+		if ( comment != null ) {
+			buf.append( dialect.getTableComment( comment ) );
+		}
+
+		return buf.append( dialect.getTableTypeString() ).toString();
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		StringBuffer buf = new StringBuffer( "drop table " );
+		if ( dialect.supportsIfExistsBeforeTableName() ) {
+			buf.append( "if exists " );
+		}
+		buf.append( getQualifiedName( dialect, defaultCatalog, defaultSchema ) )
+				.append( dialect.getCascadeConstraintsString() );
+		if ( dialect.supportsIfExistsAfterTableName() ) {
+			buf.append( " if exists" );
+		}
+		return buf.toString();
+	}
+
+	public PrimaryKey getPrimaryKey() {
+		return primaryKey;
+	}
+
+	public void setPrimaryKey(PrimaryKey primaryKey) {
+		this.primaryKey = primaryKey;
+	}
+
+	public Index getOrCreateIndex(String indexName) {
+
+		Index index = (Index) indexes.get( indexName );
+
+		if ( index == null ) {
+			index = new Index();
+			index.setName( indexName );
+			index.setTable( this );
+			indexes.put( indexName, index );
+		}
+
+		return index;
+	}
+
+	public Index getIndex(String indexName) {
+		return (Index) indexes.get( indexName );
+	}
+
+	public Index addIndex(Index index) {
+		Index current = (Index) indexes.get( index.getName() );
+		if ( current != null ) {
+			throw new MappingException( "Index " + index.getName() + " already exists!" );
+		}
+		indexes.put( index.getName(), index );
+		return index;
+	}
+
+	public UniqueKey addUniqueKey(UniqueKey uniqueKey) {
+		UniqueKey current = (UniqueKey) uniqueKeys.get( uniqueKey.getName() );
+		if ( current != null ) {
+			throw new MappingException( "UniqueKey " + uniqueKey.getName() + " already exists!" );
+		}
+		uniqueKeys.put( uniqueKey.getName(), uniqueKey );
+		return uniqueKey;
+	}
+
+	public UniqueKey createUniqueKey(List keyColumns) {
+		String keyName = "UK" + uniqueColumnString( keyColumns.iterator() );
+		UniqueKey uk = getOrCreateUniqueKey( keyName );
+		uk.addColumns( keyColumns.iterator() );
+		return uk;
+	}
+
+	public UniqueKey getUniqueKey(String keyName) {
+		return (UniqueKey) uniqueKeys.get( keyName );
+	}
+
+	public UniqueKey getOrCreateUniqueKey(String keyName) {
+		UniqueKey uk = (UniqueKey) uniqueKeys.get( keyName );
+
+		if ( uk == null ) {
+			uk = new UniqueKey();
+			uk.setName( keyName );
+			uk.setTable( this );
+			uniqueKeys.put( keyName, uk );
+		}
+		return uk;
+	}
+
+	public void createForeignKeys() {
+	}
+
+	public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName) {
+		return createForeignKey( keyName, keyColumns, referencedEntityName, null );
+	}
+
+	public ForeignKey createForeignKey(String keyName, List keyColumns, String referencedEntityName,
+									   List referencedColumns) {
+		Object key = new ForeignKeyKey( keyColumns, referencedEntityName, referencedColumns );
+
+		ForeignKey fk = (ForeignKey) foreignKeys.get( key );
+		if ( fk == null ) {
+			fk = new ForeignKey();
+			if ( keyName != null ) {
+				fk.setName( keyName );
+			}
+			else {
+				fk.setName( "FK" + uniqueColumnString( keyColumns.iterator(), referencedEntityName ) );
+				//TODO: add referencedClass to disambiguate to FKs on the same
+				//      columns, pointing to different tables
+			}
+			fk.setTable( this );
+			foreignKeys.put( key, fk );
+			fk.setReferencedEntityName( referencedEntityName );
+			fk.addColumns( keyColumns.iterator() );
+			if ( referencedColumns != null ) {
+				fk.addReferencedColumns( referencedColumns.iterator() );
+			}
+		}
+
+		if ( keyName != null ) {
+			fk.setName( keyName );
+		}
+
+		return fk;
+	}
+
+
+	public String uniqueColumnString(Iterator iterator) {
+		return uniqueColumnString( iterator, null );
+	}
+
+	public String uniqueColumnString(Iterator iterator, String referencedEntityName) {
+		int result = 0;
+		if ( referencedEntityName != null ) {
+			result += referencedEntityName.hashCode();
+		}
+		while ( iterator.hasNext() ) {
+			result += iterator.next().hashCode();
+		}
+		return ( Integer.toHexString( name.hashCode() ) + Integer.toHexString( result ) ).toUpperCase();
+	}
+
+
+	public String getSchema() {
+		return schema;
+	}
+
+	public void setSchema(String schema) {
+		if ( schema != null && schema.charAt( 0 ) == '`' ) {
+			schemaQuoted = true;
+			this.schema = schema.substring( 1, schema.length() - 1 );
+		}
+		else {
+			this.schema = schema;
+		}
+	}
+
+	public String getCatalog() {
+		return catalog;
+	}
+
+	public void setCatalog(String catalog) {
+		this.catalog = catalog;
+	}
+
+	public int getUniqueInteger() {
+		return uniqueInteger;
+	}
+
+	public void setIdentifierValue(KeyValue idValue) {
+		this.idValue = idValue;
+	}
+
+	public KeyValue getIdentifierValue() {
+		return idValue;
+	}
+
+	public boolean isSchemaQuoted() {
+		return schemaQuoted;
+	}
+
+	public boolean isQuoted() {
+		return quoted;
+	}
+
+	public void setQuoted(boolean quoted) {
+		this.quoted = quoted;
+	}
+
+	public void addCheckConstraint(String constraint) {
+		checkConstraints.add( constraint );
+	}
+
+	public boolean containsColumn(Column column) {
+		return columns.containsValue( column );
+	}
+
+	public String getRowId() {
+		return rowId;
+	}
+
+	public void setRowId(String rowId) {
+		this.rowId = rowId;
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer().append( getClass().getName() )
+				.append( '(' );
+		if ( getCatalog() != null ) {
+			buf.append( getCatalog() + "." );
+		}
+		if ( getSchema() != null ) {
+			buf.append( getSchema() + "." );
+		}
+		buf.append( getName() ).append( ')' );
+		return buf.toString();
+	}
+
+	public String getSubselect() {
+		return subselect;
+	}
+
+	public void setSubselect(String subselect) {
+		this.subselect = subselect;
+	}
+
+	public boolean isSubselect() {
+		return subselect != null;
+	}
+
+	public boolean isAbstractUnionTable() {
+		return hasDenormalizedTables() && isAbstract;
+	}
+
+	public boolean hasDenormalizedTables() {
+		return hasDenormalizedTables;
+	}
+
+	void setHasDenormalizedTables() {
+		hasDenormalizedTables = true;
+	}
+
+	public void setAbstract(boolean isAbstract) {
+		this.isAbstract = isAbstract;
+	}
+
+	public boolean isAbstract() {
+		return isAbstract;
+	}
+
+	public boolean isPhysicalTable() {
+		return !isSubselect() && !isAbstractUnionTable();
+	}
+
+	public String getComment() {
+		return comment;
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public Iterator getCheckConstraintsIterator() {
+		return checkConstraints.iterator();
+	}
+
+	public Iterator sqlCommentStrings(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		List comments = new ArrayList();
+		if ( dialect.supportsCommentOn() ) {
+			String tableName = getQualifiedName( dialect, defaultCatalog, defaultSchema );
+			if ( comment != null ) {
+				StringBuffer buf = new StringBuffer()
+						.append( "comment on table " )
+						.append( tableName )
+						.append( " is '" )
+						.append( comment )
+						.append( "'" );
+				comments.add( buf.toString() );
+			}
+			Iterator iter = getColumnIterator();
+			while ( iter.hasNext() ) {
+				Column column = (Column) iter.next();
+				String columnComment = column.getComment();
+				if ( columnComment != null ) {
+					StringBuffer buf = new StringBuffer()
+							.append( "comment on column " )
+							.append( tableName )
+							.append( '.' )
+							.append( column.getQuotedName( dialect ) )
+							.append( " is '" )
+							.append( columnComment )
+							.append( "'" );
+					comments.add( buf.toString() );
+				}
+			}
+		}
+		return comments.iterator();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/TableOwner.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-//$Id: TableOwner.java 4646 2004-10-06 23:24:14Z epbernard $
-package org.hibernate.mapping;
-
-/**
- * Interface allowing to differenciate SubClasses
- * from Classes, JoinedSubClasses and UnionSubClasses
- * The first one has not its own table while the others have
- * 
- * @author Emmanuel Bernard
- */
-public interface TableOwner {
-	void setTable(Table table);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/TableOwner.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TableOwner.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+/**
+ * Interface allowing to differenciate SubClasses
+ * from Classes, JoinedSubClasses and UnionSubClasses
+ * The first one has not its own table while the others have
+ * 
+ * @author Emmanuel Bernard
+ */
+public interface TableOwner {
+	void setTable(Table table);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/ToOne.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-//$Id: ToOne.java 7246 2005-06-20 20:32:36Z oneovthafew $
-package org.hibernate.mapping;
-
-import org.hibernate.FetchMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.Type;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A simple-point association (ie. a reference to another entity).
- * @author Gavin King
- */
-public abstract class ToOne extends SimpleValue implements Fetchable {
-
-	private FetchMode fetchMode;
-	protected String referencedPropertyName;
-	private String referencedEntityName;
-	private boolean embedded;
-	private boolean lazy = true;
-	protected boolean unwrapProxy;
-
-	protected ToOne(Table table) {
-		super(table);
-	}
-
-	public FetchMode getFetchMode() {
-		return fetchMode;
-	}
-
-	public void setFetchMode(FetchMode fetchMode) {
-		this.fetchMode=fetchMode;
-	}
-
-	public abstract void createForeignKey() throws MappingException;
-	public abstract Type getType() throws MappingException;
-
-	public String getReferencedPropertyName() {
-		return referencedPropertyName;
-	}
-
-	public void setReferencedPropertyName(String name) {
-		referencedPropertyName = name==null ? null : name.intern();
-	}
-
-	public String getReferencedEntityName() {
-		return referencedEntityName;
-	}
-
-	public void setReferencedEntityName(String referencedEntityName) {
-		this.referencedEntityName = referencedEntityName==null ? 
-				null : referencedEntityName.intern();
-	}
-
-	public void setTypeUsingReflection(String className, String propertyName)
-	throws MappingException {
-		if (referencedEntityName==null) {
-			referencedEntityName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName();
-		}
-	}
-
-	public boolean isTypeSpecified() {
-		return referencedEntityName!=null;
-	}
-	
-	public Object accept(ValueVisitor visitor) {
-		return visitor.accept(this);
-	}
-	
-	public boolean isEmbedded() {
-		return embedded;
-	}
-	
-	public void setEmbedded(boolean embedded) {
-		this.embedded = embedded;
-	}
-
-	public boolean isValid(Mapping mapping) throws MappingException {
-		if (referencedEntityName==null) {
-			throw new MappingException("association must specify the referenced entity");
-		}
-		return super.isValid( mapping );
-	}
-
-	public boolean isLazy() {
-		return lazy;
-	}
-	
-	public void setLazy(boolean lazy) {
-		this.lazy = lazy;
-	}
-
-	public boolean isUnwrapProxy() {
-		return unwrapProxy;
-	}
-
-	public void setUnwrapProxy(boolean unwrapProxy) {
-		this.unwrapProxy = unwrapProxy;
-	}
-	
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/ToOne.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ToOne.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,131 @@
+/*
+ * 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.mapping;
+
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.Type;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A simple-point association (ie. a reference to another entity).
+ * @author Gavin King
+ */
+public abstract class ToOne extends SimpleValue implements Fetchable {
+
+	private FetchMode fetchMode;
+	protected String referencedPropertyName;
+	private String referencedEntityName;
+	private boolean embedded;
+	private boolean lazy = true;
+	protected boolean unwrapProxy;
+
+	protected ToOne(Table table) {
+		super(table);
+	}
+
+	public FetchMode getFetchMode() {
+		return fetchMode;
+	}
+
+	public void setFetchMode(FetchMode fetchMode) {
+		this.fetchMode=fetchMode;
+	}
+
+	public abstract void createForeignKey() throws MappingException;
+	public abstract Type getType() throws MappingException;
+
+	public String getReferencedPropertyName() {
+		return referencedPropertyName;
+	}
+
+	public void setReferencedPropertyName(String name) {
+		referencedPropertyName = name==null ? null : name.intern();
+	}
+
+	public String getReferencedEntityName() {
+		return referencedEntityName;
+	}
+
+	public void setReferencedEntityName(String referencedEntityName) {
+		this.referencedEntityName = referencedEntityName==null ? 
+				null : referencedEntityName.intern();
+	}
+
+	public void setTypeUsingReflection(String className, String propertyName)
+	throws MappingException {
+		if (referencedEntityName==null) {
+			referencedEntityName = ReflectHelper.reflectedPropertyClass(className, propertyName).getName();
+		}
+	}
+
+	public boolean isTypeSpecified() {
+		return referencedEntityName!=null;
+	}
+	
+	public Object accept(ValueVisitor visitor) {
+		return visitor.accept(this);
+	}
+	
+	public boolean isEmbedded() {
+		return embedded;
+	}
+	
+	public void setEmbedded(boolean embedded) {
+		this.embedded = embedded;
+	}
+
+	public boolean isValid(Mapping mapping) throws MappingException {
+		if (referencedEntityName==null) {
+			throw new MappingException("association must specify the referenced entity");
+		}
+		return super.isValid( mapping );
+	}
+
+	public boolean isLazy() {
+		return lazy;
+	}
+	
+	public void setLazy(boolean lazy) {
+		this.lazy = lazy;
+	}
+
+	public boolean isUnwrapProxy() {
+		return unwrapProxy;
+	}
+
+	public void setUnwrapProxy(boolean unwrapProxy) {
+		this.unwrapProxy = unwrapProxy;
+	}
+	
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/TypeDef.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,26 +0,0 @@
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.Properties;
-
-/**
- * Placeholder for typedef information
- */
-public class TypeDef implements Serializable {
-
-	private String typeClass;
-	private Properties parameters;
-
-	public TypeDef(String typeClass, Properties parameters) {
-		this.typeClass = typeClass;
-		this.parameters = parameters;
-	}
-
-	public Properties getParameters() {
-		return parameters;
-	}
-	public String getTypeClass() {
-		return typeClass;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/TypeDef.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/TypeDef.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.Properties;
+
+/**
+ * Placeholder for typedef information
+ */
+public class TypeDef implements Serializable {
+
+	private String typeClass;
+	private Properties parameters;
+
+	public TypeDef(String typeClass, Properties parameters) {
+		this.typeClass = typeClass;
+		this.parameters = parameters;
+	}
+
+	public Properties getParameters() {
+		return parameters;
+	}
+	public String getTypeClass() {
+		return typeClass;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/UnionSubclass.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: UnionSubclass.java 6514 2005-04-26 06:37:54Z oneovthafew $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-
-/**
- * A subclass in a table-per-concrete-class mapping
- * @author Gavin King
- */
-public class UnionSubclass extends Subclass implements TableOwner {
-
-	private Table table;
-	private KeyValue key;
-
-	public UnionSubclass(PersistentClass superclass) {
-		super(superclass);
-	}
-
-	public Table getTable() {
-		return table;
-	}
-
-	public void setTable(Table table) {
-		this.table = table;
-		getSuperclass().addSubclassTable(table);
-	}
-
-	public java.util.Set getSynchronizedTables() {
-		return synchronizedTables;
-	}
-	
-	protected Iterator getNonDuplicatedPropertyIterator() {
-		return getPropertyClosureIterator();
-	}
-
-	public void validate(Mapping mapping) throws MappingException {
-		super.validate(mapping);
-		if ( key!=null && !key.isValid(mapping) ) {
-			throw new MappingException(
-				"subclass key mapping has wrong number of columns: " +
-				getEntityName() +
-				" type: " +
-				key.getType().getName()
-			);
-		}
-	}
-	
-	public Table getIdentityTable() {
-		return getTable();
-	}
-	
-	public Object accept(PersistentClassVisitor mv) {
-		return mv.accept(this);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/UnionSubclass.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UnionSubclass.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+
+/**
+ * A subclass in a table-per-concrete-class mapping
+ * @author Gavin King
+ */
+public class UnionSubclass extends Subclass implements TableOwner {
+
+	private Table table;
+	private KeyValue key;
+
+	public UnionSubclass(PersistentClass superclass) {
+		super(superclass);
+	}
+
+	public Table getTable() {
+		return table;
+	}
+
+	public void setTable(Table table) {
+		this.table = table;
+		getSuperclass().addSubclassTable(table);
+	}
+
+	public java.util.Set getSynchronizedTables() {
+		return synchronizedTables;
+	}
+	
+	protected Iterator getNonDuplicatedPropertyIterator() {
+		return getPropertyClosureIterator();
+	}
+
+	public void validate(Mapping mapping) throws MappingException {
+		super.validate(mapping);
+		if ( key!=null && !key.isValid(mapping) ) {
+			throw new MappingException(
+				"subclass key mapping has wrong number of columns: " +
+				getEntityName() +
+				" type: " +
+				key.getType().getName()
+			);
+		}
+	}
+	
+	public Table getIdentityTable() {
+		return getTable();
+	}
+	
+	public Object accept(PersistentClassVisitor mv) {
+		return mv.accept(this);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: UniqueKey.java 10661 2006-10-31 02:19:13Z epbernard $
-package org.hibernate.mapping;
-
-import java.util.Iterator;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.util.StringHelper;
-
-/**
- * A relational unique key constraint
- *
- * @author Gavin King
- */
-public class UniqueKey extends Constraint {
-
-	public String sqlConstraintString(Dialect dialect) {
-		StringBuffer buf = new StringBuffer( "unique (" );
-		Iterator iter = getColumnIterator();
-		boolean nullable = false;
-		while ( iter.hasNext() ) {
-			Column column = (Column) iter.next();
-			if ( !nullable && column.isNullable() ) nullable = true;
-			buf.append( column.getQuotedName( dialect ) );
-			if ( iter.hasNext() ) buf.append( ", " );
-		}
-		//do not add unique constraint on DB not supporting unique and nullable columns
-		return !nullable || dialect.supportsNotNullUnique() ?
-				buf.append( ')' ).toString() :
-				null;
-	}
-
-	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog,
-									  String defaultSchema) {
-		StringBuffer buf = new StringBuffer(
-				dialect.getAddPrimaryKeyConstraintString( constraintName )
-		).append( '(' );
-		Iterator iter = getColumnIterator();
-		boolean nullable = false;
-		while ( iter.hasNext() ) {
-			Column column = (Column) iter.next();
-			if ( !nullable && column.isNullable() ) nullable = true;
-			buf.append( column.getQuotedName( dialect ) );
-			if ( iter.hasNext() ) buf.append( ", " );
-		}
-		return !nullable || dialect.supportsNotNullUnique() ?
-				StringHelper.replace( buf.append( ')' ).toString(), "primary key", "unique" ) :
-				//TODO: improve this hack!
-				null;
-	}
-
-	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
-		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
-			return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema );
-		}
-		else {
-			return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true,
-					defaultCatalog, defaultSchema );
-		}
-	}
-
-	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
-		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
-			return super.sqlDropString( dialect, defaultCatalog, defaultSchema );
-		}
-		else {
-			return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema );
-		}
-	}
-
-	public boolean isGenerated(Dialect dialect) {
-		if ( dialect.supportsNotNullUnique() ) return true;
-		Iterator iter = getColumnIterator();
-		while ( iter.hasNext() ) {
-			if ( ( (Column) iter.next() ).isNullable() ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/UniqueKey.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/UniqueKey.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,105 @@
+/*
+ * 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.mapping;
+
+import java.util.Iterator;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A relational unique key constraint
+ *
+ * @author Gavin King
+ */
+public class UniqueKey extends Constraint {
+
+	public String sqlConstraintString(Dialect dialect) {
+		StringBuffer buf = new StringBuffer( "unique (" );
+		Iterator iter = getColumnIterator();
+		boolean nullable = false;
+		while ( iter.hasNext() ) {
+			Column column = (Column) iter.next();
+			if ( !nullable && column.isNullable() ) nullable = true;
+			buf.append( column.getQuotedName( dialect ) );
+			if ( iter.hasNext() ) buf.append( ", " );
+		}
+		//do not add unique constraint on DB not supporting unique and nullable columns
+		return !nullable || dialect.supportsNotNullUnique() ?
+				buf.append( ')' ).toString() :
+				null;
+	}
+
+	public String sqlConstraintString(Dialect dialect, String constraintName, String defaultCatalog,
+									  String defaultSchema) {
+		StringBuffer buf = new StringBuffer(
+				dialect.getAddPrimaryKeyConstraintString( constraintName )
+		).append( '(' );
+		Iterator iter = getColumnIterator();
+		boolean nullable = false;
+		while ( iter.hasNext() ) {
+			Column column = (Column) iter.next();
+			if ( !nullable && column.isNullable() ) nullable = true;
+			buf.append( column.getQuotedName( dialect ) );
+			if ( iter.hasNext() ) buf.append( ", " );
+		}
+		return !nullable || dialect.supportsNotNullUnique() ?
+				StringHelper.replace( buf.append( ')' ).toString(), "primary key", "unique" ) :
+				//TODO: improve this hack!
+				null;
+	}
+
+	public String sqlCreateString(Dialect dialect, Mapping p, String defaultCatalog, String defaultSchema) {
+		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+			return super.sqlCreateString( dialect, p, defaultCatalog, defaultSchema );
+		}
+		else {
+			return Index.buildSqlCreateIndexString( dialect, getName(), getTable(), getColumnIterator(), true,
+					defaultCatalog, defaultSchema );
+		}
+	}
+
+	public String sqlDropString(Dialect dialect, String defaultCatalog, String defaultSchema) {
+		if ( dialect.supportsUniqueConstraintInCreateAlterTable() ) {
+			return super.sqlDropString( dialect, defaultCatalog, defaultSchema );
+		}
+		else {
+			return Index.buildSqlDropIndexString( dialect, getTable(), getName(), defaultCatalog, defaultSchema );
+		}
+	}
+
+	public boolean isGenerated(Dialect dialect) {
+		if ( dialect.supportsNotNullUnique() ) return true;
+		Iterator iter = getColumnIterator();
+		while ( iter.hasNext() ) {
+			if ( ( (Column) iter.next() ).isNullable() ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Value.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: Value.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.mapping;
-
-import java.io.Serializable;
-import java.util.Iterator;
-
-import org.hibernate.FetchMode;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.type.Type;
-
-/**
- * A value is anything that is persisted by value, instead of
- * by reference. It is essentially a Hibernate Type, together
- * with zero or more columns. Values are wrapped by things with
- * higher level semantics, for example properties, collections,
- * classes.
- *
- * @author Gavin King
- */
-public interface Value extends Serializable {
-	public int getColumnSpan();
-	public Iterator getColumnIterator();
-	public Type getType() throws MappingException;
-	public FetchMode getFetchMode();
-	public Table getTable();
-	public boolean hasFormula();
-	public boolean isAlternateUniqueKey();
-	public boolean isNullable();
-	public boolean[] getColumnUpdateability();
-	public boolean[] getColumnInsertability();
-	public void createForeignKey() throws MappingException;
-	public boolean isSimpleValue();
-	public boolean isValid(Mapping mapping) throws MappingException;
-	public void setTypeUsingReflection(String className, String propertyName) throws MappingException;
-	public Object accept(ValueVisitor visitor);
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/Value.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/Value.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.mapping;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.hibernate.FetchMode;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.type.Type;
+
+/**
+ * A value is anything that is persisted by value, instead of
+ * by reference. It is essentially a Hibernate Type, together
+ * with zero or more columns. Values are wrapped by things with
+ * higher level semantics, for example properties, collections,
+ * classes.
+ *
+ * @author Gavin King
+ */
+public interface Value extends Serializable {
+	public int getColumnSpan();
+	public Iterator getColumnIterator();
+	public Type getType() throws MappingException;
+	public FetchMode getFetchMode();
+	public Table getTable();
+	public boolean hasFormula();
+	public boolean isAlternateUniqueKey();
+	public boolean isNullable();
+	public boolean[] getColumnUpdateability();
+	public boolean[] getColumnInsertability();
+	public void createForeignKey() throws MappingException;
+	public boolean isSimpleValue();
+	public boolean isValid(Mapping mapping) throws MappingException;
+	public void setTypeUsingReflection(String className, String propertyName) throws MappingException;
+	public Object accept(ValueVisitor visitor);
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/ValueVisitor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-/*
- * Created on 06-Dec-2004
- *
- */
-package org.hibernate.mapping;
-
-/**
- * @author max
- *
- */
-public interface ValueVisitor {
-
-	/**
-	 * @param bag
-	 */
-	Object accept(Bag bag);
-
-	/**
-	 * @param bag
-	 */
-	Object accept(IdentifierBag bag);
-
-	/**
-	 * @param list
-	 */
-	Object accept(List list);
-	
-	Object accept(PrimitiveArray primitiveArray);
-	Object accept(Array list);
-
-	/**
-	 * @param map
-	 */
-	Object accept(Map map);
-
-	/**
-	 * @param many
-	 */
-	Object accept(OneToMany many);
-
-	/**
-	 * @param set
-	 */
-	Object accept(Set set);
-
-	/**
-	 * @param any
-	 */
-	Object accept(Any any);
-
-	/**
-	 * @param value
-	 */
-	Object accept(SimpleValue value);
-	Object accept(DependantValue value);
-	
-	Object accept(Component component);
-	
-	Object accept(ManyToOne mto);
-	Object accept(OneToOne oto);
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/ValueVisitor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/ValueVisitor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,83 @@
+/*
+ * 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.mapping;
+
+/**
+ * @author max
+ *
+ */
+public interface ValueVisitor {
+
+	/**
+	 * @param bag
+	 */
+	Object accept(Bag bag);
+
+	/**
+	 * @param bag
+	 */
+	Object accept(IdentifierBag bag);
+
+	/**
+	 * @param list
+	 */
+	Object accept(List list);
+	
+	Object accept(PrimitiveArray primitiveArray);
+	Object accept(Array list);
+
+	/**
+	 * @param map
+	 */
+	Object accept(Map map);
+
+	/**
+	 * @param many
+	 */
+	Object accept(OneToMany many);
+
+	/**
+	 * @param set
+	 */
+	Object accept(Set set);
+
+	/**
+	 * @param any
+	 */
+	Object accept(Any any);
+
+	/**
+	 * @param value
+	 */
+	Object accept(SimpleValue value);
+	Object accept(DependantValue value);
+	
+	Object accept(Component component);
+	
+	Object accept(ManyToOne mto);
+	Object accept(OneToOne oto);
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines the Hibernate configuration-time metamodel.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/mapping/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/mapping/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines the Hibernate configuration-time metamodel.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/metadata/ClassMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,186 +0,0 @@
-//$Id: ClassMetadata.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.metadata;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.EntityMode;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Exposes entity class metadata to the application
- *
- * @see org.hibernate.SessionFactory#getClassMetadata(Class)
- * @author Gavin King
- */
-public interface ClassMetadata {
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * The name of the entity
-	 */
-	public String getEntityName();
-
-	/**
-	 * Get the name of the identifier property (or return null)
-	 */
-	public String getIdentifierPropertyName();
-
-	/**
-	 * Get the names of the class' persistent properties
-	 */
-	public String[] getPropertyNames();
-
-	/**
-	 * Get the identifier Hibernate type
-	 */
-	public Type getIdentifierType();
-
-	/**
-	 * Get the Hibernate types of the class properties
-	 */
-	public Type[] getPropertyTypes();
-
-	/**
-	 * Get the type of a particular (named) property
-	 */
-	public Type getPropertyType(String propertyName) throws HibernateException;
-
-	/**
-	 * Does this class support dynamic proxies?
-	 */
-	public boolean hasProxy();
-
-	/**
-	 * Are instances of this class mutable?
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Are instances of this class versioned by a timestamp or version number column?
-	 */
-	public boolean isVersioned();
-
-	/**
-	 * Get the index of the version property
-	 */
-	public int getVersionProperty();
-
-	/**
-	 * Get the nullability of the class' persistent properties
-	 */
-	public boolean[] getPropertyNullability();
-
-
-	/**
-	 * Get the "laziness" of the properties of this class
-	 */
-	public boolean[] getPropertyLaziness();
-
-	/**
-	 * Does this class have an identifier property?
-	 */
-	public boolean hasIdentifierProperty();
-
-	/**
-	 * Does this entity declare a natural id?
-	 */
-	public boolean hasNaturalIdentifier();
-
-	/**
-	 * Which properties hold the natural id?
-	 */
-	public int[] getNaturalIdentifierProperties();
-	
-	/**
-	 * Does this entity have mapped subclasses?
-	 */
-	public boolean hasSubclasses();
-	
-	/**
-	 * Does this entity extend a mapped superclass?
-	 */
-	public boolean isInherited();
-	
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// stuff that is tuplizer-centric, but is passed a session ~~~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Return the values of the mapped properties of the object
-	 */
-	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) 
-	throws HibernateException;
-
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// stuff that is Tuplizer-centric ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * The persistent class, or null
-	 */
-	public Class getMappedClass(EntityMode entityMode);
-
-	/**
-	 * Create a class instance initialized with the given identifier
-	 */
-	public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the value of a particular (named) property
-	 */
-	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Extract the property values from the given entity.
-	 *
-	 * @param entity The entity from which to extract the property values.
-	 * @param entityMode The entity-mode of the given entity
-	 * @return The property values.
-	 * @throws HibernateException
-	 */
-	public Object[] getPropertyValues(Object entity, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Set the value of a particular (named) property
-	 */
-	public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Set the given values to the mapped properties of the given object
-	 */
-	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the identifier of an instance (throw an exception if no identifier property)
-	 */
-	public Serializable getIdentifier(Object entity, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Set the identifier of an instance (or do nothing if no identifier property)
-	 */
-	public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Does the class implement the <tt>Lifecycle</tt> interface?
-	 */
-	public boolean implementsLifecycle(EntityMode entityMode);
-
-	/**
-	 * Does the class implement the <tt>Validatable</tt> interface?
-	 */
-	public boolean implementsValidatable(EntityMode entityMode);
-
-	/**
-	 * Get the version number (or timestamp) from the object's version property
-	 * (or return null if not versioned)
-	 */
-	public Object getVersion(Object object, EntityMode entityMode) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/metadata/ClassMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/ClassMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,209 @@
+/*
+ * 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.metadata;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Exposes entity class metadata to the application
+ *
+ * @see org.hibernate.SessionFactory#getClassMetadata(Class)
+ * @author Gavin King
+ */
+public interface ClassMetadata {
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * The name of the entity
+	 */
+	public String getEntityName();
+
+	/**
+	 * Get the name of the identifier property (or return null)
+	 */
+	public String getIdentifierPropertyName();
+
+	/**
+	 * Get the names of the class' persistent properties
+	 */
+	public String[] getPropertyNames();
+
+	/**
+	 * Get the identifier Hibernate type
+	 */
+	public Type getIdentifierType();
+
+	/**
+	 * Get the Hibernate types of the class properties
+	 */
+	public Type[] getPropertyTypes();
+
+	/**
+	 * Get the type of a particular (named) property
+	 */
+	public Type getPropertyType(String propertyName) throws HibernateException;
+
+	/**
+	 * Does this class support dynamic proxies?
+	 */
+	public boolean hasProxy();
+
+	/**
+	 * Are instances of this class mutable?
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Are instances of this class versioned by a timestamp or version number column?
+	 */
+	public boolean isVersioned();
+
+	/**
+	 * Get the index of the version property
+	 */
+	public int getVersionProperty();
+
+	/**
+	 * Get the nullability of the class' persistent properties
+	 */
+	public boolean[] getPropertyNullability();
+
+
+	/**
+	 * Get the "laziness" of the properties of this class
+	 */
+	public boolean[] getPropertyLaziness();
+
+	/**
+	 * Does this class have an identifier property?
+	 */
+	public boolean hasIdentifierProperty();
+
+	/**
+	 * Does this entity declare a natural id?
+	 */
+	public boolean hasNaturalIdentifier();
+
+	/**
+	 * Which properties hold the natural id?
+	 */
+	public int[] getNaturalIdentifierProperties();
+	
+	/**
+	 * Does this entity have mapped subclasses?
+	 */
+	public boolean hasSubclasses();
+	
+	/**
+	 * Does this entity extend a mapped superclass?
+	 */
+	public boolean isInherited();
+	
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// stuff that is tuplizer-centric, but is passed a session ~~~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Return the values of the mapped properties of the object
+	 */
+	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) 
+	throws HibernateException;
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// stuff that is Tuplizer-centric ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * The persistent class, or null
+	 */
+	public Class getMappedClass(EntityMode entityMode);
+
+	/**
+	 * Create a class instance initialized with the given identifier
+	 */
+	public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the value of a particular (named) property
+	 */
+	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Extract the property values from the given entity.
+	 *
+	 * @param entity The entity from which to extract the property values.
+	 * @param entityMode The entity-mode of the given entity
+	 * @return The property values.
+	 * @throws HibernateException
+	 */
+	public Object[] getPropertyValues(Object entity, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Set the value of a particular (named) property
+	 */
+	public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Set the given values to the mapped properties of the given object
+	 */
+	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the identifier of an instance (throw an exception if no identifier property)
+	 */
+	public Serializable getIdentifier(Object entity, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Set the identifier of an instance (or do nothing if no identifier property)
+	 */
+	public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Does the class implement the <tt>Lifecycle</tt> interface?
+	 */
+	public boolean implementsLifecycle(EntityMode entityMode);
+
+	/**
+	 * Does the class implement the <tt>Validatable</tt> interface?
+	 */
+	public boolean implementsValidatable(EntityMode entityMode);
+
+	/**
+	 * Get the version number (or timestamp) from the object's version property
+	 * (or return null if not versioned)
+	 */
+	public Object getVersion(Object object, EntityMode entityMode) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: CollectionMetadata.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.metadata;
-
-import org.hibernate.type.Type;
-
-/**
- * Exposes collection metadata to the application
- *
- * @author Gavin King
- */
-public interface CollectionMetadata {
-	/**
-	 * The collection key type
-	 */
-	public Type getKeyType();
-	/**
-	 * The collection element type
-	 */
-	public Type getElementType();
-	/**
-	 * The collection index type (or null if the collection has no index)
-	 */
-	public Type getIndexType();
-	/**
-	 * Is this collection indexed?
-	 */
-	public boolean hasIndex();
-	/**
-	 * The name of this collection role
-	 */
-	public String getRole();
-	/**
-	 * Is the collection an array?
-	 */
-	public boolean isArray();
-	/**
-	 * Is the collection a primitive array?
-	 */
-	public boolean isPrimitiveArray();
-	/**
-	 * Is the collection lazily initialized?
-	 */
-	public boolean isLazy();
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/CollectionMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.metadata;
+
+import org.hibernate.type.Type;
+
+/**
+ * Exposes collection metadata to the application
+ *
+ * @author Gavin King
+ */
+public interface CollectionMetadata {
+	/**
+	 * The collection key type
+	 */
+	public Type getKeyType();
+	/**
+	 * The collection element type
+	 */
+	public Type getElementType();
+	/**
+	 * The collection index type (or null if the collection has no index)
+	 */
+	public Type getIndexType();
+	/**
+	 * Is this collection indexed?
+	 */
+	public boolean hasIndex();
+	/**
+	 * The name of this collection role
+	 */
+	public String getRole();
+	/**
+	 * Is the collection an array?
+	 */
+	public boolean isArray();
+	/**
+	 * Is the collection a primitive array?
+	 */
+	public boolean isPrimitiveArray();
+	/**
+	 * Is the collection lazily initialized?
+	 */
+	public boolean isLazy();
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/metadata/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines an API for accessing the Hibernate 
-	runtime metamodel.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/metadata/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/metadata/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines an API for accessing the Hibernate 
+	runtime metamodel.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines the central Hibernate APIs.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines the central Hibernate APIs.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-package org.hibernate.param;
-
-import org.hibernate.type.Type;
-
-/**
- * Convenience base class for explicitly defined query parameters.
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public abstract class AbstractExplicitParameterSpecification implements ExplicitParameterSpecification {
-
-	private final int sourceLine;
-	private final int sourceColumn;
-	private Type expectedType;
-
-	protected AbstractExplicitParameterSpecification(int sourceLine, int sourceColumn) {
-		this.sourceLine = sourceLine;
-		this.sourceColumn = sourceColumn;
-	}
-
-	public int getSourceLine() {
-		return sourceLine;
-	}
-
-	public int getSourceColumn() {
-		return sourceColumn;
-	}
-
-	public Type getExpectedType() {
-		return expectedType;
-	}
-
-	public void setExpectedType(Type expectedType) {
-		this.expectedType = expectedType;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/AbstractExplicitParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.param;
+
+import org.hibernate.type.Type;
+
+/**
+ * Convenience base class for explicitly defined query parameters.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractExplicitParameterSpecification implements ExplicitParameterSpecification {
+
+	private final int sourceLine;
+	private final int sourceColumn;
+	private Type expectedType;
+
+	protected AbstractExplicitParameterSpecification(int sourceLine, int sourceColumn) {
+		this.sourceLine = sourceLine;
+		this.sourceColumn = sourceColumn;
+	}
+
+	public int getSourceLine() {
+		return sourceLine;
+	}
+
+	public int getSourceColumn() {
+		return sourceColumn;
+	}
+
+	public Type getExpectedType() {
+		return expectedType;
+	}
+
+	public void setExpectedType(Type expectedType) {
+		this.expectedType = expectedType;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-package org.hibernate.param;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * A specialized ParameterSpecification impl for dealing with a collection-key
- * as part of a collection filter compilation.
- *
- * @author Steve Ebersole
- */
-public class CollectionFilterKeyParameterSpecification implements ParameterSpecification {
-
-	private final String collectionRole;
-	private final Type keyType;
-	private final int queryParameterPosition;
-
-	/**
-	 * Creates a specialized collection-filter collection-key parameter spec.
-	 *
-	 * @param collectionRole The collection role being filtered.
-	 * @param keyType The mapped collection-key type.
-	 * @param queryParameterPosition The position within {@link org.hibernate.engine.QueryParameters} where
-	 * we can find the appropriate param value to bind.
-	 */
-	public CollectionFilterKeyParameterSpecification(String collectionRole, Type keyType, int queryParameterPosition) {
-		this.collectionRole = collectionRole;
-		this.keyType = keyType;
-		this.queryParameterPosition = queryParameterPosition;
-	}
-
-	public int bind(
-			PreparedStatement statement,
-			QueryParameters qp,
-			SessionImplementor session,
-			int position) throws SQLException {
-		Object value = qp.getPositionalParameterValues()[queryParameterPosition];
-		keyType.nullSafeSet( statement, value, position, session );
-		return keyType.getColumnSpan( session.getFactory() );
-	}
-
-	public Type getExpectedType() {
-		return keyType;
-	}
-
-	public void setExpectedType(Type expectedType) {
-		// todo : throw exception?
-	}
-
-	public String renderDisplayInfo() {
-		return "collection-filter-key=" + collectionRole;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/CollectionFilterKeyParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.param;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A specialized ParameterSpecification impl for dealing with a collection-key
+ * as part of a collection filter compilation.
+ *
+ * @author Steve Ebersole
+ */
+public class CollectionFilterKeyParameterSpecification implements ParameterSpecification {
+
+	private final String collectionRole;
+	private final Type keyType;
+	private final int queryParameterPosition;
+
+	/**
+	 * Creates a specialized collection-filter collection-key parameter spec.
+	 *
+	 * @param collectionRole The collection role being filtered.
+	 * @param keyType The mapped collection-key type.
+	 * @param queryParameterPosition The position within {@link org.hibernate.engine.QueryParameters} where
+	 * we can find the appropriate param value to bind.
+	 */
+	public CollectionFilterKeyParameterSpecification(String collectionRole, Type keyType, int queryParameterPosition) {
+		this.collectionRole = collectionRole;
+		this.keyType = keyType;
+		this.queryParameterPosition = queryParameterPosition;
+	}
+
+	public int bind(
+			PreparedStatement statement,
+			QueryParameters qp,
+			SessionImplementor session,
+			int position) throws SQLException {
+		Object value = qp.getPositionalParameterValues()[queryParameterPosition];
+		keyType.nullSafeSet( statement, value, position, session );
+		return keyType.getColumnSpan( session.getFactory() );
+	}
+
+	public Type getExpectedType() {
+		return keyType;
+	}
+
+	public void setExpectedType(Type expectedType) {
+		// todo : throw exception?
+	}
+
+	public String renderDisplayInfo() {
+		return "collection-filter-key=" + collectionRole;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,60 +0,0 @@
-package org.hibernate.param;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * A specialized ParameterSpecification impl for dealing with a dynamic filter
- * parameters.
- * <p/>
- * Note: this class is currently not used.  The ideal way to deal with dynamic filter
- * parameters for HQL would be to track them just as we do with other parameters
- * in the translator.  However, the problem with that is that we currently do not
- * know the filters which actually apply to the query; we know the active/enabled ones,
- * but not the ones that actually "make it into" the resulting query.
- *
- * @author Steve Ebersole
- */
-public class DynamicFilterParameterSpecification implements ParameterSpecification {
-	private final String filterName;
-	private final String parameterName;
-	private final Type definedParameterType;
-	private final int queryParameterPosition;
-
-	public DynamicFilterParameterSpecification(
-			String filterName,
-			String parameterName,
-			Type definedParameterType,
-			int queryParameterPosition) {
-		this.filterName = filterName;
-		this.parameterName = parameterName;
-		this.definedParameterType = definedParameterType;
-		this.queryParameterPosition = queryParameterPosition;
-	}
-
-	public int bind(
-			PreparedStatement statement,
-			QueryParameters qp,
-			SessionImplementor session,
-			int position) throws SQLException {
-		Object value = qp.getFilteredPositionalParameterValues()[queryParameterPosition];
-		definedParameterType.nullSafeSet( statement, value, position, session );
-		return definedParameterType.getColumnSpan( session.getFactory() );
-	}
-
-	public Type getExpectedType() {
-		return definedParameterType;
-	}
-
-	public void setExpectedType(Type expectedType) {
-		// todo : throw exception?
-	}
-
-	public String renderDisplayInfo() {
-		return "dynamic-filter={filterName=" + filterName + ",paramName=" + parameterName + "}";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/DynamicFilterParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.param;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A specialized ParameterSpecification impl for dealing with a dynamic filter
+ * parameters.
+ * <p/>
+ * Note: this class is currently not used.  The ideal way to deal with dynamic filter
+ * parameters for HQL would be to track them just as we do with other parameters
+ * in the translator.  However, the problem with that is that we currently do not
+ * know the filters which actually apply to the query; we know the active/enabled ones,
+ * but not the ones that actually "make it into" the resulting query.
+ *
+ * @author Steve Ebersole
+ */
+public class DynamicFilterParameterSpecification implements ParameterSpecification {
+	private final String filterName;
+	private final String parameterName;
+	private final Type definedParameterType;
+	private final int queryParameterPosition;
+
+	public DynamicFilterParameterSpecification(
+			String filterName,
+			String parameterName,
+			Type definedParameterType,
+			int queryParameterPosition) {
+		this.filterName = filterName;
+		this.parameterName = parameterName;
+		this.definedParameterType = definedParameterType;
+		this.queryParameterPosition = queryParameterPosition;
+	}
+
+	public int bind(
+			PreparedStatement statement,
+			QueryParameters qp,
+			SessionImplementor session,
+			int position) throws SQLException {
+		Object value = qp.getFilteredPositionalParameterValues()[queryParameterPosition];
+		definedParameterType.nullSafeSet( statement, value, position, session );
+		return definedParameterType.getColumnSpan( session.getFactory() );
+	}
+
+	public Type getExpectedType() {
+		return definedParameterType;
+	}
+
+	public void setExpectedType(Type expectedType) {
+		// todo : throw exception?
+	}
+
+	public String renderDisplayInfo() {
+		return "dynamic-filter={filterName=" + filterName + ",paramName=" + parameterName + "}";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,13 +0,0 @@
-package org.hibernate.param;
-
-/**
- * An additional contract for parameters which originate from
- * parameters explicitly encountered in the source statement
- * (HQL or native-SQL).
- *
- * @author <a href="mailto:steve at hibernate.org">Steve Ebersole </a>
- */
-public interface ExplicitParameterSpecification extends ParameterSpecification {
-	public int getSourceLine();
-	public int getSourceColumn();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ExplicitParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.param;
+
+/**
+ * An additional contract for parameters which originate from
+ * parameters explicitly encountered in the source statement
+ * (HQL or native-SQL).
+ *
+ * @author Steve Ebersole
+ */
+public interface ExplicitParameterSpecification extends ParameterSpecification {
+	public int getSourceLine();
+	public int getSourceColumn();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-// $Id: NamedParameterSpecification.java 8513 2005-11-02 18:47:40Z steveebersole $
-package org.hibernate.param;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.TypedValue;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Relates to an explicit query named-parameter.
- *
- * @author Steve Ebersole
- */
-public class NamedParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
-
-	private final String name;
-
-	public NamedParameterSpecification(int sourceLine, int sourceColumn, String name) {
-		super( sourceLine, sourceColumn );
-		this.name = name;
-	}
-
-	/**
-	 * Bind the appropriate value into the given statement at the specified position.
-	 *
-	 * @param statement The statement into which the value should be bound.
-	 * @param qp The defined values for the current query execution.
-	 * @param session The session against which the current execution is occuring.
-	 * @param position The position from which to start binding value(s).
-	 *
-	 * @return The number of sql bind positions "eaten" by this bind operation.
-	 */
-	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position)
-	        throws SQLException {
-		TypedValue typedValue = ( TypedValue ) qp.getNamedParameters().get( name );
-		typedValue.getType().nullSafeSet( statement, typedValue.getValue(), position, session );
-		return typedValue.getType().getColumnSpan( session.getFactory() );
-	}
-
-	public String renderDisplayInfo() {
-		return "name=" + name + ", expectedType=" + getExpectedType();
-	}
-
-	public String getName() {
-		return name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/NamedParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.param;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.TypedValue;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Relates to an explicit query named-parameter.
+ *
+ * @author Steve Ebersole
+ */
+public class NamedParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
+
+	private final String name;
+
+	public NamedParameterSpecification(int sourceLine, int sourceColumn, String name) {
+		super( sourceLine, sourceColumn );
+		this.name = name;
+	}
+
+	/**
+	 * Bind the appropriate value into the given statement at the specified position.
+	 *
+	 * @param statement The statement into which the value should be bound.
+	 * @param qp The defined values for the current query execution.
+	 * @param session The session against which the current execution is occuring.
+	 * @param position The position from which to start binding value(s).
+	 *
+	 * @return The number of sql bind positions "eaten" by this bind operation.
+	 */
+	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position)
+	        throws SQLException {
+		TypedValue typedValue = ( TypedValue ) qp.getNamedParameters().get( name );
+		typedValue.getType().nullSafeSet( statement, typedValue.getValue(), position, session );
+		return typedValue.getType().getColumnSpan( session.getFactory() );
+	}
+
+	public String renderDisplayInfo() {
+		return "name=" + name + ", expectedType=" + getExpectedType();
+	}
+
+	public String getName() {
+		return name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/ParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-// $Id: ParameterSpecification.java 10765 2006-11-08 04:30:27Z steve.ebersole at jboss.com $
-package org.hibernate.param;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Maintains information relating to parameters which need to get bound into a
- * JDBC {@link PreparedStatement}.
- *
- * @author Steve Ebersole
- */
-public interface ParameterSpecification {
-	/**
-	 * Bind the appropriate value into the given statement at the specified position.
-	 *
-	 * @param statement The statement into which the value should be bound.
-	 * @param qp The defined values for the current query execution.
-	 * @param session The session against which the current execution is occuring.
-	 * @param position The position from which to start binding value(s).
-	 *
-	 * @return The number of sql bind positions "eaten" by this bind operation.
-	 * @throws java.sql.SQLException Indicates problems performing the JDBC biind operation.
-	 */
-	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException;
-
-	/**
-	 * Get the type which we are expeting for a bind into this parameter based
-	 * on translated contextual information.
-	 *
-	 * @return The expected type.
-	 */
-	public Type getExpectedType();
-
-	/**
-	 * Injects the expected type.  Called during translation.
-	 *
-	 * @param expectedType The type to expect.
-	 */
-	public void setExpectedType(Type expectedType);
-
-	/**
-	 * Render this parameter into displayable info (for logging, etc).
-	 *
-	 * @return The displayable info.
-	 */
-	public String renderDisplayInfo();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/ParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/ParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.param;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Maintains information relating to parameters which need to get bound into a
+ * JDBC {@link PreparedStatement}.
+ *
+ * @author Steve Ebersole
+ */
+public interface ParameterSpecification {
+	/**
+	 * Bind the appropriate value into the given statement at the specified position.
+	 *
+	 * @param statement The statement into which the value should be bound.
+	 * @param qp The defined values for the current query execution.
+	 * @param session The session against which the current execution is occuring.
+	 * @param position The position from which to start binding value(s).
+	 *
+	 * @return The number of sql bind positions "eaten" by this bind operation.
+	 * @throws java.sql.SQLException Indicates problems performing the JDBC biind operation.
+	 */
+	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException;
+
+	/**
+	 * Get the type which we are expeting for a bind into this parameter based
+	 * on translated contextual information.
+	 *
+	 * @return The expected type.
+	 */
+	public Type getExpectedType();
+
+	/**
+	 * Injects the expected type.  Called during translation.
+	 *
+	 * @param expectedType The type to expect.
+	 */
+	public void setExpectedType(Type expectedType);
+
+	/**
+	 * Render this parameter into displayable info (for logging, etc).
+	 *
+	 * @return The displayable info.
+	 */
+	public String renderDisplayInfo();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-// $Id: PositionalParameterSpecification.java 8513 2005-11-02 18:47:40Z steveebersole $
-package org.hibernate.param;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Relates to an explicit query positional (or ordinal) parameter.
- *
- * @author Steve Ebersole
- */
-public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
-
-	private final int hqlPosition;
-
-	public PositionalParameterSpecification(int sourceLine, int sourceColumn, int hqlPosition) {
-		super( sourceLine, sourceColumn );
-		this.hqlPosition = hqlPosition;
-	}
-
-	/**
-	 * Bind the appropriate value into the given statement at the specified position.
-	 *
-	 * @param statement The statement into which the value should be bound.
-	 * @param qp The defined values for the current query execution.
-	 * @param session The session against which the current execution is occuring.
-	 * @param position The position from which to start binding value(s).
-	 *
-	 * @return The number of sql bind positions "eaten" by this bind operation.
-	 */
-	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException {
-		Type type = qp.getPositionalParameterTypes()[hqlPosition];
-		Object value = qp.getPositionalParameterValues()[hqlPosition];
-
-		type.nullSafeSet( statement, value, position, session );
-		return type.getColumnSpan( session.getFactory() );
-	}
-
-	public String renderDisplayInfo() {
-		return "ordinal=" + hqlPosition + ", expectedType=" + getExpectedType();
-	}
-
-	public int getHqlPosition() {
-		return hqlPosition;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/PositionalParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.param;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Relates to an explicit query positional (or ordinal) parameter.
+ *
+ * @author Steve Ebersole
+ */
+public class PositionalParameterSpecification extends AbstractExplicitParameterSpecification implements ParameterSpecification {
+
+	private final int hqlPosition;
+
+	public PositionalParameterSpecification(int sourceLine, int sourceColumn, int hqlPosition) {
+		super( sourceLine, sourceColumn );
+		this.hqlPosition = hqlPosition;
+	}
+
+	/**
+	 * Bind the appropriate value into the given statement at the specified position.
+	 *
+	 * @param statement The statement into which the value should be bound.
+	 * @param qp The defined values for the current query execution.
+	 * @param session The session against which the current execution is occuring.
+	 * @param position The position from which to start binding value(s).
+	 *
+	 * @return The number of sql bind positions "eaten" by this bind operation.
+	 */
+	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position) throws SQLException {
+		Type type = qp.getPositionalParameterTypes()[hqlPosition];
+		Object value = qp.getPositionalParameterValues()[hqlPosition];
+
+		type.nullSafeSet( statement, value, position, session );
+		return type.getColumnSpan( session.getFactory() );
+	}
+
+	public String renderDisplayInfo() {
+		return "ordinal=" + hqlPosition + ", expectedType=" + getExpectedType();
+	}
+
+	public int getHqlPosition() {
+		return hqlPosition;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-// $Id: VersionTypeSeedParameterSpecification.java 8513 2005-11-02 18:47:40Z steveebersole $
-package org.hibernate.param;
-
-import org.hibernate.engine.QueryParameters;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.VersionType;
-import org.hibernate.type.Type;
-import org.hibernate.param.ParameterSpecification;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-
-/**
- * Implementation of VersionTypeSeedParameterSpecification.
- *
- * @author Steve Ebersole
- */
-public class VersionTypeSeedParameterSpecification implements ParameterSpecification {
-
-	private VersionType type;
-
-	public VersionTypeSeedParameterSpecification(VersionType type) {
-		this.type = type;
-	}
-
-	/**
-	 * @see org.hibernate.param.ParameterSpecification#bind
-	 */
-	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position)
-	        throws SQLException {
-		type.nullSafeSet( statement, type.seed( session ), position, session );
-		return 1;
-	}
-
-	public Type getExpectedType() {
-		return type;
-	}
-
-	public void setExpectedType(Type expectedType) {
-		// expected type is intrinsic here...
-	}
-
-	public String renderDisplayInfo() {
-		return "version-seed, type=" + type;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/param/VersionTypeSeedParameterSpecification.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.param;
+
+import org.hibernate.engine.QueryParameters;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.VersionType;
+import org.hibernate.type.Type;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Implementation of VersionTypeSeedParameterSpecification.
+ *
+ * @author Steve Ebersole
+ */
+public class VersionTypeSeedParameterSpecification implements ParameterSpecification {
+
+	private VersionType type;
+
+	public VersionTypeSeedParameterSpecification(VersionType type) {
+		this.type = type;
+	}
+
+	/**
+	 * @see org.hibernate.param.ParameterSpecification#bind
+	 */
+	public int bind(PreparedStatement statement, QueryParameters qp, SessionImplementor session, int position)
+	        throws SQLException {
+		type.nullSafeSet( statement, type.seed( session ), position, session );
+		return 1;
+	}
+
+	public Type getExpectedType() {
+		return type;
+	}
+
+	public void setExpectedType(Type expectedType) {
+		// expected type is intrinsic here...
+	}
+
+	public String renderDisplayInfo() {
+		return "version-seed, type=" + type;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/PersisterFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,154 +0,0 @@
-//$Id: PersisterFactory.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.persister.collection.BasicCollectionPersister;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.OneToManyPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
-import org.hibernate.persister.entity.SingleTableEntityPersister;
-import org.hibernate.persister.entity.UnionSubclassEntityPersister;
-
-/**
- * Factory for <tt>EntityPersister</tt> and <tt>CollectionPersister</tt> instances
- *
- * @author Gavin King
- */
-public final class PersisterFactory {
-
-	//TODO: make EntityPersister *not* depend on SessionFactoryImplementor
-	//interface, if possible
-
-	// TODO : still need to make CollectionPersisters EntityMode-aware
-
-	private PersisterFactory() {}
-
-	private static final Class[] PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
-		PersistentClass.class, EntityRegionAccessStrategy.class, SessionFactoryImplementor.class, Mapping.class
-	};
-
-	// TODO: is it really neceassry to provide Configuration to CollectionPersisters ? Should it not be enough with associated class ?
-	// or why does EntityPersister's not get access to configuration ?
-	//
-	// The only reason I could see that Configuration gets passed to collection persisters
-	// is so that they can look up the dom4j node name of the entity element in case
-	// no explicit node name was applied at the collection element level.  Are you kidding me?
-	// Trivial to fix then.  Just store and expose the node name on the entity persister
-	// (which the collection persister looks up anyway via other means...).
-	private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
-			Collection.class, CollectionRegionAccessStrategy.class, Configuration.class, SessionFactoryImplementor.class
-		};
-
-	public static EntityPersister createClassPersister(
-			PersistentClass model,
-			EntityRegionAccessStrategy cacheAccessStrategy,
-			SessionFactoryImplementor factory,
-			Mapping cfg) throws HibernateException {
-		Class persisterClass = model.getEntityPersisterClass();
-		if ( persisterClass == null || persisterClass == SingleTableEntityPersister.class ) {
-			return new SingleTableEntityPersister( model, cacheAccessStrategy, factory, cfg );
-		}
-		else if ( persisterClass == JoinedSubclassEntityPersister.class ) {
-			return new JoinedSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
-		}
-		else if ( persisterClass == UnionSubclassEntityPersister.class ) {
-			return new UnionSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
-		}
-		else {
-			return create( persisterClass, model, cacheAccessStrategy, factory, cfg );
-		}
-	}
-
-	public static CollectionPersister createCollectionPersister(
-			Configuration cfg,
-			Collection model,
-			CollectionRegionAccessStrategy cacheAccessStrategy,
-			SessionFactoryImplementor factory) throws HibernateException {
-		Class persisterClass = model.getCollectionPersisterClass();
-		if ( persisterClass == null ) {
-			return model.isOneToMany()
-					? ( CollectionPersister ) new OneToManyPersister( model, cacheAccessStrategy, cfg, factory )
-					: ( CollectionPersister ) new BasicCollectionPersister( model, cacheAccessStrategy, cfg, factory );
-		}
-		else {
-			return create( persisterClass, cfg, model, cacheAccessStrategy, factory );
-		}
-
-	}
-
-	private static EntityPersister create(
-			Class persisterClass, 
-			PersistentClass model, 
-			EntityRegionAccessStrategy cacheAccessStrategy,
-			SessionFactoryImplementor factory,
-			Mapping cfg) throws HibernateException {
-		Constructor pc;
-		try {
-			pc = persisterClass.getConstructor( PERSISTER_CONSTRUCTOR_ARGS );
-		}
-		catch ( Exception e ) {
-			throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
-		}
-
-		try {
-			return (EntityPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, factory, cfg } );
-		}
-		catch (InvocationTargetException ite) {
-			Throwable e = ite.getTargetException();
-			if (e instanceof HibernateException) {
-				throw (HibernateException) e;
-			}
-			else {
-				throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
-			}
-		}
-		catch (Exception e) {
-			throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
-		}
-	}
-
-	private static CollectionPersister create(
-			Class persisterClass,
-			Configuration cfg,
-			Collection model,
-			CollectionRegionAccessStrategy cacheAccessStrategy,
-			SessionFactoryImplementor factory) throws HibernateException {
-		Constructor pc;
-		try {
-			pc = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
-		}
-		catch (Exception e) {
-			throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
-		}
-
-		try {
-			return (CollectionPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, cfg, factory } );
-		}
-		catch (InvocationTargetException ite) {
-			Throwable e = ite.getTargetException();
-			if (e instanceof HibernateException) {
-				throw (HibernateException) e;
-			}
-			else {
-				throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
-			}
-		}
-		catch (Exception e) {
-			throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
-		}
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/PersisterFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/PersisterFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,177 @@
+/*
+ * 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.persister;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.persister.collection.BasicCollectionPersister;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.OneToManyPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.JoinedSubclassEntityPersister;
+import org.hibernate.persister.entity.SingleTableEntityPersister;
+import org.hibernate.persister.entity.UnionSubclassEntityPersister;
+
+/**
+ * Factory for <tt>EntityPersister</tt> and <tt>CollectionPersister</tt> instances
+ *
+ * @author Gavin King
+ */
+public final class PersisterFactory {
+
+	//TODO: make EntityPersister *not* depend on SessionFactoryImplementor
+	//interface, if possible
+
+	// TODO : still need to make CollectionPersisters EntityMode-aware
+
+	private PersisterFactory() {}
+
+	private static final Class[] PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
+		PersistentClass.class, EntityRegionAccessStrategy.class, SessionFactoryImplementor.class, Mapping.class
+	};
+
+	// TODO: is it really neceassry to provide Configuration to CollectionPersisters ? Should it not be enough with associated class ?
+	// or why does EntityPersister's not get access to configuration ?
+	//
+	// The only reason I could see that Configuration gets passed to collection persisters
+	// is so that they can look up the dom4j node name of the entity element in case
+	// no explicit node name was applied at the collection element level.  Are you kidding me?
+	// Trivial to fix then.  Just store and expose the node name on the entity persister
+	// (which the collection persister looks up anyway via other means...).
+	private static final Class[] COLLECTION_PERSISTER_CONSTRUCTOR_ARGS = new Class[] {
+			Collection.class, CollectionRegionAccessStrategy.class, Configuration.class, SessionFactoryImplementor.class
+		};
+
+	public static EntityPersister createClassPersister(
+			PersistentClass model,
+			EntityRegionAccessStrategy cacheAccessStrategy,
+			SessionFactoryImplementor factory,
+			Mapping cfg) throws HibernateException {
+		Class persisterClass = model.getEntityPersisterClass();
+		if ( persisterClass == null || persisterClass == SingleTableEntityPersister.class ) {
+			return new SingleTableEntityPersister( model, cacheAccessStrategy, factory, cfg );
+		}
+		else if ( persisterClass == JoinedSubclassEntityPersister.class ) {
+			return new JoinedSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
+		}
+		else if ( persisterClass == UnionSubclassEntityPersister.class ) {
+			return new UnionSubclassEntityPersister( model, cacheAccessStrategy, factory, cfg );
+		}
+		else {
+			return create( persisterClass, model, cacheAccessStrategy, factory, cfg );
+		}
+	}
+
+	public static CollectionPersister createCollectionPersister(
+			Configuration cfg,
+			Collection model,
+			CollectionRegionAccessStrategy cacheAccessStrategy,
+			SessionFactoryImplementor factory) throws HibernateException {
+		Class persisterClass = model.getCollectionPersisterClass();
+		if ( persisterClass == null ) {
+			return model.isOneToMany()
+					? ( CollectionPersister ) new OneToManyPersister( model, cacheAccessStrategy, cfg, factory )
+					: ( CollectionPersister ) new BasicCollectionPersister( model, cacheAccessStrategy, cfg, factory );
+		}
+		else {
+			return create( persisterClass, cfg, model, cacheAccessStrategy, factory );
+		}
+
+	}
+
+	private static EntityPersister create(
+			Class persisterClass, 
+			PersistentClass model, 
+			EntityRegionAccessStrategy cacheAccessStrategy,
+			SessionFactoryImplementor factory,
+			Mapping cfg) throws HibernateException {
+		Constructor pc;
+		try {
+			pc = persisterClass.getConstructor( PERSISTER_CONSTRUCTOR_ARGS );
+		}
+		catch ( Exception e ) {
+			throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
+		}
+
+		try {
+			return (EntityPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, factory, cfg } );
+		}
+		catch (InvocationTargetException ite) {
+			Throwable e = ite.getTargetException();
+			if (e instanceof HibernateException) {
+				throw (HibernateException) e;
+			}
+			else {
+				throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
+			}
+		}
+		catch (Exception e) {
+			throw new MappingException( "Could not instantiate persister " + persisterClass.getName(), e );
+		}
+	}
+
+	private static CollectionPersister create(
+			Class persisterClass,
+			Configuration cfg,
+			Collection model,
+			CollectionRegionAccessStrategy cacheAccessStrategy,
+			SessionFactoryImplementor factory) throws HibernateException {
+		Constructor pc;
+		try {
+			pc = persisterClass.getConstructor( COLLECTION_PERSISTER_CONSTRUCTOR_ARGS );
+		}
+		catch (Exception e) {
+			throw new MappingException( "Could not get constructor for " + persisterClass.getName(), e );
+		}
+
+		try {
+			return (CollectionPersister) pc.newInstance( new Object[] { model, cacheAccessStrategy, cfg, factory } );
+		}
+		catch (InvocationTargetException ite) {
+			Throwable e = ite.getTargetException();
+			if (e instanceof HibernateException) {
+				throw (HibernateException) e;
+			}
+			else {
+				throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
+			}
+		}
+		catch (Exception e) {
+			throw new MappingException( "Could not instantiate collection persister " + persisterClass.getName(), e );
+		}
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1784 +0,0 @@
-//$Id: AbstractCollectionPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.jdbc.Expectation;
-import org.hibernate.jdbc.Expectations;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.entry.CacheEntryStructure;
-import org.hibernate.cache.entry.StructuredCollectionCacheEntry;
-import org.hibernate.cache.entry.StructuredMapCacheEntry;
-import org.hibernate.cache.entry.UnstructuredCacheEntry;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SubselectFetch;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.loader.collection.CollectionInitializer;
-import org.hibernate.mapping.Collection;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.Formula;
-import org.hibernate.mapping.IdentifierCollection;
-import org.hibernate.mapping.IndexedCollection;
-import org.hibernate.mapping.List;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.mapping.Table;
-import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Loadable;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.sql.Alias;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.sql.SimpleSelect;
-import org.hibernate.sql.Template;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.FilterHelper;
-import org.hibernate.util.StringHelper;
-
-
-/**
- * Base implementation of the <tt>QueryableCollection</tt> interface.
- *
- * @author Gavin King
- * @see BasicCollectionPersister
- * @see OneToManyPersister
- */
-public abstract class AbstractCollectionPersister
-		implements CollectionMetadata, SQLLoadableCollection {
-	// TODO: encapsulate the protected instance variables!
-
-	private final String role;
-
-	//SQL statements
-	private final String sqlDeleteString;
-	private final String sqlInsertRowString;
-	private final String sqlUpdateRowString;
-	private final String sqlDeleteRowString;
-	private final String sqlSelectSizeString;
-	private final String sqlSelectRowByIndexString;
-	private final String sqlDetectRowByIndexString;
-	private final String sqlDetectRowByElementString;
-
-	private final String sqlOrderByString;
-	protected final String sqlWhereString;
-	private final String sqlOrderByStringTemplate;
-	private final String sqlWhereStringTemplate;
-	private final boolean hasOrder;
-	protected final boolean hasWhere;
-	private final int baseIndex;
-	
-	private final String nodeName;
-	private final String elementNodeName;
-	private final String indexNodeName;
-
-	protected final boolean indexContainsFormula;
-	protected final boolean elementIsPureFormula;
-	
-	//types
-	private final Type keyType;
-	private final Type indexType;
-	protected final Type elementType;
-	private final Type identifierType;
-
-	//columns
-	protected final String[] keyColumnNames;
-	protected final String[] indexColumnNames;
-	protected final String[] indexFormulaTemplates;
-	protected final String[] indexFormulas;
-	protected final boolean[] indexColumnIsSettable;
-	protected final String[] elementColumnNames;
-	protected final String[] elementFormulaTemplates;
-	protected final String[] elementFormulas;
-	protected final boolean[] elementColumnIsSettable;
-	protected final boolean[] elementColumnIsInPrimaryKey;
-	protected final String[] indexColumnAliases;
-	protected final String[] elementColumnAliases;
-	protected final String[] keyColumnAliases;
-	
-	protected final String identifierColumnName;
-	private final String identifierColumnAlias;
-	//private final String unquotedIdentifierColumnName;
-
-	protected final String qualifiedTableName;
-
-	private final String queryLoaderName;
-
-	private final boolean isPrimitiveArray;
-	private final boolean isArray;
-	protected final boolean hasIndex;
-	protected final boolean hasIdentifier;
-	private final boolean isLazy;
-	private final boolean isExtraLazy;
-	private final boolean isInverse;
-	private final boolean isMutable;
-	private final boolean isVersioned;
-	protected final int batchSize;
-	private final FetchMode fetchMode;
-	private final boolean hasOrphanDelete;
-	private final boolean subselectLoadable;
-
-	//extra information about the element type
-	private final Class elementClass;
-	private final String entityName;
-
-	private final Dialect dialect;
-	private final SQLExceptionConverter sqlExceptionConverter;
-	private final SessionFactoryImplementor factory;
-	private final EntityPersister ownerPersister;
-	private final IdentifierGenerator identifierGenerator;
-	private final PropertyMapping elementPropertyMapping;
-	private final EntityPersister elementPersister;
-	private final CollectionRegionAccessStrategy cacheAccessStrategy;
-	private final CollectionType collectionType;
-	private CollectionInitializer initializer;
-	
-	private final CacheEntryStructure cacheEntryStructure;
-
-	// dynamic filters for the collection
-	private final FilterHelper filterHelper;
-
-	// dynamic filters specifically for many-to-many inside the collection
-	private final FilterHelper manyToManyFilterHelper;
-
-	private final String manyToManyWhereString;
-	private final String manyToManyWhereTemplate;
-
-	private final String manyToManyOrderByString;
-	private final String manyToManyOrderByTemplate;
-
-	// custom sql
-	private final boolean insertCallable;
-	private final boolean updateCallable;
-	private final boolean deleteCallable;
-	private final boolean deleteAllCallable;
-	private ExecuteUpdateResultCheckStyle insertCheckStyle;
-	private ExecuteUpdateResultCheckStyle updateCheckStyle;
-	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
-	private ExecuteUpdateResultCheckStyle deleteAllCheckStyle;
-
-	private final Serializable[] spaces;
-
-	private Map collectionPropertyColumnAliases = new HashMap();
-	private Map collectionPropertyColumnNames = new HashMap();
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractCollectionPersister.class );
-
-	public AbstractCollectionPersister(
-			final Collection collection,
-			final CollectionRegionAccessStrategy cacheAccessStrategy,
-			final Configuration cfg,
-			final SessionFactoryImplementor factory) throws MappingException, CacheException {
-
-		this.factory = factory;
-		this.cacheAccessStrategy = cacheAccessStrategy;
-		if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) {
-			cacheEntryStructure = collection.isMap() ?
-					( CacheEntryStructure ) new StructuredMapCacheEntry() :
-					( CacheEntryStructure ) new StructuredCollectionCacheEntry();
-		}
-		else {
-			cacheEntryStructure = new UnstructuredCacheEntry();
-		}
-		
-		dialect = factory.getDialect();
-		sqlExceptionConverter = factory.getSQLExceptionConverter();
-		collectionType = collection.getCollectionType();
-		role = collection.getRole();
-		entityName = collection.getOwnerEntityName();
-		ownerPersister = factory.getEntityPersister(entityName);
-		queryLoaderName = collection.getLoaderName();
-		nodeName = collection.getNodeName();
-		isMutable = collection.isMutable();
-
-		Table table = collection.getCollectionTable();
-		fetchMode = collection.getElement().getFetchMode();
-		elementType = collection.getElement().getType();
-		//isSet = collection.isSet();
-		//isSorted = collection.isSorted();
-		isPrimitiveArray = collection.isPrimitiveArray();
-		isArray = collection.isArray();
-		subselectLoadable = collection.isSubselectLoadable();
-		
-		qualifiedTableName = table.getQualifiedName( 
-				dialect,
-				factory.getSettings().getDefaultCatalogName(),
-				factory.getSettings().getDefaultSchemaName() 
-			);
-
-		int spacesSize = 1 + collection.getSynchronizedTables().size();
-		spaces = new String[spacesSize];
-		spaces[0] = qualifiedTableName;
-		Iterator iter = collection.getSynchronizedTables().iterator();
-		for ( int i = 1; i < spacesSize; i++ ) {
-			spaces[i] = (String) iter.next();
-		}
-		
-		sqlOrderByString = collection.getOrderBy();
-		hasOrder = sqlOrderByString != null;
-		sqlOrderByStringTemplate = hasOrder ?
-				Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) :
-				null;
-		sqlWhereString = StringHelper.isNotEmpty( collection.getWhere() ) ? "( " + collection.getWhere() + ") " : null;
-		hasWhere = sqlWhereString != null;
-		sqlWhereStringTemplate = hasWhere ?
-				Template.renderWhereStringTemplate(sqlWhereString, dialect, factory.getSqlFunctionRegistry()) :
-				null;
-
-		hasOrphanDelete = collection.hasOrphanDelete();
-
-		int batch = collection.getBatchSize();
-		if ( batch == -1 ) {
-			batch = factory.getSettings().getDefaultBatchFetchSize();
-		}
-		batchSize = batch;
-
-		isVersioned = collection.isOptimisticLocked();
-		
-		// KEY
-
-		keyType = collection.getKey().getType();
-		iter = collection.getKey().getColumnIterator();
-		int keySpan = collection.getKey().getColumnSpan();
-		keyColumnNames = new String[keySpan];
-		keyColumnAliases = new String[keySpan];
-		int k = 0;
-		while ( iter.hasNext() ) {
-			// NativeSQL: collect key column and auto-aliases
-			Column col = ( (Column) iter.next() );
-			keyColumnNames[k] = col.getQuotedName(dialect);
-			keyColumnAliases[k] = col.getAlias(dialect);
-			k++;
-		}
-		
-		//unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases);
-
-		//ELEMENT
-
-		String elemNode = collection.getElementNodeName();
-		if ( elementType.isEntityType() ) {
-			String entityName = ( (EntityType) elementType ).getAssociatedEntityName();
-			elementPersister = factory.getEntityPersister(entityName);
-			if ( elemNode==null ) {
-				elemNode = cfg.getClassMapping(entityName).getNodeName();
-			}
-			// NativeSQL: collect element column and auto-aliases
-			
-		}
-		else {
-			elementPersister = null;
-		}		
-		elementNodeName = elemNode;
-
-		int elementSpan = collection.getElement().getColumnSpan();
-		elementColumnAliases = new String[elementSpan];
-		elementColumnNames = new String[elementSpan];
-		elementFormulaTemplates = new String[elementSpan];
-		elementFormulas = new String[elementSpan];
-		elementColumnIsSettable = new boolean[elementSpan];
-		elementColumnIsInPrimaryKey = new boolean[elementSpan];
-		boolean isPureFormula = true;
-		boolean hasNotNullableColumns = false;
-		int j = 0;
-		iter = collection.getElement().getColumnIterator();
-		while ( iter.hasNext() ) {
-			Selectable selectable = (Selectable) iter.next();
-			elementColumnAliases[j] = selectable.getAlias(dialect);
-			if ( selectable.isFormula() ) {
-				Formula form = (Formula) selectable;
-				elementFormulaTemplates[j] = form.getTemplate(dialect, factory.getSqlFunctionRegistry());
-				elementFormulas[j] = form.getFormula();
-			}
-			else {
-				Column col = (Column) selectable;
-				elementColumnNames[j] = col.getQuotedName(dialect);
-				elementColumnIsSettable[j] = true;
-				elementColumnIsInPrimaryKey[j] = !col.isNullable();
-				if ( !col.isNullable() ) {
-					hasNotNullableColumns = true;
-				}
-				isPureFormula = false;
-			}
-			j++;
-		}
-		elementIsPureFormula = isPureFormula;
-		
-		//workaround, for backward compatibility of sets with no
-		//not-null columns, assume all columns are used in the
-		//row locator SQL
-		if ( !hasNotNullableColumns ) {
-			Arrays.fill( elementColumnIsInPrimaryKey, true );
-		}
-
-
-		// INDEX AND ROW SELECT
-
-		hasIndex = collection.isIndexed();
-		if (hasIndex) {
-			// NativeSQL: collect index column and auto-aliases
-			IndexedCollection indexedCollection = (IndexedCollection) collection;
-			indexType = indexedCollection.getIndex().getType();
-			int indexSpan = indexedCollection.getIndex().getColumnSpan();
-			iter = indexedCollection.getIndex().getColumnIterator();
-			indexColumnNames = new String[indexSpan];
-			indexFormulaTemplates = new String[indexSpan];
-			indexFormulas = new String[indexSpan];
-			indexColumnIsSettable = new boolean[indexSpan];
-			indexColumnAliases = new String[indexSpan];
-			int i = 0;
-			boolean hasFormula = false;
-			while ( iter.hasNext() ) {
-				Selectable s = (Selectable) iter.next();
-				indexColumnAliases[i] = s.getAlias(dialect);
-				if ( s.isFormula() ) {
-					Formula indexForm = (Formula) s;
-					indexFormulaTemplates[i] = indexForm.getTemplate(dialect, factory.getSqlFunctionRegistry());
-					indexFormulas[i] = indexForm.getFormula();
-					hasFormula = true;
-				}
-				else {
-					Column indexCol = (Column) s;
-					indexColumnNames[i] = indexCol.getQuotedName(dialect);
-					indexColumnIsSettable[i] = true;
-				}
-				i++;
-			}
-			indexContainsFormula = hasFormula;
-			baseIndex = indexedCollection.isList() ? 
-					( (List) indexedCollection ).getBaseIndex() : 0;
-
-			indexNodeName = indexedCollection.getIndexNodeName(); 
-
-		}
-		else {
-			indexContainsFormula = false;
-			indexColumnIsSettable = null;
-			indexFormulaTemplates = null;
-			indexFormulas = null;
-			indexType = null;
-			indexColumnNames = null;
-			indexColumnAliases = null;
-			baseIndex = 0;
-			indexNodeName = null;
-		}
-		
-		hasIdentifier = collection.isIdentified();
-		if (hasIdentifier) {
-			if ( collection.isOneToMany() ) {
-				throw new MappingException( "one-to-many collections with identifiers are not supported" );
-			}
-			IdentifierCollection idColl = (IdentifierCollection) collection;
-			identifierType = idColl.getIdentifier().getType();
-			iter = idColl.getIdentifier().getColumnIterator();
-			Column col = ( Column ) iter.next();
-			identifierColumnName = col.getQuotedName(dialect);
-			identifierColumnAlias = col.getAlias(dialect);
-			//unquotedIdentifierColumnName = identifierColumnAlias;
-			identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( 
-					factory.getDialect(),
-					factory.getSettings().getDefaultCatalogName(),
-					factory.getSettings().getDefaultSchemaName(),
-					null
-				);
-		}
-		else {
-			identifierType = null;
-			identifierColumnName = null;
-			identifierColumnAlias = null;
-			//unquotedIdentifierColumnName = null;
-			identifierGenerator = null;
-		}
-		
-		//GENERATE THE SQL:
-				
-		//sqlSelectString = sqlSelectString();
-		//sqlSelectRowString = sqlSelectRowString();
-
-		if ( collection.getCustomSQLInsert() == null ) {
-			sqlInsertRowString = generateInsertRowString();
-			insertCallable = false;
-			insertCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
-		}
-		else {
-			sqlInsertRowString = collection.getCustomSQLInsert();
-			insertCallable = collection.isCustomInsertCallable();
-			insertCheckStyle = collection.getCustomSQLInsertCheckStyle() == null
-					? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLInsert(), insertCallable )
-		            : collection.getCustomSQLInsertCheckStyle();
-		}
-
-		if ( collection.getCustomSQLUpdate() == null ) {
-			sqlUpdateRowString = generateUpdateRowString();
-			updateCallable = false;
-			updateCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
-		}
-		else {
-			sqlUpdateRowString = collection.getCustomSQLUpdate();
-			updateCallable = collection.isCustomUpdateCallable();
-			updateCheckStyle = collection.getCustomSQLUpdateCheckStyle() == null
-					? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLUpdate(), insertCallable )
-		            : collection.getCustomSQLUpdateCheckStyle();
-		}
-
-		if ( collection.getCustomSQLDelete() == null ) {
-			sqlDeleteRowString = generateDeleteRowString();
-			deleteCallable = false;
-			deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
-		}
-		else {
-			sqlDeleteRowString = collection.getCustomSQLDelete();
-			deleteCallable = collection.isCustomDeleteCallable();
-			deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
-		}
-
-		if ( collection.getCustomSQLDeleteAll() == null ) {
-			sqlDeleteString = generateDeleteString();
-			deleteAllCallable = false;
-			deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
-		}
-		else {
-			sqlDeleteString = collection.getCustomSQLDeleteAll();
-			deleteAllCallable = collection.isCustomDeleteAllCallable();
-			deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
-		}
-
-		sqlSelectSizeString = generateSelectSizeString(  collection.isIndexed() && !collection.isMap() );
-		sqlDetectRowByIndexString = generateDetectRowByIndexString();
-		sqlDetectRowByElementString = generateDetectRowByElementString();
-		sqlSelectRowByIndexString = generateSelectRowByIndexString();
-		
-		logStaticSQL();
-		
-		isLazy = collection.isLazy();
-		isExtraLazy = collection.isExtraLazy();
-
-		isInverse = collection.isInverse();
-
-		if ( collection.isArray() ) {
-			elementClass = ( (org.hibernate.mapping.Array) collection ).getElementClass();
-		}
-		else {
-			// for non-arrays, we don't need to know the element class
-			elementClass = null; //elementType.returnedClass();
-		}
-
-		if ( elementType.isComponentType() ) {
-			elementPropertyMapping = new CompositeElementPropertyMapping( 
-					elementColumnNames,
-					elementFormulaTemplates,
-					(AbstractComponentType) elementType,
-					factory 
-				);
-		}
-		else if ( !elementType.isEntityType() ) {
-			elementPropertyMapping = new ElementPropertyMapping( 
-					elementColumnNames,
-					elementType 
-				);
-		}
-		else {
-			if ( elementPersister instanceof PropertyMapping ) { //not all classpersisters implement PropertyMapping!
-				elementPropertyMapping = (PropertyMapping) elementPersister;
-			}
-			else {
-				elementPropertyMapping = new ElementPropertyMapping( 
-						elementColumnNames,
-						elementType 
-					);
-			}
-		}
-			
-		// Handle any filters applied to this collection
-		filterHelper = new FilterHelper( collection.getFilterMap(), dialect, factory.getSqlFunctionRegistry() );
-
-		// Handle any filters applied to this collection for many-to-many
-		manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilterMap(), dialect, factory.getSqlFunctionRegistry() );
-		manyToManyWhereString = StringHelper.isNotEmpty( collection.getManyToManyWhere() ) ?
-				"( " + collection.getManyToManyWhere() + ")" :
-				null;
-		manyToManyWhereTemplate = manyToManyWhereString == null ?
-				null :
-				Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
-		manyToManyOrderByString = collection.getManyToManyOrdering();
-		manyToManyOrderByTemplate = manyToManyOrderByString == null
-				? null
-	            : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect(), factory.getSqlFunctionRegistry() );
-
-		initCollectionPropertyMap();
-	}
-
-	public void postInstantiate() throws MappingException {
-		initializer = queryLoaderName == null ?
-				createCollectionInitializer( CollectionHelper.EMPTY_MAP ) :
-				new NamedQueryCollectionInitializer( queryLoaderName, this );
-	}
-
-	protected void logStaticSQL() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Static SQL for collection: " + getRole() );
-			if ( getSQLInsertRowString() != null ) {
-				log.debug( " Row insert: " + getSQLInsertRowString() );
-			}
-			if ( getSQLUpdateRowString() != null ) {
-				log.debug( " Row update: " + getSQLUpdateRowString() );
-			}
-			if ( getSQLDeleteRowString() != null ) {
-				log.debug( " Row delete: " + getSQLDeleteRowString() );
-			}
-			if ( getSQLDeleteString() != null ) {
-				log.debug( " One-shot delete: " + getSQLDeleteString() );
-			}
-		}
-	}
-
-	public void initialize(Serializable key, SessionImplementor session) throws HibernateException {
-		getAppropriateInitializer( key, session ).initialize( key, session );
-	}
-
-	protected CollectionInitializer getAppropriateInitializer(Serializable key, SessionImplementor session) {
-		if ( queryLoaderName != null ) {
-			//if there is a user-specified loader, return that
-			//TODO: filters!?
-			return initializer;
-		}
-		CollectionInitializer subselectInitializer = getSubselectInitializer( key, session );
-		if ( subselectInitializer != null ) {
-			return subselectInitializer;
-		}
-		else if ( session.getEnabledFilters().isEmpty() ) {
-			return initializer;
-		}
-		else {
-			return createCollectionInitializer( session.getEnabledFilters() );
-		}
-	}
-
-	private CollectionInitializer getSubselectInitializer(Serializable key, SessionImplementor session) {
-
-		if ( !isSubselectLoadable() ) {
-			return null;
-		}
-		
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		
-		SubselectFetch subselect = persistenceContext.getBatchFetchQueue()
-			.getSubselect( new EntityKey( key, getOwnerEntityPersister(), session.getEntityMode() ) );
-		
-		if (subselect == null) {
-			return null;
-		}
-		else {
-			
-			// Take care of any entities that might have
-			// been evicted!	
-			Iterator iter = subselect.getResult().iterator();
-			while ( iter.hasNext() ) {
-				if ( !persistenceContext.containsEntity( (EntityKey) iter.next() ) ) {
-					iter.remove();
-				}
-			}	
-			
-			// Run a subquery loader
-			return createSubselectInitializer( subselect, session );
-		}
-	}
-
-	protected abstract CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session);
-
-	protected abstract CollectionInitializer createCollectionInitializer(Map enabledFilters)
-			throws MappingException;
-
-	public CollectionRegionAccessStrategy getCacheAccessStrategy() {
-		return cacheAccessStrategy;
-	}
-
-	public boolean hasCache() {
-		return cacheAccessStrategy != null;
-	}
-
-	public CollectionType getCollectionType() {
-		return collectionType;
-	}
-
-	protected String getSQLWhereString(String alias) {
-		return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias );
-	}
-
-	public String getSQLOrderByString(String alias) {
-		return hasOrdering() ? 
-			StringHelper.replace( sqlOrderByStringTemplate, Template.TEMPLATE, alias ) : "";
-	}
-
-	public String getManyToManyOrderByString(String alias) {
-		if ( isManyToMany() && manyToManyOrderByString != null ) {
-			return StringHelper.replace( manyToManyOrderByTemplate, Template.TEMPLATE, alias );
-		}
-		else {
-			return "";
-		}
-	}
-	public FetchMode getFetchMode() {
-		return fetchMode;
-	}
-
-	public boolean hasOrdering() {
-		return hasOrder;
-	}
-
-	public boolean hasManyToManyOrdering() {
-		return isManyToMany() && manyToManyOrderByTemplate != null;
-	}
-
-	public boolean hasWhere() {
-		return hasWhere;
-	}
-
-	protected String getSQLDeleteString() {
-		return sqlDeleteString;
-	}
-
-	protected String getSQLInsertRowString() {
-		return sqlInsertRowString;
-	}
-
-	protected String getSQLUpdateRowString() {
-		return sqlUpdateRowString;
-	}
-
-	protected String getSQLDeleteRowString() {
-		return sqlDeleteRowString;
-	}
-
-	public Type getKeyType() {
-		return keyType;
-	}
-
-	public Type getIndexType() {
-		return indexType;
-	}
-
-	public Type getElementType() {
-		return elementType;
-	}
-
-	/**
-	 * Return the element class of an array, or null otherwise
-	 */
-	public Class getElementClass() { //needed by arrays
-		return elementClass;
-	}
-
-	public Object readElement(ResultSet rs, Object owner, String[] aliases, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		return getElementType().nullSafeGet( rs, aliases, session, owner );
-	}
-
-	public Object readIndex(ResultSet rs, String[] aliases, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		Object index = getIndexType().nullSafeGet( rs, aliases, session, null );
-		if ( index == null ) {
-			throw new HibernateException( "null index column for collection: " + role );
-		}
-		index = decrementIndexByBase( index );
-		return index;
-	}
-
-	protected Object decrementIndexByBase(Object index) {
-		if (baseIndex!=0) {
-			index = new Integer( ( (Integer) index ).intValue() - baseIndex );
-		}
-		return index;
-	}
-
-	public Object readIdentifier(ResultSet rs, String alias, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		Object id = getIdentifierType().nullSafeGet( rs, alias, session, null );
-		if ( id == null ) {
-			throw new HibernateException( "null identifier column for collection: " + role );
-		}
-		return id;
-	}
-
-	public Object readKey(ResultSet rs, String[] aliases, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		return getKeyType().nullSafeGet( rs, aliases, session, null );
-	}
-
-	/**
-	 * Write the key to a JDBC <tt>PreparedStatement</tt>
-	 */
-	protected int writeKey(PreparedStatement st, Serializable key, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		
-		if ( key == null ) {
-			throw new NullPointerException( "null key for collection: " + role );  //an assertion
-		}
-		getKeyType().nullSafeSet( st, key, i, session );
-		return i + keyColumnAliases.length;
-	}
-
-	/**
-	 * Write the element to a JDBC <tt>PreparedStatement</tt>
-	 */
-	protected int writeElement(PreparedStatement st, Object elt, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		getElementType().nullSafeSet(st, elt, i, elementColumnIsSettable, session);
-		return i + ArrayHelper.countTrue(elementColumnIsSettable);
-
-	}
-
-	/**
-	 * Write the index to a JDBC <tt>PreparedStatement</tt>
-	 */
-	protected int writeIndex(PreparedStatement st, Object index, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, indexColumnIsSettable, session );
-		return i + ArrayHelper.countTrue(indexColumnIsSettable);
-	}
-
-	protected Object incrementIndexByBase(Object index) {
-		if (baseIndex!=0) {
-			index = new Integer( ( (Integer) index ).intValue() + baseIndex );
-		}
-		return index;
-	}
-
-	/**
-	 * Write the element to a JDBC <tt>PreparedStatement</tt>
-	 */
-	protected int writeElementToWhere(PreparedStatement st, Object elt, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if (elementIsPureFormula) {
-			throw new AssertionFailure("cannot use a formula-based element in the where condition");
-		}
-		getElementType().nullSafeSet(st, elt, i, elementColumnIsInPrimaryKey, session);
-		return i + elementColumnAliases.length;
-
-	}
-
-	/**
-	 * Write the index to a JDBC <tt>PreparedStatement</tt>
-	 */
-	protected int writeIndexToWhere(PreparedStatement st, Object index, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if (indexContainsFormula) {
-			throw new AssertionFailure("cannot use a formula-based index in the where condition");
-		}
-		getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, session );
-		return i + indexColumnAliases.length;
-	}
-
-	/**
-	 * Write the identifier to a JDBC <tt>PreparedStatement</tt>
-	 */
-	public int writeIdentifier(PreparedStatement st, Object id, int i, SessionImplementor session)
-			throws HibernateException, SQLException {
-		
-		getIdentifierType().nullSafeSet( st, id, i, session );
-		return i + 1;
-	}
-
-	public boolean isPrimitiveArray() {
-		return isPrimitiveArray;
-	}
-
-	public boolean isArray() {
-		return isArray;
-	}
-
-	public String[] getKeyColumnAliases(String suffix) {
-		return new Alias( suffix ).toAliasStrings( keyColumnAliases );
-	}
-
-	public String[] getElementColumnAliases(String suffix) {
-		return new Alias( suffix ).toAliasStrings( elementColumnAliases );
-	}
-
-	public String[] getIndexColumnAliases(String suffix) {
-		if ( hasIndex ) {
-			return new Alias( suffix ).toAliasStrings( indexColumnAliases );
-		}
-		else {
-			return null;
-		}
-	}
-
-	public String getIdentifierColumnAlias(String suffix) {
-		if ( hasIdentifier ) {
-			return new Alias( suffix ).toAliasString( identifierColumnAlias );
-		}
-		else {
-			return null;
-		}
-	}
-	
-	public String getIdentifierColumnName() {
-		if ( hasIdentifier ) {
-			return identifierColumnName;
-		} else {
-			return null;
-		}
-	}
-
-	/**
-	 * Generate a list of collection index, key and element columns
-	 */
-	public String selectFragment(String alias, String columnSuffix) {
-		SelectFragment frag = generateSelectFragment( alias, columnSuffix );
-		appendElementColumns( frag, alias );
-		appendIndexColumns( frag, alias );
-		appendIdentifierColumns( frag, alias );
-
-		return frag.toFragmentString()
-				.substring( 2 ); //strip leading ','
-	}
-
-	protected String generateSelectSizeString(boolean isIntegerIndexed) {
-		String selectValue = isIntegerIndexed ? 
-			"max(" + getIndexColumnNames()[0] + ") + 1": //lists, arrays
-			"count(" + getElementColumnNames()[0] + ")"; //sets, maps, bags
-		return new SimpleSelect(dialect)
-				.setTableName( getTableName() )
-				.addCondition( getKeyColumnNames(), "=?" )
-				.addColumn(selectValue)
-				.toStatementString();
-	}
-
-	protected String generateDetectRowByIndexString() {
-		if ( !hasIndex() ) {
-			return null;
-		}
-		return new SimpleSelect(dialect)
-				.setTableName( getTableName() )
-				.addCondition( getKeyColumnNames(), "=?" )
-				.addCondition( getIndexColumnNames(), "=?" )
-				.addCondition( indexFormulas, "=?" )
-				.addColumn("1")
-				.toStatementString();
-	}
-
-	protected String generateSelectRowByIndexString() {
-		if ( !hasIndex() ) {
-			return null;
-		}
-		return new SimpleSelect(dialect)
-				.setTableName( getTableName() )
-				.addCondition( getKeyColumnNames(), "=?" )
-				.addCondition( getIndexColumnNames(), "=?" )
-				.addCondition( indexFormulas, "=?" )
-				.addColumns( getElementColumnNames(), elementColumnAliases )
-				.addColumns( indexFormulas, indexColumnAliases )
-				.toStatementString();
-	}
-
-	protected String generateDetectRowByElementString() {
-		return new SimpleSelect(dialect)
-				.setTableName( getTableName() )
-				.addCondition( getKeyColumnNames(), "=?" )
-				.addCondition( getElementColumnNames(), "=?" )
-				.addCondition( elementFormulas, "=?" )
-				.addColumn("1")
-				.toStatementString();
-	}
-
-	protected SelectFragment generateSelectFragment(String alias, String columnSuffix) {
-		return new SelectFragment()
-				.setSuffix( columnSuffix )
-				.addColumns( alias, keyColumnNames, keyColumnAliases );
-	}
-
-	protected void appendElementColumns(SelectFragment frag, String elemAlias) {
-		for ( int i=0; i<elementColumnIsSettable.length; i++ ) {
-			if ( elementColumnIsSettable[i] ) {
-				frag.addColumn( elemAlias, elementColumnNames[i], elementColumnAliases[i] );
-			}
-			else {
-				frag.addFormula( elemAlias, elementFormulaTemplates[i], elementColumnAliases[i] );
-			}
-		}
-	}
-
-	protected void appendIndexColumns(SelectFragment frag, String alias) {
-		if ( hasIndex ) {
-			for ( int i=0; i<indexColumnIsSettable.length; i++ ) {
-				if ( indexColumnIsSettable[i] ) {
-					frag.addColumn( alias, indexColumnNames[i], indexColumnAliases[i] );
-				}
-				else {
-					frag.addFormula( alias, indexFormulaTemplates[i], indexColumnAliases[i] );
-				}
-			}
-		}
-	}
-
-	protected void appendIdentifierColumns(SelectFragment frag, String alias) {
-		if ( hasIdentifier ) {
-			frag.addColumn( alias, identifierColumnName, identifierColumnAlias );
-		}
-	}
-
-	public String[] getIndexColumnNames() {
-		return indexColumnNames;
-	}
-
-	public String[] getIndexFormulas() {
-		return indexFormulas;
-	}
-
-	public String[] getIndexColumnNames(String alias) {
-		return qualify(alias, indexColumnNames, indexFormulaTemplates);
-
-	}
-
-	public String[] getElementColumnNames(String alias) {
-		return qualify(alias, elementColumnNames, elementFormulaTemplates);
-	}
-	
-	private static String[] qualify(String alias, String[] columnNames, String[] formulaTemplates) {
-		int span = columnNames.length;
-		String[] result = new String[span];
-		for (int i=0; i<span; i++) {
-			if ( columnNames[i]==null ) {
-				result[i] = StringHelper.replace( formulaTemplates[i], Template.TEMPLATE, alias );
-			}
-			else {
-				result[i] = StringHelper.qualify( alias, columnNames[i] );
-			}
-		}
-		return result;
-	}
-
-	public String[] getElementColumnNames() {
-		return elementColumnNames; //TODO: something with formulas...
-	}
-
-	public String[] getKeyColumnNames() {
-		return keyColumnNames;
-	}
-
-	public boolean hasIndex() {
-		return hasIndex;
-	}
-
-	public boolean isLazy() {
-		return isLazy;
-	}
-
-	public boolean isInverse() {
-		return isInverse;
-	}
-
-	public String getTableName() {
-		return qualifiedTableName;
-	}
-
-	public void remove(Serializable id, SessionImplementor session) throws HibernateException {
-
-		if ( !isInverse && isRowDeleteEnabled() ) {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"Deleting collection: " + 
-						MessageHelper.collectionInfoString( this, id, getFactory() ) 
-					);
-			}
-
-			// Remove all the old entries
-
-			try {
-				int offset = 1;
-				PreparedStatement st = null;
-				Expectation expectation = Expectations.appropriateExpectation( getDeleteAllCheckStyle() );
-				boolean callable = isDeleteAllCallable();
-				boolean useBatch = expectation.canBeBatched();
-				String sql = getSQLDeleteString();
-				if ( useBatch ) {
-					if ( callable ) {
-						st = session.getBatcher().prepareBatchCallableStatement( sql );
-					}
-					else {
-						st = session.getBatcher().prepareBatchStatement( sql );
-					}
-				}
-				else {
-					if ( callable ) {
-						st = session.getBatcher().prepareCallableStatement( sql );
-					}
-					else {
-						st = session.getBatcher().prepareStatement( sql );
-					}
-				}
-
-
-				try {
-					offset+= expectation.prepare( st );
-
-					writeKey( st, id, offset, session );
-					if ( useBatch ) {
-						session.getBatcher().addToBatch( expectation );
-					}
-					else {
-						expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-					}
-				}
-				catch ( SQLException sqle ) {
-					if ( useBatch ) {
-						session.getBatcher().abortBatch( sqle );
-					}
-					throw sqle;
-				}
-				finally {
-					if ( !useBatch ) {
-						session.getBatcher().closeStatement( st );
-					}
-				}
-
-				if ( log.isDebugEnabled() ) {
-					log.debug( "done deleting collection" );
-				}
-			}
-			catch ( SQLException sqle ) {
-				throw JDBCExceptionHelper.convert(
-				        sqlExceptionConverter,
-				        sqle,
-				        "could not delete collection: " + 
-				        MessageHelper.collectionInfoString( this, id, getFactory() ),
-				        getSQLDeleteString()
-					);
-			}
-
-		}
-
-	}
-
-	public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session)
-			throws HibernateException {
-
-		if ( !isInverse && isRowInsertEnabled() ) {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"Inserting collection: " + 
-						MessageHelper.collectionInfoString( this, id, getFactory() ) 
-					);
-			}
-
-			try {
-				//create all the new entries
-				Iterator entries = collection.entries(this);
-				if ( entries.hasNext() ) {
-					collection.preInsert( this );
-					int i = 0;
-					int count = 0;
-					while ( entries.hasNext() ) {
-
-						final Object entry = entries.next();
-						if ( collection.entryExists( entry, i ) ) {
-							int offset = 1;
-							PreparedStatement st = null;
-							Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
-							boolean callable = isInsertCallable();
-							boolean useBatch = expectation.canBeBatched();
-							String sql = getSQLInsertRowString();
-
-							if ( useBatch ) {
-								if ( callable ) {
-									st = session.getBatcher().prepareBatchCallableStatement( sql );
-								}
-								else {
-									st = session.getBatcher().prepareBatchStatement( sql );
-								}
-							}
-							else {
-								if ( callable ) {
-									st = session.getBatcher().prepareCallableStatement( sql );
-								}
-								else {
-									st = session.getBatcher().prepareStatement( sql );
-								}
-							}
-
-
-							try {
-								offset+= expectation.prepare( st );
-
-								//TODO: copy/paste from insertRows()
-								int loc = writeKey( st, id, offset, session );
-								if ( hasIdentifier ) {
-									loc = writeIdentifier( st, collection.getIdentifier(entry, i), loc, session );
-								}
-								if ( hasIndex /*&& !indexIsFormula*/ ) {
-									loc = writeIndex( st, collection.getIndex(entry, i, this), loc, session );
-								}
-								loc = writeElement(st, collection.getElement(entry), loc, session );
-
-								if ( useBatch ) {
-									session.getBatcher().addToBatch( expectation );
-								}
-								else {
-									expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-								}
-
-								collection.afterRowInsert( this, entry, i );
-								count++;
-							}
-							catch ( SQLException sqle ) {
-								if ( useBatch ) {
-									session.getBatcher().abortBatch( sqle );
-								}
-								throw sqle;
-							}
-							finally {
-								if ( !useBatch ) {
-									session.getBatcher().closeStatement( st );
-								}
-							}
-
-						}
-						i++;
-					}
-
-					if ( log.isDebugEnabled() ) {
-						log.debug( "done inserting collection: " + count + " rows inserted" );
-					}
-
-				}
-				else {
-					if ( log.isDebugEnabled() ) {
-						log.debug( "collection was empty" );
-					}
-				}
-			}
-			catch ( SQLException sqle ) {
-				throw JDBCExceptionHelper.convert(
-				        sqlExceptionConverter,
-				        sqle,
-				        "could not insert collection: " + 
-				        MessageHelper.collectionInfoString( this, id, getFactory() ),
-				        getSQLInsertRowString()
-					);
-			}
-		}
-	}
-	
-	protected boolean isRowDeleteEnabled() {
-		return true;
-	}
-
-	public void deleteRows(PersistentCollection collection, Serializable id, SessionImplementor session)
-			throws HibernateException {
-
-		if ( !isInverse && isRowDeleteEnabled() ) {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"Deleting rows of collection: " + 
-						MessageHelper.collectionInfoString( this, id, getFactory() ) 
-					);
-			}
-			
-			boolean deleteByIndex = !isOneToMany() && hasIndex && !indexContainsFormula;
-			
-			try {
-				//delete all the deleted entries
-				Iterator deletes = collection.getDeletes( this, !deleteByIndex );
-				if ( deletes.hasNext() ) {
-					int offset = 1;
-					int count = 0;
-					while ( deletes.hasNext() ) {
-						PreparedStatement st = null;
-						Expectation expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
-						boolean callable = isDeleteCallable();
-						boolean useBatch = expectation.canBeBatched();
-						String sql = getSQLDeleteRowString();
-
-						if ( useBatch ) {
-							if ( callable ) {
-								st = session.getBatcher().prepareBatchCallableStatement( sql );
-							}
-							else {
-								st = session.getBatcher().prepareBatchStatement( sql );
-							}
-						}
-						else {
-							if ( callable ) {
-								st = session.getBatcher().prepareCallableStatement( sql );
-							}
-							else {
-								st = session.getBatcher().prepareStatement( sql );
-							}
-						}
-
-						try {
-							expectation.prepare( st );
-
-							Object entry = deletes.next();
-							int loc = offset;
-							if ( hasIdentifier ) {
-								writeIdentifier( st, entry, loc, session );
-							}
-							else {
-								loc = writeKey( st, id, loc, session );
-								if ( deleteByIndex ) {
-									writeIndexToWhere( st, entry, loc, session );
-								}
-								else {
-									writeElementToWhere( st, entry, loc, session );
-								}
-							}
-
-							if ( useBatch ) {
-								session.getBatcher().addToBatch( expectation );
-							}
-							else {
-								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-							}
-							count++;
-						}
-						catch ( SQLException sqle ) {
-							if ( useBatch ) {
-								session.getBatcher().abortBatch( sqle );
-							}
-							throw sqle;
-						}
-						finally {
-							if ( !useBatch ) {
-								session.getBatcher().closeStatement( st );
-							}
-						}
-
-						if ( log.isDebugEnabled() ) {
-							log.debug( "done deleting collection rows: " + count + " deleted" );
-						}
-					}
-				}
-				else {
-					if ( log.isDebugEnabled() ) {
-						log.debug( "no rows to delete" );
-					}
-				}
-			}
-			catch ( SQLException sqle ) {
-				throw JDBCExceptionHelper.convert(
-				        sqlExceptionConverter,
-				        sqle,
-				        "could not delete collection rows: " + 
-				        MessageHelper.collectionInfoString( this, id, getFactory() ),
-				        getSQLDeleteRowString()
-					);
-			}
-		}
-	}
-	
-	protected boolean isRowInsertEnabled() {
-		return true;
-	}
-
-	public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session)
-			throws HibernateException {
-
-		if ( !isInverse && isRowInsertEnabled() ) {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( 
-						"Inserting rows of collection: " + 
-						MessageHelper.collectionInfoString( this, id, getFactory() ) 
-					);
-			}
-
-			try {
-				//insert all the new entries
-				collection.preInsert( this );
-				Iterator entries = collection.entries( this );
-				Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
-				boolean callable = isInsertCallable();
-				boolean useBatch = expectation.canBeBatched();
-				String sql = getSQLInsertRowString();
-				int i = 0;
-				int count = 0;
-				while ( entries.hasNext() ) {
-					int offset = 1;
-					Object entry = entries.next();
-					PreparedStatement st = null;
-					if ( collection.needsInserting( entry, i, elementType ) ) {
-
-						if ( useBatch ) {
-							if ( st == null ) {
-								if ( callable ) {
-									st = session.getBatcher().prepareBatchCallableStatement( sql );
-								}
-								else {
-									st = session.getBatcher().prepareBatchStatement( sql );
-								}
-							}
-						}
-						else {
-							if ( callable ) {
-								st = session.getBatcher().prepareCallableStatement( sql );
-							}
-							else {
-								st = session.getBatcher().prepareStatement( sql );
-							}
-						}
-
-						try {
-							offset += expectation.prepare( st );
-							//TODO: copy/paste from recreate()
-							offset = writeKey( st, id, offset, session );
-							if ( hasIdentifier ) {
-								offset = writeIdentifier( st, collection.getIdentifier(entry, i), offset, session );
-							}
-							if ( hasIndex /*&& !indexIsFormula*/ ) {
-								offset = writeIndex( st, collection.getIndex(entry, i, this), offset, session );
-							}
-							writeElement(st, collection.getElement(entry), offset, session );
-
-							if ( useBatch ) {
-								session.getBatcher().addToBatch( expectation );
-							}
-							else {
-								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-							}
-							collection.afterRowInsert( this, entry, i );
-							count++;
-						}
-						catch ( SQLException sqle ) {
-							if ( useBatch ) {
-								session.getBatcher().abortBatch( sqle );
-							}
-							throw sqle;
-						}
-						finally {
-							if ( !useBatch ) {
-								session.getBatcher().closeStatement( st );
-							}
-						}
-					}
-					i++;
-				}
-				if ( log.isDebugEnabled() ) {
-					log.debug( "done inserting rows: " + count + " inserted" );
-				}
-			}
-			catch ( SQLException sqle ) {
-				throw JDBCExceptionHelper.convert(
-				        sqlExceptionConverter,
-				        sqle,
-				        "could not insert collection rows: " + 
-				        MessageHelper.collectionInfoString( this, id, getFactory() ),
-				        getSQLInsertRowString()
-					);
-			}
-
-		}
-	}
-
-
-	public String getRole() {
-		return role;
-	}
-
-	public String getOwnerEntityName() {
-		return entityName;
-	}
-
-	public EntityPersister getOwnerEntityPersister() {
-		return ownerPersister;
-	}
-
-	public IdentifierGenerator getIdentifierGenerator() {
-		return identifierGenerator;
-	}
-
-	public Type getIdentifierType() {
-		return identifierType;
-	}
-
-	public boolean hasOrphanDelete() {
-		return hasOrphanDelete;
-	}
-
-	public Type toType(String propertyName) throws QueryException {
-		if ( "index".equals( propertyName ) ) {
-			return indexType;
-		}
-		return elementPropertyMapping.toType( propertyName );
-	}
-
-	public abstract boolean isManyToMany();
-
-	public String getManyToManyFilterFragment(String alias, Map enabledFilters) {
-		StringBuffer buffer = new StringBuffer();
-		manyToManyFilterHelper.render( buffer, alias, enabledFilters );
-
-		if ( manyToManyWhereString != null ) {
-			buffer.append( " and " )
-					.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, alias ) );
-		}
-
-		return buffer.toString();
-	}
-
-	public String[] toColumns(String alias, String propertyName)
-			throws QueryException {
-
-		if ( "index".equals( propertyName ) ) {
-			if ( isManyToMany() ) {
-				throw new QueryException( "index() function not supported for many-to-many association" );
-			}
-			return StringHelper.qualify( alias, indexColumnNames );
-		}
-
-		return elementPropertyMapping.toColumns( alias, propertyName );
-	}
-
-	public String[] toColumns(String propertyName)
-			throws QueryException {
-
-		if ( "index".equals( propertyName ) ) {
-			if ( isManyToMany() ) {
-				throw new QueryException( "index() function not supported for many-to-many association" );
-			}
-			return indexColumnNames;
-		}
-
-		return elementPropertyMapping.toColumns( propertyName );
-	}
-
-	public Type getType() {
-		return elementPropertyMapping.getType(); //==elementType ??
-	}
-
-	public String getName() {
-		return getRole();
-	}
-
-	public EntityPersister getElementPersister() {
-		if ( elementPersister == null ) {
-			throw new AssertionFailure( "not an association" );
-		}
-		return ( Loadable ) elementPersister;
-	}
-
-	public boolean isCollection() {
-		return true;
-	}
-
-	public Serializable[] getCollectionSpaces() {
-		return spaces;
-	}
-
-	protected abstract String generateDeleteString();
-
-	protected abstract String generateDeleteRowString();
-
-	protected abstract String generateUpdateRowString();
-
-	protected abstract String generateInsertRowString();
-
-	public void updateRows(PersistentCollection collection, Serializable id, SessionImplementor session) 
-	throws HibernateException {
-
-		if ( !isInverse && collection.isRowUpdatePossible() ) {
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( "Updating rows of collection: " + role + "#" + id );
-			}
-
-			//update all the modified entries
-			int count = doUpdateRows( id, collection, session );
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( "done updating rows: " + count + " updated" );
-			}
-		}
-	}
-
-	protected abstract int doUpdateRows(Serializable key, PersistentCollection collection, SessionImplementor session) 
-	throws HibernateException;
-
-	public CollectionMetadata getCollectionMetadata() {
-		return this;
-	}
-
-	public SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	protected String filterFragment(String alias) throws MappingException {
-		return hasWhere() ? " and " + getSQLWhereString( alias ) : "";
-	}
-
-	public String filterFragment(String alias, Map enabledFilters) throws MappingException {
-
-		StringBuffer sessionFilterFragment = new StringBuffer();
-		filterHelper.render( sessionFilterFragment, alias, enabledFilters );
-
-		return sessionFilterFragment.append( filterFragment( alias ) ).toString();
-	}
-
-	public String oneToManyFilterFragment(String alias) throws MappingException {
-		return "";
-	}
-
-	protected boolean isInsertCallable() {
-		return insertCallable;
-	}
-
-	protected ExecuteUpdateResultCheckStyle getInsertCheckStyle() {
-		return insertCheckStyle;
-	}
-
-	protected boolean isUpdateCallable() {
-		return updateCallable;
-	}
-
-	protected ExecuteUpdateResultCheckStyle getUpdateCheckStyle() {
-		return updateCheckStyle;
-	}
-
-	protected boolean isDeleteCallable() {
-		return deleteCallable;
-	}
-
-	protected ExecuteUpdateResultCheckStyle getDeleteCheckStyle() {
-		return deleteCheckStyle;
-	}
-
-	protected boolean isDeleteAllCallable() {
-		return deleteAllCallable;
-	}
-
-	protected ExecuteUpdateResultCheckStyle getDeleteAllCheckStyle() {
-		return deleteAllCheckStyle;
-	}
-
-	public String toString() {
-		return StringHelper.unqualify( getClass().getName() ) + '(' + role + ')';
-	}
-
-	public boolean isVersioned() {
-		return isVersioned && getOwnerEntityPersister().isVersioned();
-	}
-	
-	public String getNodeName() {
-		return nodeName;
-	}
-
-	public String getElementNodeName() {
-		return elementNodeName;
-	}
-
-	public String getIndexNodeName() {
-		return indexNodeName;
-	}
-
-	protected SQLExceptionConverter getSQLExceptionConverter() {
-		return sqlExceptionConverter;
-	}
-
-	public CacheEntryStructure getCacheEntryStructure() {
-		return cacheEntryStructure;
-	}
-
-	public boolean isAffectedByEnabledFilters(SessionImplementor session) {
-		return filterHelper.isAffectedBy( session.getEnabledFilters() ) ||
-		        ( isManyToMany() && manyToManyFilterHelper.isAffectedBy( session.getEnabledFilters() ) );
-	}
-
-	public boolean isSubselectLoadable() {
-		return subselectLoadable;
-	}
-	
-	public boolean isMutable() {
-		return isMutable;
-	}
-
-	public String[] getCollectionPropertyColumnAliases(String propertyName, String suffix) {
-		String rawAliases[] = (String[]) collectionPropertyColumnAliases.get(propertyName);
-
-		if ( rawAliases == null ) {
-			return null;
-		}
-		
-		String result[] = new String[rawAliases.length];
-		for ( int i=0; i<rawAliases.length; i++ ) {
-			result[i] = new Alias(suffix).toUnquotedAliasString( rawAliases[i] );
-		}
-		return result;
-	}
-	
-	//TODO: formulas ?
-	public void initCollectionPropertyMap() {
-
-		initCollectionPropertyMap( "key", keyType, keyColumnAliases, keyColumnNames );
-		initCollectionPropertyMap( "element", elementType, elementColumnAliases, elementColumnNames );
-		if (hasIndex) {
-			initCollectionPropertyMap( "index", indexType, indexColumnAliases, indexColumnNames );
-		}
-		if (hasIdentifier) {
-			initCollectionPropertyMap( 
-					"id", 
-					identifierType, 
-					new String[] { identifierColumnAlias }, 
-					new String[] { identifierColumnName } 
-				);
-		}
-	}
-
-	private void initCollectionPropertyMap(String aliasName, Type type, String[] columnAliases, String[] columnNames) {
-		
-		collectionPropertyColumnAliases.put(aliasName, columnAliases);
-		collectionPropertyColumnNames.put(aliasName, columnNames);
-	
-		if( type.isComponentType() ) {
-			AbstractComponentType ct = (AbstractComponentType) type;
-			String[] propertyNames = ct.getPropertyNames();
-			for (int i = 0; i < propertyNames.length; i++) {
-				String name = propertyNames[i];
-				collectionPropertyColumnAliases.put( aliasName + "." + name, columnAliases[i] );
-				collectionPropertyColumnNames.put( aliasName + "." + name, columnNames[i] );
-			}
-		} 
-		
-	}
-
-	public int getSize(Serializable key, SessionImplementor session) {
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectSizeString);
-			try {
-				getKeyType().nullSafeSet(st, key, 1, session);
-				ResultSet rs = st.executeQuery();
-				try {
-					return rs.next() ? rs.getInt(1) - baseIndex : 0;
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve collection size: " + 
-					MessageHelper.collectionInfoString( this, key, getFactory() ),
-					sqlSelectSizeString
-				);
-		}
-	}
-	
-	public boolean indexExists(Serializable key, Object index, SessionImplementor session) {
-		return exists(key, incrementIndexByBase(index), getIndexType(), sqlDetectRowByIndexString, session);
-	}
-
-	public boolean elementExists(Serializable key, Object element, SessionImplementor session) {
-		return exists(key, element, getElementType(), sqlDetectRowByElementString, session);
-	}
-
-	private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) {
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
-			try {
-				getKeyType().nullSafeSet(st, key, 1, session);
-				indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session );
-				ResultSet rs = st.executeQuery();
-				try {
-					return rs.next();
-				}
-				finally {
-					rs.close();
-				}
-			}
-			catch( TransientObjectException e ) {
-				return false;
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not check row existence: " + 
-					MessageHelper.collectionInfoString( this, key, getFactory() ),
-					sqlSelectSizeString
-				);
-		}
-	}
-
-	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
-		try {
-			PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectRowByIndexString);
-			try {
-				getKeyType().nullSafeSet(st, key, 1, session);
-				getIndexType().nullSafeSet( st, incrementIndexByBase(index), keyColumnNames.length + 1, session );
-				ResultSet rs = st.executeQuery();
-				try {
-					if ( rs.next() ) {
-						return getElementType().nullSafeGet(rs, elementColumnAliases, session, owner);
-					}
-					else {
-						return null;
-					}
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-		}
-		catch (SQLException sqle) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not read row: " + 
-					MessageHelper.collectionInfoString( this, key, getFactory() ),
-					sqlSelectSizeString
-				);
-		}
-	}
-
-	public boolean isExtraLazy() {
-		return isExtraLazy;
-	}
-	
-	protected Dialect getDialect() {
-		return dialect;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1807 @@
+/*
+ * 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.persister.collection;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.entry.CacheEntryStructure;
+import org.hibernate.cache.entry.StructuredCollectionCacheEntry;
+import org.hibernate.cache.entry.StructuredMapCacheEntry;
+import org.hibernate.cache.entry.UnstructuredCacheEntry;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SubselectFetch;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.loader.collection.CollectionInitializer;
+import org.hibernate.mapping.Collection;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.IdentifierCollection;
+import org.hibernate.mapping.IndexedCollection;
+import org.hibernate.mapping.List;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.Table;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Loadable;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.sql.Alias;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.sql.Template;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.FilterHelper;
+import org.hibernate.util.StringHelper;
+
+
+/**
+ * Base implementation of the <tt>QueryableCollection</tt> interface.
+ *
+ * @author Gavin King
+ * @see BasicCollectionPersister
+ * @see OneToManyPersister
+ */
+public abstract class AbstractCollectionPersister
+		implements CollectionMetadata, SQLLoadableCollection {
+	// TODO: encapsulate the protected instance variables!
+
+	private final String role;
+
+	//SQL statements
+	private final String sqlDeleteString;
+	private final String sqlInsertRowString;
+	private final String sqlUpdateRowString;
+	private final String sqlDeleteRowString;
+	private final String sqlSelectSizeString;
+	private final String sqlSelectRowByIndexString;
+	private final String sqlDetectRowByIndexString;
+	private final String sqlDetectRowByElementString;
+
+	private final String sqlOrderByString;
+	protected final String sqlWhereString;
+	private final String sqlOrderByStringTemplate;
+	private final String sqlWhereStringTemplate;
+	private final boolean hasOrder;
+	protected final boolean hasWhere;
+	private final int baseIndex;
+	
+	private final String nodeName;
+	private final String elementNodeName;
+	private final String indexNodeName;
+
+	protected final boolean indexContainsFormula;
+	protected final boolean elementIsPureFormula;
+	
+	//types
+	private final Type keyType;
+	private final Type indexType;
+	protected final Type elementType;
+	private final Type identifierType;
+
+	//columns
+	protected final String[] keyColumnNames;
+	protected final String[] indexColumnNames;
+	protected final String[] indexFormulaTemplates;
+	protected final String[] indexFormulas;
+	protected final boolean[] indexColumnIsSettable;
+	protected final String[] elementColumnNames;
+	protected final String[] elementFormulaTemplates;
+	protected final String[] elementFormulas;
+	protected final boolean[] elementColumnIsSettable;
+	protected final boolean[] elementColumnIsInPrimaryKey;
+	protected final String[] indexColumnAliases;
+	protected final String[] elementColumnAliases;
+	protected final String[] keyColumnAliases;
+	
+	protected final String identifierColumnName;
+	private final String identifierColumnAlias;
+	//private final String unquotedIdentifierColumnName;
+
+	protected final String qualifiedTableName;
+
+	private final String queryLoaderName;
+
+	private final boolean isPrimitiveArray;
+	private final boolean isArray;
+	protected final boolean hasIndex;
+	protected final boolean hasIdentifier;
+	private final boolean isLazy;
+	private final boolean isExtraLazy;
+	private final boolean isInverse;
+	private final boolean isMutable;
+	private final boolean isVersioned;
+	protected final int batchSize;
+	private final FetchMode fetchMode;
+	private final boolean hasOrphanDelete;
+	private final boolean subselectLoadable;
+
+	//extra information about the element type
+	private final Class elementClass;
+	private final String entityName;
+
+	private final Dialect dialect;
+	private final SQLExceptionConverter sqlExceptionConverter;
+	private final SessionFactoryImplementor factory;
+	private final EntityPersister ownerPersister;
+	private final IdentifierGenerator identifierGenerator;
+	private final PropertyMapping elementPropertyMapping;
+	private final EntityPersister elementPersister;
+	private final CollectionRegionAccessStrategy cacheAccessStrategy;
+	private final CollectionType collectionType;
+	private CollectionInitializer initializer;
+	
+	private final CacheEntryStructure cacheEntryStructure;
+
+	// dynamic filters for the collection
+	private final FilterHelper filterHelper;
+
+	// dynamic filters specifically for many-to-many inside the collection
+	private final FilterHelper manyToManyFilterHelper;
+
+	private final String manyToManyWhereString;
+	private final String manyToManyWhereTemplate;
+
+	private final String manyToManyOrderByString;
+	private final String manyToManyOrderByTemplate;
+
+	// custom sql
+	private final boolean insertCallable;
+	private final boolean updateCallable;
+	private final boolean deleteCallable;
+	private final boolean deleteAllCallable;
+	private ExecuteUpdateResultCheckStyle insertCheckStyle;
+	private ExecuteUpdateResultCheckStyle updateCheckStyle;
+	private ExecuteUpdateResultCheckStyle deleteCheckStyle;
+	private ExecuteUpdateResultCheckStyle deleteAllCheckStyle;
+
+	private final Serializable[] spaces;
+
+	private Map collectionPropertyColumnAliases = new HashMap();
+	private Map collectionPropertyColumnNames = new HashMap();
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractCollectionPersister.class );
+
+	public AbstractCollectionPersister(
+			final Collection collection,
+			final CollectionRegionAccessStrategy cacheAccessStrategy,
+			final Configuration cfg,
+			final SessionFactoryImplementor factory) throws MappingException, CacheException {
+
+		this.factory = factory;
+		this.cacheAccessStrategy = cacheAccessStrategy;
+		if ( factory.getSettings().isStructuredCacheEntriesEnabled() ) {
+			cacheEntryStructure = collection.isMap() ?
+					( CacheEntryStructure ) new StructuredMapCacheEntry() :
+					( CacheEntryStructure ) new StructuredCollectionCacheEntry();
+		}
+		else {
+			cacheEntryStructure = new UnstructuredCacheEntry();
+		}
+		
+		dialect = factory.getDialect();
+		sqlExceptionConverter = factory.getSQLExceptionConverter();
+		collectionType = collection.getCollectionType();
+		role = collection.getRole();
+		entityName = collection.getOwnerEntityName();
+		ownerPersister = factory.getEntityPersister(entityName);
+		queryLoaderName = collection.getLoaderName();
+		nodeName = collection.getNodeName();
+		isMutable = collection.isMutable();
+
+		Table table = collection.getCollectionTable();
+		fetchMode = collection.getElement().getFetchMode();
+		elementType = collection.getElement().getType();
+		//isSet = collection.isSet();
+		//isSorted = collection.isSorted();
+		isPrimitiveArray = collection.isPrimitiveArray();
+		isArray = collection.isArray();
+		subselectLoadable = collection.isSubselectLoadable();
+		
+		qualifiedTableName = table.getQualifiedName( 
+				dialect,
+				factory.getSettings().getDefaultCatalogName(),
+				factory.getSettings().getDefaultSchemaName() 
+			);
+
+		int spacesSize = 1 + collection.getSynchronizedTables().size();
+		spaces = new String[spacesSize];
+		spaces[0] = qualifiedTableName;
+		Iterator iter = collection.getSynchronizedTables().iterator();
+		for ( int i = 1; i < spacesSize; i++ ) {
+			spaces[i] = (String) iter.next();
+		}
+		
+		sqlOrderByString = collection.getOrderBy();
+		hasOrder = sqlOrderByString != null;
+		sqlOrderByStringTemplate = hasOrder ?
+				Template.renderOrderByStringTemplate(sqlOrderByString, dialect, factory.getSqlFunctionRegistry()) :
+				null;
+		sqlWhereString = StringHelper.isNotEmpty( collection.getWhere() ) ? "( " + collection.getWhere() + ") " : null;
+		hasWhere = sqlWhereString != null;
+		sqlWhereStringTemplate = hasWhere ?
+				Template.renderWhereStringTemplate(sqlWhereString, dialect, factory.getSqlFunctionRegistry()) :
+				null;
+
+		hasOrphanDelete = collection.hasOrphanDelete();
+
+		int batch = collection.getBatchSize();
+		if ( batch == -1 ) {
+			batch = factory.getSettings().getDefaultBatchFetchSize();
+		}
+		batchSize = batch;
+
+		isVersioned = collection.isOptimisticLocked();
+		
+		// KEY
+
+		keyType = collection.getKey().getType();
+		iter = collection.getKey().getColumnIterator();
+		int keySpan = collection.getKey().getColumnSpan();
+		keyColumnNames = new String[keySpan];
+		keyColumnAliases = new String[keySpan];
+		int k = 0;
+		while ( iter.hasNext() ) {
+			// NativeSQL: collect key column and auto-aliases
+			Column col = ( (Column) iter.next() );
+			keyColumnNames[k] = col.getQuotedName(dialect);
+			keyColumnAliases[k] = col.getAlias(dialect);
+			k++;
+		}
+		
+		//unquotedKeyColumnNames = StringHelper.unQuote(keyColumnAliases);
+
+		//ELEMENT
+
+		String elemNode = collection.getElementNodeName();
+		if ( elementType.isEntityType() ) {
+			String entityName = ( (EntityType) elementType ).getAssociatedEntityName();
+			elementPersister = factory.getEntityPersister(entityName);
+			if ( elemNode==null ) {
+				elemNode = cfg.getClassMapping(entityName).getNodeName();
+			}
+			// NativeSQL: collect element column and auto-aliases
+			
+		}
+		else {
+			elementPersister = null;
+		}		
+		elementNodeName = elemNode;
+
+		int elementSpan = collection.getElement().getColumnSpan();
+		elementColumnAliases = new String[elementSpan];
+		elementColumnNames = new String[elementSpan];
+		elementFormulaTemplates = new String[elementSpan];
+		elementFormulas = new String[elementSpan];
+		elementColumnIsSettable = new boolean[elementSpan];
+		elementColumnIsInPrimaryKey = new boolean[elementSpan];
+		boolean isPureFormula = true;
+		boolean hasNotNullableColumns = false;
+		int j = 0;
+		iter = collection.getElement().getColumnIterator();
+		while ( iter.hasNext() ) {
+			Selectable selectable = (Selectable) iter.next();
+			elementColumnAliases[j] = selectable.getAlias(dialect);
+			if ( selectable.isFormula() ) {
+				Formula form = (Formula) selectable;
+				elementFormulaTemplates[j] = form.getTemplate(dialect, factory.getSqlFunctionRegistry());
+				elementFormulas[j] = form.getFormula();
+			}
+			else {
+				Column col = (Column) selectable;
+				elementColumnNames[j] = col.getQuotedName(dialect);
+				elementColumnIsSettable[j] = true;
+				elementColumnIsInPrimaryKey[j] = !col.isNullable();
+				if ( !col.isNullable() ) {
+					hasNotNullableColumns = true;
+				}
+				isPureFormula = false;
+			}
+			j++;
+		}
+		elementIsPureFormula = isPureFormula;
+		
+		//workaround, for backward compatibility of sets with no
+		//not-null columns, assume all columns are used in the
+		//row locator SQL
+		if ( !hasNotNullableColumns ) {
+			Arrays.fill( elementColumnIsInPrimaryKey, true );
+		}
+
+
+		// INDEX AND ROW SELECT
+
+		hasIndex = collection.isIndexed();
+		if (hasIndex) {
+			// NativeSQL: collect index column and auto-aliases
+			IndexedCollection indexedCollection = (IndexedCollection) collection;
+			indexType = indexedCollection.getIndex().getType();
+			int indexSpan = indexedCollection.getIndex().getColumnSpan();
+			iter = indexedCollection.getIndex().getColumnIterator();
+			indexColumnNames = new String[indexSpan];
+			indexFormulaTemplates = new String[indexSpan];
+			indexFormulas = new String[indexSpan];
+			indexColumnIsSettable = new boolean[indexSpan];
+			indexColumnAliases = new String[indexSpan];
+			int i = 0;
+			boolean hasFormula = false;
+			while ( iter.hasNext() ) {
+				Selectable s = (Selectable) iter.next();
+				indexColumnAliases[i] = s.getAlias(dialect);
+				if ( s.isFormula() ) {
+					Formula indexForm = (Formula) s;
+					indexFormulaTemplates[i] = indexForm.getTemplate(dialect, factory.getSqlFunctionRegistry());
+					indexFormulas[i] = indexForm.getFormula();
+					hasFormula = true;
+				}
+				else {
+					Column indexCol = (Column) s;
+					indexColumnNames[i] = indexCol.getQuotedName(dialect);
+					indexColumnIsSettable[i] = true;
+				}
+				i++;
+			}
+			indexContainsFormula = hasFormula;
+			baseIndex = indexedCollection.isList() ? 
+					( (List) indexedCollection ).getBaseIndex() : 0;
+
+			indexNodeName = indexedCollection.getIndexNodeName(); 
+
+		}
+		else {
+			indexContainsFormula = false;
+			indexColumnIsSettable = null;
+			indexFormulaTemplates = null;
+			indexFormulas = null;
+			indexType = null;
+			indexColumnNames = null;
+			indexColumnAliases = null;
+			baseIndex = 0;
+			indexNodeName = null;
+		}
+		
+		hasIdentifier = collection.isIdentified();
+		if (hasIdentifier) {
+			if ( collection.isOneToMany() ) {
+				throw new MappingException( "one-to-many collections with identifiers are not supported" );
+			}
+			IdentifierCollection idColl = (IdentifierCollection) collection;
+			identifierType = idColl.getIdentifier().getType();
+			iter = idColl.getIdentifier().getColumnIterator();
+			Column col = ( Column ) iter.next();
+			identifierColumnName = col.getQuotedName(dialect);
+			identifierColumnAlias = col.getAlias(dialect);
+			//unquotedIdentifierColumnName = identifierColumnAlias;
+			identifierGenerator = idColl.getIdentifier().createIdentifierGenerator( 
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName(),
+					null
+				);
+		}
+		else {
+			identifierType = null;
+			identifierColumnName = null;
+			identifierColumnAlias = null;
+			//unquotedIdentifierColumnName = null;
+			identifierGenerator = null;
+		}
+		
+		//GENERATE THE SQL:
+				
+		//sqlSelectString = sqlSelectString();
+		//sqlSelectRowString = sqlSelectRowString();
+
+		if ( collection.getCustomSQLInsert() == null ) {
+			sqlInsertRowString = generateInsertRowString();
+			insertCallable = false;
+			insertCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
+		}
+		else {
+			sqlInsertRowString = collection.getCustomSQLInsert();
+			insertCallable = collection.isCustomInsertCallable();
+			insertCheckStyle = collection.getCustomSQLInsertCheckStyle() == null
+					? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLInsert(), insertCallable )
+		            : collection.getCustomSQLInsertCheckStyle();
+		}
+
+		if ( collection.getCustomSQLUpdate() == null ) {
+			sqlUpdateRowString = generateUpdateRowString();
+			updateCallable = false;
+			updateCheckStyle = ExecuteUpdateResultCheckStyle.COUNT;
+		}
+		else {
+			sqlUpdateRowString = collection.getCustomSQLUpdate();
+			updateCallable = collection.isCustomUpdateCallable();
+			updateCheckStyle = collection.getCustomSQLUpdateCheckStyle() == null
+					? ExecuteUpdateResultCheckStyle.determineDefault( collection.getCustomSQLUpdate(), insertCallable )
+		            : collection.getCustomSQLUpdateCheckStyle();
+		}
+
+		if ( collection.getCustomSQLDelete() == null ) {
+			sqlDeleteRowString = generateDeleteRowString();
+			deleteCallable = false;
+			deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
+		}
+		else {
+			sqlDeleteRowString = collection.getCustomSQLDelete();
+			deleteCallable = collection.isCustomDeleteCallable();
+			deleteCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
+		}
+
+		if ( collection.getCustomSQLDeleteAll() == null ) {
+			sqlDeleteString = generateDeleteString();
+			deleteAllCallable = false;
+			deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
+		}
+		else {
+			sqlDeleteString = collection.getCustomSQLDeleteAll();
+			deleteAllCallable = collection.isCustomDeleteAllCallable();
+			deleteAllCheckStyle = ExecuteUpdateResultCheckStyle.NONE;
+		}
+
+		sqlSelectSizeString = generateSelectSizeString(  collection.isIndexed() && !collection.isMap() );
+		sqlDetectRowByIndexString = generateDetectRowByIndexString();
+		sqlDetectRowByElementString = generateDetectRowByElementString();
+		sqlSelectRowByIndexString = generateSelectRowByIndexString();
+		
+		logStaticSQL();
+		
+		isLazy = collection.isLazy();
+		isExtraLazy = collection.isExtraLazy();
+
+		isInverse = collection.isInverse();
+
+		if ( collection.isArray() ) {
+			elementClass = ( (org.hibernate.mapping.Array) collection ).getElementClass();
+		}
+		else {
+			// for non-arrays, we don't need to know the element class
+			elementClass = null; //elementType.returnedClass();
+		}
+
+		if ( elementType.isComponentType() ) {
+			elementPropertyMapping = new CompositeElementPropertyMapping( 
+					elementColumnNames,
+					elementFormulaTemplates,
+					(AbstractComponentType) elementType,
+					factory 
+				);
+		}
+		else if ( !elementType.isEntityType() ) {
+			elementPropertyMapping = new ElementPropertyMapping( 
+					elementColumnNames,
+					elementType 
+				);
+		}
+		else {
+			if ( elementPersister instanceof PropertyMapping ) { //not all classpersisters implement PropertyMapping!
+				elementPropertyMapping = (PropertyMapping) elementPersister;
+			}
+			else {
+				elementPropertyMapping = new ElementPropertyMapping( 
+						elementColumnNames,
+						elementType 
+					);
+			}
+		}
+			
+		// Handle any filters applied to this collection
+		filterHelper = new FilterHelper( collection.getFilterMap(), dialect, factory.getSqlFunctionRegistry() );
+
+		// Handle any filters applied to this collection for many-to-many
+		manyToManyFilterHelper = new FilterHelper( collection.getManyToManyFilterMap(), dialect, factory.getSqlFunctionRegistry() );
+		manyToManyWhereString = StringHelper.isNotEmpty( collection.getManyToManyWhere() ) ?
+				"( " + collection.getManyToManyWhere() + ")" :
+				null;
+		manyToManyWhereTemplate = manyToManyWhereString == null ?
+				null :
+				Template.renderWhereStringTemplate( manyToManyWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
+		manyToManyOrderByString = collection.getManyToManyOrdering();
+		manyToManyOrderByTemplate = manyToManyOrderByString == null
+				? null
+	            : Template.renderOrderByStringTemplate( manyToManyOrderByString, factory.getDialect(), factory.getSqlFunctionRegistry() );
+
+		initCollectionPropertyMap();
+	}
+
+	public void postInstantiate() throws MappingException {
+		initializer = queryLoaderName == null ?
+				createCollectionInitializer( CollectionHelper.EMPTY_MAP ) :
+				new NamedQueryCollectionInitializer( queryLoaderName, this );
+	}
+
+	protected void logStaticSQL() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Static SQL for collection: " + getRole() );
+			if ( getSQLInsertRowString() != null ) {
+				log.debug( " Row insert: " + getSQLInsertRowString() );
+			}
+			if ( getSQLUpdateRowString() != null ) {
+				log.debug( " Row update: " + getSQLUpdateRowString() );
+			}
+			if ( getSQLDeleteRowString() != null ) {
+				log.debug( " Row delete: " + getSQLDeleteRowString() );
+			}
+			if ( getSQLDeleteString() != null ) {
+				log.debug( " One-shot delete: " + getSQLDeleteString() );
+			}
+		}
+	}
+
+	public void initialize(Serializable key, SessionImplementor session) throws HibernateException {
+		getAppropriateInitializer( key, session ).initialize( key, session );
+	}
+
+	protected CollectionInitializer getAppropriateInitializer(Serializable key, SessionImplementor session) {
+		if ( queryLoaderName != null ) {
+			//if there is a user-specified loader, return that
+			//TODO: filters!?
+			return initializer;
+		}
+		CollectionInitializer subselectInitializer = getSubselectInitializer( key, session );
+		if ( subselectInitializer != null ) {
+			return subselectInitializer;
+		}
+		else if ( session.getEnabledFilters().isEmpty() ) {
+			return initializer;
+		}
+		else {
+			return createCollectionInitializer( session.getEnabledFilters() );
+		}
+	}
+
+	private CollectionInitializer getSubselectInitializer(Serializable key, SessionImplementor session) {
+
+		if ( !isSubselectLoadable() ) {
+			return null;
+		}
+		
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		
+		SubselectFetch subselect = persistenceContext.getBatchFetchQueue()
+			.getSubselect( new EntityKey( key, getOwnerEntityPersister(), session.getEntityMode() ) );
+		
+		if (subselect == null) {
+			return null;
+		}
+		else {
+			
+			// Take care of any entities that might have
+			// been evicted!	
+			Iterator iter = subselect.getResult().iterator();
+			while ( iter.hasNext() ) {
+				if ( !persistenceContext.containsEntity( (EntityKey) iter.next() ) ) {
+					iter.remove();
+				}
+			}	
+			
+			// Run a subquery loader
+			return createSubselectInitializer( subselect, session );
+		}
+	}
+
+	protected abstract CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session);
+
+	protected abstract CollectionInitializer createCollectionInitializer(Map enabledFilters)
+			throws MappingException;
+
+	public CollectionRegionAccessStrategy getCacheAccessStrategy() {
+		return cacheAccessStrategy;
+	}
+
+	public boolean hasCache() {
+		return cacheAccessStrategy != null;
+	}
+
+	public CollectionType getCollectionType() {
+		return collectionType;
+	}
+
+	protected String getSQLWhereString(String alias) {
+		return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias );
+	}
+
+	public String getSQLOrderByString(String alias) {
+		return hasOrdering() ? 
+			StringHelper.replace( sqlOrderByStringTemplate, Template.TEMPLATE, alias ) : "";
+	}
+
+	public String getManyToManyOrderByString(String alias) {
+		if ( isManyToMany() && manyToManyOrderByString != null ) {
+			return StringHelper.replace( manyToManyOrderByTemplate, Template.TEMPLATE, alias );
+		}
+		else {
+			return "";
+		}
+	}
+	public FetchMode getFetchMode() {
+		return fetchMode;
+	}
+
+	public boolean hasOrdering() {
+		return hasOrder;
+	}
+
+	public boolean hasManyToManyOrdering() {
+		return isManyToMany() && manyToManyOrderByTemplate != null;
+	}
+
+	public boolean hasWhere() {
+		return hasWhere;
+	}
+
+	protected String getSQLDeleteString() {
+		return sqlDeleteString;
+	}
+
+	protected String getSQLInsertRowString() {
+		return sqlInsertRowString;
+	}
+
+	protected String getSQLUpdateRowString() {
+		return sqlUpdateRowString;
+	}
+
+	protected String getSQLDeleteRowString() {
+		return sqlDeleteRowString;
+	}
+
+	public Type getKeyType() {
+		return keyType;
+	}
+
+	public Type getIndexType() {
+		return indexType;
+	}
+
+	public Type getElementType() {
+		return elementType;
+	}
+
+	/**
+	 * Return the element class of an array, or null otherwise
+	 */
+	public Class getElementClass() { //needed by arrays
+		return elementClass;
+	}
+
+	public Object readElement(ResultSet rs, Object owner, String[] aliases, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		return getElementType().nullSafeGet( rs, aliases, session, owner );
+	}
+
+	public Object readIndex(ResultSet rs, String[] aliases, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		Object index = getIndexType().nullSafeGet( rs, aliases, session, null );
+		if ( index == null ) {
+			throw new HibernateException( "null index column for collection: " + role );
+		}
+		index = decrementIndexByBase( index );
+		return index;
+	}
+
+	protected Object decrementIndexByBase(Object index) {
+		if (baseIndex!=0) {
+			index = new Integer( ( (Integer) index ).intValue() - baseIndex );
+		}
+		return index;
+	}
+
+	public Object readIdentifier(ResultSet rs, String alias, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		Object id = getIdentifierType().nullSafeGet( rs, alias, session, null );
+		if ( id == null ) {
+			throw new HibernateException( "null identifier column for collection: " + role );
+		}
+		return id;
+	}
+
+	public Object readKey(ResultSet rs, String[] aliases, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		return getKeyType().nullSafeGet( rs, aliases, session, null );
+	}
+
+	/**
+	 * Write the key to a JDBC <tt>PreparedStatement</tt>
+	 */
+	protected int writeKey(PreparedStatement st, Serializable key, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		
+		if ( key == null ) {
+			throw new NullPointerException( "null key for collection: " + role );  //an assertion
+		}
+		getKeyType().nullSafeSet( st, key, i, session );
+		return i + keyColumnAliases.length;
+	}
+
+	/**
+	 * Write the element to a JDBC <tt>PreparedStatement</tt>
+	 */
+	protected int writeElement(PreparedStatement st, Object elt, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		getElementType().nullSafeSet(st, elt, i, elementColumnIsSettable, session);
+		return i + ArrayHelper.countTrue(elementColumnIsSettable);
+
+	}
+
+	/**
+	 * Write the index to a JDBC <tt>PreparedStatement</tt>
+	 */
+	protected int writeIndex(PreparedStatement st, Object index, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, indexColumnIsSettable, session );
+		return i + ArrayHelper.countTrue(indexColumnIsSettable);
+	}
+
+	protected Object incrementIndexByBase(Object index) {
+		if (baseIndex!=0) {
+			index = new Integer( ( (Integer) index ).intValue() + baseIndex );
+		}
+		return index;
+	}
+
+	/**
+	 * Write the element to a JDBC <tt>PreparedStatement</tt>
+	 */
+	protected int writeElementToWhere(PreparedStatement st, Object elt, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		if (elementIsPureFormula) {
+			throw new AssertionFailure("cannot use a formula-based element in the where condition");
+		}
+		getElementType().nullSafeSet(st, elt, i, elementColumnIsInPrimaryKey, session);
+		return i + elementColumnAliases.length;
+
+	}
+
+	/**
+	 * Write the index to a JDBC <tt>PreparedStatement</tt>
+	 */
+	protected int writeIndexToWhere(PreparedStatement st, Object index, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		if (indexContainsFormula) {
+			throw new AssertionFailure("cannot use a formula-based index in the where condition");
+		}
+		getIndexType().nullSafeSet( st, incrementIndexByBase(index), i, session );
+		return i + indexColumnAliases.length;
+	}
+
+	/**
+	 * Write the identifier to a JDBC <tt>PreparedStatement</tt>
+	 */
+	public int writeIdentifier(PreparedStatement st, Object id, int i, SessionImplementor session)
+			throws HibernateException, SQLException {
+		
+		getIdentifierType().nullSafeSet( st, id, i, session );
+		return i + 1;
+	}
+
+	public boolean isPrimitiveArray() {
+		return isPrimitiveArray;
+	}
+
+	public boolean isArray() {
+		return isArray;
+	}
+
+	public String[] getKeyColumnAliases(String suffix) {
+		return new Alias( suffix ).toAliasStrings( keyColumnAliases );
+	}
+
+	public String[] getElementColumnAliases(String suffix) {
+		return new Alias( suffix ).toAliasStrings( elementColumnAliases );
+	}
+
+	public String[] getIndexColumnAliases(String suffix) {
+		if ( hasIndex ) {
+			return new Alias( suffix ).toAliasStrings( indexColumnAliases );
+		}
+		else {
+			return null;
+		}
+	}
+
+	public String getIdentifierColumnAlias(String suffix) {
+		if ( hasIdentifier ) {
+			return new Alias( suffix ).toAliasString( identifierColumnAlias );
+		}
+		else {
+			return null;
+		}
+	}
+	
+	public String getIdentifierColumnName() {
+		if ( hasIdentifier ) {
+			return identifierColumnName;
+		} else {
+			return null;
+		}
+	}
+
+	/**
+	 * Generate a list of collection index, key and element columns
+	 */
+	public String selectFragment(String alias, String columnSuffix) {
+		SelectFragment frag = generateSelectFragment( alias, columnSuffix );
+		appendElementColumns( frag, alias );
+		appendIndexColumns( frag, alias );
+		appendIdentifierColumns( frag, alias );
+
+		return frag.toFragmentString()
+				.substring( 2 ); //strip leading ','
+	}
+
+	protected String generateSelectSizeString(boolean isIntegerIndexed) {
+		String selectValue = isIntegerIndexed ? 
+			"max(" + getIndexColumnNames()[0] + ") + 1": //lists, arrays
+			"count(" + getElementColumnNames()[0] + ")"; //sets, maps, bags
+		return new SimpleSelect(dialect)
+				.setTableName( getTableName() )
+				.addCondition( getKeyColumnNames(), "=?" )
+				.addColumn(selectValue)
+				.toStatementString();
+	}
+
+	protected String generateDetectRowByIndexString() {
+		if ( !hasIndex() ) {
+			return null;
+		}
+		return new SimpleSelect(dialect)
+				.setTableName( getTableName() )
+				.addCondition( getKeyColumnNames(), "=?" )
+				.addCondition( getIndexColumnNames(), "=?" )
+				.addCondition( indexFormulas, "=?" )
+				.addColumn("1")
+				.toStatementString();
+	}
+
+	protected String generateSelectRowByIndexString() {
+		if ( !hasIndex() ) {
+			return null;
+		}
+		return new SimpleSelect(dialect)
+				.setTableName( getTableName() )
+				.addCondition( getKeyColumnNames(), "=?" )
+				.addCondition( getIndexColumnNames(), "=?" )
+				.addCondition( indexFormulas, "=?" )
+				.addColumns( getElementColumnNames(), elementColumnAliases )
+				.addColumns( indexFormulas, indexColumnAliases )
+				.toStatementString();
+	}
+
+	protected String generateDetectRowByElementString() {
+		return new SimpleSelect(dialect)
+				.setTableName( getTableName() )
+				.addCondition( getKeyColumnNames(), "=?" )
+				.addCondition( getElementColumnNames(), "=?" )
+				.addCondition( elementFormulas, "=?" )
+				.addColumn("1")
+				.toStatementString();
+	}
+
+	protected SelectFragment generateSelectFragment(String alias, String columnSuffix) {
+		return new SelectFragment()
+				.setSuffix( columnSuffix )
+				.addColumns( alias, keyColumnNames, keyColumnAliases );
+	}
+
+	protected void appendElementColumns(SelectFragment frag, String elemAlias) {
+		for ( int i=0; i<elementColumnIsSettable.length; i++ ) {
+			if ( elementColumnIsSettable[i] ) {
+				frag.addColumn( elemAlias, elementColumnNames[i], elementColumnAliases[i] );
+			}
+			else {
+				frag.addFormula( elemAlias, elementFormulaTemplates[i], elementColumnAliases[i] );
+			}
+		}
+	}
+
+	protected void appendIndexColumns(SelectFragment frag, String alias) {
+		if ( hasIndex ) {
+			for ( int i=0; i<indexColumnIsSettable.length; i++ ) {
+				if ( indexColumnIsSettable[i] ) {
+					frag.addColumn( alias, indexColumnNames[i], indexColumnAliases[i] );
+				}
+				else {
+					frag.addFormula( alias, indexFormulaTemplates[i], indexColumnAliases[i] );
+				}
+			}
+		}
+	}
+
+	protected void appendIdentifierColumns(SelectFragment frag, String alias) {
+		if ( hasIdentifier ) {
+			frag.addColumn( alias, identifierColumnName, identifierColumnAlias );
+		}
+	}
+
+	public String[] getIndexColumnNames() {
+		return indexColumnNames;
+	}
+
+	public String[] getIndexFormulas() {
+		return indexFormulas;
+	}
+
+	public String[] getIndexColumnNames(String alias) {
+		return qualify(alias, indexColumnNames, indexFormulaTemplates);
+
+	}
+
+	public String[] getElementColumnNames(String alias) {
+		return qualify(alias, elementColumnNames, elementFormulaTemplates);
+	}
+	
+	private static String[] qualify(String alias, String[] columnNames, String[] formulaTemplates) {
+		int span = columnNames.length;
+		String[] result = new String[span];
+		for (int i=0; i<span; i++) {
+			if ( columnNames[i]==null ) {
+				result[i] = StringHelper.replace( formulaTemplates[i], Template.TEMPLATE, alias );
+			}
+			else {
+				result[i] = StringHelper.qualify( alias, columnNames[i] );
+			}
+		}
+		return result;
+	}
+
+	public String[] getElementColumnNames() {
+		return elementColumnNames; //TODO: something with formulas...
+	}
+
+	public String[] getKeyColumnNames() {
+		return keyColumnNames;
+	}
+
+	public boolean hasIndex() {
+		return hasIndex;
+	}
+
+	public boolean isLazy() {
+		return isLazy;
+	}
+
+	public boolean isInverse() {
+		return isInverse;
+	}
+
+	public String getTableName() {
+		return qualifiedTableName;
+	}
+
+	public void remove(Serializable id, SessionImplementor session) throws HibernateException {
+
+		if ( !isInverse && isRowDeleteEnabled() ) {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"Deleting collection: " + 
+						MessageHelper.collectionInfoString( this, id, getFactory() ) 
+					);
+			}
+
+			// Remove all the old entries
+
+			try {
+				int offset = 1;
+				PreparedStatement st = null;
+				Expectation expectation = Expectations.appropriateExpectation( getDeleteAllCheckStyle() );
+				boolean callable = isDeleteAllCallable();
+				boolean useBatch = expectation.canBeBatched();
+				String sql = getSQLDeleteString();
+				if ( useBatch ) {
+					if ( callable ) {
+						st = session.getBatcher().prepareBatchCallableStatement( sql );
+					}
+					else {
+						st = session.getBatcher().prepareBatchStatement( sql );
+					}
+				}
+				else {
+					if ( callable ) {
+						st = session.getBatcher().prepareCallableStatement( sql );
+					}
+					else {
+						st = session.getBatcher().prepareStatement( sql );
+					}
+				}
+
+
+				try {
+					offset+= expectation.prepare( st );
+
+					writeKey( st, id, offset, session );
+					if ( useBatch ) {
+						session.getBatcher().addToBatch( expectation );
+					}
+					else {
+						expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+					}
+				}
+				catch ( SQLException sqle ) {
+					if ( useBatch ) {
+						session.getBatcher().abortBatch( sqle );
+					}
+					throw sqle;
+				}
+				finally {
+					if ( !useBatch ) {
+						session.getBatcher().closeStatement( st );
+					}
+				}
+
+				if ( log.isDebugEnabled() ) {
+					log.debug( "done deleting collection" );
+				}
+			}
+			catch ( SQLException sqle ) {
+				throw JDBCExceptionHelper.convert(
+				        sqlExceptionConverter,
+				        sqle,
+				        "could not delete collection: " + 
+				        MessageHelper.collectionInfoString( this, id, getFactory() ),
+				        getSQLDeleteString()
+					);
+			}
+
+		}
+
+	}
+
+	public void recreate(PersistentCollection collection, Serializable id, SessionImplementor session)
+			throws HibernateException {
+
+		if ( !isInverse && isRowInsertEnabled() ) {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"Inserting collection: " + 
+						MessageHelper.collectionInfoString( this, id, getFactory() ) 
+					);
+			}
+
+			try {
+				//create all the new entries
+				Iterator entries = collection.entries(this);
+				if ( entries.hasNext() ) {
+					collection.preInsert( this );
+					int i = 0;
+					int count = 0;
+					while ( entries.hasNext() ) {
+
+						final Object entry = entries.next();
+						if ( collection.entryExists( entry, i ) ) {
+							int offset = 1;
+							PreparedStatement st = null;
+							Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
+							boolean callable = isInsertCallable();
+							boolean useBatch = expectation.canBeBatched();
+							String sql = getSQLInsertRowString();
+
+							if ( useBatch ) {
+								if ( callable ) {
+									st = session.getBatcher().prepareBatchCallableStatement( sql );
+								}
+								else {
+									st = session.getBatcher().prepareBatchStatement( sql );
+								}
+							}
+							else {
+								if ( callable ) {
+									st = session.getBatcher().prepareCallableStatement( sql );
+								}
+								else {
+									st = session.getBatcher().prepareStatement( sql );
+								}
+							}
+
+
+							try {
+								offset+= expectation.prepare( st );
+
+								//TODO: copy/paste from insertRows()
+								int loc = writeKey( st, id, offset, session );
+								if ( hasIdentifier ) {
+									loc = writeIdentifier( st, collection.getIdentifier(entry, i), loc, session );
+								}
+								if ( hasIndex /*&& !indexIsFormula*/ ) {
+									loc = writeIndex( st, collection.getIndex(entry, i, this), loc, session );
+								}
+								loc = writeElement(st, collection.getElement(entry), loc, session );
+
+								if ( useBatch ) {
+									session.getBatcher().addToBatch( expectation );
+								}
+								else {
+									expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+								}
+
+								collection.afterRowInsert( this, entry, i );
+								count++;
+							}
+							catch ( SQLException sqle ) {
+								if ( useBatch ) {
+									session.getBatcher().abortBatch( sqle );
+								}
+								throw sqle;
+							}
+							finally {
+								if ( !useBatch ) {
+									session.getBatcher().closeStatement( st );
+								}
+							}
+
+						}
+						i++;
+					}
+
+					if ( log.isDebugEnabled() ) {
+						log.debug( "done inserting collection: " + count + " rows inserted" );
+					}
+
+				}
+				else {
+					if ( log.isDebugEnabled() ) {
+						log.debug( "collection was empty" );
+					}
+				}
+			}
+			catch ( SQLException sqle ) {
+				throw JDBCExceptionHelper.convert(
+				        sqlExceptionConverter,
+				        sqle,
+				        "could not insert collection: " + 
+				        MessageHelper.collectionInfoString( this, id, getFactory() ),
+				        getSQLInsertRowString()
+					);
+			}
+		}
+	}
+	
+	protected boolean isRowDeleteEnabled() {
+		return true;
+	}
+
+	public void deleteRows(PersistentCollection collection, Serializable id, SessionImplementor session)
+			throws HibernateException {
+
+		if ( !isInverse && isRowDeleteEnabled() ) {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"Deleting rows of collection: " + 
+						MessageHelper.collectionInfoString( this, id, getFactory() ) 
+					);
+			}
+			
+			boolean deleteByIndex = !isOneToMany() && hasIndex && !indexContainsFormula;
+			
+			try {
+				//delete all the deleted entries
+				Iterator deletes = collection.getDeletes( this, !deleteByIndex );
+				if ( deletes.hasNext() ) {
+					int offset = 1;
+					int count = 0;
+					while ( deletes.hasNext() ) {
+						PreparedStatement st = null;
+						Expectation expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
+						boolean callable = isDeleteCallable();
+						boolean useBatch = expectation.canBeBatched();
+						String sql = getSQLDeleteRowString();
+
+						if ( useBatch ) {
+							if ( callable ) {
+								st = session.getBatcher().prepareBatchCallableStatement( sql );
+							}
+							else {
+								st = session.getBatcher().prepareBatchStatement( sql );
+							}
+						}
+						else {
+							if ( callable ) {
+								st = session.getBatcher().prepareCallableStatement( sql );
+							}
+							else {
+								st = session.getBatcher().prepareStatement( sql );
+							}
+						}
+
+						try {
+							expectation.prepare( st );
+
+							Object entry = deletes.next();
+							int loc = offset;
+							if ( hasIdentifier ) {
+								writeIdentifier( st, entry, loc, session );
+							}
+							else {
+								loc = writeKey( st, id, loc, session );
+								if ( deleteByIndex ) {
+									writeIndexToWhere( st, entry, loc, session );
+								}
+								else {
+									writeElementToWhere( st, entry, loc, session );
+								}
+							}
+
+							if ( useBatch ) {
+								session.getBatcher().addToBatch( expectation );
+							}
+							else {
+								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+							}
+							count++;
+						}
+						catch ( SQLException sqle ) {
+							if ( useBatch ) {
+								session.getBatcher().abortBatch( sqle );
+							}
+							throw sqle;
+						}
+						finally {
+							if ( !useBatch ) {
+								session.getBatcher().closeStatement( st );
+							}
+						}
+
+						if ( log.isDebugEnabled() ) {
+							log.debug( "done deleting collection rows: " + count + " deleted" );
+						}
+					}
+				}
+				else {
+					if ( log.isDebugEnabled() ) {
+						log.debug( "no rows to delete" );
+					}
+				}
+			}
+			catch ( SQLException sqle ) {
+				throw JDBCExceptionHelper.convert(
+				        sqlExceptionConverter,
+				        sqle,
+				        "could not delete collection rows: " + 
+				        MessageHelper.collectionInfoString( this, id, getFactory() ),
+				        getSQLDeleteRowString()
+					);
+			}
+		}
+	}
+	
+	protected boolean isRowInsertEnabled() {
+		return true;
+	}
+
+	public void insertRows(PersistentCollection collection, Serializable id, SessionImplementor session)
+			throws HibernateException {
+
+		if ( !isInverse && isRowInsertEnabled() ) {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( 
+						"Inserting rows of collection: " + 
+						MessageHelper.collectionInfoString( this, id, getFactory() ) 
+					);
+			}
+
+			try {
+				//insert all the new entries
+				collection.preInsert( this );
+				Iterator entries = collection.entries( this );
+				Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
+				boolean callable = isInsertCallable();
+				boolean useBatch = expectation.canBeBatched();
+				String sql = getSQLInsertRowString();
+				int i = 0;
+				int count = 0;
+				while ( entries.hasNext() ) {
+					int offset = 1;
+					Object entry = entries.next();
+					PreparedStatement st = null;
+					if ( collection.needsInserting( entry, i, elementType ) ) {
+
+						if ( useBatch ) {
+							if ( st == null ) {
+								if ( callable ) {
+									st = session.getBatcher().prepareBatchCallableStatement( sql );
+								}
+								else {
+									st = session.getBatcher().prepareBatchStatement( sql );
+								}
+							}
+						}
+						else {
+							if ( callable ) {
+								st = session.getBatcher().prepareCallableStatement( sql );
+							}
+							else {
+								st = session.getBatcher().prepareStatement( sql );
+							}
+						}
+
+						try {
+							offset += expectation.prepare( st );
+							//TODO: copy/paste from recreate()
+							offset = writeKey( st, id, offset, session );
+							if ( hasIdentifier ) {
+								offset = writeIdentifier( st, collection.getIdentifier(entry, i), offset, session );
+							}
+							if ( hasIndex /*&& !indexIsFormula*/ ) {
+								offset = writeIndex( st, collection.getIndex(entry, i, this), offset, session );
+							}
+							writeElement(st, collection.getElement(entry), offset, session );
+
+							if ( useBatch ) {
+								session.getBatcher().addToBatch( expectation );
+							}
+							else {
+								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+							}
+							collection.afterRowInsert( this, entry, i );
+							count++;
+						}
+						catch ( SQLException sqle ) {
+							if ( useBatch ) {
+								session.getBatcher().abortBatch( sqle );
+							}
+							throw sqle;
+						}
+						finally {
+							if ( !useBatch ) {
+								session.getBatcher().closeStatement( st );
+							}
+						}
+					}
+					i++;
+				}
+				if ( log.isDebugEnabled() ) {
+					log.debug( "done inserting rows: " + count + " inserted" );
+				}
+			}
+			catch ( SQLException sqle ) {
+				throw JDBCExceptionHelper.convert(
+				        sqlExceptionConverter,
+				        sqle,
+				        "could not insert collection rows: " + 
+				        MessageHelper.collectionInfoString( this, id, getFactory() ),
+				        getSQLInsertRowString()
+					);
+			}
+
+		}
+	}
+
+
+	public String getRole() {
+		return role;
+	}
+
+	public String getOwnerEntityName() {
+		return entityName;
+	}
+
+	public EntityPersister getOwnerEntityPersister() {
+		return ownerPersister;
+	}
+
+	public IdentifierGenerator getIdentifierGenerator() {
+		return identifierGenerator;
+	}
+
+	public Type getIdentifierType() {
+		return identifierType;
+	}
+
+	public boolean hasOrphanDelete() {
+		return hasOrphanDelete;
+	}
+
+	public Type toType(String propertyName) throws QueryException {
+		if ( "index".equals( propertyName ) ) {
+			return indexType;
+		}
+		return elementPropertyMapping.toType( propertyName );
+	}
+
+	public abstract boolean isManyToMany();
+
+	public String getManyToManyFilterFragment(String alias, Map enabledFilters) {
+		StringBuffer buffer = new StringBuffer();
+		manyToManyFilterHelper.render( buffer, alias, enabledFilters );
+
+		if ( manyToManyWhereString != null ) {
+			buffer.append( " and " )
+					.append( StringHelper.replace( manyToManyWhereTemplate, Template.TEMPLATE, alias ) );
+		}
+
+		return buffer.toString();
+	}
+
+	public String[] toColumns(String alias, String propertyName)
+			throws QueryException {
+
+		if ( "index".equals( propertyName ) ) {
+			if ( isManyToMany() ) {
+				throw new QueryException( "index() function not supported for many-to-many association" );
+			}
+			return StringHelper.qualify( alias, indexColumnNames );
+		}
+
+		return elementPropertyMapping.toColumns( alias, propertyName );
+	}
+
+	public String[] toColumns(String propertyName)
+			throws QueryException {
+
+		if ( "index".equals( propertyName ) ) {
+			if ( isManyToMany() ) {
+				throw new QueryException( "index() function not supported for many-to-many association" );
+			}
+			return indexColumnNames;
+		}
+
+		return elementPropertyMapping.toColumns( propertyName );
+	}
+
+	public Type getType() {
+		return elementPropertyMapping.getType(); //==elementType ??
+	}
+
+	public String getName() {
+		return getRole();
+	}
+
+	public EntityPersister getElementPersister() {
+		if ( elementPersister == null ) {
+			throw new AssertionFailure( "not an association" );
+		}
+		return ( Loadable ) elementPersister;
+	}
+
+	public boolean isCollection() {
+		return true;
+	}
+
+	public Serializable[] getCollectionSpaces() {
+		return spaces;
+	}
+
+	protected abstract String generateDeleteString();
+
+	protected abstract String generateDeleteRowString();
+
+	protected abstract String generateUpdateRowString();
+
+	protected abstract String generateInsertRowString();
+
+	public void updateRows(PersistentCollection collection, Serializable id, SessionImplementor session) 
+	throws HibernateException {
+
+		if ( !isInverse && collection.isRowUpdatePossible() ) {
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( "Updating rows of collection: " + role + "#" + id );
+			}
+
+			//update all the modified entries
+			int count = doUpdateRows( id, collection, session );
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( "done updating rows: " + count + " updated" );
+			}
+		}
+	}
+
+	protected abstract int doUpdateRows(Serializable key, PersistentCollection collection, SessionImplementor session) 
+	throws HibernateException;
+
+	public CollectionMetadata getCollectionMetadata() {
+		return this;
+	}
+
+	public SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	protected String filterFragment(String alias) throws MappingException {
+		return hasWhere() ? " and " + getSQLWhereString( alias ) : "";
+	}
+
+	public String filterFragment(String alias, Map enabledFilters) throws MappingException {
+
+		StringBuffer sessionFilterFragment = new StringBuffer();
+		filterHelper.render( sessionFilterFragment, alias, enabledFilters );
+
+		return sessionFilterFragment.append( filterFragment( alias ) ).toString();
+	}
+
+	public String oneToManyFilterFragment(String alias) throws MappingException {
+		return "";
+	}
+
+	protected boolean isInsertCallable() {
+		return insertCallable;
+	}
+
+	protected ExecuteUpdateResultCheckStyle getInsertCheckStyle() {
+		return insertCheckStyle;
+	}
+
+	protected boolean isUpdateCallable() {
+		return updateCallable;
+	}
+
+	protected ExecuteUpdateResultCheckStyle getUpdateCheckStyle() {
+		return updateCheckStyle;
+	}
+
+	protected boolean isDeleteCallable() {
+		return deleteCallable;
+	}
+
+	protected ExecuteUpdateResultCheckStyle getDeleteCheckStyle() {
+		return deleteCheckStyle;
+	}
+
+	protected boolean isDeleteAllCallable() {
+		return deleteAllCallable;
+	}
+
+	protected ExecuteUpdateResultCheckStyle getDeleteAllCheckStyle() {
+		return deleteAllCheckStyle;
+	}
+
+	public String toString() {
+		return StringHelper.unqualify( getClass().getName() ) + '(' + role + ')';
+	}
+
+	public boolean isVersioned() {
+		return isVersioned && getOwnerEntityPersister().isVersioned();
+	}
+	
+	public String getNodeName() {
+		return nodeName;
+	}
+
+	public String getElementNodeName() {
+		return elementNodeName;
+	}
+
+	public String getIndexNodeName() {
+		return indexNodeName;
+	}
+
+	protected SQLExceptionConverter getSQLExceptionConverter() {
+		return sqlExceptionConverter;
+	}
+
+	public CacheEntryStructure getCacheEntryStructure() {
+		return cacheEntryStructure;
+	}
+
+	public boolean isAffectedByEnabledFilters(SessionImplementor session) {
+		return filterHelper.isAffectedBy( session.getEnabledFilters() ) ||
+		        ( isManyToMany() && manyToManyFilterHelper.isAffectedBy( session.getEnabledFilters() ) );
+	}
+
+	public boolean isSubselectLoadable() {
+		return subselectLoadable;
+	}
+	
+	public boolean isMutable() {
+		return isMutable;
+	}
+
+	public String[] getCollectionPropertyColumnAliases(String propertyName, String suffix) {
+		String rawAliases[] = (String[]) collectionPropertyColumnAliases.get(propertyName);
+
+		if ( rawAliases == null ) {
+			return null;
+		}
+		
+		String result[] = new String[rawAliases.length];
+		for ( int i=0; i<rawAliases.length; i++ ) {
+			result[i] = new Alias(suffix).toUnquotedAliasString( rawAliases[i] );
+		}
+		return result;
+	}
+	
+	//TODO: formulas ?
+	public void initCollectionPropertyMap() {
+
+		initCollectionPropertyMap( "key", keyType, keyColumnAliases, keyColumnNames );
+		initCollectionPropertyMap( "element", elementType, elementColumnAliases, elementColumnNames );
+		if (hasIndex) {
+			initCollectionPropertyMap( "index", indexType, indexColumnAliases, indexColumnNames );
+		}
+		if (hasIdentifier) {
+			initCollectionPropertyMap( 
+					"id", 
+					identifierType, 
+					new String[] { identifierColumnAlias }, 
+					new String[] { identifierColumnName } 
+				);
+		}
+	}
+
+	private void initCollectionPropertyMap(String aliasName, Type type, String[] columnAliases, String[] columnNames) {
+		
+		collectionPropertyColumnAliases.put(aliasName, columnAliases);
+		collectionPropertyColumnNames.put(aliasName, columnNames);
+	
+		if( type.isComponentType() ) {
+			AbstractComponentType ct = (AbstractComponentType) type;
+			String[] propertyNames = ct.getPropertyNames();
+			for (int i = 0; i < propertyNames.length; i++) {
+				String name = propertyNames[i];
+				collectionPropertyColumnAliases.put( aliasName + "." + name, columnAliases[i] );
+				collectionPropertyColumnNames.put( aliasName + "." + name, columnNames[i] );
+			}
+		} 
+		
+	}
+
+	public int getSize(Serializable key, SessionImplementor session) {
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectSizeString);
+			try {
+				getKeyType().nullSafeSet(st, key, 1, session);
+				ResultSet rs = st.executeQuery();
+				try {
+					return rs.next() ? rs.getInt(1) - baseIndex : 0;
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve collection size: " + 
+					MessageHelper.collectionInfoString( this, key, getFactory() ),
+					sqlSelectSizeString
+				);
+		}
+	}
+	
+	public boolean indexExists(Serializable key, Object index, SessionImplementor session) {
+		return exists(key, incrementIndexByBase(index), getIndexType(), sqlDetectRowByIndexString, session);
+	}
+
+	public boolean elementExists(Serializable key, Object element, SessionImplementor session) {
+		return exists(key, element, getElementType(), sqlDetectRowByElementString, session);
+	}
+
+	private boolean exists(Serializable key, Object indexOrElement, Type indexOrElementType, String sql, SessionImplementor session) {
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sql);
+			try {
+				getKeyType().nullSafeSet(st, key, 1, session);
+				indexOrElementType.nullSafeSet( st, indexOrElement, keyColumnNames.length + 1, session );
+				ResultSet rs = st.executeQuery();
+				try {
+					return rs.next();
+				}
+				finally {
+					rs.close();
+				}
+			}
+			catch( TransientObjectException e ) {
+				return false;
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not check row existence: " + 
+					MessageHelper.collectionInfoString( this, key, getFactory() ),
+					sqlSelectSizeString
+				);
+		}
+	}
+
+	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
+		try {
+			PreparedStatement st = session.getBatcher().prepareSelectStatement(sqlSelectRowByIndexString);
+			try {
+				getKeyType().nullSafeSet(st, key, 1, session);
+				getIndexType().nullSafeSet( st, incrementIndexByBase(index), keyColumnNames.length + 1, session );
+				ResultSet rs = st.executeQuery();
+				try {
+					if ( rs.next() ) {
+						return getElementType().nullSafeGet(rs, elementColumnAliases, session, owner);
+					}
+					else {
+						return null;
+					}
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+		}
+		catch (SQLException sqle) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not read row: " + 
+					MessageHelper.collectionInfoString( this, key, getFactory() ),
+					sqlSelectSizeString
+				);
+		}
+	}
+
+	public boolean isExtraLazy() {
+		return isExtraLazy;
+	}
+	
+	protected Dialect getDialect() {
+		return dialect;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,320 +0,0 @@
-//$Id: BasicCollectionPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.jdbc.Expectations;
-import org.hibernate.jdbc.Expectation;
-import org.hibernate.type.AssociationType;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SubselectFetch;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.loader.collection.BatchingCollectionInitializer;
-import org.hibernate.loader.collection.CollectionInitializer;
-import org.hibernate.loader.collection.SubselectCollectionLoader;
-import org.hibernate.mapping.Collection;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.sql.Delete;
-import org.hibernate.sql.Insert;
-import org.hibernate.sql.Update;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Collection persister for collections of values and many-to-many associations.
- *
- * @author Gavin King
- */
-public class BasicCollectionPersister extends AbstractCollectionPersister {
-
-	public boolean isCascadeDeleteEnabled() {
-		return false;
-	}
-
-	public BasicCollectionPersister(
-			Collection collection,
-			CollectionRegionAccessStrategy cacheAccessStrategy,
-			Configuration cfg,
-			SessionFactoryImplementor factory) throws MappingException, CacheException {
-		super( collection, cacheAccessStrategy, cfg, factory );
-	}
-
-	/**
-	 * Generate the SQL DELETE that deletes all rows
-	 */
-	protected String generateDeleteString() {
-		
-		Delete delete = new Delete()
-				.setTableName( qualifiedTableName )
-				.setPrimaryKeyColumnNames( keyColumnNames );
-		
-		if ( hasWhere ) delete.setWhere( sqlWhereString );
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			delete.setComment( "delete collection " + getRole() );
-		}
-		
-		return delete.toStatementString();
-	}
-
-	/**
-	 * Generate the SQL INSERT that creates a new row
-	 */
-	protected String generateInsertRowString() {
-		
-		Insert insert = new Insert( getDialect() )
-				.setTableName( qualifiedTableName )
-				.addColumns( keyColumnNames );
-		
-		if ( hasIdentifier) insert.addColumn( identifierColumnName );
-		
-		if ( hasIndex /*&& !indexIsFormula*/ ) {
-			insert.addColumns( indexColumnNames, indexColumnIsSettable );
-		}
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			insert.setComment( "insert collection row " + getRole() );
-		}
-		
-		//if ( !elementIsFormula ) {
-			insert.addColumns( elementColumnNames, elementColumnIsSettable );
-		//}
-		
-		return insert.toStatementString();
-	}
-
-	/**
-	 * Generate the SQL UPDATE that updates a row
-	 */
-	protected String generateUpdateRowString() {
-		
-		Update update = new Update( getDialect() )
-			.setTableName( qualifiedTableName );
-		
-		//if ( !elementIsFormula ) {
-			update.addColumns( elementColumnNames, elementColumnIsSettable );
-		//}
-		
-		if ( hasIdentifier ) {
-			update.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } );
-		}
-		else if ( hasIndex && !indexContainsFormula ) {
-			update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
-		}
-		else {
-			update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
-		}
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "update collection row " + getRole() );
-		}
-		
-		return update.toStatementString();
-	}
-
-	/**
-	 * Generate the SQL DELETE that deletes a particular row
-	 */
-	protected String generateDeleteRowString() {
-		
-		Delete delete = new Delete()
-			.setTableName( qualifiedTableName );
-		
-		if ( hasIdentifier ) {
-			delete.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } );
-		}
-		else if ( hasIndex && !indexContainsFormula ) {
-			delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
-		}
-		else {
-			delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
-		}
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			delete.setComment( "delete collection row " + getRole() );
-		}
-		
-		return delete.toStatementString();
-	}
-
-	public boolean consumesEntityAlias() {
-		return false;
-	}
-
-	public boolean consumesCollectionAlias() {
-//		return !isOneToMany();
-		return true;
-	}
-
-	public boolean isOneToMany() {
-		return false;
-	}
-
-	public boolean isManyToMany() {
-		return elementType.isEntityType(); //instanceof AssociationType;
-	}
-
-	protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
-			throws HibernateException {
-		
-		if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0;
-
-		try {
-			PreparedStatement st = null;
-			Expectation expectation = Expectations.appropriateExpectation( getUpdateCheckStyle() );
-			boolean callable = isUpdateCallable();
-			boolean useBatch = expectation.canBeBatched();
-			Iterator entries = collection.entries( this );
-			String sql = getSQLUpdateRowString();
-			int i = 0;
-			int count = 0;
-			while ( entries.hasNext() ) {
-				Object entry = entries.next();
-				if ( collection.needsUpdating( entry, i, elementType ) ) {
-					int offset = 1;
-
-					if ( useBatch ) {
-						if ( st == null ) {
-							if ( callable ) {
-								st = session.getBatcher().prepareBatchCallableStatement( sql );
-							}
-							else {
-								st = session.getBatcher().prepareBatchStatement( sql );
-							}
-						}
-					}
-					else {
-						if ( callable ) {
-							st = session.getBatcher().prepareCallableStatement( sql );
-						}
-						else {
-							st = session.getBatcher().prepareStatement( sql );
-						}
-					}
-
-					try {
-						offset+= expectation.prepare( st );
-						int loc = writeElement( st, collection.getElement( entry ), offset, session );
-						if ( hasIdentifier ) {
-							writeIdentifier( st, collection.getIdentifier( entry, i ), loc, session );
-						}
-						else {
-							loc = writeKey( st, id, loc, session );
-							if ( hasIndex && !indexContainsFormula ) {
-								writeIndexToWhere( st, collection.getIndex( entry, i, this ), loc, session );
-							}
-							else {
-								writeElementToWhere( st, collection.getSnapshotElement( entry, i ), loc, session );
-							}
-						}
-
-						if ( useBatch ) {
-							session.getBatcher().addToBatch( expectation );
-						}
-						else {
-							expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-						}
-					}
-					catch ( SQLException sqle ) {
-						if ( useBatch ) {
-							session.getBatcher().abortBatch( sqle );
-						}
-						throw sqle;
-					}
-					finally {
-						if ( !useBatch ) {
-							session.getBatcher().closeStatement( st );
-						}
-					}
-					count++;
-				}
-				i++;
-			}
-			return count;
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getSQLExceptionConverter(),
-					sqle,
-					"could not update collection rows: " + MessageHelper.collectionInfoString( this, id, getFactory() ),
-					getSQLUpdateRowString()
-				);
-		}
-	}
-
-	public String selectFragment(
-	        Joinable rhs,
-	        String rhsAlias,
-	        String lhsAlias,
-	        String entitySuffix,
-	        String collectionSuffix,
-	        boolean includeCollectionColumns) {
-		// we need to determine the best way to know that two joinables
-		// represent a single many-to-many...
-		if ( rhs != null && isManyToMany() && !rhs.isCollection() ) {
-			AssociationType elementType = ( ( AssociationType ) getElementType() );
-			if ( rhs.equals( elementType.getAssociatedJoinable( getFactory() ) ) ) {
-				return manyToManySelectFragment( rhs, rhsAlias, lhsAlias, collectionSuffix );
-			}
-		}
-		return includeCollectionColumns ? selectFragment( lhsAlias, collectionSuffix ) : "";
-	}
-
-	private String manyToManySelectFragment(
-	        Joinable rhs,
-	        String rhsAlias,
-	        String lhsAlias,
-	        String collectionSuffix) {
-		SelectFragment frag = generateSelectFragment( lhsAlias, collectionSuffix );
-
-		String[] elementColumnNames = rhs.getKeyColumnNames();
-		frag.addColumns( rhsAlias, elementColumnNames, elementColumnAliases );
-		appendIndexColumns( frag, lhsAlias );
-		appendIdentifierColumns( frag, lhsAlias );
-
-		return frag.toFragmentString()
-				.substring( 2 ); //strip leading ','
-	}
-
-	/**
-	 * Create the <tt>CollectionLoader</tt>
-	 *
-	 * @see org.hibernate.loader.collection.BasicCollectionLoader
-	 */
-	protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters)
-			throws MappingException {
-		return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), enabledFilters );
-	}
-
-	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
-		return "";
-	}
-
-	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
-		return "";
-	}
-
-	protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
-		return new SubselectCollectionLoader( 
-				this,
-				subselect.toSubselectString( getCollectionType().getLHSPropertyName() ),
-				subselect.getResult(),
-				subselect.getQueryParameters(),
-				subselect.getNamedParameterLocMap(),
-				session.getFactory(),
-				session.getEnabledFilters() 
-			);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/BasicCollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,343 @@
+/*
+ * 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.persister.collection;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.type.AssociationType;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SubselectFetch;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.loader.collection.BatchingCollectionInitializer;
+import org.hibernate.loader.collection.CollectionInitializer;
+import org.hibernate.loader.collection.SubselectCollectionLoader;
+import org.hibernate.mapping.Collection;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.sql.Delete;
+import org.hibernate.sql.Insert;
+import org.hibernate.sql.Update;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Collection persister for collections of values and many-to-many associations.
+ *
+ * @author Gavin King
+ */
+public class BasicCollectionPersister extends AbstractCollectionPersister {
+
+	public boolean isCascadeDeleteEnabled() {
+		return false;
+	}
+
+	public BasicCollectionPersister(
+			Collection collection,
+			CollectionRegionAccessStrategy cacheAccessStrategy,
+			Configuration cfg,
+			SessionFactoryImplementor factory) throws MappingException, CacheException {
+		super( collection, cacheAccessStrategy, cfg, factory );
+	}
+
+	/**
+	 * Generate the SQL DELETE that deletes all rows
+	 */
+	protected String generateDeleteString() {
+		
+		Delete delete = new Delete()
+				.setTableName( qualifiedTableName )
+				.setPrimaryKeyColumnNames( keyColumnNames );
+		
+		if ( hasWhere ) delete.setWhere( sqlWhereString );
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			delete.setComment( "delete collection " + getRole() );
+		}
+		
+		return delete.toStatementString();
+	}
+
+	/**
+	 * Generate the SQL INSERT that creates a new row
+	 */
+	protected String generateInsertRowString() {
+		
+		Insert insert = new Insert( getDialect() )
+				.setTableName( qualifiedTableName )
+				.addColumns( keyColumnNames );
+		
+		if ( hasIdentifier) insert.addColumn( identifierColumnName );
+		
+		if ( hasIndex /*&& !indexIsFormula*/ ) {
+			insert.addColumns( indexColumnNames, indexColumnIsSettable );
+		}
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			insert.setComment( "insert collection row " + getRole() );
+		}
+		
+		//if ( !elementIsFormula ) {
+			insert.addColumns( elementColumnNames, elementColumnIsSettable );
+		//}
+		
+		return insert.toStatementString();
+	}
+
+	/**
+	 * Generate the SQL UPDATE that updates a row
+	 */
+	protected String generateUpdateRowString() {
+		
+		Update update = new Update( getDialect() )
+			.setTableName( qualifiedTableName );
+		
+		//if ( !elementIsFormula ) {
+			update.addColumns( elementColumnNames, elementColumnIsSettable );
+		//}
+		
+		if ( hasIdentifier ) {
+			update.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } );
+		}
+		else if ( hasIndex && !indexContainsFormula ) {
+			update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
+		}
+		else {
+			update.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
+		}
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "update collection row " + getRole() );
+		}
+		
+		return update.toStatementString();
+	}
+
+	/**
+	 * Generate the SQL DELETE that deletes a particular row
+	 */
+	protected String generateDeleteRowString() {
+		
+		Delete delete = new Delete()
+			.setTableName( qualifiedTableName );
+		
+		if ( hasIdentifier ) {
+			delete.setPrimaryKeyColumnNames( new String[]{ identifierColumnName } );
+		}
+		else if ( hasIndex && !indexContainsFormula ) {
+			delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, indexColumnNames ) );
+		}
+		else {
+			delete.setPrimaryKeyColumnNames( ArrayHelper.join( keyColumnNames, elementColumnNames, elementColumnIsInPrimaryKey ) );
+		}
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			delete.setComment( "delete collection row " + getRole() );
+		}
+		
+		return delete.toStatementString();
+	}
+
+	public boolean consumesEntityAlias() {
+		return false;
+	}
+
+	public boolean consumesCollectionAlias() {
+//		return !isOneToMany();
+		return true;
+	}
+
+	public boolean isOneToMany() {
+		return false;
+	}
+
+	public boolean isManyToMany() {
+		return elementType.isEntityType(); //instanceof AssociationType;
+	}
+
+	protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
+			throws HibernateException {
+		
+		if ( ArrayHelper.isAllFalse(elementColumnIsSettable) ) return 0;
+
+		try {
+			PreparedStatement st = null;
+			Expectation expectation = Expectations.appropriateExpectation( getUpdateCheckStyle() );
+			boolean callable = isUpdateCallable();
+			boolean useBatch = expectation.canBeBatched();
+			Iterator entries = collection.entries( this );
+			String sql = getSQLUpdateRowString();
+			int i = 0;
+			int count = 0;
+			while ( entries.hasNext() ) {
+				Object entry = entries.next();
+				if ( collection.needsUpdating( entry, i, elementType ) ) {
+					int offset = 1;
+
+					if ( useBatch ) {
+						if ( st == null ) {
+							if ( callable ) {
+								st = session.getBatcher().prepareBatchCallableStatement( sql );
+							}
+							else {
+								st = session.getBatcher().prepareBatchStatement( sql );
+							}
+						}
+					}
+					else {
+						if ( callable ) {
+							st = session.getBatcher().prepareCallableStatement( sql );
+						}
+						else {
+							st = session.getBatcher().prepareStatement( sql );
+						}
+					}
+
+					try {
+						offset+= expectation.prepare( st );
+						int loc = writeElement( st, collection.getElement( entry ), offset, session );
+						if ( hasIdentifier ) {
+							writeIdentifier( st, collection.getIdentifier( entry, i ), loc, session );
+						}
+						else {
+							loc = writeKey( st, id, loc, session );
+							if ( hasIndex && !indexContainsFormula ) {
+								writeIndexToWhere( st, collection.getIndex( entry, i, this ), loc, session );
+							}
+							else {
+								writeElementToWhere( st, collection.getSnapshotElement( entry, i ), loc, session );
+							}
+						}
+
+						if ( useBatch ) {
+							session.getBatcher().addToBatch( expectation );
+						}
+						else {
+							expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+						}
+					}
+					catch ( SQLException sqle ) {
+						if ( useBatch ) {
+							session.getBatcher().abortBatch( sqle );
+						}
+						throw sqle;
+					}
+					finally {
+						if ( !useBatch ) {
+							session.getBatcher().closeStatement( st );
+						}
+					}
+					count++;
+				}
+				i++;
+			}
+			return count;
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getSQLExceptionConverter(),
+					sqle,
+					"could not update collection rows: " + MessageHelper.collectionInfoString( this, id, getFactory() ),
+					getSQLUpdateRowString()
+				);
+		}
+	}
+
+	public String selectFragment(
+	        Joinable rhs,
+	        String rhsAlias,
+	        String lhsAlias,
+	        String entitySuffix,
+	        String collectionSuffix,
+	        boolean includeCollectionColumns) {
+		// we need to determine the best way to know that two joinables
+		// represent a single many-to-many...
+		if ( rhs != null && isManyToMany() && !rhs.isCollection() ) {
+			AssociationType elementType = ( ( AssociationType ) getElementType() );
+			if ( rhs.equals( elementType.getAssociatedJoinable( getFactory() ) ) ) {
+				return manyToManySelectFragment( rhs, rhsAlias, lhsAlias, collectionSuffix );
+			}
+		}
+		return includeCollectionColumns ? selectFragment( lhsAlias, collectionSuffix ) : "";
+	}
+
+	private String manyToManySelectFragment(
+	        Joinable rhs,
+	        String rhsAlias,
+	        String lhsAlias,
+	        String collectionSuffix) {
+		SelectFragment frag = generateSelectFragment( lhsAlias, collectionSuffix );
+
+		String[] elementColumnNames = rhs.getKeyColumnNames();
+		frag.addColumns( rhsAlias, elementColumnNames, elementColumnAliases );
+		appendIndexColumns( frag, lhsAlias );
+		appendIdentifierColumns( frag, lhsAlias );
+
+		return frag.toFragmentString()
+				.substring( 2 ); //strip leading ','
+	}
+
+	/**
+	 * Create the <tt>CollectionLoader</tt>
+	 *
+	 * @see org.hibernate.loader.collection.BasicCollectionLoader
+	 */
+	protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters)
+			throws MappingException {
+		return BatchingCollectionInitializer.createBatchingCollectionInitializer( this, batchSize, getFactory(), enabledFilters );
+	}
+
+	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
+		return "";
+	}
+
+	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
+		return "";
+	}
+
+	protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
+		return new SubselectCollectionLoader( 
+				this,
+				subselect.toSubselectString( getCollectionType().getLHSPropertyName() ),
+				subselect.getResult(),
+				subselect.getQueryParameters(),
+				subselect.getNamedParameterLocMap(),
+				session.getFactory(),
+				session.getEnabledFilters() 
+			);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,288 +0,0 @@
-//$Id: CollectionPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cache.entry.CacheEntryStructure;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.metadata.CollectionMetadata;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-/**
- * A strategy for persisting a collection role. Defines a contract between
- * the persistence strategy and the actual persistent collection framework
- * and session. Does not define operations that are required for querying
- * collections, or loading by outer join.<br>
- * <br>
- * Implements persistence of a collection instance while the instance is
- * referenced in a particular role.<br>
- * <br>
- * This class is highly coupled to the <tt>PersistentCollection</tt>
- * hierarchy, since double dispatch is used to load and update collection
- * elements.<br>
- * <br>
- * May be considered an immutable view of the mapping object
- *
- * @see QueryableCollection
- * @see PersistentCollection
- * @author Gavin King
- */
-public interface CollectionPersister {
-	/**
-	 * Initialize the given collection with the given key
-	 */
-	public void initialize(Serializable key, SessionImplementor session) //TODO: add owner argument!!
-	throws HibernateException;
-	/**
-	 * Is this collection role cacheable
-	 */
-	public boolean hasCache();
-	/**
-	 * Get the cache
-	 */
-	public CollectionRegionAccessStrategy getCacheAccessStrategy();
-	/**
-	 * Get the cache structure
-	 */
-	public CacheEntryStructure getCacheEntryStructure();
-	/**
-	 * Get the associated <tt>Type</tt>
-	 */
-	public CollectionType getCollectionType();
-	/**
-	 * Get the "key" type (the type of the foreign key)
-	 */
-	public Type getKeyType();
-	/**
-	 * Get the "index" type for a list or map (optional operation)
-	 */
-	public Type getIndexType();
-	/**
-	 * Get the "element" type
-	 */
-	public Type getElementType();
-	/**
-	 * Return the element class of an array, or null otherwise
-	 */
-	public Class getElementClass();
-	/**
-	 * Read the key from a row of the JDBC <tt>ResultSet</tt>
-	 */
-	public Object readKey(ResultSet rs, String[] keyAliases, SessionImplementor session)
-		throws HibernateException, SQLException;
-	/**
-	 * Read the element from a row of the JDBC <tt>ResultSet</tt>
-	 */
-	public Object readElement(
-		ResultSet rs,
-		Object owner,
-		String[] columnAliases,
-		SessionImplementor session)
-		throws HibernateException, SQLException;
-	/**
-	 * Read the index from a row of the JDBC <tt>ResultSet</tt>
-	 */
-	public Object readIndex(ResultSet rs, String[] columnAliases, SessionImplementor session)
-		throws HibernateException, SQLException;
-	/**
-	 * Read the identifier from a row of the JDBC <tt>ResultSet</tt>
-	 */
-	public Object readIdentifier(
-		ResultSet rs,
-		String columnAlias,
-		SessionImplementor session)
-		throws HibernateException, SQLException;
-	/**
-	 * Is this an array or primitive values?
-	 */
-	public boolean isPrimitiveArray();
-	/**
-	 * Is this an array?
-	 */
-	public boolean isArray();
-	/**
-	 * Is this a one-to-many association?
-	 */
-	public boolean isOneToMany();
-	/**
-	 * Is this a many-to-many association?  Note that this is mainly
-	 * a convenience feature as the single persister does not
-	 * conatin all the information needed to handle a many-to-many
-	 * itself, as internally it is looked at as two many-to-ones.
-	 */
-	public boolean isManyToMany();
-
-	public String getManyToManyFilterFragment(String alias, Map enabledFilters);
-
-	/**
-	 * Is this an "indexed" collection? (list or map)
-	 */
-	public boolean hasIndex();
-	/**
-	 * Is this collection lazyily initialized?
-	 */
-	public boolean isLazy();
-	/**
-	 * Is this collection "inverse", so state changes are not
-	 * propogated to the database.
-	 */
-	public boolean isInverse();
-	/**
-	 * Completely remove the persistent state of the collection
-	 */
-	public void remove(Serializable id, SessionImplementor session)
-		throws HibernateException;
-	/**
-	 * (Re)create the collection's persistent state
-	 */
-	public void recreate(
-		PersistentCollection collection,
-		Serializable key,
-		SessionImplementor session)
-		throws HibernateException;
-	/**
-	 * Delete the persistent state of any elements that were removed from
-	 * the collection
-	 */
-	public void deleteRows(
-		PersistentCollection collection,
-		Serializable key,
-		SessionImplementor session)
-		throws HibernateException;
-	/**
-	 * Update the persistent state of any elements that were modified
-	 */
-	public void updateRows(
-		PersistentCollection collection,
-		Serializable key,
-		SessionImplementor session)
-		throws HibernateException;
-	/**
-	 * Insert the persistent state of any new collection elements
-	 */
-	public void insertRows(
-		PersistentCollection collection,
-		Serializable key,
-		SessionImplementor session)
-		throws HibernateException;
-	/**
-	 * Get the name of this collection role (the fully qualified class name,
-	 * extended by a "property path")
-	 */
-	public String getRole();
-	/**
-	 * Get the persister of the entity that "owns" this collection
-	 */
-	public EntityPersister getOwnerEntityPersister();
-	/**
-	 * Get the surrogate key generation strategy (optional operation)
-	 */
-	public IdentifierGenerator getIdentifierGenerator();
-	/**
-	 * Get the type of the surrogate key
-	 */
-	public Type getIdentifierType();
-	/**
-	 * Does this collection implement "orphan delete"?
-	 */
-	public boolean hasOrphanDelete();
-	/**
-	 * Is this an ordered collection? (An ordered collection is
-	 * ordered by the initialization operation, not by sorting
-	 * that happens in memory, as in the case of a sorted collection.)
-	 */
-	public boolean hasOrdering();
-
-	public boolean hasManyToManyOrdering();
-
-	/**
-	 * Get the "space" that holds the persistent state
-	 */
-	public Serializable[] getCollectionSpaces();
-
-	public CollectionMetadata getCollectionMetadata();
-
-	/**
-	 * Is cascade delete handled by the database-level
-	 * foreign key constraint definition?
-	 */
-	public abstract boolean isCascadeDeleteEnabled();
-	
-	/**
-	 * Does this collection cause version increment of the 
-	 * owning entity?
-	 */
-	public boolean isVersioned();
-	
-	/**
-	 * Can the elements of this collection change?
-	 */
-	public boolean isMutable();
-	
-	//public boolean isSubselectLoadable();
-	
-	public String getNodeName();
-	
-	public String getElementNodeName();
-	
-	public String getIndexNodeName();
-
-	public void postInstantiate() throws MappingException;
-	
-	public SessionFactoryImplementor getFactory();
-
-	public boolean isAffectedByEnabledFilters(SessionImplementor session);
-
-	/**
-	 * Generates the collection's key column aliases, based on the given
-	 * suffix.
-	 *
-	 * @param suffix The suffix to use in the key column alias generation.
-	 * @return The key column aliases.
-	 */
-	public String[] getKeyColumnAliases(String suffix);
-
-	/**
-	 * Generates the collection's index column aliases, based on the given
-	 * suffix.
-	 *
-	 * @param suffix The suffix to use in the index column alias generation.
-	 * @return The key column aliases, or null if not indexed.
-	 */
-	public String[] getIndexColumnAliases(String suffix);
-
-	/**
-	 * Generates the collection's element column aliases, based on the given
-	 * suffix.
-	 *
-	 * @param suffix The suffix to use in the element column alias generation.
-	 * @return The key column aliases.
-	 */
-	public String[] getElementColumnAliases(String suffix);
-
-	/**
-	 * Generates the collection's identifier column aliases, based on the given
-	 * suffix.
-	 *
-	 * @param suffix The suffix to use in the key column alias generation.
-	 * @return The key column aliases.
-	 */
-	public String getIdentifierColumnAlias(String suffix);
-	
-	public boolean isExtraLazy();
-	public int getSize(Serializable key, SessionImplementor session);
-	public boolean indexExists(Serializable key, Object index, SessionImplementor session);
-	public boolean elementExists(Serializable key, Object element, SessionImplementor session);
-	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,311 @@
+/*
+ * 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.persister.collection;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cache.entry.CacheEntryStructure;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.metadata.CollectionMetadata;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+/**
+ * A strategy for persisting a collection role. Defines a contract between
+ * the persistence strategy and the actual persistent collection framework
+ * and session. Does not define operations that are required for querying
+ * collections, or loading by outer join.<br>
+ * <br>
+ * Implements persistence of a collection instance while the instance is
+ * referenced in a particular role.<br>
+ * <br>
+ * This class is highly coupled to the <tt>PersistentCollection</tt>
+ * hierarchy, since double dispatch is used to load and update collection
+ * elements.<br>
+ * <br>
+ * May be considered an immutable view of the mapping object
+ *
+ * @see QueryableCollection
+ * @see PersistentCollection
+ * @author Gavin King
+ */
+public interface CollectionPersister {
+	/**
+	 * Initialize the given collection with the given key
+	 */
+	public void initialize(Serializable key, SessionImplementor session) //TODO: add owner argument!!
+	throws HibernateException;
+	/**
+	 * Is this collection role cacheable
+	 */
+	public boolean hasCache();
+	/**
+	 * Get the cache
+	 */
+	public CollectionRegionAccessStrategy getCacheAccessStrategy();
+	/**
+	 * Get the cache structure
+	 */
+	public CacheEntryStructure getCacheEntryStructure();
+	/**
+	 * Get the associated <tt>Type</tt>
+	 */
+	public CollectionType getCollectionType();
+	/**
+	 * Get the "key" type (the type of the foreign key)
+	 */
+	public Type getKeyType();
+	/**
+	 * Get the "index" type for a list or map (optional operation)
+	 */
+	public Type getIndexType();
+	/**
+	 * Get the "element" type
+	 */
+	public Type getElementType();
+	/**
+	 * Return the element class of an array, or null otherwise
+	 */
+	public Class getElementClass();
+	/**
+	 * Read the key from a row of the JDBC <tt>ResultSet</tt>
+	 */
+	public Object readKey(ResultSet rs, String[] keyAliases, SessionImplementor session)
+		throws HibernateException, SQLException;
+	/**
+	 * Read the element from a row of the JDBC <tt>ResultSet</tt>
+	 */
+	public Object readElement(
+		ResultSet rs,
+		Object owner,
+		String[] columnAliases,
+		SessionImplementor session)
+		throws HibernateException, SQLException;
+	/**
+	 * Read the index from a row of the JDBC <tt>ResultSet</tt>
+	 */
+	public Object readIndex(ResultSet rs, String[] columnAliases, SessionImplementor session)
+		throws HibernateException, SQLException;
+	/**
+	 * Read the identifier from a row of the JDBC <tt>ResultSet</tt>
+	 */
+	public Object readIdentifier(
+		ResultSet rs,
+		String columnAlias,
+		SessionImplementor session)
+		throws HibernateException, SQLException;
+	/**
+	 * Is this an array or primitive values?
+	 */
+	public boolean isPrimitiveArray();
+	/**
+	 * Is this an array?
+	 */
+	public boolean isArray();
+	/**
+	 * Is this a one-to-many association?
+	 */
+	public boolean isOneToMany();
+	/**
+	 * Is this a many-to-many association?  Note that this is mainly
+	 * a convenience feature as the single persister does not
+	 * conatin all the information needed to handle a many-to-many
+	 * itself, as internally it is looked at as two many-to-ones.
+	 */
+	public boolean isManyToMany();
+
+	public String getManyToManyFilterFragment(String alias, Map enabledFilters);
+
+	/**
+	 * Is this an "indexed" collection? (list or map)
+	 */
+	public boolean hasIndex();
+	/**
+	 * Is this collection lazyily initialized?
+	 */
+	public boolean isLazy();
+	/**
+	 * Is this collection "inverse", so state changes are not
+	 * propogated to the database.
+	 */
+	public boolean isInverse();
+	/**
+	 * Completely remove the persistent state of the collection
+	 */
+	public void remove(Serializable id, SessionImplementor session)
+		throws HibernateException;
+	/**
+	 * (Re)create the collection's persistent state
+	 */
+	public void recreate(
+		PersistentCollection collection,
+		Serializable key,
+		SessionImplementor session)
+		throws HibernateException;
+	/**
+	 * Delete the persistent state of any elements that were removed from
+	 * the collection
+	 */
+	public void deleteRows(
+		PersistentCollection collection,
+		Serializable key,
+		SessionImplementor session)
+		throws HibernateException;
+	/**
+	 * Update the persistent state of any elements that were modified
+	 */
+	public void updateRows(
+		PersistentCollection collection,
+		Serializable key,
+		SessionImplementor session)
+		throws HibernateException;
+	/**
+	 * Insert the persistent state of any new collection elements
+	 */
+	public void insertRows(
+		PersistentCollection collection,
+		Serializable key,
+		SessionImplementor session)
+		throws HibernateException;
+	/**
+	 * Get the name of this collection role (the fully qualified class name,
+	 * extended by a "property path")
+	 */
+	public String getRole();
+	/**
+	 * Get the persister of the entity that "owns" this collection
+	 */
+	public EntityPersister getOwnerEntityPersister();
+	/**
+	 * Get the surrogate key generation strategy (optional operation)
+	 */
+	public IdentifierGenerator getIdentifierGenerator();
+	/**
+	 * Get the type of the surrogate key
+	 */
+	public Type getIdentifierType();
+	/**
+	 * Does this collection implement "orphan delete"?
+	 */
+	public boolean hasOrphanDelete();
+	/**
+	 * Is this an ordered collection? (An ordered collection is
+	 * ordered by the initialization operation, not by sorting
+	 * that happens in memory, as in the case of a sorted collection.)
+	 */
+	public boolean hasOrdering();
+
+	public boolean hasManyToManyOrdering();
+
+	/**
+	 * Get the "space" that holds the persistent state
+	 */
+	public Serializable[] getCollectionSpaces();
+
+	public CollectionMetadata getCollectionMetadata();
+
+	/**
+	 * Is cascade delete handled by the database-level
+	 * foreign key constraint definition?
+	 */
+	public abstract boolean isCascadeDeleteEnabled();
+	
+	/**
+	 * Does this collection cause version increment of the 
+	 * owning entity?
+	 */
+	public boolean isVersioned();
+	
+	/**
+	 * Can the elements of this collection change?
+	 */
+	public boolean isMutable();
+	
+	//public boolean isSubselectLoadable();
+	
+	public String getNodeName();
+	
+	public String getElementNodeName();
+	
+	public String getIndexNodeName();
+
+	public void postInstantiate() throws MappingException;
+	
+	public SessionFactoryImplementor getFactory();
+
+	public boolean isAffectedByEnabledFilters(SessionImplementor session);
+
+	/**
+	 * Generates the collection's key column aliases, based on the given
+	 * suffix.
+	 *
+	 * @param suffix The suffix to use in the key column alias generation.
+	 * @return The key column aliases.
+	 */
+	public String[] getKeyColumnAliases(String suffix);
+
+	/**
+	 * Generates the collection's index column aliases, based on the given
+	 * suffix.
+	 *
+	 * @param suffix The suffix to use in the index column alias generation.
+	 * @return The key column aliases, or null if not indexed.
+	 */
+	public String[] getIndexColumnAliases(String suffix);
+
+	/**
+	 * Generates the collection's element column aliases, based on the given
+	 * suffix.
+	 *
+	 * @param suffix The suffix to use in the element column alias generation.
+	 * @return The key column aliases.
+	 */
+	public String[] getElementColumnAliases(String suffix);
+
+	/**
+	 * Generates the collection's identifier column aliases, based on the given
+	 * suffix.
+	 *
+	 * @param suffix The suffix to use in the key column alias generation.
+	 * @return The key column aliases.
+	 */
+	public String getIdentifierColumnAlias(String suffix);
+	
+	public boolean isExtraLazy();
+	public int getSize(Serializable key, SessionImplementor session);
+	public boolean indexExists(Serializable key, Object index, SessionImplementor session);
+	public boolean elementExists(Serializable key, Object element, SessionImplementor session);
+	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-package org.hibernate.persister.collection;
-
-import org.hibernate.Hibernate;
-import org.hibernate.QueryException;
-import org.hibernate.persister.entity.PropertyMapping;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class CollectionPropertyMapping implements PropertyMapping {
-
-	private final QueryableCollection memberPersister;
-
-	public CollectionPropertyMapping(QueryableCollection memberPersister) {
-		this.memberPersister = memberPersister;
-	}
-
-	public Type toType(String propertyName) throws QueryException {
-		if ( propertyName.equals(CollectionPropertyNames.COLLECTION_ELEMENTS) ) {
-			return memberPersister.getElementType();
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_INDICES) ) {
-			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection before indices()");
-			return memberPersister.getIndexType();
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) {
-			return Hibernate.INTEGER;
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) {
-			return memberPersister.getIndexType();
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_INDEX) ) {
-			return memberPersister.getIndexType();
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_ELEMENT) ) {
-			return memberPersister.getElementType();
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_ELEMENT) ) {
-			return memberPersister.getElementType();
-		}
-		else {
-			//return memberPersister.getPropertyType(propertyName);
-			throw new QueryException("illegal syntax near collection: " + propertyName);
-		}
-	}
-
-	public String[] toColumns(String alias, String propertyName) throws QueryException {
-		if ( propertyName.equals(CollectionPropertyNames.COLLECTION_ELEMENTS) ) {
-			return memberPersister.getElementColumnNames(alias);
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_INDICES) ) {
-			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in indices()");
-			return memberPersister.getIndexColumnNames(alias);
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) {
-			String[] cols = memberPersister.getKeyColumnNames();
-			return new String[] { "count(" + alias + '.' + cols[0] + ')' };
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) {
-			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in maxIndex()");
-			String[] cols = memberPersister.getIndexColumnNames(alias);
-			if ( cols.length!=1 ) throw new QueryException("composite collection index in maxIndex()");
-			return new String[] { "max(" + cols[0] + ')' };
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_INDEX) ) {
-			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in minIndex()");
-			String[] cols = memberPersister.getIndexColumnNames(alias);
-			if ( cols.length!=1 ) throw new QueryException("composite collection index in minIndex()");
-			return new String[] { "min(" + cols[0] + ')' };
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_ELEMENT) ) {
-			String[] cols = memberPersister.getElementColumnNames(alias);
-			if ( cols.length!=1 ) throw new QueryException("composite collection element in maxElement()");
-			return new String[] { "max(" + cols[0] + ')' };
-		}
-		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_ELEMENT) ) {
-			String[] cols = memberPersister.getElementColumnNames(alias);
-			if ( cols.length!=1 ) throw new QueryException("composite collection element in minElement()");
-			return new String[] { "min(" + cols[0] + ')' };
-		}
-		else {
-			//return memberPersister.toColumns(alias, propertyName);
-			throw new QueryException("illegal syntax near collection: " + propertyName);
-		}
-	}
-
-	/**
-	 * Given a property path, return the corresponding column name(s).
-	 */
-	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
-		throw new UnsupportedOperationException( "References to collections must be define a SQL alias" );
-	}
-
-	public Type getType() {
-		//return memberPersister.getType();
-		return memberPersister.getCollectionType();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.collection;
+
+import org.hibernate.Hibernate;
+import org.hibernate.QueryException;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class CollectionPropertyMapping implements PropertyMapping {
+
+	private final QueryableCollection memberPersister;
+
+	public CollectionPropertyMapping(QueryableCollection memberPersister) {
+		this.memberPersister = memberPersister;
+	}
+
+	public Type toType(String propertyName) throws QueryException {
+		if ( propertyName.equals(CollectionPropertyNames.COLLECTION_ELEMENTS) ) {
+			return memberPersister.getElementType();
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_INDICES) ) {
+			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection before indices()");
+			return memberPersister.getIndexType();
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) {
+			return Hibernate.INTEGER;
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) {
+			return memberPersister.getIndexType();
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_INDEX) ) {
+			return memberPersister.getIndexType();
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_ELEMENT) ) {
+			return memberPersister.getElementType();
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_ELEMENT) ) {
+			return memberPersister.getElementType();
+		}
+		else {
+			//return memberPersister.getPropertyType(propertyName);
+			throw new QueryException("illegal syntax near collection: " + propertyName);
+		}
+	}
+
+	public String[] toColumns(String alias, String propertyName) throws QueryException {
+		if ( propertyName.equals(CollectionPropertyNames.COLLECTION_ELEMENTS) ) {
+			return memberPersister.getElementColumnNames(alias);
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_INDICES) ) {
+			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in indices()");
+			return memberPersister.getIndexColumnNames(alias);
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_SIZE) ) {
+			String[] cols = memberPersister.getKeyColumnNames();
+			return new String[] { "count(" + alias + '.' + cols[0] + ')' };
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_INDEX) ) {
+			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in maxIndex()");
+			String[] cols = memberPersister.getIndexColumnNames(alias);
+			if ( cols.length!=1 ) throw new QueryException("composite collection index in maxIndex()");
+			return new String[] { "max(" + cols[0] + ')' };
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_INDEX) ) {
+			if ( !memberPersister.hasIndex() ) throw new QueryException("unindexed collection in minIndex()");
+			String[] cols = memberPersister.getIndexColumnNames(alias);
+			if ( cols.length!=1 ) throw new QueryException("composite collection index in minIndex()");
+			return new String[] { "min(" + cols[0] + ')' };
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MAX_ELEMENT) ) {
+			String[] cols = memberPersister.getElementColumnNames(alias);
+			if ( cols.length!=1 ) throw new QueryException("composite collection element in maxElement()");
+			return new String[] { "max(" + cols[0] + ')' };
+		}
+		else if ( propertyName.equals(CollectionPropertyNames.COLLECTION_MIN_ELEMENT) ) {
+			String[] cols = memberPersister.getElementColumnNames(alias);
+			if ( cols.length!=1 ) throw new QueryException("composite collection element in minElement()");
+			return new String[] { "min(" + cols[0] + ')' };
+		}
+		else {
+			//return memberPersister.toColumns(alias, propertyName);
+			throw new QueryException("illegal syntax near collection: " + propertyName);
+		}
+	}
+
+	/**
+	 * Given a property path, return the corresponding column name(s).
+	 */
+	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
+		throw new UnsupportedOperationException( "References to collections must be define a SQL alias" );
+	}
+
+	public Type getType() {
+		//return memberPersister.getType();
+		return memberPersister.getCollectionType();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,19 +0,0 @@
-// $Id: CollectionPropertyNames.java 5699 2005-02-13 11:50:11Z oneovthafew $
-package org.hibernate.persister.collection;
-
-/**
- * The names of all the collection properties.
- *
- * @author josh Dec 23, 2004 7:35:02 AM
- */
-public class CollectionPropertyNames {
-
-	public static final String COLLECTION_SIZE = "size";
-	public static final String COLLECTION_ELEMENTS = "elements";
-	public static final String COLLECTION_INDICES = "indices";
-	public static final String COLLECTION_MAX_INDEX = "maxIndex";
-	public static final String COLLECTION_MIN_INDEX = "minIndex";
-	public static final String COLLECTION_MAX_ELEMENT = "maxElement";
-	public static final String COLLECTION_MIN_ELEMENT = "minElement";
-	public static final String COLLECTION_INDEX = "index";
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CollectionPropertyNames.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.persister.collection;
+
+/**
+ * The names of all the collection properties.
+ *
+ * @author josh
+ */
+public class CollectionPropertyNames {
+
+	public static final String COLLECTION_SIZE = "size";
+	public static final String COLLECTION_ELEMENTS = "elements";
+	public static final String COLLECTION_INDICES = "indices";
+	public static final String COLLECTION_MAX_INDEX = "maxIndex";
+	public static final String COLLECTION_MIN_INDEX = "minIndex";
+	public static final String COLLECTION_MAX_ELEMENT = "maxElement";
+	public static final String COLLECTION_MIN_ELEMENT = "minElement";
+	public static final String COLLECTION_INDEX = "index";
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: CompositeElementPropertyMapping.java 6136 2005-03-21 18:15:29Z oneovthafew $
-package org.hibernate.persister.collection;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.persister.entity.AbstractPropertyMapping;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class CompositeElementPropertyMapping extends AbstractPropertyMapping {
-
-	private final AbstractComponentType compositeType;
-	
-	public CompositeElementPropertyMapping(
-			String[] elementColumns, 
-			String[] elementFormulaTemplates, 
-			AbstractComponentType compositeType, 
-			Mapping factory)
-	throws MappingException {
-
-		this.compositeType = compositeType;
-
-		initComponentPropertyPaths(null, compositeType, elementColumns, elementFormulaTemplates, factory);
-
-	}
-
-	public Type getType() {
-		return compositeType;
-	}
-
-	protected String getEntityName() {
-		return compositeType.getName();
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/CompositeElementPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.collection;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.persister.entity.AbstractPropertyMapping;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class CompositeElementPropertyMapping extends AbstractPropertyMapping {
+
+	private final AbstractComponentType compositeType;
+	
+	public CompositeElementPropertyMapping(
+			String[] elementColumns, 
+			String[] elementFormulaTemplates, 
+			AbstractComponentType compositeType, 
+			Mapping factory)
+	throws MappingException {
+
+		this.compositeType = compositeType;
+
+		initComponentPropertyPaths(null, compositeType, elementColumns, elementFormulaTemplates, factory);
+
+	}
+
+	public Type getType() {
+		return compositeType;
+	}
+
+	protected String getEntityName() {
+		return compositeType.getName();
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-//$Id: ElementPropertyMapping.java 6179 2005-03-23 15:41:48Z steveebersole $
-package org.hibernate.persister.collection;
-
-import org.hibernate.MappingException;
-
-import org.hibernate.QueryException;
-
-import org.hibernate.persister.entity.PropertyMapping;
-
-import org.hibernate.type.Type;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Gavin King
- */
-public class ElementPropertyMapping implements PropertyMapping {
-
-	private final String[] elementColumns;
-	private final Type type;
-
-	public ElementPropertyMapping(String[] elementColumns, Type type)
-	throws MappingException {
-		this.elementColumns = elementColumns;
-		this.type = type;
-	}
-
-	public Type toType(String propertyName) throws QueryException {
-		if ( propertyName==null || "id".equals(propertyName) ) {
-			return type;
-		}
-		else {
-			throw new QueryException("cannot dereference scalar collection element: " + propertyName);
-		}
-	}
-
-	public String[] toColumns(String alias, String propertyName) throws QueryException {
-		if (propertyName==null || "id".equals(propertyName) ) {
-			return StringHelper.qualify(alias, elementColumns);
-		}
-		else {
-			throw new QueryException("cannot dereference scalar collection element: " + propertyName);
-		}
-	}
-
-	/**
-	 * Given a property path, return the corresponding column name(s).
-	 */
-	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
-		throw new UnsupportedOperationException( "References to collections must be define a SQL alias" );
-	}
-
-	public Type getType() {
-		return type;
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/ElementPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.persister.collection;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.persister.entity.PropertyMapping;
+import org.hibernate.type.Type;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Gavin King
+ */
+public class ElementPropertyMapping implements PropertyMapping {
+
+	private final String[] elementColumns;
+	private final Type type;
+
+	public ElementPropertyMapping(String[] elementColumns, Type type)
+	throws MappingException {
+		this.elementColumns = elementColumns;
+		this.type = type;
+	}
+
+	public Type toType(String propertyName) throws QueryException {
+		if ( propertyName==null || "id".equals(propertyName) ) {
+			return type;
+		}
+		else {
+			throw new QueryException("cannot dereference scalar collection element: " + propertyName);
+		}
+	}
+
+	public String[] toColumns(String alias, String propertyName) throws QueryException {
+		if (propertyName==null || "id".equals(propertyName) ) {
+			return StringHelper.qualify(alias, elementColumns);
+		}
+		else {
+			throw new QueryException("cannot dereference scalar collection element: " + propertyName);
+		}
+	}
+
+	/**
+	 * Given a property path, return the corresponding column name(s).
+	 */
+	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException {
+		throw new UnsupportedOperationException( "References to collections must be define a SQL alias" );
+	}
+
+	public Type getType() {
+		return type;
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-//$Id: NamedQueryCollectionInitializer.java 10019 2006-06-15 07:50:12Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.impl.AbstractQueryImpl;
-import org.hibernate.loader.collection.CollectionInitializer;
-
-/**
- * A wrapper around a named query.
- * @author Gavin King
- */
-public final class NamedQueryCollectionInitializer implements CollectionInitializer {
-	private final String queryName;
-	private final CollectionPersister persister;
-	
-	private static final Logger log = LoggerFactory.getLogger(NamedQueryCollectionInitializer.class);
-
-	public NamedQueryCollectionInitializer(String queryName, CollectionPersister persister) {
-		super();
-		this.queryName = queryName;
-		this.persister = persister;
-	}
-
-	public void initialize(Serializable key, SessionImplementor session) 
-	throws HibernateException {
-		
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"initializing collection: " + 
-					persister.getRole() + 
-					" using named query: " + 
-					queryName 
-				);
-		}
-		
-		//TODO: is there a more elegant way than downcasting?
-		AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedSQLQuery(queryName); 
-		if ( query.getNamedParameters().length>0 ) {
-			query.setParameter( 
-					query.getNamedParameters()[0], 
-					key, 
-					persister.getKeyType() 
-				);
-		}
-		else {
-			query.setParameter( 0, key, persister.getKeyType() );
-		}
-		query.setCollectionKey( key )
-				.setFlushMode( FlushMode.MANUAL )
-				.list();
-
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/NamedQueryCollectionInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.collection;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.AbstractQueryImpl;
+import org.hibernate.loader.collection.CollectionInitializer;
+
+/**
+ * A wrapper around a named query.
+ * @author Gavin King
+ */
+public final class NamedQueryCollectionInitializer implements CollectionInitializer {
+	private final String queryName;
+	private final CollectionPersister persister;
+	
+	private static final Logger log = LoggerFactory.getLogger(NamedQueryCollectionInitializer.class);
+
+	public NamedQueryCollectionInitializer(String queryName, CollectionPersister persister) {
+		super();
+		this.queryName = queryName;
+		this.persister = persister;
+	}
+
+	public void initialize(Serializable key, SessionImplementor session) 
+	throws HibernateException {
+		
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"initializing collection: " + 
+					persister.getRole() + 
+					" using named query: " + 
+					queryName 
+				);
+		}
+		
+		//TODO: is there a more elegant way than downcasting?
+		AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedSQLQuery(queryName); 
+		if ( query.getNamedParameters().length>0 ) {
+			query.setParameter( 
+					query.getNamedParameters()[0], 
+					key, 
+					persister.getKeyType() 
+				);
+		}
+		else {
+			query.setParameter( 0, key, persister.getKeyType() );
+		}
+		query.setCollectionKey( key )
+				.setFlushMode( FlushMode.MANUAL )
+				.list();
+
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,364 +0,0 @@
-//$Id: OneToManyPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.jdbc.Expectation;
-import org.hibernate.jdbc.Expectations;
-import org.hibernate.cache.CacheException;
-import org.hibernate.cache.access.CollectionRegionAccessStrategy;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SubselectFetch;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.loader.collection.BatchingCollectionInitializer;
-import org.hibernate.loader.collection.CollectionInitializer;
-import org.hibernate.loader.collection.SubselectOneToManyLoader;
-import org.hibernate.loader.entity.CollectionElementLoader;
-import org.hibernate.mapping.Collection;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.OuterJoinLoadable;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.sql.Update;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Collection persister for one-to-many associations.
- *
- * @author Gavin King
- */
-public class OneToManyPersister extends AbstractCollectionPersister {
-
-	private final boolean cascadeDeleteEnabled;
-	private final boolean keyIsNullable;
-	private final boolean keyIsUpdateable;
-
-	protected boolean isRowDeleteEnabled() {
-		return keyIsUpdateable && keyIsNullable;
-	}
-
-	protected boolean isRowInsertEnabled() {
-		return keyIsUpdateable;
-	}
-
-	public boolean isCascadeDeleteEnabled() {
-		return cascadeDeleteEnabled;
-	}
-
-	public OneToManyPersister(
-			Collection collection,
-			CollectionRegionAccessStrategy cacheAccessStrategy,
-			Configuration cfg,
-			SessionFactoryImplementor factory) throws MappingException, CacheException {
-		super( collection, cacheAccessStrategy, cfg, factory );
-		cascadeDeleteEnabled = collection.getKey().isCascadeDeleteEnabled() &&
-				factory.getDialect().supportsCascadeDelete();
-		keyIsNullable = collection.getKey().isNullable();
-		keyIsUpdateable = collection.getKey().isUpdateable();
-	}
-
-	/**
-	 * Generate the SQL UPDATE that updates all the foreign keys to null
-	 */
-	protected String generateDeleteString() {
-		
-		Update update = new Update( getDialect() )
-				.setTableName( qualifiedTableName )
-				.addColumns( keyColumnNames, "null" )
-				.setPrimaryKeyColumnNames( keyColumnNames );
-		
-		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames, "null" );
-		
-		if ( hasWhere ) update.setWhere( sqlWhereString );
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "delete one-to-many " + getRole() );
-		}
-		
-		return update.toStatementString();
-	}
-
-	/**
-	 * Generate the SQL UPDATE that updates a foreign key to a value
-	 */
-	protected String generateInsertRowString() {
-		
-		Update update = new Update( getDialect() )
-				.setTableName( qualifiedTableName )
-				.addColumns( keyColumnNames );
-		
-		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames );
-		
-		//identifier collections not supported for 1-to-many
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "create one-to-many row " + getRole() );
-		}
-		
-		return update.setPrimaryKeyColumnNames( elementColumnNames )
-				.toStatementString();
-	}
-
-	/**
-	 * Not needed for one-to-many association
-	 */
-	protected String generateUpdateRowString() {
-		return null;
-	}
-
-	/**
-	 * Generate the SQL UPDATE that updates a particular row's foreign
-	 * key to null
-	 */
-	protected String generateDeleteRowString() {
-		
-		Update update = new Update( getDialect() )
-				.setTableName( qualifiedTableName )
-				.addColumns( keyColumnNames, "null" );
-		
-		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames, "null" );
-		
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "delete one-to-many row " + getRole() );
-		}
-		
-		//use a combination of foreign key columns and pk columns, since
-		//the ordering of removal and addition is not guaranteed when
-		//a child moves from one parent to another
-		String[] rowSelectColumnNames = ArrayHelper.join(keyColumnNames, elementColumnNames);
-		return update.setPrimaryKeyColumnNames( rowSelectColumnNames )
-				.toStatementString();
-	}
-
-	public boolean consumesEntityAlias() {
-		return true;
-	}
-	public boolean consumesCollectionAlias() {
-		return true;
-	}
-
-	public boolean isOneToMany() {
-		return true;
-	}
-
-	public boolean isManyToMany() {
-		return false;
-	}
-
-	protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
-			throws HibernateException {
-
-		// we finish all the "removes" first to take care of possible unique
-		// constraints and so that we can take better advantage of batching
-		
-		try {
-			int count = 0;
-			if ( isRowDeleteEnabled() ) {
-				boolean useBatch = true;
-				PreparedStatement st = null;
-				// update removed rows fks to null
-				try {
-					int i = 0;
-	
-					Iterator entries = collection.entries( this );
-					int offset = 1;
-					Expectation expectation = Expectations.NONE;
-					while ( entries.hasNext() ) {
-	
-						Object entry = entries.next();
-						if ( collection.needsUpdating( entry, i, elementType ) ) {  // will still be issued when it used to be null
-							if ( st == null ) {
-								String sql = getSQLDeleteRowString();
-								if ( isDeleteCallable() ) {
-									expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
-									useBatch = expectation.canBeBatched();
-									st = useBatch
-											? session.getBatcher().prepareBatchCallableStatement( sql )
-								            : session.getBatcher().prepareCallableStatement( sql );
-									offset += expectation.prepare( st );
-								}
-								else {
-									st = session.getBatcher().prepareBatchStatement( getSQLDeleteRowString() );
-								}
-							}
-							int loc = writeKey( st, id, offset, session );
-							writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
-							if ( useBatch ) {
-								session.getBatcher().addToBatch( expectation );
-							}
-							else {
-								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-							}
-							count++;
-						}
-						i++;
-					}
-				}
-				catch ( SQLException sqle ) {
-					if ( useBatch ) {
-						session.getBatcher().abortBatch( sqle );
-					}
-					throw sqle;
-				}
-				finally {
-					if ( !useBatch ) {
-						session.getBatcher().closeStatement( st );
-					}
-				}
-			}
-			
-			if ( isRowInsertEnabled() ) {
-				Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
-				boolean callable = isInsertCallable();
-				boolean useBatch = expectation.canBeBatched();
-				String sql = getSQLInsertRowString();
-				PreparedStatement st = null;
-				// now update all changed or added rows fks
-				try {
-					int i = 0;
-					Iterator entries = collection.entries( this );
-					while ( entries.hasNext() ) {
-						Object entry = entries.next();
-						int offset = 1;
-						if ( collection.needsUpdating( entry, i, elementType ) ) {
-							if ( useBatch ) {
-								if ( st == null ) {
-									if ( callable ) {
-										st = session.getBatcher().prepareBatchCallableStatement( sql );
-									}
-									else {
-										st = session.getBatcher().prepareBatchStatement( sql );
-									}
-								}
-							}
-							else {
-								if ( callable ) {
-									st = session.getBatcher().prepareCallableStatement( sql );
-								}
-								else {
-									st = session.getBatcher().prepareStatement( sql );
-								}
-							}
-
-							offset += expectation.prepare( st );
-
-							int loc = writeKey( st, id, offset, session );
-							if ( hasIndex && !indexContainsFormula ) {
-								loc = writeIndexToWhere( st, collection.getIndex( entry, i, this ), loc, session );
-							}
-
-							writeElementToWhere( st, collection.getElement( entry ), loc, session );
-
-							if ( useBatch ) {
-								session.getBatcher().addToBatch( expectation );
-							}
-							else {
-								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
-							}
-							count++;
-						}
-						i++;
-					}
-				}
-				catch ( SQLException sqle ) {
-					if ( useBatch ) {
-						session.getBatcher().abortBatch( sqle );
-					}
-					throw sqle;
-				}
-				finally {
-					if ( !useBatch ) {
-						session.getBatcher().closeStatement( st );
-					}
-				}
-			}
-
-			return count;
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getSQLExceptionConverter(),
-					sqle,
-					"could not update collection rows: " + 
-					MessageHelper.collectionInfoString( this, id, getFactory() ),
-					getSQLInsertRowString()
-			);
-		}
-	}
-
-	public String selectFragment(
-	        Joinable rhs,
-	        String rhsAlias,
-	        String lhsAlias,
-	        String entitySuffix,
-	        String collectionSuffix,
-	        boolean includeCollectionColumns) {
-		StringBuffer buf = new StringBuffer();
-		if ( includeCollectionColumns ) {
-//			buf.append( selectFragment( lhsAlias, "" ) )//ignore suffix for collection columns!
-			buf.append( selectFragment( lhsAlias, collectionSuffix ) )
-					.append( ", " );
-		}
-		OuterJoinLoadable ojl = ( OuterJoinLoadable ) getElementPersister();
-		return buf.append( ojl.selectFragment( lhsAlias, entitySuffix ) )//use suffix for the entity columns
-				.toString();
-	}
-
-	/**
-	 * Create the <tt>OneToManyLoader</tt>
-	 *
-	 * @see org.hibernate.loader.collection.OneToManyLoader
-	 */
-	protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters) throws MappingException {
-		return BatchingCollectionInitializer.createBatchingOneToManyInitializer( this, batchSize, getFactory(), enabledFilters );
-	}
-
-	public String fromJoinFragment(String alias,
-								   boolean innerJoin,
-								   boolean includeSubclasses) {
-		return ( ( Joinable ) getElementPersister() ).fromJoinFragment( alias, innerJoin, includeSubclasses );
-	}
-
-	public String whereJoinFragment(String alias,
-									boolean innerJoin,
-									boolean includeSubclasses) {
-		return ( ( Joinable ) getElementPersister() ).whereJoinFragment( alias, innerJoin, includeSubclasses );
-	}
-
-	public String getTableName() {
-		return ( ( Joinable ) getElementPersister() ).getTableName();
-	}
-
-	public String filterFragment(String alias) throws MappingException {
-		String result = super.filterFragment( alias );
-		if ( getElementPersister() instanceof Joinable ) {
-			result += ( ( Joinable ) getElementPersister() ).oneToManyFilterFragment( alias );
-		}
-		return result;
-
-	}
-
-	protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
-		return new SubselectOneToManyLoader( 
-				this,
-				subselect.toSubselectString( getCollectionType().getLHSPropertyName() ),
-				subselect.getResult(),
-				subselect.getQueryParameters(),
-				subselect.getNamedParameterLocMap(),
-				session.getFactory(),
-				session.getEnabledFilters() 
-			);
-	}
-
-	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
-		return new CollectionElementLoader( this, getFactory(), session.getEnabledFilters() )
-				.loadElement( session, key, incrementIndexByBase(index) );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/OneToManyPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,387 @@
+/*
+ * 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.persister.collection;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.cache.CacheException;
+import org.hibernate.cache.access.CollectionRegionAccessStrategy;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SubselectFetch;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.loader.collection.BatchingCollectionInitializer;
+import org.hibernate.loader.collection.CollectionInitializer;
+import org.hibernate.loader.collection.SubselectOneToManyLoader;
+import org.hibernate.loader.entity.CollectionElementLoader;
+import org.hibernate.mapping.Collection;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.OuterJoinLoadable;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.sql.Update;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Collection persister for one-to-many associations.
+ *
+ * @author Gavin King
+ */
+public class OneToManyPersister extends AbstractCollectionPersister {
+
+	private final boolean cascadeDeleteEnabled;
+	private final boolean keyIsNullable;
+	private final boolean keyIsUpdateable;
+
+	protected boolean isRowDeleteEnabled() {
+		return keyIsUpdateable && keyIsNullable;
+	}
+
+	protected boolean isRowInsertEnabled() {
+		return keyIsUpdateable;
+	}
+
+	public boolean isCascadeDeleteEnabled() {
+		return cascadeDeleteEnabled;
+	}
+
+	public OneToManyPersister(
+			Collection collection,
+			CollectionRegionAccessStrategy cacheAccessStrategy,
+			Configuration cfg,
+			SessionFactoryImplementor factory) throws MappingException, CacheException {
+		super( collection, cacheAccessStrategy, cfg, factory );
+		cascadeDeleteEnabled = collection.getKey().isCascadeDeleteEnabled() &&
+				factory.getDialect().supportsCascadeDelete();
+		keyIsNullable = collection.getKey().isNullable();
+		keyIsUpdateable = collection.getKey().isUpdateable();
+	}
+
+	/**
+	 * Generate the SQL UPDATE that updates all the foreign keys to null
+	 */
+	protected String generateDeleteString() {
+		
+		Update update = new Update( getDialect() )
+				.setTableName( qualifiedTableName )
+				.addColumns( keyColumnNames, "null" )
+				.setPrimaryKeyColumnNames( keyColumnNames );
+		
+		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames, "null" );
+		
+		if ( hasWhere ) update.setWhere( sqlWhereString );
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "delete one-to-many " + getRole() );
+		}
+		
+		return update.toStatementString();
+	}
+
+	/**
+	 * Generate the SQL UPDATE that updates a foreign key to a value
+	 */
+	protected String generateInsertRowString() {
+		
+		Update update = new Update( getDialect() )
+				.setTableName( qualifiedTableName )
+				.addColumns( keyColumnNames );
+		
+		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames );
+		
+		//identifier collections not supported for 1-to-many
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "create one-to-many row " + getRole() );
+		}
+		
+		return update.setPrimaryKeyColumnNames( elementColumnNames )
+				.toStatementString();
+	}
+
+	/**
+	 * Not needed for one-to-many association
+	 */
+	protected String generateUpdateRowString() {
+		return null;
+	}
+
+	/**
+	 * Generate the SQL UPDATE that updates a particular row's foreign
+	 * key to null
+	 */
+	protected String generateDeleteRowString() {
+		
+		Update update = new Update( getDialect() )
+				.setTableName( qualifiedTableName )
+				.addColumns( keyColumnNames, "null" );
+		
+		if ( hasIndex && !indexContainsFormula ) update.addColumns( indexColumnNames, "null" );
+		
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "delete one-to-many row " + getRole() );
+		}
+		
+		//use a combination of foreign key columns and pk columns, since
+		//the ordering of removal and addition is not guaranteed when
+		//a child moves from one parent to another
+		String[] rowSelectColumnNames = ArrayHelper.join(keyColumnNames, elementColumnNames);
+		return update.setPrimaryKeyColumnNames( rowSelectColumnNames )
+				.toStatementString();
+	}
+
+	public boolean consumesEntityAlias() {
+		return true;
+	}
+	public boolean consumesCollectionAlias() {
+		return true;
+	}
+
+	public boolean isOneToMany() {
+		return true;
+	}
+
+	public boolean isManyToMany() {
+		return false;
+	}
+
+	protected int doUpdateRows(Serializable id, PersistentCollection collection, SessionImplementor session)
+			throws HibernateException {
+
+		// we finish all the "removes" first to take care of possible unique
+		// constraints and so that we can take better advantage of batching
+		
+		try {
+			int count = 0;
+			if ( isRowDeleteEnabled() ) {
+				boolean useBatch = true;
+				PreparedStatement st = null;
+				// update removed rows fks to null
+				try {
+					int i = 0;
+	
+					Iterator entries = collection.entries( this );
+					int offset = 1;
+					Expectation expectation = Expectations.NONE;
+					while ( entries.hasNext() ) {
+	
+						Object entry = entries.next();
+						if ( collection.needsUpdating( entry, i, elementType ) ) {  // will still be issued when it used to be null
+							if ( st == null ) {
+								String sql = getSQLDeleteRowString();
+								if ( isDeleteCallable() ) {
+									expectation = Expectations.appropriateExpectation( getDeleteCheckStyle() );
+									useBatch = expectation.canBeBatched();
+									st = useBatch
+											? session.getBatcher().prepareBatchCallableStatement( sql )
+								            : session.getBatcher().prepareCallableStatement( sql );
+									offset += expectation.prepare( st );
+								}
+								else {
+									st = session.getBatcher().prepareBatchStatement( getSQLDeleteRowString() );
+								}
+							}
+							int loc = writeKey( st, id, offset, session );
+							writeElementToWhere( st, collection.getSnapshotElement(entry, i), loc, session );
+							if ( useBatch ) {
+								session.getBatcher().addToBatch( expectation );
+							}
+							else {
+								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+							}
+							count++;
+						}
+						i++;
+					}
+				}
+				catch ( SQLException sqle ) {
+					if ( useBatch ) {
+						session.getBatcher().abortBatch( sqle );
+					}
+					throw sqle;
+				}
+				finally {
+					if ( !useBatch ) {
+						session.getBatcher().closeStatement( st );
+					}
+				}
+			}
+			
+			if ( isRowInsertEnabled() ) {
+				Expectation expectation = Expectations.appropriateExpectation( getInsertCheckStyle() );
+				boolean callable = isInsertCallable();
+				boolean useBatch = expectation.canBeBatched();
+				String sql = getSQLInsertRowString();
+				PreparedStatement st = null;
+				// now update all changed or added rows fks
+				try {
+					int i = 0;
+					Iterator entries = collection.entries( this );
+					while ( entries.hasNext() ) {
+						Object entry = entries.next();
+						int offset = 1;
+						if ( collection.needsUpdating( entry, i, elementType ) ) {
+							if ( useBatch ) {
+								if ( st == null ) {
+									if ( callable ) {
+										st = session.getBatcher().prepareBatchCallableStatement( sql );
+									}
+									else {
+										st = session.getBatcher().prepareBatchStatement( sql );
+									}
+								}
+							}
+							else {
+								if ( callable ) {
+									st = session.getBatcher().prepareCallableStatement( sql );
+								}
+								else {
+									st = session.getBatcher().prepareStatement( sql );
+								}
+							}
+
+							offset += expectation.prepare( st );
+
+							int loc = writeKey( st, id, offset, session );
+							if ( hasIndex && !indexContainsFormula ) {
+								loc = writeIndexToWhere( st, collection.getIndex( entry, i, this ), loc, session );
+							}
+
+							writeElementToWhere( st, collection.getElement( entry ), loc, session );
+
+							if ( useBatch ) {
+								session.getBatcher().addToBatch( expectation );
+							}
+							else {
+								expectation.verifyOutcome( st.executeUpdate(), st, -1 );
+							}
+							count++;
+						}
+						i++;
+					}
+				}
+				catch ( SQLException sqle ) {
+					if ( useBatch ) {
+						session.getBatcher().abortBatch( sqle );
+					}
+					throw sqle;
+				}
+				finally {
+					if ( !useBatch ) {
+						session.getBatcher().closeStatement( st );
+					}
+				}
+			}
+
+			return count;
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getSQLExceptionConverter(),
+					sqle,
+					"could not update collection rows: " + 
+					MessageHelper.collectionInfoString( this, id, getFactory() ),
+					getSQLInsertRowString()
+			);
+		}
+	}
+
+	public String selectFragment(
+	        Joinable rhs,
+	        String rhsAlias,
+	        String lhsAlias,
+	        String entitySuffix,
+	        String collectionSuffix,
+	        boolean includeCollectionColumns) {
+		StringBuffer buf = new StringBuffer();
+		if ( includeCollectionColumns ) {
+//			buf.append( selectFragment( lhsAlias, "" ) )//ignore suffix for collection columns!
+			buf.append( selectFragment( lhsAlias, collectionSuffix ) )
+					.append( ", " );
+		}
+		OuterJoinLoadable ojl = ( OuterJoinLoadable ) getElementPersister();
+		return buf.append( ojl.selectFragment( lhsAlias, entitySuffix ) )//use suffix for the entity columns
+				.toString();
+	}
+
+	/**
+	 * Create the <tt>OneToManyLoader</tt>
+	 *
+	 * @see org.hibernate.loader.collection.OneToManyLoader
+	 */
+	protected CollectionInitializer createCollectionInitializer(java.util.Map enabledFilters) throws MappingException {
+		return BatchingCollectionInitializer.createBatchingOneToManyInitializer( this, batchSize, getFactory(), enabledFilters );
+	}
+
+	public String fromJoinFragment(String alias,
+								   boolean innerJoin,
+								   boolean includeSubclasses) {
+		return ( ( Joinable ) getElementPersister() ).fromJoinFragment( alias, innerJoin, includeSubclasses );
+	}
+
+	public String whereJoinFragment(String alias,
+									boolean innerJoin,
+									boolean includeSubclasses) {
+		return ( ( Joinable ) getElementPersister() ).whereJoinFragment( alias, innerJoin, includeSubclasses );
+	}
+
+	public String getTableName() {
+		return ( ( Joinable ) getElementPersister() ).getTableName();
+	}
+
+	public String filterFragment(String alias) throws MappingException {
+		String result = super.filterFragment( alias );
+		if ( getElementPersister() instanceof Joinable ) {
+			result += ( ( Joinable ) getElementPersister() ).oneToManyFilterFragment( alias );
+		}
+		return result;
+
+	}
+
+	protected CollectionInitializer createSubselectInitializer(SubselectFetch subselect, SessionImplementor session) {
+		return new SubselectOneToManyLoader( 
+				this,
+				subselect.toSubselectString( getCollectionType().getLHSPropertyName() ),
+				subselect.getResult(),
+				subselect.getQueryParameters(),
+				subselect.getNamedParameterLocMap(),
+				session.getFactory(),
+				session.getEnabledFilters() 
+			);
+	}
+
+	public Object getElementByIndex(Serializable key, Object index, SessionImplementor session, Object owner) {
+		return new CollectionElementLoader( this, getFactory(), session.getEnabledFilters() )
+				.loadElement( session, key, incrementIndexByBase(index) );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-//$Id: QueryableCollection.java 9875 2006-05-04 16:23:44Z steve.ebersole at jboss.com $
-package org.hibernate.persister.collection;
-
-import org.hibernate.FetchMode;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.PropertyMapping;
-
-/**
- * A collection role that may be queried or loaded by outer join.
- * @author Gavin King
- */
-public interface QueryableCollection extends PropertyMapping, Joinable, CollectionPersister {
-	/**
-	 * Generate a list of collection index and element columns
-	 */
-	public abstract String selectFragment(String alias, String columnSuffix);
-	/**
-	 * Get the names of the collection index columns if
-	 * this is an indexed collection (optional operation)
-	 */
-	public abstract String[] getIndexColumnNames();
-	/**
-	 * Get the index formulas if this is an indexed collection 
-	 * (optional operation)
-	 */
-	public abstract String[] getIndexFormulas();
-	/**
-	 * Get the names of the collection index columns if
-	 * this is an indexed collection (optional operation),
-	 * aliased by the given table alias
-	 */
-	public abstract String[] getIndexColumnNames(String alias);
-	/**
-	 * Get the names of the collection element columns (or the primary
-	 * key columns in the case of a one-to-many association),
-	 * aliased by the given table alias
-	 */
-	public abstract String[] getElementColumnNames(String alias);
-	/**
-	 * Get the names of the collection element columns (or the primary
-	 * key columns in the case of a one-to-many association)
-	 */
-	public abstract String[] getElementColumnNames();
-	/**
-	 * Get the order by SQL
-	 */
-	public abstract String getSQLOrderByString(String alias);
-
-	/**
-	 * Get the order-by to be applied at the target table of a many to many
-	 *
-	 * @param alias The alias for the many-to-many target table
-	 * @return appropriate order-by fragment or empty string.
-	 */
-	public abstract String getManyToManyOrderByString(String alias);
-
-	/**
-	 * Does this collection role have a where clause filter?
-	 */
-	public abstract boolean hasWhere();
-	/**
-	 * Get the persister of the element class, if this is a
-	 * collection of entities (optional operation).  Note that
-	 * for a one-to-many association, the returned persister
-	 * must be <tt>OuterJoinLoadable</tt>.
-	 */
-	public abstract EntityPersister getElementPersister();
-	/**
-	 * Should we load this collection role by outerjoining?
-	 */
-	public abstract FetchMode getFetchMode();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/QueryableCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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.persister.collection;
+
+import org.hibernate.FetchMode;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.PropertyMapping;
+
+/**
+ * A collection role that may be queried or loaded by outer join.
+ * @author Gavin King
+ */
+public interface QueryableCollection extends PropertyMapping, Joinable, CollectionPersister {
+	/**
+	 * Generate a list of collection index and element columns
+	 */
+	public abstract String selectFragment(String alias, String columnSuffix);
+	/**
+	 * Get the names of the collection index columns if
+	 * this is an indexed collection (optional operation)
+	 */
+	public abstract String[] getIndexColumnNames();
+	/**
+	 * Get the index formulas if this is an indexed collection 
+	 * (optional operation)
+	 */
+	public abstract String[] getIndexFormulas();
+	/**
+	 * Get the names of the collection index columns if
+	 * this is an indexed collection (optional operation),
+	 * aliased by the given table alias
+	 */
+	public abstract String[] getIndexColumnNames(String alias);
+	/**
+	 * Get the names of the collection element columns (or the primary
+	 * key columns in the case of a one-to-many association),
+	 * aliased by the given table alias
+	 */
+	public abstract String[] getElementColumnNames(String alias);
+	/**
+	 * Get the names of the collection element columns (or the primary
+	 * key columns in the case of a one-to-many association)
+	 */
+	public abstract String[] getElementColumnNames();
+	/**
+	 * Get the order by SQL
+	 */
+	public abstract String getSQLOrderByString(String alias);
+
+	/**
+	 * Get the order-by to be applied at the target table of a many to many
+	 *
+	 * @param alias The alias for the many-to-many target table
+	 * @return appropriate order-by fragment or empty string.
+	 */
+	public abstract String getManyToManyOrderByString(String alias);
+
+	/**
+	 * Does this collection role have a where clause filter?
+	 */
+	public abstract boolean hasWhere();
+	/**
+	 * Get the persister of the element class, if this is a
+	 * collection of entities (optional operation).  Note that
+	 * for a one-to-many association, the returned persister
+	 * must be <tt>OuterJoinLoadable</tt>.
+	 */
+	public abstract EntityPersister getElementPersister();
+	/**
+	 * Should we load this collection role by outerjoining?
+	 */
+	public abstract FetchMode getFetchMode();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-package org.hibernate.persister.collection;
-
-public interface SQLLoadableCollection extends QueryableCollection {
-
-	public abstract String[] getCollectionPropertyColumnAliases(String propertyName, String string);
-	
-	public abstract String getIdentifierColumnName();
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/SQLLoadableCollection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+/*
+ * 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.persister.collection;
+
+public interface SQLLoadableCollection extends QueryableCollection {
+
+	public abstract String[] getCollectionPropertyColumnAliases(String propertyName, String string);
+	
+	public abstract String getIdentifierColumnName();
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/collection/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the persistence mechanism for collections.
-</p>
-<p>
-	Concrete implementations of <tt>CollectionPersister</tt>
-	define strategies for persistence of particular collection
-	roles. Collection persisters may optionally implement 
-	<tt>QueryableCollection</tt> if they should be queryable
-	using HQL or loaded using <tt>OuterJoinLoader</tt>.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/collection/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/collection/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the persistence mechanism for collections.
+</p>
+<p>
+	Concrete implementations of <tt>CollectionPersister</tt>
+	define strategies for persistence of particular collection
+	roles. Collection persisters may optionally implement 
+	<tt>QueryableCollection</tt> if they should be queryable
+	using HQL or loaded using <tt>OuterJoinLoader</tt>.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,3850 +0,0 @@
-//$Id: AbstractEntityPersister.java 11527 2007-05-15 20:16:50Z epbernard $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.Comparator;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.StaleStateException;
-import org.hibernate.jdbc.Expectation;
-import org.hibernate.jdbc.Expectations;
-import org.hibernate.jdbc.TooManyRowsAffectedException;
-import org.hibernate.dialect.lock.LockingStrategy;
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.entry.CacheEntry;
-import org.hibernate.cache.entry.CacheEntryStructure;
-import org.hibernate.cache.entry.StructuredCacheEntry;
-import org.hibernate.cache.entry.UnstructuredCacheEntry;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.CascadingAction;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.Versioning;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.ValueInclusion;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.PostInsertIdentifierGenerator;
-import org.hibernate.id.PostInsertIdentityPersister;
-import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
-import org.hibernate.id.insert.Binder;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.loader.entity.BatchingEntityLoader;
-import org.hibernate.loader.entity.CascadeEntityLoader;
-import org.hibernate.loader.entity.EntityLoader;
-import org.hibernate.loader.entity.UniqueEntityLoader;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.pretty.MessageHelper;
-import org.hibernate.property.BackrefPropertyAccessor;
-import org.hibernate.sql.Alias;
-import org.hibernate.sql.Delete;
-import org.hibernate.sql.Insert;
-import org.hibernate.sql.JoinFragment;
-import org.hibernate.sql.Select;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.sql.SimpleSelect;
-import org.hibernate.sql.Template;
-import org.hibernate.sql.Update;
-import org.hibernate.tuple.entity.EntityMetamodel;
-import org.hibernate.tuple.entity.EntityTuplizer;
-import org.hibernate.tuple.Tuplizer;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.type.VersionType;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.CollectionHelper;
-import org.hibernate.util.FilterHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Basic functionality for persisting an entity via JDBC
- * through either generated or custom SQL
- *
- * @author Gavin King
- */
-public abstract class AbstractEntityPersister
-		implements OuterJoinLoadable, Queryable, ClassMetadata, UniqueKeyLoadable,
-		SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister, Lockable {
-
-	private static final Logger log = LoggerFactory.getLogger( AbstractEntityPersister.class );
-
-	public static final String ENTITY_CLASS = "class";
-
-	// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	private final SessionFactoryImplementor factory;
-	private final EntityRegionAccessStrategy cacheAccessStrategy;
-	private final boolean isLazyPropertiesCacheable;
-	private final CacheEntryStructure cacheEntryStructure;
-	private final EntityMetamodel entityMetamodel;
-	private final Map entityNameBySubclass = new HashMap();
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	private final String[] rootTableKeyColumnNames;
-	private final String[] identifierAliases;
-	private final int identifierColumnSpan;
-	private final String versionColumnName;
-	private final boolean hasFormulaProperties;
-	private final int batchSize;
-	private final boolean hasSubselectLoadableCollections;
-	protected final String rowIdName;
-
-	private final Set lazyProperties;
-
-	// The optional SQL string defined in the where attribute
-	private final String sqlWhereString;
-	private final String sqlWhereStringTemplate;
-
-	//information about properties of this class,
-	//including inherited properties
-	//(only really needed for updatable/insertable properties)
-	private final int[] propertyColumnSpans;
-	private final String[] propertySubclassNames;
-	private final String[][] propertyColumnAliases;
-	private final String[][] propertyColumnNames;
-	private final String[][] propertyColumnFormulaTemplates;
-	private final boolean[][] propertyColumnUpdateable;
-	private final boolean[][] propertyColumnInsertable;
-	private final boolean[] propertyUniqueness;
-	private final boolean[] propertySelectable;
-
-	//information about lazy properties of this class
-	private final String[] lazyPropertyNames;
-	private final int[] lazyPropertyNumbers;
-	private final Type[] lazyPropertyTypes;
-	private final String[][] lazyPropertyColumnAliases;
-
-	//information about all properties in class hierarchy
-	private final String[] subclassPropertyNameClosure;
-	private final String[] subclassPropertySubclassNameClosure;
-	private final Type[] subclassPropertyTypeClosure;
-	private final String[][] subclassPropertyFormulaTemplateClosure;
-	private final String[][] subclassPropertyColumnNameClosure;
-	private final FetchMode[] subclassPropertyFetchModeClosure;
-	private final boolean[] subclassPropertyNullabilityClosure;
-	private final boolean[] propertyDefinedOnSubclass;
-	private final int[][] subclassPropertyColumnNumberClosure;
-	private final int[][] subclassPropertyFormulaNumberClosure;
-	private final CascadeStyle[] subclassPropertyCascadeStyleClosure;
-
-	//information about all columns/formulas in class hierarchy
-	private final String[] subclassColumnClosure;
-	private final boolean[] subclassColumnLazyClosure;
-	private final String[] subclassColumnAliasClosure;
-	private final boolean[] subclassColumnSelectableClosure;
-	private final String[] subclassFormulaClosure;
-	private final String[] subclassFormulaTemplateClosure;
-	private final String[] subclassFormulaAliasClosure;
-	private final boolean[] subclassFormulaLazyClosure;
-
-	// dynamic filters attached to the class-level
-	private final FilterHelper filterHelper;
-
-	private final Map uniqueKeyLoaders = new HashMap();
-	private final Map lockers = new HashMap();
-	private final Map loaders = new HashMap();
-
-	// SQL strings
-	private String sqlVersionSelectString;
-	private String sqlSnapshotSelectString;
-	private String sqlLazySelectString;
-
-	private String sqlIdentityInsertString;
-	private String sqlUpdateByRowIdString;
-	private String sqlLazyUpdateByRowIdString;
-
-	private String[] sqlDeleteStrings;
-	private String[] sqlInsertStrings;
-	private String[] sqlUpdateStrings;
-	private String[] sqlLazyUpdateStrings;
-
-	private String sqlInsertGeneratedValuesSelectString;
-	private String sqlUpdateGeneratedValuesSelectString;
-
-	//Custom SQL (would be better if these were private)
-	protected boolean[] insertCallable;
-	protected boolean[] updateCallable;
-	protected boolean[] deleteCallable;
-	protected String[] customSQLInsert;
-	protected String[] customSQLUpdate;
-	protected String[] customSQLDelete;
-	protected ExecuteUpdateResultCheckStyle[] insertResultCheckStyles;
-	protected ExecuteUpdateResultCheckStyle[] updateResultCheckStyles;
-	protected ExecuteUpdateResultCheckStyle[] deleteResultCheckStyles;
-
-	private InsertGeneratedIdentifierDelegate identityDelegate;
-
-	private boolean[] tableHasColumns;
-
-	private final String loaderName;
-
-	private UniqueEntityLoader queryLoader;
-
-	private final String temporaryIdTableName;
-	private final String temporaryIdTableDDL;
-
-	private final Map subclassPropertyAliases = new HashMap();
-	private final Map subclassPropertyColumnNames = new HashMap();
-
-	protected final BasicEntityPropertyMapping propertyMapping;
-
-	protected void addDiscriminatorToInsert(Insert insert) {}
-
-	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {}
-
-	protected abstract int[] getSubclassColumnTableNumberClosure();
-
-	protected abstract int[] getSubclassFormulaTableNumberClosure();
-
-	public abstract String getSubclassTableName(int j);
-
-	protected abstract String[] getSubclassTableKeyColumns(int j);
-
-	protected abstract boolean isClassOrSuperclassTable(int j);
-
-	protected abstract int getSubclassTableSpan();
-
-	protected abstract int getTableSpan();
-
-	protected abstract boolean isTableCascadeDeleteEnabled(int j);
-
-	protected abstract String getTableName(int j);
-
-	protected abstract String[] getKeyColumns(int j);
-
-	protected abstract boolean isPropertyOfTable(int property, int j);
-
-	protected abstract int[] getPropertyTableNumbersInSelect();
-
-	protected abstract int[] getPropertyTableNumbers();
-
-	protected abstract int getSubclassPropertyTableNumber(int i);
-
-	protected abstract String filterFragment(String alias) throws MappingException;
-
-	private static final String DISCRIMINATOR_ALIAS = "clazz_";
-
-	public String getDiscriminatorColumnName() {
-		return DISCRIMINATOR_ALIAS;
-	}
-
-	protected String getDiscriminatorAlias() {
-		return DISCRIMINATOR_ALIAS;
-	}
-
-	protected String getDiscriminatorFormulaTemplate() {
-		return null;
-	}
-
-	protected boolean isInverseTable(int j) {
-		return false;
-	}
-
-	protected boolean isNullableTable(int j) {
-		return false;
-	}
-
-	protected boolean isNullableSubclassTable(int j) {
-		return false;
-	}
-
-	protected boolean isInverseSubclassTable(int j) {
-		return false;
-	}
-
-	public boolean isSubclassEntityName(String entityName) {
-		return entityMetamodel.getSubclassEntityNames().contains(entityName);
-	}
-
-	private boolean[] getTableHasColumns() {
-		return tableHasColumns;
-	}
-
-	public String[] getRootTableKeyColumnNames() {
-		return rootTableKeyColumnNames;
-	}
-
-	protected String[] getSQLUpdateByRowIdStrings() {
-		if ( sqlUpdateByRowIdString == null ) {
-			throw new AssertionFailure( "no update by row id" );
-		}
-		String[] result = new String[getTableSpan() + 1];
-		result[0] = sqlUpdateByRowIdString;
-		System.arraycopy( sqlUpdateStrings, 0, result, 1, getTableSpan() );
-		return result;
-	}
-
-	protected String[] getSQLLazyUpdateByRowIdStrings() {
-		if ( sqlLazyUpdateByRowIdString == null ) {
-			throw new AssertionFailure( "no update by row id" );
-		}
-		String[] result = new String[getTableSpan()];
-		result[0] = sqlLazyUpdateByRowIdString;
-		for ( int i = 1; i < getTableSpan(); i++ ) {
-			result[i] = sqlLazyUpdateStrings[i];
-		}
-		return result;
-	}
-
-	protected String getSQLSnapshotSelectString() {
-		return sqlSnapshotSelectString;
-	}
-
-	protected String getSQLLazySelectString() {
-		return sqlLazySelectString;
-	}
-
-	protected String[] getSQLDeleteStrings() {
-		return sqlDeleteStrings;
-	}
-
-	protected String[] getSQLInsertStrings() {
-		return sqlInsertStrings;
-	}
-
-	protected String[] getSQLUpdateStrings() {
-		return sqlUpdateStrings;
-	}
-
-	protected String[] getSQLLazyUpdateStrings() {
-		return sqlLazyUpdateStrings;
-	}
-
-	/**
-	 * The query that inserts a row, letting the database generate an id
-	 * 
-	 * @return The IDENTITY-based insertion query.
-	 */
-	protected String getSQLIdentityInsertString() {
-		return sqlIdentityInsertString;
-	}
-
-	protected String getVersionSelectString() {
-		return sqlVersionSelectString;
-	}
-
-	protected boolean isInsertCallable(int j) {
-		return insertCallable[j];
-	}
-
-	protected boolean isUpdateCallable(int j) {
-		return updateCallable[j];
-	}
-
-	protected boolean isDeleteCallable(int j) {
-		return deleteCallable[j];
-	}
-
-	protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) {
-		return false;
-	}
-
-	protected boolean isSubclassTableSequentialSelect(int j) {
-		return false;
-	}
-
-	public boolean hasSequentialSelect() {
-		return false;
-	}
-
-	/**
-	 * Decide which tables need to be updated.
-	 * <p/>
-	 * The return here is an array of boolean values with each index corresponding
-	 * to a given table in the scope of this persister.
-	 *
-	 * @param dirtyProperties The indices of all the entity properties considered dirty.
-	 * @param hasDirtyCollection Whether any collections owned by the entity which were considered dirty.
-	 *
-	 * @return Array of booleans indicating which table require updating.
-	 */
-	protected boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) {
-
-		if ( dirtyProperties == null ) {
-			return getTableHasColumns(); // for objects that came in via update()
-		}
-		else {
-			boolean[] updateability = getPropertyUpdateability();
-			int[] propertyTableNumbers = getPropertyTableNumbers();
-			boolean[] tableUpdateNeeded = new boolean[ getTableSpan() ];
-			for ( int i = 0; i < dirtyProperties.length; i++ ) {
-				int property = dirtyProperties[i];
-				int table = propertyTableNumbers[property];
-				tableUpdateNeeded[table] = tableUpdateNeeded[table] ||
-						( getPropertyColumnSpan(property) > 0 && updateability[property] );
-			}
-			if ( isVersioned() ) {
-				tableUpdateNeeded[0] = tableUpdateNeeded[0] ||
-					Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() );
-			}
-			return tableUpdateNeeded;
-		}
-	}
-
-	public boolean hasRowId() {
-		return rowIdName != null;
-	}
-
-	public AbstractEntityPersister(
-			final PersistentClass persistentClass,
-			final EntityRegionAccessStrategy cacheAccessStrategy,
-			final SessionFactoryImplementor factory) throws HibernateException {
-
-		// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		this.factory = factory;
-		this.cacheAccessStrategy = cacheAccessStrategy;
-		isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
-		this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ?
-				(CacheEntryStructure) new StructuredCacheEntry(this) :
-				(CacheEntryStructure) new UnstructuredCacheEntry();
-
-		this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
-
-		if ( persistentClass.hasPojoRepresentation() ) {
-			//TODO: this is currently specific to pojos, but need to be available for all entity-modes
-			Iterator iter = persistentClass.getSubclassIterator();
-			while ( iter.hasNext() ) {
-				PersistentClass pc = ( PersistentClass ) iter.next();
-				entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() );
-			}
-		}
-		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-		int batch = persistentClass.getBatchSize();
-		if ( batch == -1 ) {
-			batch = factory.getSettings().getDefaultBatchFetchSize();
-		}
-		batchSize = batch;
-		hasSubselectLoadableCollections = persistentClass.hasSubselectLoadableCollections();
-
-		propertyMapping = new BasicEntityPropertyMapping( this );
-
-		// IDENTIFIER
-
-		identifierColumnSpan = persistentClass.getIdentifier().getColumnSpan();
-		rootTableKeyColumnNames = new String[identifierColumnSpan];
-		identifierAliases = new String[identifierColumnSpan];
-
-		rowIdName = persistentClass.getRootTable().getRowId();
-
-		loaderName = persistentClass.getLoaderName();
-
-		Iterator iter = persistentClass.getIdentifier().getColumnIterator();
-		int i = 0;
-		while ( iter.hasNext() ) {
-			Column col = ( Column ) iter.next();
-			rootTableKeyColumnNames[i] = col.getQuotedName( factory.getDialect() );
-			identifierAliases[i] = col.getAlias( factory.getDialect(), persistentClass.getRootTable() );
-			i++;
-		}
-
-		// VERSION
-
-		if ( persistentClass.isVersioned() ) {
-			versionColumnName = ( ( Column ) persistentClass.getVersion().getColumnIterator().next() ).getQuotedName( factory.getDialect() );
-		}
-		else {
-			versionColumnName = null;
-		}
-
-		//WHERE STRING
-
-		sqlWhereString = StringHelper.isNotEmpty( persistentClass.getWhere() ) ? "( " + persistentClass.getWhere() + ") " : null;
-		sqlWhereStringTemplate = sqlWhereString == null ?
-				null :
-				Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
-
-		// PROPERTIES
-
-		final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
-
-		int hydrateSpan = entityMetamodel.getPropertySpan();
-		propertyColumnSpans = new int[hydrateSpan];
-		propertySubclassNames = new String[hydrateSpan];
-		propertyColumnAliases = new String[hydrateSpan][];
-		propertyColumnNames = new String[hydrateSpan][];
-		propertyColumnFormulaTemplates = new String[hydrateSpan][];
-		propertyUniqueness = new boolean[hydrateSpan];
-		propertySelectable = new boolean[hydrateSpan];
-		propertyColumnUpdateable = new boolean[hydrateSpan][];
-		propertyColumnInsertable = new boolean[hydrateSpan][];
-		HashSet thisClassProperties = new HashSet();
-
-		lazyProperties = new HashSet();
-		ArrayList lazyNames = new ArrayList();
-		ArrayList lazyNumbers = new ArrayList();
-		ArrayList lazyTypes = new ArrayList();
-		ArrayList lazyColAliases = new ArrayList();
-
-		iter = persistentClass.getPropertyClosureIterator();
-		i = 0;
-		boolean foundFormula = false;
-		while ( iter.hasNext() ) {
-			Property prop = ( Property ) iter.next();
-			thisClassProperties.add( prop );
-
-			int span = prop.getColumnSpan();
-			propertyColumnSpans[i] = span;
-			propertySubclassNames[i] = prop.getPersistentClass().getEntityName();
-			String[] colNames = new String[span];
-			String[] colAliases = new String[span];
-			String[] templates = new String[span];
-			Iterator colIter = prop.getColumnIterator();
-			int k = 0;
-			while ( colIter.hasNext() ) {
-				Selectable thing = ( Selectable ) colIter.next();
-				colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() );
-				if ( thing.isFormula() ) {
-					foundFormula = true;
-					templates[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
-				}
-				else {
-					colNames[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
-				}
-				k++;
-			}
-			propertyColumnNames[i] = colNames;
-			propertyColumnFormulaTemplates[i] = templates;
-			propertyColumnAliases[i] = colAliases;
-
-			if ( lazyAvailable && prop.isLazy() ) {
-				lazyProperties.add( prop.getName() );
-				lazyNames.add( prop.getName() );
-				lazyNumbers.add( new Integer( i ) );
-				lazyTypes.add( prop.getValue().getType() );
-				lazyColAliases.add( colAliases );
-			}
-
-			propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability();
-			propertyColumnInsertable[i] = prop.getValue().getColumnInsertability();
-
-			propertySelectable[i] = prop.isSelectable();
-
-			propertyUniqueness[i] = prop.getValue().isAlternateUniqueKey();
-
-			i++;
-
-		}
-		hasFormulaProperties = foundFormula;
-		lazyPropertyColumnAliases = ArrayHelper.to2DStringArray( lazyColAliases );
-		lazyPropertyNames = ArrayHelper.toStringArray( lazyNames );
-		lazyPropertyNumbers = ArrayHelper.toIntArray( lazyNumbers );
-		lazyPropertyTypes = ArrayHelper.toTypeArray( lazyTypes );
-
-		// SUBCLASS PROPERTY CLOSURE
-
-		ArrayList columns = new ArrayList();
-		ArrayList columnsLazy = new ArrayList();
-		ArrayList aliases = new ArrayList();
-		ArrayList formulas = new ArrayList();
-		ArrayList formulaAliases = new ArrayList();
-		ArrayList formulaTemplates = new ArrayList();
-		ArrayList formulasLazy = new ArrayList();
-		ArrayList types = new ArrayList();
-		ArrayList names = new ArrayList();
-		ArrayList classes = new ArrayList();
-		ArrayList templates = new ArrayList();
-		ArrayList propColumns = new ArrayList();
-		ArrayList joinedFetchesList = new ArrayList();
-		ArrayList cascades = new ArrayList();
-		ArrayList definedBySubclass = new ArrayList();
-		ArrayList propColumnNumbers = new ArrayList();
-		ArrayList propFormulaNumbers = new ArrayList();
-		ArrayList columnSelectables = new ArrayList();
-		ArrayList propNullables = new ArrayList();
-
-		iter = persistentClass.getSubclassPropertyClosureIterator();
-		while ( iter.hasNext() ) {
-			Property prop = ( Property ) iter.next();
-			names.add( prop.getName() );
-			classes.add( prop.getPersistentClass().getEntityName() );
-			boolean isDefinedBySubclass = !thisClassProperties.contains( prop );
-			definedBySubclass.add( Boolean.valueOf( isDefinedBySubclass ) );
-			propNullables.add( Boolean.valueOf( prop.isOptional() || isDefinedBySubclass ) ); //TODO: is this completely correct?
-			types.add( prop.getType() );
-
-			Iterator colIter = prop.getColumnIterator();
-			String[] cols = new String[prop.getColumnSpan()];
-			String[] forms = new String[prop.getColumnSpan()];
-			int[] colnos = new int[prop.getColumnSpan()];
-			int[] formnos = new int[prop.getColumnSpan()];
-			int l = 0;
-			Boolean lazy = Boolean.valueOf( prop.isLazy() && lazyAvailable );
-			while ( colIter.hasNext() ) {
-				Selectable thing = ( Selectable ) colIter.next();
-				if ( thing.isFormula() ) {
-					String template = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
-					formnos[l] = formulaTemplates.size();
-					colnos[l] = -1;
-					formulaTemplates.add( template );
-					forms[l] = template;
-					formulas.add( thing.getText( factory.getDialect() ) );
-					formulaAliases.add( thing.getAlias( factory.getDialect() ) );
-					formulasLazy.add( lazy );
-				}
-				else {
-					String colName = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
-					colnos[l] = columns.size(); //before add :-)
-					formnos[l] = -1;
-					columns.add( colName );
-					cols[l] = colName;
-					aliases.add( thing.getAlias( factory.getDialect(), prop.getValue().getTable() ) );
-					columnsLazy.add( lazy );
-					columnSelectables.add( Boolean.valueOf( prop.isSelectable() ) );
-				}
-				l++;
-			}
-			propColumns.add( cols );
-			templates.add( forms );
-			propColumnNumbers.add( colnos );
-			propFormulaNumbers.add( formnos );
-
-			joinedFetchesList.add( prop.getValue().getFetchMode() );
-			cascades.add( prop.getCascadeStyle() );
-		}
-		subclassColumnClosure = ArrayHelper.toStringArray( columns );
-		subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases );
-		subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy );
-		subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables );
-
-		subclassFormulaClosure = ArrayHelper.toStringArray( formulas );
-		subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates );
-		subclassFormulaAliasClosure = ArrayHelper.toStringArray( formulaAliases );
-		subclassFormulaLazyClosure = ArrayHelper.toBooleanArray( formulasLazy );
-
-		subclassPropertyNameClosure = ArrayHelper.toStringArray( names );
-		subclassPropertySubclassNameClosure = ArrayHelper.toStringArray( classes );
-		subclassPropertyTypeClosure = ArrayHelper.toTypeArray( types );
-		subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables );
-		subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates );
-		subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns );
-		subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers );
-		subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers );
-
-		subclassPropertyCascadeStyleClosure = new CascadeStyle[cascades.size()];
-		iter = cascades.iterator();
-		int j = 0;
-		while ( iter.hasNext() ) {
-			subclassPropertyCascadeStyleClosure[j++] = ( CascadeStyle ) iter.next();
-		}
-		subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()];
-		iter = joinedFetchesList.iterator();
-		j = 0;
-		while ( iter.hasNext() ) {
-			subclassPropertyFetchModeClosure[j++] = ( FetchMode ) iter.next();
-		}
-
-		propertyDefinedOnSubclass = new boolean[definedBySubclass.size()];
-		iter = definedBySubclass.iterator();
-		j = 0;
-		while ( iter.hasNext() ) {
-			propertyDefinedOnSubclass[j++] = ( ( Boolean ) iter.next() ).booleanValue();
-		}
-
-		// Handle any filters applied to the class level
-		filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect(), factory.getSqlFunctionRegistry() );
-
-		temporaryIdTableName = persistentClass.getTemporaryIdTableName();
-		temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL();
-	}
-
-	protected String generateLazySelectString() {
-
-		if ( !entityMetamodel.hasLazyProperties() ) {
-			return null;
-		}
-
-		HashSet tableNumbers = new HashSet();
-		ArrayList columnNumbers = new ArrayList();
-		ArrayList formulaNumbers = new ArrayList();
-		for ( int i = 0; i < lazyPropertyNames.length; i++ ) {
-			// all this only really needs to consider properties
-			// of this class, not its subclasses, but since we
-			// are reusing code used for sequential selects, we
-			// use the subclass closure
-			int propertyNumber = getSubclassPropertyIndex( lazyPropertyNames[i] );
-
-			int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
-			tableNumbers.add( new Integer( tableNumber ) );
-
-			int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber];
-			for ( int j = 0; j < colNumbers.length; j++ ) {
-				if ( colNumbers[j]!=-1 ) {
-					columnNumbers.add( new Integer( colNumbers[j] ) );
-				}
-			}
-			int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber];
-			for ( int j = 0; j < formNumbers.length; j++ ) {
-				if ( formNumbers[j]!=-1 ) {
-					formulaNumbers.add( new Integer( formNumbers[j] ) );
-				}
-			}
-		}
-
-		if ( columnNumbers.size()==0 && formulaNumbers.size()==0 ) {
-			// only one-to-one is lazy fetched
-			return null;
-		}
-
-		return renderSelect( ArrayHelper.toIntArray( tableNumbers ),
-				ArrayHelper.toIntArray( columnNumbers ),
-				ArrayHelper.toIntArray( formulaNumbers ) );
-
-	}
-
-	public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
-			throws HibernateException {
-
-		final Serializable id = session.getContextEntityIdentifier( entity );
-
-		final EntityEntry entry = session.getPersistenceContext().getEntry( entity );
-		if ( entry == null ) {
-			throw new HibernateException( "entity is not associated with the session: " + id );
-		}
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"initializing lazy properties of: " +
-					MessageHelper.infoString( this, id, getFactory() ) +
-					", field access: " + fieldName
-				);
-		}
-
-		if ( hasCache() ) {
-			CacheKey cacheKey = new CacheKey(id, getIdentifierType(), getEntityName(), session.getEntityMode(), getFactory() );
-			Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() );
-			if (ce!=null) {
-				CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
-				if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
-					//note early exit here:
-					return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
-				}
-			}
-		}
-
-		return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry );
-
-	}
-
-	private Object initializeLazyPropertiesFromDatastore(
-			final String fieldName,
-			final Object entity,
-			final SessionImplementor session,
-			final Serializable id,
-			final EntityEntry entry) {
-
-		if ( !hasLazyProperties() ) {
-			throw new AssertionFailure("no lazy properties");
-		}
-
-		log.trace("initializing lazy properties from datastore");
-
-		try {
-
-			Object result = null;
-			PreparedStatement ps = null;
-			try {
-				final String lazySelect = getSQLLazySelectString();
-				ResultSet rs = null;
-				try {
-					if ( lazySelect != null ) {
-						// null sql means that the only lazy properties
-						// are shared PK one-to-one associations which are
-						// handled differently in the Type#nullSafeGet code...
-						ps = session.getBatcher().prepareSelectStatement(lazySelect);
-						getIdentifierType().nullSafeSet( ps, id, 1, session );
-						rs = ps.executeQuery();
-						rs.next();
-					}
-					final Object[] snapshot = entry.getLoadedState();
-					for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
-						Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity );
-						if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
-							result = propValue;
-						}
-					}
-				}
-				finally {
-					if ( rs != null ) {
-						rs.close();
-					}
-				}
-			}
-			finally {
-				if ( ps != null ) {
-					session.getBatcher().closeStatement( ps );
-				}
-			}
-
-			log.trace( "done initializing lazy properties" );
-
-			return result;
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not initialize lazy properties: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-					getSQLLazySelectString()
-				);
-		}
-	}
-
-	private Object initializeLazyPropertiesFromCache(
-			final String fieldName,
-			final Object entity,
-			final SessionImplementor session,
-			final EntityEntry entry,
-			final CacheEntry cacheEntry
-	) {
-
-		log.trace("initializing lazy properties from second-level cache");
-
-		Object result = null;
-		Serializable[] disassembledValues = cacheEntry.getDisassembledState();
-		final Object[] snapshot = entry.getLoadedState();
-		for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
-			final Object propValue = lazyPropertyTypes[j].assemble(
-					disassembledValues[ lazyPropertyNumbers[j] ],
-					session,
-					entity
-				);
-			if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
-				result = propValue;
-			}
-		}
-
-		log.trace( "done initializing lazy properties" );
-
-		return result;
-	}
-
-	private boolean initializeLazyProperty(
-			final String fieldName,
-			final Object entity,
-			final SessionImplementor session,
-			final Object[] snapshot,
-			final int j,
-			final Object propValue) {
-		setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() );
-		if (snapshot != null) {
-			// object have been loaded with setReadOnly(true); HHH-2236
-			snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
-		}
-		return fieldName.equals( lazyPropertyNames[j] );
-	}
-
-	public boolean isBatchable() {
-		return optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_NONE ||
-			( !isVersioned() && optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) ||
-			getFactory().getSettings().isJdbcBatchVersionedData();
-	}
-
-	public Serializable[] getQuerySpaces() {
-		return getPropertySpaces();
-	}
-
-	protected Set getLazyProperties() {
-		return lazyProperties;
-	}
-
-	public boolean isBatchLoadable() {
-		return batchSize > 1;
-	}
-
-	public String[] getIdentifierColumnNames() {
-		return rootTableKeyColumnNames;
-	}
-
-	protected int getIdentifierColumnSpan() {
-		return identifierColumnSpan;
-	}
-
-	protected String[] getIdentifierAliases() {
-		return identifierAliases;
-	}
-
-	public String getVersionColumnName() {
-		return versionColumnName;
-	}
-
-	protected String getVersionedTableName() {
-		return getTableName( 0 );
-	}
-
-	protected boolean[] getSubclassColumnLazyiness() {
-		return subclassColumnLazyClosure;
-	}
-
-	protected boolean[] getSubclassFormulaLazyiness() {
-		return subclassFormulaLazyClosure;
-	}
-
-	/**
-	 * We can't immediately add to the cache if we have formulas
-	 * which must be evaluated, or if we have the possibility of
-	 * two concurrent updates to the same item being merged on
-	 * the database. This can happen if (a) the item is not
-	 * versioned and either (b) we have dynamic update enabled
-	 * or (c) we have multiple tables holding the state of the
-	 * item.
-	 */
-	public boolean isCacheInvalidationRequired() {
-		return hasFormulaProperties() ||
-				( !isVersioned() && ( entityMetamodel.isDynamicUpdate() || getTableSpan() > 1 ) );
-	}
-
-	public boolean isLazyPropertiesCacheable() {
-		return isLazyPropertiesCacheable;
-	}
-
-	public String selectFragment(String alias, String suffix) {
-		return identifierSelectFragment( alias, suffix ) +
-				propertySelectFragment( alias, suffix, false );
-	}
-
-	public String[] getIdentifierAliases(String suffix) {
-		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
-		// was toUnqotedAliasStrings( getIdentiferColumnNames() ) before - now tried
-		// to remove that unqoting and missing aliases..
-		return new Alias( suffix ).toAliasStrings( getIdentifierAliases() );
-	}
-
-	public String[] getPropertyAliases(String suffix, int i) {
-		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
-		return new Alias( suffix ).toUnquotedAliasStrings( propertyColumnAliases[i] );
-	}
-
-	public String getDiscriminatorAlias(String suffix) {
-		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
-		// was toUnqotedAliasStrings( getdiscriminatorColumnName() ) before - now tried
-		// to remove that unqoting and missing aliases..
-		return entityMetamodel.hasSubclasses() ?
-				new Alias( suffix ).toAliasString( getDiscriminatorAlias() ) :
-				null;
-	}
-
-	public String identifierSelectFragment(String name, String suffix) {
-		return new SelectFragment()
-				.setSuffix( suffix )
-				.addColumns( name, getIdentifierColumnNames(), getIdentifierAliases() )
-				.toFragmentString()
-				.substring( 2 ); //strip leading ", "
-	}
-
-
-	public String propertySelectFragment(String name, String suffix, boolean allProperties) {
-
-		SelectFragment select = new SelectFragment()
-				.setSuffix( suffix )
-				.setUsedAliases( getIdentifierAliases() );
-
-		int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
-		String[] columnAliases = getSubclassColumnAliasClosure();
-		String[] columns = getSubclassColumnClosure();
-		for ( int i = 0; i < getSubclassColumnClosure().length; i++ ) {
-			boolean selectable = ( allProperties || !subclassColumnLazyClosure[i] ) &&
-				!isSubclassTableSequentialSelect( columnTableNumbers[i] ) &&
-				subclassColumnSelectableClosure[i];
-			if ( selectable ) {
-				String subalias = generateTableAlias( name, columnTableNumbers[i] );
-				select.addColumn( subalias, columns[i], columnAliases[i] );
-			}
-		}
-
-		int[] formulaTableNumbers = getSubclassFormulaTableNumberClosure();
-		String[] formulaTemplates = getSubclassFormulaTemplateClosure();
-		String[] formulaAliases = getSubclassFormulaAliasClosure();
-		for ( int i = 0; i < getSubclassFormulaTemplateClosure().length; i++ ) {
-			boolean selectable = ( allProperties || !subclassFormulaLazyClosure[i] )
-				&& !isSubclassTableSequentialSelect( formulaTableNumbers[i] );
-			if ( selectable ) {
-				String subalias = generateTableAlias( name, formulaTableNumbers[i] );
-				select.addFormula( subalias, formulaTemplates[i], formulaAliases[i] );
-			}
-		}
-
-		if ( entityMetamodel.hasSubclasses() ) {
-			addDiscriminatorToSelect( select, name, suffix );
-		}
-
-		if ( hasRowId() ) {
-			select.addColumn( name, rowIdName, ROWID_ALIAS );
-		}
-
-		return select.toFragmentString();
-	}
-
-	public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session)
-			throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Getting current persistent state for: " + MessageHelper.infoString( this, id, getFactory() ) );
-		}
-
-		try {
-			PreparedStatement ps = session.getBatcher().prepareSelectStatement( getSQLSnapshotSelectString() );
-			try {
-				getIdentifierType().nullSafeSet( ps, id, 1, session );
-				//if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session );
-				ResultSet rs = ps.executeQuery();
-				try {
-					//if there is no resulting row, return null
-					if ( !rs.next() ) {
-						return null;
-					}
-
-					//otherwise return the "hydrated" state (ie. associations are not resolved)
-					Type[] types = getPropertyTypes();
-					Object[] values = new Object[types.length];
-					boolean[] includeProperty = getPropertyUpdateability();
-					for ( int i = 0; i < types.length; i++ ) {
-						if ( includeProperty[i] ) {
-							values[i] = types[i].hydrate( rs, getPropertyAliases( "", i ), session, null ); //null owner ok??
-						}
-					}
-					return values;
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( ps );
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve snapshot: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-			        getSQLSnapshotSelectString()
-				);
-		}
-
-	}
-
-	/**
-	 * Generate the SQL that selects the version number by id
-	 */
-	protected String generateSelectVersionString() {
-		SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
-				.setTableName( getVersionedTableName() );
-		if ( isVersioned() ) {
-			select.addColumn( versionColumnName );
-		}
-		else {
-			select.addColumns( rootTableKeyColumnNames );
-		}
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "get version " + getEntityName() );
-		}
-		return select.addCondition( rootTableKeyColumnNames, "=?" ).toStatementString();
-	}
-
-	protected String generateInsertGeneratedValuesSelectString() {
-		return generateGeneratedValuesSelectString( getPropertyInsertGenerationInclusions() );
-	}
-
-	protected String generateUpdateGeneratedValuesSelectString() {
-		return generateGeneratedValuesSelectString( getPropertyUpdateGenerationInclusions() );
-	}
-
-	private String generateGeneratedValuesSelectString(ValueInclusion[] inclusions) {
-		Select select = new Select( getFactory().getDialect() );
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "get generated state " + getEntityName() );
-		}
-
-		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
-
-		// Here we render the select column list based on the properties defined as being generated.
-		// For partial component generation, we currently just re-select the whole component
-		// rather than trying to handle the individual generated portions.
-		String selectClause = concretePropertySelectFragment( getRootAlias(), inclusions );
-		selectClause = selectClause.substring( 2 );
-
-		String fromClause = fromTableFragment( getRootAlias() ) +
-				fromJoinFragment( getRootAlias(), true, false );
-
-		String whereClause = new StringBuffer()
-			.append( StringHelper.join( "=? and ", aliasedIdColumns ) )
-			.append( "=?" )
-			.append( whereJoinFragment( getRootAlias(), true, false ) )
-			.toString();
-
-		return select.setSelectClause( selectClause )
-				.setFromClause( fromClause )
-				.setOuterJoins( "", "" )
-				.setWhereClause( whereClause )
-				.toStatementString();
-	}
-
-	protected static interface InclusionChecker {
-		public boolean includeProperty(int propertyNumber);
-	}
-
-	protected String concretePropertySelectFragment(String alias, final ValueInclusion[] inclusions) {
-		return concretePropertySelectFragment(
-				alias,
-				new InclusionChecker() {
-					// TODO : currently we really do not handle ValueInclusion.PARTIAL...
-					// ValueInclusion.PARTIAL would indicate parts of a component need to
-					// be included in the select; currently we then just render the entire
-					// component into the select clause in that case.
-					public boolean includeProperty(int propertyNumber) {
-						return inclusions[propertyNumber] != ValueInclusion.NONE;
-					}
-				}
-		);
-	}
-
-	protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) {
-		return concretePropertySelectFragment(
-				alias,
-				new InclusionChecker() {
-					public boolean includeProperty(int propertyNumber) {
-						return includeProperty[propertyNumber];
-					}
-				}
-		);
-	}
-
-	protected String concretePropertySelectFragment(String alias, InclusionChecker inclusionChecker) {
-		int propertyCount = getPropertyNames().length;
-		int[] propertyTableNumbers = getPropertyTableNumbersInSelect();
-		SelectFragment frag = new SelectFragment();
-		for ( int i = 0; i < propertyCount; i++ ) {
-			if ( inclusionChecker.includeProperty( i ) ) {
-				frag.addColumns(
-						generateTableAlias( alias, propertyTableNumbers[i] ),
-						propertyColumnNames[i],
-						propertyColumnAliases[i]
-				);
-				frag.addFormulas(
-						generateTableAlias( alias, propertyTableNumbers[i] ),
-						propertyColumnFormulaTemplates[i],
-						propertyColumnAliases[i]
-				);
-			}
-		}
-		return frag.toFragmentString();
-	}
-
-	protected String generateSnapshotSelectString() {
-
-		//TODO: should we use SELECT .. FOR UPDATE?
-
-		Select select = new Select( getFactory().getDialect() );
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "get current state " + getEntityName() );
-		}
-
-		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
-		String selectClause = StringHelper.join( ", ", aliasedIdColumns ) +
-				concretePropertySelectFragment( getRootAlias(), getPropertyUpdateability() );
-
-		String fromClause = fromTableFragment( getRootAlias() ) +
-				fromJoinFragment( getRootAlias(), true, false );
-
-		String whereClause = new StringBuffer()
-			.append( StringHelper.join( "=? and ",
-					aliasedIdColumns ) )
-			.append( "=?" )
-			.append( whereJoinFragment( getRootAlias(), true, false ) )
-			.toString();
-
-		/*if ( isVersioned() ) {
-			where.append(" and ")
-				.append( getVersionColumnName() )
-				.append("=?");
-		}*/
-
-		return select.setSelectClause( selectClause )
-				.setFromClause( fromClause )
-				.setOuterJoins( "", "" )
-				.setWhereClause( whereClause )
-				.toStatementString();
-	}
-
-	public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session) {
-		if ( !isVersioned() ) {
-			throw new AssertionFailure( "cannot force version increment on non-versioned entity" );
-		}
-
-		if ( isVersionPropertyGenerated() ) {
-			// the difficulty here is exactly what do we update in order to
-			// force the version to be incremented in the db...
-			throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" );
-		}
-
-		Object nextVersion = getVersionType().next( currentVersion, session );
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) +
-					"; " + getVersionType().toLoggableString( currentVersion, getFactory() ) +
-					" -> " + getVersionType().toLoggableString( nextVersion, getFactory() ) + "]"
-			);
-		}
-
-		// todo : cache this sql...
-		String versionIncrementString = generateVersionIncrementUpdateString();
-		PreparedStatement st = null;
-		try {
-			try {
-				st = session.getBatcher().prepareStatement( versionIncrementString );
-				getVersionType().nullSafeSet( st, nextVersion, 1, session );
-				getIdentifierType().nullSafeSet( st, id, 2, session );
-				getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session );
-				int rows = st.executeUpdate();
-				if ( rows != 1 ) {
-					throw new StaleObjectStateException( getEntityName(), id );
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve version: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-					getVersionSelectString()
-				);
-		}
-
-		return nextVersion;
-	}
-
-	private String generateVersionIncrementUpdateString() {
-		Update update = new Update( getFactory().getDialect() );
-		update.setTableName( getTableName( 0 ) );
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "forced version increment" );
-		}
-		update.addColumn( getVersionColumnName() );
-		update.setPrimaryKeyColumnNames( getIdentifierColumnNames() );
-		update.setVersionColumnName( getVersionColumnName() );
-		return update.toStatementString();
-	}
-
-	/**
-	 * Retrieve the version number
-	 */
-	public Object getCurrentVersion(Serializable id, SessionImplementor session) throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Getting version: " + MessageHelper.infoString( this, id, getFactory() ) );
-		}
-
-		try {
-
-			PreparedStatement st = session.getBatcher().prepareSelectStatement( getVersionSelectString() );
-			try {
-				getIdentifierType().nullSafeSet( st, id, 1, session );
-
-				ResultSet rs = st.executeQuery();
-				try {
-					if ( !rs.next() ) {
-						return null;
-					}
-					if ( !isVersioned() ) {
-						return this;
-					}
-					return getVersionType().nullSafeGet( rs, getVersionColumnName(), session, null );
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( st );
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve version: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-					getVersionSelectString()
-				);
-		}
-
-	}
-
-	protected void initLockers() {
-		lockers.put( LockMode.READ, generateLocker( LockMode.READ ) );
-		lockers.put( LockMode.UPGRADE, generateLocker( LockMode.UPGRADE ) );
-		lockers.put( LockMode.UPGRADE_NOWAIT, generateLocker( LockMode.UPGRADE_NOWAIT ) );
-		lockers.put( LockMode.FORCE, generateLocker( LockMode.FORCE ) );
-	}
-
-	protected LockingStrategy generateLocker(LockMode lockMode) {
-		return factory.getDialect().getLockingStrategy( this, lockMode );
-	}
-
-	private LockingStrategy getLocker(LockMode lockMode) {
-		return ( LockingStrategy ) lockers.get( lockMode );
-	}
-
-	public void lock(
-			Serializable id,
-	        Object version,
-	        Object object,
-	        LockMode lockMode,
-	        SessionImplementor session) throws HibernateException {
-		getLocker( lockMode ).lock( id, version, object, session );
-	}
-
-	public String getRootTableName() {
-		return getSubclassTableName( 0 );
-	}
-
-	public String getRootTableAlias(String drivingAlias) {
-		return drivingAlias;
-	}
-
-	public String[] getRootTableIdentifierColumnNames() {
-		return getRootTableKeyColumnNames();
-	}
-
-	public String[] toColumns(String alias, String propertyName) throws QueryException {
-		return propertyMapping.toColumns( alias, propertyName );
-	}
-
-	public String[] toColumns(String propertyName) throws QueryException {
-		return propertyMapping.getColumnNames( propertyName );
-	}
-
-	public Type toType(String propertyName) throws QueryException {
-		return propertyMapping.toType( propertyName );
-	}
-
-	public String[] getPropertyColumnNames(String propertyName) {
-		return propertyMapping.getColumnNames( propertyName );
-	}
-
-	/**
-	 * Warning:
-	 * When there are duplicated property names in the subclasses
-	 * of the class, this method may return the wrong table
-	 * number for the duplicated subclass property (note that
-	 * SingleTableEntityPersister defines an overloaded form
-	 * which takes the entity name.
-	 */
-	public int getSubclassPropertyTableNumber(String propertyPath) {
-		String rootPropertyName = StringHelper.root(propertyPath);
-		Type type = propertyMapping.toType(rootPropertyName);
-		if ( type.isAssociationType() ) {
-			AssociationType assocType = ( AssociationType ) type;
-			if ( assocType.useLHSPrimaryKey() ) {
-				// performance op to avoid the array search
-				return 0;
-			}
-			else if ( type.isCollectionType() ) {
-				// properly handle property-ref-based associations
-				rootPropertyName = assocType.getLHSPropertyName();
-			}
-		}
-		//Enable for HHH-440, which we don't like:
-		/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
-			String unrooted = StringHelper.unroot(propertyName);
-			int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
-			if ( idx != -1 ) {
-				return getSubclassColumnTableNumberClosure()[idx];
-			}
-		}*/
-		int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName); //TODO: optimize this better!
-		return index==-1 ? 0 : getSubclassPropertyTableNumber(index);
-	}
-
-	public Declarer getSubclassPropertyDeclarer(String propertyPath) {
-		int tableIndex = getSubclassPropertyTableNumber( propertyPath );
-		if ( tableIndex == 0 ) {
-			return Declarer.CLASS;
-		}
-		else if ( isClassOrSuperclassTable( tableIndex ) ) {
-			return Declarer.SUPERCLASS;
-		}
-		else {
-			return Declarer.SUBCLASS;
-		}
-	}
-
-	protected String generateTableAlias(String rootAlias, int tableNumber) {
-		if ( tableNumber == 0 ) {
-			return rootAlias;
-		}
-		StringBuffer buf = new StringBuffer().append( rootAlias );
-		if ( !rootAlias.endsWith( "_" ) ) {
-			buf.append( '_' );
-		}
-		return buf.append( tableNumber ).append( '_' ).toString();
-	}
-
-	public String[] toColumns(String name, final int i) {
-		final String alias = generateTableAlias( name, getSubclassPropertyTableNumber( i ) );
-		String[] cols = getSubclassPropertyColumnNames( i );
-		String[] templates = getSubclassPropertyFormulaTemplateClosure()[i];
-		String[] result = new String[cols.length];
-		for ( int j = 0; j < cols.length; j++ ) {
-			if ( cols[j] == null ) {
-				result[j] = StringHelper.replace( templates[j], Template.TEMPLATE, alias );
-			}
-			else {
-				result[j] = StringHelper.qualify( alias, cols[j] );
-			}
-		}
-		return result;
-	}
-
-	private int getSubclassPropertyIndex(String propertyName) {
-		return ArrayHelper.indexOf(subclassPropertyNameClosure, propertyName);
-	}
-
-	protected String[] getPropertySubclassNames() {
-		return propertySubclassNames;
-	}
-
-	public String[] getPropertyColumnNames(int i) {
-		return propertyColumnNames[i];
-	}
-
-	protected int getPropertyColumnSpan(int i) {
-		return propertyColumnSpans[i];
-	}
-
-	protected boolean hasFormulaProperties() {
-		return hasFormulaProperties;
-	}
-
-	public FetchMode getFetchMode(int i) {
-		return subclassPropertyFetchModeClosure[i];
-	}
-
-	public CascadeStyle getCascadeStyle(int i) {
-		return subclassPropertyCascadeStyleClosure[i];
-	}
-
-	public Type getSubclassPropertyType(int i) {
-		return subclassPropertyTypeClosure[i];
-	}
-
-	public String getSubclassPropertyName(int i) {
-		return subclassPropertyNameClosure[i];
-	}
-
-	public int countSubclassProperties() {
-		return subclassPropertyTypeClosure.length;
-	}
-
-	public String[] getSubclassPropertyColumnNames(int i) {
-		return subclassPropertyColumnNameClosure[i];
-	}
-
-	public boolean isDefinedOnSubclass(int i) {
-		return propertyDefinedOnSubclass[i];
-	}
-
-	protected String[][] getSubclassPropertyFormulaTemplateClosure() {
-		return subclassPropertyFormulaTemplateClosure;
-	}
-
-	protected Type[] getSubclassPropertyTypeClosure() {
-		return subclassPropertyTypeClosure;
-	}
-
-	protected String[][] getSubclassPropertyColumnNameClosure() {
-		return subclassPropertyColumnNameClosure;
-	}
-
-	protected String[] getSubclassPropertyNameClosure() {
-		return subclassPropertyNameClosure;
-	}
-
-	protected String[] getSubclassPropertySubclassNameClosure() {
-		return subclassPropertySubclassNameClosure;
-	}
-
-	protected String[] getSubclassColumnClosure() {
-		return subclassColumnClosure;
-	}
-
-	protected String[] getSubclassColumnAliasClosure() {
-		return subclassColumnAliasClosure;
-	}
-
-	protected String[] getSubclassFormulaClosure() {
-		return subclassFormulaClosure;
-	}
-
-	protected String[] getSubclassFormulaTemplateClosure() {
-		return subclassFormulaTemplateClosure;
-	}
-
-	protected String[] getSubclassFormulaAliasClosure() {
-		return subclassFormulaAliasClosure;
-	}
-
-	public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) {
-		String rawAliases[] = ( String[] ) subclassPropertyAliases.get( propertyName );
-
-		if ( rawAliases == null ) {
-			return null;
-		}
-
-		String result[] = new String[rawAliases.length];
-		for ( int i = 0; i < rawAliases.length; i++ ) {
-			result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] );
-		}
-		return result;
-	}
-
-	public String[] getSubclassPropertyColumnNames(String propertyName) {
-		//TODO: should we allow suffixes on these ?
-		return ( String[] ) subclassPropertyColumnNames.get( propertyName );
-	}
-
-
-
-	//This is really ugly, but necessary:
-	/**
-	 * Must be called by subclasses, at the end of their constructors
-	 */
-	protected void initSubclassPropertyAliasesMap(PersistentClass model) throws MappingException {
-
-		// ALIASES
-		internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosureIterator() );
-
-		// aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id'
-		if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
-			subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() );
-			subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() );
-		}
-
-		// aliases named identifier ( alias.idname )
-		if ( hasIdentifierProperty() ) {
-			subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() );
-			subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() );
-		}
-
-		// aliases for composite-id's
-		if ( getIdentifierType().isComponentType() ) {
-			// Fetch embedded identifiers propertynames from the "virtual" identifier component
-			AbstractComponentType componentId = ( AbstractComponentType ) getIdentifierType();
-			String[] idPropertyNames = componentId.getPropertyNames();
-			String[] idAliases = getIdentifierAliases();
-			String[] idColumnNames = getIdentifierColumnNames();
-
-			for ( int i = 0; i < idPropertyNames.length; i++ ) {
-				if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
-					subclassPropertyAliases.put(
-							ENTITY_ID + "." + idPropertyNames[i],
-							new String[] { idAliases[i] }
-					);
-					subclassPropertyColumnNames.put(
-							ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i],
-							new String[] { idColumnNames[i] }
-					);
-				}
-//				if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) {
-				if ( hasIdentifierProperty() ) {
-					subclassPropertyAliases.put(
-							getIdentifierPropertyName() + "." + idPropertyNames[i],
-							new String[] { idAliases[i] }
-					);
-					subclassPropertyColumnNames.put(
-							getIdentifierPropertyName() + "." + idPropertyNames[i],
-							new String[] { idColumnNames[i] }
-					);
-				}
-				else {
-					// embedded composite ids ( alias.idname1, alias.idname2 )
-					subclassPropertyAliases.put( idPropertyNames[i], new String[] { idAliases[i] } );
-					subclassPropertyColumnNames.put( idPropertyNames[i],  new String[] { idColumnNames[i] } );
-				}
-			}
-		}
-
-		if ( entityMetamodel.isPolymorphic() ) {
-			subclassPropertyAliases.put( ENTITY_CLASS, new String[] { getDiscriminatorAlias() } );
-			subclassPropertyColumnNames.put( ENTITY_CLASS, new String[] { getDiscriminatorColumnName() } );
-		}
-
-	}
-
-	private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) {
-		while ( propertyIterator.hasNext() ) {
-
-			Property prop = ( Property ) propertyIterator.next();
-			String propname = path == null ? prop.getName() : path + "." + prop.getName();
-			if ( prop.isComposite() ) {
-				Component component = ( Component ) prop.getValue();
-				Iterator compProps = component.getPropertyIterator();
-				internalInitSubclassPropertyAliasesMap( propname, compProps );
-			}
-			else {
-				String[] aliases = new String[prop.getColumnSpan()];
-				String[] cols = new String[prop.getColumnSpan()];
-				Iterator colIter = prop.getColumnIterator();
-				int l = 0;
-				while ( colIter.hasNext() ) {
-					Selectable thing = ( Selectable ) colIter.next();
-					aliases[l] = thing.getAlias( getFactory().getDialect(), prop.getValue().getTable() );
-					cols[l] = thing.getText( getFactory().getDialect() ); // TODO: skip formulas?
-					l++;
-				}
-
-				subclassPropertyAliases.put( propname, aliases );
-				subclassPropertyColumnNames.put( propname, cols );
-			}
-		}
-
-	}
-
-	public Object loadByUniqueKey(String propertyName, Object uniqueKey, SessionImplementor session)
-			throws HibernateException {
-		return getAppropriateUniqueKeyLoader( propertyName, session.getEnabledFilters() )
-				.loadByUniqueKey( session, uniqueKey );
-	}
-
-	private EntityLoader getAppropriateUniqueKeyLoader(String propertyName, Map enabledFilters) {
-
-		final boolean useStaticLoader = ( enabledFilters == null || enabledFilters.isEmpty() )
-				&& propertyName.indexOf('.')<0; //ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties
-
-		if ( useStaticLoader ) {
-			return (EntityLoader) uniqueKeyLoaders.get( propertyName );
-		}
-		else {
-			return createUniqueKeyLoader(
-					propertyMapping.toType(propertyName),
-					propertyMapping.toColumns(propertyName),
-					enabledFilters
-				);
-		}
-	}
-
-	public int getPropertyIndex(String propertyName) {
-		return entityMetamodel.getPropertyIndex(propertyName);
-	}
-
-	protected void createUniqueKeyLoaders() throws MappingException {
-		Type[] propertyTypes = getPropertyTypes();
-		String[] propertyNames = getPropertyNames();
-		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-			if ( propertyUniqueness[i] ) {
-				//don't need filters for the static loaders
-				uniqueKeyLoaders.put(
-						propertyNames[i],
-						createUniqueKeyLoader(
-								propertyTypes[i],
-								getPropertyColumnNames( i ),
-								CollectionHelper.EMPTY_MAP
-							)
-					);
-				//TODO: create uk loaders for component properties
-			}
-		}
-	}
-
-	private EntityLoader createUniqueKeyLoader(Type uniqueKeyType, String[] columns, Map enabledFilters) {
-		if ( uniqueKeyType.isEntityType() ) {
-			String className = ( ( EntityType ) uniqueKeyType ).getAssociatedEntityName();
-			uniqueKeyType = getFactory().getEntityPersister( className ).getIdentifierType();
-		}
-
-		return new EntityLoader( this, columns, uniqueKeyType, 1, LockMode.NONE, getFactory(), enabledFilters );
-	}
-
-	protected String getSQLWhereString(String alias) {
-		return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias );
-	}
-
-	protected boolean hasWhere() {
-		return sqlWhereString != null;
-	}
-
-	private void initOrdinaryPropertyPaths(Mapping mapping) throws MappingException {
-		for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) {
-			propertyMapping.initPropertyPaths( getSubclassPropertyNameClosure()[i],
-					getSubclassPropertyTypeClosure()[i],
-					getSubclassPropertyColumnNameClosure()[i],
-					getSubclassPropertyFormulaTemplateClosure()[i],
-					mapping );
-		}
-	}
-
-	private void initIdentifierPropertyPaths(Mapping mapping) throws MappingException {
-		String idProp = getIdentifierPropertyName();
-		if ( idProp != null ) {
-			propertyMapping.initPropertyPaths( idProp, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
-		}
-		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
-			propertyMapping.initPropertyPaths( null, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
-		}
-		if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
-			propertyMapping.initPropertyPaths( ENTITY_ID, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
-		}
-	}
-
-	private void initDiscriminatorPropertyPath(Mapping mapping) throws MappingException {
-		propertyMapping.initPropertyPaths( ENTITY_CLASS,
-				getDiscriminatorType(),
-				new String[]{getDiscriminatorColumnName()},
-				new String[]{getDiscriminatorFormulaTemplate()},
-				getFactory() );
-	}
-
-	protected void initPropertyPaths(Mapping mapping) throws MappingException {
-		initOrdinaryPropertyPaths(mapping);
-		initOrdinaryPropertyPaths(mapping); //do two passes, for collection property-ref!
-		initIdentifierPropertyPaths(mapping);
-		if ( entityMetamodel.isPolymorphic() ) {
-			initDiscriminatorPropertyPath( mapping );
-		}
-	}
-
-	protected UniqueEntityLoader createEntityLoader(LockMode lockMode, Map enabledFilters) throws MappingException {
-		//TODO: disable batch loading if lockMode > READ?
-		return BatchingEntityLoader.createBatchingEntityLoader( this, batchSize, lockMode, getFactory(), enabledFilters );
-	}
-
-	protected UniqueEntityLoader createEntityLoader(LockMode lockMode) throws MappingException {
-		return createEntityLoader( lockMode, CollectionHelper.EMPTY_MAP );
-	}
-
-	protected boolean check(int rows, Serializable id, int tableNumber, Expectation expectation, PreparedStatement statement) throws HibernateException {
-		try {
-			expectation.verifyOutcome( rows, statement, -1 );
-		}
-		catch( StaleStateException e ) {
-			if ( !isNullableTable( tableNumber ) ) {
-				if ( getFactory().getStatistics().isStatisticsEnabled() ) {
-					getFactory().getStatisticsImplementor()
-							.optimisticFailure( getEntityName() );
-				}
-				throw new StaleObjectStateException( getEntityName(), id );
-			}
-			return false;
-		}
-		catch( TooManyRowsAffectedException e ) {
-			throw new HibernateException(
-					"Duplicate identifier in table for: " +
-					MessageHelper.infoString( this, id, getFactory() )
-			);
-		}
-		catch ( Throwable t ) {
-			return false;
-		}
-		return true;
-	}
-
-	protected String generateUpdateString(boolean[] includeProperty, int j, boolean useRowId) {
-		return generateUpdateString( includeProperty, j, null, useRowId );
-	}
-
-	/**
-	 * Generate the SQL that updates a row by id (and version)
-	 */
-	protected String generateUpdateString(final boolean[] includeProperty,
-										  final int j,
-										  final Object[] oldFields,
-										  final boolean useRowId) {
-
-		Update update = new Update( getFactory().getDialect() ).setTableName( getTableName( j ) );
-
-		// select the correct row by either pk or rowid
-		if ( useRowId ) {
-			update.setPrimaryKeyColumnNames( new String[]{rowIdName} ); //TODO: eventually, rowIdName[j]
-		}
-		else {
-			update.setPrimaryKeyColumnNames( getKeyColumns( j ) );
-		}
-
-		boolean hasColumns = false;
-		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
-				// this is a property of the table, which we are updating
-				update.addColumns( getPropertyColumnNames(i), propertyColumnUpdateable[i] );
-				hasColumns = hasColumns || getPropertyColumnSpan( i ) > 0;
-			}
-		}
-
-		if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_VERSION ) {
-			// this is the root (versioned) table, and we are using version-based
-			// optimistic locking;  if we are not updating the version, also don't
-			// check it (unless this is a "generated" version column)!
-			if ( checkVersion( includeProperty ) ) {
-				update.setVersionColumnName( getVersionColumnName() );
-				hasColumns = true;
-			}
-		}
-		else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) {
-			// we are using "all" or "dirty" property-based optimistic locking
-
-			boolean[] includeInWhere = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ?
-					getPropertyUpdateability() : //optimistic-lock="all", include all updatable properties
-					includeProperty; //optimistic-lock="dirty", include all properties we are updating this time
-
-			boolean[] versionability = getPropertyVersionability();
-			Type[] types = getPropertyTypes();
-			for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-				boolean include = includeInWhere[i] &&
-						isPropertyOfTable( i, j ) &&
-						versionability[i];
-				if ( include ) {
-					// this property belongs to the table, and it is not specifically
-					// excluded from optimistic locking by optimistic-lock="false"
-					String[] propertyColumnNames = getPropertyColumnNames( i );
-					boolean[] propertyNullness = types[i].toColumnNullness( oldFields[i], getFactory() );
-					for ( int k=0; k<propertyNullness.length; k++ ) {
-						if ( propertyNullness[k] ) {
-							update.addWhereColumn( propertyColumnNames[k] );
-						}
-						else {
-							update.addWhereColumn( propertyColumnNames[k], " is null" );
-						}
-					}
-				}
-			}
-
-		}
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			update.setComment( "update " + getEntityName() );
-		}
-
-		return hasColumns ? update.toStatementString() : null;
-	}
-
-	private boolean checkVersion(final boolean[] includeProperty) {
-        return includeProperty[ getVersionProperty() ] ||
-				entityMetamodel.getPropertyUpdateGenerationInclusions()[ getVersionProperty() ] != ValueInclusion.NONE;
-	}
-
-	protected String generateInsertString(boolean[] includeProperty, int j) {
-		return generateInsertString( false, includeProperty, j );
-	}
-
-	protected String generateInsertString(boolean identityInsert, boolean[] includeProperty) {
-		return generateInsertString( identityInsert, includeProperty, 0 );
-	}
-
-	/**
-	 * Generate the SQL that inserts a row
-	 */
-	protected String generateInsertString(boolean identityInsert, boolean[] includeProperty, int j) {
-
-		// todo : remove the identityInsert param and variations;
-		//   identity-insert strings are now generated from generateIdentityInsertString()
-
-		Insert insert = new Insert( getFactory().getDialect() )
-				.setTableName( getTableName( j ) );
-
-		// add normal properties
-		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
-				// this property belongs on the table and is to be inserted
-				insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i] );
-			}
-		}
-
-		// add the discriminator
-		if ( j == 0 ) {
-			addDiscriminatorToInsert( insert );
-		}
-
-		// add the primary key
-		if ( j == 0 && identityInsert ) {
-			insert.addIdentityColumn( getKeyColumns( 0 )[0] );
-		}
-		else {
-			insert.addColumns( getKeyColumns( j ) );
-		}
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			insert.setComment( "insert " + getEntityName() );
-		}
-
-		String result = insert.toStatementString();
-
-		// append the SQL to return the generated identifier
-		if ( j == 0 && identityInsert && useInsertSelectIdentity() ) { //TODO: suck into Insert
-			result = getFactory().getDialect().appendIdentitySelectToInsert( result );
-		}
-
-		return result;
-	}
-
-	/**
-	 * Used to generate an insery statement against the root table in the
-	 * case of identifier generation strategies where the insert statement
-	 * executions actually generates the identifier value.
-	 *
-	 * @param includeProperty indices of the properties to include in the
-	 * insert statement.
-	 * @return The insert SQL statement string
-	 */
-	protected String generateIdentityInsertString(boolean[] includeProperty) {
-		Insert insert = identityDelegate.prepareIdentifierGeneratingInsert();
-		insert.setTableName( getTableName( 0 ) );
-
-		// add normal properties
-		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-			if ( includeProperty[i] && isPropertyOfTable( i, 0 ) ) {
-				// this property belongs on the table and is to be inserted
-				insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i] );
-			}
-		}
-
-		// add the discriminator
-		addDiscriminatorToInsert( insert );
-
-		// delegate already handles PK columns
-
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			insert.setComment( "insert " + getEntityName() );
-		}
-
-		return insert.toStatementString();
-	}
-
-	/**
-	 * Generate the SQL that deletes a row by id (and version)
-	 */
-	protected String generateDeleteString(int j) {
-		Delete delete = new Delete()
-				.setTableName( getTableName( j ) )
-				.setPrimaryKeyColumnNames( getKeyColumns( j ) );
-		if ( j == 0 ) {
-			delete.setVersionColumnName( getVersionColumnName() );
-		}
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			delete.setComment( "delete " + getEntityName() );
-		}
-		return delete.toStatementString();
-	}
-
-	protected int dehydrate(
-			Serializable id,
-			Object[] fields,
-			boolean[] includeProperty,
-			boolean[][] includeColumns,
-			int j,
-			PreparedStatement st,
-			SessionImplementor session) throws HibernateException, SQLException {
-		return dehydrate( id, fields, null, includeProperty, includeColumns, j, st, session, 1 );
-	}
-
-	/**
-	 * Marshall the fields of a persistent instance to a prepared statement
-	 */
-	protected int dehydrate(
-			final Serializable id,
-	        final Object[] fields,
-	        final Object rowId,
-	        final boolean[] includeProperty,
-	        final boolean[][] includeColumns,
-	        final int j,
-	        final PreparedStatement ps,
-	        final SessionImplementor session,
-	        int index) throws SQLException, HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Dehydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-		}
-
-		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
-				getPropertyTypes()[i].nullSafeSet( ps, fields[i], index, includeColumns[i], session );
-				//index += getPropertyColumnSpan( i );
-				index += ArrayHelper.countTrue( includeColumns[i] ); //TODO:  this is kinda slow...
-			}
-		}
-
-		if ( rowId != null ) {
-			ps.setObject( index, rowId );
-			index += 1;
-		}
-		else if ( id != null ) {
-			getIdentifierType().nullSafeSet( ps, id, index, session );
-			index += getIdentifierColumnSpan();
-		}
-
-		return index;
-
-	}
-
-	/**
-	 * Unmarshall the fields of a persistent instance from a result set,
-	 * without resolving associations or collections. Question: should
-	 * this really be here, or should it be sent back to Loader?
-	 */
-	public Object[] hydrate(
-			final ResultSet rs,
-	        final Serializable id,
-	        final Object object,
-	        final Loadable rootLoadable,
-	        final String[][] suffixedPropertyColumns,
-	        final boolean allProperties,
-	        final SessionImplementor session) throws SQLException, HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Hydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-		}
-
-		final AbstractEntityPersister rootPersister = (AbstractEntityPersister) rootLoadable;
-
-		final boolean hasDeferred = rootPersister.hasSequentialSelect();
-		PreparedStatement sequentialSelect = null;
-		ResultSet sequentialResultSet = null;
-		boolean sequentialSelectEmpty = false;
-		try {
-
-			if ( hasDeferred ) {
-				final String sql = rootPersister.getSequentialSelect( getEntityName() );
-				if ( sql != null ) {
-					//TODO: I am not so sure about the exception handling in this bit!
-					sequentialSelect = session.getBatcher().prepareSelectStatement( sql );
-					rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
-					sequentialResultSet = sequentialSelect.executeQuery();
-					if ( !sequentialResultSet.next() ) {
-						// TODO: Deal with the "optional" attribute in the <join> mapping;
-						// this code assumes that optional defaults to "true" because it
-						// doesn't actually seem to work in the fetch="join" code
-						//
-						// Note that actual proper handling of optional-ality here is actually
-						// more involved than this patch assumes.  Remember that we might have
-						// multiple <join/> mappings associated with a single entity.  Really
-						// a couple of things need to happen to properly handle optional here:
-						//  1) First and foremost, when handling multiple <join/>s, we really
-						//      should be using the entity root table as the driving table;
-						//      another option here would be to choose some non-optional joined
-						//      table to use as the driving table.  In all likelihood, just using
-						//      the root table is much simplier
-						//  2) Need to add the FK columns corresponding to each joined table
-						//      to the generated select list; these would then be used when
-						//      iterating the result set to determine whether all non-optional
-						//      data is present
-						// My initial thoughts on the best way to deal with this would be
-						// to introduce a new SequentialSelect abstraction that actually gets
-						// generated in the persisters (ok, SingleTable...) and utilized here.
-						// It would encapsulated all this required optional-ality checking...
-						sequentialSelectEmpty = true;
-					}
-				}
-			}
-
-			final String[] propNames = getPropertyNames();
-			final Type[] types = getPropertyTypes();
-			final Object[] values = new Object[types.length];
-			final boolean[] laziness = getPropertyLaziness();
-			final String[] propSubclassNames = getSubclassPropertySubclassNameClosure();
-
-			for ( int i = 0; i < types.length; i++ ) {
-				if ( !propertySelectable[i] ) {
-					values[i] = BackrefPropertyAccessor.UNKNOWN;
-				}
-				else if ( allProperties || !laziness[i] ) {
-					//decide which ResultSet to get the property value from:
-					final boolean propertyIsDeferred = hasDeferred &&
-							rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
-					if ( propertyIsDeferred && sequentialSelectEmpty ) {
-						values[i] = null;
-					}
-					else {
-						final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
-						final String[] cols = propertyIsDeferred ? propertyColumnAliases[i] : suffixedPropertyColumns[i];
-						values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
-					}
-				}
-				else {
-					values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
-				}
-			}
-
-			if ( sequentialResultSet != null ) {
-				sequentialResultSet.close();
-			}
-
-			return values;
-
-		}
-		finally {
-			if ( sequentialSelect != null ) {
-				session.getBatcher().closeStatement( sequentialSelect );
-			}
-		}
-	}
-
-	protected boolean useInsertSelectIdentity() {
-		return !useGetGeneratedKeys() && getFactory().getDialect().supportsInsertSelectIdentity();
-	}
-
-	protected boolean useGetGeneratedKeys() {
-		return getFactory().getSettings().isGetGeneratedKeysEnabled();
-	}
-
-	protected String getSequentialSelect(String entityName) {
-		throw new UnsupportedOperationException("no sequential selects");
-	}
-
-	/**
-	 * Perform an SQL INSERT, and then retrieve a generated identifier.
-	 * <p/>
-	 * This form is used for PostInsertIdentifierGenerator-style ids (IDENTITY,
-	 * select, etc).
-	 */
-	protected Serializable insert(
-			final Object[] fields,
-	        final boolean[] notNull,
-	        String sql,
-	        final Object object,
-	        final SessionImplementor session) throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Inserting entity: " + getEntityName() + " (native id)" );
-			if ( isVersioned() ) {
-				log.trace( "Version: " + Versioning.getVersion( fields, this ) );
-			}
-		}
-
-		Binder binder = new Binder() {
-			public void bindValues(PreparedStatement ps) throws SQLException {
-				dehydrate( null, fields, notNull, propertyColumnInsertable, 0, ps, session );
-			}
-			public Object getEntity() {
-				return object;
-			}
-		};
-		return identityDelegate.performInsert( sql, session, binder );
-	}
-
-	public String getIdentitySelectString() {
-		//TODO: cache this in an instvar
-		return getFactory().getDialect().getIdentitySelectString(
-				getTableName(0),
-				getKeyColumns(0)[0],
-				getIdentifierType().sqlTypes( getFactory() )[0]
-		);
-	}
-
-	public String getSelectByUniqueKeyString(String propertyName) {
-		return new SimpleSelect( getFactory().getDialect() )
-			.setTableName( getTableName(0) )
-			.addColumns( getKeyColumns(0) )
-			.addCondition( getPropertyColumnNames(propertyName), "=?" )
-			.toStatementString();
-	}
-
-	/**
-	 * Perform an SQL INSERT.
-	 * <p/>
-	 * This for is used for all non-root tables as well as the root table
-	 * in cases where the identifier value is known before the insert occurs.
-	 */
-	protected void insert(
-			final Serializable id,
-	        final Object[] fields,
-	        final boolean[] notNull,
-	        final int j,
-	        final String sql,
-	        final Object object,
-	        final SessionImplementor session) throws HibernateException {
-
-		if ( isInverseTable( j ) ) {
-			return;
-		}
-
-		//note: it is conceptually possible that a UserType could map null to
-		//	  a non-null value, so the following is arguable:
-		if ( isNullableTable( j ) && isAllNull( fields, j ) ) {
-			return;
-		}
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Inserting entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-			if ( j == 0 && isVersioned() ) {
-				log.trace( "Version: " + Versioning.getVersion( fields, this ) );
-			}
-		}
-
-		Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] );
-		boolean callable = isInsertCallable( j );
-		// we can't batch joined inserts, *especially* not if it is an identity insert;
-		// nor can we batch statements where the expectation is based on an output param
-		final boolean useBatch = j == 0 && expectation.canBeBatched();
-		try {
-
-			// Render the SQL query
-			final PreparedStatement insert;
-			if ( useBatch ) {
-				if ( callable ) {
-					insert = session.getBatcher().prepareBatchCallableStatement( sql );
-				}
-				else {
-					insert = session.getBatcher().prepareBatchStatement( sql );
-				}
-			}
-			else {
-				if ( callable ) {
-					insert = session.getBatcher().prepareCallableStatement( sql );
-				}
-				else {
-					insert = session.getBatcher().prepareStatement( sql );
-				}
-			}
-
-			try {
-				int index = 1;
-				index += expectation.prepare( insert );
-
-				// Write the values of fields onto the prepared statement - we MUST use the state at the time the
-				// insert was issued (cos of foreign key constraints). Not necessarily the object's current state
-
-				dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index );
-
-				if ( useBatch ) {
-					// TODO : shouldnt inserts be Expectations.NONE?
-					session.getBatcher().addToBatch( expectation );
-				}
-				else {
-					expectation.verifyOutcome( insert.executeUpdate(), insert, -1 );
-				}
-
-			}
-			catch ( SQLException sqle ) {
-				if ( useBatch ) {
-					session.getBatcher().abortBatch( sqle );
-				}
-				throw sqle;
-			}
-			finally {
-				if ( !useBatch ) {
-					session.getBatcher().closeStatement( insert );
-				}
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not insert: " + MessageHelper.infoString( this ),
-					sql
-				);
-		}
-
-	}
-
-	/**
-	 * Perform an SQL UPDATE or SQL INSERT
-	 */
-	protected void updateOrInsert(
-			final Serializable id,
-	        final Object[] fields,
-	        final Object[] oldFields,
-	        final Object rowId,
-	        final boolean[] includeProperty,
-	        final int j,
-	        final Object oldVersion,
-	        final Object object,
-	        final String sql,
-	        final SessionImplementor session) throws HibernateException {
-
-		if ( !isInverseTable( j ) ) {
-
-			final boolean isRowToUpdate;
-			if ( isNullableTable( j ) && oldFields != null && isAllNull( oldFields, j ) ) {
-				//don't bother trying to update, we know there is no row there yet
-				isRowToUpdate = false;
-			}
-			else if ( isNullableTable( j ) && isAllNull( fields, j ) ) {
-				//if all fields are null, we might need to delete existing row
-				isRowToUpdate = true;
-				delete( id, oldVersion, j, object, getSQLDeleteStrings()[j], session, null );
-			}
-			else {
-				//there is probably a row there, so try to update
-				//if no rows were updated, we will find out
-				isRowToUpdate = update( id, fields, oldFields, rowId, includeProperty, j, oldVersion, object, sql, session );
-			}
-
-			if ( !isRowToUpdate && !isAllNull( fields, j ) ) {
-				// assume that the row was not there since it previously had only null
-				// values, so do an INSERT instead
-				//TODO: does not respect dynamic-insert
-				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
-			}
-
-		}
-
-	}
-
-	protected boolean update(
-			final Serializable id,
-	        final Object[] fields,
-	        final Object[] oldFields,
-	        final Object rowId,
-	        final boolean[] includeProperty,
-	        final int j,
-	        final Object oldVersion,
-	        final Object object,
-	        final String sql,
-	        final SessionImplementor session) throws HibernateException {
-
-		final boolean useVersion = j == 0 && isVersioned();
-		final Expectation expectation = Expectations.appropriateExpectation( updateResultCheckStyles[j] );
-		final boolean callable = isUpdateCallable( j );
-		final boolean useBatch = j == 0 && expectation.canBeBatched() && isBatchable(); //note: updates to joined tables can't be batched...
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Updating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-			if ( useVersion ) {
-				log.trace( "Existing version: " + oldVersion + " -> New version: " + fields[getVersionProperty()] );
-			}
-		}
-
-		try {
-
-			int index = 1; // starting index
-			final PreparedStatement update;
-			if ( useBatch ) {
-				if ( callable ) {
-					update = session.getBatcher().prepareBatchCallableStatement( sql );
-				}
-				else {
-					update = session.getBatcher().prepareBatchStatement( sql );
-				}
-			}
-			else {
-				if ( callable ) {
-					update = session.getBatcher().prepareCallableStatement( sql );
-				}
-				else {
-					update = session.getBatcher().prepareStatement( sql );
-				}
-			}
-
-			try {
-
-				index+= expectation.prepare( update );
-
-				//Now write the values of fields onto the prepared statement
-				index = dehydrate( id, fields, rowId, includeProperty, propertyColumnUpdateable, j, update, session, index );
-
-				// Write any appropriate versioning conditional parameters
-				if ( useVersion && Versioning.OPTIMISTIC_LOCK_VERSION == entityMetamodel.getOptimisticLockMode() ) {
-					if ( checkVersion( includeProperty ) ) {
-						getVersionType().nullSafeSet( update, oldVersion, index, session );
-					}
-				}
-				else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) {
-					boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary????
-					boolean[] includeOldField = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ?
-							getPropertyUpdateability() : includeProperty;
-					Type[] types = getPropertyTypes();
-					for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-						boolean include = includeOldField[i] &&
-								isPropertyOfTable( i, j ) &&
-								versionability[i]; //TODO: is this really necessary????
-						if ( include ) {
-							boolean[] settable = types[i].toColumnNullness( oldFields[i], getFactory() );
-							types[i].nullSafeSet(
-									update,
-									oldFields[i],
-									index,
-									settable,
-									session
-								);
-							index += ArrayHelper.countTrue(settable);
-						}
-					}
-				}
-
-				if ( useBatch ) {
-					session.getBatcher().addToBatch( expectation );
-					return true;
-				}
-				else {
-					return check( update.executeUpdate(), id, j, expectation, update );
-				}
-
-			}
-			catch ( SQLException sqle ) {
-				if ( useBatch ) {
-					session.getBatcher().abortBatch( sqle );
-				}
-				throw sqle;
-			}
-			finally {
-				if ( !useBatch ) {
-					session.getBatcher().closeStatement( update );
-				}
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not update: " + MessageHelper.infoString( this, id, getFactory() ),
-					sql
-				);
-		}
-	}
-
-	/**
-	 * Perform an SQL DELETE
-	 */
-	protected void delete(
-			final Serializable id,
-			final Object version,
-			final int j,
-			final Object object,
-			final String sql,
-			final SessionImplementor session,
-			final Object[] loadedState) throws HibernateException {
-
-		if ( isInverseTable( j ) ) {
-			return;
-		}
-
-		final boolean useVersion = j == 0 && isVersioned();
-		final boolean callable = isDeleteCallable( j );
-		final Expectation expectation = Expectations.appropriateExpectation( deleteResultCheckStyles[j] );
-		final boolean useBatch = j == 0 && isBatchable() && expectation.canBeBatched();
-
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Deleting entity: " + MessageHelper.infoString( this, id, getFactory() ) );
-			if ( useVersion ) {
-				log.trace( "Version: " + version );
-			}
-		}
-
-		if ( isTableCascadeDeleteEnabled( j ) ) {
-			if ( log.isTraceEnabled() ) {
-				log.trace( "delete handled by foreign key constraint: " + getTableName( j ) );
-			}
-			return; //EARLY EXIT!
-		}
-
-		try {
-
-			//Render the SQL query
-			PreparedStatement delete;
-			int index = 1;
-			if ( useBatch ) {
-				if ( callable ) {
-					delete = session.getBatcher().prepareBatchCallableStatement( sql );
-				}
-				else {
-					delete = session.getBatcher().prepareBatchStatement( sql );
-				}
-			}
-			else {
-				if ( callable ) {
-					delete = session.getBatcher().prepareCallableStatement( sql );
-				}
-				else {
-					delete = session.getBatcher().prepareStatement( sql );
-				}
-			}
-
-			try {
-
-				index += expectation.prepare( delete );
-
-				// Do the key. The key is immutable so we can use the _current_ object state - not necessarily
-				// the state at the time the delete was issued
-				getIdentifierType().nullSafeSet( delete, id, index, session );
-				index += getIdentifierColumnSpan();
-
-				// We should use the _current_ object state (ie. after any updates that occurred during flush)
-
-				if ( useVersion ) {
-					getVersionType().nullSafeSet( delete, version, index, session );
-				}
-				else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && loadedState != null ) {
-					boolean[] versionability = getPropertyVersionability();
-					Type[] types = getPropertyTypes();
-					for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-						if ( isPropertyOfTable( i, j ) && versionability[i] ) {
-							// this property belongs to the table and it is not specifically
-							// excluded from optimistic locking by optimistic-lock="false"
-							boolean[] settable = types[i].toColumnNullness( loadedState[i], getFactory() );
-							types[i].nullSafeSet( delete, loadedState[i], index, settable, session );
-							index += ArrayHelper.countTrue( settable );
-						}
-					}
-				}
-
-				if ( useBatch ) {
-					session.getBatcher().addToBatch( expectation );
-				}
-				else {
-					check( delete.executeUpdate(), id, j, expectation, delete );
-				}
-
-			}
-			catch ( SQLException sqle ) {
-				if ( useBatch ) {
-					session.getBatcher().abortBatch( sqle );
-				}
-				throw sqle;
-			}
-			finally {
-				if ( !useBatch ) {
-					session.getBatcher().closeStatement( delete );
-				}
-			}
-
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not delete: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-					sql
-				);
-
-		}
-
-	}
-
-	private String[] getUpdateStrings(boolean byRowId, boolean lazy) {
-		if ( byRowId ) {
-			return lazy ? getSQLLazyUpdateByRowIdStrings() : getSQLUpdateByRowIdStrings();
-		}
-		else {
-			return lazy ? getSQLLazyUpdateStrings() : getSQLUpdateStrings();
-		}
-	}
-
-	/**
-	 * Update an object
-	 */
-	public void update(
-			final Serializable id,
-	        final Object[] fields,
-	        final int[] dirtyFields,
-	        final boolean hasDirtyCollection,
-	        final Object[] oldFields,
-	        final Object oldVersion,
-	        final Object object,
-	        final Object rowId,
-	        final SessionImplementor session) throws HibernateException {
-
-		//note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update
-		//	  oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields)
-
-		final boolean[] tableUpdateNeeded = getTableUpdateNeeded( dirtyFields, hasDirtyCollection );
-		final int span = getTableSpan();
-
-		final boolean[] propsToUpdate;
-		final String[] updateStrings;
-		if ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) {
-			// For the case of dynamic-update="true", we need to generate the UPDATE SQL
-			propsToUpdate = getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
-			// don't need to check laziness (dirty checking algorithm handles that)
-			updateStrings = new String[span];
-			for ( int j = 0; j < span; j++ ) {
-				updateStrings[j] = tableUpdateNeeded[j] ?
-						generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) :
-						null;
-			}
-		}
-		else {
-			// For the case of dynamic-update="false", or no snapshot, we use the static SQL
-			updateStrings = getUpdateStrings(
-					rowId != null,
-					hasUninitializedLazyProperties( object, session.getEntityMode() )
-				);
-			propsToUpdate = getPropertyUpdateability( object, session.getEntityMode() );
-		}
-
-		for ( int j = 0; j < span; j++ ) {
-			// Now update only the tables with dirty properties (and the table with the version number)
-			if ( tableUpdateNeeded[j] ) {
-				updateOrInsert(
-						id,
-						fields,
-						oldFields,
-						j == 0 ? rowId : null,
-						propsToUpdate,
-						j,
-						oldVersion,
-						object,
-						updateStrings[j],
-						session
-					);
-			}
-		}
-	}
-
-	public Serializable insert(Object[] fields, Object object, SessionImplementor session)
-			throws HibernateException {
-
-		final int span = getTableSpan();
-		final Serializable id;
-		if ( entityMetamodel.isDynamicInsert() ) {
-			// For the case of dynamic-insert="true", we need to generate the INSERT SQL
-			boolean[] notNull = getPropertiesToInsert( fields );
-			id = insert( fields, notNull, generateInsertString( true, notNull ), object, session );
-			for ( int j = 1; j < span; j++ ) {
-				insert( id, fields, notNull, j, generateInsertString( notNull, j ), object, session );
-			}
-		}
-		else {
-			// For the case of dynamic-insert="false", use the static SQL
-			id = insert( fields, getPropertyInsertability(), getSQLIdentityInsertString(), object, session );
-			for ( int j = 1; j < span; j++ ) {
-				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
-			}
-		}
-		return id;
-	}
-
-	public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session)
-			throws HibernateException {
-
-		final int span = getTableSpan();
-		if ( entityMetamodel.isDynamicInsert() ) {
-			// For the case of dynamic-insert="true", we need to generate the INSERT SQL
-			boolean[] notNull = getPropertiesToInsert( fields );
-			for ( int j = 0; j < span; j++ ) {
-				insert( id, fields, notNull, j, generateInsertString( notNull, j ), object, session );
-			}
-		}
-		else {
-			// For the case of dynamic-insert="false", use the static SQL
-			for ( int j = 0; j < span; j++ ) {
-				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
-			}
-		}
-	}
-
-	/**
-	 * Delete an object
-	 */
-	public void delete(Serializable id, Object version, Object object, SessionImplementor session)
-			throws HibernateException {
-		final int span = getTableSpan();
-		boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION;
-		Object[] loadedState = null;
-		if ( isImpliedOptimisticLocking ) {
-			// need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
-			// first we need to locate the "loaded" state
-			//
-			// Note, it potentially could be a proxy, so perform the location the safe way...
-			EntityKey key = new EntityKey( id, this, session.getEntityMode() );
-			Object entity = session.getPersistenceContext().getEntity( key );
-			if ( entity != null ) {
-				EntityEntry entry = session.getPersistenceContext().getEntry( entity );
-				loadedState = entry.getLoadedState();
-			}
-		}
-
-		final String[] deleteStrings;
-		if ( isImpliedOptimisticLocking && loadedState != null ) {
-			// we need to utilize dynamic delete statements
-			deleteStrings = generateSQLDeletStrings( loadedState );
-		}
-		else {
-			// otherwise, utilize the static delete statements
-			deleteStrings = getSQLDeleteStrings();
-		}
-
-		for ( int j = span - 1; j >= 0; j-- ) {
-			delete( id, version, j, object, deleteStrings[j], session, loadedState );
-		}
-
-	}
-
-	private String[] generateSQLDeletStrings(Object[] loadedState) {
-		int span = getTableSpan();
-		String[] deleteStrings = new String[span];
-		for ( int j = span - 1; j >= 0; j-- ) {
-			Delete delete = new Delete()
-					.setTableName( getTableName( j ) )
-					.setPrimaryKeyColumnNames( getKeyColumns( j ) );
-			if ( getFactory().getSettings().isCommentsEnabled() ) {
-				delete.setComment( "delete " + getEntityName() + " [" + j + "]" );
-			}
-
-			boolean[] versionability = getPropertyVersionability();
-			Type[] types = getPropertyTypes();
-			for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
-				if ( isPropertyOfTable( i, j ) && versionability[i] ) {
-					// this property belongs to the table and it is not specifically
-					// excluded from optimistic locking by optimistic-lock="false"
-					String[] propertyColumnNames = getPropertyColumnNames( i );
-					boolean[] propertyNullness = types[i].toColumnNullness( loadedState[i], getFactory() );
-					for ( int k = 0; k < propertyNullness.length; k++ ) {
-						if ( propertyNullness[k] ) {
-							delete.addWhereFragment( propertyColumnNames[k] + " = ?" );
-						}
-						else {
-							delete.addWhereFragment( propertyColumnNames[k] + " is null" );
-						}
-					}
-				}
-			}
-			deleteStrings[j] = delete.toStatementString();
-		}
-		return deleteStrings;
-	}
-
-	protected void logStaticSQL() {
-		if ( log.isDebugEnabled() ) {
-			log.debug( "Static SQL for entity: " + getEntityName() );
-			if ( sqlLazySelectString != null ) {
-				log.debug( " Lazy select: " + sqlLazySelectString );
-			}
-			if ( sqlVersionSelectString != null ) {
-				log.debug( " Version select: " + sqlVersionSelectString );
-			}
-			if ( sqlSnapshotSelectString != null ) {
-				log.debug( " Snapshot select: " + sqlSnapshotSelectString );
-			}
-			for ( int j = 0; j < getTableSpan(); j++ ) {
-				log.debug( " Insert " + j + ": " + getSQLInsertStrings()[j] );
-				log.debug( " Update " + j + ": " + getSQLUpdateStrings()[j] );
-				log.debug( " Delete " + j + ": " + getSQLDeleteStrings()[j] );
-
-			}
-			if ( sqlIdentityInsertString != null ) {
-				log.debug( " Identity insert: " + sqlIdentityInsertString );
-			}
-			if ( sqlUpdateByRowIdString != null ) {
-				log.debug( " Update by row id (all fields): " + sqlUpdateByRowIdString );
-			}
-			if ( sqlLazyUpdateByRowIdString != null ) {
-				log.debug( " Update by row id (non-lazy fields): " + sqlLazyUpdateByRowIdString );
-			}
-			if ( sqlInsertGeneratedValuesSelectString != null ) {
-				log.debug( "Insert-generated property select: " + sqlInsertGeneratedValuesSelectString );
-			}
-			if ( sqlUpdateGeneratedValuesSelectString != null ) {
-				log.debug( "Update-generated property select: " + sqlUpdateGeneratedValuesSelectString );
-			}
-		}
-	}
-
-	public String filterFragment(String alias, Map enabledFilters) throws MappingException {
-		final StringBuffer sessionFilterFragment = new StringBuffer();
-		filterHelper.render( sessionFilterFragment, generateFilterConditionAlias( alias ), enabledFilters );
-
-		return sessionFilterFragment.append( filterFragment( alias ) ).toString();
-	}
-
-	public String generateFilterConditionAlias(String rootAlias) {
-		return rootAlias;
-	}
-
-	public String oneToManyFilterFragment(String alias) throws MappingException {
-		return "";
-	}
-
-	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
-		return getSubclassTableSpan() == 1 ?
-				"" : //just a performance opt!
-				createJoin( alias, innerJoin, includeSubclasses ).toFromFragmentString();
-	}
-
-	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
-		return getSubclassTableSpan() == 1 ?
-				"" : //just a performance opt!
-				createJoin( alias, innerJoin, includeSubclasses ).toWhereFragmentString();
-	}
-
-	protected boolean isSubclassTableLazy(int j) {
-		return false;
-	}
-
-	protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses) {
-		final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table
-		final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
-		final int tableSpan = getSubclassTableSpan();
-		for ( int j = 1; j < tableSpan; j++ ) { //notice that we skip the first table; it is the driving table!
-			final boolean joinIsIncluded = isClassOrSuperclassTable( j ) ||
-					( includeSubclasses && !isSubclassTableSequentialSelect( j ) && !isSubclassTableLazy( j ) );
-			if ( joinIsIncluded ) {
-				join.addJoin( getSubclassTableName( j ),
-						generateTableAlias( name, j ),
-						idCols,
-						getSubclassTableKeyColumns( j ),
-						innerJoin && isClassOrSuperclassTable( j ) && !isInverseTable( j ) && !isNullableTable( j ) ?
-						JoinFragment.INNER_JOIN : //we can inner join to superclass tables (the row MUST be there)
-						JoinFragment.LEFT_OUTER_JOIN //we can never inner join to subclass tables
-					);
-			}
-		}
-		return join;
-	}
-
-	protected JoinFragment createJoin(int[] tableNumbers, String drivingAlias) {
-		final String[] keyCols = StringHelper.qualify( drivingAlias, getSubclassTableKeyColumns( tableNumbers[0] ) );
-		final JoinFragment jf = getFactory().getDialect().createOuterJoinFragment();
-		for ( int i = 1; i < tableNumbers.length; i++ ) { //skip the driving table
-			final int j = tableNumbers[i];
-			jf.addJoin( getSubclassTableName( j ),
-					generateTableAlias( getRootAlias(), j ),
-					keyCols,
-					getSubclassTableKeyColumns( j ),
-					isInverseSubclassTable( j ) || isNullableSubclassTable( j ) ?
-					JoinFragment.LEFT_OUTER_JOIN :
-					JoinFragment.INNER_JOIN );
-		}
-		return jf;
-	}
-
-	protected SelectFragment createSelect(final int[] subclassColumnNumbers,
-										  final int[] subclassFormulaNumbers) {
-
-		SelectFragment selectFragment = new SelectFragment();
-
-		int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
-		String[] columnAliases = getSubclassColumnAliasClosure();
-		String[] columns = getSubclassColumnClosure();
-		for ( int i = 0; i < subclassColumnNumbers.length; i++ ) {
-			if ( subclassColumnSelectableClosure[i] ) {
-				int columnNumber = subclassColumnNumbers[i];
-				final String subalias = generateTableAlias( getRootAlias(), columnTableNumbers[columnNumber] );
-				selectFragment.addColumn( subalias, columns[columnNumber], columnAliases[columnNumber] );
-			}
-		}
-
-		int[] formulaTableNumbers = getSubclassFormulaTableNumberClosure();
-		String[] formulaTemplates = getSubclassFormulaTemplateClosure();
-		String[] formulaAliases = getSubclassFormulaAliasClosure();
-		for ( int i = 0; i < subclassFormulaNumbers.length; i++ ) {
-			int formulaNumber = subclassFormulaNumbers[i];
-			final String subalias = generateTableAlias( getRootAlias(), formulaTableNumbers[formulaNumber] );
-			selectFragment.addFormula( subalias, formulaTemplates[formulaNumber], formulaAliases[formulaNumber] );
-		}
-
-		return selectFragment;
-	}
-
-	protected String createFrom(int tableNumber, String alias) {
-		return getSubclassTableName( tableNumber ) + ' ' + alias;
-	}
-
-	protected String createWhereByKey(int tableNumber, String alias) {
-		//TODO: move to .sql package, and refactor with similar things!
-		return StringHelper.join( "=? and ",
-				StringHelper.qualify( alias, getSubclassTableKeyColumns( tableNumber ) ) ) + "=?";
-	}
-
-	protected String renderSelect(
-			final int[] tableNumbers,
-	        final int[] columnNumbers,
-	        final int[] formulaNumbers) {
-
-		Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
-
-		//render the where and from parts
-		int drivingTable = tableNumbers[0];
-		final String drivingAlias = generateTableAlias( getRootAlias(), drivingTable ); //we *could* regerate this inside each called method!
-		final String where = createWhereByKey( drivingTable, drivingAlias );
-		final String from = createFrom( drivingTable, drivingAlias );
-
-		//now render the joins
-		JoinFragment jf = createJoin( tableNumbers, drivingAlias );
-
-		//now render the select clause
-		SelectFragment selectFragment = createSelect( columnNumbers, formulaNumbers );
-
-		//now tie it all together
-		Select select = new Select( getFactory().getDialect() );
-		select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
-		select.setFromClause( from );
-		select.setWhereClause( where );
-		select.setOuterJoins( jf.toFromFragmentString(), jf.toWhereFragmentString() );
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "sequential select " + getEntityName() );
-		}
-		return select.toStatementString();
-	}
-
-	private String getRootAlias() {
-		return StringHelper.generateAlias( getEntityName() );
-	}
-
-	protected void postConstruct(Mapping mapping) throws MappingException {
-		initPropertyPaths(mapping);
-
-		//insert/update/delete SQL
-		final int joinSpan = getTableSpan();
-		sqlDeleteStrings = new String[joinSpan];
-		sqlInsertStrings = new String[joinSpan];
-		sqlUpdateStrings = new String[joinSpan];
-		sqlLazyUpdateStrings = new String[joinSpan];
-
-		sqlUpdateByRowIdString = rowIdName == null ?
-				null :
-				generateUpdateString( getPropertyUpdateability(), 0, true );
-		sqlLazyUpdateByRowIdString = rowIdName == null ?
-				null :
-				generateUpdateString( getNonLazyPropertyUpdateability(), 0, true );
-
-		for ( int j = 0; j < joinSpan; j++ ) {
-			sqlInsertStrings[j] = customSQLInsert[j] == null ?
-					generateInsertString( getPropertyInsertability(), j ) :
-					customSQLInsert[j];
-			sqlUpdateStrings[j] = customSQLUpdate[j] == null ?
-					generateUpdateString( getPropertyUpdateability(), j, false ) :
-					customSQLUpdate[j];
-			sqlLazyUpdateStrings[j] = customSQLUpdate[j] == null ?
-					generateUpdateString( getNonLazyPropertyUpdateability(), j, false ) :
-					customSQLUpdate[j];
-			sqlDeleteStrings[j] = customSQLDelete[j] == null ?
-					generateDeleteString( j ) :
-					customSQLDelete[j];
-		}
-
-		tableHasColumns = new boolean[joinSpan];
-		for ( int j = 0; j < joinSpan; j++ ) {
-			tableHasColumns[j] = sqlUpdateStrings[j] != null;
-		}
-
-		//select SQL
-		sqlSnapshotSelectString = generateSnapshotSelectString();
-		sqlLazySelectString = generateLazySelectString();
-		sqlVersionSelectString = generateSelectVersionString();
-		if ( hasInsertGeneratedProperties() ) {
-			sqlInsertGeneratedValuesSelectString = generateInsertGeneratedValuesSelectString();
-		}
-		if ( hasUpdateGeneratedProperties() ) {
-			sqlUpdateGeneratedValuesSelectString = generateUpdateGeneratedValuesSelectString();
-		}
-		if ( isIdentifierAssignedByInsert() ) {
-			identityDelegate = ( ( PostInsertIdentifierGenerator ) getIdentifierGenerator() )
-					.getInsertGeneratedIdentifierDelegate( this, getFactory().getDialect(), useGetGeneratedKeys() );
-			sqlIdentityInsertString = customSQLInsert[0] == null
-					? generateIdentityInsertString( getPropertyInsertability() )
-					: customSQLInsert[0];
-		}
-		else {
-			sqlIdentityInsertString = null;
-		}
-
-		logStaticSQL();
-
-	}
-
-	public void postInstantiate() throws MappingException {
-
-		createLoaders();
-		createUniqueKeyLoaders();
-		createQueryLoader();
-
-	}
-
-	private void createLoaders() {
-		loaders.put( LockMode.NONE, createEntityLoader( LockMode.NONE ) );
-
-		UniqueEntityLoader readLoader = createEntityLoader( LockMode.READ );
-		loaders.put( LockMode.READ, readLoader );
-
-		//TODO: inexact, what we really need to know is: are any outer joins used?
-		boolean disableForUpdate = getSubclassTableSpan() > 1 &&
-				hasSubclasses() &&
-				!getFactory().getDialect().supportsOuterJoinForUpdate();
-
-		loaders.put(
-				LockMode.UPGRADE,
-				disableForUpdate ?
-						readLoader :
-						createEntityLoader( LockMode.UPGRADE )
-			);
-		loaders.put(
-				LockMode.UPGRADE_NOWAIT,
-				disableForUpdate ?
-						readLoader :
-						createEntityLoader( LockMode.UPGRADE_NOWAIT )
-			);
-		loaders.put(
-				LockMode.FORCE,
-				disableForUpdate ?
-						readLoader :
-						createEntityLoader( LockMode.FORCE )
-			);
-
-		loaders.put(
-				"merge",
-				new CascadeEntityLoader( this, CascadingAction.MERGE, getFactory() )
-			);
-		loaders.put(
-				"refresh",
-				new CascadeEntityLoader( this, CascadingAction.REFRESH, getFactory() )
-			);
-	}
-
-	protected void createQueryLoader() {
-		if ( loaderName != null ) {
-			queryLoader = new NamedQueryLoader( loaderName, this );
-		}
-	}
-
-	/**
-	 * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>,
-	 * depending upon the value of the <tt>lock</tt> parameter
-	 */
-	public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session)
-			throws HibernateException {
-
-		if ( log.isTraceEnabled() ) {
-			log.trace(
-					"Fetching entity: " +
-					MessageHelper.infoString( this, id, getFactory() )
-				);
-		}
-
-		final UniqueEntityLoader loader = getAppropriateLoader( lockMode, session );
-		return loader.load( id, optionalObject, session );
-	}
-
-	private UniqueEntityLoader getAppropriateLoader(LockMode lockMode, SessionImplementor session) {
-		final Map enabledFilters = session.getEnabledFilters();
-		if ( queryLoader != null ) {
-			return queryLoader;
-		}
-		else if ( enabledFilters == null || enabledFilters.isEmpty() ) {
-			if ( session.getFetchProfile()!=null && LockMode.UPGRADE.greaterThan(lockMode) ) {
-				return (UniqueEntityLoader) loaders.get( session.getFetchProfile() );
-			}
-			else {
-				return (UniqueEntityLoader) loaders.get( lockMode );
-			}
-		}
-		else {
-			return createEntityLoader( lockMode, enabledFilters );
-		}
-	}
-
-	private boolean isAllNull(Object[] array, int tableNumber) {
-		for ( int i = 0; i < array.length; i++ ) {
-			if ( isPropertyOfTable( i, tableNumber ) && array[i] != null ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public boolean isSubclassPropertyNullable(int i) {
-		return subclassPropertyNullabilityClosure[i];
-	}
-
-	/**
-	 * Transform the array of property indexes to an array of booleans,
-	 * true when the property is dirty
-	 */
-	protected final boolean[] getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection) {
-		final boolean[] propsToUpdate = new boolean[ entityMetamodel.getPropertySpan() ];
-		final boolean[] updateability = getPropertyUpdateability(); //no need to check laziness, dirty checking handles that
-		for ( int j = 0; j < dirtyProperties.length; j++ ) {
-			int property = dirtyProperties[j];
-			if ( updateability[property] ) {
-				propsToUpdate[property] = true;
-			}
-		}
-		if ( isVersioned() ) {
-			propsToUpdate[ getVersionProperty() ] =
-				Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() );
-		}
-		return propsToUpdate;
-	}
-
-	/**
-	 * Transform the array of property indexes to an array of booleans,
-	 * true when the property is insertable and non-null
-	 */
-	protected boolean[] getPropertiesToInsert(Object[] fields) {
-		boolean[] notNull = new boolean[fields.length];
-		boolean[] insertable = getPropertyInsertability();
-		for ( int i = 0; i < fields.length; i++ ) {
-			notNull[i] = insertable[i] && fields[i] != null;
-		}
-		return notNull;
-	}
-
-	/**
-	 * Locate the property-indices of all properties considered to be dirty.
-	 *
-	 * @param currentState The current state of the entity (the state to be checked).
-	 * @param previousState The previous state of the entity (the state to be checked against).
-	 * @param entity The entity for which we are checking state dirtiness.
-	 * @param session The session in which the check is ccurring.
-	 * @return <tt>null</tt> or the indices of the dirty properties
-	 * @throws HibernateException
-	 */
-	public int[] findDirty(Object[] currentState, Object[] previousState, Object entity, SessionImplementor session)
-	throws HibernateException {
-		int[] props = TypeFactory.findDirty(
-				entityMetamodel.getProperties(),
-				currentState,
-				previousState,
-				propertyColumnUpdateable,
-				hasUninitializedLazyProperties( entity, session.getEntityMode() ),
-				session
-			);
-		if ( props == null ) {
-			return null;
-		}
-		else {
-			logDirtyProperties( props );
-			return props;
-		}
-	}
-
-	/**
-	 * Locate the property-indices of all properties considered to be dirty.
-	 *
-	 * @param old The old state of the entity.
-	 * @param current The current state of the entity.
-	 * @param entity The entity for which we are checking state modification.
-	 * @param session The session in which the check is ccurring.
-	 * @return <tt>null</tt> or the indices of the modified properties
-	 * @throws HibernateException
-	 */
-	public int[] findModified(Object[] old, Object[] current, Object entity, SessionImplementor session)
-	throws HibernateException {
-		int[] props = TypeFactory.findModified(
-				entityMetamodel.getProperties(),
-				current,
-				old,
-				propertyColumnUpdateable,
-				hasUninitializedLazyProperties( entity, session.getEntityMode() ),
-				session
-			);
-		if ( props == null ) {
-			return null;
-		}
-		else {
-			logDirtyProperties( props );
-			return props;
-		}
-	}
-
-	/**
-	 * Which properties appear in the SQL update?
-	 * (Initialized, updateable ones!)
-	 */
-	protected boolean[] getPropertyUpdateability(Object entity, EntityMode entityMode) {
-		return hasUninitializedLazyProperties( entity, entityMode ) ?
-				getNonLazyPropertyUpdateability() :
-				getPropertyUpdateability();
-	}
-
-	private void logDirtyProperties(int[] props) {
-		if ( log.isTraceEnabled() ) {
-			for ( int i = 0; i < props.length; i++ ) {
-				String propertyName = entityMetamodel.getProperties()[ props[i] ].getName();
-				log.trace( StringHelper.qualify( getEntityName(), propertyName ) + " is dirty" );
-			}
-		}
-	}
-
-	protected EntityTuplizer getTuplizer(SessionImplementor session) {
-		return getTuplizer( session.getEntityMode() );
-	}
-
-	protected EntityTuplizer getTuplizer(EntityMode entityMode) {
-		return entityMetamodel.getTuplizer( entityMode );
-	}
-
-	public SessionFactoryImplementor getFactory() {
-		return factory;
-	}
-
-	public EntityMetamodel getEntityMetamodel() {
-		return entityMetamodel;
-	}
-
-	public boolean hasCache() {
-		return cacheAccessStrategy != null;
-	}
-
-	public EntityRegionAccessStrategy getCacheAccessStrategy() {
-		return cacheAccessStrategy;
-	}
-
-	public CacheEntryStructure getCacheEntryStructure() {
-		return cacheEntryStructure;
-	}
-
-	public Comparator getVersionComparator() {
-		return isVersioned() ? getVersionType().getComparator() : null;
-	}
-
-	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	public final String getEntityName() {
-		return entityMetamodel.getName();
-	}
-
-	public EntityType getEntityType() {
-		return entityMetamodel.getEntityType();
-	}
-
-	private String getSubclassEntityName(Class clazz) {
-		return ( String ) entityNameBySubclass.get( clazz );
-	}
-
-	public boolean isPolymorphic() {
-		return entityMetamodel.isPolymorphic();
-	}
-
-	public boolean isInherited() {
-		return entityMetamodel.isInherited();
-	}
-
-	public boolean hasCascades() {
-		return entityMetamodel.hasCascades();
-	}
-
-	public boolean hasIdentifierProperty() {
-		return !entityMetamodel.getIdentifierProperty().isVirtual();
-	}
-
-	public VersionType getVersionType() {
-		return ( VersionType ) locateVersionType();
-	}
-
-	private Type locateVersionType() {
-		return entityMetamodel.getVersionProperty() == null ?
-				null :
-				entityMetamodel.getVersionProperty().getType();
-	}
-
-	public int getVersionProperty() {
-		return entityMetamodel.getVersionPropertyIndex();
-	}
-
-	public boolean isVersioned() {
-		return entityMetamodel.isVersioned();
-	}
-
-	public boolean isIdentifierAssignedByInsert() {
-		return entityMetamodel.getIdentifierProperty().isIdentifierAssignedByInsert();
-	}
-
-	public boolean hasLazyProperties() {
-		return entityMetamodel.hasLazyProperties();
-	}
-
-//	public boolean hasUninitializedLazyProperties(Object entity) {
-//		if ( hasLazyProperties() ) {
-//			InterceptFieldCallback callback = ( ( InterceptFieldEnabled ) entity ).getInterceptFieldCallback();
-//			return callback != null && !( ( FieldInterceptor ) callback ).isInitialized();
-//		}
-//		else {
-//			return false;
-//		}
-//	}
-
-	public void afterReassociate(Object entity, SessionImplementor session) {
-		//if ( hasLazyProperties() ) {
-		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
-			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
-			if ( interceptor != null ) {
-				interceptor.setSession( session );
-			}
-			else {
-				FieldInterceptor fieldInterceptor = FieldInterceptionHelper.injectFieldInterceptor(
-						entity,
-						getEntityName(),
-						null,
-						session
-				);
-				fieldInterceptor.dirty();
-			}
-		}
-	}
-
-	public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException {
-		final Serializable id;
-		if ( canExtractIdOutOfEntity() ) {
-			id = getIdentifier( entity, session.getEntityMode() );
-		}
-		else {
-			id = null;
-		}
-		// we *always* assume an instance with a null
-		// identifier or no identifier property is unsaved!
-		if ( id == null ) {
-			return Boolean.TRUE;
-		}
-
-		// check the version unsaved-value, if appropriate
-		final Object version = getVersion( entity, session.getEntityMode() );
-		if ( isVersioned() ) {
-			// let this take precedence if defined, since it works for
-			// assigned identifiers
-			Boolean result = entityMetamodel.getVersionProperty()
-					.getUnsavedValue().isUnsaved( version );
-			if ( result != null ) {
-				return result;
-			}
-		}
-
-		// check the id unsaved-value
-		Boolean result = entityMetamodel.getIdentifierProperty()
-				.getUnsavedValue().isUnsaved( id );
-		if ( result != null ) {
-			return result;
-		}
-
-		// check to see if it is in the second-level cache
-		if ( hasCache() ) {
-			CacheKey ck = new CacheKey(
-					id,
-					getIdentifierType(),
-					getRootEntityName(),
-					session.getEntityMode(),
-					session.getFactory()
-				);
-			if ( getCacheAccessStrategy().get( ck, session.getTimestamp() ) != null ) {
-				return Boolean.FALSE;
-			}
-		}
-
-		return null;
-	}
-
-	public boolean hasCollections() {
-		return entityMetamodel.hasCollections();
-	}
-
-	public boolean hasMutableProperties() {
-		return entityMetamodel.hasMutableProperties();
-	}
-
-	public boolean isMutable() {
-		return entityMetamodel.isMutable();
-	}
-
-	public boolean isAbstract() {
-		return entityMetamodel.isAbstract();
-	}
-
-	public boolean hasSubclasses() {
-		return entityMetamodel.hasSubclasses();
-	}
-
-	public boolean hasProxy() {
-		return entityMetamodel.isLazy();
-	}
-
-	public IdentifierGenerator getIdentifierGenerator() throws HibernateException {
-		return entityMetamodel.getIdentifierProperty().getIdentifierGenerator();
-	}
-
-	public String getRootEntityName() {
-		return entityMetamodel.getRootName();
-	}
-
-	public ClassMetadata getClassMetadata() {
-		return this;
-	}
-
-	public String getMappedSuperclass() {
-		return entityMetamodel.getSuperclass();
-	}
-
-	public boolean isExplicitPolymorphism() {
-		return entityMetamodel.isExplicitPolymorphism();
-	}
-
-	protected boolean useDynamicUpdate() {
-		return entityMetamodel.isDynamicUpdate();
-	}
-
-	protected boolean useDynamicInsert() {
-		return entityMetamodel.isDynamicInsert();
-	}
-
-	protected boolean hasEmbeddedCompositeIdentifier() {
-		return entityMetamodel.getIdentifierProperty().isEmbedded();
-	}
-
-	public boolean canExtractIdOutOfEntity() {
-		return hasIdentifierProperty() || hasEmbeddedCompositeIdentifier() || hasIdentifierMapper();
-	}
-
-	private boolean hasIdentifierMapper() {
-		return entityMetamodel.getIdentifierProperty().hasIdentifierMapper();
-	}
-
-	public String[] getKeyColumnNames() {
-		return getIdentifierColumnNames();
-	}
-
-	public String getName() {
-		return getEntityName();
-	}
-
-	public boolean isCollection() {
-		return false;
-	}
-
-	public boolean consumesEntityAlias() {
-		return true;
-	}
-
-	public boolean consumesCollectionAlias() {
-		return false;
-	}
-
-	public Type getPropertyType(String propertyName) throws MappingException {
-		return propertyMapping.toType(propertyName);
-	}
-
-	public Type getType() {
-		return entityMetamodel.getEntityType();
-	}
-
-	public boolean isSelectBeforeUpdateRequired() {
-		return entityMetamodel.isSelectBeforeUpdate();
-	}
-
-	protected final int optimisticLockMode() {
-		return entityMetamodel.getOptimisticLockMode();
-	}
-
-	public Object createProxy(Serializable id, SessionImplementor session) throws HibernateException {
-		return entityMetamodel.getTuplizer( session.getEntityMode() )
-				.createProxy( id, session );
-	}
-
-	public String toString() {
-		return StringHelper.unqualify( getClass().getName() ) +
-				'(' + entityMetamodel.getName() + ')';
-	}
-
-	public final String selectFragment(
-			Joinable rhs,
-			String rhsAlias,
-			String lhsAlias,
-			String entitySuffix,
-			String collectionSuffix,
-			boolean includeCollectionColumns) {
-		return selectFragment( lhsAlias, entitySuffix );
-	}
-
-	public boolean isInstrumented(EntityMode entityMode) {
-		EntityTuplizer tuplizer = entityMetamodel.getTuplizerOrNull(entityMode);
-		return tuplizer!=null && tuplizer.isInstrumented();
-	}
-
-	public boolean hasInsertGeneratedProperties() {
-		return entityMetamodel.hasInsertGeneratedValues();
-	}
-
-	public boolean hasUpdateGeneratedProperties() {
-		return entityMetamodel.hasUpdateGeneratedValues();
-	}
-
-	public boolean isVersionPropertyGenerated() {
-		return isVersioned() && ( getPropertyUpdateGenerationInclusions() [ getVersionProperty() ] != ValueInclusion.NONE );
-	}
-
-	public boolean isVersionPropertyInsertable() {
-		return isVersioned() && getPropertyInsertability() [ getVersionProperty() ];
-	}
-
-	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
-		getTuplizer( session ).afterInitialize( entity, lazyPropertiesAreUnfetched, session );
-	}
-
-	public String[] getPropertyNames() {
-		return entityMetamodel.getPropertyNames();
-	}
-
-	public Type[] getPropertyTypes() {
-		return entityMetamodel.getPropertyTypes();
-	}
-
-	public boolean[] getPropertyLaziness() {
-		return entityMetamodel.getPropertyLaziness();
-	}
-
-	public boolean[] getPropertyUpdateability() {
-		return entityMetamodel.getPropertyUpdateability();
-	}
-
-	public boolean[] getPropertyCheckability() {
-		return entityMetamodel.getPropertyCheckability();
-	}
-
-	public boolean[] getNonLazyPropertyUpdateability() {
-		return entityMetamodel.getNonlazyPropertyUpdateability();
-	}
-
-	public boolean[] getPropertyInsertability() {
-		return entityMetamodel.getPropertyInsertability();
-	}
-
-	public ValueInclusion[] getPropertyInsertGenerationInclusions() {
-		return entityMetamodel.getPropertyInsertGenerationInclusions();
-	}
-
-	public ValueInclusion[] getPropertyUpdateGenerationInclusions() {
-		return entityMetamodel.getPropertyUpdateGenerationInclusions();
-	}
-
-	public boolean[] getPropertyNullability() {
-		return entityMetamodel.getPropertyNullability();
-	}
-
-	public boolean[] getPropertyVersionability() {
-		return entityMetamodel.getPropertyVersionability();
-	}
-
-	public CascadeStyle[] getPropertyCascadeStyles() {
-		return entityMetamodel.getCascadeStyles();
-	}
-
-	public final Class getMappedClass(EntityMode entityMode) {
-		Tuplizer tup = entityMetamodel.getTuplizerOrNull(entityMode);
-		return tup==null ? null : tup.getMappedClass();
-	}
-
-	public boolean implementsLifecycle(EntityMode entityMode) {
-		return getTuplizer( entityMode ).isLifecycleImplementor();
-	}
-
-	public boolean implementsValidatable(EntityMode entityMode) {
-		return getTuplizer( entityMode ).isValidatableImplementor();
-	}
-
-	public Class getConcreteProxyClass(EntityMode entityMode) {
-		return getTuplizer( entityMode ).getConcreteProxyClass();
-	}
-
-	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode)
-			throws HibernateException {
-		getTuplizer( entityMode ).setPropertyValues( object, values );
-	}
-
-	public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode)
-			throws HibernateException {
-		getTuplizer( entityMode ).setPropertyValue( object, i, value );
-	}
-
-	public Object[] getPropertyValues(Object object, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).getPropertyValues( object );
-	}
-
-	public Object getPropertyValue(Object object, int i, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).getPropertyValue( object , i );
-	}
-
-	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).getPropertyValue( object, propertyName );
-	}
-
-	public Serializable getIdentifier(Object object, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).getIdentifier( object );
-	}
-
-	public void setIdentifier(Object object, Serializable id, EntityMode entityMode)
-			throws HibernateException {
-		getTuplizer( entityMode ).setIdentifier( object, id );
-	}
-
-	public Object getVersion(Object object, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).getVersion( object );
-	}
-
-	public Object instantiate(Serializable id, EntityMode entityMode)
-			throws HibernateException {
-		return getTuplizer( entityMode ).instantiate( id );
-	}
-
-	public boolean isInstance(Object object, EntityMode entityMode) {
-		return getTuplizer( entityMode ).isInstance( object );
-	}
-
-	public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode) {
-		return getTuplizer( entityMode ).hasUninitializedLazyProperties( object );
-	}
-
-	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode) {
-		getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion );
-	}
-
-	public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode) {
-		if ( !hasSubclasses() ) {
-			return this;
-		}
-		else {
-			// TODO : really need a way to do something like :
-			//      getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
-			Class clazz = instance.getClass();
-			if ( clazz == getMappedClass( entityMode ) ) {
-				return this;
-			}
-			else {
-				String subclassEntityName = getSubclassEntityName( clazz );
-				if ( subclassEntityName == null ) {
-					throw new HibernateException(
-							"instance not of expected entity type: " + clazz.getName() +
-							" is not a: " + getEntityName()
-						);
-				}
-				else {
-					return factory.getEntityPersister( subclassEntityName );
-				}
-			}
-		}
-	}
-
-	public EntityMode guessEntityMode(Object object) {
-		return entityMetamodel.guessEntityMode(object);
-	}
-
-	public boolean isMultiTable() {
-		return false;
-	}
-
-	public String getTemporaryIdTableName() {
-		return temporaryIdTableName;
-	}
-
-	public String getTemporaryIdTableDDL() {
-		return temporaryIdTableDDL;
-	}
-
-	protected int getPropertySpan() {
-		return entityMetamodel.getPropertySpan();
-	}
-
-	public Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SessionImplementor session) throws HibernateException {
-		return getTuplizer( session.getEntityMode() ).getPropertyValuesToInsert( object, mergeMap, session );
-	}
-
-	public void processInsertGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) {
-		if ( !hasInsertGeneratedProperties() ) {
-			throw new AssertionFailure("no insert-generated properties");
-		}
-		processGeneratedProperties( id, entity, state, session, sqlInsertGeneratedValuesSelectString, getPropertyInsertGenerationInclusions() );
-	}
-
-	public void processUpdateGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) {
-		if ( !hasUpdateGeneratedProperties() ) {
-			throw new AssertionFailure("no update-generated properties");
-		}
-		processGeneratedProperties( id, entity, state, session, sqlUpdateGeneratedValuesSelectString, getPropertyUpdateGenerationInclusions() );
-	}
-
-	private void processGeneratedProperties(
-			Serializable id,
-	        Object entity,
-	        Object[] state,
-	        SessionImplementor session,
-	        String selectionSQL,
-	        ValueInclusion[] includeds) {
-
-		session.getBatcher().executeBatch(); //force immediate execution of the insert
-
-		try {
-			PreparedStatement ps = session.getBatcher().prepareSelectStatement( selectionSQL );
-			try {
-				getIdentifierType().nullSafeSet( ps, id, 1, session );
-				ResultSet rs = ps.executeQuery();
-				try {
-					if ( !rs.next() ) {
-						throw new HibernateException(
-								"Unable to locate row for retrieval of generated properties: " +
-								MessageHelper.infoString( this, id, getFactory() )
-							);
-					}
-					for ( int i = 0; i < getPropertySpan(); i++ ) {
-						if ( includeds[i] != ValueInclusion.NONE ) {
-							Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity );
-							state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity );
-							setPropertyValue( entity, i, state[i], session.getEntityMode() );
-						}
-					}
-				}
-				finally {
-					if ( rs != null ) {
-						rs.close();
-					}
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( ps );
-			}
-		}
-		catch( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"unable to select generated column values",
-					selectionSQL
-			);
-		}
-
-	}
-
-	public String getIdentifierPropertyName() {
-		return entityMetamodel.getIdentifierProperty().getName();
-	}
-
-	public Type getIdentifierType() {
-		return entityMetamodel.getIdentifierProperty().getType();
-	}
-
-	public boolean hasSubselectLoadableCollections() {
-		return hasSubselectLoadableCollections;
-	}
-
-	public int[] getNaturalIdentifierProperties() {
-		return entityMetamodel.getNaturalIdentifierProperties();
-	}
-
-	public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) throws HibernateException {
-		if ( !hasNaturalIdentifier() ) {
-			throw new MappingException( "persistent class did not define a natural-id : " + MessageHelper.infoString( this ) );
-		}
-		if ( log.isTraceEnabled() ) {
-			log.trace( "Getting current natural-id snapshot state for: " + MessageHelper.infoString( this, id, getFactory() ) );
-		}
-
-		int[] naturalIdPropertyIndexes = getNaturalIdentifierProperties();
-		int naturalIdPropertyCount = naturalIdPropertyIndexes.length;
-		boolean[] naturalIdMarkers = new boolean[ getPropertySpan() ];
-		Type[] extractionTypes = new Type[ naturalIdPropertyCount ];
-		for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
-			extractionTypes[i] = getPropertyTypes()[ naturalIdPropertyIndexes[i] ];
-			naturalIdMarkers[ naturalIdPropertyIndexes[i] ] = true;
-		}
-
-		///////////////////////////////////////////////////////////////////////
-		// TODO : look at perhaps caching this...
-		Select select = new Select( getFactory().getDialect() );
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "get current natural-id state " + getEntityName() );
-		}
-		select.setSelectClause( concretePropertySelectFragmentSansLeadingComma( getRootAlias(), naturalIdMarkers ) );
-		select.setFromClause( fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ) );
-
-		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
-		String whereClause = new StringBuffer()
-			.append( StringHelper.join( "=? and ",
-					aliasedIdColumns ) )
-			.append( "=?" )
-			.append( whereJoinFragment( getRootAlias(), true, false ) )
-			.toString();
-
-		String sql = select.setOuterJoins( "", "" )
-				.setWhereClause( whereClause )
-				.toStatementString();
-		///////////////////////////////////////////////////////////////////////
-
-		Object[] snapshot = new Object[ naturalIdPropertyCount ];
-		try {
-			PreparedStatement ps = session.getBatcher().prepareSelectStatement( sql );
-			try {
-				getIdentifierType().nullSafeSet( ps, id, 1, session );
-				ResultSet rs = ps.executeQuery();
-				try {
-					//if there is no resulting row, return null
-					if ( !rs.next() ) {
-						return null;
-					}
-
-					for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
-						snapshot[i] = extractionTypes[i].hydrate( rs, getPropertyAliases( "", naturalIdPropertyIndexes[i] ), session, null );
-					}
-					return snapshot;
-				}
-				finally {
-					rs.close();
-				}
-			}
-			finally {
-				session.getBatcher().closeStatement( ps );
-			}
-		}
-		catch ( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-					getFactory().getSQLExceptionConverter(),
-					sqle,
-					"could not retrieve snapshot: " +
-					MessageHelper.infoString( this, id, getFactory() ),
-			        sql
-				);
-		}
-	}
-
-	protected String concretePropertySelectFragmentSansLeadingComma(String alias, boolean[] include) {
-		String concretePropertySelectFragment = concretePropertySelectFragment( alias, include );
-		int firstComma = concretePropertySelectFragment.indexOf( ", " );
-		if ( firstComma == 0 ) {
-			concretePropertySelectFragment = concretePropertySelectFragment.substring( 2 );
-		}
-		return concretePropertySelectFragment;
-	}
-	public boolean hasNaturalIdentifier() {
-		return entityMetamodel.hasNaturalIdentifier();
-	}
-
-	public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode)
-			throws HibernateException {
-		getTuplizer( entityMode ).setPropertyValue( object, propertyName, value );
-	}
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,3873 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.Comparator;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.StaleStateException;
+import org.hibernate.jdbc.Expectation;
+import org.hibernate.jdbc.Expectations;
+import org.hibernate.jdbc.TooManyRowsAffectedException;
+import org.hibernate.dialect.lock.LockingStrategy;
+import org.hibernate.cache.CacheConcurrencyStrategy;
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.entry.CacheEntry;
+import org.hibernate.cache.entry.CacheEntryStructure;
+import org.hibernate.cache.entry.StructuredCacheEntry;
+import org.hibernate.cache.entry.UnstructuredCacheEntry;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.Versioning;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.ValueInclusion;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.PostInsertIdentifierGenerator;
+import org.hibernate.id.PostInsertIdentityPersister;
+import org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;
+import org.hibernate.id.insert.Binder;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.loader.entity.BatchingEntityLoader;
+import org.hibernate.loader.entity.CascadeEntityLoader;
+import org.hibernate.loader.entity.EntityLoader;
+import org.hibernate.loader.entity.UniqueEntityLoader;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.pretty.MessageHelper;
+import org.hibernate.property.BackrefPropertyAccessor;
+import org.hibernate.sql.Alias;
+import org.hibernate.sql.Delete;
+import org.hibernate.sql.Insert;
+import org.hibernate.sql.JoinFragment;
+import org.hibernate.sql.Select;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.sql.Template;
+import org.hibernate.sql.Update;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.tuple.entity.EntityTuplizer;
+import org.hibernate.tuple.Tuplizer;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.type.VersionType;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.CollectionHelper;
+import org.hibernate.util.FilterHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Basic functionality for persisting an entity via JDBC
+ * through either generated or custom SQL
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractEntityPersister
+		implements OuterJoinLoadable, Queryable, ClassMetadata, UniqueKeyLoadable,
+		SQLLoadable, LazyPropertyInitializer, PostInsertIdentityPersister, Lockable {
+
+	private static final Logger log = LoggerFactory.getLogger( AbstractEntityPersister.class );
+
+	public static final String ENTITY_CLASS = "class";
+
+	// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private final SessionFactoryImplementor factory;
+	private final EntityRegionAccessStrategy cacheAccessStrategy;
+	private final boolean isLazyPropertiesCacheable;
+	private final CacheEntryStructure cacheEntryStructure;
+	private final EntityMetamodel entityMetamodel;
+	private final Map entityNameBySubclass = new HashMap();
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	private final String[] rootTableKeyColumnNames;
+	private final String[] identifierAliases;
+	private final int identifierColumnSpan;
+	private final String versionColumnName;
+	private final boolean hasFormulaProperties;
+	private final int batchSize;
+	private final boolean hasSubselectLoadableCollections;
+	protected final String rowIdName;
+
+	private final Set lazyProperties;
+
+	// The optional SQL string defined in the where attribute
+	private final String sqlWhereString;
+	private final String sqlWhereStringTemplate;
+
+	//information about properties of this class,
+	//including inherited properties
+	//(only really needed for updatable/insertable properties)
+	private final int[] propertyColumnSpans;
+	private final String[] propertySubclassNames;
+	private final String[][] propertyColumnAliases;
+	private final String[][] propertyColumnNames;
+	private final String[][] propertyColumnFormulaTemplates;
+	private final boolean[][] propertyColumnUpdateable;
+	private final boolean[][] propertyColumnInsertable;
+	private final boolean[] propertyUniqueness;
+	private final boolean[] propertySelectable;
+
+	//information about lazy properties of this class
+	private final String[] lazyPropertyNames;
+	private final int[] lazyPropertyNumbers;
+	private final Type[] lazyPropertyTypes;
+	private final String[][] lazyPropertyColumnAliases;
+
+	//information about all properties in class hierarchy
+	private final String[] subclassPropertyNameClosure;
+	private final String[] subclassPropertySubclassNameClosure;
+	private final Type[] subclassPropertyTypeClosure;
+	private final String[][] subclassPropertyFormulaTemplateClosure;
+	private final String[][] subclassPropertyColumnNameClosure;
+	private final FetchMode[] subclassPropertyFetchModeClosure;
+	private final boolean[] subclassPropertyNullabilityClosure;
+	private final boolean[] propertyDefinedOnSubclass;
+	private final int[][] subclassPropertyColumnNumberClosure;
+	private final int[][] subclassPropertyFormulaNumberClosure;
+	private final CascadeStyle[] subclassPropertyCascadeStyleClosure;
+
+	//information about all columns/formulas in class hierarchy
+	private final String[] subclassColumnClosure;
+	private final boolean[] subclassColumnLazyClosure;
+	private final String[] subclassColumnAliasClosure;
+	private final boolean[] subclassColumnSelectableClosure;
+	private final String[] subclassFormulaClosure;
+	private final String[] subclassFormulaTemplateClosure;
+	private final String[] subclassFormulaAliasClosure;
+	private final boolean[] subclassFormulaLazyClosure;
+
+	// dynamic filters attached to the class-level
+	private final FilterHelper filterHelper;
+
+	private final Map uniqueKeyLoaders = new HashMap();
+	private final Map lockers = new HashMap();
+	private final Map loaders = new HashMap();
+
+	// SQL strings
+	private String sqlVersionSelectString;
+	private String sqlSnapshotSelectString;
+	private String sqlLazySelectString;
+
+	private String sqlIdentityInsertString;
+	private String sqlUpdateByRowIdString;
+	private String sqlLazyUpdateByRowIdString;
+
+	private String[] sqlDeleteStrings;
+	private String[] sqlInsertStrings;
+	private String[] sqlUpdateStrings;
+	private String[] sqlLazyUpdateStrings;
+
+	private String sqlInsertGeneratedValuesSelectString;
+	private String sqlUpdateGeneratedValuesSelectString;
+
+	//Custom SQL (would be better if these were private)
+	protected boolean[] insertCallable;
+	protected boolean[] updateCallable;
+	protected boolean[] deleteCallable;
+	protected String[] customSQLInsert;
+	protected String[] customSQLUpdate;
+	protected String[] customSQLDelete;
+	protected ExecuteUpdateResultCheckStyle[] insertResultCheckStyles;
+	protected ExecuteUpdateResultCheckStyle[] updateResultCheckStyles;
+	protected ExecuteUpdateResultCheckStyle[] deleteResultCheckStyles;
+
+	private InsertGeneratedIdentifierDelegate identityDelegate;
+
+	private boolean[] tableHasColumns;
+
+	private final String loaderName;
+
+	private UniqueEntityLoader queryLoader;
+
+	private final String temporaryIdTableName;
+	private final String temporaryIdTableDDL;
+
+	private final Map subclassPropertyAliases = new HashMap();
+	private final Map subclassPropertyColumnNames = new HashMap();
+
+	protected final BasicEntityPropertyMapping propertyMapping;
+
+	protected void addDiscriminatorToInsert(Insert insert) {}
+
+	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {}
+
+	protected abstract int[] getSubclassColumnTableNumberClosure();
+
+	protected abstract int[] getSubclassFormulaTableNumberClosure();
+
+	public abstract String getSubclassTableName(int j);
+
+	protected abstract String[] getSubclassTableKeyColumns(int j);
+
+	protected abstract boolean isClassOrSuperclassTable(int j);
+
+	protected abstract int getSubclassTableSpan();
+
+	protected abstract int getTableSpan();
+
+	protected abstract boolean isTableCascadeDeleteEnabled(int j);
+
+	protected abstract String getTableName(int j);
+
+	protected abstract String[] getKeyColumns(int j);
+
+	protected abstract boolean isPropertyOfTable(int property, int j);
+
+	protected abstract int[] getPropertyTableNumbersInSelect();
+
+	protected abstract int[] getPropertyTableNumbers();
+
+	protected abstract int getSubclassPropertyTableNumber(int i);
+
+	protected abstract String filterFragment(String alias) throws MappingException;
+
+	private static final String DISCRIMINATOR_ALIAS = "clazz_";
+
+	public String getDiscriminatorColumnName() {
+		return DISCRIMINATOR_ALIAS;
+	}
+
+	protected String getDiscriminatorAlias() {
+		return DISCRIMINATOR_ALIAS;
+	}
+
+	protected String getDiscriminatorFormulaTemplate() {
+		return null;
+	}
+
+	protected boolean isInverseTable(int j) {
+		return false;
+	}
+
+	protected boolean isNullableTable(int j) {
+		return false;
+	}
+
+	protected boolean isNullableSubclassTable(int j) {
+		return false;
+	}
+
+	protected boolean isInverseSubclassTable(int j) {
+		return false;
+	}
+
+	public boolean isSubclassEntityName(String entityName) {
+		return entityMetamodel.getSubclassEntityNames().contains(entityName);
+	}
+
+	private boolean[] getTableHasColumns() {
+		return tableHasColumns;
+	}
+
+	public String[] getRootTableKeyColumnNames() {
+		return rootTableKeyColumnNames;
+	}
+
+	protected String[] getSQLUpdateByRowIdStrings() {
+		if ( sqlUpdateByRowIdString == null ) {
+			throw new AssertionFailure( "no update by row id" );
+		}
+		String[] result = new String[getTableSpan() + 1];
+		result[0] = sqlUpdateByRowIdString;
+		System.arraycopy( sqlUpdateStrings, 0, result, 1, getTableSpan() );
+		return result;
+	}
+
+	protected String[] getSQLLazyUpdateByRowIdStrings() {
+		if ( sqlLazyUpdateByRowIdString == null ) {
+			throw new AssertionFailure( "no update by row id" );
+		}
+		String[] result = new String[getTableSpan()];
+		result[0] = sqlLazyUpdateByRowIdString;
+		for ( int i = 1; i < getTableSpan(); i++ ) {
+			result[i] = sqlLazyUpdateStrings[i];
+		}
+		return result;
+	}
+
+	protected String getSQLSnapshotSelectString() {
+		return sqlSnapshotSelectString;
+	}
+
+	protected String getSQLLazySelectString() {
+		return sqlLazySelectString;
+	}
+
+	protected String[] getSQLDeleteStrings() {
+		return sqlDeleteStrings;
+	}
+
+	protected String[] getSQLInsertStrings() {
+		return sqlInsertStrings;
+	}
+
+	protected String[] getSQLUpdateStrings() {
+		return sqlUpdateStrings;
+	}
+
+	protected String[] getSQLLazyUpdateStrings() {
+		return sqlLazyUpdateStrings;
+	}
+
+	/**
+	 * The query that inserts a row, letting the database generate an id
+	 * 
+	 * @return The IDENTITY-based insertion query.
+	 */
+	protected String getSQLIdentityInsertString() {
+		return sqlIdentityInsertString;
+	}
+
+	protected String getVersionSelectString() {
+		return sqlVersionSelectString;
+	}
+
+	protected boolean isInsertCallable(int j) {
+		return insertCallable[j];
+	}
+
+	protected boolean isUpdateCallable(int j) {
+		return updateCallable[j];
+	}
+
+	protected boolean isDeleteCallable(int j) {
+		return deleteCallable[j];
+	}
+
+	protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) {
+		return false;
+	}
+
+	protected boolean isSubclassTableSequentialSelect(int j) {
+		return false;
+	}
+
+	public boolean hasSequentialSelect() {
+		return false;
+	}
+
+	/**
+	 * Decide which tables need to be updated.
+	 * <p/>
+	 * The return here is an array of boolean values with each index corresponding
+	 * to a given table in the scope of this persister.
+	 *
+	 * @param dirtyProperties The indices of all the entity properties considered dirty.
+	 * @param hasDirtyCollection Whether any collections owned by the entity which were considered dirty.
+	 *
+	 * @return Array of booleans indicating which table require updating.
+	 */
+	protected boolean[] getTableUpdateNeeded(final int[] dirtyProperties, boolean hasDirtyCollection) {
+
+		if ( dirtyProperties == null ) {
+			return getTableHasColumns(); // for objects that came in via update()
+		}
+		else {
+			boolean[] updateability = getPropertyUpdateability();
+			int[] propertyTableNumbers = getPropertyTableNumbers();
+			boolean[] tableUpdateNeeded = new boolean[ getTableSpan() ];
+			for ( int i = 0; i < dirtyProperties.length; i++ ) {
+				int property = dirtyProperties[i];
+				int table = propertyTableNumbers[property];
+				tableUpdateNeeded[table] = tableUpdateNeeded[table] ||
+						( getPropertyColumnSpan(property) > 0 && updateability[property] );
+			}
+			if ( isVersioned() ) {
+				tableUpdateNeeded[0] = tableUpdateNeeded[0] ||
+					Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() );
+			}
+			return tableUpdateNeeded;
+		}
+	}
+
+	public boolean hasRowId() {
+		return rowIdName != null;
+	}
+
+	public AbstractEntityPersister(
+			final PersistentClass persistentClass,
+			final EntityRegionAccessStrategy cacheAccessStrategy,
+			final SessionFactoryImplementor factory) throws HibernateException {
+
+		// moved up from AbstractEntityPersister ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		this.factory = factory;
+		this.cacheAccessStrategy = cacheAccessStrategy;
+		isLazyPropertiesCacheable = persistentClass.isLazyPropertiesCacheable();
+		this.cacheEntryStructure = factory.getSettings().isStructuredCacheEntriesEnabled() ?
+				(CacheEntryStructure) new StructuredCacheEntry(this) :
+				(CacheEntryStructure) new UnstructuredCacheEntry();
+
+		this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
+
+		if ( persistentClass.hasPojoRepresentation() ) {
+			//TODO: this is currently specific to pojos, but need to be available for all entity-modes
+			Iterator iter = persistentClass.getSubclassIterator();
+			while ( iter.hasNext() ) {
+				PersistentClass pc = ( PersistentClass ) iter.next();
+				entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() );
+			}
+		}
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+		int batch = persistentClass.getBatchSize();
+		if ( batch == -1 ) {
+			batch = factory.getSettings().getDefaultBatchFetchSize();
+		}
+		batchSize = batch;
+		hasSubselectLoadableCollections = persistentClass.hasSubselectLoadableCollections();
+
+		propertyMapping = new BasicEntityPropertyMapping( this );
+
+		// IDENTIFIER
+
+		identifierColumnSpan = persistentClass.getIdentifier().getColumnSpan();
+		rootTableKeyColumnNames = new String[identifierColumnSpan];
+		identifierAliases = new String[identifierColumnSpan];
+
+		rowIdName = persistentClass.getRootTable().getRowId();
+
+		loaderName = persistentClass.getLoaderName();
+
+		Iterator iter = persistentClass.getIdentifier().getColumnIterator();
+		int i = 0;
+		while ( iter.hasNext() ) {
+			Column col = ( Column ) iter.next();
+			rootTableKeyColumnNames[i] = col.getQuotedName( factory.getDialect() );
+			identifierAliases[i] = col.getAlias( factory.getDialect(), persistentClass.getRootTable() );
+			i++;
+		}
+
+		// VERSION
+
+		if ( persistentClass.isVersioned() ) {
+			versionColumnName = ( ( Column ) persistentClass.getVersion().getColumnIterator().next() ).getQuotedName( factory.getDialect() );
+		}
+		else {
+			versionColumnName = null;
+		}
+
+		//WHERE STRING
+
+		sqlWhereString = StringHelper.isNotEmpty( persistentClass.getWhere() ) ? "( " + persistentClass.getWhere() + ") " : null;
+		sqlWhereStringTemplate = sqlWhereString == null ?
+				null :
+				Template.renderWhereStringTemplate( sqlWhereString, factory.getDialect(), factory.getSqlFunctionRegistry() );
+
+		// PROPERTIES
+
+		final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
+
+		int hydrateSpan = entityMetamodel.getPropertySpan();
+		propertyColumnSpans = new int[hydrateSpan];
+		propertySubclassNames = new String[hydrateSpan];
+		propertyColumnAliases = new String[hydrateSpan][];
+		propertyColumnNames = new String[hydrateSpan][];
+		propertyColumnFormulaTemplates = new String[hydrateSpan][];
+		propertyUniqueness = new boolean[hydrateSpan];
+		propertySelectable = new boolean[hydrateSpan];
+		propertyColumnUpdateable = new boolean[hydrateSpan][];
+		propertyColumnInsertable = new boolean[hydrateSpan][];
+		HashSet thisClassProperties = new HashSet();
+
+		lazyProperties = new HashSet();
+		ArrayList lazyNames = new ArrayList();
+		ArrayList lazyNumbers = new ArrayList();
+		ArrayList lazyTypes = new ArrayList();
+		ArrayList lazyColAliases = new ArrayList();
+
+		iter = persistentClass.getPropertyClosureIterator();
+		i = 0;
+		boolean foundFormula = false;
+		while ( iter.hasNext() ) {
+			Property prop = ( Property ) iter.next();
+			thisClassProperties.add( prop );
+
+			int span = prop.getColumnSpan();
+			propertyColumnSpans[i] = span;
+			propertySubclassNames[i] = prop.getPersistentClass().getEntityName();
+			String[] colNames = new String[span];
+			String[] colAliases = new String[span];
+			String[] templates = new String[span];
+			Iterator colIter = prop.getColumnIterator();
+			int k = 0;
+			while ( colIter.hasNext() ) {
+				Selectable thing = ( Selectable ) colIter.next();
+				colAliases[k] = thing.getAlias( factory.getDialect() , prop.getValue().getTable() );
+				if ( thing.isFormula() ) {
+					foundFormula = true;
+					templates[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
+				}
+				else {
+					colNames[k] = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
+				}
+				k++;
+			}
+			propertyColumnNames[i] = colNames;
+			propertyColumnFormulaTemplates[i] = templates;
+			propertyColumnAliases[i] = colAliases;
+
+			if ( lazyAvailable && prop.isLazy() ) {
+				lazyProperties.add( prop.getName() );
+				lazyNames.add( prop.getName() );
+				lazyNumbers.add( new Integer( i ) );
+				lazyTypes.add( prop.getValue().getType() );
+				lazyColAliases.add( colAliases );
+			}
+
+			propertyColumnUpdateable[i] = prop.getValue().getColumnUpdateability();
+			propertyColumnInsertable[i] = prop.getValue().getColumnInsertability();
+
+			propertySelectable[i] = prop.isSelectable();
+
+			propertyUniqueness[i] = prop.getValue().isAlternateUniqueKey();
+
+			i++;
+
+		}
+		hasFormulaProperties = foundFormula;
+		lazyPropertyColumnAliases = ArrayHelper.to2DStringArray( lazyColAliases );
+		lazyPropertyNames = ArrayHelper.toStringArray( lazyNames );
+		lazyPropertyNumbers = ArrayHelper.toIntArray( lazyNumbers );
+		lazyPropertyTypes = ArrayHelper.toTypeArray( lazyTypes );
+
+		// SUBCLASS PROPERTY CLOSURE
+
+		ArrayList columns = new ArrayList();
+		ArrayList columnsLazy = new ArrayList();
+		ArrayList aliases = new ArrayList();
+		ArrayList formulas = new ArrayList();
+		ArrayList formulaAliases = new ArrayList();
+		ArrayList formulaTemplates = new ArrayList();
+		ArrayList formulasLazy = new ArrayList();
+		ArrayList types = new ArrayList();
+		ArrayList names = new ArrayList();
+		ArrayList classes = new ArrayList();
+		ArrayList templates = new ArrayList();
+		ArrayList propColumns = new ArrayList();
+		ArrayList joinedFetchesList = new ArrayList();
+		ArrayList cascades = new ArrayList();
+		ArrayList definedBySubclass = new ArrayList();
+		ArrayList propColumnNumbers = new ArrayList();
+		ArrayList propFormulaNumbers = new ArrayList();
+		ArrayList columnSelectables = new ArrayList();
+		ArrayList propNullables = new ArrayList();
+
+		iter = persistentClass.getSubclassPropertyClosureIterator();
+		while ( iter.hasNext() ) {
+			Property prop = ( Property ) iter.next();
+			names.add( prop.getName() );
+			classes.add( prop.getPersistentClass().getEntityName() );
+			boolean isDefinedBySubclass = !thisClassProperties.contains( prop );
+			definedBySubclass.add( Boolean.valueOf( isDefinedBySubclass ) );
+			propNullables.add( Boolean.valueOf( prop.isOptional() || isDefinedBySubclass ) ); //TODO: is this completely correct?
+			types.add( prop.getType() );
+
+			Iterator colIter = prop.getColumnIterator();
+			String[] cols = new String[prop.getColumnSpan()];
+			String[] forms = new String[prop.getColumnSpan()];
+			int[] colnos = new int[prop.getColumnSpan()];
+			int[] formnos = new int[prop.getColumnSpan()];
+			int l = 0;
+			Boolean lazy = Boolean.valueOf( prop.isLazy() && lazyAvailable );
+			while ( colIter.hasNext() ) {
+				Selectable thing = ( Selectable ) colIter.next();
+				if ( thing.isFormula() ) {
+					String template = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
+					formnos[l] = formulaTemplates.size();
+					colnos[l] = -1;
+					formulaTemplates.add( template );
+					forms[l] = template;
+					formulas.add( thing.getText( factory.getDialect() ) );
+					formulaAliases.add( thing.getAlias( factory.getDialect() ) );
+					formulasLazy.add( lazy );
+				}
+				else {
+					String colName = thing.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
+					colnos[l] = columns.size(); //before add :-)
+					formnos[l] = -1;
+					columns.add( colName );
+					cols[l] = colName;
+					aliases.add( thing.getAlias( factory.getDialect(), prop.getValue().getTable() ) );
+					columnsLazy.add( lazy );
+					columnSelectables.add( Boolean.valueOf( prop.isSelectable() ) );
+				}
+				l++;
+			}
+			propColumns.add( cols );
+			templates.add( forms );
+			propColumnNumbers.add( colnos );
+			propFormulaNumbers.add( formnos );
+
+			joinedFetchesList.add( prop.getValue().getFetchMode() );
+			cascades.add( prop.getCascadeStyle() );
+		}
+		subclassColumnClosure = ArrayHelper.toStringArray( columns );
+		subclassColumnAliasClosure = ArrayHelper.toStringArray( aliases );
+		subclassColumnLazyClosure = ArrayHelper.toBooleanArray( columnsLazy );
+		subclassColumnSelectableClosure = ArrayHelper.toBooleanArray( columnSelectables );
+
+		subclassFormulaClosure = ArrayHelper.toStringArray( formulas );
+		subclassFormulaTemplateClosure = ArrayHelper.toStringArray( formulaTemplates );
+		subclassFormulaAliasClosure = ArrayHelper.toStringArray( formulaAliases );
+		subclassFormulaLazyClosure = ArrayHelper.toBooleanArray( formulasLazy );
+
+		subclassPropertyNameClosure = ArrayHelper.toStringArray( names );
+		subclassPropertySubclassNameClosure = ArrayHelper.toStringArray( classes );
+		subclassPropertyTypeClosure = ArrayHelper.toTypeArray( types );
+		subclassPropertyNullabilityClosure = ArrayHelper.toBooleanArray( propNullables );
+		subclassPropertyFormulaTemplateClosure = ArrayHelper.to2DStringArray( templates );
+		subclassPropertyColumnNameClosure = ArrayHelper.to2DStringArray( propColumns );
+		subclassPropertyColumnNumberClosure = ArrayHelper.to2DIntArray( propColumnNumbers );
+		subclassPropertyFormulaNumberClosure = ArrayHelper.to2DIntArray( propFormulaNumbers );
+
+		subclassPropertyCascadeStyleClosure = new CascadeStyle[cascades.size()];
+		iter = cascades.iterator();
+		int j = 0;
+		while ( iter.hasNext() ) {
+			subclassPropertyCascadeStyleClosure[j++] = ( CascadeStyle ) iter.next();
+		}
+		subclassPropertyFetchModeClosure = new FetchMode[joinedFetchesList.size()];
+		iter = joinedFetchesList.iterator();
+		j = 0;
+		while ( iter.hasNext() ) {
+			subclassPropertyFetchModeClosure[j++] = ( FetchMode ) iter.next();
+		}
+
+		propertyDefinedOnSubclass = new boolean[definedBySubclass.size()];
+		iter = definedBySubclass.iterator();
+		j = 0;
+		while ( iter.hasNext() ) {
+			propertyDefinedOnSubclass[j++] = ( ( Boolean ) iter.next() ).booleanValue();
+		}
+
+		// Handle any filters applied to the class level
+		filterHelper = new FilterHelper( persistentClass.getFilterMap(), factory.getDialect(), factory.getSqlFunctionRegistry() );
+
+		temporaryIdTableName = persistentClass.getTemporaryIdTableName();
+		temporaryIdTableDDL = persistentClass.getTemporaryIdTableDDL();
+	}
+
+	protected String generateLazySelectString() {
+
+		if ( !entityMetamodel.hasLazyProperties() ) {
+			return null;
+		}
+
+		HashSet tableNumbers = new HashSet();
+		ArrayList columnNumbers = new ArrayList();
+		ArrayList formulaNumbers = new ArrayList();
+		for ( int i = 0; i < lazyPropertyNames.length; i++ ) {
+			// all this only really needs to consider properties
+			// of this class, not its subclasses, but since we
+			// are reusing code used for sequential selects, we
+			// use the subclass closure
+			int propertyNumber = getSubclassPropertyIndex( lazyPropertyNames[i] );
+
+			int tableNumber = getSubclassPropertyTableNumber( propertyNumber );
+			tableNumbers.add( new Integer( tableNumber ) );
+
+			int[] colNumbers = subclassPropertyColumnNumberClosure[propertyNumber];
+			for ( int j = 0; j < colNumbers.length; j++ ) {
+				if ( colNumbers[j]!=-1 ) {
+					columnNumbers.add( new Integer( colNumbers[j] ) );
+				}
+			}
+			int[] formNumbers = subclassPropertyFormulaNumberClosure[propertyNumber];
+			for ( int j = 0; j < formNumbers.length; j++ ) {
+				if ( formNumbers[j]!=-1 ) {
+					formulaNumbers.add( new Integer( formNumbers[j] ) );
+				}
+			}
+		}
+
+		if ( columnNumbers.size()==0 && formulaNumbers.size()==0 ) {
+			// only one-to-one is lazy fetched
+			return null;
+		}
+
+		return renderSelect( ArrayHelper.toIntArray( tableNumbers ),
+				ArrayHelper.toIntArray( columnNumbers ),
+				ArrayHelper.toIntArray( formulaNumbers ) );
+
+	}
+
+	public Object initializeLazyProperty(String fieldName, Object entity, SessionImplementor session)
+			throws HibernateException {
+
+		final Serializable id = session.getContextEntityIdentifier( entity );
+
+		final EntityEntry entry = session.getPersistenceContext().getEntry( entity );
+		if ( entry == null ) {
+			throw new HibernateException( "entity is not associated with the session: " + id );
+		}
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"initializing lazy properties of: " +
+					MessageHelper.infoString( this, id, getFactory() ) +
+					", field access: " + fieldName
+				);
+		}
+
+		if ( hasCache() ) {
+			CacheKey cacheKey = new CacheKey(id, getIdentifierType(), getEntityName(), session.getEntityMode(), getFactory() );
+			Object ce = getCacheAccessStrategy().get( cacheKey, session.getTimestamp() );
+			if (ce!=null) {
+				CacheEntry cacheEntry = (CacheEntry) getCacheEntryStructure().destructure(ce, factory);
+				if ( !cacheEntry.areLazyPropertiesUnfetched() ) {
+					//note early exit here:
+					return initializeLazyPropertiesFromCache( fieldName, entity, session, entry, cacheEntry );
+				}
+			}
+		}
+
+		return initializeLazyPropertiesFromDatastore( fieldName, entity, session, id, entry );
+
+	}
+
+	private Object initializeLazyPropertiesFromDatastore(
+			final String fieldName,
+			final Object entity,
+			final SessionImplementor session,
+			final Serializable id,
+			final EntityEntry entry) {
+
+		if ( !hasLazyProperties() ) {
+			throw new AssertionFailure("no lazy properties");
+		}
+
+		log.trace("initializing lazy properties from datastore");
+
+		try {
+
+			Object result = null;
+			PreparedStatement ps = null;
+			try {
+				final String lazySelect = getSQLLazySelectString();
+				ResultSet rs = null;
+				try {
+					if ( lazySelect != null ) {
+						// null sql means that the only lazy properties
+						// are shared PK one-to-one associations which are
+						// handled differently in the Type#nullSafeGet code...
+						ps = session.getBatcher().prepareSelectStatement(lazySelect);
+						getIdentifierType().nullSafeSet( ps, id, 1, session );
+						rs = ps.executeQuery();
+						rs.next();
+					}
+					final Object[] snapshot = entry.getLoadedState();
+					for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
+						Object propValue = lazyPropertyTypes[j].nullSafeGet( rs, lazyPropertyColumnAliases[j], session, entity );
+						if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
+							result = propValue;
+						}
+					}
+				}
+				finally {
+					if ( rs != null ) {
+						rs.close();
+					}
+				}
+			}
+			finally {
+				if ( ps != null ) {
+					session.getBatcher().closeStatement( ps );
+				}
+			}
+
+			log.trace( "done initializing lazy properties" );
+
+			return result;
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not initialize lazy properties: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+					getSQLLazySelectString()
+				);
+		}
+	}
+
+	private Object initializeLazyPropertiesFromCache(
+			final String fieldName,
+			final Object entity,
+			final SessionImplementor session,
+			final EntityEntry entry,
+			final CacheEntry cacheEntry
+	) {
+
+		log.trace("initializing lazy properties from second-level cache");
+
+		Object result = null;
+		Serializable[] disassembledValues = cacheEntry.getDisassembledState();
+		final Object[] snapshot = entry.getLoadedState();
+		for ( int j = 0; j < lazyPropertyNames.length; j++ ) {
+			final Object propValue = lazyPropertyTypes[j].assemble(
+					disassembledValues[ lazyPropertyNumbers[j] ],
+					session,
+					entity
+				);
+			if ( initializeLazyProperty( fieldName, entity, session, snapshot, j, propValue ) ) {
+				result = propValue;
+			}
+		}
+
+		log.trace( "done initializing lazy properties" );
+
+		return result;
+	}
+
+	private boolean initializeLazyProperty(
+			final String fieldName,
+			final Object entity,
+			final SessionImplementor session,
+			final Object[] snapshot,
+			final int j,
+			final Object propValue) {
+		setPropertyValue( entity, lazyPropertyNumbers[j], propValue, session.getEntityMode() );
+		if (snapshot != null) {
+			// object have been loaded with setReadOnly(true); HHH-2236
+			snapshot[ lazyPropertyNumbers[j] ] = lazyPropertyTypes[j].deepCopy( propValue, session.getEntityMode(), factory );
+		}
+		return fieldName.equals( lazyPropertyNames[j] );
+	}
+
+	public boolean isBatchable() {
+		return optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_NONE ||
+			( !isVersioned() && optimisticLockMode()==Versioning.OPTIMISTIC_LOCK_VERSION ) ||
+			getFactory().getSettings().isJdbcBatchVersionedData();
+	}
+
+	public Serializable[] getQuerySpaces() {
+		return getPropertySpaces();
+	}
+
+	protected Set getLazyProperties() {
+		return lazyProperties;
+	}
+
+	public boolean isBatchLoadable() {
+		return batchSize > 1;
+	}
+
+	public String[] getIdentifierColumnNames() {
+		return rootTableKeyColumnNames;
+	}
+
+	protected int getIdentifierColumnSpan() {
+		return identifierColumnSpan;
+	}
+
+	protected String[] getIdentifierAliases() {
+		return identifierAliases;
+	}
+
+	public String getVersionColumnName() {
+		return versionColumnName;
+	}
+
+	protected String getVersionedTableName() {
+		return getTableName( 0 );
+	}
+
+	protected boolean[] getSubclassColumnLazyiness() {
+		return subclassColumnLazyClosure;
+	}
+
+	protected boolean[] getSubclassFormulaLazyiness() {
+		return subclassFormulaLazyClosure;
+	}
+
+	/**
+	 * We can't immediately add to the cache if we have formulas
+	 * which must be evaluated, or if we have the possibility of
+	 * two concurrent updates to the same item being merged on
+	 * the database. This can happen if (a) the item is not
+	 * versioned and either (b) we have dynamic update enabled
+	 * or (c) we have multiple tables holding the state of the
+	 * item.
+	 */
+	public boolean isCacheInvalidationRequired() {
+		return hasFormulaProperties() ||
+				( !isVersioned() && ( entityMetamodel.isDynamicUpdate() || getTableSpan() > 1 ) );
+	}
+
+	public boolean isLazyPropertiesCacheable() {
+		return isLazyPropertiesCacheable;
+	}
+
+	public String selectFragment(String alias, String suffix) {
+		return identifierSelectFragment( alias, suffix ) +
+				propertySelectFragment( alias, suffix, false );
+	}
+
+	public String[] getIdentifierAliases(String suffix) {
+		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
+		// was toUnqotedAliasStrings( getIdentiferColumnNames() ) before - now tried
+		// to remove that unqoting and missing aliases..
+		return new Alias( suffix ).toAliasStrings( getIdentifierAliases() );
+	}
+
+	public String[] getPropertyAliases(String suffix, int i) {
+		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
+		return new Alias( suffix ).toUnquotedAliasStrings( propertyColumnAliases[i] );
+	}
+
+	public String getDiscriminatorAlias(String suffix) {
+		// NOTE: this assumes something about how propertySelectFragment is implemented by the subclass!
+		// was toUnqotedAliasStrings( getdiscriminatorColumnName() ) before - now tried
+		// to remove that unqoting and missing aliases..
+		return entityMetamodel.hasSubclasses() ?
+				new Alias( suffix ).toAliasString( getDiscriminatorAlias() ) :
+				null;
+	}
+
+	public String identifierSelectFragment(String name, String suffix) {
+		return new SelectFragment()
+				.setSuffix( suffix )
+				.addColumns( name, getIdentifierColumnNames(), getIdentifierAliases() )
+				.toFragmentString()
+				.substring( 2 ); //strip leading ", "
+	}
+
+
+	public String propertySelectFragment(String name, String suffix, boolean allProperties) {
+
+		SelectFragment select = new SelectFragment()
+				.setSuffix( suffix )
+				.setUsedAliases( getIdentifierAliases() );
+
+		int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
+		String[] columnAliases = getSubclassColumnAliasClosure();
+		String[] columns = getSubclassColumnClosure();
+		for ( int i = 0; i < getSubclassColumnClosure().length; i++ ) {
+			boolean selectable = ( allProperties || !subclassColumnLazyClosure[i] ) &&
+				!isSubclassTableSequentialSelect( columnTableNumbers[i] ) &&
+				subclassColumnSelectableClosure[i];
+			if ( selectable ) {
+				String subalias = generateTableAlias( name, columnTableNumbers[i] );
+				select.addColumn( subalias, columns[i], columnAliases[i] );
+			}
+		}
+
+		int[] formulaTableNumbers = getSubclassFormulaTableNumberClosure();
+		String[] formulaTemplates = getSubclassFormulaTemplateClosure();
+		String[] formulaAliases = getSubclassFormulaAliasClosure();
+		for ( int i = 0; i < getSubclassFormulaTemplateClosure().length; i++ ) {
+			boolean selectable = ( allProperties || !subclassFormulaLazyClosure[i] )
+				&& !isSubclassTableSequentialSelect( formulaTableNumbers[i] );
+			if ( selectable ) {
+				String subalias = generateTableAlias( name, formulaTableNumbers[i] );
+				select.addFormula( subalias, formulaTemplates[i], formulaAliases[i] );
+			}
+		}
+
+		if ( entityMetamodel.hasSubclasses() ) {
+			addDiscriminatorToSelect( select, name, suffix );
+		}
+
+		if ( hasRowId() ) {
+			select.addColumn( name, rowIdName, ROWID_ALIAS );
+		}
+
+		return select.toFragmentString();
+	}
+
+	public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session)
+			throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Getting current persistent state for: " + MessageHelper.infoString( this, id, getFactory() ) );
+		}
+
+		try {
+			PreparedStatement ps = session.getBatcher().prepareSelectStatement( getSQLSnapshotSelectString() );
+			try {
+				getIdentifierType().nullSafeSet( ps, id, 1, session );
+				//if ( isVersioned() ) getVersionType().nullSafeSet( ps, version, getIdentifierColumnSpan()+1, session );
+				ResultSet rs = ps.executeQuery();
+				try {
+					//if there is no resulting row, return null
+					if ( !rs.next() ) {
+						return null;
+					}
+
+					//otherwise return the "hydrated" state (ie. associations are not resolved)
+					Type[] types = getPropertyTypes();
+					Object[] values = new Object[types.length];
+					boolean[] includeProperty = getPropertyUpdateability();
+					for ( int i = 0; i < types.length; i++ ) {
+						if ( includeProperty[i] ) {
+							values[i] = types[i].hydrate( rs, getPropertyAliases( "", i ), session, null ); //null owner ok??
+						}
+					}
+					return values;
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( ps );
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve snapshot: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+			        getSQLSnapshotSelectString()
+				);
+		}
+
+	}
+
+	/**
+	 * Generate the SQL that selects the version number by id
+	 */
+	protected String generateSelectVersionString() {
+		SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
+				.setTableName( getVersionedTableName() );
+		if ( isVersioned() ) {
+			select.addColumn( versionColumnName );
+		}
+		else {
+			select.addColumns( rootTableKeyColumnNames );
+		}
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "get version " + getEntityName() );
+		}
+		return select.addCondition( rootTableKeyColumnNames, "=?" ).toStatementString();
+	}
+
+	protected String generateInsertGeneratedValuesSelectString() {
+		return generateGeneratedValuesSelectString( getPropertyInsertGenerationInclusions() );
+	}
+
+	protected String generateUpdateGeneratedValuesSelectString() {
+		return generateGeneratedValuesSelectString( getPropertyUpdateGenerationInclusions() );
+	}
+
+	private String generateGeneratedValuesSelectString(ValueInclusion[] inclusions) {
+		Select select = new Select( getFactory().getDialect() );
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "get generated state " + getEntityName() );
+		}
+
+		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
+
+		// Here we render the select column list based on the properties defined as being generated.
+		// For partial component generation, we currently just re-select the whole component
+		// rather than trying to handle the individual generated portions.
+		String selectClause = concretePropertySelectFragment( getRootAlias(), inclusions );
+		selectClause = selectClause.substring( 2 );
+
+		String fromClause = fromTableFragment( getRootAlias() ) +
+				fromJoinFragment( getRootAlias(), true, false );
+
+		String whereClause = new StringBuffer()
+			.append( StringHelper.join( "=? and ", aliasedIdColumns ) )
+			.append( "=?" )
+			.append( whereJoinFragment( getRootAlias(), true, false ) )
+			.toString();
+
+		return select.setSelectClause( selectClause )
+				.setFromClause( fromClause )
+				.setOuterJoins( "", "" )
+				.setWhereClause( whereClause )
+				.toStatementString();
+	}
+
+	protected static interface InclusionChecker {
+		public boolean includeProperty(int propertyNumber);
+	}
+
+	protected String concretePropertySelectFragment(String alias, final ValueInclusion[] inclusions) {
+		return concretePropertySelectFragment(
+				alias,
+				new InclusionChecker() {
+					// TODO : currently we really do not handle ValueInclusion.PARTIAL...
+					// ValueInclusion.PARTIAL would indicate parts of a component need to
+					// be included in the select; currently we then just render the entire
+					// component into the select clause in that case.
+					public boolean includeProperty(int propertyNumber) {
+						return inclusions[propertyNumber] != ValueInclusion.NONE;
+					}
+				}
+		);
+	}
+
+	protected String concretePropertySelectFragment(String alias, final boolean[] includeProperty) {
+		return concretePropertySelectFragment(
+				alias,
+				new InclusionChecker() {
+					public boolean includeProperty(int propertyNumber) {
+						return includeProperty[propertyNumber];
+					}
+				}
+		);
+	}
+
+	protected String concretePropertySelectFragment(String alias, InclusionChecker inclusionChecker) {
+		int propertyCount = getPropertyNames().length;
+		int[] propertyTableNumbers = getPropertyTableNumbersInSelect();
+		SelectFragment frag = new SelectFragment();
+		for ( int i = 0; i < propertyCount; i++ ) {
+			if ( inclusionChecker.includeProperty( i ) ) {
+				frag.addColumns(
+						generateTableAlias( alias, propertyTableNumbers[i] ),
+						propertyColumnNames[i],
+						propertyColumnAliases[i]
+				);
+				frag.addFormulas(
+						generateTableAlias( alias, propertyTableNumbers[i] ),
+						propertyColumnFormulaTemplates[i],
+						propertyColumnAliases[i]
+				);
+			}
+		}
+		return frag.toFragmentString();
+	}
+
+	protected String generateSnapshotSelectString() {
+
+		//TODO: should we use SELECT .. FOR UPDATE?
+
+		Select select = new Select( getFactory().getDialect() );
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "get current state " + getEntityName() );
+		}
+
+		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
+		String selectClause = StringHelper.join( ", ", aliasedIdColumns ) +
+				concretePropertySelectFragment( getRootAlias(), getPropertyUpdateability() );
+
+		String fromClause = fromTableFragment( getRootAlias() ) +
+				fromJoinFragment( getRootAlias(), true, false );
+
+		String whereClause = new StringBuffer()
+			.append( StringHelper.join( "=? and ",
+					aliasedIdColumns ) )
+			.append( "=?" )
+			.append( whereJoinFragment( getRootAlias(), true, false ) )
+			.toString();
+
+		/*if ( isVersioned() ) {
+			where.append(" and ")
+				.append( getVersionColumnName() )
+				.append("=?");
+		}*/
+
+		return select.setSelectClause( selectClause )
+				.setFromClause( fromClause )
+				.setOuterJoins( "", "" )
+				.setWhereClause( whereClause )
+				.toStatementString();
+	}
+
+	public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session) {
+		if ( !isVersioned() ) {
+			throw new AssertionFailure( "cannot force version increment on non-versioned entity" );
+		}
+
+		if ( isVersionPropertyGenerated() ) {
+			// the difficulty here is exactly what do we update in order to
+			// force the version to be incremented in the db...
+			throw new HibernateException( "LockMode.FORCE is currently not supported for generated version properties" );
+		}
+
+		Object nextVersion = getVersionType().next( currentVersion, session );
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"Forcing version increment [" + MessageHelper.infoString( this, id, getFactory() ) +
+					"; " + getVersionType().toLoggableString( currentVersion, getFactory() ) +
+					" -> " + getVersionType().toLoggableString( nextVersion, getFactory() ) + "]"
+			);
+		}
+
+		// todo : cache this sql...
+		String versionIncrementString = generateVersionIncrementUpdateString();
+		PreparedStatement st = null;
+		try {
+			try {
+				st = session.getBatcher().prepareStatement( versionIncrementString );
+				getVersionType().nullSafeSet( st, nextVersion, 1, session );
+				getIdentifierType().nullSafeSet( st, id, 2, session );
+				getVersionType().nullSafeSet( st, currentVersion, 2 + getIdentifierColumnSpan(), session );
+				int rows = st.executeUpdate();
+				if ( rows != 1 ) {
+					throw new StaleObjectStateException( getEntityName(), id );
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve version: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+					getVersionSelectString()
+				);
+		}
+
+		return nextVersion;
+	}
+
+	private String generateVersionIncrementUpdateString() {
+		Update update = new Update( getFactory().getDialect() );
+		update.setTableName( getTableName( 0 ) );
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "forced version increment" );
+		}
+		update.addColumn( getVersionColumnName() );
+		update.setPrimaryKeyColumnNames( getIdentifierColumnNames() );
+		update.setVersionColumnName( getVersionColumnName() );
+		return update.toStatementString();
+	}
+
+	/**
+	 * Retrieve the version number
+	 */
+	public Object getCurrentVersion(Serializable id, SessionImplementor session) throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Getting version: " + MessageHelper.infoString( this, id, getFactory() ) );
+		}
+
+		try {
+
+			PreparedStatement st = session.getBatcher().prepareSelectStatement( getVersionSelectString() );
+			try {
+				getIdentifierType().nullSafeSet( st, id, 1, session );
+
+				ResultSet rs = st.executeQuery();
+				try {
+					if ( !rs.next() ) {
+						return null;
+					}
+					if ( !isVersioned() ) {
+						return this;
+					}
+					return getVersionType().nullSafeGet( rs, getVersionColumnName(), session, null );
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( st );
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve version: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+					getVersionSelectString()
+				);
+		}
+
+	}
+
+	protected void initLockers() {
+		lockers.put( LockMode.READ, generateLocker( LockMode.READ ) );
+		lockers.put( LockMode.UPGRADE, generateLocker( LockMode.UPGRADE ) );
+		lockers.put( LockMode.UPGRADE_NOWAIT, generateLocker( LockMode.UPGRADE_NOWAIT ) );
+		lockers.put( LockMode.FORCE, generateLocker( LockMode.FORCE ) );
+	}
+
+	protected LockingStrategy generateLocker(LockMode lockMode) {
+		return factory.getDialect().getLockingStrategy( this, lockMode );
+	}
+
+	private LockingStrategy getLocker(LockMode lockMode) {
+		return ( LockingStrategy ) lockers.get( lockMode );
+	}
+
+	public void lock(
+			Serializable id,
+	        Object version,
+	        Object object,
+	        LockMode lockMode,
+	        SessionImplementor session) throws HibernateException {
+		getLocker( lockMode ).lock( id, version, object, session );
+	}
+
+	public String getRootTableName() {
+		return getSubclassTableName( 0 );
+	}
+
+	public String getRootTableAlias(String drivingAlias) {
+		return drivingAlias;
+	}
+
+	public String[] getRootTableIdentifierColumnNames() {
+		return getRootTableKeyColumnNames();
+	}
+
+	public String[] toColumns(String alias, String propertyName) throws QueryException {
+		return propertyMapping.toColumns( alias, propertyName );
+	}
+
+	public String[] toColumns(String propertyName) throws QueryException {
+		return propertyMapping.getColumnNames( propertyName );
+	}
+
+	public Type toType(String propertyName) throws QueryException {
+		return propertyMapping.toType( propertyName );
+	}
+
+	public String[] getPropertyColumnNames(String propertyName) {
+		return propertyMapping.getColumnNames( propertyName );
+	}
+
+	/**
+	 * Warning:
+	 * When there are duplicated property names in the subclasses
+	 * of the class, this method may return the wrong table
+	 * number for the duplicated subclass property (note that
+	 * SingleTableEntityPersister defines an overloaded form
+	 * which takes the entity name.
+	 */
+	public int getSubclassPropertyTableNumber(String propertyPath) {
+		String rootPropertyName = StringHelper.root(propertyPath);
+		Type type = propertyMapping.toType(rootPropertyName);
+		if ( type.isAssociationType() ) {
+			AssociationType assocType = ( AssociationType ) type;
+			if ( assocType.useLHSPrimaryKey() ) {
+				// performance op to avoid the array search
+				return 0;
+			}
+			else if ( type.isCollectionType() ) {
+				// properly handle property-ref-based associations
+				rootPropertyName = assocType.getLHSPropertyName();
+			}
+		}
+		//Enable for HHH-440, which we don't like:
+		/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
+			String unrooted = StringHelper.unroot(propertyName);
+			int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
+			if ( idx != -1 ) {
+				return getSubclassColumnTableNumberClosure()[idx];
+			}
+		}*/
+		int index = ArrayHelper.indexOf( getSubclassPropertyNameClosure(), rootPropertyName); //TODO: optimize this better!
+		return index==-1 ? 0 : getSubclassPropertyTableNumber(index);
+	}
+
+	public Declarer getSubclassPropertyDeclarer(String propertyPath) {
+		int tableIndex = getSubclassPropertyTableNumber( propertyPath );
+		if ( tableIndex == 0 ) {
+			return Declarer.CLASS;
+		}
+		else if ( isClassOrSuperclassTable( tableIndex ) ) {
+			return Declarer.SUPERCLASS;
+		}
+		else {
+			return Declarer.SUBCLASS;
+		}
+	}
+
+	protected String generateTableAlias(String rootAlias, int tableNumber) {
+		if ( tableNumber == 0 ) {
+			return rootAlias;
+		}
+		StringBuffer buf = new StringBuffer().append( rootAlias );
+		if ( !rootAlias.endsWith( "_" ) ) {
+			buf.append( '_' );
+		}
+		return buf.append( tableNumber ).append( '_' ).toString();
+	}
+
+	public String[] toColumns(String name, final int i) {
+		final String alias = generateTableAlias( name, getSubclassPropertyTableNumber( i ) );
+		String[] cols = getSubclassPropertyColumnNames( i );
+		String[] templates = getSubclassPropertyFormulaTemplateClosure()[i];
+		String[] result = new String[cols.length];
+		for ( int j = 0; j < cols.length; j++ ) {
+			if ( cols[j] == null ) {
+				result[j] = StringHelper.replace( templates[j], Template.TEMPLATE, alias );
+			}
+			else {
+				result[j] = StringHelper.qualify( alias, cols[j] );
+			}
+		}
+		return result;
+	}
+
+	private int getSubclassPropertyIndex(String propertyName) {
+		return ArrayHelper.indexOf(subclassPropertyNameClosure, propertyName);
+	}
+
+	protected String[] getPropertySubclassNames() {
+		return propertySubclassNames;
+	}
+
+	public String[] getPropertyColumnNames(int i) {
+		return propertyColumnNames[i];
+	}
+
+	protected int getPropertyColumnSpan(int i) {
+		return propertyColumnSpans[i];
+	}
+
+	protected boolean hasFormulaProperties() {
+		return hasFormulaProperties;
+	}
+
+	public FetchMode getFetchMode(int i) {
+		return subclassPropertyFetchModeClosure[i];
+	}
+
+	public CascadeStyle getCascadeStyle(int i) {
+		return subclassPropertyCascadeStyleClosure[i];
+	}
+
+	public Type getSubclassPropertyType(int i) {
+		return subclassPropertyTypeClosure[i];
+	}
+
+	public String getSubclassPropertyName(int i) {
+		return subclassPropertyNameClosure[i];
+	}
+
+	public int countSubclassProperties() {
+		return subclassPropertyTypeClosure.length;
+	}
+
+	public String[] getSubclassPropertyColumnNames(int i) {
+		return subclassPropertyColumnNameClosure[i];
+	}
+
+	public boolean isDefinedOnSubclass(int i) {
+		return propertyDefinedOnSubclass[i];
+	}
+
+	protected String[][] getSubclassPropertyFormulaTemplateClosure() {
+		return subclassPropertyFormulaTemplateClosure;
+	}
+
+	protected Type[] getSubclassPropertyTypeClosure() {
+		return subclassPropertyTypeClosure;
+	}
+
+	protected String[][] getSubclassPropertyColumnNameClosure() {
+		return subclassPropertyColumnNameClosure;
+	}
+
+	protected String[] getSubclassPropertyNameClosure() {
+		return subclassPropertyNameClosure;
+	}
+
+	protected String[] getSubclassPropertySubclassNameClosure() {
+		return subclassPropertySubclassNameClosure;
+	}
+
+	protected String[] getSubclassColumnClosure() {
+		return subclassColumnClosure;
+	}
+
+	protected String[] getSubclassColumnAliasClosure() {
+		return subclassColumnAliasClosure;
+	}
+
+	protected String[] getSubclassFormulaClosure() {
+		return subclassFormulaClosure;
+	}
+
+	protected String[] getSubclassFormulaTemplateClosure() {
+		return subclassFormulaTemplateClosure;
+	}
+
+	protected String[] getSubclassFormulaAliasClosure() {
+		return subclassFormulaAliasClosure;
+	}
+
+	public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix) {
+		String rawAliases[] = ( String[] ) subclassPropertyAliases.get( propertyName );
+
+		if ( rawAliases == null ) {
+			return null;
+		}
+
+		String result[] = new String[rawAliases.length];
+		for ( int i = 0; i < rawAliases.length; i++ ) {
+			result[i] = new Alias( suffix ).toUnquotedAliasString( rawAliases[i] );
+		}
+		return result;
+	}
+
+	public String[] getSubclassPropertyColumnNames(String propertyName) {
+		//TODO: should we allow suffixes on these ?
+		return ( String[] ) subclassPropertyColumnNames.get( propertyName );
+	}
+
+
+
+	//This is really ugly, but necessary:
+	/**
+	 * Must be called by subclasses, at the end of their constructors
+	 */
+	protected void initSubclassPropertyAliasesMap(PersistentClass model) throws MappingException {
+
+		// ALIASES
+		internalInitSubclassPropertyAliasesMap( null, model.getSubclassPropertyClosureIterator() );
+
+		// aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id'
+		if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
+			subclassPropertyAliases.put( ENTITY_ID, getIdentifierAliases() );
+			subclassPropertyColumnNames.put( ENTITY_ID, getIdentifierColumnNames() );
+		}
+
+		// aliases named identifier ( alias.idname )
+		if ( hasIdentifierProperty() ) {
+			subclassPropertyAliases.put( getIdentifierPropertyName(), getIdentifierAliases() );
+			subclassPropertyColumnNames.put( getIdentifierPropertyName(), getIdentifierColumnNames() );
+		}
+
+		// aliases for composite-id's
+		if ( getIdentifierType().isComponentType() ) {
+			// Fetch embedded identifiers propertynames from the "virtual" identifier component
+			AbstractComponentType componentId = ( AbstractComponentType ) getIdentifierType();
+			String[] idPropertyNames = componentId.getPropertyNames();
+			String[] idAliases = getIdentifierAliases();
+			String[] idColumnNames = getIdentifierColumnNames();
+
+			for ( int i = 0; i < idPropertyNames.length; i++ ) {
+				if ( entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
+					subclassPropertyAliases.put(
+							ENTITY_ID + "." + idPropertyNames[i],
+							new String[] { idAliases[i] }
+					);
+					subclassPropertyColumnNames.put(
+							ENTITY_ID + "." + getIdentifierPropertyName() + "." + idPropertyNames[i],
+							new String[] { idColumnNames[i] }
+					);
+				}
+//				if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) {
+				if ( hasIdentifierProperty() ) {
+					subclassPropertyAliases.put(
+							getIdentifierPropertyName() + "." + idPropertyNames[i],
+							new String[] { idAliases[i] }
+					);
+					subclassPropertyColumnNames.put(
+							getIdentifierPropertyName() + "." + idPropertyNames[i],
+							new String[] { idColumnNames[i] }
+					);
+				}
+				else {
+					// embedded composite ids ( alias.idname1, alias.idname2 )
+					subclassPropertyAliases.put( idPropertyNames[i], new String[] { idAliases[i] } );
+					subclassPropertyColumnNames.put( idPropertyNames[i],  new String[] { idColumnNames[i] } );
+				}
+			}
+		}
+
+		if ( entityMetamodel.isPolymorphic() ) {
+			subclassPropertyAliases.put( ENTITY_CLASS, new String[] { getDiscriminatorAlias() } );
+			subclassPropertyColumnNames.put( ENTITY_CLASS, new String[] { getDiscriminatorColumnName() } );
+		}
+
+	}
+
+	private void internalInitSubclassPropertyAliasesMap(String path, Iterator propertyIterator) {
+		while ( propertyIterator.hasNext() ) {
+
+			Property prop = ( Property ) propertyIterator.next();
+			String propname = path == null ? prop.getName() : path + "." + prop.getName();
+			if ( prop.isComposite() ) {
+				Component component = ( Component ) prop.getValue();
+				Iterator compProps = component.getPropertyIterator();
+				internalInitSubclassPropertyAliasesMap( propname, compProps );
+			}
+			else {
+				String[] aliases = new String[prop.getColumnSpan()];
+				String[] cols = new String[prop.getColumnSpan()];
+				Iterator colIter = prop.getColumnIterator();
+				int l = 0;
+				while ( colIter.hasNext() ) {
+					Selectable thing = ( Selectable ) colIter.next();
+					aliases[l] = thing.getAlias( getFactory().getDialect(), prop.getValue().getTable() );
+					cols[l] = thing.getText( getFactory().getDialect() ); // TODO: skip formulas?
+					l++;
+				}
+
+				subclassPropertyAliases.put( propname, aliases );
+				subclassPropertyColumnNames.put( propname, cols );
+			}
+		}
+
+	}
+
+	public Object loadByUniqueKey(String propertyName, Object uniqueKey, SessionImplementor session)
+			throws HibernateException {
+		return getAppropriateUniqueKeyLoader( propertyName, session.getEnabledFilters() )
+				.loadByUniqueKey( session, uniqueKey );
+	}
+
+	private EntityLoader getAppropriateUniqueKeyLoader(String propertyName, Map enabledFilters) {
+
+		final boolean useStaticLoader = ( enabledFilters == null || enabledFilters.isEmpty() )
+				&& propertyName.indexOf('.')<0; //ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties
+
+		if ( useStaticLoader ) {
+			return (EntityLoader) uniqueKeyLoaders.get( propertyName );
+		}
+		else {
+			return createUniqueKeyLoader(
+					propertyMapping.toType(propertyName),
+					propertyMapping.toColumns(propertyName),
+					enabledFilters
+				);
+		}
+	}
+
+	public int getPropertyIndex(String propertyName) {
+		return entityMetamodel.getPropertyIndex(propertyName);
+	}
+
+	protected void createUniqueKeyLoaders() throws MappingException {
+		Type[] propertyTypes = getPropertyTypes();
+		String[] propertyNames = getPropertyNames();
+		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+			if ( propertyUniqueness[i] ) {
+				//don't need filters for the static loaders
+				uniqueKeyLoaders.put(
+						propertyNames[i],
+						createUniqueKeyLoader(
+								propertyTypes[i],
+								getPropertyColumnNames( i ),
+								CollectionHelper.EMPTY_MAP
+							)
+					);
+				//TODO: create uk loaders for component properties
+			}
+		}
+	}
+
+	private EntityLoader createUniqueKeyLoader(Type uniqueKeyType, String[] columns, Map enabledFilters) {
+		if ( uniqueKeyType.isEntityType() ) {
+			String className = ( ( EntityType ) uniqueKeyType ).getAssociatedEntityName();
+			uniqueKeyType = getFactory().getEntityPersister( className ).getIdentifierType();
+		}
+
+		return new EntityLoader( this, columns, uniqueKeyType, 1, LockMode.NONE, getFactory(), enabledFilters );
+	}
+
+	protected String getSQLWhereString(String alias) {
+		return StringHelper.replace( sqlWhereStringTemplate, Template.TEMPLATE, alias );
+	}
+
+	protected boolean hasWhere() {
+		return sqlWhereString != null;
+	}
+
+	private void initOrdinaryPropertyPaths(Mapping mapping) throws MappingException {
+		for ( int i = 0; i < getSubclassPropertyNameClosure().length; i++ ) {
+			propertyMapping.initPropertyPaths( getSubclassPropertyNameClosure()[i],
+					getSubclassPropertyTypeClosure()[i],
+					getSubclassPropertyColumnNameClosure()[i],
+					getSubclassPropertyFormulaTemplateClosure()[i],
+					mapping );
+		}
+	}
+
+	private void initIdentifierPropertyPaths(Mapping mapping) throws MappingException {
+		String idProp = getIdentifierPropertyName();
+		if ( idProp != null ) {
+			propertyMapping.initPropertyPaths( idProp, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
+		}
+		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
+			propertyMapping.initPropertyPaths( null, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
+		}
+		if ( ! entityMetamodel.hasNonIdentifierPropertyNamedId() ) {
+			propertyMapping.initPropertyPaths( ENTITY_ID, getIdentifierType(), getIdentifierColumnNames(), null, mapping );
+		}
+	}
+
+	private void initDiscriminatorPropertyPath(Mapping mapping) throws MappingException {
+		propertyMapping.initPropertyPaths( ENTITY_CLASS,
+				getDiscriminatorType(),
+				new String[]{getDiscriminatorColumnName()},
+				new String[]{getDiscriminatorFormulaTemplate()},
+				getFactory() );
+	}
+
+	protected void initPropertyPaths(Mapping mapping) throws MappingException {
+		initOrdinaryPropertyPaths(mapping);
+		initOrdinaryPropertyPaths(mapping); //do two passes, for collection property-ref!
+		initIdentifierPropertyPaths(mapping);
+		if ( entityMetamodel.isPolymorphic() ) {
+			initDiscriminatorPropertyPath( mapping );
+		}
+	}
+
+	protected UniqueEntityLoader createEntityLoader(LockMode lockMode, Map enabledFilters) throws MappingException {
+		//TODO: disable batch loading if lockMode > READ?
+		return BatchingEntityLoader.createBatchingEntityLoader( this, batchSize, lockMode, getFactory(), enabledFilters );
+	}
+
+	protected UniqueEntityLoader createEntityLoader(LockMode lockMode) throws MappingException {
+		return createEntityLoader( lockMode, CollectionHelper.EMPTY_MAP );
+	}
+
+	protected boolean check(int rows, Serializable id, int tableNumber, Expectation expectation, PreparedStatement statement) throws HibernateException {
+		try {
+			expectation.verifyOutcome( rows, statement, -1 );
+		}
+		catch( StaleStateException e ) {
+			if ( !isNullableTable( tableNumber ) ) {
+				if ( getFactory().getStatistics().isStatisticsEnabled() ) {
+					getFactory().getStatisticsImplementor()
+							.optimisticFailure( getEntityName() );
+				}
+				throw new StaleObjectStateException( getEntityName(), id );
+			}
+			return false;
+		}
+		catch( TooManyRowsAffectedException e ) {
+			throw new HibernateException(
+					"Duplicate identifier in table for: " +
+					MessageHelper.infoString( this, id, getFactory() )
+			);
+		}
+		catch ( Throwable t ) {
+			return false;
+		}
+		return true;
+	}
+
+	protected String generateUpdateString(boolean[] includeProperty, int j, boolean useRowId) {
+		return generateUpdateString( includeProperty, j, null, useRowId );
+	}
+
+	/**
+	 * Generate the SQL that updates a row by id (and version)
+	 */
+	protected String generateUpdateString(final boolean[] includeProperty,
+										  final int j,
+										  final Object[] oldFields,
+										  final boolean useRowId) {
+
+		Update update = new Update( getFactory().getDialect() ).setTableName( getTableName( j ) );
+
+		// select the correct row by either pk or rowid
+		if ( useRowId ) {
+			update.setPrimaryKeyColumnNames( new String[]{rowIdName} ); //TODO: eventually, rowIdName[j]
+		}
+		else {
+			update.setPrimaryKeyColumnNames( getKeyColumns( j ) );
+		}
+
+		boolean hasColumns = false;
+		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
+				// this is a property of the table, which we are updating
+				update.addColumns( getPropertyColumnNames(i), propertyColumnUpdateable[i] );
+				hasColumns = hasColumns || getPropertyColumnSpan( i ) > 0;
+			}
+		}
+
+		if ( j == 0 && isVersioned() && entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_VERSION ) {
+			// this is the root (versioned) table, and we are using version-based
+			// optimistic locking;  if we are not updating the version, also don't
+			// check it (unless this is a "generated" version column)!
+			if ( checkVersion( includeProperty ) ) {
+				update.setVersionColumnName( getVersionColumnName() );
+				hasColumns = true;
+			}
+		}
+		else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) {
+			// we are using "all" or "dirty" property-based optimistic locking
+
+			boolean[] includeInWhere = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ?
+					getPropertyUpdateability() : //optimistic-lock="all", include all updatable properties
+					includeProperty; //optimistic-lock="dirty", include all properties we are updating this time
+
+			boolean[] versionability = getPropertyVersionability();
+			Type[] types = getPropertyTypes();
+			for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+				boolean include = includeInWhere[i] &&
+						isPropertyOfTable( i, j ) &&
+						versionability[i];
+				if ( include ) {
+					// this property belongs to the table, and it is not specifically
+					// excluded from optimistic locking by optimistic-lock="false"
+					String[] propertyColumnNames = getPropertyColumnNames( i );
+					boolean[] propertyNullness = types[i].toColumnNullness( oldFields[i], getFactory() );
+					for ( int k=0; k<propertyNullness.length; k++ ) {
+						if ( propertyNullness[k] ) {
+							update.addWhereColumn( propertyColumnNames[k] );
+						}
+						else {
+							update.addWhereColumn( propertyColumnNames[k], " is null" );
+						}
+					}
+				}
+			}
+
+		}
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			update.setComment( "update " + getEntityName() );
+		}
+
+		return hasColumns ? update.toStatementString() : null;
+	}
+
+	private boolean checkVersion(final boolean[] includeProperty) {
+        return includeProperty[ getVersionProperty() ] ||
+				entityMetamodel.getPropertyUpdateGenerationInclusions()[ getVersionProperty() ] != ValueInclusion.NONE;
+	}
+
+	protected String generateInsertString(boolean[] includeProperty, int j) {
+		return generateInsertString( false, includeProperty, j );
+	}
+
+	protected String generateInsertString(boolean identityInsert, boolean[] includeProperty) {
+		return generateInsertString( identityInsert, includeProperty, 0 );
+	}
+
+	/**
+	 * Generate the SQL that inserts a row
+	 */
+	protected String generateInsertString(boolean identityInsert, boolean[] includeProperty, int j) {
+
+		// todo : remove the identityInsert param and variations;
+		//   identity-insert strings are now generated from generateIdentityInsertString()
+
+		Insert insert = new Insert( getFactory().getDialect() )
+				.setTableName( getTableName( j ) );
+
+		// add normal properties
+		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
+				// this property belongs on the table and is to be inserted
+				insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i] );
+			}
+		}
+
+		// add the discriminator
+		if ( j == 0 ) {
+			addDiscriminatorToInsert( insert );
+		}
+
+		// add the primary key
+		if ( j == 0 && identityInsert ) {
+			insert.addIdentityColumn( getKeyColumns( 0 )[0] );
+		}
+		else {
+			insert.addColumns( getKeyColumns( j ) );
+		}
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			insert.setComment( "insert " + getEntityName() );
+		}
+
+		String result = insert.toStatementString();
+
+		// append the SQL to return the generated identifier
+		if ( j == 0 && identityInsert && useInsertSelectIdentity() ) { //TODO: suck into Insert
+			result = getFactory().getDialect().appendIdentitySelectToInsert( result );
+		}
+
+		return result;
+	}
+
+	/**
+	 * Used to generate an insery statement against the root table in the
+	 * case of identifier generation strategies where the insert statement
+	 * executions actually generates the identifier value.
+	 *
+	 * @param includeProperty indices of the properties to include in the
+	 * insert statement.
+	 * @return The insert SQL statement string
+	 */
+	protected String generateIdentityInsertString(boolean[] includeProperty) {
+		Insert insert = identityDelegate.prepareIdentifierGeneratingInsert();
+		insert.setTableName( getTableName( 0 ) );
+
+		// add normal properties
+		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+			if ( includeProperty[i] && isPropertyOfTable( i, 0 ) ) {
+				// this property belongs on the table and is to be inserted
+				insert.addColumns( getPropertyColumnNames(i), propertyColumnInsertable[i] );
+			}
+		}
+
+		// add the discriminator
+		addDiscriminatorToInsert( insert );
+
+		// delegate already handles PK columns
+
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			insert.setComment( "insert " + getEntityName() );
+		}
+
+		return insert.toStatementString();
+	}
+
+	/**
+	 * Generate the SQL that deletes a row by id (and version)
+	 */
+	protected String generateDeleteString(int j) {
+		Delete delete = new Delete()
+				.setTableName( getTableName( j ) )
+				.setPrimaryKeyColumnNames( getKeyColumns( j ) );
+		if ( j == 0 ) {
+			delete.setVersionColumnName( getVersionColumnName() );
+		}
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			delete.setComment( "delete " + getEntityName() );
+		}
+		return delete.toStatementString();
+	}
+
+	protected int dehydrate(
+			Serializable id,
+			Object[] fields,
+			boolean[] includeProperty,
+			boolean[][] includeColumns,
+			int j,
+			PreparedStatement st,
+			SessionImplementor session) throws HibernateException, SQLException {
+		return dehydrate( id, fields, null, includeProperty, includeColumns, j, st, session, 1 );
+	}
+
+	/**
+	 * Marshall the fields of a persistent instance to a prepared statement
+	 */
+	protected int dehydrate(
+			final Serializable id,
+	        final Object[] fields,
+	        final Object rowId,
+	        final boolean[] includeProperty,
+	        final boolean[][] includeColumns,
+	        final int j,
+	        final PreparedStatement ps,
+	        final SessionImplementor session,
+	        int index) throws SQLException, HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Dehydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
+		}
+
+		for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+			if ( includeProperty[i] && isPropertyOfTable( i, j ) ) {
+				getPropertyTypes()[i].nullSafeSet( ps, fields[i], index, includeColumns[i], session );
+				//index += getPropertyColumnSpan( i );
+				index += ArrayHelper.countTrue( includeColumns[i] ); //TODO:  this is kinda slow...
+			}
+		}
+
+		if ( rowId != null ) {
+			ps.setObject( index, rowId );
+			index += 1;
+		}
+		else if ( id != null ) {
+			getIdentifierType().nullSafeSet( ps, id, index, session );
+			index += getIdentifierColumnSpan();
+		}
+
+		return index;
+
+	}
+
+	/**
+	 * Unmarshall the fields of a persistent instance from a result set,
+	 * without resolving associations or collections. Question: should
+	 * this really be here, or should it be sent back to Loader?
+	 */
+	public Object[] hydrate(
+			final ResultSet rs,
+	        final Serializable id,
+	        final Object object,
+	        final Loadable rootLoadable,
+	        final String[][] suffixedPropertyColumns,
+	        final boolean allProperties,
+	        final SessionImplementor session) throws SQLException, HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Hydrating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
+		}
+
+		final AbstractEntityPersister rootPersister = (AbstractEntityPersister) rootLoadable;
+
+		final boolean hasDeferred = rootPersister.hasSequentialSelect();
+		PreparedStatement sequentialSelect = null;
+		ResultSet sequentialResultSet = null;
+		boolean sequentialSelectEmpty = false;
+		try {
+
+			if ( hasDeferred ) {
+				final String sql = rootPersister.getSequentialSelect( getEntityName() );
+				if ( sql != null ) {
+					//TODO: I am not so sure about the exception handling in this bit!
+					sequentialSelect = session.getBatcher().prepareSelectStatement( sql );
+					rootPersister.getIdentifierType().nullSafeSet( sequentialSelect, id, 1, session );
+					sequentialResultSet = sequentialSelect.executeQuery();
+					if ( !sequentialResultSet.next() ) {
+						// TODO: Deal with the "optional" attribute in the <join> mapping;
+						// this code assumes that optional defaults to "true" because it
+						// doesn't actually seem to work in the fetch="join" code
+						//
+						// Note that actual proper handling of optional-ality here is actually
+						// more involved than this patch assumes.  Remember that we might have
+						// multiple <join/> mappings associated with a single entity.  Really
+						// a couple of things need to happen to properly handle optional here:
+						//  1) First and foremost, when handling multiple <join/>s, we really
+						//      should be using the entity root table as the driving table;
+						//      another option here would be to choose some non-optional joined
+						//      table to use as the driving table.  In all likelihood, just using
+						//      the root table is much simplier
+						//  2) Need to add the FK columns corresponding to each joined table
+						//      to the generated select list; these would then be used when
+						//      iterating the result set to determine whether all non-optional
+						//      data is present
+						// My initial thoughts on the best way to deal with this would be
+						// to introduce a new SequentialSelect abstraction that actually gets
+						// generated in the persisters (ok, SingleTable...) and utilized here.
+						// It would encapsulated all this required optional-ality checking...
+						sequentialSelectEmpty = true;
+					}
+				}
+			}
+
+			final String[] propNames = getPropertyNames();
+			final Type[] types = getPropertyTypes();
+			final Object[] values = new Object[types.length];
+			final boolean[] laziness = getPropertyLaziness();
+			final String[] propSubclassNames = getSubclassPropertySubclassNameClosure();
+
+			for ( int i = 0; i < types.length; i++ ) {
+				if ( !propertySelectable[i] ) {
+					values[i] = BackrefPropertyAccessor.UNKNOWN;
+				}
+				else if ( allProperties || !laziness[i] ) {
+					//decide which ResultSet to get the property value from:
+					final boolean propertyIsDeferred = hasDeferred &&
+							rootPersister.isSubclassPropertyDeferred( propNames[i], propSubclassNames[i] );
+					if ( propertyIsDeferred && sequentialSelectEmpty ) {
+						values[i] = null;
+					}
+					else {
+						final ResultSet propertyResultSet = propertyIsDeferred ? sequentialResultSet : rs;
+						final String[] cols = propertyIsDeferred ? propertyColumnAliases[i] : suffixedPropertyColumns[i];
+						values[i] = types[i].hydrate( propertyResultSet, cols, session, object );
+					}
+				}
+				else {
+					values[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
+				}
+			}
+
+			if ( sequentialResultSet != null ) {
+				sequentialResultSet.close();
+			}
+
+			return values;
+
+		}
+		finally {
+			if ( sequentialSelect != null ) {
+				session.getBatcher().closeStatement( sequentialSelect );
+			}
+		}
+	}
+
+	protected boolean useInsertSelectIdentity() {
+		return !useGetGeneratedKeys() && getFactory().getDialect().supportsInsertSelectIdentity();
+	}
+
+	protected boolean useGetGeneratedKeys() {
+		return getFactory().getSettings().isGetGeneratedKeysEnabled();
+	}
+
+	protected String getSequentialSelect(String entityName) {
+		throw new UnsupportedOperationException("no sequential selects");
+	}
+
+	/**
+	 * Perform an SQL INSERT, and then retrieve a generated identifier.
+	 * <p/>
+	 * This form is used for PostInsertIdentifierGenerator-style ids (IDENTITY,
+	 * select, etc).
+	 */
+	protected Serializable insert(
+			final Object[] fields,
+	        final boolean[] notNull,
+	        String sql,
+	        final Object object,
+	        final SessionImplementor session) throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Inserting entity: " + getEntityName() + " (native id)" );
+			if ( isVersioned() ) {
+				log.trace( "Version: " + Versioning.getVersion( fields, this ) );
+			}
+		}
+
+		Binder binder = new Binder() {
+			public void bindValues(PreparedStatement ps) throws SQLException {
+				dehydrate( null, fields, notNull, propertyColumnInsertable, 0, ps, session );
+			}
+			public Object getEntity() {
+				return object;
+			}
+		};
+		return identityDelegate.performInsert( sql, session, binder );
+	}
+
+	public String getIdentitySelectString() {
+		//TODO: cache this in an instvar
+		return getFactory().getDialect().getIdentitySelectString(
+				getTableName(0),
+				getKeyColumns(0)[0],
+				getIdentifierType().sqlTypes( getFactory() )[0]
+		);
+	}
+
+	public String getSelectByUniqueKeyString(String propertyName) {
+		return new SimpleSelect( getFactory().getDialect() )
+			.setTableName( getTableName(0) )
+			.addColumns( getKeyColumns(0) )
+			.addCondition( getPropertyColumnNames(propertyName), "=?" )
+			.toStatementString();
+	}
+
+	/**
+	 * Perform an SQL INSERT.
+	 * <p/>
+	 * This for is used for all non-root tables as well as the root table
+	 * in cases where the identifier value is known before the insert occurs.
+	 */
+	protected void insert(
+			final Serializable id,
+	        final Object[] fields,
+	        final boolean[] notNull,
+	        final int j,
+	        final String sql,
+	        final Object object,
+	        final SessionImplementor session) throws HibernateException {
+
+		if ( isInverseTable( j ) ) {
+			return;
+		}
+
+		//note: it is conceptually possible that a UserType could map null to
+		//	  a non-null value, so the following is arguable:
+		if ( isNullableTable( j ) && isAllNull( fields, j ) ) {
+			return;
+		}
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Inserting entity: " + MessageHelper.infoString( this, id, getFactory() ) );
+			if ( j == 0 && isVersioned() ) {
+				log.trace( "Version: " + Versioning.getVersion( fields, this ) );
+			}
+		}
+
+		Expectation expectation = Expectations.appropriateExpectation( insertResultCheckStyles[j] );
+		boolean callable = isInsertCallable( j );
+		// we can't batch joined inserts, *especially* not if it is an identity insert;
+		// nor can we batch statements where the expectation is based on an output param
+		final boolean useBatch = j == 0 && expectation.canBeBatched();
+		try {
+
+			// Render the SQL query
+			final PreparedStatement insert;
+			if ( useBatch ) {
+				if ( callable ) {
+					insert = session.getBatcher().prepareBatchCallableStatement( sql );
+				}
+				else {
+					insert = session.getBatcher().prepareBatchStatement( sql );
+				}
+			}
+			else {
+				if ( callable ) {
+					insert = session.getBatcher().prepareCallableStatement( sql );
+				}
+				else {
+					insert = session.getBatcher().prepareStatement( sql );
+				}
+			}
+
+			try {
+				int index = 1;
+				index += expectation.prepare( insert );
+
+				// Write the values of fields onto the prepared statement - we MUST use the state at the time the
+				// insert was issued (cos of foreign key constraints). Not necessarily the object's current state
+
+				dehydrate( id, fields, null, notNull, propertyColumnInsertable, j, insert, session, index );
+
+				if ( useBatch ) {
+					// TODO : shouldnt inserts be Expectations.NONE?
+					session.getBatcher().addToBatch( expectation );
+				}
+				else {
+					expectation.verifyOutcome( insert.executeUpdate(), insert, -1 );
+				}
+
+			}
+			catch ( SQLException sqle ) {
+				if ( useBatch ) {
+					session.getBatcher().abortBatch( sqle );
+				}
+				throw sqle;
+			}
+			finally {
+				if ( !useBatch ) {
+					session.getBatcher().closeStatement( insert );
+				}
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not insert: " + MessageHelper.infoString( this ),
+					sql
+				);
+		}
+
+	}
+
+	/**
+	 * Perform an SQL UPDATE or SQL INSERT
+	 */
+	protected void updateOrInsert(
+			final Serializable id,
+	        final Object[] fields,
+	        final Object[] oldFields,
+	        final Object rowId,
+	        final boolean[] includeProperty,
+	        final int j,
+	        final Object oldVersion,
+	        final Object object,
+	        final String sql,
+	        final SessionImplementor session) throws HibernateException {
+
+		if ( !isInverseTable( j ) ) {
+
+			final boolean isRowToUpdate;
+			if ( isNullableTable( j ) && oldFields != null && isAllNull( oldFields, j ) ) {
+				//don't bother trying to update, we know there is no row there yet
+				isRowToUpdate = false;
+			}
+			else if ( isNullableTable( j ) && isAllNull( fields, j ) ) {
+				//if all fields are null, we might need to delete existing row
+				isRowToUpdate = true;
+				delete( id, oldVersion, j, object, getSQLDeleteStrings()[j], session, null );
+			}
+			else {
+				//there is probably a row there, so try to update
+				//if no rows were updated, we will find out
+				isRowToUpdate = update( id, fields, oldFields, rowId, includeProperty, j, oldVersion, object, sql, session );
+			}
+
+			if ( !isRowToUpdate && !isAllNull( fields, j ) ) {
+				// assume that the row was not there since it previously had only null
+				// values, so do an INSERT instead
+				//TODO: does not respect dynamic-insert
+				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
+			}
+
+		}
+
+	}
+
+	protected boolean update(
+			final Serializable id,
+	        final Object[] fields,
+	        final Object[] oldFields,
+	        final Object rowId,
+	        final boolean[] includeProperty,
+	        final int j,
+	        final Object oldVersion,
+	        final Object object,
+	        final String sql,
+	        final SessionImplementor session) throws HibernateException {
+
+		final boolean useVersion = j == 0 && isVersioned();
+		final Expectation expectation = Expectations.appropriateExpectation( updateResultCheckStyles[j] );
+		final boolean callable = isUpdateCallable( j );
+		final boolean useBatch = j == 0 && expectation.canBeBatched() && isBatchable(); //note: updates to joined tables can't be batched...
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Updating entity: " + MessageHelper.infoString( this, id, getFactory() ) );
+			if ( useVersion ) {
+				log.trace( "Existing version: " + oldVersion + " -> New version: " + fields[getVersionProperty()] );
+			}
+		}
+
+		try {
+
+			int index = 1; // starting index
+			final PreparedStatement update;
+			if ( useBatch ) {
+				if ( callable ) {
+					update = session.getBatcher().prepareBatchCallableStatement( sql );
+				}
+				else {
+					update = session.getBatcher().prepareBatchStatement( sql );
+				}
+			}
+			else {
+				if ( callable ) {
+					update = session.getBatcher().prepareCallableStatement( sql );
+				}
+				else {
+					update = session.getBatcher().prepareStatement( sql );
+				}
+			}
+
+			try {
+
+				index+= expectation.prepare( update );
+
+				//Now write the values of fields onto the prepared statement
+				index = dehydrate( id, fields, rowId, includeProperty, propertyColumnUpdateable, j, update, session, index );
+
+				// Write any appropriate versioning conditional parameters
+				if ( useVersion && Versioning.OPTIMISTIC_LOCK_VERSION == entityMetamodel.getOptimisticLockMode() ) {
+					if ( checkVersion( includeProperty ) ) {
+						getVersionType().nullSafeSet( update, oldVersion, index, session );
+					}
+				}
+				else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && oldFields != null ) {
+					boolean[] versionability = getPropertyVersionability(); //TODO: is this really necessary????
+					boolean[] includeOldField = entityMetamodel.getOptimisticLockMode() == Versioning.OPTIMISTIC_LOCK_ALL ?
+							getPropertyUpdateability() : includeProperty;
+					Type[] types = getPropertyTypes();
+					for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+						boolean include = includeOldField[i] &&
+								isPropertyOfTable( i, j ) &&
+								versionability[i]; //TODO: is this really necessary????
+						if ( include ) {
+							boolean[] settable = types[i].toColumnNullness( oldFields[i], getFactory() );
+							types[i].nullSafeSet(
+									update,
+									oldFields[i],
+									index,
+									settable,
+									session
+								);
+							index += ArrayHelper.countTrue(settable);
+						}
+					}
+				}
+
+				if ( useBatch ) {
+					session.getBatcher().addToBatch( expectation );
+					return true;
+				}
+				else {
+					return check( update.executeUpdate(), id, j, expectation, update );
+				}
+
+			}
+			catch ( SQLException sqle ) {
+				if ( useBatch ) {
+					session.getBatcher().abortBatch( sqle );
+				}
+				throw sqle;
+			}
+			finally {
+				if ( !useBatch ) {
+					session.getBatcher().closeStatement( update );
+				}
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not update: " + MessageHelper.infoString( this, id, getFactory() ),
+					sql
+				);
+		}
+	}
+
+	/**
+	 * Perform an SQL DELETE
+	 */
+	protected void delete(
+			final Serializable id,
+			final Object version,
+			final int j,
+			final Object object,
+			final String sql,
+			final SessionImplementor session,
+			final Object[] loadedState) throws HibernateException {
+
+		if ( isInverseTable( j ) ) {
+			return;
+		}
+
+		final boolean useVersion = j == 0 && isVersioned();
+		final boolean callable = isDeleteCallable( j );
+		final Expectation expectation = Expectations.appropriateExpectation( deleteResultCheckStyles[j] );
+		final boolean useBatch = j == 0 && isBatchable() && expectation.canBeBatched();
+
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Deleting entity: " + MessageHelper.infoString( this, id, getFactory() ) );
+			if ( useVersion ) {
+				log.trace( "Version: " + version );
+			}
+		}
+
+		if ( isTableCascadeDeleteEnabled( j ) ) {
+			if ( log.isTraceEnabled() ) {
+				log.trace( "delete handled by foreign key constraint: " + getTableName( j ) );
+			}
+			return; //EARLY EXIT!
+		}
+
+		try {
+
+			//Render the SQL query
+			PreparedStatement delete;
+			int index = 1;
+			if ( useBatch ) {
+				if ( callable ) {
+					delete = session.getBatcher().prepareBatchCallableStatement( sql );
+				}
+				else {
+					delete = session.getBatcher().prepareBatchStatement( sql );
+				}
+			}
+			else {
+				if ( callable ) {
+					delete = session.getBatcher().prepareCallableStatement( sql );
+				}
+				else {
+					delete = session.getBatcher().prepareStatement( sql );
+				}
+			}
+
+			try {
+
+				index += expectation.prepare( delete );
+
+				// Do the key. The key is immutable so we can use the _current_ object state - not necessarily
+				// the state at the time the delete was issued
+				getIdentifierType().nullSafeSet( delete, id, index, session );
+				index += getIdentifierColumnSpan();
+
+				// We should use the _current_ object state (ie. after any updates that occurred during flush)
+
+				if ( useVersion ) {
+					getVersionType().nullSafeSet( delete, version, index, session );
+				}
+				else if ( entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION && loadedState != null ) {
+					boolean[] versionability = getPropertyVersionability();
+					Type[] types = getPropertyTypes();
+					for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+						if ( isPropertyOfTable( i, j ) && versionability[i] ) {
+							// this property belongs to the table and it is not specifically
+							// excluded from optimistic locking by optimistic-lock="false"
+							boolean[] settable = types[i].toColumnNullness( loadedState[i], getFactory() );
+							types[i].nullSafeSet( delete, loadedState[i], index, settable, session );
+							index += ArrayHelper.countTrue( settable );
+						}
+					}
+				}
+
+				if ( useBatch ) {
+					session.getBatcher().addToBatch( expectation );
+				}
+				else {
+					check( delete.executeUpdate(), id, j, expectation, delete );
+				}
+
+			}
+			catch ( SQLException sqle ) {
+				if ( useBatch ) {
+					session.getBatcher().abortBatch( sqle );
+				}
+				throw sqle;
+			}
+			finally {
+				if ( !useBatch ) {
+					session.getBatcher().closeStatement( delete );
+				}
+			}
+
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not delete: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+					sql
+				);
+
+		}
+
+	}
+
+	private String[] getUpdateStrings(boolean byRowId, boolean lazy) {
+		if ( byRowId ) {
+			return lazy ? getSQLLazyUpdateByRowIdStrings() : getSQLUpdateByRowIdStrings();
+		}
+		else {
+			return lazy ? getSQLLazyUpdateStrings() : getSQLUpdateStrings();
+		}
+	}
+
+	/**
+	 * Update an object
+	 */
+	public void update(
+			final Serializable id,
+	        final Object[] fields,
+	        final int[] dirtyFields,
+	        final boolean hasDirtyCollection,
+	        final Object[] oldFields,
+	        final Object oldVersion,
+	        final Object object,
+	        final Object rowId,
+	        final SessionImplementor session) throws HibernateException {
+
+		//note: dirtyFields==null means we had no snapshot, and we couldn't get one using select-before-update
+		//	  oldFields==null just means we had no snapshot to begin with (we might have used select-before-update to get the dirtyFields)
+
+		final boolean[] tableUpdateNeeded = getTableUpdateNeeded( dirtyFields, hasDirtyCollection );
+		final int span = getTableSpan();
+
+		final boolean[] propsToUpdate;
+		final String[] updateStrings;
+		if ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) {
+			// For the case of dynamic-update="true", we need to generate the UPDATE SQL
+			propsToUpdate = getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
+			// don't need to check laziness (dirty checking algorithm handles that)
+			updateStrings = new String[span];
+			for ( int j = 0; j < span; j++ ) {
+				updateStrings[j] = tableUpdateNeeded[j] ?
+						generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) :
+						null;
+			}
+		}
+		else {
+			// For the case of dynamic-update="false", or no snapshot, we use the static SQL
+			updateStrings = getUpdateStrings(
+					rowId != null,
+					hasUninitializedLazyProperties( object, session.getEntityMode() )
+				);
+			propsToUpdate = getPropertyUpdateability( object, session.getEntityMode() );
+		}
+
+		for ( int j = 0; j < span; j++ ) {
+			// Now update only the tables with dirty properties (and the table with the version number)
+			if ( tableUpdateNeeded[j] ) {
+				updateOrInsert(
+						id,
+						fields,
+						oldFields,
+						j == 0 ? rowId : null,
+						propsToUpdate,
+						j,
+						oldVersion,
+						object,
+						updateStrings[j],
+						session
+					);
+			}
+		}
+	}
+
+	public Serializable insert(Object[] fields, Object object, SessionImplementor session)
+			throws HibernateException {
+
+		final int span = getTableSpan();
+		final Serializable id;
+		if ( entityMetamodel.isDynamicInsert() ) {
+			// For the case of dynamic-insert="true", we need to generate the INSERT SQL
+			boolean[] notNull = getPropertiesToInsert( fields );
+			id = insert( fields, notNull, generateInsertString( true, notNull ), object, session );
+			for ( int j = 1; j < span; j++ ) {
+				insert( id, fields, notNull, j, generateInsertString( notNull, j ), object, session );
+			}
+		}
+		else {
+			// For the case of dynamic-insert="false", use the static SQL
+			id = insert( fields, getPropertyInsertability(), getSQLIdentityInsertString(), object, session );
+			for ( int j = 1; j < span; j++ ) {
+				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
+			}
+		}
+		return id;
+	}
+
+	public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session)
+			throws HibernateException {
+
+		final int span = getTableSpan();
+		if ( entityMetamodel.isDynamicInsert() ) {
+			// For the case of dynamic-insert="true", we need to generate the INSERT SQL
+			boolean[] notNull = getPropertiesToInsert( fields );
+			for ( int j = 0; j < span; j++ ) {
+				insert( id, fields, notNull, j, generateInsertString( notNull, j ), object, session );
+			}
+		}
+		else {
+			// For the case of dynamic-insert="false", use the static SQL
+			for ( int j = 0; j < span; j++ ) {
+				insert( id, fields, getPropertyInsertability(), j, getSQLInsertStrings()[j], object, session );
+			}
+		}
+	}
+
+	/**
+	 * Delete an object
+	 */
+	public void delete(Serializable id, Object version, Object object, SessionImplementor session)
+			throws HibernateException {
+		final int span = getTableSpan();
+		boolean isImpliedOptimisticLocking = !entityMetamodel.isVersioned() && entityMetamodel.getOptimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION;
+		Object[] loadedState = null;
+		if ( isImpliedOptimisticLocking ) {
+			// need to treat this as if it where optimistic-lock="all" (dirty does *not* make sense);
+			// first we need to locate the "loaded" state
+			//
+			// Note, it potentially could be a proxy, so perform the location the safe way...
+			EntityKey key = new EntityKey( id, this, session.getEntityMode() );
+			Object entity = session.getPersistenceContext().getEntity( key );
+			if ( entity != null ) {
+				EntityEntry entry = session.getPersistenceContext().getEntry( entity );
+				loadedState = entry.getLoadedState();
+			}
+		}
+
+		final String[] deleteStrings;
+		if ( isImpliedOptimisticLocking && loadedState != null ) {
+			// we need to utilize dynamic delete statements
+			deleteStrings = generateSQLDeletStrings( loadedState );
+		}
+		else {
+			// otherwise, utilize the static delete statements
+			deleteStrings = getSQLDeleteStrings();
+		}
+
+		for ( int j = span - 1; j >= 0; j-- ) {
+			delete( id, version, j, object, deleteStrings[j], session, loadedState );
+		}
+
+	}
+
+	private String[] generateSQLDeletStrings(Object[] loadedState) {
+		int span = getTableSpan();
+		String[] deleteStrings = new String[span];
+		for ( int j = span - 1; j >= 0; j-- ) {
+			Delete delete = new Delete()
+					.setTableName( getTableName( j ) )
+					.setPrimaryKeyColumnNames( getKeyColumns( j ) );
+			if ( getFactory().getSettings().isCommentsEnabled() ) {
+				delete.setComment( "delete " + getEntityName() + " [" + j + "]" );
+			}
+
+			boolean[] versionability = getPropertyVersionability();
+			Type[] types = getPropertyTypes();
+			for ( int i = 0; i < entityMetamodel.getPropertySpan(); i++ ) {
+				if ( isPropertyOfTable( i, j ) && versionability[i] ) {
+					// this property belongs to the table and it is not specifically
+					// excluded from optimistic locking by optimistic-lock="false"
+					String[] propertyColumnNames = getPropertyColumnNames( i );
+					boolean[] propertyNullness = types[i].toColumnNullness( loadedState[i], getFactory() );
+					for ( int k = 0; k < propertyNullness.length; k++ ) {
+						if ( propertyNullness[k] ) {
+							delete.addWhereFragment( propertyColumnNames[k] + " = ?" );
+						}
+						else {
+							delete.addWhereFragment( propertyColumnNames[k] + " is null" );
+						}
+					}
+				}
+			}
+			deleteStrings[j] = delete.toStatementString();
+		}
+		return deleteStrings;
+	}
+
+	protected void logStaticSQL() {
+		if ( log.isDebugEnabled() ) {
+			log.debug( "Static SQL for entity: " + getEntityName() );
+			if ( sqlLazySelectString != null ) {
+				log.debug( " Lazy select: " + sqlLazySelectString );
+			}
+			if ( sqlVersionSelectString != null ) {
+				log.debug( " Version select: " + sqlVersionSelectString );
+			}
+			if ( sqlSnapshotSelectString != null ) {
+				log.debug( " Snapshot select: " + sqlSnapshotSelectString );
+			}
+			for ( int j = 0; j < getTableSpan(); j++ ) {
+				log.debug( " Insert " + j + ": " + getSQLInsertStrings()[j] );
+				log.debug( " Update " + j + ": " + getSQLUpdateStrings()[j] );
+				log.debug( " Delete " + j + ": " + getSQLDeleteStrings()[j] );
+
+			}
+			if ( sqlIdentityInsertString != null ) {
+				log.debug( " Identity insert: " + sqlIdentityInsertString );
+			}
+			if ( sqlUpdateByRowIdString != null ) {
+				log.debug( " Update by row id (all fields): " + sqlUpdateByRowIdString );
+			}
+			if ( sqlLazyUpdateByRowIdString != null ) {
+				log.debug( " Update by row id (non-lazy fields): " + sqlLazyUpdateByRowIdString );
+			}
+			if ( sqlInsertGeneratedValuesSelectString != null ) {
+				log.debug( "Insert-generated property select: " + sqlInsertGeneratedValuesSelectString );
+			}
+			if ( sqlUpdateGeneratedValuesSelectString != null ) {
+				log.debug( "Update-generated property select: " + sqlUpdateGeneratedValuesSelectString );
+			}
+		}
+	}
+
+	public String filterFragment(String alias, Map enabledFilters) throws MappingException {
+		final StringBuffer sessionFilterFragment = new StringBuffer();
+		filterHelper.render( sessionFilterFragment, generateFilterConditionAlias( alias ), enabledFilters );
+
+		return sessionFilterFragment.append( filterFragment( alias ) ).toString();
+	}
+
+	public String generateFilterConditionAlias(String rootAlias) {
+		return rootAlias;
+	}
+
+	public String oneToManyFilterFragment(String alias) throws MappingException {
+		return "";
+	}
+
+	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
+		return getSubclassTableSpan() == 1 ?
+				"" : //just a performance opt!
+				createJoin( alias, innerJoin, includeSubclasses ).toFromFragmentString();
+	}
+
+	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses) {
+		return getSubclassTableSpan() == 1 ?
+				"" : //just a performance opt!
+				createJoin( alias, innerJoin, includeSubclasses ).toWhereFragmentString();
+	}
+
+	protected boolean isSubclassTableLazy(int j) {
+		return false;
+	}
+
+	protected JoinFragment createJoin(String name, boolean innerJoin, boolean includeSubclasses) {
+		final String[] idCols = StringHelper.qualify( name, getIdentifierColumnNames() ); //all joins join to the pk of the driving table
+		final JoinFragment join = getFactory().getDialect().createOuterJoinFragment();
+		final int tableSpan = getSubclassTableSpan();
+		for ( int j = 1; j < tableSpan; j++ ) { //notice that we skip the first table; it is the driving table!
+			final boolean joinIsIncluded = isClassOrSuperclassTable( j ) ||
+					( includeSubclasses && !isSubclassTableSequentialSelect( j ) && !isSubclassTableLazy( j ) );
+			if ( joinIsIncluded ) {
+				join.addJoin( getSubclassTableName( j ),
+						generateTableAlias( name, j ),
+						idCols,
+						getSubclassTableKeyColumns( j ),
+						innerJoin && isClassOrSuperclassTable( j ) && !isInverseTable( j ) && !isNullableTable( j ) ?
+						JoinFragment.INNER_JOIN : //we can inner join to superclass tables (the row MUST be there)
+						JoinFragment.LEFT_OUTER_JOIN //we can never inner join to subclass tables
+					);
+			}
+		}
+		return join;
+	}
+
+	protected JoinFragment createJoin(int[] tableNumbers, String drivingAlias) {
+		final String[] keyCols = StringHelper.qualify( drivingAlias, getSubclassTableKeyColumns( tableNumbers[0] ) );
+		final JoinFragment jf = getFactory().getDialect().createOuterJoinFragment();
+		for ( int i = 1; i < tableNumbers.length; i++ ) { //skip the driving table
+			final int j = tableNumbers[i];
+			jf.addJoin( getSubclassTableName( j ),
+					generateTableAlias( getRootAlias(), j ),
+					keyCols,
+					getSubclassTableKeyColumns( j ),
+					isInverseSubclassTable( j ) || isNullableSubclassTable( j ) ?
+					JoinFragment.LEFT_OUTER_JOIN :
+					JoinFragment.INNER_JOIN );
+		}
+		return jf;
+	}
+
+	protected SelectFragment createSelect(final int[] subclassColumnNumbers,
+										  final int[] subclassFormulaNumbers) {
+
+		SelectFragment selectFragment = new SelectFragment();
+
+		int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
+		String[] columnAliases = getSubclassColumnAliasClosure();
+		String[] columns = getSubclassColumnClosure();
+		for ( int i = 0; i < subclassColumnNumbers.length; i++ ) {
+			if ( subclassColumnSelectableClosure[i] ) {
+				int columnNumber = subclassColumnNumbers[i];
+				final String subalias = generateTableAlias( getRootAlias(), columnTableNumbers[columnNumber] );
+				selectFragment.addColumn( subalias, columns[columnNumber], columnAliases[columnNumber] );
+			}
+		}
+
+		int[] formulaTableNumbers = getSubclassFormulaTableNumberClosure();
+		String[] formulaTemplates = getSubclassFormulaTemplateClosure();
+		String[] formulaAliases = getSubclassFormulaAliasClosure();
+		for ( int i = 0; i < subclassFormulaNumbers.length; i++ ) {
+			int formulaNumber = subclassFormulaNumbers[i];
+			final String subalias = generateTableAlias( getRootAlias(), formulaTableNumbers[formulaNumber] );
+			selectFragment.addFormula( subalias, formulaTemplates[formulaNumber], formulaAliases[formulaNumber] );
+		}
+
+		return selectFragment;
+	}
+
+	protected String createFrom(int tableNumber, String alias) {
+		return getSubclassTableName( tableNumber ) + ' ' + alias;
+	}
+
+	protected String createWhereByKey(int tableNumber, String alias) {
+		//TODO: move to .sql package, and refactor with similar things!
+		return StringHelper.join( "=? and ",
+				StringHelper.qualify( alias, getSubclassTableKeyColumns( tableNumber ) ) ) + "=?";
+	}
+
+	protected String renderSelect(
+			final int[] tableNumbers,
+	        final int[] columnNumbers,
+	        final int[] formulaNumbers) {
+
+		Arrays.sort( tableNumbers ); //get 'em in the right order (not that it really matters)
+
+		//render the where and from parts
+		int drivingTable = tableNumbers[0];
+		final String drivingAlias = generateTableAlias( getRootAlias(), drivingTable ); //we *could* regerate this inside each called method!
+		final String where = createWhereByKey( drivingTable, drivingAlias );
+		final String from = createFrom( drivingTable, drivingAlias );
+
+		//now render the joins
+		JoinFragment jf = createJoin( tableNumbers, drivingAlias );
+
+		//now render the select clause
+		SelectFragment selectFragment = createSelect( columnNumbers, formulaNumbers );
+
+		//now tie it all together
+		Select select = new Select( getFactory().getDialect() );
+		select.setSelectClause( selectFragment.toFragmentString().substring( 2 ) );
+		select.setFromClause( from );
+		select.setWhereClause( where );
+		select.setOuterJoins( jf.toFromFragmentString(), jf.toWhereFragmentString() );
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "sequential select " + getEntityName() );
+		}
+		return select.toStatementString();
+	}
+
+	private String getRootAlias() {
+		return StringHelper.generateAlias( getEntityName() );
+	}
+
+	protected void postConstruct(Mapping mapping) throws MappingException {
+		initPropertyPaths(mapping);
+
+		//insert/update/delete SQL
+		final int joinSpan = getTableSpan();
+		sqlDeleteStrings = new String[joinSpan];
+		sqlInsertStrings = new String[joinSpan];
+		sqlUpdateStrings = new String[joinSpan];
+		sqlLazyUpdateStrings = new String[joinSpan];
+
+		sqlUpdateByRowIdString = rowIdName == null ?
+				null :
+				generateUpdateString( getPropertyUpdateability(), 0, true );
+		sqlLazyUpdateByRowIdString = rowIdName == null ?
+				null :
+				generateUpdateString( getNonLazyPropertyUpdateability(), 0, true );
+
+		for ( int j = 0; j < joinSpan; j++ ) {
+			sqlInsertStrings[j] = customSQLInsert[j] == null ?
+					generateInsertString( getPropertyInsertability(), j ) :
+					customSQLInsert[j];
+			sqlUpdateStrings[j] = customSQLUpdate[j] == null ?
+					generateUpdateString( getPropertyUpdateability(), j, false ) :
+					customSQLUpdate[j];
+			sqlLazyUpdateStrings[j] = customSQLUpdate[j] == null ?
+					generateUpdateString( getNonLazyPropertyUpdateability(), j, false ) :
+					customSQLUpdate[j];
+			sqlDeleteStrings[j] = customSQLDelete[j] == null ?
+					generateDeleteString( j ) :
+					customSQLDelete[j];
+		}
+
+		tableHasColumns = new boolean[joinSpan];
+		for ( int j = 0; j < joinSpan; j++ ) {
+			tableHasColumns[j] = sqlUpdateStrings[j] != null;
+		}
+
+		//select SQL
+		sqlSnapshotSelectString = generateSnapshotSelectString();
+		sqlLazySelectString = generateLazySelectString();
+		sqlVersionSelectString = generateSelectVersionString();
+		if ( hasInsertGeneratedProperties() ) {
+			sqlInsertGeneratedValuesSelectString = generateInsertGeneratedValuesSelectString();
+		}
+		if ( hasUpdateGeneratedProperties() ) {
+			sqlUpdateGeneratedValuesSelectString = generateUpdateGeneratedValuesSelectString();
+		}
+		if ( isIdentifierAssignedByInsert() ) {
+			identityDelegate = ( ( PostInsertIdentifierGenerator ) getIdentifierGenerator() )
+					.getInsertGeneratedIdentifierDelegate( this, getFactory().getDialect(), useGetGeneratedKeys() );
+			sqlIdentityInsertString = customSQLInsert[0] == null
+					? generateIdentityInsertString( getPropertyInsertability() )
+					: customSQLInsert[0];
+		}
+		else {
+			sqlIdentityInsertString = null;
+		}
+
+		logStaticSQL();
+
+	}
+
+	public void postInstantiate() throws MappingException {
+
+		createLoaders();
+		createUniqueKeyLoaders();
+		createQueryLoader();
+
+	}
+
+	private void createLoaders() {
+		loaders.put( LockMode.NONE, createEntityLoader( LockMode.NONE ) );
+
+		UniqueEntityLoader readLoader = createEntityLoader( LockMode.READ );
+		loaders.put( LockMode.READ, readLoader );
+
+		//TODO: inexact, what we really need to know is: are any outer joins used?
+		boolean disableForUpdate = getSubclassTableSpan() > 1 &&
+				hasSubclasses() &&
+				!getFactory().getDialect().supportsOuterJoinForUpdate();
+
+		loaders.put(
+				LockMode.UPGRADE,
+				disableForUpdate ?
+						readLoader :
+						createEntityLoader( LockMode.UPGRADE )
+			);
+		loaders.put(
+				LockMode.UPGRADE_NOWAIT,
+				disableForUpdate ?
+						readLoader :
+						createEntityLoader( LockMode.UPGRADE_NOWAIT )
+			);
+		loaders.put(
+				LockMode.FORCE,
+				disableForUpdate ?
+						readLoader :
+						createEntityLoader( LockMode.FORCE )
+			);
+
+		loaders.put(
+				"merge",
+				new CascadeEntityLoader( this, CascadingAction.MERGE, getFactory() )
+			);
+		loaders.put(
+				"refresh",
+				new CascadeEntityLoader( this, CascadingAction.REFRESH, getFactory() )
+			);
+	}
+
+	protected void createQueryLoader() {
+		if ( loaderName != null ) {
+			queryLoader = new NamedQueryLoader( loaderName, this );
+		}
+	}
+
+	/**
+	 * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>,
+	 * depending upon the value of the <tt>lock</tt> parameter
+	 */
+	public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session)
+			throws HibernateException {
+
+		if ( log.isTraceEnabled() ) {
+			log.trace(
+					"Fetching entity: " +
+					MessageHelper.infoString( this, id, getFactory() )
+				);
+		}
+
+		final UniqueEntityLoader loader = getAppropriateLoader( lockMode, session );
+		return loader.load( id, optionalObject, session );
+	}
+
+	private UniqueEntityLoader getAppropriateLoader(LockMode lockMode, SessionImplementor session) {
+		final Map enabledFilters = session.getEnabledFilters();
+		if ( queryLoader != null ) {
+			return queryLoader;
+		}
+		else if ( enabledFilters == null || enabledFilters.isEmpty() ) {
+			if ( session.getFetchProfile()!=null && LockMode.UPGRADE.greaterThan(lockMode) ) {
+				return (UniqueEntityLoader) loaders.get( session.getFetchProfile() );
+			}
+			else {
+				return (UniqueEntityLoader) loaders.get( lockMode );
+			}
+		}
+		else {
+			return createEntityLoader( lockMode, enabledFilters );
+		}
+	}
+
+	private boolean isAllNull(Object[] array, int tableNumber) {
+		for ( int i = 0; i < array.length; i++ ) {
+			if ( isPropertyOfTable( i, tableNumber ) && array[i] != null ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public boolean isSubclassPropertyNullable(int i) {
+		return subclassPropertyNullabilityClosure[i];
+	}
+
+	/**
+	 * Transform the array of property indexes to an array of booleans,
+	 * true when the property is dirty
+	 */
+	protected final boolean[] getPropertiesToUpdate(final int[] dirtyProperties, final boolean hasDirtyCollection) {
+		final boolean[] propsToUpdate = new boolean[ entityMetamodel.getPropertySpan() ];
+		final boolean[] updateability = getPropertyUpdateability(); //no need to check laziness, dirty checking handles that
+		for ( int j = 0; j < dirtyProperties.length; j++ ) {
+			int property = dirtyProperties[j];
+			if ( updateability[property] ) {
+				propsToUpdate[property] = true;
+			}
+		}
+		if ( isVersioned() ) {
+			propsToUpdate[ getVersionProperty() ] =
+				Versioning.isVersionIncrementRequired( dirtyProperties, hasDirtyCollection, getPropertyVersionability() );
+		}
+		return propsToUpdate;
+	}
+
+	/**
+	 * Transform the array of property indexes to an array of booleans,
+	 * true when the property is insertable and non-null
+	 */
+	protected boolean[] getPropertiesToInsert(Object[] fields) {
+		boolean[] notNull = new boolean[fields.length];
+		boolean[] insertable = getPropertyInsertability();
+		for ( int i = 0; i < fields.length; i++ ) {
+			notNull[i] = insertable[i] && fields[i] != null;
+		}
+		return notNull;
+	}
+
+	/**
+	 * Locate the property-indices of all properties considered to be dirty.
+	 *
+	 * @param currentState The current state of the entity (the state to be checked).
+	 * @param previousState The previous state of the entity (the state to be checked against).
+	 * @param entity The entity for which we are checking state dirtiness.
+	 * @param session The session in which the check is ccurring.
+	 * @return <tt>null</tt> or the indices of the dirty properties
+	 * @throws HibernateException
+	 */
+	public int[] findDirty(Object[] currentState, Object[] previousState, Object entity, SessionImplementor session)
+	throws HibernateException {
+		int[] props = TypeFactory.findDirty(
+				entityMetamodel.getProperties(),
+				currentState,
+				previousState,
+				propertyColumnUpdateable,
+				hasUninitializedLazyProperties( entity, session.getEntityMode() ),
+				session
+			);
+		if ( props == null ) {
+			return null;
+		}
+		else {
+			logDirtyProperties( props );
+			return props;
+		}
+	}
+
+	/**
+	 * Locate the property-indices of all properties considered to be dirty.
+	 *
+	 * @param old The old state of the entity.
+	 * @param current The current state of the entity.
+	 * @param entity The entity for which we are checking state modification.
+	 * @param session The session in which the check is ccurring.
+	 * @return <tt>null</tt> or the indices of the modified properties
+	 * @throws HibernateException
+	 */
+	public int[] findModified(Object[] old, Object[] current, Object entity, SessionImplementor session)
+	throws HibernateException {
+		int[] props = TypeFactory.findModified(
+				entityMetamodel.getProperties(),
+				current,
+				old,
+				propertyColumnUpdateable,
+				hasUninitializedLazyProperties( entity, session.getEntityMode() ),
+				session
+			);
+		if ( props == null ) {
+			return null;
+		}
+		else {
+			logDirtyProperties( props );
+			return props;
+		}
+	}
+
+	/**
+	 * Which properties appear in the SQL update?
+	 * (Initialized, updateable ones!)
+	 */
+	protected boolean[] getPropertyUpdateability(Object entity, EntityMode entityMode) {
+		return hasUninitializedLazyProperties( entity, entityMode ) ?
+				getNonLazyPropertyUpdateability() :
+				getPropertyUpdateability();
+	}
+
+	private void logDirtyProperties(int[] props) {
+		if ( log.isTraceEnabled() ) {
+			for ( int i = 0; i < props.length; i++ ) {
+				String propertyName = entityMetamodel.getProperties()[ props[i] ].getName();
+				log.trace( StringHelper.qualify( getEntityName(), propertyName ) + " is dirty" );
+			}
+		}
+	}
+
+	protected EntityTuplizer getTuplizer(SessionImplementor session) {
+		return getTuplizer( session.getEntityMode() );
+	}
+
+	protected EntityTuplizer getTuplizer(EntityMode entityMode) {
+		return entityMetamodel.getTuplizer( entityMode );
+	}
+
+	public SessionFactoryImplementor getFactory() {
+		return factory;
+	}
+
+	public EntityMetamodel getEntityMetamodel() {
+		return entityMetamodel;
+	}
+
+	public boolean hasCache() {
+		return cacheAccessStrategy != null;
+	}
+
+	public EntityRegionAccessStrategy getCacheAccessStrategy() {
+		return cacheAccessStrategy;
+	}
+
+	public CacheEntryStructure getCacheEntryStructure() {
+		return cacheEntryStructure;
+	}
+
+	public Comparator getVersionComparator() {
+		return isVersioned() ? getVersionType().getComparator() : null;
+	}
+
+	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	public final String getEntityName() {
+		return entityMetamodel.getName();
+	}
+
+	public EntityType getEntityType() {
+		return entityMetamodel.getEntityType();
+	}
+
+	private String getSubclassEntityName(Class clazz) {
+		return ( String ) entityNameBySubclass.get( clazz );
+	}
+
+	public boolean isPolymorphic() {
+		return entityMetamodel.isPolymorphic();
+	}
+
+	public boolean isInherited() {
+		return entityMetamodel.isInherited();
+	}
+
+	public boolean hasCascades() {
+		return entityMetamodel.hasCascades();
+	}
+
+	public boolean hasIdentifierProperty() {
+		return !entityMetamodel.getIdentifierProperty().isVirtual();
+	}
+
+	public VersionType getVersionType() {
+		return ( VersionType ) locateVersionType();
+	}
+
+	private Type locateVersionType() {
+		return entityMetamodel.getVersionProperty() == null ?
+				null :
+				entityMetamodel.getVersionProperty().getType();
+	}
+
+	public int getVersionProperty() {
+		return entityMetamodel.getVersionPropertyIndex();
+	}
+
+	public boolean isVersioned() {
+		return entityMetamodel.isVersioned();
+	}
+
+	public boolean isIdentifierAssignedByInsert() {
+		return entityMetamodel.getIdentifierProperty().isIdentifierAssignedByInsert();
+	}
+
+	public boolean hasLazyProperties() {
+		return entityMetamodel.hasLazyProperties();
+	}
+
+//	public boolean hasUninitializedLazyProperties(Object entity) {
+//		if ( hasLazyProperties() ) {
+//			InterceptFieldCallback callback = ( ( InterceptFieldEnabled ) entity ).getInterceptFieldCallback();
+//			return callback != null && !( ( FieldInterceptor ) callback ).isInitialized();
+//		}
+//		else {
+//			return false;
+//		}
+//	}
+
+	public void afterReassociate(Object entity, SessionImplementor session) {
+		//if ( hasLazyProperties() ) {
+		if ( FieldInterceptionHelper.isInstrumented( entity ) ) {
+			FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor( entity );
+			if ( interceptor != null ) {
+				interceptor.setSession( session );
+			}
+			else {
+				FieldInterceptor fieldInterceptor = FieldInterceptionHelper.injectFieldInterceptor(
+						entity,
+						getEntityName(),
+						null,
+						session
+				);
+				fieldInterceptor.dirty();
+			}
+		}
+	}
+
+	public Boolean isTransient(Object entity, SessionImplementor session) throws HibernateException {
+		final Serializable id;
+		if ( canExtractIdOutOfEntity() ) {
+			id = getIdentifier( entity, session.getEntityMode() );
+		}
+		else {
+			id = null;
+		}
+		// we *always* assume an instance with a null
+		// identifier or no identifier property is unsaved!
+		if ( id == null ) {
+			return Boolean.TRUE;
+		}
+
+		// check the version unsaved-value, if appropriate
+		final Object version = getVersion( entity, session.getEntityMode() );
+		if ( isVersioned() ) {
+			// let this take precedence if defined, since it works for
+			// assigned identifiers
+			Boolean result = entityMetamodel.getVersionProperty()
+					.getUnsavedValue().isUnsaved( version );
+			if ( result != null ) {
+				return result;
+			}
+		}
+
+		// check the id unsaved-value
+		Boolean result = entityMetamodel.getIdentifierProperty()
+				.getUnsavedValue().isUnsaved( id );
+		if ( result != null ) {
+			return result;
+		}
+
+		// check to see if it is in the second-level cache
+		if ( hasCache() ) {
+			CacheKey ck = new CacheKey(
+					id,
+					getIdentifierType(),
+					getRootEntityName(),
+					session.getEntityMode(),
+					session.getFactory()
+				);
+			if ( getCacheAccessStrategy().get( ck, session.getTimestamp() ) != null ) {
+				return Boolean.FALSE;
+			}
+		}
+
+		return null;
+	}
+
+	public boolean hasCollections() {
+		return entityMetamodel.hasCollections();
+	}
+
+	public boolean hasMutableProperties() {
+		return entityMetamodel.hasMutableProperties();
+	}
+
+	public boolean isMutable() {
+		return entityMetamodel.isMutable();
+	}
+
+	public boolean isAbstract() {
+		return entityMetamodel.isAbstract();
+	}
+
+	public boolean hasSubclasses() {
+		return entityMetamodel.hasSubclasses();
+	}
+
+	public boolean hasProxy() {
+		return entityMetamodel.isLazy();
+	}
+
+	public IdentifierGenerator getIdentifierGenerator() throws HibernateException {
+		return entityMetamodel.getIdentifierProperty().getIdentifierGenerator();
+	}
+
+	public String getRootEntityName() {
+		return entityMetamodel.getRootName();
+	}
+
+	public ClassMetadata getClassMetadata() {
+		return this;
+	}
+
+	public String getMappedSuperclass() {
+		return entityMetamodel.getSuperclass();
+	}
+
+	public boolean isExplicitPolymorphism() {
+		return entityMetamodel.isExplicitPolymorphism();
+	}
+
+	protected boolean useDynamicUpdate() {
+		return entityMetamodel.isDynamicUpdate();
+	}
+
+	protected boolean useDynamicInsert() {
+		return entityMetamodel.isDynamicInsert();
+	}
+
+	protected boolean hasEmbeddedCompositeIdentifier() {
+		return entityMetamodel.getIdentifierProperty().isEmbedded();
+	}
+
+	public boolean canExtractIdOutOfEntity() {
+		return hasIdentifierProperty() || hasEmbeddedCompositeIdentifier() || hasIdentifierMapper();
+	}
+
+	private boolean hasIdentifierMapper() {
+		return entityMetamodel.getIdentifierProperty().hasIdentifierMapper();
+	}
+
+	public String[] getKeyColumnNames() {
+		return getIdentifierColumnNames();
+	}
+
+	public String getName() {
+		return getEntityName();
+	}
+
+	public boolean isCollection() {
+		return false;
+	}
+
+	public boolean consumesEntityAlias() {
+		return true;
+	}
+
+	public boolean consumesCollectionAlias() {
+		return false;
+	}
+
+	public Type getPropertyType(String propertyName) throws MappingException {
+		return propertyMapping.toType(propertyName);
+	}
+
+	public Type getType() {
+		return entityMetamodel.getEntityType();
+	}
+
+	public boolean isSelectBeforeUpdateRequired() {
+		return entityMetamodel.isSelectBeforeUpdate();
+	}
+
+	protected final int optimisticLockMode() {
+		return entityMetamodel.getOptimisticLockMode();
+	}
+
+	public Object createProxy(Serializable id, SessionImplementor session) throws HibernateException {
+		return entityMetamodel.getTuplizer( session.getEntityMode() )
+				.createProxy( id, session );
+	}
+
+	public String toString() {
+		return StringHelper.unqualify( getClass().getName() ) +
+				'(' + entityMetamodel.getName() + ')';
+	}
+
+	public final String selectFragment(
+			Joinable rhs,
+			String rhsAlias,
+			String lhsAlias,
+			String entitySuffix,
+			String collectionSuffix,
+			boolean includeCollectionColumns) {
+		return selectFragment( lhsAlias, entitySuffix );
+	}
+
+	public boolean isInstrumented(EntityMode entityMode) {
+		EntityTuplizer tuplizer = entityMetamodel.getTuplizerOrNull(entityMode);
+		return tuplizer!=null && tuplizer.isInstrumented();
+	}
+
+	public boolean hasInsertGeneratedProperties() {
+		return entityMetamodel.hasInsertGeneratedValues();
+	}
+
+	public boolean hasUpdateGeneratedProperties() {
+		return entityMetamodel.hasUpdateGeneratedValues();
+	}
+
+	public boolean isVersionPropertyGenerated() {
+		return isVersioned() && ( getPropertyUpdateGenerationInclusions() [ getVersionProperty() ] != ValueInclusion.NONE );
+	}
+
+	public boolean isVersionPropertyInsertable() {
+		return isVersioned() && getPropertyInsertability() [ getVersionProperty() ];
+	}
+
+	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
+		getTuplizer( session ).afterInitialize( entity, lazyPropertiesAreUnfetched, session );
+	}
+
+	public String[] getPropertyNames() {
+		return entityMetamodel.getPropertyNames();
+	}
+
+	public Type[] getPropertyTypes() {
+		return entityMetamodel.getPropertyTypes();
+	}
+
+	public boolean[] getPropertyLaziness() {
+		return entityMetamodel.getPropertyLaziness();
+	}
+
+	public boolean[] getPropertyUpdateability() {
+		return entityMetamodel.getPropertyUpdateability();
+	}
+
+	public boolean[] getPropertyCheckability() {
+		return entityMetamodel.getPropertyCheckability();
+	}
+
+	public boolean[] getNonLazyPropertyUpdateability() {
+		return entityMetamodel.getNonlazyPropertyUpdateability();
+	}
+
+	public boolean[] getPropertyInsertability() {
+		return entityMetamodel.getPropertyInsertability();
+	}
+
+	public ValueInclusion[] getPropertyInsertGenerationInclusions() {
+		return entityMetamodel.getPropertyInsertGenerationInclusions();
+	}
+
+	public ValueInclusion[] getPropertyUpdateGenerationInclusions() {
+		return entityMetamodel.getPropertyUpdateGenerationInclusions();
+	}
+
+	public boolean[] getPropertyNullability() {
+		return entityMetamodel.getPropertyNullability();
+	}
+
+	public boolean[] getPropertyVersionability() {
+		return entityMetamodel.getPropertyVersionability();
+	}
+
+	public CascadeStyle[] getPropertyCascadeStyles() {
+		return entityMetamodel.getCascadeStyles();
+	}
+
+	public final Class getMappedClass(EntityMode entityMode) {
+		Tuplizer tup = entityMetamodel.getTuplizerOrNull(entityMode);
+		return tup==null ? null : tup.getMappedClass();
+	}
+
+	public boolean implementsLifecycle(EntityMode entityMode) {
+		return getTuplizer( entityMode ).isLifecycleImplementor();
+	}
+
+	public boolean implementsValidatable(EntityMode entityMode) {
+		return getTuplizer( entityMode ).isValidatableImplementor();
+	}
+
+	public Class getConcreteProxyClass(EntityMode entityMode) {
+		return getTuplizer( entityMode ).getConcreteProxyClass();
+	}
+
+	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode)
+			throws HibernateException {
+		getTuplizer( entityMode ).setPropertyValues( object, values );
+	}
+
+	public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode)
+			throws HibernateException {
+		getTuplizer( entityMode ).setPropertyValue( object, i, value );
+	}
+
+	public Object[] getPropertyValues(Object object, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).getPropertyValues( object );
+	}
+
+	public Object getPropertyValue(Object object, int i, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).getPropertyValue( object , i );
+	}
+
+	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).getPropertyValue( object, propertyName );
+	}
+
+	public Serializable getIdentifier(Object object, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).getIdentifier( object );
+	}
+
+	public void setIdentifier(Object object, Serializable id, EntityMode entityMode)
+			throws HibernateException {
+		getTuplizer( entityMode ).setIdentifier( object, id );
+	}
+
+	public Object getVersion(Object object, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).getVersion( object );
+	}
+
+	public Object instantiate(Serializable id, EntityMode entityMode)
+			throws HibernateException {
+		return getTuplizer( entityMode ).instantiate( id );
+	}
+
+	public boolean isInstance(Object object, EntityMode entityMode) {
+		return getTuplizer( entityMode ).isInstance( object );
+	}
+
+	public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode) {
+		return getTuplizer( entityMode ).hasUninitializedLazyProperties( object );
+	}
+
+	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode) {
+		getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion );
+	}
+
+	public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode) {
+		if ( !hasSubclasses() ) {
+			return this;
+		}
+		else {
+			// TODO : really need a way to do something like :
+			//      getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
+			Class clazz = instance.getClass();
+			if ( clazz == getMappedClass( entityMode ) ) {
+				return this;
+			}
+			else {
+				String subclassEntityName = getSubclassEntityName( clazz );
+				if ( subclassEntityName == null ) {
+					throw new HibernateException(
+							"instance not of expected entity type: " + clazz.getName() +
+							" is not a: " + getEntityName()
+						);
+				}
+				else {
+					return factory.getEntityPersister( subclassEntityName );
+				}
+			}
+		}
+	}
+
+	public EntityMode guessEntityMode(Object object) {
+		return entityMetamodel.guessEntityMode(object);
+	}
+
+	public boolean isMultiTable() {
+		return false;
+	}
+
+	public String getTemporaryIdTableName() {
+		return temporaryIdTableName;
+	}
+
+	public String getTemporaryIdTableDDL() {
+		return temporaryIdTableDDL;
+	}
+
+	protected int getPropertySpan() {
+		return entityMetamodel.getPropertySpan();
+	}
+
+	public Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SessionImplementor session) throws HibernateException {
+		return getTuplizer( session.getEntityMode() ).getPropertyValuesToInsert( object, mergeMap, session );
+	}
+
+	public void processInsertGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) {
+		if ( !hasInsertGeneratedProperties() ) {
+			throw new AssertionFailure("no insert-generated properties");
+		}
+		processGeneratedProperties( id, entity, state, session, sqlInsertGeneratedValuesSelectString, getPropertyInsertGenerationInclusions() );
+	}
+
+	public void processUpdateGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session) {
+		if ( !hasUpdateGeneratedProperties() ) {
+			throw new AssertionFailure("no update-generated properties");
+		}
+		processGeneratedProperties( id, entity, state, session, sqlUpdateGeneratedValuesSelectString, getPropertyUpdateGenerationInclusions() );
+	}
+
+	private void processGeneratedProperties(
+			Serializable id,
+	        Object entity,
+	        Object[] state,
+	        SessionImplementor session,
+	        String selectionSQL,
+	        ValueInclusion[] includeds) {
+
+		session.getBatcher().executeBatch(); //force immediate execution of the insert
+
+		try {
+			PreparedStatement ps = session.getBatcher().prepareSelectStatement( selectionSQL );
+			try {
+				getIdentifierType().nullSafeSet( ps, id, 1, session );
+				ResultSet rs = ps.executeQuery();
+				try {
+					if ( !rs.next() ) {
+						throw new HibernateException(
+								"Unable to locate row for retrieval of generated properties: " +
+								MessageHelper.infoString( this, id, getFactory() )
+							);
+					}
+					for ( int i = 0; i < getPropertySpan(); i++ ) {
+						if ( includeds[i] != ValueInclusion.NONE ) {
+							Object hydratedState = getPropertyTypes()[i].hydrate( rs, getPropertyAliases( "", i ), session, entity );
+							state[i] = getPropertyTypes()[i].resolve( hydratedState, session, entity );
+							setPropertyValue( entity, i, state[i], session.getEntityMode() );
+						}
+					}
+				}
+				finally {
+					if ( rs != null ) {
+						rs.close();
+					}
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( ps );
+			}
+		}
+		catch( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"unable to select generated column values",
+					selectionSQL
+			);
+		}
+
+	}
+
+	public String getIdentifierPropertyName() {
+		return entityMetamodel.getIdentifierProperty().getName();
+	}
+
+	public Type getIdentifierType() {
+		return entityMetamodel.getIdentifierProperty().getType();
+	}
+
+	public boolean hasSubselectLoadableCollections() {
+		return hasSubselectLoadableCollections;
+	}
+
+	public int[] getNaturalIdentifierProperties() {
+		return entityMetamodel.getNaturalIdentifierProperties();
+	}
+
+	public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session) throws HibernateException {
+		if ( !hasNaturalIdentifier() ) {
+			throw new MappingException( "persistent class did not define a natural-id : " + MessageHelper.infoString( this ) );
+		}
+		if ( log.isTraceEnabled() ) {
+			log.trace( "Getting current natural-id snapshot state for: " + MessageHelper.infoString( this, id, getFactory() ) );
+		}
+
+		int[] naturalIdPropertyIndexes = getNaturalIdentifierProperties();
+		int naturalIdPropertyCount = naturalIdPropertyIndexes.length;
+		boolean[] naturalIdMarkers = new boolean[ getPropertySpan() ];
+		Type[] extractionTypes = new Type[ naturalIdPropertyCount ];
+		for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
+			extractionTypes[i] = getPropertyTypes()[ naturalIdPropertyIndexes[i] ];
+			naturalIdMarkers[ naturalIdPropertyIndexes[i] ] = true;
+		}
+
+		///////////////////////////////////////////////////////////////////////
+		// TODO : look at perhaps caching this...
+		Select select = new Select( getFactory().getDialect() );
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "get current natural-id state " + getEntityName() );
+		}
+		select.setSelectClause( concretePropertySelectFragmentSansLeadingComma( getRootAlias(), naturalIdMarkers ) );
+		select.setFromClause( fromTableFragment( getRootAlias() ) + fromJoinFragment( getRootAlias(), true, false ) );
+
+		String[] aliasedIdColumns = StringHelper.qualify( getRootAlias(), getIdentifierColumnNames() );
+		String whereClause = new StringBuffer()
+			.append( StringHelper.join( "=? and ",
+					aliasedIdColumns ) )
+			.append( "=?" )
+			.append( whereJoinFragment( getRootAlias(), true, false ) )
+			.toString();
+
+		String sql = select.setOuterJoins( "", "" )
+				.setWhereClause( whereClause )
+				.toStatementString();
+		///////////////////////////////////////////////////////////////////////
+
+		Object[] snapshot = new Object[ naturalIdPropertyCount ];
+		try {
+			PreparedStatement ps = session.getBatcher().prepareSelectStatement( sql );
+			try {
+				getIdentifierType().nullSafeSet( ps, id, 1, session );
+				ResultSet rs = ps.executeQuery();
+				try {
+					//if there is no resulting row, return null
+					if ( !rs.next() ) {
+						return null;
+					}
+
+					for ( int i = 0; i < naturalIdPropertyCount; i++ ) {
+						snapshot[i] = extractionTypes[i].hydrate( rs, getPropertyAliases( "", naturalIdPropertyIndexes[i] ), session, null );
+					}
+					return snapshot;
+				}
+				finally {
+					rs.close();
+				}
+			}
+			finally {
+				session.getBatcher().closeStatement( ps );
+			}
+		}
+		catch ( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+					getFactory().getSQLExceptionConverter(),
+					sqle,
+					"could not retrieve snapshot: " +
+					MessageHelper.infoString( this, id, getFactory() ),
+			        sql
+				);
+		}
+	}
+
+	protected String concretePropertySelectFragmentSansLeadingComma(String alias, boolean[] include) {
+		String concretePropertySelectFragment = concretePropertySelectFragment( alias, include );
+		int firstComma = concretePropertySelectFragment.indexOf( ", " );
+		if ( firstComma == 0 ) {
+			concretePropertySelectFragment = concretePropertySelectFragment.substring( 2 );
+		}
+		return concretePropertySelectFragment;
+	}
+	public boolean hasNaturalIdentifier() {
+		return entityMetamodel.hasNaturalIdentifier();
+	}
+
+	public void setPropertyValue(Object object, String propertyName, Object value, EntityMode entityMode)
+			throws HibernateException {
+		getTuplizer( entityMode ).setPropertyValue( object, propertyName, value );
+	}
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,234 +0,0 @@
-//$Id: AbstractPropertyMapping.java 10852 2006-11-21 17:39:14Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.sql.Template;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Base implementation of a <tt>PropertyMapping</tt>
- *
- * @author Gavin King
- */
-public abstract class AbstractPropertyMapping implements PropertyMapping {
-
-	private final Map typesByPropertyPath = new HashMap();
-	private final Map columnsByPropertyPath = new HashMap();
-	private final Map formulaTemplatesByPropertyPath = new HashMap();
-
-	public String[] getIdentifierColumnNames() {
-		throw new UnsupportedOperationException("one-to-one is not supported here");
-	}
-
-	protected abstract String getEntityName();
-
-	public Type toType(String propertyName) throws QueryException {
-		Type type = (Type) typesByPropertyPath.get(propertyName);
-		if ( type == null ) {
-			throw propertyException( propertyName );
-		}
-		return type;
-	}
-
-	protected final QueryException propertyException(String propertyName) throws QueryException {
-		return new QueryException( "could not resolve property: " + propertyName + " of: " + getEntityName() );
-	}
-
-	public String[] getColumnNames(String propertyName) {
-		String[] cols = (String[]) columnsByPropertyPath.get(propertyName);
-		if (cols==null) {
-			throw new MappingException("unknown property: " + propertyName);
-		}
-		return cols;
-	}
-
-	public String[] toColumns(String alias, String propertyName) throws QueryException {
-		//TODO: *two* hashmap lookups here is one too many...
-		String[] columns = (String[]) columnsByPropertyPath.get(propertyName);
-		if ( columns == null ) {
-			throw propertyException( propertyName );
-		}
-		String[] templates = (String[]) formulaTemplatesByPropertyPath.get(propertyName);
-		String[] result = new String[columns.length];
-		for ( int i=0; i<columns.length; i++ ) {
-			if ( columns[i]==null ) {
-				result[i] = StringHelper.replace( templates[i], Template.TEMPLATE, alias );
-			}
-			else {
-				result[i] = StringHelper.qualify( alias, columns[i] );
-			}
-		}
-		return result;
-	}
-
-	public String[] toColumns(String propertyName) throws QueryException {
-		String[] columns = (String[]) columnsByPropertyPath.get(propertyName);
-		if ( columns == null ) {
-			throw propertyException( propertyName );
-		}
-		String[] templates = (String[]) formulaTemplatesByPropertyPath.get(propertyName);
-		String[] result = new String[columns.length];
-		for ( int i=0; i<columns.length; i++ ) {
-			if ( columns[i]==null ) {
-				result[i] = StringHelper.replace( templates[i], Template.TEMPLATE, "" );
-			}
-			else {
-				result[i] = columns[i];
-			}
-		}
-		return result;
-	}
-
-	protected void addPropertyPath(String path, Type type, String[] columns, String[] formulaTemplates) {
-		typesByPropertyPath.put(path, type);
-		columnsByPropertyPath.put(path, columns);
-		if (formulaTemplates!=null) {
-			formulaTemplatesByPropertyPath.put(path, formulaTemplates);
-		}
-	}
-
-	/*protected void initPropertyPaths(
-			final String path,
-			final Type type,
-			final String[] columns,
-			final String[] formulaTemplates,
-			final Mapping factory)
-	throws MappingException {
-		//addFormulaPropertyPath(path, type, formulaTemplates);
-		initPropertyPaths(path, type, columns, formulaTemplates, factory);
-	}*/
-
-	protected void initPropertyPaths(
-			final String path,
-			final Type type,
-			String[] columns,
-			final String[] formulaTemplates,
-			final Mapping factory)
-	throws MappingException {
-
-		if ( columns.length!=type.getColumnSpan(factory) ) {
-			throw new MappingException(
-					"broken column mapping for: " + path +
-					" of: " + getEntityName()
-				);
-		}
-
-		if ( type.isAssociationType() ) {
-			AssociationType actype = (AssociationType) type;
-			if ( actype.useLHSPrimaryKey() ) {
-				columns = getIdentifierColumnNames();
-			}
-			else {
-				String foreignKeyProperty = actype.getLHSPropertyName();
-				if ( foreignKeyProperty!=null && !path.equals(foreignKeyProperty) ) {
-					//TODO: this requires that the collection is defined after the
-					//      referenced property in the mapping file (ok?)
-					columns = (String[]) columnsByPropertyPath.get(foreignKeyProperty);
-					if (columns==null) return; //get em on the second pass!
-				}
-			}
-		}
-
-		if (path!=null) addPropertyPath(path, type, columns, formulaTemplates);
-
-		if ( type.isComponentType() ) {
-			AbstractComponentType actype = (AbstractComponentType) type;
-			initComponentPropertyPaths( path, actype, columns, formulaTemplates, factory );
-			if ( actype.isEmbedded() ) {
-				initComponentPropertyPaths(
-						path==null ? null : StringHelper.qualifier(path),
-						actype,
-						columns,
-						formulaTemplates,
-						factory
-					);
-			}
-		}
-		else if ( type.isEntityType() ) {
-			initIdentifierPropertyPaths( path, (EntityType) type, columns, factory );
-		}
-	}
-
-	protected void initIdentifierPropertyPaths(
-			final String path,
-			final EntityType etype,
-			final String[] columns,
-			final Mapping factory) throws MappingException {
-
-		Type idtype = etype.getIdentifierOrUniqueKeyType( factory );
-		String idPropName = etype.getIdentifierOrUniqueKeyPropertyName(factory);
-		boolean hasNonIdentifierPropertyNamedId = hasNonIdentifierPropertyNamedId( etype, factory );
-
-		if ( etype.isReferenceToPrimaryKey() ) {
-			if ( !hasNonIdentifierPropertyNamedId ) {
-				String idpath1 = extendPath(path, EntityPersister.ENTITY_ID);
-				addPropertyPath(idpath1, idtype, columns, null);
-				initPropertyPaths(idpath1, idtype, columns, null, factory);
-			}
-		}
-
-		if (idPropName!=null) {
-			String idpath2 = extendPath(path, idPropName);
-			addPropertyPath(idpath2, idtype, columns, null);
-			initPropertyPaths(idpath2, idtype, columns, null, factory);
-		}
-	}
-
-	private boolean hasNonIdentifierPropertyNamedId(final EntityType entityType, final Mapping factory) {
-		// TODO : would be great to have a Mapping#hasNonIdentifierPropertyNamedId method
-		// I don't believe that Mapping#getReferencedPropertyType accounts for the identifier property; so
-		// if it returns for a property named 'id', then we should have a non-id field named id
-		try {
-			return factory.getReferencedPropertyType( entityType.getAssociatedEntityName(), EntityPersister.ENTITY_ID ) != null;
-		}
-		catch( MappingException e ) {
-			return false;
-		}
-	}
-
-	protected void initComponentPropertyPaths(
-			final String path,
-			final AbstractComponentType type,
-			final String[] columns,
-			String[] formulaTemplates, final Mapping factory)
-	throws MappingException {
-
-		Type[] types = type.getSubtypes();
-		String[] properties = type.getPropertyNames();
-		int begin=0;
-		for ( int i=0; i<properties.length; i++ ) {
-			String subpath = extendPath( path, properties[i] );
-			try {
-				int length = types[i].getColumnSpan(factory);
-				String[] columnSlice = ArrayHelper.slice(columns, begin, length);
-				String[] formulaSlice = formulaTemplates==null ?
-						null : ArrayHelper.slice(formulaTemplates, begin, length);
-				initPropertyPaths(subpath, types[i], columnSlice, formulaSlice, factory);
-				begin+=length;
-			}
-			catch (Exception e) {
-				throw new MappingException("bug in initComponentPropertyPaths", e);
-			}
-		}
-	}
-
-	private static String extendPath(String path, String property) {
-		if ( path==null || "".equals(path) ) {
-			return property;
-		}
-		else {
-			return StringHelper.qualify(path, property);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/AbstractPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,257 @@
+/*
+ * 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.persister.entity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.sql.Template;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Basic implementation of the {@link PropertyMapping} contract.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractPropertyMapping implements PropertyMapping {
+
+	private final Map typesByPropertyPath = new HashMap();
+	private final Map columnsByPropertyPath = new HashMap();
+	private final Map formulaTemplatesByPropertyPath = new HashMap();
+
+	public String[] getIdentifierColumnNames() {
+		throw new UnsupportedOperationException("one-to-one is not supported here");
+	}
+
+	protected abstract String getEntityName();
+
+	public Type toType(String propertyName) throws QueryException {
+		Type type = (Type) typesByPropertyPath.get(propertyName);
+		if ( type == null ) {
+			throw propertyException( propertyName );
+		}
+		return type;
+	}
+
+	protected final QueryException propertyException(String propertyName) throws QueryException {
+		return new QueryException( "could not resolve property: " + propertyName + " of: " + getEntityName() );
+	}
+
+	public String[] getColumnNames(String propertyName) {
+		String[] cols = (String[]) columnsByPropertyPath.get(propertyName);
+		if (cols==null) {
+			throw new MappingException("unknown property: " + propertyName);
+		}
+		return cols;
+	}
+
+	public String[] toColumns(String alias, String propertyName) throws QueryException {
+		//TODO: *two* hashmap lookups here is one too many...
+		String[] columns = (String[]) columnsByPropertyPath.get(propertyName);
+		if ( columns == null ) {
+			throw propertyException( propertyName );
+		}
+		String[] templates = (String[]) formulaTemplatesByPropertyPath.get(propertyName);
+		String[] result = new String[columns.length];
+		for ( int i=0; i<columns.length; i++ ) {
+			if ( columns[i]==null ) {
+				result[i] = StringHelper.replace( templates[i], Template.TEMPLATE, alias );
+			}
+			else {
+				result[i] = StringHelper.qualify( alias, columns[i] );
+			}
+		}
+		return result;
+	}
+
+	public String[] toColumns(String propertyName) throws QueryException {
+		String[] columns = (String[]) columnsByPropertyPath.get(propertyName);
+		if ( columns == null ) {
+			throw propertyException( propertyName );
+		}
+		String[] templates = (String[]) formulaTemplatesByPropertyPath.get(propertyName);
+		String[] result = new String[columns.length];
+		for ( int i=0; i<columns.length; i++ ) {
+			if ( columns[i]==null ) {
+				result[i] = StringHelper.replace( templates[i], Template.TEMPLATE, "" );
+			}
+			else {
+				result[i] = columns[i];
+			}
+		}
+		return result;
+	}
+
+	protected void addPropertyPath(String path, Type type, String[] columns, String[] formulaTemplates) {
+		typesByPropertyPath.put(path, type);
+		columnsByPropertyPath.put(path, columns);
+		if (formulaTemplates!=null) {
+			formulaTemplatesByPropertyPath.put(path, formulaTemplates);
+		}
+	}
+
+	/*protected void initPropertyPaths(
+			final String path,
+			final Type type,
+			final String[] columns,
+			final String[] formulaTemplates,
+			final Mapping factory)
+	throws MappingException {
+		//addFormulaPropertyPath(path, type, formulaTemplates);
+		initPropertyPaths(path, type, columns, formulaTemplates, factory);
+	}*/
+
+	protected void initPropertyPaths(
+			final String path,
+			final Type type,
+			String[] columns,
+			final String[] formulaTemplates,
+			final Mapping factory)
+	throws MappingException {
+
+		if ( columns.length!=type.getColumnSpan(factory) ) {
+			throw new MappingException(
+					"broken column mapping for: " + path +
+					" of: " + getEntityName()
+				);
+		}
+
+		if ( type.isAssociationType() ) {
+			AssociationType actype = (AssociationType) type;
+			if ( actype.useLHSPrimaryKey() ) {
+				columns = getIdentifierColumnNames();
+			}
+			else {
+				String foreignKeyProperty = actype.getLHSPropertyName();
+				if ( foreignKeyProperty!=null && !path.equals(foreignKeyProperty) ) {
+					//TODO: this requires that the collection is defined after the
+					//      referenced property in the mapping file (ok?)
+					columns = (String[]) columnsByPropertyPath.get(foreignKeyProperty);
+					if (columns==null) return; //get em on the second pass!
+				}
+			}
+		}
+
+		if (path!=null) addPropertyPath(path, type, columns, formulaTemplates);
+
+		if ( type.isComponentType() ) {
+			AbstractComponentType actype = (AbstractComponentType) type;
+			initComponentPropertyPaths( path, actype, columns, formulaTemplates, factory );
+			if ( actype.isEmbedded() ) {
+				initComponentPropertyPaths(
+						path==null ? null : StringHelper.qualifier(path),
+						actype,
+						columns,
+						formulaTemplates,
+						factory
+					);
+			}
+		}
+		else if ( type.isEntityType() ) {
+			initIdentifierPropertyPaths( path, (EntityType) type, columns, factory );
+		}
+	}
+
+	protected void initIdentifierPropertyPaths(
+			final String path,
+			final EntityType etype,
+			final String[] columns,
+			final Mapping factory) throws MappingException {
+
+		Type idtype = etype.getIdentifierOrUniqueKeyType( factory );
+		String idPropName = etype.getIdentifierOrUniqueKeyPropertyName(factory);
+		boolean hasNonIdentifierPropertyNamedId = hasNonIdentifierPropertyNamedId( etype, factory );
+
+		if ( etype.isReferenceToPrimaryKey() ) {
+			if ( !hasNonIdentifierPropertyNamedId ) {
+				String idpath1 = extendPath(path, EntityPersister.ENTITY_ID);
+				addPropertyPath(idpath1, idtype, columns, null);
+				initPropertyPaths(idpath1, idtype, columns, null, factory);
+			}
+		}
+
+		if (idPropName!=null) {
+			String idpath2 = extendPath(path, idPropName);
+			addPropertyPath(idpath2, idtype, columns, null);
+			initPropertyPaths(idpath2, idtype, columns, null, factory);
+		}
+	}
+
+	private boolean hasNonIdentifierPropertyNamedId(final EntityType entityType, final Mapping factory) {
+		// TODO : would be great to have a Mapping#hasNonIdentifierPropertyNamedId method
+		// I don't believe that Mapping#getReferencedPropertyType accounts for the identifier property; so
+		// if it returns for a property named 'id', then we should have a non-id field named id
+		try {
+			return factory.getReferencedPropertyType( entityType.getAssociatedEntityName(), EntityPersister.ENTITY_ID ) != null;
+		}
+		catch( MappingException e ) {
+			return false;
+		}
+	}
+
+	protected void initComponentPropertyPaths(
+			final String path,
+			final AbstractComponentType type,
+			final String[] columns,
+			String[] formulaTemplates, final Mapping factory)
+	throws MappingException {
+
+		Type[] types = type.getSubtypes();
+		String[] properties = type.getPropertyNames();
+		int begin=0;
+		for ( int i=0; i<properties.length; i++ ) {
+			String subpath = extendPath( path, properties[i] );
+			try {
+				int length = types[i].getColumnSpan(factory);
+				String[] columnSlice = ArrayHelper.slice(columns, begin, length);
+				String[] formulaSlice = formulaTemplates==null ?
+						null : ArrayHelper.slice(formulaTemplates, begin, length);
+				initPropertyPaths(subpath, types[i], columnSlice, formulaSlice, factory);
+				begin+=length;
+			}
+			catch (Exception e) {
+				throw new MappingException("bug in initComponentPropertyPaths", e);
+			}
+		}
+	}
+
+	private static String extendPath(String path, String property) {
+		if ( path==null || "".equals(path) ) {
+			return property;
+		}
+		else {
+			return StringHelper.qualify(path, property);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: BasicEntityPropertyMapping.java 7636 2005-07-24 23:51:12Z oneovthafew $
-package org.hibernate.persister.entity;
-
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-
-/**
- * @author Gavin King
- */
-public class BasicEntityPropertyMapping extends AbstractPropertyMapping {
-
-	private final AbstractEntityPersister persister;
-
-	public BasicEntityPropertyMapping(AbstractEntityPersister persister) {
-		this.persister = persister;
-	}
-	
-	public String[] getIdentifierColumnNames() {
-		return persister.getIdentifierColumnNames();
-	}
-
-	protected String getEntityName() {
-		return persister.getEntityName();
-	}
-
-	public Type getType() {
-		return persister.getType();
-	}
-
-	public String[] toColumns(final String alias, final String propertyName) throws QueryException {
-		return super.toColumns( 
-				persister.generateTableAlias( alias, persister.getSubclassPropertyTableNumber(propertyName) ), 
-				propertyName 
-			);
-	}
-	
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/BasicEntityPropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+import org.hibernate.QueryException;
+import org.hibernate.type.Type;
+
+/**
+ * @author Gavin King
+ */
+public class BasicEntityPropertyMapping extends AbstractPropertyMapping {
+
+	private final AbstractEntityPersister persister;
+
+	public BasicEntityPropertyMapping(AbstractEntityPersister persister) {
+		this.persister = persister;
+	}
+	
+	public String[] getIdentifierColumnNames() {
+		return persister.getIdentifierColumnNames();
+	}
+
+	protected String getEntityName() {
+		return persister.getEntityName();
+	}
+
+	public Type getType() {
+		return persister.getType();
+	}
+
+	public String[] toColumns(final String alias, final String propertyName) throws QueryException {
+		return super.toColumns( 
+				persister.generateTableAlias( alias, persister.getSubclassPropertyTableNumber(propertyName) ), 
+				propertyName 
+			);
+	}
+	
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,660 +0,0 @@
-//$Id: EntityPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.EntityMode;
-import org.hibernate.tuple.entity.EntityMetamodel;
-import org.hibernate.cache.CacheConcurrencyStrategy;
-import org.hibernate.cache.OptimisticCacheSource;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cache.entry.CacheEntryStructure;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.ValueInclusion;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.type.Type;
-import org.hibernate.type.VersionType;
-
-/**
- * Implementors define mapping and persistence logic for a particular
- * strategy of entity mapping.  An instance of entity persisters corresponds
- * to a given mapped entity.
- * <p/>
- * Implementors must be threadsafe (preferrably immutable) and must provide a constructor
- * matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.SessionFactoryImplementor}
- *
- * @author Gavin King
- */
-public interface EntityPersister extends OptimisticCacheSource {
-
-	/**
-	 * The property name of the "special" identifier property in HQL
-	 */
-	public static final String ENTITY_ID = "id";
-
-	/**
-	 * Finish the initialization of this object.
-	 * <p/>
-	 * Called only once per {@link org.hibernate.SessionFactory} lifecycle,
-	 * after all entity persisters have been instantiated.
-	 *
-	 * @throws org.hibernate.MappingException Indicates an issue in the metdata.
-	 */
-	public void postInstantiate() throws MappingException;
-
-	/**
-	 * Return the SessionFactory to which this persister "belongs".
-	 *
-	 * @return The owning SessionFactory.
-	 */
-	public SessionFactoryImplementor getFactory();
-
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Returns an object that identifies the space in which identifiers of
-	 * this entity hierarchy are unique.  Might be a table name, a JNDI URL, etc.
-	 *
-	 * @return The root entity name.
-	 */
-	public String getRootEntityName();
-
-	/**
-	 * The entity name which this persister maps.
-	 *
-	 * @return The name of the entity which this persister maps.
-	 */
-	public String getEntityName();
-
-	/**
-	 * Retrieve the underlying entity metamodel instance...
-	 *
-	 *@return The metamodel
-	 */
-	public EntityMetamodel getEntityMetamodel();
-
-	/**
-	 * Determine whether the given name represents a subclass entity
-	 * (or this entity itself) of the entity mapped by this persister.
-	 *
-	 * @param entityName The entity name to be checked.
-	 * @return True if the given entity name represents either the entity
-	 * mapped by this persister or one of its subclass entities; false
-	 * otherwise.
-	 */
-	public boolean isSubclassEntityName(String entityName);
-
-	/**
-	 * Returns an array of objects that identify spaces in which properties of
-	 * this entity are persisted, for instances of this class only.
-	 * <p/>
-	 * For most implementations, this returns the complete set of table names
-	 * to which instances of the mapped entity are persisted (not accounting
-	 * for superclass entity mappings).
-	 *
-	 * @return The property spaces.
-	 */
-	public Serializable[] getPropertySpaces();
-
-	/**
-	 * Returns an array of objects that identify spaces in which properties of
-	 * this entity are persisted, for instances of this class and its subclasses.
-	 * <p/>
-	 * Much like {@link #getPropertySpaces()}, except that here we include subclass
-	 * entity spaces.
-	 *
-	 * @return The query spaces.
-	 */
-	public Serializable[] getQuerySpaces();
-
-	/**
-	 * Determine whether this entity supports dynamic proxies.
-	 *
-	 * @return True if the entity has dynamic proxy support; false otherwise.
-	 */
-	public boolean hasProxy();
-
-	/**
-	 * Determine whether this entity contains references to persistent collections.
-	 *
-	 * @return True if the entity does contain persistent collections; false otherwise.
-	 */
-	public boolean hasCollections();
-
-	/**
-	 * Determine whether any properties of this entity are considered mutable.
-	 *
-	 * @return True if any properties of the entity are mutable; false otherwise (meaning none are).
-	 */
-	public boolean hasMutableProperties();
-
-	/**
-	 * Determine whether this entity contains references to persistent collections
-	 * which are fetchable by subselect?
-	 *
-	 * @return True if the entity contains collections fetchable by subselect; false otherwise.
-	 */
-	public boolean hasSubselectLoadableCollections();
-
-	/**
-	 * Determine whether this entity has any non-none cascading.
-	 *
-	 * @return True if the entity has any properties with a cscade other than NONE;
-	 * false otherwise (aka, no cascading).
-	 */
-	public boolean hasCascades();
-
-	/**
-	 * Determine whether instances of this entity are considered mutable.
-	 *
-	 * @return True if the entity is considered mutable; false otherwise.
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Determine whether the entity is inherited one or more other entities.
-	 * In other words, is this entity a subclass of other entities.
-	 *
-	 * @return True if other entities extend this entity; false otherwise.
-	 */
-	public boolean isInherited();
-
-	/**
-	 * Are identifiers of this entity assigned known before the insert execution?
-	 * Or, are they generated (in the database) by the insert execution.
-	 *
-	 * @return True if identifiers for this entity are generated by the insert
-	 * execution.
-	 */
-	public boolean isIdentifierAssignedByInsert();
-
-	/**
-	 * Get the type of a particular property by name.
-	 *
-	 * @param propertyName The name of the property for which to retrieve
-	 * the typpe.
-	 * @return The type.
-	 * @throws org.hibernate.MappingException Typically indicates an unknown
-	 * property name.
-	 */
-	public Type getPropertyType(String propertyName) throws MappingException;
-
-	/**
-	 * Compare the two snapshots to determine if they represent dirty state.
-	 *
-	 * @param currentState The current snapshot
-	 * @param previousState The baseline snapshot
-	 * @param owner The entity containing the state
-	 * @param session The originating session
-	 * @return The indices of all dirty properties, or null if no properties
-	 * were dirty.
-	 */
-	public int[] findDirty(Object[] currentState, Object[] previousState, Object owner, SessionImplementor session);
-
-	/**
-	 * Compare the two snapshots to determine if they represent modified state.
-	 *
-	 * @param old The baseline snapshot
-	 * @param current The current snapshot
-	 * @param object The entity containing the state
-	 * @param session The originating session
-	 * @return The indices of all modified properties, or null if no properties
-	 * were modified.
-	 */
-	public int[] findModified(Object[] old, Object[] current, Object object, SessionImplementor session);
-
-	/**
-	 * Determine whether the entity has a particular property holding
-	 * the identifier value.
-	 *
-	 * @return True if the entity has a specific property holding identifier value.
-	 */
-	public boolean hasIdentifierProperty();
-
-	/**
-	 * Determine whether detahced instances of this entity carry their own
-	 * identifier value.
-	 * <p/>
-	 * The other option is the deperecated feature where users could supply
-	 * the id during session calls.
-	 *
-	 * @return True if either (1) {@link #hasIdentifierProperty()} or
-	 * (2) the identifier is an embedded composite identifier; false otherwise.
-	 */
-	public boolean canExtractIdOutOfEntity();
-
-	/**
-	 * Determine whether optimistic locking by column is enabled for this
-	 * entity.
-	 *
-	 * @return True if optimistic locking by column (i.e., <version/> or
-	 * <timestamp/>) is enabled; false otherwise.
-	 */
-	public boolean isVersioned();
-
-	/**
-	 * If {@link #isVersioned()}, then what is the type of the property
-	 * holding the locking value.
-	 *
-	 * @return The type of the version property; or null, if not versioned.
-	 */
-	public VersionType getVersionType();
-
-	/**
-	 * If {@link #isVersioned()}, then what is the index of the property
-	 * holding the locking value.
-	 *
-	 * @return The type of the version property; or -66, if not versioned.
-	 */
-	public int getVersionProperty();
-
-	/**
-	 * Determine whether this entity defines a natural identifier.
-	 *
-	 * @return True if the entity defines a natural id; false otherwise.
-	 */
-	public boolean hasNaturalIdentifier();
-
-	/**
-	 * If the entity defines a natural id ({@link #hasNaturalIdentifier()}), which
-	 * properties make up the natural id.
-	 *
-	 * @return The indices of the properties making of the natural id; or
-	 * null, if no natural id is defined.
-	 */
-	public int[] getNaturalIdentifierProperties();
-
-	/**
-	 * Retrieve the current state of the natural-id properties from the database.
-	 *
-	 * @param id The identifier of the entity for which to retrieve the naturak-id values.
-	 * @param session The session from which the request originated.
-	 * @return The natural-id snapshot.
-	 */
-	public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session);
-
-	/**
-	 * Determine which identifier generation strategy is used for this entity.
-	 *
-	 * @return The identifier generation strategy.
-	 */
-	public IdentifierGenerator getIdentifierGenerator();
-
-	/**
-	 * Determine whether this entity defines any lazy properties (ala
-	 * bytecode instrumentation).
-	 *
-	 * @return True if the entity has properties mapped as lazy; false otherwise.
-	 */
-	public boolean hasLazyProperties();
-
-	/**
-	 * Load an instance of the persistent class.
-	 */
-	public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Do a version check (optional operation)
-	 */
-	public void lock(Serializable id, Object version, Object object, LockMode lockMode, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Persist an instance
-	 */
-	public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Persist an instance, using a natively generated identifier (optional operation)
-	 */
-	public Serializable insert(Object[] fields, Object object, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Delete a persistent instance
-	 */
-	public void delete(Serializable id, Object version, Object object, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Update a persistent instance
-	 */
-	public void update(
-		Serializable id,
-		Object[] fields,
-		int[] dirtyFields,
-		boolean hasDirtyCollection,
-		Object[] oldFields,
-		Object oldVersion,
-		Object object,
-		Object rowId,
-		SessionImplementor session
-	) throws HibernateException;
-
-	/**
-	 * Get the Hibernate types of the class properties
-	 */
-	public Type[] getPropertyTypes();
-
-	/**
-	 * Get the names of the class properties - doesn't have to be the names of the
-	 * actual Java properties (used for XML generation only)
-	 */
-	public String[] getPropertyNames();
-
-	/**
-	 * Get the "insertability" of the properties of this class
-	 * (does the property appear in an SQL INSERT)
-	 */
-	public boolean[] getPropertyInsertability();
-
-	/**
-	 * Which of the properties of this class are database generated values on insert?
-	 */
-	public ValueInclusion[] getPropertyInsertGenerationInclusions();
-
-	/**
-	 * Which of the properties of this class are database generated values on update?
-	 */
-	public ValueInclusion[] getPropertyUpdateGenerationInclusions();
-
-	/**
-	 * Get the "updateability" of the properties of this class
-	 * (does the property appear in an SQL UPDATE)
-	 */
-	public boolean[] getPropertyUpdateability();
-
-	/**
-	 * Get the "checkability" of the properties of this class
-	 * (is the property dirty checked, does the cache need
-	 * to be updated)
-	 */
-	public boolean[] getPropertyCheckability();
-
-	/**
-	 * Get the nullability of the properties of this class
-	 */
-	public boolean[] getPropertyNullability();
-
-	/**
-	 * Get the "versionability" of the properties of this class
-	 * (is the property optimistic-locked)
-	 */
-	public boolean[] getPropertyVersionability();
-	public boolean[] getPropertyLaziness();
-	/**
-	 * Get the cascade styles of the propertes (optional operation)
-	 */
-	public CascadeStyle[] getPropertyCascadeStyles();
-
-	/**
-	 * Get the identifier type
-	 */
-	public Type getIdentifierType();
-
-	/**
-	 * Get the name of the identifier property (or return null) - need not return the
-	 * name of an actual Java property
-	 */
-	public String getIdentifierPropertyName();
-
-	/**
-	 * Should we always invalidate the cache instead of
-	 * recaching updated state
-	 */
-	public boolean isCacheInvalidationRequired();
-	/**
-	 * Should lazy properties of this entity be cached?
-	 */
-	public boolean isLazyPropertiesCacheable();
-	/**
-	 * Does this class have a cache.
-	 */
-	public boolean hasCache();
-	/**
-	 * Get the cache (optional operation)
-	 */
-	public EntityRegionAccessStrategy getCacheAccessStrategy();
-	/**
-	 * Get the cache structure
-	 */
-	public CacheEntryStructure getCacheEntryStructure();
-
-	/**
-	 * Get the user-visible metadata for the class (optional operation)
-	 */
-	public ClassMetadata getClassMetadata();
-
-	/**
-	 * Is batch loading enabled?
-	 */
-	public boolean isBatchLoadable();
-
-	/**
-	 * Is select snapshot before update enabled?
-	 */
-	public boolean isSelectBeforeUpdateRequired();
-
-	/**
-	 * Get the current database state of the object, in a "hydrated" form, without
-	 * resolving identifiers
-	 * @return null if there is no row in the database
-	 */
-	public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Get the current version of the object, or return null if there is no row for
-	 * the given identifier. In the case of unversioned data, return any object
-	 * if the row exists.
-	 */
-	public Object getCurrentVersion(Serializable id, SessionImplementor session)
-	throws HibernateException;
-
-	public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Try to discover the entity mode from the entity instance
-	 */
-	public EntityMode guessEntityMode(Object object);
-
-	/**
-	 * Has the class actually been bytecode instrumented?
-	 */
-	public boolean isInstrumented(EntityMode entityMode);
-
-	/**
-	 * Does this entity define any properties as being database generated on insert?
-	 *
-	 * @return True if this entity contains at least one property defined
-	 * as generated (including version property, but not identifier).
-	 */
-	public boolean hasInsertGeneratedProperties();
-
-	/**
-	 * Does this entity define any properties as being database generated on update?
-	 *
-	 * @return True if this entity contains at least one property defined
-	 * as generated (including version property, but not identifier).
-	 */
-	public boolean hasUpdateGeneratedProperties();
-
-	/**
-	 * Does this entity contain a version property that is defined
-	 * to be database generated?
-	 *
-	 * @return true if this entity contains a version property and that
-	 * property has been marked as generated.
-	 */
-	public boolean isVersionPropertyGenerated();
-
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// stuff that is tuplizer-centric, but is passed a session ~~~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Called just after the entities properties have been initialized
-	 */
-	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
-
-	/**
-	 * Called just after the entity has been reassociated with the session
-	 */
-	public void afterReassociate(Object entity, SessionImplementor session);
-
-	/**
-	 * Create a new proxy instance
-	 */
-	public Object createProxy(Serializable id, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Is this a new transient instance?
-	 */
-	public Boolean isTransient(Object object, SessionImplementor session) throws HibernateException;
-
-	/**
-	 * Return the values of the insertable properties of the object (including backrefs)
-	 */
-	public Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SessionImplementor session) throws HibernateException;
-
-	/**
-	 * Perform a select to retrieve the values of any generated properties
-	 * back from the database, injecting these generated values into the
-	 * given entity as well as writing this state to the
-	 * {@link org.hibernate.engine.PersistenceContext}.
-	 * <p/>
-	 * Note, that because we update the PersistenceContext here, callers
-	 * need to take care that they have already written the initial snapshot
-	 * to the PersistenceContext before calling this method.
-	 *
-	 * @param id The entity's id value.
-	 * @param entity The entity for which to get the state.
-	 * @param state
-	 * @param session The session
-	 */
-	public void processInsertGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session);
-	/**
-	 * Perform a select to retrieve the values of any generated properties
-	 * back from the database, injecting these generated values into the
-	 * given entity as well as writing this state to the
-	 * {@link org.hibernate.engine.PersistenceContext}.
-	 * <p/>
-	 * Note, that because we update the PersistenceContext here, callers
-	 * need to take care that they have already written the initial snapshot
-	 * to the PersistenceContext before calling this method.
-	 *
-	 * @param id The entity's id value.
-	 * @param entity The entity for which to get the state.
-	 * @param state
-	 * @param session The session
-	 */
-	public void processUpdateGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session);
-
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// stuff that is Tuplizer-centric ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * The persistent class, or null
-	 */
-	public Class getMappedClass(EntityMode entityMode);
-
-	/**
-	 * Does the class implement the <tt>Lifecycle</tt> interface.
-	 */
-	public boolean implementsLifecycle(EntityMode entityMode);
-
-	/**
-	 * Does the class implement the <tt>Validatable</tt> interface.
-	 */
-	public boolean implementsValidatable(EntityMode entityMode);
-	/**
-	 * Get the proxy interface that instances of <em>this</em> concrete class will be
-	 * cast to (optional operation).
-	 */
-	public Class getConcreteProxyClass(EntityMode entityMode);
-
-	/**
-	 * Set the given values to the mapped properties of the given object
-	 */
-	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Set the value of a particular property
-	 */
-	public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Return the (loaded) values of the mapped properties of the object (not including backrefs)
-	 */
-	public Object[] getPropertyValues(Object object, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the value of a particular property
-	 */
-	public Object getPropertyValue(Object object, int i, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the value of a particular property
-	 */
-	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the identifier of an instance (throw an exception if no identifier property)
-	 */
-	public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Set the identifier of an instance (or do nothing if no identifier property)
-	 */
-	public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get the version number (or timestamp) from the object's version property (or return null if not versioned)
-	 */
-	public Object getVersion(Object object, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Create a class instance initialized with the given identifier
-	 */
-	public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Is the given object an instance of this entity?
-	 */
-	public boolean isInstance(Object object, EntityMode entityMode);
-
-	/**
-	 * Does the given instance have any uninitialized lazy properties?
-	 */
-	public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode);
-
-	/**
-	 * Set the identifier and version of the given instance back
-	 * to its "unsaved" value, returning the id
-	 * @param currentId TODO
-	 * @param currentVersion TODO
-	 */
-	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode);
-
-	/**
-	 * Get the persister for an instance of this class or a subclass
-	 */
-	public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/EntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,682 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.EntityMode;
+import org.hibernate.tuple.entity.EntityMetamodel;
+import org.hibernate.cache.OptimisticCacheSource;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cache.entry.CacheEntryStructure;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.ValueInclusion;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.type.Type;
+import org.hibernate.type.VersionType;
+
+/**
+ * Implementors define mapping and persistence logic for a particular
+ * strategy of entity mapping.  An instance of entity persisters corresponds
+ * to a given mapped entity.
+ * <p/>
+ * Implementors must be threadsafe (preferrably immutable) and must provide a constructor
+ * matching the signature of: {@link org.hibernate.mapping.PersistentClass}, {@link org.hibernate.engine.SessionFactoryImplementor}
+ *
+ * @author Gavin King
+ */
+public interface EntityPersister extends OptimisticCacheSource {
+
+	/**
+	 * The property name of the "special" identifier property in HQL
+	 */
+	public static final String ENTITY_ID = "id";
+
+	/**
+	 * Finish the initialization of this object.
+	 * <p/>
+	 * Called only once per {@link org.hibernate.SessionFactory} lifecycle,
+	 * after all entity persisters have been instantiated.
+	 *
+	 * @throws org.hibernate.MappingException Indicates an issue in the metdata.
+	 */
+	public void postInstantiate() throws MappingException;
+
+	/**
+	 * Return the SessionFactory to which this persister "belongs".
+	 *
+	 * @return The owning SessionFactory.
+	 */
+	public SessionFactoryImplementor getFactory();
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // stuff that is persister-centric and/or EntityInfo-centric ~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Returns an object that identifies the space in which identifiers of
+	 * this entity hierarchy are unique.  Might be a table name, a JNDI URL, etc.
+	 *
+	 * @return The root entity name.
+	 */
+	public String getRootEntityName();
+
+	/**
+	 * The entity name which this persister maps.
+	 *
+	 * @return The name of the entity which this persister maps.
+	 */
+	public String getEntityName();
+
+	/**
+	 * Retrieve the underlying entity metamodel instance...
+	 *
+	 *@return The metamodel
+	 */
+	public EntityMetamodel getEntityMetamodel();
+
+	/**
+	 * Determine whether the given name represents a subclass entity
+	 * (or this entity itself) of the entity mapped by this persister.
+	 *
+	 * @param entityName The entity name to be checked.
+	 * @return True if the given entity name represents either the entity
+	 * mapped by this persister or one of its subclass entities; false
+	 * otherwise.
+	 */
+	public boolean isSubclassEntityName(String entityName);
+
+	/**
+	 * Returns an array of objects that identify spaces in which properties of
+	 * this entity are persisted, for instances of this class only.
+	 * <p/>
+	 * For most implementations, this returns the complete set of table names
+	 * to which instances of the mapped entity are persisted (not accounting
+	 * for superclass entity mappings).
+	 *
+	 * @return The property spaces.
+	 */
+	public Serializable[] getPropertySpaces();
+
+	/**
+	 * Returns an array of objects that identify spaces in which properties of
+	 * this entity are persisted, for instances of this class and its subclasses.
+	 * <p/>
+	 * Much like {@link #getPropertySpaces()}, except that here we include subclass
+	 * entity spaces.
+	 *
+	 * @return The query spaces.
+	 */
+	public Serializable[] getQuerySpaces();
+
+	/**
+	 * Determine whether this entity supports dynamic proxies.
+	 *
+	 * @return True if the entity has dynamic proxy support; false otherwise.
+	 */
+	public boolean hasProxy();
+
+	/**
+	 * Determine whether this entity contains references to persistent collections.
+	 *
+	 * @return True if the entity does contain persistent collections; false otherwise.
+	 */
+	public boolean hasCollections();
+
+	/**
+	 * Determine whether any properties of this entity are considered mutable.
+	 *
+	 * @return True if any properties of the entity are mutable; false otherwise (meaning none are).
+	 */
+	public boolean hasMutableProperties();
+
+	/**
+	 * Determine whether this entity contains references to persistent collections
+	 * which are fetchable by subselect?
+	 *
+	 * @return True if the entity contains collections fetchable by subselect; false otherwise.
+	 */
+	public boolean hasSubselectLoadableCollections();
+
+	/**
+	 * Determine whether this entity has any non-none cascading.
+	 *
+	 * @return True if the entity has any properties with a cscade other than NONE;
+	 * false otherwise (aka, no cascading).
+	 */
+	public boolean hasCascades();
+
+	/**
+	 * Determine whether instances of this entity are considered mutable.
+	 *
+	 * @return True if the entity is considered mutable; false otherwise.
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Determine whether the entity is inherited one or more other entities.
+	 * In other words, is this entity a subclass of other entities.
+	 *
+	 * @return True if other entities extend this entity; false otherwise.
+	 */
+	public boolean isInherited();
+
+	/**
+	 * Are identifiers of this entity assigned known before the insert execution?
+	 * Or, are they generated (in the database) by the insert execution.
+	 *
+	 * @return True if identifiers for this entity are generated by the insert
+	 * execution.
+	 */
+	public boolean isIdentifierAssignedByInsert();
+
+	/**
+	 * Get the type of a particular property by name.
+	 *
+	 * @param propertyName The name of the property for which to retrieve
+	 * the typpe.
+	 * @return The type.
+	 * @throws org.hibernate.MappingException Typically indicates an unknown
+	 * property name.
+	 */
+	public Type getPropertyType(String propertyName) throws MappingException;
+
+	/**
+	 * Compare the two snapshots to determine if they represent dirty state.
+	 *
+	 * @param currentState The current snapshot
+	 * @param previousState The baseline snapshot
+	 * @param owner The entity containing the state
+	 * @param session The originating session
+	 * @return The indices of all dirty properties, or null if no properties
+	 * were dirty.
+	 */
+	public int[] findDirty(Object[] currentState, Object[] previousState, Object owner, SessionImplementor session);
+
+	/**
+	 * Compare the two snapshots to determine if they represent modified state.
+	 *
+	 * @param old The baseline snapshot
+	 * @param current The current snapshot
+	 * @param object The entity containing the state
+	 * @param session The originating session
+	 * @return The indices of all modified properties, or null if no properties
+	 * were modified.
+	 */
+	public int[] findModified(Object[] old, Object[] current, Object object, SessionImplementor session);
+
+	/**
+	 * Determine whether the entity has a particular property holding
+	 * the identifier value.
+	 *
+	 * @return True if the entity has a specific property holding identifier value.
+	 */
+	public boolean hasIdentifierProperty();
+
+	/**
+	 * Determine whether detahced instances of this entity carry their own
+	 * identifier value.
+	 * <p/>
+	 * The other option is the deperecated feature where users could supply
+	 * the id during session calls.
+	 *
+	 * @return True if either (1) {@link #hasIdentifierProperty()} or
+	 * (2) the identifier is an embedded composite identifier; false otherwise.
+	 */
+	public boolean canExtractIdOutOfEntity();
+
+	/**
+	 * Determine whether optimistic locking by column is enabled for this
+	 * entity.
+	 *
+	 * @return True if optimistic locking by column (i.e., <version/> or
+	 * <timestamp/>) is enabled; false otherwise.
+	 */
+	public boolean isVersioned();
+
+	/**
+	 * If {@link #isVersioned()}, then what is the type of the property
+	 * holding the locking value.
+	 *
+	 * @return The type of the version property; or null, if not versioned.
+	 */
+	public VersionType getVersionType();
+
+	/**
+	 * If {@link #isVersioned()}, then what is the index of the property
+	 * holding the locking value.
+	 *
+	 * @return The type of the version property; or -66, if not versioned.
+	 */
+	public int getVersionProperty();
+
+	/**
+	 * Determine whether this entity defines a natural identifier.
+	 *
+	 * @return True if the entity defines a natural id; false otherwise.
+	 */
+	public boolean hasNaturalIdentifier();
+
+	/**
+	 * If the entity defines a natural id ({@link #hasNaturalIdentifier()}), which
+	 * properties make up the natural id.
+	 *
+	 * @return The indices of the properties making of the natural id; or
+	 * null, if no natural id is defined.
+	 */
+	public int[] getNaturalIdentifierProperties();
+
+	/**
+	 * Retrieve the current state of the natural-id properties from the database.
+	 *
+	 * @param id The identifier of the entity for which to retrieve the naturak-id values.
+	 * @param session The session from which the request originated.
+	 * @return The natural-id snapshot.
+	 */
+	public Object[] getNaturalIdentifierSnapshot(Serializable id, SessionImplementor session);
+
+	/**
+	 * Determine which identifier generation strategy is used for this entity.
+	 *
+	 * @return The identifier generation strategy.
+	 */
+	public IdentifierGenerator getIdentifierGenerator();
+
+	/**
+	 * Determine whether this entity defines any lazy properties (ala
+	 * bytecode instrumentation).
+	 *
+	 * @return True if the entity has properties mapped as lazy; false otherwise.
+	 */
+	public boolean hasLazyProperties();
+
+	/**
+	 * Load an instance of the persistent class.
+	 */
+	public Object load(Serializable id, Object optionalObject, LockMode lockMode, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Do a version check (optional operation)
+	 */
+	public void lock(Serializable id, Object version, Object object, LockMode lockMode, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Persist an instance
+	 */
+	public void insert(Serializable id, Object[] fields, Object object, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Persist an instance, using a natively generated identifier (optional operation)
+	 */
+	public Serializable insert(Object[] fields, Object object, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Delete a persistent instance
+	 */
+	public void delete(Serializable id, Object version, Object object, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Update a persistent instance
+	 */
+	public void update(
+		Serializable id,
+		Object[] fields,
+		int[] dirtyFields,
+		boolean hasDirtyCollection,
+		Object[] oldFields,
+		Object oldVersion,
+		Object object,
+		Object rowId,
+		SessionImplementor session
+	) throws HibernateException;
+
+	/**
+	 * Get the Hibernate types of the class properties
+	 */
+	public Type[] getPropertyTypes();
+
+	/**
+	 * Get the names of the class properties - doesn't have to be the names of the
+	 * actual Java properties (used for XML generation only)
+	 */
+	public String[] getPropertyNames();
+
+	/**
+	 * Get the "insertability" of the properties of this class
+	 * (does the property appear in an SQL INSERT)
+	 */
+	public boolean[] getPropertyInsertability();
+
+	/**
+	 * Which of the properties of this class are database generated values on insert?
+	 */
+	public ValueInclusion[] getPropertyInsertGenerationInclusions();
+
+	/**
+	 * Which of the properties of this class are database generated values on update?
+	 */
+	public ValueInclusion[] getPropertyUpdateGenerationInclusions();
+
+	/**
+	 * Get the "updateability" of the properties of this class
+	 * (does the property appear in an SQL UPDATE)
+	 */
+	public boolean[] getPropertyUpdateability();
+
+	/**
+	 * Get the "checkability" of the properties of this class
+	 * (is the property dirty checked, does the cache need
+	 * to be updated)
+	 */
+	public boolean[] getPropertyCheckability();
+
+	/**
+	 * Get the nullability of the properties of this class
+	 */
+	public boolean[] getPropertyNullability();
+
+	/**
+	 * Get the "versionability" of the properties of this class
+	 * (is the property optimistic-locked)
+	 */
+	public boolean[] getPropertyVersionability();
+	public boolean[] getPropertyLaziness();
+	/**
+	 * Get the cascade styles of the propertes (optional operation)
+	 */
+	public CascadeStyle[] getPropertyCascadeStyles();
+
+	/**
+	 * Get the identifier type
+	 */
+	public Type getIdentifierType();
+
+	/**
+	 * Get the name of the identifier property (or return null) - need not return the
+	 * name of an actual Java property
+	 */
+	public String getIdentifierPropertyName();
+
+	/**
+	 * Should we always invalidate the cache instead of
+	 * recaching updated state
+	 */
+	public boolean isCacheInvalidationRequired();
+	/**
+	 * Should lazy properties of this entity be cached?
+	 */
+	public boolean isLazyPropertiesCacheable();
+	/**
+	 * Does this class have a cache.
+	 */
+	public boolean hasCache();
+	/**
+	 * Get the cache (optional operation)
+	 */
+	public EntityRegionAccessStrategy getCacheAccessStrategy();
+	/**
+	 * Get the cache structure
+	 */
+	public CacheEntryStructure getCacheEntryStructure();
+
+	/**
+	 * Get the user-visible metadata for the class (optional operation)
+	 */
+	public ClassMetadata getClassMetadata();
+
+	/**
+	 * Is batch loading enabled?
+	 */
+	public boolean isBatchLoadable();
+
+	/**
+	 * Is select snapshot before update enabled?
+	 */
+	public boolean isSelectBeforeUpdateRequired();
+
+	/**
+	 * Get the current database state of the object, in a "hydrated" form, without
+	 * resolving identifiers
+	 * @return null if there is no row in the database
+	 */
+	public Object[] getDatabaseSnapshot(Serializable id, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Get the current version of the object, or return null if there is no row for
+	 * the given identifier. In the case of unversioned data, return any object
+	 * if the row exists.
+	 */
+	public Object getCurrentVersion(Serializable id, SessionImplementor session)
+	throws HibernateException;
+
+	public Object forceVersionIncrement(Serializable id, Object currentVersion, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Try to discover the entity mode from the entity instance
+	 */
+	public EntityMode guessEntityMode(Object object);
+
+	/**
+	 * Has the class actually been bytecode instrumented?
+	 */
+	public boolean isInstrumented(EntityMode entityMode);
+
+	/**
+	 * Does this entity define any properties as being database generated on insert?
+	 *
+	 * @return True if this entity contains at least one property defined
+	 * as generated (including version property, but not identifier).
+	 */
+	public boolean hasInsertGeneratedProperties();
+
+	/**
+	 * Does this entity define any properties as being database generated on update?
+	 *
+	 * @return True if this entity contains at least one property defined
+	 * as generated (including version property, but not identifier).
+	 */
+	public boolean hasUpdateGeneratedProperties();
+
+	/**
+	 * Does this entity contain a version property that is defined
+	 * to be database generated?
+	 *
+	 * @return true if this entity contains a version property and that
+	 * property has been marked as generated.
+	 */
+	public boolean isVersionPropertyGenerated();
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// stuff that is tuplizer-centric, but is passed a session ~~~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Called just after the entities properties have been initialized
+	 */
+	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
+
+	/**
+	 * Called just after the entity has been reassociated with the session
+	 */
+	public void afterReassociate(Object entity, SessionImplementor session);
+
+	/**
+	 * Create a new proxy instance
+	 */
+	public Object createProxy(Serializable id, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Is this a new transient instance?
+	 */
+	public Boolean isTransient(Object object, SessionImplementor session) throws HibernateException;
+
+	/**
+	 * Return the values of the insertable properties of the object (including backrefs)
+	 */
+	public Object[] getPropertyValuesToInsert(Object object, Map mergeMap, SessionImplementor session) throws HibernateException;
+
+	/**
+	 * Perform a select to retrieve the values of any generated properties
+	 * back from the database, injecting these generated values into the
+	 * given entity as well as writing this state to the
+	 * {@link org.hibernate.engine.PersistenceContext}.
+	 * <p/>
+	 * Note, that because we update the PersistenceContext here, callers
+	 * need to take care that they have already written the initial snapshot
+	 * to the PersistenceContext before calling this method.
+	 *
+	 * @param id The entity's id value.
+	 * @param entity The entity for which to get the state.
+	 * @param state
+	 * @param session The session
+	 */
+	public void processInsertGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session);
+	/**
+	 * Perform a select to retrieve the values of any generated properties
+	 * back from the database, injecting these generated values into the
+	 * given entity as well as writing this state to the
+	 * {@link org.hibernate.engine.PersistenceContext}.
+	 * <p/>
+	 * Note, that because we update the PersistenceContext here, callers
+	 * need to take care that they have already written the initial snapshot
+	 * to the PersistenceContext before calling this method.
+	 *
+	 * @param id The entity's id value.
+	 * @param entity The entity for which to get the state.
+	 * @param state
+	 * @param session The session
+	 */
+	public void processUpdateGeneratedProperties(Serializable id, Object entity, Object[] state, SessionImplementor session);
+
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// stuff that is Tuplizer-centric ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * The persistent class, or null
+	 */
+	public Class getMappedClass(EntityMode entityMode);
+
+	/**
+	 * Does the class implement the <tt>Lifecycle</tt> interface.
+	 */
+	public boolean implementsLifecycle(EntityMode entityMode);
+
+	/**
+	 * Does the class implement the <tt>Validatable</tt> interface.
+	 */
+	public boolean implementsValidatable(EntityMode entityMode);
+	/**
+	 * Get the proxy interface that instances of <em>this</em> concrete class will be
+	 * cast to (optional operation).
+	 */
+	public Class getConcreteProxyClass(EntityMode entityMode);
+
+	/**
+	 * Set the given values to the mapped properties of the given object
+	 */
+	public void setPropertyValues(Object object, Object[] values, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Set the value of a particular property
+	 */
+	public void setPropertyValue(Object object, int i, Object value, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Return the (loaded) values of the mapped properties of the object (not including backrefs)
+	 */
+	public Object[] getPropertyValues(Object object, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the value of a particular property
+	 */
+	public Object getPropertyValue(Object object, int i, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the value of a particular property
+	 */
+	public Object getPropertyValue(Object object, String propertyName, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the identifier of an instance (throw an exception if no identifier property)
+	 */
+	public Serializable getIdentifier(Object object, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Set the identifier of an instance (or do nothing if no identifier property)
+	 */
+	public void setIdentifier(Object object, Serializable id, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get the version number (or timestamp) from the object's version property (or return null if not versioned)
+	 */
+	public Object getVersion(Object object, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Create a class instance initialized with the given identifier
+	 */
+	public Object instantiate(Serializable id, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Is the given object an instance of this entity?
+	 */
+	public boolean isInstance(Object object, EntityMode entityMode);
+
+	/**
+	 * Does the given instance have any uninitialized lazy properties?
+	 */
+	public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode);
+
+	/**
+	 * Set the identifier and version of the given instance back
+	 * to its "unsaved" value, returning the id
+	 * @param currentId TODO
+	 * @param currentVersion TODO
+	 */
+	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode);
+
+	/**
+	 * Get the persister for an instance of this class or a subclass
+	 */
+	public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/Joinable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-//$Id: Joinable.java 6828 2005-05-19 07:28:59Z steveebersole $
-package org.hibernate.persister.entity;
-
-import org.hibernate.MappingException;
-
-import java.util.Map;
-
-/**
- * Anything that can be loaded by outer join - namely
- * persisters for classes or collections.
- *
- * @author Gavin King
- */
-public interface Joinable {
-	//should this interface extend PropertyMapping?
-
-	/**
-	 * An identifying name; a class name or collection role name.
-	 */
-	public String getName();
-	/**
-	 * The table to join to.
-	 */
-	public String getTableName();
-
-	/**
-	 * All columns to select, when loading.
-	 */
-	public String selectFragment(Joinable rhs, String rhsAlias, String lhsAlias, String currentEntitySuffix, String currentCollectionSuffix, boolean includeCollectionColumns);
-
-	/**
-	 * Get the where clause part of any joins
-	 * (optional operation)
-	 */
-	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses);
-	/**
-	 * Get the from clause part of any joins
-	 * (optional operation)
-	 */
-	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses);
-	/**
-	 * The columns to join on
-	 */
-	public String[] getKeyColumnNames();
-	/**
-	 * Get the where clause filter, given a query alias and considering enabled session filters
-	 */
-	public String filterFragment(String alias, Map enabledFilters) throws MappingException;
-
-	public String oneToManyFilterFragment(String alias) throws MappingException;
-	/**
-	 * Is this instance actually a CollectionPersister?
-	 */
-	public boolean isCollection();
-
-	/**
-	 * Very, very, very ugly...
-	 *
-	 * @return Does this persister "consume" entity column aliases in the result
-	 * set?
-	 */
-	public boolean consumesEntityAlias();
-
-	/**
-	 * Very, very, very ugly...
-	 *
-	 * @return Does this persister "consume" collection column aliases in the result
-	 * set?
-	 */
-	public boolean consumesCollectionAlias();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/Joinable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Joinable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.persister.entity;
+
+import org.hibernate.MappingException;
+
+import java.util.Map;
+
+/**
+ * Anything that can be loaded by outer join - namely
+ * persisters for classes or collections.
+ *
+ * @author Gavin King
+ */
+public interface Joinable {
+	//should this interface extend PropertyMapping?
+
+	/**
+	 * An identifying name; a class name or collection role name.
+	 */
+	public String getName();
+	/**
+	 * The table to join to.
+	 */
+	public String getTableName();
+
+	/**
+	 * All columns to select, when loading.
+	 */
+	public String selectFragment(Joinable rhs, String rhsAlias, String lhsAlias, String currentEntitySuffix, String currentCollectionSuffix, boolean includeCollectionColumns);
+
+	/**
+	 * Get the where clause part of any joins
+	 * (optional operation)
+	 */
+	public String whereJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses);
+	/**
+	 * Get the from clause part of any joins
+	 * (optional operation)
+	 */
+	public String fromJoinFragment(String alias, boolean innerJoin, boolean includeSubclasses);
+	/**
+	 * The columns to join on
+	 */
+	public String[] getKeyColumnNames();
+	/**
+	 * Get the where clause filter, given a query alias and considering enabled session filters
+	 */
+	public String filterFragment(String alias, Map enabledFilters) throws MappingException;
+
+	public String oneToManyFilterFragment(String alias) throws MappingException;
+	/**
+	 * Is this instance actually a CollectionPersister?
+	 */
+	public boolean isCollection();
+
+	/**
+	 * Very, very, very ugly...
+	 *
+	 * @return Does this persister "consume" entity column aliases in the result
+	 * set?
+	 */
+	public boolean consumesEntityAlias();
+
+	/**
+	 * Very, very, very ugly...
+	 *
+	 * @return Does this persister "consume" collection column aliases in the result
+	 * set?
+	 */
+	public boolean consumesCollectionAlias();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,586 +0,0 @@
-//$Id: JoinedSubclassEntityPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.QueryException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.Versioning;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.KeyValue;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.mapping.Subclass;
-import org.hibernate.mapping.Table;
-import org.hibernate.sql.CaseFragment;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * An <tt>EntityPersister</tt> implementing the normalized "table-per-subclass"
- * mapping strategy
- *
- * @author Gavin King
- */
-public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
-
-	// the class hierarchy structure
-	private final int tableSpan;
-	private final String[] tableNames;
-	private final String[] naturalOrderTableNames;
-	private final String[][] tableKeyColumns;
-	private final String[][] naturalOrderTableKeyColumns;
-	private final boolean[] naturalOrderCascadeDeleteEnabled;
-
-	private final String[] spaces;
-
-	private final String[] subclassClosure;
-
-	private final String[] subclassTableNameClosure;
-	private final String[][] subclassTableKeyColumnClosure;
-	private final boolean[] isClassOrSuperclassTable;
-
-	// properties of this class, including inherited properties
-	private final int[] naturalOrderPropertyTableNumbers;
-	private final int[] propertyTableNumbers;
-
-	// the closure of all properties in the entire hierarchy including
-	// subclasses and superclasses of this class
-	private final int[] subclassPropertyTableNumberClosure;
-
-	// the closure of all columns used by the entire hierarchy including
-	// subclasses and superclasses of this class
-	private final int[] subclassColumnTableNumberClosure;
-	private final int[] subclassFormulaTableNumberClosure;
-
-	// subclass discrimination works by assigning particular
-	// values to certain combinations of null primary key
-	// values in the outer join using an SQL CASE
-	private final Map subclassesByDiscriminatorValue = new HashMap();
-	private final String[] discriminatorValues;
-	private final String[] notNullColumnNames;
-	private final int[] notNullColumnTableNumbers;
-
-	private final String[] constraintOrderedTableNames;
-	private final String[][] constraintOrderedKeyColumnNames;
-
-	private final String discriminatorSQLString;
-
-	//INITIALIZATION:
-
-	public JoinedSubclassEntityPersister(
-			final PersistentClass persistentClass,
-			final EntityRegionAccessStrategy cacheAccessStrategy,
-			final SessionFactoryImplementor factory,
-			final Mapping mapping) throws HibernateException {
-
-		super( persistentClass, cacheAccessStrategy, factory );
-
-		// DISCRIMINATOR
-
-		final Object discriminatorValue;
-		if ( persistentClass.isPolymorphic() ) {
-			try {
-				discriminatorValue = new Integer( persistentClass.getSubclassId() );
-				discriminatorSQLString = discriminatorValue.toString();
-			}
-			catch (Exception e) {
-				throw new MappingException("Could not format discriminator value to SQL string", e );
-			}
-		}
-		else {
-			discriminatorValue = null;
-			discriminatorSQLString = null;
-		}
-
-		if ( optimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION ) {
-			throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" );
-		}
-
-		//MULTITABLES
-
-		final int idColumnSpan = getIdentifierColumnSpan();
-
-		ArrayList tables = new ArrayList();
-		ArrayList keyColumns = new ArrayList();
-		ArrayList cascadeDeletes = new ArrayList();
-		Iterator titer = persistentClass.getTableClosureIterator();
-		Iterator kiter = persistentClass.getKeyClosureIterator();
-		while ( titer.hasNext() ) {
-			Table tab = (Table) titer.next();
-			KeyValue key = (KeyValue) kiter.next();
-			String tabname = tab.getQualifiedName(
-					factory.getDialect(),
-					factory.getSettings().getDefaultCatalogName(),
-					factory.getSettings().getDefaultSchemaName()
-			);
-			tables.add(tabname);
-			String[] keyCols = new String[idColumnSpan];
-			Iterator citer = key.getColumnIterator();
-			for ( int k=0; k<idColumnSpan; k++ ) {
-				keyCols[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
-			}
-			keyColumns.add(keyCols);
-			cascadeDeletes.add( new Boolean( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() ) );
-		}
-		naturalOrderTableNames = ArrayHelper.toStringArray(tables);
-		naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray(keyColumns);
-		naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray(cascadeDeletes);
-
-		ArrayList subtables = new ArrayList();
-		ArrayList isConcretes = new ArrayList();
-		keyColumns = new ArrayList();
-		titer = persistentClass.getSubclassTableClosureIterator();
-		while ( titer.hasNext() ) {
-			Table tab = (Table) titer.next();
-			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassTable(tab) ) );
-			String tabname = tab.getQualifiedName(
-					factory.getDialect(),
-					factory.getSettings().getDefaultCatalogName(),
-					factory.getSettings().getDefaultSchemaName()
-			);
-			subtables.add(tabname);
-			String[] key = new String[idColumnSpan];
-			Iterator citer = tab.getPrimaryKey().getColumnIterator();
-			for ( int k=0; k<idColumnSpan; k++ ) {
-				key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
-			}
-			keyColumns.add(key);
-		}
-		subclassTableNameClosure = ArrayHelper.toStringArray(subtables);
-		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(keyColumns);
-		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
-
-		constraintOrderedTableNames = new String[subclassTableNameClosure.length];
-		constraintOrderedKeyColumnNames = new String[subclassTableNameClosure.length][];
-		int currentPosition = 0;
-		for ( int i = subclassTableNameClosure.length - 1; i >= 0 ; i--, currentPosition++ ) {
-			constraintOrderedTableNames[currentPosition] = subclassTableNameClosure[i];
-			constraintOrderedKeyColumnNames[currentPosition] = subclassTableKeyColumnClosure[i];
-		}
-
-		tableSpan = naturalOrderTableNames.length;
-		tableNames = reverse(naturalOrderTableNames);
-		tableKeyColumns = reverse(naturalOrderTableKeyColumns);
-		reverse(subclassTableNameClosure, tableSpan);
-		reverse(subclassTableKeyColumnClosure, tableSpan);
-
-		spaces = ArrayHelper.join(
-				tableNames,
-				ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
-		);
-
-		// Custom sql
-		customSQLInsert = new String[tableSpan];
-		customSQLUpdate = new String[tableSpan];
-		customSQLDelete = new String[tableSpan];
-		insertCallable = new boolean[tableSpan];
-		updateCallable = new boolean[tableSpan];
-		deleteCallable = new boolean[tableSpan];
-		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
-		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
-		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
-
-		PersistentClass pc = persistentClass;
-		int jk = tableSpan-1;
-		while (pc!=null) {
-			customSQLInsert[jk] = pc.getCustomSQLInsert();
-			insertCallable[jk] = customSQLInsert[jk] != null && pc.isCustomInsertCallable();
-			insertResultCheckStyles[jk] = pc.getCustomSQLInsertCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[jk], insertCallable[jk] )
-		                                  : pc.getCustomSQLInsertCheckStyle();
-			customSQLUpdate[jk] = pc.getCustomSQLUpdate();
-			updateCallable[jk] = customSQLUpdate[jk] != null && pc.isCustomUpdateCallable();
-			updateResultCheckStyles[jk] = pc.getCustomSQLUpdateCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] )
-		                                  : pc.getCustomSQLUpdateCheckStyle();
-			customSQLDelete[jk] = pc.getCustomSQLDelete();
-			deleteCallable[jk] = customSQLDelete[jk] != null && pc.isCustomDeleteCallable();
-			deleteResultCheckStyles[jk] = pc.getCustomSQLDeleteCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] )
-		                                  : pc.getCustomSQLDeleteCheckStyle();
-			jk--;
-			pc = pc.getSuperclass();
-		}
-		if ( jk != -1 ) {
-			throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." );
-		}
-
-		// PROPERTIES
-
-		int hydrateSpan = getPropertySpan();
-		naturalOrderPropertyTableNumbers = new int[hydrateSpan];
-		propertyTableNumbers = new int[hydrateSpan];
-		Iterator iter = persistentClass.getPropertyClosureIterator();
-		int i=0;
-		while( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			String tabname = prop.getValue().getTable().getQualifiedName(
-				factory.getDialect(),
-				factory.getSettings().getDefaultCatalogName(),
-				factory.getSettings().getDefaultSchemaName()
-			);
-			propertyTableNumbers[i] = getTableId(tabname, tableNames);
-			naturalOrderPropertyTableNumbers[i] = getTableId(tabname, naturalOrderTableNames);
-			i++;
-		}
-
-		// subclass closure properties
-
-		//TODO: code duplication with SingleTableEntityPersister
-
-		ArrayList columnTableNumbers = new ArrayList();
-		ArrayList formulaTableNumbers = new ArrayList();
-		ArrayList propTableNumbers = new ArrayList();
-
-		iter = persistentClass.getSubclassPropertyClosureIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			Table tab = prop.getValue().getTable();
-			String tabname = tab.getQualifiedName(
-					factory.getDialect(),
-					factory.getSettings().getDefaultCatalogName(),
-					factory.getSettings().getDefaultSchemaName()
-			);
-			Integer tabnum = new Integer( getTableId(tabname, subclassTableNameClosure) );
-			propTableNumbers.add(tabnum);
-
-			Iterator citer = prop.getColumnIterator();
-			while ( citer.hasNext() ) {
-				Selectable thing = (Selectable) citer.next();
-				if ( thing.isFormula() ) {
-					formulaTableNumbers.add(tabnum);
-				}
-				else {
-					columnTableNumbers.add(tabnum);
-				}
-			}
-
-		}
-
-		subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnTableNumbers);
-		subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propTableNumbers);
-		subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaTableNumbers);
-
-		// SUBCLASSES
-
-		int subclassSpan = persistentClass.getSubclassSpan() + 1;
-		subclassClosure = new String[subclassSpan];
-		subclassClosure[subclassSpan-1] = getEntityName();
-		if ( persistentClass.isPolymorphic() ) {
-			subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
-			discriminatorValues = new String[subclassSpan];
-			discriminatorValues[subclassSpan-1] = discriminatorSQLString;
-			notNullColumnTableNumbers = new int[subclassSpan];
-			final int id = getTableId(
-				persistentClass.getTable().getQualifiedName(
-						factory.getDialect(),
-						factory.getSettings().getDefaultCatalogName(),
-						factory.getSettings().getDefaultSchemaName()
-				),
-				subclassTableNameClosure
-			);
-			notNullColumnTableNumbers[subclassSpan-1] = id;
-			notNullColumnNames = new String[subclassSpan];
-			notNullColumnNames[subclassSpan-1] =  subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName();
-		}
-		else {
-			discriminatorValues = null;
-			notNullColumnTableNumbers = null;
-			notNullColumnNames = null;
-		}
-
-		iter = persistentClass.getSubclassIterator();
-		int k=0;
-		while ( iter.hasNext() ) {
-			Subclass sc = (Subclass) iter.next();
-			subclassClosure[k] = sc.getEntityName();
-			try {
-				if ( persistentClass.isPolymorphic() ) {
-					// we now use subclass ids that are consistent across all
-					// persisters for a class hierarchy, so that the use of
-					// "foo.class = Bar" works in HQL
-					Integer subclassId = new Integer( sc.getSubclassId() );//new Integer(k+1);
-					subclassesByDiscriminatorValue.put( subclassId, sc.getEntityName() );
-					discriminatorValues[k] = subclassId.toString();
-					int id = getTableId(
-						sc.getTable().getQualifiedName(
-								factory.getDialect(),
-								factory.getSettings().getDefaultCatalogName(),
-								factory.getSettings().getDefaultSchemaName()
-						),
-						subclassTableNameClosure
-					);
-					notNullColumnTableNumbers[k] = id;
-					notNullColumnNames[k] = subclassTableKeyColumnClosure[id][0]; //( (Column) sc.getTable().getPrimaryKey().getColumnIterator().next() ).getName();
-				}
-			}
-			catch (Exception e) {
-				throw new MappingException("Error parsing discriminator value", e );
-			}
-			k++;
-		}
-
-		initLockers();
-
-		initSubclassPropertyAliasesMap(persistentClass);
-
-		postConstruct(mapping);
-
-	}
-
-	/*public void postInstantiate() throws MappingException {
-		super.postInstantiate();
-		//TODO: other lock modes?
-		loader = createEntityLoader(LockMode.NONE, CollectionHelper.EMPTY_MAP);
-	}*/
-
-	public String getSubclassPropertyTableName(int i) {
-		return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ];
-	}
-
-	public Type getDiscriminatorType() {
-		return Hibernate.INTEGER;
-	}
-
-	public String getDiscriminatorSQLValue() {
-		return discriminatorSQLString;
-	}
-
-
-	public String getSubclassForDiscriminatorValue(Object value) {
-		return (String) subclassesByDiscriminatorValue.get(value);
-	}
-
-	public Serializable[] getPropertySpaces() {
-		return spaces; // don't need subclass tables, because they can't appear in conditions
-	}
-
-
-	protected String getTableName(int j) {
-		return naturalOrderTableNames[j];
-	}
-
-	protected String[] getKeyColumns(int j) {
-		return naturalOrderTableKeyColumns[j];
-	}
-
-	protected boolean isTableCascadeDeleteEnabled(int j) {
-		return naturalOrderCascadeDeleteEnabled[j];
-	}
-
-	protected boolean isPropertyOfTable(int property, int j) {
-		return naturalOrderPropertyTableNumbers[property]==j;
-	}
-
-	/**
-	 * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>,
-	 * depending upon the value of the <tt>lock</tt> parameter
-	 */
-	/*public Object load(Serializable id,	Object optionalObject, LockMode lockMode, SessionImplementor session)
-	throws HibernateException {
-
-		if ( log.isTraceEnabled() ) log.trace( "Materializing entity: " + MessageHelper.infoString(this, id) );
-
-		final UniqueEntityLoader loader = hasQueryLoader() ?
-				getQueryLoader() :
-				this.loader;
-		try {
-
-			final Object result = loader.load(id, optionalObject, session);
-
-			if (result!=null) lock(id, getVersion(result), result, lockMode, session);
-
-			return result;
-
-		}
-		catch (SQLException sqle) {
-			throw new JDBCException( "could not load by id: " +  MessageHelper.infoString(this, id), sqle );
-		}
-	}*/
-
-	private static final void reverse(Object[] objects, int len) {
-		Object[] temp = new Object[len];
-		for (int i=0; i<len; i++) {
-			temp[i] = objects[len-i-1];
-		}
-		for (int i=0; i<len; i++) {
-			objects[i] = temp[i];
-		}
-	}
-
-	private static final String[] reverse(String[] objects) {
-		int len = objects.length;
-		String[] temp = new String[len];
-		for (int i=0; i<len; i++) {
-			temp[i] = objects[len-i-1];
-		}
-		return temp;
-	}
-
-	private static final String[][] reverse(String[][] objects) {
-		int len = objects.length;
-		String[][] temp = new String[len][];
-		for (int i=0; i<len; i++) {
-			temp[i] = objects[len-i-1];
-		}
-		return temp;
-	}
-
-	public String fromTableFragment(String alias) {
-		return getTableName() + ' ' + alias;
-	}
-
-	public String getTableName() {
-		return tableNames[0];
-	}
-
-	private static int getTableId(String tableName, String[] tables) {
-		for ( int j=0; j<tables.length; j++ ) {
-			if ( tableName.equals( tables[j] ) ) {
-				return j;
-			}
-		}
-		throw new AssertionFailure("Table " + tableName + " not found");
-	}
-
-	public void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
-		if ( hasSubclasses() ) {
-			select.setExtraSelectList( discriminatorFragment(name), getDiscriminatorAlias() );
-		}
-	}
-
-	private CaseFragment discriminatorFragment(String alias) {
-		CaseFragment cases = getFactory().getDialect().createCaseFragment();
-
-		for ( int i=0; i<discriminatorValues.length; i++ ) {
-			cases.addWhenColumnNotNull(
-				generateTableAlias( alias, notNullColumnTableNumbers[i] ),
-				notNullColumnNames[i],
-				discriminatorValues[i]
-			);
-		}
-
-		return cases;
-	}
-
-	public String filterFragment(String alias) {
-		return hasWhere() ?
-			" and " + getSQLWhereString( generateFilterConditionAlias( alias ) ) :
-			"";
-	}
-
-	public String generateFilterConditionAlias(String rootAlias) {
-		return generateTableAlias( rootAlias, tableSpan-1 );
-	}
-
-	public String[] getIdentifierColumnNames() {
-		return tableKeyColumns[0];
-	}
-
-	public String[] toColumns(String alias, String propertyName) throws QueryException {
-
-		if ( ENTITY_CLASS.equals(propertyName) ) {
-			// This doesn't actually seem to work but it *might*
-			// work on some dbs. Also it doesn't work if there
-			// are multiple columns of results because it
-			// is not accounting for the suffix:
-			// return new String[] { getDiscriminatorColumnName() };
-
-			return new String[] { discriminatorFragment(alias).toFragmentString() };
-		}
-		else {
-			return super.toColumns(alias, propertyName);
-		}
-
-	}
-
-	protected int[] getPropertyTableNumbersInSelect() {
-		return propertyTableNumbers;
-	}
-
-	protected int getSubclassPropertyTableNumber(int i) {
-		return subclassPropertyTableNumberClosure[i];
-	}
-
-	public int getTableSpan() {
-		return tableSpan;
-	}
-
-	public boolean isMultiTable() {
-		return true;
-	}
-
-	protected int[] getSubclassColumnTableNumberClosure() {
-		return subclassColumnTableNumberClosure;
-	}
-
-	protected int[] getSubclassFormulaTableNumberClosure() {
-		return subclassFormulaTableNumberClosure;
-	}
-
-	protected int[] getPropertyTableNumbers() {
-		return naturalOrderPropertyTableNumbers;
-	}
-
-	protected String[] getSubclassTableKeyColumns(int j) {
-		return subclassTableKeyColumnClosure[j];
-	}
-
-	public String getSubclassTableName(int j) {
-		return subclassTableNameClosure[j];
-	}
-
-	public int getSubclassTableSpan() {
-		return subclassTableNameClosure.length;
-	}
-
-	protected boolean isClassOrSuperclassTable(int j) {
-		return isClassOrSuperclassTable[j];
-	}
-
-	public String getPropertyTableName(String propertyName) {
-		Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName);
-		if ( index == null ) {
-			return null;
-		}
-		return tableNames[ propertyTableNumbers[ index.intValue() ] ];
-	}
-
-	public String[] getConstraintOrderedTableNameClosure() {
-		return constraintOrderedTableNames;
-	}
-
-	public String[][] getContraintOrderedTableKeyColumnClosure() {
-		return constraintOrderedKeyColumnNames;
-	}
-
-	public String getRootTableName() {
-		return naturalOrderTableNames[0];
-	}
-
-	public String getRootTableAlias(String drivingAlias) {
-		return generateTableAlias( drivingAlias, getTableId( getRootTableName(), tableNames ) );
-	}
-
-	public Declarer getSubclassPropertyDeclarer(String propertyPath) {
-		if ( "class".equals( propertyPath ) ) {
-			// special case where we need to force incloude all subclass joins
-			return Declarer.SUBCLASS;
-		}
-		return super.getSubclassPropertyDeclarer( propertyPath );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/JoinedSubclassEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.QueryException;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.Versioning;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.Table;
+import org.hibernate.sql.CaseFragment;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * An <tt>EntityPersister</tt> implementing the normalized "table-per-subclass"
+ * mapping strategy
+ *
+ * @author Gavin King
+ */
+public class JoinedSubclassEntityPersister extends AbstractEntityPersister {
+
+	// the class hierarchy structure
+	private final int tableSpan;
+	private final String[] tableNames;
+	private final String[] naturalOrderTableNames;
+	private final String[][] tableKeyColumns;
+	private final String[][] naturalOrderTableKeyColumns;
+	private final boolean[] naturalOrderCascadeDeleteEnabled;
+
+	private final String[] spaces;
+
+	private final String[] subclassClosure;
+
+	private final String[] subclassTableNameClosure;
+	private final String[][] subclassTableKeyColumnClosure;
+	private final boolean[] isClassOrSuperclassTable;
+
+	// properties of this class, including inherited properties
+	private final int[] naturalOrderPropertyTableNumbers;
+	private final int[] propertyTableNumbers;
+
+	// the closure of all properties in the entire hierarchy including
+	// subclasses and superclasses of this class
+	private final int[] subclassPropertyTableNumberClosure;
+
+	// the closure of all columns used by the entire hierarchy including
+	// subclasses and superclasses of this class
+	private final int[] subclassColumnTableNumberClosure;
+	private final int[] subclassFormulaTableNumberClosure;
+
+	// subclass discrimination works by assigning particular
+	// values to certain combinations of null primary key
+	// values in the outer join using an SQL CASE
+	private final Map subclassesByDiscriminatorValue = new HashMap();
+	private final String[] discriminatorValues;
+	private final String[] notNullColumnNames;
+	private final int[] notNullColumnTableNumbers;
+
+	private final String[] constraintOrderedTableNames;
+	private final String[][] constraintOrderedKeyColumnNames;
+
+	private final String discriminatorSQLString;
+
+	//INITIALIZATION:
+
+	public JoinedSubclassEntityPersister(
+			final PersistentClass persistentClass,
+			final EntityRegionAccessStrategy cacheAccessStrategy,
+			final SessionFactoryImplementor factory,
+			final Mapping mapping) throws HibernateException {
+
+		super( persistentClass, cacheAccessStrategy, factory );
+
+		// DISCRIMINATOR
+
+		final Object discriminatorValue;
+		if ( persistentClass.isPolymorphic() ) {
+			try {
+				discriminatorValue = new Integer( persistentClass.getSubclassId() );
+				discriminatorSQLString = discriminatorValue.toString();
+			}
+			catch (Exception e) {
+				throw new MappingException("Could not format discriminator value to SQL string", e );
+			}
+		}
+		else {
+			discriminatorValue = null;
+			discriminatorSQLString = null;
+		}
+
+		if ( optimisticLockMode() > Versioning.OPTIMISTIC_LOCK_VERSION ) {
+			throw new MappingException( "optimistic-lock=all|dirty not supported for joined-subclass mappings [" + getEntityName() + "]" );
+		}
+
+		//MULTITABLES
+
+		final int idColumnSpan = getIdentifierColumnSpan();
+
+		ArrayList tables = new ArrayList();
+		ArrayList keyColumns = new ArrayList();
+		ArrayList cascadeDeletes = new ArrayList();
+		Iterator titer = persistentClass.getTableClosureIterator();
+		Iterator kiter = persistentClass.getKeyClosureIterator();
+		while ( titer.hasNext() ) {
+			Table tab = (Table) titer.next();
+			KeyValue key = (KeyValue) kiter.next();
+			String tabname = tab.getQualifiedName(
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName()
+			);
+			tables.add(tabname);
+			String[] keyCols = new String[idColumnSpan];
+			Iterator citer = key.getColumnIterator();
+			for ( int k=0; k<idColumnSpan; k++ ) {
+				keyCols[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
+			}
+			keyColumns.add(keyCols);
+			cascadeDeletes.add( new Boolean( key.isCascadeDeleteEnabled() && factory.getDialect().supportsCascadeDelete() ) );
+		}
+		naturalOrderTableNames = ArrayHelper.toStringArray(tables);
+		naturalOrderTableKeyColumns = ArrayHelper.to2DStringArray(keyColumns);
+		naturalOrderCascadeDeleteEnabled = ArrayHelper.toBooleanArray(cascadeDeletes);
+
+		ArrayList subtables = new ArrayList();
+		ArrayList isConcretes = new ArrayList();
+		keyColumns = new ArrayList();
+		titer = persistentClass.getSubclassTableClosureIterator();
+		while ( titer.hasNext() ) {
+			Table tab = (Table) titer.next();
+			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassTable(tab) ) );
+			String tabname = tab.getQualifiedName(
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName()
+			);
+			subtables.add(tabname);
+			String[] key = new String[idColumnSpan];
+			Iterator citer = tab.getPrimaryKey().getColumnIterator();
+			for ( int k=0; k<idColumnSpan; k++ ) {
+				key[k] = ( (Column) citer.next() ).getQuotedName( factory.getDialect() );
+			}
+			keyColumns.add(key);
+		}
+		subclassTableNameClosure = ArrayHelper.toStringArray(subtables);
+		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(keyColumns);
+		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
+
+		constraintOrderedTableNames = new String[subclassTableNameClosure.length];
+		constraintOrderedKeyColumnNames = new String[subclassTableNameClosure.length][];
+		int currentPosition = 0;
+		for ( int i = subclassTableNameClosure.length - 1; i >= 0 ; i--, currentPosition++ ) {
+			constraintOrderedTableNames[currentPosition] = subclassTableNameClosure[i];
+			constraintOrderedKeyColumnNames[currentPosition] = subclassTableKeyColumnClosure[i];
+		}
+
+		tableSpan = naturalOrderTableNames.length;
+		tableNames = reverse(naturalOrderTableNames);
+		tableKeyColumns = reverse(naturalOrderTableKeyColumns);
+		reverse(subclassTableNameClosure, tableSpan);
+		reverse(subclassTableKeyColumnClosure, tableSpan);
+
+		spaces = ArrayHelper.join(
+				tableNames,
+				ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
+		);
+
+		// Custom sql
+		customSQLInsert = new String[tableSpan];
+		customSQLUpdate = new String[tableSpan];
+		customSQLDelete = new String[tableSpan];
+		insertCallable = new boolean[tableSpan];
+		updateCallable = new boolean[tableSpan];
+		deleteCallable = new boolean[tableSpan];
+		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
+		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
+		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[tableSpan];
+
+		PersistentClass pc = persistentClass;
+		int jk = tableSpan-1;
+		while (pc!=null) {
+			customSQLInsert[jk] = pc.getCustomSQLInsert();
+			insertCallable[jk] = customSQLInsert[jk] != null && pc.isCustomInsertCallable();
+			insertResultCheckStyles[jk] = pc.getCustomSQLInsertCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[jk], insertCallable[jk] )
+		                                  : pc.getCustomSQLInsertCheckStyle();
+			customSQLUpdate[jk] = pc.getCustomSQLUpdate();
+			updateCallable[jk] = customSQLUpdate[jk] != null && pc.isCustomUpdateCallable();
+			updateResultCheckStyles[jk] = pc.getCustomSQLUpdateCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[jk], updateCallable[jk] )
+		                                  : pc.getCustomSQLUpdateCheckStyle();
+			customSQLDelete[jk] = pc.getCustomSQLDelete();
+			deleteCallable[jk] = customSQLDelete[jk] != null && pc.isCustomDeleteCallable();
+			deleteResultCheckStyles[jk] = pc.getCustomSQLDeleteCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[jk], deleteCallable[jk] )
+		                                  : pc.getCustomSQLDeleteCheckStyle();
+			jk--;
+			pc = pc.getSuperclass();
+		}
+		if ( jk != -1 ) {
+			throw new AssertionFailure( "Tablespan does not match height of joined-subclass hiearchy." );
+		}
+
+		// PROPERTIES
+
+		int hydrateSpan = getPropertySpan();
+		naturalOrderPropertyTableNumbers = new int[hydrateSpan];
+		propertyTableNumbers = new int[hydrateSpan];
+		Iterator iter = persistentClass.getPropertyClosureIterator();
+		int i=0;
+		while( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			String tabname = prop.getValue().getTable().getQualifiedName(
+				factory.getDialect(),
+				factory.getSettings().getDefaultCatalogName(),
+				factory.getSettings().getDefaultSchemaName()
+			);
+			propertyTableNumbers[i] = getTableId(tabname, tableNames);
+			naturalOrderPropertyTableNumbers[i] = getTableId(tabname, naturalOrderTableNames);
+			i++;
+		}
+
+		// subclass closure properties
+
+		//TODO: code duplication with SingleTableEntityPersister
+
+		ArrayList columnTableNumbers = new ArrayList();
+		ArrayList formulaTableNumbers = new ArrayList();
+		ArrayList propTableNumbers = new ArrayList();
+
+		iter = persistentClass.getSubclassPropertyClosureIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			Table tab = prop.getValue().getTable();
+			String tabname = tab.getQualifiedName(
+					factory.getDialect(),
+					factory.getSettings().getDefaultCatalogName(),
+					factory.getSettings().getDefaultSchemaName()
+			);
+			Integer tabnum = new Integer( getTableId(tabname, subclassTableNameClosure) );
+			propTableNumbers.add(tabnum);
+
+			Iterator citer = prop.getColumnIterator();
+			while ( citer.hasNext() ) {
+				Selectable thing = (Selectable) citer.next();
+				if ( thing.isFormula() ) {
+					formulaTableNumbers.add(tabnum);
+				}
+				else {
+					columnTableNumbers.add(tabnum);
+				}
+			}
+
+		}
+
+		subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnTableNumbers);
+		subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propTableNumbers);
+		subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaTableNumbers);
+
+		// SUBCLASSES
+
+		int subclassSpan = persistentClass.getSubclassSpan() + 1;
+		subclassClosure = new String[subclassSpan];
+		subclassClosure[subclassSpan-1] = getEntityName();
+		if ( persistentClass.isPolymorphic() ) {
+			subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
+			discriminatorValues = new String[subclassSpan];
+			discriminatorValues[subclassSpan-1] = discriminatorSQLString;
+			notNullColumnTableNumbers = new int[subclassSpan];
+			final int id = getTableId(
+				persistentClass.getTable().getQualifiedName(
+						factory.getDialect(),
+						factory.getSettings().getDefaultCatalogName(),
+						factory.getSettings().getDefaultSchemaName()
+				),
+				subclassTableNameClosure
+			);
+			notNullColumnTableNumbers[subclassSpan-1] = id;
+			notNullColumnNames = new String[subclassSpan];
+			notNullColumnNames[subclassSpan-1] =  subclassTableKeyColumnClosure[id][0]; //( (Column) model.getTable().getPrimaryKey().getColumnIterator().next() ).getName();
+		}
+		else {
+			discriminatorValues = null;
+			notNullColumnTableNumbers = null;
+			notNullColumnNames = null;
+		}
+
+		iter = persistentClass.getSubclassIterator();
+		int k=0;
+		while ( iter.hasNext() ) {
+			Subclass sc = (Subclass) iter.next();
+			subclassClosure[k] = sc.getEntityName();
+			try {
+				if ( persistentClass.isPolymorphic() ) {
+					// we now use subclass ids that are consistent across all
+					// persisters for a class hierarchy, so that the use of
+					// "foo.class = Bar" works in HQL
+					Integer subclassId = new Integer( sc.getSubclassId() );//new Integer(k+1);
+					subclassesByDiscriminatorValue.put( subclassId, sc.getEntityName() );
+					discriminatorValues[k] = subclassId.toString();
+					int id = getTableId(
+						sc.getTable().getQualifiedName(
+								factory.getDialect(),
+								factory.getSettings().getDefaultCatalogName(),
+								factory.getSettings().getDefaultSchemaName()
+						),
+						subclassTableNameClosure
+					);
+					notNullColumnTableNumbers[k] = id;
+					notNullColumnNames[k] = subclassTableKeyColumnClosure[id][0]; //( (Column) sc.getTable().getPrimaryKey().getColumnIterator().next() ).getName();
+				}
+			}
+			catch (Exception e) {
+				throw new MappingException("Error parsing discriminator value", e );
+			}
+			k++;
+		}
+
+		initLockers();
+
+		initSubclassPropertyAliasesMap(persistentClass);
+
+		postConstruct(mapping);
+
+	}
+
+	/*public void postInstantiate() throws MappingException {
+		super.postInstantiate();
+		//TODO: other lock modes?
+		loader = createEntityLoader(LockMode.NONE, CollectionHelper.EMPTY_MAP);
+	}*/
+
+	public String getSubclassPropertyTableName(int i) {
+		return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ];
+	}
+
+	public Type getDiscriminatorType() {
+		return Hibernate.INTEGER;
+	}
+
+	public String getDiscriminatorSQLValue() {
+		return discriminatorSQLString;
+	}
+
+
+	public String getSubclassForDiscriminatorValue(Object value) {
+		return (String) subclassesByDiscriminatorValue.get(value);
+	}
+
+	public Serializable[] getPropertySpaces() {
+		return spaces; // don't need subclass tables, because they can't appear in conditions
+	}
+
+
+	protected String getTableName(int j) {
+		return naturalOrderTableNames[j];
+	}
+
+	protected String[] getKeyColumns(int j) {
+		return naturalOrderTableKeyColumns[j];
+	}
+
+	protected boolean isTableCascadeDeleteEnabled(int j) {
+		return naturalOrderCascadeDeleteEnabled[j];
+	}
+
+	protected boolean isPropertyOfTable(int property, int j) {
+		return naturalOrderPropertyTableNumbers[property]==j;
+	}
+
+	/**
+	 * Load an instance using either the <tt>forUpdateLoader</tt> or the outer joining <tt>loader</tt>,
+	 * depending upon the value of the <tt>lock</tt> parameter
+	 */
+	/*public Object load(Serializable id,	Object optionalObject, LockMode lockMode, SessionImplementor session)
+	throws HibernateException {
+
+		if ( log.isTraceEnabled() ) log.trace( "Materializing entity: " + MessageHelper.infoString(this, id) );
+
+		final UniqueEntityLoader loader = hasQueryLoader() ?
+				getQueryLoader() :
+				this.loader;
+		try {
+
+			final Object result = loader.load(id, optionalObject, session);
+
+			if (result!=null) lock(id, getVersion(result), result, lockMode, session);
+
+			return result;
+
+		}
+		catch (SQLException sqle) {
+			throw new JDBCException( "could not load by id: " +  MessageHelper.infoString(this, id), sqle );
+		}
+	}*/
+
+	private static final void reverse(Object[] objects, int len) {
+		Object[] temp = new Object[len];
+		for (int i=0; i<len; i++) {
+			temp[i] = objects[len-i-1];
+		}
+		for (int i=0; i<len; i++) {
+			objects[i] = temp[i];
+		}
+	}
+
+	private static final String[] reverse(String[] objects) {
+		int len = objects.length;
+		String[] temp = new String[len];
+		for (int i=0; i<len; i++) {
+			temp[i] = objects[len-i-1];
+		}
+		return temp;
+	}
+
+	private static final String[][] reverse(String[][] objects) {
+		int len = objects.length;
+		String[][] temp = new String[len][];
+		for (int i=0; i<len; i++) {
+			temp[i] = objects[len-i-1];
+		}
+		return temp;
+	}
+
+	public String fromTableFragment(String alias) {
+		return getTableName() + ' ' + alias;
+	}
+
+	public String getTableName() {
+		return tableNames[0];
+	}
+
+	private static int getTableId(String tableName, String[] tables) {
+		for ( int j=0; j<tables.length; j++ ) {
+			if ( tableName.equals( tables[j] ) ) {
+				return j;
+			}
+		}
+		throw new AssertionFailure("Table " + tableName + " not found");
+	}
+
+	public void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
+		if ( hasSubclasses() ) {
+			select.setExtraSelectList( discriminatorFragment(name), getDiscriminatorAlias() );
+		}
+	}
+
+	private CaseFragment discriminatorFragment(String alias) {
+		CaseFragment cases = getFactory().getDialect().createCaseFragment();
+
+		for ( int i=0; i<discriminatorValues.length; i++ ) {
+			cases.addWhenColumnNotNull(
+				generateTableAlias( alias, notNullColumnTableNumbers[i] ),
+				notNullColumnNames[i],
+				discriminatorValues[i]
+			);
+		}
+
+		return cases;
+	}
+
+	public String filterFragment(String alias) {
+		return hasWhere() ?
+			" and " + getSQLWhereString( generateFilterConditionAlias( alias ) ) :
+			"";
+	}
+
+	public String generateFilterConditionAlias(String rootAlias) {
+		return generateTableAlias( rootAlias, tableSpan-1 );
+	}
+
+	public String[] getIdentifierColumnNames() {
+		return tableKeyColumns[0];
+	}
+
+	public String[] toColumns(String alias, String propertyName) throws QueryException {
+
+		if ( ENTITY_CLASS.equals(propertyName) ) {
+			// This doesn't actually seem to work but it *might*
+			// work on some dbs. Also it doesn't work if there
+			// are multiple columns of results because it
+			// is not accounting for the suffix:
+			// return new String[] { getDiscriminatorColumnName() };
+
+			return new String[] { discriminatorFragment(alias).toFragmentString() };
+		}
+		else {
+			return super.toColumns(alias, propertyName);
+		}
+
+	}
+
+	protected int[] getPropertyTableNumbersInSelect() {
+		return propertyTableNumbers;
+	}
+
+	protected int getSubclassPropertyTableNumber(int i) {
+		return subclassPropertyTableNumberClosure[i];
+	}
+
+	public int getTableSpan() {
+		return tableSpan;
+	}
+
+	public boolean isMultiTable() {
+		return true;
+	}
+
+	protected int[] getSubclassColumnTableNumberClosure() {
+		return subclassColumnTableNumberClosure;
+	}
+
+	protected int[] getSubclassFormulaTableNumberClosure() {
+		return subclassFormulaTableNumberClosure;
+	}
+
+	protected int[] getPropertyTableNumbers() {
+		return naturalOrderPropertyTableNumbers;
+	}
+
+	protected String[] getSubclassTableKeyColumns(int j) {
+		return subclassTableKeyColumnClosure[j];
+	}
+
+	public String getSubclassTableName(int j) {
+		return subclassTableNameClosure[j];
+	}
+
+	public int getSubclassTableSpan() {
+		return subclassTableNameClosure.length;
+	}
+
+	protected boolean isClassOrSuperclassTable(int j) {
+		return isClassOrSuperclassTable[j];
+	}
+
+	public String getPropertyTableName(String propertyName) {
+		Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName);
+		if ( index == null ) {
+			return null;
+		}
+		return tableNames[ propertyTableNumbers[ index.intValue() ] ];
+	}
+
+	public String[] getConstraintOrderedTableNameClosure() {
+		return constraintOrderedTableNames;
+	}
+
+	public String[][] getContraintOrderedTableKeyColumnClosure() {
+		return constraintOrderedKeyColumnNames;
+	}
+
+	public String getRootTableName() {
+		return naturalOrderTableNames[0];
+	}
+
+	public String getRootTableAlias(String drivingAlias) {
+		return generateTableAlias( drivingAlias, getTableId( getRootTableName(), tableNames ) );
+	}
+
+	public Declarer getSubclassPropertyDeclarer(String propertyPath) {
+		if ( "class".equals( propertyPath ) ) {
+			// special case where we need to force incloude all subclass joins
+			return Declarer.SUBCLASS;
+		}
+		return super.getSubclassPropertyDeclarer( propertyPath );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/Loadable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,88 +0,0 @@
-//$Id: Loadable.java 7458 2005-07-12 20:12:57Z oneovthafew $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * Implemented by a <tt>EntityPersister</tt> that may be loaded
- * using <tt>Loader</tt>.
- *
- * @see org.hibernate.loader.Loader
- * @author Gavin King
- */
-public interface Loadable extends EntityPersister {
-	
-	public static final String ROWID_ALIAS = "rowid_";
-
-	/**
-	 * Does this persistent class have subclasses?
-	 */
-	public boolean hasSubclasses();
-
-	/**
-	 * Get the discriminator type
-	 */
-	public Type getDiscriminatorType();
-
-	/**
-	 * Get the concrete subclass corresponding to the given discriminator
-	 * value
-	 */
-	public String getSubclassForDiscriminatorValue(Object value);
-
-	/**
-	 * Get the names of columns used to persist the identifier
-	 */
-	public String[] getIdentifierColumnNames();
-
-	/**
-	 * Get the result set aliases used for the identifier columns, given a suffix
-	 */
-	public String[] getIdentifierAliases(String suffix);
-	/**
-	 * Get the result set aliases used for the property columns, given a suffix (properties of this class, only).
-	 */
-	public String[] getPropertyAliases(String suffix, int i);
-	
-	/**
-	 * Get the result set column names mapped for this property (properties of this class, only).
-	 */
-	public String[] getPropertyColumnNames(int i);
-	
-	/**
-	 * Get the result set aliases used for the identifier columns, given a suffix
-	 */
-	public String getDiscriminatorAlias(String suffix);
-	
-	/**
-	 * @return the column name for the discriminator as specified in the mapping.
-	 */
-	public String getDiscriminatorColumnName();
-	
-	/**
-	 * Does the result set contain rowids?
-	 */
-	public boolean hasRowId();
-	
-	/**
-	 * Retrieve property values from one row of a result set
-	 */
-	public Object[] hydrate(
-			ResultSet rs,
-			Serializable id,
-			Object object,
-			Loadable rootLoadable,
-			String[][] suffixedPropertyColumns,
-			boolean allProperties, 
-			SessionImplementor session)
-	throws SQLException, HibernateException;
-
-	public boolean isAbstract();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/Loadable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Loadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,111 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * Implemented by a <tt>EntityPersister</tt> that may be loaded
+ * using <tt>Loader</tt>.
+ *
+ * @see org.hibernate.loader.Loader
+ * @author Gavin King
+ */
+public interface Loadable extends EntityPersister {
+	
+	public static final String ROWID_ALIAS = "rowid_";
+
+	/**
+	 * Does this persistent class have subclasses?
+	 */
+	public boolean hasSubclasses();
+
+	/**
+	 * Get the discriminator type
+	 */
+	public Type getDiscriminatorType();
+
+	/**
+	 * Get the concrete subclass corresponding to the given discriminator
+	 * value
+	 */
+	public String getSubclassForDiscriminatorValue(Object value);
+
+	/**
+	 * Get the names of columns used to persist the identifier
+	 */
+	public String[] getIdentifierColumnNames();
+
+	/**
+	 * Get the result set aliases used for the identifier columns, given a suffix
+	 */
+	public String[] getIdentifierAliases(String suffix);
+	/**
+	 * Get the result set aliases used for the property columns, given a suffix (properties of this class, only).
+	 */
+	public String[] getPropertyAliases(String suffix, int i);
+	
+	/**
+	 * Get the result set column names mapped for this property (properties of this class, only).
+	 */
+	public String[] getPropertyColumnNames(int i);
+	
+	/**
+	 * Get the result set aliases used for the identifier columns, given a suffix
+	 */
+	public String getDiscriminatorAlias(String suffix);
+	
+	/**
+	 * @return the column name for the discriminator as specified in the mapping.
+	 */
+	public String getDiscriminatorColumnName();
+	
+	/**
+	 * Does the result set contain rowids?
+	 */
+	public boolean hasRowId();
+	
+	/**
+	 * Retrieve property values from one row of a result set
+	 */
+	public Object[] hydrate(
+			ResultSet rs,
+			Serializable id,
+			Object object,
+			Loadable rootLoadable,
+			String[][] suffixedPropertyColumns,
+			boolean allProperties, 
+			SessionImplementor session)
+	throws SQLException, HibernateException;
+
+	public boolean isAbstract();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/Lockable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-package org.hibernate.persister.entity;
-
-/**
- * Contract for things that can be locked via a {@link org.hibernate.dialect.lock.LockingStrategy}.
- * <p/>
- * Currently only the root table gets locked, except for the case of HQL and Criteria queries
- * against dialects which do not support either (1) FOR UPDATE OF or (2) support hint locking
- * (in which case *all* queried tables would be locked).
- *
- * @author Steve Ebersole
- * @since 3.2
- */
-public interface Lockable extends EntityPersister {
-	/**
-	 * Locks are always applied to the "root table".
-	 *
-	 * @return The root table name
-	 */
-	public String getRootTableName();
-
-	/**
-	 * Get the SQL alias this persister would use for the root table
-	 * given the passed driving alias.
-	 *
-	 * @param drivingAlias The driving alias; or the alias for the table
-	 * mapped by this persister in the hierarchy.
-	 * @return The root table alias.
-	 */
-	public String getRootTableAlias(String drivingAlias);
-
-	/**
-	 * Get the names of columns on the root table used to persist the identifier.
-	 *
-	 * @return The root table identifier column names.
-	 */
-	public String[] getRootTableIdentifierColumnNames();
-
-	/**
-	 * For versioned entities, get the name of the column (again, expected on the
-	 * root table) used to store the version values.
-	 *
-	 * @return The version column name.
-	 */
-	public String getVersionColumnName();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/Lockable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Lockable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+/**
+ * Contract for things that can be locked via a {@link org.hibernate.dialect.lock.LockingStrategy}.
+ * <p/>
+ * Currently only the root table gets locked, except for the case of HQL and Criteria queries
+ * against dialects which do not support either (1) FOR UPDATE OF or (2) support hint locking
+ * (in which case *all* queried tables would be locked).
+ *
+ * @author Steve Ebersole
+ * @since 3.2
+ */
+public interface Lockable extends EntityPersister {
+	/**
+	 * Locks are always applied to the "root table".
+	 *
+	 * @return The root table name
+	 */
+	public String getRootTableName();
+
+	/**
+	 * Get the SQL alias this persister would use for the root table
+	 * given the passed driving alias.
+	 *
+	 * @param drivingAlias The driving alias; or the alias for the table
+	 * mapped by this persister in the hierarchy.
+	 * @return The root table alias.
+	 */
+	public String getRootTableAlias(String drivingAlias);
+
+	/**
+	 * Get the names of columns on the root table used to persist the identifier.
+	 *
+	 * @return The root table identifier column names.
+	 */
+	public String[] getRootTableIdentifierColumnNames();
+
+	/**
+	 * For versioned entities, get the name of the column (again, expected on the
+	 * root table) used to store the version values.
+	 *
+	 * @return The version column name.
+	 */
+	public String getVersionColumnName();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-//$Id: NamedQueryLoader.java 10019 2006-06-15 07:50:12Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.FlushMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.impl.AbstractQueryImpl;
-import org.hibernate.loader.entity.UniqueEntityLoader;
-
-/**
- * Not really a <tt>Loader</tt>, just a wrapper around a
- * named query.
- * @author Gavin King
- */
-public final class NamedQueryLoader implements UniqueEntityLoader {
-	private final String queryName;
-	private final EntityPersister persister;
-	
-	private static final Logger log = LoggerFactory.getLogger(NamedQueryLoader.class);
-
-	public NamedQueryLoader(String queryName, EntityPersister persister) {
-		super();
-		this.queryName = queryName;
-		this.persister = persister;
-	}
-
-	public Object load(Serializable id, Object optionalObject, SessionImplementor session) 
-	throws HibernateException {
-		
-		if ( log.isDebugEnabled() ) {
-			log.debug(
-					"loading entity: " + persister.getEntityName() + 
-					" using named query: " + queryName 
-				);
-		}
-		
-		AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedQuery(queryName);
-		if ( query.hasNamedParameters() ) {
-			query.setParameter( 
-					query.getNamedParameters()[0], 
-					id, 
-					persister.getIdentifierType() 
-				);
-		}
-		else {
-			query.setParameter( 0, id, persister.getIdentifierType() );
-		}
-		query.setOptionalId(id);
-		query.setOptionalEntityName( persister.getEntityName() );
-		query.setOptionalObject(optionalObject);
-		query.setFlushMode( FlushMode.MANUAL );
-		query.list();
-		
-		// now look up the object we are really interested in!
-		// (this lets us correctly handle proxies and multi-row
-		// or multi-column queries)
-		return session.getPersistenceContext()
-				.getEntity( new EntityKey( id, persister, session.getEntityMode() ) );
-
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/NamedQueryLoader.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,89 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.FlushMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.impl.AbstractQueryImpl;
+import org.hibernate.loader.entity.UniqueEntityLoader;
+
+/**
+ * Not really a <tt>Loader</tt>, just a wrapper around a
+ * named query.
+ * @author Gavin King
+ */
+public final class NamedQueryLoader implements UniqueEntityLoader {
+	private final String queryName;
+	private final EntityPersister persister;
+	
+	private static final Logger log = LoggerFactory.getLogger(NamedQueryLoader.class);
+
+	public NamedQueryLoader(String queryName, EntityPersister persister) {
+		super();
+		this.queryName = queryName;
+		this.persister = persister;
+	}
+
+	public Object load(Serializable id, Object optionalObject, SessionImplementor session) 
+	throws HibernateException {
+		
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"loading entity: " + persister.getEntityName() + 
+					" using named query: " + queryName 
+				);
+		}
+		
+		AbstractQueryImpl query = (AbstractQueryImpl) session.getNamedQuery(queryName);
+		if ( query.hasNamedParameters() ) {
+			query.setParameter( 
+					query.getNamedParameters()[0], 
+					id, 
+					persister.getIdentifierType() 
+				);
+		}
+		else {
+			query.setParameter( 0, id, persister.getIdentifierType() );
+		}
+		query.setOptionalId(id);
+		query.setOptionalEntityName( persister.getEntityName() );
+		query.setOptionalObject(optionalObject);
+		query.setFlushMode( FlushMode.MANUAL );
+		query.list();
+		
+		// now look up the object we are really interested in!
+		// (this lets us correctly handle proxies and multi-row
+		// or multi-column queries)
+		return session.getPersistenceContext()
+				.getEntity( new EntityKey( id, persister, session.getEntityMode() ) );
+
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,90 +0,0 @@
-//$Id: OuterJoinLoadable.java 7652 2005-07-26 05:51:47Z oneovthafew $
-package org.hibernate.persister.entity;
-
-import org.hibernate.FetchMode;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-
-/**
- * A <tt>EntityPersister</tt> that may be loaded by outer join using
- * the <tt>OuterJoinLoader</tt> hierarchy and may be an element
- * of a one-to-many association.
- *
- * @see org.hibernate.loader.OuterJoinLoader
- * @author Gavin King
- */
-public interface OuterJoinLoadable extends Loadable, Joinable {
-
-	/**
-	 * Generate a list of collection index, key and element columns
-	 */
-	public String selectFragment(String alias, String suffix);
-	/**
-	 * How many properties are there, for this class and all subclasses?
-	 */
-	public int countSubclassProperties();
-
-	/**
-	 * May this (subclass closure) property be fetched using an SQL outerjoin?
-	 */
-	public FetchMode getFetchMode(int i);
-	/**
-	 * Get the cascade style of this (subclass closure) property
-	 */
-	public CascadeStyle getCascadeStyle(int i);
-
-	/**
-	 * Is this property defined on a subclass of the mapped class.
-	 */
-	public boolean isDefinedOnSubclass(int i);
-
-	/**
-	 * Get the type of the numbered property of the class or a subclass.
-	 */
-	public Type getSubclassPropertyType(int i);
-
-	/**
-	 * Get the name of the numbered property of the class or a subclass.
-	 */
-	public String getSubclassPropertyName(int i);
-	
-	/**
-	 * Is the numbered property of the class of subclass nullable?
-	 */
-	public boolean isSubclassPropertyNullable(int i);
-
-	/**
-	 * Return the column names used to persist the numbered property of the
-	 * class or a subclass.
-	 */
-	public String[] getSubclassPropertyColumnNames(int i);
-
-	/**
-	 * Return the table name used to persist the numbered property of the
-	 * class or a subclass.
-	 */
-	public String getSubclassPropertyTableName(int i);
-	/**
-	 * Given the number of a property of a subclass, and a table alias,
-	 * return the aliased column names.
-	 */
-	public String[] toColumns(String name, int i);
-
-	/**
-	 * Get the main from table fragment, given a query alias.
-	 */
-	public String fromTableFragment(String alias);
-
-	/**
-	 * Get the column names for the given property path
-	 */
-	public String[] getPropertyColumnNames(String propertyPath);
-	/**
-	 * Get the table name for the given property path
-	 */
-	public String getPropertyTableName(String propertyName);
-	
-	public EntityType getEntityType();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/OuterJoinLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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.persister.entity;
+
+import org.hibernate.FetchMode;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+
+/**
+ * A <tt>EntityPersister</tt> that may be loaded by outer join using
+ * the <tt>OuterJoinLoader</tt> hierarchy and may be an element
+ * of a one-to-many association.
+ *
+ * @see org.hibernate.loader.OuterJoinLoader
+ * @author Gavin King
+ */
+public interface OuterJoinLoadable extends Loadable, Joinable {
+
+	/**
+	 * Generate a list of collection index, key and element columns
+	 */
+	public String selectFragment(String alias, String suffix);
+	/**
+	 * How many properties are there, for this class and all subclasses?
+	 */
+	public int countSubclassProperties();
+
+	/**
+	 * May this (subclass closure) property be fetched using an SQL outerjoin?
+	 */
+	public FetchMode getFetchMode(int i);
+	/**
+	 * Get the cascade style of this (subclass closure) property
+	 */
+	public CascadeStyle getCascadeStyle(int i);
+
+	/**
+	 * Is this property defined on a subclass of the mapped class.
+	 */
+	public boolean isDefinedOnSubclass(int i);
+
+	/**
+	 * Get the type of the numbered property of the class or a subclass.
+	 */
+	public Type getSubclassPropertyType(int i);
+
+	/**
+	 * Get the name of the numbered property of the class or a subclass.
+	 */
+	public String getSubclassPropertyName(int i);
+	
+	/**
+	 * Is the numbered property of the class of subclass nullable?
+	 */
+	public boolean isSubclassPropertyNullable(int i);
+
+	/**
+	 * Return the column names used to persist the numbered property of the
+	 * class or a subclass.
+	 */
+	public String[] getSubclassPropertyColumnNames(int i);
+
+	/**
+	 * Return the table name used to persist the numbered property of the
+	 * class or a subclass.
+	 */
+	public String getSubclassPropertyTableName(int i);
+	/**
+	 * Given the number of a property of a subclass, and a table alias,
+	 * return the aliased column names.
+	 */
+	public String[] toColumns(String name, int i);
+
+	/**
+	 * Get the main from table fragment, given a query alias.
+	 */
+	public String fromTableFragment(String alias);
+
+	/**
+	 * Get the column names for the given property path
+	 */
+	public String[] getPropertyColumnNames(String propertyPath);
+	/**
+	 * Get the table name for the given property path
+	 */
+	public String getPropertyTableName(String propertyName);
+	
+	public EntityType getEntityType();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: PropertyMapping.java 6179 2005-03-23 15:41:48Z steveebersole $
-package org.hibernate.persister.entity;
-
-import org.hibernate.QueryException;
-import org.hibernate.type.Type;
-
-/**
- * Abstraction of all mappings that define properties:
- * entities, collection elements.
- *
- * @author Gavin King
- */
-public interface PropertyMapping {
-	// TODO: It would be really, really nice to use this to also model components!
-	/**
-	 * Given a component path expression, get the type of the property
-	 */
-	public Type toType(String propertyName) throws QueryException;
-	/**
-	 * Given a query alias and a property path, return the qualified
-	 * column name
-	 */
-	public String[] toColumns(String alias, String propertyName) throws QueryException;
-	/**
-	 * Given a property path, return the corresponding column name(s).
-	 */
-	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException;
-	/**
-	 * Get the type of the thing containing the properties
-	 */
-	public Type getType();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/PropertyMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+import org.hibernate.QueryException;
+import org.hibernate.type.Type;
+
+/**
+ * Abstraction of all mappings that define properties:
+ * entities, collection elements.
+ *
+ * @author Gavin King
+ */
+public interface PropertyMapping {
+	// TODO: It would be really, really nice to use this to also model components!
+	/**
+	 * Given a component path expression, get the type of the property
+	 */
+	public Type toType(String propertyName) throws QueryException;
+	/**
+	 * Given a query alias and a property path, return the qualified
+	 * column name
+	 */
+	public String[] toColumns(String alias, String propertyName) throws QueryException;
+	/**
+	 * Given a property path, return the corresponding column name(s).
+	 */
+	public String[] toColumns(String propertyName) throws QueryException, UnsupportedOperationException;
+	/**
+	 * Get the type of the thing containing the properties
+	 */
+	public Type getType();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/Queryable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,154 +0,0 @@
-//$Id: Queryable.java 10824 2006-11-16 19:32:48Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-/**
- * Extends the generic <tt>EntityPersister</tt> contract to add
- * operations required by the Hibernate Query Language
- *
- * @author Gavin King
- */
-public interface Queryable extends Loadable, PropertyMapping, Joinable {
-
-	/**
-	 * Is this an abstract class?
-	 */
-	public boolean isAbstract();
-	/**
-	 * Is this class explicit polymorphism only?
-	 */
-	public boolean isExplicitPolymorphism();
-	/**
-	 * Get the class that this class is mapped as a subclass of -
-	 * not necessarily the direct superclass
-	 */
-	public String getMappedSuperclass();
-	/**
-	 * Get the discriminator value for this particular concrete subclass,
-	 * as a string that may be embedded in a select statement
-	 */
-	public String getDiscriminatorSQLValue();
-
-	/**
-	 * Given a query alias and an identifying suffix, render the intentifier select fragment.
-	 */
-	public String identifierSelectFragment(String name, String suffix);
-	/**
-	 * Given a query alias and an identifying suffix, render the property select fragment.
-	 */
-	public String propertySelectFragment(String alias, String suffix, boolean allProperties);
-
-	/**
-	 * Get the names of columns used to persist the identifier
-	 */
-	public String[] getIdentifierColumnNames();
-
-	/**
-	 * Is the inheritence hierarchy described by this persister contained across
-	 * multiple tables?
-	 *
-	 * @return True if the inheritence hierarchy is spread across multiple tables; false otherwise.
-	 */
-	public boolean isMultiTable();
-
-	/**
-	 * Get the names of all tables used in the hierarchy (up and down) ordered such
-	 * that deletes in the given order would not cause contraint violations.
-	 *
-	 * @return The ordered array of table names.
-	 */
-	public String[] getConstraintOrderedTableNameClosure();
-
-	/**
-	 * For each table specified in {@link #getConstraintOrderedTableNameClosure()}, get
-	 * the columns that define the key between the various hierarchy classes.
-	 * <p/>
-	 * The first dimension here corresponds to the table indexes returned in
-	 * {@link #getConstraintOrderedTableNameClosure()}.
-	 * <p/>
-	 * The second dimension should have the same length across all the elements in
-	 * the first dimension.  If not, that'd be a problem ;)
-	 *
-	 * @return
-	 */
-	public String[][] getContraintOrderedTableKeyColumnClosure();
-
-	/**
-	 * Get the name of the temporary table to be used to (potentially) store id values
-	 * when performing bulk update/deletes.
-	 *
-	 * @return The appropriate temporary table name.
-	 */
-	public String getTemporaryIdTableName();
-
-	/**
-	 * Get the appropriate DDL command for generating the temporary table to
-	 * be used to (potentially) store id values when performing bulk update/deletes.
-	 *
-	 * @return The appropriate temporary table creation command.
-	 */
-	public String getTemporaryIdTableDDL();
-
-	/**
-	 * Given a property name, determine the number of the table which contains the column
-	 * to which this property is mapped.
-	 * <p/>
-	 * Note that this is <b>not</b> relative to the results from {@link #getConstraintOrderedTableNameClosure()}.
-	 * It is relative to the subclass table name closure maintained internal to the persister (yick!).
-	 * It is also relative to the indexing used to resolve {@link #getSubclassTableName}...
-	 *
-	 * @param propertyPath The name of the property.
-	 * @return The nunber of the table to which the property is mapped.
-	 */
-	public int getSubclassPropertyTableNumber(String propertyPath);
-
-	/**
-	 * Determine whether the given property is declared by our
-	 * mapped class, our super class, or one of our subclasses...
-	 * <p/>
-	 * Note: the method is called 'subclass property...' simply
-	 * for consistency sake (e.g. {@link #getSubclassPropertyTableNumber}
-	 *
-	 * @param propertyPath The property name.
-	 * @return The property declarer
-	 */
-	public Declarer getSubclassPropertyDeclarer(String propertyPath);
-
-	/**
-	 * Get the name of the table with the given index from the internal
-	 * array.
-	 *
-	 * @param number The index into the internal array.
-	 * @return
-	 */
-	public String getSubclassTableName(int number);
-
-	/**
-	 * Is the version property included in insert statements?
-	 */
-	public boolean isVersionPropertyInsertable();
-
-	/**
-	 * The alias used for any filter conditions (mapped where-fragments or
-	 * enabled-filters).
-	 * </p>
-	 * This may or may not be different from the root alias depending upon the
-	 * inheritence mapping strategy.
-	 *
-	 * @param rootAlias The root alias
-	 * @return The alias used for "filter conditions" within the where clause.
-	 */
-	public String generateFilterConditionAlias(String rootAlias);
-
-	public static class Declarer {
-		public static final Declarer CLASS = new Declarer( "class" );
-		public static final Declarer SUBCLASS = new Declarer( "subclass" );
-		public static final Declarer SUPERCLASS = new Declarer( "superclass" );
-		private final String name;
-		public Declarer(String name) {
-			this.name = name;
-		}
-		public String toString() {
-			return name;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/Queryable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/Queryable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,177 @@
+/*
+ * 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.persister.entity;
+
+/**
+ * Extends the generic <tt>EntityPersister</tt> contract to add
+ * operations required by the Hibernate Query Language
+ *
+ * @author Gavin King
+ */
+public interface Queryable extends Loadable, PropertyMapping, Joinable {
+
+	/**
+	 * Is this an abstract class?
+	 */
+	public boolean isAbstract();
+	/**
+	 * Is this class explicit polymorphism only?
+	 */
+	public boolean isExplicitPolymorphism();
+	/**
+	 * Get the class that this class is mapped as a subclass of -
+	 * not necessarily the direct superclass
+	 */
+	public String getMappedSuperclass();
+	/**
+	 * Get the discriminator value for this particular concrete subclass,
+	 * as a string that may be embedded in a select statement
+	 */
+	public String getDiscriminatorSQLValue();
+
+	/**
+	 * Given a query alias and an identifying suffix, render the intentifier select fragment.
+	 */
+	public String identifierSelectFragment(String name, String suffix);
+	/**
+	 * Given a query alias and an identifying suffix, render the property select fragment.
+	 */
+	public String propertySelectFragment(String alias, String suffix, boolean allProperties);
+
+	/**
+	 * Get the names of columns used to persist the identifier
+	 */
+	public String[] getIdentifierColumnNames();
+
+	/**
+	 * Is the inheritence hierarchy described by this persister contained across
+	 * multiple tables?
+	 *
+	 * @return True if the inheritence hierarchy is spread across multiple tables; false otherwise.
+	 */
+	public boolean isMultiTable();
+
+	/**
+	 * Get the names of all tables used in the hierarchy (up and down) ordered such
+	 * that deletes in the given order would not cause contraint violations.
+	 *
+	 * @return The ordered array of table names.
+	 */
+	public String[] getConstraintOrderedTableNameClosure();
+
+	/**
+	 * For each table specified in {@link #getConstraintOrderedTableNameClosure()}, get
+	 * the columns that define the key between the various hierarchy classes.
+	 * <p/>
+	 * The first dimension here corresponds to the table indexes returned in
+	 * {@link #getConstraintOrderedTableNameClosure()}.
+	 * <p/>
+	 * The second dimension should have the same length across all the elements in
+	 * the first dimension.  If not, that'd be a problem ;)
+	 *
+	 * @return
+	 */
+	public String[][] getContraintOrderedTableKeyColumnClosure();
+
+	/**
+	 * Get the name of the temporary table to be used to (potentially) store id values
+	 * when performing bulk update/deletes.
+	 *
+	 * @return The appropriate temporary table name.
+	 */
+	public String getTemporaryIdTableName();
+
+	/**
+	 * Get the appropriate DDL command for generating the temporary table to
+	 * be used to (potentially) store id values when performing bulk update/deletes.
+	 *
+	 * @return The appropriate temporary table creation command.
+	 */
+	public String getTemporaryIdTableDDL();
+
+	/**
+	 * Given a property name, determine the number of the table which contains the column
+	 * to which this property is mapped.
+	 * <p/>
+	 * Note that this is <b>not</b> relative to the results from {@link #getConstraintOrderedTableNameClosure()}.
+	 * It is relative to the subclass table name closure maintained internal to the persister (yick!).
+	 * It is also relative to the indexing used to resolve {@link #getSubclassTableName}...
+	 *
+	 * @param propertyPath The name of the property.
+	 * @return The nunber of the table to which the property is mapped.
+	 */
+	public int getSubclassPropertyTableNumber(String propertyPath);
+
+	/**
+	 * Determine whether the given property is declared by our
+	 * mapped class, our super class, or one of our subclasses...
+	 * <p/>
+	 * Note: the method is called 'subclass property...' simply
+	 * for consistency sake (e.g. {@link #getSubclassPropertyTableNumber}
+	 *
+	 * @param propertyPath The property name.
+	 * @return The property declarer
+	 */
+	public Declarer getSubclassPropertyDeclarer(String propertyPath);
+
+	/**
+	 * Get the name of the table with the given index from the internal
+	 * array.
+	 *
+	 * @param number The index into the internal array.
+	 * @return
+	 */
+	public String getSubclassTableName(int number);
+
+	/**
+	 * Is the version property included in insert statements?
+	 */
+	public boolean isVersionPropertyInsertable();
+
+	/**
+	 * The alias used for any filter conditions (mapped where-fragments or
+	 * enabled-filters).
+	 * </p>
+	 * This may or may not be different from the root alias depending upon the
+	 * inheritence mapping strategy.
+	 *
+	 * @param rootAlias The root alias
+	 * @return The alias used for "filter conditions" within the where clause.
+	 */
+	public String generateFilterConditionAlias(String rootAlias);
+
+	public static class Declarer {
+		public static final Declarer CLASS = new Declarer( "class" );
+		public static final Declarer SUBCLASS = new Declarer( "subclass" );
+		public static final Declarer SUPERCLASS = new Declarer( "superclass" );
+		private final String name;
+		public Declarer(String name) {
+			this.name = name;
+		}
+		public String toString() {
+			return name;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-//$Id: SQLLoadable.java 7363 2005-07-03 19:42:43Z maxcsaucdk $
-package org.hibernate.persister.entity;
-
-import org.hibernate.type.Type;
-
-/**
- * A class persister that supports queries expressed in the
- * platform native SQL dialect
- *
- * @author Gavin King, Max Andersen
- */
-public interface SQLLoadable extends Loadable {
-
-	/**
-	 * Return the column alias names used to persist/query the named property of the class or a subclass (optional operation).
-	 */
-	public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix);
-
-	/**
-	 * Return the column names used to persist/query the named property of the class or a subclass (optional operation).
-	 */
-	public String[] getSubclassPropertyColumnNames(String propertyName);
-	
-	/**
-	 * All columns to select, when loading.
-	 */
-	public String selectFragment(String alias, String suffix);
-
-	/**
-	 * Get the type
-	 */
-	public Type getType();
-
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SQLLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+import org.hibernate.type.Type;
+
+/**
+ * A class persister that supports queries expressed in the
+ * platform native SQL dialect
+ *
+ * @author Gavin King, Max Andersen
+ */
+public interface SQLLoadable extends Loadable {
+
+	/**
+	 * Return the column alias names used to persist/query the named property of the class or a subclass (optional operation).
+	 */
+	public String[] getSubclassPropertyColumnAliases(String propertyName, String suffix);
+
+	/**
+	 * Return the column names used to persist/query the named property of the class or a subclass (optional operation).
+	 */
+	public String[] getSubclassPropertyColumnNames(String propertyName);
+	
+	/**
+	 * All columns to select, when loading.
+	 */
+	public String selectFragment(String alias, String suffix);
+
+	/**
+	 * Get the type
+	 */
+	public Type getType();
+
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,713 +0,0 @@
-//$Id: SingleTableEntityPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.Formula;
-import org.hibernate.mapping.Join;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Selectable;
-import org.hibernate.mapping.Subclass;
-import org.hibernate.mapping.Table;
-import org.hibernate.mapping.Value;
-import org.hibernate.sql.InFragment;
-import org.hibernate.sql.Insert;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.DiscriminatorType;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.MarkerObject;
-
-/**
- * The default implementation of the <tt>EntityPersister</tt> interface.
- * Implements the "table-per-class-hierarchy" or "roll-up" mapping strategy
- * for an entity class and its inheritence hierarchy.  This is implemented
- * as a single table holding all classes in the hierarchy with a discrimator
- * column used to determine which concrete class is referenced.
- *
- * @author Gavin King
- */
-public class SingleTableEntityPersister extends AbstractEntityPersister {
-
-	// the class hierarchy structure
-	private final int joinSpan;
-	private final String[] qualifiedTableNames;
-	private final boolean[] isInverseTable;
-	private final boolean[] isNullableTable;
-	private final String[][] keyColumnNames;
-	private final boolean[] cascadeDeleteEnabled;
-	private final boolean hasSequentialSelects;
-	
-	private final String[] spaces;
-
-	private final String[] subclassClosure;
-
-	private final String[] subclassTableNameClosure;
-	private final boolean[] subclassTableIsLazyClosure;
-	private final boolean[] isInverseSubclassTable;
-	private final boolean[] isNullableSubclassTable;
-	private final boolean[] subclassTableSequentialSelect;
-	private final String[][] subclassTableKeyColumnClosure;
-	private final boolean[] isClassOrSuperclassTable;
-
-	// properties of this class, including inherited properties
-	private final int[] propertyTableNumbers;
-
-	// the closure of all columns used by the entire hierarchy including
-	// subclasses and superclasses of this class
-	private final int[] subclassPropertyTableNumberClosure;
-
-	private final int[] subclassColumnTableNumberClosure;
-	private final int[] subclassFormulaTableNumberClosure;
-
-	// discriminator column
-	private final Map subclassesByDiscriminatorValue = new HashMap();
-	private final boolean forceDiscriminator;
-	private final String discriminatorColumnName;
-	private final String discriminatorFormula;
-	private final String discriminatorFormulaTemplate;
-	private final String discriminatorAlias;
-	private final Type discriminatorType;
-	private final String discriminatorSQLValue;
-	private final boolean discriminatorInsertable;
-
-	private final String[] constraintOrderedTableNames;
-	private final String[][] constraintOrderedKeyColumnNames;
-
-	//private final Map propertyTableNumbersByName = new HashMap();
-	private final Map propertyTableNumbersByNameAndSubclass = new HashMap();
-	
-	private final Map sequentialSelectStringsByEntityName = new HashMap();
-
-	private static final Object NULL_DISCRIMINATOR = new MarkerObject("<null discriminator>");
-	private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject("<not null discriminator>");
-
-	//INITIALIZATION:
-
-	public SingleTableEntityPersister(
-			final PersistentClass persistentClass, 
-			final EntityRegionAccessStrategy cacheAccessStrategy,
-			final SessionFactoryImplementor factory,
-			final Mapping mapping) throws HibernateException {
-
-		super( persistentClass, cacheAccessStrategy, factory );
-
-		// CLASS + TABLE
-
-		joinSpan = persistentClass.getJoinClosureSpan()+1;
-		qualifiedTableNames = new String[joinSpan];
-		isInverseTable = new boolean[joinSpan];
-		isNullableTable = new boolean[joinSpan];
-		keyColumnNames = new String[joinSpan][];
-		final Table table = persistentClass.getRootTable();
-		qualifiedTableNames[0] = table.getQualifiedName( 
-				factory.getDialect(), 
-				factory.getSettings().getDefaultCatalogName(), 
-				factory.getSettings().getDefaultSchemaName() 
-		);
-		isInverseTable[0] = false;
-		isNullableTable[0] = false;
-		keyColumnNames[0] = getIdentifierColumnNames();
-		cascadeDeleteEnabled = new boolean[joinSpan];
-
-		// Custom sql
-		customSQLInsert = new String[joinSpan];
-		customSQLUpdate = new String[joinSpan];
-		customSQLDelete = new String[joinSpan];
-		insertCallable = new boolean[joinSpan];
-		updateCallable = new boolean[joinSpan];
-		deleteCallable = new boolean[joinSpan];
-		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
-		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
-		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
-
-		customSQLInsert[0] = persistentClass.getCustomSQLInsert();
-		insertCallable[0] = customSQLInsert[0] != null && persistentClass.isCustomInsertCallable();
-		insertResultCheckStyles[0] = persistentClass.getCustomSQLInsertCheckStyle() == null
-									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[0], insertCallable[0] )
-									  : persistentClass.getCustomSQLInsertCheckStyle();
-		customSQLUpdate[0] = persistentClass.getCustomSQLUpdate();
-		updateCallable[0] = customSQLUpdate[0] != null && persistentClass.isCustomUpdateCallable();
-		updateResultCheckStyles[0] = persistentClass.getCustomSQLUpdateCheckStyle() == null
-									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[0], updateCallable[0] )
-									  : persistentClass.getCustomSQLUpdateCheckStyle();
-		customSQLDelete[0] = persistentClass.getCustomSQLDelete();
-		deleteCallable[0] = customSQLDelete[0] != null && persistentClass.isCustomDeleteCallable();
-		deleteResultCheckStyles[0] = persistentClass.getCustomSQLDeleteCheckStyle() == null
-									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[0], deleteCallable[0] )
-									  : persistentClass.getCustomSQLDeleteCheckStyle();
-
-		// JOINS
-
-		Iterator joinIter = persistentClass.getJoinClosureIterator();
-		int j = 1;
-		while ( joinIter.hasNext() ) {
-			Join join = (Join) joinIter.next();
-			qualifiedTableNames[j] = join.getTable().getQualifiedName( 
-					factory.getDialect(), 
-					factory.getSettings().getDefaultCatalogName(), 
-					factory.getSettings().getDefaultSchemaName() 
-			);
-			isInverseTable[j] = join.isInverse();
-			isNullableTable[j] = join.isOptional();
-			cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() && 
-				factory.getDialect().supportsCascadeDelete();
-
-			customSQLInsert[j] = join.getCustomSQLInsert();
-			insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
-			insertResultCheckStyles[j] = join.getCustomSQLInsertCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
-		                                  : join.getCustomSQLInsertCheckStyle();
-			customSQLUpdate[j] = join.getCustomSQLUpdate();
-			updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
-			updateResultCheckStyles[j] = join.getCustomSQLUpdateCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
-		                                  : join.getCustomSQLUpdateCheckStyle();
-			customSQLDelete[j] = join.getCustomSQLDelete();
-			deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
-			deleteResultCheckStyles[j] = join.getCustomSQLDeleteCheckStyle() == null
-			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
-		                                  : join.getCustomSQLDeleteCheckStyle();
-
-			Iterator iter = join.getKey().getColumnIterator();
-			keyColumnNames[j] = new String[ join.getKey().getColumnSpan() ];
-			int i = 0;
-			while ( iter.hasNext() ) {
-				Column col = (Column) iter.next();
-				keyColumnNames[j][i++] = col.getQuotedName( factory.getDialect() );
-			}
-
-			j++;
-		}
-
-		constraintOrderedTableNames = new String[qualifiedTableNames.length];
-		constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][];
-		for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) {
-			constraintOrderedTableNames[position] = qualifiedTableNames[i];
-			constraintOrderedKeyColumnNames[position] = keyColumnNames[i];
-		}
-
-		spaces = ArrayHelper.join(
-				qualifiedTableNames, 
-				ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
-		);
-		
-		final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
-
-		boolean hasDeferred = false;
-		ArrayList subclassTables = new ArrayList();
-		ArrayList joinKeyColumns = new ArrayList();
-		ArrayList isConcretes = new ArrayList();
-		ArrayList isDeferreds = new ArrayList();
-		ArrayList isInverses = new ArrayList();
-		ArrayList isNullables = new ArrayList();
-		ArrayList isLazies = new ArrayList();
-		subclassTables.add( qualifiedTableNames[0] );
-		joinKeyColumns.add( getIdentifierColumnNames() );
-		isConcretes.add(Boolean.TRUE);
-		isDeferreds.add(Boolean.FALSE);
-		isInverses.add(Boolean.FALSE);
-		isNullables.add(Boolean.FALSE);
-		isLazies.add(Boolean.FALSE);
-		joinIter = persistentClass.getSubclassJoinClosureIterator();
-		while ( joinIter.hasNext() ) {
-			Join join = (Join) joinIter.next();
-			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassJoin(join) ) );
-			isDeferreds.add( new Boolean( join.isSequentialSelect() ) );
-			isInverses.add( new Boolean( join.isInverse() ) );
-			isNullables.add( new Boolean( join.isOptional() ) );
-			isLazies.add( new Boolean( lazyAvailable && join.isLazy() ) );
-			if ( join.isSequentialSelect() && !persistentClass.isClassOrSuperclassJoin(join) ) hasDeferred = true;
-			subclassTables.add( join.getTable().getQualifiedName( 
-					factory.getDialect(), 
-					factory.getSettings().getDefaultCatalogName(), 
-					factory.getSettings().getDefaultSchemaName() 
-			) );
-			Iterator iter = join.getKey().getColumnIterator();
-			String[] keyCols = new String[ join.getKey().getColumnSpan() ];
-			int i = 0;
-			while ( iter.hasNext() ) {
-				Column col = (Column) iter.next();
-				keyCols[i++] = col.getQuotedName( factory.getDialect() );
-			}
-			joinKeyColumns.add(keyCols);
-		}
-		
-		subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds);
-		subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables);
-		subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies);
-		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(joinKeyColumns);
-		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
-		isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses);
-		isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables);
-		hasSequentialSelects = hasDeferred;
-
-		// DISCRIMINATOR
-
-		final Object discriminatorValue;
-		if ( persistentClass.isPolymorphic() ) {
-			Value discrimValue = persistentClass.getDiscriminator();
-			if (discrimValue==null) {
-				throw new MappingException("discriminator mapping required for single table polymorphic persistence");
-			}
-			forceDiscriminator = persistentClass.isForceDiscriminator();
-			Selectable selectable = (Selectable) discrimValue.getColumnIterator().next();
-			if ( discrimValue.hasFormula() ) {
-				Formula formula = (Formula) selectable;
-				discriminatorFormula = formula.getFormula();
-				discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
-				discriminatorColumnName = null;
-				discriminatorAlias = "clazz_";
-			}
-			else {
-				Column column = (Column) selectable;
-				discriminatorColumnName = column.getQuotedName( factory.getDialect() );
-				discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() );
-				discriminatorFormula = null;
-				discriminatorFormulaTemplate = null;
-			}
-			discriminatorType = persistentClass.getDiscriminator().getType();
-			if ( persistentClass.isDiscriminatorValueNull() ) {
-				discriminatorValue = NULL_DISCRIMINATOR;
-				discriminatorSQLValue = InFragment.NULL;
-				discriminatorInsertable = false;
-			}
-			else if ( persistentClass.isDiscriminatorValueNotNull() ) {
-				discriminatorValue = NOT_NULL_DISCRIMINATOR;
-				discriminatorSQLValue = InFragment.NOT_NULL;
-				discriminatorInsertable = false;
-			}
-			else {
-				discriminatorInsertable = persistentClass.isDiscriminatorInsertable() && !discrimValue.hasFormula();
-				try {
-					DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
-					discriminatorValue = dtype.stringToObject( persistentClass.getDiscriminatorValue() );
-					discriminatorSQLValue = dtype.objectToSQLString( discriminatorValue, factory.getDialect() );
-				}
-				catch (ClassCastException cce) {
-					throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
-				}
-				catch (Exception e) {
-					throw new MappingException("Could not format discriminator value to SQL string", e);
-				}
-			}
-		}
-		else {
-			forceDiscriminator = false;
-			discriminatorInsertable = false;
-			discriminatorColumnName = null;
-			discriminatorAlias = null;
-			discriminatorType = null;
-			discriminatorValue = null;
-			discriminatorSQLValue = null;
-			discriminatorFormula = null;
-			discriminatorFormulaTemplate = null;
-		}
-
-		// PROPERTIES
-
-		propertyTableNumbers = new int[ getPropertySpan() ];
-		Iterator iter = persistentClass.getPropertyClosureIterator();
-		int i=0;
-		while( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			propertyTableNumbers[i++] = persistentClass.getJoinNumber(prop);
-
-		}
-
-		//TODO: code duplication with JoinedSubclassEntityPersister
-		
-		ArrayList columnJoinNumbers = new ArrayList();
-		ArrayList formulaJoinedNumbers = new ArrayList();
-		ArrayList propertyJoinNumbers = new ArrayList();
-		
-		iter = persistentClass.getSubclassPropertyClosureIterator();
-		while ( iter.hasNext() ) {
-			Property prop = (Property) iter.next();
-			Integer join = new Integer( persistentClass.getJoinNumber(prop) );
-			propertyJoinNumbers.add(join);
-
-			//propertyTableNumbersByName.put( prop.getName(), join );
-			propertyTableNumbersByNameAndSubclass.put( 
-					prop.getPersistentClass().getEntityName() + '.' + prop.getName(), 
-					join 
-			);
-
-			Iterator citer = prop.getColumnIterator();
-			while ( citer.hasNext() ) {
-				Selectable thing = (Selectable) citer.next();
-				if ( thing.isFormula() ) {
-					formulaJoinedNumbers.add(join);
-				}
-				else {
-					columnJoinNumbers.add(join);
-				}
-			}
-		}
-		subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers);
-		subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
-		subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
-
-		int subclassSpan = persistentClass.getSubclassSpan() + 1;
-		subclassClosure = new String[subclassSpan];
-		subclassClosure[0] = getEntityName();
-		if ( persistentClass.isPolymorphic() ) {
-			subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
-		}
-
-		// SUBCLASSES
-		if ( persistentClass.isPolymorphic() ) {
-			iter = persistentClass.getSubclassIterator();
-			int k=1;
-			while ( iter.hasNext() ) {
-				Subclass sc = (Subclass) iter.next();
-				subclassClosure[k++] = sc.getEntityName();
-				if ( sc.isDiscriminatorValueNull() ) {
-					subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
-				}
-				else if ( sc.isDiscriminatorValueNotNull() ) {
-					subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
-				}
-				else {
-					try {
-						DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
-						subclassesByDiscriminatorValue.put(
-							dtype.stringToObject( sc.getDiscriminatorValue() ),
-							sc.getEntityName()
-						);
-					}
-					catch (ClassCastException cce) {
-						throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
-					}
-					catch (Exception e) {
-						throw new MappingException("Error parsing discriminator value", e);
-					}
-				}
-			}
-		}
-
-		initLockers();
-
-		initSubclassPropertyAliasesMap(persistentClass);
-		
-		postConstruct(mapping);
-
-	}
-
-	protected boolean isInverseTable(int j) {
-		return isInverseTable[j];
-	}
-
-	protected boolean isInverseSubclassTable(int j) {
-		return isInverseSubclassTable[j];
-	}
-
-	public String getDiscriminatorColumnName() {
-		return discriminatorColumnName;
-	}
-
-	protected String getDiscriminatorAlias() {
-		return discriminatorAlias;
-	}
-
-	protected String getDiscriminatorFormulaTemplate() {
-		return discriminatorFormulaTemplate;
-	}
-
-	public String getTableName() {
-		return qualifiedTableNames[0];
-	}
-
-	public Type getDiscriminatorType() {
-		return discriminatorType;
-	}
-
-	public String getDiscriminatorSQLValue() {
-		return discriminatorSQLValue;
-	}
-
-	public String[] getSubclassClosure() {
-		return subclassClosure;
-	}
-
-	public String getSubclassForDiscriminatorValue(Object value) {
-		if (value==null) {
-			return (String) subclassesByDiscriminatorValue.get(NULL_DISCRIMINATOR);
-		}
-		else {
-			String result = (String) subclassesByDiscriminatorValue.get(value);
-			if (result==null) result = (String) subclassesByDiscriminatorValue.get(NOT_NULL_DISCRIMINATOR);
-			return result;
-		}
-	}
-
-	public Serializable[] getPropertySpaces() {
-		return spaces;
-	}
-
-	//Access cached SQL
-
-	protected boolean isDiscriminatorFormula() {
-		return discriminatorColumnName==null;
-	}
-
-	protected String getDiscriminatorFormula() {
-		return discriminatorFormula;
-	}
-
-	protected String getTableName(int j) {
-		return qualifiedTableNames[j];
-	}
-	
-	protected String[] getKeyColumns(int j) {
-		return keyColumnNames[j];
-	}
-	
-	protected boolean isTableCascadeDeleteEnabled(int j) {
-		return cascadeDeleteEnabled[j];
-	}
-	
-	protected boolean isPropertyOfTable(int property, int j) {
-		return propertyTableNumbers[property]==j;
-	}
-
-	protected boolean isSubclassTableSequentialSelect(int j) {
-		return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j];
-	}
-	
-	// Execute the SQL:
-
-	public String fromTableFragment(String name) {
-		return getTableName() + ' ' + name;
-	}
-
-	public String filterFragment(String alias) throws MappingException {
-		String result = discriminatorFilterFragment(alias);
-		if ( hasWhere() ) result += " and " + getSQLWhereString(alias);
-		return result;
-	}
-	
-	public String oneToManyFilterFragment(String alias) throws MappingException {
-		return forceDiscriminator ?
-			discriminatorFilterFragment(alias) :
-			"";
-	}
-
-	private String discriminatorFilterFragment(String alias) throws MappingException {
-		if ( needsDiscriminator() ) {
-			InFragment frag = new InFragment();
-
-			if ( isDiscriminatorFormula() ) {
-				frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
-			}
-			else {
-				frag.setColumn( alias, getDiscriminatorColumnName() );
-			}
-
-			String[] subclasses = getSubclassClosure();
-			for ( int i=0; i<subclasses.length; i++ ) {
-				final Queryable queryable = (Queryable) getFactory().getEntityPersister( subclasses[i] );
-				if ( !queryable.isAbstract() ) frag.addValue( queryable.getDiscriminatorSQLValue() );
-			}
-
-			StringBuffer buf = new StringBuffer(50)
-				.append(" and ")
-				.append( frag.toFragmentString() );
-
-			return buf.toString();
-		}
-		else {
-			return "";
-		}
-	}
-
-	private boolean needsDiscriminator() {
-		return forceDiscriminator || isInherited();
-	}
-
-	public String getSubclassPropertyTableName(int i) {
-		return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ];
-	}
-
-	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
-		if ( isDiscriminatorFormula() ) {
-			select.addFormula( name, getDiscriminatorFormulaTemplate(), getDiscriminatorAlias() );
-		}
-		else {
-			select.addColumn( name, getDiscriminatorColumnName(),  getDiscriminatorAlias() );
-		}
-	}
-	
-	protected int[] getPropertyTableNumbersInSelect() {
-		return propertyTableNumbers;
-	}
-
-	protected int getSubclassPropertyTableNumber(int i) {
-		return subclassPropertyTableNumberClosure[i];
-	}
-
-	public int getTableSpan() {
-		return joinSpan;
-	}
-
-	protected void addDiscriminatorToInsert(Insert insert) {
-
-		if (discriminatorInsertable) {
-			insert.addColumn( getDiscriminatorColumnName(), discriminatorSQLValue );
-		}
-
-	}
-
-	protected int[] getSubclassColumnTableNumberClosure() {
-		return subclassColumnTableNumberClosure;
-	}
-
-	protected int[] getSubclassFormulaTableNumberClosure() {
-		return subclassFormulaTableNumberClosure;
-	}
-
-	protected int[] getPropertyTableNumbers() {
-		return propertyTableNumbers;
-	}
-		
-	protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) {
-		return hasSequentialSelects && 
-			isSubclassTableSequentialSelect( getSubclassPropertyTableNumber(propertyName, entityName) );
-	}
-	
-	public boolean hasSequentialSelect() {
-		return hasSequentialSelects;
-	}
-	
-	private int getSubclassPropertyTableNumber(String propertyName, String entityName) {
-		Type type = propertyMapping.toType(propertyName);
-		if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) return 0;
-		final Integer tabnum = (Integer) propertyTableNumbersByNameAndSubclass.get(entityName + '.' + propertyName);
-		return tabnum==null ? 0 : tabnum.intValue();
-	}
-	
-	protected String getSequentialSelect(String entityName) {
-		return (String) sequentialSelectStringsByEntityName.get(entityName);
-	}
-
-	private String generateSequentialSelect(Loadable persister) {
-		//if ( this==persister || !hasSequentialSelects ) return null;
-
-		//note that this method could easily be moved up to BasicEntityPersister,
-		//if we ever needed to reuse it from other subclasses
-		
-		//figure out which tables need to be fetched
-		AbstractEntityPersister subclassPersister = (AbstractEntityPersister) persister;
-		HashSet tableNumbers = new HashSet();
-		String[] props = subclassPersister.getPropertyNames();
-		String[] classes = subclassPersister.getPropertySubclassNames();
-		for ( int i=0; i<props.length; i++ ) {
-			int propTableNumber = getSubclassPropertyTableNumber( props[i], classes[i] );
-			if ( isSubclassTableSequentialSelect(propTableNumber) && !isSubclassTableLazy(propTableNumber) ) {
-				tableNumbers.add( new Integer(propTableNumber) );
-			}
-		}
-		if ( tableNumbers.isEmpty() ) return null;
-		
-		//figure out which columns are needed
-		ArrayList columnNumbers = new ArrayList();
-		final int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
-		for ( int i=0; i<getSubclassColumnClosure().length; i++ ) {
-			if ( tableNumbers.contains( new Integer( columnTableNumbers[i] ) ) ) {
-				columnNumbers.add( new Integer(i) );
-			}
-		}
-		
-		//figure out which formulas are needed
-		ArrayList formulaNumbers = new ArrayList();
-		final int[] formulaTableNumbers = getSubclassColumnTableNumberClosure();
-		for ( int i=0; i<getSubclassFormulaTemplateClosure().length; i++ ) {
-			if ( tableNumbers.contains( new Integer( formulaTableNumbers[i] ) ) ) {
-				formulaNumbers.add( new Integer(i) );
-			}
-		}
-		
-		//render the SQL
-		return renderSelect( 
-			ArrayHelper.toIntArray(tableNumbers),
-			ArrayHelper.toIntArray(columnNumbers),
-			ArrayHelper.toIntArray(formulaNumbers)
-		);
-	}
-		
-		
-	protected String[] getSubclassTableKeyColumns(int j) {
-		return subclassTableKeyColumnClosure[j];
-	}
-
-	public String getSubclassTableName(int j) {
-		return subclassTableNameClosure[j];
-	}
-
-	public int getSubclassTableSpan() {
-		return subclassTableNameClosure.length;
-	}
-
-	protected boolean isClassOrSuperclassTable(int j) {
-		return isClassOrSuperclassTable[j];
-	}
-
-	protected boolean isSubclassTableLazy(int j) {
-		return subclassTableIsLazyClosure[j];
-	}
-	
-	protected boolean isNullableTable(int j) {
-		return isNullableTable[j];
-	}
-	
-	protected boolean isNullableSubclassTable(int j) {
-		return isNullableSubclassTable[j];
-	}
-
-	public String getPropertyTableName(String propertyName) {
-		Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName);
-		if (index==null) return null;
-		return qualifiedTableNames[ propertyTableNumbers[ index.intValue() ] ];
-	}
-	
-	public void postInstantiate() {
-		super.postInstantiate();
-		if (hasSequentialSelects) {
-			String[] entityNames = getSubclassClosure();
-			for ( int i=1; i<entityNames.length; i++ ) {
-				Loadable loadable = (Loadable) getFactory().getEntityPersister( entityNames[i] );
-				if ( !loadable.isAbstract() ) { //perhaps not really necessary...
-					String sequentialSelect = generateSequentialSelect(loadable);
-					sequentialSelectStringsByEntityName.put( entityNames[i], sequentialSelect );
-				}
-			}
-		}
-	}
-
-	public boolean isMultiTable() {
-		return getTableSpan() > 1;
-	}
-
-	public String[] getConstraintOrderedTableNameClosure() {
-		return constraintOrderedTableNames;
-	}
-
-	public String[][] getContraintOrderedTableKeyColumnClosure() {
-		return constraintOrderedKeyColumnNames;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/SingleTableEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,736 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.Formula;
+import org.hibernate.mapping.Join;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Selectable;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.Table;
+import org.hibernate.mapping.Value;
+import org.hibernate.sql.InFragment;
+import org.hibernate.sql.Insert;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.DiscriminatorType;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.MarkerObject;
+
+/**
+ * The default implementation of the <tt>EntityPersister</tt> interface.
+ * Implements the "table-per-class-hierarchy" or "roll-up" mapping strategy
+ * for an entity class and its inheritence hierarchy.  This is implemented
+ * as a single table holding all classes in the hierarchy with a discrimator
+ * column used to determine which concrete class is referenced.
+ *
+ * @author Gavin King
+ */
+public class SingleTableEntityPersister extends AbstractEntityPersister {
+
+	// the class hierarchy structure
+	private final int joinSpan;
+	private final String[] qualifiedTableNames;
+	private final boolean[] isInverseTable;
+	private final boolean[] isNullableTable;
+	private final String[][] keyColumnNames;
+	private final boolean[] cascadeDeleteEnabled;
+	private final boolean hasSequentialSelects;
+	
+	private final String[] spaces;
+
+	private final String[] subclassClosure;
+
+	private final String[] subclassTableNameClosure;
+	private final boolean[] subclassTableIsLazyClosure;
+	private final boolean[] isInverseSubclassTable;
+	private final boolean[] isNullableSubclassTable;
+	private final boolean[] subclassTableSequentialSelect;
+	private final String[][] subclassTableKeyColumnClosure;
+	private final boolean[] isClassOrSuperclassTable;
+
+	// properties of this class, including inherited properties
+	private final int[] propertyTableNumbers;
+
+	// the closure of all columns used by the entire hierarchy including
+	// subclasses and superclasses of this class
+	private final int[] subclassPropertyTableNumberClosure;
+
+	private final int[] subclassColumnTableNumberClosure;
+	private final int[] subclassFormulaTableNumberClosure;
+
+	// discriminator column
+	private final Map subclassesByDiscriminatorValue = new HashMap();
+	private final boolean forceDiscriminator;
+	private final String discriminatorColumnName;
+	private final String discriminatorFormula;
+	private final String discriminatorFormulaTemplate;
+	private final String discriminatorAlias;
+	private final Type discriminatorType;
+	private final String discriminatorSQLValue;
+	private final boolean discriminatorInsertable;
+
+	private final String[] constraintOrderedTableNames;
+	private final String[][] constraintOrderedKeyColumnNames;
+
+	//private final Map propertyTableNumbersByName = new HashMap();
+	private final Map propertyTableNumbersByNameAndSubclass = new HashMap();
+	
+	private final Map sequentialSelectStringsByEntityName = new HashMap();
+
+	private static final Object NULL_DISCRIMINATOR = new MarkerObject("<null discriminator>");
+	private static final Object NOT_NULL_DISCRIMINATOR = new MarkerObject("<not null discriminator>");
+
+	//INITIALIZATION:
+
+	public SingleTableEntityPersister(
+			final PersistentClass persistentClass, 
+			final EntityRegionAccessStrategy cacheAccessStrategy,
+			final SessionFactoryImplementor factory,
+			final Mapping mapping) throws HibernateException {
+
+		super( persistentClass, cacheAccessStrategy, factory );
+
+		// CLASS + TABLE
+
+		joinSpan = persistentClass.getJoinClosureSpan()+1;
+		qualifiedTableNames = new String[joinSpan];
+		isInverseTable = new boolean[joinSpan];
+		isNullableTable = new boolean[joinSpan];
+		keyColumnNames = new String[joinSpan][];
+		final Table table = persistentClass.getRootTable();
+		qualifiedTableNames[0] = table.getQualifiedName( 
+				factory.getDialect(), 
+				factory.getSettings().getDefaultCatalogName(), 
+				factory.getSettings().getDefaultSchemaName() 
+		);
+		isInverseTable[0] = false;
+		isNullableTable[0] = false;
+		keyColumnNames[0] = getIdentifierColumnNames();
+		cascadeDeleteEnabled = new boolean[joinSpan];
+
+		// Custom sql
+		customSQLInsert = new String[joinSpan];
+		customSQLUpdate = new String[joinSpan];
+		customSQLDelete = new String[joinSpan];
+		insertCallable = new boolean[joinSpan];
+		updateCallable = new boolean[joinSpan];
+		deleteCallable = new boolean[joinSpan];
+		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
+		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
+		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[joinSpan];
+
+		customSQLInsert[0] = persistentClass.getCustomSQLInsert();
+		insertCallable[0] = customSQLInsert[0] != null && persistentClass.isCustomInsertCallable();
+		insertResultCheckStyles[0] = persistentClass.getCustomSQLInsertCheckStyle() == null
+									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[0], insertCallable[0] )
+									  : persistentClass.getCustomSQLInsertCheckStyle();
+		customSQLUpdate[0] = persistentClass.getCustomSQLUpdate();
+		updateCallable[0] = customSQLUpdate[0] != null && persistentClass.isCustomUpdateCallable();
+		updateResultCheckStyles[0] = persistentClass.getCustomSQLUpdateCheckStyle() == null
+									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[0], updateCallable[0] )
+									  : persistentClass.getCustomSQLUpdateCheckStyle();
+		customSQLDelete[0] = persistentClass.getCustomSQLDelete();
+		deleteCallable[0] = customSQLDelete[0] != null && persistentClass.isCustomDeleteCallable();
+		deleteResultCheckStyles[0] = persistentClass.getCustomSQLDeleteCheckStyle() == null
+									  ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[0], deleteCallable[0] )
+									  : persistentClass.getCustomSQLDeleteCheckStyle();
+
+		// JOINS
+
+		Iterator joinIter = persistentClass.getJoinClosureIterator();
+		int j = 1;
+		while ( joinIter.hasNext() ) {
+			Join join = (Join) joinIter.next();
+			qualifiedTableNames[j] = join.getTable().getQualifiedName( 
+					factory.getDialect(), 
+					factory.getSettings().getDefaultCatalogName(), 
+					factory.getSettings().getDefaultSchemaName() 
+			);
+			isInverseTable[j] = join.isInverse();
+			isNullableTable[j] = join.isOptional();
+			cascadeDeleteEnabled[j] = join.getKey().isCascadeDeleteEnabled() && 
+				factory.getDialect().supportsCascadeDelete();
+
+			customSQLInsert[j] = join.getCustomSQLInsert();
+			insertCallable[j] = customSQLInsert[j] != null && join.isCustomInsertCallable();
+			insertResultCheckStyles[j] = join.getCustomSQLInsertCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLInsert[j], insertCallable[j] )
+		                                  : join.getCustomSQLInsertCheckStyle();
+			customSQLUpdate[j] = join.getCustomSQLUpdate();
+			updateCallable[j] = customSQLUpdate[j] != null && join.isCustomUpdateCallable();
+			updateResultCheckStyles[j] = join.getCustomSQLUpdateCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLUpdate[j], updateCallable[j] )
+		                                  : join.getCustomSQLUpdateCheckStyle();
+			customSQLDelete[j] = join.getCustomSQLDelete();
+			deleteCallable[j] = customSQLDelete[j] != null && join.isCustomDeleteCallable();
+			deleteResultCheckStyles[j] = join.getCustomSQLDeleteCheckStyle() == null
+			                              ? ExecuteUpdateResultCheckStyle.determineDefault( customSQLDelete[j], deleteCallable[j] )
+		                                  : join.getCustomSQLDeleteCheckStyle();
+
+			Iterator iter = join.getKey().getColumnIterator();
+			keyColumnNames[j] = new String[ join.getKey().getColumnSpan() ];
+			int i = 0;
+			while ( iter.hasNext() ) {
+				Column col = (Column) iter.next();
+				keyColumnNames[j][i++] = col.getQuotedName( factory.getDialect() );
+			}
+
+			j++;
+		}
+
+		constraintOrderedTableNames = new String[qualifiedTableNames.length];
+		constraintOrderedKeyColumnNames = new String[qualifiedTableNames.length][];
+		for ( int i = qualifiedTableNames.length - 1, position = 0; i >= 0; i--, position++ ) {
+			constraintOrderedTableNames[position] = qualifiedTableNames[i];
+			constraintOrderedKeyColumnNames[position] = keyColumnNames[i];
+		}
+
+		spaces = ArrayHelper.join(
+				qualifiedTableNames, 
+				ArrayHelper.toStringArray( persistentClass.getSynchronizedTables() )
+		);
+		
+		final boolean lazyAvailable = isInstrumented(EntityMode.POJO);
+
+		boolean hasDeferred = false;
+		ArrayList subclassTables = new ArrayList();
+		ArrayList joinKeyColumns = new ArrayList();
+		ArrayList isConcretes = new ArrayList();
+		ArrayList isDeferreds = new ArrayList();
+		ArrayList isInverses = new ArrayList();
+		ArrayList isNullables = new ArrayList();
+		ArrayList isLazies = new ArrayList();
+		subclassTables.add( qualifiedTableNames[0] );
+		joinKeyColumns.add( getIdentifierColumnNames() );
+		isConcretes.add(Boolean.TRUE);
+		isDeferreds.add(Boolean.FALSE);
+		isInverses.add(Boolean.FALSE);
+		isNullables.add(Boolean.FALSE);
+		isLazies.add(Boolean.FALSE);
+		joinIter = persistentClass.getSubclassJoinClosureIterator();
+		while ( joinIter.hasNext() ) {
+			Join join = (Join) joinIter.next();
+			isConcretes.add( new Boolean( persistentClass.isClassOrSuperclassJoin(join) ) );
+			isDeferreds.add( new Boolean( join.isSequentialSelect() ) );
+			isInverses.add( new Boolean( join.isInverse() ) );
+			isNullables.add( new Boolean( join.isOptional() ) );
+			isLazies.add( new Boolean( lazyAvailable && join.isLazy() ) );
+			if ( join.isSequentialSelect() && !persistentClass.isClassOrSuperclassJoin(join) ) hasDeferred = true;
+			subclassTables.add( join.getTable().getQualifiedName( 
+					factory.getDialect(), 
+					factory.getSettings().getDefaultCatalogName(), 
+					factory.getSettings().getDefaultSchemaName() 
+			) );
+			Iterator iter = join.getKey().getColumnIterator();
+			String[] keyCols = new String[ join.getKey().getColumnSpan() ];
+			int i = 0;
+			while ( iter.hasNext() ) {
+				Column col = (Column) iter.next();
+				keyCols[i++] = col.getQuotedName( factory.getDialect() );
+			}
+			joinKeyColumns.add(keyCols);
+		}
+		
+		subclassTableSequentialSelect = ArrayHelper.toBooleanArray(isDeferreds);
+		subclassTableNameClosure = ArrayHelper.toStringArray(subclassTables);
+		subclassTableIsLazyClosure = ArrayHelper.toBooleanArray(isLazies);
+		subclassTableKeyColumnClosure = ArrayHelper.to2DStringArray(joinKeyColumns);
+		isClassOrSuperclassTable = ArrayHelper.toBooleanArray(isConcretes);
+		isInverseSubclassTable = ArrayHelper.toBooleanArray(isInverses);
+		isNullableSubclassTable = ArrayHelper.toBooleanArray(isNullables);
+		hasSequentialSelects = hasDeferred;
+
+		// DISCRIMINATOR
+
+		final Object discriminatorValue;
+		if ( persistentClass.isPolymorphic() ) {
+			Value discrimValue = persistentClass.getDiscriminator();
+			if (discrimValue==null) {
+				throw new MappingException("discriminator mapping required for single table polymorphic persistence");
+			}
+			forceDiscriminator = persistentClass.isForceDiscriminator();
+			Selectable selectable = (Selectable) discrimValue.getColumnIterator().next();
+			if ( discrimValue.hasFormula() ) {
+				Formula formula = (Formula) selectable;
+				discriminatorFormula = formula.getFormula();
+				discriminatorFormulaTemplate = formula.getTemplate( factory.getDialect(), factory.getSqlFunctionRegistry() );
+				discriminatorColumnName = null;
+				discriminatorAlias = "clazz_";
+			}
+			else {
+				Column column = (Column) selectable;
+				discriminatorColumnName = column.getQuotedName( factory.getDialect() );
+				discriminatorAlias = column.getAlias( factory.getDialect(), persistentClass.getRootTable() );
+				discriminatorFormula = null;
+				discriminatorFormulaTemplate = null;
+			}
+			discriminatorType = persistentClass.getDiscriminator().getType();
+			if ( persistentClass.isDiscriminatorValueNull() ) {
+				discriminatorValue = NULL_DISCRIMINATOR;
+				discriminatorSQLValue = InFragment.NULL;
+				discriminatorInsertable = false;
+			}
+			else if ( persistentClass.isDiscriminatorValueNotNull() ) {
+				discriminatorValue = NOT_NULL_DISCRIMINATOR;
+				discriminatorSQLValue = InFragment.NOT_NULL;
+				discriminatorInsertable = false;
+			}
+			else {
+				discriminatorInsertable = persistentClass.isDiscriminatorInsertable() && !discrimValue.hasFormula();
+				try {
+					DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
+					discriminatorValue = dtype.stringToObject( persistentClass.getDiscriminatorValue() );
+					discriminatorSQLValue = dtype.objectToSQLString( discriminatorValue, factory.getDialect() );
+				}
+				catch (ClassCastException cce) {
+					throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
+				}
+				catch (Exception e) {
+					throw new MappingException("Could not format discriminator value to SQL string", e);
+				}
+			}
+		}
+		else {
+			forceDiscriminator = false;
+			discriminatorInsertable = false;
+			discriminatorColumnName = null;
+			discriminatorAlias = null;
+			discriminatorType = null;
+			discriminatorValue = null;
+			discriminatorSQLValue = null;
+			discriminatorFormula = null;
+			discriminatorFormulaTemplate = null;
+		}
+
+		// PROPERTIES
+
+		propertyTableNumbers = new int[ getPropertySpan() ];
+		Iterator iter = persistentClass.getPropertyClosureIterator();
+		int i=0;
+		while( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			propertyTableNumbers[i++] = persistentClass.getJoinNumber(prop);
+
+		}
+
+		//TODO: code duplication with JoinedSubclassEntityPersister
+		
+		ArrayList columnJoinNumbers = new ArrayList();
+		ArrayList formulaJoinedNumbers = new ArrayList();
+		ArrayList propertyJoinNumbers = new ArrayList();
+		
+		iter = persistentClass.getSubclassPropertyClosureIterator();
+		while ( iter.hasNext() ) {
+			Property prop = (Property) iter.next();
+			Integer join = new Integer( persistentClass.getJoinNumber(prop) );
+			propertyJoinNumbers.add(join);
+
+			//propertyTableNumbersByName.put( prop.getName(), join );
+			propertyTableNumbersByNameAndSubclass.put( 
+					prop.getPersistentClass().getEntityName() + '.' + prop.getName(), 
+					join 
+			);
+
+			Iterator citer = prop.getColumnIterator();
+			while ( citer.hasNext() ) {
+				Selectable thing = (Selectable) citer.next();
+				if ( thing.isFormula() ) {
+					formulaJoinedNumbers.add(join);
+				}
+				else {
+					columnJoinNumbers.add(join);
+				}
+			}
+		}
+		subclassColumnTableNumberClosure = ArrayHelper.toIntArray(columnJoinNumbers);
+		subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
+		subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
+
+		int subclassSpan = persistentClass.getSubclassSpan() + 1;
+		subclassClosure = new String[subclassSpan];
+		subclassClosure[0] = getEntityName();
+		if ( persistentClass.isPolymorphic() ) {
+			subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
+		}
+
+		// SUBCLASSES
+		if ( persistentClass.isPolymorphic() ) {
+			iter = persistentClass.getSubclassIterator();
+			int k=1;
+			while ( iter.hasNext() ) {
+				Subclass sc = (Subclass) iter.next();
+				subclassClosure[k++] = sc.getEntityName();
+				if ( sc.isDiscriminatorValueNull() ) {
+					subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, sc.getEntityName() );
+				}
+				else if ( sc.isDiscriminatorValueNotNull() ) {
+					subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, sc.getEntityName() );
+				}
+				else {
+					try {
+						DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
+						subclassesByDiscriminatorValue.put(
+							dtype.stringToObject( sc.getDiscriminatorValue() ),
+							sc.getEntityName()
+						);
+					}
+					catch (ClassCastException cce) {
+						throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
+					}
+					catch (Exception e) {
+						throw new MappingException("Error parsing discriminator value", e);
+					}
+				}
+			}
+		}
+
+		initLockers();
+
+		initSubclassPropertyAliasesMap(persistentClass);
+		
+		postConstruct(mapping);
+
+	}
+
+	protected boolean isInverseTable(int j) {
+		return isInverseTable[j];
+	}
+
+	protected boolean isInverseSubclassTable(int j) {
+		return isInverseSubclassTable[j];
+	}
+
+	public String getDiscriminatorColumnName() {
+		return discriminatorColumnName;
+	}
+
+	protected String getDiscriminatorAlias() {
+		return discriminatorAlias;
+	}
+
+	protected String getDiscriminatorFormulaTemplate() {
+		return discriminatorFormulaTemplate;
+	}
+
+	public String getTableName() {
+		return qualifiedTableNames[0];
+	}
+
+	public Type getDiscriminatorType() {
+		return discriminatorType;
+	}
+
+	public String getDiscriminatorSQLValue() {
+		return discriminatorSQLValue;
+	}
+
+	public String[] getSubclassClosure() {
+		return subclassClosure;
+	}
+
+	public String getSubclassForDiscriminatorValue(Object value) {
+		if (value==null) {
+			return (String) subclassesByDiscriminatorValue.get(NULL_DISCRIMINATOR);
+		}
+		else {
+			String result = (String) subclassesByDiscriminatorValue.get(value);
+			if (result==null) result = (String) subclassesByDiscriminatorValue.get(NOT_NULL_DISCRIMINATOR);
+			return result;
+		}
+	}
+
+	public Serializable[] getPropertySpaces() {
+		return spaces;
+	}
+
+	//Access cached SQL
+
+	protected boolean isDiscriminatorFormula() {
+		return discriminatorColumnName==null;
+	}
+
+	protected String getDiscriminatorFormula() {
+		return discriminatorFormula;
+	}
+
+	protected String getTableName(int j) {
+		return qualifiedTableNames[j];
+	}
+	
+	protected String[] getKeyColumns(int j) {
+		return keyColumnNames[j];
+	}
+	
+	protected boolean isTableCascadeDeleteEnabled(int j) {
+		return cascadeDeleteEnabled[j];
+	}
+	
+	protected boolean isPropertyOfTable(int property, int j) {
+		return propertyTableNumbers[property]==j;
+	}
+
+	protected boolean isSubclassTableSequentialSelect(int j) {
+		return subclassTableSequentialSelect[j] && !isClassOrSuperclassTable[j];
+	}
+	
+	// Execute the SQL:
+
+	public String fromTableFragment(String name) {
+		return getTableName() + ' ' + name;
+	}
+
+	public String filterFragment(String alias) throws MappingException {
+		String result = discriminatorFilterFragment(alias);
+		if ( hasWhere() ) result += " and " + getSQLWhereString(alias);
+		return result;
+	}
+	
+	public String oneToManyFilterFragment(String alias) throws MappingException {
+		return forceDiscriminator ?
+			discriminatorFilterFragment(alias) :
+			"";
+	}
+
+	private String discriminatorFilterFragment(String alias) throws MappingException {
+		if ( needsDiscriminator() ) {
+			InFragment frag = new InFragment();
+
+			if ( isDiscriminatorFormula() ) {
+				frag.setFormula( alias, getDiscriminatorFormulaTemplate() );
+			}
+			else {
+				frag.setColumn( alias, getDiscriminatorColumnName() );
+			}
+
+			String[] subclasses = getSubclassClosure();
+			for ( int i=0; i<subclasses.length; i++ ) {
+				final Queryable queryable = (Queryable) getFactory().getEntityPersister( subclasses[i] );
+				if ( !queryable.isAbstract() ) frag.addValue( queryable.getDiscriminatorSQLValue() );
+			}
+
+			StringBuffer buf = new StringBuffer(50)
+				.append(" and ")
+				.append( frag.toFragmentString() );
+
+			return buf.toString();
+		}
+		else {
+			return "";
+		}
+	}
+
+	private boolean needsDiscriminator() {
+		return forceDiscriminator || isInherited();
+	}
+
+	public String getSubclassPropertyTableName(int i) {
+		return subclassTableNameClosure[ subclassPropertyTableNumberClosure[i] ];
+	}
+
+	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
+		if ( isDiscriminatorFormula() ) {
+			select.addFormula( name, getDiscriminatorFormulaTemplate(), getDiscriminatorAlias() );
+		}
+		else {
+			select.addColumn( name, getDiscriminatorColumnName(),  getDiscriminatorAlias() );
+		}
+	}
+	
+	protected int[] getPropertyTableNumbersInSelect() {
+		return propertyTableNumbers;
+	}
+
+	protected int getSubclassPropertyTableNumber(int i) {
+		return subclassPropertyTableNumberClosure[i];
+	}
+
+	public int getTableSpan() {
+		return joinSpan;
+	}
+
+	protected void addDiscriminatorToInsert(Insert insert) {
+
+		if (discriminatorInsertable) {
+			insert.addColumn( getDiscriminatorColumnName(), discriminatorSQLValue );
+		}
+
+	}
+
+	protected int[] getSubclassColumnTableNumberClosure() {
+		return subclassColumnTableNumberClosure;
+	}
+
+	protected int[] getSubclassFormulaTableNumberClosure() {
+		return subclassFormulaTableNumberClosure;
+	}
+
+	protected int[] getPropertyTableNumbers() {
+		return propertyTableNumbers;
+	}
+		
+	protected boolean isSubclassPropertyDeferred(String propertyName, String entityName) {
+		return hasSequentialSelects && 
+			isSubclassTableSequentialSelect( getSubclassPropertyTableNumber(propertyName, entityName) );
+	}
+	
+	public boolean hasSequentialSelect() {
+		return hasSequentialSelects;
+	}
+	
+	private int getSubclassPropertyTableNumber(String propertyName, String entityName) {
+		Type type = propertyMapping.toType(propertyName);
+		if ( type.isAssociationType() && ( (AssociationType) type ).useLHSPrimaryKey() ) return 0;
+		final Integer tabnum = (Integer) propertyTableNumbersByNameAndSubclass.get(entityName + '.' + propertyName);
+		return tabnum==null ? 0 : tabnum.intValue();
+	}
+	
+	protected String getSequentialSelect(String entityName) {
+		return (String) sequentialSelectStringsByEntityName.get(entityName);
+	}
+
+	private String generateSequentialSelect(Loadable persister) {
+		//if ( this==persister || !hasSequentialSelects ) return null;
+
+		//note that this method could easily be moved up to BasicEntityPersister,
+		//if we ever needed to reuse it from other subclasses
+		
+		//figure out which tables need to be fetched
+		AbstractEntityPersister subclassPersister = (AbstractEntityPersister) persister;
+		HashSet tableNumbers = new HashSet();
+		String[] props = subclassPersister.getPropertyNames();
+		String[] classes = subclassPersister.getPropertySubclassNames();
+		for ( int i=0; i<props.length; i++ ) {
+			int propTableNumber = getSubclassPropertyTableNumber( props[i], classes[i] );
+			if ( isSubclassTableSequentialSelect(propTableNumber) && !isSubclassTableLazy(propTableNumber) ) {
+				tableNumbers.add( new Integer(propTableNumber) );
+			}
+		}
+		if ( tableNumbers.isEmpty() ) return null;
+		
+		//figure out which columns are needed
+		ArrayList columnNumbers = new ArrayList();
+		final int[] columnTableNumbers = getSubclassColumnTableNumberClosure();
+		for ( int i=0; i<getSubclassColumnClosure().length; i++ ) {
+			if ( tableNumbers.contains( new Integer( columnTableNumbers[i] ) ) ) {
+				columnNumbers.add( new Integer(i) );
+			}
+		}
+		
+		//figure out which formulas are needed
+		ArrayList formulaNumbers = new ArrayList();
+		final int[] formulaTableNumbers = getSubclassColumnTableNumberClosure();
+		for ( int i=0; i<getSubclassFormulaTemplateClosure().length; i++ ) {
+			if ( tableNumbers.contains( new Integer( formulaTableNumbers[i] ) ) ) {
+				formulaNumbers.add( new Integer(i) );
+			}
+		}
+		
+		//render the SQL
+		return renderSelect( 
+			ArrayHelper.toIntArray(tableNumbers),
+			ArrayHelper.toIntArray(columnNumbers),
+			ArrayHelper.toIntArray(formulaNumbers)
+		);
+	}
+		
+		
+	protected String[] getSubclassTableKeyColumns(int j) {
+		return subclassTableKeyColumnClosure[j];
+	}
+
+	public String getSubclassTableName(int j) {
+		return subclassTableNameClosure[j];
+	}
+
+	public int getSubclassTableSpan() {
+		return subclassTableNameClosure.length;
+	}
+
+	protected boolean isClassOrSuperclassTable(int j) {
+		return isClassOrSuperclassTable[j];
+	}
+
+	protected boolean isSubclassTableLazy(int j) {
+		return subclassTableIsLazyClosure[j];
+	}
+	
+	protected boolean isNullableTable(int j) {
+		return isNullableTable[j];
+	}
+	
+	protected boolean isNullableSubclassTable(int j) {
+		return isNullableSubclassTable[j];
+	}
+
+	public String getPropertyTableName(String propertyName) {
+		Integer index = getEntityMetamodel().getPropertyIndexOrNull(propertyName);
+		if (index==null) return null;
+		return qualifiedTableNames[ propertyTableNumbers[ index.intValue() ] ];
+	}
+	
+	public void postInstantiate() {
+		super.postInstantiate();
+		if (hasSequentialSelects) {
+			String[] entityNames = getSubclassClosure();
+			for ( int i=1; i<entityNames.length; i++ ) {
+				Loadable loadable = (Loadable) getFactory().getEntityPersister( entityNames[i] );
+				if ( !loadable.isAbstract() ) { //perhaps not really necessary...
+					String sequentialSelect = generateSequentialSelect(loadable);
+					sequentialSelectStringsByEntityName.put( entityNames[i], sequentialSelect );
+				}
+			}
+		}
+	}
+
+	public boolean isMultiTable() {
+		return getTableSpan() > 1;
+	}
+
+	public String[] getConstraintOrderedTableNameClosure() {
+		return constraintOrderedTableNames;
+	}
+
+	public String[][] getContraintOrderedTableKeyColumnClosure() {
+		return constraintOrderedKeyColumnNames;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,459 +0,0 @@
-//$Id: UnionSubclassEntityPersister.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.persister.entity;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.ArrayList;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.LockMode;
-import org.hibernate.MappingException;
-import org.hibernate.cache.access.EntityRegionAccessStrategy;
-import org.hibernate.cfg.Settings;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
-import org.hibernate.id.IdentityGenerator;
-import org.hibernate.mapping.Column;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Subclass;
-import org.hibernate.mapping.Table;
-import org.hibernate.sql.SelectFragment;
-import org.hibernate.sql.SimpleSelect;
-import org.hibernate.type.Type;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.JoinedIterator;
-import org.hibernate.util.SingletonIterator;
-
-/**
- * Implementation of the "table-per-concrete-class" or "roll-down" mapping 
- * strategy for an entity and its inheritence hierarchy.
- *
- * @author Gavin King
- */
-public class UnionSubclassEntityPersister extends AbstractEntityPersister {
-
-	// the class hierarchy structure
-	private final String subquery;
-	private final String tableName;
-	//private final String rootTableName;
-	private final String[] subclassClosure;
-	private final String[] spaces;
-	private final String[] subclassSpaces;
-	private final String discriminatorSQLValue;
-	private final Map subclassByDiscriminatorValue = new HashMap();
-
-	private final String[] constraintOrderedTableNames;
-	private final String[][] constraintOrderedKeyColumnNames;
-
-	//INITIALIZATION:
-
-	public UnionSubclassEntityPersister(
-			final PersistentClass persistentClass, 
-			final EntityRegionAccessStrategy cacheAccessStrategy,
-			final SessionFactoryImplementor factory,
-			final Mapping mapping) throws HibernateException {
-
-		super( persistentClass, cacheAccessStrategy, factory );
-		
-		if ( getIdentifierGenerator() instanceof IdentityGenerator ) {
-			throw new MappingException(
-					"Cannot use identity column key generation with <union-subclass> mapping for: " + 
-					getEntityName() 
-			);
-		}
-
-		// TABLE
-
-		tableName = persistentClass.getTable().getQualifiedName( 
-				factory.getDialect(), 
-				factory.getSettings().getDefaultCatalogName(), 
-				factory.getSettings().getDefaultSchemaName() 
-		);
-		/*rootTableName = persistentClass.getRootTable().getQualifiedName( 
-				factory.getDialect(), 
-				factory.getDefaultCatalog(), 
-				factory.getDefaultSchema() 
-		);*/
-
-		//Custom SQL
-
-		String sql;
-		boolean callable = false;
-		ExecuteUpdateResultCheckStyle checkStyle = null;
-		sql = persistentClass.getCustomSQLInsert();
-		callable = sql != null && persistentClass.isCustomInsertCallable();
-		checkStyle = sql == null
-				? ExecuteUpdateResultCheckStyle.COUNT
-	            : persistentClass.getCustomSQLInsertCheckStyle() == null
-						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
-	                    : persistentClass.getCustomSQLInsertCheckStyle();
-		customSQLInsert = new String[] { sql };
-		insertCallable = new boolean[] { callable };
-		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
-
-		sql = persistentClass.getCustomSQLUpdate();
-		callable = sql != null && persistentClass.isCustomUpdateCallable();
-		checkStyle = sql == null
-				? ExecuteUpdateResultCheckStyle.COUNT
-	            : persistentClass.getCustomSQLUpdateCheckStyle() == null
-						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
-	                    : persistentClass.getCustomSQLUpdateCheckStyle();
-		customSQLUpdate = new String[] { sql };
-		updateCallable = new boolean[] { callable };
-		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
-
-		sql = persistentClass.getCustomSQLDelete();
-		callable = sql != null && persistentClass.isCustomDeleteCallable();
-		checkStyle = sql == null
-				? ExecuteUpdateResultCheckStyle.COUNT
-	            : persistentClass.getCustomSQLDeleteCheckStyle() == null
-						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
-	                    : persistentClass.getCustomSQLDeleteCheckStyle();
-		customSQLDelete = new String[] { sql };
-		deleteCallable = new boolean[] { callable };
-		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
-
-		discriminatorSQLValue = String.valueOf( persistentClass.getSubclassId() );
-
-		// PROPERTIES
-
-		int subclassSpan = persistentClass.getSubclassSpan() + 1;
-		subclassClosure = new String[subclassSpan];
-		subclassClosure[0] = getEntityName();
-
-		// SUBCLASSES
-		subclassByDiscriminatorValue.put( 
-				new Integer( persistentClass.getSubclassId() ), 
-				persistentClass.getEntityName() 
-		);
-		if ( persistentClass.isPolymorphic() ) {
-			Iterator iter = persistentClass.getSubclassIterator();
-			int k=1;
-			while ( iter.hasNext() ) {
-				Subclass sc = (Subclass) iter.next();
-				subclassClosure[k++] = sc.getEntityName();
-				subclassByDiscriminatorValue.put( new Integer( sc.getSubclassId() ), sc.getEntityName() );
-			}
-		}
-		
-		//SPACES
-		//TODO: i'm not sure, but perhaps we should exclude
-		//      abstract denormalized tables?
-		
-		int spacesSize = 1 + persistentClass.getSynchronizedTables().size();
-		spaces = new String[spacesSize];
-		spaces[0] = tableName;
-		Iterator iter = persistentClass.getSynchronizedTables().iterator();
-		for ( int i=1; i<spacesSize; i++ ) {
-			spaces[i] = (String) iter.next();
-		}
-		
-		HashSet subclassTables = new HashSet();
-		iter = persistentClass.getSubclassTableClosureIterator();
-		while ( iter.hasNext() ) {
-			Table table = (Table) iter.next();
-			subclassTables.add( table.getQualifiedName(
-					factory.getDialect(), 
-					factory.getSettings().getDefaultCatalogName(), 
-					factory.getSettings().getDefaultSchemaName() 
-			) );
-		}
-		subclassSpaces = ArrayHelper.toStringArray(subclassTables);
-
-		subquery = generateSubquery(persistentClass, mapping);
-
-		if ( isMultiTable() ) {
-			int idColumnSpan = getIdentifierColumnSpan();
-			ArrayList tableNames = new ArrayList();
-			ArrayList keyColumns = new ArrayList();
-			if ( !isAbstract() ) {
-				tableNames.add( tableName );
-				keyColumns.add( getIdentifierColumnNames() );
-			}
-			iter = persistentClass.getSubclassTableClosureIterator();
-			while ( iter.hasNext() ) {
-				Table tab = ( Table ) iter.next();
-				if ( !tab.isAbstractUnionTable() ) {
-					String tableName = tab.getQualifiedName(
-							factory.getDialect(),
-							factory.getSettings().getDefaultCatalogName(),
-							factory.getSettings().getDefaultSchemaName()
-					);
-					tableNames.add( tableName );
-					String[] key = new String[idColumnSpan];
-					Iterator citer = tab.getPrimaryKey().getColumnIterator();
-					for ( int k=0; k<idColumnSpan; k++ ) {
-						key[k] = ( ( Column ) citer.next() ).getQuotedName( factory.getDialect() );
-					}
-					keyColumns.add( key );
-				}
-			}
-
-			constraintOrderedTableNames = ArrayHelper.toStringArray( tableNames );
-			constraintOrderedKeyColumnNames = ArrayHelper.to2DStringArray( keyColumns );
-		}
-		else {
-			constraintOrderedTableNames = new String[] { tableName };
-			constraintOrderedKeyColumnNames = new String[][] { getIdentifierColumnNames() };
-		}
-
-		initLockers();
-
-		initSubclassPropertyAliasesMap(persistentClass);
-		
-		postConstruct(mapping);
-
-	}
-
-	public Serializable[] getQuerySpaces() {
-		return subclassSpaces;
-	}
-	
-	public String getTableName() {
-		return subquery;
-	}
-
-	public Type getDiscriminatorType() {
-		return Hibernate.INTEGER;
-	}
-
-	public String getDiscriminatorSQLValue() {
-		return discriminatorSQLValue;
-	}
-
-	public String[] getSubclassClosure() {
-		return subclassClosure;
-	}
-
-	public String getSubclassForDiscriminatorValue(Object value) {
-		return (String) subclassByDiscriminatorValue.get(value);
-	}
-
-	public Serializable[] getPropertySpaces() {
-		return spaces;
-	}
-
-	protected boolean isDiscriminatorFormula() {
-		return false;
-	}
-
-	/**
-	 * Generate the SQL that selects a row by id
-	 */
-	protected String generateSelectString(LockMode lockMode) {
-		SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
-			.setLockMode(lockMode)
-			.setTableName( getTableName() )
-			.addColumns( getIdentifierColumnNames() )
-			.addColumns( 
-					getSubclassColumnClosure(), 
-					getSubclassColumnAliasClosure(),
-					getSubclassColumnLazyiness()
-			)
-			.addColumns( 
-					getSubclassFormulaClosure(), 
-					getSubclassFormulaAliasClosure(),
-					getSubclassFormulaLazyiness()
-			);
-		//TODO: include the rowids!!!!
-		if ( hasSubclasses() ) {
-			if ( isDiscriminatorFormula() ) {
-				select.addColumn( getDiscriminatorFormula(), getDiscriminatorAlias() );
-			}
-			else {
-				select.addColumn( getDiscriminatorColumnName(), getDiscriminatorAlias() );
-			}
-		}
-		if ( getFactory().getSettings().isCommentsEnabled() ) {
-			select.setComment( "load " + getEntityName() );
-		}
-		return select.addCondition( getIdentifierColumnNames(), "=?" ).toStatementString();
-	}
-
-	protected String getDiscriminatorFormula() {
-		return null;
-	}
-
-	protected String getTableName(int j) {
-		return tableName;
-	}
-
-	protected String[] getKeyColumns(int j) {
-		return getIdentifierColumnNames();
-	}
-	
-	protected boolean isTableCascadeDeleteEnabled(int j) {
-		return false;
-	}
-	
-	protected boolean isPropertyOfTable(int property, int j) {
-		return true;
-	}
-
-	// Execute the SQL:
-
-	public String fromTableFragment(String name) {
-		return getTableName() + ' '  + name;
-	}
-
-	public String filterFragment(String name) {
-		return hasWhere() ?
-			" and " + getSQLWhereString(name) :
-			"";
-	}
-
-	public String getSubclassPropertyTableName(int i) {
-		return getTableName();//ie. the subquery! yuck!
-	}
-
-	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
-		select.addColumn( name, getDiscriminatorColumnName(),  getDiscriminatorAlias() );
-	}
-	
-	protected int[] getPropertyTableNumbersInSelect() {
-		return new int[ getPropertySpan() ];
-	}
-
-	protected int getSubclassPropertyTableNumber(int i) {
-		return 0;
-	}
-
-	public int getSubclassPropertyTableNumber(String propertyName) {
-		return 0;
-	}
-
-	public boolean isMultiTable() {
-		// This could also just be true all the time...
-		return isAbstract() || hasSubclasses();
-	}
-
-	public int getTableSpan() {
-		return 1;
-	}
-
-	protected int[] getSubclassColumnTableNumberClosure() {
-		return new int[ getSubclassColumnClosure().length ];
-	}
-
-	protected int[] getSubclassFormulaTableNumberClosure() {
-		return new int[ getSubclassFormulaClosure().length ];
-	}
-
-	protected boolean[] getTableHasColumns() {
-		return new boolean[] { true };
-	}
-
-	protected int[] getPropertyTableNumbers() {
-		return new int[ getPropertySpan() ];
-	}
-
-	protected String generateSubquery(PersistentClass model, Mapping mapping) {
-
-		Dialect dialect = getFactory().getDialect();
-		Settings settings = getFactory().getSettings();
-		
-		if ( !model.hasSubclasses() ) {
-			return model.getTable().getQualifiedName(
-					dialect,
-					settings.getDefaultCatalogName(),
-					settings.getDefaultSchemaName()
-				);
-		}
-
-		HashSet columns = new HashSet();
-		Iterator titer = model.getSubclassTableClosureIterator();
-		while ( titer.hasNext() ) {
-			Table table = (Table) titer.next();
-			if ( !table.isAbstractUnionTable() ) {
-				Iterator citer = table.getColumnIterator();
-				while ( citer.hasNext() ) columns.add( citer.next() );
-			}
-		}
-
-		StringBuffer buf = new StringBuffer()
-			.append("( ");
-
-		Iterator siter = new JoinedIterator(
-			new SingletonIterator(model),
-			model.getSubclassIterator()
-		);
-
-		while ( siter.hasNext() ) {
-			PersistentClass clazz = (PersistentClass) siter.next();
-			Table table = clazz.getTable();
-			if ( !table.isAbstractUnionTable() ) {
-				//TODO: move to .sql package!!
-				buf.append("select ");
-				Iterator citer = columns.iterator();
-				while ( citer.hasNext() ) {
-					Column col = (Column) citer.next();
-					if ( !table.containsColumn(col) ) {
-						int sqlType = col.getSqlTypeCode(mapping);
-						buf.append( dialect.getSelectClauseNullString(sqlType) )
-							.append(" as ");
-					}
-					buf.append( col.getName() );
-					buf.append(", ");
-				}
-				buf.append( clazz.getSubclassId() )
-					.append(" as clazz_");
-				buf.append(" from ")
-					.append( table.getQualifiedName(
-							dialect,
-							settings.getDefaultCatalogName(),
-							settings.getDefaultSchemaName()
-					) );
-				buf.append(" union ");
-				if ( dialect.supportsUnionAll() ) {
-					buf.append("all ");
-				}
-			}
-		}
-		
-		if ( buf.length() > 2 ) {
-			//chop the last union (all)
-			buf.setLength( buf.length() - ( dialect.supportsUnionAll() ? 11 : 7 ) );
-		}
-
-		return buf.append(" )").toString();
-	}
-
-	protected String[] getSubclassTableKeyColumns(int j) {
-		if (j!=0) throw new AssertionFailure("only one table");
-		return getIdentifierColumnNames();
-	}
-
-	public String getSubclassTableName(int j) {
-		if (j!=0) throw new AssertionFailure("only one table");
-		return tableName;
-	}
-
-	public int getSubclassTableSpan() {
-		return 1;
-	}
-
-	protected boolean isClassOrSuperclassTable(int j) {
-		if (j!=0) throw new AssertionFailure("only one table");
-		return true;
-	}
-
-	public String getPropertyTableName(String propertyName) {
-		//TODO: check this....
-		return getTableName();
-	}
-
-	public String[] getConstraintOrderedTableNameClosure() {
-			return constraintOrderedTableNames;
-	}
-
-	public String[][] getContraintOrderedTableKeyColumnClosure() {
-		return constraintOrderedKeyColumnNames;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UnionSubclassEntityPersister.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,482 @@
+/*
+ * 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.persister.entity;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ArrayList;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.LockMode;
+import org.hibernate.MappingException;
+import org.hibernate.cache.access.EntityRegionAccessStrategy;
+import org.hibernate.cfg.Settings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.ExecuteUpdateResultCheckStyle;
+import org.hibernate.id.IdentityGenerator;
+import org.hibernate.mapping.Column;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.mapping.Table;
+import org.hibernate.sql.SelectFragment;
+import org.hibernate.sql.SimpleSelect;
+import org.hibernate.type.Type;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.JoinedIterator;
+import org.hibernate.util.SingletonIterator;
+
+/**
+ * Implementation of the "table-per-concrete-class" or "roll-down" mapping 
+ * strategy for an entity and its inheritence hierarchy.
+ *
+ * @author Gavin King
+ */
+public class UnionSubclassEntityPersister extends AbstractEntityPersister {
+
+	// the class hierarchy structure
+	private final String subquery;
+	private final String tableName;
+	//private final String rootTableName;
+	private final String[] subclassClosure;
+	private final String[] spaces;
+	private final String[] subclassSpaces;
+	private final String discriminatorSQLValue;
+	private final Map subclassByDiscriminatorValue = new HashMap();
+
+	private final String[] constraintOrderedTableNames;
+	private final String[][] constraintOrderedKeyColumnNames;
+
+	//INITIALIZATION:
+
+	public UnionSubclassEntityPersister(
+			final PersistentClass persistentClass, 
+			final EntityRegionAccessStrategy cacheAccessStrategy,
+			final SessionFactoryImplementor factory,
+			final Mapping mapping) throws HibernateException {
+
+		super( persistentClass, cacheAccessStrategy, factory );
+		
+		if ( getIdentifierGenerator() instanceof IdentityGenerator ) {
+			throw new MappingException(
+					"Cannot use identity column key generation with <union-subclass> mapping for: " + 
+					getEntityName() 
+			);
+		}
+
+		// TABLE
+
+		tableName = persistentClass.getTable().getQualifiedName( 
+				factory.getDialect(), 
+				factory.getSettings().getDefaultCatalogName(), 
+				factory.getSettings().getDefaultSchemaName() 
+		);
+		/*rootTableName = persistentClass.getRootTable().getQualifiedName( 
+				factory.getDialect(), 
+				factory.getDefaultCatalog(), 
+				factory.getDefaultSchema() 
+		);*/
+
+		//Custom SQL
+
+		String sql;
+		boolean callable = false;
+		ExecuteUpdateResultCheckStyle checkStyle = null;
+		sql = persistentClass.getCustomSQLInsert();
+		callable = sql != null && persistentClass.isCustomInsertCallable();
+		checkStyle = sql == null
+				? ExecuteUpdateResultCheckStyle.COUNT
+	            : persistentClass.getCustomSQLInsertCheckStyle() == null
+						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
+	                    : persistentClass.getCustomSQLInsertCheckStyle();
+		customSQLInsert = new String[] { sql };
+		insertCallable = new boolean[] { callable };
+		insertResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
+
+		sql = persistentClass.getCustomSQLUpdate();
+		callable = sql != null && persistentClass.isCustomUpdateCallable();
+		checkStyle = sql == null
+				? ExecuteUpdateResultCheckStyle.COUNT
+	            : persistentClass.getCustomSQLUpdateCheckStyle() == null
+						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
+	                    : persistentClass.getCustomSQLUpdateCheckStyle();
+		customSQLUpdate = new String[] { sql };
+		updateCallable = new boolean[] { callable };
+		updateResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
+
+		sql = persistentClass.getCustomSQLDelete();
+		callable = sql != null && persistentClass.isCustomDeleteCallable();
+		checkStyle = sql == null
+				? ExecuteUpdateResultCheckStyle.COUNT
+	            : persistentClass.getCustomSQLDeleteCheckStyle() == null
+						? ExecuteUpdateResultCheckStyle.determineDefault( sql, callable )
+	                    : persistentClass.getCustomSQLDeleteCheckStyle();
+		customSQLDelete = new String[] { sql };
+		deleteCallable = new boolean[] { callable };
+		deleteResultCheckStyles = new ExecuteUpdateResultCheckStyle[] { checkStyle };
+
+		discriminatorSQLValue = String.valueOf( persistentClass.getSubclassId() );
+
+		// PROPERTIES
+
+		int subclassSpan = persistentClass.getSubclassSpan() + 1;
+		subclassClosure = new String[subclassSpan];
+		subclassClosure[0] = getEntityName();
+
+		// SUBCLASSES
+		subclassByDiscriminatorValue.put( 
+				new Integer( persistentClass.getSubclassId() ), 
+				persistentClass.getEntityName() 
+		);
+		if ( persistentClass.isPolymorphic() ) {
+			Iterator iter = persistentClass.getSubclassIterator();
+			int k=1;
+			while ( iter.hasNext() ) {
+				Subclass sc = (Subclass) iter.next();
+				subclassClosure[k++] = sc.getEntityName();
+				subclassByDiscriminatorValue.put( new Integer( sc.getSubclassId() ), sc.getEntityName() );
+			}
+		}
+		
+		//SPACES
+		//TODO: i'm not sure, but perhaps we should exclude
+		//      abstract denormalized tables?
+		
+		int spacesSize = 1 + persistentClass.getSynchronizedTables().size();
+		spaces = new String[spacesSize];
+		spaces[0] = tableName;
+		Iterator iter = persistentClass.getSynchronizedTables().iterator();
+		for ( int i=1; i<spacesSize; i++ ) {
+			spaces[i] = (String) iter.next();
+		}
+		
+		HashSet subclassTables = new HashSet();
+		iter = persistentClass.getSubclassTableClosureIterator();
+		while ( iter.hasNext() ) {
+			Table table = (Table) iter.next();
+			subclassTables.add( table.getQualifiedName(
+					factory.getDialect(), 
+					factory.getSettings().getDefaultCatalogName(), 
+					factory.getSettings().getDefaultSchemaName() 
+			) );
+		}
+		subclassSpaces = ArrayHelper.toStringArray(subclassTables);
+
+		subquery = generateSubquery(persistentClass, mapping);
+
+		if ( isMultiTable() ) {
+			int idColumnSpan = getIdentifierColumnSpan();
+			ArrayList tableNames = new ArrayList();
+			ArrayList keyColumns = new ArrayList();
+			if ( !isAbstract() ) {
+				tableNames.add( tableName );
+				keyColumns.add( getIdentifierColumnNames() );
+			}
+			iter = persistentClass.getSubclassTableClosureIterator();
+			while ( iter.hasNext() ) {
+				Table tab = ( Table ) iter.next();
+				if ( !tab.isAbstractUnionTable() ) {
+					String tableName = tab.getQualifiedName(
+							factory.getDialect(),
+							factory.getSettings().getDefaultCatalogName(),
+							factory.getSettings().getDefaultSchemaName()
+					);
+					tableNames.add( tableName );
+					String[] key = new String[idColumnSpan];
+					Iterator citer = tab.getPrimaryKey().getColumnIterator();
+					for ( int k=0; k<idColumnSpan; k++ ) {
+						key[k] = ( ( Column ) citer.next() ).getQuotedName( factory.getDialect() );
+					}
+					keyColumns.add( key );
+				}
+			}
+
+			constraintOrderedTableNames = ArrayHelper.toStringArray( tableNames );
+			constraintOrderedKeyColumnNames = ArrayHelper.to2DStringArray( keyColumns );
+		}
+		else {
+			constraintOrderedTableNames = new String[] { tableName };
+			constraintOrderedKeyColumnNames = new String[][] { getIdentifierColumnNames() };
+		}
+
+		initLockers();
+
+		initSubclassPropertyAliasesMap(persistentClass);
+		
+		postConstruct(mapping);
+
+	}
+
+	public Serializable[] getQuerySpaces() {
+		return subclassSpaces;
+	}
+	
+	public String getTableName() {
+		return subquery;
+	}
+
+	public Type getDiscriminatorType() {
+		return Hibernate.INTEGER;
+	}
+
+	public String getDiscriminatorSQLValue() {
+		return discriminatorSQLValue;
+	}
+
+	public String[] getSubclassClosure() {
+		return subclassClosure;
+	}
+
+	public String getSubclassForDiscriminatorValue(Object value) {
+		return (String) subclassByDiscriminatorValue.get(value);
+	}
+
+	public Serializable[] getPropertySpaces() {
+		return spaces;
+	}
+
+	protected boolean isDiscriminatorFormula() {
+		return false;
+	}
+
+	/**
+	 * Generate the SQL that selects a row by id
+	 */
+	protected String generateSelectString(LockMode lockMode) {
+		SimpleSelect select = new SimpleSelect( getFactory().getDialect() )
+			.setLockMode(lockMode)
+			.setTableName( getTableName() )
+			.addColumns( getIdentifierColumnNames() )
+			.addColumns( 
+					getSubclassColumnClosure(), 
+					getSubclassColumnAliasClosure(),
+					getSubclassColumnLazyiness()
+			)
+			.addColumns( 
+					getSubclassFormulaClosure(), 
+					getSubclassFormulaAliasClosure(),
+					getSubclassFormulaLazyiness()
+			);
+		//TODO: include the rowids!!!!
+		if ( hasSubclasses() ) {
+			if ( isDiscriminatorFormula() ) {
+				select.addColumn( getDiscriminatorFormula(), getDiscriminatorAlias() );
+			}
+			else {
+				select.addColumn( getDiscriminatorColumnName(), getDiscriminatorAlias() );
+			}
+		}
+		if ( getFactory().getSettings().isCommentsEnabled() ) {
+			select.setComment( "load " + getEntityName() );
+		}
+		return select.addCondition( getIdentifierColumnNames(), "=?" ).toStatementString();
+	}
+
+	protected String getDiscriminatorFormula() {
+		return null;
+	}
+
+	protected String getTableName(int j) {
+		return tableName;
+	}
+
+	protected String[] getKeyColumns(int j) {
+		return getIdentifierColumnNames();
+	}
+	
+	protected boolean isTableCascadeDeleteEnabled(int j) {
+		return false;
+	}
+	
+	protected boolean isPropertyOfTable(int property, int j) {
+		return true;
+	}
+
+	// Execute the SQL:
+
+	public String fromTableFragment(String name) {
+		return getTableName() + ' '  + name;
+	}
+
+	public String filterFragment(String name) {
+		return hasWhere() ?
+			" and " + getSQLWhereString(name) :
+			"";
+	}
+
+	public String getSubclassPropertyTableName(int i) {
+		return getTableName();//ie. the subquery! yuck!
+	}
+
+	protected void addDiscriminatorToSelect(SelectFragment select, String name, String suffix) {
+		select.addColumn( name, getDiscriminatorColumnName(),  getDiscriminatorAlias() );
+	}
+	
+	protected int[] getPropertyTableNumbersInSelect() {
+		return new int[ getPropertySpan() ];
+	}
+
+	protected int getSubclassPropertyTableNumber(int i) {
+		return 0;
+	}
+
+	public int getSubclassPropertyTableNumber(String propertyName) {
+		return 0;
+	}
+
+	public boolean isMultiTable() {
+		// This could also just be true all the time...
+		return isAbstract() || hasSubclasses();
+	}
+
+	public int getTableSpan() {
+		return 1;
+	}
+
+	protected int[] getSubclassColumnTableNumberClosure() {
+		return new int[ getSubclassColumnClosure().length ];
+	}
+
+	protected int[] getSubclassFormulaTableNumberClosure() {
+		return new int[ getSubclassFormulaClosure().length ];
+	}
+
+	protected boolean[] getTableHasColumns() {
+		return new boolean[] { true };
+	}
+
+	protected int[] getPropertyTableNumbers() {
+		return new int[ getPropertySpan() ];
+	}
+
+	protected String generateSubquery(PersistentClass model, Mapping mapping) {
+
+		Dialect dialect = getFactory().getDialect();
+		Settings settings = getFactory().getSettings();
+		
+		if ( !model.hasSubclasses() ) {
+			return model.getTable().getQualifiedName(
+					dialect,
+					settings.getDefaultCatalogName(),
+					settings.getDefaultSchemaName()
+				);
+		}
+
+		HashSet columns = new HashSet();
+		Iterator titer = model.getSubclassTableClosureIterator();
+		while ( titer.hasNext() ) {
+			Table table = (Table) titer.next();
+			if ( !table.isAbstractUnionTable() ) {
+				Iterator citer = table.getColumnIterator();
+				while ( citer.hasNext() ) columns.add( citer.next() );
+			}
+		}
+
+		StringBuffer buf = new StringBuffer()
+			.append("( ");
+
+		Iterator siter = new JoinedIterator(
+			new SingletonIterator(model),
+			model.getSubclassIterator()
+		);
+
+		while ( siter.hasNext() ) {
+			PersistentClass clazz = (PersistentClass) siter.next();
+			Table table = clazz.getTable();
+			if ( !table.isAbstractUnionTable() ) {
+				//TODO: move to .sql package!!
+				buf.append("select ");
+				Iterator citer = columns.iterator();
+				while ( citer.hasNext() ) {
+					Column col = (Column) citer.next();
+					if ( !table.containsColumn(col) ) {
+						int sqlType = col.getSqlTypeCode(mapping);
+						buf.append( dialect.getSelectClauseNullString(sqlType) )
+							.append(" as ");
+					}
+					buf.append( col.getName() );
+					buf.append(", ");
+				}
+				buf.append( clazz.getSubclassId() )
+					.append(" as clazz_");
+				buf.append(" from ")
+					.append( table.getQualifiedName(
+							dialect,
+							settings.getDefaultCatalogName(),
+							settings.getDefaultSchemaName()
+					) );
+				buf.append(" union ");
+				if ( dialect.supportsUnionAll() ) {
+					buf.append("all ");
+				}
+			}
+		}
+		
+		if ( buf.length() > 2 ) {
+			//chop the last union (all)
+			buf.setLength( buf.length() - ( dialect.supportsUnionAll() ? 11 : 7 ) );
+		}
+
+		return buf.append(" )").toString();
+	}
+
+	protected String[] getSubclassTableKeyColumns(int j) {
+		if (j!=0) throw new AssertionFailure("only one table");
+		return getIdentifierColumnNames();
+	}
+
+	public String getSubclassTableName(int j) {
+		if (j!=0) throw new AssertionFailure("only one table");
+		return tableName;
+	}
+
+	public int getSubclassTableSpan() {
+		return 1;
+	}
+
+	protected boolean isClassOrSuperclassTable(int j) {
+		if (j!=0) throw new AssertionFailure("only one table");
+		return true;
+	}
+
+	public String getPropertyTableName(String propertyName) {
+		//TODO: check this....
+		return getTableName();
+	}
+
+	public String[] getConstraintOrderedTableNameClosure() {
+			return constraintOrderedTableNames;
+	}
+
+	public String[][] getContraintOrderedTableKeyColumnClosure() {
+		return constraintOrderedKeyColumnNames;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: UniqueKeyLoadable.java 5732 2005-02-14 15:53:24Z oneovthafew $
-package org.hibernate.persister.entity;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * @author Gavin King
- */
-public interface UniqueKeyLoadable extends Loadable {
-	/**
-	 * Load an instance of the persistent class, by a unique key other
-	 * than the primary key.
-	 */
-	public Object loadByUniqueKey(String propertyName, Object uniqueKey, SessionImplementor session) 
-	throws HibernateException;
-	/**
-	 * Get the property number of the unique key property
-	 */
-	public int getPropertyIndex(String propertyName);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/UniqueKeyLoadable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.persister.entity;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * @author Gavin King
+ */
+public interface UniqueKeyLoadable extends Loadable {
+	/**
+	 * Load an instance of the persistent class, by a unique key other
+	 * than the primary key.
+	 */
+	public Object loadByUniqueKey(String propertyName, Object uniqueKey, SessionImplementor session) 
+	throws HibernateException;
+	/**
+	 * Get the property number of the unique key property
+	 */
+	public int getPropertyIndex(String propertyName);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/entity/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts persistence mechanisms for
-	entities, and defines the Hibernate runtime
-	metamodel.
-</p>
-<p>
-    Strategies for persisting entities implement the
-    <tt>EntityPersister</tt> interface. Optionally, 
-    they may implement certain additional interfaces
-    that define contracts with various loaders.
-    Concrete implementations in this package define
-    the built-in inheritance mapping strategies.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/entity/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/entity/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts persistence mechanisms for
+	entities, and defines the Hibernate runtime
+	metamodel.
+</p>
+<p>
+    Strategies for persisting entities implement the
+    <tt>EntityPersister</tt> interface. Optionally, 
+    they may implement certain additional interfaces
+    that define contracts with various loaders.
+    Concrete implementations in this package define
+    the built-in inheritance mapping strategies.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/persister/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	A persister defines a mapping strategy for a collection
-	or entity.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/persister/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/persister/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	A persister defines a mapping strategy for a collection
+	or entity.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/pretty/MessageHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,321 +0,0 @@
-//$Id: MessageHelper.java 9561 2006-03-07 14:17:16Z steve.ebersole at jboss.com $
-package org.hibernate.pretty;
-
-import java.io.Serializable;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.type.Type;
-
-/**
- * MessageHelper methods for rendering log messages relating to managed
- * entities and collections typically used in log statements and exception
- * messages.
- *
- * @author Max Andersen, Gavin King
- */
-public final class MessageHelper {
-
-	private MessageHelper() {
-	}
-
-
-	// entities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	/**
-	 * Generate an info message string relating to a particular entity,
-	 * based on the given entityName and id.
-	 *
-	 * @param entityName The defined entity name.
-	 * @param id The entity id value.
-	 * @return An info string, in the form [FooBar#1].
-	 */
-	public static String infoString(String entityName, Serializable id) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if( entityName == null ) {
-			s.append( "<null entity name>" );
-		}
-		else {
-			s.append( entityName );
-		}
-		s.append( '#' );
-
-		if ( id == null ) {
-			s.append( "<null>" );
-		}
-		else {
-			s.append( id );
-		}
-		s.append( ']' );
-
-		return s.toString();
-	}
-
-	/**
-	 * Generate an info message string relating to a particular entity.
-	 *
-	 * @param persister The persister for the entity
-	 * @param id The entity id value
-	 * @param factory The session factory
-	 * @return An info string, in the form [FooBar#1]
-	 */
-	public static String infoString(
-			EntityPersister persister, 
-			Object id, 
-			SessionFactoryImplementor factory) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		Type idType;
-		if( persister == null ) {
-			s.append( "<null EntityPersister>" );
-			idType = null;
-		}
-		else {
-			s.append( persister.getEntityName() );
-			idType = persister.getIdentifierType();
-		}
-		s.append( '#' );
-
-		if ( id == null ) {
-			s.append( "<null>" );
-		}
-		else {
-			if ( idType == null ) {
-				s.append( id );
-			}
-			else {
-				s.append( idType.toLoggableString( id, factory ) );
-			}
-		}
-		s.append( ']' );
-
-		return s.toString();
-
-	}
-
-	/**
-	 * Generate an info message string relating to a particular entity,.
-	 *
-	 * @param persister The persister for the entity
-	 * @param id The entity id value
-	 * @param identifierType The entity identifier type mapping
-	 * @param factory The session factory
-	 * @return An info string, in the form [FooBar#1]
-	 */
-	public static String infoString(
-			EntityPersister persister, 
-			Object id, 
-			Type identifierType,
-			SessionFactoryImplementor factory) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if( persister == null ) {
-			s.append( "<null EntityPersister>" );
-		}
-		else {
-			s.append( persister.getEntityName() );
-		}
-		s.append( '#' );
-
-		if ( id == null ) {
-			s.append( "<null>" );
-		}
-		else {
-			s.append( identifierType.toLoggableString( id, factory ) );
-		}
-		s.append( ']' );
-
-		return s.toString();
-	}
-
-	/**
-	 * Generate an info message string relating to a series of entities.
-	 *
-	 * @param persister The persister for the entities
-	 * @param ids The entity id values
-	 * @param factory The session factory
-	 * @return An info string, in the form [FooBar#<1,2,3>]
-	 */
-	public static String infoString(
-			EntityPersister persister, 
-			Serializable[] ids, 
-			SessionFactoryImplementor factory) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if( persister == null ) {
-			s.append( "<null EntityPersister>" );
-		}
-		else {
-			s.append( persister.getEntityName() );
-			s.append( "#<" );
-			for ( int i=0; i<ids.length; i++ ) {
-				s.append( persister.getIdentifierType().toLoggableString( ids[i], factory ) );
-				if ( i < ids.length-1 ) {
-					s.append( ", " );
-				}
-			}
-			s.append( '>' );
-		}
-		s.append( ']' );
-
-		return s.toString();
-
-	}
-
-	/**
-	 * Generate an info message string relating to given entity persister.
-	 *
-	 * @param persister The persister.
-	 * @return An info string, in the form [FooBar]
-	 */
-	public static String infoString(EntityPersister persister) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if ( persister == null ) {
-			s.append( "<null EntityPersister>" );
-		}
-		else {
-			s.append( persister.getEntityName() );
-		}
-		s.append( ']' );
-		return s.toString();
-	}
-
-	/**
-	 * Generate an info message string relating to a given property value
-	 * for an entity.
-	 *
-	 * @param entityName The entity name
-	 * @param propertyName The name of the property
-	 * @param key The property value.
-	 * @return An info string, in the form [Foo.bars#1]
-	 */
-	public static String infoString(String entityName, String propertyName, Object key) {
-		StringBuffer s = new StringBuffer()
-				.append( '[' )
-				.append( entityName )
-				.append( '.' )
-				.append( propertyName )
-				.append( '#' );
-
-		if ( key == null ) {
-			s.append( "<null>" );
-		}
-		else {
-			s.append( key );
-		}
-		s.append( ']' );
-		return s.toString();
-	}
-
-
-	// collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-	/**
-	 * Generate an info message string relating to a series of managed
-	 * collections.
-	 *
-	 * @param persister The persister for the collections
-	 * @param ids The id values of the owners
-	 * @param factory The session factory
-	 * @return An info string, in the form [Foo.bars#<1,2,3>]
-	 */
-	public static String collectionInfoString(
-			CollectionPersister persister, 
-			Serializable[] ids, 
-			SessionFactoryImplementor factory) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if ( persister == null ) {
-			s.append( "<unreferenced>" );
-		}
-		else {
-			s.append( persister.getRole() );
-			s.append( "#<" );
-			for ( int i = 0; i < ids.length; i++ ) {
-				// Need to use the identifier type of the collection owner
-				// since the incoming is value is actually the owner's id.
-				// Using the collection's key type causes problems with
-				// property-ref keys...
-				s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( ids[i], factory ) );
-				if ( i < ids.length-1 ) {
-					s.append( ", " );
-				}
-			}
-			s.append( '>' );
-		}
-		s.append( ']' );
-		return s.toString();
-	}
-
-	/**
-	 * Generate an info message string relating to a particular managed
-	 * collection.
-	 *
-	 * @param persister The persister for the collection
-	 * @param id The id value of the owner
-	 * @param factory The session factory
-	 * @return An info string, in the form [Foo.bars#1]
-	 */
-	public static String collectionInfoString(
-			CollectionPersister persister, 
-			Serializable id, 
-			SessionFactoryImplementor factory) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if ( persister == null ) {
-			s.append( "<unreferenced>" );
-		}
-		else {
-			s.append( persister.getRole() );
-			s.append( '#' );
-
-			if ( id == null ) {
-				s.append( "<null>" );
-			}
-			else {
-				// Need to use the identifier type of the collection owner
-				// since the incoming is value is actually the owner's id.
-				// Using the collection's key type causes problems with
-				// property-ref keys...
-				s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( id, factory ) );
-			}
-		}
-		s.append( ']' );
-
-		return s.toString();
-	}
-
-	/**
-	 * Generate an info message string relating to a particular managed
-	 * collection.
-	 *
-	 * @param role The role-name of the collection
-	 * @param id The id value of the owner
-	 * @return An info string, in the form [Foo.bars#1]
-	 */
-	public static String collectionInfoString(String role, Serializable id) {
-		StringBuffer s = new StringBuffer();
-		s.append( '[' );
-		if( role == null ) {
-			s.append( "<unreferenced>" );
-		}
-		else {
-			s.append( role );
-			s.append( '#' );
-
-			if ( id == null ) {
-				s.append( "<null>" );
-			}
-			else {
-				s.append( id );
-			}
-		}
-		s.append( ']' );
-		return s.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/pretty/MessageHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/MessageHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,344 @@
+/*
+ * 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.pretty;
+
+import java.io.Serializable;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.type.Type;
+
+/**
+ * MessageHelper methods for rendering log messages relating to managed
+ * entities and collections typically used in log statements and exception
+ * messages.
+ *
+ * @author Max Andersen, Gavin King
+ */
+public final class MessageHelper {
+
+	private MessageHelper() {
+	}
+
+
+	// entities ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	/**
+	 * Generate an info message string relating to a particular entity,
+	 * based on the given entityName and id.
+	 *
+	 * @param entityName The defined entity name.
+	 * @param id The entity id value.
+	 * @return An info string, in the form [FooBar#1].
+	 */
+	public static String infoString(String entityName, Serializable id) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if( entityName == null ) {
+			s.append( "<null entity name>" );
+		}
+		else {
+			s.append( entityName );
+		}
+		s.append( '#' );
+
+		if ( id == null ) {
+			s.append( "<null>" );
+		}
+		else {
+			s.append( id );
+		}
+		s.append( ']' );
+
+		return s.toString();
+	}
+
+	/**
+	 * Generate an info message string relating to a particular entity.
+	 *
+	 * @param persister The persister for the entity
+	 * @param id The entity id value
+	 * @param factory The session factory
+	 * @return An info string, in the form [FooBar#1]
+	 */
+	public static String infoString(
+			EntityPersister persister, 
+			Object id, 
+			SessionFactoryImplementor factory) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		Type idType;
+		if( persister == null ) {
+			s.append( "<null EntityPersister>" );
+			idType = null;
+		}
+		else {
+			s.append( persister.getEntityName() );
+			idType = persister.getIdentifierType();
+		}
+		s.append( '#' );
+
+		if ( id == null ) {
+			s.append( "<null>" );
+		}
+		else {
+			if ( idType == null ) {
+				s.append( id );
+			}
+			else {
+				s.append( idType.toLoggableString( id, factory ) );
+			}
+		}
+		s.append( ']' );
+
+		return s.toString();
+
+	}
+
+	/**
+	 * Generate an info message string relating to a particular entity,.
+	 *
+	 * @param persister The persister for the entity
+	 * @param id The entity id value
+	 * @param identifierType The entity identifier type mapping
+	 * @param factory The session factory
+	 * @return An info string, in the form [FooBar#1]
+	 */
+	public static String infoString(
+			EntityPersister persister, 
+			Object id, 
+			Type identifierType,
+			SessionFactoryImplementor factory) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if( persister == null ) {
+			s.append( "<null EntityPersister>" );
+		}
+		else {
+			s.append( persister.getEntityName() );
+		}
+		s.append( '#' );
+
+		if ( id == null ) {
+			s.append( "<null>" );
+		}
+		else {
+			s.append( identifierType.toLoggableString( id, factory ) );
+		}
+		s.append( ']' );
+
+		return s.toString();
+	}
+
+	/**
+	 * Generate an info message string relating to a series of entities.
+	 *
+	 * @param persister The persister for the entities
+	 * @param ids The entity id values
+	 * @param factory The session factory
+	 * @return An info string, in the form [FooBar#<1,2,3>]
+	 */
+	public static String infoString(
+			EntityPersister persister, 
+			Serializable[] ids, 
+			SessionFactoryImplementor factory) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if( persister == null ) {
+			s.append( "<null EntityPersister>" );
+		}
+		else {
+			s.append( persister.getEntityName() );
+			s.append( "#<" );
+			for ( int i=0; i<ids.length; i++ ) {
+				s.append( persister.getIdentifierType().toLoggableString( ids[i], factory ) );
+				if ( i < ids.length-1 ) {
+					s.append( ", " );
+				}
+			}
+			s.append( '>' );
+		}
+		s.append( ']' );
+
+		return s.toString();
+
+	}
+
+	/**
+	 * Generate an info message string relating to given entity persister.
+	 *
+	 * @param persister The persister.
+	 * @return An info string, in the form [FooBar]
+	 */
+	public static String infoString(EntityPersister persister) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if ( persister == null ) {
+			s.append( "<null EntityPersister>" );
+		}
+		else {
+			s.append( persister.getEntityName() );
+		}
+		s.append( ']' );
+		return s.toString();
+	}
+
+	/**
+	 * Generate an info message string relating to a given property value
+	 * for an entity.
+	 *
+	 * @param entityName The entity name
+	 * @param propertyName The name of the property
+	 * @param key The property value.
+	 * @return An info string, in the form [Foo.bars#1]
+	 */
+	public static String infoString(String entityName, String propertyName, Object key) {
+		StringBuffer s = new StringBuffer()
+				.append( '[' )
+				.append( entityName )
+				.append( '.' )
+				.append( propertyName )
+				.append( '#' );
+
+		if ( key == null ) {
+			s.append( "<null>" );
+		}
+		else {
+			s.append( key );
+		}
+		s.append( ']' );
+		return s.toString();
+	}
+
+
+	// collections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+	/**
+	 * Generate an info message string relating to a series of managed
+	 * collections.
+	 *
+	 * @param persister The persister for the collections
+	 * @param ids The id values of the owners
+	 * @param factory The session factory
+	 * @return An info string, in the form [Foo.bars#<1,2,3>]
+	 */
+	public static String collectionInfoString(
+			CollectionPersister persister, 
+			Serializable[] ids, 
+			SessionFactoryImplementor factory) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if ( persister == null ) {
+			s.append( "<unreferenced>" );
+		}
+		else {
+			s.append( persister.getRole() );
+			s.append( "#<" );
+			for ( int i = 0; i < ids.length; i++ ) {
+				// Need to use the identifier type of the collection owner
+				// since the incoming is value is actually the owner's id.
+				// Using the collection's key type causes problems with
+				// property-ref keys...
+				s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( ids[i], factory ) );
+				if ( i < ids.length-1 ) {
+					s.append( ", " );
+				}
+			}
+			s.append( '>' );
+		}
+		s.append( ']' );
+		return s.toString();
+	}
+
+	/**
+	 * Generate an info message string relating to a particular managed
+	 * collection.
+	 *
+	 * @param persister The persister for the collection
+	 * @param id The id value of the owner
+	 * @param factory The session factory
+	 * @return An info string, in the form [Foo.bars#1]
+	 */
+	public static String collectionInfoString(
+			CollectionPersister persister, 
+			Serializable id, 
+			SessionFactoryImplementor factory) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if ( persister == null ) {
+			s.append( "<unreferenced>" );
+		}
+		else {
+			s.append( persister.getRole() );
+			s.append( '#' );
+
+			if ( id == null ) {
+				s.append( "<null>" );
+			}
+			else {
+				// Need to use the identifier type of the collection owner
+				// since the incoming is value is actually the owner's id.
+				// Using the collection's key type causes problems with
+				// property-ref keys...
+				s.append( persister.getOwnerEntityPersister().getIdentifierType().toLoggableString( id, factory ) );
+			}
+		}
+		s.append( ']' );
+
+		return s.toString();
+	}
+
+	/**
+	 * Generate an info message string relating to a particular managed
+	 * collection.
+	 *
+	 * @param role The role-name of the collection
+	 * @param id The id value of the owner
+	 * @return An info string, in the form [Foo.bars#1]
+	 */
+	public static String collectionInfoString(String role, Serializable id) {
+		StringBuffer s = new StringBuffer();
+		s.append( '[' );
+		if( role == null ) {
+			s.append( "<unreferenced>" );
+		}
+		else {
+			s.append( role );
+			s.append( '#' );
+
+			if ( id == null ) {
+				s.append( "<null>" );
+			}
+			else {
+				s.append( id );
+			}
+		}
+		s.append( ']' );
+		return s.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/pretty/Printer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,98 +0,0 @@
-//$Id: Printer.java 5785 2005-02-19 12:58:24Z oneovthafew $
-package org.hibernate.pretty;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.EntityMode;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.TypedValue;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.metadata.ClassMetadata;
-import org.hibernate.type.Type;
-
-/**
- * Renders entities to a nicely readable string.
- * @author Gavin King
- */
-public final class Printer {
-
-	private SessionFactoryImplementor factory;
-	private static final Logger log = LoggerFactory.getLogger(Printer.class);
-
-	/**
-	 * @param entity an actual entity object, not a proxy!
-	 */
-	public String toString(Object entity, EntityMode entityMode) throws HibernateException {
-
-		// todo : this call will not work for anything other than pojos!
-		ClassMetadata cm = factory.getClassMetadata( entity.getClass() );
-
-		if ( cm==null ) return entity.getClass().getName();
-
-		Map result = new HashMap();
-
-		if ( cm.hasIdentifierProperty() ) {
-			result.put(
-				cm.getIdentifierPropertyName(),
-				cm.getIdentifierType().toLoggableString( cm.getIdentifier( entity, entityMode ), factory )
-			);
-		}
-
-		Type[] types = cm.getPropertyTypes();
-		String[] names = cm.getPropertyNames();
-		Object[] values = cm.getPropertyValues( entity, entityMode );
-		for ( int i=0; i<types.length; i++ ) {
-			if ( !names[i].startsWith("_") ) {
-				String strValue = values[i]==LazyPropertyInitializer.UNFETCHED_PROPERTY ?
-					values[i].toString() :
-					types[i].toLoggableString( values[i], factory );
-				result.put( names[i], strValue );
-			}
-		}
-		return cm.getEntityName() + result.toString();
-	}
-
-	public String toString(Type[] types, Object[] values) throws HibernateException {
-		List list = new ArrayList( types.length * 5 );
-		for ( int i=0; i<types.length; i++ ) {
-			if ( types[i]!=null ) list.add( types[i].toLoggableString( values[i], factory ) );
-		}
-		return list.toString();
-	}
-
-	public String toString(Map namedTypedValues) throws HibernateException {
-		Map result = new HashMap();
-		Iterator iter = namedTypedValues.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			TypedValue tv = (TypedValue) me.getValue();
-			result.put( me.getKey(), tv.getType().toLoggableString( tv.getValue(), factory ) );
-		}
-		return result.toString();
-	}
-
-	public void toString(Iterator iter, EntityMode entityMode) throws HibernateException {
-		if ( !log.isDebugEnabled() || !iter.hasNext() ) return;
-		log.debug("listing entities:");
-		int i=0;
-		while ( iter.hasNext() ) {
-			if (i++>20) {
-				log.debug("more......");
-				break;
-			}
-			log.debug( toString( iter.next(), entityMode ) );
-		}
-	}
-
-	public Printer(SessionFactoryImplementor factory) {
-		this.factory = factory;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/pretty/Printer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/Printer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.pretty;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.TypedValue;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.metadata.ClassMetadata;
+import org.hibernate.type.Type;
+
+/**
+ * Renders entities to a nicely readable string.
+ * @author Gavin King
+ */
+public final class Printer {
+
+	private SessionFactoryImplementor factory;
+	private static final Logger log = LoggerFactory.getLogger(Printer.class);
+
+	/**
+	 * @param entity an actual entity object, not a proxy!
+	 */
+	public String toString(Object entity, EntityMode entityMode) throws HibernateException {
+
+		// todo : this call will not work for anything other than pojos!
+		ClassMetadata cm = factory.getClassMetadata( entity.getClass() );
+
+		if ( cm==null ) return entity.getClass().getName();
+
+		Map result = new HashMap();
+
+		if ( cm.hasIdentifierProperty() ) {
+			result.put(
+				cm.getIdentifierPropertyName(),
+				cm.getIdentifierType().toLoggableString( cm.getIdentifier( entity, entityMode ), factory )
+			);
+		}
+
+		Type[] types = cm.getPropertyTypes();
+		String[] names = cm.getPropertyNames();
+		Object[] values = cm.getPropertyValues( entity, entityMode );
+		for ( int i=0; i<types.length; i++ ) {
+			if ( !names[i].startsWith("_") ) {
+				String strValue = values[i]==LazyPropertyInitializer.UNFETCHED_PROPERTY ?
+					values[i].toString() :
+					types[i].toLoggableString( values[i], factory );
+				result.put( names[i], strValue );
+			}
+		}
+		return cm.getEntityName() + result.toString();
+	}
+
+	public String toString(Type[] types, Object[] values) throws HibernateException {
+		List list = new ArrayList( types.length * 5 );
+		for ( int i=0; i<types.length; i++ ) {
+			if ( types[i]!=null ) list.add( types[i].toLoggableString( values[i], factory ) );
+		}
+		return list.toString();
+	}
+
+	public String toString(Map namedTypedValues) throws HibernateException {
+		Map result = new HashMap();
+		Iterator iter = namedTypedValues.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			TypedValue tv = (TypedValue) me.getValue();
+			result.put( me.getKey(), tv.getType().toLoggableString( tv.getValue(), factory ) );
+		}
+		return result.toString();
+	}
+
+	public void toString(Iterator iter, EntityMode entityMode) throws HibernateException {
+		if ( !log.isDebugEnabled() || !iter.hasNext() ) return;
+		log.debug("listing entities:");
+		int i=0;
+		while ( iter.hasNext() ) {
+			if (i++>20) {
+				log.debug("more......");
+				break;
+			}
+			log.debug( toString( iter.next(), entityMode ) );
+		}
+	}
+
+	public Printer(SessionFactoryImplementor factory) {
+		this.factory = factory;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/pretty/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Classes for pretty printing things for exception
-	and log messages.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/pretty/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/pretty/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Classes for pretty printing things for exception
+	and log messages.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
- *
- * 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, v. 2.1. This program is distributed in the
- * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
- * distribution; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Red Hat Author(s): Gavin King, Steve Ebersole
- */
-package org.hibernate.property;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Represents a "back-reference" to the id of a collection owner.  A "back-reference" is pertinent in mapping scenarios
- * where we have a uni-directional one-to-many association in which only the many side is mapped.  In this case it is
- * the collection itself which is responsible for the FK value.
- * <p/>
- * In this scenario, the one side has no inherent knowledge of its "owner".  So we introduce a synthetic property into
- * the one side to represent the association; a so-called back-reference.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class BackrefPropertyAccessor implements PropertyAccessor {
-
-	private final String propertyName;
-	private final String entityName;
-
-	// cache these since they are stateless
-	private final BackrefSetter setter; // this one could even be static...
-	private final BackrefGetter getter;
-
-	/**
-	 * A placeholder for a property value, indicating that
-	 * we don't know the value of the back reference
-	 */
-	public static final Serializable UNKNOWN = new Serializable() {
-		public String toString() {
-			return "<unknown>";
-		}
-
-		public Object readResolve() {
-			return UNKNOWN;
-		}
-	};
-
-	/**
-	 * Constructs a new instance of BackrefPropertyAccessor.
-	 *
-	 * @param collectionRole The collection role which this back ref references.
-	 * @param entityName The owner's entity name.
-	 */
-	public BackrefPropertyAccessor(String collectionRole, String entityName) {
-		this.propertyName = collectionRole.substring( entityName.length() + 1 );
-		this.entityName = entityName;
-
-		this.setter = new BackrefSetter();
-		this.getter = new BackrefGetter();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Setter getSetter(Class theClass, String propertyName) {
-		return setter;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Getter getGetter(Class theClass, String propertyName) {
-		return getter;
-	}
-
-
-	/**
-	 * Internal implementation of a property setter specific to these back-ref properties.
-	 */
-	public static final class BackrefSetter implements Setter {
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Method getMethod() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public String getMethodName() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void set(Object target, Object value, SessionFactoryImplementor factory) {
-			// this page intentionally left blank :)
-		}
-
-	}
-
-
-	/**
-	 * Internal implementation of a property getter specific to these back-ref properties.
-	 */
-	public class BackrefGetter implements Getter {
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
-			if ( session == null ) {
-				return UNKNOWN;
-			}
-			else {
-				return session.getPersistenceContext().getOwnerId( entityName, propertyName, target, mergeMap );
-			}
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Object get(Object target) {
-			return UNKNOWN;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Method getMethod() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public String getMethodName() {
-			return null;
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Class getReturnType() {
-			return Object.class;
-		}
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BackrefPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,172 @@
+/*
+ * 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.property;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Represents a "back-reference" to the id of a collection owner.  A "back-reference" is pertinent in mapping scenarios
+ * where we have a uni-directional one-to-many association in which only the many side is mapped.  In this case it is
+ * the collection itself which is responsible for the FK value.
+ * <p/>
+ * In this scenario, the one side has no inherent knowledge of its "owner".  So we introduce a synthetic property into
+ * the one side to represent the association; a so-called back-reference.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class BackrefPropertyAccessor implements PropertyAccessor {
+
+	private final String propertyName;
+	private final String entityName;
+
+	// cache these since they are stateless
+	private final BackrefSetter setter; // this one could even be static...
+	private final BackrefGetter getter;
+
+	/**
+	 * A placeholder for a property value, indicating that
+	 * we don't know the value of the back reference
+	 */
+	public static final Serializable UNKNOWN = new Serializable() {
+		public String toString() {
+			return "<unknown>";
+		}
+
+		public Object readResolve() {
+			return UNKNOWN;
+		}
+	};
+
+	/**
+	 * Constructs a new instance of BackrefPropertyAccessor.
+	 *
+	 * @param collectionRole The collection role which this back ref references.
+	 * @param entityName The owner's entity name.
+	 */
+	public BackrefPropertyAccessor(String collectionRole, String entityName) {
+		this.propertyName = collectionRole.substring( entityName.length() + 1 );
+		this.entityName = entityName;
+
+		this.setter = new BackrefSetter();
+		this.getter = new BackrefGetter();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Setter getSetter(Class theClass, String propertyName) {
+		return setter;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Getter getGetter(Class theClass, String propertyName) {
+		return getter;
+	}
+
+
+	/**
+	 * Internal implementation of a property setter specific to these back-ref properties.
+	 */
+	public static final class BackrefSetter implements Setter {
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Method getMethod() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public String getMethodName() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void set(Object target, Object value, SessionFactoryImplementor factory) {
+			// this page intentionally left blank :)
+		}
+
+	}
+
+
+	/**
+	 * Internal implementation of a property getter specific to these back-ref properties.
+	 */
+	public class BackrefGetter implements Getter {
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
+			if ( session == null ) {
+				return UNKNOWN;
+			}
+			else {
+				return session.getPersistenceContext().getOwnerId( entityName, propertyName, target, mergeMap );
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Object get(Object target) {
+			return UNKNOWN;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Method getMethod() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public String getMethodName() {
+			return null;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Class getReturnType() {
+			return Object.class;
+		}
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,346 +0,0 @@
-//$Id: BasicPropertyAccessor.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.property;
-
-import java.beans.Introspector;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyAccessException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Accesses property values via a get/set pair, which may be nonpublic.
- * The default (and recommended strategy).
- * @author Gavin King
- */
-public class BasicPropertyAccessor implements PropertyAccessor {
-
-	private static final Logger log = LoggerFactory.getLogger(BasicPropertyAccessor.class);
-
-	public static final class BasicSetter implements Setter {
-		private Class clazz;
-		private final transient Method method;
-		private final String propertyName;
-
-		private BasicSetter(Class clazz, Method method, String propertyName) {
-			this.clazz=clazz;
-			this.method=method;
-			this.propertyName=propertyName;
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) 
-		throws HibernateException {
-			try {
-				method.invoke( target, new Object[] { value } );
-			}
-			catch (NullPointerException npe) {
-				if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
-					throw new PropertyAccessException(
-							npe, 
-							"Null value was assigned to a property of primitive type", 
-							true, 
-							clazz, 
-							propertyName
-						);
-				}
-				else {
-					throw new PropertyAccessException(
-							npe, 
-							"NullPointerException occurred while calling", 
-							true, 
-							clazz, 
-							propertyName
-						);
-				}
-			}
-			catch (InvocationTargetException ite) {
-				throw new PropertyAccessException(
-						ite, 
-						"Exception occurred inside", 
-						true, 
-						clazz, 
-						propertyName
-					);
-			}
-			catch (IllegalAccessException iae) {
-				throw new PropertyAccessException(
-						iae, 
-						"IllegalAccessException occurred while calling", 
-						true, 
-						clazz, 
-						propertyName
-					);
-				//cannot occur
-			}
-			catch (IllegalArgumentException iae) {
-				if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
-					throw new PropertyAccessException(
-							iae, 
-							"Null value was assigned to a property of primitive type", 
-							true, 
-							clazz, 
-							propertyName
-						);
-				}
-				else {
-					log.error(
-							"IllegalArgumentException in class: " + clazz.getName() +
-							", setter method of property: " + propertyName
-						);
-					log.error(
-							"expected type: " + 
-							method.getParameterTypes()[0].getName() +
-							", actual value: " + 
-							( value==null ? null : value.getClass().getName() )
-						);
-					throw new PropertyAccessException(
-							iae, 
-							"IllegalArgumentException occurred while calling", 
-							true, 
-							clazz, 
-							propertyName
-						);
-				}
-			}
-		}
-
-		public Method getMethod() {
-			return method;
-		}
-
-		public String getMethodName() {
-			return method.getName();
-		}
-
-		Object readResolve() {
-			return createSetter(clazz, propertyName);
-		}
-
-		public String toString() {
-			return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')';
-		}
-	}
-
-	public static final class BasicGetter implements Getter {
-		private Class clazz;
-		private final transient Method method;
-		private final String propertyName;
-
-		private BasicGetter(Class clazz, Method method, String propertyName) {
-			this.clazz=clazz;
-			this.method=method;
-			this.propertyName=propertyName;
-		}
-
-		public Object get(Object target) throws HibernateException {
-			try {
-				return method.invoke(target, null);
-			}
-			catch (InvocationTargetException ite) {
-				throw new PropertyAccessException(
-						ite, 
-						"Exception occurred inside", 
-						false, 
-						clazz, 
-						propertyName
-					);
-			}
-			catch (IllegalAccessException iae) {
-				throw new PropertyAccessException(
-						iae, 
-						"IllegalAccessException occurred while calling", 
-						false, 
-						clazz, 
-						propertyName
-					);
-				//cannot occur
-			}
-			catch (IllegalArgumentException iae) {
-				log.error(
-						"IllegalArgumentException in class: " + clazz.getName() +
-						", getter method of property: " + propertyName
-					);
-				throw new PropertyAccessException(
-						iae, 
-						"IllegalArgumentException occurred calling", 
-						false, 
-						clazz, 
-						propertyName
-					);
-			}
-		}
-
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
-			return get( target );
-		}
-
-		public Class getReturnType() {
-			return method.getReturnType();
-		}
-
-		public Method getMethod() {
-			return method;
-		}
-
-		public String getMethodName() {
-			return method.getName();
-		}
-
-		public String toString() {
-			return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')';
-		}
-		
-		Object readResolve() {
-			return createGetter(clazz, propertyName);
-		}
-	}
-
-
-	public Setter getSetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		return createSetter(theClass, propertyName);
-	}
-	
-	private static Setter createSetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		BasicSetter result = getSetterOrNull(theClass, propertyName);
-		if (result==null) {
-			throw new PropertyNotFoundException( 
-					"Could not find a setter for property " + 
-					propertyName + 
-					" in class " + 
-					theClass.getName() 
-				);
-		}
-		return result;
-	}
-
-	private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
-
-		if (theClass==Object.class || theClass==null) return null;
-
-		Method method = setterMethod(theClass, propertyName);
-
-		if (method!=null) {
-			if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
-			return new BasicSetter(theClass, method, propertyName);
-		}
-		else {
-			BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
-			if (setter==null) {
-				Class[] interfaces = theClass.getInterfaces();
-				for ( int i=0; setter==null && i<interfaces.length; i++ ) {
-					setter=getSetterOrNull( interfaces[i], propertyName );
-				}
-			}
-			return setter;
-		}
-
-	}
-
-	private static Method setterMethod(Class theClass, String propertyName) {
-
-		BasicGetter getter = getGetterOrNull(theClass, propertyName);
-		Class returnType = (getter==null) ? null : getter.getReturnType();
-
-		Method[] methods = theClass.getDeclaredMethods();
-		Method potentialSetter = null;
-		for (int i=0; i<methods.length; i++) {
-			String methodName = methods[i].getName();
-
-			if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
-				String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
-				String testOldMethod = methodName.substring(3);
-				if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
-					potentialSetter = methods[i];
-					if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) {
-						return potentialSetter;
-					}
-				}
-			}
-		}
-		return potentialSetter;
-	}
-
-	public Getter getGetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		return createGetter(theClass, propertyName);
-	}
-	
-	public static Getter createGetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		BasicGetter result = getGetterOrNull(theClass, propertyName);
-		if (result==null) {
-			throw new PropertyNotFoundException( 
-					"Could not find a getter for " + 
-					propertyName + 
-					" in class " + 
-					theClass.getName() 
-			);
-		}
-		return result;
-
-	}
-
-	private static BasicGetter getGetterOrNull(Class theClass, String propertyName) {
-
-		if (theClass==Object.class || theClass==null) return null;
-
-		Method method = getterMethod(theClass, propertyName);
-
-		if (method!=null) {
-			if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
-			return new BasicGetter(theClass, method, propertyName);
-		}
-		else {
-			BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName );
-			if (getter==null) {
-				Class[] interfaces = theClass.getInterfaces();
-				for ( int i=0; getter==null && i<interfaces.length; i++ ) {
-					getter=getGetterOrNull( interfaces[i], propertyName );
-				}
-			}
-			return getter;
-		}
-	}
-
-	private static Method getterMethod(Class theClass, String propertyName) {
-
-		Method[] methods = theClass.getDeclaredMethods();
-		for (int i=0; i<methods.length; i++) {
-			// only carry on if the method has no parameters
-			if ( methods[i].getParameterTypes().length == 0 ) {
-				String methodName = methods[i].getName();
-
-				// try "get"
-				if ( methodName.startsWith("get") ) {
-					String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
-					String testOldMethod = methodName.substring(3);
-					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
-						return methods[i];
-					}
-
-				}
-
-				// if not "get", then try "is"
-				if ( methodName.startsWith("is") ) {
-					String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
-					String testOldMethod = methodName.substring(2);
-					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
-						return methods[i];
-					}
-				}
-			}
-		}
-		return null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/BasicPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,370 @@
+/*
+ * 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.property;
+
+import java.beans.Introspector;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyAccessException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Accesses property values via a get/set pair, which may be nonpublic.
+ * The default (and recommended strategy).
+ * 
+ * @author Gavin King
+ */
+public class BasicPropertyAccessor implements PropertyAccessor {
+
+	private static final Logger log = LoggerFactory.getLogger(BasicPropertyAccessor.class);
+
+	public static final class BasicSetter implements Setter {
+		private Class clazz;
+		private final transient Method method;
+		private final String propertyName;
+
+		private BasicSetter(Class clazz, Method method, String propertyName) {
+			this.clazz=clazz;
+			this.method=method;
+			this.propertyName=propertyName;
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) 
+		throws HibernateException {
+			try {
+				method.invoke( target, new Object[] { value } );
+			}
+			catch (NullPointerException npe) {
+				if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
+					throw new PropertyAccessException(
+							npe, 
+							"Null value was assigned to a property of primitive type", 
+							true, 
+							clazz, 
+							propertyName
+						);
+				}
+				else {
+					throw new PropertyAccessException(
+							npe, 
+							"NullPointerException occurred while calling", 
+							true, 
+							clazz, 
+							propertyName
+						);
+				}
+			}
+			catch (InvocationTargetException ite) {
+				throw new PropertyAccessException(
+						ite, 
+						"Exception occurred inside", 
+						true, 
+						clazz, 
+						propertyName
+					);
+			}
+			catch (IllegalAccessException iae) {
+				throw new PropertyAccessException(
+						iae, 
+						"IllegalAccessException occurred while calling", 
+						true, 
+						clazz, 
+						propertyName
+					);
+				//cannot occur
+			}
+			catch (IllegalArgumentException iae) {
+				if ( value==null && method.getParameterTypes()[0].isPrimitive() ) {
+					throw new PropertyAccessException(
+							iae, 
+							"Null value was assigned to a property of primitive type", 
+							true, 
+							clazz, 
+							propertyName
+						);
+				}
+				else {
+					log.error(
+							"IllegalArgumentException in class: " + clazz.getName() +
+							", setter method of property: " + propertyName
+						);
+					log.error(
+							"expected type: " + 
+							method.getParameterTypes()[0].getName() +
+							", actual value: " + 
+							( value==null ? null : value.getClass().getName() )
+						);
+					throw new PropertyAccessException(
+							iae, 
+							"IllegalArgumentException occurred while calling", 
+							true, 
+							clazz, 
+							propertyName
+						);
+				}
+			}
+		}
+
+		public Method getMethod() {
+			return method;
+		}
+
+		public String getMethodName() {
+			return method.getName();
+		}
+
+		Object readResolve() {
+			return createSetter(clazz, propertyName);
+		}
+
+		public String toString() {
+			return "BasicSetter(" + clazz.getName() + '.' + propertyName + ')';
+		}
+	}
+
+	public static final class BasicGetter implements Getter {
+		private Class clazz;
+		private final transient Method method;
+		private final String propertyName;
+
+		private BasicGetter(Class clazz, Method method, String propertyName) {
+			this.clazz=clazz;
+			this.method=method;
+			this.propertyName=propertyName;
+		}
+
+		public Object get(Object target) throws HibernateException {
+			try {
+				return method.invoke(target, null);
+			}
+			catch (InvocationTargetException ite) {
+				throw new PropertyAccessException(
+						ite, 
+						"Exception occurred inside", 
+						false, 
+						clazz, 
+						propertyName
+					);
+			}
+			catch (IllegalAccessException iae) {
+				throw new PropertyAccessException(
+						iae, 
+						"IllegalAccessException occurred while calling", 
+						false, 
+						clazz, 
+						propertyName
+					);
+				//cannot occur
+			}
+			catch (IllegalArgumentException iae) {
+				log.error(
+						"IllegalArgumentException in class: " + clazz.getName() +
+						", getter method of property: " + propertyName
+					);
+				throw new PropertyAccessException(
+						iae, 
+						"IllegalArgumentException occurred calling", 
+						false, 
+						clazz, 
+						propertyName
+					);
+			}
+		}
+
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
+			return get( target );
+		}
+
+		public Class getReturnType() {
+			return method.getReturnType();
+		}
+
+		public Method getMethod() {
+			return method;
+		}
+
+		public String getMethodName() {
+			return method.getName();
+		}
+
+		public String toString() {
+			return "BasicGetter(" + clazz.getName() + '.' + propertyName + ')';
+		}
+		
+		Object readResolve() {
+			return createGetter(clazz, propertyName);
+		}
+	}
+
+
+	public Setter getSetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		return createSetter(theClass, propertyName);
+	}
+	
+	private static Setter createSetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		BasicSetter result = getSetterOrNull(theClass, propertyName);
+		if (result==null) {
+			throw new PropertyNotFoundException( 
+					"Could not find a setter for property " + 
+					propertyName + 
+					" in class " + 
+					theClass.getName() 
+				);
+		}
+		return result;
+	}
+
+	private static BasicSetter getSetterOrNull(Class theClass, String propertyName) {
+
+		if (theClass==Object.class || theClass==null) return null;
+
+		Method method = setterMethod(theClass, propertyName);
+
+		if (method!=null) {
+			if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
+			return new BasicSetter(theClass, method, propertyName);
+		}
+		else {
+			BasicSetter setter = getSetterOrNull( theClass.getSuperclass(), propertyName );
+			if (setter==null) {
+				Class[] interfaces = theClass.getInterfaces();
+				for ( int i=0; setter==null && i<interfaces.length; i++ ) {
+					setter=getSetterOrNull( interfaces[i], propertyName );
+				}
+			}
+			return setter;
+		}
+
+	}
+
+	private static Method setterMethod(Class theClass, String propertyName) {
+
+		BasicGetter getter = getGetterOrNull(theClass, propertyName);
+		Class returnType = (getter==null) ? null : getter.getReturnType();
+
+		Method[] methods = theClass.getDeclaredMethods();
+		Method potentialSetter = null;
+		for (int i=0; i<methods.length; i++) {
+			String methodName = methods[i].getName();
+
+			if ( methods[i].getParameterTypes().length==1 && methodName.startsWith("set") ) {
+				String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
+				String testOldMethod = methodName.substring(3);
+				if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
+					potentialSetter = methods[i];
+					if ( returnType==null || methods[i].getParameterTypes()[0].equals(returnType) ) {
+						return potentialSetter;
+					}
+				}
+			}
+		}
+		return potentialSetter;
+	}
+
+	public Getter getGetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		return createGetter(theClass, propertyName);
+	}
+	
+	public static Getter createGetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		BasicGetter result = getGetterOrNull(theClass, propertyName);
+		if (result==null) {
+			throw new PropertyNotFoundException( 
+					"Could not find a getter for " + 
+					propertyName + 
+					" in class " + 
+					theClass.getName() 
+			);
+		}
+		return result;
+
+	}
+
+	private static BasicGetter getGetterOrNull(Class theClass, String propertyName) {
+
+		if (theClass==Object.class || theClass==null) return null;
+
+		Method method = getterMethod(theClass, propertyName);
+
+		if (method!=null) {
+			if ( !ReflectHelper.isPublic(theClass, method) ) method.setAccessible(true);
+			return new BasicGetter(theClass, method, propertyName);
+		}
+		else {
+			BasicGetter getter = getGetterOrNull( theClass.getSuperclass(), propertyName );
+			if (getter==null) {
+				Class[] interfaces = theClass.getInterfaces();
+				for ( int i=0; getter==null && i<interfaces.length; i++ ) {
+					getter=getGetterOrNull( interfaces[i], propertyName );
+				}
+			}
+			return getter;
+		}
+	}
+
+	private static Method getterMethod(Class theClass, String propertyName) {
+
+		Method[] methods = theClass.getDeclaredMethods();
+		for (int i=0; i<methods.length; i++) {
+			// only carry on if the method has no parameters
+			if ( methods[i].getParameterTypes().length == 0 ) {
+				String methodName = methods[i].getName();
+
+				// try "get"
+				if ( methodName.startsWith("get") ) {
+					String testStdMethod = Introspector.decapitalize( methodName.substring(3) );
+					String testOldMethod = methodName.substring(3);
+					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
+						return methods[i];
+					}
+
+				}
+
+				// if not "get", then try "is"
+				if ( methodName.startsWith("is") ) {
+					String testStdMethod = Introspector.decapitalize( methodName.substring(2) );
+					String testOldMethod = methodName.substring(2);
+					if ( testStdMethod.equals(propertyName) || testOldMethod.equals(propertyName) ) {
+						return methods[i];
+					}
+				}
+			}
+		}
+		return null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +0,0 @@
-package org.hibernate.property;
-
-import org.hibernate.PropertyNotFoundException;
-
-/**
- * @author max
- *
- */
-public class ChainedPropertyAccessor implements PropertyAccessor {
-
-	final PropertyAccessor[] chain;
-	
-	public ChainedPropertyAccessor(PropertyAccessor[] chain) {
-		this.chain = chain;
-	}
-	
-	public Getter getGetter(Class theClass, String propertyName)
-			throws PropertyNotFoundException {
-		Getter result = null;
-		for (int i = 0; i < chain.length; i++) {
-			PropertyAccessor candidate = chain[i];
-			try {
-				result = candidate.getGetter(theClass, propertyName);
-				return result;
-			} catch (PropertyNotFoundException pnfe) {
-				// ignore
-			}
-		}
-		throw new PropertyNotFoundException("Could not find getter for " + propertyName + " on " + theClass);
-	}
-
-	public Setter getSetter(Class theClass, String propertyName)
-			throws PropertyNotFoundException {
-		Setter result = null;
-		for (int i = 0; i < chain.length; i++) {
-			PropertyAccessor candidate = chain[i];
-			try {
-				result = candidate.getSetter(theClass, propertyName);
-				return result;
-			} catch (PropertyNotFoundException pnfe) {
-				//
-			}
-		}
-		throw new PropertyNotFoundException("Could not find setter for " + propertyName + " on " + theClass);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/ChainedPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.property;
+
+import org.hibernate.PropertyNotFoundException;
+
+/**
+ * @author max
+ *
+ */
+public class ChainedPropertyAccessor implements PropertyAccessor {
+
+	final PropertyAccessor[] chain;
+	
+	public ChainedPropertyAccessor(PropertyAccessor[] chain) {
+		this.chain = chain;
+	}
+	
+	public Getter getGetter(Class theClass, String propertyName)
+			throws PropertyNotFoundException {
+		Getter result = null;
+		for (int i = 0; i < chain.length; i++) {
+			PropertyAccessor candidate = chain[i];
+			try {
+				result = candidate.getGetter(theClass, propertyName);
+				return result;
+			} catch (PropertyNotFoundException pnfe) {
+				// ignore
+			}
+		}
+		throw new PropertyNotFoundException("Could not find getter for " + propertyName + " on " + theClass);
+	}
+
+	public Setter getSetter(Class theClass, String propertyName)
+			throws PropertyNotFoundException {
+		Setter result = null;
+		for (int i = 0; i < chain.length; i++) {
+			PropertyAccessor candidate = chain[i];
+			try {
+				result = candidate.getSetter(theClass, propertyName);
+				return result;
+			} catch (PropertyNotFoundException pnfe) {
+				//
+			}
+		}
+		throw new PropertyNotFoundException("Could not find setter for " + propertyName + " on " + theClass);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,145 +0,0 @@
-//$Id: DirectPropertyAccessor.java 11412 2007-04-17 14:38:51Z max.andersen at jboss.com $
-package org.hibernate.property;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyAccessException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Accesses fields directly.
- * @author Gavin King
- */
-public class DirectPropertyAccessor implements PropertyAccessor {
-
-	public static final class DirectGetter implements Getter {
-		private final transient Field field;
-		private final Class clazz;
-		private final String name;
-		DirectGetter(Field field, Class clazz, String name) {
-			this.field = field;
-			this.clazz = clazz;
-			this.name = name;
-		}
-		public Object get(Object target) throws HibernateException {
-			try {
-				return field.get(target);
-			}
-			catch (Exception e) {
-				throw new PropertyAccessException(e, "could not get a field value by reflection", false, clazz, name);
-			}
-		}
-
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
-			return get( target );
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-		public String getMethodName() {
-			return null;
-		}
-		public Class getReturnType() {
-			return field.getType();
-		}
-
-		Object readResolve() {
-			return new DirectGetter( getField(clazz, name), clazz, name );
-		}
-		
-		public String toString() {
-			return "DirectGetter(" + clazz.getName() + '.' + name + ')';
-		}
-	}
-
-	public static final class DirectSetter implements Setter {
-		private final transient Field field;
-		private final Class clazz;
-		private final String name;
-		DirectSetter(Field field, Class clazz, String name) {
-			this.field = field;
-			this.clazz = clazz;
-			this.name = name;
-		}
-		public Method getMethod() {
-			return null;
-		}
-		public String getMethodName() {
-			return null;
-		}
-		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {
-			try {
-				field.set(target, value);
-			}
-			catch (Exception e) {
-				if(value == null && field.getType().isPrimitive()) {
-					throw new PropertyAccessException(
-							e, 
-							"Null value was assigned to a property of primitive type", 
-							true, 
-							clazz, 
-							name
-						);					
-				} else {
-					throw new PropertyAccessException(e, "could not set a field value by reflection", true, clazz, name);
-				}
-			}
-		}
-
-		public String toString() {
-			return "DirectSetter(" + clazz.getName() + '.' + name + ')';
-		}
-		
-		Object readResolve() {
-			return new DirectSetter( getField(clazz, name), clazz, name );
-		}
-	}
-
-	private static Field getField(Class clazz, String name) throws PropertyNotFoundException {
-		if ( clazz==null || clazz==Object.class ) {
-			throw new PropertyNotFoundException("field not found: " + name); 
-		}
-		Field field;
-		try {
-			field = clazz.getDeclaredField(name);
-		}
-		catch (NoSuchFieldException nsfe) {
-			field = getField( clazz, clazz.getSuperclass(), name );
-		}
-		if ( !ReflectHelper.isPublic(clazz, field) ) field.setAccessible(true);
-		return field;
-	}
-
-	private static Field getField(Class root, Class clazz, String name) throws PropertyNotFoundException {
-		if ( clazz==null || clazz==Object.class ) {
-			throw new PropertyNotFoundException("field [" + name + "] not found on " + root.getName()); 
-		}
-		Field field;
-		try {
-			field = clazz.getDeclaredField(name);
-		}
-		catch (NoSuchFieldException nsfe) {
-			field = getField( root, clazz.getSuperclass(), name );
-		}
-		if ( !ReflectHelper.isPublic(clazz, field) ) field.setAccessible(true);
-		return field;
-	}
-	
-	public Getter getGetter(Class theClass, String propertyName)
-		throws PropertyNotFoundException {
-		return new DirectGetter( getField(theClass, propertyName), theClass, propertyName );
-	}
-
-	public Setter getSetter(Class theClass, String propertyName)
-		throws PropertyNotFoundException {
-		return new DirectSetter( getField(theClass, propertyName), theClass, propertyName );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/DirectPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,168 @@
+/*
+ * 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.property;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyAccessException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Accesses fields directly.
+ * @author Gavin King
+ */
+public class DirectPropertyAccessor implements PropertyAccessor {
+
+	public static final class DirectGetter implements Getter {
+		private final transient Field field;
+		private final Class clazz;
+		private final String name;
+		DirectGetter(Field field, Class clazz, String name) {
+			this.field = field;
+			this.clazz = clazz;
+			this.name = name;
+		}
+		public Object get(Object target) throws HibernateException {
+			try {
+				return field.get(target);
+			}
+			catch (Exception e) {
+				throw new PropertyAccessException(e, "could not get a field value by reflection", false, clazz, name);
+			}
+		}
+
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
+			return get( target );
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+		public String getMethodName() {
+			return null;
+		}
+		public Class getReturnType() {
+			return field.getType();
+		}
+
+		Object readResolve() {
+			return new DirectGetter( getField(clazz, name), clazz, name );
+		}
+		
+		public String toString() {
+			return "DirectGetter(" + clazz.getName() + '.' + name + ')';
+		}
+	}
+
+	public static final class DirectSetter implements Setter {
+		private final transient Field field;
+		private final Class clazz;
+		private final String name;
+		DirectSetter(Field field, Class clazz, String name) {
+			this.field = field;
+			this.clazz = clazz;
+			this.name = name;
+		}
+		public Method getMethod() {
+			return null;
+		}
+		public String getMethodName() {
+			return null;
+		}
+		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {
+			try {
+				field.set(target, value);
+			}
+			catch (Exception e) {
+				if(value == null && field.getType().isPrimitive()) {
+					throw new PropertyAccessException(
+							e, 
+							"Null value was assigned to a property of primitive type", 
+							true, 
+							clazz, 
+							name
+						);					
+				} else {
+					throw new PropertyAccessException(e, "could not set a field value by reflection", true, clazz, name);
+				}
+			}
+		}
+
+		public String toString() {
+			return "DirectSetter(" + clazz.getName() + '.' + name + ')';
+		}
+		
+		Object readResolve() {
+			return new DirectSetter( getField(clazz, name), clazz, name );
+		}
+	}
+
+	private static Field getField(Class clazz, String name) throws PropertyNotFoundException {
+		if ( clazz==null || clazz==Object.class ) {
+			throw new PropertyNotFoundException("field not found: " + name); 
+		}
+		Field field;
+		try {
+			field = clazz.getDeclaredField(name);
+		}
+		catch (NoSuchFieldException nsfe) {
+			field = getField( clazz, clazz.getSuperclass(), name );
+		}
+		if ( !ReflectHelper.isPublic(clazz, field) ) field.setAccessible(true);
+		return field;
+	}
+
+	private static Field getField(Class root, Class clazz, String name) throws PropertyNotFoundException {
+		if ( clazz==null || clazz==Object.class ) {
+			throw new PropertyNotFoundException("field [" + name + "] not found on " + root.getName()); 
+		}
+		Field field;
+		try {
+			field = clazz.getDeclaredField(name);
+		}
+		catch (NoSuchFieldException nsfe) {
+			field = getField( root, clazz.getSuperclass(), name );
+		}
+		if ( !ReflectHelper.isPublic(clazz, field) ) field.setAccessible(true);
+		return field;
+	}
+	
+	public Getter getGetter(Class theClass, String propertyName)
+		throws PropertyNotFoundException {
+		return new DirectGetter( getField(theClass, propertyName), theClass, propertyName );
+	}
+
+	public Setter getSetter(Class theClass, String propertyName)
+		throws PropertyNotFoundException {
+		return new DirectSetter( getField(theClass, propertyName), theClass, propertyName );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/Dom4jAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,359 +0,0 @@
-// $Id: Dom4jAccessor.java 8063 2005-09-01 18:49:39Z oneovthafew $
-package org.hibernate.property;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.dom4j.Attribute;
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.CollectionType;
-import org.hibernate.type.Type;
-
-/**
- * Responsible for accessing property values represented as a dom4j Element
- * or Attribute.
- *
- * @author Steve Ebersole
- */
-public class Dom4jAccessor implements PropertyAccessor {
-	private String nodeName;
-	private Type propertyType;
-	private final SessionFactoryImplementor factory;
-
-	public Dom4jAccessor(String nodeName, Type propertyType, SessionFactoryImplementor factory) {
-		this.factory = factory;
-		this.nodeName = nodeName;
-		this.propertyType = propertyType;
-		
-	}
-
-	/**
-	 * Create a "getter" for the named attribute
-	 */
-	public Getter getGetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		if (nodeName==null) {
-			throw new MappingException("no node name for property: " + propertyName);
-		}
-		if ( ".".equals(nodeName) ) {
-			return new TextGetter(propertyType, factory);
-		}
-		else if ( nodeName.indexOf('/')>-1 ) {
-			return new ElementAttributeGetter(nodeName, propertyType, factory);
-		}
-		else if ( nodeName.indexOf('@')>-1 ) {
-			return new AttributeGetter(nodeName, propertyType, factory);
-		}
-		else {
-			return new ElementGetter(nodeName, propertyType, factory);
-		}
-	}
-
-	/**
-	 * Create a "setter" for the named attribute
-	 */
-	public Setter getSetter(Class theClass, String propertyName) 
-	throws PropertyNotFoundException {
-		if (nodeName==null) {
-			throw new MappingException("no node name for property: " + propertyName);
-		}
-		if ( ".".equals(nodeName) ) {
-			return new TextSetter(propertyType);
-		}
-		else if ( nodeName.indexOf('/')>-1 ) {
-			return new ElementAttributeSetter(nodeName, propertyType);
-		}
-		else if ( nodeName.indexOf('@')>-1 ) {
-			return new AttributeSetter(nodeName, propertyType);
-		}
-		else {
-			return new ElementSetter(nodeName, propertyType);
-		}
-	}
-
-	/**
-	 * Defines the strategy for getting property values out of a dom4j Node.
-	 */
-	public abstract static class Dom4jGetter implements Getter {
-		protected final Type propertyType;
-		protected final SessionFactoryImplementor factory;
-		
-		Dom4jGetter(Type propertyType, SessionFactoryImplementor factory) {
-			this.propertyType = propertyType;
-			this.factory = factory;
-		}
-		
-		public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) 
-		throws HibernateException {
-			return get( owner );
-		}
-
-		/**
-		 * Get the declared Java type
-		 */
-		public Class getReturnType() {
-			return Object.class;
-		}
-
-		/**
-		 * Optional operation (return null)
-		 */
-		public String getMethodName() {
-			return null;
-		}
-
-		/**
-		 * Optional operation (return null)
-		 */
-		public Method getMethod() {
-			return null;
-		}
-	}
-
-	public abstract static class Dom4jSetter implements Setter {
-		protected final Type propertyType;
-
-		Dom4jSetter(Type propertyType) {
-			this.propertyType = propertyType;
-		}
-		
-		/**
-		 * Optional operation (return null)
-		 */
-		public String getMethodName() {
-			return null;
-		}
-
-		/**
-		 * Optional operation (return null)
-		 */
-		public Method getMethod() {
-			return null;
-		}
-	}
-	
-	/**
-	 * For nodes like <tt>"."</tt>
-	 * @author Gavin King
-	 */
-	public static class TextGetter extends Dom4jGetter {
-		
-		TextGetter(Type propertyType, SessionFactoryImplementor factory) {
-			super(propertyType, factory);
-		}
-
-		public Object get(Object owner) throws HibernateException {
-			Element ownerElement = (Element) owner;
-			return super.propertyType.fromXMLNode(ownerElement, super.factory);
-		}	
-		
-	}
-	
-	/**
-	 * For nodes like <tt>"@bar"</tt>
-	 * @author Gavin King
-	 */
-	public static class AttributeGetter extends Dom4jGetter {
-		private final String attributeName;
-		
-		AttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
-			super(propertyType, factory);
-			attributeName = name.substring(1);
-		}
-
-		public Object get(Object owner) throws HibernateException {
-			Element ownerElement = (Element) owner;
-			Node attribute = ownerElement.attribute(attributeName);
-			return attribute==null ? null : 
-				super.propertyType.fromXMLNode(attribute, super.factory);
-		}	
-		
-	}
-
-	/**
-	 * For nodes like <tt>"foo"</tt>
-	 * @author Gavin King
-	 */
-	public static class ElementGetter extends Dom4jGetter {
-		private final String elementName;
-		
-		ElementGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
-			super(propertyType, factory);
-			elementName = name;
-		}
-
-		public Object get(Object owner) throws HibernateException {
-			Element ownerElement = (Element) owner;
-			Node element = ownerElement.element(elementName);
-			return element==null ? 
-					null : super.propertyType.fromXMLNode(element, super.factory);
-		}	
-		
-	}
-	
-	/**
-	 * For nodes like <tt>"foo/@bar"</tt>
-	 * @author Gavin King
-	 */
-	public static class ElementAttributeGetter extends Dom4jGetter {
-		private final String elementName;
-		private final String attributeName;
-		
-		ElementAttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
-			super(propertyType, factory);
-			elementName = name.substring( 0, name.indexOf('/') );
-			attributeName = name.substring( name.indexOf('/')+2 );
-		}
-
-		public Object get(Object owner) throws HibernateException {
-			Element ownerElement = (Element) owner;
-			
-			Element element = ownerElement.element(elementName);
-			
-			if ( element==null ) {
-				return null;
-			}
-			else {
-				Attribute attribute = element.attribute(attributeName);
-				if (attribute==null) {
-					return null;
-				}
-				else {
-					return super.propertyType.fromXMLNode(attribute, super.factory);
-				}
-			}
-		}
-	}
-	
-	
-	/**
-	 * For nodes like <tt>"."</tt>
-	 * @author Gavin King
-	 */
-	public static class TextSetter extends Dom4jSetter {
-		
-		TextSetter(Type propertyType) {
-			super(propertyType);
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) 
-		throws HibernateException {
-			Element owner = ( Element ) target;
-			if ( !super.propertyType.isXMLElement() ) { //kinda ugly, but needed for collections with a "." node mapping
-				if (value==null) {
-					owner.setText(null); //is this ok?
-				}
-				else {
-					super.propertyType.setToXMLNode(owner, value, factory);
-				}
-			}
-		}
-
-	}
-	
-	/**
-	 * For nodes like <tt>"@bar"</tt>
-	 * @author Gavin King
-	 */
-	public static class AttributeSetter extends Dom4jSetter {
-		private final String attributeName;
-		
-		AttributeSetter(String name, Type propertyType) {
-			super(propertyType);
-			attributeName = name.substring(1);
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) 
-		throws HibernateException {
-			Element owner = ( Element ) target;
-			Attribute attribute = owner.attribute(attributeName);
-			if (value==null) {
-				if (attribute!=null) attribute.detach();
-			}
-			else {
-				if (attribute==null) {
-					owner.addAttribute(attributeName, "null");
-					attribute = owner.attribute(attributeName);
-				}
-				super.propertyType.setToXMLNode(attribute, value, factory);
-			}
-		}
-
-	}
-	
-	/**
-	 * For nodes like <tt>"foo"</tt>
-	 * @author Gavin King
-	 */
-	public static class ElementSetter extends Dom4jSetter {
-		private final String elementName;
-		
-		ElementSetter(String name, Type propertyType) {
-			super(propertyType);
-			elementName = name;
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) 
-		throws HibernateException {
-			if (value!=CollectionType.UNFETCHED_COLLECTION) {
-				Element owner = ( Element ) target;
-				Element existing = owner.element(elementName);
-				if (existing!=null) existing.detach();
-				if (value!=null) {
-					Element element = owner.addElement(elementName);
-					super.propertyType.setToXMLNode(element, value, factory);
-				}
-			}
-		}
-
-	}
-	
-	/**
-	 * For nodes like <tt>"foo/@bar"</tt>
-	 * @author Gavin King
-	 */
-	public static class ElementAttributeSetter extends Dom4jSetter {
-		private final String elementName;
-		private final String attributeName;
-		
-		ElementAttributeSetter(String name, Type propertyType) {
-			super(propertyType);
-			elementName = name.substring( 0, name.indexOf('/') );
-			attributeName = name.substring( name.indexOf('/')+2 );
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) 
-		throws HibernateException {
-			Element owner = ( Element ) target;
-			Element element = owner.element(elementName);
-			if (value==null) {
-				if (element!=null) element.detach();
-			}
-			else {
-				Attribute attribute;
-				if (element==null) {
-					element = owner.addElement(elementName);
-					attribute = null;
-				}
-				else {
-					attribute = element.attribute(attributeName);
-				}
-				
-				if (attribute==null) {
-					element.addAttribute(attributeName, "null");
-					attribute = element.attribute(attributeName);
-				}				
-				super.propertyType.setToXMLNode(attribute, value, factory);
-			}
-		}
-
-	}
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/Dom4jAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Dom4jAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,382 @@
+/*
+ * 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.property;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.dom4j.Attribute;
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.CollectionType;
+import org.hibernate.type.Type;
+
+/**
+ * Responsible for accessing property values represented as a dom4j Element
+ * or Attribute.
+ *
+ * @author Steve Ebersole
+ */
+public class Dom4jAccessor implements PropertyAccessor {
+	private String nodeName;
+	private Type propertyType;
+	private final SessionFactoryImplementor factory;
+
+	public Dom4jAccessor(String nodeName, Type propertyType, SessionFactoryImplementor factory) {
+		this.factory = factory;
+		this.nodeName = nodeName;
+		this.propertyType = propertyType;
+		
+	}
+
+	/**
+	 * Create a "getter" for the named attribute
+	 */
+	public Getter getGetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		if (nodeName==null) {
+			throw new MappingException("no node name for property: " + propertyName);
+		}
+		if ( ".".equals(nodeName) ) {
+			return new TextGetter(propertyType, factory);
+		}
+		else if ( nodeName.indexOf('/')>-1 ) {
+			return new ElementAttributeGetter(nodeName, propertyType, factory);
+		}
+		else if ( nodeName.indexOf('@')>-1 ) {
+			return new AttributeGetter(nodeName, propertyType, factory);
+		}
+		else {
+			return new ElementGetter(nodeName, propertyType, factory);
+		}
+	}
+
+	/**
+	 * Create a "setter" for the named attribute
+	 */
+	public Setter getSetter(Class theClass, String propertyName) 
+	throws PropertyNotFoundException {
+		if (nodeName==null) {
+			throw new MappingException("no node name for property: " + propertyName);
+		}
+		if ( ".".equals(nodeName) ) {
+			return new TextSetter(propertyType);
+		}
+		else if ( nodeName.indexOf('/')>-1 ) {
+			return new ElementAttributeSetter(nodeName, propertyType);
+		}
+		else if ( nodeName.indexOf('@')>-1 ) {
+			return new AttributeSetter(nodeName, propertyType);
+		}
+		else {
+			return new ElementSetter(nodeName, propertyType);
+		}
+	}
+
+	/**
+	 * Defines the strategy for getting property values out of a dom4j Node.
+	 */
+	public abstract static class Dom4jGetter implements Getter {
+		protected final Type propertyType;
+		protected final SessionFactoryImplementor factory;
+		
+		Dom4jGetter(Type propertyType, SessionFactoryImplementor factory) {
+			this.propertyType = propertyType;
+			this.factory = factory;
+		}
+		
+		public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) 
+		throws HibernateException {
+			return get( owner );
+		}
+
+		/**
+		 * Get the declared Java type
+		 */
+		public Class getReturnType() {
+			return Object.class;
+		}
+
+		/**
+		 * Optional operation (return null)
+		 */
+		public String getMethodName() {
+			return null;
+		}
+
+		/**
+		 * Optional operation (return null)
+		 */
+		public Method getMethod() {
+			return null;
+		}
+	}
+
+	public abstract static class Dom4jSetter implements Setter {
+		protected final Type propertyType;
+
+		Dom4jSetter(Type propertyType) {
+			this.propertyType = propertyType;
+		}
+		
+		/**
+		 * Optional operation (return null)
+		 */
+		public String getMethodName() {
+			return null;
+		}
+
+		/**
+		 * Optional operation (return null)
+		 */
+		public Method getMethod() {
+			return null;
+		}
+	}
+	
+	/**
+	 * For nodes like <tt>"."</tt>
+	 * @author Gavin King
+	 */
+	public static class TextGetter extends Dom4jGetter {
+		
+		TextGetter(Type propertyType, SessionFactoryImplementor factory) {
+			super(propertyType, factory);
+		}
+
+		public Object get(Object owner) throws HibernateException {
+			Element ownerElement = (Element) owner;
+			return super.propertyType.fromXMLNode(ownerElement, super.factory);
+		}	
+		
+	}
+	
+	/**
+	 * For nodes like <tt>"@bar"</tt>
+	 * @author Gavin King
+	 */
+	public static class AttributeGetter extends Dom4jGetter {
+		private final String attributeName;
+		
+		AttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
+			super(propertyType, factory);
+			attributeName = name.substring(1);
+		}
+
+		public Object get(Object owner) throws HibernateException {
+			Element ownerElement = (Element) owner;
+			Node attribute = ownerElement.attribute(attributeName);
+			return attribute==null ? null : 
+				super.propertyType.fromXMLNode(attribute, super.factory);
+		}	
+		
+	}
+
+	/**
+	 * For nodes like <tt>"foo"</tt>
+	 * @author Gavin King
+	 */
+	public static class ElementGetter extends Dom4jGetter {
+		private final String elementName;
+		
+		ElementGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
+			super(propertyType, factory);
+			elementName = name;
+		}
+
+		public Object get(Object owner) throws HibernateException {
+			Element ownerElement = (Element) owner;
+			Node element = ownerElement.element(elementName);
+			return element==null ? 
+					null : super.propertyType.fromXMLNode(element, super.factory);
+		}	
+		
+	}
+	
+	/**
+	 * For nodes like <tt>"foo/@bar"</tt>
+	 * @author Gavin King
+	 */
+	public static class ElementAttributeGetter extends Dom4jGetter {
+		private final String elementName;
+		private final String attributeName;
+		
+		ElementAttributeGetter(String name, Type propertyType, SessionFactoryImplementor factory) {
+			super(propertyType, factory);
+			elementName = name.substring( 0, name.indexOf('/') );
+			attributeName = name.substring( name.indexOf('/')+2 );
+		}
+
+		public Object get(Object owner) throws HibernateException {
+			Element ownerElement = (Element) owner;
+			
+			Element element = ownerElement.element(elementName);
+			
+			if ( element==null ) {
+				return null;
+			}
+			else {
+				Attribute attribute = element.attribute(attributeName);
+				if (attribute==null) {
+					return null;
+				}
+				else {
+					return super.propertyType.fromXMLNode(attribute, super.factory);
+				}
+			}
+		}
+	}
+	
+	
+	/**
+	 * For nodes like <tt>"."</tt>
+	 * @author Gavin King
+	 */
+	public static class TextSetter extends Dom4jSetter {
+		
+		TextSetter(Type propertyType) {
+			super(propertyType);
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) 
+		throws HibernateException {
+			Element owner = ( Element ) target;
+			if ( !super.propertyType.isXMLElement() ) { //kinda ugly, but needed for collections with a "." node mapping
+				if (value==null) {
+					owner.setText(null); //is this ok?
+				}
+				else {
+					super.propertyType.setToXMLNode(owner, value, factory);
+				}
+			}
+		}
+
+	}
+	
+	/**
+	 * For nodes like <tt>"@bar"</tt>
+	 * @author Gavin King
+	 */
+	public static class AttributeSetter extends Dom4jSetter {
+		private final String attributeName;
+		
+		AttributeSetter(String name, Type propertyType) {
+			super(propertyType);
+			attributeName = name.substring(1);
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) 
+		throws HibernateException {
+			Element owner = ( Element ) target;
+			Attribute attribute = owner.attribute(attributeName);
+			if (value==null) {
+				if (attribute!=null) attribute.detach();
+			}
+			else {
+				if (attribute==null) {
+					owner.addAttribute(attributeName, "null");
+					attribute = owner.attribute(attributeName);
+				}
+				super.propertyType.setToXMLNode(attribute, value, factory);
+			}
+		}
+
+	}
+	
+	/**
+	 * For nodes like <tt>"foo"</tt>
+	 * @author Gavin King
+	 */
+	public static class ElementSetter extends Dom4jSetter {
+		private final String elementName;
+		
+		ElementSetter(String name, Type propertyType) {
+			super(propertyType);
+			elementName = name;
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) 
+		throws HibernateException {
+			if (value!=CollectionType.UNFETCHED_COLLECTION) {
+				Element owner = ( Element ) target;
+				Element existing = owner.element(elementName);
+				if (existing!=null) existing.detach();
+				if (value!=null) {
+					Element element = owner.addElement(elementName);
+					super.propertyType.setToXMLNode(element, value, factory);
+				}
+			}
+		}
+
+	}
+	
+	/**
+	 * For nodes like <tt>"foo/@bar"</tt>
+	 * @author Gavin King
+	 */
+	public static class ElementAttributeSetter extends Dom4jSetter {
+		private final String elementName;
+		private final String attributeName;
+		
+		ElementAttributeSetter(String name, Type propertyType) {
+			super(propertyType);
+			elementName = name.substring( 0, name.indexOf('/') );
+			attributeName = name.substring( name.indexOf('/')+2 );
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) 
+		throws HibernateException {
+			Element owner = ( Element ) target;
+			Element element = owner.element(elementName);
+			if (value==null) {
+				if (element!=null) element.detach();
+			}
+			else {
+				Attribute attribute;
+				if (element==null) {
+					element = owner.addElement(elementName);
+					attribute = null;
+				}
+				else {
+					attribute = element.attribute(attributeName);
+				}
+				
+				if (attribute==null) {
+					element.addAttribute(attributeName, "null");
+					attribute = element.attribute(attributeName);
+				}				
+				super.propertyType.setToXMLNode(attribute, value, factory);
+			}
+		}
+
+	}
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,83 +0,0 @@
-//$Id: EmbeddedPropertyAccessor.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.property;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * @author Gavin King
- */
-public class EmbeddedPropertyAccessor implements PropertyAccessor {
-	
-	public static final class EmbeddedGetter implements Getter {
-		
-		private final Class clazz;
-		
-		EmbeddedGetter(Class clazz) {
-			this.clazz = clazz;
-		}
-		
-		public Object get(Object target) throws HibernateException {
-			return target;
-		}
-		
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
-			return get( target );
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public Class getReturnType() {
-			return clazz;
-		}
-		
-		public String toString() {
-			return "EmbeddedGetter(" + clazz.getName() + ')';
-		}
-	}
-
-	public static final class EmbeddedSetter implements Setter {
-		
-		private final Class clazz;
-		
-		EmbeddedSetter(Class clazz) {
-			this.clazz = clazz;
-		}
-		
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {}
-		
-		public String toString() {
-			return "EmbeddedSetter(" + clazz.getName() + ')';
-		}
-	}
-
-	public Getter getGetter(Class theClass, String propertyName)
-	throws PropertyNotFoundException {
-		return new EmbeddedGetter(theClass);
-	}
-
-	public Setter getSetter(Class theClass, String propertyName)
-	throws PropertyNotFoundException {
-		return new EmbeddedSetter(theClass);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/EmbeddedPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,106 @@
+/*
+ * 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.property;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class EmbeddedPropertyAccessor implements PropertyAccessor {
+	
+	public static final class EmbeddedGetter implements Getter {
+		
+		private final Class clazz;
+		
+		EmbeddedGetter(Class clazz) {
+			this.clazz = clazz;
+		}
+		
+		public Object get(Object target) throws HibernateException {
+			return target;
+		}
+		
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
+			return get( target );
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public Class getReturnType() {
+			return clazz;
+		}
+		
+		public String toString() {
+			return "EmbeddedGetter(" + clazz.getName() + ')';
+		}
+	}
+
+	public static final class EmbeddedSetter implements Setter {
+		
+		private final Class clazz;
+		
+		EmbeddedSetter(Class clazz) {
+			this.clazz = clazz;
+		}
+		
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {}
+		
+		public String toString() {
+			return "EmbeddedSetter(" + clazz.getName() + ')';
+		}
+	}
+
+	public Getter getGetter(Class theClass, String propertyName)
+	throws PropertyNotFoundException {
+		return new EmbeddedGetter(theClass);
+	}
+
+	public Setter getSetter(Class theClass, String propertyName)
+	throws PropertyNotFoundException {
+		return new EmbeddedSetter(theClass);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/Getter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-//$Id: Getter.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.property;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Gets values of a particular property
- *
- * @author Gavin King
- */
-public interface Getter extends Serializable {
-	/**
-	 * Get the property value from the given instance .
-	 * @param owner The instance containing the value to be retreived.
-	 * @return The extracted value.
-	 * @throws HibernateException
-	 */
-	public Object get(Object owner) throws HibernateException;
-
-	/**
-	 * Get the property value from the given owner instance.
-	 *
-	 * @param owner The instance containing the value to be retreived.
-	 * @param mergeMap a map of merged persistent instances to detached instances
-	 * @param session The session from which this request originated.
-	 * @return The extracted value.
-	 * @throws HibernateException
-	 */
-	public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) 
-	throws HibernateException;
-
-	/**
-	 * Get the declared Java type
-	 */
-	public Class getReturnType();
-
-	/**
-	 * Optional operation (return null)
-	 */
-	public String getMethodName();
-
-	/**
-	 * Optional operation (return null)
-	 */
-	public Method getMethod();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/Getter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Getter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.property;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Gets values of a particular property
+ *
+ * @author Gavin King
+ */
+public interface Getter extends Serializable {
+	/**
+	 * Get the property value from the given instance .
+	 * @param owner The instance containing the value to be retreived.
+	 * @return The extracted value.
+	 * @throws HibernateException
+	 */
+	public Object get(Object owner) throws HibernateException;
+
+	/**
+	 * Get the property value from the given owner instance.
+	 *
+	 * @param owner The instance containing the value to be retreived.
+	 * @param mergeMap a map of merged persistent instances to detached instances
+	 * @param session The session from which this request originated.
+	 * @return The extracted value.
+	 * @throws HibernateException
+	 */
+	public Object getForInsert(Object owner, Map mergeMap, SessionImplementor session) 
+	throws HibernateException;
+
+	/**
+	 * Get the declared Java type
+	 */
+	public Class getReturnType();
+
+	/**
+	 * Optional operation (return null)
+	 */
+	public String getMethodName();
+
+	/**
+	 * Optional operation (return null)
+	 */
+	public Method getMethod();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,95 +0,0 @@
-//$Id: IndexPropertyAccessor.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.property;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Represents a "back-reference" to the index of a collection.
- *
- * @author Gavin King
- */
-public class IndexPropertyAccessor implements PropertyAccessor {
-	
-	private final String propertyName;
-	private final String entityName;
-
-	/**
-	 * Constructs a new instance of IndexPropertyAccessor.
-	 *
-	 * @param collectionRole The collection role which this back ref references.
-	 */
-	public IndexPropertyAccessor(String collectionRole, String entityName) {
-		this.propertyName = collectionRole.substring( entityName.length()+1 );
-		this.entityName = entityName;
-	}
-
-	public Setter getSetter(Class theClass, String propertyName) {
-		return new IndexSetter();
-	}
-
-	public Getter getGetter(Class theClass, String propertyName) {
-		return new IndexGetter();
-	}
-
-
-	/**
-	 * The Setter implementation for index backrefs.
-	 */
-	public static final class IndexSetter implements Setter {
-
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public void set(Object target, Object value) {
-			// do nothing...
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {
-			// do nothing...
-		}
-
-	}
-
-
-	/**
-	 * The Getter implementation for index backrefs.
-	 */
-	public class IndexGetter implements Getter {
-		
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException {
-			if (session==null) {
-				return BackrefPropertyAccessor.UNKNOWN;
-			}
-			else {
-				return session.getPersistenceContext()
-						.getIndexInOwner(entityName, propertyName, target, mergeMap);
-			}
-		}
-
-		public Object get(Object target)  {
-			return BackrefPropertyAccessor.UNKNOWN;
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public Class getReturnType() {
-			return Object.class;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/IndexPropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,118 @@
+/*
+ * 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.property;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Represents a "back-reference" to the index of a collection.
+ *
+ * @author Gavin King
+ */
+public class IndexPropertyAccessor implements PropertyAccessor {
+	
+	private final String propertyName;
+	private final String entityName;
+
+	/**
+	 * Constructs a new instance of IndexPropertyAccessor.
+	 *
+	 * @param collectionRole The collection role which this back ref references.
+	 */
+	public IndexPropertyAccessor(String collectionRole, String entityName) {
+		this.propertyName = collectionRole.substring( entityName.length()+1 );
+		this.entityName = entityName;
+	}
+
+	public Setter getSetter(Class theClass, String propertyName) {
+		return new IndexSetter();
+	}
+
+	public Getter getGetter(Class theClass, String propertyName) {
+		return new IndexGetter();
+	}
+
+
+	/**
+	 * The Setter implementation for index backrefs.
+	 */
+	public static final class IndexSetter implements Setter {
+
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public void set(Object target, Object value) {
+			// do nothing...
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException {
+			// do nothing...
+		}
+
+	}
+
+
+	/**
+	 * The Getter implementation for index backrefs.
+	 */
+	public class IndexGetter implements Getter {
+		
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) throws HibernateException {
+			if (session==null) {
+				return BackrefPropertyAccessor.UNKNOWN;
+			}
+			else {
+				return session.getPersistenceContext()
+						.getIndexInOwner(entityName, propertyName, target, mergeMap);
+			}
+		}
+
+		public Object get(Object target)  {
+			return BackrefPropertyAccessor.UNKNOWN;
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public Class getReturnType() {
+			return Object.class;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/MapAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,80 +0,0 @@
-//$Id: MapAccessor.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.property;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * @author Gavin King
- */
-public class MapAccessor implements PropertyAccessor {
-
-	public Getter getGetter(Class theClass, String propertyName)
-		throws PropertyNotFoundException {
-		return new MapGetter(propertyName);
-	}
-
-	public Setter getSetter(Class theClass, String propertyName)
-		throws PropertyNotFoundException {
-		return new MapSetter(propertyName);
-	}
-
-	public static final class MapSetter implements Setter {
-
-		private String name;
-
-		MapSetter(String name) {
-			this.name = name;
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public void set(Object target, Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-			( (Map) target ).put(name, value);
-		}
-
-	}
-
-	public static final class MapGetter implements Getter {
-
-		private String name;
-
-		MapGetter(String name) {
-			this.name = name;
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public Object get(Object target) throws HibernateException {
-			return ( (Map) target ).get(name);
-		}
-
-		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
-			return get( target );
-		}
-
-		public Class getReturnType() {
-			return Object.class;
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/MapAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/MapAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.property;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class MapAccessor implements PropertyAccessor {
+
+	public Getter getGetter(Class theClass, String propertyName)
+		throws PropertyNotFoundException {
+		return new MapGetter(propertyName);
+	}
+
+	public Setter getSetter(Class theClass, String propertyName)
+		throws PropertyNotFoundException {
+		return new MapSetter(propertyName);
+	}
+
+	public static final class MapSetter implements Setter {
+
+		private String name;
+
+		MapSetter(String name) {
+			this.name = name;
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public void set(Object target, Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+			( (Map) target ).put(name, value);
+		}
+
+	}
+
+	public static final class MapGetter implements Getter {
+
+		private String name;
+
+		MapGetter(String name) {
+			this.name = name;
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public Object get(Object target) throws HibernateException {
+			return ( (Map) target ).get(name);
+		}
+
+		public Object getForInsert(Object target, Map mergeMap, SessionImplementor session) {
+			return get( target );
+		}
+
+		public Class getReturnType() {
+			return Object.class;
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/NoopAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,79 +0,0 @@
-package org.hibernate.property;
-
-import java.lang.reflect.Method;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.Setter;
-
-/**
- * Used to declare properties not represented at the pojo level
- * 
- * @author Michael Bartmann
- */
-public class NoopAccessor implements PropertyAccessor {
-
-	public Getter getGetter(Class arg0, String arg1) throws PropertyNotFoundException {
-		return new NoopGetter();
-	}
-
-	public Setter getSetter(Class arg0, String arg1) throws PropertyNotFoundException {
-		return new NoopSetter();
-	}
-
-	/**
-	 * A Getter which will always return null. It should not be called anyway.
-	 */
-	private static class NoopGetter implements Getter {
-
-		/**
-		 * @return always null
-		 */
-		public Object get(Object target) throws HibernateException {
-			return null;
-		}
-
-		public Object getForInsert(Object target, Map map, SessionImplementor arg1)
-				throws HibernateException {
-			return null;
-		}
-
-		public Class getReturnType() {
-			return Object.class;
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-	}
-
-	/**
-	 * A Setter which will just do nothing.
-	 */
-	private static class NoopSetter implements Setter {
-
-		public void set(Object target, Object value, SessionFactoryImplementor arg2)
-				throws HibernateException {
-			// do not do anything
-		}
-
-		public String getMethodName() {
-			return null;
-		}
-
-		public Method getMethod() {
-			return null;
-		}
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/NoopAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/NoopAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,100 @@
+/*
+ * 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.property;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Used to declare properties not represented at the pojo level
+ * 
+ * @author Michael Bartmann
+ */
+public class NoopAccessor implements PropertyAccessor {
+
+	public Getter getGetter(Class arg0, String arg1) throws PropertyNotFoundException {
+		return new NoopGetter();
+	}
+
+	public Setter getSetter(Class arg0, String arg1) throws PropertyNotFoundException {
+		return new NoopSetter();
+	}
+
+	/**
+	 * A Getter which will always return null. It should not be called anyway.
+	 */
+	private static class NoopGetter implements Getter {
+
+		/**
+		 * @return always null
+		 */
+		public Object get(Object target) throws HibernateException {
+			return null;
+		}
+
+		public Object getForInsert(Object target, Map map, SessionImplementor arg1)
+				throws HibernateException {
+			return null;
+		}
+
+		public Class getReturnType() {
+			return Object.class;
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+	}
+
+	/**
+	 * A Setter which will just do nothing.
+	 */
+	private static class NoopSetter implements Setter {
+
+		public void set(Object target, Object value, SessionFactoryImplementor arg2)
+				throws HibernateException {
+			// do not do anything
+		}
+
+		public String getMethodName() {
+			return null;
+		}
+
+		public Method getMethod() {
+			return null;
+		}
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/PropertyAccessor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-//$Id: PropertyAccessor.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.property;
-
-import org.hibernate.PropertyNotFoundException;
-
-/**
- * Abstracts the notion of a "property". Defines a strategy for accessing the
- * value of an attribute.
- * @author Gavin King
- */
-public interface PropertyAccessor {
-	/**
-	 * Create a "getter" for the named attribute
-	 */
-	public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException;
-	/**
-	 * Create a "setter" for the named attribute
-	 */
-	public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/PropertyAccessor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,43 @@
+/*
+ * 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.property;
+
+import org.hibernate.PropertyNotFoundException;
+
+/**
+ * Abstracts the notion of a "property". Defines a strategy for accessing the
+ * value of an attribute.
+ * @author Gavin King
+ */
+public interface PropertyAccessor {
+	/**
+	 * Create a "getter" for the named attribute
+	 */
+	public Getter getGetter(Class theClass, String propertyName) throws PropertyNotFoundException;
+	/**
+	 * Create a "setter" for the named attribute
+	 */
+	public Setter getSetter(Class theClass, String propertyName) throws PropertyNotFoundException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,135 +0,0 @@
-//$Id: PropertyAccessorFactory.java 8451 2005-10-24 08:45:37Z maxcsaucdk $
-package org.hibernate.property;
-
-import java.util.Map;
-
-import org.hibernate.MappingException;
-import org.hibernate.EntityMode;
-import org.hibernate.type.Type;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Property;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * A factory for building/retrieving PropertyAccessor instances.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public final class PropertyAccessorFactory {
-
-	private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
-	private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
-	private static final PropertyAccessor MAP_ACCESSOR = new MapAccessor();
-	private static final PropertyAccessor NOOP_ACCESSOR = new NoopAccessor();
-	private static final PropertyAccessor EMBEDDED_PROPERTY_ACCESSOR = new EmbeddedPropertyAccessor();
-
-	//TODO: ideally we need the construction of PropertyAccessor to take the following:
-	//      1) EntityMode
-	//      2) EntityMode-specific data (i.e., the classname for pojo entities)
-	//      3) Property-specific data based on the EntityMode (i.e., property-name or dom4j-node-name)
-	// The easiest way, with the introduction of the new runtime-metamodel classes, would be the
-	// the following predicates:
-	//      1) PropertyAccessorFactory.getPropertyAccessor() takes references to both a
-	//          org.hibernate.metadata.EntityModeMetadata and org.hibernate.metadata.Property
-	//      2) What is now termed a "PropertyAccessor" stores any values needed from those two
-	//          pieces of information
-	//      3) Code can then simply call PropertyAccess.getGetter() with no parameters; likewise with
-	//          PropertyAccessor.getSetter()
-
-    /**
-     * Retrieves a PropertyAccessor instance based on the given property definition and
-     * entity mode.
-     *
-     * @param property The property for which to retrieve an accessor.
-     * @param mode The mode for the resulting entity.
-     * @return An appropriate accessor.
-     * @throws MappingException
-     */
-	public static PropertyAccessor getPropertyAccessor(Property property, EntityMode mode) throws MappingException {
-		//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
-	    if ( null == mode || EntityMode.POJO.equals( mode ) ) {
-		    return getPojoPropertyAccessor( property.getPropertyAccessorName() );
-	    }
-	    else if ( EntityMode.MAP.equals( mode ) ) {
-		    return getDynamicMapPropertyAccessor();
-	    }
-	    else if ( EntityMode.DOM4J.equals( mode ) ) {
-	    	//TODO: passing null here, because this method is not really used for DOM4J at the moment
-	    	//      but it is still a bug, if we don't get rid of this!
-		    return getDom4jPropertyAccessor( property.getAccessorPropertyName( mode ), property.getType(), null );
-	    }
-	    else {
-		    throw new MappingException( "Unknown entity mode [" + mode + "]" );
-	    }
-	}	/**
-	 * Retreives a PropertyAccessor specific for a PojoRepresentation with the given access strategy.
-	 *
-	 * @param pojoAccessorStrategy The access strategy.
-	 * @return An appropriate accessor.
-	 */
-	private static PropertyAccessor getPojoPropertyAccessor(String pojoAccessorStrategy) {
-		if ( StringHelper.isEmpty( pojoAccessorStrategy ) || "property".equals( pojoAccessorStrategy ) ) {
-			return BASIC_PROPERTY_ACCESSOR;
-		}
-		else if ( "field".equals( pojoAccessorStrategy ) ) {
-			return DIRECT_PROPERTY_ACCESSOR;
-		}
-		else if ( "embedded".equals( pojoAccessorStrategy ) ) {
-			return EMBEDDED_PROPERTY_ACCESSOR;
-		}
-		else if ( "noop".equals(pojoAccessorStrategy) ) {
-			return NOOP_ACCESSOR;
-		}
-		else {
-			return resolveCustomAccessor( pojoAccessorStrategy );
-		}
-	}
-
-	public static PropertyAccessor getDynamicMapPropertyAccessor() throws MappingException {
-		return MAP_ACCESSOR;
-	}
-
-	public static PropertyAccessor getDom4jPropertyAccessor(String nodeName, Type type, SessionFactoryImplementor factory) 
-	throws MappingException {
-		//TODO: need some caching scheme? really comes down to decision 
-		//      regarding amount of state (if any) kept on PropertyAccessors
-		return new Dom4jAccessor( nodeName, type, factory );
-	}
-
-	private static PropertyAccessor resolveCustomAccessor(String accessorName) {
-		Class accessorClass;
-		try {
-			accessorClass = ReflectHelper.classForName(accessorName);
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new MappingException("could not find PropertyAccessor class: " + accessorName, cnfe);
-		}
-		try {
-			return (PropertyAccessor) accessorClass.newInstance();
-		}
-		catch (Exception e) {
-			throw new MappingException("could not instantiate PropertyAccessor class: " + accessorName, e);
-		}
-	}
-
-	private PropertyAccessorFactory() {}
-
-	// todo : this eventually needs to be removed
-	public static PropertyAccessor getPropertyAccessor(Class optionalClass, String type) throws MappingException {
-		if ( type==null ) type = optionalClass==null || optionalClass==Map.class ? "map" : "property";
-		return getPropertyAccessor(type);
-	}
-
-	// todo : this eventually needs to be removed
-	public static PropertyAccessor getPropertyAccessor(String type) throws MappingException {
-		if ( type==null || "property".equals(type) ) return BASIC_PROPERTY_ACCESSOR;
-		if ( "field".equals(type) ) return DIRECT_PROPERTY_ACCESSOR;
-		if ( "map".equals(type) ) return MAP_ACCESSOR;
-		if ( "embedded".equals(type) ) return EMBEDDED_PROPERTY_ACCESSOR;
-		if ( "noop".equals(type)) return NOOP_ACCESSOR;
-		
-		return resolveCustomAccessor(type);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/PropertyAccessorFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,158 @@
+/*
+ * 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.property;
+
+import java.util.Map;
+
+import org.hibernate.MappingException;
+import org.hibernate.EntityMode;
+import org.hibernate.type.Type;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Property;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * A factory for building/retrieving PropertyAccessor instances.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public final class PropertyAccessorFactory {
+
+	private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
+	private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
+	private static final PropertyAccessor MAP_ACCESSOR = new MapAccessor();
+	private static final PropertyAccessor NOOP_ACCESSOR = new NoopAccessor();
+	private static final PropertyAccessor EMBEDDED_PROPERTY_ACCESSOR = new EmbeddedPropertyAccessor();
+
+	//TODO: ideally we need the construction of PropertyAccessor to take the following:
+	//      1) EntityMode
+	//      2) EntityMode-specific data (i.e., the classname for pojo entities)
+	//      3) Property-specific data based on the EntityMode (i.e., property-name or dom4j-node-name)
+	// The easiest way, with the introduction of the new runtime-metamodel classes, would be the
+	// the following predicates:
+	//      1) PropertyAccessorFactory.getPropertyAccessor() takes references to both a
+	//          org.hibernate.metadata.EntityModeMetadata and org.hibernate.metadata.Property
+	//      2) What is now termed a "PropertyAccessor" stores any values needed from those two
+	//          pieces of information
+	//      3) Code can then simply call PropertyAccess.getGetter() with no parameters; likewise with
+	//          PropertyAccessor.getSetter()
+
+    /**
+     * Retrieves a PropertyAccessor instance based on the given property definition and
+     * entity mode.
+     *
+     * @param property The property for which to retrieve an accessor.
+     * @param mode The mode for the resulting entity.
+     * @return An appropriate accessor.
+     * @throws MappingException
+     */
+	public static PropertyAccessor getPropertyAccessor(Property property, EntityMode mode) throws MappingException {
+		//TODO: this is temporary in that the end result will probably not take a Property reference per-se.
+	    if ( null == mode || EntityMode.POJO.equals( mode ) ) {
+		    return getPojoPropertyAccessor( property.getPropertyAccessorName() );
+	    }
+	    else if ( EntityMode.MAP.equals( mode ) ) {
+		    return getDynamicMapPropertyAccessor();
+	    }
+	    else if ( EntityMode.DOM4J.equals( mode ) ) {
+	    	//TODO: passing null here, because this method is not really used for DOM4J at the moment
+	    	//      but it is still a bug, if we don't get rid of this!
+		    return getDom4jPropertyAccessor( property.getAccessorPropertyName( mode ), property.getType(), null );
+	    }
+	    else {
+		    throw new MappingException( "Unknown entity mode [" + mode + "]" );
+	    }
+	}	/**
+	 * Retreives a PropertyAccessor specific for a PojoRepresentation with the given access strategy.
+	 *
+	 * @param pojoAccessorStrategy The access strategy.
+	 * @return An appropriate accessor.
+	 */
+	private static PropertyAccessor getPojoPropertyAccessor(String pojoAccessorStrategy) {
+		if ( StringHelper.isEmpty( pojoAccessorStrategy ) || "property".equals( pojoAccessorStrategy ) ) {
+			return BASIC_PROPERTY_ACCESSOR;
+		}
+		else if ( "field".equals( pojoAccessorStrategy ) ) {
+			return DIRECT_PROPERTY_ACCESSOR;
+		}
+		else if ( "embedded".equals( pojoAccessorStrategy ) ) {
+			return EMBEDDED_PROPERTY_ACCESSOR;
+		}
+		else if ( "noop".equals(pojoAccessorStrategy) ) {
+			return NOOP_ACCESSOR;
+		}
+		else {
+			return resolveCustomAccessor( pojoAccessorStrategy );
+		}
+	}
+
+	public static PropertyAccessor getDynamicMapPropertyAccessor() throws MappingException {
+		return MAP_ACCESSOR;
+	}
+
+	public static PropertyAccessor getDom4jPropertyAccessor(String nodeName, Type type, SessionFactoryImplementor factory) 
+	throws MappingException {
+		//TODO: need some caching scheme? really comes down to decision 
+		//      regarding amount of state (if any) kept on PropertyAccessors
+		return new Dom4jAccessor( nodeName, type, factory );
+	}
+
+	private static PropertyAccessor resolveCustomAccessor(String accessorName) {
+		Class accessorClass;
+		try {
+			accessorClass = ReflectHelper.classForName(accessorName);
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new MappingException("could not find PropertyAccessor class: " + accessorName, cnfe);
+		}
+		try {
+			return (PropertyAccessor) accessorClass.newInstance();
+		}
+		catch (Exception e) {
+			throw new MappingException("could not instantiate PropertyAccessor class: " + accessorName, e);
+		}
+	}
+
+	private PropertyAccessorFactory() {}
+
+	// todo : this eventually needs to be removed
+	public static PropertyAccessor getPropertyAccessor(Class optionalClass, String type) throws MappingException {
+		if ( type==null ) type = optionalClass==null || optionalClass==Map.class ? "map" : "property";
+		return getPropertyAccessor(type);
+	}
+
+	// todo : this eventually needs to be removed
+	public static PropertyAccessor getPropertyAccessor(String type) throws MappingException {
+		if ( type==null || "property".equals(type) ) return BASIC_PROPERTY_ACCESSOR;
+		if ( "field".equals(type) ) return DIRECT_PROPERTY_ACCESSOR;
+		if ( "map".equals(type) ) return MAP_ACCESSOR;
+		if ( "embedded".equals(type) ) return EMBEDDED_PROPERTY_ACCESSOR;
+		if ( "noop".equals(type)) return NOOP_ACCESSOR;
+		
+		return resolveCustomAccessor(type);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/Setter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-//$Id: Setter.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.property;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Sets values to a particular property.
- * 
- * @author Gavin King
- */
-public interface Setter extends Serializable {
-	/**
-	 * Set the property value from the given instance
-	 *
-	 * @param target The instance upon which to set the given value.
-	 * @param value The value to be set on the target.
-	 * @param factory The session factory from which this request originated.
-	 * @throws HibernateException
-	 */
-	public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException;
-	/**
-	 * Optional operation (return null)
-	 */
-	public String getMethodName();
-	/**
-	 * Optional operation (return null)
-	 */
-	public Method getMethod();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/Setter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/Setter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.property;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Sets values to a particular property.
+ * 
+ * @author Gavin King
+ */
+public interface Setter extends Serializable {
+	/**
+	 * Set the property value from the given instance
+	 *
+	 * @param target The instance upon which to set the given value.
+	 * @param value The value to be set on the target.
+	 * @param factory The session factory from which this request originated.
+	 * @throws HibernateException
+	 */
+	public void set(Object target, Object value, SessionFactoryImplementor factory) throws HibernateException;
+	/**
+	 * Optional operation (return null)
+	 */
+	public String getMethodName();
+	/**
+	 * Optional operation (return null)
+	 */
+	public Method getMethod();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/property/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the notion of a "property" of
-	an entity. Support for JavaBean properties and
-	<tt>Map</tt> elements is included.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/property/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/property/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the notion of a "property" of
+	an entity. Support for JavaBean properties and
+	<tt>Map</tt> elements is included.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,146 +0,0 @@
-package org.hibernate.proxy;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LazyInitializationException;
-import org.hibernate.ObjectNotFoundException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Convenience base class for lazy initialization handlers.  Centralizes the
- * basic plumbing of doing lazy initialization freeing subclasses to
- * acts as essentially adapters to their intended entity mode and/or
- * proxy generation strategy.
- *
- * @author Gavin King
- */
-public abstract class AbstractLazyInitializer implements LazyInitializer {
-	
-	private Object target;
-	private boolean initialized;
-	private String entityName;
-	private Serializable id;
-	private transient SessionImplementor session;
-	private boolean unwrap;
-
-	/**
-	 * For serialization from the non-pojo initializers (HHH-3309)
-	 */
-	protected AbstractLazyInitializer() {
-	}
-	
-	protected AbstractLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
-		this.id = id;
-		this.session = session;
-		this.entityName = entityName;
-	}
-
-	public final Serializable getIdentifier() {
-		return id;
-	}
-
-	public final void setIdentifier(Serializable id) {
-		this.id = id;
-	}
-
-	public final String getEntityName() {
-		return entityName;
-	}
-
-	public final boolean isUninitialized() {
-		return !initialized;
-	}
-
-	public final SessionImplementor getSession() {
-		return session;
-	}
-
-	public final void initialize() throws HibernateException {
-		if (!initialized) {
-			if ( session==null ) {
-				throw new LazyInitializationException("could not initialize proxy - no Session");
-			}
-			else if ( !session.isOpen() ) {
-				throw new LazyInitializationException("could not initialize proxy - the owning Session was closed");
-			}
-			else if ( !session.isConnected() ) {
-				throw new LazyInitializationException("could not initialize proxy - the owning Session is disconnected");
-			}
-			else {
-				target = session.immediateLoad(entityName, id);
-				initialized = true;
-				checkTargetState();
-			}
-		}
-		else {
-			checkTargetState();
-		}
-	}
-
-	private void checkTargetState() {
-		if ( !unwrap ) {
-			if ( target == null ) {
-				getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
-			}
-		}
-	}
-
-	public final void setSession(SessionImplementor s) throws HibernateException {
-		if (s!=session) {
-			if ( isConnectedToSession() ) {
-				//TODO: perhaps this should be some other RuntimeException...
-				throw new HibernateException("illegally attempted to associate a proxy with two open Sessions");
-			}
-			else {
-				session = s;
-			}
-		}
-	}
-
-	protected final boolean isConnectedToSession() {
-		return session!=null && 
-				session.isOpen() && 
-				session.getPersistenceContext().containsProxy(this);
-	}
-	
-	public final void setImplementation(Object target) {
-		this.target = target;
-		initialized = true;
-	}
-
-	/**
-	 * Return the underlying persistent object, initializing if necessary
-	 */
-	public final Object getImplementation() {
-		initialize();
-		return target;
-	}
-
-	/**
-	 * Return the underlying persistent object in the given <tt>Session</tt>, or null,
-	 * do not initialize the proxy
-	 */
-	public final Object getImplementation(SessionImplementor s) throws HibernateException {
-		final EntityKey entityKey = new EntityKey(
-				getIdentifier(),
-				s.getFactory().getEntityPersister( getEntityName() ),
-				s.getEntityMode()
-			);
-		return s.getPersistenceContext().getEntity( entityKey );
-	}
-
-	protected final Object getTarget() {
-		return target;
-	}
-
-	public boolean isUnwrap() {
-		return unwrap;
-	}
-
-	public void setUnwrap(boolean unwrap) {
-		this.unwrap = unwrap;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/AbstractLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,169 @@
+/*
+ * 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.proxy;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Convenience base class for lazy initialization handlers.  Centralizes the
+ * basic plumbing of doing lazy initialization freeing subclasses to
+ * acts as essentially adapters to their intended entity mode and/or
+ * proxy generation strategy.
+ *
+ * @author Gavin King
+ */
+public abstract class AbstractLazyInitializer implements LazyInitializer {
+	
+	private Object target;
+	private boolean initialized;
+	private String entityName;
+	private Serializable id;
+	private transient SessionImplementor session;
+	private boolean unwrap;
+
+	/**
+	 * For serialization from the non-pojo initializers (HHH-3309)
+	 */
+	protected AbstractLazyInitializer() {
+	}
+	
+	protected AbstractLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
+		this.id = id;
+		this.session = session;
+		this.entityName = entityName;
+	}
+
+	public final Serializable getIdentifier() {
+		return id;
+	}
+
+	public final void setIdentifier(Serializable id) {
+		this.id = id;
+	}
+
+	public final String getEntityName() {
+		return entityName;
+	}
+
+	public final boolean isUninitialized() {
+		return !initialized;
+	}
+
+	public final SessionImplementor getSession() {
+		return session;
+	}
+
+	public final void initialize() throws HibernateException {
+		if (!initialized) {
+			if ( session==null ) {
+				throw new LazyInitializationException("could not initialize proxy - no Session");
+			}
+			else if ( !session.isOpen() ) {
+				throw new LazyInitializationException("could not initialize proxy - the owning Session was closed");
+			}
+			else if ( !session.isConnected() ) {
+				throw new LazyInitializationException("could not initialize proxy - the owning Session is disconnected");
+			}
+			else {
+				target = session.immediateLoad(entityName, id);
+				initialized = true;
+				checkTargetState();
+			}
+		}
+		else {
+			checkTargetState();
+		}
+	}
+
+	private void checkTargetState() {
+		if ( !unwrap ) {
+			if ( target == null ) {
+				getSession().getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
+			}
+		}
+	}
+
+	public final void setSession(SessionImplementor s) throws HibernateException {
+		if (s!=session) {
+			if ( isConnectedToSession() ) {
+				//TODO: perhaps this should be some other RuntimeException...
+				throw new HibernateException("illegally attempted to associate a proxy with two open Sessions");
+			}
+			else {
+				session = s;
+			}
+		}
+	}
+
+	protected final boolean isConnectedToSession() {
+		return session!=null && 
+				session.isOpen() && 
+				session.getPersistenceContext().containsProxy(this);
+	}
+	
+	public final void setImplementation(Object target) {
+		this.target = target;
+		initialized = true;
+	}
+
+	/**
+	 * Return the underlying persistent object, initializing if necessary
+	 */
+	public final Object getImplementation() {
+		initialize();
+		return target;
+	}
+
+	/**
+	 * Return the underlying persistent object in the given <tt>Session</tt>, or null,
+	 * do not initialize the proxy
+	 */
+	public final Object getImplementation(SessionImplementor s) throws HibernateException {
+		final EntityKey entityKey = new EntityKey(
+				getIdentifier(),
+				s.getFactory().getEntityPersister( getEntityName() ),
+				s.getEntityMode()
+			);
+		return s.getPersistenceContext().getEntity( entityKey );
+	}
+
+	protected final Object getTarget() {
+		return target;
+	}
+
+	public boolean isUnwrap() {
+		return unwrap;
+	}
+
+	public void setUnwrap(boolean unwrap) {
+		this.unwrap = unwrap;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,12 +0,0 @@
-package org.hibernate.proxy;
-
-import java.io.Serializable;
-
-/**
- * Delegate to handle the scenario of an entity not found by a specified id.
- *
- * @author Steve Ebersole
- */
-public interface EntityNotFoundDelegate {
-	public void handleEntityNotFound(String entityName, Serializable id);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/EntityNotFoundDelegate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy;
+
+import java.io.Serializable;
+
+/**
+ * Delegate to handle the scenario of an entity not found by a specified id.
+ *
+ * @author Steve Ebersole
+ */
+public interface EntityNotFoundDelegate {
+	public void handleEntityNotFound(String entityName, Serializable id);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/HibernateProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,31 +0,0 @@
-package org.hibernate.proxy;
-
-import java.io.Serializable;
-
-/**
- * Marker interface for entity proxies
- *
- * @author Gavin King
- */
-public interface HibernateProxy extends Serializable {
-	/**
-	 * Perform serialization-time write-replacement of this proxy.
-	 *
-	 * @return The serializable proxy replacement.
-	 */
-	public Object writeReplace();
-
-	/**
-	 * Get the underlying lazy initialization handler.
-	 *
-	 * @return The lazy initializer.
-	 */
-	public LazyInitializer getHibernateLazyInitializer();
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/HibernateProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy;
+
+import java.io.Serializable;
+
+/**
+ * Marker interface for entity proxies
+ *
+ * @author Gavin King
+ */
+public interface HibernateProxy extends Serializable {
+	/**
+	 * Perform serialization-time write-replacement of this proxy.
+	 *
+	 * @return The serializable proxy replacement.
+	 */
+	public Object writeReplace();
+
+	/**
+	 * Get the underlying lazy initialization handler.
+	 *
+	 * @return The lazy initializer.
+	 */
+	public LazyInitializer getHibernateLazyInitializer();
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: HibernateProxyHelper.java 4453 2004-08-29 07:31:03Z oneovthafew $
-package org.hibernate.proxy;
-
-
-/**
- * Utility methods for working with proxies. (this class is being phased out)
- * @author Gavin King
- */
-public final class HibernateProxyHelper {
-
-	/**
-	 * Get the class of an instance or the underlying class
-	 * of a proxy (without initializing the proxy!). It is
-	 * almost always better to use the entity name!
-	 */
-	public static Class getClassWithoutInitializingProxy(Object object) {
-		if (object instanceof HibernateProxy) {
-			HibernateProxy proxy = (HibernateProxy) object;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			return li.getPersistentClass();
-		}
-		else {
-			return object.getClass();
-		}
-	}
-
-	private HibernateProxyHelper() {
-		//cant instantiate
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/HibernateProxyHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.proxy;
+
+
+/**
+ * Utility methods for working with proxies. (this class is being phased out)
+ * @author Gavin King
+ */
+public final class HibernateProxyHelper {
+
+	/**
+	 * Get the class of an instance or the underlying class
+	 * of a proxy (without initializing the proxy!). It is
+	 * almost always better to use the entity name!
+	 */
+	public static Class getClassWithoutInitializingProxy(Object object) {
+		if (object instanceof HibernateProxy) {
+			HibernateProxy proxy = (HibernateProxy) object;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			return li.getPersistentClass();
+		}
+		else {
+			return object.getClass();
+		}
+	}
+
+	private HibernateProxyHelper() {
+		//cant instantiate
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,75 +0,0 @@
-//$Id: LazyInitializer.java 7246 2005-06-20 20:32:36Z oneovthafew $
-package org.hibernate.proxy;
-
-import java.io.Serializable;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Handles fetching of the underlying entity for a proxy
- * @author Gavin King
- */
-public interface LazyInitializer {
-	
-	/**
-	 * Initialize the proxy, fetching the target
-	 * entity if necessary
-	 */
-	public abstract void initialize() throws HibernateException;
-	
-	/**
-	 * Get the identifier held by the proxy
-	 */
-	public abstract Serializable getIdentifier();
-
-	/**
-	 * Set the identifier property of the proxy
-	 */
-	public abstract void setIdentifier(Serializable id);
-	
-	/**
-	 * Get the entity name
-	 */
-	public abstract String getEntityName();
-	
-	/**
-	 * Get the actual class of the entity (don't
-	 * use this, use the entityName)
-	 */
-	public abstract Class getPersistentClass();
-	
-	/**
-	 * Is the proxy uninitialzed?
-	 */
-	public abstract boolean isUninitialized();
-	
-	/**
-	 * Initialize the proxy manually
-	 */
-	public abstract void setImplementation(Object target);
-	
-	/**
-	 * Get the session, if this proxy is attached
-	 */
-	public abstract SessionImplementor getSession();
-	
-	/**
-	 * Attach the proxy to a session
-	 */
-	public abstract void setSession(SessionImplementor s) throws HibernateException;
-
-	/**
-	 * Return the underlying persistent object, initializing if necessary
-	 */
-	public abstract Object getImplementation();
-
-	/**
-	 * Return the underlying persistent object in the given <tt>Session</tt>, or null
-	 */
-	public abstract Object getImplementation(SessionImplementor s)
-			throws HibernateException;
-	
-	public void setUnwrap(boolean unwrap);
-	public boolean isUnwrap();
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/LazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/LazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy;
+
+import java.io.Serializable;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Handles fetching of the underlying entity for a proxy
+ * @author Gavin King
+ */
+public interface LazyInitializer {
+	
+	/**
+	 * Initialize the proxy, fetching the target
+	 * entity if necessary
+	 */
+	public abstract void initialize() throws HibernateException;
+	
+	/**
+	 * Get the identifier held by the proxy
+	 */
+	public abstract Serializable getIdentifier();
+
+	/**
+	 * Set the identifier property of the proxy
+	 */
+	public abstract void setIdentifier(Serializable id);
+	
+	/**
+	 * Get the entity name
+	 */
+	public abstract String getEntityName();
+	
+	/**
+	 * Get the actual class of the entity (don't
+	 * use this, use the entityName)
+	 */
+	public abstract Class getPersistentClass();
+	
+	/**
+	 * Is the proxy uninitialzed?
+	 */
+	public abstract boolean isUninitialized();
+	
+	/**
+	 * Initialize the proxy manually
+	 */
+	public abstract void setImplementation(Object target);
+	
+	/**
+	 * Get the session, if this proxy is attached
+	 */
+	public abstract SessionImplementor getSession();
+	
+	/**
+	 * Attach the proxy to a session
+	 */
+	public abstract void setSession(SessionImplementor s) throws HibernateException;
+
+	/**
+	 * Return the underlying persistent object, initializing if necessary
+	 */
+	public abstract Object getImplementation();
+
+	/**
+	 * Return the underlying persistent object in the given <tt>Session</tt>, or null
+	 */
+	public abstract Object getImplementation(SessionImplementor s)
+			throws HibernateException;
+	
+	public void setUnwrap(boolean unwrap);
+	public boolean isUnwrap();
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/ProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: ProxyFactory.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * Contract for run-time, proxy-based lazy initialization proxies.
- *
- * @author Gavin King
- */
-public interface ProxyFactory {
-
-	/**
-	 * Called immediately after instantiation of this factory.
-	 * <p/>
-	 * Essentially equivalent to contructor injection, but contracted
-	 * here via interface.
-	 *
-	 * @param entityName The name of the entity for which this factory should
-	 * generate proxies.
-	 * @param persistentClass The entity class for which to generate proxies;
-	 * not always the same as the entityName.
-	 * @param interfaces The interfaces to expose in the generated proxy;
-	 * {@link HibernateProxy} is already included in this collection.
-	 * @param getIdentifierMethod Reference to the identifier getter method;
-	 * invocation on this method should not force initialization
-	 * @param setIdentifierMethod Reference to the identifier setter method;
-	 * invocation on this method should not force initialization
-	 * @param componentIdType For composite identifier types, a reference to
-	 * the {@link org.hibernate.type.ComponentType type} of the identifier
-	 * property; again accessing the id should generally not cause
-	 * initialization - but need to bear in mind <key-many-to-one/>
-	 * mappings.
-	 * @throws HibernateException Indicates a problem completing post
-	 * instantiation initialization.
-	 */
-	public void postInstantiate(
-			String entityName,
-	        Class persistentClass,
-	        Set interfaces,
-	        Method getIdentifierMethod,
-	        Method setIdentifierMethod,
-	        AbstractComponentType componentIdType) throws HibernateException;
-
-	/**
-	 * Create a new proxy instance
-	 *
-	 * @param id The id value for the proxy to be generated.
-	 * @param session The session to which the generated proxy will be
-	 * associated.
-	 * @return The generated proxy.
-	 * @throws HibernateException Indicates problems generating the requested
-	 * proxy.
-	 */
-	public HibernateProxy getProxy(Serializable id,SessionImplementor session) throws HibernateException;
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/ProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/ProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * Contract for run-time, proxy-based lazy initialization proxies.
+ *
+ * @author Gavin King
+ */
+public interface ProxyFactory {
+
+	/**
+	 * Called immediately after instantiation of this factory.
+	 * <p/>
+	 * Essentially equivalent to contructor injection, but contracted
+	 * here via interface.
+	 *
+	 * @param entityName The name of the entity for which this factory should
+	 * generate proxies.
+	 * @param persistentClass The entity class for which to generate proxies;
+	 * not always the same as the entityName.
+	 * @param interfaces The interfaces to expose in the generated proxy;
+	 * {@link HibernateProxy} is already included in this collection.
+	 * @param getIdentifierMethod Reference to the identifier getter method;
+	 * invocation on this method should not force initialization
+	 * @param setIdentifierMethod Reference to the identifier setter method;
+	 * invocation on this method should not force initialization
+	 * @param componentIdType For composite identifier types, a reference to
+	 * the {@link org.hibernate.type.ComponentType type} of the identifier
+	 * property; again accessing the id should generally not cause
+	 * initialization - but need to bear in mind <key-many-to-one/>
+	 * mappings.
+	 * @throws HibernateException Indicates a problem completing post
+	 * instantiation initialization.
+	 */
+	public void postInstantiate(
+			String entityName,
+	        Class persistentClass,
+	        Set interfaces,
+	        Method getIdentifierMethod,
+	        Method setIdentifierMethod,
+	        AbstractComponentType componentIdType) throws HibernateException;
+
+	/**
+	 * Create a new proxy instance
+	 *
+	 * @param id The id value for the proxy to be generated.
+	 * @param session The session to which the generated proxy will be
+	 * associated.
+	 * @return The generated proxy.
+	 * @throws HibernateException Indicates problems generating the requested
+	 * proxy.
+	 */
+	public HibernateProxy getProxy(Serializable id,SessionImplementor session) throws HibernateException;
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-// $Id: Dom4jLazyInitializer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.dom4j;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.AbstractLazyInitializer;
-import org.dom4j.Element;
-
-import java.io.Serializable;
-
-/**
- * Lazy initializer for "dom4j" entity representations.
- *
- * @author Steve Ebersole
- */
-public class Dom4jLazyInitializer extends AbstractLazyInitializer implements Serializable {
-
-	Dom4jLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
-		super(entityName, id, session);
-	}
-
-	public Element getElement() {
-		return (Element) getImplementation();
-	}
-
-	public Class getPersistentClass() {
-		throw new UnsupportedOperationException("dom4j entity representation");
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.dom4j;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.AbstractLazyInitializer;
+import org.dom4j.Element;
+
+import java.io.Serializable;
+
+/**
+ * Lazy initializer for "dom4j" entity representations.
+ *
+ * @author Steve Ebersole
+ */
+public class Dom4jLazyInitializer extends AbstractLazyInitializer implements Serializable {
+
+	Dom4jLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
+		super(entityName, id, session);
+	}
+
+	public Element getElement() {
+		return (Element) getImplementation();
+	}
+
+	public Class getPersistentClass() {
+		throw new UnsupportedOperationException("dom4j entity representation");
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,568 +0,0 @@
-// $Id: Dom4jProxy.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.dom4j;
-
-import org.dom4j.Element;
-import org.dom4j.QName;
-import org.dom4j.Namespace;
-import org.dom4j.Attribute;
-import org.dom4j.CDATA;
-import org.dom4j.Entity;
-import org.dom4j.Text;
-import org.dom4j.Node;
-import org.dom4j.Branch;
-import org.dom4j.ProcessingInstruction;
-import org.dom4j.Comment;
-import org.dom4j.Document;
-import org.dom4j.XPath;
-import org.dom4j.InvalidXPathException;
-import org.dom4j.Visitor;
-import org.hibernate.proxy.dom4j.Dom4jLazyInitializer;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-
-import java.io.Serializable;
-import java.io.Writer;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Iterator;
-
-/**
- * Proxy for "dom4j" entity representations.
- *
- * @author Steve Ebersole
- */
-public class Dom4jProxy implements HibernateProxy, Element, Serializable {
-
-	private Dom4jLazyInitializer li;
-
-	public Dom4jProxy(Dom4jLazyInitializer li) {
-		this.li = li;
-	}
-
-	public Object writeReplace() {
-		return this;
-	}
-
-	public LazyInitializer getHibernateLazyInitializer() {
-		return li;
-	}
-
-	public QName getQName() {
-		return target().getQName();
-	}
-
-	public QName getQName(String s) {
-		return target().getQName( s );
-	}
-
-	public void setQName(QName qName) {
-		target().setQName( qName );
-	}
-
-	public Namespace getNamespace() {
-		return target().getNamespace();
-	}
-
-	public Namespace getNamespaceForPrefix(String s) {
-		return target().getNamespaceForPrefix( s );
-	}
-
-	public Namespace getNamespaceForURI(String s) {
-		return target().getNamespaceForURI( s );
-	}
-
-	public List getNamespacesForURI(String s) {
-		return target().getNamespacesForURI( s );
-	}
-
-	public String getNamespacePrefix() {
-		return target().getNamespacePrefix();
-	}
-
-	public String getNamespaceURI() {
-		return target().getNamespaceURI();
-	}
-
-	public String getQualifiedName() {
-		return target().getQualifiedName();
-	}
-
-	public List additionalNamespaces() {
-		return target().additionalNamespaces();
-	}
-
-	public List declaredNamespaces() {
-		return target().declaredNamespaces();
-	}
-
-	public Element addAttribute(String attrName, String text) {
-		return target().addAttribute( attrName, text );
-	}
-
-	public Element addAttribute(QName attrName, String text) {
-		return target().addAttribute( attrName, text );
-	}
-
-	public Element addComment(String text) {
-		return target().addComment( text );
-	}
-
-	public Element addCDATA(String text) {
-		return target().addCDATA( text );
-	}
-
-	public Element addEntity(String name, String text) {
-		return target().addEntity( name, text );
-	}
-
-	public Element addNamespace(String prefix, String uri) {
-		return target().addNamespace( prefix, uri );
-	}
-
-	public Element addProcessingInstruction(String target, String text) {
-		return target().addProcessingInstruction( target, text );
-	}
-
-	public Element addProcessingInstruction(String target, Map data) {
-		return target().addProcessingInstruction( target, data );
-	}
-
-	public Element addText(String text) {
-		return target().addText( text );
-	}
-
-	public void add(Attribute attribute) {
-		target().add( attribute );
-	}
-
-	public void add(CDATA cdata) {
-		target().add( cdata );
-	}
-
-	public void add(Entity entity) {
-		target().add( entity );
-	}
-
-	public void add(Text text) {
-		target().add( text );
-	}
-
-	public void add(Namespace namespace) {
-		target().add( namespace );
-	}
-
-	public boolean remove(Attribute attribute) {
-		return target().remove( attribute );
-	}
-
-	public boolean remove(CDATA cdata) {
-		return target().remove( cdata );
-	}
-
-	public boolean remove(Entity entity) {
-		return target().remove( entity );
-	}
-
-	public boolean remove(Namespace namespace) {
-		return target().remove( namespace );
-	}
-
-	public boolean remove(Text text) {
-		return target().remove( text );
-	}
-
-	public boolean supportsParent() {
-		return target().supportsParent();
-	}
-
-	public Element getParent() {
-		return target().getParent();
-	}
-
-	public void setParent(Element element) {
-		target().setParent( element );
-	}
-
-	public Document getDocument() {
-		return target().getDocument();
-	}
-
-	public void setDocument(Document document) {
-		target().setDocument( document );
-	}
-
-	public boolean isReadOnly() {
-		return target().isReadOnly();
-	}
-
-	public boolean hasContent() {
-		return target().hasContent();
-	}
-
-	public String getName() {
-		return target().getName();
-	}
-
-	public void setName(String name) {
-		target().setName( name );
-	}
-
-	public String getText() {
-		return target().getText();
-	}
-
-	public void setText(String text) {
-		target().setText( text );
-	}
-
-	public String getTextTrim() {
-		return target().getTextTrim();
-	}
-
-	public String getStringValue() {
-		return target().getStringValue();
-	}
-
-	public String getPath() {
-		return target().getPath();
-	}
-
-	public String getPath(Element element) {
-		return target().getPath( element );
-	}
-
-	public String getUniquePath() {
-		return target().getUniquePath();
-	}
-
-	public String getUniquePath(Element element) {
-		return target().getUniquePath( element );
-	}
-
-	public String asXML() {
-		return target().asXML();
-	}
-
-	public void write(Writer writer) throws IOException {
-		target().write( writer );
-	}
-
-	public short getNodeType() {
-		return target().getNodeType();
-	}
-
-	public String getNodeTypeName() {
-		return target().getNodeTypeName();
-	}
-
-	public Node detach() {
-		Element parent = target().getParent();
-		if (parent!=null) parent.remove(this);
-		return target().detach();
-	}
-
-	public List selectNodes(String xpath) {
-		return target().selectNodes( xpath );
-	}
-
-	public Object selectObject(String xpath) {
-		return target().selectObject( xpath );
-	}
-
-	public List selectNodes(String xpath, String comparison) {
-		return target().selectNodes( xpath, comparison );
-	}
-
-	public List selectNodes(String xpath, String comparison, boolean removeDups) {
-		return target().selectNodes( xpath, comparison, removeDups );
-	}
-
-	public Node selectSingleNode(String xpath) {
-        return target().selectSingleNode( xpath );
-	}
-
-	public String valueOf(String xpath) {
-		return target().valueOf( xpath );
-	}
-
-	public Number numberValueOf(String xpath) {
-		return target().numberValueOf( xpath );
-	}
-
-	public boolean matches(String xpath) {
-		return target().matches( xpath );
-	}
-
-	public XPath createXPath(String xpath) throws InvalidXPathException {
-		return target().createXPath( xpath );
-	}
-
-	public Node asXPathResult(Element element) {
-		return target().asXPathResult( element );
-	}
-
-	public void accept(Visitor visitor) {
-		target().accept( visitor );
-	}
-
-	public Object clone() {
-		return target().clone();
-	}
-
-	public Object getData() {
-		return target().getData();
-	}
-
-	public void setData(Object data) {
-		target().setData( data );
-	}
-
-	public List attributes() {
-		return target().attributes();
-	}
-
-	public void setAttributes(List list) {
-		target().setAttributes( list );
-	}
-
-	public int attributeCount() {
-		return target().attributeCount();
-	}
-
-	public Iterator attributeIterator() {
-		return target().attributeIterator();
-	}
-
-	public Attribute attribute(int i) {
-		return target().attribute( i );
-	}
-
-	public Attribute attribute(String name) {
-		return target().attribute( name );
-	}
-
-	public Attribute attribute(QName qName) {
-		return target().attribute( qName );
-	}
-
-	public String attributeValue(String name) {
-		return target().attributeValue( name );
-	}
-
-	public String attributeValue(String name, String defaultValue) {
-		return target().attributeValue( name, defaultValue );
-	}
-
-	public String attributeValue(QName qName) {
-		return target().attributeValue( qName );
-	}
-
-	public String attributeValue(QName qName, String defaultValue) {
-		return target().attributeValue( qName, defaultValue );
-	}
-
-	/**
-	 * @deprecated
-	 */
-	public void setAttributeValue(String name, String value) {
-		target().setAttributeValue( name, value );
-	}
-
-	/**
-	 * @deprecated
-	 */
-	public void setAttributeValue(QName qName, String value) {
-		target().setAttributeValue( qName, value );
-	}
-
-	public Element element(String name) {
-		return target().element( name );
-	}
-
-	public Element element(QName qName) {
-		return target().element( qName );
-	}
-
-	public List elements() {
-		return target().elements();
-	}
-
-	public List elements(String name) {
-		return target().elements( name );
-	}
-
-	public List elements(QName qName) {
-		return target().elements( qName );
-	}
-
-	public Iterator elementIterator() {
-		return target().elementIterator();
-	}
-
-	public Iterator elementIterator(String name) {
-		return target().elementIterator( name );
-
-	}
-
-	public Iterator elementIterator(QName qName) {
-		return target().elementIterator( qName );
-	}
-
-	public boolean isRootElement() {
-		return target().isRootElement();
-	}
-
-	public boolean hasMixedContent() {
-		return target().hasMixedContent();
-	}
-
-	public boolean isTextOnly() {
-		return target().isTextOnly();
-	}
-
-	public void appendAttributes(Element element) {
-		target().appendAttributes( element );
-	}
-
-	public Element createCopy() {
-		return target().createCopy();
-	}
-
-	public Element createCopy(String name) {
-		return target().createCopy( name );
-	}
-
-	public Element createCopy(QName qName) {
-		return target().createCopy( qName );
-	}
-
-	public String elementText(String name) {
-		return target().elementText( name );
-	}
-
-	public String elementText(QName qName) {
-		return target().elementText( qName );
-	}
-
-	public String elementTextTrim(String name) {
-		return target().elementTextTrim( name );
-	}
-
-	public String elementTextTrim(QName qName) {
-		return target().elementTextTrim( qName );
-	}
-
-	public Node getXPathResult(int i) {
-		return target().getXPathResult( i );
-	}
-
-	public Node node(int i) {
-		return target().node( i );
-	}
-
-	public int indexOf(Node node) {
-		return target().indexOf( node );
-	}
-
-	public int nodeCount() {
-		return target().nodeCount();
-	}
-
-	public Element elementByID(String id) {
-		return target().elementByID( id );
-	}
-
-	public List content() {
-		return target().content();
-	}
-
-	public Iterator nodeIterator() {
-		return target().nodeIterator();
-	}
-
-	public void setContent(List list) {
-		target().setContent( list );
-	}
-
-	public void appendContent(Branch branch) {
-		target().appendContent( branch );
-	}
-
-	public void clearContent() {
-		target().clearContent();
-	}
-
-	public List processingInstructions() {
-		return target().processingInstructions();
-	}
-
-	public List processingInstructions(String name) {
-		return target().processingInstructions( name );
-	}
-
-	public ProcessingInstruction processingInstruction(String name) {
-		return target().processingInstruction( name );
-	}
-
-	public void setProcessingInstructions(List list) {
-		target().setProcessingInstructions( list );
-	}
-
-	public Element addElement(String name) {
-		return target().addElement( name );
-	}
-
-	public Element addElement(QName qName) {
-		return target().addElement( qName );
-	}
-
-	public Element addElement(String name, String text) {
-		return target().addElement( name, text );
-
-	}
-
-	public boolean removeProcessingInstruction(String name) {
-		return target().removeProcessingInstruction( name );
-	}
-
-	public void add(Node node) {
-		target().add( node );
-	}
-
-	public void add(Comment comment) {
-		target().add( comment );
-	}
-
-	public void add(Element element) {
-		target().add( element );
-	}
-
-	public void add(ProcessingInstruction processingInstruction) {
-		target().add( processingInstruction );
-	}
-
-	public boolean remove(Node node) {
-		return target().remove( node );
-	}
-
-	public boolean remove(Comment comment) {
-		return target().remove( comment );
-	}
-
-	public boolean remove(Element element) {
-		return target().remove( element );
-	}
-
-	public boolean remove(ProcessingInstruction processingInstruction) {
-		return target().remove( processingInstruction );
-	}
-
-	public void normalize() {
-		target().normalize();
-	}
-
-	private Element target() {
-		return li.getElement();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,590 @@
+/*
+ * 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.proxy.dom4j;
+
+import org.dom4j.Element;
+import org.dom4j.QName;
+import org.dom4j.Namespace;
+import org.dom4j.Attribute;
+import org.dom4j.CDATA;
+import org.dom4j.Entity;
+import org.dom4j.Text;
+import org.dom4j.Node;
+import org.dom4j.Branch;
+import org.dom4j.ProcessingInstruction;
+import org.dom4j.Comment;
+import org.dom4j.Document;
+import org.dom4j.XPath;
+import org.dom4j.InvalidXPathException;
+import org.dom4j.Visitor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+
+import java.io.Serializable;
+import java.io.Writer;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Iterator;
+
+/**
+ * Proxy for "dom4j" entity representations.
+ *
+ * @author Steve Ebersole
+ */
+public class Dom4jProxy implements HibernateProxy, Element, Serializable {
+
+	private Dom4jLazyInitializer li;
+
+	public Dom4jProxy(Dom4jLazyInitializer li) {
+		this.li = li;
+	}
+
+	public Object writeReplace() {
+		return this;
+	}
+
+	public LazyInitializer getHibernateLazyInitializer() {
+		return li;
+	}
+
+	public QName getQName() {
+		return target().getQName();
+	}
+
+	public QName getQName(String s) {
+		return target().getQName( s );
+	}
+
+	public void setQName(QName qName) {
+		target().setQName( qName );
+	}
+
+	public Namespace getNamespace() {
+		return target().getNamespace();
+	}
+
+	public Namespace getNamespaceForPrefix(String s) {
+		return target().getNamespaceForPrefix( s );
+	}
+
+	public Namespace getNamespaceForURI(String s) {
+		return target().getNamespaceForURI( s );
+	}
+
+	public List getNamespacesForURI(String s) {
+		return target().getNamespacesForURI( s );
+	}
+
+	public String getNamespacePrefix() {
+		return target().getNamespacePrefix();
+	}
+
+	public String getNamespaceURI() {
+		return target().getNamespaceURI();
+	}
+
+	public String getQualifiedName() {
+		return target().getQualifiedName();
+	}
+
+	public List additionalNamespaces() {
+		return target().additionalNamespaces();
+	}
+
+	public List declaredNamespaces() {
+		return target().declaredNamespaces();
+	}
+
+	public Element addAttribute(String attrName, String text) {
+		return target().addAttribute( attrName, text );
+	}
+
+	public Element addAttribute(QName attrName, String text) {
+		return target().addAttribute( attrName, text );
+	}
+
+	public Element addComment(String text) {
+		return target().addComment( text );
+	}
+
+	public Element addCDATA(String text) {
+		return target().addCDATA( text );
+	}
+
+	public Element addEntity(String name, String text) {
+		return target().addEntity( name, text );
+	}
+
+	public Element addNamespace(String prefix, String uri) {
+		return target().addNamespace( prefix, uri );
+	}
+
+	public Element addProcessingInstruction(String target, String text) {
+		return target().addProcessingInstruction( target, text );
+	}
+
+	public Element addProcessingInstruction(String target, Map data) {
+		return target().addProcessingInstruction( target, data );
+	}
+
+	public Element addText(String text) {
+		return target().addText( text );
+	}
+
+	public void add(Attribute attribute) {
+		target().add( attribute );
+	}
+
+	public void add(CDATA cdata) {
+		target().add( cdata );
+	}
+
+	public void add(Entity entity) {
+		target().add( entity );
+	}
+
+	public void add(Text text) {
+		target().add( text );
+	}
+
+	public void add(Namespace namespace) {
+		target().add( namespace );
+	}
+
+	public boolean remove(Attribute attribute) {
+		return target().remove( attribute );
+	}
+
+	public boolean remove(CDATA cdata) {
+		return target().remove( cdata );
+	}
+
+	public boolean remove(Entity entity) {
+		return target().remove( entity );
+	}
+
+	public boolean remove(Namespace namespace) {
+		return target().remove( namespace );
+	}
+
+	public boolean remove(Text text) {
+		return target().remove( text );
+	}
+
+	public boolean supportsParent() {
+		return target().supportsParent();
+	}
+
+	public Element getParent() {
+		return target().getParent();
+	}
+
+	public void setParent(Element element) {
+		target().setParent( element );
+	}
+
+	public Document getDocument() {
+		return target().getDocument();
+	}
+
+	public void setDocument(Document document) {
+		target().setDocument( document );
+	}
+
+	public boolean isReadOnly() {
+		return target().isReadOnly();
+	}
+
+	public boolean hasContent() {
+		return target().hasContent();
+	}
+
+	public String getName() {
+		return target().getName();
+	}
+
+	public void setName(String name) {
+		target().setName( name );
+	}
+
+	public String getText() {
+		return target().getText();
+	}
+
+	public void setText(String text) {
+		target().setText( text );
+	}
+
+	public String getTextTrim() {
+		return target().getTextTrim();
+	}
+
+	public String getStringValue() {
+		return target().getStringValue();
+	}
+
+	public String getPath() {
+		return target().getPath();
+	}
+
+	public String getPath(Element element) {
+		return target().getPath( element );
+	}
+
+	public String getUniquePath() {
+		return target().getUniquePath();
+	}
+
+	public String getUniquePath(Element element) {
+		return target().getUniquePath( element );
+	}
+
+	public String asXML() {
+		return target().asXML();
+	}
+
+	public void write(Writer writer) throws IOException {
+		target().write( writer );
+	}
+
+	public short getNodeType() {
+		return target().getNodeType();
+	}
+
+	public String getNodeTypeName() {
+		return target().getNodeTypeName();
+	}
+
+	public Node detach() {
+		Element parent = target().getParent();
+		if (parent!=null) parent.remove(this);
+		return target().detach();
+	}
+
+	public List selectNodes(String xpath) {
+		return target().selectNodes( xpath );
+	}
+
+	public Object selectObject(String xpath) {
+		return target().selectObject( xpath );
+	}
+
+	public List selectNodes(String xpath, String comparison) {
+		return target().selectNodes( xpath, comparison );
+	}
+
+	public List selectNodes(String xpath, String comparison, boolean removeDups) {
+		return target().selectNodes( xpath, comparison, removeDups );
+	}
+
+	public Node selectSingleNode(String xpath) {
+        return target().selectSingleNode( xpath );
+	}
+
+	public String valueOf(String xpath) {
+		return target().valueOf( xpath );
+	}
+
+	public Number numberValueOf(String xpath) {
+		return target().numberValueOf( xpath );
+	}
+
+	public boolean matches(String xpath) {
+		return target().matches( xpath );
+	}
+
+	public XPath createXPath(String xpath) throws InvalidXPathException {
+		return target().createXPath( xpath );
+	}
+
+	public Node asXPathResult(Element element) {
+		return target().asXPathResult( element );
+	}
+
+	public void accept(Visitor visitor) {
+		target().accept( visitor );
+	}
+
+	public Object clone() {
+		return target().clone();
+	}
+
+	public Object getData() {
+		return target().getData();
+	}
+
+	public void setData(Object data) {
+		target().setData( data );
+	}
+
+	public List attributes() {
+		return target().attributes();
+	}
+
+	public void setAttributes(List list) {
+		target().setAttributes( list );
+	}
+
+	public int attributeCount() {
+		return target().attributeCount();
+	}
+
+	public Iterator attributeIterator() {
+		return target().attributeIterator();
+	}
+
+	public Attribute attribute(int i) {
+		return target().attribute( i );
+	}
+
+	public Attribute attribute(String name) {
+		return target().attribute( name );
+	}
+
+	public Attribute attribute(QName qName) {
+		return target().attribute( qName );
+	}
+
+	public String attributeValue(String name) {
+		return target().attributeValue( name );
+	}
+
+	public String attributeValue(String name, String defaultValue) {
+		return target().attributeValue( name, defaultValue );
+	}
+
+	public String attributeValue(QName qName) {
+		return target().attributeValue( qName );
+	}
+
+	public String attributeValue(QName qName, String defaultValue) {
+		return target().attributeValue( qName, defaultValue );
+	}
+
+	/**
+	 * @deprecated
+	 */
+	public void setAttributeValue(String name, String value) {
+		target().setAttributeValue( name, value );
+	}
+
+	/**
+	 * @deprecated
+	 */
+	public void setAttributeValue(QName qName, String value) {
+		target().setAttributeValue( qName, value );
+	}
+
+	public Element element(String name) {
+		return target().element( name );
+	}
+
+	public Element element(QName qName) {
+		return target().element( qName );
+	}
+
+	public List elements() {
+		return target().elements();
+	}
+
+	public List elements(String name) {
+		return target().elements( name );
+	}
+
+	public List elements(QName qName) {
+		return target().elements( qName );
+	}
+
+	public Iterator elementIterator() {
+		return target().elementIterator();
+	}
+
+	public Iterator elementIterator(String name) {
+		return target().elementIterator( name );
+
+	}
+
+	public Iterator elementIterator(QName qName) {
+		return target().elementIterator( qName );
+	}
+
+	public boolean isRootElement() {
+		return target().isRootElement();
+	}
+
+	public boolean hasMixedContent() {
+		return target().hasMixedContent();
+	}
+
+	public boolean isTextOnly() {
+		return target().isTextOnly();
+	}
+
+	public void appendAttributes(Element element) {
+		target().appendAttributes( element );
+	}
+
+	public Element createCopy() {
+		return target().createCopy();
+	}
+
+	public Element createCopy(String name) {
+		return target().createCopy( name );
+	}
+
+	public Element createCopy(QName qName) {
+		return target().createCopy( qName );
+	}
+
+	public String elementText(String name) {
+		return target().elementText( name );
+	}
+
+	public String elementText(QName qName) {
+		return target().elementText( qName );
+	}
+
+	public String elementTextTrim(String name) {
+		return target().elementTextTrim( name );
+	}
+
+	public String elementTextTrim(QName qName) {
+		return target().elementTextTrim( qName );
+	}
+
+	public Node getXPathResult(int i) {
+		return target().getXPathResult( i );
+	}
+
+	public Node node(int i) {
+		return target().node( i );
+	}
+
+	public int indexOf(Node node) {
+		return target().indexOf( node );
+	}
+
+	public int nodeCount() {
+		return target().nodeCount();
+	}
+
+	public Element elementByID(String id) {
+		return target().elementByID( id );
+	}
+
+	public List content() {
+		return target().content();
+	}
+
+	public Iterator nodeIterator() {
+		return target().nodeIterator();
+	}
+
+	public void setContent(List list) {
+		target().setContent( list );
+	}
+
+	public void appendContent(Branch branch) {
+		target().appendContent( branch );
+	}
+
+	public void clearContent() {
+		target().clearContent();
+	}
+
+	public List processingInstructions() {
+		return target().processingInstructions();
+	}
+
+	public List processingInstructions(String name) {
+		return target().processingInstructions( name );
+	}
+
+	public ProcessingInstruction processingInstruction(String name) {
+		return target().processingInstruction( name );
+	}
+
+	public void setProcessingInstructions(List list) {
+		target().setProcessingInstructions( list );
+	}
+
+	public Element addElement(String name) {
+		return target().addElement( name );
+	}
+
+	public Element addElement(QName qName) {
+		return target().addElement( qName );
+	}
+
+	public Element addElement(String name, String text) {
+		return target().addElement( name, text );
+
+	}
+
+	public boolean removeProcessingInstruction(String name) {
+		return target().removeProcessingInstruction( name );
+	}
+
+	public void add(Node node) {
+		target().add( node );
+	}
+
+	public void add(Comment comment) {
+		target().add( comment );
+	}
+
+	public void add(Element element) {
+		target().add( element );
+	}
+
+	public void add(ProcessingInstruction processingInstruction) {
+		target().add( processingInstruction );
+	}
+
+	public boolean remove(Node node) {
+		return target().remove( node );
+	}
+
+	public boolean remove(Comment comment) {
+		return target().remove( comment );
+	}
+
+	public boolean remove(Element element) {
+		return target().remove( element );
+	}
+
+	public boolean remove(ProcessingInstruction processingInstruction) {
+		return target().remove( processingInstruction );
+	}
+
+	public void normalize() {
+		target().normalize();
+	}
+
+	private Element target() {
+		return li.getElement();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,44 +0,0 @@
-// $Id: Dom4jProxyFactory.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.dom4j;
-
-import org.hibernate.HibernateException;
-import org.hibernate.proxy.dom4j.Dom4jLazyInitializer;
-import org.hibernate.proxy.dom4j.Dom4jProxy;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.engine.SessionImplementor;
-
-import java.util.Set;
-import java.lang.reflect.Method;
-import java.io.Serializable;
-
-/**
- * Builds proxies for "dom4j" entity representations.
- *
- * @author Steve Ebersole
- */
-public class Dom4jProxyFactory implements ProxyFactory {
-
-	private String entityName;
-
-	/**
-	 * Called immediately after instantiation
-	 */
-	public void postInstantiate(
-	        String entityName,
-	        Class persistentClass,
-	        Set interfaces,
-	        Method getIdentifierMethod,
-	        Method setIdentifierMethod,
-	        AbstractComponentType componentIdType) throws HibernateException {
-		this.entityName = entityName;
-	}
-
-	/**
-	 * Create a new proxy
-	 */
-	public HibernateProxy getProxy(Serializable id, SessionImplementor session) throws HibernateException {
-		return new Dom4jProxy( new Dom4jLazyInitializer( entityName, id, session ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/dom4j/Dom4jProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.dom4j;
+
+import org.hibernate.HibernateException;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.engine.SessionImplementor;
+
+import java.util.Set;
+import java.lang.reflect.Method;
+import java.io.Serializable;
+
+/**
+ * Builds proxies for "dom4j" entity representations.
+ *
+ * @author Steve Ebersole
+ */
+public class Dom4jProxyFactory implements ProxyFactory {
+
+	private String entityName;
+
+	/**
+	 * Called immediately after instantiation
+	 */
+	public void postInstantiate(
+	        String entityName,
+	        Class persistentClass,
+	        Set interfaces,
+	        Method getIdentifierMethod,
+	        Method setIdentifierMethod,
+	        AbstractComponentType componentIdType) throws HibernateException {
+		this.entityName = entityName;
+	}
+
+	/**
+	 * Create a new proxy
+	 */
+	public HibernateProxy getProxy(Serializable id, SessionImplementor session) throws HibernateException {
+		return new Dom4jProxy( new Dom4jLazyInitializer( entityName, id, session ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,29 +0,0 @@
-//$Id: MapLazyInitializer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.map;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.AbstractLazyInitializer;
-
-/**
- * Lazy initializer for "dynamic-map" entity representations.
- *
- * @author Gavin King
- */
-public class MapLazyInitializer extends AbstractLazyInitializer implements Serializable {
-
-	MapLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
-		super(entityName, id, session);
-	}
-
-	public Map getMap() {
-		return (Map) getImplementation();
-	}
-
-	public Class getPersistentClass() {
-		throw new UnsupportedOperationException("dynamic-map entity representation");
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.map;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.AbstractLazyInitializer;
+
+/**
+ * Lazy initializer for "dynamic-map" entity representations.
+ *
+ * @author Gavin King
+ */
+public class MapLazyInitializer extends AbstractLazyInitializer implements Serializable {
+
+	MapLazyInitializer(String entityName, Serializable id, SessionImplementor session) {
+		super(entityName, id, session);
+	}
+
+	public Map getMap() {
+		return (Map) getImplementation();
+	}
+
+	public Class getPersistentClass() {
+		throw new UnsupportedOperationException("dynamic-map entity representation");
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/map/MapProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,82 +0,0 @@
-//$Id: MapProxy.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.map;
-
-import org.hibernate.proxy.map.MapLazyInitializer;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Proxy for "dynamic-map" entity representations.
- *
- * @author Gavin King
- */
-public class MapProxy implements HibernateProxy, Map, Serializable {
-
-	private MapLazyInitializer li;
-
-	MapProxy(MapLazyInitializer li) {
-		this.li = li;
-	}
-
-	public Object writeReplace() {
-		return this;
-	}
-
-	public LazyInitializer getHibernateLazyInitializer() {
-		return li;
-	}
-
-	public int size() {
-		return li.getMap().size();
-	}
-
-	public void clear() {
-		li.getMap().clear();
-	}
-
-	public boolean isEmpty() {
-		return li.getMap().isEmpty();
-	}
-
-	public boolean containsKey(Object key) {
-		return li.getMap().containsKey(key);
-	}
-
-	public boolean containsValue(Object value) {
-		return li.getMap().containsValue(value);
-	}
-
-	public Collection values() {
-		return li.getMap().values();
-	}
-
-	public void putAll(Map t) {
-		li.getMap().putAll(t);
-	}
-
-	public Set entrySet() {
-		return li.getMap().entrySet();
-	}
-
-	public Set keySet() {
-		return li.getMap().keySet();
-	}
-
-	public Object get(Object key) {
-		return li.getMap().get(key);
-	}
-
-	public Object remove(Object key) {
-		return li.getMap().remove(key);
-	}
-
-	public Object put(Object key, Object value) {
-		return li.getMap().put(key, value);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/map/MapProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.map;
+
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Proxy for "dynamic-map" entity representations.
+ *
+ * @author Gavin King
+ */
+public class MapProxy implements HibernateProxy, Map, Serializable {
+
+	private MapLazyInitializer li;
+
+	MapProxy(MapLazyInitializer li) {
+		this.li = li;
+	}
+
+	public Object writeReplace() {
+		return this;
+	}
+
+	public LazyInitializer getHibernateLazyInitializer() {
+		return li;
+	}
+
+	public int size() {
+		return li.getMap().size();
+	}
+
+	public void clear() {
+		li.getMap().clear();
+	}
+
+	public boolean isEmpty() {
+		return li.getMap().isEmpty();
+	}
+
+	public boolean containsKey(Object key) {
+		return li.getMap().containsKey(key);
+	}
+
+	public boolean containsValue(Object value) {
+		return li.getMap().containsValue(value);
+	}
+
+	public Collection values() {
+		return li.getMap().values();
+	}
+
+	public void putAll(Map t) {
+		li.getMap().putAll(t);
+	}
+
+	public Set entrySet() {
+		return li.getMap().entrySet();
+	}
+
+	public Set keySet() {
+		return li.getMap().keySet();
+	}
+
+	public Object get(Object key) {
+		return li.getMap().get(key);
+	}
+
+	public Object remove(Object key) {
+		return li.getMap().remove(key);
+	}
+
+	public Object put(Object key, Object value) {
+		return li.getMap().put(key, value);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,43 +0,0 @@
-//$Id: MapProxyFactory.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.map;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.proxy.map.MapLazyInitializer;
-import org.hibernate.proxy.map.MapProxy;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * @author Gavin King
- */
-public class MapProxyFactory implements ProxyFactory {
-
-	private String entityName;
-
-	public void postInstantiate(
-		final String entityName, 
-		final Class persistentClass,
-		final Set interfaces, 
-		final Method getIdentifierMethod,
-		final Method setIdentifierMethod,
-		AbstractComponentType componentIdType) 
-	throws HibernateException {
-		
-		this.entityName = entityName;
-
-	}
-
-	public HibernateProxy getProxy(
-		final Serializable id, 
-		final SessionImplementor session)
-	throws HibernateException {
-		return new MapProxy( new MapLazyInitializer(entityName, id, session) );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/map/MapProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.map;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * @author Gavin King
+ */
+public class MapProxyFactory implements ProxyFactory {
+
+	private String entityName;
+
+	public void postInstantiate(
+		final String entityName, 
+		final Class persistentClass,
+		final Set interfaces, 
+		final Method getIdentifierMethod,
+		final Method setIdentifierMethod,
+		AbstractComponentType componentIdType) 
+	throws HibernateException {
+		
+		this.entityName = entityName;
+
+	}
+
+	public HibernateProxy getProxy(
+		final Serializable id, 
+		final SessionImplementor session)
+	throws HibernateException {
+		return new MapProxy( new MapLazyInitializer(entityName, id, session) );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a framework for lazy-initializing
-	entity proxies.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a framework for lazy-initializing
+	entity proxies.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,121 +0,0 @@
-//$Id: BasicLazyInitializer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.pojo;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.util.MarkerObject;
-import org.hibernate.util.ReflectHelper;
-import org.hibernate.proxy.AbstractLazyInitializer;
-
-/**
- * Lazy initializer for POJOs
- * @author Gavin King
- */
-public abstract class BasicLazyInitializer extends AbstractLazyInitializer {
-
-	protected static final Object INVOKE_IMPLEMENTATION = new MarkerObject("INVOKE_IMPLEMENTATION");
-
-	protected Class persistentClass;
-	protected Method getIdentifierMethod;
-	protected Method setIdentifierMethod;
-	protected boolean overridesEquals;
-	private Object replacement;
-	protected AbstractComponentType componentIdType;
-
-	protected BasicLazyInitializer(
-			String entityName,
-	        Class persistentClass,
-	        Serializable id,
-	        Method getIdentifierMethod,
-	        Method setIdentifierMethod,
-	        AbstractComponentType componentIdType,
-	        SessionImplementor session) {
-		super(entityName, id, session);
-		this.persistentClass = persistentClass;
-		this.getIdentifierMethod = getIdentifierMethod;
-		this.setIdentifierMethod = setIdentifierMethod;
-		this.componentIdType = componentIdType;
-		overridesEquals = ReflectHelper.overridesEquals(persistentClass);
-	}
-
-	protected abstract Object serializableProxy();
-
-	protected final Object invoke(Method method, Object[] args, Object proxy) throws Throwable {
-
-		String methodName = method.getName();
-		int params = args.length;
-
-		if ( params==0 ) {
-
-			if ( "writeReplace".equals(methodName) ) {
-				return getReplacement();
-			}
-			else if ( !overridesEquals && "hashCode".equals(methodName) ) {
-				return new Integer( System.identityHashCode(proxy) );
-			}
-			else if ( isUninitialized() && method.equals(getIdentifierMethod) ) {
-				return getIdentifier();
-			}
-
-			else if ( "getHibernateLazyInitializer".equals(methodName) ) {
-				return this;
-			}
-
-		}
-		else if ( params==1 ) {
-
-			if ( !overridesEquals && "equals".equals(methodName) ) {
-				return args[0]==proxy ? Boolean.TRUE : Boolean.FALSE;
-			}
-			else if ( method.equals(setIdentifierMethod) ) {
-				initialize();
-				setIdentifier( (Serializable) args[0] );
-				return INVOKE_IMPLEMENTATION;
-			}
-
-		}
-
-		//if it is a property of an embedded component, invoke on the "identifier"
-		if ( componentIdType!=null && componentIdType.isMethodOf(method) ) {
-			return method.invoke( getIdentifier(), args );
-		}
-
-		// otherwise:
-		return INVOKE_IMPLEMENTATION;
-
-	}
-
-	private Object getReplacement() {
-
-		final SessionImplementor session = getSession();
-		if ( isUninitialized() && session != null && session.isOpen()) {
-			final EntityKey key = new EntityKey(
-					getIdentifier(),
-			        session.getFactory().getEntityPersister( getEntityName() ),
-			        session.getEntityMode()
-				);
-			final Object entity = session.getPersistenceContext().getEntity(key);
-			if (entity!=null) setImplementation( entity );
-		}
-
-		if ( isUninitialized() ) {
-			if (replacement==null) {
-				replacement = serializableProxy();
-			}
-			return replacement;
-		}
-		else {
-			return getTarget();
-		}
-
-	}
-
-	public final Class getPersistentClass() {
-		return persistentClass;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/BasicLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,145 @@
+/*
+ * 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.proxy.pojo;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.util.MarkerObject;
+import org.hibernate.util.ReflectHelper;
+import org.hibernate.proxy.AbstractLazyInitializer;
+
+/**
+ * Lazy initializer for POJOs
+ * 
+ * @author Gavin King
+ */
+public abstract class BasicLazyInitializer extends AbstractLazyInitializer {
+
+	protected static final Object INVOKE_IMPLEMENTATION = new MarkerObject("INVOKE_IMPLEMENTATION");
+
+	protected Class persistentClass;
+	protected Method getIdentifierMethod;
+	protected Method setIdentifierMethod;
+	protected boolean overridesEquals;
+	private Object replacement;
+	protected AbstractComponentType componentIdType;
+
+	protected BasicLazyInitializer(
+			String entityName,
+	        Class persistentClass,
+	        Serializable id,
+	        Method getIdentifierMethod,
+	        Method setIdentifierMethod,
+	        AbstractComponentType componentIdType,
+	        SessionImplementor session) {
+		super(entityName, id, session);
+		this.persistentClass = persistentClass;
+		this.getIdentifierMethod = getIdentifierMethod;
+		this.setIdentifierMethod = setIdentifierMethod;
+		this.componentIdType = componentIdType;
+		overridesEquals = ReflectHelper.overridesEquals(persistentClass);
+	}
+
+	protected abstract Object serializableProxy();
+
+	protected final Object invoke(Method method, Object[] args, Object proxy) throws Throwable {
+
+		String methodName = method.getName();
+		int params = args.length;
+
+		if ( params==0 ) {
+
+			if ( "writeReplace".equals(methodName) ) {
+				return getReplacement();
+			}
+			else if ( !overridesEquals && "hashCode".equals(methodName) ) {
+				return new Integer( System.identityHashCode(proxy) );
+			}
+			else if ( isUninitialized() && method.equals(getIdentifierMethod) ) {
+				return getIdentifier();
+			}
+
+			else if ( "getHibernateLazyInitializer".equals(methodName) ) {
+				return this;
+			}
+
+		}
+		else if ( params==1 ) {
+
+			if ( !overridesEquals && "equals".equals(methodName) ) {
+				return args[0]==proxy ? Boolean.TRUE : Boolean.FALSE;
+			}
+			else if ( method.equals(setIdentifierMethod) ) {
+				initialize();
+				setIdentifier( (Serializable) args[0] );
+				return INVOKE_IMPLEMENTATION;
+			}
+
+		}
+
+		//if it is a property of an embedded component, invoke on the "identifier"
+		if ( componentIdType!=null && componentIdType.isMethodOf(method) ) {
+			return method.invoke( getIdentifier(), args );
+		}
+
+		// otherwise:
+		return INVOKE_IMPLEMENTATION;
+
+	}
+
+	private Object getReplacement() {
+
+		final SessionImplementor session = getSession();
+		if ( isUninitialized() && session != null && session.isOpen()) {
+			final EntityKey key = new EntityKey(
+					getIdentifier(),
+			        session.getFactory().getEntityPersister( getEntityName() ),
+			        session.getEntityMode()
+				);
+			final Object entity = session.getPersistenceContext().getEntity(key);
+			if (entity!=null) setImplementation( entity );
+		}
+
+		if ( isUninitialized() ) {
+			if (replacement==null) {
+				replacement = serializableProxy();
+			}
+			return replacement;
+		}
+		else {
+			return getTarget();
+		}
+
+	}
+
+	public final Class getPersistentClass() {
+		return persistentClass;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,198 +0,0 @@
-// $Id: CGLIBLazyInitializer.java 11295 2007-03-18 04:05:28Z scottmarlownovell $
-package org.hibernate.proxy.pojo.cglib;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import org.hibernate.repackage.cglib.proxy.Callback;
-import org.hibernate.repackage.cglib.proxy.CallbackFilter;
-import org.hibernate.repackage.cglib.proxy.Enhancer;
-import org.hibernate.repackage.cglib.proxy.InvocationHandler;
-import org.hibernate.repackage.cglib.proxy.NoOp;
-
-import org.hibernate.HibernateException;
-import org.hibernate.LazyInitializationException;
-import org.hibernate.proxy.pojo.BasicLazyInitializer;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.util.ReflectHelper;
-
-import org.slf4j.LoggerFactory;
-
-/**
- * A <tt>LazyInitializer</tt> implemented using the CGLIB bytecode generation library
- */
-public final class CGLIBLazyInitializer extends BasicLazyInitializer implements InvocationHandler {
-
-	private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
-		public int accept(Method method) {
-			if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
-				return 1;
-			}
-			else {
-				return 0;
-			}
-		}
-	};
-
-	private Class[] interfaces;
-	private boolean constructed = false;
-
-	static HibernateProxy getProxy(final String entityName, final Class persistentClass,
-			final Class[] interfaces, final Method getIdentifierMethod,
-			final Method setIdentifierMethod, AbstractComponentType componentIdType,
-			final Serializable id, final SessionImplementor session) throws HibernateException {
-		// note: interfaces is assumed to already contain HibernateProxy.class
-
-		try {
-			final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
-					entityName,
-					persistentClass,
-					interfaces,
-					id,
-					getIdentifierMethod,
-					setIdentifierMethod,
-					componentIdType,
-					session
-				);
-
-			final HibernateProxy proxy;
-			Class factory = getProxyFactory(persistentClass,  interfaces);
-			proxy = getProxyInstance(factory, instance);
-			instance.constructed = true;
-			return proxy;
-		}
-		catch (Throwable t) {
-			LoggerFactory.getLogger( BasicLazyInitializer.class )
-				.error( "CGLIB Enhancement failed: " + entityName, t );
-			throw new HibernateException( "CGLIB Enhancement failed: " + entityName, t );
-		}
-	}
-
-	public static HibernateProxy getProxy(final Class factory, final String entityName,
-			final Class persistentClass, final Class[] interfaces,
-			final Method getIdentifierMethod, final Method setIdentifierMethod,
-			final AbstractComponentType componentIdType, final Serializable id,
-			final SessionImplementor session) throws HibernateException {
-
-		final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
-				entityName,
-				persistentClass,
-				interfaces,
-				id,
-				getIdentifierMethod,
-				setIdentifierMethod,
-				componentIdType,
-				session
-			);
-
-		final HibernateProxy proxy;
-		try {
-			proxy = getProxyInstance(factory, instance);
-		}
-		catch (Exception e) {
-			throw new HibernateException( "CGLIB Enhancement failed: " + persistentClass.getName(), e );
-		}
-		instance.constructed = true;
-
-		return proxy;
-	}
-
-    private static HibernateProxy getProxyInstance(Class factory, CGLIBLazyInitializer instance) throws InstantiationException, IllegalAccessException {
-		HibernateProxy proxy;
-		try {
-			Enhancer.registerCallbacks(factory, new Callback[]{ instance, null });
-			proxy = (HibernateProxy)factory.newInstance();
-		} finally {
-			// HHH-2481 make sure the callback gets cleared, otherwise the instance stays in a static thread local.
-			Enhancer.registerCallbacks(factory, null);
-		}
-		return proxy;
-	}
-
-	public static Class getProxyFactory(Class persistentClass, Class[] interfaces)
-			throws HibernateException {
-		Enhancer e = new Enhancer();
-		e.setSuperclass( interfaces.length == 1 ? persistentClass : null );
-		e.setInterfaces(interfaces);
-		e.setCallbackTypes(new Class[]{
-			InvocationHandler.class,
-			NoOp.class,
-	  		});
-  		e.setCallbackFilter(FINALIZE_FILTER);
-  		e.setUseFactory(false);
-		e.setInterceptDuringConstruction( false );
-		return e.createClass();
-	}
-
-	private CGLIBLazyInitializer(final String entityName, final Class persistentClass,
-			final Class[] interfaces, final Serializable id, final Method getIdentifierMethod,
-			final Method setIdentifierMethod, final AbstractComponentType componentIdType,
-			final SessionImplementor session) {
-		super(
-				entityName,
-				persistentClass,
-				id,
-				getIdentifierMethod,
-				setIdentifierMethod,
-				componentIdType,
-				session
-			);
-		this.interfaces = interfaces;
-	}
-
-	public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
-		if ( constructed ) {
-			Object result = invoke( method, args, proxy );
-			if ( result == INVOKE_IMPLEMENTATION ) {
-				Object target = getImplementation();
-				try {
-					final Object returnValue;
-					if ( ReflectHelper.isPublic( persistentClass, method ) ) {
-						if ( !method.getDeclaringClass().isInstance( target ) ) {
-							throw new ClassCastException( target.getClass().getName() );
-						}
-						returnValue = method.invoke( target, args );
-					}
-					else {
-						if ( !method.isAccessible() ) {
-							method.setAccessible( true );
-						}
-						returnValue = method.invoke( target, args );
-					}
-					return returnValue == target ? proxy : returnValue;
-				}
-				catch ( InvocationTargetException ite ) {
-					throw ite.getTargetException();
-				}
-			}
-			else {
-				return result;
-			}
-		}
-		else {
-			// while constructor is running
-			if ( method.getName().equals( "getHibernateLazyInitializer" ) ) {
-				return this;
-			}
-			else {
-				throw new LazyInitializationException( "unexpected case hit, method=" + method.getName() );
-			}
-		}
-	}
-
-	protected Object serializableProxy() {
-		return new SerializableProxy(
-				getEntityName(),
-				persistentClass,
-				interfaces,
-				getIdentifier(),
-				getIdentifierMethod,
-				setIdentifierMethod,
-				componentIdType 
-			);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,221 @@
+/*
+ * 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.proxy.pojo.cglib;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.hibernate.repackage.cglib.proxy.Callback;
+import org.hibernate.repackage.cglib.proxy.CallbackFilter;
+import org.hibernate.repackage.cglib.proxy.Enhancer;
+import org.hibernate.repackage.cglib.proxy.InvocationHandler;
+import org.hibernate.repackage.cglib.proxy.NoOp;
+
+import org.hibernate.HibernateException;
+import org.hibernate.LazyInitializationException;
+import org.hibernate.proxy.pojo.BasicLazyInitializer;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.util.ReflectHelper;
+
+import org.slf4j.LoggerFactory;
+
+/**
+ * A <tt>LazyInitializer</tt> implemented using the CGLIB bytecode generation library
+ */
+public final class CGLIBLazyInitializer extends BasicLazyInitializer implements InvocationHandler {
+
+	private static final CallbackFilter FINALIZE_FILTER = new CallbackFilter() {
+		public int accept(Method method) {
+			if ( method.getParameterTypes().length == 0 && method.getName().equals("finalize") ){
+				return 1;
+			}
+			else {
+				return 0;
+			}
+		}
+	};
+
+	private Class[] interfaces;
+	private boolean constructed = false;
+
+	static HibernateProxy getProxy(final String entityName, final Class persistentClass,
+			final Class[] interfaces, final Method getIdentifierMethod,
+			final Method setIdentifierMethod, AbstractComponentType componentIdType,
+			final Serializable id, final SessionImplementor session) throws HibernateException {
+		// note: interfaces is assumed to already contain HibernateProxy.class
+
+		try {
+			final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
+					entityName,
+					persistentClass,
+					interfaces,
+					id,
+					getIdentifierMethod,
+					setIdentifierMethod,
+					componentIdType,
+					session
+				);
+
+			final HibernateProxy proxy;
+			Class factory = getProxyFactory(persistentClass,  interfaces);
+			proxy = getProxyInstance(factory, instance);
+			instance.constructed = true;
+			return proxy;
+		}
+		catch (Throwable t) {
+			LoggerFactory.getLogger( BasicLazyInitializer.class )
+				.error( "CGLIB Enhancement failed: " + entityName, t );
+			throw new HibernateException( "CGLIB Enhancement failed: " + entityName, t );
+		}
+	}
+
+	public static HibernateProxy getProxy(final Class factory, final String entityName,
+			final Class persistentClass, final Class[] interfaces,
+			final Method getIdentifierMethod, final Method setIdentifierMethod,
+			final AbstractComponentType componentIdType, final Serializable id,
+			final SessionImplementor session) throws HibernateException {
+
+		final CGLIBLazyInitializer instance = new CGLIBLazyInitializer(
+				entityName,
+				persistentClass,
+				interfaces,
+				id,
+				getIdentifierMethod,
+				setIdentifierMethod,
+				componentIdType,
+				session
+			);
+
+		final HibernateProxy proxy;
+		try {
+			proxy = getProxyInstance(factory, instance);
+		}
+		catch (Exception e) {
+			throw new HibernateException( "CGLIB Enhancement failed: " + persistentClass.getName(), e );
+		}
+		instance.constructed = true;
+
+		return proxy;
+	}
+
+    private static HibernateProxy getProxyInstance(Class factory, CGLIBLazyInitializer instance) throws InstantiationException, IllegalAccessException {
+		HibernateProxy proxy;
+		try {
+			Enhancer.registerCallbacks(factory, new Callback[]{ instance, null });
+			proxy = (HibernateProxy)factory.newInstance();
+		} finally {
+			// HHH-2481 make sure the callback gets cleared, otherwise the instance stays in a static thread local.
+			Enhancer.registerCallbacks(factory, null);
+		}
+		return proxy;
+	}
+
+	public static Class getProxyFactory(Class persistentClass, Class[] interfaces)
+			throws HibernateException {
+		Enhancer e = new Enhancer();
+		e.setSuperclass( interfaces.length == 1 ? persistentClass : null );
+		e.setInterfaces(interfaces);
+		e.setCallbackTypes(new Class[]{
+			InvocationHandler.class,
+			NoOp.class,
+	  		});
+  		e.setCallbackFilter(FINALIZE_FILTER);
+  		e.setUseFactory(false);
+		e.setInterceptDuringConstruction( false );
+		return e.createClass();
+	}
+
+	private CGLIBLazyInitializer(final String entityName, final Class persistentClass,
+			final Class[] interfaces, final Serializable id, final Method getIdentifierMethod,
+			final Method setIdentifierMethod, final AbstractComponentType componentIdType,
+			final SessionImplementor session) {
+		super(
+				entityName,
+				persistentClass,
+				id,
+				getIdentifierMethod,
+				setIdentifierMethod,
+				componentIdType,
+				session
+			);
+		this.interfaces = interfaces;
+	}
+
+	public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+		if ( constructed ) {
+			Object result = invoke( method, args, proxy );
+			if ( result == INVOKE_IMPLEMENTATION ) {
+				Object target = getImplementation();
+				try {
+					final Object returnValue;
+					if ( ReflectHelper.isPublic( persistentClass, method ) ) {
+						if ( !method.getDeclaringClass().isInstance( target ) ) {
+							throw new ClassCastException( target.getClass().getName() );
+						}
+						returnValue = method.invoke( target, args );
+					}
+					else {
+						if ( !method.isAccessible() ) {
+							method.setAccessible( true );
+						}
+						returnValue = method.invoke( target, args );
+					}
+					return returnValue == target ? proxy : returnValue;
+				}
+				catch ( InvocationTargetException ite ) {
+					throw ite.getTargetException();
+				}
+			}
+			else {
+				return result;
+			}
+		}
+		else {
+			// while constructor is running
+			if ( method.getName().equals( "getHibernateLazyInitializer" ) ) {
+				return this;
+			}
+			else {
+				throw new LazyInitializationException( "unexpected case hit, method=" + method.getName() );
+			}
+		}
+	}
+
+	protected Object serializableProxy() {
+		return new SerializableProxy(
+				getEntityName(),
+				persistentClass,
+				interfaces,
+				getIdentifier(),
+				getIdentifierMethod,
+				setIdentifierMethod,
+				componentIdType 
+			);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-//$Id: CGLIBProxyFactory.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.pojo.cglib;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * @author Gavin King
- */
-public class CGLIBProxyFactory implements ProxyFactory {
-
-	protected static final Class[] NO_CLASSES = new Class[0];
-
-	private Class persistentClass;
-	private String entityName;
-	private Class[] interfaces;
-	private Method getIdentifierMethod;
-	private Method setIdentifierMethod;
-	private AbstractComponentType componentIdType;
-	private Class factory;
-
-	public void postInstantiate(
-		final String entityName,
-		final Class persistentClass,
-		final Set interfaces,
-		final Method getIdentifierMethod,
-		final Method setIdentifierMethod,
-		AbstractComponentType componentIdType)
-	throws HibernateException {
-		this.entityName = entityName;
-		this.persistentClass = persistentClass;
-		this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
-		this.getIdentifierMethod = getIdentifierMethod;
-		this.setIdentifierMethod = setIdentifierMethod;
-		this.componentIdType = componentIdType;
-		factory = CGLIBLazyInitializer.getProxyFactory(persistentClass, this.interfaces);
-	}
-
-	public HibernateProxy getProxy(Serializable id, SessionImplementor session)
-		throws HibernateException {
-
-		return CGLIBLazyInitializer.getProxy(
-				factory, 
-				entityName, 
-				persistentClass, 
-				interfaces, 
-				getIdentifierMethod, 
-				setIdentifierMethod,
-				componentIdType,
-				id, 
-				session
-			);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/CGLIBProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.proxy.pojo.cglib;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * @author Gavin King
+ */
+public class CGLIBProxyFactory implements ProxyFactory {
+
+	protected static final Class[] NO_CLASSES = new Class[0];
+
+	private Class persistentClass;
+	private String entityName;
+	private Class[] interfaces;
+	private Method getIdentifierMethod;
+	private Method setIdentifierMethod;
+	private AbstractComponentType componentIdType;
+	private Class factory;
+
+	public void postInstantiate(
+		final String entityName,
+		final Class persistentClass,
+		final Set interfaces,
+		final Method getIdentifierMethod,
+		final Method setIdentifierMethod,
+		AbstractComponentType componentIdType)
+	throws HibernateException {
+		this.entityName = entityName;
+		this.persistentClass = persistentClass;
+		this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
+		this.getIdentifierMethod = getIdentifierMethod;
+		this.setIdentifierMethod = setIdentifierMethod;
+		this.componentIdType = componentIdType;
+		factory = CGLIBLazyInitializer.getProxyFactory(persistentClass, this.interfaces);
+	}
+
+	public HibernateProxy getProxy(Serializable id, SessionImplementor session)
+		throws HibernateException {
+
+		return CGLIBLazyInitializer.getProxy(
+				factory, 
+				entityName, 
+				persistentClass, 
+				interfaces, 
+				getIdentifierMethod, 
+				setIdentifierMethod,
+				componentIdType,
+				id, 
+				session
+			);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,75 +0,0 @@
-//$Id: SerializableProxy.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.proxy.pojo.cglib;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.HibernateException;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * Serializable placeholder for <tt>CGLIB</tt> proxies
- */
-public final class SerializableProxy implements Serializable {
-
-	private String entityName;
-	private Class persistentClass;
-	private Class[] interfaces;
-	private Serializable id;
-	private Class getIdentifierMethodClass;
-	private Class setIdentifierMethodClass;
-	private String getIdentifierMethodName;
-	private String setIdentifierMethodName;
-	private Class[] setIdentifierMethodParams;
-	private AbstractComponentType componentIdType;
-
-	public SerializableProxy() {}
-
-	public SerializableProxy(
-		final String entityName,
-		final Class persistentClass,
-		final Class[] interfaces,
-		final Serializable id,
-		final Method getIdentifierMethod,
-		final Method setIdentifierMethod,
-		AbstractComponentType componentIdType
-	) {
-		this.entityName = entityName;
-		this.persistentClass = persistentClass;
-		this.interfaces = interfaces;
-		this.id = id;
-		if (getIdentifierMethod!=null) {
-			getIdentifierMethodClass = getIdentifierMethod.getDeclaringClass();
-			getIdentifierMethodName = getIdentifierMethod.getName();
-		}
-		if (setIdentifierMethod!=null) {
-			setIdentifierMethodClass = setIdentifierMethod.getDeclaringClass();
-			setIdentifierMethodName = setIdentifierMethod.getName();
-			setIdentifierMethodParams = setIdentifierMethod.getParameterTypes();
-		}
-		this.componentIdType = componentIdType;
-	}
-
-	private Object readResolve() {
-		try {
-			return CGLIBLazyInitializer.getProxy(
-				entityName,
-				persistentClass,
-				interfaces,
-				getIdentifierMethodName==null ?
-					null :
-					getIdentifierMethodClass.getDeclaredMethod(getIdentifierMethodName, null),
-				setIdentifierMethodName==null ?
-					null :
-					setIdentifierMethodClass.getDeclaredMethod(setIdentifierMethodName, setIdentifierMethodParams),
-					componentIdType,
-				id,
-				null
-			);
-		}
-		catch (NoSuchMethodException nsme) {
-			throw new HibernateException("could not create proxy for entity: " + entityName, nsme);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/cglib/SerializableProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.pojo.cglib;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * Serializable placeholder for <tt>CGLIB</tt> proxies
+ */
+public final class SerializableProxy implements Serializable {
+
+	private String entityName;
+	private Class persistentClass;
+	private Class[] interfaces;
+	private Serializable id;
+	private Class getIdentifierMethodClass;
+	private Class setIdentifierMethodClass;
+	private String getIdentifierMethodName;
+	private String setIdentifierMethodName;
+	private Class[] setIdentifierMethodParams;
+	private AbstractComponentType componentIdType;
+
+	public SerializableProxy() {}
+
+	public SerializableProxy(
+		final String entityName,
+		final Class persistentClass,
+		final Class[] interfaces,
+		final Serializable id,
+		final Method getIdentifierMethod,
+		final Method setIdentifierMethod,
+		AbstractComponentType componentIdType
+	) {
+		this.entityName = entityName;
+		this.persistentClass = persistentClass;
+		this.interfaces = interfaces;
+		this.id = id;
+		if (getIdentifierMethod!=null) {
+			getIdentifierMethodClass = getIdentifierMethod.getDeclaringClass();
+			getIdentifierMethodName = getIdentifierMethod.getName();
+		}
+		if (setIdentifierMethod!=null) {
+			setIdentifierMethodClass = setIdentifierMethod.getDeclaringClass();
+			setIdentifierMethodName = setIdentifierMethod.getName();
+			setIdentifierMethodParams = setIdentifierMethod.getParameterTypes();
+		}
+		this.componentIdType = componentIdType;
+	}
+
+	private Object readResolve() {
+		try {
+			return CGLIBLazyInitializer.getProxy(
+				entityName,
+				persistentClass,
+				interfaces,
+				getIdentifierMethodName==null ?
+					null :
+					getIdentifierMethodClass.getDeclaredMethod(getIdentifierMethodName, null),
+				setIdentifierMethodName==null ?
+					null :
+					setIdentifierMethodClass.getDeclaredMethod(setIdentifierMethodName, setIdentifierMethodParams),
+					componentIdType,
+				id,
+				null
+			);
+		}
+		catch (NoSuchMethodException nsme) {
+			throw new HibernateException("could not create proxy for entity: " + entityName, nsme);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,213 +0,0 @@
-package org.hibernate.proxy.pojo.javassist;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-import javassist.util.proxy.MethodFilter;
-import javassist.util.proxy.MethodHandler;
-import javassist.util.proxy.ProxyFactory;
-import javassist.util.proxy.ProxyObject;
-
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.pojo.BasicLazyInitializer;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A Javassist-based lazy initializer proxy.
- *
- * @author Muga Nishizawa
- */
-public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler {
-
-	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
-		public boolean isHandled(Method m) {
-			// skip finalize methods
-			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
-		}
-	};
-
-	private Class[] interfaces;
-	private boolean constructed = false;
-
-	private JavassistLazyInitializer(
-			final String entityName,
-	        final Class persistentClass,
-	        final Class[] interfaces,
-	        final Serializable id,
-	        final Method getIdentifierMethod,
-	        final Method setIdentifierMethod,
-	        final AbstractComponentType componentIdType,
-	        final SessionImplementor session) {
-		super( entityName, persistentClass, id, getIdentifierMethod, setIdentifierMethod, componentIdType, session );
-		this.interfaces = interfaces;
-	}
-
-	public static HibernateProxy getProxy(
-			final String entityName,
-	        final Class persistentClass,
-	        final Class[] interfaces,
-	        final Method getIdentifierMethod,
-	        final Method setIdentifierMethod,
-	        AbstractComponentType componentIdType,
-	        final Serializable id,
-	        final SessionImplementor session) throws HibernateException {
-		// note: interface is assumed to already contain HibernateProxy.class
-		try {
-			final JavassistLazyInitializer instance = new JavassistLazyInitializer(
-					entityName,
-			        persistentClass,
-			        interfaces,
-			        id,
-			        getIdentifierMethod,
-			        setIdentifierMethod,
-			        componentIdType,
-			        session
-			);
-			ProxyFactory factory = new ProxyFactory();
-			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
-			factory.setInterfaces( interfaces );
-			factory.setFilter( FINALIZE_FILTER );
-			Class cl = factory.createClass();
-			final HibernateProxy proxy = ( HibernateProxy ) cl.newInstance();
-			( ( ProxyObject ) proxy ).setHandler( instance );
-			instance.constructed = true;
-			return proxy;
-		}
-		catch ( Throwable t ) {
-			LoggerFactory.getLogger( BasicLazyInitializer.class ).error(
-					"Javassist Enhancement failed: " + entityName, t
-			);
-			throw new HibernateException(
-					"Javassist Enhancement failed: "
-					+ entityName, t
-			);
-		}
-	}
-
-	public static HibernateProxy getProxy(
-			final Class factory,
-	        final String entityName,
-	        final Class persistentClass,
-	        final Class[] interfaces,
-	        final Method getIdentifierMethod,
-	        final Method setIdentifierMethod,
-	        final AbstractComponentType componentIdType,
-	        final Serializable id,
-	        final SessionImplementor session) throws HibernateException {
-
-		final JavassistLazyInitializer instance = new JavassistLazyInitializer(
-				entityName,
-		        persistentClass,
-		        interfaces, id,
-		        getIdentifierMethod,
-		        setIdentifierMethod,
-		        componentIdType,
-		        session
-		);
-
-		final HibernateProxy proxy;
-		try {
-			proxy = ( HibernateProxy ) factory.newInstance();
-		}
-		catch ( Exception e ) {
-			throw new HibernateException(
-					"Javassist Enhancement failed: "
-					+ persistentClass.getName(), e
-			);
-		}
-		( ( ProxyObject ) proxy ).setHandler( instance );
-		instance.constructed = true;
-		return proxy;
-	}
-
-	public static Class getProxyFactory(
-			Class persistentClass,
-	        Class[] interfaces) throws HibernateException {
-		// note: interfaces is assumed to already contain HibernateProxy.class
-
-		try {
-			ProxyFactory factory = new ProxyFactory();
-			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
-			factory.setInterfaces( interfaces );
-			factory.setFilter( FINALIZE_FILTER );
-			return factory.createClass();
-		}
-		catch ( Throwable t ) {
-			LoggerFactory.getLogger( BasicLazyInitializer.class ).error(
-					"Javassist Enhancement failed: "
-					+ persistentClass.getName(), t
-			);
-			throw new HibernateException(
-					"Javassist Enhancement failed: "
-					+ persistentClass.getName(), t
-			);
-		}
-	}
-
-	public Object invoke(
-			final Object proxy,
-			final Method thisMethod,
-			final Method proceed,
-			final Object[] args) throws Throwable {
-		if ( this.constructed ) {
-			Object result;
-			try {
-				result = this.invoke( thisMethod, args, proxy );
-			}
-			catch ( Throwable t ) {
-				throw new Exception( t.getCause() );
-			}
-			if ( result == INVOKE_IMPLEMENTATION ) {
-				Object target = getImplementation();
-				final Object returnValue;
-				try {
-					if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
-						if ( !thisMethod.getDeclaringClass().isInstance( target ) ) {
-							throw new ClassCastException( target.getClass().getName() );
-						}
-						returnValue = thisMethod.invoke( target, args );
-					}
-					else {
-						if ( !thisMethod.isAccessible() ) {
-							thisMethod.setAccessible( true );
-						}
-						returnValue = thisMethod.invoke( target, args );
-					}
-					return returnValue == target ? proxy : returnValue;
-				}
-				catch ( InvocationTargetException ite ) {
-					throw ite.getTargetException();
-				}
-			}
-			else {
-				return result;
-			}
-		}
-		else {
-			// while constructor is running
-			if ( thisMethod.getName().equals( "getHibernateLazyInitializer" ) ) {
-				return this;
-			}
-			else {
-				return proceed.invoke( proxy, args );
-			}
-		}
-	}
-
-	protected Object serializableProxy() {
-		return new SerializableProxy(
-				getEntityName(),
-		        persistentClass,
-		        interfaces,
-		        getIdentifier(),
-		        getIdentifierMethod,
-		        setIdentifierMethod,
-		        componentIdType
-		);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistLazyInitializer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,237 @@
+/*
+ * 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.proxy.pojo.javassist;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import javassist.util.proxy.MethodFilter;
+import javassist.util.proxy.MethodHandler;
+import javassist.util.proxy.ProxyFactory;
+import javassist.util.proxy.ProxyObject;
+
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.pojo.BasicLazyInitializer;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A Javassist-based lazy initializer proxy.
+ *
+ * @author Muga Nishizawa
+ */
+public class JavassistLazyInitializer extends BasicLazyInitializer implements MethodHandler {
+
+	private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
+		public boolean isHandled(Method m) {
+			// skip finalize methods
+			return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
+		}
+	};
+
+	private Class[] interfaces;
+	private boolean constructed = false;
+
+	private JavassistLazyInitializer(
+			final String entityName,
+	        final Class persistentClass,
+	        final Class[] interfaces,
+	        final Serializable id,
+	        final Method getIdentifierMethod,
+	        final Method setIdentifierMethod,
+	        final AbstractComponentType componentIdType,
+	        final SessionImplementor session) {
+		super( entityName, persistentClass, id, getIdentifierMethod, setIdentifierMethod, componentIdType, session );
+		this.interfaces = interfaces;
+	}
+
+	public static HibernateProxy getProxy(
+			final String entityName,
+	        final Class persistentClass,
+	        final Class[] interfaces,
+	        final Method getIdentifierMethod,
+	        final Method setIdentifierMethod,
+	        AbstractComponentType componentIdType,
+	        final Serializable id,
+	        final SessionImplementor session) throws HibernateException {
+		// note: interface is assumed to already contain HibernateProxy.class
+		try {
+			final JavassistLazyInitializer instance = new JavassistLazyInitializer(
+					entityName,
+			        persistentClass,
+			        interfaces,
+			        id,
+			        getIdentifierMethod,
+			        setIdentifierMethod,
+			        componentIdType,
+			        session
+			);
+			ProxyFactory factory = new ProxyFactory();
+			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
+			factory.setInterfaces( interfaces );
+			factory.setFilter( FINALIZE_FILTER );
+			Class cl = factory.createClass();
+			final HibernateProxy proxy = ( HibernateProxy ) cl.newInstance();
+			( ( ProxyObject ) proxy ).setHandler( instance );
+			instance.constructed = true;
+			return proxy;
+		}
+		catch ( Throwable t ) {
+			LoggerFactory.getLogger( BasicLazyInitializer.class ).error(
+					"Javassist Enhancement failed: " + entityName, t
+			);
+			throw new HibernateException(
+					"Javassist Enhancement failed: "
+					+ entityName, t
+			);
+		}
+	}
+
+	public static HibernateProxy getProxy(
+			final Class factory,
+	        final String entityName,
+	        final Class persistentClass,
+	        final Class[] interfaces,
+	        final Method getIdentifierMethod,
+	        final Method setIdentifierMethod,
+	        final AbstractComponentType componentIdType,
+	        final Serializable id,
+	        final SessionImplementor session) throws HibernateException {
+
+		final JavassistLazyInitializer instance = new JavassistLazyInitializer(
+				entityName,
+		        persistentClass,
+		        interfaces, id,
+		        getIdentifierMethod,
+		        setIdentifierMethod,
+		        componentIdType,
+		        session
+		);
+
+		final HibernateProxy proxy;
+		try {
+			proxy = ( HibernateProxy ) factory.newInstance();
+		}
+		catch ( Exception e ) {
+			throw new HibernateException(
+					"Javassist Enhancement failed: "
+					+ persistentClass.getName(), e
+			);
+		}
+		( ( ProxyObject ) proxy ).setHandler( instance );
+		instance.constructed = true;
+		return proxy;
+	}
+
+	public static Class getProxyFactory(
+			Class persistentClass,
+	        Class[] interfaces) throws HibernateException {
+		// note: interfaces is assumed to already contain HibernateProxy.class
+
+		try {
+			ProxyFactory factory = new ProxyFactory();
+			factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
+			factory.setInterfaces( interfaces );
+			factory.setFilter( FINALIZE_FILTER );
+			return factory.createClass();
+		}
+		catch ( Throwable t ) {
+			LoggerFactory.getLogger( BasicLazyInitializer.class ).error(
+					"Javassist Enhancement failed: "
+					+ persistentClass.getName(), t
+			);
+			throw new HibernateException(
+					"Javassist Enhancement failed: "
+					+ persistentClass.getName(), t
+			);
+		}
+	}
+
+	public Object invoke(
+			final Object proxy,
+			final Method thisMethod,
+			final Method proceed,
+			final Object[] args) throws Throwable {
+		if ( this.constructed ) {
+			Object result;
+			try {
+				result = this.invoke( thisMethod, args, proxy );
+			}
+			catch ( Throwable t ) {
+				throw new Exception( t.getCause() );
+			}
+			if ( result == INVOKE_IMPLEMENTATION ) {
+				Object target = getImplementation();
+				final Object returnValue;
+				try {
+					if ( ReflectHelper.isPublic( persistentClass, thisMethod ) ) {
+						if ( !thisMethod.getDeclaringClass().isInstance( target ) ) {
+							throw new ClassCastException( target.getClass().getName() );
+						}
+						returnValue = thisMethod.invoke( target, args );
+					}
+					else {
+						if ( !thisMethod.isAccessible() ) {
+							thisMethod.setAccessible( true );
+						}
+						returnValue = thisMethod.invoke( target, args );
+					}
+					return returnValue == target ? proxy : returnValue;
+				}
+				catch ( InvocationTargetException ite ) {
+					throw ite.getTargetException();
+				}
+			}
+			else {
+				return result;
+			}
+		}
+		else {
+			// while constructor is running
+			if ( thisMethod.getName().equals( "getHibernateLazyInitializer" ) ) {
+				return this;
+			}
+			else {
+				return proceed.invoke( proxy, args );
+			}
+		}
+	}
+
+	protected Object serializableProxy() {
+		return new SerializableProxy(
+				getEntityName(),
+		        persistentClass,
+		        interfaces,
+		        getIdentifier(),
+		        getIdentifierMethod,
+		        setIdentifierMethod,
+		        componentIdType
+		);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-package org.hibernate.proxy.pojo.javassist;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.Set;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * A {@link ProxyFactory} implementation for producing Javassist-based proxies.
- *
- * @author Muga Nishizawa
- */
-public class JavassistProxyFactory implements ProxyFactory, Serializable {
-
-	protected static final Class[] NO_CLASSES = new Class[0];
-	private Class persistentClass;
-	private String entityName;
-	private Class[] interfaces;
-	private Method getIdentifierMethod;
-	private Method setIdentifierMethod;
-	private AbstractComponentType componentIdType;
-	private Class factory;
-
-	public void postInstantiate(
-			final String entityName,
-			final Class persistentClass,
-	        final Set interfaces,
-			final Method getIdentifierMethod,
-	        final Method setIdentifierMethod,
-			AbstractComponentType componentIdType) throws HibernateException {
-		this.entityName = entityName;
-		this.persistentClass = persistentClass;
-		this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
-		this.getIdentifierMethod = getIdentifierMethod;
-		this.setIdentifierMethod = setIdentifierMethod;
-		this.componentIdType = componentIdType;
-		factory = JavassistLazyInitializer.getProxyFactory( persistentClass, this.interfaces );
-	}
-
-	public HibernateProxy getProxy(
-			Serializable id,
-	        SessionImplementor session) throws HibernateException {
-		return JavassistLazyInitializer.getProxy(
-				factory,
-		        entityName,
-				persistentClass,
-		        interfaces,
-		        getIdentifierMethod,
-				setIdentifierMethod,
-		        componentIdType,
-		        id,
-		        session
-		);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/JavassistProxyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.proxy.pojo.javassist;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Set;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * A {@link ProxyFactory} implementation for producing Javassist-based proxies.
+ *
+ * @author Muga Nishizawa
+ */
+public class JavassistProxyFactory implements ProxyFactory, Serializable {
+
+	protected static final Class[] NO_CLASSES = new Class[0];
+	private Class persistentClass;
+	private String entityName;
+	private Class[] interfaces;
+	private Method getIdentifierMethod;
+	private Method setIdentifierMethod;
+	private AbstractComponentType componentIdType;
+	private Class factory;
+
+	public void postInstantiate(
+			final String entityName,
+			final Class persistentClass,
+	        final Set interfaces,
+			final Method getIdentifierMethod,
+	        final Method setIdentifierMethod,
+			AbstractComponentType componentIdType) throws HibernateException {
+		this.entityName = entityName;
+		this.persistentClass = persistentClass;
+		this.interfaces = (Class[]) interfaces.toArray(NO_CLASSES);
+		this.getIdentifierMethod = getIdentifierMethod;
+		this.setIdentifierMethod = setIdentifierMethod;
+		this.componentIdType = componentIdType;
+		factory = JavassistLazyInitializer.getProxyFactory( persistentClass, this.interfaces );
+	}
+
+	public HibernateProxy getProxy(
+			Serializable id,
+	        SessionImplementor session) throws HibernateException {
+		return JavassistLazyInitializer.getProxy(
+				factory,
+		        entityName,
+				persistentClass,
+		        interfaces,
+		        getIdentifierMethod,
+				setIdentifierMethod,
+		        componentIdType,
+		        id,
+		        session
+		);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-package org.hibernate.proxy.pojo.javassist;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.HibernateException;
-import org.hibernate.type.AbstractComponentType;
-
-/**
- * Serializable placeholder for Javassist proxies
- */
-public final class SerializableProxy implements Serializable {
-
-	private String entityName;
-	private Class persistentClass;
-	private Class[] interfaces;
-	private Serializable id;
-	private Class getIdentifierMethodClass;
-	private Class setIdentifierMethodClass;
-	private String getIdentifierMethodName;
-	private String setIdentifierMethodName;
-	private Class[] setIdentifierMethodParams;
-	private AbstractComponentType componentIdType;
-
-	public SerializableProxy() {}
-
-	public SerializableProxy(
-		final String entityName,
-	    final Class persistentClass,
-	    final Class[] interfaces,
-	    final Serializable id,
-	    final Method getIdentifierMethod,
-	    final Method setIdentifierMethod,
-	    AbstractComponentType componentIdType
-	) {
-		this.entityName = entityName;
-		this.persistentClass = persistentClass;
-		this.interfaces = interfaces;
-		this.id = id;
-		if (getIdentifierMethod!=null) {
-			getIdentifierMethodClass = getIdentifierMethod.getDeclaringClass();
-			getIdentifierMethodName = getIdentifierMethod.getName();
-		}
-		if (setIdentifierMethod!=null) {
-			setIdentifierMethodClass = setIdentifierMethod.getDeclaringClass();
-			setIdentifierMethodName = setIdentifierMethod.getName();
-			setIdentifierMethodParams = setIdentifierMethod.getParameterTypes();
-		}
-		this.componentIdType = componentIdType;
-	}
-
-	private Object readResolve() {
-		try {
-			return JavassistLazyInitializer.getProxy(
-				entityName,
-				persistentClass,
-				interfaces,
-				getIdentifierMethodName==null ?
-					null :
-					getIdentifierMethodClass.getDeclaredMethod(getIdentifierMethodName, null),
-				setIdentifierMethodName==null ?
-					null :
-					setIdentifierMethodClass.getDeclaredMethod(setIdentifierMethodName, setIdentifierMethodParams),
-					componentIdType,
-				id,
-				null
-			);
-		}
-		catch (NoSuchMethodException nsme) {
-			throw new HibernateException("could not create proxy for entity: " + entityName, nsme);
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/proxy/pojo/javassist/SerializableProxy.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.proxy.pojo.javassist;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.HibernateException;
+import org.hibernate.type.AbstractComponentType;
+
+/**
+ * Serializable placeholder for Javassist proxies
+ */
+public final class SerializableProxy implements Serializable {
+
+	private String entityName;
+	private Class persistentClass;
+	private Class[] interfaces;
+	private Serializable id;
+	private Class getIdentifierMethodClass;
+	private Class setIdentifierMethodClass;
+	private String getIdentifierMethodName;
+	private String setIdentifierMethodName;
+	private Class[] setIdentifierMethodParams;
+	private AbstractComponentType componentIdType;
+
+	public SerializableProxy() {}
+
+	public SerializableProxy(
+		final String entityName,
+	    final Class persistentClass,
+	    final Class[] interfaces,
+	    final Serializable id,
+	    final Method getIdentifierMethod,
+	    final Method setIdentifierMethod,
+	    AbstractComponentType componentIdType
+	) {
+		this.entityName = entityName;
+		this.persistentClass = persistentClass;
+		this.interfaces = interfaces;
+		this.id = id;
+		if (getIdentifierMethod!=null) {
+			getIdentifierMethodClass = getIdentifierMethod.getDeclaringClass();
+			getIdentifierMethodName = getIdentifierMethod.getName();
+		}
+		if (setIdentifierMethod!=null) {
+			setIdentifierMethodClass = setIdentifierMethod.getDeclaringClass();
+			setIdentifierMethodName = setIdentifierMethod.getName();
+			setIdentifierMethodParams = setIdentifierMethod.getParameterTypes();
+		}
+		this.componentIdType = componentIdType;
+	}
+
+	private Object readResolve() {
+		try {
+			return JavassistLazyInitializer.getProxy(
+				entityName,
+				persistentClass,
+				interfaces,
+				getIdentifierMethodName==null ?
+					null :
+					getIdentifierMethodClass.getDeclaredMethod(getIdentifierMethodName, null),
+				setIdentifierMethodName==null ?
+					null :
+					setIdentifierMethodClass.getDeclaredMethod(setIdentifierMethodName, setIdentifierMethodParams),
+					componentIdType,
+				id,
+				null
+			);
+		}
+		catch (NoSuchMethodException nsme) {
+			throw new HibernateException("could not create proxy for entity: " + entityName, nsme);
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/HibernatePermission.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: HibernatePermission.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.secure;
-
-import java.security.Permission;
-
-/**
- * @author Gavin King
- */
-public class HibernatePermission extends Permission {
-	
-	public static final String INSERT = "insert";
-	public static final String UPDATE = "update";
-	public static final String DELETE = "delete";
-	public static final String READ = "read";
-	public static final String ANY = "*";
-	
-	private final String actions;
-
-	public HibernatePermission(String entityName, String actions) {
-		super(entityName);
-		this.actions = actions;
-	}
-
-	public boolean implies(Permission permission) {
-		//TODO!
-		return ( "*".equals( getName() ) || getName().equals( permission.getName() ) ) &&
-			( "*".equals(actions) || actions.indexOf( permission.getActions() ) >= 0 );
-	}
-
-	public boolean equals(Object obj) {
-		if ( !(obj instanceof HibernatePermission) ) return false;
-		HibernatePermission permission = (HibernatePermission) obj;
-		return permission.getName().equals( getName() ) && 
-			permission.getActions().equals(actions);
-	}
-
-	public int hashCode() {
-		return getName().hashCode() * 37 + actions.hashCode();
-	}
-
-	public String getActions() {
-		return actions;
-	}
-	
-	public String toString() {
-		return "HibernatePermission(" + getName() + ':' + actions + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/HibernatePermission.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/HibernatePermission.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.secure;
+
+import java.security.Permission;
+
+/**
+ * @author Gavin King
+ */
+public class HibernatePermission extends Permission {
+	
+	public static final String INSERT = "insert";
+	public static final String UPDATE = "update";
+	public static final String DELETE = "delete";
+	public static final String READ = "read";
+	public static final String ANY = "*";
+	
+	private final String actions;
+
+	public HibernatePermission(String entityName, String actions) {
+		super(entityName);
+		this.actions = actions;
+	}
+
+	public boolean implies(Permission permission) {
+		//TODO!
+		return ( "*".equals( getName() ) || getName().equals( permission.getName() ) ) &&
+			( "*".equals(actions) || actions.indexOf( permission.getActions() ) >= 0 );
+	}
+
+	public boolean equals(Object obj) {
+		if ( !(obj instanceof HibernatePermission) ) return false;
+		HibernatePermission permission = (HibernatePermission) obj;
+		return permission.getName().equals( getName() ) && 
+			permission.getActions().equals(actions);
+	}
+
+	public int hashCode() {
+		return getName().hashCode() * 37 + actions.hashCode();
+	}
+
+	public String getActions() {
+		return actions;
+	}
+	
+	public String toString() {
+		return "HibernatePermission(" + getName() + ':' + actions + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCConfiguration.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-// $Id: JACCConfiguration.java 7592 2005-07-21 04:56:17Z oneovthafew $
-package org.hibernate.secure;
-
-import java.util.StringTokenizer;
-
-import javax.security.jacc.EJBMethodPermission;
-import javax.security.jacc.PolicyConfiguration;
-import javax.security.jacc.PolicyConfigurationFactory;
-import javax.security.jacc.PolicyContextException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-
-/**
- * Adds Hibernate permissions to roles via JACC
- * 
- * @author Gavin King
- */
-public class JACCConfiguration {
-
-	private static final Logger log = LoggerFactory.getLogger( JACCConfiguration.class );
-
-	private final PolicyConfiguration policyConfiguration;
-
-	public JACCConfiguration(String contextId) throws HibernateException {
-		try {
-			policyConfiguration = PolicyConfigurationFactory
-					.getPolicyConfigurationFactory()
-					.getPolicyConfiguration( contextId, false );
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new HibernateException( "JACC provider class not found", cnfe );
-		}
-		catch (PolicyContextException pce) {
-			throw new HibernateException( "policy context exception occurred", pce );
-		}
-	}
-
-	public void addPermission(String role, String entityName, String action) {
-
-		if ( action.equals( "*" ) ) {
-			action = "insert,read,update,delete";
-		}
-
-		StringTokenizer tok = new StringTokenizer( action, "," );
-
-		while ( tok.hasMoreTokens() ) {
-			String methodName = tok.nextToken().trim();
-			EJBMethodPermission permission = new EJBMethodPermission( 
-					entityName, 
-					methodName, 
-					null, // interfaces
-					null // arguments
-				);
-
-			if ( log.isDebugEnabled() ) {
-				log.debug( "adding permission to role " + role + ": " + permission );
-			}
-			try {
-				policyConfiguration.addToRole( role, permission );
-			}
-			catch (PolicyContextException pce) {
-				throw new HibernateException( "policy context exception occurred", pce );
-			}
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCConfiguration.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCConfiguration.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.secure;
+
+import java.util.StringTokenizer;
+
+import javax.security.jacc.EJBMethodPermission;
+import javax.security.jacc.PolicyConfiguration;
+import javax.security.jacc.PolicyConfigurationFactory;
+import javax.security.jacc.PolicyContextException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+
+/**
+ * Adds Hibernate permissions to roles via JACC
+ * 
+ * @author Gavin King
+ */
+public class JACCConfiguration {
+
+	private static final Logger log = LoggerFactory.getLogger( JACCConfiguration.class );
+
+	private final PolicyConfiguration policyConfiguration;
+
+	public JACCConfiguration(String contextId) throws HibernateException {
+		try {
+			policyConfiguration = PolicyConfigurationFactory
+					.getPolicyConfigurationFactory()
+					.getPolicyConfiguration( contextId, false );
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new HibernateException( "JACC provider class not found", cnfe );
+		}
+		catch (PolicyContextException pce) {
+			throw new HibernateException( "policy context exception occurred", pce );
+		}
+	}
+
+	public void addPermission(String role, String entityName, String action) {
+
+		if ( action.equals( "*" ) ) {
+			action = "insert,read,update,delete";
+		}
+
+		StringTokenizer tok = new StringTokenizer( action, "," );
+
+		while ( tok.hasMoreTokens() ) {
+			String methodName = tok.nextToken().trim();
+			EJBMethodPermission permission = new EJBMethodPermission( 
+					entityName, 
+					methodName, 
+					null, // interfaces
+					null // arguments
+				);
+
+			if ( log.isDebugEnabled() ) {
+				log.debug( "adding permission to role " + role + ": " + permission );
+			}
+			try {
+				policyConfiguration.addToRole( role, permission );
+			}
+			catch (PolicyContextException pce) {
+				throw new HibernateException( "policy context exception occurred", pce );
+			}
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCPermissions.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +0,0 @@
-//$Id: JACCPermissions.java 8661 2005-11-25 12:00:22Z epbernard $
-package org.hibernate.secure;
-
-import java.lang.reflect.UndeclaredThrowableException;
-import java.security.AccessController;
-import java.security.CodeSource;
-import java.security.Policy;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
-import java.util.Set;
-import javax.security.auth.Subject;
-import javax.security.jacc.EJBMethodPermission;
-import javax.security.jacc.PolicyContext;
-import javax.security.jacc.PolicyContextException;
-
-
-/**
- * Copied from JBoss org.jboss.ejb3.security.JaccHelper and org.jboss.ejb3.security.SecurityActions
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- */
-public class JACCPermissions {
-
-	public static void checkPermission(Class clazz, String contextID, EJBMethodPermission methodPerm)
-			throws SecurityException {
-		CodeSource ejbCS = clazz.getProtectionDomain().getCodeSource();
-
-		try {
-			setContextID( contextID );
-
-			Policy policy = Policy.getPolicy();
-			// Get the caller
-			Subject caller = getContextSubject();
-
-			Principal[] principals = null;
-			if ( caller != null ) {
-				// Get the caller principals
-				Set principalsSet = caller.getPrincipals();
-				principals = new Principal[ principalsSet.size() ];
-				principalsSet.toArray( principals );
-			}
-
-			ProtectionDomain pd = new ProtectionDomain( ejbCS, null, null, principals );
-			if ( policy.implies( pd, methodPerm ) == false ) {
-				String msg = "Denied: " + methodPerm + ", caller=" + caller;
-				SecurityException e = new SecurityException( msg );
-				throw e;
-			}
-		}
-		catch (PolicyContextException e) {
-			throw new RuntimeException( e );
-		}
-	}
-
-	interface PolicyContextActions {
-		/**
-		 * The JACC PolicyContext key for the current Subject
-		 */
-		static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
-		PolicyContextActions PRIVILEGED = new PolicyContextActions() {
-			private final PrivilegedExceptionAction exAction = new PrivilegedExceptionAction() {
-				public Object run() throws Exception {
-					return (Subject) PolicyContext.getContext( SUBJECT_CONTEXT_KEY );
-				}
-			};
-
-			public Subject getContextSubject() throws PolicyContextException {
-				try {
-					return (Subject) AccessController.doPrivileged( exAction );
-				}
-				catch (PrivilegedActionException e) {
-					Exception ex = e.getException();
-					if ( ex instanceof PolicyContextException ) {
-						throw (PolicyContextException) ex;
-					}
-					else {
-						throw new UndeclaredThrowableException( ex );
-					}
-				}
-			}
-		};
-
-		PolicyContextActions NON_PRIVILEGED = new PolicyContextActions() {
-			public Subject getContextSubject() throws PolicyContextException {
-				return (Subject) PolicyContext.getContext( SUBJECT_CONTEXT_KEY );
-			}
-		};
-
-		Subject getContextSubject() throws PolicyContextException;
-	}
-
-	static Subject getContextSubject() throws PolicyContextException {
-		if ( System.getSecurityManager() == null ) {
-			return PolicyContextActions.NON_PRIVILEGED.getContextSubject();
-		}
-		else {
-			return PolicyContextActions.PRIVILEGED.getContextSubject();
-		}
-	}
-
-	private static class SetContextID implements PrivilegedAction {
-		String contextID;
-
-		SetContextID(String contextID) {
-			this.contextID = contextID;
-		}
-
-		public Object run() {
-			String previousID = PolicyContext.getContextID();
-			PolicyContext.setContextID( contextID );
-			return previousID;
-		}
-	}
-
-	static String setContextID(String contextID) {
-		PrivilegedAction action = new SetContextID( contextID );
-		String previousID = (String) AccessController.doPrivileged( action );
-		return previousID;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCPermissions.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPermissions.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.secure;
+
+import java.lang.reflect.UndeclaredThrowableException;
+import java.security.AccessController;
+import java.security.CodeSource;
+import java.security.Policy;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.util.Set;
+import javax.security.auth.Subject;
+import javax.security.jacc.EJBMethodPermission;
+import javax.security.jacc.PolicyContext;
+import javax.security.jacc.PolicyContextException;
+
+
+/**
+ * Copied from JBoss org.jboss.ejb3.security.JaccHelper and org.jboss.ejb3.security.SecurityActions
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ */
+public class JACCPermissions {
+
+	public static void checkPermission(Class clazz, String contextID, EJBMethodPermission methodPerm)
+			throws SecurityException {
+		CodeSource ejbCS = clazz.getProtectionDomain().getCodeSource();
+
+		try {
+			setContextID( contextID );
+
+			Policy policy = Policy.getPolicy();
+			// Get the caller
+			Subject caller = getContextSubject();
+
+			Principal[] principals = null;
+			if ( caller != null ) {
+				// Get the caller principals
+				Set principalsSet = caller.getPrincipals();
+				principals = new Principal[ principalsSet.size() ];
+				principalsSet.toArray( principals );
+			}
+
+			ProtectionDomain pd = new ProtectionDomain( ejbCS, null, null, principals );
+			if ( policy.implies( pd, methodPerm ) == false ) {
+				String msg = "Denied: " + methodPerm + ", caller=" + caller;
+				SecurityException e = new SecurityException( msg );
+				throw e;
+			}
+		}
+		catch (PolicyContextException e) {
+			throw new RuntimeException( e );
+		}
+	}
+
+	interface PolicyContextActions {
+		/**
+		 * The JACC PolicyContext key for the current Subject
+		 */
+		static final String SUBJECT_CONTEXT_KEY = "javax.security.auth.Subject.container";
+		PolicyContextActions PRIVILEGED = new PolicyContextActions() {
+			private final PrivilegedExceptionAction exAction = new PrivilegedExceptionAction() {
+				public Object run() throws Exception {
+					return (Subject) PolicyContext.getContext( SUBJECT_CONTEXT_KEY );
+				}
+			};
+
+			public Subject getContextSubject() throws PolicyContextException {
+				try {
+					return (Subject) AccessController.doPrivileged( exAction );
+				}
+				catch (PrivilegedActionException e) {
+					Exception ex = e.getException();
+					if ( ex instanceof PolicyContextException ) {
+						throw (PolicyContextException) ex;
+					}
+					else {
+						throw new UndeclaredThrowableException( ex );
+					}
+				}
+			}
+		};
+
+		PolicyContextActions NON_PRIVILEGED = new PolicyContextActions() {
+			public Subject getContextSubject() throws PolicyContextException {
+				return (Subject) PolicyContext.getContext( SUBJECT_CONTEXT_KEY );
+			}
+		};
+
+		Subject getContextSubject() throws PolicyContextException;
+	}
+
+	static Subject getContextSubject() throws PolicyContextException {
+		if ( System.getSecurityManager() == null ) {
+			return PolicyContextActions.NON_PRIVILEGED.getContextSubject();
+		}
+		else {
+			return PolicyContextActions.PRIVILEGED.getContextSubject();
+		}
+	}
+
+	private static class SetContextID implements PrivilegedAction {
+		String contextID;
+
+		SetContextID(String contextID) {
+			this.contextID = contextID;
+		}
+
+		public Object run() {
+			String previousID = PolicyContext.getContextID();
+			PolicyContext.setContextID( contextID );
+			return previousID;
+		}
+	}
+
+	static String setContextID(String contextID) {
+		PrivilegedAction action = new SetContextID( contextID );
+		String previousID = (String) AccessController.doPrivileged( action );
+		return previousID;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: JACCPreDeleteEventListener.java 8702 2005-11-29 18:34:29Z kabkhan $
-package org.hibernate.secure;
-
-import javax.security.jacc.EJBMethodPermission;
-
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.event.Initializable;
-import org.hibernate.event.PreDeleteEvent;
-import org.hibernate.event.PreDeleteEventListener;
-
-/**
- * Check security before any deletion
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- */
-public class JACCPreDeleteEventListener implements PreDeleteEventListener, Initializable, JACCSecurityListener {
-	private String contextID;
-
-	public boolean onPreDelete(PreDeleteEvent event) {
-
-		EJBMethodPermission deletePermission = new EJBMethodPermission(
-				event.getPersister().getEntityName(),
-				HibernatePermission.DELETE,
-				null,
-				null
-		);
-
-		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, deletePermission );
-
-		return false;
-	}
-
-   public void initialize(Configuration cfg){
-      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
-   }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreDeleteEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.secure;
+
+import javax.security.jacc.EJBMethodPermission;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.event.Initializable;
+import org.hibernate.event.PreDeleteEvent;
+import org.hibernate.event.PreDeleteEventListener;
+
+/**
+ * Check security before any deletion
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ */
+public class JACCPreDeleteEventListener implements PreDeleteEventListener, Initializable, JACCSecurityListener {
+	private String contextID;
+
+	public boolean onPreDelete(PreDeleteEvent event) {
+
+		EJBMethodPermission deletePermission = new EJBMethodPermission(
+				event.getPersister().getEntityName(),
+				HibernatePermission.DELETE,
+				null,
+				null
+		);
+
+		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, deletePermission );
+
+		return false;
+	}
+
+   public void initialize(Configuration cfg){
+      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
+   }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-//$Id: JACCPreInsertEventListener.java 8702 2005-11-29 18:34:29Z kabkhan $
-package org.hibernate.secure;
-
-import javax.security.jacc.EJBMethodPermission;
-
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.event.Initializable;
-import org.hibernate.event.PreInsertEvent;
-import org.hibernate.event.PreInsertEventListener;
-
-/**
- * Check security before an insertion
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- */
-public class JACCPreInsertEventListener implements PreInsertEventListener, Initializable, JACCSecurityListener {
-	private String contextID;
-
-	public boolean onPreInsert(PreInsertEvent event) {
-
-		EJBMethodPermission insertPermission = new EJBMethodPermission(
-				event.getPersister().getEntityName(),
-				HibernatePermission.INSERT,
-				null,
-				null
-		);
-
-		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, insertPermission );
-
-		return false;
-	}
-
-
-   public void initialize(Configuration cfg){
-      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
-   }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreInsertEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.secure;
+
+import javax.security.jacc.EJBMethodPermission;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.event.Initializable;
+import org.hibernate.event.PreInsertEvent;
+import org.hibernate.event.PreInsertEventListener;
+
+/**
+ * Check security before an insertion
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ */
+public class JACCPreInsertEventListener implements PreInsertEventListener, Initializable, JACCSecurityListener {
+	private String contextID;
+
+	public boolean onPreInsert(PreInsertEvent event) {
+
+		EJBMethodPermission insertPermission = new EJBMethodPermission(
+				event.getPersister().getEntityName(),
+				HibernatePermission.INSERT,
+				null,
+				null
+		);
+
+		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, insertPermission );
+
+		return false;
+	}
+
+
+   public void initialize(Configuration cfg){
+      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
+   }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,38 +0,0 @@
-// $Id: JACCPreLoadEventListener.java 8702 2005-11-29 18:34:29Z kabkhan $
-package org.hibernate.secure;
-
-import javax.security.jacc.EJBMethodPermission;
-
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.event.Initializable;
-import org.hibernate.event.PreLoadEvent;
-import org.hibernate.event.PreLoadEventListener;
-
-/**
- * Check security before any load
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- * @version $Revision: 8702 $
- */
-public class JACCPreLoadEventListener implements PreLoadEventListener, Initializable, JACCSecurityListener {
-	private String contextID;
-
-	public void onPreLoad(PreLoadEvent event) {
-
-		EJBMethodPermission loadPermission = new EJBMethodPermission(
-				event.getPersister().getEntityName(),
-				HibernatePermission.READ,
-				null,
-				null
-		);
-
-		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, loadPermission );
-
-	}
-
-
-   public void initialize(Configuration cfg){
-      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
-   }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreLoadEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.secure;
+
+import javax.security.jacc.EJBMethodPermission;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.event.Initializable;
+import org.hibernate.event.PreLoadEvent;
+import org.hibernate.event.PreLoadEventListener;
+
+/**
+ * Check security before any load
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ * @version $Revision: 8702 $
+ */
+public class JACCPreLoadEventListener implements PreLoadEventListener, Initializable, JACCSecurityListener {
+	private String contextID;
+
+	public void onPreLoad(PreLoadEvent event) {
+
+		EJBMethodPermission loadPermission = new EJBMethodPermission(
+				event.getPersister().getEntityName(),
+				HibernatePermission.READ,
+				null,
+				null
+		);
+
+		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, loadPermission );
+
+	}
+
+
+   public void initialize(Configuration cfg){
+      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
+   }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: JACCPreUpdateEventListener.java 8702 2005-11-29 18:34:29Z kabkhan $
-package org.hibernate.secure;
-
-import javax.security.jacc.EJBMethodPermission;
-
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.event.Initializable;
-import org.hibernate.event.PreUpdateEvent;
-import org.hibernate.event.PreUpdateEventListener;
-
-/**
- * Check security before any update
- *
- * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
- * @version $Revision: 8702 $
- */
-public class JACCPreUpdateEventListener implements PreUpdateEventListener, Initializable, JACCSecurityListener {
-	private String contextID;
-
-	public boolean onPreUpdate(PreUpdateEvent event) {
-
-		EJBMethodPermission updatePermission = new EJBMethodPermission(
-				event.getPersister().getEntityName(),
-				HibernatePermission.UPDATE,
-				null,
-				null
-		);
-
-		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, updatePermission );
-
-		return false;
-	}
-
-
-   public void initialize(Configuration cfg){
-      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
-   }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCPreUpdateEventListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.secure;
+
+import javax.security.jacc.EJBMethodPermission;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.event.Initializable;
+import org.hibernate.event.PreUpdateEvent;
+import org.hibernate.event.PreUpdateEventListener;
+
+/**
+ * Check security before any update
+ *
+ * @author <a href="mailto:kabir.khan at jboss.org">Kabir Khan</a>
+ * @version $Revision: 8702 $
+ */
+public class JACCPreUpdateEventListener implements PreUpdateEventListener, Initializable, JACCSecurityListener {
+	private String contextID;
+
+	public boolean onPreUpdate(PreUpdateEvent event) {
+
+		EJBMethodPermission updatePermission = new EJBMethodPermission(
+				event.getPersister().getEntityName(),
+				HibernatePermission.UPDATE,
+				null,
+				null
+		);
+
+		JACCPermissions.checkPermission( event.getEntity().getClass(), contextID, updatePermission );
+
+		return false;
+	}
+
+
+   public void initialize(Configuration cfg){
+      contextID = cfg.getProperty(Environment.JACC_CONTEXTID);
+   }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,11 +0,0 @@
-package org.hibernate.secure;
-
-/**
- * Marker interface for JACC event listeners
- * 
- * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
- * @version $Revision: 8702 $
- */
-public interface JACCSecurityListener{
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/JACCSecurityListener.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.secure;
+
+/**
+ * Marker interface for JACC event listeners
+ * 
+ * @author <a href="kabir.khan at jboss.com">Kabir Khan</a>
+ * @version $Revision: 8702 $
+ */
+public interface JACCSecurityListener{
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/secure/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Declarative security for CRUD operations on entities.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/secure/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/secure/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Declarative security for CRUD operations on entities.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-//$Id: ANSICaseFragment.java 4851 2004-12-02 05:09:49Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- An ANSI SQL CASE expression.
- <br>
- <code>case when ... then ... end as ...</code>
- <br>
- @author Gavin King, Simon Harris
- */
-public class ANSICaseFragment extends CaseFragment {
-
-	public String toFragmentString() {
-		
-		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 )
-			.append("case");
-
-		Iterator iter = cases.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			buf.append(" when ")
-				.append( me.getKey() )
-				.append(" is not null then ")
-				.append( me.getValue() );
-		}
-		
-		buf.append(" end");
-
-		if (returnColumnName!=null) {
-			buf.append(" as ")
-				.append(returnColumnName);
-		}
-
-		return buf.toString();
-	}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSICaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ An ANSI SQL CASE expression.
+ <br>
+ <code>case when ... then ... end as ...</code>
+ <br>
+ @author Gavin King, Simon Harris
+ */
+public class ANSICaseFragment extends CaseFragment {
+
+	public String toFragmentString() {
+		
+		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 )
+			.append("case");
+
+		Iterator iter = cases.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			buf.append(" when ")
+				.append( me.getKey() )
+				.append(" is not null then ")
+				.append( me.getValue() );
+		}
+		
+		buf.append(" end");
+
+		if (returnColumnName!=null) {
+			buf.append(" as ")
+				.append(returnColumnName);
+		}
+
+		return buf.toString();
+	}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,117 +0,0 @@
-//$Id: ANSIJoinFragment.java 4886 2004-12-05 15:04:21Z pgmjsd $
-package org.hibernate.sql;
-
-import org.hibernate.AssertionFailure;
-
-/**
- * An ANSI-style join
- *
- * @author Gavin King
- */
-public class ANSIJoinFragment extends JoinFragment {
-
-	private StringBuffer buffer = new StringBuffer();
-	private StringBuffer conditions = new StringBuffer();
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
-		addJoin(tableName, alias, fkColumns, pkColumns, joinType, null);
-	}
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		String joinString;
-		switch (joinType) {
-			case INNER_JOIN:
-				joinString = " inner join ";
-				break;
-			case LEFT_OUTER_JOIN:
-				joinString = " left outer join ";
-				break;
-			case RIGHT_OUTER_JOIN:
-				joinString = " right outer join ";
-				break;
-			case FULL_JOIN:
-				joinString = " full outer join ";
-				break;
-			default:
-				throw new AssertionFailure("undefined join type");
-		}
-
-		buffer.append(joinString)
-			.append(tableName)
-			.append(' ')
-			.append(alias)
-			.append(" on ");
-
-
-		for ( int j=0; j<fkColumns.length; j++) {
-			/*if ( fkColumns[j].indexOf('.')<1 ) {
-				throw new AssertionFailure("missing alias");
-			}*/
-			buffer.append( fkColumns[j] )
-				.append('=')
-				.append(alias)
-				.append('.')
-				.append( pkColumns[j] );
-			if ( j<fkColumns.length-1 ) buffer.append(" and ");
-		}
-
-		addCondition(buffer, on);
-
-	}
-
-	public String toFromFragmentString() {
-		return buffer.toString();
-	}
-
-	public String toWhereFragmentString() {
-		return conditions.toString();
-	}
-
-	public void addJoins(String fromFragment, String whereFragment) {
-		buffer.append(fromFragment);
-		//where fragment must be empty!
-	}
-
-	public JoinFragment copy() {
-		ANSIJoinFragment copy = new ANSIJoinFragment();
-		copy.buffer = new StringBuffer( buffer.toString() );
-		return copy;
-	}
-
-	public void addCondition(String alias, String[] columns, String condition) {
-		for ( int i=0; i<columns.length; i++ ) {
-			conditions.append(" and ")
-				.append(alias)
-				.append('.')
-				.append( columns[i] )
-				.append(condition);
-		}
-	}
-
-	public void addCrossJoin(String tableName, String alias) {
-		buffer.append(", ")
-			.append(tableName)
-			.append(' ')
-			.append(alias);
-	}
-
-	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
-		throw new UnsupportedOperationException();
-
-	}
-
-	public boolean addCondition(String condition) {
-		return addCondition(conditions, condition);
-	}
-
-	public void addFromFragmentString(String fromFragmentString) {
-		buffer.append(fromFragmentString);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ANSIJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,140 @@
+/*
+ * 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;
+
+import org.hibernate.AssertionFailure;
+
+/**
+ * An ANSI-style join
+ *
+ * @author Gavin King
+ */
+public class ANSIJoinFragment extends JoinFragment {
+
+	private StringBuffer buffer = new StringBuffer();
+	private StringBuffer conditions = new StringBuffer();
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
+		addJoin(tableName, alias, fkColumns, pkColumns, joinType, null);
+	}
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		String joinString;
+		switch (joinType) {
+			case INNER_JOIN:
+				joinString = " inner join ";
+				break;
+			case LEFT_OUTER_JOIN:
+				joinString = " left outer join ";
+				break;
+			case RIGHT_OUTER_JOIN:
+				joinString = " right outer join ";
+				break;
+			case FULL_JOIN:
+				joinString = " full outer join ";
+				break;
+			default:
+				throw new AssertionFailure("undefined join type");
+		}
+
+		buffer.append(joinString)
+			.append(tableName)
+			.append(' ')
+			.append(alias)
+			.append(" on ");
+
+
+		for ( int j=0; j<fkColumns.length; j++) {
+			/*if ( fkColumns[j].indexOf('.')<1 ) {
+				throw new AssertionFailure("missing alias");
+			}*/
+			buffer.append( fkColumns[j] )
+				.append('=')
+				.append(alias)
+				.append('.')
+				.append( pkColumns[j] );
+			if ( j<fkColumns.length-1 ) buffer.append(" and ");
+		}
+
+		addCondition(buffer, on);
+
+	}
+
+	public String toFromFragmentString() {
+		return buffer.toString();
+	}
+
+	public String toWhereFragmentString() {
+		return conditions.toString();
+	}
+
+	public void addJoins(String fromFragment, String whereFragment) {
+		buffer.append(fromFragment);
+		//where fragment must be empty!
+	}
+
+	public JoinFragment copy() {
+		ANSIJoinFragment copy = new ANSIJoinFragment();
+		copy.buffer = new StringBuffer( buffer.toString() );
+		return copy;
+	}
+
+	public void addCondition(String alias, String[] columns, String condition) {
+		for ( int i=0; i<columns.length; i++ ) {
+			conditions.append(" and ")
+				.append(alias)
+				.append('.')
+				.append( columns[i] )
+				.append(condition);
+		}
+	}
+
+	public void addCrossJoin(String tableName, String alias) {
+		buffer.append(", ")
+			.append(tableName)
+			.append(' ')
+			.append(alias);
+	}
+
+	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
+		throw new UnsupportedOperationException();
+
+	}
+
+	public boolean addCondition(String condition) {
+		return addCondition(conditions, condition);
+	}
+
+	public void addFromFragmentString(String fromFragmentString) {
+		buffer.append(fromFragmentString);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Alias.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,90 +0,0 @@
-//$Id: Alias.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.sql;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * An alias generator for SQL identifiers
- * @author Gavin King
- */
-public final class Alias {
-
-	private final int length;
-	private final String suffix;
-
-	/**
-	 * Constructor for Alias.
-	 */
-	public Alias(int length, String suffix) {
-		super();
-		this.length = (suffix==null) ? length : length - suffix.length();
-		this.suffix = suffix;
-	}
-
-	/**
-	 * Constructor for Alias.
-	 */
-	public Alias(String suffix) {
-		super();
-		this.length = Integer.MAX_VALUE;
-		this.suffix = suffix;
-	}
-
-	public String toAliasString(String sqlIdentifier) {
-		char begin = sqlIdentifier.charAt(0);
-		int quoteType = Dialect.QUOTE.indexOf(begin);
-		String unquoted = getUnquotedAliasString(sqlIdentifier, quoteType);
-		if ( quoteType >= 0 ) {
-			char endQuote = Dialect.CLOSED_QUOTE.charAt(quoteType);
-			return begin + unquoted + endQuote;
-		}
-		else {
-			return unquoted;
-		}
-	}
-
-	public String toUnquotedAliasString(String sqlIdentifier) {
-		return getUnquotedAliasString(sqlIdentifier);
-	}
-
-	private String getUnquotedAliasString(String sqlIdentifier) {
-		char begin = sqlIdentifier.charAt(0);
-		int quoteType = Dialect.QUOTE.indexOf(begin);
-		return getUnquotedAliasString(sqlIdentifier, quoteType);
-	}
-
-	private String getUnquotedAliasString(String sqlIdentifier, int quoteType) {
-		String unquoted = sqlIdentifier;
-		if ( quoteType >= 0 ) {
-			//if the identifier is quoted, remove the quotes
-			unquoted = unquoted.substring( 1, unquoted.length()-1 );
-		}
-		if ( unquoted.length() > length ) {
-			//truncate the identifier to the max alias length, less the suffix length
-			unquoted = unquoted.substring(0, length);
-		}
-		if ( suffix == null ) {
-			return unquoted;
-		}
-		else {
-			return unquoted + suffix;
-		}
-	}
-
-	public String[] toUnquotedAliasStrings(String[] sqlIdentifiers) {
-		String[] aliases = new String[ sqlIdentifiers.length ];
-		for ( int i=0; i<sqlIdentifiers.length; i++ ) {
-			aliases[i] = toUnquotedAliasString(sqlIdentifiers[i]);
-		}
-		return aliases;
-	}
-
-	public String[] toAliasStrings(String[] sqlIdentifiers) {
-		String[] aliases = new String[ sqlIdentifiers.length ];
-		for ( int i=0; i<sqlIdentifiers.length; i++ ) {
-			aliases[i] = toAliasString(sqlIdentifiers[i]);
-		}
-		return aliases;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Alias.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Alias.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * An alias generator for SQL identifiers
+ * @author Gavin King
+ */
+public final class Alias {
+
+	private final int length;
+	private final String suffix;
+
+	/**
+	 * Constructor for Alias.
+	 */
+	public Alias(int length, String suffix) {
+		super();
+		this.length = (suffix==null) ? length : length - suffix.length();
+		this.suffix = suffix;
+	}
+
+	/**
+	 * Constructor for Alias.
+	 */
+	public Alias(String suffix) {
+		super();
+		this.length = Integer.MAX_VALUE;
+		this.suffix = suffix;
+	}
+
+	public String toAliasString(String sqlIdentifier) {
+		char begin = sqlIdentifier.charAt(0);
+		int quoteType = Dialect.QUOTE.indexOf(begin);
+		String unquoted = getUnquotedAliasString(sqlIdentifier, quoteType);
+		if ( quoteType >= 0 ) {
+			char endQuote = Dialect.CLOSED_QUOTE.charAt(quoteType);
+			return begin + unquoted + endQuote;
+		}
+		else {
+			return unquoted;
+		}
+	}
+
+	public String toUnquotedAliasString(String sqlIdentifier) {
+		return getUnquotedAliasString(sqlIdentifier);
+	}
+
+	private String getUnquotedAliasString(String sqlIdentifier) {
+		char begin = sqlIdentifier.charAt(0);
+		int quoteType = Dialect.QUOTE.indexOf(begin);
+		return getUnquotedAliasString(sqlIdentifier, quoteType);
+	}
+
+	private String getUnquotedAliasString(String sqlIdentifier, int quoteType) {
+		String unquoted = sqlIdentifier;
+		if ( quoteType >= 0 ) {
+			//if the identifier is quoted, remove the quotes
+			unquoted = unquoted.substring( 1, unquoted.length()-1 );
+		}
+		if ( unquoted.length() > length ) {
+			//truncate the identifier to the max alias length, less the suffix length
+			unquoted = unquoted.substring(0, length);
+		}
+		if ( suffix == null ) {
+			return unquoted;
+		}
+		else {
+			return unquoted + suffix;
+		}
+	}
+
+	public String[] toUnquotedAliasStrings(String[] sqlIdentifiers) {
+		String[] aliases = new String[ sqlIdentifiers.length ];
+		for ( int i=0; i<sqlIdentifiers.length; i++ ) {
+			aliases[i] = toUnquotedAliasString(sqlIdentifiers[i]);
+		}
+		return aliases;
+	}
+
+	public String[] toAliasStrings(String[] sqlIdentifiers) {
+		String[] aliases = new String[ sqlIdentifiers.length ];
+		for ( int i=0; i<sqlIdentifiers.length; i++ ) {
+			aliases[i] = toAliasString(sqlIdentifiers[i]);
+		}
+		return aliases;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: $
-package org.hibernate.sql;
-
-import org.hibernate.AssertionFailure;
-
-/**
- * A Cach&eacute; dialect join.  Differs from ANSI only in that full outer join
- * is not supported.
- *
- * @author Jeff Miller
- * @author Jonathan Levinson
- */
-public class CacheJoinFragment extends ANSIJoinFragment {
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		if ( joinType == FULL_JOIN ) {
-			throw new AssertionFailure( "Cache does not support full outer joins" );
-		}
-		super.addJoin( tableName, alias, fkColumns, pkColumns, joinType, on );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CacheJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.AssertionFailure;
+
+/**
+ * A Cach&eacute; dialect join.  Differs from ANSI only in that full outer join
+ * is not supported.
+ *
+ * @author Jeff Miller
+ * @author Jonathan Levinson
+ */
+public class CacheJoinFragment extends ANSIJoinFragment {
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		if ( joinType == FULL_JOIN ) {
+			throw new AssertionFailure( "Cache does not support full outer joins" );
+		}
+		super.addJoin( tableName, alias, fkColumns, pkColumns, joinType, on );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/CaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,34 +0,0 @@
-//$Id: CaseFragment.java 4070 2004-07-23 05:30:26Z steveebersole $
-package org.hibernate.sql;
-
-import java.util.Map;
-import java.util.LinkedHashMap;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * Abstract SQL case fragment renderer
- *
- * @author Gavin King, Simon Harris
- */
-public abstract class CaseFragment {
-	public abstract String toFragmentString();
-
-	protected String returnColumnName;
-
-	protected Map cases = new LinkedHashMap();
-
-	public CaseFragment setReturnColumnName(String returnColumnName) {
-		this.returnColumnName = returnColumnName;
-		return this;
-	}
-
-	public CaseFragment setReturnColumnName(String returnColumnName, String suffix) {
-		return setReturnColumnName( new Alias(suffix).toAliasString(returnColumnName) );
-	}
-
-	public CaseFragment addWhenColumnNotNull(String alias, String columnName, String value) {
-		cases.put( StringHelper.qualify(alias, columnName), value );
-		return this;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/CaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/CaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * Abstract SQL case fragment renderer
+ *
+ * @author Gavin King, Simon Harris
+ */
+public abstract class CaseFragment {
+	public abstract String toFragmentString();
+
+	protected String returnColumnName;
+
+	protected Map cases = new LinkedHashMap();
+
+	public CaseFragment setReturnColumnName(String returnColumnName) {
+		this.returnColumnName = returnColumnName;
+		return this;
+	}
+
+	public CaseFragment setReturnColumnName(String returnColumnName, String suffix) {
+		return setReturnColumnName( new Alias(suffix).toAliasString(returnColumnName) );
+	}
+
+	public CaseFragment addWhenColumnNotNull(String alias, String columnName, String value) {
+		cases.put( StringHelper.qualify(alias, columnName), value );
+		return this;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ConditionFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: ConditionFragment.java 4218 2004-08-10 05:06:14Z oneovthafew $
-package org.hibernate.sql;
-
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @author Gavin King
- */
-public class ConditionFragment {
-	private String tableAlias;
-	private String[] lhs;
-	private String[] rhs;
-	private String op = "=";
-
-	/**
-	 * Sets the op.
-	 * @param op The op to set
-	 */
-	public ConditionFragment setOp(String op) {
-		this.op = op;
-		return this;
-	}
-
-	/**
-	 * Sets the tableAlias.
-	 * @param tableAlias The tableAlias to set
-	 */
-	public ConditionFragment setTableAlias(String tableAlias) {
-		this.tableAlias = tableAlias;
-		return this;
-	}
-
-	public ConditionFragment setCondition(String[] lhs, String[] rhs) {
-		this.lhs = lhs;
-		this.rhs = rhs;
-		return this;
-	}
-
-	public ConditionFragment setCondition(String[] lhs, String rhs) {
-		this.lhs = lhs;
-		this.rhs = ArrayHelper.fillArray(rhs, lhs.length);
-		return this;
-	}
-
-	public String toFragmentString() {
-		StringBuffer buf = new StringBuffer( lhs.length * 10 );
-		for ( int i=0; i<lhs.length; i++ ) {
-			buf.append(tableAlias)
-				.append('.')
-				.append( lhs[i] )
-				.append(op)
-				.append( rhs[i] );
-			if (i<lhs.length-1) buf.append(" and ");
-		}
-		return buf.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/ConditionFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ConditionFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @author Gavin King
+ */
+public class ConditionFragment {
+	private String tableAlias;
+	private String[] lhs;
+	private String[] rhs;
+	private String op = "=";
+
+	/**
+	 * Sets the op.
+	 * @param op The op to set
+	 */
+	public ConditionFragment setOp(String op) {
+		this.op = op;
+		return this;
+	}
+
+	/**
+	 * Sets the tableAlias.
+	 * @param tableAlias The tableAlias to set
+	 */
+	public ConditionFragment setTableAlias(String tableAlias) {
+		this.tableAlias = tableAlias;
+		return this;
+	}
+
+	public ConditionFragment setCondition(String[] lhs, String[] rhs) {
+		this.lhs = lhs;
+		this.rhs = rhs;
+		return this;
+	}
+
+	public ConditionFragment setCondition(String[] lhs, String rhs) {
+		this.lhs = lhs;
+		this.rhs = ArrayHelper.fillArray(rhs, lhs.length);
+		return this;
+	}
+
+	public String toFragmentString() {
+		StringBuffer buf = new StringBuffer( lhs.length * 10 );
+		for ( int i=0; i<lhs.length; i++ ) {
+			buf.append(tableAlias)
+				.append('.')
+				.append( lhs[i] )
+				.append(op)
+				.append( rhs[i] );
+			if (i<lhs.length-1) buf.append(" and ");
+		}
+		return buf.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,48 +0,0 @@
-//$Id: DecodeCaseFragment.java 4851 2004-12-02 05:09:49Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- An Oracle-style DECODE function.
- <br>
- <code>decode(pkvalue, key1, 1, key2, 2, ..., 0)</code>
- <br>
-
- @author Simon Harris
- */
-public class DecodeCaseFragment extends CaseFragment {
-
-	public String toFragmentString() {
-		
-		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 )
-			.append("decode(");
-
-		Iterator iter = cases.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-
-			if ( iter.hasNext() ) {
-				buf.append(", ")
-					.append( me.getKey() )
-					.append(", ")
-					.append( me.getValue() );
-			}
-			else {
-				buf.insert( 7, me.getKey() )
-					.append(", ")
-					.append( me.getValue() );
-			}
-		}
-
-		buf.append(')');
-		
-		if (returnColumnName!=null) {
-			buf.append(" as ")
-				.append(returnColumnName);
-		}
-		
-		return buf.toString();
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DecodeCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * An Oracle-style DECODE function.
+ * <br>
+ * <code>decode(pkvalue, key1, 1, key2, 2, ..., 0)</code>
+ *
+ * @author Simon Harris
+ */
+public class DecodeCaseFragment extends CaseFragment {
+
+	public String toFragmentString() {
+		
+		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 )
+			.append("decode(");
+
+		Iterator iter = cases.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+
+			if ( iter.hasNext() ) {
+				buf.append(", ")
+					.append( me.getKey() )
+					.append(", ")
+					.append( me.getValue() );
+			}
+			else {
+				buf.insert( 7, me.getKey() )
+					.append(", ")
+					.append( me.getValue() );
+			}
+		}
+
+		buf.append(')');
+		
+		if (returnColumnName!=null) {
+			buf.append(" as ")
+				.append(returnColumnName);
+		}
+		
+		return buf.toString();
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Delete.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,84 +0,0 @@
-//$Id: Delete.java 10226 2006-08-05 04:27:55Z steve.ebersole at jboss.com $
-package org.hibernate.sql;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * An SQL <tt>DELETE</tt> statement
- *
- * @author Gavin King
- */
-public class Delete {
-
-	private String tableName;
-	private String[] primaryKeyColumnNames;
-	private String versionColumnName;
-	private String where;
-
-	private String comment;
-	public Delete setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public Delete setTableName(String tableName) {
-		this.tableName = tableName;
-		return this;
-	}
-
-	public String toStatementString() {
-		StringBuffer buf = new StringBuffer( tableName.length() + 10 );
-		if ( comment!=null ) {
-			buf.append( "/* " ).append(comment).append( " */ " );
-		}
-		buf.append( "delete from " ).append(tableName);
-		if ( where != null || primaryKeyColumnNames != null || versionColumnName != null ) {
-			buf.append( " where " );
-		}
-		boolean conditionsAppended = false;
-		if ( primaryKeyColumnNames != null ) {
-			buf.append( StringHelper.join( "=? and ", primaryKeyColumnNames ) ).append( "=?" );
-			conditionsAppended = true;
-		}
-		if ( where!=null ) {
-			if ( conditionsAppended ) {
-				buf.append( " and " );
-			}
-			buf.append( where );
-			conditionsAppended = true;
-		}
-		if ( versionColumnName!=null ) {
-			if ( conditionsAppended ) {
-				buf.append( " and " );
-			}
-			buf.append( versionColumnName ).append( "=?" );
-		}
-		return buf.toString();
-	}
-
-	public Delete setWhere(String where) {
-		this.where=where;
-		return this;
-	}
-
-	public Delete addWhereFragment(String fragment) {
-		if ( where == null ) {
-			where = fragment;
-		}
-		else {
-			where += ( " and " + fragment );
-		}
-		return this;
-	}
-
-	public Delete setPrimaryKeyColumnNames(String[] primaryKeyColumnNames) {
-		this.primaryKeyColumnNames = primaryKeyColumnNames;
-		return this;
-	}
-
-	public Delete setVersionColumnName(String versionColumnName) {
-		this.versionColumnName = versionColumnName;
-		return this;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Delete.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Delete.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,107 @@
+/*
+ * 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;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * An SQL <tt>DELETE</tt> statement
+ *
+ * @author Gavin King
+ */
+public class Delete {
+
+	private String tableName;
+	private String[] primaryKeyColumnNames;
+	private String versionColumnName;
+	private String where;
+
+	private String comment;
+	public Delete setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public Delete setTableName(String tableName) {
+		this.tableName = tableName;
+		return this;
+	}
+
+	public String toStatementString() {
+		StringBuffer buf = new StringBuffer( tableName.length() + 10 );
+		if ( comment!=null ) {
+			buf.append( "/* " ).append(comment).append( " */ " );
+		}
+		buf.append( "delete from " ).append(tableName);
+		if ( where != null || primaryKeyColumnNames != null || versionColumnName != null ) {
+			buf.append( " where " );
+		}
+		boolean conditionsAppended = false;
+		if ( primaryKeyColumnNames != null ) {
+			buf.append( StringHelper.join( "=? and ", primaryKeyColumnNames ) ).append( "=?" );
+			conditionsAppended = true;
+		}
+		if ( where!=null ) {
+			if ( conditionsAppended ) {
+				buf.append( " and " );
+			}
+			buf.append( where );
+			conditionsAppended = true;
+		}
+		if ( versionColumnName!=null ) {
+			if ( conditionsAppended ) {
+				buf.append( " and " );
+			}
+			buf.append( versionColumnName ).append( "=?" );
+		}
+		return buf.toString();
+	}
+
+	public Delete setWhere(String where) {
+		this.where=where;
+		return this;
+	}
+
+	public Delete addWhereFragment(String fragment) {
+		if ( where == null ) {
+			where = fragment;
+		}
+		else {
+			where += ( " and " + fragment );
+		}
+		return this;
+	}
+
+	public Delete setPrimaryKeyColumnNames(String[] primaryKeyColumnNames) {
+		this.primaryKeyColumnNames = primaryKeyColumnNames;
+		return this;
+	}
+
+	public Delete setVersionColumnName(String versionColumnName) {
+		this.versionColumnName = versionColumnName;
+		return this;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: DerbyCaseFragment.java 4631 2004-09-29 12:29:05Z pgmjsd $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * @author Simon Johnston
- * @see org.hibernate.dialect.DerbyDialect
- */
-public class DerbyCaseFragment extends CaseFragment {
-
-	/**
-	 * From http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
-	 * <p/>
-	 * The problem we had, was when Hibernate does a select with a case statement, for joined subclasses.
-	 * This seems to be because there was no else at the end of the case statement (other dbs seem to not mind).
-	 */
-	public String toFragmentString() {
-		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
-		buf.append( "case" ); 								//$NON-NLS-1
-		Iterator iter = cases.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = ( Map.Entry ) iter.next();
-			buf.append( " when " )//$NON-NLS-1
-					.append( me.getKey() )
-					.append( " is not null then " )//$NON-NLS-1
-					.append( me.getValue() );
-		}
-		// null is not considered the same type as Integer.
-		buf.append( " else -1" );								//$NON-NLS-1
-		buf.append( " end" );									//$NON-NLS-1
-		if ( returnColumnName != null ) {
-			buf.append( " as " )//$NON-NLS-1
-					.append( returnColumnName );
-		}
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DerbyCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @author Simon Johnston
+ * @see org.hibernate.dialect.DerbyDialect
+ */
+public class DerbyCaseFragment extends CaseFragment {
+
+	/**
+	 * From http://www.jroller.com/comments/kenlars99/Weblog/cloudscape_soon_to_be_derby
+	 * <p/>
+	 * The problem we had, was when Hibernate does a select with a case statement, for joined subclasses.
+	 * This seems to be because there was no else at the end of the case statement (other dbs seem to not mind).
+	 */
+	public String toFragmentString() {
+		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
+		buf.append( "case" ); 								//$NON-NLS-1
+		Iterator iter = cases.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = ( Map.Entry ) iter.next();
+			buf.append( " when " )//$NON-NLS-1
+					.append( me.getKey() )
+					.append( " is not null then " )//$NON-NLS-1
+					.append( me.getValue() );
+		}
+		// null is not considered the same type as Integer.
+		buf.append( " else -1" );								//$NON-NLS-1
+		buf.append( " end" );									//$NON-NLS-1
+		if ( returnColumnName != null ) {
+			buf.append( " as " )//$NON-NLS-1
+					.append( returnColumnName );
+		}
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: DisjunctionFragment.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.sql;
-
-/**
- * A disjunctive string of conditions
- * @author Gavin King
- */
-public class DisjunctionFragment {
-
-	private StringBuffer buffer = new StringBuffer();
-
-	public DisjunctionFragment addCondition(ConditionFragment fragment) {
-		if ( buffer.length()>0 ) buffer.append(" or ");
-		buffer.append("(")
-			.append( fragment.toFragmentString() )
-			.append(")");
-		return this;
-	}
-
-	public String toFragmentString() {
-		return buffer.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/DisjunctionFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+/**
+ * A disjunctive string of conditions
+ * @author Gavin King
+ */
+public class DisjunctionFragment {
+
+	private StringBuffer buffer = new StringBuffer();
+
+	public DisjunctionFragment addCondition(ConditionFragment fragment) {
+		if ( buffer.length()>0 ) buffer.append(" or ");
+		buffer.append("(")
+			.append( fragment.toFragmentString() )
+			.append(")");
+		return this;
+	}
+
+	public String toFragmentString() {
+		return buffer.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,79 +0,0 @@
-//$Id: ForUpdateFragment.java 11320 2007-03-20 11:50:53Z steve.ebersole at jboss.com $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.LockMode;
-import org.hibernate.QueryException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.StringHelper;
-
-/**
- * @author Gavin King
- */
-public class ForUpdateFragment {
-	private final StringBuffer aliases = new StringBuffer();
-	private boolean isNowaitEnabled;
-	private final Dialect dialect;
-
-	public ForUpdateFragment(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	public ForUpdateFragment(Dialect dialect, Map lockModes, Map keyColumnNames) throws QueryException {
-		this( dialect );
-		LockMode upgradeType = null;
-		Iterator iter = lockModes.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			final Map.Entry me = ( Map.Entry ) iter.next();
-			final LockMode lockMode = ( LockMode ) me.getValue();
-			if ( LockMode.READ.lessThan( lockMode ) ) {
-				final String tableAlias = ( String ) me.getKey();
-				if ( dialect.forUpdateOfColumns() ) {
-					String[] keyColumns = ( String[] ) keyColumnNames.get( tableAlias ); //use the id column alias
-					if ( keyColumns == null ) {
-						throw new IllegalArgumentException( "alias not found: " + tableAlias );
-					}
-					keyColumns = StringHelper.qualify( tableAlias, keyColumns );
-					for ( int i = 0; i < keyColumns.length; i++ ) {
-						addTableAlias( keyColumns[i] );
-					}
-				}
-				else {
-					addTableAlias( tableAlias );
-				}
-				if ( upgradeType != null && lockMode != upgradeType ) {
-					throw new QueryException( "mixed LockModes" );
-				}
-				upgradeType = lockMode;
-			}
-		}
-
-		if ( upgradeType == LockMode.UPGRADE_NOWAIT ) {
-			setNowaitEnabled( true );
-		}
-	}
-
-	public ForUpdateFragment addTableAlias(String alias) {
-		if ( aliases.length() > 0 ) {
-			aliases.append( ", " );
-		}
-		aliases.append( alias );
-		return this;
-	}
-
-	public String toFragmentString() {
-		if ( aliases.length() == 0 ) {
-			return "";
-		}
-		return isNowaitEnabled ?
-				dialect.getForUpdateNowaitString( aliases.toString() ) :
-				dialect.getForUpdateString( aliases.toString() );
-	}
-
-	public ForUpdateFragment setNowaitEnabled(boolean nowait) {
-		isNowaitEnabled = nowait;
-		return this;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/ForUpdateFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.LockMode;
+import org.hibernate.QueryException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+
+/**
+ * @author Gavin King
+ */
+public class ForUpdateFragment {
+	private final StringBuffer aliases = new StringBuffer();
+	private boolean isNowaitEnabled;
+	private final Dialect dialect;
+
+	public ForUpdateFragment(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	public ForUpdateFragment(Dialect dialect, Map lockModes, Map keyColumnNames) throws QueryException {
+		this( dialect );
+		LockMode upgradeType = null;
+		Iterator iter = lockModes.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			final Map.Entry me = ( Map.Entry ) iter.next();
+			final LockMode lockMode = ( LockMode ) me.getValue();
+			if ( LockMode.READ.lessThan( lockMode ) ) {
+				final String tableAlias = ( String ) me.getKey();
+				if ( dialect.forUpdateOfColumns() ) {
+					String[] keyColumns = ( String[] ) keyColumnNames.get( tableAlias ); //use the id column alias
+					if ( keyColumns == null ) {
+						throw new IllegalArgumentException( "alias not found: " + tableAlias );
+					}
+					keyColumns = StringHelper.qualify( tableAlias, keyColumns );
+					for ( int i = 0; i < keyColumns.length; i++ ) {
+						addTableAlias( keyColumns[i] );
+					}
+				}
+				else {
+					addTableAlias( tableAlias );
+				}
+				if ( upgradeType != null && lockMode != upgradeType ) {
+					throw new QueryException( "mixed LockModes" );
+				}
+				upgradeType = lockMode;
+			}
+		}
+
+		if ( upgradeType == LockMode.UPGRADE_NOWAIT ) {
+			setNowaitEnabled( true );
+		}
+	}
+
+	public ForUpdateFragment addTableAlias(String alias) {
+		if ( aliases.length() > 0 ) {
+			aliases.append( ", " );
+		}
+		aliases.append( alias );
+		return this;
+	}
+
+	public String toFragmentString() {
+		if ( aliases.length() == 0 ) {
+			return "";
+		}
+		return isNowaitEnabled ?
+				dialect.getForUpdateNowaitString( aliases.toString() ) :
+				dialect.getForUpdateString( aliases.toString() );
+	}
+
+	public ForUpdateFragment setNowaitEnabled(boolean nowait) {
+		isNowaitEnabled = nowait;
+		return this;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-//$Id: HSQLCaseFragment.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * The HSQL CASEWHEN function.
- * <br>
- * <code>casewhen(..., ..., ...) as ...</code>
- * <br>
- * @author Wolfgang Jung
- */
-public class HSQLCaseFragment extends CaseFragment {
-
-	public String toFragmentString() {
-		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
-		StringBuffer buf2 = new StringBuffer( cases.size() );
-
-		Iterator iter = cases.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			buf.append(" casewhen(")
-				.append( me.getKey() )
-				.append(" is not null")
-				.append(", ")
-				.append( me.getValue() )
-				.append(", ");
-			buf2.append(")");
-		}
-
-		buf.append("-1"); //null caused some problems
-		buf.append( buf2.toString() );
-		if ( returnColumnName!=null ) {
-			buf.append(" as ")
-				.append(returnColumnName);
-		}
-		return buf.toString();
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/HSQLCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * The HSQL CASEWHEN function.
+ * <br>
+ * <code>casewhen(..., ..., ...) as ...</code>
+ * <br>
+ * @author Wolfgang Jung
+ */
+public class HSQLCaseFragment extends CaseFragment {
+
+	public String toFragmentString() {
+		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
+		StringBuffer buf2 = new StringBuffer( cases.size() );
+
+		Iterator iter = cases.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			buf.append(" casewhen(")
+				.append( me.getKey() )
+				.append(" is not null")
+				.append(", ")
+				.append( me.getValue() )
+				.append(", ");
+			buf2.append(")");
+		}
+
+		buf.append("-1"); //null caused some problems
+		buf.append( buf2.toString() );
+		if ( returnColumnName!=null ) {
+			buf.append(" as ")
+				.append(returnColumnName);
+		}
+		return buf.toString();
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/InFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-//$Id: InFragment.java 7022 2005-06-05 06:36:26Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * An SQL IN expression.
- * <br>
- * <code>... in(...)</code>
- * <br>
- * @author Gavin King
- */
-public class InFragment {
-
-	public static final String NULL = "null";
-	public static final String NOT_NULL = "not null";
-
-	private String columnName;
-	private List values = new ArrayList();
-
-	/**
-	 * @param value, an SQL literal, NULL, or NOT_NULL
-	 */
-	public InFragment addValue(Object value) {
-		values.add(value);
-		return this;
-	}
-
-	public InFragment setColumn(String columnName) {
-		this.columnName = columnName;
-		return this;
-	}
-
-	public InFragment setColumn(String alias, String columnName) {
-		this.columnName = StringHelper.qualify(alias, columnName);
-		return setColumn(this.columnName);
-	}
-
-	public InFragment setFormula(String alias, String formulaTemplate) {
-		this.columnName = StringHelper.replace(formulaTemplate, Template.TEMPLATE, alias);
-		return setColumn(this.columnName);
-	}
-
-	public String toFragmentString() {
-		if ( values.size()==0 ) return "1=2";
-		StringBuffer buf = new StringBuffer( values.size() * 5 );
-		buf.append(columnName);
-		//following doesn't handle (null, not null) but unnecessary
-		//since this would mean all rows
-		if ( values.size()>1 ) {
-			boolean allowNull = false;
-			buf.append(" in (");
-			Iterator iter = values.iterator();
-			while ( iter.hasNext() ) {
-				Object value = iter.next();
-				if ( NULL.equals(value) ) {
-					allowNull = true;
-				}
-				else if ( NOT_NULL.equals(value) ) {
-					throw new IllegalArgumentException("not null makes no sense for in expression");
-				}
-				else {
-					buf.append(value);
-					buf.append(", ");
-				}
-			}
-			buf.setLength( buf.length()-2 );
-			buf.append(')');
-			if (allowNull) {
-				buf.insert(0, " is null or ")
-					.insert(0, columnName)
-					.insert(0, '(')
-					.append(')');
-			}
-		}
-		else {
-			Object value = values.iterator().next();
-			if ( NULL.equals(value) ) {
-				buf.append(" is null");
-			}
-			else if ( NOT_NULL.equals(value) ) {
-				buf.append(" is not null");
-			}
-			else {
-				buf.append("=").append(value);
-			}
-		}
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/InFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * An SQL IN expression.
+ * <br>
+ * <code>... in(...)</code>
+ * <br>
+ * @author Gavin King
+ */
+public class InFragment {
+
+	public static final String NULL = "null";
+	public static final String NOT_NULL = "not null";
+
+	private String columnName;
+	private List values = new ArrayList();
+
+	/**
+	 * @param value, an SQL literal, NULL, or NOT_NULL
+	 */
+	public InFragment addValue(Object value) {
+		values.add(value);
+		return this;
+	}
+
+	public InFragment setColumn(String columnName) {
+		this.columnName = columnName;
+		return this;
+	}
+
+	public InFragment setColumn(String alias, String columnName) {
+		this.columnName = StringHelper.qualify(alias, columnName);
+		return setColumn(this.columnName);
+	}
+
+	public InFragment setFormula(String alias, String formulaTemplate) {
+		this.columnName = StringHelper.replace(formulaTemplate, Template.TEMPLATE, alias);
+		return setColumn(this.columnName);
+	}
+
+	public String toFragmentString() {
+		if ( values.size()==0 ) return "1=2";
+		StringBuffer buf = new StringBuffer( values.size() * 5 );
+		buf.append(columnName);
+		//following doesn't handle (null, not null) but unnecessary
+		//since this would mean all rows
+		if ( values.size()>1 ) {
+			boolean allowNull = false;
+			buf.append(" in (");
+			Iterator iter = values.iterator();
+			while ( iter.hasNext() ) {
+				Object value = iter.next();
+				if ( NULL.equals(value) ) {
+					allowNull = true;
+				}
+				else if ( NOT_NULL.equals(value) ) {
+					throw new IllegalArgumentException("not null makes no sense for in expression");
+				}
+				else {
+					buf.append(value);
+					buf.append(", ");
+				}
+			}
+			buf.setLength( buf.length()-2 );
+			buf.append(')');
+			if (allowNull) {
+				buf.insert(0, " is null or ")
+					.insert(0, columnName)
+					.insert(0, '(')
+					.append(')');
+			}
+		}
+		else {
+			Object value = values.iterator().next();
+			if ( NULL.equals(value) ) {
+				buf.append(" is null");
+			}
+			else if ( NOT_NULL.equals(value) ) {
+				buf.append(" is not null");
+			}
+			else {
+				buf.append("=").append(value);
+			}
+		}
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Insert.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-//$Id: Insert.java 9681 2006-03-24 18:10:04Z steve.ebersole at jboss.com $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.LinkedHashMap;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.type.LiteralType;
-
-/**
- * An SQL <tt>INSERT</tt> statement
- *
- * @author Gavin King
- */
-public class Insert {
-	private Dialect dialect;
-	private String tableName;
-	private String comment;
-	private Map columns = new LinkedHashMap();
-
-	public Insert(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	protected Dialect getDialect() {
-		return dialect;
-	}
-
-	public Insert setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public Insert addColumn(String columnName) {
-		return addColumn(columnName, "?");
-	}
-
-	public Insert addColumns(String[] columnNames) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			addColumn( columnNames[i] );
-		}
-		return this;
-	}
-
-	public Insert addColumns(String[] columnNames, boolean[] insertable) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			if ( insertable[i] ) {
-				addColumn( columnNames[i] );
-			}
-		}
-		return this;
-	}
-
-	public Insert addColumn(String columnName, String value) {
-		columns.put(columnName, value);
-		return this;
-	}
-
-	public Insert addColumn(String columnName, Object value, LiteralType type) throws Exception {
-		return addColumn( columnName, type.objectToSQLString(value, dialect) );
-	}
-
-	public Insert addIdentityColumn(String columnName) {
-		String value = dialect.getIdentityInsertString();
-		if ( value != null ) {
-			addColumn( columnName, value );
-		}
-		return this;
-	}
-
-	public Insert setTableName(String tableName) {
-		this.tableName = tableName;
-		return this;
-	}
-
-	public String toStatementString() {
-		StringBuffer buf = new StringBuffer( columns.size()*15 + tableName.length() + 10 );
-		if ( comment != null ) {
-			buf.append( "/* " ).append( comment ).append( " */ " );
-		}
-		buf.append("insert into ")
-			.append(tableName);
-		if ( columns.size()==0 ) {
-			buf.append(' ').append( dialect.getNoColumnsInsertString() );
-		}
-		else {
-			buf.append(" (");
-			Iterator iter = columns.keySet().iterator();
-			while ( iter.hasNext() ) {
-				buf.append( iter.next() );
-				if ( iter.hasNext() ) {
-					buf.append( ", " );
-				}
-			}
-			buf.append(") values (");
-			iter = columns.values().iterator();
-			while ( iter.hasNext() ) {
-				buf.append( iter.next() );
-				if ( iter.hasNext() ) {
-					buf.append( ", " );
-				}
-			}
-			buf.append(')');
-		}
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Insert.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Insert.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,131 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.type.LiteralType;
+
+/**
+ * An SQL <tt>INSERT</tt> statement
+ *
+ * @author Gavin King
+ */
+public class Insert {
+	private Dialect dialect;
+	private String tableName;
+	private String comment;
+	private Map columns = new LinkedHashMap();
+
+	public Insert(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	protected Dialect getDialect() {
+		return dialect;
+	}
+
+	public Insert setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public Insert addColumn(String columnName) {
+		return addColumn(columnName, "?");
+	}
+
+	public Insert addColumns(String[] columnNames) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			addColumn( columnNames[i] );
+		}
+		return this;
+	}
+
+	public Insert addColumns(String[] columnNames, boolean[] insertable) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			if ( insertable[i] ) {
+				addColumn( columnNames[i] );
+			}
+		}
+		return this;
+	}
+
+	public Insert addColumn(String columnName, String value) {
+		columns.put(columnName, value);
+		return this;
+	}
+
+	public Insert addColumn(String columnName, Object value, LiteralType type) throws Exception {
+		return addColumn( columnName, type.objectToSQLString(value, dialect) );
+	}
+
+	public Insert addIdentityColumn(String columnName) {
+		String value = dialect.getIdentityInsertString();
+		if ( value != null ) {
+			addColumn( columnName, value );
+		}
+		return this;
+	}
+
+	public Insert setTableName(String tableName) {
+		this.tableName = tableName;
+		return this;
+	}
+
+	public String toStatementString() {
+		StringBuffer buf = new StringBuffer( columns.size()*15 + tableName.length() + 10 );
+		if ( comment != null ) {
+			buf.append( "/* " ).append( comment ).append( " */ " );
+		}
+		buf.append("insert into ")
+			.append(tableName);
+		if ( columns.size()==0 ) {
+			buf.append(' ').append( dialect.getNoColumnsInsertString() );
+		}
+		else {
+			buf.append(" (");
+			Iterator iter = columns.keySet().iterator();
+			while ( iter.hasNext() ) {
+				buf.append( iter.next() );
+				if ( iter.hasNext() ) {
+					buf.append( ", " );
+				}
+			}
+			buf.append(") values (");
+			iter = columns.values().iterator();
+			while ( iter.hasNext() ) {
+				buf.append( iter.next() );
+				if ( iter.hasNext() ) {
+					buf.append( ", " );
+				}
+			}
+			buf.append(')');
+		}
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/InsertSelect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-// $Id: InsertSelect.java 7057 2005-06-07 20:06:10Z steveebersole $
-package org.hibernate.sql;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.HibernateException;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-
-/**
- * Implementation of InsertSelect.
- *
- * @author Steve Ebersole
- */
-public class InsertSelect {
-
-	private Dialect dialect;
-	private String tableName;
-	private String comment;
-	private List columnNames = new ArrayList();
-	private Select select;
-
-	public InsertSelect(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	public InsertSelect setTableName(String tableName) {
-		this.tableName = tableName;
-		return this;
-	}
-
-	public InsertSelect setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public InsertSelect addColumn(String columnName) {
-		columnNames.add( columnName );
-		return this;
-	}
-
-	public InsertSelect addColumns(String[] columnNames) {
-		for ( int i = 0; i < columnNames.length; i++ ) {
-			this.columnNames.add( columnNames[i] );
-		}
-		return this;
-	}
-
-	public InsertSelect setSelect(Select select) {
-		this.select = select;
-		return this;
-	}
-
-	public String toStatementString() {
-		if ( tableName == null ) throw new HibernateException( "no table name defined for insert-select" );
-		if ( select == null ) throw new HibernateException( "no select defined for insert-select" );
-
-		StringBuffer buf = new StringBuffer( (columnNames.size() * 15) + tableName.length() + 10 );
-		if ( comment!=null ) {
-			buf.append( "/* " ).append( comment ).append( " */ " );
-		}
-		buf.append( "insert into " ).append( tableName );
-		if ( !columnNames.isEmpty() ) {
-			buf.append( " (" );
-			Iterator itr = columnNames.iterator();
-			while ( itr.hasNext() ) {
-				buf.append( itr.next() );
-				if ( itr.hasNext() ) {
-					buf.append( ", " );
-				}
-			}
-			buf.append( ")" );
-		}
-		buf.append( ' ' ).append( select.toStatementString() );
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/InsertSelect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/InsertSelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.HibernateException;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * Implementation of InsertSelect.
+ *
+ * @author Steve Ebersole
+ */
+public class InsertSelect {
+
+	private Dialect dialect;
+	private String tableName;
+	private String comment;
+	private List columnNames = new ArrayList();
+	private Select select;
+
+	public InsertSelect(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	public InsertSelect setTableName(String tableName) {
+		this.tableName = tableName;
+		return this;
+	}
+
+	public InsertSelect setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public InsertSelect addColumn(String columnName) {
+		columnNames.add( columnName );
+		return this;
+	}
+
+	public InsertSelect addColumns(String[] columnNames) {
+		for ( int i = 0; i < columnNames.length; i++ ) {
+			this.columnNames.add( columnNames[i] );
+		}
+		return this;
+	}
+
+	public InsertSelect setSelect(Select select) {
+		this.select = select;
+		return this;
+	}
+
+	public String toStatementString() {
+		if ( tableName == null ) throw new HibernateException( "no table name defined for insert-select" );
+		if ( select == null ) throw new HibernateException( "no select defined for insert-select" );
+
+		StringBuffer buf = new StringBuffer( (columnNames.size() * 15) + tableName.length() + 10 );
+		if ( comment!=null ) {
+			buf.append( "/* " ).append( comment ).append( " */ " );
+		}
+		buf.append( "insert into " ).append( tableName );
+		if ( !columnNames.isEmpty() ) {
+			buf.append( " (" );
+			Iterator itr = columnNames.iterator();
+			while ( itr.hasNext() ) {
+				buf.append( itr.next() );
+				if ( itr.hasNext() ) {
+					buf.append( ", " );
+				}
+			}
+			buf.append( ")" );
+		}
+		buf.append( ' ' ).append( select.toStatementString() );
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/JoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,87 +0,0 @@
-//$Id: JoinFragment.java 6034 2005-03-07 12:31:37Z pgmjsd $
-package org.hibernate.sql;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * An abstract SQL join fragment renderer
- *
- * @author Gavin King
- */
-public abstract class JoinFragment {
-
-	public abstract void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType);
-
-	public abstract void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on);
-
-	public abstract void addCrossJoin(String tableName, String alias);
-
-	public abstract void addJoins(String fromFragment, String whereFragment);
-
-	public abstract String toFromFragmentString();
-
-	public abstract String toWhereFragmentString();
-
-	// --Commented out by Inspection (12/4/04 9:10 AM): public abstract void addCondition(String alias, String[] columns, String condition);
-	public abstract void addCondition(String alias, String[] fkColumns, String[] pkColumns);
-
-	public abstract boolean addCondition(String condition);
-	// --Commented out by Inspection (12/4/04 9:10 AM): public abstract void addFromFragmentString(String fromFragmentString);
-
-	public abstract JoinFragment copy();
-
-	public static final int INNER_JOIN = 0;
-	public static final int FULL_JOIN = 4;
-	public static final int LEFT_OUTER_JOIN = 1;
-	public static final int RIGHT_OUTER_JOIN = 2;
-
-	private boolean hasFilterCondition = false;
-	private boolean hasThetaJoins = false;
-
-	public void addFragment(JoinFragment ojf) {
-		if ( ojf.hasThetaJoins() ) {
-			hasThetaJoins = true;
-		}
-		addJoins( ojf.toFromFragmentString(), ojf.toWhereFragmentString() );
-	}
-
-	/**
-	 * Appends the 'on' condition to the buffer, returning true if the condition was added.
-	 * Returns false if the 'on' condition was empty.
-	 *
-	 * @param buffer The buffer to append the 'on' condition to.
-	 * @param on     The 'on' condition.
-	 * @return Returns true if the condition was added, false if the condition was already in 'on' string.
-	 */
-	protected boolean addCondition(StringBuffer buffer, String on) {
-		if ( StringHelper.isNotEmpty( on ) ) {
-			if ( !on.startsWith( " and" ) ) buffer.append( " and " );
-			buffer.append( on );
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	/**
-	 * True if the where fragment is from a filter condition.
-	 *
-	 * @return True if the where fragment is from a filter condition.
-	 */
-	public boolean hasFilterCondition() {
-		return hasFilterCondition;
-	}
-
-	public void setHasFilterCondition(boolean b) {
-		this.hasFilterCondition = b;
-	}
-
-	public boolean hasThetaJoins() {
-		return hasThetaJoins;
-	}
-
-	public void setHasThetaJoins(boolean hasThetaJoins) {
-		this.hasThetaJoins = hasThetaJoins;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/JoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/JoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,110 @@
+/*
+ * 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;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * An abstract SQL join fragment renderer
+ *
+ * @author Gavin King
+ */
+public abstract class JoinFragment {
+
+	public abstract void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType);
+
+	public abstract void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on);
+
+	public abstract void addCrossJoin(String tableName, String alias);
+
+	public abstract void addJoins(String fromFragment, String whereFragment);
+
+	public abstract String toFromFragmentString();
+
+	public abstract String toWhereFragmentString();
+
+	// --Commented out by Inspection (12/4/04 9:10 AM): public abstract void addCondition(String alias, String[] columns, String condition);
+	public abstract void addCondition(String alias, String[] fkColumns, String[] pkColumns);
+
+	public abstract boolean addCondition(String condition);
+	// --Commented out by Inspection (12/4/04 9:10 AM): public abstract void addFromFragmentString(String fromFragmentString);
+
+	public abstract JoinFragment copy();
+
+	public static final int INNER_JOIN = 0;
+	public static final int FULL_JOIN = 4;
+	public static final int LEFT_OUTER_JOIN = 1;
+	public static final int RIGHT_OUTER_JOIN = 2;
+
+	private boolean hasFilterCondition = false;
+	private boolean hasThetaJoins = false;
+
+	public void addFragment(JoinFragment ojf) {
+		if ( ojf.hasThetaJoins() ) {
+			hasThetaJoins = true;
+		}
+		addJoins( ojf.toFromFragmentString(), ojf.toWhereFragmentString() );
+	}
+
+	/**
+	 * Appends the 'on' condition to the buffer, returning true if the condition was added.
+	 * Returns false if the 'on' condition was empty.
+	 *
+	 * @param buffer The buffer to append the 'on' condition to.
+	 * @param on     The 'on' condition.
+	 * @return Returns true if the condition was added, false if the condition was already in 'on' string.
+	 */
+	protected boolean addCondition(StringBuffer buffer, String on) {
+		if ( StringHelper.isNotEmpty( on ) ) {
+			if ( !on.startsWith( " and" ) ) buffer.append( " and " );
+			buffer.append( on );
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	/**
+	 * True if the where fragment is from a filter condition.
+	 *
+	 * @return True if the where fragment is from a filter condition.
+	 */
+	public boolean hasFilterCondition() {
+		return hasFilterCondition;
+	}
+
+	public void setHasFilterCondition(boolean b) {
+		this.hasFilterCondition = b;
+	}
+
+	public boolean hasThetaJoins() {
+		return hasThetaJoins;
+	}
+
+	public void setHasThetaJoins(boolean hasThetaJoins) {
+		this.hasThetaJoins = hasThetaJoins;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: MckoiCaseFragment.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-
-/**
- * A Mckoi IF function.
- * <br>
- * <code>if(..., ..., ...) as ...</code>
- * <br>
- * @author Gavin King
- */
-public class MckoiCaseFragment extends CaseFragment {
-
-	public String toFragmentString() {
-		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
-		StringBuffer buf2= new StringBuffer( cases.size() );
-
-		Iterator iter = cases.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			buf.append(" if(")
-				.append( me.getKey() )
-				.append(" is not null")
-				.append(", ")
-				.append( me.getValue() )
-				.append(", ");
-			buf2.append(")");
-		}
-
-		buf.append("null");
-		buf.append(buf2);
-		if (returnColumnName!=null) {
-			buf.append(" as ")
-				.append(returnColumnName);
-		}
-
-		return buf.toString();
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/MckoiCaseFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * A Mckoi IF function.
+ * <br>
+ * <code>if(..., ..., ...) as ...</code>
+ * <br>
+ * @author Gavin King
+ */
+public class MckoiCaseFragment extends CaseFragment {
+
+	public String toFragmentString() {
+		StringBuffer buf = new StringBuffer( cases.size() * 15 + 10 );
+		StringBuffer buf2= new StringBuffer( cases.size() );
+
+		Iterator iter = cases.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			buf.append(" if(")
+				.append( me.getKey() )
+				.append(" is not null")
+				.append(", ")
+				.append( me.getValue() )
+				.append(", ");
+			buf2.append(")");
+		}
+
+		buf.append("null");
+		buf.append(buf2);
+		if (returnColumnName!=null) {
+			buf.append(" as ")
+				.append(returnColumnName);
+		}
+
+		return buf.toString();
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,127 +0,0 @@
-//$Id: OracleJoinFragment.java 6750 2005-05-11 15:26:04Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * An Oracle-style (theta) join
- *
- * @author Jon Lipsky, Gavin King
- */
-public class OracleJoinFragment extends JoinFragment {
-
-	private StringBuffer afterFrom = new StringBuffer();
-	private StringBuffer afterWhere = new StringBuffer();
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
-
-		addCrossJoin( tableName, alias );
-
-		for ( int j = 0; j < fkColumns.length; j++ ) {
-			setHasThetaJoins( true );
-			afterWhere.append( " and " )
-					.append( fkColumns[j] );
-			if ( joinType == RIGHT_OUTER_JOIN || joinType == FULL_JOIN ) afterWhere.append( "(+)" );
-			afterWhere.append( '=' )
-					.append( alias )
-					.append( '.' )
-					.append( pkColumns[j] );
-			if ( joinType == LEFT_OUTER_JOIN || joinType == FULL_JOIN ) afterWhere.append( "(+)" );
-		}
-
-	}
-
-	public String toFromFragmentString() {
-		return afterFrom.toString();
-	}
-
-	public String toWhereFragmentString() {
-		return afterWhere.toString();
-	}
-
-	public void addJoins(String fromFragment, String whereFragment) {
-		afterFrom.append( fromFragment );
-		afterWhere.append( whereFragment );
-	}
-
-	public JoinFragment copy() {
-		OracleJoinFragment copy = new OracleJoinFragment();
-		copy.afterFrom = new StringBuffer( afterFrom.toString() );
-		copy.afterWhere = new StringBuffer( afterWhere.toString() );
-		return copy;
-	}
-
-	public void addCondition(String alias, String[] columns, String condition) {
-		for ( int i = 0; i < columns.length; i++ ) {
-			afterWhere.append( " and " )
-					.append( alias )
-					.append( '.' )
-					.append( columns[i] )
-					.append( condition );
-		}
-	}
-
-	public void addCrossJoin(String tableName, String alias) {
-		afterFrom.append( ", " )
-				.append( tableName )
-				.append( ' ' )
-				.append( alias );
-	}
-
-	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
-		throw new UnsupportedOperationException();
-	}
-
-	public boolean addCondition(String condition) {
-		return addCondition( afterWhere, condition );
-	}
-
-	public void addFromFragmentString(String fromFragmentString) {
-		afterFrom.append( fromFragmentString );
-	}
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		//arbitrary on clause ignored!!
-		addJoin( tableName, alias, fkColumns, pkColumns, joinType );
-		if ( joinType == JoinFragment.INNER_JOIN ) {
-			addCondition( on );
-		}
-		else if ( joinType == JoinFragment.LEFT_OUTER_JOIN ) {
-			addLeftOuterJoinCondition( on );
-		}
-		else {
-			throw new UnsupportedOperationException( "join type not supported by OracleJoinFragment (use Oracle9Dialect)" );
-		}
-	}
-
-	/**
-	 * This method is a bit of a hack, and assumes
-	 * that the column on the "right" side of the
-	 * join appears on the "left" side of the
-	 * operator, which is extremely wierd if this
-	 * was a normal join condition, but is natural
-	 * for a filter.
-	 */
-	private void addLeftOuterJoinCondition(String on) {
-		StringBuffer buf = new StringBuffer( on );
-		for ( int i = 0; i < buf.length(); i++ ) {
-			char character = buf.charAt( i );
-			boolean isInsertPoint = OPERATORS.contains( new Character( character ) ) ||
-					( character == ' ' && buf.length() > i + 3 && "is ".equals( buf.substring( i + 1, i + 4 ) ) );
-			if ( isInsertPoint ) {
-				buf.insert( i, "(+)" );
-				i += 3;
-			}
-		}
-		addCondition( buf.toString() );
-	}
-
-	private static final Set OPERATORS = new HashSet();
-
-	static {
-		OPERATORS.add( new Character( '=' ) );
-		OPERATORS.add( new Character( '<' ) );
-		OPERATORS.add( new Character( '>' ) );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/OracleJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * An Oracle-style (theta) join
+ *
+ * @author Jon Lipsky, Gavin King
+ */
+public class OracleJoinFragment extends JoinFragment {
+
+	private StringBuffer afterFrom = new StringBuffer();
+	private StringBuffer afterWhere = new StringBuffer();
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
+
+		addCrossJoin( tableName, alias );
+
+		for ( int j = 0; j < fkColumns.length; j++ ) {
+			setHasThetaJoins( true );
+			afterWhere.append( " and " )
+					.append( fkColumns[j] );
+			if ( joinType == RIGHT_OUTER_JOIN || joinType == FULL_JOIN ) afterWhere.append( "(+)" );
+			afterWhere.append( '=' )
+					.append( alias )
+					.append( '.' )
+					.append( pkColumns[j] );
+			if ( joinType == LEFT_OUTER_JOIN || joinType == FULL_JOIN ) afterWhere.append( "(+)" );
+		}
+
+	}
+
+	public String toFromFragmentString() {
+		return afterFrom.toString();
+	}
+
+	public String toWhereFragmentString() {
+		return afterWhere.toString();
+	}
+
+	public void addJoins(String fromFragment, String whereFragment) {
+		afterFrom.append( fromFragment );
+		afterWhere.append( whereFragment );
+	}
+
+	public JoinFragment copy() {
+		OracleJoinFragment copy = new OracleJoinFragment();
+		copy.afterFrom = new StringBuffer( afterFrom.toString() );
+		copy.afterWhere = new StringBuffer( afterWhere.toString() );
+		return copy;
+	}
+
+	public void addCondition(String alias, String[] columns, String condition) {
+		for ( int i = 0; i < columns.length; i++ ) {
+			afterWhere.append( " and " )
+					.append( alias )
+					.append( '.' )
+					.append( columns[i] )
+					.append( condition );
+		}
+	}
+
+	public void addCrossJoin(String tableName, String alias) {
+		afterFrom.append( ", " )
+				.append( tableName )
+				.append( ' ' )
+				.append( alias );
+	}
+
+	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean addCondition(String condition) {
+		return addCondition( afterWhere, condition );
+	}
+
+	public void addFromFragmentString(String fromFragmentString) {
+		afterFrom.append( fromFragmentString );
+	}
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		//arbitrary on clause ignored!!
+		addJoin( tableName, alias, fkColumns, pkColumns, joinType );
+		if ( joinType == JoinFragment.INNER_JOIN ) {
+			addCondition( on );
+		}
+		else if ( joinType == JoinFragment.LEFT_OUTER_JOIN ) {
+			addLeftOuterJoinCondition( on );
+		}
+		else {
+			throw new UnsupportedOperationException( "join type not supported by OracleJoinFragment (use Oracle9Dialect)" );
+		}
+	}
+
+	/**
+	 * This method is a bit of a hack, and assumes
+	 * that the column on the "right" side of the
+	 * join appears on the "left" side of the
+	 * operator, which is extremely wierd if this
+	 * was a normal join condition, but is natural
+	 * for a filter.
+	 */
+	private void addLeftOuterJoinCondition(String on) {
+		StringBuffer buf = new StringBuffer( on );
+		for ( int i = 0; i < buf.length(); i++ ) {
+			char character = buf.charAt( i );
+			boolean isInsertPoint = OPERATORS.contains( new Character( character ) ) ||
+					( character == ' ' && buf.length() > i + 3 && "is ".equals( buf.substring( i + 1, i + 4 ) ) );
+			if ( isInsertPoint ) {
+				buf.insert( i, "(+)" );
+				i += 3;
+			}
+		}
+		addCondition( buf.toString() );
+	}
+
+	private static final Set OPERATORS = new HashSet();
+
+	static {
+		OPERATORS.add( new Character( '=' ) );
+		OPERATORS.add( new Character( '<' ) );
+		OPERATORS.add( new Character( '>' ) );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,129 +0,0 @@
-//$Id: QueryJoinFragment.java 4889 2004-12-05 17:20:21Z pgmjsd $
-package org.hibernate.sql;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * A join that appears in a translated HQL query
- *
- * @author Gavin King
- */
-public class QueryJoinFragment extends JoinFragment {
-
-	private StringBuffer afterFrom = new StringBuffer();
-	private StringBuffer afterWhere = new StringBuffer();
-	private Dialect dialect;
-	private boolean useThetaStyleInnerJoins;
-
-	public QueryJoinFragment(Dialect dialect, boolean useThetaStyleInnerJoins) {
-		this.dialect = dialect;
-		this.useThetaStyleInnerJoins = useThetaStyleInnerJoins;
-	}
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
-		addJoin( tableName, alias, alias, fkColumns, pkColumns, joinType, null );
-	}
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		addJoin( tableName, alias, alias, fkColumns, pkColumns, joinType, on );
-	}
-
-	private void addJoin(String tableName, String alias, String concreteAlias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		if ( !useThetaStyleInnerJoins || joinType != INNER_JOIN ) {
-			JoinFragment jf = dialect.createOuterJoinFragment();
-			jf.addJoin( tableName, alias, fkColumns, pkColumns, joinType, on );
-			addFragment( jf );
-		}
-		else {
-			addCrossJoin( tableName, alias );
-			addCondition( concreteAlias, fkColumns, pkColumns );
-			addCondition( on );
-		}
-	}
-
-	public String toFromFragmentString() {
-		return afterFrom.toString();
-	}
-
-	public String toWhereFragmentString() {
-		return afterWhere.toString();
-	}
-
-	public void addJoins(String fromFragment, String whereFragment) {
-		afterFrom.append( fromFragment );
-		afterWhere.append( whereFragment );
-	}
-
-	public JoinFragment copy() {
-		QueryJoinFragment copy = new QueryJoinFragment( dialect, useThetaStyleInnerJoins );
-		copy.afterFrom = new StringBuffer( afterFrom.toString() );
-		copy.afterWhere = new StringBuffer( afterWhere.toString() );
-		return copy;
-	}
-
-	public void addCondition(String alias, String[] columns, String condition) {
-		for ( int i = 0; i < columns.length; i++ ) {
-			afterWhere.append( " and " )
-					.append( alias )
-					.append( '.' )
-					.append( columns[i] )
-					.append( condition );
-		}
-	}
-
-
-	public void addCrossJoin(String tableName, String alias) {
-		afterFrom.append( ", " )
-				.append( tableName )
-				.append( ' ' )
-				.append( alias );
-	}
-
-	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
-		for ( int j = 0; j < fkColumns.length; j++ ) {
-			afterWhere.append( " and " )
-					.append( fkColumns[j] )
-					.append( '=' )
-					.append( alias )
-					.append( '.' )
-					.append( pkColumns[j] );
-		}
-	}
-
-	/**
-	 * Add the condition string to the join fragment.
-	 *
-	 * @param condition
-	 * @return true if the condition was added, false if it was already in the fragment.
-	 */
-	public boolean addCondition(String condition) {
-		// if the condition is not already there...
-		if (
-				afterFrom.toString().indexOf( condition.trim() ) < 0 &&
-				afterWhere.toString().indexOf( condition.trim() ) < 0
-		) {
-			if ( !condition.startsWith( " and " ) ) {
-				afterWhere.append( " and " );
-			}
-			afterWhere.append( condition );
-			return true;
-		}
-		else {
-			return false;
-		}
-	}
-
-	public void addFromFragmentString(String fromFragmentString) {
-		afterFrom.append( fromFragmentString );
-	}
-
-	public void clearWherePart() {
-		afterWhere.setLength( 0 );
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QueryJoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,152 @@
+/*
+ * 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;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A join that appears in a translated HQL query
+ *
+ * @author Gavin King
+ */
+public class QueryJoinFragment extends JoinFragment {
+
+	private StringBuffer afterFrom = new StringBuffer();
+	private StringBuffer afterWhere = new StringBuffer();
+	private Dialect dialect;
+	private boolean useThetaStyleInnerJoins;
+
+	public QueryJoinFragment(Dialect dialect, boolean useThetaStyleInnerJoins) {
+		this.dialect = dialect;
+		this.useThetaStyleInnerJoins = useThetaStyleInnerJoins;
+	}
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
+		addJoin( tableName, alias, alias, fkColumns, pkColumns, joinType, null );
+	}
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		addJoin( tableName, alias, alias, fkColumns, pkColumns, joinType, on );
+	}
+
+	private void addJoin(String tableName, String alias, String concreteAlias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		if ( !useThetaStyleInnerJoins || joinType != INNER_JOIN ) {
+			JoinFragment jf = dialect.createOuterJoinFragment();
+			jf.addJoin( tableName, alias, fkColumns, pkColumns, joinType, on );
+			addFragment( jf );
+		}
+		else {
+			addCrossJoin( tableName, alias );
+			addCondition( concreteAlias, fkColumns, pkColumns );
+			addCondition( on );
+		}
+	}
+
+	public String toFromFragmentString() {
+		return afterFrom.toString();
+	}
+
+	public String toWhereFragmentString() {
+		return afterWhere.toString();
+	}
+
+	public void addJoins(String fromFragment, String whereFragment) {
+		afterFrom.append( fromFragment );
+		afterWhere.append( whereFragment );
+	}
+
+	public JoinFragment copy() {
+		QueryJoinFragment copy = new QueryJoinFragment( dialect, useThetaStyleInnerJoins );
+		copy.afterFrom = new StringBuffer( afterFrom.toString() );
+		copy.afterWhere = new StringBuffer( afterWhere.toString() );
+		return copy;
+	}
+
+	public void addCondition(String alias, String[] columns, String condition) {
+		for ( int i = 0; i < columns.length; i++ ) {
+			afterWhere.append( " and " )
+					.append( alias )
+					.append( '.' )
+					.append( columns[i] )
+					.append( condition );
+		}
+	}
+
+
+	public void addCrossJoin(String tableName, String alias) {
+		afterFrom.append( ", " )
+				.append( tableName )
+				.append( ' ' )
+				.append( alias );
+	}
+
+	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
+		for ( int j = 0; j < fkColumns.length; j++ ) {
+			afterWhere.append( " and " )
+					.append( fkColumns[j] )
+					.append( '=' )
+					.append( alias )
+					.append( '.' )
+					.append( pkColumns[j] );
+		}
+	}
+
+	/**
+	 * Add the condition string to the join fragment.
+	 *
+	 * @param condition
+	 * @return true if the condition was added, false if it was already in the fragment.
+	 */
+	public boolean addCondition(String condition) {
+		// if the condition is not already there...
+		if (
+				afterFrom.toString().indexOf( condition.trim() ) < 0 &&
+				afterWhere.toString().indexOf( condition.trim() ) < 0
+		) {
+			if ( !condition.startsWith( " and " ) ) {
+				afterWhere.append( " and " );
+			}
+			afterWhere.append( condition );
+			return true;
+		}
+		else {
+			return false;
+		}
+	}
+
+	public void addFromFragmentString(String fromFragmentString) {
+		afterFrom.append( fromFragmentString );
+	}
+
+	public void clearWherePart() {
+		afterWhere.setLength( 0 );
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/QuerySelect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,190 +0,0 @@
-//$Id: QuerySelect.java 6999 2005-06-03 02:04:13Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.HashSet;
-import java.util.Iterator;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * A translated HQL query
- * @author Gavin King
- */
-public class QuerySelect {
-	private Dialect dialect;
-	private JoinFragment joins;
-	private StringBuffer select = new StringBuffer();
-	private StringBuffer where = new StringBuffer();
-	private StringBuffer groupBy = new StringBuffer();
-	private StringBuffer orderBy = new StringBuffer();
-	private StringBuffer having = new StringBuffer();
-	private String comment;
-	private boolean distinct=false;
-
-	private static final HashSet DONT_SPACE_TOKENS = new HashSet();
-	static {
-		//dontSpace.add("'");
-		DONT_SPACE_TOKENS.add(".");
-		DONT_SPACE_TOKENS.add("+");
-		DONT_SPACE_TOKENS.add("-");
-		DONT_SPACE_TOKENS.add("/");
-		DONT_SPACE_TOKENS.add("*");
-		DONT_SPACE_TOKENS.add("<");
-		DONT_SPACE_TOKENS.add(">");
-		DONT_SPACE_TOKENS.add("=");
-		DONT_SPACE_TOKENS.add("#");
-		DONT_SPACE_TOKENS.add("~");
-		DONT_SPACE_TOKENS.add("|");
-		DONT_SPACE_TOKENS.add("&");
-		DONT_SPACE_TOKENS.add("<=");
-		DONT_SPACE_TOKENS.add(">=");
-		DONT_SPACE_TOKENS.add("=>");
-		DONT_SPACE_TOKENS.add("=<");
-		DONT_SPACE_TOKENS.add("!=");
-		DONT_SPACE_TOKENS.add("<>");
-		DONT_SPACE_TOKENS.add("!#");
-		DONT_SPACE_TOKENS.add("!~");
-		DONT_SPACE_TOKENS.add("!<");
-		DONT_SPACE_TOKENS.add("!>");
-		DONT_SPACE_TOKENS.add("("); //for MySQL
-		DONT_SPACE_TOKENS.add(")");
-	}
-
-	public QuerySelect(Dialect dialect) {
-		this.dialect = dialect;
-		joins = new QueryJoinFragment(dialect, false);
-	}
-
-	public JoinFragment getJoinFragment() {
-		return joins;
-	}
-
-	public void addSelectFragmentString(String fragment) {
-		if ( fragment.length()>0 && fragment.charAt(0)==',' ) fragment = fragment.substring(1);
-		fragment = fragment.trim();
-		if ( fragment.length()>0 ) {
-			if ( select.length()>0 ) select.append(", ");
-			select.append(fragment);
-		}
-	}
-
-	public void addSelectColumn(String columnName, String alias) {
-		addSelectFragmentString(columnName + ' ' + alias);
-	}
-
-	public void setDistinct(boolean distinct) {
-		this.distinct = distinct;
-	}
-
-	public void setWhereTokens(Iterator tokens) {
-		//if ( conjunctiveWhere.length()>0 ) conjunctiveWhere.append(" and ");
-		appendTokens(where, tokens);
-	}
-
-	public void prependWhereConditions(String conditions) {
-		if (where.length() > 0) {
-			where.insert(0, conditions + " and ");
-		}
-		else {
-			where.append(conditions);
-		}
-	}
-
-	public void setGroupByTokens(Iterator tokens) {
-		//if ( groupBy.length()>0 ) groupBy.append(" and ");
-		appendTokens(groupBy, tokens);
-	}
-
-	public void setOrderByTokens(Iterator tokens) {
-		//if ( orderBy.length()>0 ) orderBy.append(" and ");
-		appendTokens(orderBy, tokens);
-	}
-
-	public void setHavingTokens(Iterator tokens) {
-		//if ( having.length()>0 ) having.append(" and ");
-		appendTokens(having, tokens);
-	}
-
-	public void addOrderBy(String orderByString) {
-		if ( orderBy.length() > 0 ) orderBy.append(", ");
-		orderBy.append(orderByString);
-	}
-
-	public String toQueryString() {
-		StringBuffer buf = new StringBuffer(50);
-		if (comment!=null) buf.append("/* ").append(comment).append(" */ ");
-		buf.append("select ");
-		if (distinct) buf.append("distinct ");
-		String from = joins.toFromFragmentString();
-		if ( from.startsWith(",") ) {
-			from = from.substring(1);
-		}
-		else if ( from.startsWith(" inner join") ){
-			from = from.substring(11);
-		}
-
-		buf.append( select.toString() )
-			.append(" from")
-			.append(from);
-
-		String outerJoinsAfterWhere = joins.toWhereFragmentString().trim();
-		String whereConditions = where.toString().trim();
-		boolean hasOuterJoinsAfterWhere = outerJoinsAfterWhere.length() > 0;
-		boolean hasWhereConditions = whereConditions.length() > 0;
-		if (hasOuterJoinsAfterWhere || hasWhereConditions) {
-			buf.append(" where ");
-			if (hasOuterJoinsAfterWhere) {
-				buf.append( outerJoinsAfterWhere.substring(4) );
-			}
-			if (hasWhereConditions) {
-				if (hasOuterJoinsAfterWhere) {
-					buf.append(" and (");
-				}
-				buf.append(whereConditions);
-				if (hasOuterJoinsAfterWhere) {
-					buf.append(")");
-				}
-			}
-		}
-
-		if ( groupBy.length() > 0 ) buf.append(" group by ").append( groupBy.toString() );
-		if ( having.length() > 0 ) buf.append(" having ").append( having.toString() );
-		if ( orderBy.length() > 0 ) buf.append(" order by ").append( orderBy.toString() );
-
-		return dialect.transformSelectString( buf.toString() );
-	}
-
-	private static void appendTokens(StringBuffer buf, Iterator iter) {
-		boolean lastSpaceable=true;
-		boolean lastQuoted=false;
-		while ( iter.hasNext() ) {
-			String token = (String) iter.next();
-			boolean spaceable = !DONT_SPACE_TOKENS.contains(token);
-			boolean quoted = token.startsWith("'");
-			if (spaceable && lastSpaceable) {
-				if ( !quoted || !lastQuoted ) buf.append(' ');
-			}
-			lastSpaceable = spaceable;
-			buf.append(token);
-			lastQuoted = token.endsWith("'");
-		}
-	}
-
-	public void setComment(String comment) {
-		this.comment = comment;
-	}
-
-	public QuerySelect copy() {
-		QuerySelect copy = new QuerySelect(dialect);
-		copy.joins = this.joins.copy();
-		copy.select.append( this.select.toString() );
-		copy.where.append( this.where.toString() );
-		copy.groupBy.append( this.groupBy.toString() );
-		copy.orderBy.append( this.orderBy.toString() );
-		copy.having.append( this.having.toString() );
-		copy.comment = this.comment;
-		copy.distinct = this.distinct;
-		return copy;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/QuerySelect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/QuerySelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,213 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A translated HQL query
+ * @author Gavin King
+ */
+public class QuerySelect {
+	private Dialect dialect;
+	private JoinFragment joins;
+	private StringBuffer select = new StringBuffer();
+	private StringBuffer where = new StringBuffer();
+	private StringBuffer groupBy = new StringBuffer();
+	private StringBuffer orderBy = new StringBuffer();
+	private StringBuffer having = new StringBuffer();
+	private String comment;
+	private boolean distinct=false;
+
+	private static final HashSet DONT_SPACE_TOKENS = new HashSet();
+	static {
+		//dontSpace.add("'");
+		DONT_SPACE_TOKENS.add(".");
+		DONT_SPACE_TOKENS.add("+");
+		DONT_SPACE_TOKENS.add("-");
+		DONT_SPACE_TOKENS.add("/");
+		DONT_SPACE_TOKENS.add("*");
+		DONT_SPACE_TOKENS.add("<");
+		DONT_SPACE_TOKENS.add(">");
+		DONT_SPACE_TOKENS.add("=");
+		DONT_SPACE_TOKENS.add("#");
+		DONT_SPACE_TOKENS.add("~");
+		DONT_SPACE_TOKENS.add("|");
+		DONT_SPACE_TOKENS.add("&");
+		DONT_SPACE_TOKENS.add("<=");
+		DONT_SPACE_TOKENS.add(">=");
+		DONT_SPACE_TOKENS.add("=>");
+		DONT_SPACE_TOKENS.add("=<");
+		DONT_SPACE_TOKENS.add("!=");
+		DONT_SPACE_TOKENS.add("<>");
+		DONT_SPACE_TOKENS.add("!#");
+		DONT_SPACE_TOKENS.add("!~");
+		DONT_SPACE_TOKENS.add("!<");
+		DONT_SPACE_TOKENS.add("!>");
+		DONT_SPACE_TOKENS.add("("); //for MySQL
+		DONT_SPACE_TOKENS.add(")");
+	}
+
+	public QuerySelect(Dialect dialect) {
+		this.dialect = dialect;
+		joins = new QueryJoinFragment(dialect, false);
+	}
+
+	public JoinFragment getJoinFragment() {
+		return joins;
+	}
+
+	public void addSelectFragmentString(String fragment) {
+		if ( fragment.length()>0 && fragment.charAt(0)==',' ) fragment = fragment.substring(1);
+		fragment = fragment.trim();
+		if ( fragment.length()>0 ) {
+			if ( select.length()>0 ) select.append(", ");
+			select.append(fragment);
+		}
+	}
+
+	public void addSelectColumn(String columnName, String alias) {
+		addSelectFragmentString(columnName + ' ' + alias);
+	}
+
+	public void setDistinct(boolean distinct) {
+		this.distinct = distinct;
+	}
+
+	public void setWhereTokens(Iterator tokens) {
+		//if ( conjunctiveWhere.length()>0 ) conjunctiveWhere.append(" and ");
+		appendTokens(where, tokens);
+	}
+
+	public void prependWhereConditions(String conditions) {
+		if (where.length() > 0) {
+			where.insert(0, conditions + " and ");
+		}
+		else {
+			where.append(conditions);
+		}
+	}
+
+	public void setGroupByTokens(Iterator tokens) {
+		//if ( groupBy.length()>0 ) groupBy.append(" and ");
+		appendTokens(groupBy, tokens);
+	}
+
+	public void setOrderByTokens(Iterator tokens) {
+		//if ( orderBy.length()>0 ) orderBy.append(" and ");
+		appendTokens(orderBy, tokens);
+	}
+
+	public void setHavingTokens(Iterator tokens) {
+		//if ( having.length()>0 ) having.append(" and ");
+		appendTokens(having, tokens);
+	}
+
+	public void addOrderBy(String orderByString) {
+		if ( orderBy.length() > 0 ) orderBy.append(", ");
+		orderBy.append(orderByString);
+	}
+
+	public String toQueryString() {
+		StringBuffer buf = new StringBuffer(50);
+		if (comment!=null) buf.append("/* ").append(comment).append(" */ ");
+		buf.append("select ");
+		if (distinct) buf.append("distinct ");
+		String from = joins.toFromFragmentString();
+		if ( from.startsWith(",") ) {
+			from = from.substring(1);
+		}
+		else if ( from.startsWith(" inner join") ){
+			from = from.substring(11);
+		}
+
+		buf.append( select.toString() )
+			.append(" from")
+			.append(from);
+
+		String outerJoinsAfterWhere = joins.toWhereFragmentString().trim();
+		String whereConditions = where.toString().trim();
+		boolean hasOuterJoinsAfterWhere = outerJoinsAfterWhere.length() > 0;
+		boolean hasWhereConditions = whereConditions.length() > 0;
+		if (hasOuterJoinsAfterWhere || hasWhereConditions) {
+			buf.append(" where ");
+			if (hasOuterJoinsAfterWhere) {
+				buf.append( outerJoinsAfterWhere.substring(4) );
+			}
+			if (hasWhereConditions) {
+				if (hasOuterJoinsAfterWhere) {
+					buf.append(" and (");
+				}
+				buf.append(whereConditions);
+				if (hasOuterJoinsAfterWhere) {
+					buf.append(")");
+				}
+			}
+		}
+
+		if ( groupBy.length() > 0 ) buf.append(" group by ").append( groupBy.toString() );
+		if ( having.length() > 0 ) buf.append(" having ").append( having.toString() );
+		if ( orderBy.length() > 0 ) buf.append(" order by ").append( orderBy.toString() );
+
+		return dialect.transformSelectString( buf.toString() );
+	}
+
+	private static void appendTokens(StringBuffer buf, Iterator iter) {
+		boolean lastSpaceable=true;
+		boolean lastQuoted=false;
+		while ( iter.hasNext() ) {
+			String token = (String) iter.next();
+			boolean spaceable = !DONT_SPACE_TOKENS.contains(token);
+			boolean quoted = token.startsWith("'");
+			if (spaceable && lastSpaceable) {
+				if ( !quoted || !lastQuoted ) buf.append(' ');
+			}
+			lastSpaceable = spaceable;
+			buf.append(token);
+			lastQuoted = token.endsWith("'");
+		}
+	}
+
+	public void setComment(String comment) {
+		this.comment = comment;
+	}
+
+	public QuerySelect copy() {
+		QuerySelect copy = new QuerySelect(dialect);
+		copy.joins = this.joins.copy();
+		copy.select.append( this.select.toString() );
+		copy.where.append( this.where.toString() );
+		copy.groupBy.append( this.groupBy.toString() );
+		copy.orderBy.append( this.orderBy.toString() );
+		copy.having.append( this.having.toString() );
+		copy.comment = this.comment;
+		copy.distinct = this.distinct;
+		return copy;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Select.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,155 +0,0 @@
-//$Id: Select.java 7143 2005-06-15 02:57:03Z oneovthafew $
-package org.hibernate.sql;
-
-import org.hibernate.LockMode;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.StringHelper;
-
-
-/**
- * A simple SQL <tt>SELECT</tt> statement
- * @author Gavin King
- */
-public class Select {
-
-	private String selectClause;
-	private String fromClause;
-	private String outerJoinsAfterFrom;
-	private String whereClause;
-	private String outerJoinsAfterWhere;
-	private String orderByClause;
-	private String groupByClause;
-	private String comment;
-	private LockMode lockMode;
-	public final Dialect dialect;
-
-	private int guesstimatedBufferSize = 20;
-	
-	public Select(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	/**
-	 * Construct an SQL <tt>SELECT</tt> statement from the given clauses
-	 */
-	public String toStatementString() {
-		StringBuffer buf = new StringBuffer(guesstimatedBufferSize);
-		if ( StringHelper.isNotEmpty(comment) ) {
-			buf.append("/* ").append(comment).append(" */ ");
-		}
-		
-		buf.append("select ").append(selectClause)
-				.append(" from ").append(fromClause);
-		
-		if ( StringHelper.isNotEmpty(outerJoinsAfterFrom) ) {
-			buf.append(outerJoinsAfterFrom);
-		}
-		
-		if ( StringHelper.isNotEmpty(whereClause) || StringHelper.isNotEmpty(outerJoinsAfterWhere) ) {
-			buf.append(" where " );
-			// the outerJoinsAfterWhere needs to come before where clause to properly
-			// handle dynamic filters
-			if ( StringHelper.isNotEmpty(outerJoinsAfterWhere) ) {
-				buf.append(outerJoinsAfterWhere);
-				if ( StringHelper.isNotEmpty(whereClause) ) {
-					buf.append( " and " );
-				}
-			}
-			if ( StringHelper.isNotEmpty(whereClause) ) {
-				buf.append(whereClause);
-			}
-		}
-		
-		if ( StringHelper.isNotEmpty(groupByClause) ) {
-			buf.append(" group by ").append(groupByClause);
-		}
-		
-		if ( StringHelper.isNotEmpty(orderByClause) ) {
-			buf.append(" order by ").append(orderByClause);
-		}
-		
-		if (lockMode!=null) {
-			buf.append( dialect.getForUpdateString(lockMode) );
-		}
-		
-		return dialect.transformSelectString( buf.toString() );
-	}
-
-	/**
-	 * Sets the fromClause.
-	 * @param fromClause The fromClause to set
-	 */
-	public Select setFromClause(String fromClause) {
-		this.fromClause = fromClause;
-		this.guesstimatedBufferSize += fromClause.length();
-		return this;
-	}
-
-	public Select setFromClause(String tableName, String alias) {
-		this.fromClause = tableName + ' ' + alias;
-		this.guesstimatedBufferSize += fromClause.length();
-		return this;
-	}
-
-	public Select setOrderByClause(String orderByClause) {
-		this.orderByClause = orderByClause;
-		this.guesstimatedBufferSize += orderByClause.length();
-		return this;
-	}
-
-	public Select setGroupByClause(String groupByClause) {
-		this.groupByClause = groupByClause;
-		this.guesstimatedBufferSize += groupByClause.length();
-		return this;
-	}
-
-	public Select setOuterJoins(String outerJoinsAfterFrom, String outerJoinsAfterWhere) {
-		this.outerJoinsAfterFrom = outerJoinsAfterFrom;
-
-		// strip off any leading 'and' token
-		String tmpOuterJoinsAfterWhere = outerJoinsAfterWhere.trim();
-		if ( tmpOuterJoinsAfterWhere.startsWith("and") ) {
-			tmpOuterJoinsAfterWhere = tmpOuterJoinsAfterWhere.substring(4);
-		}
-		this.outerJoinsAfterWhere = tmpOuterJoinsAfterWhere;
-
-		this.guesstimatedBufferSize += outerJoinsAfterFrom.length() + outerJoinsAfterWhere.length();
-		return this;
-	}
-
-
-	/**
-	 * Sets the selectClause.
-	 * @param selectClause The selectClause to set
-	 */
-	public Select setSelectClause(String selectClause) {
-		this.selectClause = selectClause;
-		this.guesstimatedBufferSize += selectClause.length();
-		return this;
-	}
-
-	/**
-	 * Sets the whereClause.
-	 * @param whereClause The whereClause to set
-	 */
-	public Select setWhereClause(String whereClause) {
-		this.whereClause = whereClause;
-		this.guesstimatedBufferSize += whereClause.length();
-		return this;
-	}
-
-	public Select setComment(String comment) {
-		this.comment = comment;
-		this.guesstimatedBufferSize += comment.length();
-		return this;
-	}
-
-	public LockMode getLockMode() {
-		return lockMode;
-	}
-	
-	public Select setLockMode(LockMode lockMode) {
-		this.lockMode = lockMode;
-		return this;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Select.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Select.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,178 @@
+/*
+ * 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;
+
+import org.hibernate.LockMode;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+
+
+/**
+ * A simple SQL <tt>SELECT</tt> statement
+ * @author Gavin King
+ */
+public class Select {
+
+	private String selectClause;
+	private String fromClause;
+	private String outerJoinsAfterFrom;
+	private String whereClause;
+	private String outerJoinsAfterWhere;
+	private String orderByClause;
+	private String groupByClause;
+	private String comment;
+	private LockMode lockMode;
+	public final Dialect dialect;
+
+	private int guesstimatedBufferSize = 20;
+	
+	public Select(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	/**
+	 * Construct an SQL <tt>SELECT</tt> statement from the given clauses
+	 */
+	public String toStatementString() {
+		StringBuffer buf = new StringBuffer(guesstimatedBufferSize);
+		if ( StringHelper.isNotEmpty(comment) ) {
+			buf.append("/* ").append(comment).append(" */ ");
+		}
+		
+		buf.append("select ").append(selectClause)
+				.append(" from ").append(fromClause);
+		
+		if ( StringHelper.isNotEmpty(outerJoinsAfterFrom) ) {
+			buf.append(outerJoinsAfterFrom);
+		}
+		
+		if ( StringHelper.isNotEmpty(whereClause) || StringHelper.isNotEmpty(outerJoinsAfterWhere) ) {
+			buf.append(" where " );
+			// the outerJoinsAfterWhere needs to come before where clause to properly
+			// handle dynamic filters
+			if ( StringHelper.isNotEmpty(outerJoinsAfterWhere) ) {
+				buf.append(outerJoinsAfterWhere);
+				if ( StringHelper.isNotEmpty(whereClause) ) {
+					buf.append( " and " );
+				}
+			}
+			if ( StringHelper.isNotEmpty(whereClause) ) {
+				buf.append(whereClause);
+			}
+		}
+		
+		if ( StringHelper.isNotEmpty(groupByClause) ) {
+			buf.append(" group by ").append(groupByClause);
+		}
+		
+		if ( StringHelper.isNotEmpty(orderByClause) ) {
+			buf.append(" order by ").append(orderByClause);
+		}
+		
+		if (lockMode!=null) {
+			buf.append( dialect.getForUpdateString(lockMode) );
+		}
+		
+		return dialect.transformSelectString( buf.toString() );
+	}
+
+	/**
+	 * Sets the fromClause.
+	 * @param fromClause The fromClause to set
+	 */
+	public Select setFromClause(String fromClause) {
+		this.fromClause = fromClause;
+		this.guesstimatedBufferSize += fromClause.length();
+		return this;
+	}
+
+	public Select setFromClause(String tableName, String alias) {
+		this.fromClause = tableName + ' ' + alias;
+		this.guesstimatedBufferSize += fromClause.length();
+		return this;
+	}
+
+	public Select setOrderByClause(String orderByClause) {
+		this.orderByClause = orderByClause;
+		this.guesstimatedBufferSize += orderByClause.length();
+		return this;
+	}
+
+	public Select setGroupByClause(String groupByClause) {
+		this.groupByClause = groupByClause;
+		this.guesstimatedBufferSize += groupByClause.length();
+		return this;
+	}
+
+	public Select setOuterJoins(String outerJoinsAfterFrom, String outerJoinsAfterWhere) {
+		this.outerJoinsAfterFrom = outerJoinsAfterFrom;
+
+		// strip off any leading 'and' token
+		String tmpOuterJoinsAfterWhere = outerJoinsAfterWhere.trim();
+		if ( tmpOuterJoinsAfterWhere.startsWith("and") ) {
+			tmpOuterJoinsAfterWhere = tmpOuterJoinsAfterWhere.substring(4);
+		}
+		this.outerJoinsAfterWhere = tmpOuterJoinsAfterWhere;
+
+		this.guesstimatedBufferSize += outerJoinsAfterFrom.length() + outerJoinsAfterWhere.length();
+		return this;
+	}
+
+
+	/**
+	 * Sets the selectClause.
+	 * @param selectClause The selectClause to set
+	 */
+	public Select setSelectClause(String selectClause) {
+		this.selectClause = selectClause;
+		this.guesstimatedBufferSize += selectClause.length();
+		return this;
+	}
+
+	/**
+	 * Sets the whereClause.
+	 * @param whereClause The whereClause to set
+	 */
+	public Select setWhereClause(String whereClause) {
+		this.whereClause = whereClause;
+		this.guesstimatedBufferSize += whereClause.length();
+		return this;
+	}
+
+	public Select setComment(String comment) {
+		this.comment = comment;
+		this.guesstimatedBufferSize += comment.length();
+		return this;
+	}
+
+	public LockMode getLockMode() {
+		return lockMode;
+	}
+	
+	public Select setLockMode(LockMode lockMode) {
+		this.lockMode = lockMode;
+		return this;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/SelectFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,128 +0,0 @@
-//$Id: SelectFragment.java 7479 2005-07-14 23:56:53Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.util.StringHelper;
-
-/**
- * A fragment of an SQL <tt>SELECT</tt> clause
- *
- * @author Gavin King
- */
-public class SelectFragment {
-	private String suffix;
-	private List columns = new ArrayList();
-	//private List aliases = new ArrayList();
-	private List columnAliases = new ArrayList();
-	private String extraSelectList;
-	private String[] usedAliases;
-	
-	public SelectFragment() {}
-	
-	public SelectFragment setUsedAliases(String[] aliases) {
-		usedAliases = aliases;
-		return this;
-	}
-	
-	public SelectFragment setExtraSelectList(String extraSelectList) {
-		this.extraSelectList = extraSelectList;
-		return this;
-	}
-	
-	public SelectFragment setExtraSelectList(CaseFragment caseFragment, String fragmentAlias) {
-		setExtraSelectList( caseFragment.setReturnColumnName(fragmentAlias, suffix).toFragmentString() );
-		return this;
-	}
-
-	public SelectFragment setSuffix(String suffix) {
-		this.suffix = suffix;
-		return this;
-	}
-
-	public SelectFragment addColumn(String columnName) {
-		addColumn(null, columnName);
-		return this;
-	}
-
-	public SelectFragment addColumns(String[] columnNames) {
-		for (int i=0; i<columnNames.length; i++) addColumn( columnNames[i] );
-		return this;
-	}
-
-	public SelectFragment addColumn(String tableAlias, String columnName) {
-		return addColumn(tableAlias, columnName, columnName);
-	}
-
-	public SelectFragment addColumn(String tableAlias, String columnName, String columnAlias) {
-		columns.add( StringHelper.qualify(tableAlias, columnName) );
-		//columns.add(columnName);
-		//aliases.add(tableAlias);
-		columnAliases.add(columnAlias);
-		return this;
-	}
-
-	public SelectFragment addColumns(String tableAlias, String[] columnNames) {
-		for (int i=0; i<columnNames.length; i++) addColumn( tableAlias, columnNames[i] );
-		return this;
-	}
-
-	public SelectFragment addColumns(String tableAlias, String[] columnNames, String[] columnAliases) {
-		for (int i=0; i<columnNames.length; i++) {
-			if ( columnNames[i]!=null ) addColumn( tableAlias, columnNames[i], columnAliases[i] );
-		}
-		return this;
-	}
-
-	public SelectFragment addFormulas(String tableAlias, String[] formulas, String[] formulaAliases) {
-		for ( int i=0; i<formulas.length; i++ ) {
-			if ( formulas[i]!=null ) addFormula( tableAlias, formulas[i], formulaAliases[i] );
-		}
-		return this;
-	}
-
-	public SelectFragment addFormula(String tableAlias, String formula, String formulaAlias) {
-		columns.add( StringHelper.replace(formula, Template.TEMPLATE, tableAlias) );
-		columnAliases.add(formulaAlias);
-		return this;
-	}
-
-	public String toFragmentString() {
-		StringBuffer buf = new StringBuffer( columns.size() * 10 );
-		Iterator iter = columns.iterator();
-		Iterator columnAliasIter = columnAliases.iterator();
-		//HashMap columnsUnique = new HashMap();
-		HashSet columnsUnique = new HashSet();
-		if (usedAliases!=null) columnsUnique.addAll( Arrays.asList(usedAliases) );
-		while ( iter.hasNext() ) {
-			String column = (String) iter.next();
-			String columnAlias = (String) columnAliasIter.next();
-			//TODO: eventually put this back in, once we think all is fixed
-			//Object otherAlias = columnsUnique.put(qualifiedColumn, columnAlias);
-			/*if ( otherAlias!=null && !columnAlias.equals(otherAlias) ) {
-				throw new AssertionFailure("bug in Hibernate SQL alias generation");
-			}*/
-			if ( columnsUnique.add(columnAlias) ) {
-				buf.append(", ")
-					.append(column)
-					.append(" as ");
-				if (suffix==null) {
-					buf.append(columnAlias);
-				}
-				else {
-					buf.append( new Alias(suffix).toAliasString(columnAlias) );
-				}
-			}
-		}
-		if (extraSelectList!=null) {
-			buf.append(", ")
-				.append(extraSelectList);
-		}
-		return buf.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/SelectFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SelectFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.util.StringHelper;
+
+/**
+ * A fragment of an SQL <tt>SELECT</tt> clause
+ *
+ * @author Gavin King
+ */
+public class SelectFragment {
+	private String suffix;
+	private List columns = new ArrayList();
+	//private List aliases = new ArrayList();
+	private List columnAliases = new ArrayList();
+	private String extraSelectList;
+	private String[] usedAliases;
+	
+	public SelectFragment() {}
+	
+	public SelectFragment setUsedAliases(String[] aliases) {
+		usedAliases = aliases;
+		return this;
+	}
+	
+	public SelectFragment setExtraSelectList(String extraSelectList) {
+		this.extraSelectList = extraSelectList;
+		return this;
+	}
+	
+	public SelectFragment setExtraSelectList(CaseFragment caseFragment, String fragmentAlias) {
+		setExtraSelectList( caseFragment.setReturnColumnName(fragmentAlias, suffix).toFragmentString() );
+		return this;
+	}
+
+	public SelectFragment setSuffix(String suffix) {
+		this.suffix = suffix;
+		return this;
+	}
+
+	public SelectFragment addColumn(String columnName) {
+		addColumn(null, columnName);
+		return this;
+	}
+
+	public SelectFragment addColumns(String[] columnNames) {
+		for (int i=0; i<columnNames.length; i++) addColumn( columnNames[i] );
+		return this;
+	}
+
+	public SelectFragment addColumn(String tableAlias, String columnName) {
+		return addColumn(tableAlias, columnName, columnName);
+	}
+
+	public SelectFragment addColumn(String tableAlias, String columnName, String columnAlias) {
+		columns.add( StringHelper.qualify(tableAlias, columnName) );
+		//columns.add(columnName);
+		//aliases.add(tableAlias);
+		columnAliases.add(columnAlias);
+		return this;
+	}
+
+	public SelectFragment addColumns(String tableAlias, String[] columnNames) {
+		for (int i=0; i<columnNames.length; i++) addColumn( tableAlias, columnNames[i] );
+		return this;
+	}
+
+	public SelectFragment addColumns(String tableAlias, String[] columnNames, String[] columnAliases) {
+		for (int i=0; i<columnNames.length; i++) {
+			if ( columnNames[i]!=null ) addColumn( tableAlias, columnNames[i], columnAliases[i] );
+		}
+		return this;
+	}
+
+	public SelectFragment addFormulas(String tableAlias, String[] formulas, String[] formulaAliases) {
+		for ( int i=0; i<formulas.length; i++ ) {
+			if ( formulas[i]!=null ) addFormula( tableAlias, formulas[i], formulaAliases[i] );
+		}
+		return this;
+	}
+
+	public SelectFragment addFormula(String tableAlias, String formula, String formulaAlias) {
+		columns.add( StringHelper.replace(formula, Template.TEMPLATE, tableAlias) );
+		columnAliases.add(formulaAlias);
+		return this;
+	}
+
+	public String toFragmentString() {
+		StringBuffer buf = new StringBuffer( columns.size() * 10 );
+		Iterator iter = columns.iterator();
+		Iterator columnAliasIter = columnAliases.iterator();
+		//HashMap columnsUnique = new HashMap();
+		HashSet columnsUnique = new HashSet();
+		if (usedAliases!=null) columnsUnique.addAll( Arrays.asList(usedAliases) );
+		while ( iter.hasNext() ) {
+			String column = (String) iter.next();
+			String columnAlias = (String) columnAliasIter.next();
+			//TODO: eventually put this back in, once we think all is fixed
+			//Object otherAlias = columnsUnique.put(qualifiedColumn, columnAlias);
+			/*if ( otherAlias!=null && !columnAlias.equals(otherAlias) ) {
+				throw new AssertionFailure("bug in Hibernate SQL alias generation");
+			}*/
+			if ( columnsUnique.add(columnAlias) ) {
+				buf.append(", ")
+					.append(column)
+					.append(" as ");
+				if (suffix==null) {
+					buf.append(columnAlias);
+				}
+				else {
+					buf.append( new Alias(suffix).toAliasString(columnAlias) );
+				}
+			}
+		}
+		if (extraSelectList!=null) {
+			buf.append(", ")
+				.append(extraSelectList);
+		}
+		return buf.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/SimpleSelect.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,188 +0,0 @@
-//$Id: SimpleSelect.java 7627 2005-07-24 06:53:06Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.LockMode;
-import org.hibernate.dialect.Dialect;
-
-/**
- * An SQL <tt>SELECT</tt> statement with no table joins
- *
- * @author Gavin King
- */
-public class SimpleSelect {
-
-	public SimpleSelect(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	//private static final Alias DEFAULT_ALIAS = new Alias(10, null);
-
-	private String tableName;
-	private String orderBy;
-	private Dialect dialect;
-	private LockMode lockMode = LockMode.READ;
-	private String comment;
-
-	private List columns = new ArrayList();
-	private Map aliases = new HashMap();
-	private List whereTokens = new ArrayList();
-
-	public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			if ( columnNames[i]!=null  ) {
-				addColumn( columnNames[i], columnAliases[i] );
-			}
-		}
-		return this;
-	}
-
-	public SimpleSelect addColumns(String[] columns, String[] aliases, boolean[] ignore) {
-		for ( int i=0; i<ignore.length; i++ ) {
-			if ( !ignore[i] && columns[i]!=null ) {
-				addColumn( columns[i], aliases[i] );
-			}
-		}
-		return this;
-	}
-
-	public SimpleSelect addColumns(String[] columnNames) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			if ( columnNames[i]!=null ) addColumn( columnNames[i] );
-		}
-		return this;
-	}
-	public SimpleSelect addColumn(String columnName) {
-		columns.add(columnName);
-		//aliases.put( columnName, DEFAULT_ALIAS.toAliasString(columnName) );
-		return this;
-	}
-
-	public SimpleSelect addColumn(String columnName, String alias) {
-		columns.add(columnName);
-		aliases.put(columnName, alias);
-		return this;
-	}
-
-	public SimpleSelect setTableName(String tableName) {
-		this.tableName = tableName;
-		return this;
-	}
-
-	public SimpleSelect setLockMode(LockMode lockMode) {
-		this.lockMode = lockMode;
-		return this;
-	}
-
-	public SimpleSelect addWhereToken(String token) {
-		whereTokens.add(token);
-		return this;
-	}
-	
-	private void and() {
-		if ( whereTokens.size()>0 ) {
-			whereTokens.add("and");
-		}
-	}
-
-	public SimpleSelect addCondition(String lhs, String op, String rhs) {
-		and();
-		whereTokens.add( lhs + ' ' + op + ' ' + rhs );
-		return this;
-	}
-
-	public SimpleSelect addCondition(String lhs, String condition) {
-		and();
-		whereTokens.add( lhs + ' ' + condition );
-		return this;
-	}
-
-	public SimpleSelect addCondition(String[] lhs, String op, String[] rhs) {
-		for ( int i=0; i<lhs.length; i++ ) {
-			addCondition( lhs[i], op, rhs[i] );
-		}
-		return this;
-	}
-
-	public SimpleSelect addCondition(String[] lhs, String condition) {
-		for ( int i=0; i<lhs.length; i++ ) {
-			if ( lhs[i]!=null ) addCondition( lhs[i], condition );
-		}
-		return this;
-	}
-
-	public String toStatementString() {
-		StringBuffer buf = new StringBuffer( 
-				columns.size()*10 + 
-				tableName.length() + 
-				whereTokens.size() * 10 + 
-				10 
-			);
-		
-		if ( comment!=null ) {
-			buf.append("/* ").append(comment).append(" */ ");
-		}
-		
-		buf.append("select ");
-		Set uniqueColumns = new HashSet();
-		Iterator iter = columns.iterator();
-		boolean appendComma = false;
-		while ( iter.hasNext() ) {
-			String col = (String) iter.next();
-			String alias = (String) aliases.get(col);
-			if ( uniqueColumns.add(alias==null ? col : alias) ) {
-				if (appendComma) buf.append(", ");
-				buf.append(col);
-				if ( alias!=null && !alias.equals(col) ) {
-					buf.append(" as ")
-						.append(alias);
-				}
-				appendComma = true;
-			}
-		}
-		
-		buf.append(" from ")
-			.append( dialect.appendLockHint(lockMode, tableName) );
-		
-		if ( whereTokens.size() > 0 ) {
-			buf.append(" where ")
-				.append( toWhereClause() );
-		}
-		
-		if (orderBy!=null) buf.append(orderBy);
-		
-		if (lockMode!=null) {
-			buf.append( dialect.getForUpdateString(lockMode) );
-		}
-
-		return dialect.transformSelectString( buf.toString() );
-	}
-
-	public String toWhereClause() {
-		StringBuffer buf = new StringBuffer( whereTokens.size() * 5 );
-		Iterator iter = whereTokens.iterator();
-		while ( iter.hasNext() ) {
-			buf.append( iter.next() );
-			if ( iter.hasNext() ) buf.append(' ');
-		}
-		return buf.toString();
-	}
-
-	public SimpleSelect setOrderBy(String orderBy) {
-		this.orderBy = orderBy;
-		return this;
-	}
-
-	public SimpleSelect setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/SimpleSelect.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/SimpleSelect.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,211 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.LockMode;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * An SQL <tt>SELECT</tt> statement with no table joins
+ *
+ * @author Gavin King
+ */
+public class SimpleSelect {
+
+	public SimpleSelect(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	//private static final Alias DEFAULT_ALIAS = new Alias(10, null);
+
+	private String tableName;
+	private String orderBy;
+	private Dialect dialect;
+	private LockMode lockMode = LockMode.READ;
+	private String comment;
+
+	private List columns = new ArrayList();
+	private Map aliases = new HashMap();
+	private List whereTokens = new ArrayList();
+
+	public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			if ( columnNames[i]!=null  ) {
+				addColumn( columnNames[i], columnAliases[i] );
+			}
+		}
+		return this;
+	}
+
+	public SimpleSelect addColumns(String[] columns, String[] aliases, boolean[] ignore) {
+		for ( int i=0; i<ignore.length; i++ ) {
+			if ( !ignore[i] && columns[i]!=null ) {
+				addColumn( columns[i], aliases[i] );
+			}
+		}
+		return this;
+	}
+
+	public SimpleSelect addColumns(String[] columnNames) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			if ( columnNames[i]!=null ) addColumn( columnNames[i] );
+		}
+		return this;
+	}
+	public SimpleSelect addColumn(String columnName) {
+		columns.add(columnName);
+		//aliases.put( columnName, DEFAULT_ALIAS.toAliasString(columnName) );
+		return this;
+	}
+
+	public SimpleSelect addColumn(String columnName, String alias) {
+		columns.add(columnName);
+		aliases.put(columnName, alias);
+		return this;
+	}
+
+	public SimpleSelect setTableName(String tableName) {
+		this.tableName = tableName;
+		return this;
+	}
+
+	public SimpleSelect setLockMode(LockMode lockMode) {
+		this.lockMode = lockMode;
+		return this;
+	}
+
+	public SimpleSelect addWhereToken(String token) {
+		whereTokens.add(token);
+		return this;
+	}
+	
+	private void and() {
+		if ( whereTokens.size()>0 ) {
+			whereTokens.add("and");
+		}
+	}
+
+	public SimpleSelect addCondition(String lhs, String op, String rhs) {
+		and();
+		whereTokens.add( lhs + ' ' + op + ' ' + rhs );
+		return this;
+	}
+
+	public SimpleSelect addCondition(String lhs, String condition) {
+		and();
+		whereTokens.add( lhs + ' ' + condition );
+		return this;
+	}
+
+	public SimpleSelect addCondition(String[] lhs, String op, String[] rhs) {
+		for ( int i=0; i<lhs.length; i++ ) {
+			addCondition( lhs[i], op, rhs[i] );
+		}
+		return this;
+	}
+
+	public SimpleSelect addCondition(String[] lhs, String condition) {
+		for ( int i=0; i<lhs.length; i++ ) {
+			if ( lhs[i]!=null ) addCondition( lhs[i], condition );
+		}
+		return this;
+	}
+
+	public String toStatementString() {
+		StringBuffer buf = new StringBuffer( 
+				columns.size()*10 + 
+				tableName.length() + 
+				whereTokens.size() * 10 + 
+				10 
+			);
+		
+		if ( comment!=null ) {
+			buf.append("/* ").append(comment).append(" */ ");
+		}
+		
+		buf.append("select ");
+		Set uniqueColumns = new HashSet();
+		Iterator iter = columns.iterator();
+		boolean appendComma = false;
+		while ( iter.hasNext() ) {
+			String col = (String) iter.next();
+			String alias = (String) aliases.get(col);
+			if ( uniqueColumns.add(alias==null ? col : alias) ) {
+				if (appendComma) buf.append(", ");
+				buf.append(col);
+				if ( alias!=null && !alias.equals(col) ) {
+					buf.append(" as ")
+						.append(alias);
+				}
+				appendComma = true;
+			}
+		}
+		
+		buf.append(" from ")
+			.append( dialect.appendLockHint(lockMode, tableName) );
+		
+		if ( whereTokens.size() > 0 ) {
+			buf.append(" where ")
+				.append( toWhereClause() );
+		}
+		
+		if (orderBy!=null) buf.append(orderBy);
+		
+		if (lockMode!=null) {
+			buf.append( dialect.getForUpdateString(lockMode) );
+		}
+
+		return dialect.transformSelectString( buf.toString() );
+	}
+
+	public String toWhereClause() {
+		StringBuffer buf = new StringBuffer( whereTokens.size() * 5 );
+		Iterator iter = whereTokens.iterator();
+		while ( iter.hasNext() ) {
+			buf.append( iter.next() );
+			if ( iter.hasNext() ) buf.append(' ');
+		}
+		return buf.toString();
+	}
+
+	public SimpleSelect setOrderBy(String orderBy) {
+		this.orderBy = orderBy;
+		return this;
+	}
+
+	public SimpleSelect setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,98 +0,0 @@
-//$Id: Sybase11JoinFragment.java 4886 2004-12-05 15:04:21Z pgmjsd $
-package org.hibernate.sql;
-
-
-/**
- * An old Sybase-style join (before Sybase supported the ANSI style "inner join" etc syntax)
- * This is needed for Sybase 11.9.2 and earlier, using the HQL 2.* syntax with Collections.
- *
- * @author Colm O' Flaherty
- */
-public class Sybase11JoinFragment extends JoinFragment {
-
-	private StringBuffer afterFrom = new StringBuffer();
-	private StringBuffer afterWhere = new StringBuffer();
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
-
-		addCrossJoin(tableName, alias);
-
-		for ( int j=0; j<fkColumns.length; j++) {
-			//full joins are not supported.. yet!
-			if (joinType==JoinFragment.FULL_JOIN ) throw new UnsupportedOperationException();
-
-			afterWhere.append(" and ")
-				.append( fkColumns[j] )
-				.append( " " );
-
-			if (joinType==LEFT_OUTER_JOIN ) afterWhere.append("*");
-			afterWhere.append('=');
-			if (joinType==RIGHT_OUTER_JOIN ) afterWhere.append("*");
-
-			afterWhere.append (" ")
-				.append(alias)
-				.append('.')
-				.append( pkColumns[j] );
-		}
-
-	}
-
-	public String toFromFragmentString() {
-		return afterFrom.toString();
-	}
-
-	public String toWhereFragmentString() {
-		return afterWhere.toString();
-	}
-
-	public void addJoins(String fromFragment, String whereFragment) {
-		afterFrom.append(fromFragment);
-		afterWhere.append(whereFragment);
-	}
-
-	public JoinFragment copy() {
-		Sybase11JoinFragment copy = new Sybase11JoinFragment();
-		copy.afterFrom = new StringBuffer( afterFrom.toString() );
-		copy.afterWhere = new StringBuffer( afterWhere.toString() );
-		return copy;
-	}
-
-	public void addCondition(String alias, String[] columns, String condition) {
-		for ( int i=0; i<columns.length; i++ ) {
-			afterWhere.append(" and ")
-				.append(alias)
-				.append('.')
-				.append( columns[i] )
-				.append(condition);
-		}
-	}
-
-	public void addCrossJoin(String tableName, String alias) {
-		afterFrom.append(", ")
-			.append(tableName)
-			.append(' ')
-			.append(alias);
-	}
-
-	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
-		throw new UnsupportedOperationException();
-
-	}
-
-	public boolean addCondition(String condition) {
-		return addCondition(afterWhere, condition);
-	}
-
-
-	public void addFromFragmentString(String fromFragmentString) {
-		afterFrom.append(fromFragmentString);
-	}
-
-
-	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
-		addJoin(tableName, alias, fkColumns, pkColumns, joinType);
-		addCondition(on);
-	}
-}
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Sybase11JoinFragment.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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;
+
+
+/**
+ * An old Sybase-style join (before Sybase supported the ANSI style "inner join" etc syntax)
+ * This is needed for Sybase 11.9.2 and earlier, using the HQL 2.* syntax with Collections.
+ *
+ * @author Colm O' Flaherty
+ */
+public class Sybase11JoinFragment extends JoinFragment {
+
+	private StringBuffer afterFrom = new StringBuffer();
+	private StringBuffer afterWhere = new StringBuffer();
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType) {
+
+		addCrossJoin(tableName, alias);
+
+		for ( int j=0; j<fkColumns.length; j++) {
+			//full joins are not supported.. yet!
+			if (joinType==JoinFragment.FULL_JOIN ) throw new UnsupportedOperationException();
+
+			afterWhere.append(" and ")
+				.append( fkColumns[j] )
+				.append( " " );
+
+			if (joinType==LEFT_OUTER_JOIN ) afterWhere.append("*");
+			afterWhere.append('=');
+			if (joinType==RIGHT_OUTER_JOIN ) afterWhere.append("*");
+
+			afterWhere.append (" ")
+				.append(alias)
+				.append('.')
+				.append( pkColumns[j] );
+		}
+
+	}
+
+	public String toFromFragmentString() {
+		return afterFrom.toString();
+	}
+
+	public String toWhereFragmentString() {
+		return afterWhere.toString();
+	}
+
+	public void addJoins(String fromFragment, String whereFragment) {
+		afterFrom.append(fromFragment);
+		afterWhere.append(whereFragment);
+	}
+
+	public JoinFragment copy() {
+		Sybase11JoinFragment copy = new Sybase11JoinFragment();
+		copy.afterFrom = new StringBuffer( afterFrom.toString() );
+		copy.afterWhere = new StringBuffer( afterWhere.toString() );
+		return copy;
+	}
+
+	public void addCondition(String alias, String[] columns, String condition) {
+		for ( int i=0; i<columns.length; i++ ) {
+			afterWhere.append(" and ")
+				.append(alias)
+				.append('.')
+				.append( columns[i] )
+				.append(condition);
+		}
+	}
+
+	public void addCrossJoin(String tableName, String alias) {
+		afterFrom.append(", ")
+			.append(tableName)
+			.append(' ')
+			.append(alias);
+	}
+
+	public void addCondition(String alias, String[] fkColumns, String[] pkColumns) {
+		throw new UnsupportedOperationException();
+
+	}
+
+	public boolean addCondition(String condition) {
+		return addCondition(afterWhere, condition);
+	}
+
+
+	public void addFromFragmentString(String fromFragmentString) {
+		afterFrom.append(fromFragmentString);
+	}
+
+
+	public void addJoin(String tableName, String alias, String[] fkColumns, String[] pkColumns, int joinType, String on) {
+		addJoin(tableName, alias, fkColumns, pkColumns, joinType);
+		addCondition(on);
+	}
+}
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Template.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,320 +0,0 @@
-//$Id: Template.java 9922 2006-05-10 16:58:09Z steve.ebersole at jboss.com $
-package org.hibernate.sql;
-
-import java.util.HashSet;
-import java.util.StringTokenizer;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-import org.hibernate.util.StringHelper;
-
-/**
- * Parses SQL fragments specified in mapping documents
- *
- * @author Gavin King
- */
-public final class Template {
-
-	private static final java.util.Set KEYWORDS = new HashSet();
-	private static final java.util.Set BEFORE_TABLE_KEYWORDS = new HashSet();
-	private static final java.util.Set FUNCTION_KEYWORDS = new HashSet();
-	static {
-		KEYWORDS.add("and");
-		KEYWORDS.add("or");
-		KEYWORDS.add("not");
-		KEYWORDS.add("like");
-		KEYWORDS.add("is");
-		KEYWORDS.add("in");
-		KEYWORDS.add("between");
-		KEYWORDS.add("null");
-		KEYWORDS.add("select");
-		KEYWORDS.add("distinct");
-		KEYWORDS.add("from");
-		KEYWORDS.add("join");
-		KEYWORDS.add("inner");
-		KEYWORDS.add("outer");
-		KEYWORDS.add("left");
-		KEYWORDS.add("right");
-		KEYWORDS.add("on");
-		KEYWORDS.add("where");
-		KEYWORDS.add("having");
-		KEYWORDS.add("group");
-		KEYWORDS.add("order");
-		KEYWORDS.add("by");
-		KEYWORDS.add("desc");
-		KEYWORDS.add("asc");
-		KEYWORDS.add("limit");
-		KEYWORDS.add("any");
-		KEYWORDS.add("some");
-		KEYWORDS.add("exists");
-		KEYWORDS.add("all");
-		KEYWORDS.add("union");
-		KEYWORDS.add("minus");
-
-		BEFORE_TABLE_KEYWORDS.add("from");
-		BEFORE_TABLE_KEYWORDS.add("join");
-		
-		FUNCTION_KEYWORDS.add("as");
-		FUNCTION_KEYWORDS.add("leading");
-		FUNCTION_KEYWORDS.add("trailing");
-		FUNCTION_KEYWORDS.add("from");
-		FUNCTION_KEYWORDS.add("case");
-		FUNCTION_KEYWORDS.add("when");
-		FUNCTION_KEYWORDS.add("then");
-		FUNCTION_KEYWORDS.add("else");
-		FUNCTION_KEYWORDS.add("end");
-	}
-
-	public static final String TEMPLATE = "$PlaceHolder$";
-
-	private Template() {}
-
-	public static String renderWhereStringTemplate(String sqlWhereString, Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, functionRegistry);
-	}
-
-	/**
-	 * Same functionality as {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)},
-	 * except that a SQLFunctionRegistry is not provided (i.e., only the dialect-defined functions are
-	 * considered).  This is only intended for use by the annotations project until the
-	 * many-to-many/map-key-from-target-table feature is pulled into core.
-	 *
-	 * @deprecated Only intended for annotations usage; use {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)} instead
-	 */
-	public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect) {
-		return renderWhereStringTemplate( sqlWhereString, placeholder, dialect, new SQLFunctionRegistry( dialect, java.util.Collections.EMPTY_MAP ) );
-	}
-
-	/**
-	 * Takes the where condition provided in the mapping attribute and interpolates the alias. 
-	 * Handles subselects, quoted identifiers, quoted strings, expressions, SQL functions, 
-	 * named parameters.
-	 *
-	 * @param sqlWhereString The string into which to interpolate the placeholder value
-	 * @param placeholder The value to be interpolated into the the sqlWhereString
-	 * @param dialect The dialect to apply
-	 * @param functionRegistry The registry of all sql functions
-	 * @return The rendered sql fragment
-	 */
-	public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SQLFunctionRegistry functionRegistry ) {
-		//TODO: make this a bit nicer
-		String symbols = new StringBuffer()
-			.append("=><!+-*/()',|&`")
-			.append(StringHelper.WHITESPACE)
-			.append( dialect.openQuote() )
-			.append( dialect.closeQuote() )
-			.toString();
-		StringTokenizer tokens = new StringTokenizer(sqlWhereString, symbols, true);
-		
-		StringBuffer result = new StringBuffer();
-		boolean quoted = false;
-		boolean quotedIdentifier = false;
-		boolean beforeTable = false;
-		boolean inFromClause = false;
-		boolean afterFromTable = false;
-		
-		boolean hasMore = tokens.hasMoreTokens();
-		String nextToken = hasMore ? tokens.nextToken() : null;
-		while (hasMore) {
-			String token = nextToken;
-			String lcToken = token.toLowerCase();
-			hasMore = tokens.hasMoreTokens();
-			nextToken = hasMore ? tokens.nextToken() : null;
-			
-			boolean isQuoteCharacter = false;
-			
-			if ( !quotedIdentifier && "'".equals(token) ) {
-				quoted = !quoted;
-				isQuoteCharacter = true;
-			}
-			
-			if ( !quoted ) {
-				
-				boolean isOpenQuote;
-				if ( "`".equals(token) ) {
-					isOpenQuote = !quotedIdentifier;
-					token = lcToken = isOpenQuote ? 
-						new Character( dialect.openQuote() ).toString() :
-						new Character( dialect.closeQuote() ).toString();
-					quotedIdentifier = isOpenQuote;	
-					isQuoteCharacter = true;
-				}
-				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
-					isOpenQuote = true;
-					quotedIdentifier = true;	
-					isQuoteCharacter = true;
-				}
-				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
-					quotedIdentifier = false;
-					isQuoteCharacter = true;
-					isOpenQuote = false;
-				}
-				else {
-					isOpenQuote = false;
-				}
-				
-				if (isOpenQuote) {
-					result.append(placeholder).append('.');
-				}
-				
-			}
-	
-			boolean quotedOrWhitespace = quoted || 
-				quotedIdentifier || 
-				isQuoteCharacter || 
-				Character.isWhitespace( token.charAt(0) );
-			
-			if (quotedOrWhitespace) {
-				result.append(token);
-			}
-			else if (beforeTable) {
-				result.append(token);
-				beforeTable = false;
-				afterFromTable = true;
-			}
-			else if (afterFromTable) {
-				if ( !"as".equals(lcToken) ) afterFromTable = false;
-				result.append(token);
-			}
-			else if ( isNamedParameter(token) ) {
-				result.append(token);
-			}
-			else if (
-				isIdentifier(token, dialect) &&
-				!isFunctionOrKeyword(lcToken, nextToken, dialect , functionRegistry)
-			) {
-				result.append(placeholder)
-					.append('.')
-					.append( dialect.quote(token) );
-			}
-			else {
-				if ( BEFORE_TABLE_KEYWORDS.contains(lcToken) ) {
-					beforeTable = true;
-					inFromClause = true;
-				}
-				else if ( inFromClause && ",".equals(lcToken) ) {
-					beforeTable = true;
-				}
-				result.append(token);
-			}
-			
-			if ( //Yuck:
-					inFromClause && 
-					KEYWORDS.contains(lcToken) && //"as" is not in KEYWORDS
-					!BEFORE_TABLE_KEYWORDS.contains(lcToken)
-			) { 
-				inFromClause = false;
-			}
-
-		}
-		return result.toString();
-	}
-
-	/**
-	 * Takes order by clause provided in the mapping attribute and interpolates the alias.
-	 * Handles asc, desc, SQL functions, quoted identifiers.
-	 */
-	public static String renderOrderByStringTemplate(String sqlOrderByString, Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		//TODO: make this a bit nicer
-		String symbols = new StringBuffer()
-			.append("=><!+-*/()',|&`")
-			.append(StringHelper.WHITESPACE)
-			.append( dialect.openQuote() )
-			.append( dialect.closeQuote() )
-			.toString();
-		StringTokenizer tokens = new StringTokenizer(sqlOrderByString, symbols, true);
-		
-		StringBuffer result = new StringBuffer();
-		boolean quoted = false;
-		boolean quotedIdentifier = false;
-		
-		boolean hasMore = tokens.hasMoreTokens();
-		String nextToken = hasMore ? tokens.nextToken() : null;
-		while (hasMore) {
-			String token = nextToken;
-			String lcToken = token.toLowerCase();
-			hasMore = tokens.hasMoreTokens();
-			nextToken = hasMore ? tokens.nextToken() : null;
-			
-			boolean isQuoteCharacter = false;
-			
-			if ( !quotedIdentifier && "'".equals(token) ) {
-				quoted = !quoted;
-				isQuoteCharacter = true;
-			}
-			
-			if ( !quoted ) {
-				
-				boolean isOpenQuote;
-				if ( "`".equals(token) ) {
-					isOpenQuote = !quotedIdentifier;
-					token = lcToken = isOpenQuote ? 
-						new Character( dialect.openQuote() ).toString() :
-						new Character( dialect.closeQuote() ).toString();
-					quotedIdentifier = isOpenQuote;	
-					isQuoteCharacter = true;
-				}
-				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
-					isOpenQuote = true;
-					quotedIdentifier = true;	
-					isQuoteCharacter = true;
-				}
-				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
-					quotedIdentifier = false;
-					isQuoteCharacter = true;
-					isOpenQuote = false;
-				}
-				else {
-					isOpenQuote = false;
-				}
-				
-				if (isOpenQuote) {
-					result.append(TEMPLATE).append('.');
-				}
-				
-			}
-	
-			boolean quotedOrWhitespace = quoted || 
-				quotedIdentifier || 
-				isQuoteCharacter || 
-				Character.isWhitespace( token.charAt(0) );
-			
-			if (quotedOrWhitespace) {
-				result.append(token);
-			}
-			else if (
-				isIdentifier(token, dialect) &&
-				!isFunctionOrKeyword(lcToken, nextToken, dialect, functionRegistry)
-			) {
-				result.append(TEMPLATE)
-					.append('.')
-					.append( dialect.quote(token) );
-			}
-			else {
-				result.append(token);
-			}
-		}
-		return result.toString();
-	}
-	
-	private static boolean isNamedParameter(String token) {
-		return token.startsWith(":");
-	}
-
-	private static boolean isFunctionOrKeyword(String lcToken, String nextToken, Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		return "(".equals(nextToken) ||
-			KEYWORDS.contains(lcToken) ||
-			functionRegistry.hasFunction(lcToken) ||
-			dialect.getKeywords().contains(lcToken) ||
-			FUNCTION_KEYWORDS.contains(lcToken);
-	}
-
-	private static boolean isIdentifier(String token, Dialect dialect) {
-		return token.charAt(0)=='`' || ( //allow any identifier quoted with backtick
-			Character.isLetter( token.charAt(0) ) && //only recognizes identifiers beginning with a letter
-			token.indexOf('.') < 0
-		);
-	}
-
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Template.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Template.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,343 @@
+/*
+ * 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;
+
+import java.util.HashSet;
+import java.util.StringTokenizer;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Parses SQL fragments specified in mapping documents
+ *
+ * @author Gavin King
+ */
+public final class Template {
+
+	private static final java.util.Set KEYWORDS = new HashSet();
+	private static final java.util.Set BEFORE_TABLE_KEYWORDS = new HashSet();
+	private static final java.util.Set FUNCTION_KEYWORDS = new HashSet();
+	static {
+		KEYWORDS.add("and");
+		KEYWORDS.add("or");
+		KEYWORDS.add("not");
+		KEYWORDS.add("like");
+		KEYWORDS.add("is");
+		KEYWORDS.add("in");
+		KEYWORDS.add("between");
+		KEYWORDS.add("null");
+		KEYWORDS.add("select");
+		KEYWORDS.add("distinct");
+		KEYWORDS.add("from");
+		KEYWORDS.add("join");
+		KEYWORDS.add("inner");
+		KEYWORDS.add("outer");
+		KEYWORDS.add("left");
+		KEYWORDS.add("right");
+		KEYWORDS.add("on");
+		KEYWORDS.add("where");
+		KEYWORDS.add("having");
+		KEYWORDS.add("group");
+		KEYWORDS.add("order");
+		KEYWORDS.add("by");
+		KEYWORDS.add("desc");
+		KEYWORDS.add("asc");
+		KEYWORDS.add("limit");
+		KEYWORDS.add("any");
+		KEYWORDS.add("some");
+		KEYWORDS.add("exists");
+		KEYWORDS.add("all");
+		KEYWORDS.add("union");
+		KEYWORDS.add("minus");
+
+		BEFORE_TABLE_KEYWORDS.add("from");
+		BEFORE_TABLE_KEYWORDS.add("join");
+		
+		FUNCTION_KEYWORDS.add("as");
+		FUNCTION_KEYWORDS.add("leading");
+		FUNCTION_KEYWORDS.add("trailing");
+		FUNCTION_KEYWORDS.add("from");
+		FUNCTION_KEYWORDS.add("case");
+		FUNCTION_KEYWORDS.add("when");
+		FUNCTION_KEYWORDS.add("then");
+		FUNCTION_KEYWORDS.add("else");
+		FUNCTION_KEYWORDS.add("end");
+	}
+
+	public static final String TEMPLATE = "$PlaceHolder$";
+
+	private Template() {}
+
+	public static String renderWhereStringTemplate(String sqlWhereString, Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		return renderWhereStringTemplate(sqlWhereString, TEMPLATE, dialect, functionRegistry);
+	}
+
+	/**
+	 * Same functionality as {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)},
+	 * except that a SQLFunctionRegistry is not provided (i.e., only the dialect-defined functions are
+	 * considered).  This is only intended for use by the annotations project until the
+	 * many-to-many/map-key-from-target-table feature is pulled into core.
+	 *
+	 * @deprecated Only intended for annotations usage; use {@link #renderWhereStringTemplate(String, String, Dialect, SQLFunctionRegistry)} instead
+	 */
+	public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect) {
+		return renderWhereStringTemplate( sqlWhereString, placeholder, dialect, new SQLFunctionRegistry( dialect, java.util.Collections.EMPTY_MAP ) );
+	}
+
+	/**
+	 * Takes the where condition provided in the mapping attribute and interpolates the alias. 
+	 * Handles subselects, quoted identifiers, quoted strings, expressions, SQL functions, 
+	 * named parameters.
+	 *
+	 * @param sqlWhereString The string into which to interpolate the placeholder value
+	 * @param placeholder The value to be interpolated into the the sqlWhereString
+	 * @param dialect The dialect to apply
+	 * @param functionRegistry The registry of all sql functions
+	 * @return The rendered sql fragment
+	 */
+	public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SQLFunctionRegistry functionRegistry ) {
+		//TODO: make this a bit nicer
+		String symbols = new StringBuffer()
+			.append("=><!+-*/()',|&`")
+			.append(StringHelper.WHITESPACE)
+			.append( dialect.openQuote() )
+			.append( dialect.closeQuote() )
+			.toString();
+		StringTokenizer tokens = new StringTokenizer(sqlWhereString, symbols, true);
+		
+		StringBuffer result = new StringBuffer();
+		boolean quoted = false;
+		boolean quotedIdentifier = false;
+		boolean beforeTable = false;
+		boolean inFromClause = false;
+		boolean afterFromTable = false;
+		
+		boolean hasMore = tokens.hasMoreTokens();
+		String nextToken = hasMore ? tokens.nextToken() : null;
+		while (hasMore) {
+			String token = nextToken;
+			String lcToken = token.toLowerCase();
+			hasMore = tokens.hasMoreTokens();
+			nextToken = hasMore ? tokens.nextToken() : null;
+			
+			boolean isQuoteCharacter = false;
+			
+			if ( !quotedIdentifier && "'".equals(token) ) {
+				quoted = !quoted;
+				isQuoteCharacter = true;
+			}
+			
+			if ( !quoted ) {
+				
+				boolean isOpenQuote;
+				if ( "`".equals(token) ) {
+					isOpenQuote = !quotedIdentifier;
+					token = lcToken = isOpenQuote ? 
+						new Character( dialect.openQuote() ).toString() :
+						new Character( dialect.closeQuote() ).toString();
+					quotedIdentifier = isOpenQuote;	
+					isQuoteCharacter = true;
+				}
+				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
+					isOpenQuote = true;
+					quotedIdentifier = true;	
+					isQuoteCharacter = true;
+				}
+				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
+					quotedIdentifier = false;
+					isQuoteCharacter = true;
+					isOpenQuote = false;
+				}
+				else {
+					isOpenQuote = false;
+				}
+				
+				if (isOpenQuote) {
+					result.append(placeholder).append('.');
+				}
+				
+			}
+	
+			boolean quotedOrWhitespace = quoted || 
+				quotedIdentifier || 
+				isQuoteCharacter || 
+				Character.isWhitespace( token.charAt(0) );
+			
+			if (quotedOrWhitespace) {
+				result.append(token);
+			}
+			else if (beforeTable) {
+				result.append(token);
+				beforeTable = false;
+				afterFromTable = true;
+			}
+			else if (afterFromTable) {
+				if ( !"as".equals(lcToken) ) afterFromTable = false;
+				result.append(token);
+			}
+			else if ( isNamedParameter(token) ) {
+				result.append(token);
+			}
+			else if (
+				isIdentifier(token, dialect) &&
+				!isFunctionOrKeyword(lcToken, nextToken, dialect , functionRegistry)
+			) {
+				result.append(placeholder)
+					.append('.')
+					.append( dialect.quote(token) );
+			}
+			else {
+				if ( BEFORE_TABLE_KEYWORDS.contains(lcToken) ) {
+					beforeTable = true;
+					inFromClause = true;
+				}
+				else if ( inFromClause && ",".equals(lcToken) ) {
+					beforeTable = true;
+				}
+				result.append(token);
+			}
+			
+			if ( //Yuck:
+					inFromClause && 
+					KEYWORDS.contains(lcToken) && //"as" is not in KEYWORDS
+					!BEFORE_TABLE_KEYWORDS.contains(lcToken)
+			) { 
+				inFromClause = false;
+			}
+
+		}
+		return result.toString();
+	}
+
+	/**
+	 * Takes order by clause provided in the mapping attribute and interpolates the alias.
+	 * Handles asc, desc, SQL functions, quoted identifiers.
+	 */
+	public static String renderOrderByStringTemplate(String sqlOrderByString, Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		//TODO: make this a bit nicer
+		String symbols = new StringBuffer()
+			.append("=><!+-*/()',|&`")
+			.append(StringHelper.WHITESPACE)
+			.append( dialect.openQuote() )
+			.append( dialect.closeQuote() )
+			.toString();
+		StringTokenizer tokens = new StringTokenizer(sqlOrderByString, symbols, true);
+		
+		StringBuffer result = new StringBuffer();
+		boolean quoted = false;
+		boolean quotedIdentifier = false;
+		
+		boolean hasMore = tokens.hasMoreTokens();
+		String nextToken = hasMore ? tokens.nextToken() : null;
+		while (hasMore) {
+			String token = nextToken;
+			String lcToken = token.toLowerCase();
+			hasMore = tokens.hasMoreTokens();
+			nextToken = hasMore ? tokens.nextToken() : null;
+			
+			boolean isQuoteCharacter = false;
+			
+			if ( !quotedIdentifier && "'".equals(token) ) {
+				quoted = !quoted;
+				isQuoteCharacter = true;
+			}
+			
+			if ( !quoted ) {
+				
+				boolean isOpenQuote;
+				if ( "`".equals(token) ) {
+					isOpenQuote = !quotedIdentifier;
+					token = lcToken = isOpenQuote ? 
+						new Character( dialect.openQuote() ).toString() :
+						new Character( dialect.closeQuote() ).toString();
+					quotedIdentifier = isOpenQuote;	
+					isQuoteCharacter = true;
+				}
+				else if ( !quotedIdentifier && ( dialect.openQuote()==token.charAt(0) ) ) {
+					isOpenQuote = true;
+					quotedIdentifier = true;	
+					isQuoteCharacter = true;
+				}
+				else if ( quotedIdentifier && ( dialect.closeQuote()==token.charAt(0) ) ) {
+					quotedIdentifier = false;
+					isQuoteCharacter = true;
+					isOpenQuote = false;
+				}
+				else {
+					isOpenQuote = false;
+				}
+				
+				if (isOpenQuote) {
+					result.append(TEMPLATE).append('.');
+				}
+				
+			}
+	
+			boolean quotedOrWhitespace = quoted || 
+				quotedIdentifier || 
+				isQuoteCharacter || 
+				Character.isWhitespace( token.charAt(0) );
+			
+			if (quotedOrWhitespace) {
+				result.append(token);
+			}
+			else if (
+				isIdentifier(token, dialect) &&
+				!isFunctionOrKeyword(lcToken, nextToken, dialect, functionRegistry)
+			) {
+				result.append(TEMPLATE)
+					.append('.')
+					.append( dialect.quote(token) );
+			}
+			else {
+				result.append(token);
+			}
+		}
+		return result.toString();
+	}
+	
+	private static boolean isNamedParameter(String token) {
+		return token.startsWith(":");
+	}
+
+	private static boolean isFunctionOrKeyword(String lcToken, String nextToken, Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		return "(".equals(nextToken) ||
+			KEYWORDS.contains(lcToken) ||
+			functionRegistry.hasFunction(lcToken) ||
+			dialect.getKeywords().contains(lcToken) ||
+			FUNCTION_KEYWORDS.contains(lcToken);
+	}
+
+	private static boolean isIdentifier(String token, Dialect dialect) {
+		return token.charAt(0)=='`' || ( //allow any identifier quoted with backtick
+			Character.isLetter( token.charAt(0) ) && //only recognizes identifiers beginning with a letter
+			token.indexOf('.') < 0
+		);
+	}
+
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/Update.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,188 +0,0 @@
-//$Id: Update.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.sql;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.LinkedHashMap;
-
-import org.hibernate.dialect.Dialect;
-import org.hibernate.type.LiteralType;
-import org.hibernate.util.StringHelper;
-
-/**
- * An SQL <tt>UPDATE</tt> statement
- *
- * @author Gavin King
- */
-public class Update {
-
-	private String tableName;
-	private String[] primaryKeyColumnNames;
-	private String versionColumnName;
-	private String where;
-	private String assignments;
-	private String comment;
-
-	private Map columns = new LinkedHashMap();
-	private Map whereColumns = new LinkedHashMap();
-	
-	private Dialect dialect;
-	
-	public Update(Dialect dialect) {
-		this.dialect = dialect;
-	}
-
-	public String getTableName() {
-		return tableName;
-	}
-
-	public Update appendAssignmentFragment(String fragment) {
-		if ( assignments == null ) {
-			assignments = fragment;
-		}
-		else {
-			assignments += ", " + fragment;
-		}
-		return this;
-	}
-
-	public Update setTableName(String tableName) {
-		this.tableName = tableName;
-		return this;
-	}
-
-	public Update setPrimaryKeyColumnNames(String[] primaryKeyColumnNames) {
-		this.primaryKeyColumnNames = primaryKeyColumnNames;
-		return this;
-	}
-
-	public Update setVersionColumnName(String versionColumnName) {
-		this.versionColumnName = versionColumnName;
-		return this;
-	}
-
-
-	public Update setComment(String comment) {
-		this.comment = comment;
-		return this;
-	}
-
-	public Update addColumns(String[] columnNames) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			addColumn( columnNames[i] );
-		}
-		return this;
-	}
-
-	public Update addColumns(String[] columnNames, boolean[] updateable) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			if ( updateable[i] ) addColumn( columnNames[i] );
-		}
-		return this;
-	}
-
-	public Update addColumns(String[] columnNames, String value) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			addColumn( columnNames[i], value );
-		}
-		return this;
-	}
-
-	public Update addColumn(String columnName) {
-		return addColumn(columnName, "?");
-	}
-
-	public Update addColumn(String columnName, String value) {
-		columns.put(columnName, value);
-		return this;
-	}
-
-	public Update addColumn(String columnName, Object value, LiteralType type) throws Exception {
-		return addColumn( columnName, type.objectToSQLString(value, dialect) );
-	}
-
-	public Update addWhereColumns(String[] columnNames) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			addWhereColumn( columnNames[i] );
-		}
-		return this;
-	}
-
-	public Update addWhereColumns(String[] columnNames, String value) {
-		for ( int i=0; i<columnNames.length; i++ ) {
-			addWhereColumn( columnNames[i], value );
-		}
-		return this;
-	}
-
-	public Update addWhereColumn(String columnName) {
-		return addWhereColumn(columnName, "=?");
-	}
-
-	public Update addWhereColumn(String columnName, String value) {
-		whereColumns.put(columnName, value);
-		return this;
-	}
-
-	public Update setWhere(String where) {
-		this.where=where;
-		return this;
-	}
-
-	public String toStatementString() {
-		StringBuffer buf = new StringBuffer( (columns.size() * 15) + tableName.length() + 10 );
-		if ( comment!=null ) {
-			buf.append( "/* " ).append( comment ).append( " */ " );
-		}
-		buf.append( "update " ).append( tableName ).append( " set " );
-		boolean assignmentsAppended = false;
-		Iterator iter = columns.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry e = (Map.Entry) iter.next();
-			buf.append( e.getKey() ).append( '=' ).append( e.getValue() );
-			if ( iter.hasNext() ) {
-				buf.append( ", " );
-			}
-			assignmentsAppended = true;
-		}
-		if ( assignments != null ) {
-			if ( assignmentsAppended ) {
-				buf.append( ", " );
-			}
-			buf.append( assignments );
-		}
-
-		boolean conditionsAppended = false;
-		if ( primaryKeyColumnNames != null || where != null || !whereColumns.isEmpty() || versionColumnName != null ) {
-			buf.append( " where " );
-		}
-		if ( primaryKeyColumnNames != null ) {
-			buf.append( StringHelper.join( "=? and ", primaryKeyColumnNames ) ).append( "=?" );
-			conditionsAppended = true;
-		}
-		if ( where != null ) {
-			if ( conditionsAppended ) {
-				buf.append( " and " );
-			}
-			buf.append( where );
-			conditionsAppended = true;
-		}
-		iter = whereColumns.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			final Map.Entry e = (Map.Entry) iter.next();
-			if ( conditionsAppended ) {
-				buf.append( " and " );
-			}
-			buf.append( e.getKey() ).append( e.getValue() );
-			conditionsAppended = true;
-		}
-		if ( versionColumnName != null ) {
-			if ( conditionsAppended ) {
-				buf.append( " and " );
-			}
-			buf.append( versionColumnName ).append( "=?" );
-		}
-
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/Update.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/Update.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,211 @@
+/*
+ * 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;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.LinkedHashMap;
+
+import org.hibernate.dialect.Dialect;
+import org.hibernate.type.LiteralType;
+import org.hibernate.util.StringHelper;
+
+/**
+ * An SQL <tt>UPDATE</tt> statement
+ *
+ * @author Gavin King
+ */
+public class Update {
+
+	private String tableName;
+	private String[] primaryKeyColumnNames;
+	private String versionColumnName;
+	private String where;
+	private String assignments;
+	private String comment;
+
+	private Map columns = new LinkedHashMap();
+	private Map whereColumns = new LinkedHashMap();
+	
+	private Dialect dialect;
+	
+	public Update(Dialect dialect) {
+		this.dialect = dialect;
+	}
+
+	public String getTableName() {
+		return tableName;
+	}
+
+	public Update appendAssignmentFragment(String fragment) {
+		if ( assignments == null ) {
+			assignments = fragment;
+		}
+		else {
+			assignments += ", " + fragment;
+		}
+		return this;
+	}
+
+	public Update setTableName(String tableName) {
+		this.tableName = tableName;
+		return this;
+	}
+
+	public Update setPrimaryKeyColumnNames(String[] primaryKeyColumnNames) {
+		this.primaryKeyColumnNames = primaryKeyColumnNames;
+		return this;
+	}
+
+	public Update setVersionColumnName(String versionColumnName) {
+		this.versionColumnName = versionColumnName;
+		return this;
+	}
+
+
+	public Update setComment(String comment) {
+		this.comment = comment;
+		return this;
+	}
+
+	public Update addColumns(String[] columnNames) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			addColumn( columnNames[i] );
+		}
+		return this;
+	}
+
+	public Update addColumns(String[] columnNames, boolean[] updateable) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			if ( updateable[i] ) addColumn( columnNames[i] );
+		}
+		return this;
+	}
+
+	public Update addColumns(String[] columnNames, String value) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			addColumn( columnNames[i], value );
+		}
+		return this;
+	}
+
+	public Update addColumn(String columnName) {
+		return addColumn(columnName, "?");
+	}
+
+	public Update addColumn(String columnName, String value) {
+		columns.put(columnName, value);
+		return this;
+	}
+
+	public Update addColumn(String columnName, Object value, LiteralType type) throws Exception {
+		return addColumn( columnName, type.objectToSQLString(value, dialect) );
+	}
+
+	public Update addWhereColumns(String[] columnNames) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			addWhereColumn( columnNames[i] );
+		}
+		return this;
+	}
+
+	public Update addWhereColumns(String[] columnNames, String value) {
+		for ( int i=0; i<columnNames.length; i++ ) {
+			addWhereColumn( columnNames[i], value );
+		}
+		return this;
+	}
+
+	public Update addWhereColumn(String columnName) {
+		return addWhereColumn(columnName, "=?");
+	}
+
+	public Update addWhereColumn(String columnName, String value) {
+		whereColumns.put(columnName, value);
+		return this;
+	}
+
+	public Update setWhere(String where) {
+		this.where=where;
+		return this;
+	}
+
+	public String toStatementString() {
+		StringBuffer buf = new StringBuffer( (columns.size() * 15) + tableName.length() + 10 );
+		if ( comment!=null ) {
+			buf.append( "/* " ).append( comment ).append( " */ " );
+		}
+		buf.append( "update " ).append( tableName ).append( " set " );
+		boolean assignmentsAppended = false;
+		Iterator iter = columns.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry e = (Map.Entry) iter.next();
+			buf.append( e.getKey() ).append( '=' ).append( e.getValue() );
+			if ( iter.hasNext() ) {
+				buf.append( ", " );
+			}
+			assignmentsAppended = true;
+		}
+		if ( assignments != null ) {
+			if ( assignmentsAppended ) {
+				buf.append( ", " );
+			}
+			buf.append( assignments );
+		}
+
+		boolean conditionsAppended = false;
+		if ( primaryKeyColumnNames != null || where != null || !whereColumns.isEmpty() || versionColumnName != null ) {
+			buf.append( " where " );
+		}
+		if ( primaryKeyColumnNames != null ) {
+			buf.append( StringHelper.join( "=? and ", primaryKeyColumnNames ) ).append( "=?" );
+			conditionsAppended = true;
+		}
+		if ( where != null ) {
+			if ( conditionsAppended ) {
+				buf.append( " and " );
+			}
+			buf.append( where );
+			conditionsAppended = true;
+		}
+		iter = whereColumns.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			final Map.Entry e = (Map.Entry) iter.next();
+			if ( conditionsAppended ) {
+				buf.append( " and " );
+			}
+			buf.append( e.getKey() ).append( e.getValue() );
+			conditionsAppended = true;
+		}
+		if ( versionColumnName != null ) {
+			if ( conditionsAppended ) {
+				buf.append( " and " );
+			}
+			buf.append( versionColumnName ).append( "=?" );
+		}
+
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/sql/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines helper classes for rendering SQL
-	fragments and SQL statements.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/sql/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/sql/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines helper classes for rendering SQL
+	fragments and SQL statements.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: CategorizedStatistics.java 7093 2005-06-09 06:33:06Z oneovthafew $
-package org.hibernate.stat;
-
-import java.io.Serializable;
-
-/**
- * Statistics for a particular "category" (a named entity,
- * collection role, second level cache region or query).
- * 
- * @author Gavin King
- */
-public class CategorizedStatistics implements Serializable {
-	
-	private final String categoryName;
-
-	CategorizedStatistics(String categoryName) {
-		this.categoryName = categoryName;
-	}
-	
-	public String getCategoryName() {
-		return categoryName;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CategorizedStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.stat;
+
+import java.io.Serializable;
+
+/**
+ * Statistics for a particular "category" (a named entity,
+ * collection role, second level cache region or query).
+ * 
+ * @author Gavin King
+ */
+public class CategorizedStatistics implements Serializable {
+	
+	private final String categoryName;
+
+	CategorizedStatistics(String categoryName) {
+		this.categoryName = categoryName;
+	}
+	
+	public String getCategoryName() {
+		return categoryName;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/CollectionStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: CollectionStatistics.java 7093 2005-06-09 06:33:06Z oneovthafew $
-package org.hibernate.stat;
-
-
-/**
- * Collection related statistics
- * 
- * @author Gavin King
- */
-public class CollectionStatistics extends CategorizedStatistics {
-	
-	CollectionStatistics(String role) {
-		super(role);
-	}
-	
-	long loadCount;
-	long fetchCount;
-	long updateCount;
-	long removeCount;
-	long recreateCount;
-	
-	public long getLoadCount() {
-		return loadCount;
-	}
-	public long getFetchCount() {
-		return fetchCount;
-	}
-	public long getRecreateCount() {
-		return recreateCount;
-	}
-	public long getRemoveCount() {
-		return removeCount;
-	}
-	public long getUpdateCount() {
-		return updateCount;
-	}
-
-	public String toString() {
-		return new StringBuffer()
-		    .append("CollectionStatistics")
-			.append("[loadCount=").append(this.loadCount)
-			.append(",fetchCount=").append(this.fetchCount)
-			.append(",recreateCount=").append(this.recreateCount)
-			.append(",removeCount=").append(this.removeCount)
-			.append(",updateCount=").append(this.updateCount)
-			.append(']')
-			.toString();
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/CollectionStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/CollectionStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,71 @@
+/*
+ * 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.stat;
+
+/**
+ * Collection related statistics
+ * 
+ * @author Gavin King
+ */
+public class CollectionStatistics extends CategorizedStatistics {
+	
+	CollectionStatistics(String role) {
+		super(role);
+	}
+	
+	long loadCount;
+	long fetchCount;
+	long updateCount;
+	long removeCount;
+	long recreateCount;
+	
+	public long getLoadCount() {
+		return loadCount;
+	}
+	public long getFetchCount() {
+		return fetchCount;
+	}
+	public long getRecreateCount() {
+		return recreateCount;
+	}
+	public long getRemoveCount() {
+		return removeCount;
+	}
+	public long getUpdateCount() {
+		return updateCount;
+	}
+
+	public String toString() {
+		return new StringBuffer()
+		    .append("CollectionStatistics")
+			.append("[loadCount=").append(this.loadCount)
+			.append(",fetchCount=").append(this.fetchCount)
+			.append(",recreateCount=").append(this.recreateCount)
+			.append(",removeCount=").append(this.removeCount)
+			.append(",updateCount=").append(this.updateCount)
+			.append(']')
+			.toString();
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/EntityStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-//$Id: EntityStatistics.java 7864 2005-08-11 23:22:52Z oneovthafew $
-package org.hibernate.stat;
-
-
-/**
- * Entity related statistics
- * 
- * @author Gavin King
- */
-public class EntityStatistics extends CategorizedStatistics {
-	
-	EntityStatistics(String name) {
-		super(name);
-	}
-
-	long loadCount;
-	long updateCount;
-	long insertCount;
-	long deleteCount;
-	long fetchCount;
-	long optimisticFailureCount;
-
-	public long getDeleteCount() {
-		return deleteCount;
-	}
-	public long getInsertCount() {
-		return insertCount;
-	}
-	public long getLoadCount() {
-		return loadCount;
-	}
-	public long getUpdateCount() {
-		return updateCount;
-	}
-	public long getFetchCount() {
-		return fetchCount;
-	}
-	public long getOptimisticFailureCount() {
-		return optimisticFailureCount;
-	}
-
-	public String toString() {
-		return new StringBuffer()
-		    .append("EntityStatistics")
-			.append("[loadCount=").append(this.loadCount)
-			.append(",updateCount=").append(this.updateCount)
-			.append(",insertCount=").append(this.insertCount)
-			.append(",deleteCount=").append(this.deleteCount)
-			.append(",fetchCount=").append(this.fetchCount)
-			.append(",optimisticLockFailureCount=").append(this.optimisticFailureCount)
-			.append(']')
-			.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/EntityStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/EntityStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,78 @@
+/*
+ * 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.stat;
+
+
+/**
+ * Entity related statistics
+ * 
+ * @author Gavin King
+ */
+public class EntityStatistics extends CategorizedStatistics {
+	
+	EntityStatistics(String name) {
+		super(name);
+	}
+
+	long loadCount;
+	long updateCount;
+	long insertCount;
+	long deleteCount;
+	long fetchCount;
+	long optimisticFailureCount;
+
+	public long getDeleteCount() {
+		return deleteCount;
+	}
+	public long getInsertCount() {
+		return insertCount;
+	}
+	public long getLoadCount() {
+		return loadCount;
+	}
+	public long getUpdateCount() {
+		return updateCount;
+	}
+	public long getFetchCount() {
+		return fetchCount;
+	}
+	public long getOptimisticFailureCount() {
+		return optimisticFailureCount;
+	}
+
+	public String toString() {
+		return new StringBuffer()
+		    .append("EntityStatistics")
+			.append("[loadCount=").append(this.loadCount)
+			.append(",updateCount=").append(this.updateCount)
+			.append(",insertCount=").append(this.insertCount)
+			.append(",deleteCount=").append(this.deleteCount)
+			.append(",fetchCount=").append(this.fetchCount)
+			.append(",optimisticLockFailureCount=").append(this.optimisticFailureCount)
+			.append(']')
+			.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/QueryStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,112 +0,0 @@
-//$Id: QueryStatistics.java 9162 2006-01-27 23:40:32Z steveebersole $
-package org.hibernate.stat;
-
-
-/**
- * Query statistics (HQL and SQL)
- * 
- * Note that for a cached query, the cache miss is equals to the db count
- * 
- * @author Gavin King
- */
-public class QueryStatistics extends CategorizedStatistics {
-
-	/*package*/ long cacheHitCount;
-	/*package*/ long cacheMissCount;
-	/*package*/ long cachePutCount;
-	private long executionCount;
-	private long executionRowCount;
-	private long executionAvgTime;
-	private long executionMaxTime;
-	private long executionMinTime = Long.MAX_VALUE;
-
-	QueryStatistics(String query) {
-		super(query);
-	}
-
-	/**
-	 * queries executed to the DB
-	 */
-	public long getExecutionCount() {
-		return executionCount;
-	}
-	
-	/**
-	 * Queries retrieved successfully from the cache
-	 */
-	public long getCacheHitCount() {
-		return cacheHitCount;
-	}
-	
-	public long getCachePutCount() {
-		return cachePutCount;
-	}
-	
-	public long getCacheMissCount() {
-		return cacheMissCount;
-	}
-	
-	/**
-	 * Number of lines returned by all the executions of this query (from DB)
-	 * For now, {@link org.hibernate.Query#iterate()} 
-	 * and {@link org.hibernate.Query#scroll()()} do not fill this statistic
-	 *
-	 * @return The number of rows cumulatively returned by the given query; iterate
-	 * and scroll queries do not effect this total as their number of returned rows
-	 * is not known at execution time.
-	 */
-	public long getExecutionRowCount() {
-		return executionRowCount;
-	}
-
-	/**
-	 * average time in ms taken by the excution of this query onto the DB
-	 */
-	public long getExecutionAvgTime() {
-		return executionAvgTime;
-	}
-
-	/**
-	 * max time in ms taken by the excution of this query onto the DB
-	 */
-	public long getExecutionMaxTime() {
-		return executionMaxTime;
-	}
-	
-	/**
-	 * min time in ms taken by the excution of this query onto the DB
-	 */
-	public long getExecutionMinTime() {
-		return executionMinTime;
-	}
-	
-	/**
-	 * add statistics report of a DB query
-	 * 
-	 * @param rows rows count returned
-	 * @param time time taken
-	 */
-	void executed(long rows, long time) {
-		if (time < executionMinTime) executionMinTime = time;
-		if (time > executionMaxTime) executionMaxTime = time;
-		executionAvgTime = ( executionAvgTime * executionCount + time ) / ( executionCount + 1 );
-		executionCount++;
-		executionRowCount += rows;
-	}
-
-	public String toString() {
-		return new StringBuffer()
-				.append( "QueryStatistics" )
-				.append( "[cacheHitCount=" ).append( this.cacheHitCount )
-				.append( ",cacheMissCount=" ).append( this.cacheMissCount )
-				.append( ",cachePutCount=" ).append( this.cachePutCount )
-				.append( ",executionCount=" ).append( this.executionCount )
-				.append( ",executionRowCount=" ).append( this.executionRowCount )
-				.append( ",executionAvgTime=" ).append( this.executionAvgTime )
-				.append( ",executionMaxTime=" ).append( this.executionMaxTime )
-				.append( ",executionMinTime=" ).append( this.executionMinTime )
-				.append( ']' )
-				.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/QueryStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/QueryStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.stat;
+
+/**
+ * Query statistics (HQL and SQL)
+ * 
+ * Note that for a cached query, the cache miss is equals to the db count
+ * 
+ * @author Gavin King
+ */
+public class QueryStatistics extends CategorizedStatistics {
+
+	/*package*/ long cacheHitCount;
+	/*package*/ long cacheMissCount;
+	/*package*/ long cachePutCount;
+	private long executionCount;
+	private long executionRowCount;
+	private long executionAvgTime;
+	private long executionMaxTime;
+	private long executionMinTime = Long.MAX_VALUE;
+
+	QueryStatistics(String query) {
+		super(query);
+	}
+
+	/**
+	 * queries executed to the DB
+	 */
+	public long getExecutionCount() {
+		return executionCount;
+	}
+	
+	/**
+	 * Queries retrieved successfully from the cache
+	 */
+	public long getCacheHitCount() {
+		return cacheHitCount;
+	}
+	
+	public long getCachePutCount() {
+		return cachePutCount;
+	}
+	
+	public long getCacheMissCount() {
+		return cacheMissCount;
+	}
+	
+	/**
+	 * Number of lines returned by all the executions of this query (from DB)
+	 * For now, {@link org.hibernate.Query#iterate()} 
+	 * and {@link org.hibernate.Query#scroll()()} do not fill this statistic
+	 *
+	 * @return The number of rows cumulatively returned by the given query; iterate
+	 * and scroll queries do not effect this total as their number of returned rows
+	 * is not known at execution time.
+	 */
+	public long getExecutionRowCount() {
+		return executionRowCount;
+	}
+
+	/**
+	 * average time in ms taken by the excution of this query onto the DB
+	 */
+	public long getExecutionAvgTime() {
+		return executionAvgTime;
+	}
+
+	/**
+	 * max time in ms taken by the excution of this query onto the DB
+	 */
+	public long getExecutionMaxTime() {
+		return executionMaxTime;
+	}
+	
+	/**
+	 * min time in ms taken by the excution of this query onto the DB
+	 */
+	public long getExecutionMinTime() {
+		return executionMinTime;
+	}
+	
+	/**
+	 * add statistics report of a DB query
+	 * 
+	 * @param rows rows count returned
+	 * @param time time taken
+	 */
+	void executed(long rows, long time) {
+		if (time < executionMinTime) executionMinTime = time;
+		if (time > executionMaxTime) executionMaxTime = time;
+		executionAvgTime = ( executionAvgTime * executionCount + time ) / ( executionCount + 1 );
+		executionCount++;
+		executionRowCount += rows;
+	}
+
+	public String toString() {
+		return new StringBuffer()
+				.append( "QueryStatistics" )
+				.append( "[cacheHitCount=" ).append( this.cacheHitCount )
+				.append( ",cacheMissCount=" ).append( this.cacheMissCount )
+				.append( ",cachePutCount=" ).append( this.cachePutCount )
+				.append( ",executionCount=" ).append( this.executionCount )
+				.append( ",executionRowCount=" ).append( this.executionRowCount )
+				.append( ",executionAvgTime=" ).append( this.executionAvgTime )
+				.append( ",executionMaxTime=" ).append( this.executionMaxTime )
+				.append( ",executionMinTime=" ).append( this.executionMinTime )
+				.append( ']' )
+				.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,71 +0,0 @@
-//$Id: SecondLevelCacheStatistics.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.stat;
-
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.cache.CacheKey;
-import org.hibernate.cache.Region;
-
-/**
- * Second level cache statistics of a specific region
- * 
- * @author Gavin King
- */
-public class SecondLevelCacheStatistics extends CategorizedStatistics {
-	
-    private transient Region region;
-	long hitCount;
-	long missCount;
-	long putCount;
-
-	SecondLevelCacheStatistics(Region region) {
-		super( region.getName() );
-		this.region = region;
-	}
-	public long getHitCount() {
-		return hitCount;
-	}
-	public long getMissCount() {
-		return missCount;
-	}
-	public long getPutCount() {
-		return putCount;
-	}
-	public long getElementCountInMemory() {
-		return region.getElementCountInMemory();
-	}
-	public long getElementCountOnDisk() {
-		return region.getElementCountOnDisk();
-	}
-	public long getSizeInMemory() {
-		return region.getSizeInMemory();
-	}
-	
-	public Map getEntries() {
-		Map map = new HashMap();
-		Iterator iter = region.toMap().entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			map.put( ( (CacheKey) me.getKey() ).getKey(), me.getValue() );
-		}
-		return map;
-	}
-
-	public String toString() {
-		StringBuffer buf = new StringBuffer()
-		    .append("SecondLevelCacheStatistics")
-			.append("[hitCount=").append(this.hitCount)
-			.append(",missCount=").append(this.missCount)
-			.append(",putCount=").append(this.putCount);
-		//not sure if this would ever be null but wanted to be careful
-		if ( region != null ) {
-			buf.append(",elementCountInMemory=").append(this.getElementCountInMemory())
-				.append(",elementCountOnDisk=").append(this.getElementCountOnDisk())
-				.append(",sizeInMemory=").append(this.getSizeInMemory());
-		}
-		buf.append(']');
-		return buf.toString();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SecondLevelCacheStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,94 @@
+/*
+ * 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.stat;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.cache.CacheKey;
+import org.hibernate.cache.Region;
+
+/**
+ * Second level cache statistics of a specific region
+ * 
+ * @author Gavin King
+ */
+public class SecondLevelCacheStatistics extends CategorizedStatistics {
+	
+    private transient Region region;
+	long hitCount;
+	long missCount;
+	long putCount;
+
+	SecondLevelCacheStatistics(Region region) {
+		super( region.getName() );
+		this.region = region;
+	}
+	public long getHitCount() {
+		return hitCount;
+	}
+	public long getMissCount() {
+		return missCount;
+	}
+	public long getPutCount() {
+		return putCount;
+	}
+	public long getElementCountInMemory() {
+		return region.getElementCountInMemory();
+	}
+	public long getElementCountOnDisk() {
+		return region.getElementCountOnDisk();
+	}
+	public long getSizeInMemory() {
+		return region.getSizeInMemory();
+	}
+	
+	public Map getEntries() {
+		Map map = new HashMap();
+		Iterator iter = region.toMap().entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			map.put( ( (CacheKey) me.getKey() ).getKey(), me.getValue() );
+		}
+		return map;
+	}
+
+	public String toString() {
+		StringBuffer buf = new StringBuffer()
+		    .append("SecondLevelCacheStatistics")
+			.append("[hitCount=").append(this.hitCount)
+			.append(",missCount=").append(this.missCount)
+			.append(",putCount=").append(this.putCount);
+		//not sure if this would ever be null but wanted to be careful
+		if ( region != null ) {
+			buf.append(",elementCountInMemory=").append(this.getElementCountInMemory())
+				.append(",elementCountOnDisk=").append(this.getElementCountOnDisk())
+				.append(",sizeInMemory=").append(this.getSizeInMemory());
+		}
+		buf.append(']');
+		return buf.toString();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/SessionStatistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-//$Id: SessionStatistics.java 6750 2005-05-11 15:26:04Z oneovthafew $
-package org.hibernate.stat;
-
-import java.util.Set;
-
-/**
- * Information about the first-level (session) cache
- * for a particular session instance
- * @author Gavin King
- */
-public interface SessionStatistics {
-
-	/**
-	 * Get the number of entity instances associated with the session
-	 */
-	public int getEntityCount();
-	/**
-	 * Get the number of collection instances associated with the session
-	 */
-	public int getCollectionCount();
-
-	/**
-	 * Get the set of all <tt>EntityKey</tt>s
-	 * @see org.hibernate.engine.EntityKey
-	 */
-	public Set getEntityKeys();
-	/**
-	 * Get the set of all <tt>CollectionKey</tt>s
-	 * @see org.hibernate.engine.CollectionKey
-	 */
-	public Set getCollectionKeys();
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/SessionStatistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.stat;
+
+import java.util.Set;
+
+/**
+ * Information about the first-level (session) cache
+ * for a particular session instance
+ * @author Gavin King
+ */
+public interface SessionStatistics {
+
+	/**
+	 * Get the number of entity instances associated with the session
+	 */
+	public int getEntityCount();
+	/**
+	 * Get the number of collection instances associated with the session
+	 */
+	public int getCollectionCount();
+
+	/**
+	 * Get the set of all <tt>EntityKey</tt>s
+	 * @see org.hibernate.engine.EntityKey
+	 */
+	public Set getEntityKeys();
+	/**
+	 * Get the set of all <tt>CollectionKey</tt>s
+	 * @see org.hibernate.engine.CollectionKey
+	 */
+	public Set getCollectionKeys();
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: SessionStatisticsImpl.java 7688 2005-07-29 21:43:18Z epbernard $
-package org.hibernate.stat;
-
-import java.util.Collections;
-import java.util.Set;
-
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * @author Gavin King
- */
-public class SessionStatisticsImpl implements SessionStatistics {
-
-	private final SessionImplementor session;
-	
-	public SessionStatisticsImpl(SessionImplementor session) {
-		this.session = session;
-	}
-
-	public int getEntityCount() {
-		return session.getPersistenceContext().getEntityEntries().size();
-	}
-	
-	public int getCollectionCount() {
-		return session.getPersistenceContext().getCollectionEntries().size();
-	}
-	
-	public Set getEntityKeys() {
-		return Collections.unmodifiableSet( session.getPersistenceContext().getEntitiesByKey().keySet() );
-	}
-	
-	public Set getCollectionKeys() {
-		return Collections.unmodifiableSet( session.getPersistenceContext().getCollectionsByKey().keySet() );
-	}
-	
-	public String toString() {
-		return new StringBuffer()
-			.append("SessionStatistics[")
-			.append("entity count=").append( getEntityCount() )
-			.append("collection count=").append( getCollectionCount() )
-			.append(']')
-			.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/SessionStatisticsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.stat;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class SessionStatisticsImpl implements SessionStatistics {
+
+	private final SessionImplementor session;
+	
+	public SessionStatisticsImpl(SessionImplementor session) {
+		this.session = session;
+	}
+
+	public int getEntityCount() {
+		return session.getPersistenceContext().getEntityEntries().size();
+	}
+	
+	public int getCollectionCount() {
+		return session.getPersistenceContext().getCollectionEntries().size();
+	}
+	
+	public Set getEntityKeys() {
+		return Collections.unmodifiableSet( session.getPersistenceContext().getEntitiesByKey().keySet() );
+	}
+	
+	public Set getCollectionKeys() {
+		return Collections.unmodifiableSet( session.getPersistenceContext().getCollectionsByKey().keySet() );
+	}
+	
+	public String toString() {
+		return new StringBuffer()
+			.append("SessionStatistics[")
+			.append("entity count=").append( getEntityCount() )
+			.append("collection count=").append( getCollectionCount() )
+			.append(']')
+			.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/Statistics.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,211 +0,0 @@
-//$Id: Statistics.java 8262 2005-09-30 07:48:53Z oneovthafew $
-package org.hibernate.stat;
-
-
-/**
- * Statistics for a particular <tt>SessionFactory</tt>.
- * Beware of milliseconds metrics, they are depdendent of the JVM precision:
- * you may then encounter a 10 ms approximation dending on you OS platform.
- * Please refer to the JVM documentation for more information.
- * 
- * @author Emmanuel Bernard
- */
-public interface Statistics {
-	/**
-	 * reset all statistics
-	 */
-	public void clear();
-
-    /**
-	 * find entity statistics per name
-	 * 
-	 * @param entityName entity name
-	 * @return EntityStatistics object
-	 */
-	public EntityStatistics getEntityStatistics(String entityName);
-	/**
-	 * Get collection statistics per role
-	 * 
-	 * @param role collection role
-	 * @return CollectionStatistics
-	 */
-	public CollectionStatistics getCollectionStatistics(String role);
-
-    /**
-	 * Second level cache statistics per region
-	 * 
-	 * @param regionName region name
-	 * @return SecondLevelCacheStatistics
-	 */
-	public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
-
-    /**
-	 * Query statistics from query string (HQL or SQL)
-	 * 
-	 * @param queryString query string
-	 * @return QueryStatistics
-	 */
-	public QueryStatistics getQueryStatistics(String queryString);
-
-    /**
-     * Get global number of entity deletes
-	 * @return entity deletion count
-	 */
-	public long getEntityDeleteCount();
-
-    /**
-     * Get global number of entity inserts
-	 * @return entity insertion count
-	 */
-	public long getEntityInsertCount();
-
-    /**
-     * Get global number of entity loads
-	 * @return entity load (from DB)
-	 */
-	public long getEntityLoadCount();
-	/**
-     * Get global number of entity fetchs
-	 * @return entity fetch (from DB)
-	 */
-	public long getEntityFetchCount();
-
-	/**
-     * Get global number of entity updates
-	 * @return entity update
-	 */
-	public long getEntityUpdateCount();
-
-    /**
-     * Get global number of executed queries
-	 * @return query execution count
-	 */
-	public long getQueryExecutionCount();
-
-    /**
-     * Get the time in milliseconds of the slowest query.
-     */
-	public long getQueryExecutionMaxTime();
-	/**
-	 * Get the query string for the slowest query.
-	 */
-	public String getQueryExecutionMaxTimeQueryString();
-
-    /**
-     * Get the global number of cached queries successfully retrieved from cache
-     */
-	public long getQueryCacheHitCount();
-    /**
-     * Get the global number of cached queries *not* found in cache
-     */
-	public long getQueryCacheMissCount();
-    /**
-     * Get the global number of cacheable queries put in cache
-     */
-	public long getQueryCachePutCount();
-	/**
-     * Get the global number of flush executed by sessions (either implicit or explicit)
-     */
-	public long getFlushCount();
-	/**
-	 * Get the global number of connections asked by the sessions
-     * (the actual number of connections used may be much smaller depending
-     * whether you use a connection pool or not)
-	 */
-	public long getConnectCount();
-	/**
-     * Global number of cacheable entities/collections successfully retrieved from the cache
-     */
-	public long getSecondLevelCacheHitCount();
-	/**
-     * Global number of cacheable entities/collections not found in the cache and loaded from the database.
-     */
-	public long getSecondLevelCacheMissCount();
-	/**
-	 * Global number of cacheable entities/collections put in the cache
-	 */
-	public long getSecondLevelCachePutCount();
-	/**
-	 * Global number of sessions closed
-	 */
-	public long getSessionCloseCount();
-	/**
-	 * Global number of sessions opened
-	 */
-	public long getSessionOpenCount();
-	/**
-	 * Global number of collections loaded
-	 */
-	public long getCollectionLoadCount();
-	/**
-	 * Global number of collections fetched
-	 */
-	public long getCollectionFetchCount();
-	/**
-	 * Global number of collections updated
-	 */
-	public long getCollectionUpdateCount();
-	/**
-	 * Global number of collections removed
-	 */
-    //even on inverse="true"
-	public long getCollectionRemoveCount();
-	/**
-	 * Global number of collections recreated
-	 */
-	public long getCollectionRecreateCount();
-	/**
-	 * @return start time in ms (JVM standards {@link System#currentTimeMillis()})
-	 */
-	public long getStartTime();
-	/**
-	 * log in info level the main statistics
-	 */
-	public void logSummary();
-	/**
-	 * Are statistics logged
-	 */
-	public boolean isStatisticsEnabled();
-	/**
-	 * Enable statistics logs (this is a dynamic parameter)
-	 */
-	public void setStatisticsEnabled(boolean b);
-
-	/**
-	 * Get all executed query strings
-	 */
-	public String[] getQueries();
-	/**
-	 * Get the names of all entities
-	 */
-	public String[] getEntityNames();
-	/**
-	 * Get the names of all collection roles
-	 */
-	public String[] getCollectionRoleNames();
-	/**
-	 * Get all second-level cache region names
-	 */
-	public String[] getSecondLevelCacheRegionNames();
-	/**
-	 * The number of transactions we know to have been successful
-	 */
-	public long getSuccessfulTransactionCount();
-	/**
-	 * The number of transactions we know to have completed
-	 */
-	public long getTransactionCount();
-	/**
-	 * The number of prepared statements that were acquired
-	 */
-	public long getPrepareStatementCount();
-	/**
-	 * The number of prepared statements that were released
-	 */
-	public long getCloseStatementCount();
-	/**
-	 * The number of <tt>StaleObjectStateException</tt>s 
-	 * that occurred
-	 */
-	public long getOptimisticFailureCount();
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/Statistics.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/Statistics.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,234 @@
+/*
+ * 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.stat;
+
+
+/**
+ * Statistics for a particular <tt>SessionFactory</tt>.
+ * Beware of milliseconds metrics, they are depdendent of the JVM precision:
+ * you may then encounter a 10 ms approximation dending on you OS platform.
+ * Please refer to the JVM documentation for more information.
+ * 
+ * @author Emmanuel Bernard
+ */
+public interface Statistics {
+	/**
+	 * reset all statistics
+	 */
+	public void clear();
+
+    /**
+	 * find entity statistics per name
+	 * 
+	 * @param entityName entity name
+	 * @return EntityStatistics object
+	 */
+	public EntityStatistics getEntityStatistics(String entityName);
+	/**
+	 * Get collection statistics per role
+	 * 
+	 * @param role collection role
+	 * @return CollectionStatistics
+	 */
+	public CollectionStatistics getCollectionStatistics(String role);
+
+    /**
+	 * Second level cache statistics per region
+	 * 
+	 * @param regionName region name
+	 * @return SecondLevelCacheStatistics
+	 */
+	public SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName);
+
+    /**
+	 * Query statistics from query string (HQL or SQL)
+	 * 
+	 * @param queryString query string
+	 * @return QueryStatistics
+	 */
+	public QueryStatistics getQueryStatistics(String queryString);
+
+    /**
+     * Get global number of entity deletes
+	 * @return entity deletion count
+	 */
+	public long getEntityDeleteCount();
+
+    /**
+     * Get global number of entity inserts
+	 * @return entity insertion count
+	 */
+	public long getEntityInsertCount();
+
+    /**
+     * Get global number of entity loads
+	 * @return entity load (from DB)
+	 */
+	public long getEntityLoadCount();
+	/**
+     * Get global number of entity fetchs
+	 * @return entity fetch (from DB)
+	 */
+	public long getEntityFetchCount();
+
+	/**
+     * Get global number of entity updates
+	 * @return entity update
+	 */
+	public long getEntityUpdateCount();
+
+    /**
+     * Get global number of executed queries
+	 * @return query execution count
+	 */
+	public long getQueryExecutionCount();
+
+    /**
+     * Get the time in milliseconds of the slowest query.
+     */
+	public long getQueryExecutionMaxTime();
+	/**
+	 * Get the query string for the slowest query.
+	 */
+	public String getQueryExecutionMaxTimeQueryString();
+
+    /**
+     * Get the global number of cached queries successfully retrieved from cache
+     */
+	public long getQueryCacheHitCount();
+    /**
+     * Get the global number of cached queries *not* found in cache
+     */
+	public long getQueryCacheMissCount();
+    /**
+     * Get the global number of cacheable queries put in cache
+     */
+	public long getQueryCachePutCount();
+	/**
+     * Get the global number of flush executed by sessions (either implicit or explicit)
+     */
+	public long getFlushCount();
+	/**
+	 * Get the global number of connections asked by the sessions
+     * (the actual number of connections used may be much smaller depending
+     * whether you use a connection pool or not)
+	 */
+	public long getConnectCount();
+	/**
+     * Global number of cacheable entities/collections successfully retrieved from the cache
+     */
+	public long getSecondLevelCacheHitCount();
+	/**
+     * Global number of cacheable entities/collections not found in the cache and loaded from the database.
+     */
+	public long getSecondLevelCacheMissCount();
+	/**
+	 * Global number of cacheable entities/collections put in the cache
+	 */
+	public long getSecondLevelCachePutCount();
+	/**
+	 * Global number of sessions closed
+	 */
+	public long getSessionCloseCount();
+	/**
+	 * Global number of sessions opened
+	 */
+	public long getSessionOpenCount();
+	/**
+	 * Global number of collections loaded
+	 */
+	public long getCollectionLoadCount();
+	/**
+	 * Global number of collections fetched
+	 */
+	public long getCollectionFetchCount();
+	/**
+	 * Global number of collections updated
+	 */
+	public long getCollectionUpdateCount();
+	/**
+	 * Global number of collections removed
+	 */
+    //even on inverse="true"
+	public long getCollectionRemoveCount();
+	/**
+	 * Global number of collections recreated
+	 */
+	public long getCollectionRecreateCount();
+	/**
+	 * @return start time in ms (JVM standards {@link System#currentTimeMillis()})
+	 */
+	public long getStartTime();
+	/**
+	 * log in info level the main statistics
+	 */
+	public void logSummary();
+	/**
+	 * Are statistics logged
+	 */
+	public boolean isStatisticsEnabled();
+	/**
+	 * Enable statistics logs (this is a dynamic parameter)
+	 */
+	public void setStatisticsEnabled(boolean b);
+
+	/**
+	 * Get all executed query strings
+	 */
+	public String[] getQueries();
+	/**
+	 * Get the names of all entities
+	 */
+	public String[] getEntityNames();
+	/**
+	 * Get the names of all collection roles
+	 */
+	public String[] getCollectionRoleNames();
+	/**
+	 * Get all second-level cache region names
+	 */
+	public String[] getSecondLevelCacheRegionNames();
+	/**
+	 * The number of transactions we know to have been successful
+	 */
+	public long getSuccessfulTransactionCount();
+	/**
+	 * The number of transactions we know to have completed
+	 */
+	public long getTransactionCount();
+	/**
+	 * The number of prepared statements that were acquired
+	 */
+	public long getPrepareStatementCount();
+	/**
+	 * The number of prepared statements that were released
+	 */
+	public long getCloseStatementCount();
+	/**
+	 * The number of <tt>StaleObjectStateException</tt>s 
+	 * that occurred
+	 */
+	public long getOptimisticFailureCount();
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/StatisticsImpl.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,640 +0,0 @@
-//$Id: StatisticsImpl.java 11398 2007-04-10 14:54:07Z steve.ebersole at jboss.com $
-package org.hibernate.stat;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.cache.Cache;
-import org.hibernate.cache.Region;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * @see org.hibernate.stat.Statistics 
- *  
- * @author Gavin King
- */
-public class StatisticsImpl implements Statistics, StatisticsImplementor {
-	
-	//TODO: we should provide some way to get keys of collection of statistics to make it easier to retrieve from a GUI perspective
-	
-	private static final Logger log = LoggerFactory.getLogger(StatisticsImpl.class);
-
-	private SessionFactoryImplementor sessionFactory;
-
-	private boolean isStatisticsEnabled;
-	private long startTime;
-	private long sessionOpenCount;
-	private long sessionCloseCount;
-	private long flushCount;
-	private long connectCount;
-	
-	private long prepareStatementCount;
-	private long closeStatementCount;
-	
-	private long entityLoadCount;
-	private long entityUpdateCount;
-	private long entityInsertCount;
-	private long entityDeleteCount;
-	private long entityFetchCount;
-	private long collectionLoadCount;
-	private long collectionUpdateCount;
-	private long collectionRemoveCount;
-	private long collectionRecreateCount;
-	private long collectionFetchCount;
-	
-	private long secondLevelCacheHitCount;
-	private long secondLevelCacheMissCount;
-	private long secondLevelCachePutCount;
-	
-	private long queryExecutionCount;
-	private long queryExecutionMaxTime;
-	private String queryExecutionMaxTimeQueryString;
-	private long queryCacheHitCount;
-	private long queryCacheMissCount;
-	private long queryCachePutCount;
-	
-	private long commitedTransactionCount;
-	private long transactionCount;
-	
-	private long optimisticFailureCount;
-	
-	/** second level cache statistics per region */
-	private final Map secondLevelCacheStatistics = new HashMap();
-	/** entity statistics per name */
-	private final Map entityStatistics = new HashMap();
-	/** collection statistics per name */
-	private final Map collectionStatistics = new HashMap();
-	/** entity statistics per query string (HQL or SQL) */
-	private final Map queryStatistics = new HashMap();
-
-	public StatisticsImpl() {
-		clear();
-	}
-
-	public StatisticsImpl(SessionFactoryImplementor sessionFactory) {
-		clear();
-		this.sessionFactory = sessionFactory;
-	}
-	
-	/**
-	 * reset all statistics
-	 */
-	public synchronized void clear() {
-		secondLevelCacheHitCount = 0;
-		secondLevelCacheMissCount = 0;
-		secondLevelCachePutCount = 0;
-		
-		sessionCloseCount = 0;
-		sessionOpenCount = 0;
-		flushCount = 0;
-		connectCount = 0;
-		
-		prepareStatementCount = 0;
-		closeStatementCount = 0;
-		
-		entityDeleteCount = 0;
-		entityInsertCount = 0;
-		entityUpdateCount = 0;
-		entityLoadCount = 0;
-		entityFetchCount = 0;
-		
-		collectionRemoveCount = 0;
-		collectionUpdateCount = 0;
-		collectionRecreateCount = 0;
-		collectionLoadCount = 0;
-		collectionFetchCount = 0;
-		
-		queryExecutionCount = 0;
-		queryCacheHitCount = 0;
-		queryExecutionMaxTime = 0;
-		queryExecutionMaxTimeQueryString = null;
-		queryCacheMissCount = 0;
-		queryCachePutCount = 0;
-		
-		transactionCount = 0;
-		commitedTransactionCount = 0;
-		
-		optimisticFailureCount = 0;
-		
-		secondLevelCacheStatistics.clear();
-		entityStatistics.clear();
-		collectionStatistics.clear();
-		queryStatistics.clear();
-		
-		startTime = System.currentTimeMillis();
-	}
-	
-	public synchronized void openSession() {
-		sessionOpenCount++;
-	}
-	
-	public synchronized void closeSession() {
-		sessionCloseCount++;
-	}
-	
-	public synchronized void flush() {
-		flushCount++;
-	}
-	
-	public synchronized void connect() {
-		connectCount++;
-	}
-	
-	public synchronized void loadEntity(String entityName) {
-		entityLoadCount++;
-		getEntityStatistics(entityName).loadCount++;
-	}
-
-	public synchronized void fetchEntity(String entityName) {
-		entityFetchCount++;
-		getEntityStatistics(entityName).fetchCount++;
-	}
-
-	/**
-	 * find entity statistics per name
-	 * 
-	 * @param entityName entity name
-	 * @return EntityStatistics object
-	 */
-	public synchronized EntityStatistics getEntityStatistics(String entityName) {
-		EntityStatistics es = (EntityStatistics) entityStatistics.get(entityName);
-		if (es==null) {
-			es = new EntityStatistics(entityName);
-			entityStatistics.put(entityName, es);
-		}
-		return es;
-	}
-	
-	public synchronized void updateEntity(String entityName) {
-		entityUpdateCount++;
-		EntityStatistics es = getEntityStatistics(entityName);
-		es.updateCount++;
-	}
-
-	public synchronized void insertEntity(String entityName) {
-		entityInsertCount++;
-		EntityStatistics es = getEntityStatistics(entityName);
-		es.insertCount++;
-	}
-
-	public synchronized void deleteEntity(String entityName) {
-		entityDeleteCount++;
-		EntityStatistics es = getEntityStatistics(entityName);
-		es.deleteCount++;
-	}
-
-	/**
-	 * Get collection statistics per role
-	 * 
-	 * @param role collection role
-	 * @return CollectionStatistics
-	 */
-	public synchronized CollectionStatistics getCollectionStatistics(String role) {
-		CollectionStatistics cs = (CollectionStatistics) collectionStatistics.get(role);
-		if (cs==null) {
-			cs = new CollectionStatistics(role);
-			collectionStatistics.put(role, cs);
-		}
-		return cs;
-	}
-	
-	public synchronized void loadCollection(String role) {
-		collectionLoadCount++;
-		getCollectionStatistics(role).loadCount++;
-	}
-
-	public synchronized void fetchCollection(String role) {
-		collectionFetchCount++;
-		getCollectionStatistics(role).fetchCount++;
-	}
-
-	public synchronized void updateCollection(String role) {
-		collectionUpdateCount++;
-		getCollectionStatistics(role).updateCount++;
-	}
-
-	public synchronized void recreateCollection(String role) {
-		collectionRecreateCount++;
-		getCollectionStatistics(role).recreateCount++;
-	}
-
-	public synchronized void removeCollection(String role) {
-		collectionRemoveCount++;
-		getCollectionStatistics(role).removeCount++;
-	}
-	
-	/**
-	 * Second level cache statistics per region
-	 * 
-	 * @param regionName region name
-	 * @return SecondLevelCacheStatistics
-	 */
-	public synchronized SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName) {
-		SecondLevelCacheStatistics slcs = ( SecondLevelCacheStatistics ) secondLevelCacheStatistics.get( regionName );
-		if ( slcs == null ) {
-			if ( sessionFactory == null ) {
-				return null;
-			}
-			Region region = sessionFactory.getSecondLevelCacheRegion( regionName );
-			if ( region == null ) {
-				return null;
-			}
-			slcs = new SecondLevelCacheStatistics( region );
-			secondLevelCacheStatistics.put( regionName, slcs );
-		}
-		return slcs;
-	}
-
-	public synchronized void secondLevelCachePut(String regionName) {
-		secondLevelCachePutCount++;
-		getSecondLevelCacheStatistics(regionName).putCount++;
-	}
-
-	public synchronized void secondLevelCacheHit(String regionName) {
-		secondLevelCacheHitCount++;
-		getSecondLevelCacheStatistics(regionName).hitCount++;
-	}
-
-	public synchronized void secondLevelCacheMiss(String regionName) {
-		secondLevelCacheMissCount++;
-		getSecondLevelCacheStatistics(regionName).missCount++;
-	}
-
-	public synchronized void queryExecuted(String hql, int rows, long time) {
-		queryExecutionCount++;
-		if (queryExecutionMaxTime<time) {
-			queryExecutionMaxTime=time;
-			queryExecutionMaxTimeQueryString = hql;
-		}
-		if (hql!=null) {
-			QueryStatistics qs = getQueryStatistics(hql);
-			qs.executed(rows, time);
-		}
-	}
-	
-	public synchronized void queryCacheHit(String hql, String regionName) {
-		queryCacheHitCount++;
-		if (hql!=null) {
-			QueryStatistics qs = getQueryStatistics(hql);
-			qs.cacheHitCount++;
-		}
-		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
-		slcs.hitCount++;
-	}
-
-	public synchronized void queryCacheMiss(String hql, String regionName) {
-		queryCacheMissCount++;
-		if (hql!=null) {
-			QueryStatistics qs = getQueryStatistics(hql);
-			qs.cacheMissCount++;
-		}
-		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
-		slcs.missCount++;
-	}
-
-	public synchronized void queryCachePut(String hql, String regionName) {
-		queryCachePutCount++;
-		if (hql!=null) {
-			QueryStatistics qs = getQueryStatistics(hql);
-			qs.cachePutCount++;
-		}
-		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
-		slcs.putCount++;
-	}
-
-	/**
-	 * Query statistics from query string (HQL or SQL)
-	 * 
-	 * @param queryString query string
-	 * @return QueryStatistics
-	 */
-	public synchronized QueryStatistics getQueryStatistics(String queryString) {
-		QueryStatistics qs = (QueryStatistics) queryStatistics.get(queryString);
-		if (qs==null) {
-			qs = new QueryStatistics(queryString);
-			queryStatistics.put(queryString, qs);
-		}
-		return qs;
-	}
-
-	/**
-	 * @return entity deletion count
-	 */
-	public long getEntityDeleteCount() {
-		return entityDeleteCount;
-	}
-	
-	/**
-	 * @return entity insertion count
-	 */
-	public long getEntityInsertCount() {
-		return entityInsertCount;
-	}
-	
-	/**
-	 * @return entity load (from DB)
-	 */
-	public long getEntityLoadCount() {
-		return entityLoadCount;
-	}
-	
-	/**
-	 * @return entity fetch (from DB)
-	 */
-	public long getEntityFetchCount() {
-		return entityFetchCount;
-	}
-
-	/**
-	 * @return entity update
-	 */
-	public long getEntityUpdateCount() {
-		return entityUpdateCount;
-	}
-
-	public long getQueryExecutionCount() {
-		return queryExecutionCount;
-	}
-	
-	public long getQueryCacheHitCount() {
-		return queryCacheHitCount;
-	}
-	
-	public long getQueryCacheMissCount() {
-		return queryCacheMissCount;
-	}
-	
-	public long getQueryCachePutCount() {
-		return queryCachePutCount;
-	}
-	
-	/**
-	 * @return flush
-	 */
-	public long getFlushCount() {
-		return flushCount;
-	}
-	
-	/**
-	 * @return session connect
-	 */
-	public long getConnectCount() {
-		return connectCount;
-	}
-
-	/**
-	 * @return second level cache hit
-	 */
-	public long getSecondLevelCacheHitCount() {
-		return secondLevelCacheHitCount;
-	}
-
-	/**
-	 * @return second level cache miss
-	 */
-	public long getSecondLevelCacheMissCount() {
-		return secondLevelCacheMissCount;
-	}
-	
-	/**
-	 * @return second level cache put
-	 */
-	public long getSecondLevelCachePutCount() {
-		return secondLevelCachePutCount;
-	}
-
-	/**
-	 * @return session closing
-	 */
-	public long getSessionCloseCount() {
-		return sessionCloseCount;
-	}
-	
-	/**
-	 * @return session opening
-	 */
-	public long getSessionOpenCount() {
-		return sessionOpenCount;
-	}
-
-	/**
-	 * @return collection loading (from DB)
-	 */
-	public long getCollectionLoadCount() {
-		return collectionLoadCount;
-	}
-
-	/**
-	 * @return collection fetching (from DB)
-	 */
-	public long getCollectionFetchCount() {
-		return collectionFetchCount;
-	}
-	
-	/**
-	 * @return collection update
-	 */
-	public long getCollectionUpdateCount() {
-		return collectionUpdateCount;
-	}
-
-	/**
-	 * @return collection removal
-	 * FIXME: even if isInverse="true"?
-	 */
-	public long getCollectionRemoveCount() {
-		return collectionRemoveCount;
-	}
-	/**
-	 * @return collection recreation
-	 */
-	public long getCollectionRecreateCount() {
-		return collectionRecreateCount;
-	}
-
-	/**
-	 * @return start time in ms (JVM standards {@link System#currentTimeMillis()})
-	 */
-	public long getStartTime() {
-		return startTime;
-	}
-	
-	/**
-	 * log in info level the main statistics
-	 */
-	public void logSummary() {
-		log.info("Logging statistics....");
-		log.info("start time: " + startTime);
-		log.info("sessions opened: " + sessionOpenCount);
-		log.info("sessions closed: " + sessionCloseCount);
-		log.info("transactions: " + transactionCount);
-		log.info("successful transactions: " + commitedTransactionCount);
-		log.info("optimistic lock failures: " + optimisticFailureCount);
-		log.info("flushes: " + flushCount);
-		log.info("connections obtained: " + connectCount);
-		log.info("statements prepared: " + prepareStatementCount);
-		log.info("statements closed: " + closeStatementCount);
-		log.info("second level cache puts: " + secondLevelCachePutCount);
-		log.info("second level cache hits: " + secondLevelCacheHitCount);
-		log.info("second level cache misses: " + secondLevelCacheMissCount);
-		log.info("entities loaded: " + entityLoadCount);
-		log.info("entities updated: " + entityUpdateCount);
-		log.info("entities inserted: " + entityInsertCount);
-		log.info("entities deleted: " + entityDeleteCount);
-		log.info("entities fetched (minimize this): " + entityFetchCount);
-		log.info("collections loaded: " + collectionLoadCount);
-		log.info("collections updated: " + collectionUpdateCount);
-		log.info("collections removed: " + collectionRemoveCount);
-		log.info("collections recreated: " + collectionRecreateCount);
-		log.info("collections fetched (minimize this): " + collectionFetchCount);
-		log.info("queries executed to database: " + queryExecutionCount);
-		log.info("query cache puts: " + queryCachePutCount);
-		log.info("query cache hits: " + queryCacheHitCount);
-		log.info("query cache misses: " + queryCacheMissCount);
-		log.info("max query time: " + queryExecutionMaxTime + "ms");
-	}
-	
-	/**
-	 * Are statistics logged
-	 */
-	public boolean isStatisticsEnabled() {
-		return isStatisticsEnabled;
-	}
-	
-	/**
-	 * Enable statistics logs (this is a dynamic parameter)
-	 */
-	public void setStatisticsEnabled(boolean b) {
-		isStatisticsEnabled = b;
-	}
-
-	/**
-	 * @return Returns the max query execution time,
-	 * for all queries
-	 */
-	public long getQueryExecutionMaxTime() {
-		return queryExecutionMaxTime;
-	}
-	
-	/**
-	 * Get all executed query strings
-	 */
-	public String[] getQueries() {
-		return ArrayHelper.toStringArray( queryStatistics.keySet() );
-	}
-	
-	/**
-	 * Get the names of all entities
-	 */
-	public String[] getEntityNames() {
-		if (sessionFactory==null) {
-			return ArrayHelper.toStringArray( entityStatistics.keySet() );
-		}
-		else {
-			return ArrayHelper.toStringArray( sessionFactory.getAllClassMetadata().keySet() );
-		}
-	}
-
-	/**
-	 * Get the names of all collection roles
-	 */
-	public String[] getCollectionRoleNames() {
-		if (sessionFactory==null) {
-			return ArrayHelper.toStringArray( collectionStatistics.keySet() );
-		}
-		else {
-			return ArrayHelper.toStringArray( sessionFactory.getAllCollectionMetadata().keySet() );
-		}
-	}
-	
-	/**
-	 * Get all second-level cache region names
-	 */
-	public String[] getSecondLevelCacheRegionNames() {
-		if (sessionFactory==null) {
-			return ArrayHelper.toStringArray( secondLevelCacheStatistics.keySet() );
-		}
-		else {
-			return ArrayHelper.toStringArray( sessionFactory.getAllSecondLevelCacheRegions().keySet() );
-		}
-	}
-
-	public void endTransaction(boolean success) {
-		transactionCount++;
-		if (success) commitedTransactionCount++;
-	}
-	
-	public long getSuccessfulTransactionCount() {
-		return commitedTransactionCount;
-	}
-	
-	public long getTransactionCount() {
-		return transactionCount;
-	}
-
-	public void closeStatement() {
-		closeStatementCount++;
-	}
-
-	public void prepareStatement() {
-		prepareStatementCount++;
-	}
-
-	public long getCloseStatementCount() {
-		return closeStatementCount;
-	}
-
-	public long getPrepareStatementCount() {
-		return prepareStatementCount;
-	}
-
-	public void optimisticFailure(String entityName) {
-		optimisticFailureCount++;
-		getEntityStatistics(entityName).optimisticFailureCount++;
-	}
-
-	public long getOptimisticFailureCount() {
-		return optimisticFailureCount;
-	}
-	public String toString() {
-		return new StringBuffer()
-			.append("Statistics[")
-			.append("start time=").append(startTime)
-			.append(",sessions opened=").append(sessionOpenCount)
-			.append(",sessions closed=").append(sessionCloseCount)
-			.append(",transactions=").append(transactionCount)
-			.append(",successful transactions=").append(commitedTransactionCount)
-			.append(",optimistic lock failures=").append(optimisticFailureCount)
-			.append(",flushes=").append(flushCount)
-			.append(",connections obtained=").append(connectCount)
-			.append(",statements prepared=").append(prepareStatementCount)
-			.append(",statements closed=").append(closeStatementCount)
-			.append(",second level cache puts=").append(secondLevelCachePutCount)
-			.append(",second level cache hits=").append(secondLevelCacheHitCount)
-			.append(",second level cache misses=").append(secondLevelCacheMissCount)
-			.append(",entities loaded=").append(entityLoadCount)
-			.append(",entities updated=").append(entityUpdateCount)
-			.append(",entities inserted=").append(entityInsertCount)
-			.append(",entities deleted=").append(entityDeleteCount)
-			.append(",entities fetched=").append(entityFetchCount)
-			.append(",collections loaded=").append(collectionLoadCount)
-			.append(",collections updated=").append(collectionUpdateCount)
-			.append(",collections removed=").append(collectionRemoveCount)
-			.append(",collections recreated=").append(collectionRecreateCount)
-			.append(",collections fetched=").append(collectionFetchCount)
-			.append(",queries executed to database=").append(queryExecutionCount)
-			.append(",query cache puts=").append(queryCachePutCount)
-			.append(",query cache hits=").append(queryCacheHitCount)
-			.append(",query cache misses=").append(queryCacheMissCount)
-			.append(",max query time=").append(queryExecutionMaxTime)
-			.append(']')
-			.toString();
-	}
-
-	public String getQueryExecutionMaxTimeQueryString() {
-		return queryExecutionMaxTimeQueryString;
-	}
-	
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/StatisticsImpl.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImpl.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,662 @@
+/*
+ * 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.stat;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.cache.Region;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * @see org.hibernate.stat.Statistics 
+ *  
+ * @author Gavin King
+ */
+public class StatisticsImpl implements Statistics, StatisticsImplementor {
+	
+	//TODO: we should provide some way to get keys of collection of statistics to make it easier to retrieve from a GUI perspective
+	
+	private static final Logger log = LoggerFactory.getLogger(StatisticsImpl.class);
+
+	private SessionFactoryImplementor sessionFactory;
+
+	private boolean isStatisticsEnabled;
+	private long startTime;
+	private long sessionOpenCount;
+	private long sessionCloseCount;
+	private long flushCount;
+	private long connectCount;
+	
+	private long prepareStatementCount;
+	private long closeStatementCount;
+	
+	private long entityLoadCount;
+	private long entityUpdateCount;
+	private long entityInsertCount;
+	private long entityDeleteCount;
+	private long entityFetchCount;
+	private long collectionLoadCount;
+	private long collectionUpdateCount;
+	private long collectionRemoveCount;
+	private long collectionRecreateCount;
+	private long collectionFetchCount;
+	
+	private long secondLevelCacheHitCount;
+	private long secondLevelCacheMissCount;
+	private long secondLevelCachePutCount;
+	
+	private long queryExecutionCount;
+	private long queryExecutionMaxTime;
+	private String queryExecutionMaxTimeQueryString;
+	private long queryCacheHitCount;
+	private long queryCacheMissCount;
+	private long queryCachePutCount;
+	
+	private long commitedTransactionCount;
+	private long transactionCount;
+	
+	private long optimisticFailureCount;
+	
+	/** second level cache statistics per region */
+	private final Map secondLevelCacheStatistics = new HashMap();
+	/** entity statistics per name */
+	private final Map entityStatistics = new HashMap();
+	/** collection statistics per name */
+	private final Map collectionStatistics = new HashMap();
+	/** entity statistics per query string (HQL or SQL) */
+	private final Map queryStatistics = new HashMap();
+
+	public StatisticsImpl() {
+		clear();
+	}
+
+	public StatisticsImpl(SessionFactoryImplementor sessionFactory) {
+		clear();
+		this.sessionFactory = sessionFactory;
+	}
+	
+	/**
+	 * reset all statistics
+	 */
+	public synchronized void clear() {
+		secondLevelCacheHitCount = 0;
+		secondLevelCacheMissCount = 0;
+		secondLevelCachePutCount = 0;
+		
+		sessionCloseCount = 0;
+		sessionOpenCount = 0;
+		flushCount = 0;
+		connectCount = 0;
+		
+		prepareStatementCount = 0;
+		closeStatementCount = 0;
+		
+		entityDeleteCount = 0;
+		entityInsertCount = 0;
+		entityUpdateCount = 0;
+		entityLoadCount = 0;
+		entityFetchCount = 0;
+		
+		collectionRemoveCount = 0;
+		collectionUpdateCount = 0;
+		collectionRecreateCount = 0;
+		collectionLoadCount = 0;
+		collectionFetchCount = 0;
+		
+		queryExecutionCount = 0;
+		queryCacheHitCount = 0;
+		queryExecutionMaxTime = 0;
+		queryExecutionMaxTimeQueryString = null;
+		queryCacheMissCount = 0;
+		queryCachePutCount = 0;
+		
+		transactionCount = 0;
+		commitedTransactionCount = 0;
+		
+		optimisticFailureCount = 0;
+		
+		secondLevelCacheStatistics.clear();
+		entityStatistics.clear();
+		collectionStatistics.clear();
+		queryStatistics.clear();
+		
+		startTime = System.currentTimeMillis();
+	}
+	
+	public synchronized void openSession() {
+		sessionOpenCount++;
+	}
+	
+	public synchronized void closeSession() {
+		sessionCloseCount++;
+	}
+	
+	public synchronized void flush() {
+		flushCount++;
+	}
+	
+	public synchronized void connect() {
+		connectCount++;
+	}
+	
+	public synchronized void loadEntity(String entityName) {
+		entityLoadCount++;
+		getEntityStatistics(entityName).loadCount++;
+	}
+
+	public synchronized void fetchEntity(String entityName) {
+		entityFetchCount++;
+		getEntityStatistics(entityName).fetchCount++;
+	}
+
+	/**
+	 * find entity statistics per name
+	 * 
+	 * @param entityName entity name
+	 * @return EntityStatistics object
+	 */
+	public synchronized EntityStatistics getEntityStatistics(String entityName) {
+		EntityStatistics es = (EntityStatistics) entityStatistics.get(entityName);
+		if (es==null) {
+			es = new EntityStatistics(entityName);
+			entityStatistics.put(entityName, es);
+		}
+		return es;
+	}
+	
+	public synchronized void updateEntity(String entityName) {
+		entityUpdateCount++;
+		EntityStatistics es = getEntityStatistics(entityName);
+		es.updateCount++;
+	}
+
+	public synchronized void insertEntity(String entityName) {
+		entityInsertCount++;
+		EntityStatistics es = getEntityStatistics(entityName);
+		es.insertCount++;
+	}
+
+	public synchronized void deleteEntity(String entityName) {
+		entityDeleteCount++;
+		EntityStatistics es = getEntityStatistics(entityName);
+		es.deleteCount++;
+	}
+
+	/**
+	 * Get collection statistics per role
+	 * 
+	 * @param role collection role
+	 * @return CollectionStatistics
+	 */
+	public synchronized CollectionStatistics getCollectionStatistics(String role) {
+		CollectionStatistics cs = (CollectionStatistics) collectionStatistics.get(role);
+		if (cs==null) {
+			cs = new CollectionStatistics(role);
+			collectionStatistics.put(role, cs);
+		}
+		return cs;
+	}
+	
+	public synchronized void loadCollection(String role) {
+		collectionLoadCount++;
+		getCollectionStatistics(role).loadCount++;
+	}
+
+	public synchronized void fetchCollection(String role) {
+		collectionFetchCount++;
+		getCollectionStatistics(role).fetchCount++;
+	}
+
+	public synchronized void updateCollection(String role) {
+		collectionUpdateCount++;
+		getCollectionStatistics(role).updateCount++;
+	}
+
+	public synchronized void recreateCollection(String role) {
+		collectionRecreateCount++;
+		getCollectionStatistics(role).recreateCount++;
+	}
+
+	public synchronized void removeCollection(String role) {
+		collectionRemoveCount++;
+		getCollectionStatistics(role).removeCount++;
+	}
+	
+	/**
+	 * Second level cache statistics per region
+	 * 
+	 * @param regionName region name
+	 * @return SecondLevelCacheStatistics
+	 */
+	public synchronized SecondLevelCacheStatistics getSecondLevelCacheStatistics(String regionName) {
+		SecondLevelCacheStatistics slcs = ( SecondLevelCacheStatistics ) secondLevelCacheStatistics.get( regionName );
+		if ( slcs == null ) {
+			if ( sessionFactory == null ) {
+				return null;
+			}
+			Region region = sessionFactory.getSecondLevelCacheRegion( regionName );
+			if ( region == null ) {
+				return null;
+			}
+			slcs = new SecondLevelCacheStatistics( region );
+			secondLevelCacheStatistics.put( regionName, slcs );
+		}
+		return slcs;
+	}
+
+	public synchronized void secondLevelCachePut(String regionName) {
+		secondLevelCachePutCount++;
+		getSecondLevelCacheStatistics(regionName).putCount++;
+	}
+
+	public synchronized void secondLevelCacheHit(String regionName) {
+		secondLevelCacheHitCount++;
+		getSecondLevelCacheStatistics(regionName).hitCount++;
+	}
+
+	public synchronized void secondLevelCacheMiss(String regionName) {
+		secondLevelCacheMissCount++;
+		getSecondLevelCacheStatistics(regionName).missCount++;
+	}
+
+	public synchronized void queryExecuted(String hql, int rows, long time) {
+		queryExecutionCount++;
+		if (queryExecutionMaxTime<time) {
+			queryExecutionMaxTime=time;
+			queryExecutionMaxTimeQueryString = hql;
+		}
+		if (hql!=null) {
+			QueryStatistics qs = getQueryStatistics(hql);
+			qs.executed(rows, time);
+		}
+	}
+	
+	public synchronized void queryCacheHit(String hql, String regionName) {
+		queryCacheHitCount++;
+		if (hql!=null) {
+			QueryStatistics qs = getQueryStatistics(hql);
+			qs.cacheHitCount++;
+		}
+		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
+		slcs.hitCount++;
+	}
+
+	public synchronized void queryCacheMiss(String hql, String regionName) {
+		queryCacheMissCount++;
+		if (hql!=null) {
+			QueryStatistics qs = getQueryStatistics(hql);
+			qs.cacheMissCount++;
+		}
+		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
+		slcs.missCount++;
+	}
+
+	public synchronized void queryCachePut(String hql, String regionName) {
+		queryCachePutCount++;
+		if (hql!=null) {
+			QueryStatistics qs = getQueryStatistics(hql);
+			qs.cachePutCount++;
+		}
+		SecondLevelCacheStatistics slcs = getSecondLevelCacheStatistics(regionName);
+		slcs.putCount++;
+	}
+
+	/**
+	 * Query statistics from query string (HQL or SQL)
+	 * 
+	 * @param queryString query string
+	 * @return QueryStatistics
+	 */
+	public synchronized QueryStatistics getQueryStatistics(String queryString) {
+		QueryStatistics qs = (QueryStatistics) queryStatistics.get(queryString);
+		if (qs==null) {
+			qs = new QueryStatistics(queryString);
+			queryStatistics.put(queryString, qs);
+		}
+		return qs;
+	}
+
+	/**
+	 * @return entity deletion count
+	 */
+	public long getEntityDeleteCount() {
+		return entityDeleteCount;
+	}
+	
+	/**
+	 * @return entity insertion count
+	 */
+	public long getEntityInsertCount() {
+		return entityInsertCount;
+	}
+	
+	/**
+	 * @return entity load (from DB)
+	 */
+	public long getEntityLoadCount() {
+		return entityLoadCount;
+	}
+	
+	/**
+	 * @return entity fetch (from DB)
+	 */
+	public long getEntityFetchCount() {
+		return entityFetchCount;
+	}
+
+	/**
+	 * @return entity update
+	 */
+	public long getEntityUpdateCount() {
+		return entityUpdateCount;
+	}
+
+	public long getQueryExecutionCount() {
+		return queryExecutionCount;
+	}
+	
+	public long getQueryCacheHitCount() {
+		return queryCacheHitCount;
+	}
+	
+	public long getQueryCacheMissCount() {
+		return queryCacheMissCount;
+	}
+	
+	public long getQueryCachePutCount() {
+		return queryCachePutCount;
+	}
+	
+	/**
+	 * @return flush
+	 */
+	public long getFlushCount() {
+		return flushCount;
+	}
+	
+	/**
+	 * @return session connect
+	 */
+	public long getConnectCount() {
+		return connectCount;
+	}
+
+	/**
+	 * @return second level cache hit
+	 */
+	public long getSecondLevelCacheHitCount() {
+		return secondLevelCacheHitCount;
+	}
+
+	/**
+	 * @return second level cache miss
+	 */
+	public long getSecondLevelCacheMissCount() {
+		return secondLevelCacheMissCount;
+	}
+	
+	/**
+	 * @return second level cache put
+	 */
+	public long getSecondLevelCachePutCount() {
+		return secondLevelCachePutCount;
+	}
+
+	/**
+	 * @return session closing
+	 */
+	public long getSessionCloseCount() {
+		return sessionCloseCount;
+	}
+	
+	/**
+	 * @return session opening
+	 */
+	public long getSessionOpenCount() {
+		return sessionOpenCount;
+	}
+
+	/**
+	 * @return collection loading (from DB)
+	 */
+	public long getCollectionLoadCount() {
+		return collectionLoadCount;
+	}
+
+	/**
+	 * @return collection fetching (from DB)
+	 */
+	public long getCollectionFetchCount() {
+		return collectionFetchCount;
+	}
+	
+	/**
+	 * @return collection update
+	 */
+	public long getCollectionUpdateCount() {
+		return collectionUpdateCount;
+	}
+
+	/**
+	 * @return collection removal
+	 * FIXME: even if isInverse="true"?
+	 */
+	public long getCollectionRemoveCount() {
+		return collectionRemoveCount;
+	}
+	/**
+	 * @return collection recreation
+	 */
+	public long getCollectionRecreateCount() {
+		return collectionRecreateCount;
+	}
+
+	/**
+	 * @return start time in ms (JVM standards {@link System#currentTimeMillis()})
+	 */
+	public long getStartTime() {
+		return startTime;
+	}
+	
+	/**
+	 * log in info level the main statistics
+	 */
+	public void logSummary() {
+		log.info("Logging statistics....");
+		log.info("start time: " + startTime);
+		log.info("sessions opened: " + sessionOpenCount);
+		log.info("sessions closed: " + sessionCloseCount);
+		log.info("transactions: " + transactionCount);
+		log.info("successful transactions: " + commitedTransactionCount);
+		log.info("optimistic lock failures: " + optimisticFailureCount);
+		log.info("flushes: " + flushCount);
+		log.info("connections obtained: " + connectCount);
+		log.info("statements prepared: " + prepareStatementCount);
+		log.info("statements closed: " + closeStatementCount);
+		log.info("second level cache puts: " + secondLevelCachePutCount);
+		log.info("second level cache hits: " + secondLevelCacheHitCount);
+		log.info("second level cache misses: " + secondLevelCacheMissCount);
+		log.info("entities loaded: " + entityLoadCount);
+		log.info("entities updated: " + entityUpdateCount);
+		log.info("entities inserted: " + entityInsertCount);
+		log.info("entities deleted: " + entityDeleteCount);
+		log.info("entities fetched (minimize this): " + entityFetchCount);
+		log.info("collections loaded: " + collectionLoadCount);
+		log.info("collections updated: " + collectionUpdateCount);
+		log.info("collections removed: " + collectionRemoveCount);
+		log.info("collections recreated: " + collectionRecreateCount);
+		log.info("collections fetched (minimize this): " + collectionFetchCount);
+		log.info("queries executed to database: " + queryExecutionCount);
+		log.info("query cache puts: " + queryCachePutCount);
+		log.info("query cache hits: " + queryCacheHitCount);
+		log.info("query cache misses: " + queryCacheMissCount);
+		log.info("max query time: " + queryExecutionMaxTime + "ms");
+	}
+	
+	/**
+	 * Are statistics logged
+	 */
+	public boolean isStatisticsEnabled() {
+		return isStatisticsEnabled;
+	}
+	
+	/**
+	 * Enable statistics logs (this is a dynamic parameter)
+	 */
+	public void setStatisticsEnabled(boolean b) {
+		isStatisticsEnabled = b;
+	}
+
+	/**
+	 * @return Returns the max query execution time,
+	 * for all queries
+	 */
+	public long getQueryExecutionMaxTime() {
+		return queryExecutionMaxTime;
+	}
+	
+	/**
+	 * Get all executed query strings
+	 */
+	public String[] getQueries() {
+		return ArrayHelper.toStringArray( queryStatistics.keySet() );
+	}
+	
+	/**
+	 * Get the names of all entities
+	 */
+	public String[] getEntityNames() {
+		if (sessionFactory==null) {
+			return ArrayHelper.toStringArray( entityStatistics.keySet() );
+		}
+		else {
+			return ArrayHelper.toStringArray( sessionFactory.getAllClassMetadata().keySet() );
+		}
+	}
+
+	/**
+	 * Get the names of all collection roles
+	 */
+	public String[] getCollectionRoleNames() {
+		if (sessionFactory==null) {
+			return ArrayHelper.toStringArray( collectionStatistics.keySet() );
+		}
+		else {
+			return ArrayHelper.toStringArray( sessionFactory.getAllCollectionMetadata().keySet() );
+		}
+	}
+	
+	/**
+	 * Get all second-level cache region names
+	 */
+	public String[] getSecondLevelCacheRegionNames() {
+		if (sessionFactory==null) {
+			return ArrayHelper.toStringArray( secondLevelCacheStatistics.keySet() );
+		}
+		else {
+			return ArrayHelper.toStringArray( sessionFactory.getAllSecondLevelCacheRegions().keySet() );
+		}
+	}
+
+	public void endTransaction(boolean success) {
+		transactionCount++;
+		if (success) commitedTransactionCount++;
+	}
+	
+	public long getSuccessfulTransactionCount() {
+		return commitedTransactionCount;
+	}
+	
+	public long getTransactionCount() {
+		return transactionCount;
+	}
+
+	public void closeStatement() {
+		closeStatementCount++;
+	}
+
+	public void prepareStatement() {
+		prepareStatementCount++;
+	}
+
+	public long getCloseStatementCount() {
+		return closeStatementCount;
+	}
+
+	public long getPrepareStatementCount() {
+		return prepareStatementCount;
+	}
+
+	public void optimisticFailure(String entityName) {
+		optimisticFailureCount++;
+		getEntityStatistics(entityName).optimisticFailureCount++;
+	}
+
+	public long getOptimisticFailureCount() {
+		return optimisticFailureCount;
+	}
+	public String toString() {
+		return new StringBuffer()
+			.append("Statistics[")
+			.append("start time=").append(startTime)
+			.append(",sessions opened=").append(sessionOpenCount)
+			.append(",sessions closed=").append(sessionCloseCount)
+			.append(",transactions=").append(transactionCount)
+			.append(",successful transactions=").append(commitedTransactionCount)
+			.append(",optimistic lock failures=").append(optimisticFailureCount)
+			.append(",flushes=").append(flushCount)
+			.append(",connections obtained=").append(connectCount)
+			.append(",statements prepared=").append(prepareStatementCount)
+			.append(",statements closed=").append(closeStatementCount)
+			.append(",second level cache puts=").append(secondLevelCachePutCount)
+			.append(",second level cache hits=").append(secondLevelCacheHitCount)
+			.append(",second level cache misses=").append(secondLevelCacheMissCount)
+			.append(",entities loaded=").append(entityLoadCount)
+			.append(",entities updated=").append(entityUpdateCount)
+			.append(",entities inserted=").append(entityInsertCount)
+			.append(",entities deleted=").append(entityDeleteCount)
+			.append(",entities fetched=").append(entityFetchCount)
+			.append(",collections loaded=").append(collectionLoadCount)
+			.append(",collections updated=").append(collectionUpdateCount)
+			.append(",collections removed=").append(collectionRemoveCount)
+			.append(",collections recreated=").append(collectionRecreateCount)
+			.append(",collections fetched=").append(collectionFetchCount)
+			.append(",queries executed to database=").append(queryExecutionCount)
+			.append(",query cache puts=").append(queryCachePutCount)
+			.append(",query cache hits=").append(queryCacheHitCount)
+			.append(",query cache misses=").append(queryCacheMissCount)
+			.append(",max query time=").append(queryExecutionMaxTime)
+			.append(']')
+			.toString();
+	}
+
+	public String getQueryExecutionMaxTimeQueryString() {
+		return queryExecutionMaxTimeQueryString;
+	}
+	
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: StatisticsImplementor.java 7864 2005-08-11 23:22:52Z oneovthafew $
-package org.hibernate.stat;
-
-/**
- * Statistics SPI for the Hibernate core
- * 
- * @author Emmanuel Bernard
- */
-public interface StatisticsImplementor {
-	public void openSession();
-	public void closeSession();
-	public void flush();
-	public void connect();
-	public void loadEntity(String entityName);
-	public void fetchEntity(String entityName);
-	public void updateEntity(String entityName);
-	public void insertEntity(String entityName);
-	public void deleteEntity(String entityName);
-	public void loadCollection(String role);
-	public void fetchCollection(String role);
-	public void updateCollection(String role);
-	public void recreateCollection(String role);
-	public void removeCollection(String role);
-	public void secondLevelCachePut(String regionName);
-	public void secondLevelCacheHit(String regionName);
-	public void secondLevelCacheMiss(String regionName);
-	public void queryExecuted(String hql, int rows, long time);
-	public void queryCacheHit(String hql, String regionName);
-	public void queryCacheMiss(String hql, String regionName);
-	public void queryCachePut(String hql, String regionName);
-	public void endTransaction(boolean success);
-	public void closeStatement();
-	public void prepareStatement();
-	public void optimisticFailure(String entityName);
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/StatisticsImplementor.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.stat;
+
+/**
+ * Statistics SPI for the Hibernate core
+ * 
+ * @author Emmanuel Bernard
+ */
+public interface StatisticsImplementor {
+	public void openSession();
+	public void closeSession();
+	public void flush();
+	public void connect();
+	public void loadEntity(String entityName);
+	public void fetchEntity(String entityName);
+	public void updateEntity(String entityName);
+	public void insertEntity(String entityName);
+	public void deleteEntity(String entityName);
+	public void loadCollection(String role);
+	public void fetchCollection(String role);
+	public void updateCollection(String role);
+	public void recreateCollection(String role);
+	public void removeCollection(String role);
+	public void secondLevelCachePut(String regionName);
+	public void secondLevelCacheHit(String regionName);
+	public void secondLevelCacheMiss(String regionName);
+	public void queryExecuted(String hql, int rows, long time);
+	public void queryCacheHit(String hql, String regionName);
+	public void queryCacheMiss(String hql, String regionName);
+	public void queryCachePut(String hql, String regionName);
+	public void endTransaction(boolean success);
+	public void closeStatement();
+	public void prepareStatement();
+	public void optimisticFailure(String entityName);
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/stat/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package exposes statistics about a running 
-	Hibernate instance to the application.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/stat/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/stat/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package exposes statistics about a running 
+	Hibernate instance to the application.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,63 +0,0 @@
-//$Id: ColumnMetadata.java 7854 2005-08-11 20:41:21Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.StringTokenizer;
-
-/**
- * JDBC column metadata
- * @author Christoph Sturm
- */
-public class ColumnMetadata {
-	private final String name;
-	private final String typeName;
-	private final int columnSize;
-	private final int decimalDigits;
-	private final String isNullable;
-	private final int typeCode;
-
-	ColumnMetadata(ResultSet rs) throws SQLException {
-		name = rs.getString("COLUMN_NAME");
-		columnSize = rs.getInt("COLUMN_SIZE");
-		decimalDigits = rs.getInt("DECIMAL_DIGITS");
-		isNullable = rs.getString("IS_NULLABLE");
-		typeCode = rs.getInt("DATA_TYPE");
-		typeName = new StringTokenizer( rs.getString("TYPE_NAME"), "() " ).nextToken();
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String getTypeName() {
-		return typeName;
-	}
-
-	public int getColumnSize() {
-		return columnSize;
-	}
-
-	public int getDecimalDigits() {
-		return decimalDigits;
-	}
-
-	public String getNullable() {
-		return isNullable;
-	}
-
-	public String toString() {
-		return "ColumnMetadata(" + name + ')';
-	}
-
-	public int getTypeCode() {
-		return typeCode;
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ColumnMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tool.hbm2ddl;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.StringTokenizer;
+
+/**
+ * JDBC column metadata
+ * @author Christoph Sturm
+ */
+public class ColumnMetadata {
+	private final String name;
+	private final String typeName;
+	private final int columnSize;
+	private final int decimalDigits;
+	private final String isNullable;
+	private final int typeCode;
+
+	ColumnMetadata(ResultSet rs) throws SQLException {
+		name = rs.getString("COLUMN_NAME");
+		columnSize = rs.getInt("COLUMN_SIZE");
+		decimalDigits = rs.getInt("DECIMAL_DIGITS");
+		isNullable = rs.getString("IS_NULLABLE");
+		typeCode = rs.getInt("DATA_TYPE");
+		typeName = new StringTokenizer( rs.getString("TYPE_NAME"), "() " ).nextToken();
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getTypeName() {
+		return typeName;
+	}
+
+	public int getColumnSize() {
+		return columnSize;
+	}
+
+	public int getDecimalDigits() {
+		return decimalDigits;
+	}
+
+	public String getNullable() {
+		return isNullable;
+	}
+
+	public String toString() {
+		return "ColumnMetadata(" + name + ')';
+	}
+
+	public int getTypeCode() {
+		return typeCode;
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * Contract for delegates responsible for managing connection used by the
- * hbm2ddl tools.
- *
- * @author Steve Ebersole
- */
-interface ConnectionHelper {
-	/**
-	 * Prepare the helper for use.
-	 *
-	 * @param needsAutoCommit Should connection be forced to auto-commit
-	 * if not already.
-	 * @throws SQLException
-	 */
-	public void prepare(boolean needsAutoCommit) throws SQLException;
-
-	/**
-	 * Get a reference to the connection we are using.
-	 *
-	 * @return The JDBC connection.
-	 * @throws SQLException
-	 */
-	public Connection getConnection() throws SQLException;
-
-	/**
-	 * Release any resources held by this helper.
-	 *
-	 * @throws SQLException
-	 */
-	public void release() throws SQLException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * Contract for delegates responsible for managing connection used by the
+ * hbm2ddl tools.
+ *
+ * @author Steve Ebersole
+ */
+interface ConnectionHelper {
+	/**
+	 * Prepare the helper for use.
+	 *
+	 * @param needsAutoCommit Should connection be forced to auto-commit
+	 * if not already.
+	 * @throws SQLException
+	 */
+	public void prepare(boolean needsAutoCommit) throws SQLException;
+
+	/**
+	 * Get a reference to the connection we are using.
+	 *
+	 * @return The JDBC connection.
+	 * @throws SQLException
+	 */
+	public Connection getConnection() throws SQLException;
+
+	/**
+	 * Release any resources held by this helper.
+	 *
+	 * @throws SQLException
+	 */
+	public void release() throws SQLException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,181 +0,0 @@
-//$Id: DatabaseMetadata.java 10726 2006-11-06 14:50:05Z max.andersen at jboss.com $
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.Connection;
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.exception.JDBCExceptionHelper;
-import org.hibernate.exception.SQLExceptionConverter;
-import org.hibernate.mapping.Table;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.StringHelper;
-
-/**
- * JDBC database metadata
- * @author Christoph Sturm, Teodor Danciu
- */
-public class DatabaseMetadata {
-	
-	private static final Logger log = LoggerFactory.getLogger(DatabaseMetadata.class);
-	
-	private final Map tables = new HashMap();
-	private final Set sequences = new HashSet();
-	private final boolean extras;
-
-	private DatabaseMetaData meta;
-	private SQLExceptionConverter sqlExceptionConverter;
-
-	public DatabaseMetadata(Connection connection, Dialect dialect) throws SQLException {
-		this(connection, dialect, true);
-	}
-
-	public DatabaseMetadata(Connection connection, Dialect dialect, boolean extras) throws SQLException {
-		sqlExceptionConverter = dialect.buildSQLExceptionConverter();
-		meta = connection.getMetaData();
-		this.extras = extras;
-		initSequences(connection, dialect);
-	}
-
-	private static final String[] TYPES = {"TABLE", "VIEW"};
-
-	public TableMetadata getTableMetadata(String name, String schema, String catalog, boolean isQuoted) throws HibernateException {
-
-		Object identifier = identifier(catalog, schema, name);
-		TableMetadata table = (TableMetadata) tables.get(identifier);
-		if (table!=null) {
-			return table;
-		}
-		else {
-			
-			try {
-				ResultSet rs = null;
-				try {
-					if ( (isQuoted && meta.storesMixedCaseQuotedIdentifiers())) {
-						rs = meta.getTables(catalog, schema, name, TYPES);
-					} else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers()) 
-						|| (!isQuoted && meta.storesUpperCaseIdentifiers() )) {
-						rs = meta.getTables( 
-								StringHelper.toUpperCase(catalog), 
-								StringHelper.toUpperCase(schema), 
-								StringHelper.toUpperCase(name), 
-								TYPES 
-							);
-					}
-					else if ( (isQuoted && meta.storesLowerCaseQuotedIdentifiers())
-							|| (!isQuoted && meta.storesLowerCaseIdentifiers() )) {
-						rs = meta.getTables( 
-								StringHelper.toLowerCase(catalog), 
-								StringHelper.toLowerCase(schema), 
-								StringHelper.toLowerCase(name), 
-								TYPES 
-							);
-					}
-					else {
-						rs = meta.getTables(catalog, schema, name, TYPES);
-					}
-					
-					while ( rs.next() ) {
-						String tableName = rs.getString("TABLE_NAME");
-						if ( name.equalsIgnoreCase(tableName) ) {
-							table = new TableMetadata(rs, meta, extras);
-							tables.put(identifier, table);
-							return table;
-						}
-					}
-					
-					log.info("table not found: " + name);
-					return null;
-
-				}
-				finally {
-					if (rs!=null) rs.close();
-				}
-			}
-			catch (SQLException sqle) {
-				throw JDBCExceptionHelper.convert(
-                        sqlExceptionConverter,
-				        sqle,
-				        "could not get table metadata: " + name
-					);
-			}
-		}
-
-	}
-
-	private Object identifier(String catalog, String schema, String name) {
-		return Table.qualify(catalog,schema,name);
-	}
-
-	private void initSequences(Connection connection, Dialect dialect) throws SQLException {
-		if ( dialect.supportsSequences() ) {
-			String sql = dialect.getQuerySequencesString();
-			if (sql!=null) {
-	
-				Statement statement = null;
-				ResultSet rs = null;
-				try {
-					statement = connection.createStatement();
-					rs = statement.executeQuery(sql);
-		
-					while ( rs.next() ) {
-						sequences.add( rs.getString(1).toLowerCase().trim() );
-					}
-				}
-				finally {
-					if (rs!=null) rs.close();
-					if (statement!=null) statement.close();
-				}
-				
-			}
-		}
-	}
-
-	public boolean isSequence(Object key) {
-		if (key instanceof String){
-			String[] strings = StringHelper.split(".", (String) key);
-			return sequences.contains( strings[strings.length-1].toLowerCase());
-		}
-		return false;
-	}
-
- 	public boolean isTable(Object key) throws HibernateException {
- 		if(key instanceof String) {
-			Table tbl = new Table((String)key);
-			if ( getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null ) {
- 				return true;
- 			} else {
- 				String[] strings = StringHelper.split(".", (String) key);
- 				if(strings.length==3) {
-					tbl = new Table(strings[2]);
-					tbl.setCatalog(strings[0]);
-					tbl.setSchema(strings[1]);
-					return getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null;
- 				} else if (strings.length==2) {
-					tbl = new Table(strings[1]);
-					tbl.setSchema(strings[0]);
-					return getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null;
- 				}
- 			}
- 		}
- 		return false;
- 	}
- 	
-	public String toString() {
-		return "DatabaseMetadata" + tables.keySet().toString() + sequences.toString();
-	}
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/DatabaseMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,204 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.exception.JDBCExceptionHelper;
+import org.hibernate.exception.SQLExceptionConverter;
+import org.hibernate.mapping.Table;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.StringHelper;
+
+/**
+ * JDBC database metadata
+ * @author Christoph Sturm, Teodor Danciu
+ */
+public class DatabaseMetadata {
+	
+	private static final Logger log = LoggerFactory.getLogger(DatabaseMetadata.class);
+	
+	private final Map tables = new HashMap();
+	private final Set sequences = new HashSet();
+	private final boolean extras;
+
+	private DatabaseMetaData meta;
+	private SQLExceptionConverter sqlExceptionConverter;
+
+	public DatabaseMetadata(Connection connection, Dialect dialect) throws SQLException {
+		this(connection, dialect, true);
+	}
+
+	public DatabaseMetadata(Connection connection, Dialect dialect, boolean extras) throws SQLException {
+		sqlExceptionConverter = dialect.buildSQLExceptionConverter();
+		meta = connection.getMetaData();
+		this.extras = extras;
+		initSequences(connection, dialect);
+	}
+
+	private static final String[] TYPES = {"TABLE", "VIEW"};
+
+	public TableMetadata getTableMetadata(String name, String schema, String catalog, boolean isQuoted) throws HibernateException {
+
+		Object identifier = identifier(catalog, schema, name);
+		TableMetadata table = (TableMetadata) tables.get(identifier);
+		if (table!=null) {
+			return table;
+		}
+		else {
+			
+			try {
+				ResultSet rs = null;
+				try {
+					if ( (isQuoted && meta.storesMixedCaseQuotedIdentifiers())) {
+						rs = meta.getTables(catalog, schema, name, TYPES);
+					} else if ( (isQuoted && meta.storesUpperCaseQuotedIdentifiers()) 
+						|| (!isQuoted && meta.storesUpperCaseIdentifiers() )) {
+						rs = meta.getTables( 
+								StringHelper.toUpperCase(catalog), 
+								StringHelper.toUpperCase(schema), 
+								StringHelper.toUpperCase(name), 
+								TYPES 
+							);
+					}
+					else if ( (isQuoted && meta.storesLowerCaseQuotedIdentifiers())
+							|| (!isQuoted && meta.storesLowerCaseIdentifiers() )) {
+						rs = meta.getTables( 
+								StringHelper.toLowerCase(catalog), 
+								StringHelper.toLowerCase(schema), 
+								StringHelper.toLowerCase(name), 
+								TYPES 
+							);
+					}
+					else {
+						rs = meta.getTables(catalog, schema, name, TYPES);
+					}
+					
+					while ( rs.next() ) {
+						String tableName = rs.getString("TABLE_NAME");
+						if ( name.equalsIgnoreCase(tableName) ) {
+							table = new TableMetadata(rs, meta, extras);
+							tables.put(identifier, table);
+							return table;
+						}
+					}
+					
+					log.info("table not found: " + name);
+					return null;
+
+				}
+				finally {
+					if (rs!=null) rs.close();
+				}
+			}
+			catch (SQLException sqle) {
+				throw JDBCExceptionHelper.convert(
+                        sqlExceptionConverter,
+				        sqle,
+				        "could not get table metadata: " + name
+					);
+			}
+		}
+
+	}
+
+	private Object identifier(String catalog, String schema, String name) {
+		return Table.qualify(catalog,schema,name);
+	}
+
+	private void initSequences(Connection connection, Dialect dialect) throws SQLException {
+		if ( dialect.supportsSequences() ) {
+			String sql = dialect.getQuerySequencesString();
+			if (sql!=null) {
+	
+				Statement statement = null;
+				ResultSet rs = null;
+				try {
+					statement = connection.createStatement();
+					rs = statement.executeQuery(sql);
+		
+					while ( rs.next() ) {
+						sequences.add( rs.getString(1).toLowerCase().trim() );
+					}
+				}
+				finally {
+					if (rs!=null) rs.close();
+					if (statement!=null) statement.close();
+				}
+				
+			}
+		}
+	}
+
+	public boolean isSequence(Object key) {
+		if (key instanceof String){
+			String[] strings = StringHelper.split(".", (String) key);
+			return sequences.contains( strings[strings.length-1].toLowerCase());
+		}
+		return false;
+	}
+
+ 	public boolean isTable(Object key) throws HibernateException {
+ 		if(key instanceof String) {
+			Table tbl = new Table((String)key);
+			if ( getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null ) {
+ 				return true;
+ 			} else {
+ 				String[] strings = StringHelper.split(".", (String) key);
+ 				if(strings.length==3) {
+					tbl = new Table(strings[2]);
+					tbl.setCatalog(strings[0]);
+					tbl.setSchema(strings[1]);
+					return getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null;
+ 				} else if (strings.length==2) {
+					tbl = new Table(strings[1]);
+					tbl.setSchema(strings[0]);
+					return getTableMetadata( tbl.getName(), tbl.getSchema(), tbl.getCatalog(), tbl.isQuoted() ) != null;
+ 				}
+ 			}
+ 		}
+ 		return false;
+ 	}
+ 	
+	public String toString() {
+		return "DatabaseMetadata" + tables.keySet().toString() + sequences.toString();
+	}
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: ForeignKeyMetadata.java 4279 2004-08-13 08:05:47Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * JDBC foreign key metadata
- * @author Christoph Sturm
- */
-public class ForeignKeyMetadata {
-	private final String name;
-	private final List columns = new ArrayList();
-
-	ForeignKeyMetadata(ResultSet rs) throws SQLException {
-		name = rs.getString("FK_NAME");
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	void addColumn(ColumnMetadata column) {
-		if (column != null) columns.add(column);
-	}
-
-	public ColumnMetadata[] getColumns() {
-		return (ColumnMetadata[]) columns.toArray(new ColumnMetadata[0]);
-	}
-
-	public String toString() {
-		return "ForeignKeyMetadata(" + name + ')';
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ForeignKeyMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tool.hbm2ddl;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * JDBC foreign key metadata
+ * @author Christoph Sturm
+ */
+public class ForeignKeyMetadata {
+	private final String name;
+	private final List columns = new ArrayList();
+
+	ForeignKeyMetadata(ResultSet rs) throws SQLException {
+		name = rs.getString("FK_NAME");
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	void addColumn(ColumnMetadata column) {
+		if (column != null) columns.add(column);
+	}
+
+	public ColumnMetadata[] getColumns() {
+		return (ColumnMetadata[]) columns.toArray(new ColumnMetadata[0]);
+	}
+
+	public String toString() {
+		return "ForeignKeyMetadata(" + name + ')';
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,42 +0,0 @@
-//$Id: IndexMetadata.java 4279 2004-08-13 08:05:47Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * JDBC index metadata
- * @author Christoph Sturm
- */
-public class IndexMetadata {
-	private final String name;
-	private final List columns = new ArrayList();
-
-	IndexMetadata(ResultSet rs) throws SQLException {
-		name = rs.getString("INDEX_NAME");
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	void addColumn(ColumnMetadata column) {
-		if (column != null) columns.add(column);
-	}
-
-	public ColumnMetadata[] getColumns() {
-		return (ColumnMetadata[]) columns.toArray(new ColumnMetadata[0]);
-	}
-
-	public String toString() {
-		return "IndexMatadata(" + name + ')';
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/IndexMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tool.hbm2ddl;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * JDBC index metadata
+ * @author Christoph Sturm
+ */
+public class IndexMetadata {
+	private final String name;
+	private final List columns = new ArrayList();
+
+	IndexMetadata(ResultSet rs) throws SQLException {
+		name = rs.getString("INDEX_NAME");
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	void addColumn(ColumnMetadata column) {
+		if (column != null) columns.add(column);
+	}
+
+	public ColumnMetadata[] getColumns() {
+		return (ColumnMetadata[]) columns.toArray(new ColumnMetadata[0]);
+	}
+
+	public String toString() {
+		return "IndexMatadata(" + name + ')';
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.connection.ConnectionProviderFactory;
-import org.hibernate.util.JDBCExceptionReporter;
-
-import java.util.Properties;
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * A {@link ConnectionHelper} implementation based on an internally
- * built and managed {@link ConnectionProvider}.
- *
- * @author Steve Ebersole
- */
-class ManagedProviderConnectionHelper implements ConnectionHelper {
-	private Properties cfgProperties;
-	private ConnectionProvider connectionProvider;
-	private Connection connection;
-
-	public ManagedProviderConnectionHelper(Properties cfgProperties) {
-		this.cfgProperties = cfgProperties;
-	}
-
-	public void prepare(boolean needsAutoCommit) throws SQLException {
-		connectionProvider = ConnectionProviderFactory.newConnectionProvider( cfgProperties );
-		connection = connectionProvider.getConnection();
-		if ( needsAutoCommit && !connection.getAutoCommit() ) {
-			connection.commit();
-			connection.setAutoCommit( true );
-		}
-	}
-
-	public Connection getConnection() throws SQLException {
-		return connection;
-	}
-
-	public void release() throws SQLException {
-		if ( connection != null ) {
-			try {
-				JDBCExceptionReporter.logAndClearWarnings( connection );
-				connectionProvider.closeConnection( connection );
-			}
-			finally {
-				connectionProvider.close();
-			}
-		}
-		connection = null;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/ManagedProviderConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.connection.ConnectionProviderFactory;
+import org.hibernate.util.JDBCExceptionReporter;
+
+import java.util.Properties;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * A {@link ConnectionHelper} implementation based on an internally
+ * built and managed {@link ConnectionProvider}.
+ *
+ * @author Steve Ebersole
+ */
+class ManagedProviderConnectionHelper implements ConnectionHelper {
+	private Properties cfgProperties;
+	private ConnectionProvider connectionProvider;
+	private Connection connection;
+
+	public ManagedProviderConnectionHelper(Properties cfgProperties) {
+		this.cfgProperties = cfgProperties;
+	}
+
+	public void prepare(boolean needsAutoCommit) throws SQLException {
+		connectionProvider = ConnectionProviderFactory.newConnectionProvider( cfgProperties );
+		connection = connectionProvider.getConnection();
+		if ( needsAutoCommit && !connection.getAutoCommit() ) {
+			connection.commit();
+			connection.setAutoCommit( true );
+		}
+	}
+
+	public Connection getConnection() throws SQLException {
+		return connection;
+	}
+
+	public void release() throws SQLException {
+		if ( connection != null ) {
+			try {
+				JDBCExceptionReporter.logAndClearWarnings( connection );
+				connectionProvider.closeConnection( connection );
+			}
+			finally {
+				connectionProvider.close();
+			}
+		}
+		connection = null;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,476 +0,0 @@
-//$Id: SchemaExport.java 10765 2006-11-08 04:30:27Z steve.ebersole at jboss.com $
-package org.hibernate.tool.hbm2ddl;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.Writer;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.JDBCException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.cfg.Settings;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.jdbc.util.FormatStyle;
-import org.hibernate.jdbc.util.Formatter;
-import org.hibernate.jdbc.util.SQLStatementLogger;
-import org.hibernate.util.ConfigHelper;
-import org.hibernate.util.JDBCExceptionReporter;
-import org.hibernate.util.PropertiesHelper;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Commandline tool to export table schema to the database. This class may also be called from inside an application.
- *
- * @author Daniel Bradby
- * @author Gavin King
- */
-public class SchemaExport {
-
-	private static final Logger log = LoggerFactory.getLogger( SchemaExport.class );
-
-	private ConnectionHelper connectionHelper;
-	private String[] dropSQL;
-	private String[] createSQL;
-	private String outputFile = null;
-	private String importFile = "/import.sql";
-	private Dialect dialect;
-	private String delimiter;
-	private final List exceptions = new ArrayList();
-	private boolean haltOnError = false;
-	private Formatter formatter;
-	private SQLStatementLogger sqlStatementLogger;
-
-	/**
-	 * Create a schema exporter for the given Configuration
-	 *
-	 * @param cfg The configuration from which to build a schema export.
-	 * @throws HibernateException Indicates problem preparing for schema export.
-	 */
-	public SchemaExport(Configuration cfg) throws HibernateException {
-		this( cfg, cfg.getProperties() );
-	}
-
-	/**
-	 * Create a schema exporter for the given Configuration and given settings
-	 *
-	 * @param cfg The configuration from which to build a schema export.
-	 * @param settings The 'parsed' settings.
-	 * @throws HibernateException Indicates problem preparing for schema export.
-	 */
-	public SchemaExport(Configuration cfg, Settings settings) throws HibernateException {
-		dialect = settings.getDialect();
-		connectionHelper = new SuppliedConnectionProviderConnectionHelper( settings.getConnectionProvider() );
-		dropSQL = cfg.generateDropSchemaScript( dialect );
-		createSQL = cfg.generateSchemaCreationScript( dialect );
-		sqlStatementLogger = settings.getSqlStatementLogger();
-		formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
-	}
-
-	/**
-	 * Create a schema exporter for the given Configuration, with the given
-	 * database connection properties.
-	 *
-	 * @param cfg The configuration from which to build a schema export.
-	 * @param properties The properties from which to configure connectivity etc.
-	 * @throws HibernateException Indicates problem preparing for schema export.
-	 *
-	 * @deprecated properties may be specified via the Configuration object
-	 */
-	public SchemaExport(Configuration cfg, Properties properties) throws HibernateException {
-		dialect = Dialect.getDialect( properties );
-
-		Properties props = new Properties();
-		props.putAll( dialect.getDefaultProperties() );
-		props.putAll( properties );
-
-		connectionHelper = new ManagedProviderConnectionHelper( props );
-		dropSQL = cfg.generateDropSchemaScript( dialect );
-		createSQL = cfg.generateSchemaCreationScript( dialect );
-
-		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
-	}
-
-	/**
-	 * Create a schema exporter for the given Configuration, using the supplied connection for connectivity.
-	 *
-	 * @param cfg The configuration to use.
-	 * @param connection The JDBC connection to use.
-	 * @throws HibernateException Indicates problem preparing for schema export.
-	 */
-	public SchemaExport(Configuration cfg, Connection connection) throws HibernateException {
-		this.connectionHelper = new SuppliedConnectionHelper( connection );
-		dialect = Dialect.getDialect( cfg.getProperties() );
-		dropSQL = cfg.generateDropSchemaScript( dialect );
-		createSQL = cfg.generateSchemaCreationScript( dialect );
-		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, cfg.getProperties() ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
-	}
-
-	/**
-	 * For generating a export script file, this is the file which will be written.
-	 *
-	 * @param filename The name of the file to which to write the export script.
-	 * @return this
-	 */
-	public SchemaExport setOutputFile(String filename) {
-		outputFile = filename;
-		return this;
-	}
-
-	/**
-	 * An import file, containing raw SQL statements to be executed.
-	 *
-	 * @param filename The import file name.
-	 * @return this
-	 */
-	public SchemaExport setImportFile(String filename) {
-		importFile = filename;
-		return this;
-	}
-
-	/**
-	 * Set the end of statement delimiter
-	 *
-	 * @param delimiter The delimiter
-	 * @return this
-	 */
-	public SchemaExport setDelimiter(String delimiter) {
-		this.delimiter = delimiter;
-		return this;
-	}
-
-	/**
-	 * Should we format the sql strings?
-	 *
-	 * @param format Should we format SQL strings
-	 * @return this
-	 */
-	public SchemaExport setFormat(boolean format) {
-		this.formatter = ( format ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
-		return this;
-	}
-
-	/**
-	 * Should we stop once an error occurs?
-	 *
-	 * @param haltOnError True if export should stop after error.
-	 * @return this
-	 */
-	public SchemaExport setHaltOnError(boolean haltOnError) {
-		this.haltOnError = haltOnError;
-		return this;
-	}
-
-	/**
-	 * Run the schema creation script.
-	 *
-	 * @param script print the DDL to the console
-	 * @param export export the script to the database
-	 */
-	public void create(boolean script, boolean export) {
-		execute( script, export, false, false );
-	}
-
-	/**
-	 * Run the drop schema script.
-	 *
-	 * @param script print the DDL to the console
-	 * @param export export the script to the database
-	 */
-	public void drop(boolean script, boolean export) {
-		execute( script, export, true, false );
-	}
-
-	public void execute(boolean script, boolean export, boolean justDrop, boolean justCreate) {
-
-		log.info( "Running hbm2ddl schema export" );
-
-		Connection connection = null;
-		Writer outputFileWriter = null;
-		Reader importFileReader = null;
-		Statement statement = null;
-
-		exceptions.clear();
-
-		try {
-
-			try {
-				InputStream stream = ConfigHelper.getResourceAsStream( importFile );
-				importFileReader = new InputStreamReader( stream );
-			}
-			catch ( HibernateException e ) {
-				log.debug( "import file not found: " + importFile );
-			}
-
-			if ( outputFile != null ) {
-				log.info( "writing generated schema to file: " + outputFile );
-				outputFileWriter = new FileWriter( outputFile );
-			}
-
-			if ( export ) {
-				log.info( "exporting generated schema to database" );
-				connectionHelper.prepare( true );
-				connection = connectionHelper.getConnection();
-				statement = connection.createStatement();
-			}
-
-			if ( !justCreate ) {
-				drop( script, export, outputFileWriter, statement );
-			}
-
-			if ( !justDrop ) {
-				create( script, export, outputFileWriter, statement );
-				if ( export && importFileReader != null ) {
-					importScript( importFileReader, statement );
-				}
-			}
-
-			log.info( "schema export complete" );
-
-		}
-
-		catch ( Exception e ) {
-			exceptions.add( e );
-			log.error( "schema export unsuccessful", e );
-		}
-
-		finally {
-
-			try {
-				if ( statement != null ) {
-					statement.close();
-				}
-				if ( connection != null ) {
-					connectionHelper.release();
-				}
-			}
-			catch ( Exception e ) {
-				exceptions.add( e );
-				log.error( "Could not close connection", e );
-			}
-
-			try {
-				if ( outputFileWriter != null ) {
-					outputFileWriter.close();
-				}
-				if ( importFileReader != null ) {
-					importFileReader.close();
-				}
-			}
-			catch ( IOException ioe ) {
-				exceptions.add( ioe );
-				log.error( "Error closing output file: " + outputFile, ioe );
-			}
-
-		}
-	}
-
-	private void importScript(Reader importFileReader, Statement statement)
-			throws IOException {
-		log.info( "Executing import script: " + importFile );
-		BufferedReader reader = new BufferedReader( importFileReader );
-		long lineNo = 0;
-		for ( String sql = reader.readLine(); sql != null; sql = reader.readLine() ) {
-			try {
-				lineNo++;
-				String trimmedSql = sql.trim();
-				if ( trimmedSql.length() == 0 ||
-				     trimmedSql.startsWith( "--" ) ||
-				     trimmedSql.startsWith( "//" ) ||
-				     trimmedSql.startsWith( "/*" ) ) {
-					continue;
-				}
-				else {
-					if ( trimmedSql.endsWith( ";" ) ) {
-						trimmedSql = trimmedSql.substring( 0, trimmedSql.length() - 1 );
-					}
-					log.debug( trimmedSql );
-					statement.execute( trimmedSql );
-				}
-			}
-			catch ( SQLException e ) {
-				throw new JDBCException( "Error during import script execution at line " + lineNo, e );
-			}
-		}
-	}
-
-	private void create(boolean script, boolean export, Writer fileOutput, Statement statement)
-			throws IOException {
-		for ( int j = 0; j < createSQL.length; j++ ) {
-			try {
-				execute( script, export, fileOutput, statement, createSQL[j] );
-			}
-			catch ( SQLException e ) {
-				if ( haltOnError ) {
-					throw new JDBCException( "Error during DDL export", e );
-				}
-				exceptions.add( e );
-				log.error( "Unsuccessful: " + createSQL[j] );
-				log.error( e.getMessage() );
-			}
-		}
-	}
-
-	private void drop(boolean script, boolean export, Writer fileOutput, Statement statement)
-			throws IOException {
-		for ( int i = 0; i < dropSQL.length; i++ ) {
-			try {
-				execute( script, export, fileOutput, statement, dropSQL[i] );
-			}
-			catch ( SQLException e ) {
-				exceptions.add( e );
-				log.debug( "Unsuccessful: " + dropSQL[i] );
-				log.debug( e.getMessage() );
-			}
-		}
-	}
-
-	private void execute(boolean script, boolean export, Writer fileOutput, Statement statement, final String sql)
-			throws IOException, SQLException {
-		String formatted = formatter.format( sql );
-		if ( delimiter != null ) {
-			formatted += delimiter;
-		}
-		if ( script ) {
-			System.out.println( formatted );
-		}
-		log.debug( formatted );
-		if ( outputFile != null ) {
-			fileOutput.write( formatted + "\n" );
-		}
-		if ( export ) {
-
-			statement.executeUpdate( sql );
-			try {
-				SQLWarning warnings = statement.getWarnings();
-				if ( warnings != null) {
-					JDBCExceptionReporter.logAndClearWarnings( connectionHelper.getConnection() );
-				}
-			}
-			catch( SQLException sqle ) {
-				log.warn( "unable to log SQLWarnings : " + sqle );
-			}
-		}
-
-		
-	}
-
-	public static void main(String[] args) {
-		try {
-			Configuration cfg = new Configuration();
-
-			boolean script = true;
-			boolean drop = false;
-			boolean create = false;
-			boolean halt = false;
-			boolean export = true;
-			String outFile = null;
-			String importFile = "/import.sql";
-			String propFile = null;
-			boolean format = false;
-			String delim = null;
-
-			for ( int i = 0; i < args.length; i++ ) {
-				if ( args[i].startsWith( "--" ) ) {
-					if ( args[i].equals( "--quiet" ) ) {
-						script = false;
-					}
-					else if ( args[i].equals( "--drop" ) ) {
-						drop = true;
-					}
-					else if ( args[i].equals( "--create" ) ) {
-						create = true;
-					}
-					else if ( args[i].equals( "--haltonerror" ) ) {
-						halt = true;
-					}
-					else if ( args[i].equals( "--text" ) ) {
-						export = false;
-					}
-					else if ( args[i].startsWith( "--output=" ) ) {
-						outFile = args[i].substring( 9 );
-					}
-					else if ( args[i].startsWith( "--import=" ) ) {
-						importFile = args[i].substring( 9 );
-					}
-					else if ( args[i].startsWith( "--properties=" ) ) {
-						propFile = args[i].substring( 13 );
-					}
-					else if ( args[i].equals( "--format" ) ) {
-						format = true;
-					}
-					else if ( args[i].startsWith( "--delimiter=" ) ) {
-						delim = args[i].substring( 12 );
-					}
-					else if ( args[i].startsWith( "--config=" ) ) {
-						cfg.configure( args[i].substring( 9 ) );
-					}
-					else if ( args[i].startsWith( "--naming=" ) ) {
-						cfg.setNamingStrategy(
-								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) )
-										.newInstance()
-						);
-					}
-				}
-				else {
-					String filename = args[i];
-					if ( filename.endsWith( ".jar" ) ) {
-						cfg.addJar( new File( filename ) );
-					}
-					else {
-						cfg.addFile( filename );
-					}
-				}
-
-			}
-
-			if ( propFile != null ) {
-				Properties props = new Properties();
-				props.putAll( cfg.getProperties() );
-				props.load( new FileInputStream( propFile ) );
-				cfg.setProperties( props );
-			}
-
-			SchemaExport se = new SchemaExport( cfg )
-					.setHaltOnError( halt )
-					.setOutputFile( outFile )
-					.setImportFile( importFile )
-					.setDelimiter( delim );
-			if ( format ) {
-				se.setFormat( true );
-			}
-			se.execute( script, export, drop, create );
-
-		}
-		catch ( Exception e ) {
-			log.error( "Error creating schema ", e );
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Returns a List of all Exceptions which occured during the export.
-	 *
-	 * @return A List containig the Exceptions occured during the export
-	 */
-	public List getExceptions() {
-		return exceptions;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExport.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,499 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.Writer;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.JDBCException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.Settings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.jdbc.util.FormatStyle;
+import org.hibernate.jdbc.util.Formatter;
+import org.hibernate.jdbc.util.SQLStatementLogger;
+import org.hibernate.util.ConfigHelper;
+import org.hibernate.util.JDBCExceptionReporter;
+import org.hibernate.util.PropertiesHelper;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Commandline tool to export table schema to the database. This class may also be called from inside an application.
+ *
+ * @author Daniel Bradby
+ * @author Gavin King
+ */
+public class SchemaExport {
+
+	private static final Logger log = LoggerFactory.getLogger( SchemaExport.class );
+
+	private ConnectionHelper connectionHelper;
+	private String[] dropSQL;
+	private String[] createSQL;
+	private String outputFile = null;
+	private String importFile = "/import.sql";
+	private Dialect dialect;
+	private String delimiter;
+	private final List exceptions = new ArrayList();
+	private boolean haltOnError = false;
+	private Formatter formatter;
+	private SQLStatementLogger sqlStatementLogger;
+
+	/**
+	 * Create a schema exporter for the given Configuration
+	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 */
+	public SchemaExport(Configuration cfg) throws HibernateException {
+		this( cfg, cfg.getProperties() );
+	}
+
+	/**
+	 * Create a schema exporter for the given Configuration and given settings
+	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @param settings The 'parsed' settings.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 */
+	public SchemaExport(Configuration cfg, Settings settings) throws HibernateException {
+		dialect = settings.getDialect();
+		connectionHelper = new SuppliedConnectionProviderConnectionHelper( settings.getConnectionProvider() );
+		dropSQL = cfg.generateDropSchemaScript( dialect );
+		createSQL = cfg.generateSchemaCreationScript( dialect );
+		sqlStatementLogger = settings.getSqlStatementLogger();
+		formatter = ( sqlStatementLogger.isFormatSql() ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
+	}
+
+	/**
+	 * Create a schema exporter for the given Configuration, with the given
+	 * database connection properties.
+	 *
+	 * @param cfg The configuration from which to build a schema export.
+	 * @param properties The properties from which to configure connectivity etc.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 *
+	 * @deprecated properties may be specified via the Configuration object
+	 */
+	public SchemaExport(Configuration cfg, Properties properties) throws HibernateException {
+		dialect = Dialect.getDialect( properties );
+
+		Properties props = new Properties();
+		props.putAll( dialect.getDefaultProperties() );
+		props.putAll( properties );
+
+		connectionHelper = new ManagedProviderConnectionHelper( props );
+		dropSQL = cfg.generateDropSchemaScript( dialect );
+		createSQL = cfg.generateSchemaCreationScript( dialect );
+
+		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, props ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
+	}
+
+	/**
+	 * Create a schema exporter for the given Configuration, using the supplied connection for connectivity.
+	 *
+	 * @param cfg The configuration to use.
+	 * @param connection The JDBC connection to use.
+	 * @throws HibernateException Indicates problem preparing for schema export.
+	 */
+	public SchemaExport(Configuration cfg, Connection connection) throws HibernateException {
+		this.connectionHelper = new SuppliedConnectionHelper( connection );
+		dialect = Dialect.getDialect( cfg.getProperties() );
+		dropSQL = cfg.generateDropSchemaScript( dialect );
+		createSQL = cfg.generateSchemaCreationScript( dialect );
+		formatter = ( PropertiesHelper.getBoolean( Environment.FORMAT_SQL, cfg.getProperties() ) ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
+	}
+
+	/**
+	 * For generating a export script file, this is the file which will be written.
+	 *
+	 * @param filename The name of the file to which to write the export script.
+	 * @return this
+	 */
+	public SchemaExport setOutputFile(String filename) {
+		outputFile = filename;
+		return this;
+	}
+
+	/**
+	 * An import file, containing raw SQL statements to be executed.
+	 *
+	 * @param filename The import file name.
+	 * @return this
+	 */
+	public SchemaExport setImportFile(String filename) {
+		importFile = filename;
+		return this;
+	}
+
+	/**
+	 * Set the end of statement delimiter
+	 *
+	 * @param delimiter The delimiter
+	 * @return this
+	 */
+	public SchemaExport setDelimiter(String delimiter) {
+		this.delimiter = delimiter;
+		return this;
+	}
+
+	/**
+	 * Should we format the sql strings?
+	 *
+	 * @param format Should we format SQL strings
+	 * @return this
+	 */
+	public SchemaExport setFormat(boolean format) {
+		this.formatter = ( format ? FormatStyle.DDL : FormatStyle.NONE ).getFormatter();
+		return this;
+	}
+
+	/**
+	 * Should we stop once an error occurs?
+	 *
+	 * @param haltOnError True if export should stop after error.
+	 * @return this
+	 */
+	public SchemaExport setHaltOnError(boolean haltOnError) {
+		this.haltOnError = haltOnError;
+		return this;
+	}
+
+	/**
+	 * Run the schema creation script.
+	 *
+	 * @param script print the DDL to the console
+	 * @param export export the script to the database
+	 */
+	public void create(boolean script, boolean export) {
+		execute( script, export, false, false );
+	}
+
+	/**
+	 * Run the drop schema script.
+	 *
+	 * @param script print the DDL to the console
+	 * @param export export the script to the database
+	 */
+	public void drop(boolean script, boolean export) {
+		execute( script, export, true, false );
+	}
+
+	public void execute(boolean script, boolean export, boolean justDrop, boolean justCreate) {
+
+		log.info( "Running hbm2ddl schema export" );
+
+		Connection connection = null;
+		Writer outputFileWriter = null;
+		Reader importFileReader = null;
+		Statement statement = null;
+
+		exceptions.clear();
+
+		try {
+
+			try {
+				InputStream stream = ConfigHelper.getResourceAsStream( importFile );
+				importFileReader = new InputStreamReader( stream );
+			}
+			catch ( HibernateException e ) {
+				log.debug( "import file not found: " + importFile );
+			}
+
+			if ( outputFile != null ) {
+				log.info( "writing generated schema to file: " + outputFile );
+				outputFileWriter = new FileWriter( outputFile );
+			}
+
+			if ( export ) {
+				log.info( "exporting generated schema to database" );
+				connectionHelper.prepare( true );
+				connection = connectionHelper.getConnection();
+				statement = connection.createStatement();
+			}
+
+			if ( !justCreate ) {
+				drop( script, export, outputFileWriter, statement );
+			}
+
+			if ( !justDrop ) {
+				create( script, export, outputFileWriter, statement );
+				if ( export && importFileReader != null ) {
+					importScript( importFileReader, statement );
+				}
+			}
+
+			log.info( "schema export complete" );
+
+		}
+
+		catch ( Exception e ) {
+			exceptions.add( e );
+			log.error( "schema export unsuccessful", e );
+		}
+
+		finally {
+
+			try {
+				if ( statement != null ) {
+					statement.close();
+				}
+				if ( connection != null ) {
+					connectionHelper.release();
+				}
+			}
+			catch ( Exception e ) {
+				exceptions.add( e );
+				log.error( "Could not close connection", e );
+			}
+
+			try {
+				if ( outputFileWriter != null ) {
+					outputFileWriter.close();
+				}
+				if ( importFileReader != null ) {
+					importFileReader.close();
+				}
+			}
+			catch ( IOException ioe ) {
+				exceptions.add( ioe );
+				log.error( "Error closing output file: " + outputFile, ioe );
+			}
+
+		}
+	}
+
+	private void importScript(Reader importFileReader, Statement statement)
+			throws IOException {
+		log.info( "Executing import script: " + importFile );
+		BufferedReader reader = new BufferedReader( importFileReader );
+		long lineNo = 0;
+		for ( String sql = reader.readLine(); sql != null; sql = reader.readLine() ) {
+			try {
+				lineNo++;
+				String trimmedSql = sql.trim();
+				if ( trimmedSql.length() == 0 ||
+				     trimmedSql.startsWith( "--" ) ||
+				     trimmedSql.startsWith( "//" ) ||
+				     trimmedSql.startsWith( "/*" ) ) {
+					continue;
+				}
+				else {
+					if ( trimmedSql.endsWith( ";" ) ) {
+						trimmedSql = trimmedSql.substring( 0, trimmedSql.length() - 1 );
+					}
+					log.debug( trimmedSql );
+					statement.execute( trimmedSql );
+				}
+			}
+			catch ( SQLException e ) {
+				throw new JDBCException( "Error during import script execution at line " + lineNo, e );
+			}
+		}
+	}
+
+	private void create(boolean script, boolean export, Writer fileOutput, Statement statement)
+			throws IOException {
+		for ( int j = 0; j < createSQL.length; j++ ) {
+			try {
+				execute( script, export, fileOutput, statement, createSQL[j] );
+			}
+			catch ( SQLException e ) {
+				if ( haltOnError ) {
+					throw new JDBCException( "Error during DDL export", e );
+				}
+				exceptions.add( e );
+				log.error( "Unsuccessful: " + createSQL[j] );
+				log.error( e.getMessage() );
+			}
+		}
+	}
+
+	private void drop(boolean script, boolean export, Writer fileOutput, Statement statement)
+			throws IOException {
+		for ( int i = 0; i < dropSQL.length; i++ ) {
+			try {
+				execute( script, export, fileOutput, statement, dropSQL[i] );
+			}
+			catch ( SQLException e ) {
+				exceptions.add( e );
+				log.debug( "Unsuccessful: " + dropSQL[i] );
+				log.debug( e.getMessage() );
+			}
+		}
+	}
+
+	private void execute(boolean script, boolean export, Writer fileOutput, Statement statement, final String sql)
+			throws IOException, SQLException {
+		String formatted = formatter.format( sql );
+		if ( delimiter != null ) {
+			formatted += delimiter;
+		}
+		if ( script ) {
+			System.out.println( formatted );
+		}
+		log.debug( formatted );
+		if ( outputFile != null ) {
+			fileOutput.write( formatted + "\n" );
+		}
+		if ( export ) {
+
+			statement.executeUpdate( sql );
+			try {
+				SQLWarning warnings = statement.getWarnings();
+				if ( warnings != null) {
+					JDBCExceptionReporter.logAndClearWarnings( connectionHelper.getConnection() );
+				}
+			}
+			catch( SQLException sqle ) {
+				log.warn( "unable to log SQLWarnings : " + sqle );
+			}
+		}
+
+		
+	}
+
+	public static void main(String[] args) {
+		try {
+			Configuration cfg = new Configuration();
+
+			boolean script = true;
+			boolean drop = false;
+			boolean create = false;
+			boolean halt = false;
+			boolean export = true;
+			String outFile = null;
+			String importFile = "/import.sql";
+			String propFile = null;
+			boolean format = false;
+			String delim = null;
+
+			for ( int i = 0; i < args.length; i++ ) {
+				if ( args[i].startsWith( "--" ) ) {
+					if ( args[i].equals( "--quiet" ) ) {
+						script = false;
+					}
+					else if ( args[i].equals( "--drop" ) ) {
+						drop = true;
+					}
+					else if ( args[i].equals( "--create" ) ) {
+						create = true;
+					}
+					else if ( args[i].equals( "--haltonerror" ) ) {
+						halt = true;
+					}
+					else if ( args[i].equals( "--text" ) ) {
+						export = false;
+					}
+					else if ( args[i].startsWith( "--output=" ) ) {
+						outFile = args[i].substring( 9 );
+					}
+					else if ( args[i].startsWith( "--import=" ) ) {
+						importFile = args[i].substring( 9 );
+					}
+					else if ( args[i].startsWith( "--properties=" ) ) {
+						propFile = args[i].substring( 13 );
+					}
+					else if ( args[i].equals( "--format" ) ) {
+						format = true;
+					}
+					else if ( args[i].startsWith( "--delimiter=" ) ) {
+						delim = args[i].substring( 12 );
+					}
+					else if ( args[i].startsWith( "--config=" ) ) {
+						cfg.configure( args[i].substring( 9 ) );
+					}
+					else if ( args[i].startsWith( "--naming=" ) ) {
+						cfg.setNamingStrategy(
+								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) )
+										.newInstance()
+						);
+					}
+				}
+				else {
+					String filename = args[i];
+					if ( filename.endsWith( ".jar" ) ) {
+						cfg.addJar( new File( filename ) );
+					}
+					else {
+						cfg.addFile( filename );
+					}
+				}
+
+			}
+
+			if ( propFile != null ) {
+				Properties props = new Properties();
+				props.putAll( cfg.getProperties() );
+				props.load( new FileInputStream( propFile ) );
+				cfg.setProperties( props );
+			}
+
+			SchemaExport se = new SchemaExport( cfg )
+					.setHaltOnError( halt )
+					.setOutputFile( outFile )
+					.setImportFile( importFile )
+					.setDelimiter( delim );
+			if ( format ) {
+				se.setFormat( true );
+			}
+			se.execute( script, export, drop, create );
+
+		}
+		catch ( Exception e ) {
+			log.error( "Error creating schema ", e );
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Returns a List of all Exceptions which occured during the export.
+	 *
+	 * @return A List containig the Exceptions occured during the export
+	 */
+	public List getExceptions() {
+		return exceptions;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,232 +0,0 @@
-//$Id: SchemaExportTask.java 7863 2005-08-11 23:11:03Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.FileSet;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * An Ant task for <tt>SchemaExport</tt>.
- *
- * <pre>
- * &lt;taskdef name="schemaexport"
- *     classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
- *     classpathref="class.path"/&gt;
- *
- * &lt;schemaexport
- *     properties="${build.classes.dir}/hibernate.properties"
- *     quiet="no"
- *     text="no"
- *     drop="no"
- *     delimiter=";"
- *     output="${build.dir}/schema-export.sql"&gt;
- *     &lt;fileset dir="${build.classes.dir}"&gt;
- *         &lt;include name="*.hbm.xml"/&gt;
- *     &lt;/fileset&gt;
- * &lt;/schemaexport&gt;
- * </pre>
- *
- * @see SchemaExport
- * @author Rong C Ou
- */
-public class SchemaExportTask extends MatchingTask {
-
-	private List fileSets = new LinkedList();
-	private File propertiesFile = null;
-	private File configurationFile = null;
-	private File outputFile = null;
-	private boolean quiet = false;
-	private boolean text = false;
-	private boolean drop = false;
-	private boolean create = false;
-	private boolean haltOnError = false;
-	private String delimiter = null;
-	private String namingStrategy = null;
-
-	public void addFileset(FileSet set) {
-		fileSets.add(set);
-	}
-
-	/**
-	 * Set a properties file
-	 * @param propertiesFile the properties file name
-	 */
-	public void setProperties(File propertiesFile) {
-		if ( !propertiesFile.exists() ) {
-			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
-	}
-
-		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
-		this.propertiesFile = propertiesFile;
-	}
-
-	/**
-	 * Set a <literal>.cfg.xml</literal> file, which will be
-	 * loaded as a resource, from the classpath
-	 * @param configurationFile the path to the resource
-	 */
-	public void setConfig(File configurationFile) {
-		this.configurationFile = configurationFile;
-	}
-
-	/**
-	 * Enable "quiet" mode. The schema will not be
-	 * written to standard out.
-	 * @param quiet true to enable quiet mode
-	 */
-	public void setQuiet(boolean quiet) {
-		this.quiet = quiet;
-	}
-
-	/**
-	 * Enable "text-only" mode. The schema will not
-	 * be exported to the database.
-	 * @param text true to enable text-only mode
-	 */
-	public void setText(boolean text) {
-		this.text = text;
-	}
-
-	/**
-	 * Enable "drop" mode. Database objects will be
-	 * dropped but not recreated.
-	 * @param drop true to enable drop mode
-	 */
-	public void setDrop(boolean drop) {
-		this.drop = drop;
-	}
-
-	/**
-	 * Enable "create" mode. Database objects will be
-	 * created but not first dropped.
-	 * @param create true to enable create mode
-	 */
-	public void setCreate(boolean create) {
-		this.create = create;
-	}
-
-	/**
-	 * Set the end of statement delimiter for the generated script
-	 * @param delimiter the delimiter
-	 */
-	public void setDelimiter(String delimiter) {
-		this.delimiter = delimiter;
-	}
-
-	/**
-	 * Set the script output file
-	 * @param outputFile the file name
-	 */
-	public void setOutput(File outputFile) {
-		this.outputFile = outputFile;
-	}
-
-	/**
-	 * Execute the task
-	 */
-	public void execute() throws BuildException {
-		try {
-			getSchemaExport( getConfiguration() ).execute(!quiet, !text, drop, create);
-		}
-		catch (HibernateException e) {
-			throw new BuildException("Schema text failed: " + e.getMessage(), e);
-		}
-		catch (FileNotFoundException e) {
-			throw new BuildException("File not found: " + e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BuildException("IOException : " + e.getMessage(), e);
-		}
-		catch (Exception e) {
-			throw new BuildException(e);
-		}
-	}
-
-	private String[] getFiles() {
-
-		List files = new LinkedList();
-		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
-
-			FileSet fs = (FileSet) i.next();
-			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
-
-			String[] dsFiles = ds.getIncludedFiles();
-			for (int j = 0; j < dsFiles.length; j++) {
-				File f = new File(dsFiles[j]);
-				if ( !f.isFile() ) {
-					f = new File( ds.getBasedir(), dsFiles[j] );
-				}
-
-				files.add( f.getAbsolutePath() );
-			}
-		}
-
-		return ArrayHelper.toStringArray(files);
-	}
-
-	private Configuration getConfiguration() throws Exception {
-		Configuration cfg = new Configuration();
-		if (namingStrategy!=null) {
-			cfg.setNamingStrategy(
-					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
-				);
-		}
-		if (configurationFile != null) {
-			cfg.configure( configurationFile );
-		}
-
-		String[] files = getFiles();
-		for (int i = 0; i < files.length; i++) {
-			String filename = files[i];
-			if ( filename.endsWith(".jar") ) {
-				cfg.addJar( new File(filename) );
-			}
-			else {
-				cfg.addFile(filename);
-			}
-		}
-		return cfg;
-	}
-
-	private SchemaExport getSchemaExport(Configuration cfg) throws HibernateException, IOException {
-		Properties properties = new Properties();
-		properties.putAll( cfg.getProperties() );
-		if (propertiesFile == null) {
-			properties.putAll( getProject().getProperties() );
-		}
-		else {
-			properties.load( new FileInputStream(propertiesFile) );
-		}
-		cfg.setProperties(properties);
-		return new SchemaExport(cfg)
-				.setHaltOnError(haltOnError)
-				.setOutputFile( outputFile.getPath() )
-				.setDelimiter(delimiter);
-	}
-
-	public void setNamingStrategy(String namingStrategy) {
-		this.namingStrategy = namingStrategy;
-	}
-
-	public void setHaltonerror(boolean haltOnError) {
-		this.haltOnError = haltOnError;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaExportTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,255 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.ReflectHelper;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * An Ant task for <tt>SchemaExport</tt>.
+ *
+ * <pre>
+ * &lt;taskdef name="schemaexport"
+ *     classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
+ *     classpathref="class.path"/&gt;
+ *
+ * &lt;schemaexport
+ *     properties="${build.classes.dir}/hibernate.properties"
+ *     quiet="no"
+ *     text="no"
+ *     drop="no"
+ *     delimiter=";"
+ *     output="${build.dir}/schema-export.sql"&gt;
+ *     &lt;fileset dir="${build.classes.dir}"&gt;
+ *         &lt;include name="*.hbm.xml"/&gt;
+ *     &lt;/fileset&gt;
+ * &lt;/schemaexport&gt;
+ * </pre>
+ *
+ * @see SchemaExport
+ * @author Rong C Ou
+ */
+public class SchemaExportTask extends MatchingTask {
+
+	private List fileSets = new LinkedList();
+	private File propertiesFile = null;
+	private File configurationFile = null;
+	private File outputFile = null;
+	private boolean quiet = false;
+	private boolean text = false;
+	private boolean drop = false;
+	private boolean create = false;
+	private boolean haltOnError = false;
+	private String delimiter = null;
+	private String namingStrategy = null;
+
+	public void addFileset(FileSet set) {
+		fileSets.add(set);
+	}
+
+	/**
+	 * Set a properties file
+	 * @param propertiesFile the properties file name
+	 */
+	public void setProperties(File propertiesFile) {
+		if ( !propertiesFile.exists() ) {
+			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
+	}
+
+		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
+		this.propertiesFile = propertiesFile;
+	}
+
+	/**
+	 * Set a <literal>.cfg.xml</literal> file, which will be
+	 * loaded as a resource, from the classpath
+	 * @param configurationFile the path to the resource
+	 */
+	public void setConfig(File configurationFile) {
+		this.configurationFile = configurationFile;
+	}
+
+	/**
+	 * Enable "quiet" mode. The schema will not be
+	 * written to standard out.
+	 * @param quiet true to enable quiet mode
+	 */
+	public void setQuiet(boolean quiet) {
+		this.quiet = quiet;
+	}
+
+	/**
+	 * Enable "text-only" mode. The schema will not
+	 * be exported to the database.
+	 * @param text true to enable text-only mode
+	 */
+	public void setText(boolean text) {
+		this.text = text;
+	}
+
+	/**
+	 * Enable "drop" mode. Database objects will be
+	 * dropped but not recreated.
+	 * @param drop true to enable drop mode
+	 */
+	public void setDrop(boolean drop) {
+		this.drop = drop;
+	}
+
+	/**
+	 * Enable "create" mode. Database objects will be
+	 * created but not first dropped.
+	 * @param create true to enable create mode
+	 */
+	public void setCreate(boolean create) {
+		this.create = create;
+	}
+
+	/**
+	 * Set the end of statement delimiter for the generated script
+	 * @param delimiter the delimiter
+	 */
+	public void setDelimiter(String delimiter) {
+		this.delimiter = delimiter;
+	}
+
+	/**
+	 * Set the script output file
+	 * @param outputFile the file name
+	 */
+	public void setOutput(File outputFile) {
+		this.outputFile = outputFile;
+	}
+
+	/**
+	 * Execute the task
+	 */
+	public void execute() throws BuildException {
+		try {
+			getSchemaExport( getConfiguration() ).execute(!quiet, !text, drop, create);
+		}
+		catch (HibernateException e) {
+			throw new BuildException("Schema text failed: " + e.getMessage(), e);
+		}
+		catch (FileNotFoundException e) {
+			throw new BuildException("File not found: " + e.getMessage(), e);
+		}
+		catch (IOException e) {
+			throw new BuildException("IOException : " + e.getMessage(), e);
+		}
+		catch (Exception e) {
+			throw new BuildException(e);
+		}
+	}
+
+	private String[] getFiles() {
+
+		List files = new LinkedList();
+		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
+
+			FileSet fs = (FileSet) i.next();
+			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
+
+			String[] dsFiles = ds.getIncludedFiles();
+			for (int j = 0; j < dsFiles.length; j++) {
+				File f = new File(dsFiles[j]);
+				if ( !f.isFile() ) {
+					f = new File( ds.getBasedir(), dsFiles[j] );
+				}
+
+				files.add( f.getAbsolutePath() );
+			}
+		}
+
+		return ArrayHelper.toStringArray(files);
+	}
+
+	private Configuration getConfiguration() throws Exception {
+		Configuration cfg = new Configuration();
+		if (namingStrategy!=null) {
+			cfg.setNamingStrategy(
+					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
+				);
+		}
+		if (configurationFile != null) {
+			cfg.configure( configurationFile );
+		}
+
+		String[] files = getFiles();
+		for (int i = 0; i < files.length; i++) {
+			String filename = files[i];
+			if ( filename.endsWith(".jar") ) {
+				cfg.addJar( new File(filename) );
+			}
+			else {
+				cfg.addFile(filename);
+			}
+		}
+		return cfg;
+	}
+
+	private SchemaExport getSchemaExport(Configuration cfg) throws HibernateException, IOException {
+		Properties properties = new Properties();
+		properties.putAll( cfg.getProperties() );
+		if (propertiesFile == null) {
+			properties.putAll( getProject().getProperties() );
+		}
+		else {
+			properties.load( new FileInputStream(propertiesFile) );
+		}
+		cfg.setProperties(properties);
+		return new SchemaExport(cfg)
+				.setHaltOnError(haltOnError)
+				.setOutputFile( outputFile.getPath() )
+				.setDelimiter(delimiter);
+	}
+
+	public void setNamingStrategy(String namingStrategy) {
+		this.namingStrategy = namingStrategy;
+	}
+
+	public void setHaltonerror(boolean haltOnError) {
+		this.haltOnError = haltOnError;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,191 +0,0 @@
-//$Id: SchemaUpdate.java 9250 2006-02-10 03:48:37Z steveebersole $
-package org.hibernate.tool.hbm2ddl;
-
-import java.io.FileInputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.cfg.Settings;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A commandline tool to update a database schema. May also be called from
- * inside an application.
- *
- * @author Christoph Sturm
- */
-public class SchemaUpdate {
-
-	private static final Logger log = LoggerFactory.getLogger( SchemaUpdate.class );
-	private ConnectionHelper connectionHelper;
-	private Configuration configuration;
-	private Dialect dialect;
-	private List exceptions;
-
-	public SchemaUpdate(Configuration cfg) throws HibernateException {
-		this( cfg, cfg.getProperties() );
-	}
-
-	public SchemaUpdate(Configuration cfg, Properties connectionProperties) throws HibernateException {
-		this.configuration = cfg;
-		dialect = Dialect.getDialect( connectionProperties );
-		Properties props = new Properties();
-		props.putAll( dialect.getDefaultProperties() );
-		props.putAll( connectionProperties );
-		connectionHelper = new ManagedProviderConnectionHelper( props );
-		exceptions = new ArrayList();
-	}
-
-	public SchemaUpdate(Configuration cfg, Settings settings) throws HibernateException {
-		this.configuration = cfg;
-		dialect = settings.getDialect();
-		connectionHelper = new SuppliedConnectionProviderConnectionHelper(
-				settings.getConnectionProvider()
-		);
-		exceptions = new ArrayList();
-	}
-
-	public static void main(String[] args) {
-		try {
-			Configuration cfg = new Configuration();
-
-			boolean script = true;
-			// If true then execute db updates, otherwise just generate and display updates
-			boolean doUpdate = true;
-			String propFile = null;
-
-			for ( int i = 0; i < args.length; i++ ) {
-				if ( args[i].startsWith( "--" ) ) {
-					if ( args[i].equals( "--quiet" ) ) {
-						script = false;
-					}
-					else if ( args[i].startsWith( "--properties=" ) ) {
-						propFile = args[i].substring( 13 );
-					}
-					else if ( args[i].startsWith( "--config=" ) ) {
-						cfg.configure( args[i].substring( 9 ) );
-					}
-					else if ( args[i].startsWith( "--text" ) ) {
-						doUpdate = false;
-					}
-					else if ( args[i].startsWith( "--naming=" ) ) {
-						cfg.setNamingStrategy(
-								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) ).newInstance()
-						);
-					}
-				}
-				else {
-					cfg.addFile( args[i] );
-				}
-
-			}
-
-			if ( propFile != null ) {
-				Properties props = new Properties();
-				props.putAll( cfg.getProperties() );
-				props.load( new FileInputStream( propFile ) );
-				cfg.setProperties( props );
-			}
-
-			new SchemaUpdate( cfg ).execute( script, doUpdate );
-		}
-		catch ( Exception e ) {
-			log.error( "Error running schema update", e );
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Execute the schema updates
-	 *
-	 * @param script print all DDL to the console
-	 */
-	public void execute(boolean script, boolean doUpdate) {
-
-		log.info( "Running hbm2ddl schema update" );
-
-		Connection connection = null;
-		Statement stmt = null;
-
-		exceptions.clear();
-
-		try {
-
-			DatabaseMetadata meta;
-			try {
-				log.info( "fetching database metadata" );
-				connectionHelper.prepare( true );
-				connection = connectionHelper.getConnection();
-				meta = new DatabaseMetadata( connection, dialect );
-				stmt = connection.createStatement();
-			}
-			catch ( SQLException sqle ) {
-				exceptions.add( sqle );
-				log.error( "could not get database metadata", sqle );
-				throw sqle;
-			}
-
-			log.info( "updating schema" );
-
-			String[] createSQL = configuration.generateSchemaUpdateScript( dialect, meta );
-			for ( int j = 0; j < createSQL.length; j++ ) {
-
-				final String sql = createSQL[j];
-				try {
-					if ( script ) {
-						System.out.println( sql );
-					}
-					if ( doUpdate ) {
-						log.debug( sql );
-						stmt.executeUpdate( sql );
-					}
-				}
-				catch ( SQLException e ) {
-					exceptions.add( e );
-					log.error( "Unsuccessful: " + sql );
-					log.error( e.getMessage() );
-				}
-			}
-
-			log.info( "schema update complete" );
-
-		}
-		catch ( Exception e ) {
-			exceptions.add( e );
-			log.error( "could not complete schema update", e );
-		}
-		finally {
-
-			try {
-				if ( stmt != null ) {
-					stmt.close();
-				}
-				connectionHelper.release();
-			}
-			catch ( Exception e ) {
-				exceptions.add( e );
-				log.error( "Error closing connection", e );
-			}
-
-		}
-	}
-
-	/**
-	 * Returns a List of all Exceptions which occured during the export.
-	 *
-	 * @return A List containig the Exceptions occured during the export
-	 */
-	public List getExceptions() {
-		return exceptions;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdate.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tool.hbm2ddl;
+
+import java.io.FileInputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.Settings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A commandline tool to update a database schema. May also be called from
+ * inside an application.
+ *
+ * @author Christoph Sturm
+ */
+public class SchemaUpdate {
+
+	private static final Logger log = LoggerFactory.getLogger( SchemaUpdate.class );
+	private ConnectionHelper connectionHelper;
+	private Configuration configuration;
+	private Dialect dialect;
+	private List exceptions;
+
+	public SchemaUpdate(Configuration cfg) throws HibernateException {
+		this( cfg, cfg.getProperties() );
+	}
+
+	public SchemaUpdate(Configuration cfg, Properties connectionProperties) throws HibernateException {
+		this.configuration = cfg;
+		dialect = Dialect.getDialect( connectionProperties );
+		Properties props = new Properties();
+		props.putAll( dialect.getDefaultProperties() );
+		props.putAll( connectionProperties );
+		connectionHelper = new ManagedProviderConnectionHelper( props );
+		exceptions = new ArrayList();
+	}
+
+	public SchemaUpdate(Configuration cfg, Settings settings) throws HibernateException {
+		this.configuration = cfg;
+		dialect = settings.getDialect();
+		connectionHelper = new SuppliedConnectionProviderConnectionHelper(
+				settings.getConnectionProvider()
+		);
+		exceptions = new ArrayList();
+	}
+
+	public static void main(String[] args) {
+		try {
+			Configuration cfg = new Configuration();
+
+			boolean script = true;
+			// If true then execute db updates, otherwise just generate and display updates
+			boolean doUpdate = true;
+			String propFile = null;
+
+			for ( int i = 0; i < args.length; i++ ) {
+				if ( args[i].startsWith( "--" ) ) {
+					if ( args[i].equals( "--quiet" ) ) {
+						script = false;
+					}
+					else if ( args[i].startsWith( "--properties=" ) ) {
+						propFile = args[i].substring( 13 );
+					}
+					else if ( args[i].startsWith( "--config=" ) ) {
+						cfg.configure( args[i].substring( 9 ) );
+					}
+					else if ( args[i].startsWith( "--text" ) ) {
+						doUpdate = false;
+					}
+					else if ( args[i].startsWith( "--naming=" ) ) {
+						cfg.setNamingStrategy(
+								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) ).newInstance()
+						);
+					}
+				}
+				else {
+					cfg.addFile( args[i] );
+				}
+
+			}
+
+			if ( propFile != null ) {
+				Properties props = new Properties();
+				props.putAll( cfg.getProperties() );
+				props.load( new FileInputStream( propFile ) );
+				cfg.setProperties( props );
+			}
+
+			new SchemaUpdate( cfg ).execute( script, doUpdate );
+		}
+		catch ( Exception e ) {
+			log.error( "Error running schema update", e );
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Execute the schema updates
+	 *
+	 * @param script print all DDL to the console
+	 */
+	public void execute(boolean script, boolean doUpdate) {
+
+		log.info( "Running hbm2ddl schema update" );
+
+		Connection connection = null;
+		Statement stmt = null;
+
+		exceptions.clear();
+
+		try {
+
+			DatabaseMetadata meta;
+			try {
+				log.info( "fetching database metadata" );
+				connectionHelper.prepare( true );
+				connection = connectionHelper.getConnection();
+				meta = new DatabaseMetadata( connection, dialect );
+				stmt = connection.createStatement();
+			}
+			catch ( SQLException sqle ) {
+				exceptions.add( sqle );
+				log.error( "could not get database metadata", sqle );
+				throw sqle;
+			}
+
+			log.info( "updating schema" );
+
+			String[] createSQL = configuration.generateSchemaUpdateScript( dialect, meta );
+			for ( int j = 0; j < createSQL.length; j++ ) {
+
+				final String sql = createSQL[j];
+				try {
+					if ( script ) {
+						System.out.println( sql );
+					}
+					if ( doUpdate ) {
+						log.debug( sql );
+						stmt.executeUpdate( sql );
+					}
+				}
+				catch ( SQLException e ) {
+					exceptions.add( e );
+					log.error( "Unsuccessful: " + sql );
+					log.error( e.getMessage() );
+				}
+			}
+
+			log.info( "schema update complete" );
+
+		}
+		catch ( Exception e ) {
+			exceptions.add( e );
+			log.error( "could not complete schema update", e );
+		}
+		finally {
+
+			try {
+				if ( stmt != null ) {
+					stmt.close();
+				}
+				connectionHelper.release();
+			}
+			catch ( Exception e ) {
+				exceptions.add( e );
+				log.error( "Error closing connection", e );
+			}
+
+		}
+	}
+
+	/**
+	 * Returns a List of all Exceptions which occured during the export.
+	 *
+	 * @return A List containig the Exceptions occured during the export
+	 */
+	public List getExceptions() {
+		return exceptions;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,182 +0,0 @@
-//$Id: SchemaUpdateTask.java 7863 2005-08-11 23:11:03Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.FileSet;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * An Ant task for <tt>SchemaUpdate</tt>.
- *
- * <pre>
- * &lt;taskdef name="schemaupdate"
- *     classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
- *     classpathref="class.path"/&gt;
- *
- * &lt;schemaupdate
- *     properties="${build.classes.dir}/hibernate.properties"
- *     quiet="no"
- *     &lt;fileset dir="${build.classes.dir}"&gt;
- *         &lt;include name="*.hbm.xml"/&gt;
- *     &lt;/fileset&gt;
- * &lt;/schemaupdate&gt;
- * </pre>
- *
- * @see SchemaUpdate
- * @author Rong C Ou, Gavin King
- */
-public class SchemaUpdateTask extends MatchingTask {
-
-	private List fileSets = new LinkedList();
-	private File propertiesFile = null;
-	private File configurationFile = null;
-	private boolean quiet = false;
-	private boolean text = true;
-	private String namingStrategy = null;
-
-	public void addFileset(FileSet set) {
-		fileSets.add(set);
-	}
-
-	/**
-	 * Set a properties file
-	 * @param propertiesFile the properties file name
-	 */
-	public void setProperties(File propertiesFile) {
-		if ( !propertiesFile.exists() ) {
-			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
-		}
-
-		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
-		this.propertiesFile = propertiesFile;
-	}
-
-	/**
-	 * Set a <literal>.cfg.xml</literal> file
-	 * @param configurationFile the file name
-	 */
-	public void setConfig(File configurationFile) {
-		this.configurationFile = configurationFile;
-	}
-
-	/**
-     * Enable "text-only" mode. The schema will not
-	 * be updated in the database.
-	 * @param text true to enable text-only mode
-     */
-    public void setText(boolean text) {
-        this.text = text;
-    }
-
-	/**
-	 * Enable "quiet" mode. The schema will not be
-	 * written to standard out.
-	 * @param quiet true to enable quiet mode
-	 */
-	public void setQuiet(boolean quiet) {
-		this.quiet = quiet;
-	}
-
-	/**
-	 * Execute the task
-	 */
-	public void execute() throws BuildException {
-		try {
-			Configuration cfg = getConfiguration();
-			getSchemaUpdate(cfg).execute(!quiet, !text);
-		}
-		catch (HibernateException e) {
-			throw new BuildException("Schema text failed: " + e.getMessage(), e);
-		}
-		catch (FileNotFoundException e) {
-			throw new BuildException("File not found: " + e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BuildException("IOException : " + e.getMessage(), e);
-		}
-		catch (Exception e) {
-			throw new BuildException(e);
-		}
-	}
-
-	private String[] getFiles() {
-
-		List files = new LinkedList();
-		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
-
-			FileSet fs = (FileSet) i.next();
-			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
-
-			String[] dsFiles = ds.getIncludedFiles();
-			for (int j = 0; j < dsFiles.length; j++) {
-				File f = new File(dsFiles[j]);
-				if ( !f.isFile() ) {
-					f = new File( ds.getBasedir(), dsFiles[j] );
-				}
-
-				files.add( f.getAbsolutePath() );
-			}
-		}
-
-		return ArrayHelper.toStringArray(files);
-	}
-
-	private Configuration getConfiguration() throws Exception {
-		Configuration cfg = new Configuration();
-		if (namingStrategy!=null) {
-			cfg.setNamingStrategy(
-					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
-				);
-		}
-		if (configurationFile!=null) {
-			cfg.configure( configurationFile );
-		}
-
-		String[] files = getFiles();
-		for (int i = 0; i < files.length; i++) {
-			String filename = files[i];
-			if ( filename.endsWith(".jar") ) {
-				cfg.addJar( new File(filename) );
-			}
-			else {
-				cfg.addFile(filename);
-			}
-		}
-		return cfg;
-	}
-
-	private SchemaUpdate getSchemaUpdate(Configuration cfg) throws HibernateException, IOException {
-		Properties properties = new Properties();
-		properties.putAll( cfg.getProperties() );
-		if (propertiesFile == null) {
-			properties.putAll( getProject().getProperties() );
-		}
-		else {
-			properties.load( new FileInputStream(propertiesFile) );
-		}
-		cfg.setProperties(properties);
-		return new SchemaUpdate(cfg);
-	}
-
-	public void setNamingStrategy(String namingStrategy) {
-		this.namingStrategy = namingStrategy;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaUpdateTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,205 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.ReflectHelper;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * An Ant task for <tt>SchemaUpdate</tt>.
+ *
+ * <pre>
+ * &lt;taskdef name="schemaupdate"
+ *     classname="org.hibernate.tool.hbm2ddl.SchemaUpdateTask"
+ *     classpathref="class.path"/&gt;
+ *
+ * &lt;schemaupdate
+ *     properties="${build.classes.dir}/hibernate.properties"
+ *     quiet="no"
+ *     &lt;fileset dir="${build.classes.dir}"&gt;
+ *         &lt;include name="*.hbm.xml"/&gt;
+ *     &lt;/fileset&gt;
+ * &lt;/schemaupdate&gt;
+ * </pre>
+ *
+ * @see SchemaUpdate
+ * @author Rong C Ou, Gavin King
+ */
+public class SchemaUpdateTask extends MatchingTask {
+
+	private List fileSets = new LinkedList();
+	private File propertiesFile = null;
+	private File configurationFile = null;
+	private boolean quiet = false;
+	private boolean text = true;
+	private String namingStrategy = null;
+
+	public void addFileset(FileSet set) {
+		fileSets.add(set);
+	}
+
+	/**
+	 * Set a properties file
+	 * @param propertiesFile the properties file name
+	 */
+	public void setProperties(File propertiesFile) {
+		if ( !propertiesFile.exists() ) {
+			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
+		}
+
+		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
+		this.propertiesFile = propertiesFile;
+	}
+
+	/**
+	 * Set a <literal>.cfg.xml</literal> file
+	 * @param configurationFile the file name
+	 */
+	public void setConfig(File configurationFile) {
+		this.configurationFile = configurationFile;
+	}
+
+	/**
+     * Enable "text-only" mode. The schema will not
+	 * be updated in the database.
+	 * @param text true to enable text-only mode
+     */
+    public void setText(boolean text) {
+        this.text = text;
+    }
+
+	/**
+	 * Enable "quiet" mode. The schema will not be
+	 * written to standard out.
+	 * @param quiet true to enable quiet mode
+	 */
+	public void setQuiet(boolean quiet) {
+		this.quiet = quiet;
+	}
+
+	/**
+	 * Execute the task
+	 */
+	public void execute() throws BuildException {
+		try {
+			Configuration cfg = getConfiguration();
+			getSchemaUpdate(cfg).execute(!quiet, !text);
+		}
+		catch (HibernateException e) {
+			throw new BuildException("Schema text failed: " + e.getMessage(), e);
+		}
+		catch (FileNotFoundException e) {
+			throw new BuildException("File not found: " + e.getMessage(), e);
+		}
+		catch (IOException e) {
+			throw new BuildException("IOException : " + e.getMessage(), e);
+		}
+		catch (Exception e) {
+			throw new BuildException(e);
+		}
+	}
+
+	private String[] getFiles() {
+
+		List files = new LinkedList();
+		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
+
+			FileSet fs = (FileSet) i.next();
+			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
+
+			String[] dsFiles = ds.getIncludedFiles();
+			for (int j = 0; j < dsFiles.length; j++) {
+				File f = new File(dsFiles[j]);
+				if ( !f.isFile() ) {
+					f = new File( ds.getBasedir(), dsFiles[j] );
+				}
+
+				files.add( f.getAbsolutePath() );
+			}
+		}
+
+		return ArrayHelper.toStringArray(files);
+	}
+
+	private Configuration getConfiguration() throws Exception {
+		Configuration cfg = new Configuration();
+		if (namingStrategy!=null) {
+			cfg.setNamingStrategy(
+					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
+				);
+		}
+		if (configurationFile!=null) {
+			cfg.configure( configurationFile );
+		}
+
+		String[] files = getFiles();
+		for (int i = 0; i < files.length; i++) {
+			String filename = files[i];
+			if ( filename.endsWith(".jar") ) {
+				cfg.addJar( new File(filename) );
+			}
+			else {
+				cfg.addFile(filename);
+			}
+		}
+		return cfg;
+	}
+
+	private SchemaUpdate getSchemaUpdate(Configuration cfg) throws HibernateException, IOException {
+		Properties properties = new Properties();
+		properties.putAll( cfg.getProperties() );
+		if (propertiesFile == null) {
+			properties.putAll( getProject().getProperties() );
+		}
+		else {
+			properties.load( new FileInputStream(propertiesFile) );
+		}
+		cfg.setProperties(properties);
+		return new SchemaUpdate(cfg);
+	}
+
+	public void setNamingStrategy(String namingStrategy) {
+		this.namingStrategy = namingStrategy;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,134 +0,0 @@
-//$Id: SchemaValidator.java 9249 2006-02-10 03:48:37Z steveebersole $
-package org.hibernate.tool.hbm2ddl;
-
-import java.io.FileInputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.cfg.Settings;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A commandline tool to update a database schema. May also be called from
- * inside an application.
- *
- * @author Christoph Sturm
- */
-public class SchemaValidator {
-
-	private static final Logger log = LoggerFactory.getLogger( SchemaValidator.class );
-	private ConnectionHelper connectionHelper;
-	private Configuration configuration;
-	private Dialect dialect;
-
-	public SchemaValidator(Configuration cfg) throws HibernateException {
-		this( cfg, cfg.getProperties() );
-	}
-
-	public SchemaValidator(Configuration cfg, Properties connectionProperties) throws HibernateException {
-		this.configuration = cfg;
-		dialect = Dialect.getDialect( connectionProperties );
-		Properties props = new Properties();
-		props.putAll( dialect.getDefaultProperties() );
-		props.putAll( connectionProperties );
-		connectionHelper = new ManagedProviderConnectionHelper( props );
-	}
-
-	public SchemaValidator(Configuration cfg, Settings settings) throws HibernateException {
-		this.configuration = cfg;
-		dialect = settings.getDialect();
-		connectionHelper = new SuppliedConnectionProviderConnectionHelper(
-				settings.getConnectionProvider()
-		);
-	}
-
-	public static void main(String[] args) {
-		try {
-			Configuration cfg = new Configuration();
-
-			String propFile = null;
-
-			for ( int i = 0; i < args.length; i++ ) {
-				if ( args[i].startsWith( "--" ) ) {
-					if ( args[i].startsWith( "--properties=" ) ) {
-						propFile = args[i].substring( 13 );
-					}
-					else if ( args[i].startsWith( "--config=" ) ) {
-						cfg.configure( args[i].substring( 9 ) );
-					}
-					else if ( args[i].startsWith( "--naming=" ) ) {
-						cfg.setNamingStrategy(
-								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) ).newInstance()
-						);
-					}
-				}
-				else {
-					cfg.addFile( args[i] );
-				}
-
-			}
-
-			if ( propFile != null ) {
-				Properties props = new Properties();
-				props.putAll( cfg.getProperties() );
-				props.load( new FileInputStream( propFile ) );
-				cfg.setProperties( props );
-			}
-
-			new SchemaValidator( cfg ).validate();
-		}
-		catch ( Exception e ) {
-			log.error( "Error running schema update", e );
-			e.printStackTrace();
-		}
-	}
-
-	/**
-	 * Perform the validations.
-	 */
-	public void validate() {
-
-		log.info( "Running schema validator" );
-
-		Connection connection = null;
-
-		try {
-
-			DatabaseMetadata meta;
-			try {
-				log.info( "fetching database metadata" );
-				connectionHelper.prepare( false );
-				connection = connectionHelper.getConnection();
-				meta = new DatabaseMetadata( connection, dialect, false );
-			}
-			catch ( SQLException sqle ) {
-				log.error( "could not get database metadata", sqle );
-				throw sqle;
-			}
-
-			configuration.validateSchema( dialect, meta );
-
-		}
-		catch ( SQLException e ) {
-			log.error( "could not complete schema validation", e );
-		}
-		finally {
-
-			try {
-				connectionHelper.release();
-			}
-			catch ( Exception e ) {
-				log.error( "Error closing connection", e );
-			}
-
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,157 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import java.io.FileInputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.cfg.Settings;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A commandline tool to update a database schema. May also be called from
+ * inside an application.
+ *
+ * @author Christoph Sturm
+ */
+public class SchemaValidator {
+
+	private static final Logger log = LoggerFactory.getLogger( SchemaValidator.class );
+	private ConnectionHelper connectionHelper;
+	private Configuration configuration;
+	private Dialect dialect;
+
+	public SchemaValidator(Configuration cfg) throws HibernateException {
+		this( cfg, cfg.getProperties() );
+	}
+
+	public SchemaValidator(Configuration cfg, Properties connectionProperties) throws HibernateException {
+		this.configuration = cfg;
+		dialect = Dialect.getDialect( connectionProperties );
+		Properties props = new Properties();
+		props.putAll( dialect.getDefaultProperties() );
+		props.putAll( connectionProperties );
+		connectionHelper = new ManagedProviderConnectionHelper( props );
+	}
+
+	public SchemaValidator(Configuration cfg, Settings settings) throws HibernateException {
+		this.configuration = cfg;
+		dialect = settings.getDialect();
+		connectionHelper = new SuppliedConnectionProviderConnectionHelper(
+				settings.getConnectionProvider()
+		);
+	}
+
+	public static void main(String[] args) {
+		try {
+			Configuration cfg = new Configuration();
+
+			String propFile = null;
+
+			for ( int i = 0; i < args.length; i++ ) {
+				if ( args[i].startsWith( "--" ) ) {
+					if ( args[i].startsWith( "--properties=" ) ) {
+						propFile = args[i].substring( 13 );
+					}
+					else if ( args[i].startsWith( "--config=" ) ) {
+						cfg.configure( args[i].substring( 9 ) );
+					}
+					else if ( args[i].startsWith( "--naming=" ) ) {
+						cfg.setNamingStrategy(
+								( NamingStrategy ) ReflectHelper.classForName( args[i].substring( 9 ) ).newInstance()
+						);
+					}
+				}
+				else {
+					cfg.addFile( args[i] );
+				}
+
+			}
+
+			if ( propFile != null ) {
+				Properties props = new Properties();
+				props.putAll( cfg.getProperties() );
+				props.load( new FileInputStream( propFile ) );
+				cfg.setProperties( props );
+			}
+
+			new SchemaValidator( cfg ).validate();
+		}
+		catch ( Exception e ) {
+			log.error( "Error running schema update", e );
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Perform the validations.
+	 */
+	public void validate() {
+
+		log.info( "Running schema validator" );
+
+		Connection connection = null;
+
+		try {
+
+			DatabaseMetadata meta;
+			try {
+				log.info( "fetching database metadata" );
+				connectionHelper.prepare( false );
+				connection = connectionHelper.getConnection();
+				meta = new DatabaseMetadata( connection, dialect, false );
+			}
+			catch ( SQLException sqle ) {
+				log.error( "could not get database metadata", sqle );
+				throw sqle;
+			}
+
+			configuration.validateSchema( dialect, meta );
+
+		}
+		catch ( SQLException e ) {
+			log.error( "could not complete schema validation", e );
+		}
+		finally {
+
+			try {
+				connectionHelper.release();
+			}
+			catch ( Exception e ) {
+				log.error( "Error closing connection", e );
+			}
+
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,161 +0,0 @@
-//$Id: SchemaValidatorTask.java 7863 2005-08-11 23:11:03Z oneovthafew $
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.NamingStrategy;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.taskdefs.MatchingTask;
-import org.apache.tools.ant.types.FileSet;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * An Ant task for <tt>SchemaUpdate</tt>.
- *
- * <pre>
- * &lt;taskdef name="schemavalidator"
- *     classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
- *     classpathref="class.path"/&gt;
- *
- * &lt;schemaupdate
- *     properties="${build.classes.dir}/hibernate.properties"
- *     &lt;fileset dir="${build.classes.dir}"&gt;
- *         &lt;include name="*.hbm.xml"/&gt;
- *     &lt;/fileset&gt;
- * &lt;/schemaupdate&gt;
- * </pre>
- *
- * @see SchemaValidator
- * @author Gavin King
- */
-public class SchemaValidatorTask extends MatchingTask {
-
-	private List fileSets = new LinkedList();
-	private File propertiesFile = null;
-	private File configurationFile = null;
-	private String namingStrategy = null;
-
-	public void addFileset(FileSet set) {
-		fileSets.add(set);
-	}
-
-	/**
-	 * Set a properties file
-	 * @param propertiesFile the properties file name
-	 */
-	public void setProperties(File propertiesFile) {
-		if ( !propertiesFile.exists() ) {
-			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
-		}
-
-		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
-		this.propertiesFile = propertiesFile;
-	}
-
-	/**
-	 * Set a <literal>.cfg.xml</literal> file
-	 * @param configurationFile the file name
-	 */
-	public void setConfig(File configurationFile) {
-		this.configurationFile = configurationFile;
-	}
-
-	/**
-	 * Execute the task
-	 */
-	public void execute() throws BuildException {
-		try {
-			Configuration cfg = getConfiguration();
-			getSchemaValidator(cfg).validate();
-		}
-		catch (HibernateException e) {
-			throw new BuildException("Schema text failed: " + e.getMessage(), e);
-		}
-		catch (FileNotFoundException e) {
-			throw new BuildException("File not found: " + e.getMessage(), e);
-		}
-		catch (IOException e) {
-			throw new BuildException("IOException : " + e.getMessage(), e);
-		}
-		catch (Exception e) {
-			throw new BuildException(e);
-		}
-	}
-
-	private String[] getFiles() {
-
-		List files = new LinkedList();
-		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
-
-			FileSet fs = (FileSet) i.next();
-			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
-
-			String[] dsFiles = ds.getIncludedFiles();
-			for (int j = 0; j < dsFiles.length; j++) {
-				File f = new File(dsFiles[j]);
-				if ( !f.isFile() ) {
-					f = new File( ds.getBasedir(), dsFiles[j] );
-				}
-
-				files.add( f.getAbsolutePath() );
-			}
-		}
-
-		return ArrayHelper.toStringArray(files);
-	}
-
-	private Configuration getConfiguration() throws Exception {
-		Configuration cfg = new Configuration();
-		if (namingStrategy!=null) {
-			cfg.setNamingStrategy(
-					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
-				);
-		}
-		if (configurationFile!=null) {
-			cfg.configure( configurationFile );
-		}
-
-		String[] files = getFiles();
-		for (int i = 0; i < files.length; i++) {
-			String filename = files[i];
-			if ( filename.endsWith(".jar") ) {
-				cfg.addJar( new File(filename) );
-			}
-			else {
-				cfg.addFile(filename);
-			}
-		}
-		return cfg;
-	}
-
-	private SchemaValidator getSchemaValidator(Configuration cfg) throws HibernateException, IOException {
-		Properties properties = new Properties();
-		properties.putAll( cfg.getProperties() );
-		if (propertiesFile == null) {
-			properties.putAll( getProject().getProperties() );
-		}
-		else {
-			properties.load( new FileInputStream(propertiesFile) );
-		}
-		cfg.setProperties(properties);
-		return new SchemaValidator(cfg);
-	}
-
-	public void setNamingStrategy(String namingStrategy) {
-		this.namingStrategy = namingStrategy;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SchemaValidatorTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,184 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.NamingStrategy;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.ReflectHelper;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.MatchingTask;
+import org.apache.tools.ant.types.FileSet;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * An Ant task for <tt>SchemaUpdate</tt>.
+ *
+ * <pre>
+ * &lt;taskdef name="schemavalidator"
+ *     classname="org.hibernate.tool.hbm2ddl.SchemaValidatorTask"
+ *     classpathref="class.path"/&gt;
+ *
+ * &lt;schemaupdate
+ *     properties="${build.classes.dir}/hibernate.properties"
+ *     &lt;fileset dir="${build.classes.dir}"&gt;
+ *         &lt;include name="*.hbm.xml"/&gt;
+ *     &lt;/fileset&gt;
+ * &lt;/schemaupdate&gt;
+ * </pre>
+ *
+ * @see SchemaValidator
+ * @author Gavin King
+ */
+public class SchemaValidatorTask extends MatchingTask {
+
+	private List fileSets = new LinkedList();
+	private File propertiesFile = null;
+	private File configurationFile = null;
+	private String namingStrategy = null;
+
+	public void addFileset(FileSet set) {
+		fileSets.add(set);
+	}
+
+	/**
+	 * Set a properties file
+	 * @param propertiesFile the properties file name
+	 */
+	public void setProperties(File propertiesFile) {
+		if ( !propertiesFile.exists() ) {
+			throw new BuildException("Properties file: " + propertiesFile + " does not exist.");
+		}
+
+		log("Using properties file " + propertiesFile, Project.MSG_DEBUG);
+		this.propertiesFile = propertiesFile;
+	}
+
+	/**
+	 * Set a <literal>.cfg.xml</literal> file
+	 * @param configurationFile the file name
+	 */
+	public void setConfig(File configurationFile) {
+		this.configurationFile = configurationFile;
+	}
+
+	/**
+	 * Execute the task
+	 */
+	public void execute() throws BuildException {
+		try {
+			Configuration cfg = getConfiguration();
+			getSchemaValidator(cfg).validate();
+		}
+		catch (HibernateException e) {
+			throw new BuildException("Schema text failed: " + e.getMessage(), e);
+		}
+		catch (FileNotFoundException e) {
+			throw new BuildException("File not found: " + e.getMessage(), e);
+		}
+		catch (IOException e) {
+			throw new BuildException("IOException : " + e.getMessage(), e);
+		}
+		catch (Exception e) {
+			throw new BuildException(e);
+		}
+	}
+
+	private String[] getFiles() {
+
+		List files = new LinkedList();
+		for ( Iterator i = fileSets.iterator(); i.hasNext(); ) {
+
+			FileSet fs = (FileSet) i.next();
+			DirectoryScanner ds = fs.getDirectoryScanner( getProject() );
+
+			String[] dsFiles = ds.getIncludedFiles();
+			for (int j = 0; j < dsFiles.length; j++) {
+				File f = new File(dsFiles[j]);
+				if ( !f.isFile() ) {
+					f = new File( ds.getBasedir(), dsFiles[j] );
+				}
+
+				files.add( f.getAbsolutePath() );
+			}
+		}
+
+		return ArrayHelper.toStringArray(files);
+	}
+
+	private Configuration getConfiguration() throws Exception {
+		Configuration cfg = new Configuration();
+		if (namingStrategy!=null) {
+			cfg.setNamingStrategy(
+					(NamingStrategy) ReflectHelper.classForName(namingStrategy).newInstance()
+				);
+		}
+		if (configurationFile!=null) {
+			cfg.configure( configurationFile );
+		}
+
+		String[] files = getFiles();
+		for (int i = 0; i < files.length; i++) {
+			String filename = files[i];
+			if ( filename.endsWith(".jar") ) {
+				cfg.addJar( new File(filename) );
+			}
+			else {
+				cfg.addFile(filename);
+			}
+		}
+		return cfg;
+	}
+
+	private SchemaValidator getSchemaValidator(Configuration cfg) throws HibernateException, IOException {
+		Properties properties = new Properties();
+		properties.putAll( cfg.getProperties() );
+		if (propertiesFile == null) {
+			properties.putAll( getProject().getProperties() );
+		}
+		else {
+			properties.load( new FileInputStream(propertiesFile) );
+		}
+		cfg.setProperties(properties);
+		return new SchemaValidator(cfg);
+	}
+
+	public void setNamingStrategy(String namingStrategy) {
+		this.namingStrategy = namingStrategy;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.util.JDBCExceptionReporter;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * A {@link ConnectionHelper} implementation based on an explicitly supplied
- * connection.
- *
- * @author Steve Ebersole
- */
-class SuppliedConnectionHelper implements ConnectionHelper {
-	private Connection connection;
-	private boolean toggleAutoCommit;
-
-	public SuppliedConnectionHelper(Connection connection) {
-		this.connection = connection;
-	}
-
-	public void prepare(boolean needsAutoCommit) throws SQLException {
-		toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit();
-		if ( toggleAutoCommit ) {
-			try {
-				connection.commit();
-			}
-			catch( Throwable ignore ) {
-				// might happen with a managed connection
-			}
-			connection.setAutoCommit( true );
-		}
-	}
-
-	public Connection getConnection() {
-		return connection;
-	}
-
-	public void release() throws SQLException {
-		JDBCExceptionReporter.logAndClearWarnings( connection );
-		if ( toggleAutoCommit ) {
-			connection.setAutoCommit( false );
-		}
-		connection = null;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import org.hibernate.util.JDBCExceptionReporter;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * A {@link ConnectionHelper} implementation based on an explicitly supplied
+ * connection.
+ *
+ * @author Steve Ebersole
+ */
+class SuppliedConnectionHelper implements ConnectionHelper {
+	private Connection connection;
+	private boolean toggleAutoCommit;
+
+	public SuppliedConnectionHelper(Connection connection) {
+		this.connection = connection;
+	}
+
+	public void prepare(boolean needsAutoCommit) throws SQLException {
+		toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit();
+		if ( toggleAutoCommit ) {
+			try {
+				connection.commit();
+			}
+			catch( Throwable ignore ) {
+				// might happen with a managed connection
+			}
+			connection.setAutoCommit( true );
+		}
+	}
+
+	public Connection getConnection() {
+		return connection;
+	}
+
+	public void release() throws SQLException {
+		JDBCExceptionReporter.logAndClearWarnings( connection );
+		if ( toggleAutoCommit ) {
+			connection.setAutoCommit( false );
+		}
+		connection = null;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,55 +0,0 @@
-package org.hibernate.tool.hbm2ddl;
-
-import org.hibernate.connection.ConnectionProvider;
-import org.hibernate.util.JDBCExceptionReporter;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-
-/**
- * A {@link ConnectionHelper} implementation based on a provided
- * {@link ConnectionProvider}.  Essentially, ensures that the connection
- * gets cleaned up, but that the provider itself remains usable since it
- * was externally provided to us.
- *
- * @author Steve Ebersole
- */
-class SuppliedConnectionProviderConnectionHelper implements ConnectionHelper {
-	private ConnectionProvider provider;
-	private Connection connection;
-	private boolean toggleAutoCommit;
-
-	public SuppliedConnectionProviderConnectionHelper(ConnectionProvider provider) {
-		this.provider = provider;
-	}
-
-	public void prepare(boolean needsAutoCommit) throws SQLException {
-		connection = provider.getConnection();
-		toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit();
-		if ( toggleAutoCommit ) {
-			try {
-				connection.commit();
-			}
-			catch( Throwable ignore ) {
-				// might happen with a managed connection
-			}
-			connection.setAutoCommit( true );
-		}
-	}
-
-	public Connection getConnection() throws SQLException {
-		return connection;
-	}
-
-	public void release() throws SQLException {
-		// we only release the connection
-		if ( connection != null ) {
-			JDBCExceptionReporter.logAndClearWarnings( connection );
-			if ( toggleAutoCommit ) {
-				connection.setAutoCommit( false );
-			}
-			provider.closeConnection( connection );
-			connection = null;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/SuppliedConnectionProviderConnectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tool.hbm2ddl;
+
+import org.hibernate.connection.ConnectionProvider;
+import org.hibernate.util.JDBCExceptionReporter;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+/**
+ * A {@link ConnectionHelper} implementation based on a provided
+ * {@link ConnectionProvider}.  Essentially, ensures that the connection
+ * gets cleaned up, but that the provider itself remains usable since it
+ * was externally provided to us.
+ *
+ * @author Steve Ebersole
+ */
+class SuppliedConnectionProviderConnectionHelper implements ConnectionHelper {
+	private ConnectionProvider provider;
+	private Connection connection;
+	private boolean toggleAutoCommit;
+
+	public SuppliedConnectionProviderConnectionHelper(ConnectionProvider provider) {
+		this.provider = provider;
+	}
+
+	public void prepare(boolean needsAutoCommit) throws SQLException {
+		connection = provider.getConnection();
+		toggleAutoCommit = needsAutoCommit && !connection.getAutoCommit();
+		if ( toggleAutoCommit ) {
+			try {
+				connection.commit();
+			}
+			catch( Throwable ignore ) {
+				// might happen with a managed connection
+			}
+			connection.setAutoCommit( true );
+		}
+	}
+
+	public Connection getConnection() throws SQLException {
+		return connection;
+	}
+
+	public void release() throws SQLException {
+		// we only release the connection
+		if ( connection != null ) {
+			JDBCExceptionReporter.logAndClearWarnings( connection );
+			if ( toggleAutoCommit ) {
+				connection.setAutoCommit( false );
+			}
+			provider.closeConnection( connection );
+			connection = null;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,160 +0,0 @@
-//$Id: TableMetadata.java 10726 2006-11-06 14:50:05Z max.andersen at jboss.com $
-package org.hibernate.tool.hbm2ddl;
-
-import java.sql.DatabaseMetaData;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * JDBC table metadata
- * @author Christoph Sturm, Max Rydahl Andersen
- */
-public class TableMetadata {
-	
-	private static final Logger log = LoggerFactory.getLogger(TableMetadata.class);
-	
-	private final String catalog;
-	private final String schema;
-	private final String name;
-	private final Map columns = new HashMap();
-	private final Map foreignKeys = new HashMap();
-	private final Map indexes = new HashMap();
-
-	TableMetadata(ResultSet rs, DatabaseMetaData meta, boolean extras) throws SQLException {
-		catalog = rs.getString("TABLE_CAT");
-		schema = rs.getString("TABLE_SCHEM");
-		name = rs.getString("TABLE_NAME");
-		initColumns(meta);
-		if (extras) {
-			initForeignKeys(meta);
-			initIndexes(meta);
-		}
-		String cat = catalog==null ? "" : catalog + '.';
-		String schem = schema==null ? "" : schema + '.';
-		log.info( "table found: " + cat + schem + name );
-		log.info( "columns: " + columns.keySet() );
-		if (extras) {
-			log.info( "foreign keys: " + foreignKeys.keySet() );
-			log.info( "indexes: " + indexes.keySet() );
-		}
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String getCatalog() {
-		return catalog;
-	}
-	
-	public String getSchema() {
-		return schema;
-	}
-	
-	public String toString() {
-		return "TableMetadata(" + name + ')';
-	}
-
-	public ColumnMetadata getColumnMetadata(String columnName) {
-		return (ColumnMetadata) columns.get( columnName.toLowerCase() );
-	}
-
-	public ForeignKeyMetadata getForeignKeyMetadata(String keyName) {
-		return (ForeignKeyMetadata) foreignKeys.get( keyName.toLowerCase() );
-	}
-
-	public IndexMetadata getIndexMetadata(String indexName) {
-		return (IndexMetadata) indexes.get( indexName.toLowerCase() );
-	}
-
-	private void addForeignKey(ResultSet rs) throws SQLException {
-		String fk = rs.getString("FK_NAME");
-
-		if (fk == null) return;
-
-		ForeignKeyMetadata info = getForeignKeyMetadata(fk);
-		if (info == null) {
-			info = new ForeignKeyMetadata(rs);
-			foreignKeys.put( info.getName().toLowerCase(), info );
-		}
-
-		info.addColumn( getColumnMetadata( rs.getString("FKCOLUMN_NAME") ) );
-	}
-
-	private void addIndex(ResultSet rs) throws SQLException {
-		String index = rs.getString("INDEX_NAME");
-
-		if (index == null) return;
-
-		IndexMetadata info = getIndexMetadata(index);
-		if (info == null) {
-			info = new IndexMetadata(rs);
-			indexes.put( info.getName().toLowerCase(), info );
-		}
-
-		info.addColumn( getColumnMetadata( rs.getString("COLUMN_NAME") ) );
-	}
-
-	public void addColumn(ResultSet rs) throws SQLException {
-		String column = rs.getString("COLUMN_NAME");
-
-		if (column==null) return;
-
-		if ( getColumnMetadata(column) == null ) {
-			ColumnMetadata info = new ColumnMetadata(rs);
-			columns.put( info.getName().toLowerCase(), info );
-		}
-	}
-
-	private void initForeignKeys(DatabaseMetaData meta) throws SQLException {
-		ResultSet rs = null;
-
-		try {
-			rs = meta.getImportedKeys(catalog, schema, name);
-			while ( rs.next() ) addForeignKey(rs);
-		}
-		finally {
-			if (rs != null) rs.close();
-		}
-	}
-
-	private void initIndexes(DatabaseMetaData meta) throws SQLException {
-		ResultSet rs = null;
-
-		try {
-			rs = meta.getIndexInfo(catalog, schema, name, false, true);
-			
-			while ( rs.next() ) {
-				if ( rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) continue;
-				addIndex(rs);
-			}
-		}
-		finally {
-			if (rs != null) rs.close();
-		}
-	}
-
-	private void initColumns(DatabaseMetaData meta) throws SQLException {
-		ResultSet rs = null;
-		
-		try {
-			rs = meta.getColumns(catalog, schema, name, "%");
-			while ( rs.next() ) addColumn(rs);
-		}
-		finally  {
-			if (rs != null) rs.close();
-		}
-	}
-	
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/TableMetadata.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,183 @@
+/*
+ * 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.tool.hbm2ddl;
+
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * JDBC table metadata
+ * @author Christoph Sturm, Max Rydahl Andersen
+ */
+public class TableMetadata {
+	
+	private static final Logger log = LoggerFactory.getLogger(TableMetadata.class);
+	
+	private final String catalog;
+	private final String schema;
+	private final String name;
+	private final Map columns = new HashMap();
+	private final Map foreignKeys = new HashMap();
+	private final Map indexes = new HashMap();
+
+	TableMetadata(ResultSet rs, DatabaseMetaData meta, boolean extras) throws SQLException {
+		catalog = rs.getString("TABLE_CAT");
+		schema = rs.getString("TABLE_SCHEM");
+		name = rs.getString("TABLE_NAME");
+		initColumns(meta);
+		if (extras) {
+			initForeignKeys(meta);
+			initIndexes(meta);
+		}
+		String cat = catalog==null ? "" : catalog + '.';
+		String schem = schema==null ? "" : schema + '.';
+		log.info( "table found: " + cat + schem + name );
+		log.info( "columns: " + columns.keySet() );
+		if (extras) {
+			log.info( "foreign keys: " + foreignKeys.keySet() );
+			log.info( "indexes: " + indexes.keySet() );
+		}
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getCatalog() {
+		return catalog;
+	}
+	
+	public String getSchema() {
+		return schema;
+	}
+	
+	public String toString() {
+		return "TableMetadata(" + name + ')';
+	}
+
+	public ColumnMetadata getColumnMetadata(String columnName) {
+		return (ColumnMetadata) columns.get( columnName.toLowerCase() );
+	}
+
+	public ForeignKeyMetadata getForeignKeyMetadata(String keyName) {
+		return (ForeignKeyMetadata) foreignKeys.get( keyName.toLowerCase() );
+	}
+
+	public IndexMetadata getIndexMetadata(String indexName) {
+		return (IndexMetadata) indexes.get( indexName.toLowerCase() );
+	}
+
+	private void addForeignKey(ResultSet rs) throws SQLException {
+		String fk = rs.getString("FK_NAME");
+
+		if (fk == null) return;
+
+		ForeignKeyMetadata info = getForeignKeyMetadata(fk);
+		if (info == null) {
+			info = new ForeignKeyMetadata(rs);
+			foreignKeys.put( info.getName().toLowerCase(), info );
+		}
+
+		info.addColumn( getColumnMetadata( rs.getString("FKCOLUMN_NAME") ) );
+	}
+
+	private void addIndex(ResultSet rs) throws SQLException {
+		String index = rs.getString("INDEX_NAME");
+
+		if (index == null) return;
+
+		IndexMetadata info = getIndexMetadata(index);
+		if (info == null) {
+			info = new IndexMetadata(rs);
+			indexes.put( info.getName().toLowerCase(), info );
+		}
+
+		info.addColumn( getColumnMetadata( rs.getString("COLUMN_NAME") ) );
+	}
+
+	public void addColumn(ResultSet rs) throws SQLException {
+		String column = rs.getString("COLUMN_NAME");
+
+		if (column==null) return;
+
+		if ( getColumnMetadata(column) == null ) {
+			ColumnMetadata info = new ColumnMetadata(rs);
+			columns.put( info.getName().toLowerCase(), info );
+		}
+	}
+
+	private void initForeignKeys(DatabaseMetaData meta) throws SQLException {
+		ResultSet rs = null;
+
+		try {
+			rs = meta.getImportedKeys(catalog, schema, name);
+			while ( rs.next() ) addForeignKey(rs);
+		}
+		finally {
+			if (rs != null) rs.close();
+		}
+	}
+
+	private void initIndexes(DatabaseMetaData meta) throws SQLException {
+		ResultSet rs = null;
+
+		try {
+			rs = meta.getIndexInfo(catalog, schema, name, false, true);
+			
+			while ( rs.next() ) {
+				if ( rs.getShort("TYPE") == DatabaseMetaData.tableIndexStatistic ) continue;
+				addIndex(rs);
+			}
+		}
+		finally {
+			if (rs != null) rs.close();
+		}
+	}
+
+	private void initColumns(DatabaseMetaData meta) throws SQLException {
+		ResultSet rs = null;
+		
+		try {
+			rs = meta.getColumns(catalog, schema, name, "%");
+			while ( rs.next() ) addColumn(rs);
+		}
+		finally  {
+			if (rs != null) rs.close();
+		}
+	}
+	
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	The <tt>hbm2ddl</tt> tool.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/hbm2ddl/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	The <tt>hbm2ddl</tt> tool.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,383 +0,0 @@
-package org.hibernate.tool.instrument;
-
-import org.apache.tools.ant.Task;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.Project;
-import org.apache.tools.ant.DirectoryScanner;
-import org.apache.tools.ant.types.FileSet;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.ByteCodeHelper;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.util.StringHelper;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.zip.ZipInputStream;
-import java.util.zip.ZipOutputStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.CRC32;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStream;
-import java.io.IOException;
-import java.io.FileInputStream;
-import java.io.DataInputStream;
-import java.io.ByteArrayInputStream;
-
-/**
- * Super class for all Hibernate instrumentation tasks.  Provides the basic
- * templating of how instrumentation should occur.
- *
- * @author Steve Ebersole
- */
-public abstract class BasicInstrumentationTask extends Task {
-
-	private static final int ZIP_MAGIC = 0x504B0304;
-	private static final int CLASS_MAGIC = 0xCAFEBABE;
-
-	protected final Logger logger = new Logger();
-	private List filesets = new ArrayList();
-	private Set classNames = new HashSet();
-	private boolean extended;
-	private boolean verbose;
-
-	public void addFileset(FileSet set) {
-		this.filesets.add( set );
-	}
-
-	protected final Iterator filesets() {
-		return filesets.iterator();
-	}
-
-	public boolean isExtended() {
-		return extended;
-	}
-
-	public void setExtended(boolean extended) {
-		this.extended = extended;
-	}
-
-	public boolean isVerbose() {
-		return verbose;
-	}
-
-	public void setVerbose(boolean verbose) {
-		this.verbose = verbose;
-	}
-
-	public void execute() throws BuildException {
-		if ( isExtended() ) {
-			collectClassNames();
-		}
-		logger.info( "starting instrumentation" );
-		Project project = getProject();
-		Iterator filesets = filesets();
-		while ( filesets.hasNext() ) {
-			FileSet fs = ( FileSet ) filesets.next();
-			DirectoryScanner ds = fs.getDirectoryScanner( project );
-			String[] includedFiles = ds.getIncludedFiles();
-			File d = fs.getDir( project );
-			for ( int i = 0; i < includedFiles.length; ++i ) {
-				File file = new File( d, includedFiles[i] );
-				try {
-					processFile( file );
-				}
-				catch ( Exception e ) {
-					throw new BuildException( e );
-				}
-			}
-		}
-	}
-
-	private void collectClassNames() {
-		logger.info( "collecting class names for extended instrumentation determination" );
-		Project project = getProject();
-		Iterator filesets = filesets();
-		while ( filesets.hasNext() ) {
-			FileSet fs = ( FileSet ) filesets.next();
-			DirectoryScanner ds = fs.getDirectoryScanner( project );
-			String[] includedFiles = ds.getIncludedFiles();
-			File d = fs.getDir( project );
-			for ( int i = 0; i < includedFiles.length; ++i ) {
-				File file = new File( d, includedFiles[i] );
-				try {
-					collectClassNames( file );
-				}
-				catch ( Exception e ) {
-					throw new BuildException( e );
-				}
-			}
-		}
-		logger.info( classNames.size() + " class(es) being checked" );
-	}
-
-	private void collectClassNames(File file) throws Exception {
-	    if ( isClassFile( file ) ) {
-			byte[] bytes = ByteCodeHelper.readByteCode( file );
-			ClassDescriptor descriptor = getClassDescriptor( bytes );
-		    classNames.add( descriptor.getName() );
-	    }
-	    else if ( isJarFile( file ) ) {
-		    ZipEntryHandler collector = new ZipEntryHandler() {
-			    public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
-					if ( !entry.isDirectory() ) {
-						// see if the entry represents a class file
-						DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
-						if ( din.readInt() == CLASS_MAGIC ) {
-				            classNames.add( getClassDescriptor( byteCode ).getName() );
-						}
-					}
-			    }
-		    };
-		    ZipFileProcessor processor = new ZipFileProcessor( collector );
-		    processor.process( file );
-	    }
-	}
-
-	protected void processFile(File file) throws Exception {
-		logger.verbose( "processing file : " + file.toURL() );
-	    if ( isClassFile( file ) ) {
-	        processClassFile(file);
-	    }
-	    else if ( isJarFile( file ) ) {
-	        processJarFile(file);
-	    }
-	    else {
-		    logger.verbose( "ignoring " + file.toURL() );
-
-	    }
-	}
-
-	protected final boolean isClassFile(File file) throws IOException {
-        return checkMagic( file, CLASS_MAGIC );
-    }
-
-    protected final boolean isJarFile(File file) throws IOException {
-        return checkMagic(file, ZIP_MAGIC);
-    }
-
-	protected final boolean checkMagic(File file, long magic) throws IOException {
-        DataInputStream in = new DataInputStream( new FileInputStream( file ) );
-        try {
-            int m = in.readInt();
-            return magic == m;
-        }
-        finally {
-            in.close();
-        }
-    }
-
-	protected void processClassFile(File file) throws Exception {
-		logger.verbose( "Starting class file : " + file.toURL() );
-		byte[] bytes = ByteCodeHelper.readByteCode( file );
-		ClassDescriptor descriptor = getClassDescriptor( bytes );
-		ClassTransformer transformer = getClassTransformer( descriptor );
-		if ( transformer == null ) {
-			logger.verbose( "skipping file : " + file.toURL() );
-			return;
-		}
-
-		logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() );
-		byte[] transformedBytes = transformer.transform(
-				getClass().getClassLoader(),
-				descriptor.getName(),
-				null,
-				null,
-				descriptor.getBytes()
-		);
-
-		OutputStream out = new FileOutputStream( file );
-		try {
-			out.write( transformedBytes );
-			out.flush();
-		}
-		finally {
-			try {
-				out.close();
-			}
-			catch ( IOException ignore) {
-				// intentionally empty
-			}
-		}
-	}
-
-	protected void processJarFile(final File file) throws Exception {
-		logger.verbose( "starting jar file : " + file.toURL() );
-
-        File tempFile = File.createTempFile(
-		        file.getName(),
-		        null,
-		        new File( file.getAbsoluteFile().getParent() )
-        );
-
-        try {
-			FileOutputStream fout = new FileOutputStream( tempFile, false );
-			try {
-				final ZipOutputStream out = new ZipOutputStream( fout );
-				ZipEntryHandler transformer = new ZipEntryHandler() {
-					public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
-								logger.verbose( "starting entry : " + entry.toString() );
-								if ( !entry.isDirectory() ) {
-									// see if the entry represents a class file
-									DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
-									if ( din.readInt() == CLASS_MAGIC ) {
-										ClassDescriptor descriptor = getClassDescriptor( byteCode );
-										ClassTransformer transformer = getClassTransformer( descriptor );
-										if ( transformer == null ) {
-											logger.verbose( "skipping entry : " + entry.toString() );
-										}
-										else {
-											logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() );
-											byteCode = transformer.transform(
-													getClass().getClassLoader(),
-													descriptor.getName(),
-													null,
-													null,
-													descriptor.getBytes()
-											);
-										}
-									}
-									else {
-										logger.verbose( "ignoring zip entry : " + entry.toString() );
-									}
-								}
-
-								ZipEntry outEntry = new ZipEntry( entry.getName() );
-								outEntry.setMethod( entry.getMethod() );
-								outEntry.setComment( entry.getComment() );
-								outEntry.setSize( byteCode.length );
-
-								if ( outEntry.getMethod() == ZipEntry.STORED ){
-									CRC32 crc = new CRC32();
-									crc.update( byteCode );
-									outEntry.setCrc( crc.getValue() );
-									outEntry.setCompressedSize( byteCode.length );
-								}
-								out.putNextEntry( outEntry );
-								out.write( byteCode );
-								out.closeEntry();
-					}
-				};
-				ZipFileProcessor processor = new ZipFileProcessor( transformer );
-				processor.process( file );
-				out.close();
-			}
-			finally{
-				fout.close();
-			}
-
-            if ( file.delete() ) {
-	            File newFile = new File( tempFile.getAbsolutePath() );
-                if( !newFile.renameTo( file ) ) {
-	                throw new IOException( "can not rename " + tempFile + " to " + file );
-                }
-            }
-            else {
-	            throw new IOException("can not delete " + file);
-            }
-        }
-        finally {
-	        tempFile.delete();
-        }
-	}
-
-	protected boolean isBeingIntrumented(String className) {
-		logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" );
-		return classNames.contains( className );
-	}
-
-	protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
-
-	protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor);
-
-	protected class CustomFieldFilter implements FieldFilter {
-		private final ClassDescriptor descriptor;
-
-		public CustomFieldFilter(ClassDescriptor descriptor) {
-			this.descriptor = descriptor;
-		}
-
-		public boolean shouldInstrumentField(String className, String fieldName) {
-			if ( descriptor.getName().equals( className ) ) {
-				logger.verbose( "accepting transformation of field [" + className + "." + fieldName + "]" );
-				return true;
-			}
-			else {
-				logger.verbose( "rejecting transformation of field [" + className + "." + fieldName + "]" );
-				return false;
-			}
-		}
-
-		public boolean shouldTransformFieldAccess(
-				String transformingClassName,
-				String fieldOwnerClassName,
-				String fieldName) {
-			if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
-				logger.verbose( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
-				return true;
-			}
-			else if ( isExtended() && isBeingIntrumented( fieldOwnerClassName ) ) {
-				logger.verbose( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
-				return true;
-			}
-			else {
-				logger.verbose( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName  );
-				return false;
-			}
-		}
-	}
-
-	protected class Logger {
-		public void verbose(String message) {
-			if ( verbose ) {
-				System.out.println( message );
-			}
-			log( message, Project.MSG_VERBOSE );
-		}
-
-		public void debug(String message) {
-			log( message, Project.MSG_DEBUG );
-		}
-
-		public void info(String message) {
-			log( message, Project.MSG_INFO );
-		}
-
-		public void warn(String message) {
-			log( message, Project.MSG_WARN );
-		}
-	}
-
-
-	private static interface ZipEntryHandler {
-		public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
-	}
-
-	private static class ZipFileProcessor {
-		private final ZipEntryHandler entryHandler;
-
-		public ZipFileProcessor(ZipEntryHandler entryHandler) {
-			this.entryHandler = entryHandler;
-		}
-
-		public void process(File file) throws Exception {
-			ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
-
-			try {
-				ZipEntry entry;
-				while ( (entry = zip.getNextEntry()) != null ) {
-					byte bytes[] = ByteCodeHelper.readByteCode( zip );
-					entryHandler.handleEntry( entry, bytes );
-					zip.closeEntry();
-				}
-            }
-            finally {
-	            zip.close();
-            }
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/BasicInstrumentationTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,406 @@
+/*
+ * 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.tool.instrument;
+
+import org.apache.tools.ant.Task;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.DirectoryScanner;
+import org.apache.tools.ant.types.FileSet;
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.ByteCodeHelper;
+import org.hibernate.bytecode.util.FieldFilter;
+import org.hibernate.bytecode.ClassTransformer;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.CRC32;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.io.FileInputStream;
+import java.io.DataInputStream;
+import java.io.ByteArrayInputStream;
+
+/**
+ * Super class for all Hibernate instrumentation tasks.  Provides the basic
+ * templating of how instrumentation should occur.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class BasicInstrumentationTask extends Task {
+
+	private static final int ZIP_MAGIC = 0x504B0304;
+	private static final int CLASS_MAGIC = 0xCAFEBABE;
+
+	protected final Logger logger = new Logger();
+	private List filesets = new ArrayList();
+	private Set classNames = new HashSet();
+	private boolean extended;
+	private boolean verbose;
+
+	public void addFileset(FileSet set) {
+		this.filesets.add( set );
+	}
+
+	protected final Iterator filesets() {
+		return filesets.iterator();
+	}
+
+	public boolean isExtended() {
+		return extended;
+	}
+
+	public void setExtended(boolean extended) {
+		this.extended = extended;
+	}
+
+	public boolean isVerbose() {
+		return verbose;
+	}
+
+	public void setVerbose(boolean verbose) {
+		this.verbose = verbose;
+	}
+
+	public void execute() throws BuildException {
+		if ( isExtended() ) {
+			collectClassNames();
+		}
+		logger.info( "starting instrumentation" );
+		Project project = getProject();
+		Iterator filesets = filesets();
+		while ( filesets.hasNext() ) {
+			FileSet fs = ( FileSet ) filesets.next();
+			DirectoryScanner ds = fs.getDirectoryScanner( project );
+			String[] includedFiles = ds.getIncludedFiles();
+			File d = fs.getDir( project );
+			for ( int i = 0; i < includedFiles.length; ++i ) {
+				File file = new File( d, includedFiles[i] );
+				try {
+					processFile( file );
+				}
+				catch ( Exception e ) {
+					throw new BuildException( e );
+				}
+			}
+		}
+	}
+
+	private void collectClassNames() {
+		logger.info( "collecting class names for extended instrumentation determination" );
+		Project project = getProject();
+		Iterator filesets = filesets();
+		while ( filesets.hasNext() ) {
+			FileSet fs = ( FileSet ) filesets.next();
+			DirectoryScanner ds = fs.getDirectoryScanner( project );
+			String[] includedFiles = ds.getIncludedFiles();
+			File d = fs.getDir( project );
+			for ( int i = 0; i < includedFiles.length; ++i ) {
+				File file = new File( d, includedFiles[i] );
+				try {
+					collectClassNames( file );
+				}
+				catch ( Exception e ) {
+					throw new BuildException( e );
+				}
+			}
+		}
+		logger.info( classNames.size() + " class(es) being checked" );
+	}
+
+	private void collectClassNames(File file) throws Exception {
+	    if ( isClassFile( file ) ) {
+			byte[] bytes = ByteCodeHelper.readByteCode( file );
+			ClassDescriptor descriptor = getClassDescriptor( bytes );
+		    classNames.add( descriptor.getName() );
+	    }
+	    else if ( isJarFile( file ) ) {
+		    ZipEntryHandler collector = new ZipEntryHandler() {
+			    public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+					if ( !entry.isDirectory() ) {
+						// see if the entry represents a class file
+						DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+						if ( din.readInt() == CLASS_MAGIC ) {
+				            classNames.add( getClassDescriptor( byteCode ).getName() );
+						}
+					}
+			    }
+		    };
+		    ZipFileProcessor processor = new ZipFileProcessor( collector );
+		    processor.process( file );
+	    }
+	}
+
+	protected void processFile(File file) throws Exception {
+		logger.verbose( "processing file : " + file.toURL() );
+	    if ( isClassFile( file ) ) {
+	        processClassFile(file);
+	    }
+	    else if ( isJarFile( file ) ) {
+	        processJarFile(file);
+	    }
+	    else {
+		    logger.verbose( "ignoring " + file.toURL() );
+
+	    }
+	}
+
+	protected final boolean isClassFile(File file) throws IOException {
+        return checkMagic( file, CLASS_MAGIC );
+    }
+
+    protected final boolean isJarFile(File file) throws IOException {
+        return checkMagic(file, ZIP_MAGIC);
+    }
+
+	protected final boolean checkMagic(File file, long magic) throws IOException {
+        DataInputStream in = new DataInputStream( new FileInputStream( file ) );
+        try {
+            int m = in.readInt();
+            return magic == m;
+        }
+        finally {
+            in.close();
+        }
+    }
+
+	protected void processClassFile(File file) throws Exception {
+		logger.verbose( "Starting class file : " + file.toURL() );
+		byte[] bytes = ByteCodeHelper.readByteCode( file );
+		ClassDescriptor descriptor = getClassDescriptor( bytes );
+		ClassTransformer transformer = getClassTransformer( descriptor );
+		if ( transformer == null ) {
+			logger.verbose( "skipping file : " + file.toURL() );
+			return;
+		}
+
+		logger.info( "processing class [" + descriptor.getName() + "]; file = " + file.toURL() );
+		byte[] transformedBytes = transformer.transform(
+				getClass().getClassLoader(),
+				descriptor.getName(),
+				null,
+				null,
+				descriptor.getBytes()
+		);
+
+		OutputStream out = new FileOutputStream( file );
+		try {
+			out.write( transformedBytes );
+			out.flush();
+		}
+		finally {
+			try {
+				out.close();
+			}
+			catch ( IOException ignore) {
+				// intentionally empty
+			}
+		}
+	}
+
+	protected void processJarFile(final File file) throws Exception {
+		logger.verbose( "starting jar file : " + file.toURL() );
+
+        File tempFile = File.createTempFile(
+		        file.getName(),
+		        null,
+		        new File( file.getAbsoluteFile().getParent() )
+        );
+
+        try {
+			FileOutputStream fout = new FileOutputStream( tempFile, false );
+			try {
+				final ZipOutputStream out = new ZipOutputStream( fout );
+				ZipEntryHandler transformer = new ZipEntryHandler() {
+					public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception {
+								logger.verbose( "starting entry : " + entry.toString() );
+								if ( !entry.isDirectory() ) {
+									// see if the entry represents a class file
+									DataInputStream din = new DataInputStream( new ByteArrayInputStream( byteCode ) );
+									if ( din.readInt() == CLASS_MAGIC ) {
+										ClassDescriptor descriptor = getClassDescriptor( byteCode );
+										ClassTransformer transformer = getClassTransformer( descriptor );
+										if ( transformer == null ) {
+											logger.verbose( "skipping entry : " + entry.toString() );
+										}
+										else {
+											logger.info( "processing class [" + descriptor.getName() + "]; entry = " + file.toURL() );
+											byteCode = transformer.transform(
+													getClass().getClassLoader(),
+													descriptor.getName(),
+													null,
+													null,
+													descriptor.getBytes()
+											);
+										}
+									}
+									else {
+										logger.verbose( "ignoring zip entry : " + entry.toString() );
+									}
+								}
+
+								ZipEntry outEntry = new ZipEntry( entry.getName() );
+								outEntry.setMethod( entry.getMethod() );
+								outEntry.setComment( entry.getComment() );
+								outEntry.setSize( byteCode.length );
+
+								if ( outEntry.getMethod() == ZipEntry.STORED ){
+									CRC32 crc = new CRC32();
+									crc.update( byteCode );
+									outEntry.setCrc( crc.getValue() );
+									outEntry.setCompressedSize( byteCode.length );
+								}
+								out.putNextEntry( outEntry );
+								out.write( byteCode );
+								out.closeEntry();
+					}
+				};
+				ZipFileProcessor processor = new ZipFileProcessor( transformer );
+				processor.process( file );
+				out.close();
+			}
+			finally{
+				fout.close();
+			}
+
+            if ( file.delete() ) {
+	            File newFile = new File( tempFile.getAbsolutePath() );
+                if( !newFile.renameTo( file ) ) {
+	                throw new IOException( "can not rename " + tempFile + " to " + file );
+                }
+            }
+            else {
+	            throw new IOException("can not delete " + file);
+            }
+        }
+        finally {
+	        tempFile.delete();
+        }
+	}
+
+	protected boolean isBeingIntrumented(String className) {
+		logger.verbose( "checking to see if class [" + className + "] is set to be instrumented" );
+		return classNames.contains( className );
+	}
+
+	protected abstract ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception;
+
+	protected abstract ClassTransformer getClassTransformer(ClassDescriptor descriptor);
+
+	protected class CustomFieldFilter implements FieldFilter {
+		private final ClassDescriptor descriptor;
+
+		public CustomFieldFilter(ClassDescriptor descriptor) {
+			this.descriptor = descriptor;
+		}
+
+		public boolean shouldInstrumentField(String className, String fieldName) {
+			if ( descriptor.getName().equals( className ) ) {
+				logger.verbose( "accepting transformation of field [" + className + "." + fieldName + "]" );
+				return true;
+			}
+			else {
+				logger.verbose( "rejecting transformation of field [" + className + "." + fieldName + "]" );
+				return false;
+			}
+		}
+
+		public boolean shouldTransformFieldAccess(
+				String transformingClassName,
+				String fieldOwnerClassName,
+				String fieldName) {
+			if ( descriptor.getName().equals( fieldOwnerClassName ) ) {
+				logger.verbose( "accepting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+				return true;
+			}
+			else if ( isExtended() && isBeingIntrumented( fieldOwnerClassName ) ) {
+				logger.verbose( "accepting extended transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]" );
+				return true;
+			}
+			else {
+				logger.verbose( "rejecting transformation of field access [" + fieldOwnerClassName + "." + fieldName + "]; caller = " + transformingClassName  );
+				return false;
+			}
+		}
+	}
+
+	protected class Logger {
+		public void verbose(String message) {
+			if ( verbose ) {
+				System.out.println( message );
+			}
+			log( message, Project.MSG_VERBOSE );
+		}
+
+		public void debug(String message) {
+			log( message, Project.MSG_DEBUG );
+		}
+
+		public void info(String message) {
+			log( message, Project.MSG_INFO );
+		}
+
+		public void warn(String message) {
+			log( message, Project.MSG_WARN );
+		}
+	}
+
+
+	private static interface ZipEntryHandler {
+		public void handleEntry(ZipEntry entry, byte[] byteCode) throws Exception;
+	}
+
+	private static class ZipFileProcessor {
+		private final ZipEntryHandler entryHandler;
+
+		public ZipFileProcessor(ZipEntryHandler entryHandler) {
+			this.entryHandler = entryHandler;
+		}
+
+		public void process(File file) throws Exception {
+			ZipInputStream zip = new ZipInputStream( new FileInputStream( file ) );
+
+			try {
+				ZipEntry entry;
+				while ( (entry = zip.getNextEntry()) != null ) {
+					byte bytes[] = ByteCodeHelper.readByteCode( zip );
+					entryHandler.handleEntry( entry, bytes );
+					zip.closeEntry();
+				}
+            }
+            finally {
+	            zip.close();
+            }
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,106 +0,0 @@
-//$Id: InstrumentTask.java 10206 2006-08-03 19:59:42Z steve.ebersole at jboss.com $
-package org.hibernate.tool.instrument.cglib;
-
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.repackage.cglib.asm.ClassReader;
-
-import java.io.ByteArrayInputStream;
-
-import org.hibernate.repackage.cglib.core.ClassNameReader;
-import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
-
-/**
- * An Ant task for instrumenting persistent classes in order to enable
- * field-level interception using CGLIB.
- * <p/>
- * In order to use this task, typically you would define a a taskdef
- * similiar to:<pre>
- * <taskdef name="instrument" classname="org.hibernate.tool.instrument.cglib.InstrumentTask">
- *     <classpath refid="lib.class.path"/>
- * </taskdef>
- * </pre>
- * where <tt>lib.class.path</tt> is an ANT path reference containing all the
- * required Hibernate and CGLIB libraries.
- * <p/>
- * And then use it like:<pre>
- * <instrument verbose="true">
- *     <fileset dir="${testclasses.dir}/org/hibernate/test">
- *         <include name="yadda/yadda/**"/>
- *         ...
- *     </fileset>
- * </instrument>
- * </pre>
- * where the nested ANT fileset includes the class you would like to have
- * instrumented.
- * <p/>
- * Optionally you can chose to enable "Extended Instrumentation" if desired
- * by specifying the extended attriubute on the task:<pre>
- * <instrument verbose="true" extended="true">
- *     ...
- * </instrument>
- * </pre>
- * See the Hibernate manual regarding this option.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class InstrumentTask extends BasicInstrumentationTask {
-
-	private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
-	private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
-
-	protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
-		return new CustomClassDescriptor( byecode );
-	}
-
-	protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
-		if ( descriptor.isInstrumented() ) {
-			logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
-			return null;
-		}
-		else {
-			return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
-		}
-	}
-
-	private static class CustomClassDescriptor implements ClassDescriptor {
-		private final byte[] bytecode;
-		private final String name;
-		private final boolean isInstrumented;
-
-		public CustomClassDescriptor(byte[] bytecode) throws Exception {
-			this.bytecode = bytecode;
-			ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
-			String[] names = ClassNameReader.getClassInfo( reader );
-			this.name = names[0];
-			boolean instrumented = false;
-			for ( int i = 1; i < names.length; i++ ) {
-				if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
-					instrumented = true;
-					break;
-				}
-			}
-			this.isInstrumented = instrumented;
-		}
-
-		public String getName() {
-			return name;
-		}
-
-		public boolean isInstrumented() {
-			return isInstrumented;
-		}
-
-		public byte[] getBytes() {
-			return bytecode;
-		}
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/cglib/InstrumentTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,129 @@
+/*
+ * 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.tool.instrument.cglib;
+
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.cglib.BytecodeProviderImpl;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.tool.instrument.BasicInstrumentationTask;
+import org.hibernate.repackage.cglib.asm.ClassReader;
+
+import java.io.ByteArrayInputStream;
+
+import org.hibernate.repackage.cglib.core.ClassNameReader;
+import org.hibernate.repackage.cglib.transform.impl.InterceptFieldEnabled;
+
+/**
+ * An Ant task for instrumenting persistent classes in order to enable
+ * field-level interception using CGLIB.
+ * <p/>
+ * In order to use this task, typically you would define a a taskdef
+ * similiar to:<pre>
+ * <taskdef name="instrument" classname="org.hibernate.tool.instrument.cglib.InstrumentTask">
+ *     <classpath refid="lib.class.path"/>
+ * </taskdef>
+ * </pre>
+ * where <tt>lib.class.path</tt> is an ANT path reference containing all the
+ * required Hibernate and CGLIB libraries.
+ * <p/>
+ * And then use it like:<pre>
+ * <instrument verbose="true">
+ *     <fileset dir="${testclasses.dir}/org/hibernate/test">
+ *         <include name="yadda/yadda/**"/>
+ *         ...
+ *     </fileset>
+ * </instrument>
+ * </pre>
+ * where the nested ANT fileset includes the class you would like to have
+ * instrumented.
+ * <p/>
+ * Optionally you can chose to enable "Extended Instrumentation" if desired
+ * by specifying the extended attriubute on the task:<pre>
+ * <instrument verbose="true" extended="true">
+ *     ...
+ * </instrument>
+ * </pre>
+ * See the Hibernate manual regarding this option.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class InstrumentTask extends BasicInstrumentationTask {
+
+	private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+	private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+
+	protected ClassDescriptor getClassDescriptor(byte[] byecode) throws Exception {
+		return new CustomClassDescriptor( byecode );
+	}
+
+	protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
+		if ( descriptor.isInstrumented() ) {
+			logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
+			return null;
+		}
+		else {
+			return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
+		}
+	}
+
+	private static class CustomClassDescriptor implements ClassDescriptor {
+		private final byte[] bytecode;
+		private final String name;
+		private final boolean isInstrumented;
+
+		public CustomClassDescriptor(byte[] bytecode) throws Exception {
+			this.bytecode = bytecode;
+			ClassReader reader = new ClassReader( new ByteArrayInputStream( bytecode ) );
+			String[] names = ClassNameReader.getClassInfo( reader );
+			this.name = names[0];
+			boolean instrumented = false;
+			for ( int i = 1; i < names.length; i++ ) {
+				if ( InterceptFieldEnabled.class.getName().equals( names[i] ) ) {
+					instrumented = true;
+					break;
+				}
+			}
+			this.isInstrumented = instrumented;
+		}
+
+		public String getName() {
+			return name;
+		}
+
+		public boolean isInstrumented() {
+			return isInstrumented;
+		}
+
+		public byte[] getBytes() {
+			return bytecode;
+		}
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-package org.hibernate.tool.instrument.javassist;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.io.ByteArrayInputStream;
-
-import javassist.bytecode.ClassFile;
-
-import org.hibernate.tool.instrument.BasicInstrumentationTask;
-import org.hibernate.bytecode.util.ClassDescriptor;
-import org.hibernate.bytecode.util.BasicClassFilter;
-import org.hibernate.bytecode.util.FieldFilter;
-import org.hibernate.bytecode.ClassTransformer;
-import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
-import org.hibernate.bytecode.javassist.FieldHandled;
-
-/**
- * An Ant task for instrumenting persistent classes in order to enable
- * field-level interception using Javassist.
- * <p/>
- * In order to use this task, typically you would define a a taskdef
- * similiar to:<pre>
- * <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
- *     <classpath refid="lib.class.path"/>
- * </taskdef>
- * </pre>
- * where <tt>lib.class.path</tt> is an ANT path reference containing all the
- * required Hibernate and Javassist libraries.
- * <p/>
- * And then use it like:<pre>
- * <instrument verbose="true">
- *     <fileset dir="${testclasses.dir}/org/hibernate/test">
- *         <include name="yadda/yadda/**"/>
- *         ...
- *     </fileset>
- * </instrument>
- * </pre>
- * where the nested ANT fileset includes the class you would like to have
- * instrumented.
- * <p/>
- * Optionally you can chose to enable "Extended Instrumentation" if desired
- * by specifying the extended attriubute on the task:<pre>
- * <instrument verbose="true" extended="true">
- *     ...
- * </instrument>
- * </pre>
- * See the Hibernate manual regarding this option.
- *
- * @author Muga Nishizawa
- * @author Steve Ebersole
- */
-public class InstrumentTask extends BasicInstrumentationTask {
-
-	private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
-
-	private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
-
-	protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
-		return new CustomClassDescriptor( bytecode );
-	}
-
-	protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
-		if ( descriptor.isInstrumented() ) {
-			logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
-			return null;
-		}
-		else {
-			return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
-		}
-	}
-
-	private static class CustomClassDescriptor implements ClassDescriptor {
-		private final byte[] bytes;
-		private final ClassFile classFile;
-
-		public CustomClassDescriptor(byte[] bytes) throws IOException {
-			this.bytes = bytes;
-			this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
-		}
-
-		public String getName() {
-			return classFile.getName();
-		}
-
-		public boolean isInstrumented() {
-			String[] intfs = classFile.getInterfaces();
-			for ( int i = 0; i < intfs.length; i++ ) {
-				if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
-					return true;
-				}
-			}
-			return false;
-		}
-
-		public byte[] getBytes() {
-			return bytes;
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/javassist/InstrumentTask.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,123 @@
+/*
+ * 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.tool.instrument.javassist;
+
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.ByteArrayInputStream;
+
+import javassist.bytecode.ClassFile;
+
+import org.hibernate.tool.instrument.BasicInstrumentationTask;
+import org.hibernate.bytecode.util.ClassDescriptor;
+import org.hibernate.bytecode.util.BasicClassFilter;
+import org.hibernate.bytecode.ClassTransformer;
+import org.hibernate.bytecode.javassist.BytecodeProviderImpl;
+import org.hibernate.bytecode.javassist.FieldHandled;
+
+/**
+ * An Ant task for instrumenting persistent classes in order to enable
+ * field-level interception using Javassist.
+ * <p/>
+ * In order to use this task, typically you would define a a taskdef
+ * similiar to:<pre>
+ * <taskdef name="instrument" classname="org.hibernate.tool.instrument.javassist.InstrumentTask">
+ *     <classpath refid="lib.class.path"/>
+ * </taskdef>
+ * </pre>
+ * where <tt>lib.class.path</tt> is an ANT path reference containing all the
+ * required Hibernate and Javassist libraries.
+ * <p/>
+ * And then use it like:<pre>
+ * <instrument verbose="true">
+ *     <fileset dir="${testclasses.dir}/org/hibernate/test">
+ *         <include name="yadda/yadda/**"/>
+ *         ...
+ *     </fileset>
+ * </instrument>
+ * </pre>
+ * where the nested ANT fileset includes the class you would like to have
+ * instrumented.
+ * <p/>
+ * Optionally you can chose to enable "Extended Instrumentation" if desired
+ * by specifying the extended attriubute on the task:<pre>
+ * <instrument verbose="true" extended="true">
+ *     ...
+ * </instrument>
+ * </pre>
+ * See the Hibernate manual regarding this option.
+ *
+ * @author Muga Nishizawa
+ * @author Steve Ebersole
+ */
+public class InstrumentTask extends BasicInstrumentationTask {
+
+	private static final BasicClassFilter CLASS_FILTER = new BasicClassFilter();
+
+	private final BytecodeProviderImpl provider = new BytecodeProviderImpl();
+
+	protected ClassDescriptor getClassDescriptor(byte[] bytecode) throws IOException {
+		return new CustomClassDescriptor( bytecode );
+	}
+
+	protected ClassTransformer getClassTransformer(ClassDescriptor descriptor) {
+		if ( descriptor.isInstrumented() ) {
+			logger.verbose( "class [" + descriptor.getName() + "] already instrumented" );
+			return null;
+		}
+		else {
+			return provider.getTransformer( CLASS_FILTER, new CustomFieldFilter( descriptor ) );
+		}
+	}
+
+	private static class CustomClassDescriptor implements ClassDescriptor {
+		private final byte[] bytes;
+		private final ClassFile classFile;
+
+		public CustomClassDescriptor(byte[] bytes) throws IOException {
+			this.bytes = bytes;
+			this.classFile = new ClassFile( new DataInputStream( new ByteArrayInputStream( bytes ) ) );
+		}
+
+		public String getName() {
+			return classFile.getName();
+		}
+
+		public boolean isInstrumented() {
+			String[] intfs = classFile.getInterfaces();
+			for ( int i = 0; i < intfs.length; i++ ) {
+				if ( FieldHandled.class.getName().equals( intfs[i] ) ) {
+					return true;
+				}
+			}
+			return false;
+		}
+
+		public byte[] getBytes() {
+			return bytes;
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tool/instrument/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,11 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	The <tt>instrument</tt> tool for adding field-interception hooks
-	to persistent classes using built-time bytecode processing. Use
-	this tool only if you wish to take advantage of lazy property
-	fetching (the <tt>&lt;lazy&gt;</tt> mapping element).
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tool/instrument/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tool/instrument/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	The <tt>instrument</tt> tool for adding field-interception hooks
+	to persistent classes using built-time bytecode processing. Use
+	this tool only if you wish to take advantage of lazy property
+	fetching (the <tt>&lt;lazy&gt;</tt> mapping element).
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +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.transaction;
-
-/**
- * A <tt>TransactionManager</tt> lookup strategy for Borland ES.
- *
- * @author Etienne Hardy
- */
-public final class BESTransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	protected String getName() {
-		return "java:pm/TransactionManager";
-	}
-
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BESTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.transaction;
+
+/**
+ * A <tt>TransactionManager</tt> lookup strategy for Borland ES.
+ *
+ * @author Etienne Hardy
+ */
+public final class BESTransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	protected String getName() {
+		return "java:pm/TransactionManager";
+	}
+
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-
-/**
- * TransactionManager lookup strategy for BTM
- *
- * @author Ludovic Orban
- */
-public class BTMTransactionManagerLookup implements TransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		try {
-			Class clazz = Class.forName("bitronix.tm.TransactionManagerServices");
-			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException( "Could not obtain BTM transaction manager instance", e );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		return transaction;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/BTMTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,67 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.hibernate.HibernateException;
+
+/**
+ * TransactionManager lookup strategy for BTM
+ *
+ * @author Ludovic Orban
+ */
+public class BTMTransactionManagerLookup implements TransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		try {
+			Class clazz = Class.forName("bitronix.tm.TransactionManagerServices");
+			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException( "Could not obtain BTM transaction manager instance", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		return transaction;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/CMTTransaction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,223 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * Implements a basic transaction strategy for CMT transactions. All work is
- * done in the context of the container managed transaction.
- * <p/>
- * The term 'CMT' is potentially misleading here; the pertinent point simply
- * being that the transactions are being managed by something other than the
- * Hibernate transaction mechanism.
- *
- * @author Gavin King
- */
-public class CMTTransaction implements Transaction {
-
-	private static final Logger log = LoggerFactory.getLogger(CMTTransaction.class);
-
-	protected final JDBCContext jdbcContext;
-	protected final TransactionFactory.Context transactionContext;
-
-	private boolean begun;
-
-	public CMTTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
-		this.jdbcContext = jdbcContext;
-		this.transactionContext = transactionContext;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void begin() throws HibernateException {
-		if (begun) {
-			return;
-		}
-
-		log.debug("begin");
-		
-		boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
-
-		if ( !synchronization ) {
-			throw new TransactionException("Could not register synchronization for container transaction");
-		}
-
-		begun = true;
-		
-		jdbcContext.afterTransactionBegin(this);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void commit() throws HibernateException {
-		if (!begun) {
-			throw new TransactionException("Transaction not successfully started");
-		}
-
-		log.debug("commit");
-
-		boolean flush = !transactionContext.isFlushModeNever() &&
-		        !transactionContext.isFlushBeforeCompletionEnabled();
-
-		if (flush) {
-			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
-		}
-
-		begun = false;
-
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void rollback() throws HibernateException {
-		if (!begun) {
-			throw new TransactionException("Transaction not successfully started");
-		}
-
-		log.debug("rollback");
-
-		try {
-			getTransaction().setRollbackOnly();
-		}
-		catch (SystemException se) {
-			log.error("Could not set transaction to rollback only", se);
-			throw new TransactionException("Could not set transaction to rollback only", se);
-		}
-
-		begun = false;
-
-	}
-
-	/**
-	 * Getter for property 'transaction'.
-	 *
-	 * @return Value for property 'transaction'.
-	 */
-	public javax.transaction.Transaction getTransaction() throws SystemException {
-		return transactionContext.getFactory().getTransactionManager().getTransaction();
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isActive() throws TransactionException {
-
-		if (!begun) return false;
-
-		final int status;
-		try {
-			status = getTransaction().getStatus();
-		}
-		catch (SystemException se) {
-			log.error("Could not determine transaction status", se);
-			throw new TransactionException("Could not determine transaction status: ", se);
-		}
-		if (status==Status.STATUS_UNKNOWN) {
-			throw new TransactionException("Could not determine transaction status");
-		}
-		else {
-			return status==Status.STATUS_ACTIVE;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasRolledBack() throws TransactionException {
-
-		if (!begun) return false;
-
-		final int status;
-		try {
-			status = getTransaction().getStatus();
-		}
-		catch (SystemException se) {
-			log.error("Could not determine transaction status", se);
-			throw new TransactionException("Could not determine transaction status", se);
-		}
-		if (status==Status.STATUS_UNKNOWN) {
-			throw new TransactionException("Could not determine transaction status");
-		}
-		else {
-			return JTAHelper.isRollback(status);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasCommitted() throws TransactionException {
-
-		if ( !begun ) return false;
-
-		final int status;
-		try {
-			status = getTransaction().getStatus();
-		}
-		catch (SystemException se) {
-			log.error("Could not determine transaction status", se);
-			throw new TransactionException("Could not determine transaction status: ", se);
-		}
-		if (status==Status.STATUS_UNKNOWN) {
-			throw new TransactionException("Could not determine transaction status");
-		}
-		else {
-			return status==Status.STATUS_COMMITTED;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void registerSynchronization(Synchronization sync) throws HibernateException {
-		try {
-			getTransaction().registerSynchronization(sync);
-		}
-		catch (Exception e) {
-			throw new TransactionException("Could not register synchronization", e);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void setTimeout(int seconds) {
-		throw new UnsupportedOperationException("cannot set transaction timeout in CMT");
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/CMTTransaction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,224 @@
+/*
+ * 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.transaction;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * Implements a basic transaction strategy for CMT transactions. All work is
+ * done in the context of the container managed transaction.
+ * <p/>
+ * The term 'CMT' is potentially misleading here; the pertinent point simply
+ * being that the transactions are being managed by something other than the
+ * Hibernate transaction mechanism.
+ *
+ * @author Gavin King
+ */
+public class CMTTransaction implements Transaction {
+
+	private static final Logger log = LoggerFactory.getLogger(CMTTransaction.class);
+
+	protected final JDBCContext jdbcContext;
+	protected final TransactionFactory.Context transactionContext;
+
+	private boolean begun;
+
+	public CMTTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
+		this.jdbcContext = jdbcContext;
+		this.transactionContext = transactionContext;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void begin() throws HibernateException {
+		if (begun) {
+			return;
+		}
+
+		log.debug("begin");
+		
+		boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
+
+		if ( !synchronization ) {
+			throw new TransactionException("Could not register synchronization for container transaction");
+		}
+
+		begun = true;
+		
+		jdbcContext.afterTransactionBegin(this);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void commit() throws HibernateException {
+		if (!begun) {
+			throw new TransactionException("Transaction not successfully started");
+		}
+
+		log.debug("commit");
+
+		boolean flush = !transactionContext.isFlushModeNever() &&
+		        !transactionContext.isFlushBeforeCompletionEnabled();
+
+		if (flush) {
+			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
+		}
+
+		begun = false;
+
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void rollback() throws HibernateException {
+		if (!begun) {
+			throw new TransactionException("Transaction not successfully started");
+		}
+
+		log.debug("rollback");
+
+		try {
+			getTransaction().setRollbackOnly();
+		}
+		catch (SystemException se) {
+			log.error("Could not set transaction to rollback only", se);
+			throw new TransactionException("Could not set transaction to rollback only", se);
+		}
+
+		begun = false;
+
+	}
+
+	/**
+	 * Getter for property 'transaction'.
+	 *
+	 * @return Value for property 'transaction'.
+	 */
+	public javax.transaction.Transaction getTransaction() throws SystemException {
+		return transactionContext.getFactory().getTransactionManager().getTransaction();
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isActive() throws TransactionException {
+
+		if (!begun) return false;
+
+		final int status;
+		try {
+			status = getTransaction().getStatus();
+		}
+		catch (SystemException se) {
+			log.error("Could not determine transaction status", se);
+			throw new TransactionException("Could not determine transaction status: ", se);
+		}
+		if (status==Status.STATUS_UNKNOWN) {
+			throw new TransactionException("Could not determine transaction status");
+		}
+		else {
+			return status==Status.STATUS_ACTIVE;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasRolledBack() throws TransactionException {
+
+		if (!begun) return false;
+
+		final int status;
+		try {
+			status = getTransaction().getStatus();
+		}
+		catch (SystemException se) {
+			log.error("Could not determine transaction status", se);
+			throw new TransactionException("Could not determine transaction status", se);
+		}
+		if (status==Status.STATUS_UNKNOWN) {
+			throw new TransactionException("Could not determine transaction status");
+		}
+		else {
+			return JTAHelper.isRollback(status);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasCommitted() throws TransactionException {
+
+		if ( !begun ) return false;
+
+		final int status;
+		try {
+			status = getTransaction().getStatus();
+		}
+		catch (SystemException se) {
+			log.error("Could not determine transaction status", se);
+			throw new TransactionException("Could not determine transaction status: ", se);
+		}
+		if (status==Status.STATUS_UNKNOWN) {
+			throw new TransactionException("Could not determine transaction status");
+		}
+		else {
+			return status==Status.STATUS_COMMITTED;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void registerSynchronization(Synchronization sync) throws HibernateException {
+		try {
+			getTransaction().registerSynchronization(sync);
+		}
+		catch (Exception e) {
+			throw new TransactionException("Could not register synchronization", e);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setTimeout(int seconds) {
+		throw new UnsupportedOperationException("cannot set transaction timeout in CMT");
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +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.transaction;
-
-import java.util.Properties;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.util.JTAHelper;
-import org.hibernate.jdbc.JDBCContext;
-
-import javax.transaction.SystemException;
-
-/**
- * Factory for {@link CMTTransaction} instances.
- *
- * @author Gavin King
- */
-public class CMTTransactionFactory implements TransactionFactory {
-
-	public ConnectionReleaseMode getDefaultReleaseMode() {
-		return ConnectionReleaseMode.AFTER_STATEMENT;
-	}
-
-	public void configure(Properties props) throws HibernateException {}
-
-	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
-	throws HibernateException {
-		return new CMTTransaction(jdbcContext, transactionContext);
-	}
-
-	public boolean isTransactionManagerRequired() {
-		return true;
-	}
-
-	public boolean areCallbacksLocalToHibernateTransactions() {
-		return false;
-	}
-
-	public boolean isTransactionInProgress(
-			JDBCContext jdbcContext,
-	        Context transactionContext,
-	        Transaction transaction) {
-		try {
-			return JTAHelper.isTransactionInProgress(
-					transactionContext.getFactory().getTransactionManager().getTransaction()
-			);
-		}
-		catch( SystemException se ) {
-			throw new TransactionException( "Unable to check transaction status", se );
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CMTTransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+import java.util.Properties;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.util.JTAHelper;
+import org.hibernate.jdbc.JDBCContext;
+
+import javax.transaction.SystemException;
+
+/**
+ * Factory for {@link CMTTransaction} instances.
+ *
+ * @author Gavin King
+ */
+public class CMTTransactionFactory implements TransactionFactory {
+
+	public ConnectionReleaseMode getDefaultReleaseMode() {
+		return ConnectionReleaseMode.AFTER_STATEMENT;
+	}
+
+	public void configure(Properties props) throws HibernateException {}
+
+	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+	throws HibernateException {
+		return new CMTTransaction(jdbcContext, transactionContext);
+	}
+
+	public boolean isTransactionManagerRequired() {
+		return true;
+	}
+
+	public boolean areCallbacksLocalToHibernateTransactions() {
+		return false;
+	}
+
+	public boolean isTransactionInProgress(
+			JDBCContext jdbcContext,
+	        Context transactionContext,
+	        Transaction transaction) {
+		try {
+			return JTAHelper.isTransactionInProgress(
+					transactionContext.getFactory().getTransactionManager().getTransaction()
+			);
+		}
+		catch( SystemException se ) {
+			throw new TransactionException( "Unable to check transaction status", se );
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,133 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * A JTA transaction synch used to allow the {@link org.hibernate.Session} to know about transaction
- * events.
- *
- * @author Gavin King
- */
-public final class CacheSynchronization implements Synchronization {
-
-	private static final Logger log = LoggerFactory.getLogger(CacheSynchronization.class);
-
-	private final TransactionFactory.Context ctx;
-	private JDBCContext jdbcContext;
-	private final Transaction transaction;
-	private final org.hibernate.Transaction hibernateTransaction;
-
-	public CacheSynchronization(
-			TransactionFactory.Context ctx, 
-			JDBCContext jdbcContext, 
-			Transaction transaction, 
-			org.hibernate.Transaction tx) {
-		this.ctx = ctx;
-		this.jdbcContext = jdbcContext;
-		this.transaction = transaction;
-		this.hibernateTransaction = tx;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void beforeCompletion() {
-		log.trace("transaction before completion callback");
-
-		boolean flush;
-		try {
-			flush = !ctx.isFlushModeNever() &&
-			        ctx.isFlushBeforeCompletionEnabled() && 
-			        !JTAHelper.isRollback( transaction.getStatus() ); 
-					//actually, this last test is probably unnecessary, since 
-					//beforeCompletion() doesn't get called during rollback
-		}
-		catch (SystemException se) {
-			log.error("could not determine transaction status", se);
-			setRollbackOnly();
-			throw new TransactionException("could not determine transaction status in beforeCompletion()", se);
-		}
-		
-		try {
-			if (flush) {
-				log.trace("automatically flushing session");
-				ctx.managedFlush();
-			}
-		}
-		catch (RuntimeException re) {
-			setRollbackOnly();
-			throw re;
-		}
-		finally {
-			jdbcContext.beforeTransactionCompletion(hibernateTransaction);
-		}
-	}
-
-	private void setRollbackOnly() {
-		try {
-			transaction.setRollbackOnly();
-		}
-		catch (SystemException se) {
-			log.error("could not set transaction to rollback only", se);
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void afterCompletion(int status) {
-		if ( log.isTraceEnabled() ) {
-			log.trace("transaction after completion callback, status: " + status);
-		}
-		try {
-			jdbcContext.afterTransactionCompletion(status==Status.STATUS_COMMITTED, hibernateTransaction);
-		}
-		finally {
-			if ( ctx.shouldAutoClose() && !ctx.isClosed() ) {
-				log.trace("automatically closing session");
-				ctx.managedClose();
-			}
-		}
-	}
-	
-	/**
-	 * {@inheritDoc}
-	 */
-	public String toString() {
-		return CacheSynchronization.class.getName();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/CacheSynchronization.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,134 @@
+/*
+ * 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.transaction;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * A JTA transaction synch used to allow the {@link org.hibernate.Session} to know about transaction
+ * events.
+ *
+ * @author Gavin King
+ */
+public final class CacheSynchronization implements Synchronization {
+
+	private static final Logger log = LoggerFactory.getLogger(CacheSynchronization.class);
+
+	private final TransactionFactory.Context ctx;
+	private JDBCContext jdbcContext;
+	private final Transaction transaction;
+	private final org.hibernate.Transaction hibernateTransaction;
+
+	public CacheSynchronization(
+			TransactionFactory.Context ctx, 
+			JDBCContext jdbcContext, 
+			Transaction transaction, 
+			org.hibernate.Transaction tx) {
+		this.ctx = ctx;
+		this.jdbcContext = jdbcContext;
+		this.transaction = transaction;
+		this.hibernateTransaction = tx;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void beforeCompletion() {
+		log.trace("transaction before completion callback");
+
+		boolean flush;
+		try {
+			flush = !ctx.isFlushModeNever() &&
+			        ctx.isFlushBeforeCompletionEnabled() && 
+			        !JTAHelper.isRollback( transaction.getStatus() ); 
+					//actually, this last test is probably unnecessary, since 
+					//beforeCompletion() doesn't get called during rollback
+		}
+		catch (SystemException se) {
+			log.error("could not determine transaction status", se);
+			setRollbackOnly();
+			throw new TransactionException("could not determine transaction status in beforeCompletion()", se);
+		}
+		
+		try {
+			if (flush) {
+				log.trace("automatically flushing session");
+				ctx.managedFlush();
+			}
+		}
+		catch (RuntimeException re) {
+			setRollbackOnly();
+			throw re;
+		}
+		finally {
+			jdbcContext.beforeTransactionCompletion(hibernateTransaction);
+		}
+	}
+
+	private void setRollbackOnly() {
+		try {
+			transaction.setRollbackOnly();
+		}
+		catch (SystemException se) {
+			log.error("could not set transaction to rollback only", se);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void afterCompletion(int status) {
+		if ( log.isTraceEnabled() ) {
+			log.trace("transaction after completion callback, status: " + status);
+		}
+		try {
+			jdbcContext.afterTransactionCompletion(status==Status.STATUS_COMMITTED, hibernateTransaction);
+		}
+		finally {
+			if ( ctx.shouldAutoClose() && !ctx.isClosed() ) {
+				log.trace("automatically closing session");
+				ctx.managedClose();
+			}
+		}
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public String toString() {
+		return CacheSynchronization.class.getName();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +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.transaction;
-
-/**
- * A {@link TransactionManagerLookup} lookup strategy for JBoss AS.
- *
- * @author Gavin King
- */
-public final class JBossTransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	protected String getName() {
-		return "java:/TransactionManager";
-	}
-
-	public String getUserTransactionName() {
-		return "UserTransaction";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JBossTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.transaction;
+
+/**
+ * A {@link TransactionManagerLookup} lookup strategy for JBoss AS.
+ *
+ * @author Gavin King
+ */
+public final class JBossTransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	protected String getName() {
+		return "java:/TransactionManager";
+	}
+
+	public String getUserTransactionName() {
+		return "UserTransaction";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,303 +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.transaction;
-
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-
-/**
- * {@link Transaction} implementation based on transaction management through
- * a JDBC {@link java.sql.Connection}.
- * <p/>
- * This the Hibernate's default transaction strategy.
- *
- * @author Anton van Straaten
- * @author Gavin King
- */
-public class JDBCTransaction implements Transaction {
-
-	private static final Logger log = LoggerFactory.getLogger(JDBCTransaction.class);
-
-	private final JDBCContext jdbcContext;
-	private final TransactionFactory.Context transactionContext;
-
-	private boolean toggleAutoCommit;
-	private boolean begun;
-	private boolean rolledBack;
-	private boolean committed;
-	private boolean commitFailed;
-	private List synchronizations;
-	private boolean callback;
-	private int timeout = -1;
-
-	public JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
-		this.jdbcContext = jdbcContext;
-		this.transactionContext = transactionContext;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void begin() throws HibernateException {
-		if (begun) {
-			return;
-		}
-		if (commitFailed) {
-			throw new TransactionException("cannot re-start transaction after failed commit");
-		}
-
-		log.debug("begin");
-
-		try {
-			toggleAutoCommit = jdbcContext.connection().getAutoCommit();
-			if ( log.isDebugEnabled() ) {
-				log.debug("current autocommit status: " + toggleAutoCommit);
-			}
-			if (toggleAutoCommit) {
-				log.debug("disabling autocommit");
-				jdbcContext.connection().setAutoCommit(false);
-			}
-		}
-		catch (SQLException e) {
-			log.error("JDBC begin failed", e);
-			throw new TransactionException("JDBC begin failed: ", e);
-		}
-
-		callback = jdbcContext.registerCallbackIfNecessary();
-
-		begun = true;
-		committed = false;
-		rolledBack = false;
-
-		if ( timeout>0 ) {
-			jdbcContext.getConnectionManager()
-					.getBatcher()
-					.setTransactionTimeout(timeout);
-		}
-
-		jdbcContext.afterTransactionBegin(this);
-	}
-
-	private void closeIfRequired() throws HibernateException {
-		if ( callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ) {
-			try {
-				transactionContext.managedClose();
-			}
-			catch (HibernateException he) {
-				log.error("Could not close session", he);
-				//swallow, the transaction was finished
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void commit() throws HibernateException {
-		if (!begun) {
-			throw new TransactionException("Transaction not successfully started");
-		}
-
-		log.debug("commit");
-
-		if ( !transactionContext.isFlushModeNever() && callback ) {
-			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
-		}
-
-		notifyLocalSynchsBeforeTransactionCompletion();
-		if ( callback ) {
-			jdbcContext.beforeTransactionCompletion( this );
-		}
-
-		try {
-			commitAndResetAutoCommit();
-			log.debug("committed JDBC Connection");
-			committed = true;
-			if ( callback ) {
-				jdbcContext.afterTransactionCompletion( true, this );
-			}
-			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_COMMITTED );
-		}
-		catch (SQLException e) {
-			log.error("JDBC commit failed", e);
-			commitFailed = true;
-			if ( callback ) {
-				jdbcContext.afterTransactionCompletion( false, this );
-			}
-			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
-			throw new TransactionException("JDBC commit failed", e);
-		}
-		finally {
-			closeIfRequired();
-		}
-	}
-
-	private void commitAndResetAutoCommit() throws SQLException {
-		try {
-			jdbcContext.connection().commit();
-		}
-		finally {
-			toggleAutoCommit();
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void rollback() throws HibernateException {
-
-		if (!begun && !commitFailed) {
-			throw new TransactionException("Transaction not successfully started");
-		}
-
-		log.debug("rollback");
-
-		if (!commitFailed) {
-
-			/*notifyLocalSynchsBeforeTransactionCompletion();
-			if ( callback ) {
-				jdbcContext.notifyLocalSynchsBeforeTransactionCompletion( this );
-			}*/
-
-			try {
-				rollbackAndResetAutoCommit();
-				log.debug("rolled back JDBC Connection");
-				rolledBack = true;
-				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_ROLLEDBACK);
-			}
-			catch (SQLException e) {
-				log.error("JDBC rollback failed", e);
-				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_UNKNOWN);
-				throw new TransactionException("JDBC rollback failed", e);
-			}
-			finally {
-				if ( callback ) {
-					jdbcContext.afterTransactionCompletion( false, this );
-				}
-				closeIfRequired();
-			}
-		}
-	}
-
-	private void rollbackAndResetAutoCommit() throws SQLException {
-		try {
-			jdbcContext.connection().rollback();
-		}
-		finally {
-			toggleAutoCommit();
-		}
-	}
-
-	private void toggleAutoCommit() {
-		try {
-			if (toggleAutoCommit) {
-				log.debug("re-enabling autocommit");
-				jdbcContext.connection().setAutoCommit( true );
-			}
-		}
-		catch (Exception sqle) {
-			log.error("Could not toggle autocommit", sqle);
-			//swallow it (the transaction _was_ successful or successfully rolled back)
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasRolledBack() {
-		return rolledBack;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasCommitted() {
-		return committed;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isActive() {
-		return begun && ! ( rolledBack || committed | commitFailed );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void registerSynchronization(Synchronization sync) throws HibernateException {
-		if (sync==null) throw new NullPointerException("null Synchronization");
-		if (synchronizations==null) {
-			synchronizations = new ArrayList();
-		}
-		synchronizations.add(sync);
-	}
-
-	private void notifyLocalSynchsBeforeTransactionCompletion() {
-		if (synchronizations!=null) {
-			for ( int i=0; i<synchronizations.size(); i++ ) {
-				Synchronization sync = (Synchronization) synchronizations.get(i);
-				try {
-					sync.beforeCompletion();
-				}
-				catch (Throwable t) {
-					log.error("exception calling user Synchronization", t);
-				}
-			}
-		}
-	}
-
-	private void notifyLocalSynchsAfterTransactionCompletion(int status) {
-		begun = false;
-		if (synchronizations!=null) {
-			for ( int i=0; i<synchronizations.size(); i++ ) {
-				Synchronization sync = (Synchronization) synchronizations.get(i);
-				try {
-					sync.afterCompletion(status);
-				}
-				catch (Throwable t) {
-					log.error("exception calling user Synchronization", t);
-				}
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void setTimeout(int seconds) {
-		timeout = seconds;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,304 @@
+/*
+ * 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.transaction;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+
+/**
+ * {@link Transaction} implementation based on transaction management through
+ * a JDBC {@link java.sql.Connection}.
+ * <p/>
+ * This the Hibernate's default transaction strategy.
+ *
+ * @author Anton van Straaten
+ * @author Gavin King
+ */
+public class JDBCTransaction implements Transaction {
+
+	private static final Logger log = LoggerFactory.getLogger(JDBCTransaction.class);
+
+	private final JDBCContext jdbcContext;
+	private final TransactionFactory.Context transactionContext;
+
+	private boolean toggleAutoCommit;
+	private boolean begun;
+	private boolean rolledBack;
+	private boolean committed;
+	private boolean commitFailed;
+	private List synchronizations;
+	private boolean callback;
+	private int timeout = -1;
+
+	public JDBCTransaction(JDBCContext jdbcContext, TransactionFactory.Context transactionContext) {
+		this.jdbcContext = jdbcContext;
+		this.transactionContext = transactionContext;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void begin() throws HibernateException {
+		if (begun) {
+			return;
+		}
+		if (commitFailed) {
+			throw new TransactionException("cannot re-start transaction after failed commit");
+		}
+
+		log.debug("begin");
+
+		try {
+			toggleAutoCommit = jdbcContext.connection().getAutoCommit();
+			if ( log.isDebugEnabled() ) {
+				log.debug("current autocommit status: " + toggleAutoCommit);
+			}
+			if (toggleAutoCommit) {
+				log.debug("disabling autocommit");
+				jdbcContext.connection().setAutoCommit(false);
+			}
+		}
+		catch (SQLException e) {
+			log.error("JDBC begin failed", e);
+			throw new TransactionException("JDBC begin failed: ", e);
+		}
+
+		callback = jdbcContext.registerCallbackIfNecessary();
+
+		begun = true;
+		committed = false;
+		rolledBack = false;
+
+		if ( timeout>0 ) {
+			jdbcContext.getConnectionManager()
+					.getBatcher()
+					.setTransactionTimeout(timeout);
+		}
+
+		jdbcContext.afterTransactionBegin(this);
+	}
+
+	private void closeIfRequired() throws HibernateException {
+		if ( callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ) {
+			try {
+				transactionContext.managedClose();
+			}
+			catch (HibernateException he) {
+				log.error("Could not close session", he);
+				//swallow, the transaction was finished
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void commit() throws HibernateException {
+		if (!begun) {
+			throw new TransactionException("Transaction not successfully started");
+		}
+
+		log.debug("commit");
+
+		if ( !transactionContext.isFlushModeNever() && callback ) {
+			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
+		}
+
+		notifyLocalSynchsBeforeTransactionCompletion();
+		if ( callback ) {
+			jdbcContext.beforeTransactionCompletion( this );
+		}
+
+		try {
+			commitAndResetAutoCommit();
+			log.debug("committed JDBC Connection");
+			committed = true;
+			if ( callback ) {
+				jdbcContext.afterTransactionCompletion( true, this );
+			}
+			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_COMMITTED );
+		}
+		catch (SQLException e) {
+			log.error("JDBC commit failed", e);
+			commitFailed = true;
+			if ( callback ) {
+				jdbcContext.afterTransactionCompletion( false, this );
+			}
+			notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_UNKNOWN );
+			throw new TransactionException("JDBC commit failed", e);
+		}
+		finally {
+			closeIfRequired();
+		}
+	}
+
+	private void commitAndResetAutoCommit() throws SQLException {
+		try {
+			jdbcContext.connection().commit();
+		}
+		finally {
+			toggleAutoCommit();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void rollback() throws HibernateException {
+
+		if (!begun && !commitFailed) {
+			throw new TransactionException("Transaction not successfully started");
+		}
+
+		log.debug("rollback");
+
+		if (!commitFailed) {
+
+			/*notifyLocalSynchsBeforeTransactionCompletion();
+			if ( callback ) {
+				jdbcContext.notifyLocalSynchsBeforeTransactionCompletion( this );
+			}*/
+
+			try {
+				rollbackAndResetAutoCommit();
+				log.debug("rolled back JDBC Connection");
+				rolledBack = true;
+				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_ROLLEDBACK);
+			}
+			catch (SQLException e) {
+				log.error("JDBC rollback failed", e);
+				notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_UNKNOWN);
+				throw new TransactionException("JDBC rollback failed", e);
+			}
+			finally {
+				if ( callback ) {
+					jdbcContext.afterTransactionCompletion( false, this );
+				}
+				closeIfRequired();
+			}
+		}
+	}
+
+	private void rollbackAndResetAutoCommit() throws SQLException {
+		try {
+			jdbcContext.connection().rollback();
+		}
+		finally {
+			toggleAutoCommit();
+		}
+	}
+
+	private void toggleAutoCommit() {
+		try {
+			if (toggleAutoCommit) {
+				log.debug("re-enabling autocommit");
+				jdbcContext.connection().setAutoCommit( true );
+			}
+		}
+		catch (Exception sqle) {
+			log.error("Could not toggle autocommit", sqle);
+			//swallow it (the transaction _was_ successful or successfully rolled back)
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasRolledBack() {
+		return rolledBack;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasCommitted() {
+		return committed;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isActive() {
+		return begun && ! ( rolledBack || committed | commitFailed );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void registerSynchronization(Synchronization sync) throws HibernateException {
+		if (sync==null) throw new NullPointerException("null Synchronization");
+		if (synchronizations==null) {
+			synchronizations = new ArrayList();
+		}
+		synchronizations.add(sync);
+	}
+
+	private void notifyLocalSynchsBeforeTransactionCompletion() {
+		if (synchronizations!=null) {
+			for ( int i=0; i<synchronizations.size(); i++ ) {
+				Synchronization sync = (Synchronization) synchronizations.get(i);
+				try {
+					sync.beforeCompletion();
+				}
+				catch (Throwable t) {
+					log.error("exception calling user Synchronization", t);
+				}
+			}
+		}
+	}
+
+	private void notifyLocalSynchsAfterTransactionCompletion(int status) {
+		begun = false;
+		if (synchronizations!=null) {
+			for ( int i=0; i<synchronizations.size(); i++ ) {
+				Synchronization sync = (Synchronization) synchronizations.get(i);
+				try {
+					sync.afterCompletion(status);
+				}
+				catch (Throwable t) {
+					log.error("exception calling user Synchronization", t);
+				}
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setTimeout(int seconds) {
+		timeout = seconds;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,95 +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.transaction;
-
-import java.util.Properties;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.jdbc.JDBCContext;
-
-/**
- * Factory for {@link JDBCTransaction} instances.
- *
- * @author Anton van Straaten
- */
-public final class JDBCTransactionFactory implements TransactionFactory {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public ConnectionReleaseMode getDefaultReleaseMode() {
-		return ConnectionReleaseMode.AFTER_TRANSACTION;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
-	throws HibernateException {
-		return new JDBCTransaction( jdbcContext, transactionContext );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void configure(Properties props) throws HibernateException {}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isTransactionManagerRequired() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean areCallbacksLocalToHibernateTransactions() {
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isTransactionInProgress(
-			JDBCContext jdbcContext,
-	        Context transactionContext,
-	        Transaction transaction) {
-//		try {
-//			// for JDBC-based transactions, we only want to return true
-//			// here if we (this transaction) are managing the transaction
-//			return transaction != null &&
-//			       transaction.isActive() &&
-//			       !jdbcContext.getConnectionManager().isAutoCommit();
-//		}
-//		catch ( SQLException e ) {
-//			// assume we are in auto-commit!
-//			return false;
-//		}
-		return transaction != null && transaction.isActive();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JDBCTransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+import java.util.Properties;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.jdbc.JDBCContext;
+
+/**
+ * Factory for {@link JDBCTransaction} instances.
+ *
+ * @author Anton van Straaten
+ */
+public final class JDBCTransactionFactory implements TransactionFactory {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ConnectionReleaseMode getDefaultReleaseMode() {
+		return ConnectionReleaseMode.AFTER_TRANSACTION;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+	throws HibernateException {
+		return new JDBCTransaction( jdbcContext, transactionContext );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void configure(Properties props) throws HibernateException {}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isTransactionManagerRequired() {
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean areCallbacksLocalToHibernateTransactions() {
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isTransactionInProgress(
+			JDBCContext jdbcContext,
+	        Context transactionContext,
+	        Transaction transaction) {
+//		try {
+//			// for JDBC-based transactions, we only want to return true
+//			// here if we (this transaction) are managing the transaction
+//			return transaction != null &&
+//			       transaction.isActive() &&
+//			       !jdbcContext.getConnectionManager().isAutoCommit();
+//		}
+//		catch ( SQLException e ) {
+//			// assume we are in auto-commit!
+//			return false;
+//		}
+		return transaction != null && transaction.isActive();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,76 +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.transaction;
-
-import java.util.Properties;
-
-import javax.naming.NamingException;
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-import org.hibernate.util.NamingHelper;
-
-/**
- * Template implementation of {@link TransactionManagerLookup} where the
- * underlying {@link TransactionManager} is available via JNDI lookup at the
- * specified location - {@link #getName}.
- *
- * @author Gavin King
- */
-public abstract class JNDITransactionManagerLookup implements TransactionManagerLookup {
-
-	/**
-	 * Get the JNDI namespace under wich we can locate the {@link TransactionManager}.
-	 *
-	 * @return The {@link TransactionManager} JNDI namespace
-	 */
-	protected abstract String getName();
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		try {
-			return (TransactionManager) NamingHelper.getInitialContext(props).lookup( getName() );
-		}
-		catch (NamingException ne) {
-			throw new HibernateException( "Could not locate TransactionManager", ne );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		// for sane JEE/JTA containers, the transaction itself functions as its identifier...
-		return transaction;
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JNDITransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+import java.util.Properties;
+
+import javax.naming.NamingException;
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.hibernate.HibernateException;
+import org.hibernate.util.NamingHelper;
+
+/**
+ * Template implementation of {@link TransactionManagerLookup} where the
+ * underlying {@link TransactionManager} is available via JNDI lookup at the
+ * specified location - {@link #getName}.
+ *
+ * @author Gavin King
+ */
+public abstract class JNDITransactionManagerLookup implements TransactionManagerLookup {
+
+	/**
+	 * Get the JNDI namespace under wich we can locate the {@link TransactionManager}.
+	 *
+	 * @return The {@link TransactionManager} JNDI namespace
+	 */
+	protected abstract String getName();
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		try {
+			return (TransactionManager) NamingHelper.getInitialContext(props).lookup( getName() );
+		}
+		catch (NamingException ne) {
+			throw new HibernateException( "Could not locate TransactionManager", ne );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		// for sane JEE/JTA containers, the transaction itself functions as its identifier...
+		return transaction;
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,72 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-
-/**
- * {@link TransactionManagerLookup} strategy for JOTM
- *
- * @author Low Heng Sin
- */
-public class JOTMTransactionManagerLookup implements TransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		try {
-			Class clazz = Class.forName("org.objectweb.jotm.Current");
-			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException( "Could not obtain JOTM transaction manager instance", e );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		return transaction;
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOTMTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.hibernate.HibernateException;
+
+/**
+ * {@link TransactionManagerLookup} strategy for JOTM
+ *
+ * @author Low Heng Sin
+ */
+public class JOTMTransactionManagerLookup implements TransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		try {
+			Class clazz = Class.forName("org.objectweb.jotm.Current");
+			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException( "Could not obtain JOTM transaction manager instance", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		return transaction;
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,65 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.hibernate.HibernateException;
-
-/**
- * {@link TransactionManagerLookup} strategy for JOnAS
- */
-public class JOnASTransactionManagerLookup implements TransactionManagerLookup {
-
-	/**
-	 * @see org.hibernate.transaction.TransactionManagerLookup#getTransactionManager(Properties)
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		try {
-			Class clazz = Class.forName("org.objectweb.jonas_tm.Current");
-			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException( "Could not obtain JOnAS transaction manager instance", e );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		return transaction;
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JOnASTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.hibernate.HibernateException;
+
+/**
+ * {@link TransactionManagerLookup} strategy for JOnAS
+ */
+public class JOnASTransactionManagerLookup implements TransactionManagerLookup {
+
+	/**
+	 * @see org.hibernate.transaction.TransactionManagerLookup#getTransactionManager(Properties)
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		try {
+			Class clazz = Class.forName("org.objectweb.jonas_tm.Current");
+			return (TransactionManager) clazz.getMethod("getTransactionManager", null).invoke(null, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException( "Could not obtain JOnAS transaction manager instance", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		return transaction;
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} strategy for JRun4 AS
- *
- * @author Joseph Bissen
- */
-public class JRun4TransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	protected String getName() {
-		return "java:/TransactionManager";
-	}
-
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JRun4TransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+/**
+ * {@link TransactionManagerLookup} strategy for JRun4 AS
+ *
+ * @author Joseph Bissen
+ */
+public class JRun4TransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	protected String getName() {
+		return "java:/TransactionManager";
+	}
+
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JTATransaction.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,358 +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.transaction;
-
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.util.JTAHelper;
-
-/**
- * {@link Transaction} implementation based on transaction management through
- * a JTA {@link UserTransaction}.  Similar to {@link CMTTransaction}, except
- * here we are actually managing the transactions through the Hibernate
- * transaction mechanism.
- *
- * @author Gavin King
- * @author Steve Ebersole
- * @author Les Hazlewood
- */
-public class JTATransaction implements Transaction {
-
-	private static final Logger log = LoggerFactory.getLogger( JTATransaction.class );
-
-	private final JDBCContext jdbcContext;
-	private final TransactionFactory.Context transactionContext;
-
-	private UserTransaction userTransaction;
-	private boolean newTransaction;
-	private boolean begun;
-	private boolean commitFailed;
-	private boolean commitSucceeded;
-	private boolean callback;
-
-	public JTATransaction(
-			UserTransaction userTransaction,
-			JDBCContext jdbcContext,
-			TransactionFactory.Context transactionContext) {
-		this.jdbcContext = jdbcContext;
-		this.transactionContext = transactionContext;
-		this.userTransaction = userTransaction;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void begin() throws HibernateException {
-		if ( begun ) {
-			return;
-		}
-		if ( commitFailed ) {
-			throw new TransactionException( "cannot re-start transaction after failed commit" );
-		}
-
-		log.debug( "begin" );
-
-		try {
-			newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
-			if ( newTransaction ) {
-				userTransaction.begin();
-				log.debug( "Began a new JTA transaction" );
-			}
-		}
-		catch ( Exception e ) {
-			log.error( "JTA transaction begin failed", e );
-			throw new TransactionException( "JTA transaction begin failed", e );
-		}
-
-		/*if (newTransaction) {
-			// don't need a synchronization since we are committing
-			// or rolling back the transaction ourselves - assuming
-			// that we do no work in beforeTransactionCompletion()
-			synchronization = false;
-		}*/
-
-		boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
-
-		if ( !newTransaction && !synchronization ) {
-			log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
-		}
-
-		if ( !synchronization ) {
-			//if we could not register a synchronization,
-			//do the before/after completion callbacks
-			//ourself (but we need to let jdbcContext
-			//know that this is what we are going to
-			//do, so it doesn't keep trying to register
-			//synchronizations)
-			callback = jdbcContext.registerCallbackIfNecessary();
-		}
-
-		begun = true;
-		commitSucceeded = false;
-
-		jdbcContext.afterTransactionBegin( this );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void commit() throws HibernateException {
-		if ( !begun ) {
-			throw new TransactionException( "Transaction not successfully started" );
-		}
-
-		log.debug( "commit" );
-
-		boolean flush = !transactionContext.isFlushModeNever()
-				&& ( callback || !transactionContext.isFlushBeforeCompletionEnabled() );
-
-		if ( flush ) {
-			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
-		}
-
-		if ( callback && newTransaction ) {
-			jdbcContext.beforeTransactionCompletion( this );
-		}
-
-		closeIfRequired();
-
-		if ( newTransaction ) {
-			try {
-				userTransaction.commit();
-				commitSucceeded = true;
-				log.debug( "Committed JTA UserTransaction" );
-			}
-			catch ( Exception e ) {
-				commitFailed = true; // so the transaction is already rolled back, by JTA spec
-				log.error( "JTA commit failed", e );
-				throw new TransactionException( "JTA commit failed: ", e );
-			}
-			finally {
-				afterCommitRollback();
-			}
-		}
-		else {
-			// this one only really needed for badly-behaved applications!
-			// (if the TransactionManager has a Sychronization registered,
-			// its a noop)
-			// (actually we do need it for downgrading locks)
-			afterCommitRollback();
-		}
-
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void rollback() throws HibernateException {
-		if ( !begun && !commitFailed ) {
-			throw new TransactionException( "Transaction not successfully started" );
-		}
-
-		log.debug( "rollback" );
-
-		try {
-			closeIfRequired();
-		}
-		catch ( Exception e ) {
-			// swallow it, and continue to roll back JTA transaction
-			log.error( "could not close session during rollback", e );
-		}
-
-		try {
-			if ( newTransaction ) {
-				if ( !commitFailed ) {
-					userTransaction.rollback();
-					log.debug( "Rolled back JTA UserTransaction" );
-				}
-			}
-			else {
-				userTransaction.setRollbackOnly();
-				log.debug( "set JTA UserTransaction to rollback only" );
-			}
-		}
-		catch ( Exception e ) {
-			log.error( "JTA rollback failed", e );
-			throw new TransactionException( "JTA rollback failed", e );
-		}
-		finally {
-			afterCommitRollback();
-		}
-	}
-
-	private static final int NULL = Integer.MIN_VALUE;
-
-	private void afterCommitRollback() throws TransactionException {
-
-		begun = false;
-		// this method is a noop if there is a Synchronization!
-		if ( callback ) {
-			if ( !newTransaction ) {
-				log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
-			}
-			int status = NULL;
-			try {
-				status = userTransaction.getStatus();
-			}
-			catch ( Exception e ) {
-				log.error( "Could not determine transaction status after commit", e );
-				throw new TransactionException( "Could not determine transaction status after commit", e );
-			}
-			finally {
-				jdbcContext.afterTransactionCompletion( status == Status.STATUS_COMMITTED, this );
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasRolledBack() throws TransactionException {
-		final int status;
-		try {
-			status = userTransaction.getStatus();
-		}
-		catch ( SystemException se ) {
-			log.error( "Could not determine transaction status", se );
-			throw new TransactionException( "Could not determine transaction status", se );
-		}
-		if ( status == Status.STATUS_UNKNOWN ) {
-			throw new TransactionException( "Could not determine transaction status" );
-		}
-		else {
-			return JTAHelper.isRollback( status );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean wasCommitted() throws TransactionException {
-		final int status;
-		try {
-			status = userTransaction.getStatus();
-		}
-		catch ( SystemException se ) {
-			log.error( "Could not determine transaction status", se );
-			throw new TransactionException( "Could not determine transaction status: ", se );
-		}
-		if ( status == Status.STATUS_UNKNOWN ) {
-			throw new TransactionException( "Could not determine transaction status" );
-		}
-		else {
-			return status == Status.STATUS_COMMITTED;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isActive() throws TransactionException {
-		if ( !begun || commitFailed || commitSucceeded ) {
-			return false;
-		}
-
-		final int status;
-		try {
-			status = userTransaction.getStatus();
-		}
-		catch ( SystemException se ) {
-			log.error( "Could not determine transaction status", se );
-			throw new TransactionException( "Could not determine transaction status: ", se );
-		}
-		if ( status == Status.STATUS_UNKNOWN ) {
-			throw new TransactionException( "Could not determine transaction status" );
-		}
-		else {
-			return status == Status.STATUS_ACTIVE;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void registerSynchronization(Synchronization sync) throws HibernateException {
-		if ( getTransactionManager() == null ) {
-			throw new IllegalStateException( "JTA TransactionManager not available" );
-		}
-		else {
-			try {
-				getTransactionManager().getTransaction().registerSynchronization( sync );
-			}
-			catch ( Exception e ) {
-				throw new TransactionException( "could not register synchronization", e );
-			}
-		}
-	}
-
-	/**
-	 * Getter for property 'transactionManager'.
-	 *
-	 * @return Value for property 'transactionManager'.
-	 */
-	private TransactionManager getTransactionManager() {
-		return transactionContext.getFactory().getTransactionManager();
-	}
-
-	private void closeIfRequired() throws HibernateException {
-		boolean close = callback &&
-				transactionContext.shouldAutoClose() &&
-				!transactionContext.isClosed();
-		if ( close ) {
-			transactionContext.managedClose();
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void setTimeout(int seconds) {
-		try {
-			userTransaction.setTransactionTimeout( seconds );
-		}
-		catch ( SystemException se ) {
-			throw new TransactionException( "could not set transaction timeout", se );
-		}
-	}
-
-	/**
-	 * Getter for property 'userTransaction'.
-	 *
-	 * @return Value for property 'userTransaction'.
-	 */
-	protected UserTransaction getUserTransaction() {
-		return userTransaction;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JTATransaction.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransaction.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,359 @@
+/*
+ * 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.transaction;
+
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+import javax.transaction.UserTransaction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * {@link Transaction} implementation based on transaction management through
+ * a JTA {@link UserTransaction}.  Similar to {@link CMTTransaction}, except
+ * here we are actually managing the transactions through the Hibernate
+ * transaction mechanism.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ */
+public class JTATransaction implements Transaction {
+
+	private static final Logger log = LoggerFactory.getLogger( JTATransaction.class );
+
+	private final JDBCContext jdbcContext;
+	private final TransactionFactory.Context transactionContext;
+
+	private UserTransaction userTransaction;
+	private boolean newTransaction;
+	private boolean begun;
+	private boolean commitFailed;
+	private boolean commitSucceeded;
+	private boolean callback;
+
+	public JTATransaction(
+			UserTransaction userTransaction,
+			JDBCContext jdbcContext,
+			TransactionFactory.Context transactionContext) {
+		this.jdbcContext = jdbcContext;
+		this.transactionContext = transactionContext;
+		this.userTransaction = userTransaction;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void begin() throws HibernateException {
+		if ( begun ) {
+			return;
+		}
+		if ( commitFailed ) {
+			throw new TransactionException( "cannot re-start transaction after failed commit" );
+		}
+
+		log.debug( "begin" );
+
+		try {
+			newTransaction = userTransaction.getStatus() == Status.STATUS_NO_TRANSACTION;
+			if ( newTransaction ) {
+				userTransaction.begin();
+				log.debug( "Began a new JTA transaction" );
+			}
+		}
+		catch ( Exception e ) {
+			log.error( "JTA transaction begin failed", e );
+			throw new TransactionException( "JTA transaction begin failed", e );
+		}
+
+		/*if (newTransaction) {
+			// don't need a synchronization since we are committing
+			// or rolling back the transaction ourselves - assuming
+			// that we do no work in beforeTransactionCompletion()
+			synchronization = false;
+		}*/
+
+		boolean synchronization = jdbcContext.registerSynchronizationIfPossible();
+
+		if ( !newTransaction && !synchronization ) {
+			log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
+		}
+
+		if ( !synchronization ) {
+			//if we could not register a synchronization,
+			//do the before/after completion callbacks
+			//ourself (but we need to let jdbcContext
+			//know that this is what we are going to
+			//do, so it doesn't keep trying to register
+			//synchronizations)
+			callback = jdbcContext.registerCallbackIfNecessary();
+		}
+
+		begun = true;
+		commitSucceeded = false;
+
+		jdbcContext.afterTransactionBegin( this );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void commit() throws HibernateException {
+		if ( !begun ) {
+			throw new TransactionException( "Transaction not successfully started" );
+		}
+
+		log.debug( "commit" );
+
+		boolean flush = !transactionContext.isFlushModeNever()
+				&& ( callback || !transactionContext.isFlushBeforeCompletionEnabled() );
+
+		if ( flush ) {
+			transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback()
+		}
+
+		if ( callback && newTransaction ) {
+			jdbcContext.beforeTransactionCompletion( this );
+		}
+
+		closeIfRequired();
+
+		if ( newTransaction ) {
+			try {
+				userTransaction.commit();
+				commitSucceeded = true;
+				log.debug( "Committed JTA UserTransaction" );
+			}
+			catch ( Exception e ) {
+				commitFailed = true; // so the transaction is already rolled back, by JTA spec
+				log.error( "JTA commit failed", e );
+				throw new TransactionException( "JTA commit failed: ", e );
+			}
+			finally {
+				afterCommitRollback();
+			}
+		}
+		else {
+			// this one only really needed for badly-behaved applications!
+			// (if the TransactionManager has a Sychronization registered,
+			// its a noop)
+			// (actually we do need it for downgrading locks)
+			afterCommitRollback();
+		}
+
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void rollback() throws HibernateException {
+		if ( !begun && !commitFailed ) {
+			throw new TransactionException( "Transaction not successfully started" );
+		}
+
+		log.debug( "rollback" );
+
+		try {
+			closeIfRequired();
+		}
+		catch ( Exception e ) {
+			// swallow it, and continue to roll back JTA transaction
+			log.error( "could not close session during rollback", e );
+		}
+
+		try {
+			if ( newTransaction ) {
+				if ( !commitFailed ) {
+					userTransaction.rollback();
+					log.debug( "Rolled back JTA UserTransaction" );
+				}
+			}
+			else {
+				userTransaction.setRollbackOnly();
+				log.debug( "set JTA UserTransaction to rollback only" );
+			}
+		}
+		catch ( Exception e ) {
+			log.error( "JTA rollback failed", e );
+			throw new TransactionException( "JTA rollback failed", e );
+		}
+		finally {
+			afterCommitRollback();
+		}
+	}
+
+	private static final int NULL = Integer.MIN_VALUE;
+
+	private void afterCommitRollback() throws TransactionException {
+
+		begun = false;
+		// this method is a noop if there is a Synchronization!
+		if ( callback ) {
+			if ( !newTransaction ) {
+				log.warn( "You should set hibernate.transaction.manager_lookup_class if cache is enabled" );
+			}
+			int status = NULL;
+			try {
+				status = userTransaction.getStatus();
+			}
+			catch ( Exception e ) {
+				log.error( "Could not determine transaction status after commit", e );
+				throw new TransactionException( "Could not determine transaction status after commit", e );
+			}
+			finally {
+				jdbcContext.afterTransactionCompletion( status == Status.STATUS_COMMITTED, this );
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasRolledBack() throws TransactionException {
+		final int status;
+		try {
+			status = userTransaction.getStatus();
+		}
+		catch ( SystemException se ) {
+			log.error( "Could not determine transaction status", se );
+			throw new TransactionException( "Could not determine transaction status", se );
+		}
+		if ( status == Status.STATUS_UNKNOWN ) {
+			throw new TransactionException( "Could not determine transaction status" );
+		}
+		else {
+			return JTAHelper.isRollback( status );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean wasCommitted() throws TransactionException {
+		final int status;
+		try {
+			status = userTransaction.getStatus();
+		}
+		catch ( SystemException se ) {
+			log.error( "Could not determine transaction status", se );
+			throw new TransactionException( "Could not determine transaction status: ", se );
+		}
+		if ( status == Status.STATUS_UNKNOWN ) {
+			throw new TransactionException( "Could not determine transaction status" );
+		}
+		else {
+			return status == Status.STATUS_COMMITTED;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isActive() throws TransactionException {
+		if ( !begun || commitFailed || commitSucceeded ) {
+			return false;
+		}
+
+		final int status;
+		try {
+			status = userTransaction.getStatus();
+		}
+		catch ( SystemException se ) {
+			log.error( "Could not determine transaction status", se );
+			throw new TransactionException( "Could not determine transaction status: ", se );
+		}
+		if ( status == Status.STATUS_UNKNOWN ) {
+			throw new TransactionException( "Could not determine transaction status" );
+		}
+		else {
+			return status == Status.STATUS_ACTIVE;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void registerSynchronization(Synchronization sync) throws HibernateException {
+		if ( getTransactionManager() == null ) {
+			throw new IllegalStateException( "JTA TransactionManager not available" );
+		}
+		else {
+			try {
+				getTransactionManager().getTransaction().registerSynchronization( sync );
+			}
+			catch ( Exception e ) {
+				throw new TransactionException( "could not register synchronization", e );
+			}
+		}
+	}
+
+	/**
+	 * Getter for property 'transactionManager'.
+	 *
+	 * @return Value for property 'transactionManager'.
+	 */
+	private TransactionManager getTransactionManager() {
+		return transactionContext.getFactory().getTransactionManager();
+	}
+
+	private void closeIfRequired() throws HibernateException {
+		boolean close = callback &&
+				transactionContext.shouldAutoClose() &&
+				!transactionContext.isClosed();
+		if ( close ) {
+			transactionContext.managedClose();
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setTimeout(int seconds) {
+		try {
+			userTransaction.setTransactionTimeout( seconds );
+		}
+		catch ( SystemException se ) {
+			throw new TransactionException( "could not set transaction timeout", se );
+		}
+	}
+
+	/**
+	 * Getter for property 'userTransaction'.
+	 *
+	 * @return Value for property 'userTransaction'.
+	 */
+	protected UserTransaction getUserTransaction() {
+		return userTransaction;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,252 +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.transaction;
-
-import java.util.Properties;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.transaction.SystemException;
-import javax.transaction.UserTransaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.TransactionException;
-import org.hibernate.jdbc.JDBCContext;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.NamingHelper;
-import org.hibernate.util.JTAHelper;
-
-/**
- * Factory for {@link JTATransaction} instances.
- * <p/>
- * To be completely accurate to the JTA spec, JTA implementations should
- * publish their contextual {@link UserTransaction} reference into JNDI.
- * However, in practice there are quite a few <tt>stand-alone</tt>
- * implementations intended for use outside of J2EE/JEE containers and
- * which therefore do not publish their {@link UserTransaction} references
- * into JNDI but which otherwise follow the aspects of the JTA specification.
- * This {@link TransactionFactory} implementation can support both models.
- * <p/>
- * For complete JTA implementations (including dependence on JNDI), the
- * {@link UserTransaction} reference is obtained by a call to
- * {@link #resolveInitialContext}.  Hibernate will then attempt to locate the
- * {@link UserTransaction} within this resolved
- * {@link InitialContext} based on the namespace returned by
- * {@link #resolveUserTransactionName}.
- * <p/>
- * For the so-called <tt>stand-alone</tt> implementations, we do not care at
- * all about the JNDI aspects just described.  Here, the implementation would
- * have a specific manner to obtain a reference to its contextual
- * {@link UserTransaction}; usually this would be a static code reference, but
- * again it varies.  Anyway, for each implementation the integration would need
- * to override the {@link #getUserTransaction} method and return the appropriate
- * thing.
- *
- * @author Gavin King
- * @author Steve Ebersole
- * @author Les Hazlewood
- */
-public class JTATransactionFactory implements TransactionFactory {
-	public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
-	private static final Logger log = LoggerFactory.getLogger( JTATransactionFactory.class );
-
-	protected InitialContext initialContext;
-	protected String userTransactionName;
-
-	/**
-	 * Configure this transaction factory.  Specifically here we are attempting to
-	 * resolve both an {@link #getInitialContext InitialContext} as well as the
-	 * {@link #getUserTransactionName() JNDI namespace} for the {@link UserTransaction}.
-	 *
-	 * @param props The configuration properties
-	 *
-	 * @exception HibernateException
-	 */
-	public void configure(Properties props) throws HibernateException {
-		this.initialContext = resolveInitialContext( props );
-		this.userTransactionName = resolveUserTransactionName( props );
-		log.trace( "Configured JTATransactionFactory to use [{}] for UserTransaction JDNI namespace", userTransactionName );
-	}
-
-	/**
-	 * Given the lot of Hibernate configuration properties, resolve appropriate
-	 * reference to JNDI {@link InitialContext}.
-	 * <p/>
-	 * In general, the properties in which we are interested here all begin with
-	 * <tt>hibernate.jndi</tt>.  Especially important depending on your
-	 * environment are {@link Environment#JNDI_URL hibernate.jndi.url} and
-	 *  {@link Environment#JNDI_CLASS hibernate.jndi.class}
-	 *
-	 * @param properties The Hibernate config properties.
-	 * @return The resolved InitialContext.
-	 */
-	protected final InitialContext resolveInitialContext(Properties properties) {
-		try {
-			return NamingHelper.getInitialContext( properties );
-		}
-		catch ( NamingException ne ) {
-			throw new HibernateException( "Could not obtain initial context", ne );
-		}
-	}
-
-	/**
-	 * Given the lot of Hibernate configuration properties, resolve appropriate
-	 * JNDI namespace to use for {@link UserTransaction} resolution.
-	 * <p/>
-	 * We determine the namespace to use by<ol>
-	 * <li>Any specified {@link Environment#USER_TRANSACTION jta.UserTransaction} config property</li>
-	 * <li>If a {@link TransactionManagerLookup} was indicated, use its
-	 * {@link TransactionManagerLookup#getUserTransactionName}</li>
-	 * <li>finally, as a last resort, we use {@link #DEFAULT_USER_TRANSACTION_NAME}</li>
-	 * </ol>
-	 *
-	 * @param properties The Hibernate config properties.
-	 * @return The resolved {@link UserTransaction} namespace
-	 */
-	protected final String resolveUserTransactionName(Properties properties) {
-		String utName = properties.getProperty( Environment.USER_TRANSACTION );
-		if ( utName == null ) {
-			TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
-			if ( lookup != null ) {
-				utName = lookup.getUserTransactionName();
-			}
-		}
-		return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
-			throws HibernateException {
-		UserTransaction ut = getUserTransaction();
-		return new JTATransaction( ut, jdbcContext, transactionContext );
-	}
-
-	/**
-	 * Get the {@link UserTransaction} reference.
-	 *
-	 * @return The appropriate {@link UserTransaction} reference.
-	 */
-	protected UserTransaction getUserTransaction() {
-		log.trace( "Attempting to locate UserTransaction via JNDI [{}]", getUserTransactionName() );
-
-		try {
-			UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( getUserTransactionName() );
-			if ( ut == null ) {
-				throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + getUserTransactionName() +"]" );
-			}
-
-			log.trace( "Obtained UserTransaction" );
-
-			return ut;
-		}
-		catch ( NamingException ne ) {
-			throw new TransactionException( "Could not find UserTransaction in JNDI [" + getUserTransaction() + "]", ne );
-		}
-	}
-
-	/**
-	 * Getter for property 'initialContext'.
-	 *
-	 * @return Value for property 'initialContext'.
-	 */
-	protected InitialContext getInitialContext() {
-		return initialContext;
-	}
-
-	/**
-	 * Getter for property 'userTransactionName'.
-	 * The algorithm here is
-	 *
-	 * @return Value for property 'userTransactionName'.
-	 */
-	protected String getUserTransactionName() {
-		return userTransactionName;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public ConnectionReleaseMode getDefaultReleaseMode() {
-		return ConnectionReleaseMode.AFTER_STATEMENT;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isTransactionManagerRequired() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean areCallbacksLocalToHibernateTransactions() {
-		return false;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isTransactionInProgress(
-			JDBCContext jdbcContext,
-			Context transactionContext,
-			Transaction transaction) {
-		try {
-			// Essentially:
-			// 1) If we have a local (Hibernate) transaction in progress
-			//      and it already has the UserTransaction cached, use that
-			//      UserTransaction to determine the status.
-			// 2) If a transaction manager has been located, use
-			//      that transaction manager to determine the status.
-			// 3) Finally, as the last resort, try to lookup the
-			//      UserTransaction via JNDI and use that to determine the
-			//      status.
-			if ( transaction != null ) {
-				UserTransaction ut = ( ( JTATransaction ) transaction ).getUserTransaction();
-				if ( ut != null ) {
-					return JTAHelper.isInProgress( ut.getStatus() );
-				}
-			}
-
-			if ( jdbcContext.getFactory().getTransactionManager() != null ) {
-				return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
-			}
-			else {
-				UserTransaction ut = getUserTransaction();
-				return ut != null && JTAHelper.isInProgress( ut.getStatus() );
-			}
-		}
-		catch ( SystemException se ) {
-			throw new TransactionException( "Unable to check transaction status", se );
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/JTATransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,253 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.transaction.SystemException;
+import javax.transaction.UserTransaction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.TransactionException;
+import org.hibernate.jdbc.JDBCContext;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.NamingHelper;
+import org.hibernate.util.JTAHelper;
+
+/**
+ * Factory for {@link JTATransaction} instances.
+ * <p/>
+ * To be completely accurate to the JTA spec, JTA implementations should
+ * publish their contextual {@link UserTransaction} reference into JNDI.
+ * However, in practice there are quite a few <tt>stand-alone</tt>
+ * implementations intended for use outside of J2EE/JEE containers and
+ * which therefore do not publish their {@link UserTransaction} references
+ * into JNDI but which otherwise follow the aspects of the JTA specification.
+ * This {@link TransactionFactory} implementation can support both models.
+ * <p/>
+ * For complete JTA implementations (including dependence on JNDI), the
+ * {@link UserTransaction} reference is obtained by a call to
+ * {@link #resolveInitialContext}.  Hibernate will then attempt to locate the
+ * {@link UserTransaction} within this resolved
+ * {@link InitialContext} based on the namespace returned by
+ * {@link #resolveUserTransactionName}.
+ * <p/>
+ * For the so-called <tt>stand-alone</tt> implementations, we do not care at
+ * all about the JNDI aspects just described.  Here, the implementation would
+ * have a specific manner to obtain a reference to its contextual
+ * {@link UserTransaction}; usually this would be a static code reference, but
+ * again it varies.  Anyway, for each implementation the integration would need
+ * to override the {@link #getUserTransaction} method and return the appropriate
+ * thing.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ * @author Les Hazlewood
+ */
+public class JTATransactionFactory implements TransactionFactory {
+	public static final String DEFAULT_USER_TRANSACTION_NAME = "java:comp/UserTransaction";
+	private static final Logger log = LoggerFactory.getLogger( JTATransactionFactory.class );
+
+	protected InitialContext initialContext;
+	protected String userTransactionName;
+
+	/**
+	 * Configure this transaction factory.  Specifically here we are attempting to
+	 * resolve both an {@link #getInitialContext InitialContext} as well as the
+	 * {@link #getUserTransactionName() JNDI namespace} for the {@link UserTransaction}.
+	 *
+	 * @param props The configuration properties
+	 *
+	 * @exception HibernateException
+	 */
+	public void configure(Properties props) throws HibernateException {
+		this.initialContext = resolveInitialContext( props );
+		this.userTransactionName = resolveUserTransactionName( props );
+		log.trace( "Configured JTATransactionFactory to use [{}] for UserTransaction JDNI namespace", userTransactionName );
+	}
+
+	/**
+	 * Given the lot of Hibernate configuration properties, resolve appropriate
+	 * reference to JNDI {@link InitialContext}.
+	 * <p/>
+	 * In general, the properties in which we are interested here all begin with
+	 * <tt>hibernate.jndi</tt>.  Especially important depending on your
+	 * environment are {@link Environment#JNDI_URL hibernate.jndi.url} and
+	 *  {@link Environment#JNDI_CLASS hibernate.jndi.class}
+	 *
+	 * @param properties The Hibernate config properties.
+	 * @return The resolved InitialContext.
+	 */
+	protected final InitialContext resolveInitialContext(Properties properties) {
+		try {
+			return NamingHelper.getInitialContext( properties );
+		}
+		catch ( NamingException ne ) {
+			throw new HibernateException( "Could not obtain initial context", ne );
+		}
+	}
+
+	/**
+	 * Given the lot of Hibernate configuration properties, resolve appropriate
+	 * JNDI namespace to use for {@link UserTransaction} resolution.
+	 * <p/>
+	 * We determine the namespace to use by<ol>
+	 * <li>Any specified {@link Environment#USER_TRANSACTION jta.UserTransaction} config property</li>
+	 * <li>If a {@link TransactionManagerLookup} was indicated, use its
+	 * {@link TransactionManagerLookup#getUserTransactionName}</li>
+	 * <li>finally, as a last resort, we use {@link #DEFAULT_USER_TRANSACTION_NAME}</li>
+	 * </ol>
+	 *
+	 * @param properties The Hibernate config properties.
+	 * @return The resolved {@link UserTransaction} namespace
+	 */
+	protected final String resolveUserTransactionName(Properties properties) {
+		String utName = properties.getProperty( Environment.USER_TRANSACTION );
+		if ( utName == null ) {
+			TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup( properties );
+			if ( lookup != null ) {
+				utName = lookup.getUserTransactionName();
+			}
+		}
+		return utName == null ? DEFAULT_USER_TRANSACTION_NAME : utName;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext)
+			throws HibernateException {
+		UserTransaction ut = getUserTransaction();
+		return new JTATransaction( ut, jdbcContext, transactionContext );
+	}
+
+	/**
+	 * Get the {@link UserTransaction} reference.
+	 *
+	 * @return The appropriate {@link UserTransaction} reference.
+	 */
+	protected UserTransaction getUserTransaction() {
+		log.trace( "Attempting to locate UserTransaction via JNDI [{}]", getUserTransactionName() );
+
+		try {
+			UserTransaction ut = ( UserTransaction ) getInitialContext().lookup( getUserTransactionName() );
+			if ( ut == null ) {
+				throw new TransactionException( "Naming service lookup for UserTransaction returned null [" + getUserTransactionName() +"]" );
+			}
+
+			log.trace( "Obtained UserTransaction" );
+
+			return ut;
+		}
+		catch ( NamingException ne ) {
+			throw new TransactionException( "Could not find UserTransaction in JNDI [" + getUserTransaction() + "]", ne );
+		}
+	}
+
+	/**
+	 * Getter for property 'initialContext'.
+	 *
+	 * @return Value for property 'initialContext'.
+	 */
+	protected InitialContext getInitialContext() {
+		return initialContext;
+	}
+
+	/**
+	 * Getter for property 'userTransactionName'.
+	 * The algorithm here is
+	 *
+	 * @return Value for property 'userTransactionName'.
+	 */
+	protected String getUserTransactionName() {
+		return userTransactionName;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public ConnectionReleaseMode getDefaultReleaseMode() {
+		return ConnectionReleaseMode.AFTER_STATEMENT;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isTransactionManagerRequired() {
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean areCallbacksLocalToHibernateTransactions() {
+		return false;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isTransactionInProgress(
+			JDBCContext jdbcContext,
+			Context transactionContext,
+			Transaction transaction) {
+		try {
+			// Essentially:
+			// 1) If we have a local (Hibernate) transaction in progress
+			//      and it already has the UserTransaction cached, use that
+			//      UserTransaction to determine the status.
+			// 2) If a transaction manager has been located, use
+			//      that transaction manager to determine the status.
+			// 3) Finally, as the last resort, try to lookup the
+			//      UserTransaction via JNDI and use that to determine the
+			//      status.
+			if ( transaction != null ) {
+				UserTransaction ut = ( ( JTATransaction ) transaction ).getUserTransaction();
+				if ( ut != null ) {
+					return JTAHelper.isInProgress( ut.getStatus() );
+				}
+			}
+
+			if ( jdbcContext.getFactory().getTransactionManager() != null ) {
+				return JTAHelper.isInProgress( jdbcContext.getFactory().getTransactionManager().getStatus() );
+			}
+			else {
+				UserTransaction ut = getUserTransaction();
+				return ut != null && JTAHelper.isInProgress( ut.getStatus() );
+			}
+		}
+		catch ( SystemException se ) {
+			throw new TransactionException( "Unable to check transaction status", se );
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} for the OC4J (Oracle) AS.
- * 
- * @author Stijn Janssens
- */
-public class OC4JTransactionManagerLookup extends JNDITransactionManagerLookup {
-	protected String getName() {
-		return "java:comp/pm/TransactionManager";
-	}
-
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OC4JTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+/*
+ * 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.transaction;
+
+/**
+ * {@link TransactionManagerLookup} for the OC4J (Oracle) AS.
+ * 
+ * @author Stijn Janssens
+ */
+public class OC4JTransactionManagerLookup extends JNDITransactionManagerLookup {
+	protected String getName() {
+		return "java:comp/pm/TransactionManager";
+	}
+
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} strategy for Orion
- *
- * @author Gavin King
- */
-public class OrionTransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	protected String getName() {
-		return "java:comp/UserTransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/OrionTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,54 @@
+/*
+ * 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.transaction;
+
+/**
+ * {@link TransactionManagerLookup} strategy for Orion
+ *
+ * @author Gavin King
+ */
+public class OrionTransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected String getName() {
+		return "java:comp/UserTransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} strategy for Resin
- *
- * @author Aapo Laakkonen
- */
-public class ResinTransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	protected String getName() {
-		return "java:comp/TransactionManager";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/ResinTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.transaction;
+
+/**
+ * {@link TransactionManagerLookup} strategy for Resin
+ *
+ * @author Aapo Laakkonen
+ */
+public class ResinTransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected String getName() {
+		return "java:comp/TransactionManager";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +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.transaction;
-
-/**
- * {@link TransactionManagerLookup} strategy for Sun ONE Application Server 7 and above
- * 
- * @author Robert Davidson
- * @author Sanjeev Krishnan
- * @author Emmanuel Bernard
- */
-public class SunONETransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	protected String getName() {
-		return "java:appserver/TransactionManager";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/SunONETransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.transaction;
+
+/**
+ * {@link TransactionManagerLookup} strategy for Sun ONE Application Server 7 and above
+ * 
+ * @author Robert Davidson
+ * @author Sanjeev Krishnan
+ * @author Emmanuel Bernard
+ */
+public class SunONETransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	protected String getName() {
+		return "java:appserver/TransactionManager";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/TransactionFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +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.transaction;
-
-import java.util.Properties;
-
-import org.hibernate.ConnectionReleaseMode;
-import org.hibernate.HibernateException;
-import org.hibernate.Transaction;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.jdbc.JDBCContext;
-
-/**
- * Contract for generating Hibernate {@link Transaction} instances.
- * <p/>
- * The concrete implementation to be used is specified by the
- * {@link org.hibernate.cfg.Environment#TRANSACTION_STRATEGY} configuration
- * setting.
- * <p/>
- * Implementors must be threadsafe and should declare a public default constructor.
- *
- * @see Transaction
- *
- * @author Anton van Straaten
- * @author Gavin King
- */
-public interface TransactionFactory {
-
-	/**
-	 * Callback mechanism; a context is always a {@link org.hibernate.Session}
-	 * in the Hibernate usage.
-	 */
-	public static interface Context {
-		public SessionFactoryImplementor getFactory();
-		public boolean isClosed();
-
-		public boolean isFlushModeNever();
-		public boolean isFlushBeforeCompletionEnabled();
-		public void managedFlush();
-
-		public boolean shouldAutoClose();
-		public void managedClose();
-	}
-
-	/**
-	 * Begin a transaction and return the associated <tt>Transaction</tt> instance.
-	 *
-	 * @param jdbcContext  The jdbc context to which the transaction belongs
-	 * @param context The contract regarding the context in which this transaction will operate.
-	 * @return Transaction
-	 * @throws HibernateException Indicates a problem generating a transaction instance
-	 */
-	public Transaction createTransaction(JDBCContext jdbcContext, Context context) throws HibernateException;
-
-	/**
-	 * Configure from the given properties.
-	 *
-	 * @param props The configuration properties.
-	 * @throws HibernateException Indicates a problem configuring this factory.
-	 */
-	public void configure(Properties props) throws HibernateException;
-	
-	/**
-	 * Get the default connection release mode.
-	 *
-	 * @return The default release mode associated with this strategy
-	 */
-	public ConnectionReleaseMode getDefaultReleaseMode();
-	
-	/**
-	 * Do we require access to the JTA TransactionManager for
-	 * this strategy?
-	 *
-	 * @return True if this strategy requires access to the JTA TransactionManager;
-	 * false otherwise.
-	 */
-	public boolean isTransactionManagerRequired();
-
-	/**
-	 * Are all transaction callbacks local to Hibernate Transactions?
-	 * Or can the callbacks originate from some other source (e.g. a JTA
-	 * Synchronization).
-	 *
-	 * @return true if callbacks only ever originate from the Hibernate
-	 * {@link Transaction}; false otherwise.
-	 */
-	public boolean areCallbacksLocalToHibernateTransactions();
-
-	/**
-	 * Determine whether an underlying transaction is in progress.
-	 * <p/>
-	 * Mainly this is used in determining whether to register a
-	 * synchronization as well as whether or not to circumvent
-	 * auto flushing outside transactions.
-	 *
-	 * @param jdbcContext The JDBC context
-	 * @param transactionContext The transaction context
-	 * @param transaction The Hibernate transaction
-	 * @return true if an underlying transaction is know to be in effect.
-	 */
-	public boolean isTransactionInProgress(JDBCContext jdbcContext, Context transactionContext, Transaction transaction);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/TransactionFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transaction;
+
+import java.util.Properties;
+
+import org.hibernate.ConnectionReleaseMode;
+import org.hibernate.HibernateException;
+import org.hibernate.Transaction;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.jdbc.JDBCContext;
+
+/**
+ * Contract for generating Hibernate {@link Transaction} instances.
+ * <p/>
+ * The concrete implementation to be used is specified by the
+ * {@link org.hibernate.cfg.Environment#TRANSACTION_STRATEGY} configuration
+ * setting.
+ * <p/>
+ * Implementors must be threadsafe and should declare a public default constructor.
+ *
+ * @see Transaction
+ *
+ * @author Anton van Straaten
+ * @author Gavin King
+ */
+public interface TransactionFactory {
+
+	/**
+	 * Callback mechanism; a context is always a {@link org.hibernate.Session}
+	 * in the Hibernate usage.
+	 */
+	public static interface Context {
+		public SessionFactoryImplementor getFactory();
+		public boolean isClosed();
+
+		public boolean isFlushModeNever();
+		public boolean isFlushBeforeCompletionEnabled();
+		public void managedFlush();
+
+		public boolean shouldAutoClose();
+		public void managedClose();
+	}
+
+	/**
+	 * Begin a transaction and return the associated <tt>Transaction</tt> instance.
+	 *
+	 * @param jdbcContext  The jdbc context to which the transaction belongs
+	 * @param context The contract regarding the context in which this transaction will operate.
+	 * @return Transaction
+	 * @throws HibernateException Indicates a problem generating a transaction instance
+	 */
+	public Transaction createTransaction(JDBCContext jdbcContext, Context context) throws HibernateException;
+
+	/**
+	 * Configure from the given properties.
+	 *
+	 * @param props The configuration properties.
+	 * @throws HibernateException Indicates a problem configuring this factory.
+	 */
+	public void configure(Properties props) throws HibernateException;
+	
+	/**
+	 * Get the default connection release mode.
+	 *
+	 * @return The default release mode associated with this strategy
+	 */
+	public ConnectionReleaseMode getDefaultReleaseMode();
+	
+	/**
+	 * Do we require access to the JTA TransactionManager for
+	 * this strategy?
+	 *
+	 * @return True if this strategy requires access to the JTA TransactionManager;
+	 * false otherwise.
+	 */
+	public boolean isTransactionManagerRequired();
+
+	/**
+	 * Are all transaction callbacks local to Hibernate Transactions?
+	 * Or can the callbacks originate from some other source (e.g. a JTA
+	 * Synchronization).
+	 *
+	 * @return true if callbacks only ever originate from the Hibernate
+	 * {@link Transaction}; false otherwise.
+	 */
+	public boolean areCallbacksLocalToHibernateTransactions();
+
+	/**
+	 * Determine whether an underlying transaction is in progress.
+	 * <p/>
+	 * Mainly this is used in determining whether to register a
+	 * synchronization as well as whether or not to circumvent
+	 * auto flushing outside transactions.
+	 *
+	 * @param jdbcContext The JDBC context
+	 * @param transactionContext The transaction context
+	 * @param transaction The Hibernate transaction
+	 * @return true if an underlying transaction is know to be in effect.
+	 */
+	public boolean isTransactionInProgress(JDBCContext jdbcContext, Context transactionContext, Transaction transaction);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,87 +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.transaction;
-
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Helper for creating {@link TransactionFactory} instances.
- *
- * @author Gavin King
- */
-public final class TransactionFactoryFactory {
-
-	private static final Logger log = LoggerFactory.getLogger( TransactionFactoryFactory.class );
-
-	/**
-	 * Create an appropriate transaction factory based on the given configuration
-	 * properties.
-	 *
-	 * @param transactionProps transaction properties
-	 *
-	 * @return The appropriate transaction factory.
-	 *
-	 * @throws HibernateException Indicates a problem creating the appropriate
-	 * transaction factory.
-	 */
-	public static TransactionFactory buildTransactionFactory(Properties transactionProps) throws HibernateException {
-		String strategyClassName = transactionProps.getProperty( Environment.TRANSACTION_STRATEGY );
-		if ( strategyClassName == null ) {
-			log.info( "Using default transaction strategy (direct JDBC transactions)" );
-			return new JDBCTransactionFactory();
-		}
-		log.info( "Transaction strategy: " + strategyClassName );
-		TransactionFactory factory;
-		try {
-			factory = ( TransactionFactory ) ReflectHelper.classForName( strategyClassName ).newInstance();
-		}
-		catch ( ClassNotFoundException e ) {
-			log.error( "TransactionFactory class not found", e );
-			throw new HibernateException( "TransactionFactory class not found: " + strategyClassName );
-		}
-		catch ( IllegalAccessException e ) {
-			log.error( "Failed to instantiate TransactionFactory", e );
-			throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
-		}
-		catch ( java.lang.InstantiationException e ) {
-			log.error( "Failed to instantiate TransactionFactory", e );
-			throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
-		}
-		factory.configure( transactionProps );
-		return factory;
-	}
-
-	/**
-	 * Disallow instantiation
-	 */
-	private TransactionFactoryFactory() {
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionFactoryFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Helper for creating {@link TransactionFactory} instances.
+ *
+ * @author Gavin King
+ */
+public final class TransactionFactoryFactory {
+
+	private static final Logger log = LoggerFactory.getLogger( TransactionFactoryFactory.class );
+
+	/**
+	 * Create an appropriate transaction factory based on the given configuration
+	 * properties.
+	 *
+	 * @param transactionProps transaction properties
+	 *
+	 * @return The appropriate transaction factory.
+	 *
+	 * @throws HibernateException Indicates a problem creating the appropriate
+	 * transaction factory.
+	 */
+	public static TransactionFactory buildTransactionFactory(Properties transactionProps) throws HibernateException {
+		String strategyClassName = transactionProps.getProperty( Environment.TRANSACTION_STRATEGY );
+		if ( strategyClassName == null ) {
+			log.info( "Using default transaction strategy (direct JDBC transactions)" );
+			return new JDBCTransactionFactory();
+		}
+		log.info( "Transaction strategy: " + strategyClassName );
+		TransactionFactory factory;
+		try {
+			factory = ( TransactionFactory ) ReflectHelper.classForName( strategyClassName ).newInstance();
+		}
+		catch ( ClassNotFoundException e ) {
+			log.error( "TransactionFactory class not found", e );
+			throw new HibernateException( "TransactionFactory class not found: " + strategyClassName );
+		}
+		catch ( IllegalAccessException e ) {
+			log.error( "Failed to instantiate TransactionFactory", e );
+			throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
+		}
+		catch ( java.lang.InstantiationException e ) {
+			log.error( "Failed to instantiate TransactionFactory", e );
+			throw new HibernateException( "Failed to instantiate TransactionFactory: " + e );
+		}
+		factory.configure( transactionProps );
+		return factory;
+	}
+
+	/**
+	 * Disallow instantiation
+	 */
+	private TransactionFactoryFactory() {
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +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.transaction;
-
-import java.util.Properties;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-import org.hibernate.HibernateException;
-
-/**
- * Contract for locating the JTA {@link TransactionManager} on given platform.
- * <p/>
- * NOTE: this contract has expanded over time, and basically is a platform
- * abstraction contract for JTA-related information.
- *
- * @author Gavin King
- */
-public interface TransactionManagerLookup {
-
-	/**
-	 * Obtain the JTA {@link TransactionManager}.
-	 *
-	 * @param props The configuration properties.
-	 * @return The JTA {@link TransactionManager}.
-	 *
-	 * @throws HibernateException Indicates problem locating {@link TransactionManager}.
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException;
-
-	/**
-	 * Return the JNDI namespace of the JTA
-	 * {@link javax.transaction.UserTransaction} for this platform or <tt>null</tt>;
-	 * optional operation.
-	 *
-	 * @return The JNDI namespace where we can locate the
-	 * {@link javax.transaction.UserTransaction} for this platform.
-	 */
-	public String getUserTransactionName();
-
-	/**
-	 * Determine an identifier for the given transaction appropriate for use in caching/lookup usages.
-	 * <p/>
-	 * Generally speaking the transaction itself will be returned here.  This method was added specifically
-	 * for use in WebSphere and other unfriendly JEE containers (although WebSphere is still the only known
-	 * such brain-dead, sales-driven impl).
-	 *
-	 * @param transaction The transaction to be identified.
-	 * @return An appropropriate identifier
-	 */
-	public Object getTransactionIdentifier(Transaction transaction);
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Contract for locating the JTA {@link TransactionManager} on given platform.
+ * <p/>
+ * NOTE: this contract has expanded over time, and basically is a platform
+ * abstraction contract for JTA-related information.
+ *
+ * @author Gavin King
+ */
+public interface TransactionManagerLookup {
+
+	/**
+	 * Obtain the JTA {@link TransactionManager}.
+	 *
+	 * @param props The configuration properties.
+	 * @return The JTA {@link TransactionManager}.
+	 *
+	 * @throws HibernateException Indicates problem locating {@link TransactionManager}.
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException;
+
+	/**
+	 * Return the JNDI namespace of the JTA
+	 * {@link javax.transaction.UserTransaction} for this platform or <tt>null</tt>;
+	 * optional operation.
+	 *
+	 * @return The JNDI namespace where we can locate the
+	 * {@link javax.transaction.UserTransaction} for this platform.
+	 */
+	public String getUserTransactionName();
+
+	/**
+	 * Determine an identifier for the given transaction appropriate for use in caching/lookup usages.
+	 * <p/>
+	 * Generally speaking the transaction itself will be returned here.  This method was added specifically
+	 * for use in WebSphere and other unfriendly JEE containers (although WebSphere is still the only known
+	 * such brain-dead, sales-driven impl).
+	 *
+	 * @param transaction The transaction to be identified.
+	 * @return An appropropriate identifier
+	 */
+	public Object getTransactionIdentifier(Transaction transaction);
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,96 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Helper for generating {@link TransactionManagerLookup} instances.
- *
- * @author Gavin King
- */
-public final class TransactionManagerLookupFactory {
-
-	private static final Logger log = LoggerFactory.getLogger(TransactionManagerLookupFactory.class);
-
-	/**
-	 * Disallow instantiation
-	 */
-	private TransactionManagerLookupFactory() {
-	}
-
-	/**
-	 * Convenience method for locating the JTA {@link TransactionManager} from the
-	 * given platform config.
-	 * <p/>
-	 * Same as calling {@link #getTransactionManager}.getTransactionManager( props )
-	 *
-	 * @param props The properties representing the platform config
-	 * @return The located {@link TransactionManager}
-	 * @throws HibernateException Indicates a problem either (a) generatng the
-	 * {@link TransactionManagerLookup} or (b) asking it to locate the {@link TransactionManager}.
-	 */
-	public static TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		log.info( "obtaining TransactionManager" );
-		return getTransactionManagerLookup( props ).getTransactionManager( props );
-	}
-
-	/**
-	 * Generate the appropriate {@link TransactionManagerLookup} given the
-	 * config settings being passed.
-	 *
-	 * @param props The config settings
-	 * @return The appropriate {@link TransactionManagerLookup}
-	 * @throws HibernateException Indicates problem generating {@link TransactionManagerLookup}
-	 */
-	public static TransactionManagerLookup getTransactionManagerLookup(Properties props) throws HibernateException {
-		String tmLookupClass = props.getProperty( Environment.TRANSACTION_MANAGER_STRATEGY );
-		if ( tmLookupClass == null ) {
-			log.info( "No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)" );
-			return null;
-		}
-		else {
-			log.info( "instantiating TransactionManagerLookup: " + tmLookupClass );
-			try {
-				TransactionManagerLookup lookup = ( TransactionManagerLookup )
-						ReflectHelper.classForName( tmLookupClass ).newInstance();
-				log.info( "instantiated TransactionManagerLookup" );
-				return lookup;
-			}
-			catch ( Exception e ) {
-				log.error( "Could not instantiate TransactionManagerLookup", e );
-				throw new HibernateException( "Could not instantiate TransactionManagerLookup '" + tmLookupClass + "'" );
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/TransactionManagerLookupFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Helper for generating {@link TransactionManagerLookup} instances.
+ *
+ * @author Gavin King
+ */
+public final class TransactionManagerLookupFactory {
+
+	private static final Logger log = LoggerFactory.getLogger(TransactionManagerLookupFactory.class);
+
+	/**
+	 * Disallow instantiation
+	 */
+	private TransactionManagerLookupFactory() {
+	}
+
+	/**
+	 * Convenience method for locating the JTA {@link TransactionManager} from the
+	 * given platform config.
+	 * <p/>
+	 * Same as calling {@link #getTransactionManager}.getTransactionManager( props )
+	 *
+	 * @param props The properties representing the platform config
+	 * @return The located {@link TransactionManager}
+	 * @throws HibernateException Indicates a problem either (a) generatng the
+	 * {@link TransactionManagerLookup} or (b) asking it to locate the {@link TransactionManager}.
+	 */
+	public static TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		log.info( "obtaining TransactionManager" );
+		return getTransactionManagerLookup( props ).getTransactionManager( props );
+	}
+
+	/**
+	 * Generate the appropriate {@link TransactionManagerLookup} given the
+	 * config settings being passed.
+	 *
+	 * @param props The config settings
+	 * @return The appropriate {@link TransactionManagerLookup}
+	 * @throws HibernateException Indicates problem generating {@link TransactionManagerLookup}
+	 */
+	public static TransactionManagerLookup getTransactionManagerLookup(Properties props) throws HibernateException {
+		String tmLookupClass = props.getProperty( Environment.TRANSACTION_MANAGER_STRATEGY );
+		if ( tmLookupClass == null ) {
+			log.info( "No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)" );
+			return null;
+		}
+		else {
+			log.info( "instantiating TransactionManagerLookup: " + tmLookupClass );
+			try {
+				TransactionManagerLookup lookup = ( TransactionManagerLookup )
+						ReflectHelper.classForName( tmLookupClass ).newInstance();
+				log.info( "instantiated TransactionManagerLookup" );
+				return lookup;
+			}
+			catch ( Exception e ) {
+				log.error( "Could not instantiate TransactionManagerLookup", e );
+				throw new HibernateException( "Could not instantiate TransactionManagerLookup '" + tmLookupClass + "'" );
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,312 +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.transaction;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Properties;
-
-import javax.naming.NamingException;
-import javax.transaction.NotSupportedException;
-import javax.transaction.RollbackException;
-import javax.transaction.Status;
-import javax.transaction.Synchronization;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-import javax.transaction.xa.XAResource;
-
-import org.hibernate.HibernateException;
-import org.hibernate.util.NamingHelper;
-
-/**
- * TransactionManagerLookup implementation intended for use with WebSphere
- * Application Server (WAS).
- * <p/>
- * WAS, unlike every other app server on the planet, does not allow direct
- * access to the JTS TransactionManager.  Instead, for common transaction-
- * related tasks users must utilize a proprietary API known as
- * ExtendedJTATransaction.
- * <p/>
- * Even more unfortunate, the exact TransactionManagerLookup to use inside of
- * WAS is highly dependent upon (1) WAS version as well as (2) the WAS
- * container in which Hibernate will be utilized.
- * <p/>
- * WebSphereExtendedJTATransactionLookup is reported to work on WAS version 6
- * in any of the standard J2EE/JEE component containers.
- *
- * @author Gavin King
- * @author <a href="mailto:jesper at udby.com>Jesper Udby</a>
- */
-public class WebSphereExtendedJTATransactionLookup implements TransactionManagerLookup {
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public TransactionManager getTransactionManager(Properties props) {
-		return new TransactionManagerAdapter( props );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return "java:comp/UserTransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		// WebSphere, however, is not a sane JEE/JTA container...
-		return new Integer( transaction.hashCode() );
-	}
-
-	public static class TransactionManagerAdapter implements TransactionManager {
-		private final Properties properties;
-		private final Class synchronizationCallbackClass;
-		private final Method registerSynchronizationMethod;
-		private final Method getLocalIdMethod;
-		private Object extendedJTATransaction;
-
-		private TransactionManagerAdapter(Properties props) throws HibernateException {
-			this.properties = props;
-			try {
-				synchronizationCallbackClass = Class.forName( "com.ibm.websphere.jtaextensions.SynchronizationCallback" );
-				Class extendedJTATransactionClass = Class.forName( "com.ibm.websphere.jtaextensions.ExtendedJTATransaction" );
-				registerSynchronizationMethod = extendedJTATransactionClass.getMethod(
-						"registerSynchronizationCallbackForCurrentTran",
-						new Class[] { synchronizationCallbackClass }
-				);
-				getLocalIdMethod = extendedJTATransactionClass.getMethod( "getLocalId", null );
-
-			}
-			catch ( ClassNotFoundException cnfe ) {
-				throw new HibernateException( cnfe );
-			}
-			catch ( NoSuchMethodException nsme ) {
-				throw new HibernateException( nsme );
-			}
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void begin() throws NotSupportedException, SystemException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void commit() throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public int getStatus() throws SystemException {
-			return getTransaction() == null ? Status.STATUS_NO_TRANSACTION : getTransaction().getStatus();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Transaction getTransaction() throws SystemException {
-			return new TransactionAdapter( properties );
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void resume(Transaction txn) throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void rollback() throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void setRollbackOnly() throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public void setTransactionTimeout(int i) throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		/**
-		 * {@inheritDoc}
-		 */
-		public Transaction suspend() throws UnsupportedOperationException {
-			throw new UnsupportedOperationException();
-		}
-
-		public class TransactionAdapter implements Transaction {
-
-			private TransactionAdapter(Properties props) {
-				try {
-					if ( extendedJTATransaction == null ) {
-						extendedJTATransaction = NamingHelper.getInitialContext( props )
-								.lookup( "java:comp/websphere/ExtendedJTATransaction" );
-					}
-				}
-				catch (NamingException ne) {
-					throw new HibernateException(ne);
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public void registerSynchronization(final Synchronization synchronization)
-					throws RollbackException, IllegalStateException,
-					SystemException {
-
-				final InvocationHandler ih = new InvocationHandler() {
-
-					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-						if ( "afterCompletion".equals( method.getName() ) ) {
-							int status = args[2].equals(Boolean.TRUE) ?
-									Status.STATUS_COMMITTED :
-									Status.STATUS_UNKNOWN;
-							synchronization.afterCompletion(status);
-						}
-						else if ( "beforeCompletion".equals( method.getName() ) ) {
-							synchronization.beforeCompletion();
-						}
-						else if ( "toString".equals( method.getName() ) ) {
-							return synchronization.toString();
-						}
-						return null;
-					}
-
-				};
-
-				final Object synchronizationCallback = Proxy.newProxyInstance(
-						getClass().getClassLoader(),
-						new Class[] { synchronizationCallbackClass },
-						ih
-					);
-
-				try {
-					registerSynchronizationMethod.invoke(
-							extendedJTATransaction,
-							new Object[] { synchronizationCallback }
-						);
-				}
-				catch (Exception e) {
-					throw new HibernateException(e);
-				}
-
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public int hashCode() {
-				return getLocalId().hashCode();
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public boolean equals(Object other) {
-				if ( !(other instanceof TransactionAdapter) ) return false;
-				TransactionAdapter that = (TransactionAdapter) other;
-				return getLocalId().equals( that.getLocalId() );
-			}
-
-			/**
-			 * Getter for property 'localId'.
-			 *
-			 * @return Value for property 'localId'.
-			 */
-			private Object getLocalId() throws HibernateException {
-				try {
-					return getLocalIdMethod.invoke( extendedJTATransaction, null );
-				}
-				catch ( Exception e ) {
-					throw new HibernateException( e );
-				}
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public void commit() throws UnsupportedOperationException {
-				throw new UnsupportedOperationException();
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public boolean delistResource(XAResource resource, int i) throws UnsupportedOperationException {
-				throw new UnsupportedOperationException();
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public boolean enlistResource(XAResource resource) throws UnsupportedOperationException {
-				throw new UnsupportedOperationException();
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public int getStatus() {
-				return new Integer(0).equals( getLocalId() ) ?
-						Status.STATUS_NO_TRANSACTION : Status.STATUS_ACTIVE;
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public void rollback() throws UnsupportedOperationException {
-				throw new UnsupportedOperationException();
-			}
-
-			/**
-			 * {@inheritDoc}
-			 */
-			public void setRollbackOnly() throws UnsupportedOperationException {
-				throw new UnsupportedOperationException();
-			}
-		}
-
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereExtendedJTATransactionLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,313 @@
+/*
+ * 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.transaction;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Properties;
+
+import javax.naming.NamingException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+
+import org.hibernate.HibernateException;
+import org.hibernate.util.NamingHelper;
+
+/**
+ * TransactionManagerLookup implementation intended for use with WebSphere
+ * Application Server (WAS).
+ * <p/>
+ * WAS, unlike every other app server on the planet, does not allow direct
+ * access to the JTS TransactionManager.  Instead, for common transaction-
+ * related tasks users must utilize a proprietary API known as
+ * ExtendedJTATransaction.
+ * <p/>
+ * Even more unfortunate, the exact TransactionManagerLookup to use inside of
+ * WAS is highly dependent upon (1) WAS version as well as (2) the WAS
+ * container in which Hibernate will be utilized.
+ * <p/>
+ * WebSphereExtendedJTATransactionLookup is reported to work on WAS version 6
+ * in any of the standard J2EE/JEE component containers.
+ *
+ * @author Gavin King
+ * @author <a href="mailto:jesper at udby.com>Jesper Udby</a>
+ */
+public class WebSphereExtendedJTATransactionLookup implements TransactionManagerLookup {
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TransactionManager getTransactionManager(Properties props) {
+		return new TransactionManagerAdapter( props );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return "java:comp/UserTransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		// WebSphere, however, is not a sane JEE/JTA container...
+		return new Integer( transaction.hashCode() );
+	}
+
+	public static class TransactionManagerAdapter implements TransactionManager {
+		private final Properties properties;
+		private final Class synchronizationCallbackClass;
+		private final Method registerSynchronizationMethod;
+		private final Method getLocalIdMethod;
+		private Object extendedJTATransaction;
+
+		private TransactionManagerAdapter(Properties props) throws HibernateException {
+			this.properties = props;
+			try {
+				synchronizationCallbackClass = Class.forName( "com.ibm.websphere.jtaextensions.SynchronizationCallback" );
+				Class extendedJTATransactionClass = Class.forName( "com.ibm.websphere.jtaextensions.ExtendedJTATransaction" );
+				registerSynchronizationMethod = extendedJTATransactionClass.getMethod(
+						"registerSynchronizationCallbackForCurrentTran",
+						new Class[] { synchronizationCallbackClass }
+				);
+				getLocalIdMethod = extendedJTATransactionClass.getMethod( "getLocalId", null );
+
+			}
+			catch ( ClassNotFoundException cnfe ) {
+				throw new HibernateException( cnfe );
+			}
+			catch ( NoSuchMethodException nsme ) {
+				throw new HibernateException( nsme );
+			}
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void begin() throws NotSupportedException, SystemException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void commit() throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public int getStatus() throws SystemException {
+			return getTransaction() == null ? Status.STATUS_NO_TRANSACTION : getTransaction().getStatus();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Transaction getTransaction() throws SystemException {
+			return new TransactionAdapter( properties );
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void resume(Transaction txn) throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void rollback() throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void setRollbackOnly() throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public void setTransactionTimeout(int i) throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public Transaction suspend() throws UnsupportedOperationException {
+			throw new UnsupportedOperationException();
+		}
+
+		public class TransactionAdapter implements Transaction {
+
+			private TransactionAdapter(Properties props) {
+				try {
+					if ( extendedJTATransaction == null ) {
+						extendedJTATransaction = NamingHelper.getInitialContext( props )
+								.lookup( "java:comp/websphere/ExtendedJTATransaction" );
+					}
+				}
+				catch (NamingException ne) {
+					throw new HibernateException(ne);
+				}
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public void registerSynchronization(final Synchronization synchronization)
+					throws RollbackException, IllegalStateException,
+					SystemException {
+
+				final InvocationHandler ih = new InvocationHandler() {
+
+					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+						if ( "afterCompletion".equals( method.getName() ) ) {
+							int status = args[2].equals(Boolean.TRUE) ?
+									Status.STATUS_COMMITTED :
+									Status.STATUS_UNKNOWN;
+							synchronization.afterCompletion(status);
+						}
+						else if ( "beforeCompletion".equals( method.getName() ) ) {
+							synchronization.beforeCompletion();
+						}
+						else if ( "toString".equals( method.getName() ) ) {
+							return synchronization.toString();
+						}
+						return null;
+					}
+
+				};
+
+				final Object synchronizationCallback = Proxy.newProxyInstance(
+						getClass().getClassLoader(),
+						new Class[] { synchronizationCallbackClass },
+						ih
+					);
+
+				try {
+					registerSynchronizationMethod.invoke(
+							extendedJTATransaction,
+							new Object[] { synchronizationCallback }
+						);
+				}
+				catch (Exception e) {
+					throw new HibernateException(e);
+				}
+
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public int hashCode() {
+				return getLocalId().hashCode();
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public boolean equals(Object other) {
+				if ( !(other instanceof TransactionAdapter) ) return false;
+				TransactionAdapter that = (TransactionAdapter) other;
+				return getLocalId().equals( that.getLocalId() );
+			}
+
+			/**
+			 * Getter for property 'localId'.
+			 *
+			 * @return Value for property 'localId'.
+			 */
+			private Object getLocalId() throws HibernateException {
+				try {
+					return getLocalIdMethod.invoke( extendedJTATransaction, null );
+				}
+				catch ( Exception e ) {
+					throw new HibernateException( e );
+				}
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public void commit() throws UnsupportedOperationException {
+				throw new UnsupportedOperationException();
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public boolean delistResource(XAResource resource, int i) throws UnsupportedOperationException {
+				throw new UnsupportedOperationException();
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public boolean enlistResource(XAResource resource) throws UnsupportedOperationException {
+				throw new UnsupportedOperationException();
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public int getStatus() {
+				return new Integer(0).equals( getLocalId() ) ?
+						Status.STATUS_NO_TRANSACTION : Status.STATUS_ACTIVE;
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public void rollback() throws UnsupportedOperationException {
+				throw new UnsupportedOperationException();
+			}
+
+			/**
+			 * {@inheritDoc}
+			 */
+			public void setRollbackOnly() throws UnsupportedOperationException {
+				throw new UnsupportedOperationException();
+			}
+		}
+
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +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.transaction;
-
-import java.util.Properties;
-
-import javax.transaction.TransactionManager;
-import javax.transaction.Transaction;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.HibernateException;
-
-/**
- * {@link TransactionManagerLookup} strategy for WebSphere (versions 4, 5.0 and 5.1)
- *
- * @author Gavin King
- */
-public class WebSphereTransactionManagerLookup implements TransactionManagerLookup {
-
-	private static final Logger log = LoggerFactory.getLogger(WebSphereTransactionManagerLookup.class);
-	private final int wsVersion;
-	private final Class tmfClass;
-	
-	/**
-	 * Constructs a new WebSphereTransactionManagerLookup.
-	 */
-	public WebSphereTransactionManagerLookup() {
-		try {
-			Class clazz;
-			int version;
-			try {
-				clazz = Class.forName( "com.ibm.ws.Transaction.TransactionManagerFactory" );
-				version = 5;
-				log.info( "WebSphere 5.1" );
-			}
-			catch ( Exception e ) {
-				try {
-					clazz = Class.forName( "com.ibm.ejs.jts.jta.TransactionManagerFactory" );
-					version = 5;
-					log.info( "WebSphere 5.0" );
-				} 
-				catch ( Exception e2 ) {
-					clazz = Class.forName( "com.ibm.ejs.jts.jta.JTSXA" );
-					version = 4;
-					log.info( "WebSphere 4" );
-				}
-			}
-
-			tmfClass = clazz;
-			wsVersion = version;
-		}
-		catch ( Exception e ) {
-			throw new HibernateException( "Could not obtain WebSphere TransactionManagerFactory instance", e );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
-		try {
-			return ( TransactionManager ) tmfClass.getMethod( "getTransactionManager", null ).invoke( null, null );
-		}
-		catch ( Exception e ) {
-			throw new HibernateException( "Could not obtain WebSphere TransactionManager", e );
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public String getUserTransactionName() {
-		return wsVersion == 5
-				? "java:comp/UserTransaction"
-				: "jta/usertransaction";
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object getTransactionIdentifier(Transaction transaction) {
-		return transaction;
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WebSphereTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,108 @@
+/*
+ * 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.transaction;
+
+import java.util.Properties;
+
+import javax.transaction.TransactionManager;
+import javax.transaction.Transaction;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.HibernateException;
+
+/**
+ * {@link TransactionManagerLookup} strategy for WebSphere (versions 4, 5.0 and 5.1)
+ *
+ * @author Gavin King
+ */
+public class WebSphereTransactionManagerLookup implements TransactionManagerLookup {
+
+	private static final Logger log = LoggerFactory.getLogger(WebSphereTransactionManagerLookup.class);
+	private final int wsVersion;
+	private final Class tmfClass;
+	
+	/**
+	 * Constructs a new WebSphereTransactionManagerLookup.
+	 */
+	public WebSphereTransactionManagerLookup() {
+		try {
+			Class clazz;
+			int version;
+			try {
+				clazz = Class.forName( "com.ibm.ws.Transaction.TransactionManagerFactory" );
+				version = 5;
+				log.info( "WebSphere 5.1" );
+			}
+			catch ( Exception e ) {
+				try {
+					clazz = Class.forName( "com.ibm.ejs.jts.jta.TransactionManagerFactory" );
+					version = 5;
+					log.info( "WebSphere 5.0" );
+				} 
+				catch ( Exception e2 ) {
+					clazz = Class.forName( "com.ibm.ejs.jts.jta.JTSXA" );
+					version = 4;
+					log.info( "WebSphere 4" );
+				}
+			}
+
+			tmfClass = clazz;
+			wsVersion = version;
+		}
+		catch ( Exception e ) {
+			throw new HibernateException( "Could not obtain WebSphere TransactionManagerFactory instance", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public TransactionManager getTransactionManager(Properties props) throws HibernateException {
+		try {
+			return ( TransactionManager ) tmfClass.getMethod( "getTransactionManager", null ).invoke( null, null );
+		}
+		catch ( Exception e ) {
+			throw new HibernateException( "Could not obtain WebSphere TransactionManager", e );
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public String getUserTransactionName() {
+		return wsVersion == 5
+				? "java:comp/UserTransaction"
+				: "jta/usertransaction";
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object getTransactionIdentifier(Transaction transaction) {
+		return transaction;
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: WeblogicTransactionManagerLookup.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.transaction;
-
-/**
- * TransactionManager lookup strategy for WebLogic
- * @author Gavin King
- */
-public final class WeblogicTransactionManagerLookup extends JNDITransactionManagerLookup {
-
-	/**
-	 * @see org.hibernate.transaction.JNDITransactionManagerLookup#getName()
-	 */
-	protected String getName() {
-		return "javax.transaction.TransactionManager";
-	}
-
-	public String getUserTransactionName() {
-		return "javax.transaction.UserTransaction";
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/WeblogicTransactionManagerLookup.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.transaction;
+
+/**
+ * TransactionManager lookup strategy for WebLogic
+ * @author Gavin King
+ */
+public final class WeblogicTransactionManagerLookup extends JNDITransactionManagerLookup {
+
+	/**
+	 * @see org.hibernate.transaction.JNDITransactionManagerLookup#getName()
+	 */
+	protected String getName() {
+		return "javax.transaction.TransactionManager";
+	}
+
+	public String getUserTransactionName() {
+		return "javax.transaction.UserTransaction";
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transaction/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,10 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package abstracts the underlying transaction mechanism
-	(JTA or JDBC) and provides strategies for obtaining application
-	server <tt>TransactionManager</tt>s.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transaction/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transaction/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package abstracts the underlying transaction mechanism
+	(JTA or JDBC) and provides strategies for obtaining application
+	server <tt>TransactionManager</tt>s.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,33 +0,0 @@
-package org.hibernate.transform;
-
-import java.lang.reflect.Constructor;
-import java.util.List;
-
-import org.hibernate.QueryException;
-
-public class AliasToBeanConstructorResultTransformer implements ResultTransformer {
-
-	private Constructor constructor;
-
-	public AliasToBeanConstructorResultTransformer(Constructor constructor) {
-		this.constructor = constructor;
-	}
-	
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		try {
-			return constructor.newInstance( tuple );
-		}
-		catch ( Exception e ) {
-			throw new QueryException( 
-					"could not instantiate: " + 
-					constructor.getDeclaringClass().getName(), 
-					e );
-		}
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanConstructorResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.transform;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+
+import org.hibernate.QueryException;
+
+/**
+ * Wraps the tuples in a constructor call.
+ *
+ * todo : why Alias* in the name???
+ */
+public class AliasToBeanConstructorResultTransformer implements ResultTransformer {
+
+	private final Constructor constructor;
+
+	/**
+	 * Instantiates a AliasToBeanConstructorResultTransformer.
+	 *
+	 * @param constructor The contructor in which to wrap the tuples.
+	 */
+	public AliasToBeanConstructorResultTransformer(Constructor constructor) {
+		this.constructor = constructor;
+	}
+	
+	/**
+	 * Wrap the incoming tuples in a call to our configured constructor.
+	 */
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		try {
+			return constructor.newInstance( tuple );
+		}
+		catch ( Exception e ) {
+			throw new QueryException( 
+					"could not instantiate class [" + constructor.getDeclaringClass().getName() + "] from tuple",
+					e
+			);
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public List transformList(List collection) {
+		return collection;
+	}
+
+	/**
+	 * Define our hashCode by our defined constructor's hasCode.
+	 *
+	 * @return Our defined ctor hashCode
+	 */
+	public int hashCode() {
+		return constructor.hashCode();
+	}
+
+	/**
+	 * 2 AliasToBeanConstructorResultTransformer are considered equal if they have the same
+	 * defined constructor.
+	 *
+	 * @param other The other instance to check for equality.
+	 * @return True if both have the same defined constuctor; false otherwise.
+	 */
+	public boolean equals(Object other) {
+		return other instanceof AliasToBeanConstructorResultTransformer
+				&& constructor.equals( ( ( AliasToBeanConstructorResultTransformer ) other ).constructor );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-/*
- * Created on 27-Jan-2005
- *
- */
-package org.hibernate.transform;
-
-import java.util.List;
-
-import org.hibernate.HibernateException;
-import org.hibernate.property.ChainedPropertyAccessor;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-
-/**
- * Result transformer that allows to transform a result to 
- * a user specified class which will be populated via setter  
- * methods or fields matching the alias names. 
- * 
- * <pre>
- * List resultWithAliasedBean = s.createCriteria(Enrolment.class)
- *			.createAlias("student", "st")
- *			.createAlias("course", "co")
- *			.setProjection( Projections.projectionList()
- *					.add( Projections.property("co.description"), "courseDescription" )
- *			)
- *			.setResultTransformer( new AliasToBeanResultTransformer(StudentDTO.class) )
- *			.list();
- *
- *  StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0);
- *	</pre>
- *
- * @author max
- *
- */
-public class AliasToBeanResultTransformer implements ResultTransformer {
-	
-	private final Class resultClass;
-	private Setter[] setters;
-	private PropertyAccessor propertyAccessor;
-	
-	public AliasToBeanResultTransformer(Class resultClass) {
-		if(resultClass==null) throw new IllegalArgumentException("resultClass cannot be null");
-		this.resultClass = resultClass;
-		propertyAccessor = new ChainedPropertyAccessor(new PropertyAccessor[] { PropertyAccessorFactory.getPropertyAccessor(resultClass,null), PropertyAccessorFactory.getPropertyAccessor("field")}); 		
-	}
-
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		Object result;
-		
-		try {
-			if(setters==null) {
-				setters = new Setter[aliases.length];
-				for (int i = 0; i < aliases.length; i++) {
-					String alias = aliases[i];
-					if(alias != null) {
-						setters[i] = propertyAccessor.getSetter(resultClass, alias);
-					}
-				}
-			}
-			result = resultClass.newInstance();
-			
-			for (int i = 0; i < aliases.length; i++) {
-				if(setters[i]!=null) {
-					setters[i].set(result, tuple[i], null);
-				}
-			}
-		} catch (InstantiationException e) {
-			throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
-		} catch (IllegalAccessException e) {
-			throw new HibernateException("Could not instantiate resultclass: " + resultClass.getName());
-		}
-		
-		return result;
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToBeanResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,119 @@
+/*
+ * 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.transform;
+
+import java.util.List;
+
+import org.hibernate.HibernateException;
+import org.hibernate.property.ChainedPropertyAccessor;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+
+/**
+ * Result transformer that allows to transform a result to
+ * a user specified class which will be populated via setter
+ * methods or fields matching the alias names.
+ * <p/>
+ * <pre>
+ * List resultWithAliasedBean = s.createCriteria(Enrolment.class)
+ * 			.createAlias("student", "st")
+ * 			.createAlias("course", "co")
+ * 			.setProjection( Projections.projectionList()
+ * 					.add( Projections.property("co.description"), "courseDescription" )
+ * 			)
+ * 			.setResultTransformer( new AliasToBeanResultTransformer(StudentDTO.class) )
+ * 			.list();
+ * <p/>
+ *  StudentDTO dto = (StudentDTO)resultWithAliasedBean.get(0);
+ * 	</pre>
+ *
+ * @author max
+ */
+public class AliasToBeanResultTransformer implements ResultTransformer {
+
+	// IMPL NOTE : due to the delayed population of setters (setters cached
+	// 		for performance), we really cannot pro0perly define equality for
+	// 		this transformer
+
+	private final Class resultClass;
+	private final PropertyAccessor propertyAccessor;
+	private Setter[] setters;
+
+	public AliasToBeanResultTransformer(Class resultClass) {
+		if ( resultClass == null ) {
+			throw new IllegalArgumentException( "resultClass cannot be null" );
+		}
+		this.resultClass = resultClass;
+		propertyAccessor = new ChainedPropertyAccessor(
+				new PropertyAccessor[] {
+						PropertyAccessorFactory.getPropertyAccessor( resultClass, null ),
+						PropertyAccessorFactory.getPropertyAccessor( "field" )
+				}
+		);
+	}
+
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		Object result;
+
+		try {
+			if ( setters == null ) {
+				setters = new Setter[aliases.length];
+				for ( int i = 0; i < aliases.length; i++ ) {
+					String alias = aliases[i];
+					if ( alias != null ) {
+						setters[i] = propertyAccessor.getSetter( resultClass, alias );
+					}
+				}
+			}
+			result = resultClass.newInstance();
+
+			for ( int i = 0; i < aliases.length; i++ ) {
+				if ( setters[i] != null ) {
+					setters[i].set( result, tuple[i], null );
+				}
+			}
+		}
+		catch ( InstantiationException e ) {
+			throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() );
+		}
+		catch ( IllegalAccessException e ) {
+			throw new HibernateException( "Could not instantiate resultclass: " + resultClass.getName() );
+		}
+
+		return result;
+	}
+
+	public List transformList(List collection) {
+		return collection;
+	}
+
+	public int hashCode() {
+		int result;
+		result = resultClass.hashCode();
+		result = 31 * result + propertyAccessor.hashCode();
+		return result;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,28 +0,0 @@
-//$Id: AliasToEntityMapResultTransformer.java 9649 2006-03-17 11:25:05Z max.andersen at jboss.com $
-package org.hibernate.transform;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Gavin King
- */
-public class AliasToEntityMapResultTransformer implements ResultTransformer {
-
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		Map result = new HashMap(tuple.length);
-		for ( int i=0; i<tuple.length; i++ ) {
-			String alias = aliases[i];
-			if ( alias!=null ) {
-				result.put( alias, tuple[i] );
-			}
-		}
-		return result;
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/AliasToEntityMapResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,99 @@
+/*
+ * 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.transform;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.io.Serializable;
+
+/**
+ * {@link ResultTransformer} implementation which builds a map for each "row",
+ * made up  of each aliased value where the alias is the map key.
+ * <p/>
+ * Since this transformer is stateless, all instances would be considered equal.
+ * So for optimization purposes we limit it to a single, singleton {@link #INSTANCE instance}.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class AliasToEntityMapResultTransformer extends BasicTransformerAdapter implements Serializable {
+
+	public static final AliasToEntityMapResultTransformer INSTANCE = new AliasToEntityMapResultTransformer();
+
+	/**
+	 * Instantiate AliasToEntityMapResultTransformer.
+	 *
+	 * @deprecated Use the {@link #INSTANCE} reference instead of explicitly creating a new one.
+	 */
+	public AliasToEntityMapResultTransformer() {
+		// todo : make private
+	}
+
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		Map result = new HashMap(tuple.length);
+		for ( int i=0; i<tuple.length; i++ ) {
+			String alias = aliases[i];
+			if ( alias!=null ) {
+				result.put( alias, tuple[i] );
+			}
+		}
+		return result;
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+
+
+	// all AliasToEntityMapResultTransformer are considered equal ~~~~~~~~~~~~~
+
+	/**
+	 * All AliasToEntityMapResultTransformer are considered equal
+	 *
+	 * @param other The other instance to check for equality
+	 * @return True if (non-null) other is a instance of
+	 * AliasToEntityMapResultTransformer.
+	 */
+	public boolean equals(Object other) {
+		// todo : we can remove this once the deprecated ctor can be made private...
+		return other != null && AliasToEntityMapResultTransformer.class.isInstance( other );
+	}
+
+	/**
+	 * All AliasToEntityMapResultTransformer are considered equal
+	 *
+	 * @return We simply return the hashCode of the
+	 * AliasToEntityMapResultTransformer class name string.
+	 */
+	public int hashCode() {
+		// todo : we can remove this once the deprecated ctor can be made private...
+		return getClass().getName().hashCode();
+	}
+}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/BasicTransformerAdapter.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/BasicTransformerAdapter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/BasicTransformerAdapter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/BasicTransformerAdapter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,42 @@
+/*
+ * 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.transform;
+
+import java.util.List;
+
+/**
+ * Provides the basic "noop" impls of the {@link ResultTransformer} contract.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class BasicTransformerAdapter implements ResultTransformer {
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		return tuple;
+	}
+
+	public List transformList(List list) {
+		return list;
+	}
+}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/DistinctResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,113 @@
+/*
+ * 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.transform;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Set;
+import java.util.HashSet;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Distinctions the result tuples in the final result based on the defined
+ * equality of the tuples.
+ * <p/>
+ * Since this transformer is stateless, all instances would be considered equal.
+ * So for optimization purposes we limit it to a single, singleton {@link #INSTANCE instance}.
+ *
+ * @author Steve Ebersole
+ */
+public class DistinctResultTransformer extends BasicTransformerAdapter implements Serializable {
+
+	public static final DistinctResultTransformer INSTANCE = new DistinctResultTransformer();
+
+	private static final Logger log = LoggerFactory.getLogger( DistinctResultTransformer.class );
+
+	/**
+	 * Helper class to handle distincting
+	 */
+	private static final class Identity {
+		final Object entity;
+
+		private Identity(Object entity) {
+			this.entity = entity;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public boolean equals(Object other) {
+			return Identity.class.isInstance( other )
+					&& this.entity == ( ( Identity ) other ).entity;
+		}
+
+		/**
+		 * {@inheritDoc}
+		 */
+		public int hashCode() {
+			return System.identityHashCode( entity );
+		}
+	}
+
+	/**
+	 * Disallow instantiation of DistinctResultTransformer.
+	 */
+	private DistinctResultTransformer() {
+	}
+
+	/**
+	 * Uniquely distinct each tuple row here.
+	 */
+	public List transformList(List list) {
+		List result = new ArrayList( list.size() );
+		Set distinct = new HashSet();
+		for ( int i = 0; i < list.size(); i++ ) {
+			Object entity = list.get( i );
+			if ( distinct.add( new Identity( entity ) ) ) {
+				result.add( entity );
+			}
+		}
+		if ( log.isDebugEnabled() ) {
+			log.debug(
+					"transformed: " +
+							list.size() + " rows to: " +
+							result.size() + " distinct results"
+			);
+		}
+		return result;
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: DistinctRootEntityResultTransformer.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.transform;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * @author Gavin King
- */
-public class DistinctRootEntityResultTransformer implements ResultTransformer {
-
-	private static final Logger log = LoggerFactory.getLogger(DistinctRootEntityResultTransformer.class);
-
-	static final class Identity {
-		final Object entity;
-		Identity(Object entity) {
-			this.entity = entity;
-		}
-		public boolean equals(Object other) {
-			Identity that = (Identity) other;
-			return entity==that.entity;
-		}
-		public int hashCode() {
-			return System.identityHashCode(entity);
-		}
-	}
-
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		return tuple[ tuple.length-1 ];
-	}
-
-	public List transformList(List list) {
-		List result = new ArrayList( list.size() );
-		Set distinct = new HashSet();
-		for ( int i=0; i<list.size(); i++ ) {
-			Object entity = list.get(i);
-			if ( distinct.add( new Identity(entity) ) ) {
-				result.add(entity);
-			}
-		}
-		if ( log.isDebugEnabled() ) log.debug(
-			"transformed: " +
-			list.size() + " rows to: " +
-			result.size() + " distinct results"
-		);
-		return result;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/DistinctRootEntityResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transform;
+
+import java.util.List;
+import java.io.Serializable;
+
+/**
+ * Much like {@link RootEntityResultTransformer}, but we also distinct
+ * the entity in the final result.
+ * <p/>
+ * Since this transformer is stateless, all instances would be considered equal.
+ * So for optimization purposes we limit it to a single, singleton {@link #INSTANCE instance}.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class DistinctRootEntityResultTransformer implements ResultTransformer, Serializable {
+
+	public static final DistinctRootEntityResultTransformer INSTANCE = new DistinctRootEntityResultTransformer();
+
+	/**
+	 * Instantiate a DistinctRootEntityResultTransformer.
+	 *
+	 * @deprecated Use the {@link #INSTANCE} reference instead of explicitly creating a new one.
+	 */
+	public DistinctRootEntityResultTransformer() {
+	}
+
+	/**
+	 * Simply delegates to {@link RootEntityResultTransformer#transformTuple}.
+	 *
+	 * @param tuple The tuple to transform
+	 * @param aliases The tuple aliases
+	 * @return The transformed tuple row.
+	 */
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		return RootEntityResultTransformer.INSTANCE.transformTuple( tuple, aliases );
+	}
+
+	/**
+	 * Simply delegates to {@link DistinctResultTransformer#transformList}.
+	 *
+	 * @param list The list to transform.
+	 * @return The transformed List.
+	 */
+	public List transformList(List list) {
+		return DistinctResultTransformer.INSTANCE.transformList( list );
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+
+	public boolean equals(Object obj) {
+		// todo : we can remove this once the deprecated ctor can be made private...
+		return DistinctRootEntityResultTransformer.class.isInstance( obj );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,19 +0,0 @@
-//$Id: PassThroughResultTransformer.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.transform;
-
-import java.util.List;
-
-/**
- * @author max
- */
-public class PassThroughResultTransformer implements ResultTransformer {
-
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		return tuple.length==1 ? tuple[0] : tuple;
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/PassThroughResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transform;
+
+import java.io.Serializable;
+
+/**
+ * ???
+ *
+ * @author max
+ */
+public class PassThroughResultTransformer extends BasicTransformerAdapter implements Serializable {
+
+	public static final PassThroughResultTransformer INSTANCE = new PassThroughResultTransformer();
+
+	/**
+	 * Instamtiate a PassThroughResultTransformer.
+	 *
+	 * @deprecated Use the {@link #INSTANCE} reference instead of explicitly creating a new one.
+	 */
+	public PassThroughResultTransformer() {
+	}
+
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		return tuple.length==1 ? tuple[0] : tuple;
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+
+	public boolean equals(Object obj) {
+		// todo : we can remove this once the deprecated ctor can be made private...
+		return PassThroughResultTransformer.class.isInstance( obj );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/ResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: ResultTransformer.java 5685 2005-02-12 07:19:50Z steveebersole $
-package org.hibernate.transform;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * Implementors define a strategy for transforming criteria query
- * results into the actual application-visible query result list.
- * @see org.hibernate.Criteria#setResultTransformer(ResultTransformer)
- * @author Gavin King
- */
-public interface ResultTransformer extends Serializable {
-	public Object transformTuple(Object[] tuple, String[] aliases);
-	public List transformList(List collection);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transform/ResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transform;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * Implementors define a strategy for transforming query results into the
+ * actual application-visible query result list.
+ *
+ * @see org.hibernate.Criteria#setResultTransformer(ResultTransformer)
+ * @see org.hibernate.Query#setResultTransformer(ResultTransformer)
+ *
+ * @author Gavin King
+ */
+public interface ResultTransformer extends Serializable {
+	/**
+	 * Tuples are the elements making up each "row" of the query result.
+	 * The contract here is to transform these elements into the final
+	 * row.
+	 *
+	 * @param tuple The result elements
+	 * @param aliases The result aliases ("parallel" array to tuple)
+	 * @return The transformed row.
+	 */
+	public Object transformTuple(Object[] tuple, String[] aliases);
+
+	/**
+	 * Here we have an opportunity to perform transformation on the
+	 * query result as a whole.  This might be useful to convert from
+	 * one collection type to another or to remove duplicates from the
+	 * result, etc.
+	 *
+	 * @param collection The result.
+	 * @return The transformed result.
+	 */
+	public List transformList(List collection);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,19 +0,0 @@
-//$Id: RootEntityResultTransformer.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.transform;
-
-import java.util.List;
-
-/**
- * @author Gavin King
- */
-public class RootEntityResultTransformer implements ResultTransformer {
-
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		return tuple[ tuple.length-1 ];
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/RootEntityResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.transform;
+
+import java.util.List;
+import java.io.Serializable;
+
+/**
+ * {@link ResultTransformer} implementation which limits the result tuple
+ * to only the "root entity".
+ * <p/>
+ * Since this transformer is stateless, all instances would be considered equal.
+ * So for optimization purposes we limit it to a single, singleton {@link #INSTANCE instance}.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public final class RootEntityResultTransformer extends BasicTransformerAdapter implements Serializable {
+
+	public static final RootEntityResultTransformer INSTANCE = new RootEntityResultTransformer();
+
+	/**
+	 * Instantiate RootEntityResultTransformer.
+	 *
+	 * @deprecated Use the {@link #INSTANCE} reference instead of explicitly creating a new one.
+	 */
+	public RootEntityResultTransformer() {
+	}
+
+	/**
+	 * Return just the root entity from the row tuple.
+	 */
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		return tuple[ tuple.length-1 ];
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+
+	public boolean equals(Object obj) {
+		// todo : we can remove this once the deprecated ctor can be made private...
+		return RootEntityResultTransformer.class.isInstance( obj );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-package org.hibernate.transform;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class ToListResultTransformer implements ResultTransformer {
-
-	public static final ResultTransformer INSTANCE = new ToListResultTransformer();
-
-	private ToListResultTransformer() {}
-	
-	public Object transformTuple(Object[] tuple, String[] aliases) {
-		return Arrays.asList(tuple);
-	}
-
-	public List transformList(List collection) {
-		return collection;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java (from rev 14995, core/trunk/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/ToListResultTransformer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.transform;
+
+import java.util.Arrays;
+import java.util.List;
+import java.io.Serializable;
+
+/**
+ * Tranforms each result row from a tuple into a {@link List}, such that what
+ * you end up with is a {@link List} of {@link List Lists}.
+ */
+public class ToListResultTransformer extends BasicTransformerAdapter implements Serializable {
+
+	public static final ToListResultTransformer INSTANCE = new ToListResultTransformer();
+
+	/**
+	 * Disallow instantiation of ToListResultTransformer.
+	 */
+	private ToListResultTransformer() {
+	}
+	
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object transformTuple(Object[] tuple, String[] aliases) {
+		return Arrays.asList( tuple );
+	}
+
+	/**
+	 * Serialization hook for ensuring singleton uniqueing.
+	 *
+	 * @return The singleton instance : {@link #INSTANCE}
+	 */
+	private Object readResolve() {
+		return INSTANCE;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/Transformers.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-package org.hibernate.transform;
-
-final public class Transformers {
-
-	private Transformers() {}
-	
-	/**
-	 * Each row of results is a <tt>Map</tt> from alias to values/entities
-	 */
-	public static final ResultTransformer ALIAS_TO_ENTITY_MAP = new AliasToEntityMapResultTransformer();
-
-	/**
-	 * Each row of results is a <tt>List</tt> 
-	 */
-	public static final ResultTransformer TO_LIST = ToListResultTransformer.INSTANCE;
-	
-	/**
-	 * Creates a resulttransformer that will inject aliased values into 
-	 * instances of Class via property methods or fields.
-	 */
-	public static ResultTransformer aliasToBean(Class target) {
-		return new AliasToBeanResultTransformer(target);
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java (from rev 14996, core/trunk/core/src/main/java/org/hibernate/transform/Transformers.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/Transformers.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.transform;
+
+final public class Transformers {
+
+	private Transformers() {}
+	
+	/**
+	 * Each row of results is a <tt>Map</tt> from alias to values/entities
+	 */
+	public static final AliasToEntityMapResultTransformer ALIAS_TO_ENTITY_MAP =
+			AliasToEntityMapResultTransformer.INSTANCE;
+
+	/**
+	 * Each row of results is a <tt>List</tt> 
+	 */
+	public static final ToListResultTransformer TO_LIST = ToListResultTransformer.INSTANCE;
+	
+	/**
+	 * Creates a resulttransformer that will inject aliased values into 
+	 * instances of Class via property methods or fields.
+	 */
+	public static ResultTransformer aliasToBean(Class target) {
+		return new AliasToBeanResultTransformer(target);
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/transform/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Defines strategies for post-processing criteria query
-	result sets into a form convenient to the application.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/transform/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/transform/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Defines strategies for post-processing criteria query
+	result sets into a form convenient to the application.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: Dom4jInstantiator.java 7449 2005-07-11 17:31:50Z steveebersole $
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Iterator;
-
-import org.dom4j.Element;
-import org.hibernate.util.XMLHelper;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Component;
-
-/**
- * Performs "instantiation" based on DOM4J elements.
- */
-public class Dom4jInstantiator implements Instantiator {
-	private final String nodeName;
-	private final HashSet isInstanceNodeNames = new HashSet();
-
-	public Dom4jInstantiator(Component component) {
-		this.nodeName = component.getNodeName();
-		isInstanceNodeNames.add( nodeName );
-	}
-
-	public Dom4jInstantiator(PersistentClass mappingInfo) {
-		this.nodeName = mappingInfo.getNodeName();
-		isInstanceNodeNames.add( nodeName );
-
-		if ( mappingInfo.hasSubclasses() ) {
-			Iterator itr = mappingInfo.getSubclassClosureIterator();
-			while ( itr.hasNext() ) {
-				final PersistentClass subclassInfo = ( PersistentClass ) itr.next();
-				isInstanceNodeNames.add( subclassInfo.getNodeName() );
-			}
-		}
-	}
-	
-	public Object instantiate(Serializable id) {
-		return instantiate();
-	}
-	
-	public Object instantiate() {
-		return XMLHelper.generateDom4jElement( nodeName );
-	}
-
-	public boolean isInstance(Object object) {
-		if ( object instanceof Element ) {
-			return isInstanceNodeNames.contains( ( ( Element ) object ).getName() );
-		}
-		else {
-			return false;
-		}
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Dom4jInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import org.dom4j.Element;
+import org.hibernate.util.XMLHelper;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Component;
+
+/**
+ * Performs "instantiation" based on DOM4J elements.
+ */
+public class Dom4jInstantiator implements Instantiator {
+	private final String nodeName;
+	private final HashSet isInstanceNodeNames = new HashSet();
+
+	public Dom4jInstantiator(Component component) {
+		this.nodeName = component.getNodeName();
+		isInstanceNodeNames.add( nodeName );
+	}
+
+	public Dom4jInstantiator(PersistentClass mappingInfo) {
+		this.nodeName = mappingInfo.getNodeName();
+		isInstanceNodeNames.add( nodeName );
+
+		if ( mappingInfo.hasSubclasses() ) {
+			Iterator itr = mappingInfo.getSubclassClosureIterator();
+			while ( itr.hasNext() ) {
+				final PersistentClass subclassInfo = ( PersistentClass ) itr.next();
+				isInstanceNodeNames.add( subclassInfo.getNodeName() );
+			}
+		}
+	}
+	
+	public Object instantiate(Serializable id) {
+		return instantiate();
+	}
+	
+	public Object instantiate() {
+		return XMLHelper.generateDom4jElement( nodeName );
+	}
+
+	public boolean isInstance(Object object) {
+		if ( object instanceof Element ) {
+			return isInstanceNodeNames.contains( ( ( Element ) object ).getName() );
+		}
+		else {
+			return false;
+		}
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,64 +0,0 @@
-//$Id: DynamicMapInstantiator.java 7674 2005-07-29 06:14:16Z oneovthafew $
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.mapping.PersistentClass;
-
-
-public class DynamicMapInstantiator implements Instantiator {
-	public static final String KEY = "$type$";
-
-	private String entityName;
-	private Set isInstanceEntityNames = new HashSet();
-
-	public DynamicMapInstantiator() {
-		this.entityName = null;
-	}
-
-	public DynamicMapInstantiator(PersistentClass mappingInfo) {
-		this.entityName = mappingInfo.getEntityName();
-		isInstanceEntityNames.add( entityName );
-		if ( mappingInfo.hasSubclasses() ) {
-			Iterator itr = mappingInfo.getSubclassClosureIterator();
-			while ( itr.hasNext() ) {
-				final PersistentClass subclassInfo = ( PersistentClass ) itr.next();
-				isInstanceEntityNames.add( subclassInfo.getEntityName() );
-			}
-		}
-	}
-
-	public final Object instantiate(Serializable id) {
-		return instantiate();
-	}
-
-	public final Object instantiate() {
-		Map map = generateMap();
-		if ( entityName!=null ) {
-			map.put( KEY, entityName );
-		}
-		return map;
-	}
-
-	public final boolean isInstance(Object object) {
-		if ( object instanceof Map ) {
-			if ( entityName == null ) {
-				return true;
-			}
-			String type = ( String ) ( ( Map ) object ).get( KEY );
-			return type == null || isInstanceEntityNames.contains( type );
-		}
-		else {
-			return false;
-		}
-	}
-
-	protected Map generateMap() {
-		return new HashMap();
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/DynamicMapInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.mapping.PersistentClass;
+
+
+public class DynamicMapInstantiator implements Instantiator {
+	public static final String KEY = "$type$";
+
+	private String entityName;
+	private Set isInstanceEntityNames = new HashSet();
+
+	public DynamicMapInstantiator() {
+		this.entityName = null;
+	}
+
+	public DynamicMapInstantiator(PersistentClass mappingInfo) {
+		this.entityName = mappingInfo.getEntityName();
+		isInstanceEntityNames.add( entityName );
+		if ( mappingInfo.hasSubclasses() ) {
+			Iterator itr = mappingInfo.getSubclassClosureIterator();
+			while ( itr.hasNext() ) {
+				final PersistentClass subclassInfo = ( PersistentClass ) itr.next();
+				isInstanceEntityNames.add( subclassInfo.getEntityName() );
+			}
+		}
+	}
+
+	public final Object instantiate(Serializable id) {
+		return instantiate();
+	}
+
+	public final Object instantiate() {
+		Map map = generateMap();
+		if ( entityName!=null ) {
+			map.put( KEY, entityName );
+		}
+		return map;
+	}
+
+	public final boolean isInstance(Object object) {
+		if ( object instanceof Map ) {
+			if ( entityName == null ) {
+				return true;
+			}
+			String type = ( String ) ( ( Map ) object ).get( KEY );
+			return type == null || isInstanceEntityNames.contains( type );
+		}
+		else {
+			return false;
+		}
+	}
+
+	protected Map generateMap() {
+		return new HashMap();
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/ElementWrapper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,575 +0,0 @@
-// $Id: ElementWrapper.java 6601 2005-04-29 03:06:37Z oneovthafew $
-package org.hibernate.tuple;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.Writer;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.dom4j.Attribute;
-import org.dom4j.Branch;
-import org.dom4j.CDATA;
-import org.dom4j.Comment;
-import org.dom4j.Document;
-import org.dom4j.Element;
-import org.dom4j.Entity;
-import org.dom4j.InvalidXPathException;
-import org.dom4j.Namespace;
-import org.dom4j.Node;
-import org.dom4j.ProcessingInstruction;
-import org.dom4j.QName;
-import org.dom4j.Text;
-import org.dom4j.Visitor;
-import org.dom4j.XPath;
-
-/**
- * Wraps dom4j elements, allowing them to exist in a 
- * non-hierarchical structure.
- *
- * @author Gavin King
- */
-public class ElementWrapper implements Element, Serializable {
-
-	private Element element;
-	private Element parent;
-	
-	public Element getElement() {
-		return element;
-	}
-
-	public ElementWrapper(Element element) {
-		this.element = element;
-	}
-
-	public QName getQName() {
-		return element.getQName();
-	}
-
-	public QName getQName(String s) {
-		return element.getQName( s );
-	}
-
-	public void setQName(QName qName) {
-		element.setQName( qName );
-	}
-
-	public Namespace getNamespace() {
-		return element.getNamespace();
-	}
-
-	public Namespace getNamespaceForPrefix(String s) {
-		return element.getNamespaceForPrefix( s );
-	}
-
-	public Namespace getNamespaceForURI(String s) {
-		return element.getNamespaceForURI( s );
-	}
-
-	public List getNamespacesForURI(String s) {
-		return element.getNamespacesForURI( s );
-	}
-
-	public String getNamespacePrefix() {
-		return element.getNamespacePrefix();
-	}
-
-	public String getNamespaceURI() {
-		return element.getNamespaceURI();
-	}
-
-	public String getQualifiedName() {
-		return element.getQualifiedName();
-	}
-
-	public List additionalNamespaces() {
-		return element.additionalNamespaces();
-	}
-
-	public List declaredNamespaces() {
-		return element.declaredNamespaces();
-	}
-
-	public Element addAttribute(String attrName, String text) {
-		return element.addAttribute( attrName, text );
-	}
-
-	public Element addAttribute(QName attrName, String text) {
-		return element.addAttribute( attrName, text );
-	}
-
-	public Element addComment(String text) {
-		return element.addComment( text );
-	}
-
-	public Element addCDATA(String text) {
-		return element.addCDATA( text );
-	}
-
-	public Element addEntity(String name, String text) {
-		return element.addEntity( name, text );
-	}
-
-	public Element addNamespace(String prefix, String uri) {
-		return element.addNamespace( prefix, uri );
-	}
-
-	public Element addProcessingInstruction(String target, String text) {
-		return element.addProcessingInstruction( target, text );
-	}
-
-	public Element addProcessingInstruction(String target, Map data) {
-		return element.addProcessingInstruction( target, data );
-	}
-
-	public Element addText(String text) {
-		return element.addText( text );
-	}
-
-	public void add(Attribute attribute) {
-		element.add( attribute );
-	}
-
-	public void add(CDATA cdata) {
-		element.add( cdata );
-	}
-
-	public void add(Entity entity) {
-		element.add( entity );
-	}
-
-	public void add(Text text) {
-		element.add( text );
-	}
-
-	public void add(Namespace namespace) {
-		element.add( namespace );
-	}
-
-	public boolean remove(Attribute attribute) {
-		return element.remove( attribute );
-	}
-
-	public boolean remove(CDATA cdata) {
-		return element.remove( cdata );
-	}
-
-	public boolean remove(Entity entity) {
-		return element.remove( entity );
-	}
-
-	public boolean remove(Namespace namespace) {
-		return element.remove( namespace );
-	}
-
-	public boolean remove(Text text) {
-		return element.remove( text );
-	}
-
-	public boolean supportsParent() {
-		return element.supportsParent();
-	}
-
-	public Element getParent() {
-		return parent==null ? element.getParent() : parent;
-	}
-
-	public void setParent(Element parent) {
-		element.setParent( parent );
-		this.parent = parent;
-	}
-
-	public Document getDocument() {
-		return element.getDocument();
-	}
-
-	public void setDocument(Document document) {
-		element.setDocument( document );
-	}
-
-	public boolean isReadOnly() {
-		return element.isReadOnly();
-	}
-
-	public boolean hasContent() {
-		return element.hasContent();
-	}
-
-	public String getName() {
-		return element.getName();
-	}
-
-	public void setName(String name) {
-		element.setName( name );
-	}
-
-	public String getText() {
-		return element.getText();
-	}
-
-	public void setText(String text) {
-		element.setText( text );
-	}
-
-	public String getTextTrim() {
-		return element.getTextTrim();
-	}
-
-	public String getStringValue() {
-		return element.getStringValue();
-	}
-
-	public String getPath() {
-		return element.getPath();
-	}
-
-	public String getPath(Element element) {
-		return element.getPath( element );
-	}
-
-	public String getUniquePath() {
-		return element.getUniquePath();
-	}
-
-	public String getUniquePath(Element element) {
-		return element.getUniquePath( element );
-	}
-
-	public String asXML() {
-		return element.asXML();
-	}
-
-	public void write(Writer writer) throws IOException {
-		element.write( writer );
-	}
-
-	public short getNodeType() {
-		return element.getNodeType();
-	}
-
-	public String getNodeTypeName() {
-		return element.getNodeTypeName();
-	}
-
-	public Node detach() {
-		if (parent!=null) {
-			parent.remove(this);
-			parent = null;
-		}
-		return element.detach();
-	}
-
-	public List selectNodes(String xpath) {
-		return element.selectNodes( xpath );
-	}
-
-	public Object selectObject(String xpath) {
-		return element.selectObject( xpath );
-	}
-
-	public List selectNodes(String xpath, String comparison) {
-		return element.selectNodes( xpath, comparison );
-	}
-
-	public List selectNodes(String xpath, String comparison, boolean removeDups) {
-		return element.selectNodes( xpath, comparison, removeDups );
-	}
-
-	public Node selectSingleNode(String xpath) {
-        return element.selectSingleNode( xpath );
-	}
-
-	public String valueOf(String xpath) {
-		return element.valueOf( xpath );
-	}
-
-	public Number numberValueOf(String xpath) {
-		return element.numberValueOf( xpath );
-	}
-
-	public boolean matches(String xpath) {
-		return element.matches( xpath );
-	}
-
-	public XPath createXPath(String xpath) throws InvalidXPathException {
-		return element.createXPath( xpath );
-	}
-
-	public Node asXPathResult(Element element) {
-		return element.asXPathResult( element );
-	}
-
-	public void accept(Visitor visitor) {
-		element.accept( visitor );
-	}
-
-	public Object clone() {
-		return element.clone();
-	}
-
-	public Object getData() {
-		return element.getData();
-	}
-
-	public void setData(Object data) {
-		element.setData( data );
-	}
-
-	public List attributes() {
-		return element.attributes();
-	}
-
-	public void setAttributes(List list) {
-		element.setAttributes( list );
-	}
-
-	public int attributeCount() {
-		return element.attributeCount();
-	}
-
-	public Iterator attributeIterator() {
-		return element.attributeIterator();
-	}
-
-	public Attribute attribute(int i) {
-		return element.attribute( i );
-	}
-
-	public Attribute attribute(String name) {
-		return element.attribute( name );
-	}
-
-	public Attribute attribute(QName qName) {
-		return element.attribute( qName );
-	}
-
-	public String attributeValue(String name) {
-		return element.attributeValue( name );
-	}
-
-	public String attributeValue(String name, String defaultValue) {
-		return element.attributeValue( name, defaultValue );
-	}
-
-	public String attributeValue(QName qName) {
-		return element.attributeValue( qName );
-	}
-
-	public String attributeValue(QName qName, String defaultValue) {
-		return element.attributeValue( qName, defaultValue );
-	}
-
-	/**
-	 * @deprecated
-	 */
-	public void setAttributeValue(String name, String value) {
-		element.setAttributeValue( name, value );
-	}
-
-	/**
-	 * @deprecated
-	 */
-	public void setAttributeValue(QName qName, String value) {
-		element.setAttributeValue( qName, value );
-	}
-
-	public Element element(String name) {
-		return element.element( name );
-	}
-
-	public Element element(QName qName) {
-		return element.element( qName );
-	}
-
-	public List elements() {
-		return element.elements();
-	}
-
-	public List elements(String name) {
-		return element.elements( name );
-	}
-
-	public List elements(QName qName) {
-		return element.elements( qName );
-	}
-
-	public Iterator elementIterator() {
-		return element.elementIterator();
-	}
-
-	public Iterator elementIterator(String name) {
-		return element.elementIterator( name );
-
-	}
-
-	public Iterator elementIterator(QName qName) {
-		return element.elementIterator( qName );
-	}
-
-	public boolean isRootElement() {
-		return element.isRootElement();
-	}
-
-	public boolean hasMixedContent() {
-		return element.hasMixedContent();
-	}
-
-	public boolean isTextOnly() {
-		return element.isTextOnly();
-	}
-
-	public void appendAttributes(Element element) {
-		element.appendAttributes( element );
-	}
-
-	public Element createCopy() {
-		return element.createCopy();
-	}
-
-	public Element createCopy(String name) {
-		return element.createCopy( name );
-	}
-
-	public Element createCopy(QName qName) {
-		return element.createCopy( qName );
-	}
-
-	public String elementText(String name) {
-		return element.elementText( name );
-	}
-
-	public String elementText(QName qName) {
-		return element.elementText( qName );
-	}
-
-	public String elementTextTrim(String name) {
-		return element.elementTextTrim( name );
-	}
-
-	public String elementTextTrim(QName qName) {
-		return element.elementTextTrim( qName );
-	}
-
-	public Node getXPathResult(int i) {
-		return element.getXPathResult( i );
-	}
-
-	public Node node(int i) {
-		return element.node( i );
-	}
-
-	public int indexOf(Node node) {
-		return element.indexOf( node );
-	}
-
-	public int nodeCount() {
-		return element.nodeCount();
-	}
-
-	public Element elementByID(String id) {
-		return element.elementByID( id );
-	}
-
-	public List content() {
-		return element.content();
-	}
-
-	public Iterator nodeIterator() {
-		return element.nodeIterator();
-	}
-
-	public void setContent(List list) {
-		element.setContent( list );
-	}
-
-	public void appendContent(Branch branch) {
-		element.appendContent( branch );
-	}
-
-	public void clearContent() {
-		element.clearContent();
-	}
-
-	public List processingInstructions() {
-		return element.processingInstructions();
-	}
-
-	public List processingInstructions(String name) {
-		return element.processingInstructions( name );
-	}
-
-	public ProcessingInstruction processingInstruction(String name) {
-		return element.processingInstruction( name );
-	}
-
-	public void setProcessingInstructions(List list) {
-		element.setProcessingInstructions( list );
-	}
-
-	public Element addElement(String name) {
-		return element.addElement( name );
-	}
-
-	public Element addElement(QName qName) {
-		return element.addElement( qName );
-	}
-
-	public Element addElement(String name, String text) {
-		return element.addElement( name, text );
-
-	}
-
-	public boolean removeProcessingInstruction(String name) {
-		return element.removeProcessingInstruction( name );
-	}
-
-	public void add(Node node) {
-		element.add( node );
-	}
-
-	public void add(Comment comment) {
-		element.add( comment );
-	}
-
-	public void add(Element element) {
-		element.add( element );
-	}
-
-	public void add(ProcessingInstruction processingInstruction) {
-		element.add( processingInstruction );
-	}
-
-	public boolean remove(Node node) {
-		return element.remove( node );
-	}
-
-	public boolean remove(Comment comment) {
-		return element.remove( comment );
-	}
-
-	public boolean remove(Element element) {
-		return element.remove( element );
-	}
-
-	public boolean remove(ProcessingInstruction processingInstruction) {
-		return element.remove( processingInstruction );
-	}
-
-	public void normalize() {
-		element.normalize();
-	}
-	
-	public boolean equals(Object other) {
-		return element.equals(other);
-	}
-	
-	public int hashCode() {
-		return element.hashCode();
-	}
-	
-	public String toString() {
-		return element.toString();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/ElementWrapper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/ElementWrapper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,598 @@
+/*
+ * 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.tuple;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Attribute;
+import org.dom4j.Branch;
+import org.dom4j.CDATA;
+import org.dom4j.Comment;
+import org.dom4j.Document;
+import org.dom4j.Element;
+import org.dom4j.Entity;
+import org.dom4j.InvalidXPathException;
+import org.dom4j.Namespace;
+import org.dom4j.Node;
+import org.dom4j.ProcessingInstruction;
+import org.dom4j.QName;
+import org.dom4j.Text;
+import org.dom4j.Visitor;
+import org.dom4j.XPath;
+
+/**
+ * Wraps dom4j elements, allowing them to exist in a 
+ * non-hierarchical structure.
+ *
+ * @author Gavin King
+ */
+public class ElementWrapper implements Element, Serializable {
+
+	private Element element;
+	private Element parent;
+	
+	public Element getElement() {
+		return element;
+	}
+
+	public ElementWrapper(Element element) {
+		this.element = element;
+	}
+
+	public QName getQName() {
+		return element.getQName();
+	}
+
+	public QName getQName(String s) {
+		return element.getQName( s );
+	}
+
+	public void setQName(QName qName) {
+		element.setQName( qName );
+	}
+
+	public Namespace getNamespace() {
+		return element.getNamespace();
+	}
+
+	public Namespace getNamespaceForPrefix(String s) {
+		return element.getNamespaceForPrefix( s );
+	}
+
+	public Namespace getNamespaceForURI(String s) {
+		return element.getNamespaceForURI( s );
+	}
+
+	public List getNamespacesForURI(String s) {
+		return element.getNamespacesForURI( s );
+	}
+
+	public String getNamespacePrefix() {
+		return element.getNamespacePrefix();
+	}
+
+	public String getNamespaceURI() {
+		return element.getNamespaceURI();
+	}
+
+	public String getQualifiedName() {
+		return element.getQualifiedName();
+	}
+
+	public List additionalNamespaces() {
+		return element.additionalNamespaces();
+	}
+
+	public List declaredNamespaces() {
+		return element.declaredNamespaces();
+	}
+
+	public Element addAttribute(String attrName, String text) {
+		return element.addAttribute( attrName, text );
+	}
+
+	public Element addAttribute(QName attrName, String text) {
+		return element.addAttribute( attrName, text );
+	}
+
+	public Element addComment(String text) {
+		return element.addComment( text );
+	}
+
+	public Element addCDATA(String text) {
+		return element.addCDATA( text );
+	}
+
+	public Element addEntity(String name, String text) {
+		return element.addEntity( name, text );
+	}
+
+	public Element addNamespace(String prefix, String uri) {
+		return element.addNamespace( prefix, uri );
+	}
+
+	public Element addProcessingInstruction(String target, String text) {
+		return element.addProcessingInstruction( target, text );
+	}
+
+	public Element addProcessingInstruction(String target, Map data) {
+		return element.addProcessingInstruction( target, data );
+	}
+
+	public Element addText(String text) {
+		return element.addText( text );
+	}
+
+	public void add(Attribute attribute) {
+		element.add( attribute );
+	}
+
+	public void add(CDATA cdata) {
+		element.add( cdata );
+	}
+
+	public void add(Entity entity) {
+		element.add( entity );
+	}
+
+	public void add(Text text) {
+		element.add( text );
+	}
+
+	public void add(Namespace namespace) {
+		element.add( namespace );
+	}
+
+	public boolean remove(Attribute attribute) {
+		return element.remove( attribute );
+	}
+
+	public boolean remove(CDATA cdata) {
+		return element.remove( cdata );
+	}
+
+	public boolean remove(Entity entity) {
+		return element.remove( entity );
+	}
+
+	public boolean remove(Namespace namespace) {
+		return element.remove( namespace );
+	}
+
+	public boolean remove(Text text) {
+		return element.remove( text );
+	}
+
+	public boolean supportsParent() {
+		return element.supportsParent();
+	}
+
+	public Element getParent() {
+		return parent==null ? element.getParent() : parent;
+	}
+
+	public void setParent(Element parent) {
+		element.setParent( parent );
+		this.parent = parent;
+	}
+
+	public Document getDocument() {
+		return element.getDocument();
+	}
+
+	public void setDocument(Document document) {
+		element.setDocument( document );
+	}
+
+	public boolean isReadOnly() {
+		return element.isReadOnly();
+	}
+
+	public boolean hasContent() {
+		return element.hasContent();
+	}
+
+	public String getName() {
+		return element.getName();
+	}
+
+	public void setName(String name) {
+		element.setName( name );
+	}
+
+	public String getText() {
+		return element.getText();
+	}
+
+	public void setText(String text) {
+		element.setText( text );
+	}
+
+	public String getTextTrim() {
+		return element.getTextTrim();
+	}
+
+	public String getStringValue() {
+		return element.getStringValue();
+	}
+
+	public String getPath() {
+		return element.getPath();
+	}
+
+	public String getPath(Element element) {
+		return element.getPath( element );
+	}
+
+	public String getUniquePath() {
+		return element.getUniquePath();
+	}
+
+	public String getUniquePath(Element element) {
+		return element.getUniquePath( element );
+	}
+
+	public String asXML() {
+		return element.asXML();
+	}
+
+	public void write(Writer writer) throws IOException {
+		element.write( writer );
+	}
+
+	public short getNodeType() {
+		return element.getNodeType();
+	}
+
+	public String getNodeTypeName() {
+		return element.getNodeTypeName();
+	}
+
+	public Node detach() {
+		if (parent!=null) {
+			parent.remove(this);
+			parent = null;
+		}
+		return element.detach();
+	}
+
+	public List selectNodes(String xpath) {
+		return element.selectNodes( xpath );
+	}
+
+	public Object selectObject(String xpath) {
+		return element.selectObject( xpath );
+	}
+
+	public List selectNodes(String xpath, String comparison) {
+		return element.selectNodes( xpath, comparison );
+	}
+
+	public List selectNodes(String xpath, String comparison, boolean removeDups) {
+		return element.selectNodes( xpath, comparison, removeDups );
+	}
+
+	public Node selectSingleNode(String xpath) {
+        return element.selectSingleNode( xpath );
+	}
+
+	public String valueOf(String xpath) {
+		return element.valueOf( xpath );
+	}
+
+	public Number numberValueOf(String xpath) {
+		return element.numberValueOf( xpath );
+	}
+
+	public boolean matches(String xpath) {
+		return element.matches( xpath );
+	}
+
+	public XPath createXPath(String xpath) throws InvalidXPathException {
+		return element.createXPath( xpath );
+	}
+
+	public Node asXPathResult(Element element) {
+		return element.asXPathResult( element );
+	}
+
+	public void accept(Visitor visitor) {
+		element.accept( visitor );
+	}
+
+	public Object clone() {
+		return element.clone();
+	}
+
+	public Object getData() {
+		return element.getData();
+	}
+
+	public void setData(Object data) {
+		element.setData( data );
+	}
+
+	public List attributes() {
+		return element.attributes();
+	}
+
+	public void setAttributes(List list) {
+		element.setAttributes( list );
+	}
+
+	public int attributeCount() {
+		return element.attributeCount();
+	}
+
+	public Iterator attributeIterator() {
+		return element.attributeIterator();
+	}
+
+	public Attribute attribute(int i) {
+		return element.attribute( i );
+	}
+
+	public Attribute attribute(String name) {
+		return element.attribute( name );
+	}
+
+	public Attribute attribute(QName qName) {
+		return element.attribute( qName );
+	}
+
+	public String attributeValue(String name) {
+		return element.attributeValue( name );
+	}
+
+	public String attributeValue(String name, String defaultValue) {
+		return element.attributeValue( name, defaultValue );
+	}
+
+	public String attributeValue(QName qName) {
+		return element.attributeValue( qName );
+	}
+
+	public String attributeValue(QName qName, String defaultValue) {
+		return element.attributeValue( qName, defaultValue );
+	}
+
+	/**
+	 * @deprecated
+	 */
+	public void setAttributeValue(String name, String value) {
+		element.setAttributeValue( name, value );
+	}
+
+	/**
+	 * @deprecated
+	 */
+	public void setAttributeValue(QName qName, String value) {
+		element.setAttributeValue( qName, value );
+	}
+
+	public Element element(String name) {
+		return element.element( name );
+	}
+
+	public Element element(QName qName) {
+		return element.element( qName );
+	}
+
+	public List elements() {
+		return element.elements();
+	}
+
+	public List elements(String name) {
+		return element.elements( name );
+	}
+
+	public List elements(QName qName) {
+		return element.elements( qName );
+	}
+
+	public Iterator elementIterator() {
+		return element.elementIterator();
+	}
+
+	public Iterator elementIterator(String name) {
+		return element.elementIterator( name );
+
+	}
+
+	public Iterator elementIterator(QName qName) {
+		return element.elementIterator( qName );
+	}
+
+	public boolean isRootElement() {
+		return element.isRootElement();
+	}
+
+	public boolean hasMixedContent() {
+		return element.hasMixedContent();
+	}
+
+	public boolean isTextOnly() {
+		return element.isTextOnly();
+	}
+
+	public void appendAttributes(Element element) {
+		element.appendAttributes( element );
+	}
+
+	public Element createCopy() {
+		return element.createCopy();
+	}
+
+	public Element createCopy(String name) {
+		return element.createCopy( name );
+	}
+
+	public Element createCopy(QName qName) {
+		return element.createCopy( qName );
+	}
+
+	public String elementText(String name) {
+		return element.elementText( name );
+	}
+
+	public String elementText(QName qName) {
+		return element.elementText( qName );
+	}
+
+	public String elementTextTrim(String name) {
+		return element.elementTextTrim( name );
+	}
+
+	public String elementTextTrim(QName qName) {
+		return element.elementTextTrim( qName );
+	}
+
+	public Node getXPathResult(int i) {
+		return element.getXPathResult( i );
+	}
+
+	public Node node(int i) {
+		return element.node( i );
+	}
+
+	public int indexOf(Node node) {
+		return element.indexOf( node );
+	}
+
+	public int nodeCount() {
+		return element.nodeCount();
+	}
+
+	public Element elementByID(String id) {
+		return element.elementByID( id );
+	}
+
+	public List content() {
+		return element.content();
+	}
+
+	public Iterator nodeIterator() {
+		return element.nodeIterator();
+	}
+
+	public void setContent(List list) {
+		element.setContent( list );
+	}
+
+	public void appendContent(Branch branch) {
+		element.appendContent( branch );
+	}
+
+	public void clearContent() {
+		element.clearContent();
+	}
+
+	public List processingInstructions() {
+		return element.processingInstructions();
+	}
+
+	public List processingInstructions(String name) {
+		return element.processingInstructions( name );
+	}
+
+	public ProcessingInstruction processingInstruction(String name) {
+		return element.processingInstruction( name );
+	}
+
+	public void setProcessingInstructions(List list) {
+		element.setProcessingInstructions( list );
+	}
+
+	public Element addElement(String name) {
+		return element.addElement( name );
+	}
+
+	public Element addElement(QName qName) {
+		return element.addElement( qName );
+	}
+
+	public Element addElement(String name, String text) {
+		return element.addElement( name, text );
+
+	}
+
+	public boolean removeProcessingInstruction(String name) {
+		return element.removeProcessingInstruction( name );
+	}
+
+	public void add(Node node) {
+		element.add( node );
+	}
+
+	public void add(Comment comment) {
+		element.add( comment );
+	}
+
+	public void add(Element element) {
+		element.add( element );
+	}
+
+	public void add(ProcessingInstruction processingInstruction) {
+		element.add( processingInstruction );
+	}
+
+	public boolean remove(Node node) {
+		return element.remove( node );
+	}
+
+	public boolean remove(Comment comment) {
+		return element.remove( comment );
+	}
+
+	public boolean remove(Element element) {
+		return element.remove( element );
+	}
+
+	public boolean remove(ProcessingInstruction processingInstruction) {
+		return element.remove( processingInstruction );
+	}
+
+	public void normalize() {
+		element.normalize();
+	}
+	
+	public boolean equals(Object other) {
+		return element.equals(other);
+	}
+	
+	public int hashCode() {
+		return element.hashCode();
+	}
+	
+	public String toString() {
+		return element.toString();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-package org.hibernate.tuple;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.util.FastHashMap;
-
-/**
- * Centralizes handling of {@link EntityMode} to {@link Tuplizer} mappings.
- *
- * @author Steve Ebersole
- */
-public abstract class EntityModeToTuplizerMapping implements Serializable {
-
-	// map of EntityMode -> Tuplizer
-	private final Map tuplizers;
-
-	public EntityModeToTuplizerMapping() {
-		tuplizers = new FastHashMap();
-	}
-
-	public EntityModeToTuplizerMapping(Map tuplizers) {
-		this.tuplizers = tuplizers;
-	}
-
-	protected void addTuplizer(EntityMode entityMode, Tuplizer tuplizer) {
-		tuplizers.put( entityMode, tuplizer );
-	}
-
-	/**
-	 * Given a supposed instance of an entity/component, guess its entity mode.
-	 *
-	 * @param object The supposed instance of the entity/component.
-	 * @return The guessed entity mode.
-	 */
-	public EntityMode guessEntityMode(Object object) {
-		Iterator itr = tuplizers.entrySet().iterator();
-		while( itr.hasNext() ) {
-			Map.Entry entry = ( Map.Entry ) itr.next();
-			Tuplizer tuplizer = ( Tuplizer ) entry.getValue();
-			if ( tuplizer.isInstance( object ) ) {
-				return ( EntityMode ) entry.getKey();
-			}
-		}
-		return null;
-	}
-
-	/**
-	 * Locate the contained tuplizer responsible for the given entity-mode.  If
-	 * no such tuplizer is defined on this mapping, then return null.
-	 *
-	 * @param entityMode The entity-mode for which the caller wants a tuplizer.
-	 * @return The tuplizer, or null if not found.
-	 */
-	public Tuplizer getTuplizerOrNull(EntityMode entityMode) {
-		return ( Tuplizer ) tuplizers.get( entityMode );
-	}
-
-	/**
-	 * Locate the tuplizer contained within this mapping which is responsible
-	 * for the given entity-mode.  If no such tuplizer is defined on this
-	 * mapping, then an exception is thrown.
-	 *
-	 * @param entityMode The entity-mode for which the caller wants a tuplizer.
-	 * @return The tuplizer.
-	 * @throws HibernateException Unable to locate the requested tuplizer.
-	 */
-	public Tuplizer getTuplizer(EntityMode entityMode) {
-		Tuplizer tuplizer = getTuplizerOrNull( entityMode );
-		if ( tuplizer == null ) {
-			throw new HibernateException( "No tuplizer found for entity-mode [" + entityMode + "]");
-		}
-		return tuplizer;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/EntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.tuple;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.util.FastHashMap;
+
+/**
+ * Centralizes handling of {@link EntityMode} to {@link Tuplizer} mappings.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class EntityModeToTuplizerMapping implements Serializable {
+
+	// map of EntityMode -> Tuplizer
+	private final Map tuplizers;
+
+	public EntityModeToTuplizerMapping() {
+		tuplizers = new FastHashMap();
+	}
+
+	public EntityModeToTuplizerMapping(Map tuplizers) {
+		this.tuplizers = tuplizers;
+	}
+
+	protected void addTuplizer(EntityMode entityMode, Tuplizer tuplizer) {
+		tuplizers.put( entityMode, tuplizer );
+	}
+
+	/**
+	 * Given a supposed instance of an entity/component, guess its entity mode.
+	 *
+	 * @param object The supposed instance of the entity/component.
+	 * @return The guessed entity mode.
+	 */
+	public EntityMode guessEntityMode(Object object) {
+		Iterator itr = tuplizers.entrySet().iterator();
+		while( itr.hasNext() ) {
+			Map.Entry entry = ( Map.Entry ) itr.next();
+			Tuplizer tuplizer = ( Tuplizer ) entry.getValue();
+			if ( tuplizer.isInstance( object ) ) {
+				return ( EntityMode ) entry.getKey();
+			}
+		}
+		return null;
+	}
+
+	/**
+	 * Locate the contained tuplizer responsible for the given entity-mode.  If
+	 * no such tuplizer is defined on this mapping, then return null.
+	 *
+	 * @param entityMode The entity-mode for which the caller wants a tuplizer.
+	 * @return The tuplizer, or null if not found.
+	 */
+	public Tuplizer getTuplizerOrNull(EntityMode entityMode) {
+		return ( Tuplizer ) tuplizers.get( entityMode );
+	}
+
+	/**
+	 * Locate the tuplizer contained within this mapping which is responsible
+	 * for the given entity-mode.  If no such tuplizer is defined on this
+	 * mapping, then an exception is thrown.
+	 *
+	 * @param entityMode The entity-mode for which the caller wants a tuplizer.
+	 * @return The tuplizer.
+	 * @throws HibernateException Unable to locate the requested tuplizer.
+	 */
+	public Tuplizer getTuplizer(EntityMode entityMode) {
+		Tuplizer tuplizer = getTuplizerOrNull( entityMode );
+		if ( tuplizer == null ) {
+			throw new HibernateException( "No tuplizer found for entity-mode [" + entityMode + "]");
+		}
+		return tuplizer;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-// $Id: IdentifierProperty.java 9295 2006-02-15 22:28:15Z epbernard $
-package org.hibernate.tuple;
-
-import org.hibernate.engine.IdentifierValue;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.id.PostInsertIdentifierGenerator;
-import org.hibernate.type.Type;
-
-/**
- * Represents a defined entity identifier property within the Hibernate
- * runtime-metamodel.
- *
- * @author Steve Ebersole
- */
-public class IdentifierProperty extends Property {
-
-	private boolean virtual;
-	private boolean embedded;
-	private IdentifierValue unsavedValue;
-	private IdentifierGenerator identifierGenerator;
-	private boolean identifierAssignedByInsert;
-	private boolean hasIdentifierMapper;
-
-	/**
-	 * Construct a non-virtual identifier property.
-	 *
-	 * @param name The name of the property representing the identifier within
-	 * its owning entity.
-	 * @param node The node name to use for XML-based representation of this
-	 * property.
-	 * @param type The Hibernate Type for the identifier property.
-	 * @param embedded Is this an embedded identifier.
-	 * @param unsavedValue The value which, if found as the value on the identifier
-	 * property, represents new (i.e., un-saved) instances of the owning entity.
-	 * @param identifierGenerator The generator to use for id value generation.
-	 */
-	public IdentifierProperty(
-			String name,
-			String node,
-			Type type,
-			boolean embedded,
-			IdentifierValue unsavedValue,
-			IdentifierGenerator identifierGenerator) {
-		super(name, node, type);
-		this.virtual = false;
-		this.embedded = embedded;
-		this.hasIdentifierMapper = false;
-		this.unsavedValue = unsavedValue;
-		this.identifierGenerator = identifierGenerator;
-		this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator;
-	}
-
-	/**
-	 * Construct a virtual IdentifierProperty.
-	 *
-	 * @param type The Hibernate Type for the identifier property.
-	 * @param embedded Is this an embedded identifier.
-	 * @param unsavedValue The value which, if found as the value on the identifier
-	 * property, represents new (i.e., un-saved) instances of the owning entity.
-	 * @param identifierGenerator The generator to use for id value generation.
-	 */
-	public IdentifierProperty(
-	        Type type,
-	        boolean embedded,
-			boolean hasIdentifierMapper,
-			IdentifierValue unsavedValue,
-	        IdentifierGenerator identifierGenerator) {
-		super(null, null, type);
-		this.virtual = true;
-		this.embedded = embedded;
-		this.hasIdentifierMapper = hasIdentifierMapper;
-		this.unsavedValue = unsavedValue;
-		this.identifierGenerator = identifierGenerator;
-		this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator;
-	}
-
-	public boolean isVirtual() {
-		return virtual;
-	}
-
-	public boolean isEmbedded() {
-		return embedded;
-	}
-
-	public IdentifierValue getUnsavedValue() {
-		return unsavedValue;
-	}
-
-	public IdentifierGenerator getIdentifierGenerator() {
-		return identifierGenerator;
-	}
-
-	public boolean isIdentifierAssignedByInsert() {
-		return identifierAssignedByInsert;
-	}
-
-	public boolean hasIdentifierMapper() {
-		return hasIdentifierMapper;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/IdentifierProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,123 @@
+/*
+ * 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.tuple;
+
+import org.hibernate.engine.IdentifierValue;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.id.PostInsertIdentifierGenerator;
+import org.hibernate.type.Type;
+
+/**
+ * Represents a defined entity identifier property within the Hibernate
+ * runtime-metamodel.
+ *
+ * @author Steve Ebersole
+ */
+public class IdentifierProperty extends Property {
+
+	private boolean virtual;
+	private boolean embedded;
+	private IdentifierValue unsavedValue;
+	private IdentifierGenerator identifierGenerator;
+	private boolean identifierAssignedByInsert;
+	private boolean hasIdentifierMapper;
+
+	/**
+	 * Construct a non-virtual identifier property.
+	 *
+	 * @param name The name of the property representing the identifier within
+	 * its owning entity.
+	 * @param node The node name to use for XML-based representation of this
+	 * property.
+	 * @param type The Hibernate Type for the identifier property.
+	 * @param embedded Is this an embedded identifier.
+	 * @param unsavedValue The value which, if found as the value on the identifier
+	 * property, represents new (i.e., un-saved) instances of the owning entity.
+	 * @param identifierGenerator The generator to use for id value generation.
+	 */
+	public IdentifierProperty(
+			String name,
+			String node,
+			Type type,
+			boolean embedded,
+			IdentifierValue unsavedValue,
+			IdentifierGenerator identifierGenerator) {
+		super(name, node, type);
+		this.virtual = false;
+		this.embedded = embedded;
+		this.hasIdentifierMapper = false;
+		this.unsavedValue = unsavedValue;
+		this.identifierGenerator = identifierGenerator;
+		this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator;
+	}
+
+	/**
+	 * Construct a virtual IdentifierProperty.
+	 *
+	 * @param type The Hibernate Type for the identifier property.
+	 * @param embedded Is this an embedded identifier.
+	 * @param unsavedValue The value which, if found as the value on the identifier
+	 * property, represents new (i.e., un-saved) instances of the owning entity.
+	 * @param identifierGenerator The generator to use for id value generation.
+	 */
+	public IdentifierProperty(
+	        Type type,
+	        boolean embedded,
+			boolean hasIdentifierMapper,
+			IdentifierValue unsavedValue,
+	        IdentifierGenerator identifierGenerator) {
+		super(null, null, type);
+		this.virtual = true;
+		this.embedded = embedded;
+		this.hasIdentifierMapper = hasIdentifierMapper;
+		this.unsavedValue = unsavedValue;
+		this.identifierGenerator = identifierGenerator;
+		this.identifierAssignedByInsert = identifierGenerator instanceof PostInsertIdentifierGenerator;
+	}
+
+	public boolean isVirtual() {
+		return virtual;
+	}
+
+	public boolean isEmbedded() {
+		return embedded;
+	}
+
+	public IdentifierValue getUnsavedValue() {
+		return unsavedValue;
+	}
+
+	public IdentifierGenerator getIdentifierGenerator() {
+		return identifierGenerator;
+	}
+
+	public boolean isIdentifierAssignedByInsert() {
+		return identifierAssignedByInsert;
+	}
+
+	public boolean hasIdentifierMapper() {
+		return hasIdentifierMapper;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/Instantiator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,40 +0,0 @@
-// $Id: Instantiator.java 7449 2005-07-11 17:31:50Z steveebersole $
-package org.hibernate.tuple;
-
-
-import java.io.Serializable;
-
-/**
- * Contract for implementors responsible for instantiating entity/component instances.
- *
- * @author Steve Ebersole
- */
-public interface Instantiator extends Serializable {
-
-	/**
-	 * Perform the requested entity instantiation.
-	 * <p/>
-	 * This form is never called for component instantiation, only entity instantiation.
-	 *
-	 * @param id The id of the entity to be instantiated.
-	 * @return An appropriately instantiated entity.
-	 */
-	public Object instantiate(Serializable id);
-
-	/**
-	 * Perform the requested instantiation.
-	 *
-	 * @return The instantiated data structure. 
-	 */
-	public Object instantiate();
-
-	/**
-	 * Performs check to see if the given object is an instance of the entity
-	 * or component which this Instantiator instantiates.
-	 *
-	 * @param object The object to be checked.
-	 * @return True is the object does respresent an instance of the underlying
-	 * entity/component.
-	 */
-	public boolean isInstance(Object object);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/Instantiator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Instantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,63 @@
+/*
+ * 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.tuple;
+
+
+import java.io.Serializable;
+
+/**
+ * Contract for implementors responsible for instantiating entity/component instances.
+ *
+ * @author Steve Ebersole
+ */
+public interface Instantiator extends Serializable {
+
+	/**
+	 * Perform the requested entity instantiation.
+	 * <p/>
+	 * This form is never called for component instantiation, only entity instantiation.
+	 *
+	 * @param id The id of the entity to be instantiated.
+	 * @return An appropriately instantiated entity.
+	 */
+	public Object instantiate(Serializable id);
+
+	/**
+	 * Perform the requested instantiation.
+	 *
+	 * @return The instantiated data structure. 
+	 */
+	public Object instantiate();
+
+	/**
+	 * Performs check to see if the given object is an instance of the entity
+	 * or component which this Instantiator instantiates.
+	 *
+	 * @param object The object to be checked.
+	 * @return True is the object does respresent an instance of the underlying
+	 * entity/component.
+	 */
+	public boolean isInstance(Object object);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: PojoInstantiator.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.lang.reflect.Constructor;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.InstantiationException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Component;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Defines a POJO-based instantiator for use from the tuplizers.
- */
-public class PojoInstantiator implements Instantiator, Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger(PojoInstantiator.class);
-
-	private transient Constructor constructor;
-
-	private final Class mappedClass;
-	private final transient ReflectionOptimizer.InstantiationOptimizer optimizer;
-	private final boolean embeddedIdentifier;
-	private final Class proxyInterface;
-
-	public PojoInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
-		this.mappedClass = component.getComponentClass();
-		this.optimizer = optimizer;
-
-		this.proxyInterface = null;
-		this.embeddedIdentifier = false;
-
-		try {
-			constructor = ReflectHelper.getDefaultConstructor(mappedClass);
-		}
-		catch ( PropertyNotFoundException pnfe ) {
-			log.info(
-			        "no default (no-argument) constructor for class: " +
-					mappedClass.getName() +
-					" (class must be instantiated by Interceptor)"
-			);
-			constructor = null;
-		}
-	}
-
-	public PojoInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
-		this.mappedClass = persistentClass.getMappedClass();
-		this.proxyInterface = persistentClass.getProxyInterface();
-		this.embeddedIdentifier = persistentClass.hasEmbeddedIdentifier();
-		this.optimizer = optimizer;
-
-		try {
-			constructor = ReflectHelper.getDefaultConstructor( mappedClass );
-		}
-		catch ( PropertyNotFoundException pnfe ) {
-			log.info(
-			        "no default (no-argument) constructor for class: " +
-					mappedClass.getName() +
-					" (class must be instantiated by Interceptor)"
-			);
-			constructor = null;
-		}
-	}
-
-	private void readObject(java.io.ObjectInputStream stream)
-	throws ClassNotFoundException, IOException {
-		stream.defaultReadObject();
-		constructor = ReflectHelper.getDefaultConstructor(mappedClass);
-	}
-
-	public Object instantiate() {
-		if ( ReflectHelper.isAbstractClass(mappedClass) ) {
-			throw new InstantiationException( "Cannot instantiate abstract class or interface: ", mappedClass );
-		}
-		else if ( optimizer != null ) {
-			return optimizer.newInstance();
-		}
-		else if ( constructor == null ) {
-			throw new InstantiationException( "No default constructor for entity: ", mappedClass );
-		}
-		else {
-			try {
-				return constructor.newInstance( null );
-			}
-			catch ( Exception e ) {
-				throw new InstantiationException( "Could not instantiate entity: ", mappedClass, e );
-			}
-		}
-	}
-	
-	public Object instantiate(Serializable id) {
-		final boolean useEmbeddedIdentifierInstanceAsEntity = embeddedIdentifier && 
-				id != null && 
-				id.getClass().equals(mappedClass);
-		return useEmbeddedIdentifierInstanceAsEntity ? id : instantiate();
-	}
-
-	public boolean isInstance(Object object) {
-		return mappedClass.isInstance(object) || 
-				( proxyInterface!=null && proxyInterface.isInstance(object) ); //this one needed only for guessEntityMode()
-	}
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PojoInstantiator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.tuple;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.InstantiationException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Component;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Defines a POJO-based instantiator for use from the tuplizers.
+ */
+public class PojoInstantiator implements Instantiator, Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(PojoInstantiator.class);
+
+	private transient Constructor constructor;
+
+	private final Class mappedClass;
+	private final transient ReflectionOptimizer.InstantiationOptimizer optimizer;
+	private final boolean embeddedIdentifier;
+	private final Class proxyInterface;
+
+	public PojoInstantiator(Component component, ReflectionOptimizer.InstantiationOptimizer optimizer) {
+		this.mappedClass = component.getComponentClass();
+		this.optimizer = optimizer;
+
+		this.proxyInterface = null;
+		this.embeddedIdentifier = false;
+
+		try {
+			constructor = ReflectHelper.getDefaultConstructor(mappedClass);
+		}
+		catch ( PropertyNotFoundException pnfe ) {
+			log.info(
+			        "no default (no-argument) constructor for class: " +
+					mappedClass.getName() +
+					" (class must be instantiated by Interceptor)"
+			);
+			constructor = null;
+		}
+	}
+
+	public PojoInstantiator(PersistentClass persistentClass, ReflectionOptimizer.InstantiationOptimizer optimizer) {
+		this.mappedClass = persistentClass.getMappedClass();
+		this.proxyInterface = persistentClass.getProxyInterface();
+		this.embeddedIdentifier = persistentClass.hasEmbeddedIdentifier();
+		this.optimizer = optimizer;
+
+		try {
+			constructor = ReflectHelper.getDefaultConstructor( mappedClass );
+		}
+		catch ( PropertyNotFoundException pnfe ) {
+			log.info(
+			        "no default (no-argument) constructor for class: " +
+					mappedClass.getName() +
+					" (class must be instantiated by Interceptor)"
+			);
+			constructor = null;
+		}
+	}
+
+	private void readObject(java.io.ObjectInputStream stream)
+	throws ClassNotFoundException, IOException {
+		stream.defaultReadObject();
+		constructor = ReflectHelper.getDefaultConstructor(mappedClass);
+	}
+
+	public Object instantiate() {
+		if ( ReflectHelper.isAbstractClass(mappedClass) ) {
+			throw new InstantiationException( "Cannot instantiate abstract class or interface: ", mappedClass );
+		}
+		else if ( optimizer != null ) {
+			return optimizer.newInstance();
+		}
+		else if ( constructor == null ) {
+			throw new InstantiationException( "No default constructor for entity: ", mappedClass );
+		}
+		else {
+			try {
+				return constructor.newInstance( null );
+			}
+			catch ( Exception e ) {
+				throw new InstantiationException( "Could not instantiate entity: ", mappedClass, e );
+			}
+		}
+	}
+	
+	public Object instantiate(Serializable id) {
+		final boolean useEmbeddedIdentifierInstanceAsEntity = embeddedIdentifier && 
+				id != null && 
+				id.getClass().equals(mappedClass);
+		return useEmbeddedIdentifierInstanceAsEntity ? id : instantiate();
+	}
+
+	public boolean isInstance(Object object) {
+		return mappedClass.isInstance(object) || 
+				( proxyInterface!=null && proxyInterface.isInstance(object) ); //this one needed only for guessEntityMode()
+	}
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/Property.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-// $Id: Property.java 5814 2005-02-21 02:08:46Z oneovthafew $
-package org.hibernate.tuple;
-
-import org.hibernate.type.Type;
-
-import java.io.Serializable;
-
-/**
- * Defines the basic contract of a Property within the runtime metamodel.
- *
- * @author Steve Ebersole
- */
-public abstract class Property implements Serializable {
-	private String name;
-	private String node;
-	private Type type;
-
-	/**
-	 * Constructor for Property instances.
-	 *
-	 * @param name The name by which the property can be referenced within
-	 * its owner.
-	 * @param node The node name to use for XML-based representation of this
-	 * property.
-	 * @param type The Hibernate Type of this property.
-	 */
-	protected Property(String name, String node, Type type) {
-		this.name = name;
-		this.node = node;
-		this.type = type;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String getNode() {
-		return node;
-	}
-
-	public Type getType() {
-		return type;
-	}
-	
-	public String toString() {
-		return "Property(" + name + ':' + type.getName() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/Property.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Property.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple;
+
+import org.hibernate.type.Type;
+
+import java.io.Serializable;
+
+/**
+ * Defines the basic contract of a Property within the runtime metamodel.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class Property implements Serializable {
+	private String name;
+	private String node;
+	private Type type;
+
+	/**
+	 * Constructor for Property instances.
+	 *
+	 * @param name The name by which the property can be referenced within
+	 * its owner.
+	 * @param node The node name to use for XML-based representation of this
+	 * property.
+	 * @param type The Hibernate Type of this property.
+	 */
+	protected Property(String name, String node, Type type) {
+		this.name = name;
+		this.node = node;
+		this.type = type;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getNode() {
+		return node;
+	}
+
+	public Type getType() {
+		return type;
+	}
+	
+	public String toString() {
+		return "Property(" + name + ':' + type.getName() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/PropertyFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,171 +0,0 @@
-// $Id: PropertyFactory.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.tuple;
-
-import java.lang.reflect.Constructor;
-
-import org.hibernate.EntityMode;
-import org.hibernate.mapping.PropertyGeneration;
-import org.hibernate.engine.IdentifierValue;
-import org.hibernate.engine.UnsavedValueFactory;
-import org.hibernate.engine.VersionValue;
-import org.hibernate.id.IdentifierGenerator;
-import org.hibernate.mapping.KeyValue;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.Type;
-import org.hibernate.type.VersionType;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Responsible for generation of runtime metamodel {@link Property} representations.
- * Makes distinction between identifier, version, and other (standard) properties.
- *
- * @author Steve Ebersole
- */
-public class PropertyFactory {
-
-	/**
-	 * Generates an IdentifierProperty representation of the for a given entity mapping.
-	 *
-	 * @param mappedEntity The mapping definition of the entity.
-	 * @param generator The identifier value generator to use for this identifier.
-	 * @return The appropriate IdentifierProperty definition.
-	 */
-	public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedEntity, IdentifierGenerator generator) {
-
-		String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue();
-		Type type = mappedEntity.getIdentifier().getType();
-		Property property = mappedEntity.getIdentifierProperty();
-		
-		IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
-				mappedUnsavedValue,
-				getGetter( property ),
-				type,
-				getConstructor(mappedEntity)
-			);
-
-		if ( property == null ) {
-			// this is a virtual id property...
-			return new IdentifierProperty(
-			        type,
-					mappedEntity.hasEmbeddedIdentifier(),
-					mappedEntity.hasIdentifierMapper(),
-					unsavedValue,
-					generator
-				);
-		}
-		else {
-			return new IdentifierProperty(
-					property.getName(),
-					property.getNodeName(),
-					type,
-					mappedEntity.hasEmbeddedIdentifier(),
-					unsavedValue,
-					generator
-				);
-		}
-	}
-
-	/**
-	 * Generates a VersionProperty representation for an entity mapping given its
-	 * version mapping Property.
-	 *
-	 * @param property The version mapping Property.
-	 * @param lazyAvailable Is property lazy loading currently available.
-	 * @return The appropriate VersionProperty definition.
-	 */
-	public static VersionProperty buildVersionProperty(Property property, boolean lazyAvailable) {
-		String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
-		
-		VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
-				mappedUnsavedValue, 
-				getGetter( property ),
-				(VersionType) property.getType(),
-				getConstructor( property.getPersistentClass() )
-			);
-
-		boolean lazy = lazyAvailable && property.isLazy();
-
-		return new VersionProperty(
-		        property.getName(),
-		        property.getNodeName(),
-		        property.getValue().getType(),
-		        lazy,
-				property.isInsertable(),
-				property.isUpdateable(),
-		        property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
-				property.getGeneration() == PropertyGeneration.ALWAYS,
-				property.isOptional(),
-				property.isUpdateable() && !lazy,
-				property.isOptimisticLocked(),
-		        property.getCascadeStyle(),
-		        unsavedValue
-			);
-	}
-
-	/**
-	 * Generate a "standard" (i.e., non-identifier and non-version) based on the given
-	 * mapped property.
-	 *
-	 * @param property The mapped property.
-	 * @param lazyAvailable Is property lazy loading currently available.
-	 * @return The appropriate StandardProperty definition.
-	 */
-	public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
-		
-		final Type type = property.getValue().getType();
-		
-		// we need to dirty check collections, since they can cause an owner
-		// version number increment
-		
-		// we need to dirty check many-to-ones with not-found="ignore" in order 
-		// to update the cache (not the database), since in this case a null
-		// entity reference can lose information
-		
-		boolean alwaysDirtyCheck = type.isAssociationType() && 
-				( (AssociationType) type ).isAlwaysDirtyChecked(); 
-
-		return new StandardProperty(
-				property.getName(),
-				property.getNodeName(),
-				type,
-				lazyAvailable && property.isLazy(),
-				property.isInsertable(),
-				property.isUpdateable(),
-		        property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
-				property.getGeneration() == PropertyGeneration.ALWAYS,
-				property.isOptional(),
-				alwaysDirtyCheck || property.isUpdateable(),
-				property.isOptimisticLocked(),
-				property.getCascadeStyle(),
-		        property.getValue().getFetchMode()
-			);
-	}
-
-	private static Constructor getConstructor(PersistentClass persistentClass) {
-		if ( persistentClass == null || !persistentClass.hasPojoRepresentation() ) {
-			return null;
-		}
-
-		try {
-			return ReflectHelper.getDefaultConstructor( persistentClass.getMappedClass() );
-		}
-		catch( Throwable t ) {
-			return null;
-		}
-	}
-
-	private static Getter getGetter(Property mappingProperty) {
-		if ( mappingProperty == null || !mappingProperty.getPersistentClass().hasPojoRepresentation() ) {
-			return null;
-		}
-
-		PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
-		return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/PropertyFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/PropertyFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,194 @@
+/*
+ * 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.tuple;
+
+import java.lang.reflect.Constructor;
+
+import org.hibernate.EntityMode;
+import org.hibernate.mapping.PropertyGeneration;
+import org.hibernate.engine.IdentifierValue;
+import org.hibernate.engine.UnsavedValueFactory;
+import org.hibernate.engine.VersionValue;
+import org.hibernate.id.IdentifierGenerator;
+import org.hibernate.mapping.KeyValue;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.Type;
+import org.hibernate.type.VersionType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Responsible for generation of runtime metamodel {@link Property} representations.
+ * Makes distinction between identifier, version, and other (standard) properties.
+ *
+ * @author Steve Ebersole
+ */
+public class PropertyFactory {
+
+	/**
+	 * Generates an IdentifierProperty representation of the for a given entity mapping.
+	 *
+	 * @param mappedEntity The mapping definition of the entity.
+	 * @param generator The identifier value generator to use for this identifier.
+	 * @return The appropriate IdentifierProperty definition.
+	 */
+	public static IdentifierProperty buildIdentifierProperty(PersistentClass mappedEntity, IdentifierGenerator generator) {
+
+		String mappedUnsavedValue = mappedEntity.getIdentifier().getNullValue();
+		Type type = mappedEntity.getIdentifier().getType();
+		Property property = mappedEntity.getIdentifierProperty();
+		
+		IdentifierValue unsavedValue = UnsavedValueFactory.getUnsavedIdentifierValue(
+				mappedUnsavedValue,
+				getGetter( property ),
+				type,
+				getConstructor(mappedEntity)
+			);
+
+		if ( property == null ) {
+			// this is a virtual id property...
+			return new IdentifierProperty(
+			        type,
+					mappedEntity.hasEmbeddedIdentifier(),
+					mappedEntity.hasIdentifierMapper(),
+					unsavedValue,
+					generator
+				);
+		}
+		else {
+			return new IdentifierProperty(
+					property.getName(),
+					property.getNodeName(),
+					type,
+					mappedEntity.hasEmbeddedIdentifier(),
+					unsavedValue,
+					generator
+				);
+		}
+	}
+
+	/**
+	 * Generates a VersionProperty representation for an entity mapping given its
+	 * version mapping Property.
+	 *
+	 * @param property The version mapping Property.
+	 * @param lazyAvailable Is property lazy loading currently available.
+	 * @return The appropriate VersionProperty definition.
+	 */
+	public static VersionProperty buildVersionProperty(Property property, boolean lazyAvailable) {
+		String mappedUnsavedValue = ( (KeyValue) property.getValue() ).getNullValue();
+		
+		VersionValue unsavedValue = UnsavedValueFactory.getUnsavedVersionValue(
+				mappedUnsavedValue, 
+				getGetter( property ),
+				(VersionType) property.getType(),
+				getConstructor( property.getPersistentClass() )
+			);
+
+		boolean lazy = lazyAvailable && property.isLazy();
+
+		return new VersionProperty(
+		        property.getName(),
+		        property.getNodeName(),
+		        property.getValue().getType(),
+		        lazy,
+				property.isInsertable(),
+				property.isUpdateable(),
+		        property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
+				property.getGeneration() == PropertyGeneration.ALWAYS,
+				property.isOptional(),
+				property.isUpdateable() && !lazy,
+				property.isOptimisticLocked(),
+		        property.getCascadeStyle(),
+		        unsavedValue
+			);
+	}
+
+	/**
+	 * Generate a "standard" (i.e., non-identifier and non-version) based on the given
+	 * mapped property.
+	 *
+	 * @param property The mapped property.
+	 * @param lazyAvailable Is property lazy loading currently available.
+	 * @return The appropriate StandardProperty definition.
+	 */
+	public static StandardProperty buildStandardProperty(Property property, boolean lazyAvailable) {
+		
+		final Type type = property.getValue().getType();
+		
+		// we need to dirty check collections, since they can cause an owner
+		// version number increment
+		
+		// we need to dirty check many-to-ones with not-found="ignore" in order 
+		// to update the cache (not the database), since in this case a null
+		// entity reference can lose information
+		
+		boolean alwaysDirtyCheck = type.isAssociationType() && 
+				( (AssociationType) type ).isAlwaysDirtyChecked(); 
+
+		return new StandardProperty(
+				property.getName(),
+				property.getNodeName(),
+				type,
+				lazyAvailable && property.isLazy(),
+				property.isInsertable(),
+				property.isUpdateable(),
+		        property.getGeneration() == PropertyGeneration.INSERT || property.getGeneration() == PropertyGeneration.ALWAYS,
+				property.getGeneration() == PropertyGeneration.ALWAYS,
+				property.isOptional(),
+				alwaysDirtyCheck || property.isUpdateable(),
+				property.isOptimisticLocked(),
+				property.getCascadeStyle(),
+		        property.getValue().getFetchMode()
+			);
+	}
+
+	private static Constructor getConstructor(PersistentClass persistentClass) {
+		if ( persistentClass == null || !persistentClass.hasPojoRepresentation() ) {
+			return null;
+		}
+
+		try {
+			return ReflectHelper.getDefaultConstructor( persistentClass.getMappedClass() );
+		}
+		catch( Throwable t ) {
+			return null;
+		}
+	}
+
+	private static Getter getGetter(Property mappingProperty) {
+		if ( mappingProperty == null || !mappingProperty.getPersistentClass().hasPojoRepresentation() ) {
+			return null;
+		}
+
+		PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( mappingProperty, EntityMode.POJO );
+		return pa.getGetter( mappingProperty.getPersistentClass().getMappedClass(), mappingProperty.getName() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/StandardProperty.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,115 +0,0 @@
-// $Id: StandardProperty.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.tuple;
-
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.type.Type;
-import org.hibernate.FetchMode;
-
-/**
- * Represents a basic property within the Hibernate runtime-metamodel.
- *
- * @author Steve Ebersole
- */
-public class StandardProperty extends Property {
-
-    private final boolean lazy;
-    private final boolean insertable;
-    private final boolean updateable;
-	private final boolean insertGenerated;
-	private final boolean updateGenerated;
-    private final boolean nullable;
-    private final boolean dirtyCheckable;
-    private final boolean versionable;
-    private final CascadeStyle cascadeStyle;
-	private final FetchMode fetchMode;
-
-    /**
-     * Constructs StandardProperty instances.
-     *
-     * @param name The name by which the property can be referenced within
-     * its owner.
-     * @param node The node name to use for XML-based representation of this
-     * property.
-     * @param type The Hibernate Type of this property.
-     * @param lazy Should this property be handled lazily?
-     * @param insertable Is this property an insertable value?
-     * @param updateable Is this property an updateable value?
-     * @param insertGenerated Is this property generated in the database on insert?
-     * @param updateGenerated Is this property generated in the database on update?
-     * @param nullable Is this property a nullable value?
-     * @param checkable Is this property a checkable value?
-     * @param versionable Is this property a versionable value?
-     * @param cascadeStyle The cascade style for this property's value.
-     * @param fetchMode Any fetch mode defined for this property
-     */
-    public StandardProperty(
-            String name,
-            String node,
-            Type type,
-            boolean lazy,
-            boolean insertable,
-            boolean updateable,
-            boolean insertGenerated,
-            boolean updateGenerated,
-            boolean nullable,
-            boolean checkable,
-            boolean versionable,
-            CascadeStyle cascadeStyle,
-            FetchMode fetchMode) {
-        super(name, node, type);
-        this.lazy = lazy;
-        this.insertable = insertable;
-        this.updateable = updateable;
-        this.insertGenerated = insertGenerated;
-	    this.updateGenerated = updateGenerated;
-        this.nullable = nullable;
-        this.dirtyCheckable = checkable;
-        this.versionable = versionable;
-        this.cascadeStyle = cascadeStyle;
-	    this.fetchMode = fetchMode;
-    }
-
-    public boolean isLazy() {
-        return lazy;
-    }
-
-    public boolean isInsertable() {
-        return insertable;
-    }
-
-    public boolean isUpdateable() {
-        return updateable;
-    }
-
-	public boolean isInsertGenerated() {
-		return insertGenerated;
-	}
-
-	public boolean isUpdateGenerated() {
-		return updateGenerated;
-	}
-
-    public boolean isNullable() {
-        return nullable;
-    }
-
-    public boolean isDirtyCheckable(boolean hasUninitializedProperties) {
-        return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() );
-    }
-
-    public boolean isDirtyCheckable() {
-        return dirtyCheckable;
-    }
-
-    public boolean isVersionable() {
-        return versionable;
-    }
-
-    public CascadeStyle getCascadeStyle() {
-        return cascadeStyle;
-    }
-
-	public FetchMode getFetchMode() {
-		return fetchMode;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/StandardProperty.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/StandardProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,138 @@
+/*
+ * 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.tuple;
+
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.type.Type;
+import org.hibernate.FetchMode;
+
+/**
+ * Represents a basic property within the Hibernate runtime-metamodel.
+ *
+ * @author Steve Ebersole
+ */
+public class StandardProperty extends Property {
+
+    private final boolean lazy;
+    private final boolean insertable;
+    private final boolean updateable;
+	private final boolean insertGenerated;
+	private final boolean updateGenerated;
+    private final boolean nullable;
+    private final boolean dirtyCheckable;
+    private final boolean versionable;
+    private final CascadeStyle cascadeStyle;
+	private final FetchMode fetchMode;
+
+    /**
+     * Constructs StandardProperty instances.
+     *
+     * @param name The name by which the property can be referenced within
+     * its owner.
+     * @param node The node name to use for XML-based representation of this
+     * property.
+     * @param type The Hibernate Type of this property.
+     * @param lazy Should this property be handled lazily?
+     * @param insertable Is this property an insertable value?
+     * @param updateable Is this property an updateable value?
+     * @param insertGenerated Is this property generated in the database on insert?
+     * @param updateGenerated Is this property generated in the database on update?
+     * @param nullable Is this property a nullable value?
+     * @param checkable Is this property a checkable value?
+     * @param versionable Is this property a versionable value?
+     * @param cascadeStyle The cascade style for this property's value.
+     * @param fetchMode Any fetch mode defined for this property
+     */
+    public StandardProperty(
+            String name,
+            String node,
+            Type type,
+            boolean lazy,
+            boolean insertable,
+            boolean updateable,
+            boolean insertGenerated,
+            boolean updateGenerated,
+            boolean nullable,
+            boolean checkable,
+            boolean versionable,
+            CascadeStyle cascadeStyle,
+            FetchMode fetchMode) {
+        super(name, node, type);
+        this.lazy = lazy;
+        this.insertable = insertable;
+        this.updateable = updateable;
+        this.insertGenerated = insertGenerated;
+	    this.updateGenerated = updateGenerated;
+        this.nullable = nullable;
+        this.dirtyCheckable = checkable;
+        this.versionable = versionable;
+        this.cascadeStyle = cascadeStyle;
+	    this.fetchMode = fetchMode;
+    }
+
+    public boolean isLazy() {
+        return lazy;
+    }
+
+    public boolean isInsertable() {
+        return insertable;
+    }
+
+    public boolean isUpdateable() {
+        return updateable;
+    }
+
+	public boolean isInsertGenerated() {
+		return insertGenerated;
+	}
+
+	public boolean isUpdateGenerated() {
+		return updateGenerated;
+	}
+
+    public boolean isNullable() {
+        return nullable;
+    }
+
+    public boolean isDirtyCheckable(boolean hasUninitializedProperties) {
+        return isDirtyCheckable() && ( !hasUninitializedProperties || !isLazy() );
+    }
+
+    public boolean isDirtyCheckable() {
+        return dirtyCheckable;
+    }
+
+    public boolean isVersionable() {
+        return versionable;
+    }
+
+    public CascadeStyle getCascadeStyle() {
+        return cascadeStyle;
+    }
+
+	public FetchMode getFetchMode() {
+		return fetchMode;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/Tuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,95 +0,0 @@
-// $Id: Tuplizer.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.tuple;
-
-import org.hibernate.HibernateException;
-
-/**
- * A tuplizer defines the contract for things which know how to manage
- * a particular representation of a piece of data, given that
- * representation's {@link org.hibernate.EntityMode} (the entity-mode
- * essentially defining which representation).
- * </p>
- * If that given piece of data is thought of as a data structure, then a tuplizer
- * is the thing which knows how to<ul>
- * <li>create such a data structure appropriately
- * <li>extract values from and inject values into such a data structure
- * </ul>
- * </p>
- * For example, a given piece of data might be represented as a POJO class.
- * Here, it's representation and entity-mode is POJO.  Well a tuplizer for POJO
- * entity-modes would know how to<ul>
- * <li>create the data structure by calling the POJO's constructor
- * <li>extract and inject values through getters/setter, or by direct field access, etc
- * </ul>
- * </p>
- * That same piece of data might also be represented as a DOM structure, using
- * the tuplizer associated with the DOM4J entity-mode, which would generate instances
- * of {@link org.dom4j.Element} as the data structure and know how to access the
- * values as either nested {@link org.dom4j.Element}s or as {@link org.dom4j.Attribute}s.
- *
- * @see org.hibernate.tuple.entity.EntityTuplizer
- * @see org.hibernate.tuple.component.ComponentTuplizer
- *
- * @author Steve Ebersole
- */
-public interface Tuplizer {
-
-	/**
-	 * Extract the current values contained on the given entity.
-	 *
-	 * @param entity The entity from which to extract values.
-	 * @return The current property values.
-	 * @throws HibernateException
-	 */
-	public Object[] getPropertyValues(Object entity) throws HibernateException;
-
-	/**
-	 * Inject the given values into the given entity.
-	 *
-	 * @param entity The entity.
-	 * @param values The values to be injected.
-	 * @throws HibernateException
-	 */
-	public void setPropertyValues(Object entity, Object[] values) throws HibernateException;
-
-	/**
-	 * Extract the value of a particular property from the given entity.
-	 *
-	 * @param entity The entity from which to extract the property value.
-	 * @param i The index of the property for which to extract the value.
-	 * @return The current value of the given property on the given entity.
-	 * @throws HibernateException
-	 */
-	public Object getPropertyValue(Object entity, int i) throws HibernateException;
-
-	/**
-	 * Generate a new, empty entity.
-	 *
-	 * @return The new, empty entity instance.
-	 * @throws HibernateException
-	 */
-	public Object instantiate() throws HibernateException;
-	
-	/**
-	 * Is the given object considered an instance of the the entity (acconting
-	 * for entity-mode) managed by this tuplizer.
-	 *
-	 * @param object The object to be checked.
-	 * @return True if the object is considered as an instance of this entity
-	 *      within the given mode.
-	 */
-	public boolean isInstance(Object object);
-
-	/**
-	 * Return the pojo class managed by this tuplizer.
-	 * </p>
-	 * Need to determine how to best handle this for the Tuplizers for EntityModes
-	 * other than POJO.
-	 * </p>
-	 * todo : be really nice to not have this here since it is essentially pojo specific...
-	 *
-	 * @return The persistent class.
-	 */
-	public Class getMappedClass();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/Tuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/Tuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,118 @@
+/*
+ * 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.tuple;
+
+import org.hibernate.HibernateException;
+
+/**
+ * A tuplizer defines the contract for things which know how to manage
+ * a particular representation of a piece of data, given that
+ * representation's {@link org.hibernate.EntityMode} (the entity-mode
+ * essentially defining which representation).
+ * </p>
+ * If that given piece of data is thought of as a data structure, then a tuplizer
+ * is the thing which knows how to<ul>
+ * <li>create such a data structure appropriately
+ * <li>extract values from and inject values into such a data structure
+ * </ul>
+ * </p>
+ * For example, a given piece of data might be represented as a POJO class.
+ * Here, it's representation and entity-mode is POJO.  Well a tuplizer for POJO
+ * entity-modes would know how to<ul>
+ * <li>create the data structure by calling the POJO's constructor
+ * <li>extract and inject values through getters/setter, or by direct field access, etc
+ * </ul>
+ * </p>
+ * That same piece of data might also be represented as a DOM structure, using
+ * the tuplizer associated with the DOM4J entity-mode, which would generate instances
+ * of {@link org.dom4j.Element} as the data structure and know how to access the
+ * values as either nested {@link org.dom4j.Element}s or as {@link org.dom4j.Attribute}s.
+ *
+ * @see org.hibernate.tuple.entity.EntityTuplizer
+ * @see org.hibernate.tuple.component.ComponentTuplizer
+ *
+ * @author Steve Ebersole
+ */
+public interface Tuplizer {
+
+	/**
+	 * Extract the current values contained on the given entity.
+	 *
+	 * @param entity The entity from which to extract values.
+	 * @return The current property values.
+	 * @throws HibernateException
+	 */
+	public Object[] getPropertyValues(Object entity) throws HibernateException;
+
+	/**
+	 * Inject the given values into the given entity.
+	 *
+	 * @param entity The entity.
+	 * @param values The values to be injected.
+	 * @throws HibernateException
+	 */
+	public void setPropertyValues(Object entity, Object[] values) throws HibernateException;
+
+	/**
+	 * Extract the value of a particular property from the given entity.
+	 *
+	 * @param entity The entity from which to extract the property value.
+	 * @param i The index of the property for which to extract the value.
+	 * @return The current value of the given property on the given entity.
+	 * @throws HibernateException
+	 */
+	public Object getPropertyValue(Object entity, int i) throws HibernateException;
+
+	/**
+	 * Generate a new, empty entity.
+	 *
+	 * @return The new, empty entity instance.
+	 * @throws HibernateException
+	 */
+	public Object instantiate() throws HibernateException;
+	
+	/**
+	 * Is the given object considered an instance of the the entity (acconting
+	 * for entity-mode) managed by this tuplizer.
+	 *
+	 * @param object The object to be checked.
+	 * @return True if the object is considered as an instance of this entity
+	 *      within the given mode.
+	 */
+	public boolean isInstance(Object object);
+
+	/**
+	 * Return the pojo class managed by this tuplizer.
+	 * </p>
+	 * Need to determine how to best handle this for the Tuplizers for EntityModes
+	 * other than POJO.
+	 * </p>
+	 * todo : be really nice to not have this here since it is essentially pojo specific...
+	 *
+	 * @return The persistent class.
+	 */
+	public Class getMappedClass();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/VersionProperty.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-// $Id: VersionProperty.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.tuple;
-
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.VersionValue;
-import org.hibernate.type.Type;
-
-/**
- * Represents a version property within the Hibernate runtime-metamodel.
- *
- * @author Steve Ebersole
- */
-public class VersionProperty extends StandardProperty {
-
-    private final VersionValue unsavedValue;
-
-    /**
-     * Constructs VersionProperty instances.
-     *
-     * @param name The name by which the property can be referenced within
-     * its owner.
-     * @param node The node name to use for XML-based representation of this
-     * property.
-     * @param type The Hibernate Type of this property.
-     * @param lazy Should this property be handled lazily?
-     * @param insertable Is this property an insertable value?
-     * @param updateable Is this property an updateable value?
-     * @param insertGenerated Is this property generated in the database on insert?
-     * @param updateGenerated Is this property generated in the database on update?
-     * @param nullable Is this property a nullable value?
-     * @param checkable Is this property a checkable value?
-     * @param versionable Is this property a versionable value?
-     * @param cascadeStyle The cascade style for this property's value.
-     * @param unsavedValue The value which, if found as the value of
-     * this (i.e., the version) property, represents new (i.e., un-saved)
-     * instances of the owning entity.
-     */
-    public VersionProperty(
-            String name,
-            String node,
-            Type type,
-            boolean lazy,
-            boolean insertable,
-            boolean updateable,
-            boolean insertGenerated,
-            boolean updateGenerated,
-            boolean nullable,
-            boolean checkable,
-            boolean versionable,
-            CascadeStyle cascadeStyle,
-            VersionValue unsavedValue) {
-        super( name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle, null );
-        this.unsavedValue = unsavedValue;
-    }
-
-    public VersionValue getUnsavedValue() {
-        return unsavedValue;
-    }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/VersionProperty.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/VersionProperty.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple;
+
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.VersionValue;
+import org.hibernate.type.Type;
+
+/**
+ * Represents a version property within the Hibernate runtime-metamodel.
+ *
+ * @author Steve Ebersole
+ */
+public class VersionProperty extends StandardProperty {
+
+    private final VersionValue unsavedValue;
+
+    /**
+     * Constructs VersionProperty instances.
+     *
+     * @param name The name by which the property can be referenced within
+     * its owner.
+     * @param node The node name to use for XML-based representation of this
+     * property.
+     * @param type The Hibernate Type of this property.
+     * @param lazy Should this property be handled lazily?
+     * @param insertable Is this property an insertable value?
+     * @param updateable Is this property an updateable value?
+     * @param insertGenerated Is this property generated in the database on insert?
+     * @param updateGenerated Is this property generated in the database on update?
+     * @param nullable Is this property a nullable value?
+     * @param checkable Is this property a checkable value?
+     * @param versionable Is this property a versionable value?
+     * @param cascadeStyle The cascade style for this property's value.
+     * @param unsavedValue The value which, if found as the value of
+     * this (i.e., the version) property, represents new (i.e., un-saved)
+     * instances of the owning entity.
+     */
+    public VersionProperty(
+            String name,
+            String node,
+            Type type,
+            boolean lazy,
+            boolean insertable,
+            boolean updateable,
+            boolean insertGenerated,
+            boolean updateGenerated,
+            boolean nullable,
+            boolean checkable,
+            boolean versionable,
+            CascadeStyle cascadeStyle,
+            VersionValue unsavedValue) {
+        super( name, node, type, lazy, insertable, updateable, insertGenerated, updateGenerated, nullable, checkable, versionable, cascadeStyle, null );
+        this.unsavedValue = unsavedValue;
+    }
+
+    public VersionValue getUnsavedValue() {
+        return unsavedValue;
+    }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-//$Id: AbstractComponentTuplizer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple.component;
-
-import java.lang.reflect.Method;
-import java.util.Iterator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-
-/**
- * Support for tuplizers relating to components.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
-
-	protected final Getter[] getters;
-	protected final Setter[] setters;
-	protected final int propertySpan;
-	protected final Instantiator instantiator;
-	protected final boolean hasCustomAccessors;
-
-	protected abstract Instantiator buildInstantiator(Component component);
-	protected abstract Getter buildGetter(Component component, Property prop);
-	protected abstract Setter buildSetter(Component component, Property prop);
-
-	protected AbstractComponentTuplizer(Component component) {
-		propertySpan = component.getPropertySpan();
-		getters = new Getter[propertySpan];
-		setters = new Setter[propertySpan];
-
-		Iterator iter = component.getPropertyIterator();
-		boolean foundCustomAccessor=false;
-		int i = 0;
-		while ( iter.hasNext() ) {
-			Property prop = ( Property ) iter.next();
-			getters[i] = buildGetter( component, prop );
-			setters[i] = buildSetter( component, prop );
-			if ( !prop.isBasicPropertyAccessor() ) {
-				foundCustomAccessor = true;
-			}
-			i++;
-		}
-		hasCustomAccessors = foundCustomAccessor;
-
-		String[] getterNames = new String[propertySpan];
-		String[] setterNames = new String[propertySpan];
-		Class[] propTypes = new Class[propertySpan];
-		for ( int j = 0; j < propertySpan; j++ ) {
-			getterNames[j] = getters[j].getMethodName();
-			setterNames[j] = setters[j].getMethodName();
-			propTypes[j] = getters[j].getReturnType();
-		}
-		instantiator = buildInstantiator( component );
-	}
-
-	public Object getPropertyValue(Object component, int i) throws HibernateException {
-		return getters[i].get( component );
-	}
-
-	public Object[] getPropertyValues(Object component) throws HibernateException {
-		Object[] values = new Object[propertySpan];
-		for ( int i = 0; i < propertySpan; i++ ) {
-			values[i] = getPropertyValue( component, i );
-		}
-		return values;
-	}
-
-	public boolean isInstance(Object object) {
-		return instantiator.isInstance(object);
-	}
-
-	public void setPropertyValues(Object component, Object[] values) throws HibernateException {
-		for ( int i = 0; i < propertySpan; i++ ) {
-			setters[i].set( component, values[i], null );
-		}
-	}
-
-	/**
-	* This method does not populate the component parent
-	*/
-	public Object instantiate() throws HibernateException {
-		return instantiator.instantiate();
-	}
-
-	public Object getParent(Object component) {
-		return null;
-	}
-
-	public boolean hasParentProperty() {
-		return false;
-	}
-
-	public boolean isMethodOf(Method method) {
-		return false;
-	}
-
-	public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
-		throw new UnsupportedOperationException();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/AbstractComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,131 @@
+/*
+ * 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.tuple.component;
+
+import java.lang.reflect.Method;
+import java.util.Iterator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+
+/**
+ * Support for tuplizers relating to components.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public abstract class AbstractComponentTuplizer implements ComponentTuplizer {
+
+	protected final Getter[] getters;
+	protected final Setter[] setters;
+	protected final int propertySpan;
+	protected final Instantiator instantiator;
+	protected final boolean hasCustomAccessors;
+
+	protected abstract Instantiator buildInstantiator(Component component);
+	protected abstract Getter buildGetter(Component component, Property prop);
+	protected abstract Setter buildSetter(Component component, Property prop);
+
+	protected AbstractComponentTuplizer(Component component) {
+		propertySpan = component.getPropertySpan();
+		getters = new Getter[propertySpan];
+		setters = new Setter[propertySpan];
+
+		Iterator iter = component.getPropertyIterator();
+		boolean foundCustomAccessor=false;
+		int i = 0;
+		while ( iter.hasNext() ) {
+			Property prop = ( Property ) iter.next();
+			getters[i] = buildGetter( component, prop );
+			setters[i] = buildSetter( component, prop );
+			if ( !prop.isBasicPropertyAccessor() ) {
+				foundCustomAccessor = true;
+			}
+			i++;
+		}
+		hasCustomAccessors = foundCustomAccessor;
+
+		String[] getterNames = new String[propertySpan];
+		String[] setterNames = new String[propertySpan];
+		Class[] propTypes = new Class[propertySpan];
+		for ( int j = 0; j < propertySpan; j++ ) {
+			getterNames[j] = getters[j].getMethodName();
+			setterNames[j] = setters[j].getMethodName();
+			propTypes[j] = getters[j].getReturnType();
+		}
+		instantiator = buildInstantiator( component );
+	}
+
+	public Object getPropertyValue(Object component, int i) throws HibernateException {
+		return getters[i].get( component );
+	}
+
+	public Object[] getPropertyValues(Object component) throws HibernateException {
+		Object[] values = new Object[propertySpan];
+		for ( int i = 0; i < propertySpan; i++ ) {
+			values[i] = getPropertyValue( component, i );
+		}
+		return values;
+	}
+
+	public boolean isInstance(Object object) {
+		return instantiator.isInstance(object);
+	}
+
+	public void setPropertyValues(Object component, Object[] values) throws HibernateException {
+		for ( int i = 0; i < propertySpan; i++ ) {
+			setters[i].set( component, values[i], null );
+		}
+	}
+
+	/**
+	* This method does not populate the component parent
+	*/
+	public Object instantiate() throws HibernateException {
+		return instantiator.instantiate();
+	}
+
+	public Object getParent(Object component) {
+		return null;
+	}
+
+	public boolean hasParentProperty() {
+		return false;
+	}
+
+	public boolean isMethodOf(Method method) {
+		return false;
+	}
+
+	public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
+		throw new UnsupportedOperationException();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,109 +0,0 @@
-package org.hibernate.tuple.component;
-
-import org.hibernate.tuple.EntityModeToTuplizerMapping;
-import org.hibernate.tuple.Tuplizer;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.util.ReflectHelper;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.io.Serializable;
-
-/**
- * Handles mapping {@link EntityMode}s to {@link ComponentTuplizer}s.
- * <p/>
- * Most of the handling is really in the super class; here we just create
- * the tuplizers and add them to the superclass
- *
- * @author Steve Ebersole
- */
-class ComponentEntityModeToTuplizerMapping extends EntityModeToTuplizerMapping implements Serializable {
-
-	private static final Class[] COMPONENT_TUP_CTOR_SIG = new Class[] { Component.class };
-
-	public ComponentEntityModeToTuplizerMapping(Component component) {
-		PersistentClass owner = component.getOwner();
-
-		// create our own copy of the user-supplied tuplizer impl map
-		Map userSuppliedTuplizerImpls = new HashMap();
-		if ( component.getTuplizerMap() != null ) {
-			userSuppliedTuplizerImpls.putAll( component.getTuplizerMap() );
-		}
-
-		// Build the dynamic-map tuplizer...
-		Tuplizer dynamicMapTuplizer = null;
-		String tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.MAP );
-		if ( tuplizerImpl == null ) {
-			dynamicMapTuplizer = new DynamicMapComponentTuplizer( component );
-		}
-		else {
-			dynamicMapTuplizer = buildComponentTuplizer( tuplizerImpl, component );
-		}
-
-		// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
-		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.POJO );
-		Tuplizer pojoTuplizer = null;
-		if ( owner.hasPojoRepresentation() && component.hasPojoRepresentation() ) {
-			if ( tuplizerImpl == null ) {
-				pojoTuplizer = new PojoComponentTuplizer( component );
-			}
-			else {
-				pojoTuplizer = buildComponentTuplizer( tuplizerImpl, component );
-			}
-		}
-		else {
-			pojoTuplizer = dynamicMapTuplizer;
-		}
-
-		// then dom4j tuplizer, if dom4j representation is available
-		Tuplizer dom4jTuplizer = null;
-		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.DOM4J );
-		if ( owner.hasDom4jRepresentation() ) {
-			if ( tuplizerImpl == null ) {
-				dom4jTuplizer = new Dom4jComponentTuplizer( component );
-			}
-			else {
-				dom4jTuplizer = buildComponentTuplizer( tuplizerImpl, component );
-			}
-		}
-		else {
-			dom4jTuplizer = null;
-		}
-
-		// put the "standard" tuplizers into the tuplizer map first
-		if ( pojoTuplizer != null ) {
-			addTuplizer( EntityMode.POJO, pojoTuplizer );
-		}
-		if ( dynamicMapTuplizer != null ) {
-			addTuplizer( EntityMode.MAP, dynamicMapTuplizer );
-		}
-		if ( dom4jTuplizer != null ) {
-			addTuplizer( EntityMode.DOM4J, dom4jTuplizer );
-		}
-
-		// then handle any user-defined entity modes...
-		if ( !userSuppliedTuplizerImpls.isEmpty() ) {
-			Iterator itr = userSuppliedTuplizerImpls.entrySet().iterator();
-			while ( itr.hasNext() ) {
-				Map.Entry entry = ( Map.Entry ) itr.next();
-				EntityMode entityMode = ( EntityMode ) entry.getKey();
-				ComponentTuplizer tuplizer = buildComponentTuplizer( ( String ) entry.getValue(), component );
-				addTuplizer( entityMode, tuplizer );
-			}
-		}
-	}
-
-	private ComponentTuplizer buildComponentTuplizer(String tuplizerImpl, Component component) {
-		try {
-			Class implClass = ReflectHelper.classForName( tuplizerImpl );
-			return ( ComponentTuplizer ) implClass.getConstructor( COMPONENT_TUP_CTOR_SIG ).newInstance( new Object[] { component } );
-		}
-		catch( Throwable t ) {
-			throw new HibernateException( "Could not build tuplizer [" + tuplizerImpl + "]", t );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentEntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,133 @@
+/*
+ * 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.tuple.component;
+
+import org.hibernate.tuple.EntityModeToTuplizerMapping;
+import org.hibernate.tuple.Tuplizer;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.io.Serializable;
+
+/**
+ * Handles mapping {@link EntityMode}s to {@link ComponentTuplizer}s.
+ * <p/>
+ * Most of the handling is really in the super class; here we just create
+ * the tuplizers and add them to the superclass
+ *
+ * @author Steve Ebersole
+ */
+class ComponentEntityModeToTuplizerMapping extends EntityModeToTuplizerMapping implements Serializable {
+
+	private static final Class[] COMPONENT_TUP_CTOR_SIG = new Class[] { Component.class };
+
+	public ComponentEntityModeToTuplizerMapping(Component component) {
+		PersistentClass owner = component.getOwner();
+
+		// create our own copy of the user-supplied tuplizer impl map
+		Map userSuppliedTuplizerImpls = new HashMap();
+		if ( component.getTuplizerMap() != null ) {
+			userSuppliedTuplizerImpls.putAll( component.getTuplizerMap() );
+		}
+
+		// Build the dynamic-map tuplizer...
+		Tuplizer dynamicMapTuplizer = null;
+		String tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.MAP );
+		if ( tuplizerImpl == null ) {
+			dynamicMapTuplizer = new DynamicMapComponentTuplizer( component );
+		}
+		else {
+			dynamicMapTuplizer = buildComponentTuplizer( tuplizerImpl, component );
+		}
+
+		// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
+		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.POJO );
+		Tuplizer pojoTuplizer = null;
+		if ( owner.hasPojoRepresentation() && component.hasPojoRepresentation() ) {
+			if ( tuplizerImpl == null ) {
+				pojoTuplizer = new PojoComponentTuplizer( component );
+			}
+			else {
+				pojoTuplizer = buildComponentTuplizer( tuplizerImpl, component );
+			}
+		}
+		else {
+			pojoTuplizer = dynamicMapTuplizer;
+		}
+
+		// then dom4j tuplizer, if dom4j representation is available
+		Tuplizer dom4jTuplizer = null;
+		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.DOM4J );
+		if ( owner.hasDom4jRepresentation() ) {
+			if ( tuplizerImpl == null ) {
+				dom4jTuplizer = new Dom4jComponentTuplizer( component );
+			}
+			else {
+				dom4jTuplizer = buildComponentTuplizer( tuplizerImpl, component );
+			}
+		}
+		else {
+			dom4jTuplizer = null;
+		}
+
+		// put the "standard" tuplizers into the tuplizer map first
+		if ( pojoTuplizer != null ) {
+			addTuplizer( EntityMode.POJO, pojoTuplizer );
+		}
+		if ( dynamicMapTuplizer != null ) {
+			addTuplizer( EntityMode.MAP, dynamicMapTuplizer );
+		}
+		if ( dom4jTuplizer != null ) {
+			addTuplizer( EntityMode.DOM4J, dom4jTuplizer );
+		}
+
+		// then handle any user-defined entity modes...
+		if ( !userSuppliedTuplizerImpls.isEmpty() ) {
+			Iterator itr = userSuppliedTuplizerImpls.entrySet().iterator();
+			while ( itr.hasNext() ) {
+				Map.Entry entry = ( Map.Entry ) itr.next();
+				EntityMode entityMode = ( EntityMode ) entry.getKey();
+				ComponentTuplizer tuplizer = buildComponentTuplizer( ( String ) entry.getValue(), component );
+				addTuplizer( entityMode, tuplizer );
+			}
+		}
+	}
+
+	private ComponentTuplizer buildComponentTuplizer(String tuplizerImpl, Component component) {
+		try {
+			Class implClass = ReflectHelper.classForName( tuplizerImpl );
+			return ( ComponentTuplizer ) implClass.getConstructor( COMPONENT_TUP_CTOR_SIG ).newInstance( new Object[] { component } );
+		}
+		catch( Throwable t ) {
+			throw new HibernateException( "Could not build tuplizer [" + tuplizerImpl + "]", t );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,88 +0,0 @@
-package org.hibernate.tuple.component;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.HibernateException;
-import org.hibernate.tuple.StandardProperty;
-import org.hibernate.tuple.PropertyFactory;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-
-/**
- * Centralizes metamodel information about a component.
- *
- * @author Steve Ebersole
- */
-public class ComponentMetamodel implements Serializable {
-
-	// TODO : will need reference to session factory to fully complete HHH-1907
-
-//	private final SessionFactoryImplementor sessionFactory;
-	private final String role;
-	private final boolean isKey;
-	private final StandardProperty[] properties;
-	private final ComponentEntityModeToTuplizerMapping tuplizerMapping;
-
-	// cached for efficiency...
-	private final int propertySpan;
-	private final Map propertyIndexes = new HashMap();
-
-//	public ComponentMetamodel(Component component, SessionFactoryImplementor sessionFactory) {
-	public ComponentMetamodel(Component component) {
-//		this.sessionFactory = sessionFactory;
-		this.role = component.getRoleName();
-		this.isKey = component.isKey();
-		propertySpan = component.getPropertySpan();
-		properties = new StandardProperty[propertySpan];
-		Iterator itr = component.getPropertyIterator();
-		int i = 0;
-		while ( itr.hasNext() ) {
-			Property property = ( Property ) itr.next();
-			properties[i] = PropertyFactory.buildStandardProperty( property, false );
-			propertyIndexes.put( property.getName(), new Integer( i ) );
-			i++;
-		}
-
-		tuplizerMapping = new ComponentEntityModeToTuplizerMapping( component );
-	}
-
-	public boolean isKey() {
-		return isKey;
-	}
-
-	public int getPropertySpan() {
-		return propertySpan;
-	}
-
-	public StandardProperty[] getProperties() {
-		return properties;
-	}
-
-	public StandardProperty getProperty(int index) {
-		if ( index < 0 || index >= propertySpan ) {
-			throw new IllegalArgumentException( "illegal index value for component property access [request=" + index + ", span=" + propertySpan + "]" );
-		}
-		return properties[index];
-	}
-
-	public int getPropertyIndex(String propertyName) {
-		Integer index = ( Integer ) propertyIndexes.get( propertyName );
-		if ( index == null ) {
-			throw new HibernateException( "component does not contain such a property [" + propertyName + "]" );
-		}
-		return index.intValue();
-	}
-
-	public StandardProperty getProperty(String propertyName) {
-		return getProperty( getPropertyIndex( propertyName ) );
-	}
-
-	public ComponentEntityModeToTuplizerMapping getTuplizerMapping() {
-		return tuplizerMapping;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentMetamodel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,111 @@
+/*
+ * 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.tuple.component;
+
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.HibernateException;
+import org.hibernate.tuple.StandardProperty;
+import org.hibernate.tuple.PropertyFactory;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Centralizes metamodel information about a component.
+ *
+ * @author Steve Ebersole
+ */
+public class ComponentMetamodel implements Serializable {
+
+	// TODO : will need reference to session factory to fully complete HHH-1907
+
+//	private final SessionFactoryImplementor sessionFactory;
+	private final String role;
+	private final boolean isKey;
+	private final StandardProperty[] properties;
+	private final ComponentEntityModeToTuplizerMapping tuplizerMapping;
+
+	// cached for efficiency...
+	private final int propertySpan;
+	private final Map propertyIndexes = new HashMap();
+
+//	public ComponentMetamodel(Component component, SessionFactoryImplementor sessionFactory) {
+	public ComponentMetamodel(Component component) {
+//		this.sessionFactory = sessionFactory;
+		this.role = component.getRoleName();
+		this.isKey = component.isKey();
+		propertySpan = component.getPropertySpan();
+		properties = new StandardProperty[propertySpan];
+		Iterator itr = component.getPropertyIterator();
+		int i = 0;
+		while ( itr.hasNext() ) {
+			Property property = ( Property ) itr.next();
+			properties[i] = PropertyFactory.buildStandardProperty( property, false );
+			propertyIndexes.put( property.getName(), new Integer( i ) );
+			i++;
+		}
+
+		tuplizerMapping = new ComponentEntityModeToTuplizerMapping( component );
+	}
+
+	public boolean isKey() {
+		return isKey;
+	}
+
+	public int getPropertySpan() {
+		return propertySpan;
+	}
+
+	public StandardProperty[] getProperties() {
+		return properties;
+	}
+
+	public StandardProperty getProperty(int index) {
+		if ( index < 0 || index >= propertySpan ) {
+			throw new IllegalArgumentException( "illegal index value for component property access [request=" + index + ", span=" + propertySpan + "]" );
+		}
+		return properties[index];
+	}
+
+	public int getPropertyIndex(String propertyName) {
+		Integer index = ( Integer ) propertyIndexes.get( propertyName );
+		if ( index == null ) {
+			throw new HibernateException( "component does not contain such a property [" + propertyName + "]" );
+		}
+		return index.intValue();
+	}
+
+	public StandardProperty getProperty(String propertyName) {
+		return getProperty( getPropertyIndex( propertyName ) );
+	}
+
+	public ComponentEntityModeToTuplizerMapping getTuplizerMapping() {
+		return tuplizerMapping;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,53 +0,0 @@
-//$Id: ComponentTuplizer.java 7451 2005-07-11 21:49:08Z steveebersole $
-package org.hibernate.tuple.component;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.tuple.Tuplizer;
-
-/**
- * Defines further responsibilities reagarding tuplization based on
- * a mapped components.
- * </p>
- * ComponentTuplizer implementations should have the following constructor signature:
- *      (org.hibernate.mapping.Component)
- * 
- * @author Gavin King
- * @author Steve Ebersole
- */
-public interface ComponentTuplizer extends Tuplizer, Serializable {
-	/**
-	 * Retreive the current value of the parent property.
-	 *
-	 * @param component The component instance from which to extract the parent
-	 * property value.
-	 * @return The current value of the parent property.
-	 */
-	public Object getParent(Object component);
-
-    /**
-     * Set the value of the parent property.
-     *
-     * @param component The component instance on which to set the parent.
-     * @param parent The parent to be set on the comonent.
-     * @param factory The current session factory.
-     */
-	public void setParent(Object component, Object parent, SessionFactoryImplementor factory);
-
-	/**
-	 * Does the component managed by this tuuplizer contain a parent property?
-	 *
-	 * @return True if the component does contain a parent property; false otherwise.
-	 */
-	public boolean hasParentProperty();
-
-	/**
-	 * Is the given method available via the managed component as a property getter?
-	 *
-	 * @param method The method which to check against the managed component.
-	 * @return True if the managed component is available from the managed component; else false.
-	 */
-	public boolean isMethodOf(Method method);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/ComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,76 @@
+/*
+ * 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.tuple.component;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.tuple.Tuplizer;
+
+/**
+ * Defines further responsibilities reagarding tuplization based on
+ * a mapped components.
+ * </p>
+ * ComponentTuplizer implementations should have the following constructor signature:
+ *      (org.hibernate.mapping.Component)
+ * 
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public interface ComponentTuplizer extends Tuplizer, Serializable {
+	/**
+	 * Retreive the current value of the parent property.
+	 *
+	 * @param component The component instance from which to extract the parent
+	 * property value.
+	 * @return The current value of the parent property.
+	 */
+	public Object getParent(Object component);
+
+    /**
+     * Set the value of the parent property.
+     *
+     * @param component The component instance on which to set the parent.
+     * @param parent The parent to be set on the comonent.
+     * @param factory The current session factory.
+     */
+	public void setParent(Object component, Object parent, SessionFactoryImplementor factory);
+
+	/**
+	 * Does the component managed by this tuuplizer contain a parent property?
+	 *
+	 * @return True if the component does contain a parent property; false otherwise.
+	 */
+	public boolean hasParentProperty();
+
+	/**
+	 * Is the given method available via the managed component as a property getter?
+	 *
+	 * @param method The method which to check against the managed component.
+	 * @return True if the managed component is available from the managed component; else false.
+	 */
+	public boolean isMethodOf(Method method);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: Dom4jComponentTuplizer.java 7449 2005-07-11 17:31:50Z steveebersole $
-package org.hibernate.tuple.component;
-
-import org.dom4j.Element;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.Dom4jInstantiator;
-
-/**
- * A {@link ComponentTuplizer} specific to the dom4j entity mode.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class Dom4jComponentTuplizer extends AbstractComponentTuplizer  {
-
-	public Class getMappedClass() {
-		return Element.class;
-	}
-
-	public Dom4jComponentTuplizer(Component component) {
-		super(component);
-	}
-
-	protected Instantiator buildInstantiator(Component component) {
-		return new Dom4jInstantiator( component );
-	}
-
-	private PropertyAccessor buildPropertyAccessor(Property property) {
-		//TODO: currently we don't know a SessionFactory reference when building the Tuplizer
-		//      THIS IS A BUG (embedded-xml=false on component)
-		// TODO : fix this after HHH-1907 is complete
-		return PropertyAccessorFactory.getDom4jPropertyAccessor( property.getNodeName(), property.getType(), null );
-	}
-
-	protected Getter buildGetter(Component component, Property prop) {
-		return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
-	}
-
-	protected Setter buildSetter(Component component, Property prop) {
-		return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/Dom4jComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple.component;
+
+import org.dom4j.Element;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.Dom4jInstantiator;
+
+/**
+ * A {@link ComponentTuplizer} specific to the dom4j entity mode.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class Dom4jComponentTuplizer extends AbstractComponentTuplizer  {
+
+	public Class getMappedClass() {
+		return Element.class;
+	}
+
+	public Dom4jComponentTuplizer(Component component) {
+		super(component);
+	}
+
+	protected Instantiator buildInstantiator(Component component) {
+		return new Dom4jInstantiator( component );
+	}
+
+	private PropertyAccessor buildPropertyAccessor(Property property) {
+		//TODO: currently we don't know a SessionFactory reference when building the Tuplizer
+		//      THIS IS A BUG (embedded-xml=false on component)
+		// TODO : fix this after HHH-1907 is complete
+		return PropertyAccessorFactory.getDom4jPropertyAccessor( property.getNodeName(), property.getType(), null );
+	}
+
+	protected Getter buildGetter(Component component, Property prop) {
+		return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
+	}
+
+	protected Setter buildSetter(Component component, Property prop) {
+		return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,47 +0,0 @@
-//$Id: DynamicMapComponentTuplizer.java 7449 2005-07-11 17:31:50Z steveebersole $
-package org.hibernate.tuple.component;
-
-import java.util.Map;
-
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.DynamicMapInstantiator;
-
-/**
- * A {@link ComponentTuplizer} specific to the dynamic-map entity mode.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer {
-
-	public Class getMappedClass() {
-		return Map.class;
-	}
-
-	protected Instantiator buildInstantiator(Component component) {
-		return new DynamicMapInstantiator();
-	}
-
-	public DynamicMapComponentTuplizer(Component component) {
-		super(component);
-	}
-
-	private PropertyAccessor buildPropertyAccessor(Property property) {
-		return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
-	}
-
-	protected Getter buildGetter(Component component, Property prop) {
-		return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
-	}
-
-	protected Setter buildSetter(Component component, Property prop) {
-		return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/DynamicMapComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,70 @@
+/*
+ * 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.tuple.component;
+
+import java.util.Map;
+
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.DynamicMapInstantiator;
+
+/**
+ * A {@link ComponentTuplizer} specific to the dynamic-map entity mode.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class DynamicMapComponentTuplizer extends AbstractComponentTuplizer {
+
+	public Class getMappedClass() {
+		return Map.class;
+	}
+
+	protected Instantiator buildInstantiator(Component component) {
+		return new DynamicMapInstantiator();
+	}
+
+	public DynamicMapComponentTuplizer(Component component) {
+		super(component);
+	}
+
+	private PropertyAccessor buildPropertyAccessor(Property property) {
+		return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
+	}
+
+	protected Getter buildGetter(Component component, Property prop) {
+		return buildPropertyAccessor(prop).getGetter( null, prop.getName() );
+	}
+
+	protected Setter buildSetter(Component component, Property prop) {
+		return buildPropertyAccessor(prop).getSetter( null, prop.getName() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,170 +0,0 @@
-//$Id: PojoComponentTuplizer.java 9619 2006-03-15 00:12:47Z steve.ebersole at jboss.com $
-package org.hibernate.tuple.component;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.bytecode.BasicProxyFactory;
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.cfg.Environment;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.BackrefPropertyAccessor;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.PojoInstantiator;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * A {@link ComponentTuplizer} specific to the pojo entity mode.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public class PojoComponentTuplizer extends AbstractComponentTuplizer {
-
-	private final Class componentClass;
-	private ReflectionOptimizer optimizer;
-	private final Getter parentGetter;
-	private final Setter parentSetter;
-
-	public PojoComponentTuplizer(Component component) {
-		super( component );
-
-		this.componentClass = component.getComponentClass();
-
-		String[] getterNames = new String[propertySpan];
-		String[] setterNames = new String[propertySpan];
-		Class[] propTypes = new Class[propertySpan];
-		for ( int i = 0; i < propertySpan; i++ ) {
-			getterNames[i] = getters[i].getMethodName();
-			setterNames[i] = setters[i].getMethodName();
-			propTypes[i] = getters[i].getReturnType();
-		}
-
-		final String parentPropertyName = component.getParentProperty();
-		if ( parentPropertyName == null ) {
-			parentSetter = null;
-			parentGetter = null;
-		}
-		else {
-			PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( null );
-			parentSetter = pa.getSetter( componentClass, parentPropertyName );
-			parentGetter = pa.getGetter( componentClass, parentPropertyName );
-		}
-
-		if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
-			optimizer = null;
-		}
-		else {
-			// TODO: here is why we need to make bytecode provider global :(
-			// TODO : again, fix this after HHH-1907 is complete
-			optimizer = Environment.getBytecodeProvider().getReflectionOptimizer(
-					componentClass, getterNames, setterNames, propTypes
-			);
-		}
-	}
-
-	public Class getMappedClass() {
-		return componentClass;
-	}
-
-	public Object[] getPropertyValues(Object component) throws HibernateException {
-		if ( component == BackrefPropertyAccessor.UNKNOWN ) {
-			return new Object[ propertySpan ];
-		}
-		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
-			return optimizer.getAccessOptimizer().getPropertyValues( component );
-		}
-		else {
-			return super.getPropertyValues(component);
-		}
-	}
-
-	public void setPropertyValues(Object component, Object[] values) throws HibernateException {
-		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
-				optimizer.getAccessOptimizer().setPropertyValues( component, values );
-		}
-		else {
-			super.setPropertyValues(component, values);
-		}
-
-	}
-
-	public Object getParent(Object component) {
-		return parentGetter.get( component );
-	}
-
-	public boolean hasParentProperty() {
-		return parentGetter!=null;
-	}
-
-	public boolean isMethodOf(Method method) {
-		for ( int i=0; i<propertySpan; i++ ) {
-			final Method getterMethod = getters[i].getMethod();
-			if ( getterMethod!=null && getterMethod.equals(method) ) return true;
-		}
-		return false;
-	}
-
-	public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
-		parentSetter.set(component, parent, factory);
-	}
-
-	protected Instantiator buildInstantiator(Component component) {
-		if ( component.isEmbedded() && ReflectHelper.isAbstractClass( component.getComponentClass() ) ) {
-			return new ProxiedInstantiator( component );
-		}
-		if ( optimizer == null ) {
-			return new PojoInstantiator( component, null );
-		}
-		else {
-			return new PojoInstantiator( component, optimizer.getInstantiationOptimizer() );
-		}
-	}
-
-	protected Getter buildGetter(Component component, Property prop) {
-		return prop.getGetter( component.getComponentClass() );
-	}
-
-	protected Setter buildSetter(Component component, Property prop) {
-		return prop.getSetter( component.getComponentClass() );
-	}
-
-	private static class ProxiedInstantiator implements Instantiator {
-		private final Class proxiedClass;
-		private final BasicProxyFactory factory;
-
-		public ProxiedInstantiator(Component component) {
-			proxiedClass = component.getComponentClass();
-			if ( proxiedClass.isInterface() ) {
-				factory = Environment.getBytecodeProvider()
-						.getProxyFactoryFactory()
-						.buildBasicProxyFactory( null, new Class[] { proxiedClass } );
-			}
-			else {
-				factory = Environment.getBytecodeProvider()
-						.getProxyFactoryFactory()
-						.buildBasicProxyFactory( proxiedClass, null );
-			}
-		}
-
-		public Object instantiate(Serializable id) {
-			throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
-		}
-
-		public Object instantiate() {
-			return factory.getProxy();
-		}
-
-		public boolean isInstance(Object object) {
-			return proxiedClass.isInstance( object );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/component/PojoComponentTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,193 @@
+/*
+ * 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.tuple.component;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.bytecode.BasicProxyFactory;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.cfg.Environment;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.BackrefPropertyAccessor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.PojoInstantiator;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * A {@link ComponentTuplizer} specific to the pojo entity mode.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class PojoComponentTuplizer extends AbstractComponentTuplizer {
+
+	private final Class componentClass;
+	private ReflectionOptimizer optimizer;
+	private final Getter parentGetter;
+	private final Setter parentSetter;
+
+	public PojoComponentTuplizer(Component component) {
+		super( component );
+
+		this.componentClass = component.getComponentClass();
+
+		String[] getterNames = new String[propertySpan];
+		String[] setterNames = new String[propertySpan];
+		Class[] propTypes = new Class[propertySpan];
+		for ( int i = 0; i < propertySpan; i++ ) {
+			getterNames[i] = getters[i].getMethodName();
+			setterNames[i] = setters[i].getMethodName();
+			propTypes[i] = getters[i].getReturnType();
+		}
+
+		final String parentPropertyName = component.getParentProperty();
+		if ( parentPropertyName == null ) {
+			parentSetter = null;
+			parentGetter = null;
+		}
+		else {
+			PropertyAccessor pa = PropertyAccessorFactory.getPropertyAccessor( null );
+			parentSetter = pa.getSetter( componentClass, parentPropertyName );
+			parentGetter = pa.getGetter( componentClass, parentPropertyName );
+		}
+
+		if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
+			optimizer = null;
+		}
+		else {
+			// TODO: here is why we need to make bytecode provider global :(
+			// TODO : again, fix this after HHH-1907 is complete
+			optimizer = Environment.getBytecodeProvider().getReflectionOptimizer(
+					componentClass, getterNames, setterNames, propTypes
+			);
+		}
+	}
+
+	public Class getMappedClass() {
+		return componentClass;
+	}
+
+	public Object[] getPropertyValues(Object component) throws HibernateException {
+		if ( component == BackrefPropertyAccessor.UNKNOWN ) {
+			return new Object[ propertySpan ];
+		}
+		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
+			return optimizer.getAccessOptimizer().getPropertyValues( component );
+		}
+		else {
+			return super.getPropertyValues(component);
+		}
+	}
+
+	public void setPropertyValues(Object component, Object[] values) throws HibernateException {
+		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
+				optimizer.getAccessOptimizer().setPropertyValues( component, values );
+		}
+		else {
+			super.setPropertyValues(component, values);
+		}
+
+	}
+
+	public Object getParent(Object component) {
+		return parentGetter.get( component );
+	}
+
+	public boolean hasParentProperty() {
+		return parentGetter!=null;
+	}
+
+	public boolean isMethodOf(Method method) {
+		for ( int i=0; i<propertySpan; i++ ) {
+			final Method getterMethod = getters[i].getMethod();
+			if ( getterMethod!=null && getterMethod.equals(method) ) return true;
+		}
+		return false;
+	}
+
+	public void setParent(Object component, Object parent, SessionFactoryImplementor factory) {
+		parentSetter.set(component, parent, factory);
+	}
+
+	protected Instantiator buildInstantiator(Component component) {
+		if ( component.isEmbedded() && ReflectHelper.isAbstractClass( component.getComponentClass() ) ) {
+			return new ProxiedInstantiator( component );
+		}
+		if ( optimizer == null ) {
+			return new PojoInstantiator( component, null );
+		}
+		else {
+			return new PojoInstantiator( component, optimizer.getInstantiationOptimizer() );
+		}
+	}
+
+	protected Getter buildGetter(Component component, Property prop) {
+		return prop.getGetter( component.getComponentClass() );
+	}
+
+	protected Setter buildSetter(Component component, Property prop) {
+		return prop.getSetter( component.getComponentClass() );
+	}
+
+	private static class ProxiedInstantiator implements Instantiator {
+		private final Class proxiedClass;
+		private final BasicProxyFactory factory;
+
+		public ProxiedInstantiator(Component component) {
+			proxiedClass = component.getComponentClass();
+			if ( proxiedClass.isInterface() ) {
+				factory = Environment.getBytecodeProvider()
+						.getProxyFactoryFactory()
+						.buildBasicProxyFactory( null, new Class[] { proxiedClass } );
+			}
+			else {
+				factory = Environment.getBytecodeProvider()
+						.getProxyFactoryFactory()
+						.buildBasicProxyFactory( proxiedClass, null );
+			}
+		}
+
+		public Object instantiate(Serializable id) {
+			throw new AssertionFailure( "ProxiedInstantiator can only be used to instantiate component" );
+		}
+
+		public Object instantiate() {
+			return factory.getProxy();
+		}
+
+		public boolean isInstance(Object object) {
+			return proxiedClass.isInstance( object );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,410 +0,0 @@
-// $Id: AbstractEntityTuplizer.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.tuple.entity;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.VersionProperty;
-import org.hibernate.tuple.StandardProperty;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.id.Assigned;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.ComponentType;
-
-
-/**
- * Support for tuplizers relating to entities.
- *
- * @author Steve Ebersole
- * @author Gavin King
- */
-public abstract class AbstractEntityTuplizer implements EntityTuplizer {
-
-	//TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
-
-	private final EntityMetamodel entityMetamodel;
-
-	private final Getter idGetter;
-	private final Setter idSetter;
-
-	protected final Getter[] getters;
-	protected final Setter[] setters;
-	protected final int propertySpan;
-	protected final boolean hasCustomAccessors;
-	private final Instantiator instantiator;
-	private final ProxyFactory proxyFactory;
-	private final AbstractComponentType identifierMapperType;
-
-
-	/**
-	 * Return the entity-mode handled by this tuplizer instance.
-	 *
-	 * @return The entity-mode
-	 */
-	protected abstract EntityMode getEntityMode();
-
-	/**
-	 * Build an appropriate Getter for the given property.
-	 *
-	 * @param mappedProperty The property to be accessed via the built Getter.
-	 * @param mappedEntity The entity information regarding the mapped entity owning this property.
-	 * @return An appropriate Getter instance.
-	 */
-	protected abstract Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity);
-
-	/**
-	 * Build an appropriate Setter for the given property.
-	 *
-	 * @param mappedProperty The property to be accessed via the built Setter.
-	 * @param mappedEntity The entity information regarding the mapped entity owning this property.
-	 * @return An appropriate Setter instance.
-	 */
-	protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity);
-
-	/**
-	 * Build an appropriate Instantiator for the given mapped entity.
-	 *
-	 * @param mappingInfo The mapping information regarding the mapped entity.
-	 * @return An appropriate Instantiator instance.
-	 */
-	protected abstract Instantiator buildInstantiator(PersistentClass mappingInfo);
-
-	/**
-	 * Build an appropriate ProxyFactory for the given mapped entity.
-	 *
-	 * @param mappingInfo The mapping information regarding the mapped entity.
-	 * @param idGetter The constructed Getter relating to the entity's id property.
-	 * @param idSetter The constructed Setter relating to the entity's id property.
-	 * @return An appropriate ProxyFactory instance.
-	 */
-	protected abstract ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter);
-
-	/**
-	 * Constructs a new AbstractEntityTuplizer instance.
-	 *
-	 * @param entityMetamodel The "interpreted" information relating to the mapped entity.
-	 * @param mappingInfo The parsed "raw" mapping data relating to the given entity.
-	 */
-	public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
-		this.entityMetamodel = entityMetamodel;
-
-		if ( !entityMetamodel.getIdentifierProperty().isVirtual() ) {
-			idGetter = buildPropertyGetter( mappingInfo.getIdentifierProperty(), mappingInfo );
-			idSetter = buildPropertySetter( mappingInfo.getIdentifierProperty(), mappingInfo );
-		}
-		else {
-			idGetter = null;
-			idSetter = null;
-		}
-
-		propertySpan = entityMetamodel.getPropertySpan();
-
-        getters = new Getter[propertySpan];
-		setters = new Setter[propertySpan];
-
-		Iterator iter = mappingInfo.getPropertyClosureIterator();
-		boolean foundCustomAccessor=false;
-		int i=0;
-		while ( iter.hasNext() ) {
-			//TODO: redesign how PropertyAccessors are acquired...
-			Property property = (Property) iter.next();
-			getters[i] = buildPropertyGetter(property, mappingInfo);
-			setters[i] = buildPropertySetter(property, mappingInfo);
-			if ( !property.isBasicPropertyAccessor() ) foundCustomAccessor = true;
-			i++;
-		}
-		hasCustomAccessors = foundCustomAccessor;
-
-        instantiator = buildInstantiator( mappingInfo );
-
-		if ( entityMetamodel.isLazy() ) {
-			proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
-			if (proxyFactory == null) {
-				entityMetamodel.setLazy( false );
-			}
-		}
-		else {
-			proxyFactory = null;
-		}
-		
-		Component mapper = mappingInfo.getIdentifierMapper();
-		identifierMapperType = mapper==null ? null : (AbstractComponentType) mapper.getType();
-	}
-
-	/** Retreives the defined entity-name for the tuplized entity.
-	 *
-	 * @return The entity-name.
-	 */
-	protected String getEntityName() {
-		return entityMetamodel.getName();
-	}
-
-	/**
-	 * Retreives the defined entity-names for any subclasses defined for this
-	 * entity.
-	 *
-	 * @return Any subclass entity-names.
-	 */
-	protected Set getSubclassEntityNames() {
-		return entityMetamodel.getSubclassEntityNames();
-	}
-
-	public Serializable getIdentifier(Object entity) throws HibernateException {
-		final Object id;
-		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
-			id = entity;
-		}
-		else {
-			if ( idGetter == null ) {
-				if (identifierMapperType==null) {
-					throw new HibernateException( "The class has no identifier property: " + getEntityName() );
-				}
-				else {
-					ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
-					id = copier.instantiate( getEntityMode() );
-					copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() );
-				}
-			}
-			else {
-				id = idGetter.get( entity );
-			}
-		}
-
-		try {
-			return (Serializable) id;
-		}
-		catch ( ClassCastException cce ) {
-			StringBuffer msg = new StringBuffer( "Identifier classes must be serializable. " );
-			if ( id != null ) {
-				msg.append( id.getClass().getName() + " is not serializable. " );
-			}
-			if ( cce.getMessage() != null ) {
-				msg.append( cce.getMessage() );
-			}
-			throw new ClassCastException( msg.toString() );
-		}
-	}
-
-
-	public void setIdentifier(Object entity, Serializable id) throws HibernateException {
-		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
-			if ( entity != id ) {
-				AbstractComponentType copier = (AbstractComponentType) entityMetamodel.getIdentifierProperty().getType();
-				copier.setPropertyValues( entity, copier.getPropertyValues( id, getEntityMode() ), getEntityMode() );
-			}
-		}
-		else if ( idSetter != null ) {
-			idSetter.set( entity, id, getFactory() );
-		}
-	}
-
-	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion) {
-		if ( entityMetamodel.getIdentifierProperty().getIdentifierGenerator() instanceof Assigned ) {
-			//return currentId;
-		}
-		else {
-			//reset the id
-			Serializable result = entityMetamodel.getIdentifierProperty()
-					.getUnsavedValue()
-					.getDefaultValue( currentId );
-			setIdentifier( entity, result );
-			//reset the version
-			VersionProperty versionProperty = entityMetamodel.getVersionProperty();
-			if ( entityMetamodel.isVersioned() ) {
-				setPropertyValue(
-				        entity,
-				        entityMetamodel.getVersionPropertyIndex(),
-						versionProperty.getUnsavedValue().getDefaultValue( currentVersion )
-					);
-			}
-			//return the id, so we can use it to reset the proxy id
-			//return result;
-		}
-	}
-
-	public Object getVersion(Object entity) throws HibernateException {
-		if ( !entityMetamodel.isVersioned() ) return null;
-		return getters[ entityMetamodel.getVersionPropertyIndex() ].get( entity );
-	}
-
-	protected boolean shouldGetAllProperties(Object entity) {
-		return !hasUninitializedLazyProperties( entity );
-	}
-
-	public Object[] getPropertyValues(Object entity) throws HibernateException {
-		boolean getAll = shouldGetAllProperties( entity );
-		final int span = entityMetamodel.getPropertySpan();
-		final Object[] result = new Object[span];
-
-		for ( int j = 0; j < span; j++ ) {
-			StandardProperty property = entityMetamodel.getProperties()[j];
-			if ( getAll || !property.isLazy() ) {
-				result[j] = getters[j].get( entity );
-			}
-			else {
-				result[j] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
-			}
-		}
-		return result;
-	}
-
-	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) 
-	throws HibernateException {
-		final int span = entityMetamodel.getPropertySpan();
-		final Object[] result = new Object[span];
-
-		for ( int j = 0; j < span; j++ ) {
-			result[j] = getters[j].getForInsert( entity, mergeMap, session );
-		}
-		return result;
-	}
-
-	public Object getPropertyValue(Object entity, int i) throws HibernateException {
-		return getters[i].get( entity );
-	}
-
-	public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException {
-		
-		int loc = propertyPath.indexOf('.');
-		String basePropertyName = loc>0 ?
-			propertyPath.substring(0, loc) : propertyPath;
-			
-		int index = entityMetamodel.getPropertyIndex( basePropertyName );
-		Object baseValue = getPropertyValue( entity, index );
-		if ( loc>0 ) {
-			ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index];
-			return getComponentValue( type, baseValue, propertyPath.substring(loc+1) );
-		}
-		else {
-			return baseValue;
-		}
-	}
-
-	/**
-	 * Extract a component property value.
-	 *
-	 * @param type The component property types.
-	 * @param component The component instance itself.
-	 * @param propertyPath The property path for the property to be extracted.
-	 * @return The property value extracted.
-	 */
-	protected Object getComponentValue(ComponentType type, Object component, String propertyPath) {
-		
-		int loc = propertyPath.indexOf('.');
-		String basePropertyName = loc>0 ?
-			propertyPath.substring(0, loc) : propertyPath;
-		
-		String[] propertyNames = type.getPropertyNames();
-		int index=0;
-		for ( ; index<propertyNames.length; index++ ) {
-			if ( basePropertyName.equals( propertyNames[index] ) ) break;
-		}
-		if (index==propertyNames.length) {
-			throw new MappingException( "component property not found: " + basePropertyName );
-		}
-		
-		Object baseValue = type.getPropertyValue( component, index, getEntityMode() );
-		
-		if ( loc>0 ) {
-			ComponentType subtype = (ComponentType) type.getSubtypes()[index];
-			return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) );
-		}
-		else {
-			return baseValue;
-		}
-		
-	}
-
-	public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
-		boolean setAll = !entityMetamodel.hasLazyProperties();
-
-		for ( int j = 0; j < entityMetamodel.getPropertySpan(); j++ ) {
-			if ( setAll || values[j] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
-				setters[j].set( entity, values[j], getFactory() );
-			}
-		}
-	}
-
-	public void setPropertyValue(Object entity, int i, Object value) throws HibernateException {
-		setters[i].set( entity, value, getFactory() );
-	}
-
-	public void setPropertyValue(Object entity, String propertyName, Object value) throws HibernateException {
-		setters[ entityMetamodel.getPropertyIndex( propertyName ) ].set( entity, value, getFactory() );
-	}
-
-	public final Object instantiate(Serializable id) throws HibernateException {
-		Object result = getInstantiator().instantiate( id );
-		if ( id != null ) {
-			setIdentifier( result, id );
-		}
-		return result;
-	}
-
-	public final Object instantiate() throws HibernateException {
-		return instantiate( null );
-	}
-
-	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {}
-
-	public boolean hasUninitializedLazyProperties(Object entity) {
-		// the default is to simply not lazy fetch properties for now...
-		return false;
-	}
-
-	public final boolean isInstance(Object object) {
-        return getInstantiator().isInstance( object );
-	}
-
-	public boolean hasProxy() {
-		return entityMetamodel.isLazy();
-	}
-
-	public final Object createProxy(Serializable id, SessionImplementor session)
-	throws HibernateException {
-		return getProxyFactory().getProxy( id, session );
-	}
-
-	public boolean isLifecycleImplementor() {
-		return false;
-	}
-
-	public boolean isValidatableImplementor() {
-		return false;
-	}
-	
-	protected final EntityMetamodel getEntityMetamodel() {
-		return entityMetamodel;
-	}
-
-	protected final SessionFactoryImplementor getFactory() {
-		return entityMetamodel.getSessionFactory();
-	}
-
-	protected final Instantiator getInstantiator() {
-		return instantiator;
-	}
-
-	protected final ProxyFactory getProxyFactory() {
-		return proxyFactory;
-	}
-	
-	public String toString() {
-		return getClass().getName() + '(' + getEntityMetamodel().getName() + ')';
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/AbstractEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,433 @@
+/*
+ * 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.tuple.entity;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.VersionProperty;
+import org.hibernate.tuple.StandardProperty;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.Assigned;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.ComponentType;
+
+
+/**
+ * Support for tuplizers relating to entities.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public abstract class AbstractEntityTuplizer implements EntityTuplizer {
+
+	//TODO: currently keeps Getters and Setters (instead of PropertyAccessors) because of the way getGetter() and getSetter() are implemented currently; yuck!
+
+	private final EntityMetamodel entityMetamodel;
+
+	private final Getter idGetter;
+	private final Setter idSetter;
+
+	protected final Getter[] getters;
+	protected final Setter[] setters;
+	protected final int propertySpan;
+	protected final boolean hasCustomAccessors;
+	private final Instantiator instantiator;
+	private final ProxyFactory proxyFactory;
+	private final AbstractComponentType identifierMapperType;
+
+
+	/**
+	 * Return the entity-mode handled by this tuplizer instance.
+	 *
+	 * @return The entity-mode
+	 */
+	protected abstract EntityMode getEntityMode();
+
+	/**
+	 * Build an appropriate Getter for the given property.
+	 *
+	 * @param mappedProperty The property to be accessed via the built Getter.
+	 * @param mappedEntity The entity information regarding the mapped entity owning this property.
+	 * @return An appropriate Getter instance.
+	 */
+	protected abstract Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity);
+
+	/**
+	 * Build an appropriate Setter for the given property.
+	 *
+	 * @param mappedProperty The property to be accessed via the built Setter.
+	 * @param mappedEntity The entity information regarding the mapped entity owning this property.
+	 * @return An appropriate Setter instance.
+	 */
+	protected abstract Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity);
+
+	/**
+	 * Build an appropriate Instantiator for the given mapped entity.
+	 *
+	 * @param mappingInfo The mapping information regarding the mapped entity.
+	 * @return An appropriate Instantiator instance.
+	 */
+	protected abstract Instantiator buildInstantiator(PersistentClass mappingInfo);
+
+	/**
+	 * Build an appropriate ProxyFactory for the given mapped entity.
+	 *
+	 * @param mappingInfo The mapping information regarding the mapped entity.
+	 * @param idGetter The constructed Getter relating to the entity's id property.
+	 * @param idSetter The constructed Setter relating to the entity's id property.
+	 * @return An appropriate ProxyFactory instance.
+	 */
+	protected abstract ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter);
+
+	/**
+	 * Constructs a new AbstractEntityTuplizer instance.
+	 *
+	 * @param entityMetamodel The "interpreted" information relating to the mapped entity.
+	 * @param mappingInfo The parsed "raw" mapping data relating to the given entity.
+	 */
+	public AbstractEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappingInfo) {
+		this.entityMetamodel = entityMetamodel;
+
+		if ( !entityMetamodel.getIdentifierProperty().isVirtual() ) {
+			idGetter = buildPropertyGetter( mappingInfo.getIdentifierProperty(), mappingInfo );
+			idSetter = buildPropertySetter( mappingInfo.getIdentifierProperty(), mappingInfo );
+		}
+		else {
+			idGetter = null;
+			idSetter = null;
+		}
+
+		propertySpan = entityMetamodel.getPropertySpan();
+
+        getters = new Getter[propertySpan];
+		setters = new Setter[propertySpan];
+
+		Iterator iter = mappingInfo.getPropertyClosureIterator();
+		boolean foundCustomAccessor=false;
+		int i=0;
+		while ( iter.hasNext() ) {
+			//TODO: redesign how PropertyAccessors are acquired...
+			Property property = (Property) iter.next();
+			getters[i] = buildPropertyGetter(property, mappingInfo);
+			setters[i] = buildPropertySetter(property, mappingInfo);
+			if ( !property.isBasicPropertyAccessor() ) foundCustomAccessor = true;
+			i++;
+		}
+		hasCustomAccessors = foundCustomAccessor;
+
+        instantiator = buildInstantiator( mappingInfo );
+
+		if ( entityMetamodel.isLazy() ) {
+			proxyFactory = buildProxyFactory( mappingInfo, idGetter, idSetter );
+			if (proxyFactory == null) {
+				entityMetamodel.setLazy( false );
+			}
+		}
+		else {
+			proxyFactory = null;
+		}
+		
+		Component mapper = mappingInfo.getIdentifierMapper();
+		identifierMapperType = mapper==null ? null : (AbstractComponentType) mapper.getType();
+	}
+
+	/** Retreives the defined entity-name for the tuplized entity.
+	 *
+	 * @return The entity-name.
+	 */
+	protected String getEntityName() {
+		return entityMetamodel.getName();
+	}
+
+	/**
+	 * Retreives the defined entity-names for any subclasses defined for this
+	 * entity.
+	 *
+	 * @return Any subclass entity-names.
+	 */
+	protected Set getSubclassEntityNames() {
+		return entityMetamodel.getSubclassEntityNames();
+	}
+
+	public Serializable getIdentifier(Object entity) throws HibernateException {
+		final Object id;
+		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
+			id = entity;
+		}
+		else {
+			if ( idGetter == null ) {
+				if (identifierMapperType==null) {
+					throw new HibernateException( "The class has no identifier property: " + getEntityName() );
+				}
+				else {
+					ComponentType copier = (ComponentType) entityMetamodel.getIdentifierProperty().getType();
+					id = copier.instantiate( getEntityMode() );
+					copier.setPropertyValues( id, identifierMapperType.getPropertyValues( entity, getEntityMode() ), getEntityMode() );
+				}
+			}
+			else {
+				id = idGetter.get( entity );
+			}
+		}
+
+		try {
+			return (Serializable) id;
+		}
+		catch ( ClassCastException cce ) {
+			StringBuffer msg = new StringBuffer( "Identifier classes must be serializable. " );
+			if ( id != null ) {
+				msg.append( id.getClass().getName() + " is not serializable. " );
+			}
+			if ( cce.getMessage() != null ) {
+				msg.append( cce.getMessage() );
+			}
+			throw new ClassCastException( msg.toString() );
+		}
+	}
+
+
+	public void setIdentifier(Object entity, Serializable id) throws HibernateException {
+		if ( entityMetamodel.getIdentifierProperty().isEmbedded() ) {
+			if ( entity != id ) {
+				AbstractComponentType copier = (AbstractComponentType) entityMetamodel.getIdentifierProperty().getType();
+				copier.setPropertyValues( entity, copier.getPropertyValues( id, getEntityMode() ), getEntityMode() );
+			}
+		}
+		else if ( idSetter != null ) {
+			idSetter.set( entity, id, getFactory() );
+		}
+	}
+
+	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion) {
+		if ( entityMetamodel.getIdentifierProperty().getIdentifierGenerator() instanceof Assigned ) {
+			//return currentId;
+		}
+		else {
+			//reset the id
+			Serializable result = entityMetamodel.getIdentifierProperty()
+					.getUnsavedValue()
+					.getDefaultValue( currentId );
+			setIdentifier( entity, result );
+			//reset the version
+			VersionProperty versionProperty = entityMetamodel.getVersionProperty();
+			if ( entityMetamodel.isVersioned() ) {
+				setPropertyValue(
+				        entity,
+				        entityMetamodel.getVersionPropertyIndex(),
+						versionProperty.getUnsavedValue().getDefaultValue( currentVersion )
+					);
+			}
+			//return the id, so we can use it to reset the proxy id
+			//return result;
+		}
+	}
+
+	public Object getVersion(Object entity) throws HibernateException {
+		if ( !entityMetamodel.isVersioned() ) return null;
+		return getters[ entityMetamodel.getVersionPropertyIndex() ].get( entity );
+	}
+
+	protected boolean shouldGetAllProperties(Object entity) {
+		return !hasUninitializedLazyProperties( entity );
+	}
+
+	public Object[] getPropertyValues(Object entity) throws HibernateException {
+		boolean getAll = shouldGetAllProperties( entity );
+		final int span = entityMetamodel.getPropertySpan();
+		final Object[] result = new Object[span];
+
+		for ( int j = 0; j < span; j++ ) {
+			StandardProperty property = entityMetamodel.getProperties()[j];
+			if ( getAll || !property.isLazy() ) {
+				result[j] = getters[j].get( entity );
+			}
+			else {
+				result[j] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
+			}
+		}
+		return result;
+	}
+
+	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) 
+	throws HibernateException {
+		final int span = entityMetamodel.getPropertySpan();
+		final Object[] result = new Object[span];
+
+		for ( int j = 0; j < span; j++ ) {
+			result[j] = getters[j].getForInsert( entity, mergeMap, session );
+		}
+		return result;
+	}
+
+	public Object getPropertyValue(Object entity, int i) throws HibernateException {
+		return getters[i].get( entity );
+	}
+
+	public Object getPropertyValue(Object entity, String propertyPath) throws HibernateException {
+		
+		int loc = propertyPath.indexOf('.');
+		String basePropertyName = loc>0 ?
+			propertyPath.substring(0, loc) : propertyPath;
+			
+		int index = entityMetamodel.getPropertyIndex( basePropertyName );
+		Object baseValue = getPropertyValue( entity, index );
+		if ( loc>0 ) {
+			ComponentType type = (ComponentType) entityMetamodel.getPropertyTypes()[index];
+			return getComponentValue( type, baseValue, propertyPath.substring(loc+1) );
+		}
+		else {
+			return baseValue;
+		}
+	}
+
+	/**
+	 * Extract a component property value.
+	 *
+	 * @param type The component property types.
+	 * @param component The component instance itself.
+	 * @param propertyPath The property path for the property to be extracted.
+	 * @return The property value extracted.
+	 */
+	protected Object getComponentValue(ComponentType type, Object component, String propertyPath) {
+		
+		int loc = propertyPath.indexOf('.');
+		String basePropertyName = loc>0 ?
+			propertyPath.substring(0, loc) : propertyPath;
+		
+		String[] propertyNames = type.getPropertyNames();
+		int index=0;
+		for ( ; index<propertyNames.length; index++ ) {
+			if ( basePropertyName.equals( propertyNames[index] ) ) break;
+		}
+		if (index==propertyNames.length) {
+			throw new MappingException( "component property not found: " + basePropertyName );
+		}
+		
+		Object baseValue = type.getPropertyValue( component, index, getEntityMode() );
+		
+		if ( loc>0 ) {
+			ComponentType subtype = (ComponentType) type.getSubtypes()[index];
+			return getComponentValue( subtype, baseValue, propertyPath.substring(loc+1) );
+		}
+		else {
+			return baseValue;
+		}
+		
+	}
+
+	public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
+		boolean setAll = !entityMetamodel.hasLazyProperties();
+
+		for ( int j = 0; j < entityMetamodel.getPropertySpan(); j++ ) {
+			if ( setAll || values[j] != LazyPropertyInitializer.UNFETCHED_PROPERTY ) {
+				setters[j].set( entity, values[j], getFactory() );
+			}
+		}
+	}
+
+	public void setPropertyValue(Object entity, int i, Object value) throws HibernateException {
+		setters[i].set( entity, value, getFactory() );
+	}
+
+	public void setPropertyValue(Object entity, String propertyName, Object value) throws HibernateException {
+		setters[ entityMetamodel.getPropertyIndex( propertyName ) ].set( entity, value, getFactory() );
+	}
+
+	public final Object instantiate(Serializable id) throws HibernateException {
+		Object result = getInstantiator().instantiate( id );
+		if ( id != null ) {
+			setIdentifier( result, id );
+		}
+		return result;
+	}
+
+	public final Object instantiate() throws HibernateException {
+		return instantiate( null );
+	}
+
+	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {}
+
+	public boolean hasUninitializedLazyProperties(Object entity) {
+		// the default is to simply not lazy fetch properties for now...
+		return false;
+	}
+
+	public final boolean isInstance(Object object) {
+        return getInstantiator().isInstance( object );
+	}
+
+	public boolean hasProxy() {
+		return entityMetamodel.isLazy();
+	}
+
+	public final Object createProxy(Serializable id, SessionImplementor session)
+	throws HibernateException {
+		return getProxyFactory().getProxy( id, session );
+	}
+
+	public boolean isLifecycleImplementor() {
+		return false;
+	}
+
+	public boolean isValidatableImplementor() {
+		return false;
+	}
+	
+	protected final EntityMetamodel getEntityMetamodel() {
+		return entityMetamodel;
+	}
+
+	protected final SessionFactoryImplementor getFactory() {
+		return entityMetamodel.getSessionFactory();
+	}
+
+	protected final Instantiator getInstantiator() {
+		return instantiator;
+	}
+
+	protected final ProxyFactory getProxyFactory() {
+		return proxyFactory;
+	}
+	
+	public String toString() {
+		return getClass().getName() + '(' + getEntityMetamodel().getName() + ')';
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,123 +0,0 @@
-// $Id: Dom4jEntityTuplizer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple.entity;
-
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.dom4j.Dom4jProxyFactory;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.Dom4jInstantiator;
-import org.hibernate.type.AbstractComponentType;
-import org.dom4j.Element;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.io.Serializable;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.Iterator;
-
-/**
- * An {@link EntityTuplizer} specific to the dom4j entity mode.
- *
- * @author Steve Ebersole
- * @author Gavin King
- */
-public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
-
-	static final Logger log = LoggerFactory.getLogger( Dom4jEntityTuplizer.class );
-
-	private Set subclassNodeNames = new HashSet();
-
-	Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
-		super(entityMetamodel, mappedEntity);
-		Iterator itr = mappedEntity.getSubclassClosureIterator();
-		while( itr.hasNext() ) {
-			final PersistentClass mapping = ( PersistentClass ) itr.next();
-			subclassNodeNames.add( mapping.getNodeName() );
-		}
-	}
-	
-	public EntityMode getEntityMode() {
-		return EntityMode.DOM4J;
-	}
-
-	private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
-		if ( mappedProperty.isBackRef() ) {
-			return mappedProperty.getPropertyAccessor(null);
-		}
-		else {
-			return PropertyAccessorFactory.getDom4jPropertyAccessor( 
-					mappedProperty.getNodeName(), 
-					mappedProperty.getType(),
-					getEntityMetamodel().getSessionFactory()
-				);
-		}
-	}
-
-	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
-	}
-
-	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
-	}
-
-	protected Instantiator buildInstantiator(PersistentClass persistentClass) {
-		return new Dom4jInstantiator( persistentClass );
-	}
-
-	public Serializable getIdentifier(Object entityOrId) throws HibernateException {
-		if (entityOrId instanceof Element) {
-			return super.getIdentifier(entityOrId);
-		}
-		else {
-			//it was not embedded, so the argument is just an id
-			return (Serializable) entityOrId;
-		}
-	}
-	
-	protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
-		HashSet proxyInterfaces = new HashSet();
-		proxyInterfaces.add( HibernateProxy.class );
-		proxyInterfaces.add( Element.class );
-
-		ProxyFactory pf = new Dom4jProxyFactory();
-		try {
-			pf.postInstantiate(
-					getEntityName(),
-					Element.class,
-					proxyInterfaces,
-					null,
-					null,
-					mappingInfo.hasEmbeddedIdentifier() ?
-			                (AbstractComponentType) mappingInfo.getIdentifier().getType() :
-			                null
-			);
-		}
-		catch ( HibernateException he ) {
-			log.warn( "could not create proxy factory for:" + getEntityName(), he );
-			pf = null;
-		}
-		return pf;
-	}
-
-	public Class getMappedClass() {
-		return Element.class;
-	}
-
-	public Class getConcreteProxyClass() {
-		return Element.class;
-	}
-
-	public boolean isInstrumented() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/Dom4jEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.tuple.entity;
+
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.dom4j.Dom4jProxyFactory;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.Dom4jInstantiator;
+import org.hibernate.type.AbstractComponentType;
+import org.dom4j.Element;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Iterator;
+
+/**
+ * An {@link EntityTuplizer} specific to the dom4j entity mode.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
+
+	static final Logger log = LoggerFactory.getLogger( Dom4jEntityTuplizer.class );
+
+	private Set subclassNodeNames = new HashSet();
+
+	Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+		super(entityMetamodel, mappedEntity);
+		Iterator itr = mappedEntity.getSubclassClosureIterator();
+		while( itr.hasNext() ) {
+			final PersistentClass mapping = ( PersistentClass ) itr.next();
+			subclassNodeNames.add( mapping.getNodeName() );
+		}
+	}
+	
+	public EntityMode getEntityMode() {
+		return EntityMode.DOM4J;
+	}
+
+	private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
+		if ( mappedProperty.isBackRef() ) {
+			return mappedProperty.getPropertyAccessor(null);
+		}
+		else {
+			return PropertyAccessorFactory.getDom4jPropertyAccessor( 
+					mappedProperty.getNodeName(), 
+					mappedProperty.getType(),
+					getEntityMetamodel().getSessionFactory()
+				);
+		}
+	}
+
+	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
+	}
+
+	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
+	}
+
+	protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+		return new Dom4jInstantiator( persistentClass );
+	}
+
+	public Serializable getIdentifier(Object entityOrId) throws HibernateException {
+		if (entityOrId instanceof Element) {
+			return super.getIdentifier(entityOrId);
+		}
+		else {
+			//it was not embedded, so the argument is just an id
+			return (Serializable) entityOrId;
+		}
+	}
+	
+	protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
+		HashSet proxyInterfaces = new HashSet();
+		proxyInterfaces.add( HibernateProxy.class );
+		proxyInterfaces.add( Element.class );
+
+		ProxyFactory pf = new Dom4jProxyFactory();
+		try {
+			pf.postInstantiate(
+					getEntityName(),
+					Element.class,
+					proxyInterfaces,
+					null,
+					null,
+					mappingInfo.hasEmbeddedIdentifier() ?
+			                (AbstractComponentType) mappingInfo.getIdentifier().getType() :
+			                null
+			);
+		}
+		catch ( HibernateException he ) {
+			log.warn( "could not create proxy factory for:" + getEntityName(), he );
+			pf = null;
+		}
+		return pf;
+	}
+
+	public Class getMappedClass() {
+		return Element.class;
+	}
+
+	public Class getConcreteProxyClass() {
+		return Element.class;
+	}
+
+	public boolean isInstrumented() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,93 +0,0 @@
-// $Id: DynamicMapEntityTuplizer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple.entity;
-
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.tuple.entity.AbstractEntityTuplizer;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.DynamicMapInstantiator;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.property.PropertyAccessorFactory;
-import org.hibernate.property.Setter;
-import org.hibernate.proxy.map.MapProxyFactory;
-import org.hibernate.proxy.ProxyFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * An {@link EntityTuplizer} specific to the dynamic-map entity mode.
- *
- * @author Steve Ebersole
- * @author Gavin King
- */
-public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
-
-	static final Logger log = LoggerFactory.getLogger( DynamicMapEntityTuplizer.class );
-
-	DynamicMapEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
-		super(entityMetamodel, mappedEntity);
-	}
-	
-	public EntityMode getEntityMode() {
-		return EntityMode.MAP;
-	}
-
-	private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
-		if ( mappedProperty.isBackRef() ) {
-			return mappedProperty.getPropertyAccessor(null);
-		}
-		else {
-			return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
-		}
-	}
-
-	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
-	}
-
-	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
-	}
-
-	protected Instantiator buildInstantiator(PersistentClass mappingInfo) {
-        return new DynamicMapInstantiator( mappingInfo );
-	}
-
-	protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
-
-		ProxyFactory pf = new MapProxyFactory();
-		try {
-			//TODO: design new lifecycle for ProxyFactory
-			pf.postInstantiate(
-					getEntityName(),
-					null,
-					null,
-					null,
-					null,
-					null
-			);
-		}
-		catch ( HibernateException he ) {
-			log.warn( "could not create proxy factory for:" + getEntityName(), he );
-			pf = null;
-		}
-		return pf;
-	}
-
-	public Class getMappedClass() {
-		return Map.class;
-	}
-
-	public Class getConcreteProxyClass() {
-		return Map.class;
-	}
-
-	public boolean isInstrumented() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/DynamicMapEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.tuple.entity;
+
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.DynamicMapInstantiator;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.property.PropertyAccessorFactory;
+import org.hibernate.property.Setter;
+import org.hibernate.proxy.map.MapProxyFactory;
+import org.hibernate.proxy.ProxyFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * An {@link EntityTuplizer} specific to the dynamic-map entity mode.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
+
+	static final Logger log = LoggerFactory.getLogger( DynamicMapEntityTuplizer.class );
+
+	DynamicMapEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+		super(entityMetamodel, mappedEntity);
+	}
+	
+	public EntityMode getEntityMode() {
+		return EntityMode.MAP;
+	}
+
+	private PropertyAccessor buildPropertyAccessor(Property mappedProperty) {
+		if ( mappedProperty.isBackRef() ) {
+			return mappedProperty.getPropertyAccessor(null);
+		}
+		else {
+			return PropertyAccessorFactory.getDynamicMapPropertyAccessor();
+		}
+	}
+
+	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
+	}
+
+	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
+	}
+
+	protected Instantiator buildInstantiator(PersistentClass mappingInfo) {
+        return new DynamicMapInstantiator( mappingInfo );
+	}
+
+	protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
+
+		ProxyFactory pf = new MapProxyFactory();
+		try {
+			//TODO: design new lifecycle for ProxyFactory
+			pf.postInstantiate(
+					getEntityName(),
+					null,
+					null,
+					null,
+					null,
+					null
+			);
+		}
+		catch ( HibernateException he ) {
+			log.warn( "could not create proxy factory for:" + getEntityName(), he );
+			pf = null;
+		}
+		return pf;
+	}
+
+	public Class getMappedClass() {
+		return Map.class;
+	}
+
+	public Class getConcreteProxyClass() {
+		return Map.class;
+	}
+
+	public boolean isInstrumented() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,113 +0,0 @@
-package org.hibernate.tuple.entity;
-
-import org.hibernate.tuple.EntityModeToTuplizerMapping;
-import org.hibernate.tuple.Tuplizer;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.util.ReflectHelper;
-
-import java.util.Iterator;
-import java.util.Map;
-import java.util.HashMap;
-import java.io.Serializable;
-
-/**
- * Handles mapping {@link EntityMode}s to {@link EntityTuplizer}s.
- * <p/>
- * Most of the handling is really in the super class; here we just create
- * the tuplizers and add them to the superclass
- *
- * @author Steve Ebersole
- */
-public class EntityEntityModeToTuplizerMapping extends EntityModeToTuplizerMapping implements Serializable {
-
-	private static final Class[] ENTITY_TUP_CTOR_SIG = new Class[] { EntityMetamodel.class, PersistentClass.class };
-
-	/**
-	 * Instantiates a EntityEntityModeToTuplizerMapping based on the given
-	 * entity mapping and metamodel definitions.
-	 *
-	 * @param mappedEntity The entity mapping definition.
-	 * @param em The entity metamodel definition.
-	 */
-	public EntityEntityModeToTuplizerMapping(PersistentClass mappedEntity, EntityMetamodel em) {
-		// create our own copy of the user-supplied tuplizer impl map
-		Map userSuppliedTuplizerImpls = new HashMap();
-		if ( mappedEntity.getTuplizerMap() != null ) {
-			userSuppliedTuplizerImpls.putAll( mappedEntity.getTuplizerMap() );
-		}
-
-		// Build the dynamic-map tuplizer...
-		Tuplizer dynamicMapTuplizer = null;
-		String tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.MAP );
-		if ( tuplizerImpl == null ) {
-			dynamicMapTuplizer = new DynamicMapEntityTuplizer( em, mappedEntity );
-		}
-		else {
-			dynamicMapTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
-		}
-
-		// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
-		Tuplizer pojoTuplizer = null;
-		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.POJO );
-		if ( mappedEntity.hasPojoRepresentation() ) {
-			if ( tuplizerImpl == null ) {
-				pojoTuplizer = new PojoEntityTuplizer( em, mappedEntity );
-			}
-			else {
-				pojoTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
-			}
-		}
-		else {
-			pojoTuplizer = dynamicMapTuplizer;
-		}
-
-		// then dom4j tuplizer, if dom4j representation is available
-		Tuplizer dom4jTuplizer = null;
-		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.DOM4J );
-		if ( mappedEntity.hasDom4jRepresentation() ) {
-			if ( tuplizerImpl == null ) {
-				dom4jTuplizer = new Dom4jEntityTuplizer( em, mappedEntity );
-			}
-			else {
-				dom4jTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
-			}
-		}
-		else {
-			dom4jTuplizer = null;
-		}
-
-		// put the "standard" tuplizers into the tuplizer map first
-		if ( pojoTuplizer != null ) {
-			addTuplizer( EntityMode.POJO, pojoTuplizer );
-		}
-		if ( dynamicMapTuplizer != null ) {
-			addTuplizer( EntityMode.MAP, dynamicMapTuplizer );
-		}
-		if ( dom4jTuplizer != null ) {
-			addTuplizer( EntityMode.DOM4J, dom4jTuplizer );
-		}
-
-		// then handle any user-defined entity modes...
-		if ( !userSuppliedTuplizerImpls.isEmpty() ) {
-			Iterator itr = userSuppliedTuplizerImpls.entrySet().iterator();
-			while ( itr.hasNext() ) {
-				Map.Entry entry = ( Map.Entry ) itr.next();
-				EntityMode entityMode = ( EntityMode ) entry.getKey();
-				EntityTuplizer tuplizer = buildEntityTuplizer( ( String ) entry.getValue(), mappedEntity, em );
-				addTuplizer( entityMode, tuplizer );
-			}
-		}
-	}
-
-	private static EntityTuplizer buildEntityTuplizer(String className, PersistentClass pc, EntityMetamodel em) {
-		try {
-			Class implClass = ReflectHelper.classForName( className );
-			return ( EntityTuplizer ) implClass.getConstructor( ENTITY_TUP_CTOR_SIG ).newInstance( new Object[] { em, pc } );
-		}
-		catch( Throwable t ) {
-			throw new HibernateException( "Could not build tuplizer [" + className + "]", t );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityEntityModeToTuplizerMapping.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,137 @@
+/*
+ * 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.tuple.entity;
+
+import org.hibernate.tuple.EntityModeToTuplizerMapping;
+import org.hibernate.tuple.Tuplizer;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.io.Serializable;
+
+/**
+ * Handles mapping {@link EntityMode}s to {@link EntityTuplizer}s.
+ * <p/>
+ * Most of the handling is really in the super class; here we just create
+ * the tuplizers and add them to the superclass
+ *
+ * @author Steve Ebersole
+ */
+public class EntityEntityModeToTuplizerMapping extends EntityModeToTuplizerMapping implements Serializable {
+
+	private static final Class[] ENTITY_TUP_CTOR_SIG = new Class[] { EntityMetamodel.class, PersistentClass.class };
+
+	/**
+	 * Instantiates a EntityEntityModeToTuplizerMapping based on the given
+	 * entity mapping and metamodel definitions.
+	 *
+	 * @param mappedEntity The entity mapping definition.
+	 * @param em The entity metamodel definition.
+	 */
+	public EntityEntityModeToTuplizerMapping(PersistentClass mappedEntity, EntityMetamodel em) {
+		// create our own copy of the user-supplied tuplizer impl map
+		Map userSuppliedTuplizerImpls = new HashMap();
+		if ( mappedEntity.getTuplizerMap() != null ) {
+			userSuppliedTuplizerImpls.putAll( mappedEntity.getTuplizerMap() );
+		}
+
+		// Build the dynamic-map tuplizer...
+		Tuplizer dynamicMapTuplizer = null;
+		String tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.MAP );
+		if ( tuplizerImpl == null ) {
+			dynamicMapTuplizer = new DynamicMapEntityTuplizer( em, mappedEntity );
+		}
+		else {
+			dynamicMapTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
+		}
+
+		// then the pojo tuplizer, using the dynamic-map tuplizer if no pojo representation is available
+		Tuplizer pojoTuplizer = null;
+		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.POJO );
+		if ( mappedEntity.hasPojoRepresentation() ) {
+			if ( tuplizerImpl == null ) {
+				pojoTuplizer = new PojoEntityTuplizer( em, mappedEntity );
+			}
+			else {
+				pojoTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
+			}
+		}
+		else {
+			pojoTuplizer = dynamicMapTuplizer;
+		}
+
+		// then dom4j tuplizer, if dom4j representation is available
+		Tuplizer dom4jTuplizer = null;
+		tuplizerImpl = ( String ) userSuppliedTuplizerImpls.remove( EntityMode.DOM4J );
+		if ( mappedEntity.hasDom4jRepresentation() ) {
+			if ( tuplizerImpl == null ) {
+				dom4jTuplizer = new Dom4jEntityTuplizer( em, mappedEntity );
+			}
+			else {
+				dom4jTuplizer = buildEntityTuplizer( tuplizerImpl, mappedEntity, em );
+			}
+		}
+		else {
+			dom4jTuplizer = null;
+		}
+
+		// put the "standard" tuplizers into the tuplizer map first
+		if ( pojoTuplizer != null ) {
+			addTuplizer( EntityMode.POJO, pojoTuplizer );
+		}
+		if ( dynamicMapTuplizer != null ) {
+			addTuplizer( EntityMode.MAP, dynamicMapTuplizer );
+		}
+		if ( dom4jTuplizer != null ) {
+			addTuplizer( EntityMode.DOM4J, dom4jTuplizer );
+		}
+
+		// then handle any user-defined entity modes...
+		if ( !userSuppliedTuplizerImpls.isEmpty() ) {
+			Iterator itr = userSuppliedTuplizerImpls.entrySet().iterator();
+			while ( itr.hasNext() ) {
+				Map.Entry entry = ( Map.Entry ) itr.next();
+				EntityMode entityMode = ( EntityMode ) entry.getKey();
+				EntityTuplizer tuplizer = buildEntityTuplizer( ( String ) entry.getValue(), mappedEntity, em );
+				addTuplizer( entityMode, tuplizer );
+			}
+		}
+	}
+
+	private static EntityTuplizer buildEntityTuplizer(String className, PersistentClass pc, EntityMetamodel em) {
+		try {
+			Class implClass = ReflectHelper.classForName( className );
+			return ( EntityTuplizer ) implClass.getConstructor( ENTITY_TUP_CTOR_SIG ).newInstance( new Object[] { em, pc } );
+		}
+		catch( Throwable t ) {
+			throw new HibernateException( "Could not build tuplizer [" + className + "]", t );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,597 +0,0 @@
-// $Id: EntityMetamodel.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple.entity;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.tuple.IdentifierProperty;
-import org.hibernate.tuple.StandardProperty;
-import org.hibernate.tuple.PropertyFactory;
-import org.hibernate.tuple.VersionProperty;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.Versioning;
-import org.hibernate.engine.ValueInclusion;
-import org.hibernate.mapping.Component;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.PropertyGeneration;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.type.AssociationType;
-import org.hibernate.type.EntityType;
-import org.hibernate.type.Type;
-import org.hibernate.type.TypeFactory;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Centralizes metamodel information about an entity.
- *
- * @author Steve Ebersole
- */
-public class EntityMetamodel implements Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger(EntityMetamodel.class);
-
-	private static final int NO_VERSION_INDX = -66;
-
-	private final SessionFactoryImplementor sessionFactory;
-
-	private final String name;
-	private final String rootName;
-	private final EntityType entityType;
-
-	private final IdentifierProperty identifierProperty;
-	private final boolean versioned;
-
-	private final int propertySpan;
-	private final int versionPropertyIndex;
-	private final StandardProperty[] properties;
-	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	private final String[] propertyNames;
-	private final Type[] propertyTypes;
-	private final boolean[] propertyLaziness;
-	private final boolean[] propertyUpdateability;
-	private final boolean[] nonlazyPropertyUpdateability;
-	private final boolean[] propertyCheckability;
-	private final boolean[] propertyInsertability;
-	private final ValueInclusion[] insertInclusions;
-	private final ValueInclusion[] updateInclusions;
-	private final boolean[] propertyNullability;
-	private final boolean[] propertyVersionability;
-	private final CascadeStyle[] cascadeStyles;
-	private final boolean hasInsertGeneratedValues;
-	private final boolean hasUpdateGeneratedValues;
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	private final Map propertyIndexes = new HashMap();
-	private final boolean hasCollections;
-	private final boolean hasMutableProperties;
-	private final boolean hasLazyProperties;
-	private final boolean hasNonIdentifierPropertyNamedId;
-
-	private final int[] naturalIdPropertyNumbers;
-	private final boolean hasImmutableNaturalId;
-
-	private boolean lazy; //not final because proxy factory creation can fail
-	private final boolean hasCascades;
-	private final boolean mutable;
-	private final boolean isAbstract;
-	private final boolean selectBeforeUpdate;
-	private final boolean dynamicUpdate;
-	private final boolean dynamicInsert;
-	private final int optimisticLockMode;
-
-	private final boolean polymorphic;
-	private final String superclass;  // superclass entity-name
-	private final boolean explicitPolymorphism;
-	private final boolean inherited;
-	private final boolean hasSubclasses;
-	private final Set subclassEntityNames = new HashSet();
-
-	private final EntityEntityModeToTuplizerMapping tuplizerMapping;
-
-	public EntityTuplizer getTuplizer(EntityMode entityMode) {
-		return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
-	}
-
-	public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
-		return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
-	}
-
-	public EntityMode guessEntityMode(Object object) {
-		return tuplizerMapping.guessEntityMode( object );
-	}
-
-	public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
-		this.sessionFactory = sessionFactory;
-
-		name = persistentClass.getEntityName();
-		rootName = persistentClass.getRootClass().getEntityName();
-		entityType = TypeFactory.manyToOne( name );
-
-		identifierProperty = PropertyFactory.buildIdentifierProperty(
-		        persistentClass,
-		        sessionFactory.getIdentifierGenerator( rootName )
-			);
-
-		versioned = persistentClass.isVersioned();
-
-		boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
-		                        FieldInterceptionHelper.isInstrumented( persistentClass.getMappedClass() );
-		boolean hasLazy = false;
-
-		propertySpan = persistentClass.getPropertyClosureSpan();
-		properties = new StandardProperty[propertySpan];
-		List naturalIdNumbers = new ArrayList();
-		// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-		propertyNames = new String[propertySpan];
-		propertyTypes = new Type[propertySpan];
-		propertyUpdateability = new boolean[propertySpan];
-		propertyInsertability = new boolean[propertySpan];
-		insertInclusions = new ValueInclusion[propertySpan];
-		updateInclusions = new ValueInclusion[propertySpan];
-		nonlazyPropertyUpdateability = new boolean[propertySpan];
-		propertyCheckability = new boolean[propertySpan];
-		propertyNullability = new boolean[propertySpan];
-		propertyVersionability = new boolean[propertySpan];
-		propertyLaziness = new boolean[propertySpan];
-		cascadeStyles = new CascadeStyle[propertySpan];
-		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-		Iterator iter = persistentClass.getPropertyClosureIterator();
-		int i = 0;
-		int tempVersionProperty = NO_VERSION_INDX;
-		boolean foundCascade = false;
-		boolean foundCollection = false;
-		boolean foundMutable = false;
-		boolean foundNonIdentifierPropertyNamedId = false;
-		boolean foundInsertGeneratedValue = false;
-		boolean foundUpdateGeneratedValue = false;
-		boolean foundUpdateableNaturalIdProperty = false;
-
-		while ( iter.hasNext() ) {
-			Property prop = ( Property ) iter.next();
-
-			if ( prop == persistentClass.getVersion() ) {
-				tempVersionProperty = i;
-				properties[i] = PropertyFactory.buildVersionProperty( prop, lazyAvailable );
-			}
-			else {
-				properties[i] = PropertyFactory.buildStandardProperty( prop, lazyAvailable );
-			}
-
-			if ( prop.isNaturalIdentifier() ) {
-				naturalIdNumbers.add( new Integer(i) );
-				if ( prop.isUpdateable() ) {
-					foundUpdateableNaturalIdProperty = true;
-				}
-			}
-
-			if ( "id".equals( prop.getName() ) ) {
-				foundNonIdentifierPropertyNamedId = true;
-			}
-
-			// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-			boolean lazy = prop.isLazy() && lazyAvailable;
-			if ( lazy ) hasLazy = true;
-			propertyLaziness[i] = lazy;
-
-			propertyNames[i] = properties[i].getName();
-			propertyTypes[i] = properties[i].getType();
-			propertyNullability[i] = properties[i].isNullable();
-			propertyUpdateability[i] = properties[i].isUpdateable();
-			propertyInsertability[i] = properties[i].isInsertable();
-			insertInclusions[i] = determineInsertValueGenerationType( prop, properties[i] );
-			updateInclusions[i] = determineUpdateValueGenerationType( prop, properties[i] );
-			propertyVersionability[i] = properties[i].isVersionable();
-			nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
-			propertyCheckability[i] = propertyUpdateability[i] ||
-					( propertyTypes[i].isAssociationType() && ( (AssociationType) propertyTypes[i] ).isAlwaysDirtyChecked() );
-
-			cascadeStyles[i] = properties[i].getCascadeStyle();
-			// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-			if ( properties[i].isLazy() ) {
-				hasLazy = true;
-			}
-
-			if ( properties[i].getCascadeStyle() != CascadeStyle.NONE ) {
-				foundCascade = true;
-			}
-
-			if ( indicatesCollection( properties[i].getType() ) ) {
-				foundCollection = true;
-			}
-
-			if ( propertyTypes[i].isMutable() && propertyCheckability[i] ) {
-				foundMutable = true;
-			}
-
-			if ( insertInclusions[i] != ValueInclusion.NONE ) {
-				foundInsertGeneratedValue = true;
-			}
-
-			if ( updateInclusions[i] != ValueInclusion.NONE ) {
-				foundUpdateGeneratedValue = true;
-			}
-
-			mapPropertyToIndex(prop, i);
-			i++;
-		}
-
-		if (naturalIdNumbers.size()==0) {
-			naturalIdPropertyNumbers = null;
-			hasImmutableNaturalId = false;
-		}
-		else {
-			naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
-			hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
-		}
-
-		hasInsertGeneratedValues = foundInsertGeneratedValue;
-		hasUpdateGeneratedValues = foundUpdateGeneratedValue;
-
-		hasCascades = foundCascade;
-		hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;
-		versionPropertyIndex = tempVersionProperty;
-		hasLazyProperties = hasLazy;
-		if ( hasLazyProperties ) {
-			log.info( "lazy property fetching available for: " + name );
-		}
-
-		lazy = persistentClass.isLazy() && (
-				// TODO: this disables laziness even in non-pojo entity modes:
-				!persistentClass.hasPojoRepresentation() ||
-				!ReflectHelper.isFinalClass( persistentClass.getProxyInterface() )
-		);
-		mutable = persistentClass.isMutable();
-		if ( persistentClass.isAbstract() == null ) {
-			// legacy behavior (with no abstract attribute specified)
-			isAbstract = persistentClass.hasPojoRepresentation() &&
-			             ReflectHelper.isAbstractClass( persistentClass.getMappedClass() );
-		}
-		else {
-			isAbstract = persistentClass.isAbstract().booleanValue();
-			if ( !isAbstract && persistentClass.hasPojoRepresentation() &&
-			     ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ) ) {
-				log.warn( "entity [" + name + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names" );
-			}
-		}
-		selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
-		dynamicUpdate = persistentClass.useDynamicUpdate();
-		dynamicInsert = persistentClass.useDynamicInsert();
-
-		polymorphic = persistentClass.isPolymorphic();
-		explicitPolymorphism = persistentClass.isExplicitPolymorphism();
-		inherited = persistentClass.isInherited();
-		superclass = inherited ?
-				persistentClass.getSuperclass().getEntityName() :
-				null;
-		hasSubclasses = persistentClass.hasSubclasses();
-
-		optimisticLockMode = persistentClass.getOptimisticLockMode();
-		if ( optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION && !dynamicUpdate ) {
-			throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name );
-		}
-		if ( versionPropertyIndex != NO_VERSION_INDX && optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION ) {
-			throw new MappingException( "version and optimistic-lock=all|dirty are not a valid combination : " + name );
-		}
-
-		hasCollections = foundCollection;
-		hasMutableProperties = foundMutable;
-
-		iter = persistentClass.getSubclassIterator();
-		while ( iter.hasNext() ) {
-			subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
-		}
-		subclassEntityNames.add( name );
-
-		tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
-	}
-
-	private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
-		if ( runtimeProperty.isInsertGenerated() ) {
-			return ValueInclusion.FULL;
-		}
-		else if ( mappingProperty.getValue() instanceof Component ) {
-			if ( hasPartialInsertComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
-				return ValueInclusion.PARTIAL;
-			}
-		}
-		return ValueInclusion.NONE;
-	}
-
-	private boolean hasPartialInsertComponentGeneration(Component component) {
-		Iterator subProperties = component.getPropertyIterator();
-		while ( subProperties.hasNext() ) {
-			Property prop = ( Property ) subProperties.next();
-			if ( prop.getGeneration() == PropertyGeneration.ALWAYS || prop.getGeneration() == PropertyGeneration.INSERT ) {
-				return true;
-			}
-			else if ( prop.getValue() instanceof Component ) {
-				if ( hasPartialInsertComponentGeneration( ( Component ) prop.getValue() ) ) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
-		if ( runtimeProperty.isUpdateGenerated() ) {
-			return ValueInclusion.FULL;
-		}
-		else if ( mappingProperty.getValue() instanceof Component ) {
-			if ( hasPartialUpdateComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
-				return ValueInclusion.PARTIAL;
-			}
-		}
-		return ValueInclusion.NONE;
-	}
-
-	private boolean hasPartialUpdateComponentGeneration(Component component) {
-		Iterator subProperties = component.getPropertyIterator();
-		while ( subProperties.hasNext() ) {
-			Property prop = ( Property ) subProperties.next();
-			if ( prop.getGeneration() == PropertyGeneration.ALWAYS ) {
-				return true;
-			}
-			else if ( prop.getValue() instanceof Component ) {
-				if ( hasPartialUpdateComponentGeneration( ( Component ) prop.getValue() ) ) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	private void mapPropertyToIndex(Property prop, int i) {
-		propertyIndexes.put( prop.getName(), new Integer(i) );
-		if ( prop.getValue() instanceof Component ) {
-			Iterator iter = ( (Component) prop.getValue() ).getPropertyIterator();
-			while ( iter.hasNext() ) {
-				Property subprop = (Property) iter.next();
-				propertyIndexes.put(
-						prop.getName() + '.' + subprop.getName(),
-						new Integer(i)
-					);
-			}
-		}
-	}
-
-	public int[] getNaturalIdentifierProperties() {
-		return naturalIdPropertyNumbers;
-	}
-
-	public boolean hasNaturalIdentifier() {
-		return naturalIdPropertyNumbers!=null;
-	}
-
-	public boolean hasImmutableNaturalId() {
-		return hasImmutableNaturalId;
-	}
-
-	public Set getSubclassEntityNames() {
-		return subclassEntityNames;
-	}
-
-	private boolean indicatesCollection(Type type) {
-		if ( type.isCollectionType() ) {
-			return true;
-		}
-		else if ( type.isComponentType() ) {
-			Type[] subtypes = ( ( AbstractComponentType ) type ).getSubtypes();
-			for ( int i = 0; i < subtypes.length; i++ ) {
-				if ( indicatesCollection( subtypes[i] ) ) {
-					return true;
-				}
-			}
-		}
-		return false;
-	}
-
-	public SessionFactoryImplementor getSessionFactory() {
-		return sessionFactory;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public String getRootName() {
-		return rootName;
-	}
-
-	public EntityType getEntityType() {
-		return entityType;
-	}
-
-	public IdentifierProperty getIdentifierProperty() {
-		return identifierProperty;
-	}
-
-	public int getPropertySpan() {
-		return propertySpan;
-	}
-
-	public int getVersionPropertyIndex() {
-		return versionPropertyIndex;
-	}
-
-	public VersionProperty getVersionProperty() {
-		if ( NO_VERSION_INDX == versionPropertyIndex ) {
-			return null;
-		}
-		else {
-			return ( VersionProperty ) properties[ versionPropertyIndex ];
-		}
-	}
-
-	public StandardProperty[] getProperties() {
-		return properties;
-	}
-
-	public int getPropertyIndex(String propertyName) {
-		Integer index = getPropertyIndexOrNull(propertyName);
-		if ( index == null ) {
-			throw new HibernateException("Unable to resolve property: " + propertyName);
-		}
-		return index.intValue();
-	}
-
-	public Integer getPropertyIndexOrNull(String propertyName) {
-		return (Integer) propertyIndexes.get( propertyName );
-	}
-
-	public boolean hasCollections() {
-		return hasCollections;
-	}
-
-	public boolean hasMutableProperties() {
-		return hasMutableProperties;
-	}
-
-	public boolean hasNonIdentifierPropertyNamedId() {
-		return hasNonIdentifierPropertyNamedId;
-	}
-
-	public boolean hasLazyProperties() {
-		return hasLazyProperties;
-	}
-
-	public boolean hasCascades() {
-		return hasCascades;
-	}
-
-	public boolean isMutable() {
-		return mutable;
-	}
-
-	public boolean isSelectBeforeUpdate() {
-		return selectBeforeUpdate;
-	}
-
-	public boolean isDynamicUpdate() {
-		return dynamicUpdate;
-	}
-
-	public boolean isDynamicInsert() {
-		return dynamicInsert;
-	}
-
-	public int getOptimisticLockMode() {
-		return optimisticLockMode;
-	}
-
-	public boolean isPolymorphic() {
-		return polymorphic;
-	}
-
-	public String getSuperclass() {
-		return superclass;
-	}
-
-	public boolean isExplicitPolymorphism() {
-		return explicitPolymorphism;
-	}
-
-	public boolean isInherited() {
-		return inherited;
-	}
-
-	public boolean hasSubclasses() {
-		return hasSubclasses;
-	}
-
-	public boolean isLazy() {
-		return lazy;
-	}
-
-	public void setLazy(boolean lazy) {
-		this.lazy = lazy;
-	}
-
-	public boolean isVersioned() {
-		return versioned;
-	}
-
-	public boolean isAbstract() {
-		return isAbstract;
-	}
-
-	public String toString() {
-		return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
-	}
-
-	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	public String[] getPropertyNames() {
-		return propertyNames;
-	}
-
-	public Type[] getPropertyTypes() {
-		return propertyTypes;
-	}
-
-	public boolean[] getPropertyLaziness() {
-		return propertyLaziness;
-	}
-
-	public boolean[] getPropertyUpdateability() {
-		return propertyUpdateability;
-	}
-
-	public boolean[] getPropertyCheckability() {
-		return propertyCheckability;
-	}
-
-	public boolean[] getNonlazyPropertyUpdateability() {
-		return nonlazyPropertyUpdateability;
-	}
-
-	public boolean[] getPropertyInsertability() {
-		return propertyInsertability;
-	}
-
-	public ValueInclusion[] getPropertyInsertGenerationInclusions() {
-		return insertInclusions;
-	}
-
-	public ValueInclusion[] getPropertyUpdateGenerationInclusions() {
-		return updateInclusions;
-	}
-
-	public boolean[] getPropertyNullability() {
-		return propertyNullability;
-	}
-
-	public boolean[] getPropertyVersionability() {
-		return propertyVersionability;
-	}
-
-	public CascadeStyle[] getCascadeStyles() {
-		return cascadeStyles;
-	}
-
-	public boolean hasInsertGeneratedValues() {
-		return hasInsertGeneratedValues;
-	}
-
-	public boolean hasUpdateGeneratedValues() {
-		return hasUpdateGeneratedValues;
-	}
-
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,620 @@
+/*
+ * 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.tuple.entity;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.tuple.IdentifierProperty;
+import org.hibernate.tuple.StandardProperty;
+import org.hibernate.tuple.PropertyFactory;
+import org.hibernate.tuple.VersionProperty;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.Versioning;
+import org.hibernate.engine.ValueInclusion;
+import org.hibernate.mapping.Component;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.PropertyGeneration;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.type.AssociationType;
+import org.hibernate.type.EntityType;
+import org.hibernate.type.Type;
+import org.hibernate.type.TypeFactory;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Centralizes metamodel information about an entity.
+ *
+ * @author Steve Ebersole
+ */
+public class EntityMetamodel implements Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger(EntityMetamodel.class);
+
+	private static final int NO_VERSION_INDX = -66;
+
+	private final SessionFactoryImplementor sessionFactory;
+
+	private final String name;
+	private final String rootName;
+	private final EntityType entityType;
+
+	private final IdentifierProperty identifierProperty;
+	private final boolean versioned;
+
+	private final int propertySpan;
+	private final int versionPropertyIndex;
+	private final StandardProperty[] properties;
+	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private final String[] propertyNames;
+	private final Type[] propertyTypes;
+	private final boolean[] propertyLaziness;
+	private final boolean[] propertyUpdateability;
+	private final boolean[] nonlazyPropertyUpdateability;
+	private final boolean[] propertyCheckability;
+	private final boolean[] propertyInsertability;
+	private final ValueInclusion[] insertInclusions;
+	private final ValueInclusion[] updateInclusions;
+	private final boolean[] propertyNullability;
+	private final boolean[] propertyVersionability;
+	private final CascadeStyle[] cascadeStyles;
+	private final boolean hasInsertGeneratedValues;
+	private final boolean hasUpdateGeneratedValues;
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	private final Map propertyIndexes = new HashMap();
+	private final boolean hasCollections;
+	private final boolean hasMutableProperties;
+	private final boolean hasLazyProperties;
+	private final boolean hasNonIdentifierPropertyNamedId;
+
+	private final int[] naturalIdPropertyNumbers;
+	private final boolean hasImmutableNaturalId;
+
+	private boolean lazy; //not final because proxy factory creation can fail
+	private final boolean hasCascades;
+	private final boolean mutable;
+	private final boolean isAbstract;
+	private final boolean selectBeforeUpdate;
+	private final boolean dynamicUpdate;
+	private final boolean dynamicInsert;
+	private final int optimisticLockMode;
+
+	private final boolean polymorphic;
+	private final String superclass;  // superclass entity-name
+	private final boolean explicitPolymorphism;
+	private final boolean inherited;
+	private final boolean hasSubclasses;
+	private final Set subclassEntityNames = new HashSet();
+
+	private final EntityEntityModeToTuplizerMapping tuplizerMapping;
+
+	public EntityTuplizer getTuplizer(EntityMode entityMode) {
+		return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
+	}
+
+	public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
+		return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
+	}
+
+	public EntityMode guessEntityMode(Object object) {
+		return tuplizerMapping.guessEntityMode( object );
+	}
+
+	public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
+		this.sessionFactory = sessionFactory;
+
+		name = persistentClass.getEntityName();
+		rootName = persistentClass.getRootClass().getEntityName();
+		entityType = TypeFactory.manyToOne( name );
+
+		identifierProperty = PropertyFactory.buildIdentifierProperty(
+		        persistentClass,
+		        sessionFactory.getIdentifierGenerator( rootName )
+			);
+
+		versioned = persistentClass.isVersioned();
+
+		boolean lazyAvailable = persistentClass.hasPojoRepresentation() &&
+		                        FieldInterceptionHelper.isInstrumented( persistentClass.getMappedClass() );
+		boolean hasLazy = false;
+
+		propertySpan = persistentClass.getPropertyClosureSpan();
+		properties = new StandardProperty[propertySpan];
+		List naturalIdNumbers = new ArrayList();
+		// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+		propertyNames = new String[propertySpan];
+		propertyTypes = new Type[propertySpan];
+		propertyUpdateability = new boolean[propertySpan];
+		propertyInsertability = new boolean[propertySpan];
+		insertInclusions = new ValueInclusion[propertySpan];
+		updateInclusions = new ValueInclusion[propertySpan];
+		nonlazyPropertyUpdateability = new boolean[propertySpan];
+		propertyCheckability = new boolean[propertySpan];
+		propertyNullability = new boolean[propertySpan];
+		propertyVersionability = new boolean[propertySpan];
+		propertyLaziness = new boolean[propertySpan];
+		cascadeStyles = new CascadeStyle[propertySpan];
+		// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+		Iterator iter = persistentClass.getPropertyClosureIterator();
+		int i = 0;
+		int tempVersionProperty = NO_VERSION_INDX;
+		boolean foundCascade = false;
+		boolean foundCollection = false;
+		boolean foundMutable = false;
+		boolean foundNonIdentifierPropertyNamedId = false;
+		boolean foundInsertGeneratedValue = false;
+		boolean foundUpdateGeneratedValue = false;
+		boolean foundUpdateableNaturalIdProperty = false;
+
+		while ( iter.hasNext() ) {
+			Property prop = ( Property ) iter.next();
+
+			if ( prop == persistentClass.getVersion() ) {
+				tempVersionProperty = i;
+				properties[i] = PropertyFactory.buildVersionProperty( prop, lazyAvailable );
+			}
+			else {
+				properties[i] = PropertyFactory.buildStandardProperty( prop, lazyAvailable );
+			}
+
+			if ( prop.isNaturalIdentifier() ) {
+				naturalIdNumbers.add( new Integer(i) );
+				if ( prop.isUpdateable() ) {
+					foundUpdateableNaturalIdProperty = true;
+				}
+			}
+
+			if ( "id".equals( prop.getName() ) ) {
+				foundNonIdentifierPropertyNamedId = true;
+			}
+
+			// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+			boolean lazy = prop.isLazy() && lazyAvailable;
+			if ( lazy ) hasLazy = true;
+			propertyLaziness[i] = lazy;
+
+			propertyNames[i] = properties[i].getName();
+			propertyTypes[i] = properties[i].getType();
+			propertyNullability[i] = properties[i].isNullable();
+			propertyUpdateability[i] = properties[i].isUpdateable();
+			propertyInsertability[i] = properties[i].isInsertable();
+			insertInclusions[i] = determineInsertValueGenerationType( prop, properties[i] );
+			updateInclusions[i] = determineUpdateValueGenerationType( prop, properties[i] );
+			propertyVersionability[i] = properties[i].isVersionable();
+			nonlazyPropertyUpdateability[i] = properties[i].isUpdateable() && !lazy;
+			propertyCheckability[i] = propertyUpdateability[i] ||
+					( propertyTypes[i].isAssociationType() && ( (AssociationType) propertyTypes[i] ).isAlwaysDirtyChecked() );
+
+			cascadeStyles[i] = properties[i].getCascadeStyle();
+			// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+			if ( properties[i].isLazy() ) {
+				hasLazy = true;
+			}
+
+			if ( properties[i].getCascadeStyle() != CascadeStyle.NONE ) {
+				foundCascade = true;
+			}
+
+			if ( indicatesCollection( properties[i].getType() ) ) {
+				foundCollection = true;
+			}
+
+			if ( propertyTypes[i].isMutable() && propertyCheckability[i] ) {
+				foundMutable = true;
+			}
+
+			if ( insertInclusions[i] != ValueInclusion.NONE ) {
+				foundInsertGeneratedValue = true;
+			}
+
+			if ( updateInclusions[i] != ValueInclusion.NONE ) {
+				foundUpdateGeneratedValue = true;
+			}
+
+			mapPropertyToIndex(prop, i);
+			i++;
+		}
+
+		if (naturalIdNumbers.size()==0) {
+			naturalIdPropertyNumbers = null;
+			hasImmutableNaturalId = false;
+		}
+		else {
+			naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers);
+			hasImmutableNaturalId = !foundUpdateableNaturalIdProperty;
+		}
+
+		hasInsertGeneratedValues = foundInsertGeneratedValue;
+		hasUpdateGeneratedValues = foundUpdateGeneratedValue;
+
+		hasCascades = foundCascade;
+		hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId;
+		versionPropertyIndex = tempVersionProperty;
+		hasLazyProperties = hasLazy;
+		if ( hasLazyProperties ) {
+			log.info( "lazy property fetching available for: " + name );
+		}
+
+		lazy = persistentClass.isLazy() && (
+				// TODO: this disables laziness even in non-pojo entity modes:
+				!persistentClass.hasPojoRepresentation() ||
+				!ReflectHelper.isFinalClass( persistentClass.getProxyInterface() )
+		);
+		mutable = persistentClass.isMutable();
+		if ( persistentClass.isAbstract() == null ) {
+			// legacy behavior (with no abstract attribute specified)
+			isAbstract = persistentClass.hasPojoRepresentation() &&
+			             ReflectHelper.isAbstractClass( persistentClass.getMappedClass() );
+		}
+		else {
+			isAbstract = persistentClass.isAbstract().booleanValue();
+			if ( !isAbstract && persistentClass.hasPojoRepresentation() &&
+			     ReflectHelper.isAbstractClass( persistentClass.getMappedClass() ) ) {
+				log.warn( "entity [" + name + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names" );
+			}
+		}
+		selectBeforeUpdate = persistentClass.hasSelectBeforeUpdate();
+		dynamicUpdate = persistentClass.useDynamicUpdate();
+		dynamicInsert = persistentClass.useDynamicInsert();
+
+		polymorphic = persistentClass.isPolymorphic();
+		explicitPolymorphism = persistentClass.isExplicitPolymorphism();
+		inherited = persistentClass.isInherited();
+		superclass = inherited ?
+				persistentClass.getSuperclass().getEntityName() :
+				null;
+		hasSubclasses = persistentClass.hasSubclasses();
+
+		optimisticLockMode = persistentClass.getOptimisticLockMode();
+		if ( optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION && !dynamicUpdate ) {
+			throw new MappingException( "optimistic-lock=all|dirty requires dynamic-update=\"true\": " + name );
+		}
+		if ( versionPropertyIndex != NO_VERSION_INDX && optimisticLockMode > Versioning.OPTIMISTIC_LOCK_VERSION ) {
+			throw new MappingException( "version and optimistic-lock=all|dirty are not a valid combination : " + name );
+		}
+
+		hasCollections = foundCollection;
+		hasMutableProperties = foundMutable;
+
+		iter = persistentClass.getSubclassIterator();
+		while ( iter.hasNext() ) {
+			subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
+		}
+		subclassEntityNames.add( name );
+
+		tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
+	}
+
+	private ValueInclusion determineInsertValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
+		if ( runtimeProperty.isInsertGenerated() ) {
+			return ValueInclusion.FULL;
+		}
+		else if ( mappingProperty.getValue() instanceof Component ) {
+			if ( hasPartialInsertComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
+				return ValueInclusion.PARTIAL;
+			}
+		}
+		return ValueInclusion.NONE;
+	}
+
+	private boolean hasPartialInsertComponentGeneration(Component component) {
+		Iterator subProperties = component.getPropertyIterator();
+		while ( subProperties.hasNext() ) {
+			Property prop = ( Property ) subProperties.next();
+			if ( prop.getGeneration() == PropertyGeneration.ALWAYS || prop.getGeneration() == PropertyGeneration.INSERT ) {
+				return true;
+			}
+			else if ( prop.getValue() instanceof Component ) {
+				if ( hasPartialInsertComponentGeneration( ( Component ) prop.getValue() ) ) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private ValueInclusion determineUpdateValueGenerationType(Property mappingProperty, StandardProperty runtimeProperty) {
+		if ( runtimeProperty.isUpdateGenerated() ) {
+			return ValueInclusion.FULL;
+		}
+		else if ( mappingProperty.getValue() instanceof Component ) {
+			if ( hasPartialUpdateComponentGeneration( ( Component ) mappingProperty.getValue() ) ) {
+				return ValueInclusion.PARTIAL;
+			}
+		}
+		return ValueInclusion.NONE;
+	}
+
+	private boolean hasPartialUpdateComponentGeneration(Component component) {
+		Iterator subProperties = component.getPropertyIterator();
+		while ( subProperties.hasNext() ) {
+			Property prop = ( Property ) subProperties.next();
+			if ( prop.getGeneration() == PropertyGeneration.ALWAYS ) {
+				return true;
+			}
+			else if ( prop.getValue() instanceof Component ) {
+				if ( hasPartialUpdateComponentGeneration( ( Component ) prop.getValue() ) ) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	private void mapPropertyToIndex(Property prop, int i) {
+		propertyIndexes.put( prop.getName(), new Integer(i) );
+		if ( prop.getValue() instanceof Component ) {
+			Iterator iter = ( (Component) prop.getValue() ).getPropertyIterator();
+			while ( iter.hasNext() ) {
+				Property subprop = (Property) iter.next();
+				propertyIndexes.put(
+						prop.getName() + '.' + subprop.getName(),
+						new Integer(i)
+					);
+			}
+		}
+	}
+
+	public int[] getNaturalIdentifierProperties() {
+		return naturalIdPropertyNumbers;
+	}
+
+	public boolean hasNaturalIdentifier() {
+		return naturalIdPropertyNumbers!=null;
+	}
+
+	public boolean hasImmutableNaturalId() {
+		return hasImmutableNaturalId;
+	}
+
+	public Set getSubclassEntityNames() {
+		return subclassEntityNames;
+	}
+
+	private boolean indicatesCollection(Type type) {
+		if ( type.isCollectionType() ) {
+			return true;
+		}
+		else if ( type.isComponentType() ) {
+			Type[] subtypes = ( ( AbstractComponentType ) type ).getSubtypes();
+			for ( int i = 0; i < subtypes.length; i++ ) {
+				if ( indicatesCollection( subtypes[i] ) ) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+	public SessionFactoryImplementor getSessionFactory() {
+		return sessionFactory;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getRootName() {
+		return rootName;
+	}
+
+	public EntityType getEntityType() {
+		return entityType;
+	}
+
+	public IdentifierProperty getIdentifierProperty() {
+		return identifierProperty;
+	}
+
+	public int getPropertySpan() {
+		return propertySpan;
+	}
+
+	public int getVersionPropertyIndex() {
+		return versionPropertyIndex;
+	}
+
+	public VersionProperty getVersionProperty() {
+		if ( NO_VERSION_INDX == versionPropertyIndex ) {
+			return null;
+		}
+		else {
+			return ( VersionProperty ) properties[ versionPropertyIndex ];
+		}
+	}
+
+	public StandardProperty[] getProperties() {
+		return properties;
+	}
+
+	public int getPropertyIndex(String propertyName) {
+		Integer index = getPropertyIndexOrNull(propertyName);
+		if ( index == null ) {
+			throw new HibernateException("Unable to resolve property: " + propertyName);
+		}
+		return index.intValue();
+	}
+
+	public Integer getPropertyIndexOrNull(String propertyName) {
+		return (Integer) propertyIndexes.get( propertyName );
+	}
+
+	public boolean hasCollections() {
+		return hasCollections;
+	}
+
+	public boolean hasMutableProperties() {
+		return hasMutableProperties;
+	}
+
+	public boolean hasNonIdentifierPropertyNamedId() {
+		return hasNonIdentifierPropertyNamedId;
+	}
+
+	public boolean hasLazyProperties() {
+		return hasLazyProperties;
+	}
+
+	public boolean hasCascades() {
+		return hasCascades;
+	}
+
+	public boolean isMutable() {
+		return mutable;
+	}
+
+	public boolean isSelectBeforeUpdate() {
+		return selectBeforeUpdate;
+	}
+
+	public boolean isDynamicUpdate() {
+		return dynamicUpdate;
+	}
+
+	public boolean isDynamicInsert() {
+		return dynamicInsert;
+	}
+
+	public int getOptimisticLockMode() {
+		return optimisticLockMode;
+	}
+
+	public boolean isPolymorphic() {
+		return polymorphic;
+	}
+
+	public String getSuperclass() {
+		return superclass;
+	}
+
+	public boolean isExplicitPolymorphism() {
+		return explicitPolymorphism;
+	}
+
+	public boolean isInherited() {
+		return inherited;
+	}
+
+	public boolean hasSubclasses() {
+		return hasSubclasses;
+	}
+
+	public boolean isLazy() {
+		return lazy;
+	}
+
+	public void setLazy(boolean lazy) {
+		this.lazy = lazy;
+	}
+
+	public boolean isVersioned() {
+		return versioned;
+	}
+
+	public boolean isAbstract() {
+		return isAbstract;
+	}
+
+	public String toString() {
+		return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
+	}
+
+	// temporary ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	public String[] getPropertyNames() {
+		return propertyNames;
+	}
+
+	public Type[] getPropertyTypes() {
+		return propertyTypes;
+	}
+
+	public boolean[] getPropertyLaziness() {
+		return propertyLaziness;
+	}
+
+	public boolean[] getPropertyUpdateability() {
+		return propertyUpdateability;
+	}
+
+	public boolean[] getPropertyCheckability() {
+		return propertyCheckability;
+	}
+
+	public boolean[] getNonlazyPropertyUpdateability() {
+		return nonlazyPropertyUpdateability;
+	}
+
+	public boolean[] getPropertyInsertability() {
+		return propertyInsertability;
+	}
+
+	public ValueInclusion[] getPropertyInsertGenerationInclusions() {
+		return insertInclusions;
+	}
+
+	public ValueInclusion[] getPropertyUpdateGenerationInclusions() {
+		return updateInclusions;
+	}
+
+	public boolean[] getPropertyNullability() {
+		return propertyNullability;
+	}
+
+	public boolean[] getPropertyVersionability() {
+		return propertyVersionability;
+	}
+
+	public CascadeStyle[] getCascadeStyles() {
+		return cascadeStyles;
+	}
+
+	public boolean hasInsertGeneratedValues() {
+		return hasInsertGeneratedValues;
+	}
+
+	public boolean hasUpdateGeneratedValues() {
+		return hasUpdateGeneratedValues;
+	}
+
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,178 +0,0 @@
-//$Id: EntityTuplizer.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.tuple.entity;
-
-import java.io.Serializable;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.tuple.Tuplizer;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Defines further responsibilities reagarding tuplization based on
- * a mapped entity.
- * <p/>
- * EntityTuplizer implementations should have the following constructor signature:
- *      (org.hibernate.tuple.entity.EntityMetamodel, org.hibernate.mapping.PersistentClass)
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public interface EntityTuplizer extends Tuplizer {
-
-    /**
-     * Create an entity instance initialized with the given identifier.
-     *
-     * @param id The identifier value for the entity to be instantiated.
-     * @return The instantiated entity.
-     * @throws HibernateException
-     */
-	public Object instantiate(Serializable id) throws HibernateException;
-
-    /**
-     * Extract the identifier value from the given entity.
-     *
-     * @param entity The entity from which to extract the identifier value.
-     * @return The identifier value.
-     * @throws HibernateException If the entity does not define an identifier property, or an
-     * error occurrs accessing its value.
-     */
-	public Serializable getIdentifier(Object entity) throws HibernateException;
-
-    /**
-     * Inject the identifier value into the given entity.
-     * </p>
-     * Has no effect if the entity does not define an identifier property
-     *
-     * @param entity The entity to inject with the identifier value.
-     * @param id The value to be injected as the identifier.
-     * @throws HibernateException
-     */
-	public void setIdentifier(Object entity, Serializable id) throws HibernateException;
-
-	/**
-	 * Inject the given identifier and version into the entity, in order to
-	 * "roll back" to their original values.
-	 *
-	 * @param currentId The identifier value to inject into the entity.
-	 * @param currentVersion The version value to inject into the entity.
-	 */
-	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion);
-
-    /**
-     * Extract the value of the version property from the given entity.
-     *
-     * @param entity The entity from which to extract the version value.
-     * @return The value of the version property, or null if not versioned.
-     * @throws HibernateException
-     */
-	public Object getVersion(Object entity) throws HibernateException;
-
-	/**
-	 * Inject the value of a particular property.
-	 *
-	 * @param entity The entity into which to inject the value.
-	 * @param i The property's index.
-	 * @param value The property value to inject.
-	 * @throws HibernateException
-	 */
-	public void setPropertyValue(Object entity, int i, Object value) throws HibernateException;
-
-	/**
-	 * Inject the value of a particular property.
-	 *
-	 * @param entity The entity into which to inject the value.
-	 * @param propertyName The name of the property.
-	 * @param value The property value to inject.
-	 * @throws HibernateException
-	 */
-	public void setPropertyValue(Object entity, String propertyName, Object value) throws HibernateException;
-
-	/**
-	 * Extract the values of the insertable properties of the entity (including backrefs)
-	 *
-	 * @param entity The entity from which to extract.
-	 * @param mergeMap a map of instances being merged to merged instances
-	 * @param session The session in which the resuest is being made.
-	 * @return The insertable property values.
-	 * @throws HibernateException
-	 */
-	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Extract the value of a particular property from the given entity.
-	 *
-	 * @param entity The entity from which to extract the property value.
-	 * @param propertyName The name of the property for which to extract the value.
-	 * @return The current value of the given property on the given entity.
-	 * @throws HibernateException
-	 */
-	public Object getPropertyValue(Object entity, String propertyName) throws HibernateException;
-
-    /**
-     * Called just after the entities properties have been initialized.
-     *
-     * @param entity The entity being initialized.
-     * @param lazyPropertiesAreUnfetched Are defined lazy properties currently unfecthed
-     * @param session The session initializing this entity.
-     */
-	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
-
-	/**
-	 * Does this entity, for this mode, present a possibility for proxying?
-	 *
-	 * @return True if this tuplizer can generate proxies for this entity.
-	 */
-	public boolean hasProxy();
-
-	/**
-	 * Generates an appropriate proxy representation of this entity for this
-	 * entity-mode.
-	 *
-	 * @param id The id of the instance for which to generate a proxy.
-	 * @param session The session to which the proxy should be bound.
-	 * @return The generate proxies.
-	 * @throws HibernateException Indicates an error generating the proxy.
-	 */
-	public Object createProxy(Serializable id, SessionImplementor session) throws HibernateException;
-
-	/**
-	 * Does the {@link #getMappedClass() class} managed by this tuplizer implement
-	 * the {@link org.hibernate.classic.Lifecycle} interface.
-	 *
-	 * @return True if the Lifecycle interface is implemented; false otherwise.
-	 */
-	public boolean isLifecycleImplementor();
-
-	/**
-	 * Does the {@link #getMappedClass() class} managed by this tuplizer implement
-	 * the {@link org.hibernate.classic.Validatable} interface.
-	 *
-	 * @return True if the Validatable interface is implemented; false otherwise.
-	 */
-	public boolean isValidatableImplementor();
-
-	// TODO: getConcreteProxyClass() is solely used (externally) to perform narrowProxy()
-	// would be great to fully encapsulate that narrowProxy() functionality within the
-	// Tuplizer, itself, with a Tuplizer.narrowProxy(..., PersistentContext) method
-	/**
-	 * Returns the java class to which generated proxies will be typed.
-	 *
-	 * @return The java class to which generated proxies will be typed
-	 */
-	public Class getConcreteProxyClass();
-	
-    /**
-     * Does the given entity instance have any currently uninitialized lazy properties?
-     *
-     * @param entity The entity to be check for uninitialized lazy properties.
-     * @return True if uninitialized lazy properties were found; false otherwise.
-     */
-	public boolean hasUninitializedLazyProperties(Object entity);
-	
-	/**
-	 * Is it an instrumented POJO?
-	 */
-	public boolean isInstrumented();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/EntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,201 @@
+/*
+ * 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.tuple.entity;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.tuple.Tuplizer;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Defines further responsibilities reagarding tuplization based on
+ * a mapped entity.
+ * <p/>
+ * EntityTuplizer implementations should have the following constructor signature:
+ *      (org.hibernate.tuple.entity.EntityMetamodel, org.hibernate.mapping.PersistentClass)
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public interface EntityTuplizer extends Tuplizer {
+
+    /**
+     * Create an entity instance initialized with the given identifier.
+     *
+     * @param id The identifier value for the entity to be instantiated.
+     * @return The instantiated entity.
+     * @throws HibernateException
+     */
+	public Object instantiate(Serializable id) throws HibernateException;
+
+    /**
+     * Extract the identifier value from the given entity.
+     *
+     * @param entity The entity from which to extract the identifier value.
+     * @return The identifier value.
+     * @throws HibernateException If the entity does not define an identifier property, or an
+     * error occurrs accessing its value.
+     */
+	public Serializable getIdentifier(Object entity) throws HibernateException;
+
+    /**
+     * Inject the identifier value into the given entity.
+     * </p>
+     * Has no effect if the entity does not define an identifier property
+     *
+     * @param entity The entity to inject with the identifier value.
+     * @param id The value to be injected as the identifier.
+     * @throws HibernateException
+     */
+	public void setIdentifier(Object entity, Serializable id) throws HibernateException;
+
+	/**
+	 * Inject the given identifier and version into the entity, in order to
+	 * "roll back" to their original values.
+	 *
+	 * @param currentId The identifier value to inject into the entity.
+	 * @param currentVersion The version value to inject into the entity.
+	 */
+	public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion);
+
+    /**
+     * Extract the value of the version property from the given entity.
+     *
+     * @param entity The entity from which to extract the version value.
+     * @return The value of the version property, or null if not versioned.
+     * @throws HibernateException
+     */
+	public Object getVersion(Object entity) throws HibernateException;
+
+	/**
+	 * Inject the value of a particular property.
+	 *
+	 * @param entity The entity into which to inject the value.
+	 * @param i The property's index.
+	 * @param value The property value to inject.
+	 * @throws HibernateException
+	 */
+	public void setPropertyValue(Object entity, int i, Object value) throws HibernateException;
+
+	/**
+	 * Inject the value of a particular property.
+	 *
+	 * @param entity The entity into which to inject the value.
+	 * @param propertyName The name of the property.
+	 * @param value The property value to inject.
+	 * @throws HibernateException
+	 */
+	public void setPropertyValue(Object entity, String propertyName, Object value) throws HibernateException;
+
+	/**
+	 * Extract the values of the insertable properties of the entity (including backrefs)
+	 *
+	 * @param entity The entity from which to extract.
+	 * @param mergeMap a map of instances being merged to merged instances
+	 * @param session The session in which the resuest is being made.
+	 * @return The insertable property values.
+	 * @throws HibernateException
+	 */
+	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Extract the value of a particular property from the given entity.
+	 *
+	 * @param entity The entity from which to extract the property value.
+	 * @param propertyName The name of the property for which to extract the value.
+	 * @return The current value of the given property on the given entity.
+	 * @throws HibernateException
+	 */
+	public Object getPropertyValue(Object entity, String propertyName) throws HibernateException;
+
+    /**
+     * Called just after the entities properties have been initialized.
+     *
+     * @param entity The entity being initialized.
+     * @param lazyPropertiesAreUnfetched Are defined lazy properties currently unfecthed
+     * @param session The session initializing this entity.
+     */
+	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session);
+
+	/**
+	 * Does this entity, for this mode, present a possibility for proxying?
+	 *
+	 * @return True if this tuplizer can generate proxies for this entity.
+	 */
+	public boolean hasProxy();
+
+	/**
+	 * Generates an appropriate proxy representation of this entity for this
+	 * entity-mode.
+	 *
+	 * @param id The id of the instance for which to generate a proxy.
+	 * @param session The session to which the proxy should be bound.
+	 * @return The generate proxies.
+	 * @throws HibernateException Indicates an error generating the proxy.
+	 */
+	public Object createProxy(Serializable id, SessionImplementor session) throws HibernateException;
+
+	/**
+	 * Does the {@link #getMappedClass() class} managed by this tuplizer implement
+	 * the {@link org.hibernate.classic.Lifecycle} interface.
+	 *
+	 * @return True if the Lifecycle interface is implemented; false otherwise.
+	 */
+	public boolean isLifecycleImplementor();
+
+	/**
+	 * Does the {@link #getMappedClass() class} managed by this tuplizer implement
+	 * the {@link org.hibernate.classic.Validatable} interface.
+	 *
+	 * @return True if the Validatable interface is implemented; false otherwise.
+	 */
+	public boolean isValidatableImplementor();
+
+	// TODO: getConcreteProxyClass() is solely used (externally) to perform narrowProxy()
+	// would be great to fully encapsulate that narrowProxy() functionality within the
+	// Tuplizer, itself, with a Tuplizer.narrowProxy(..., PersistentContext) method
+	/**
+	 * Returns the java class to which generated proxies will be typed.
+	 *
+	 * @return The java class to which generated proxies will be typed
+	 */
+	public Class getConcreteProxyClass();
+	
+    /**
+     * Does the given entity instance have any currently uninitialized lazy properties?
+     *
+     * @param entity The entity to be check for uninitialized lazy properties.
+     * @return True if uninitialized lazy properties were found; false otherwise.
+     */
+	public boolean hasUninitializedLazyProperties(Object entity);
+	
+	/**
+	 * Is it an instrumented POJO?
+	 */
+	public boolean isInstrumented();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,284 +0,0 @@
-// $Id: PojoEntityTuplizer.java 9210 2006-02-03 22:15:19Z steveebersole $
-package org.hibernate.tuple.entity;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.tuple.entity.AbstractEntityTuplizer;
-import org.hibernate.tuple.entity.EntityMetamodel;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.PojoInstantiator;
-import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.cfg.Environment;
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.classic.Validatable;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.intercept.FieldInterceptor;
-import org.hibernate.intercept.FieldInterceptionHelper;
-import org.hibernate.mapping.PersistentClass;
-import org.hibernate.mapping.Property;
-import org.hibernate.mapping.Subclass;
-import org.hibernate.property.Getter;
-import org.hibernate.property.Setter;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.ProxyFactory;
-import org.hibernate.type.AbstractComponentType;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * An {@link EntityTuplizer} specific to the pojo entity mode.
- *
- * @author Steve Ebersole
- * @author Gavin King
- */
-public class PojoEntityTuplizer extends AbstractEntityTuplizer {
-
-	static final Logger log = LoggerFactory.getLogger( PojoEntityTuplizer.class );
-
-	private final Class mappedClass;
-	private final Class proxyInterface;
-	private final boolean lifecycleImplementor;
-	private final boolean validatableImplementor;
-	private final Set lazyPropertyNames = new HashSet();
-	private ReflectionOptimizer optimizer;
-
-	public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
-		super( entityMetamodel, mappedEntity );
-		this.mappedClass = mappedEntity.getMappedClass();
-		this.proxyInterface = mappedEntity.getProxyInterface();
-		this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass );
-		this.validatableImplementor = Validatable.class.isAssignableFrom( mappedClass );
-
-		Iterator iter = mappedEntity.getPropertyClosureIterator();
-		while ( iter.hasNext() ) {
-			Property property = (Property) iter.next();
-			if ( property.isLazy() ) {
-				lazyPropertyNames.add( property.getName() );
-			}
-		}
-
-		String[] getterNames = new String[propertySpan];
-		String[] setterNames = new String[propertySpan];
-		Class[] propTypes = new Class[propertySpan];
-		for ( int i = 0; i < propertySpan; i++ ) {
-			getterNames[i] = getters[i].getMethodName();
-			setterNames[i] = setters[i].getMethodName();
-			propTypes[i] = getters[i].getReturnType();
-		}
-
-		if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
-			optimizer = null;
-		}
-		else {
-			// todo : YUCK!!!
-			optimizer = Environment.getBytecodeProvider().getReflectionOptimizer( mappedClass, getterNames, setterNames, propTypes );
-//			optimizer = getFactory().getSettings().getBytecodeProvider().getReflectionOptimizer(
-//					mappedClass, getterNames, setterNames, propTypes
-//			);
-		}
-	
-	}
-
-	protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
-		// determine the id getter and setter methods from the proxy interface (if any)
-        // determine all interfaces needed by the resulting proxy
-		HashSet proxyInterfaces = new HashSet();
-		proxyInterfaces.add( HibernateProxy.class );
-		
-		Class mappedClass = persistentClass.getMappedClass();
-		Class proxyInterface = persistentClass.getProxyInterface();
-
-		if ( proxyInterface!=null && !mappedClass.equals( proxyInterface ) ) {
-			if ( !proxyInterface.isInterface() ) {
-				throw new MappingException(
-				        "proxy must be either an interface, or the class itself: " + 
-				        getEntityName()
-					);
-			}
-			proxyInterfaces.add( proxyInterface );
-		}
-
-		if ( mappedClass.isInterface() ) {
-			proxyInterfaces.add( mappedClass );
-		}
-
-		Iterator iter = persistentClass.getSubclassIterator();
-		while ( iter.hasNext() ) {
-			Subclass subclass = ( Subclass ) iter.next();
-			Class subclassProxy = subclass.getProxyInterface();
-			Class subclassClass = subclass.getMappedClass();
-			if ( subclassProxy!=null && !subclassClass.equals( subclassProxy ) ) {
-				if ( !proxyInterface.isInterface() ) {
-					throw new MappingException(
-					        "proxy must be either an interface, or the class itself: " + 
-					        subclass.getEntityName()
-					);
-				}
-				proxyInterfaces.add( subclassProxy );
-			}
-		}
-
-		Iterator properties = persistentClass.getPropertyIterator();
-		Class clazz = persistentClass.getMappedClass();
-		while ( properties.hasNext() ) {
-			Property property = (Property) properties.next();
-			Method method = property.getGetter(clazz).getMethod();
-			if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
-				log.error(
-						"Getters of lazy classes cannot be final: " + persistentClass.getEntityName() + 
-						"." + property.getName() 
-					);
-			}
-			method = property.getSetter(clazz).getMethod();
-            if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
-				log.error(
-						"Setters of lazy classes cannot be final: " + persistentClass.getEntityName() + 
-						"." + property.getName() 
-					);
-			}
-		}
-
-		Method idGetterMethod = idGetter==null ? null : idGetter.getMethod();
-		Method idSetterMethod = idSetter==null ? null : idSetter.getMethod();
-
-		Method proxyGetIdentifierMethod = idGetterMethod==null || proxyInterface==null ? 
-				null :
-		        ReflectHelper.getMethod(proxyInterface, idGetterMethod);
-		Method proxySetIdentifierMethod = idSetterMethod==null || proxyInterface==null  ? 
-				null :
-		        ReflectHelper.getMethod(proxyInterface, idSetterMethod);
-
-		ProxyFactory pf = buildProxyFactoryInternal( persistentClass, idGetter, idSetter );
-		try {
-			pf.postInstantiate(
-					getEntityName(),
-					mappedClass,
-					proxyInterfaces,
-					proxyGetIdentifierMethod,
-					proxySetIdentifierMethod,
-					persistentClass.hasEmbeddedIdentifier() ?
-			                (AbstractComponentType) persistentClass.getIdentifier().getType() :
-			                null
-			);
-		}
-		catch ( HibernateException he ) {
-			log.warn( "could not create proxy factory for:" + getEntityName(), he );
-			pf = null;
-		}
-		return pf;
-	}
-
-	protected ProxyFactory buildProxyFactoryInternal(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
-		// TODO : YUCK!!!  finx after HHH-1907 is complete
-		return Environment.getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
-//		return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
-	}
-
-	protected Instantiator buildInstantiator(PersistentClass persistentClass) {
-		if ( optimizer == null ) {
-			return new PojoInstantiator( persistentClass, null );
-		}
-		else {
-			return new PojoInstantiator( persistentClass, optimizer.getInstantiationOptimizer() );
-		}
-	}
-
-	public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
-		if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
-			setPropertyValuesWithOptimizer( entity, values );
-		}
-		else {
-			super.setPropertyValues( entity, values );
-		}
-	}
-
-	public Object[] getPropertyValues(Object entity) throws HibernateException {
-		if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
-			return getPropertyValuesWithOptimizer( entity );
-		}
-		else {
-			return super.getPropertyValues( entity );
-		}
-	}
-
-	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException {
-		if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
-			return getPropertyValuesWithOptimizer( entity );
-		}
-		else {
-			return super.getPropertyValuesToInsert( entity, mergeMap, session );
-		}
-	}
-
-	protected void setPropertyValuesWithOptimizer(Object object, Object[] values) {
-		optimizer.getAccessOptimizer().setPropertyValues( object, values );
-	}
-
-	protected Object[] getPropertyValuesWithOptimizer(Object object) {
-		return optimizer.getAccessOptimizer().getPropertyValues( object );
-	}
-
-	public EntityMode getEntityMode() {
-		return EntityMode.POJO;
-	}
-
-	public Class getMappedClass() {
-		return mappedClass;
-	}
-
-	public boolean isLifecycleImplementor() {
-		return lifecycleImplementor;
-	}
-
-	public boolean isValidatableImplementor() {
-		return validatableImplementor;
-	}
-
-	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return mappedProperty.getGetter( mappedEntity.getMappedClass() );
-	}
-
-	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
-		return mappedProperty.getSetter( mappedEntity.getMappedClass() );
-	}
-
-	public Class getConcreteProxyClass() {
-		return proxyInterface;
-	}
-
-    //TODO: need to make the majority of this functionality into a top-level support class for custom impl support
-
-	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
-		if ( isInstrumented() ) {
-			Set lazyProps = lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ?
-					lazyPropertyNames : null;
-			//TODO: if we support multiple fetch groups, we would need
-			//      to clone the set of lazy properties!
-			FieldInterceptionHelper.injectFieldInterceptor( entity, getEntityName(), lazyProps, session );
-		}
-	}
-
-	public boolean hasUninitializedLazyProperties(Object entity) {
-		if ( getEntityMetamodel().hasLazyProperties() ) {
-			FieldInterceptor callback = FieldInterceptionHelper.extractFieldInterceptor( entity );
-			return callback != null && !callback.isInitialized();
-		}
-		else {
-			return false;
-		}
-	}
-
-	public boolean isInstrumented() {
-		return FieldInterceptionHelper.isInstrumented( getMappedClass() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/entity/PojoEntityTuplizer.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,305 @@
+/*
+ * 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.tuple.entity;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.PojoInstantiator;
+import org.hibernate.bytecode.ReflectionOptimizer;
+import org.hibernate.cfg.Environment;
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.classic.Validatable;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.intercept.FieldInterceptor;
+import org.hibernate.intercept.FieldInterceptionHelper;
+import org.hibernate.mapping.PersistentClass;
+import org.hibernate.mapping.Property;
+import org.hibernate.mapping.Subclass;
+import org.hibernate.property.Getter;
+import org.hibernate.property.Setter;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.ProxyFactory;
+import org.hibernate.type.AbstractComponentType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * An {@link EntityTuplizer} specific to the pojo entity mode.
+ *
+ * @author Steve Ebersole
+ * @author Gavin King
+ */
+public class PojoEntityTuplizer extends AbstractEntityTuplizer {
+
+	static final Logger log = LoggerFactory.getLogger( PojoEntityTuplizer.class );
+
+	private final Class mappedClass;
+	private final Class proxyInterface;
+	private final boolean lifecycleImplementor;
+	private final boolean validatableImplementor;
+	private final Set lazyPropertyNames = new HashSet();
+	private ReflectionOptimizer optimizer;
+
+	public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
+		super( entityMetamodel, mappedEntity );
+		this.mappedClass = mappedEntity.getMappedClass();
+		this.proxyInterface = mappedEntity.getProxyInterface();
+		this.lifecycleImplementor = Lifecycle.class.isAssignableFrom( mappedClass );
+		this.validatableImplementor = Validatable.class.isAssignableFrom( mappedClass );
+
+		Iterator iter = mappedEntity.getPropertyClosureIterator();
+		while ( iter.hasNext() ) {
+			Property property = (Property) iter.next();
+			if ( property.isLazy() ) {
+				lazyPropertyNames.add( property.getName() );
+			}
+		}
+
+		String[] getterNames = new String[propertySpan];
+		String[] setterNames = new String[propertySpan];
+		Class[] propTypes = new Class[propertySpan];
+		for ( int i = 0; i < propertySpan; i++ ) {
+			getterNames[i] = getters[i].getMethodName();
+			setterNames[i] = setters[i].getMethodName();
+			propTypes[i] = getters[i].getReturnType();
+		}
+
+		if ( hasCustomAccessors || !Environment.useReflectionOptimizer() ) {
+			optimizer = null;
+		}
+		else {
+			// todo : YUCK!!!
+			optimizer = Environment.getBytecodeProvider().getReflectionOptimizer( mappedClass, getterNames, setterNames, propTypes );
+//			optimizer = getFactory().getSettings().getBytecodeProvider().getReflectionOptimizer(
+//					mappedClass, getterNames, setterNames, propTypes
+//			);
+		}
+	
+	}
+
+	protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
+		// determine the id getter and setter methods from the proxy interface (if any)
+        // determine all interfaces needed by the resulting proxy
+		HashSet proxyInterfaces = new HashSet();
+		proxyInterfaces.add( HibernateProxy.class );
+		
+		Class mappedClass = persistentClass.getMappedClass();
+		Class proxyInterface = persistentClass.getProxyInterface();
+
+		if ( proxyInterface!=null && !mappedClass.equals( proxyInterface ) ) {
+			if ( !proxyInterface.isInterface() ) {
+				throw new MappingException(
+				        "proxy must be either an interface, or the class itself: " + 
+				        getEntityName()
+					);
+			}
+			proxyInterfaces.add( proxyInterface );
+		}
+
+		if ( mappedClass.isInterface() ) {
+			proxyInterfaces.add( mappedClass );
+		}
+
+		Iterator iter = persistentClass.getSubclassIterator();
+		while ( iter.hasNext() ) {
+			Subclass subclass = ( Subclass ) iter.next();
+			Class subclassProxy = subclass.getProxyInterface();
+			Class subclassClass = subclass.getMappedClass();
+			if ( subclassProxy!=null && !subclassClass.equals( subclassProxy ) ) {
+				if ( !proxyInterface.isInterface() ) {
+					throw new MappingException(
+					        "proxy must be either an interface, or the class itself: " + 
+					        subclass.getEntityName()
+					);
+				}
+				proxyInterfaces.add( subclassProxy );
+			}
+		}
+
+		Iterator properties = persistentClass.getPropertyIterator();
+		Class clazz = persistentClass.getMappedClass();
+		while ( properties.hasNext() ) {
+			Property property = (Property) properties.next();
+			Method method = property.getGetter(clazz).getMethod();
+			if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
+				log.error(
+						"Getters of lazy classes cannot be final: " + persistentClass.getEntityName() + 
+						"." + property.getName() 
+					);
+			}
+			method = property.getSetter(clazz).getMethod();
+            if ( method != null && Modifier.isFinal( method.getModifiers() ) ) {
+				log.error(
+						"Setters of lazy classes cannot be final: " + persistentClass.getEntityName() + 
+						"." + property.getName() 
+					);
+			}
+		}
+
+		Method idGetterMethod = idGetter==null ? null : idGetter.getMethod();
+		Method idSetterMethod = idSetter==null ? null : idSetter.getMethod();
+
+		Method proxyGetIdentifierMethod = idGetterMethod==null || proxyInterface==null ? 
+				null :
+		        ReflectHelper.getMethod(proxyInterface, idGetterMethod);
+		Method proxySetIdentifierMethod = idSetterMethod==null || proxyInterface==null  ? 
+				null :
+		        ReflectHelper.getMethod(proxyInterface, idSetterMethod);
+
+		ProxyFactory pf = buildProxyFactoryInternal( persistentClass, idGetter, idSetter );
+		try {
+			pf.postInstantiate(
+					getEntityName(),
+					mappedClass,
+					proxyInterfaces,
+					proxyGetIdentifierMethod,
+					proxySetIdentifierMethod,
+					persistentClass.hasEmbeddedIdentifier() ?
+			                (AbstractComponentType) persistentClass.getIdentifier().getType() :
+			                null
+			);
+		}
+		catch ( HibernateException he ) {
+			log.warn( "could not create proxy factory for:" + getEntityName(), he );
+			pf = null;
+		}
+		return pf;
+	}
+
+	protected ProxyFactory buildProxyFactoryInternal(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
+		// TODO : YUCK!!!  finx after HHH-1907 is complete
+		return Environment.getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
+//		return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
+	}
+
+	protected Instantiator buildInstantiator(PersistentClass persistentClass) {
+		if ( optimizer == null ) {
+			return new PojoInstantiator( persistentClass, null );
+		}
+		else {
+			return new PojoInstantiator( persistentClass, optimizer.getInstantiationOptimizer() );
+		}
+	}
+
+	public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
+		if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
+			setPropertyValuesWithOptimizer( entity, values );
+		}
+		else {
+			super.setPropertyValues( entity, values );
+		}
+	}
+
+	public Object[] getPropertyValues(Object entity) throws HibernateException {
+		if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
+			return getPropertyValuesWithOptimizer( entity );
+		}
+		else {
+			return super.getPropertyValues( entity );
+		}
+	}
+
+	public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException {
+		if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
+			return getPropertyValuesWithOptimizer( entity );
+		}
+		else {
+			return super.getPropertyValuesToInsert( entity, mergeMap, session );
+		}
+	}
+
+	protected void setPropertyValuesWithOptimizer(Object object, Object[] values) {
+		optimizer.getAccessOptimizer().setPropertyValues( object, values );
+	}
+
+	protected Object[] getPropertyValuesWithOptimizer(Object object) {
+		return optimizer.getAccessOptimizer().getPropertyValues( object );
+	}
+
+	public EntityMode getEntityMode() {
+		return EntityMode.POJO;
+	}
+
+	public Class getMappedClass() {
+		return mappedClass;
+	}
+
+	public boolean isLifecycleImplementor() {
+		return lifecycleImplementor;
+	}
+
+	public boolean isValidatableImplementor() {
+		return validatableImplementor;
+	}
+
+	protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return mappedProperty.getGetter( mappedEntity.getMappedClass() );
+	}
+
+	protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
+		return mappedProperty.getSetter( mappedEntity.getMappedClass() );
+	}
+
+	public Class getConcreteProxyClass() {
+		return proxyInterface;
+	}
+
+    //TODO: need to make the majority of this functionality into a top-level support class for custom impl support
+
+	public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
+		if ( isInstrumented() ) {
+			Set lazyProps = lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ?
+					lazyPropertyNames : null;
+			//TODO: if we support multiple fetch groups, we would need
+			//      to clone the set of lazy properties!
+			FieldInterceptionHelper.injectFieldInterceptor( entity, getEntityName(), lazyProps, session );
+		}
+	}
+
+	public boolean hasUninitializedLazyProperties(Object entity) {
+		if ( getEntityMetamodel().hasLazyProperties() ) {
+			FieldInterceptor callback = FieldInterceptionHelper.extractFieldInterceptor( entity );
+			return callback != null && !callback.isInitialized();
+		}
+		else {
+			return false;
+		}
+	}
+
+	public boolean isInstrumented() {
+		return FieldInterceptionHelper.isInstrumented( getMappedClass() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/tuple/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	This package defines a runtime metamodel for entities at
-	the object level and abstracts the differences between
-	the various entity modes. It is unaware of mappings to
-	the database. 
-</p>
-<p>
-    (This package is still undergoing maturation and will change 
-    over the next few months.)
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/tuple/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/tuple/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,40 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	This package defines a runtime metamodel for entities at
+	the object level and abstracts the differences between
+	the various entity modes. It is unaware of mappings to
+	the database. 
+</p>
+<p>
+    (This package is still undergoing maturation and will change 
+    over the next few months.)
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractBynaryType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,166 +0,0 @@
-//$Id: $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.ResultSet;
-import java.sql.Types;
-import java.io.ByteArrayInputStream;
-import java.io.InputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Comparator;
-
-import org.hibernate.HibernateException;
-import org.hibernate.EntityMode;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.cfg.Environment;
-
-/**
- * Logic to bind stream of byte into a VARBINARY
- *
- * @author Gavin King
- * @author Emmanuel Bernard
- */
-public abstract class AbstractBynaryType extends MutableType implements VersionType, Comparator {
-
-	/**
-	 * Convert the byte[] into the expected object type
-	 */
-	abstract protected Object toExternalFormat(byte[] bytes);
-
-	/**
-	 * Convert the object into the internal byte[] representation
-	 */
-	abstract protected byte[] toInternalFormat(Object bytes);
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		byte[] internalValue = toInternalFormat( value );
-		if ( Environment.useStreamsForBinary() ) {
-			st.setBinaryStream( index, new ByteArrayInputStream( internalValue ), internalValue.length );
-		}
-		else {
-			st.setBytes( index, internalValue );
-		}
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
-		if ( Environment.useStreamsForBinary() ) {
-
-			InputStream inputStream = rs.getBinaryStream(name);
-
-			if (inputStream==null) return toExternalFormat( null ); // is this really necessary?
-
-			ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048);
-			byte[] buffer = new byte[2048];
-
-			try {
-				while (true) {
-					int amountRead = inputStream.read(buffer);
-					if (amountRead == -1) {
-						break;
-					}
-					outputStream.write(buffer, 0, amountRead);
-				}
-
-				inputStream.close();
-				outputStream.close();
-			}
-			catch (IOException ioe) {
-				throw new HibernateException( "IOException occurred reading a binary value", ioe );
-			}
-
-			return toExternalFormat( outputStream.toByteArray() );
-
-		}
-		else {
-			return toExternalFormat( rs.getBytes(name) );
-		}
-	}
-
-	public int sqlType() {
-		return Types.VARBINARY;
-	}
-
-	// VersionType impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-	//      Note : simply returns null for seed() and next() as the only known
-	//      application of binary types for versioning is for use with the
-	//      TIMESTAMP datatype supported by Sybase and SQL Server, which
-	//      are completely db-generated values...
-	public Object seed(SessionImplementor session) {
-		return null;
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return current;
-	}
-
-	public Comparator getComparator() {
-		return this;
-	}
-
-	public int compare(Object o1, Object o2) {
-		return compare( o1, o2, null );
-	}
-	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-	public boolean isEqual(Object x, Object y) {
-		return x==y || ( x!=null && y!=null && java.util.Arrays.equals( toInternalFormat(x), toInternalFormat(y) ) );
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		byte[] bytes = toInternalFormat(x);
-		int hashCode = 1;
-		for ( int j=0; j<bytes.length; j++ ) {
-			hashCode = 31 * hashCode + bytes[j];
-		}
-		return hashCode;
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		byte[] xbytes = toInternalFormat(x);
-		byte[] ybytes = toInternalFormat(y);
-		if ( xbytes.length < ybytes.length ) return -1;
-		if ( xbytes.length > ybytes.length ) return 1;
-		for ( int i=0; i<xbytes.length; i++ ) {
-			if ( xbytes[i] < ybytes[i] ) return -1;
-			if ( xbytes[i] > ybytes[i] ) return 1;
-		}
-		return 0;
-	}
-
-	public abstract String getName();
-
-	public String toString(Object val) {
-		byte[] bytes = toInternalFormat(val);
-		StringBuffer buf = new StringBuffer();
-		for ( int i=0; i<bytes.length; i++ ) {
-			String hexStr = Integer.toHexString( bytes[i] - Byte.MIN_VALUE );
-			if ( hexStr.length()==1 ) buf.append('0');
-			buf.append(hexStr);
-		}
-		return buf.toString();
-	}
-
-	public Object deepCopyNotNull(Object value) {
-		byte[] bytes = toInternalFormat(value);
-		byte[] result = new byte[bytes.length];
-		System.arraycopy(bytes, 0, result, 0, bytes.length);
-		return toExternalFormat(result);
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		if (xml == null)
-			return null;
-		if (xml.length() % 2 != 0)
-			throw new IllegalArgumentException("The string is not a valid xml representation of a binary content.");
-		byte[] bytes = new byte[xml.length() / 2];
-		for (int i = 0; i < bytes.length; i++) {
-			String hexStr = xml.substring(i * 2, (i + 1) * 2);
-			bytes[i] = (byte) (Integer.parseInt(hexStr, 16) + Byte.MIN_VALUE);
-		}
-		return toExternalFormat(bytes);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AbstractBynaryType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractBynaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,189 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.sql.Types;
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Comparator;
+
+import org.hibernate.HibernateException;
+import org.hibernate.EntityMode;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.cfg.Environment;
+
+/**
+ * Logic to bind stream of byte into a VARBINARY
+ *
+ * @author Gavin King
+ * @author Emmanuel Bernard
+ */
+public abstract class AbstractBynaryType extends MutableType implements VersionType, Comparator {
+
+	/**
+	 * Convert the byte[] into the expected object type
+	 */
+	abstract protected Object toExternalFormat(byte[] bytes);
+
+	/**
+	 * Convert the object into the internal byte[] representation
+	 */
+	abstract protected byte[] toInternalFormat(Object bytes);
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		byte[] internalValue = toInternalFormat( value );
+		if ( Environment.useStreamsForBinary() ) {
+			st.setBinaryStream( index, new ByteArrayInputStream( internalValue ), internalValue.length );
+		}
+		else {
+			st.setBytes( index, internalValue );
+		}
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+		if ( Environment.useStreamsForBinary() ) {
+
+			InputStream inputStream = rs.getBinaryStream(name);
+
+			if (inputStream==null) return toExternalFormat( null ); // is this really necessary?
+
+			ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048);
+			byte[] buffer = new byte[2048];
+
+			try {
+				while (true) {
+					int amountRead = inputStream.read(buffer);
+					if (amountRead == -1) {
+						break;
+					}
+					outputStream.write(buffer, 0, amountRead);
+				}
+
+				inputStream.close();
+				outputStream.close();
+			}
+			catch (IOException ioe) {
+				throw new HibernateException( "IOException occurred reading a binary value", ioe );
+			}
+
+			return toExternalFormat( outputStream.toByteArray() );
+
+		}
+		else {
+			return toExternalFormat( rs.getBytes(name) );
+		}
+	}
+
+	public int sqlType() {
+		return Types.VARBINARY;
+	}
+
+	// VersionType impl ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	//      Note : simply returns null for seed() and next() as the only known
+	//      application of binary types for versioning is for use with the
+	//      TIMESTAMP datatype supported by Sybase and SQL Server, which
+	//      are completely db-generated values...
+	public Object seed(SessionImplementor session) {
+		return null;
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return current;
+	}
+
+	public Comparator getComparator() {
+		return this;
+	}
+
+	public int compare(Object o1, Object o2) {
+		return compare( o1, o2, null );
+	}
+	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+	public boolean isEqual(Object x, Object y) {
+		return x==y || ( x!=null && y!=null && java.util.Arrays.equals( toInternalFormat(x), toInternalFormat(y) ) );
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		byte[] bytes = toInternalFormat(x);
+		int hashCode = 1;
+		for ( int j=0; j<bytes.length; j++ ) {
+			hashCode = 31 * hashCode + bytes[j];
+		}
+		return hashCode;
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		byte[] xbytes = toInternalFormat(x);
+		byte[] ybytes = toInternalFormat(y);
+		if ( xbytes.length < ybytes.length ) return -1;
+		if ( xbytes.length > ybytes.length ) return 1;
+		for ( int i=0; i<xbytes.length; i++ ) {
+			if ( xbytes[i] < ybytes[i] ) return -1;
+			if ( xbytes[i] > ybytes[i] ) return 1;
+		}
+		return 0;
+	}
+
+	public abstract String getName();
+
+	public String toString(Object val) {
+		byte[] bytes = toInternalFormat(val);
+		StringBuffer buf = new StringBuffer();
+		for ( int i=0; i<bytes.length; i++ ) {
+			String hexStr = Integer.toHexString( bytes[i] - Byte.MIN_VALUE );
+			if ( hexStr.length()==1 ) buf.append('0');
+			buf.append(hexStr);
+		}
+		return buf.toString();
+	}
+
+	public Object deepCopyNotNull(Object value) {
+		byte[] bytes = toInternalFormat(value);
+		byte[] result = new byte[bytes.length];
+		System.arraycopy(bytes, 0, result, 0, bytes.length);
+		return toExternalFormat(result);
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		if (xml == null)
+			return null;
+		if (xml.length() % 2 != 0)
+			throw new IllegalArgumentException("The string is not a valid xml representation of a binary content.");
+		byte[] bytes = new byte[xml.length() / 2];
+		for (int i = 0; i < bytes.length; i++) {
+			String hexStr = xml.substring(i * 2, (i + 1) * 2);
+			bytes[i] = (byte) (Integer.parseInt(hexStr, 16) + Byte.MIN_VALUE);
+		}
+		return toExternalFormat(bytes);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,96 +0,0 @@
-//$Id: $
-package org.hibernate.type;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.PreparedStatement;
-import java.sql.Types;
-import java.io.Reader;
-import java.io.CharArrayWriter;
-import java.io.IOException;
-import java.io.CharArrayReader;
-
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * Logic to bind stream of char into a VARCHAR
- *
- * @author Emmanuel Bernard
- */
-public abstract class AbstractCharArrayType extends MutableType {
-
-	/**
-	 * Convert the char[] into the expected object type
-	 */
-	abstract protected Object toExternalFormat(char[] chars);
-
-	/**
-	 * Convert the object into the internal char[] representation
-	 */
-	abstract protected char[] toInternalFormat(Object chars);
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		Reader stream = rs.getCharacterStream(name);
-		if ( stream == null ) return toExternalFormat( null );
-		CharArrayWriter writer = new CharArrayWriter();
-		for(;;) {
-			try {
-				int c = stream.read();
-				if ( c == -1) return toExternalFormat( writer.toCharArray() );
-				writer.write( c );
-			}
-			catch (IOException e) {
-				throw new HibernateException("Unable to read character stream from rs");
-			}
-		}
-	}
-
-	public abstract Class getReturnedClass();
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		char[] chars = toInternalFormat( value );
-		st.setCharacterStream(index, new CharArrayReader(chars), chars.length);
-	}
-
-	public int sqlType() {
-		return Types.VARCHAR;
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-
-		return '\'' + new String( toInternalFormat( value ) ) + '\'';
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		if (xml == null) return toExternalFormat( null );
-		int length = xml.length();
-		char[] chars = new char[length];
-		for (int index = 0 ; index < length ; index++ ) {
-			chars[index] = xml.charAt( index );
-		}
-		return toExternalFormat( chars );
-	}
-
-	public String toString(Object value) {
-		if (value == null) return null;
-		return new String( toInternalFormat( value ) );
-	}
-
-	public Object fromStringValue(String xml) {
-		if (xml == null) return null;
-		int length = xml.length();
-		char[] chars = new char[length];
-		for (int index = 0 ; index < length ; index++ ) {
-			chars[index] = xml.charAt( index );
-		}
-		return toExternalFormat( chars );
-	}
-
-	protected Object deepCopyNotNull(Object value) throws HibernateException {
-		char[] chars = toInternalFormat(value);
-		char[] result = new char[chars.length];
-		System.arraycopy(chars, 0, result, 0, chars.length);
-		return toExternalFormat(result);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractCharArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,119 @@
+/*
+ * 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.type;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.PreparedStatement;
+import java.sql.Types;
+import java.io.Reader;
+import java.io.CharArrayWriter;
+import java.io.IOException;
+import java.io.CharArrayReader;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * Logic to bind stream of char into a VARCHAR
+ *
+ * @author Emmanuel Bernard
+ */
+public abstract class AbstractCharArrayType extends MutableType {
+
+	/**
+	 * Convert the char[] into the expected object type
+	 */
+	abstract protected Object toExternalFormat(char[] chars);
+
+	/**
+	 * Convert the object into the internal char[] representation
+	 */
+	abstract protected char[] toInternalFormat(Object chars);
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		Reader stream = rs.getCharacterStream(name);
+		if ( stream == null ) return toExternalFormat( null );
+		CharArrayWriter writer = new CharArrayWriter();
+		for(;;) {
+			try {
+				int c = stream.read();
+				if ( c == -1) return toExternalFormat( writer.toCharArray() );
+				writer.write( c );
+			}
+			catch (IOException e) {
+				throw new HibernateException("Unable to read character stream from rs");
+			}
+		}
+	}
+
+	public abstract Class getReturnedClass();
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		char[] chars = toInternalFormat( value );
+		st.setCharacterStream(index, new CharArrayReader(chars), chars.length);
+	}
+
+	public int sqlType() {
+		return Types.VARCHAR;
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+
+		return '\'' + new String( toInternalFormat( value ) ) + '\'';
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		if (xml == null) return toExternalFormat( null );
+		int length = xml.length();
+		char[] chars = new char[length];
+		for (int index = 0 ; index < length ; index++ ) {
+			chars[index] = xml.charAt( index );
+		}
+		return toExternalFormat( chars );
+	}
+
+	public String toString(Object value) {
+		if (value == null) return null;
+		return new String( toInternalFormat( value ) );
+	}
+
+	public Object fromStringValue(String xml) {
+		if (xml == null) return null;
+		int length = xml.length();
+		char[] chars = new char[length];
+		for (int index = 0 ; index < length ; index++ ) {
+			chars[index] = xml.charAt( index );
+		}
+		return toExternalFormat( chars );
+	}
+
+	protected Object deepCopyNotNull(Object value) throws HibernateException {
+		char[] chars = toInternalFormat(value);
+		char[] result = new char[chars.length];
+		System.arraycopy(chars, 0, result, 0, chars.length);
+		return toExternalFormat(result);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractComponentType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-//$Id: AbstractComponentType.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.type;
-
-import java.lang.reflect.Method;
-
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Enables other Component-like types to hold collections and have cascades, etc.
- *
- * @see ComponentType
- * @see AnyType
- * @author Gavin King
- */
-public interface AbstractComponentType extends Type {
-	/**
-	 * Get the types of the component properties
-	 */
-	public Type[] getSubtypes();
-	/**
-	 * Get the names of the component properties
-	 */
-	public String[] getPropertyNames();
-	/**
-	 * Optional operation
-	 * @return nullability of component properties
-	 */
-	public boolean[] getPropertyNullability();
-	/**
-	 * Get the values of the component properties of 
-	 * a component instance
-	 */
-	public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException;
-	/**
-	 * Optional operation
-	 */
-	public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException;
-	/**
-	 * Optional operation
-	 */
-	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException;
-	public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException;
-	//public Object instantiate(Object parent, SessionImplementor session) throws HibernateException;
-	public CascadeStyle getCascadeStyle(int i);
-	public FetchMode getFetchMode(int i);
-	public boolean isMethodOf(Method method);
-	public boolean isEmbedded();
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AbstractComponentType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.Method;
+
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Enables other Component-like types to hold collections and have cascades, etc.
+ *
+ * @see ComponentType
+ * @see AnyType
+ * @author Gavin King
+ */
+public interface AbstractComponentType extends Type {
+	/**
+	 * Get the types of the component properties
+	 */
+	public Type[] getSubtypes();
+	/**
+	 * Get the names of the component properties
+	 */
+	public String[] getPropertyNames();
+	/**
+	 * Optional operation
+	 * @return nullability of component properties
+	 */
+	public boolean[] getPropertyNullability();
+	/**
+	 * Get the values of the component properties of 
+	 * a component instance
+	 */
+	public Object[] getPropertyValues(Object component, SessionImplementor session) throws HibernateException;
+	/**
+	 * Optional operation
+	 */
+	public Object[] getPropertyValues(Object component, EntityMode entityMode) throws HibernateException;
+	/**
+	 * Optional operation
+	 */
+	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode) throws HibernateException;
+	public Object getPropertyValue(Object component, int i, SessionImplementor session) throws HibernateException;
+	//public Object instantiate(Object parent, SessionImplementor session) throws HibernateException;
+	public CascadeStyle getCascadeStyle(int i);
+	public FetchMode getFetchMode(int i);
+	public boolean isMethodOf(Method method);
+	public boolean isEmbedded();
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AbstractType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,164 +0,0 @@
-//$Id: AbstractType.java 7793 2005-08-10 05:06:40Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.EqualsHelper;
-
-/**
- * Abstract superclass of the built in Type hierarchy.
- * @author Gavin King
- */
-public abstract class AbstractType implements Type {
-
-	public boolean isAssociationType() {
-		return false;
-	}
-
-	public boolean isCollectionType() {
-		return false;
-	}
-
-	public boolean isComponentType() {
-		return false;
-	}
-
-	public boolean isEntityType() {
-		return false;
-	}
-	
-	public boolean isXMLElement() {
-		return false;
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return ( (Comparable) x ).compareTo(y);
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-
-		if (value==null) {
-			return null;
-		}
-		else {
-			return (Serializable) deepCopy( value, session.getEntityMode(), session.getFactory() );
-		}
-	}
-
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner) 
-	throws HibernateException {
-		if ( cached==null ) {
-			return null;
-		}
-		else {
-			return deepCopy( cached, session.getEntityMode(), session.getFactory() );
-		}
-	}
-
-	public boolean isDirty(Object old, Object current, SessionImplementor session) 
-	throws HibernateException {
-		return !isSame( old, current, session.getEntityMode() );
-	}
-
-	public Object hydrate(
-		ResultSet rs,
-		String[] names,
-		SessionImplementor session,
-		Object owner)
-	throws HibernateException, SQLException {
-		// TODO: this is very suboptimal for some subclasses (namely components),
-		// since it does not take advantage of two-phase-load
-		return nullSafeGet(rs, names, session, owner);
-	}
-
-	public Object resolve(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return value;
-	}
-
-	public Object semiResolve(Object value, SessionImplementor session, Object owner) 
-	throws HibernateException {
-		return value;
-	}
-	
-	public boolean isAnyType() {
-		return false;
-	}
-
-	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
-	throws HibernateException {
-		return isDirty(old, current, session);
-	}
-	
-	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
-		return isEqual(x, y, entityMode);
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
-		return EqualsHelper.equals(x, y);
-	}
-	
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return x.hashCode();
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) {
-		return isEqual(x, y, entityMode);
-	}
-	
-	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
-		return getHashCode(x, entityMode);
-	}
-	
-	protected static void replaceNode(Node container, Element value) {
-		if ( container!=value ) { //not really necessary, I guess...
-			Element parent = container.getParent();
-			container.detach();
-			value.setName( container.getName() );
-			value.detach();
-			parent.add(value);
-		}
-	}
-	
-	public Type getSemiResolvedType(SessionFactoryImplementor factory) {
-		return this;
-	}
-
-	public Object replace(
-			Object original, 
-			Object target, 
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache, 
-			ForeignKeyDirection foreignKeyDirection) 
-	throws HibernateException {
-		boolean include;
-		if ( isAssociationType() ) {
-			AssociationType atype = (AssociationType) this;
-			include = atype.getForeignKeyDirection()==foreignKeyDirection;
-		}
-		else {
-			include = ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT==foreignKeyDirection;
-		}
-		return include ? replace(original, target, session, owner, copyCache) : target;
-	}
-
-	public void beforeAssemble(Serializable cached, SessionImplementor session) {}
-
-	/*public Object copy(Object original, Object target, SessionImplementor session, Object owner, Map copyCache)
-	throws HibernateException {
-		if (original==null) return null;
-		return assemble( disassemble(original, session), session, owner );
-	}*/
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AbstractType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AbstractType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,188 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.EqualsHelper;
+
+/**
+ * Abstract superclass of the built in Type hierarchy.
+ * 
+ * @author Gavin King
+ */
+public abstract class AbstractType implements Type {
+
+	public boolean isAssociationType() {
+		return false;
+	}
+
+	public boolean isCollectionType() {
+		return false;
+	}
+
+	public boolean isComponentType() {
+		return false;
+	}
+
+	public boolean isEntityType() {
+		return false;
+	}
+	
+	public boolean isXMLElement() {
+		return false;
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return ( (Comparable) x ).compareTo(y);
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+
+		if (value==null) {
+			return null;
+		}
+		else {
+			return (Serializable) deepCopy( value, session.getEntityMode(), session.getFactory() );
+		}
+	}
+
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner) 
+	throws HibernateException {
+		if ( cached==null ) {
+			return null;
+		}
+		else {
+			return deepCopy( cached, session.getEntityMode(), session.getFactory() );
+		}
+	}
+
+	public boolean isDirty(Object old, Object current, SessionImplementor session) 
+	throws HibernateException {
+		return !isSame( old, current, session.getEntityMode() );
+	}
+
+	public Object hydrate(
+		ResultSet rs,
+		String[] names,
+		SessionImplementor session,
+		Object owner)
+	throws HibernateException, SQLException {
+		// TODO: this is very suboptimal for some subclasses (namely components),
+		// since it does not take advantage of two-phase-load
+		return nullSafeGet(rs, names, session, owner);
+	}
+
+	public Object resolve(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return value;
+	}
+
+	public Object semiResolve(Object value, SessionImplementor session, Object owner) 
+	throws HibernateException {
+		return value;
+	}
+	
+	public boolean isAnyType() {
+		return false;
+	}
+
+	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
+	throws HibernateException {
+		return isDirty(old, current, session);
+	}
+	
+	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
+		return isEqual(x, y, entityMode);
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
+		return EqualsHelper.equals(x, y);
+	}
+	
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return x.hashCode();
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) {
+		return isEqual(x, y, entityMode);
+	}
+	
+	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
+		return getHashCode(x, entityMode);
+	}
+	
+	protected static void replaceNode(Node container, Element value) {
+		if ( container!=value ) { //not really necessary, I guess...
+			Element parent = container.getParent();
+			container.detach();
+			value.setName( container.getName() );
+			value.detach();
+			parent.add(value);
+		}
+	}
+	
+	public Type getSemiResolvedType(SessionFactoryImplementor factory) {
+		return this;
+	}
+
+	public Object replace(
+			Object original, 
+			Object target, 
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache, 
+			ForeignKeyDirection foreignKeyDirection) 
+	throws HibernateException {
+		boolean include;
+		if ( isAssociationType() ) {
+			AssociationType atype = (AssociationType) this;
+			include = atype.getForeignKeyDirection()==foreignKeyDirection;
+		}
+		else {
+			include = ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT==foreignKeyDirection;
+		}
+		return include ? replace(original, target, session, owner, copyCache) : target;
+	}
+
+	public void beforeAssemble(Serializable cached, SessionImplementor session) {}
+
+	/*public Object copy(Object original, Object target, SessionImplementor session, Object owner, Map copyCache)
+	throws HibernateException {
+		if (original==null) return null;
+		return assemble( disassemble(original, session), session, owner );
+	}*/
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,65 +0,0 @@
-//$Id: AdaptedImmutableType.java 7238 2005-06-20 09:17:00Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-
-/**
- * Optimize a mutable type, if the user promises not to mutable the
- * instances.
- * 
- * @author Gavin King
- */
-public class AdaptedImmutableType extends ImmutableType {
-	
-	private final NullableType mutableType;
-
-	public AdaptedImmutableType(NullableType mutableType) {
-		this.mutableType = mutableType;
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		return mutableType.get(rs, name);
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException,
-			SQLException {
-		mutableType.set(st, value, index);
-	}
-
-	public int sqlType() {
-		return mutableType.sqlType();
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return mutableType.toString(value);
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		return mutableType.fromStringValue(xml);
-	}
-
-	public Class getReturnedClass() {
-		return mutableType.getReturnedClass();
-	}
-
-	public String getName() {
-		return "imm_" + mutableType.getName();
-	}
-	
-	public boolean isEqual(Object x, Object y) {
-		return mutableType.isEqual(x, y);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return mutableType.getHashCode(x, entityMode);
-	}
-	
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return mutableType.compare(x, y, entityMode);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AdaptedImmutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+
+/**
+ * Optimize a mutable type, if the user promises not to mutable the
+ * instances.
+ * 
+ * @author Gavin King
+ */
+public class AdaptedImmutableType extends ImmutableType {
+	
+	private final NullableType mutableType;
+
+	public AdaptedImmutableType(NullableType mutableType) {
+		this.mutableType = mutableType;
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		return mutableType.get(rs, name);
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException,
+			SQLException {
+		mutableType.set(st, value, index);
+	}
+
+	public int sqlType() {
+		return mutableType.sqlType();
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return mutableType.toString(value);
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		return mutableType.fromStringValue(xml);
+	}
+
+	public Class getReturnedClass() {
+		return mutableType.getReturnedClass();
+	}
+
+	public String getName() {
+		return "imm_" + mutableType.getName();
+	}
+	
+	public boolean isEqual(Object x, Object y) {
+		return mutableType.isEqual(x, y);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return mutableType.getHashCode(x, entityMode);
+	}
+	
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return mutableType.compare(x, y, entityMode);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AnyType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,369 +0,0 @@
-//$Id: AnyType.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Map;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.TransientObjectException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.proxy.HibernateProxyHelper;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * Handles "any" mappings and the old deprecated "object" type
- * @author Gavin King
- */
-public class AnyType extends AbstractType implements AbstractComponentType, AssociationType {
-
-	private final Type identifierType;
-	private final Type metaType;
-
-	public AnyType(Type metaType, Type identifierType) {
-		this.identifierType = identifierType;
-		this.metaType = metaType;
-	}
-
-	public AnyType() {
-		this(Hibernate.STRING, Hibernate.SERIALIZABLE);
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
-	throws HibernateException {
-		return value;
-	}
-	
-	public boolean isMethodOf(Method method) {
-		return false;
-	}
-
-	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
-		return x==y;
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return 0; //TODO: entities CAN be compared, by PK and entity name, fix this!
-	}
-
-	public int getColumnSpan(Mapping session)
-	throws MappingException {
-		return 2;
-	}
-
-	public String getName() {
-		return "object";
-	}
-
-	public boolean isMutable() {
-		return false;
-	}
-
-	public Object nullSafeGet(ResultSet rs,	String name, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException {
-
-		throw new UnsupportedOperationException("object is a multicolumn type");
-	}
-
-	public Object nullSafeGet(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
-	throws HibernateException, SQLException {
-		return resolveAny(
-				(String) metaType.nullSafeGet(rs, names[0], session, owner),
-				(Serializable) identifierType.nullSafeGet(rs, names[1], session, owner),
-				session
-			);
-	}
-
-	public Object hydrate(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
-	throws HibernateException, SQLException {
-		String entityName = (String) metaType.nullSafeGet(rs, names[0], session, owner);
-		Serializable id = (Serializable) identifierType.nullSafeGet(rs, names[1], session, owner);
-		return new ObjectTypeCacheEntry(entityName, id);
-	}
-
-	public Object resolve(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value;
-		return resolveAny(holder.entityName, holder.id, session);
-	}
-
-	public Object semiResolve(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		throw new UnsupportedOperationException("any mappings may not form part of a property-ref");
-	}
-	
-	private Object resolveAny(String entityName, Serializable id, SessionImplementor session)
-	throws HibernateException {
-		return entityName==null || id==null ?
-				null : session.internalLoad( entityName, id, false, false );
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value,	int index, SessionImplementor session)
-	throws HibernateException, SQLException {
-		nullSafeSet(st, value, index, null, session);
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value,	int index, boolean[] settable, SessionImplementor session)
-	throws HibernateException, SQLException {
-
-		Serializable id;
-		String entityName;
-		if (value==null) {
-			id=null;
-			entityName=null;
-		}
-		else {
-			entityName = session.bestGuessEntityName(value);
-			id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, value, session);
-		}
-		
-		// metaType is assumed to be single-column type
-		if ( settable==null || settable[0] ) {
-			metaType.nullSafeSet(st, entityName, index, session);
-		}
-		if (settable==null) {
-			identifierType.nullSafeSet(st, id, index+1, session);
-		}
-		else {
-			boolean[] idsettable = new boolean[ settable.length-1 ];
-			System.arraycopy(settable, 1, idsettable, 0, idsettable.length);
-			identifierType.nullSafeSet(st, id, index+1, idsettable, session);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return Object.class;
-	}
-
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return ArrayHelper.join(
-				metaType.sqlTypes(mapping),
-				identifierType.sqlTypes(mapping)
-			);
-	}
-
-	public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) {
-		throw new UnsupportedOperationException("any types cannot be stringified");
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		//TODO: terrible implementation!
-		return value==null ?
-				"null" :
-				Hibernate.entity( HibernateProxyHelper.getClassWithoutInitializingProxy(value) )
-						.toLoggableString(value, factory);
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		throw new UnsupportedOperationException(); //TODO: is this right??
-	}
-
-	public static final class ObjectTypeCacheEntry implements Serializable {
-		String entityName;
-		Serializable id;
-		ObjectTypeCacheEntry(String entityName, Serializable id) {
-			this.entityName = entityName;
-			this.id = id;
-		}
-	}
-
-	public Object assemble(
-		Serializable cached,
-		SessionImplementor session,
-		Object owner)
-	throws HibernateException {
-
-		ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached;
-		return e==null ? null : session.internalLoad(e.entityName, e.id, false, false);
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return value==null ?
-			null :
-			new ObjectTypeCacheEntry(
-						session.bestGuessEntityName(value),
-						ForeignKeys.getEntityIdentifierIfNotUnsaved( 
-								session.bestGuessEntityName(value), value, session 
-							)
-					);
-	}
-
-	public boolean isAnyType() {
-		return true;
-	}
-
-	public Object replace(
-			Object original, 
-			Object target,
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache)
-	throws HibernateException {
-		if (original==null) {
-			return null;
-		}
-		else {
-			String entityName = session.bestGuessEntityName(original);
-			Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 
-					entityName, 
-					original, 
-					session 
-				);
-			return session.internalLoad( 
-					entityName, 
-					id, 
-					false, 
-					false
-				);
-		}
-	}
-	public CascadeStyle getCascadeStyle(int i) {
-		return CascadeStyle.NONE;
-	}
-
-	public FetchMode getFetchMode(int i) {
-		return FetchMode.SELECT;
-	}
-
-	private static final String[] PROPERTY_NAMES = new String[] { "class", "id" };
-
-	public String[] getPropertyNames() {
-		return PROPERTY_NAMES;
-	}
-
-	public Object getPropertyValue(Object component, int i, SessionImplementor session)
-		throws HibernateException {
-
-		return i==0 ?
-				session.bestGuessEntityName(component) :
-				getIdentifier(component, session);
-	}
-
-	public Object[] getPropertyValues(Object component, SessionImplementor session)
-		throws HibernateException {
-
-		return new Object[] { session.bestGuessEntityName(component), getIdentifier(component, session) };
-	}
-
-	private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException {
-		try {
-			return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session );
-		}
-		catch (TransientObjectException toe) {
-			return null;
-		}
-	}
-
-	public Type[] getSubtypes() {
-		return new Type[] { metaType, identifierType };
-	}
-
-	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
-		throws HibernateException {
-
-		throw new UnsupportedOperationException();
-
-	}
-
-	public Object[] getPropertyValues(Object component, EntityMode entityMode) {
-		throw new UnsupportedOperationException();
-	}
-
-	public boolean isComponentType() {
-		return true;
-	}
-
-	public ForeignKeyDirection getForeignKeyDirection() {
-		//return AssociationType.FOREIGN_KEY_TO_PARENT; //this is better but causes a transient object exception...
-		return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
-	}
-
-	public boolean isAssociationType() {
-		return true;
-	}
-
-	public boolean useLHSPrimaryKey() {
-		return false;
-	}
-
-	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) {
-		throw new UnsupportedOperationException("any types do not have a unique referenced persister");
-	}
-
-	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
-	throws HibernateException {
-		if (current==null) return old!=null;
-		if (old==null) return current!=null;
-		ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old;
-		boolean[] idcheckable = new boolean[checkable.length-1];
-		System.arraycopy(checkable, 1, idcheckable, 0, idcheckable.length);
-		return ( checkable[0] && !holder.entityName.equals( session.bestGuessEntityName(current) ) ) ||
-				identifierType.isModified(holder.id, getIdentifier(current, session), idcheckable, session);
-	}
-
-	public String getAssociatedEntityName(SessionFactoryImplementor factory)
-		throws MappingException {
-		throw new UnsupportedOperationException("any types do not have a unique referenced persister");
-	}
-	
-	public boolean[] getPropertyNullability() {
-		return null;
-	}
-
-	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
-	throws MappingException {
-		throw new UnsupportedOperationException();
-	}
-	
-	public boolean isReferenceToPrimaryKey() {
-		return true;
-	}
-	
-	public String getRHSUniqueKeyPropertyName() {
-		return null;
-	}
-
-	public String getLHSPropertyName() {
-		return null;
-	}
-
-	public boolean isAlwaysDirtyChecked() {
-		return false;
-	}
-
-	public boolean isEmbeddedInXML() {
-		return false;
-	}
-	
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		boolean[] result = new boolean[ getColumnSpan(mapping) ];
-		if (value!=null) Arrays.fill(result, true);
-		return result;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) 
-	throws HibernateException {
-		//TODO!!!
-		return isDirty(old, current, session);
-	}
-
-	public boolean isEmbedded() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AnyType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AnyType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,392 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.TransientObjectException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.proxy.HibernateProxyHelper;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * Handles "any" mappings and the old deprecated "object" type
+ * @author Gavin King
+ */
+public class AnyType extends AbstractType implements AbstractComponentType, AssociationType {
+
+	private final Type identifierType;
+	private final Type metaType;
+
+	public AnyType(Type metaType, Type identifierType) {
+		this.identifierType = identifierType;
+		this.metaType = metaType;
+	}
+
+	public AnyType() {
+		this(Hibernate.STRING, Hibernate.SERIALIZABLE);
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
+	throws HibernateException {
+		return value;
+	}
+	
+	public boolean isMethodOf(Method method) {
+		return false;
+	}
+
+	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
+		return x==y;
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return 0; //TODO: entities CAN be compared, by PK and entity name, fix this!
+	}
+
+	public int getColumnSpan(Mapping session)
+	throws MappingException {
+		return 2;
+	}
+
+	public String getName() {
+		return "object";
+	}
+
+	public boolean isMutable() {
+		return false;
+	}
+
+	public Object nullSafeGet(ResultSet rs,	String name, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException {
+
+		throw new UnsupportedOperationException("object is a multicolumn type");
+	}
+
+	public Object nullSafeGet(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
+	throws HibernateException, SQLException {
+		return resolveAny(
+				(String) metaType.nullSafeGet(rs, names[0], session, owner),
+				(Serializable) identifierType.nullSafeGet(rs, names[1], session, owner),
+				session
+			);
+	}
+
+	public Object hydrate(ResultSet rs,	String[] names,	SessionImplementor session,	Object owner)
+	throws HibernateException, SQLException {
+		String entityName = (String) metaType.nullSafeGet(rs, names[0], session, owner);
+		Serializable id = (Serializable) identifierType.nullSafeGet(rs, names[1], session, owner);
+		return new ObjectTypeCacheEntry(entityName, id);
+	}
+
+	public Object resolve(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) value;
+		return resolveAny(holder.entityName, holder.id, session);
+	}
+
+	public Object semiResolve(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		throw new UnsupportedOperationException("any mappings may not form part of a property-ref");
+	}
+	
+	private Object resolveAny(String entityName, Serializable id, SessionImplementor session)
+	throws HibernateException {
+		return entityName==null || id==null ?
+				null : session.internalLoad( entityName, id, false, false );
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value,	int index, SessionImplementor session)
+	throws HibernateException, SQLException {
+		nullSafeSet(st, value, index, null, session);
+	}
+	
+	public void nullSafeSet(PreparedStatement st, Object value,	int index, boolean[] settable, SessionImplementor session)
+	throws HibernateException, SQLException {
+
+		Serializable id;
+		String entityName;
+		if (value==null) {
+			id=null;
+			entityName=null;
+		}
+		else {
+			entityName = session.bestGuessEntityName(value);
+			id = ForeignKeys.getEntityIdentifierIfNotUnsaved(entityName, value, session);
+		}
+		
+		// metaType is assumed to be single-column type
+		if ( settable==null || settable[0] ) {
+			metaType.nullSafeSet(st, entityName, index, session);
+		}
+		if (settable==null) {
+			identifierType.nullSafeSet(st, id, index+1, session);
+		}
+		else {
+			boolean[] idsettable = new boolean[ settable.length-1 ];
+			System.arraycopy(settable, 1, idsettable, 0, idsettable.length);
+			identifierType.nullSafeSet(st, id, index+1, idsettable, session);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return Object.class;
+	}
+
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return ArrayHelper.join(
+				metaType.sqlTypes(mapping),
+				identifierType.sqlTypes(mapping)
+			);
+	}
+
+	public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory) {
+		throw new UnsupportedOperationException("any types cannot be stringified");
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		//TODO: terrible implementation!
+		return value==null ?
+				"null" :
+				Hibernate.entity( HibernateProxyHelper.getClassWithoutInitializingProxy(value) )
+						.toLoggableString(value, factory);
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		throw new UnsupportedOperationException(); //TODO: is this right??
+	}
+
+	public static final class ObjectTypeCacheEntry implements Serializable {
+		String entityName;
+		Serializable id;
+		ObjectTypeCacheEntry(String entityName, Serializable id) {
+			this.entityName = entityName;
+			this.id = id;
+		}
+	}
+
+	public Object assemble(
+		Serializable cached,
+		SessionImplementor session,
+		Object owner)
+	throws HibernateException {
+
+		ObjectTypeCacheEntry e = (ObjectTypeCacheEntry) cached;
+		return e==null ? null : session.internalLoad(e.entityName, e.id, false, false);
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return value==null ?
+			null :
+			new ObjectTypeCacheEntry(
+						session.bestGuessEntityName(value),
+						ForeignKeys.getEntityIdentifierIfNotUnsaved( 
+								session.bestGuessEntityName(value), value, session 
+							)
+					);
+	}
+
+	public boolean isAnyType() {
+		return true;
+	}
+
+	public Object replace(
+			Object original, 
+			Object target,
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache)
+	throws HibernateException {
+		if (original==null) {
+			return null;
+		}
+		else {
+			String entityName = session.bestGuessEntityName(original);
+			Serializable id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 
+					entityName, 
+					original, 
+					session 
+				);
+			return session.internalLoad( 
+					entityName, 
+					id, 
+					false, 
+					false
+				);
+		}
+	}
+	public CascadeStyle getCascadeStyle(int i) {
+		return CascadeStyle.NONE;
+	}
+
+	public FetchMode getFetchMode(int i) {
+		return FetchMode.SELECT;
+	}
+
+	private static final String[] PROPERTY_NAMES = new String[] { "class", "id" };
+
+	public String[] getPropertyNames() {
+		return PROPERTY_NAMES;
+	}
+
+	public Object getPropertyValue(Object component, int i, SessionImplementor session)
+		throws HibernateException {
+
+		return i==0 ?
+				session.bestGuessEntityName(component) :
+				getIdentifier(component, session);
+	}
+
+	public Object[] getPropertyValues(Object component, SessionImplementor session)
+		throws HibernateException {
+
+		return new Object[] { session.bestGuessEntityName(component), getIdentifier(component, session) };
+	}
+
+	private Serializable getIdentifier(Object value, SessionImplementor session) throws HibernateException {
+		try {
+			return ForeignKeys.getEntityIdentifierIfNotUnsaved( session.bestGuessEntityName(value), value, session );
+		}
+		catch (TransientObjectException toe) {
+			return null;
+		}
+	}
+
+	public Type[] getSubtypes() {
+		return new Type[] { metaType, identifierType };
+	}
+
+	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
+		throws HibernateException {
+
+		throw new UnsupportedOperationException();
+
+	}
+
+	public Object[] getPropertyValues(Object component, EntityMode entityMode) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean isComponentType() {
+		return true;
+	}
+
+	public ForeignKeyDirection getForeignKeyDirection() {
+		//return AssociationType.FOREIGN_KEY_TO_PARENT; //this is better but causes a transient object exception...
+		return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
+	}
+
+	public boolean isAssociationType() {
+		return true;
+	}
+
+	public boolean useLHSPrimaryKey() {
+		return false;
+	}
+
+	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) {
+		throw new UnsupportedOperationException("any types do not have a unique referenced persister");
+	}
+
+	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
+	throws HibernateException {
+		if (current==null) return old!=null;
+		if (old==null) return current!=null;
+		ObjectTypeCacheEntry holder = (ObjectTypeCacheEntry) old;
+		boolean[] idcheckable = new boolean[checkable.length-1];
+		System.arraycopy(checkable, 1, idcheckable, 0, idcheckable.length);
+		return ( checkable[0] && !holder.entityName.equals( session.bestGuessEntityName(current) ) ) ||
+				identifierType.isModified(holder.id, getIdentifier(current, session), idcheckable, session);
+	}
+
+	public String getAssociatedEntityName(SessionFactoryImplementor factory)
+		throws MappingException {
+		throw new UnsupportedOperationException("any types do not have a unique referenced persister");
+	}
+	
+	public boolean[] getPropertyNullability() {
+		return null;
+	}
+
+	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
+	throws MappingException {
+		throw new UnsupportedOperationException();
+	}
+	
+	public boolean isReferenceToPrimaryKey() {
+		return true;
+	}
+	
+	public String getRHSUniqueKeyPropertyName() {
+		return null;
+	}
+
+	public String getLHSPropertyName() {
+		return null;
+	}
+
+	public boolean isAlwaysDirtyChecked() {
+		return false;
+	}
+
+	public boolean isEmbeddedInXML() {
+		return false;
+	}
+	
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		boolean[] result = new boolean[ getColumnSpan(mapping) ];
+		if (value!=null) Arrays.fill(result, true);
+		return result;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) 
+	throws HibernateException {
+		//TODO!!!
+		return isDirty(old, current, session);
+	}
+
+	public boolean isEmbedded() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ArrayType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,121 +0,0 @@
-//$Id: ArrayType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentArrayHolder;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * A type for persistent arrays.
- * @author Gavin King
- */
-public class ArrayType extends CollectionType {
-
-	private final Class elementClass;
-	private final Class arrayClass;
-
-	public ArrayType(String role, String propertyRef, Class elementClass, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-		this.elementClass = elementClass;
-		arrayClass = Array.newInstance(elementClass, 0).getClass();
-	}
-
-	public Class getReturnedClass() {
-		return arrayClass;
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) 
-	throws HibernateException {
-		return new PersistentArrayHolder(session, persister);
-	}
-
-	/**
-	 * Not defined for collections of primitive type
-	 */
-	public Iterator getElementsIterator(Object collection) {
-		return Arrays.asList( (Object[]) collection ).iterator();
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object array) {
-		return new PersistentArrayHolder(session, array);
-	}
-
-	public boolean isArrayType() {
-		return true;
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
-		if ( value == null ) {
-			return "null";
-		}
-		int length = Array.getLength(value);
-		List list = new ArrayList(length);
-		Type elemType = getElementType(factory);
-		for ( int i=0; i<length; i++ ) {
-			list.add( elemType.toLoggableString( Array.get(value, i), factory ) );
-		}
-		return list.toString();
-	}
-	
-	public Object instantiateResult(Object original) {
-		return Array.newInstance( elementClass, Array.getLength(original) );
-	}
-
-	public Object replaceElements(
-		Object original,
-		Object target,
-		Object owner, 
-		Map copyCache, 
-		SessionImplementor session)
-	throws HibernateException {
-		
-		int length = Array.getLength(original);
-		if ( length!=Array.getLength(target) ) {
-			//note: this affects the return value!
-			target=instantiateResult(original);
-		}
-		
-		Type elemType = getElementType( session.getFactory() );
-		for ( int i=0; i<length; i++ ) {
-			Array.set( target, i, elemType.replace( Array.get(original, i), null, session, owner, copyCache ) );
-		}
-		
-		return target;
-	
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		throw new UnsupportedOperationException();
-	}
-
-	public Object indexOf(Object array, Object element) {
-		int length = Array.getLength(array);
-		for ( int i=0; i<length; i++ ) {
-			//TODO: proxies!
-			if ( Array.get(array, i)==element ) return new Integer(i);
-		}
-		return null;
-	}
-
-	protected boolean initializeImmediately(EntityMode entityMode) {
-		return true;
-	}
-
-	public boolean hasHolder(EntityMode entityMode) {
-		return true;
-	}
-	
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ArrayType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,144 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentArrayHolder;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * A type for persistent arrays.
+ * @author Gavin King
+ */
+public class ArrayType extends CollectionType {
+
+	private final Class elementClass;
+	private final Class arrayClass;
+
+	public ArrayType(String role, String propertyRef, Class elementClass, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+		this.elementClass = elementClass;
+		arrayClass = Array.newInstance(elementClass, 0).getClass();
+	}
+
+	public Class getReturnedClass() {
+		return arrayClass;
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) 
+	throws HibernateException {
+		return new PersistentArrayHolder(session, persister);
+	}
+
+	/**
+	 * Not defined for collections of primitive type
+	 */
+	public Iterator getElementsIterator(Object collection) {
+		return Arrays.asList( (Object[]) collection ).iterator();
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object array) {
+		return new PersistentArrayHolder(session, array);
+	}
+
+	public boolean isArrayType() {
+		return true;
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
+		if ( value == null ) {
+			return "null";
+		}
+		int length = Array.getLength(value);
+		List list = new ArrayList(length);
+		Type elemType = getElementType(factory);
+		for ( int i=0; i<length; i++ ) {
+			list.add( elemType.toLoggableString( Array.get(value, i), factory ) );
+		}
+		return list.toString();
+	}
+	
+	public Object instantiateResult(Object original) {
+		return Array.newInstance( elementClass, Array.getLength(original) );
+	}
+
+	public Object replaceElements(
+		Object original,
+		Object target,
+		Object owner, 
+		Map copyCache, 
+		SessionImplementor session)
+	throws HibernateException {
+		
+		int length = Array.getLength(original);
+		if ( length!=Array.getLength(target) ) {
+			//note: this affects the return value!
+			target=instantiateResult(original);
+		}
+		
+		Type elemType = getElementType( session.getFactory() );
+		for ( int i=0; i<length; i++ ) {
+			Array.set( target, i, elemType.replace( Array.get(original, i), null, session, owner, copyCache ) );
+		}
+		
+		return target;
+	
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Object indexOf(Object array, Object element) {
+		int length = Array.getLength(array);
+		for ( int i=0; i<length; i++ ) {
+			//TODO: proxies!
+			if ( Array.get(array, i)==element ) return new Integer(i);
+		}
+		return null;
+	}
+
+	protected boolean initializeImmediately(EntityMode entityMode) {
+		return true;
+	}
+
+	public boolean hasHolder(EntityMode entityMode) {
+		return true;
+	}
+	
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/AssociationType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-//$Id: AssociationType.java 7017 2005-06-05 04:31:34Z oneovthafew $
-package org.hibernate.type;
-
-import org.hibernate.MappingException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.entity.Joinable;
-
-import java.util.Map;
-
-/**
- * A type that represents some kind of association between entities.
- * @see org.hibernate.engine.Cascade
- * @author Gavin King
- */
-public interface AssociationType extends Type {
-
-	/**
-	 * Get the foreign key directionality of this association
-	 */
-	public ForeignKeyDirection getForeignKeyDirection();
-
-	//TODO: move these to a new JoinableType abstract class,
-	//extended by EntityType and PersistentCollectionType:
-
-	/**
-	 * Is the primary key of the owning entity table
-	 * to be used in the join?
-	 */
-	public boolean useLHSPrimaryKey();
-	/**
-	 * Get the name of a property in the owning entity 
-	 * that provides the join key (null if the identifier)
-	 */
-	public String getLHSPropertyName();
-	
-	/**
-	 * The name of a unique property of the associated entity 
-	 * that provides the join key (null if the identifier of
-	 * an entity, or key of a collection)
-	 */
-	public String getRHSUniqueKeyPropertyName();
-
-	/**
-	 * Get the "persister" for this association - a class or
-	 * collection persister
-	 */
-	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException;
-	
-	/**
-	 * Get the entity name of the associated entity
-	 */
-	public String getAssociatedEntityName(SessionFactoryImplementor factory) throws MappingException;
-	
-	/**
-	 * Get the "filtering" SQL fragment that is applied in the 
-	 * SQL on clause, in addition to the usual join condition
-	 */	
-	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) 
-	throws MappingException;
-	
-	/**
-	 * Do we dirty check this association, even when there are
-	 * no columns to be updated?
-	 */
-	public abstract boolean isAlwaysDirtyChecked();
-	
-	public boolean isEmbeddedInXML();
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/AssociationType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/AssociationType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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.type;
+
+import org.hibernate.MappingException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.entity.Joinable;
+
+import java.util.Map;
+
+/**
+ * A type that represents some kind of association between entities.
+ * @see org.hibernate.engine.Cascade
+ * @author Gavin King
+ */
+public interface AssociationType extends Type {
+
+	/**
+	 * Get the foreign key directionality of this association
+	 */
+	public ForeignKeyDirection getForeignKeyDirection();
+
+	//TODO: move these to a new JoinableType abstract class,
+	//extended by EntityType and PersistentCollectionType:
+
+	/**
+	 * Is the primary key of the owning entity table
+	 * to be used in the join?
+	 */
+	public boolean useLHSPrimaryKey();
+	/**
+	 * Get the name of a property in the owning entity 
+	 * that provides the join key (null if the identifier)
+	 */
+	public String getLHSPropertyName();
+	
+	/**
+	 * The name of a unique property of the associated entity 
+	 * that provides the join key (null if the identifier of
+	 * an entity, or key of a collection)
+	 */
+	public String getRHSUniqueKeyPropertyName();
+
+	/**
+	 * Get the "persister" for this association - a class or
+	 * collection persister
+	 */
+	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException;
+	
+	/**
+	 * Get the entity name of the associated entity
+	 */
+	public String getAssociatedEntityName(SessionFactoryImplementor factory) throws MappingException;
+	
+	/**
+	 * Get the "filtering" SQL fragment that is applied in the 
+	 * SQL on clause, in addition to the usual join condition
+	 */	
+	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters) 
+	throws MappingException;
+	
+	/**
+	 * Do we dirty check this association, even when there are
+	 * no columns to be updated?
+	 */
+	public abstract boolean isAlwaysDirtyChecked();
+	
+	public boolean isEmbeddedInXML();
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BagType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,50 +0,0 @@
-//$Id: BagType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentBag;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentElementHolder;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-public class BagType extends CollectionType {
-
-	public BagType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key)
-	throws HibernateException {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder(session, persister, key);
-		}
-		else {
-			return new PersistentBag(session);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return java.util.Collection.class;
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentBag( session, (Collection) collection );
-		}
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BagType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BagType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,73 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentElementHolder;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+public class BagType extends CollectionType {
+
+	public BagType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key)
+	throws HibernateException {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder(session, persister, key);
+		}
+		else {
+			return new PersistentBag(session);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return java.util.Collection.class;
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentBag( session, (Collection) collection );
+		}
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BigDecimalType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,66 +0,0 @@
-//$Id: BigDecimalType.java 5744 2005-02-16 12:50:19Z oneovthafew $
-package org.hibernate.type;
-
-import java.math.BigDecimal;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-
-/**
- * <tt>big_decimal</tt>: A type that maps an SQL NUMERIC to a
- * <tt>java.math.BigDecimal</tt>
- * @see java.math.BigDecimal
- * @author Gavin King
- */
-public class BigDecimalType extends ImmutableType {
-
-	public Object get(ResultSet rs, String name)
-	throws HibernateException, SQLException {
-		return rs.getBigDecimal(name);
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws HibernateException, SQLException {
-		st.setBigDecimal(index, (BigDecimal) value);
-	}
-
-	public int sqlType() {
-		return Types.NUMERIC;
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return value.toString();
-	}
-
-	public Class getReturnedClass() {
-		return BigDecimal.class;
-	}
-
-	public boolean isEqual(Object x, Object y) {
-		return x==y || ( x!=null && y!=null && ( (BigDecimal) x ).compareTo( (BigDecimal) y )==0 );
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return ( (BigDecimal) x ).intValue();
-	}
-
-	public String getName() {
-		return "big_decimal";
-	}
-
-	public Object fromStringValue(String xml) {
-		return new BigDecimal(xml);
-	}
-
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BigDecimalType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigDecimalType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,89 @@
+/*
+ * 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.type;
+
+import java.math.BigDecimal;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+
+/**
+ * <tt>big_decimal</tt>: A type that maps an SQL NUMERIC to a
+ * <tt>java.math.BigDecimal</tt>
+ * @see java.math.BigDecimal
+ * @author Gavin King
+ */
+public class BigDecimalType extends ImmutableType {
+
+	public Object get(ResultSet rs, String name)
+	throws HibernateException, SQLException {
+		return rs.getBigDecimal(name);
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws HibernateException, SQLException {
+		st.setBigDecimal(index, (BigDecimal) value);
+	}
+
+	public int sqlType() {
+		return Types.NUMERIC;
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return value.toString();
+	}
+
+	public Class getReturnedClass() {
+		return BigDecimal.class;
+	}
+
+	public boolean isEqual(Object x, Object y) {
+		return x==y || ( x!=null && y!=null && ( (BigDecimal) x ).compareTo( (BigDecimal) y )==0 );
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return ( (BigDecimal) x ).intValue();
+	}
+
+	public String getName() {
+		return "big_decimal";
+	}
+
+	public Object fromStringValue(String xml) {
+		return new BigDecimal(xml);
+	}
+
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BigIntegerType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,79 +0,0 @@
-//$Id: BigIntegerType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>big_integer</tt>: A type that maps an SQL NUMERIC to a
- * <tt>java.math.BigInteger</tt>
- * @see java.math.BigInteger
- * @author Gavin King
- */
-public class BigIntegerType extends ImmutableType implements DiscriminatorType {
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return new BigInteger(xml);
-	}
-
-	public Object get(ResultSet rs, String name)
-	throws HibernateException, SQLException {
-		//return rs.getBigDecimal(name).toBigIntegerExact(); this 1.5 only. 
-		BigDecimal bigDecimal = rs.getBigDecimal(name);
-		return bigDecimal==null ? null : 
-			bigDecimal.setScale(0, BigDecimal.ROUND_UNNECESSARY).unscaledValue();
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws HibernateException, SQLException {
-		st.setBigDecimal( index, new BigDecimal( (BigInteger) value ) );
-	}
-
-	public int sqlType() {
-		return Types.NUMERIC;
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return value.toString();
-	}
-
-	public Class getReturnedClass() {
-		return BigInteger.class;
-	}
-
-	public boolean isEqual(Object x, Object y) {
-		return x==y || ( x!=null && y!=null && ( (BigInteger) x ).compareTo( (BigInteger) y )==0 );
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return ( (BigInteger) x ).intValue();
-	}
-
-	public String getName() {
-		return "big_integer";
-	}
-
-	public Object fromStringValue(String xml) {
-		return new BigInteger(xml);
-	}
-
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BigIntegerType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BigIntegerType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+/*
+ * 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.type;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>big_integer</tt>: A type that maps an SQL NUMERIC to a
+ * <tt>java.math.BigInteger</tt>
+ * @see java.math.BigInteger
+ * @author Gavin King
+ */
+public class BigIntegerType extends ImmutableType implements DiscriminatorType {
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return new BigInteger(xml);
+	}
+
+	public Object get(ResultSet rs, String name)
+	throws HibernateException, SQLException {
+		//return rs.getBigDecimal(name).toBigIntegerExact(); this 1.5 only. 
+		BigDecimal bigDecimal = rs.getBigDecimal(name);
+		return bigDecimal==null ? null : 
+			bigDecimal.setScale(0, BigDecimal.ROUND_UNNECESSARY).unscaledValue();
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws HibernateException, SQLException {
+		st.setBigDecimal( index, new BigDecimal( (BigInteger) value ) );
+	}
+
+	public int sqlType() {
+		return Types.NUMERIC;
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return value.toString();
+	}
+
+	public Class getReturnedClass() {
+		return BigInteger.class;
+	}
+
+	public boolean isEqual(Object x, Object y) {
+		return x==y || ( x!=null && y!=null && ( (BigInteger) x ).compareTo( (BigInteger) y )==0 );
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return ( (BigInteger) x ).intValue();
+	}
+
+	public String getName() {
+		return "big_integer";
+	}
+
+	public Object fromStringValue(String xml) {
+		return new BigInteger(xml);
+	}
+
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BinaryType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: BinaryType.java 10009 2006-06-10 03:24:05Z epbernard $
-package org.hibernate.type;
-
-/**
- * <tt>binary</tt>: A type that maps an SQL VARBINARY to a Java byte[].
- * @author Gavin King
- */
-public class BinaryType extends AbstractBynaryType {
-
-	protected Object toExternalFormat(byte[] bytes) {
-		return bytes;
-	}
-
-	protected byte[] toInternalFormat(Object bytes) {
-		return (byte[]) bytes;
-	}
-
-	public Class getReturnedClass() {
-		return byte[].class;
-	}
-
-	public String getName() { return "binary"; }
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BinaryType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BinaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+/**
+ * <tt>binary</tt>: A type that maps an SQL VARBINARY to a Java byte[].
+ * @author Gavin King
+ */
+public class BinaryType extends AbstractBynaryType {
+
+	protected Object toExternalFormat(byte[] bytes) {
+		return bytes;
+	}
+
+	protected byte[] toInternalFormat(Object bytes) {
+		return (byte[]) bytes;
+	}
+
+	public Class getReturnedClass() {
+		return byte[].class;
+	}
+
+	public String getName() { return "binary"; }
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BlobType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,159 +0,0 @@
-//$Id: BlobType.java 7644 2005-07-25 06:53:09Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.Blob;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Map;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.BlobImpl;
-import org.hibernate.lob.SerializableBlob;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * <tt>blob</tt>: A type that maps an SQL BLOB to a java.sql.Blob.
- * @author Gavin King
- */
-public class BlobType extends AbstractType {
-
-	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		
-		if (value==null) {
-			st.setNull(index, Types.BLOB);
-		}
-		else {
-			
-			if (value instanceof SerializableBlob) {
-				value = ( (SerializableBlob) value ).getWrappedBlob();
-			}
-		
-			final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
-				(value instanceof BlobImpl);
-			
-			if ( useInputStream ) {
-				BlobImpl blob = (BlobImpl) value;
-				st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
-			}
-			else {
-				st.setBlob(index, (Blob) value);
-			}
-			
-		}
-		
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		Blob value = rs.getBlob(name);
-		return rs.wasNull() ? null : new SerializableBlob(value);
-	}
-
-	public Class getReturnedClass() {
-		return Blob.class;
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
-		return x == y;
-	}
-	
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return System.identityHashCode(x);
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return 0; //lobs cannot be compared
-	}
-
-	public String getName() {
-		return "blob";
-	}
-	
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-		throws HibernateException {
-		throw new UnsupportedOperationException("Blobs are not cacheable");
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)  {
-		return value;
-	}
-	
-	public Object fromXMLNode(Node xml, Mapping factory) {
-		throw new UnsupportedOperationException("todo");
-	}
-	
-	public int getColumnSpan(Mapping mapping) {
-		return 1;
-	}
-	
-	public boolean isMutable() {
-		return false;
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String name,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get(rs, name);
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String[] names,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get( rs, names[0] );
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			boolean[] settable, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if ( settable[0] ) set(st, value, index, session);
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-		set(st, value, index, session);
-	}
-	
-	public Object replace(Object original, Object target,
-			SessionImplementor session, Object owner, Map copyCache)
-			throws HibernateException {
-		//Blobs are ignored by merge()
-		return target;
-	}
-	
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return new int[] { Types.BLOB };
-	}
-	
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
-		throw new UnsupportedOperationException("todo");
-	}
-	
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-		return value==null ? "null" : value.toString();
-	}
-	
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return checkable[0] && isDirty(old, current, session);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BlobType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BlobType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,182 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.Blob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.lob.BlobImpl;
+import org.hibernate.lob.SerializableBlob;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * <tt>blob</tt>: A type that maps an SQL BLOB to a java.sql.Blob.
+ * @author Gavin King
+ */
+public class BlobType extends AbstractType {
+
+	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		
+		if (value==null) {
+			st.setNull(index, Types.BLOB);
+		}
+		else {
+			
+			if (value instanceof SerializableBlob) {
+				value = ( (SerializableBlob) value ).getWrappedBlob();
+			}
+		
+			final boolean useInputStream = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
+				(value instanceof BlobImpl);
+			
+			if ( useInputStream ) {
+				BlobImpl blob = (BlobImpl) value;
+				st.setBinaryStream( index, blob.getBinaryStream(), (int) blob.length() );
+			}
+			else {
+				st.setBlob(index, (Blob) value);
+			}
+			
+		}
+		
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		Blob value = rs.getBlob(name);
+		return rs.wasNull() ? null : new SerializableBlob(value);
+	}
+
+	public Class getReturnedClass() {
+		return Blob.class;
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
+		return x == y;
+	}
+	
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return System.identityHashCode(x);
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return 0; //lobs cannot be compared
+	}
+
+	public String getName() {
+		return "blob";
+	}
+	
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+		throws HibernateException {
+		throw new UnsupportedOperationException("Blobs are not cacheable");
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)  {
+		return value;
+	}
+	
+	public Object fromXMLNode(Node xml, Mapping factory) {
+		throw new UnsupportedOperationException("todo");
+	}
+	
+	public int getColumnSpan(Mapping mapping) {
+		return 1;
+	}
+	
+	public boolean isMutable() {
+		return false;
+	}
+	
+	public Object nullSafeGet(ResultSet rs, String name,
+			SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return get(rs, name);
+	}
+	
+	public Object nullSafeGet(ResultSet rs, String[] names,
+			SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return get( rs, names[0] );
+	}
+	
+	public void nullSafeSet(PreparedStatement st, Object value, int index,
+			boolean[] settable, SessionImplementor session)
+			throws HibernateException, SQLException {
+		if ( settable[0] ) set(st, value, index, session);
+	}
+	
+	public void nullSafeSet(PreparedStatement st, Object value, int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+		set(st, value, index, session);
+	}
+	
+	public Object replace(Object original, Object target,
+			SessionImplementor session, Object owner, Map copyCache)
+			throws HibernateException {
+		//Blobs are ignored by merge()
+		return target;
+	}
+	
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return new int[] { Types.BLOB };
+	}
+	
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
+		throw new UnsupportedOperationException("todo");
+	}
+	
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+		return value==null ? "null" : value.toString();
+	}
+	
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return checkable[0] && isDirty(old, current, session);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/BooleanType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-//$Id: BooleanType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>boolean</tt>: A type that maps an SQL BIT to a Java Boolean.
- * @author Gavin King
- */
-public class BooleanType extends PrimitiveType implements DiscriminatorType {
-
-	public Serializable getDefaultValue() {
-		return Boolean.FALSE;
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return rs.getBoolean(name) ? Boolean.TRUE : Boolean.FALSE;
-	}
-
-	public Class getPrimitiveClass() {
-		return boolean.class;
-	}
-
-	public Class getReturnedClass() {
-		return Boolean.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws SQLException {
-		st.setBoolean( index, ( (Boolean) value ).booleanValue() );
-	}
-
-	public int sqlType() {
-		return Types.BIT;
-	}
-
-	public String getName() { return "boolean"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return dialect.toBooleanValueString( ( (Boolean) value ).booleanValue() );
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return fromStringValue(xml);
-	}
-
-	public Object fromStringValue(String xml) {
-		return Boolean.valueOf(xml);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/BooleanType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/BooleanType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>boolean</tt>: A type that maps an SQL BIT to a Java Boolean.
+ * @author Gavin King
+ */
+public class BooleanType extends PrimitiveType implements DiscriminatorType {
+
+	public Serializable getDefaultValue() {
+		return Boolean.FALSE;
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return rs.getBoolean(name) ? Boolean.TRUE : Boolean.FALSE;
+	}
+
+	public Class getPrimitiveClass() {
+		return boolean.class;
+	}
+
+	public Class getReturnedClass() {
+		return Boolean.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws SQLException {
+		st.setBoolean( index, ( (Boolean) value ).booleanValue() );
+	}
+
+	public int sqlType() {
+		return Types.BIT;
+	}
+
+	public String getName() { return "boolean"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return dialect.toBooleanValueString( ( (Boolean) value ).booleanValue() );
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return fromStringValue(xml);
+	}
+
+	public Object fromStringValue(String xml) {
+		return Boolean.valueOf(xml);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ByteType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,73 +0,0 @@
-//$Id: ByteType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Comparator;
-
-import org.hibernate.util.ComparableComparator;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * <tt>byte</tt>: A type that maps an SQL TINYINT to a Java Byte.
- * @author Gavin King
- */
-public class ByteType extends PrimitiveType implements DiscriminatorType, VersionType {
-
-	private static final Byte ZERO = new Byte( (byte) 0 );
-
-	public Serializable getDefaultValue() {
-		return ZERO;
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Byte( rs.getByte(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return byte.class;
-	}
-
-	public Class getReturnedClass() {
-		return Byte.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		st.setByte( index, ( (Byte) value ).byteValue() );
-	}
-
-	public int sqlType() {
-		return Types.TINYINT;
-	}
-
-	public String getName() { return "byte"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return new Byte(xml);
-	}
-
-	public Object fromStringValue(String xml) {
-		return new Byte(xml);
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return new Byte( (byte) ( ( (Byte) current ).byteValue() + 1 ) );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return ZERO;
-	}
-
-	public Comparator getComparator() {
-		return ComparableComparator.INSTANCE;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ByteType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ByteType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Comparator;
+
+import org.hibernate.util.ComparableComparator;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * <tt>byte</tt>: A type that maps an SQL TINYINT to a Java Byte.
+ * @author Gavin King
+ */
+public class ByteType extends PrimitiveType implements DiscriminatorType, VersionType {
+
+	private static final Byte ZERO = new Byte( (byte) 0 );
+
+	public Serializable getDefaultValue() {
+		return ZERO;
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Byte( rs.getByte(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return byte.class;
+	}
+
+	public Class getReturnedClass() {
+		return Byte.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		st.setByte( index, ( (Byte) value ).byteValue() );
+	}
+
+	public int sqlType() {
+		return Types.TINYINT;
+	}
+
+	public String getName() { return "byte"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return new Byte(xml);
+	}
+
+	public Object fromStringValue(String xml) {
+		return new Byte(xml);
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return new Byte( (byte) ( ( (Byte) current ).byteValue() + 1 ) );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return ZERO;
+	}
+
+	public Comparator getComparator() {
+		return ComparableComparator.INSTANCE;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CalendarDateType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,95 +0,0 @@
-//$Id: CalendarDateType.java 8761 2005-12-06 04:34:23Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.util.CalendarComparator;
-
-/**
- * <tt>calendar_date</tt>: A type mapping for a <tt>Calendar</tt>
- * object that represents a date.
- * @author Gavin King
- */
-public class CalendarDateType extends MutableType {
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
-		Date date = rs.getDate(name);
-		if (date!=null) {
-			Calendar cal = new GregorianCalendar();
-			cal.setTime(date);
-			return cal;
-		}
-		else {
-			return null;
-		}
-
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		final Calendar cal = (Calendar) value;
-		//st.setDate( index,  new Date( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
-		st.setDate( index,  new Date( cal.getTime().getTime() ), cal );
-	}
-
-	public int sqlType() {
-		return Types.DATE;
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return Hibernate.DATE.toString( ( (Calendar) value ).getTime() );
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		Calendar result = new GregorianCalendar();
-		result.setTime( ( (java.util.Date) Hibernate.DATE.fromStringValue(xml) ) );
-		return result;
-	}
-
-	public Object deepCopyNotNull(Object value)  {
-		return ( (Calendar) value ).clone();
-	}
-
-	public Class getReturnedClass() {
-		return Calendar.class;
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return CalendarComparator.INSTANCE.compare(x, y);
-	}
-
-	public boolean isEqual(Object x, Object y)  {
-		if (x==y) return true;
-		if (x==null || y==null) return false;
-
-		Calendar calendar1 = (Calendar) x;
-		Calendar calendar2 = (Calendar) y;
-
-		return calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
-			&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
-			&& calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		Calendar calendar = (Calendar) x;
-		int hashCode = 1;
-		hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH);
-		hashCode = 31 * hashCode + calendar.get(Calendar.MONTH);
-		hashCode = 31 * hashCode + calendar.get(Calendar.YEAR);
-		return hashCode;
-	}
-
-	public String getName() {
-		return "calendar_date";
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CalendarDateType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarDateType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,118 @@
+/*
+ * 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.type;
+
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.util.CalendarComparator;
+
+/**
+ * <tt>calendar_date</tt>: A type mapping for a <tt>Calendar</tt>
+ * object that represents a date.
+ * @author Gavin King
+ */
+public class CalendarDateType extends MutableType {
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+		Date date = rs.getDate(name);
+		if (date!=null) {
+			Calendar cal = new GregorianCalendar();
+			cal.setTime(date);
+			return cal;
+		}
+		else {
+			return null;
+		}
+
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		final Calendar cal = (Calendar) value;
+		//st.setDate( index,  new Date( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
+		st.setDate( index,  new Date( cal.getTime().getTime() ), cal );
+	}
+
+	public int sqlType() {
+		return Types.DATE;
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return Hibernate.DATE.toString( ( (Calendar) value ).getTime() );
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		Calendar result = new GregorianCalendar();
+		result.setTime( ( (java.util.Date) Hibernate.DATE.fromStringValue(xml) ) );
+		return result;
+	}
+
+	public Object deepCopyNotNull(Object value)  {
+		return ( (Calendar) value ).clone();
+	}
+
+	public Class getReturnedClass() {
+		return Calendar.class;
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return CalendarComparator.INSTANCE.compare(x, y);
+	}
+
+	public boolean isEqual(Object x, Object y)  {
+		if (x==y) return true;
+		if (x==null || y==null) return false;
+
+		Calendar calendar1 = (Calendar) x;
+		Calendar calendar2 = (Calendar) y;
+
+		return calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
+			&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
+			&& calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		Calendar calendar = (Calendar) x;
+		int hashCode = 1;
+		hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH);
+		hashCode = 31 * hashCode + calendar.get(Calendar.MONTH);
+		hashCode = 31 * hashCode + calendar.get(Calendar.YEAR);
+		return hashCode;
+	}
+
+	public String getName() {
+		return "calendar_date";
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CalendarType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,124 +0,0 @@
-//$Id: CalendarType.java 7736 2005-08-03 20:03:34Z steveebersole $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.util.Calendar;
-import java.util.Comparator;
-import java.util.Date;
-import java.util.GregorianCalendar;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.cfg.Environment;
-import org.hibernate.util.CalendarComparator;
-
-/**
- * <tt>calendar</tt>: A type mapping for a <tt>Calendar</tt> object that
- * represents a datetime.
- * @author Gavin King
- */
-public class CalendarType extends MutableType implements VersionType {
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
-		Timestamp ts = rs.getTimestamp(name);
-		if (ts!=null) {
-			Calendar cal = new GregorianCalendar();
-			if ( Environment.jvmHasTimestampBug() ) {
-				cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
-			}
-			else {
-				cal.setTime(ts);
-			}
-			return cal;
-		}
-		else {
-			return null;
-		}
-
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		final Calendar cal = (Calendar) value;
-		//st.setTimestamp( index,  new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
-		st.setTimestamp( index,  new Timestamp( cal.getTime().getTime() ), cal );
-	}
-
-	public int sqlType() {
-		return Types.TIMESTAMP;
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return Hibernate.TIMESTAMP.toString( ( (Calendar) value ).getTime() );
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		Calendar result = new GregorianCalendar();
-		result.setTime( ( (Date) Hibernate.TIMESTAMP.fromStringValue(xml) ) );
-		return result;
-	}
-
-	public Object deepCopyNotNull(Object value) throws HibernateException {
-		return ( (Calendar) value ).clone();
-	}
-
-	public Class getReturnedClass() {
-		return Calendar.class;
-	}
-	
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return CalendarComparator.INSTANCE.compare(x, y);
-	}
-
-	public boolean isEqual(Object x, Object y) {
-		if (x==y) return true;
-		if (x==null || y==null) return false;
-
-		Calendar calendar1 = (Calendar) x;
-		Calendar calendar2 = (Calendar) y;
-
-		return calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND)
-			&& calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND)
-			&& calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE)
-			&& calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY)
-			&& calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
-			&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
-			&& calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		Calendar calendar = (Calendar) x;
-		int hashCode = 1;
-		hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND);
-		hashCode = 31 * hashCode + calendar.get(Calendar.SECOND);
-		hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE);
-		hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY);
-		hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH);
-		hashCode = 31 * hashCode + calendar.get(Calendar.MONTH);
-		hashCode = 31 * hashCode + calendar.get(Calendar.YEAR);
-		return hashCode;
-	}
-
-	public String getName() {
-		return "calendar";
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return seed( session );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return Calendar.getInstance();
-	}
-
-	public Comparator getComparator() {
-		return CalendarComparator.INSTANCE;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CalendarType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CalendarType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,147 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.cfg.Environment;
+import org.hibernate.util.CalendarComparator;
+
+/**
+ * <tt>calendar</tt>: A type mapping for a <tt>Calendar</tt> object that
+ * represents a datetime.
+ * @author Gavin King
+ */
+public class CalendarType extends MutableType implements VersionType {
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+		Timestamp ts = rs.getTimestamp(name);
+		if (ts!=null) {
+			Calendar cal = new GregorianCalendar();
+			if ( Environment.jvmHasTimestampBug() ) {
+				cal.setTime( new Date( ts.getTime() + ts.getNanos() / 1000000 ) );
+			}
+			else {
+				cal.setTime(ts);
+			}
+			return cal;
+		}
+		else {
+			return null;
+		}
+
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		final Calendar cal = (Calendar) value;
+		//st.setTimestamp( index,  new Timestamp( cal.getTimeInMillis() ), cal ); //JDK 1.5 only
+		st.setTimestamp( index,  new Timestamp( cal.getTime().getTime() ), cal );
+	}
+
+	public int sqlType() {
+		return Types.TIMESTAMP;
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return Hibernate.TIMESTAMP.toString( ( (Calendar) value ).getTime() );
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		Calendar result = new GregorianCalendar();
+		result.setTime( ( (Date) Hibernate.TIMESTAMP.fromStringValue(xml) ) );
+		return result;
+	}
+
+	public Object deepCopyNotNull(Object value) throws HibernateException {
+		return ( (Calendar) value ).clone();
+	}
+
+	public Class getReturnedClass() {
+		return Calendar.class;
+	}
+	
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return CalendarComparator.INSTANCE.compare(x, y);
+	}
+
+	public boolean isEqual(Object x, Object y) {
+		if (x==y) return true;
+		if (x==null || y==null) return false;
+
+		Calendar calendar1 = (Calendar) x;
+		Calendar calendar2 = (Calendar) y;
+
+		return calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND)
+			&& calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND)
+			&& calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE)
+			&& calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY)
+			&& calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH)
+			&& calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH)
+			&& calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		Calendar calendar = (Calendar) x;
+		int hashCode = 1;
+		hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND);
+		hashCode = 31 * hashCode + calendar.get(Calendar.SECOND);
+		hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE);
+		hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY);
+		hashCode = 31 * hashCode + calendar.get(Calendar.DAY_OF_MONTH);
+		hashCode = 31 * hashCode + calendar.get(Calendar.MONTH);
+		hashCode = 31 * hashCode + calendar.get(Calendar.YEAR);
+		return hashCode;
+	}
+
+	public String getName() {
+		return "calendar";
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return seed( session );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return Calendar.getInstance();
+	}
+
+	public Comparator getComparator() {
+		return CalendarComparator.INSTANCE;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CharArrayType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,23 +0,0 @@
-//$Id: $
-package org.hibernate.type;
-
-/**
- * put char[] into VARCHAR
- * @author Emmanuel Bernard
- */
-public class CharArrayType extends AbstractCharArrayType {
-
-	protected Object toExternalFormat(char[] chars) {
-		return chars;
-	}
-
-	protected char[] toInternalFormat(Object chars) {
-		return (char[]) chars;
-	}
-
-	public Class getReturnedClass() {
-		return char[].class;
-	}
-
-	public String getName() { return "characters"; }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CharArrayType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+/**
+ * put char[] into VARCHAR
+ * @author Emmanuel Bernard
+ */
+public class CharArrayType extends AbstractCharArrayType {
+
+	protected Object toExternalFormat(char[] chars) {
+		return chars;
+	}
+
+	protected char[] toInternalFormat(Object chars) {
+		return (char[]) chars;
+	}
+
+	public Class getReturnedClass() {
+		return char[].class;
+	}
+
+	public String getName() { return "characters"; }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CharBooleanType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,70 +0,0 @@
-//$Id: CharBooleanType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-
-/**
- * Superclass for types that map Java boolean to SQL CHAR(1).
- * @author Gavin King
- */
-public abstract class CharBooleanType extends BooleanType {
-
-	protected abstract String getTrueString();
-	protected abstract String getFalseString();
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		String code = rs.getString(name);
-		if ( code==null || code.length()==0 ) {
-			return null;
-		}
-		else {
-			return getTrueString().equalsIgnoreCase( code.trim() ) ? 
-					Boolean.TRUE : Boolean.FALSE;
-		}
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws SQLException {
-		st.setString( index, toCharacter(value) );
-
-	}
-
-	public int sqlType() {
-		return Types.CHAR;
-	}
-
-	private String toCharacter(Object value) {
-		return ( (Boolean) value ).booleanValue() ? getTrueString() : getFalseString();
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return "'" + toCharacter(value) + "'";
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		if ( getTrueString().equalsIgnoreCase(xml) ) {
-			return Boolean.TRUE;
-		}
-		else if ( getFalseString().equalsIgnoreCase(xml) ) {
-			return Boolean.FALSE;
-		}
-		else {
-			throw new HibernateException("Could not interpret: " + xml);
-		}
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CharBooleanType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharBooleanType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+
+/**
+ * Superclass for types that map Java boolean to SQL CHAR(1).
+ * @author Gavin King
+ */
+public abstract class CharBooleanType extends BooleanType {
+
+	protected abstract String getTrueString();
+	protected abstract String getFalseString();
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		String code = rs.getString(name);
+		if ( code==null || code.length()==0 ) {
+			return null;
+		}
+		else {
+			return getTrueString().equalsIgnoreCase( code.trim() ) ? 
+					Boolean.TRUE : Boolean.FALSE;
+		}
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws SQLException {
+		st.setString( index, toCharacter(value) );
+
+	}
+
+	public int sqlType() {
+		return Types.CHAR;
+	}
+
+	private String toCharacter(Object value) {
+		return ( (Boolean) value ).booleanValue() ? getTrueString() : getFalseString();
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return "'" + toCharacter(value) + "'";
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		if ( getTrueString().equalsIgnoreCase(xml) ) {
+			return Boolean.TRUE;
+		}
+		else if ( getFalseString().equalsIgnoreCase(xml) ) {
+			return Boolean.FALSE;
+		}
+		else {
+			throw new HibernateException("Could not interpret: " + xml);
+		}
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-//$Id: $
-package org.hibernate.type;
-
-import org.hibernate.HibernateException;
-
-/**
- * Bridge Character[] and VARCHAR
- * @author Emmanuel Bernard
- */
-public class CharacterArrayType extends AbstractCharArrayType {
-	protected Object toExternalFormat(char[] chars) {
-		if (chars == null) return null;
-		Character[] characters = new Character[chars.length];
-		for (int i = 0 ; i < chars.length ; i++) {
-			characters[i] = new Character( chars[i] );
-		}
-		return characters;
-	}
-
-	protected char[] toInternalFormat(Object value) {
-		if (value == null) return null;
-		Character[] characters = (Character[]) value;
-		char[] chars = new char[characters.length];
-		for (int i = 0 ; i < characters.length ; i++) {
-			if (characters[i] == null)
-				throw new HibernateException("Unable to store an Character[] when one of its element is null");
-			chars[i] = characters[i].charValue();
-		}
-		return chars;
-	}
-
-	public Class getReturnedClass() {
-		return Character[].class;
-	}
-
-	public String getName() { return "wrapper-characters"; }
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CharacterArrayType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterArrayType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,60 @@
+/*
+ * 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.type;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Bridge Character[] and VARCHAR
+ * @author Emmanuel Bernard
+ */
+public class CharacterArrayType extends AbstractCharArrayType {
+	protected Object toExternalFormat(char[] chars) {
+		if (chars == null) return null;
+		Character[] characters = new Character[chars.length];
+		for (int i = 0 ; i < chars.length ; i++) {
+			characters[i] = new Character( chars[i] );
+		}
+		return characters;
+	}
+
+	protected char[] toInternalFormat(Object value) {
+		if (value == null) return null;
+		Character[] characters = (Character[]) value;
+		char[] chars = new char[characters.length];
+		for (int i = 0 ; i < characters.length ; i++) {
+			if (characters[i] == null)
+				throw new HibernateException("Unable to store an Character[] when one of its element is null");
+			chars[i] = characters[i].charValue();
+		}
+		return chars;
+	}
+
+	public Class getReturnedClass() {
+		return Character[].class;
+	}
+
+	public String getName() { return "wrapper-characters"; }
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CharacterType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,68 +0,0 @@
-//$Id: CharacterType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>character</tt>: A type that maps an SQL CHAR(1) to a Java Character.
- * @author Gavin King
- */
-public class CharacterType extends PrimitiveType implements DiscriminatorType {
-
-	public Serializable getDefaultValue() {
-		throw new UnsupportedOperationException("not a valid id type");
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		String str = rs.getString(name);
-		if (str==null) {
-			return null;
-		}
-		else {
-			return new Character( str.charAt(0) );
-		}
-	}
-
-	public Class getPrimitiveClass() {
-		return char.class;
-	}
-
-	public Class getReturnedClass() {
-		return Character.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		st.setString( index, (value).toString() );
-	}
-
-	public int sqlType() {
-		return Types.CHAR;
-	}
-	public String getName() { return "character"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return '\'' + value.toString() + '\'';
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		if ( xml.length() != 1 ) throw new MappingException("multiple or zero characters found parsing string");
-		return new Character( xml.charAt(0) );
-	}
-
-	public Object fromStringValue(String xml) {
-		return new Character( xml.charAt(0) );
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CharacterType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CharacterType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,91 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>character</tt>: A type that maps an SQL CHAR(1) to a Java Character.
+ * @author Gavin King
+ */
+public class CharacterType extends PrimitiveType implements DiscriminatorType {
+
+	public Serializable getDefaultValue() {
+		throw new UnsupportedOperationException("not a valid id type");
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		String str = rs.getString(name);
+		if (str==null) {
+			return null;
+		}
+		else {
+			return new Character( str.charAt(0) );
+		}
+	}
+
+	public Class getPrimitiveClass() {
+		return char.class;
+	}
+
+	public Class getReturnedClass() {
+		return Character.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		st.setString( index, (value).toString() );
+	}
+
+	public int sqlType() {
+		return Types.CHAR;
+	}
+	public String getName() { return "character"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return '\'' + value.toString() + '\'';
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		if ( xml.length() != 1 ) throw new MappingException("multiple or zero characters found parsing string");
+		return new Character( xml.charAt(0) );
+	}
+
+	public Object fromStringValue(String xml) {
+		return new Character( xml.charAt(0) );
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ClassType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-//$Id: ClassType.java 4582 2004-09-25 11:22:20Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * <tt>class</tt>: A type that maps an SQL VARCHAR to a Java Class.
- * @author Gavin King
- */
-public class ClassType extends ImmutableType {
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		String str = (String) Hibernate.STRING.get(rs, name);
-		if (str == null) {
-			return null;
-		}
-		else {
-			try {
-				return ReflectHelper.classForName(str);
-			}
-			catch (ClassNotFoundException cnfe) {
-				throw new HibernateException("Class not found: " + str);
-			}
-		}
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		//TODO: would be nice to handle proxy classes elegantly!
-		Hibernate.STRING.set(st, ( (Class) value ).getName(), index);
-	}
-
-	public int sqlType() {
-		return Hibernate.STRING.sqlType();
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return ( (Class) value ).getName();
-	}
-
-	public Class getReturnedClass() {
-		return Class.class;
-	}
-
-	public String getName() {
-		return "class";
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		try {
-			return ReflectHelper.classForName(xml);
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new HibernateException("could not parse xml", cnfe);
-		}
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ClassType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClassType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * <tt>class</tt>: A type that maps an SQL VARCHAR to a Java Class.
+ * @author Gavin King
+ */
+public class ClassType extends ImmutableType {
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		String str = (String) Hibernate.STRING.get(rs, name);
+		if (str == null) {
+			return null;
+		}
+		else {
+			try {
+				return ReflectHelper.classForName(str);
+			}
+			catch (ClassNotFoundException cnfe) {
+				throw new HibernateException("Class not found: " + str);
+			}
+		}
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		//TODO: would be nice to handle proxy classes elegantly!
+		Hibernate.STRING.set(st, ( (Class) value ).getName(), index);
+	}
+
+	public int sqlType() {
+		return Hibernate.STRING.sqlType();
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return ( (Class) value ).getName();
+	}
+
+	public Class getReturnedClass() {
+		return Class.class;
+	}
+
+	public String getName() {
+		return "class";
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		try {
+			return ReflectHelper.classForName(xml);
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new HibernateException("could not parse xml", cnfe);
+		}
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ClobType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,169 +0,0 @@
-//$Id: ClobType.java 7644 2005-07-25 06:53:09Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.Clob;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Map;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.lob.ClobImpl;
-import org.hibernate.lob.SerializableClob;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * <tt>clob</tt>: A type that maps an SQL CLOB to a java.sql.Clob.
- * @author Gavin King
- */
-public class ClobType extends AbstractType {
-
-	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
-	throws HibernateException, SQLException {
-		
-		if (value==null) {
-			st.setNull(index, Types.CLOB);
-		}
-		else {
-		
-			if (value instanceof SerializableClob) {
-				value = ( (SerializableClob) value ).getWrappedClob();
-			}
-		
-			final boolean useReader = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
-				(value instanceof ClobImpl);
-			
-			if ( useReader ) {
-				ClobImpl clob = (ClobImpl) value;
-				st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
-			}
-			else {
-				st.setClob(index, (Clob) value);
-			}
-			
-		}
-		
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		Clob value = rs.getClob(name);
-		return rs.wasNull() ? null : new SerializableClob(value);
-	}
-
-	public Class getReturnedClass() {
-		return Clob.class;
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
-		return x == y;
-	}
-	
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return System.identityHashCode(x);
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return 0; //lobs cannot be compared
-	}
-
-	public String getName() {
-		return "clob";
-	}
-	
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-		throws HibernateException {
-		throw new UnsupportedOperationException("Clobs are not cacheable");
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)  {
-		return value;
-	}
-	
-	public Object fromXMLNode(Node xml, Mapping factory) {
-		return Hibernate.createClob( xml.getText() );
-	}
-	
-	public int getColumnSpan(Mapping mapping) {
-		return 1;
-	}
-	
-	public boolean isMutable() {
-		return false;
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String name,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get(rs, name);
-	}
-	
-	public Object nullSafeGet(ResultSet rs, String[] names,
-			SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return get( rs, names[0] );
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			boolean[] settable, SessionImplementor session)
-			throws HibernateException, SQLException {
-		if ( settable[0] ) set(st, value, index, session);
-	}
-	
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-		set(st, value, index, session);
-	}
-	
-	public Object replace(Object original, Object target,
-			SessionImplementor session, Object owner, Map copyCache)
-			throws HibernateException {
-		//Clobs are ignored by merge() operation
-		return target;
-	}
-	
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return new int[] { Types.CLOB };
-	}
-	
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
-		if (value!=null) {
-			Clob clob = (Clob) value;
-			try {
-				int len = (int) clob.length();
-				node.setText( clob.getSubString(0, len) );
-			}
-			catch (SQLException sqle) {
-				throw new HibernateException("could not read XML from Clob", sqle);
-			}
-		}
-	}
-	
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-		return value==null ? "null" : value.toString();
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return checkable[0] && isDirty(old, current, session);
-	}
-	
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ClobType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ClobType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,192 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.Clob;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.lob.ClobImpl;
+import org.hibernate.lob.SerializableClob;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * <tt>clob</tt>: A type that maps an SQL CLOB to a java.sql.Clob.
+ * @author Gavin King
+ */
+public class ClobType extends AbstractType {
+
+	public void set(PreparedStatement st, Object value, int index, SessionImplementor session) 
+	throws HibernateException, SQLException {
+		
+		if (value==null) {
+			st.setNull(index, Types.CLOB);
+		}
+		else {
+		
+			if (value instanceof SerializableClob) {
+				value = ( (SerializableClob) value ).getWrappedClob();
+			}
+		
+			final boolean useReader = session.getFactory().getDialect().useInputStreamToInsertBlob() && 
+				(value instanceof ClobImpl);
+			
+			if ( useReader ) {
+				ClobImpl clob = (ClobImpl) value;
+				st.setCharacterStream( index, clob.getCharacterStream(), (int) clob.length() );
+			}
+			else {
+				st.setClob(index, (Clob) value);
+			}
+			
+		}
+		
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		Clob value = rs.getClob(name);
+		return rs.wasNull() ? null : new SerializableClob(value);
+	}
+
+	public Class getReturnedClass() {
+		return Clob.class;
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode) {
+		return x == y;
+	}
+	
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return System.identityHashCode(x);
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return 0; //lobs cannot be compared
+	}
+
+	public String getName() {
+		return "clob";
+	}
+	
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+		throws HibernateException {
+		throw new UnsupportedOperationException("Clobs are not cacheable");
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)  {
+		return value;
+	}
+	
+	public Object fromXMLNode(Node xml, Mapping factory) {
+		return Hibernate.createClob( xml.getText() );
+	}
+	
+	public int getColumnSpan(Mapping mapping) {
+		return 1;
+	}
+	
+	public boolean isMutable() {
+		return false;
+	}
+	
+	public Object nullSafeGet(ResultSet rs, String name,
+			SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return get(rs, name);
+	}
+	
+	public Object nullSafeGet(ResultSet rs, String[] names,
+			SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return get( rs, names[0] );
+	}
+	
+	public void nullSafeSet(PreparedStatement st, Object value, int index,
+			boolean[] settable, SessionImplementor session)
+			throws HibernateException, SQLException {
+		if ( settable[0] ) set(st, value, index, session);
+	}
+	
+	public void nullSafeSet(PreparedStatement st, Object value, int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+		set(st, value, index, session);
+	}
+	
+	public Object replace(Object original, Object target,
+			SessionImplementor session, Object owner, Map copyCache)
+			throws HibernateException {
+		//Clobs are ignored by merge() operation
+		return target;
+	}
+	
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return new int[] { Types.CLOB };
+	}
+	
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) {
+		if (value!=null) {
+			Clob clob = (Clob) value;
+			try {
+				int len = (int) clob.length();
+				node.setText( clob.getSubString(0, len) );
+			}
+			catch (SQLException sqle) {
+				throw new HibernateException("could not read XML from Clob", sqle);
+			}
+		}
+	}
+	
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+		return value==null ? "null" : value.toString();
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return checkable[0] && isDirty(old, current, session);
+	}
+	
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CollectionType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,684 +0,0 @@
-// $Id: CollectionType.java 11302 2007-03-19 20:44:11Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.dom4j.Node;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.CollectionKey;
-import org.hibernate.engine.EntityEntry;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.persister.collection.QueryableCollection;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.MarkerObject;
-
-/**
- * A type that handles Hibernate <tt>PersistentCollection</tt>s (including arrays).
- * 
- * @author Gavin King
- */
-public abstract class CollectionType extends AbstractType implements AssociationType {
-
-	private static final Object NOT_NULL_COLLECTION = new MarkerObject( "NOT NULL COLLECTION" );
-	public static final Object UNFETCHED_COLLECTION = new MarkerObject( "UNFETCHED COLLECTION" );
-
-	private final String role;
-	private final String foreignKeyPropertyName;
-	private final boolean isEmbeddedInXML;
-
-	public CollectionType(String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) {
-		this.role = role;
-		this.foreignKeyPropertyName = foreignKeyPropertyName;
-		this.isEmbeddedInXML = isEmbeddedInXML;
-	}
-	
-	public boolean isEmbeddedInXML() {
-		return isEmbeddedInXML;
-	}
-
-	public String getRole() {
-		return role;
-	}
-
-	public Object indexOf(Object collection, Object element) {
-		throw new UnsupportedOperationException( "generic collections don't have indexes" );
-	}
-
-	public boolean contains(Object collection, Object childObject, SessionImplementor session) {
-		// we do not have to worry about queued additions to uninitialized
-		// collections, since they can only occur for inverse collections!
-		Iterator elems = getElementsIterator( collection, session );
-		while ( elems.hasNext() ) {
-			Object element = elems.next();
-			// worrying about proxies is perhaps a little bit of overkill here...
-			if ( element instanceof HibernateProxy ) {
-				LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();
-				if ( !li.isUninitialized() ) element = li.getImplementation();
-			}
-			if ( element == childObject ) return true;
-		}
-		return false;
-	}
-
-	public boolean isCollectionType() {
-		return true;
-	}
-
-	public final boolean isEqual(Object x, Object y, EntityMode entityMode) {
-		return x == y
-			|| ( x instanceof PersistentCollection && ( (PersistentCollection) x ).isWrapper( y ) )
-			|| ( y instanceof PersistentCollection && ( (PersistentCollection) y ).isWrapper( x ) );
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return 0; // collections cannot be compared
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		throw new UnsupportedOperationException( "cannot perform lookups on collections" );
-	}
-
-	/**
-	 * Instantiate an uninitialized collection wrapper or holder. Callers MUST add the holder to the
-	 * persistence context!
-	 *
-	 * @param session The session from which the request is originating.
-	 * @param persister The underlying collection persister (metadata)
-	 * @param key The owner key.
-	 * @return The instantiated collection.
-	 */
-	public abstract PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key);
-
-	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws SQLException {
-		return nullSafeGet( rs, new String[] { name }, session, owner );
-	}
-
-	public Object nullSafeGet(ResultSet rs, String[] name, SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return resolve( null, session, owner );
-	}
-
-	public final void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable,
-			SessionImplementor session) throws HibernateException, SQLException {
-		//NOOP
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value, int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-	}
-
-	public int[] sqlTypes(Mapping session) throws MappingException {
-		return ArrayHelper.EMPTY_INT_ARRAY;
-	}
-
-	public int getColumnSpan(Mapping session) throws MappingException {
-		return 0;
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-		if ( value == null ) {
-			return "null";
-		}
-		else if ( !Hibernate.isInitialized( value ) ) {
-			return "<uninitialized>";
-		}
-		else {
-			return renderLoggableString( value, factory );
-		}
-	}
-
-	protected String renderLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-		if ( Element.class.isInstance( value ) ) {
-			// for DOM4J "collections" only
-			// TODO: it would be better if this was done at the higher level by Printer
-			return ( ( Element ) value ).asXML();
-		}
-		else {
-			List list = new ArrayList();
-			Type elemType = getElementType( factory );
-			Iterator iter = getElementsIterator( value );
-			while ( iter.hasNext() ) {
-				list.add( elemType.toLoggableString( iter.next(), factory ) );
-			}
-			return list.toString();
-		}
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
-			throws HibernateException {
-		return value;
-	}
-
-	public String getName() {
-		return getReturnedClass().getName() + '(' + getRole() + ')';
-	}
-
-	/**
-	 * Get an iterator over the element set of the collection, which may not yet be wrapped
-	 *
-	 * @param collection The collection to be iterated
-	 * @param session The session from which the request is originating.
-	 * @return The iterator.
-	 */
-	public Iterator getElementsIterator(Object collection, SessionImplementor session) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			final SessionFactoryImplementor factory = session.getFactory();
-			final CollectionPersister persister = factory.getCollectionPersister( getRole() );
-			final Type elementType = persister.getElementType();
-			
-			List elements = ( (Element) collection ).elements( persister.getElementNodeName() );
-			ArrayList results = new ArrayList();
-			for ( int i=0; i<elements.size(); i++ ) {
-				Element value = (Element) elements.get(i);
-				results.add( elementType.fromXMLNode( value, factory ) );
-			}
-			return results.iterator();
-		}
-		else {
-			return getElementsIterator(collection);
-		}
-	}
-
-	/**
-	 * Get an iterator over the element set of the collection in POJO mode
-	 *
-	 * @param collection The collection to be iterated
-	 * @return The iterator.
-	 */
-	protected Iterator getElementsIterator(Object collection) {
-		return ( (Collection) collection ).iterator();
-	}
-
-	public boolean isMutable() {
-		return false;
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-		//remember the uk value
-		
-		//This solution would allow us to eliminate the owner arg to disassemble(), but
-		//what if the collection was null, and then later had elements added? seems unsafe
-		//session.getPersistenceContext().getCollectionEntry( (PersistentCollection) value ).getKey();
-		
-		final Serializable key = getKeyOfOwner(owner, session);
-		if (key==null) {
-			return null;
-		}
-		else {
-			return getPersister(session)
-					.getKeyType()
-					.disassemble( key, session, owner );
-		}
-	}
-
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
-			throws HibernateException {
-		//we must use the "remembered" uk value, since it is 
-		//not available from the EntityEntry during assembly
-		if (cached==null) {
-			return null;
-		}
-		else {
-			final Serializable key = (Serializable) getPersister(session)
-					.getKeyType()
-					.assemble( cached, session, owner);
-			return resolveKey( key, session, owner );
-		}
-	}
-
-	/**
-	 * Is the owning entity versioned?
-	 *
-	 * @param session The session from which the request is originating.
-	 * @return True if the collection owner is versioned; false otherwise.
-	 * @throws org.hibernate.MappingException Indicates our persister could not be located.
-	 */
-	private boolean isOwnerVersioned(SessionImplementor session) throws MappingException {
-		return getPersister( session ).getOwnerEntityPersister().isVersioned();
-	}
-
-	/**
-	 * Get our underlying collection persister (using the session to access the
-	 * factory).
-	 *
-	 * @param session The session from which the request is originating.
-	 * @return The underlying collection persister
-	 */
-	private CollectionPersister getPersister(SessionImplementor session) {
-		return session.getFactory().getCollectionPersister( role );
-	}
-
-	public boolean isDirty(Object old, Object current, SessionImplementor session)
-			throws HibernateException {
-
-		// collections don't dirty an unversioned parent entity
-
-		// TODO: I don't really like this implementation; it would be better if
-		// this was handled by searchForDirtyCollections()
-		return isOwnerVersioned( session ) && super.isDirty( old, current, session );
-		// return false;
-
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
-			throws HibernateException {
-		return isDirty(old, current, session);
-	}
-
-	/**
-	 * Wrap the naked collection instance in a wrapper, or instantiate a
-	 * holder. Callers <b>MUST</b> add the holder to the persistence context!
-	 *
-	 * @param session The session from which the request is originating.
-	 * @param collection The bare collection to be wrapped.
-	 * @return The wrapped collection.
-	 */
-	public abstract PersistentCollection wrap(SessionImplementor session, Object collection);
-
-	/**
-	 * Note: return true because this type is castable to <tt>AssociationType</tt>. Not because
-	 * all collections are associations.
-	 */
-	public boolean isAssociationType() {
-		return true;
-	}
-
-	public ForeignKeyDirection getForeignKeyDirection() {
-		return ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;
-	}
-
-	/**
-	 * Get the key value from the owning entity instance, usually the identifier, but might be some
-	 * other unique key, in the case of property-ref
-	 *
-	 * @param owner The collection owner
-	 * @param session The session from which the request is originating.
-	 * @return The collection owner's key
-	 */
-	public Serializable getKeyOfOwner(Object owner, SessionImplementor session) {
-		
-		EntityEntry entityEntry = session.getPersistenceContext().getEntry( owner );
-		if ( entityEntry == null ) return null; // This just handles a particular case of component
-									  // projection, perhaps get rid of it and throw an exception
-		
-		if ( foreignKeyPropertyName == null ) {
-			return entityEntry.getId();
-		}
-		else {
-			// TODO: at the point where we are resolving collection references, we don't
-			// know if the uk value has been resolved (depends if it was earlier or
-			// later in the mapping document) - now, we could try and use e.getStatus()
-			// to decide to semiResolve(), trouble is that initializeEntity() reuses
-			// the same array for resolved and hydrated values
-			Object id;
-			if ( entityEntry.getLoadedState() != null ) {
-				id = entityEntry.getLoadedValue( foreignKeyPropertyName );
-			}
-			else {
-				id = entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName, session.getEntityMode() );
-			}
-
-			// NOTE VERY HACKISH WORKAROUND!!
-			// TODO: Fix this so it will work for non-POJO entity mode
-			Type keyType = getPersister( session ).getKeyType();
-			if ( !keyType.getReturnedClass().isInstance( id ) ) {
-				id = (Serializable) keyType.semiResolve(
-						entityEntry.getLoadedValue( foreignKeyPropertyName ),
-						session,
-						owner 
-					);
-			}
-
-			return (Serializable) id;
-		}
-	}
-
-	/**
-	 * Get the id value from the owning entity key, usually the same as the key, but might be some
-	 * other property, in the case of property-ref
-	 *
-	 * @param key The collection owner key
-	 * @param session The session from which the request is originating.
-	 * @return The collection owner's id, if it can be obtained from the key;
-	 * otherwise, null is returned
-	 */
-	public Serializable getIdOfOwnerOrNull(Serializable key, SessionImplementor session) {
-		Serializable ownerId = null;
-		if ( foreignKeyPropertyName == null ) {
-			ownerId = key;
-		}
-		else {
-			Type keyType = getPersister( session ).getKeyType();
-			EntityPersister ownerPersister = getPersister( session ).getOwnerEntityPersister();
-			// TODO: Fix this so it will work for non-POJO entity mode
-			Class ownerMappedClass = ownerPersister.getMappedClass( session.getEntityMode() );
-			if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) &&
-					keyType.getReturnedClass().isInstance( key ) ) {
-				// the key is the owning entity itself, so get the ID from the key
-				ownerId = ownerPersister.getIdentifier( key, session.getEntityMode() );
-			}
-			else {
-				// TODO: check if key contains the owner ID
-			}
-		}
-		return ownerId;
-	}
-
-	public Object hydrate(ResultSet rs, String[] name, SessionImplementor session, Object owner) {
-		// can't just return null here, since that would
-		// cause an owning component to become null
-		return NOT_NULL_COLLECTION;
-	}
-
-	public Object resolve(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-		
-		return resolveKey( getKeyOfOwner( owner, session ), session, owner );
-	}
-	
-	private Object resolveKey(Serializable key, SessionImplementor session, Object owner) {
-		// if (key==null) throw new AssertionFailure("owner identifier unknown when re-assembling
-		// collection reference");
-		return key == null ? null : // TODO: can this case really occur??
-			getCollection( key, session, owner );
-	}
-
-	public Object semiResolve(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-		throw new UnsupportedOperationException(
-			"collection mappings may not form part of a property-ref" );
-	}
-
-	public boolean isArrayType() {
-		return false;
-	}
-
-	public boolean useLHSPrimaryKey() {
-		return foreignKeyPropertyName == null;
-	}
-
-	public String getRHSUniqueKeyPropertyName() {
-		return null;
-	}
-
-	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory)
-			throws MappingException {
-		return (Joinable) factory.getCollectionPersister( role );
-	}
-
-	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return false;
-	}
-
-	public String getAssociatedEntityName(SessionFactoryImplementor factory)
-			throws MappingException {
-		try {
-			
-			QueryableCollection collectionPersister = (QueryableCollection) factory
-					.getCollectionPersister( role );
-			
-			if ( !collectionPersister.getElementType().isEntityType() ) {
-				throw new MappingException( 
-						"collection was not an association: " + 
-						collectionPersister.getRole() 
-					);
-			}
-			
-			return collectionPersister.getElementPersister().getEntityName();
-			
-		}
-		catch (ClassCastException cce) {
-			throw new MappingException( "collection role is not queryable " + role );
-		}
-	}
-
-	/**
-	 * Replace the elements of a collection with the elements of another collection.
-	 *
-	 * @param original The 'source' of the replacement elements (where we copy from)
-	 * @param target The target of the replacement elements (where we copy to)
-	 * @param owner The owner of the collection being merged
-	 * @param copyCache The map of elements already replaced.
-	 * @param session The session from which the merge event originated.
-	 * @return The merged collection.
-	 */
-	public Object replaceElements(
-			Object original,
-			Object target,
-			Object owner,
-			Map copyCache,
-			SessionImplementor session) {
-		// TODO: does not work for EntityMode.DOM4J yet!
-		java.util.Collection result = ( java.util.Collection ) target;
-		result.clear();
-
-		// copy elements into newly empty target collection
-		Type elemType = getElementType( session.getFactory() );
-		Iterator iter = ( (java.util.Collection) original ).iterator();
-		while ( iter.hasNext() ) {
-			result.add( elemType.replace( iter.next(), null, session, owner, copyCache ) );
-		}
-
-		// if the original is a PersistentCollection, and that original
-		// was not flagged as dirty, then reset the target's dirty flag
-		// here after the copy operation.
-		// </p>
-		// One thing to be careful of here is a "bare" original collection
-		// in which case we should never ever ever reset the dirty flag
-		// on the target because we simply do not know...
-		if ( original instanceof PersistentCollection ) {
-			if ( result instanceof PersistentCollection ) {
-				if ( ! ( ( PersistentCollection ) original ).isDirty() ) {
-					( ( PersistentCollection ) result ).clearDirty();
-				}
-			}
-		}
-
-		return result;
-	}
-
-	/**
-	 * Instantiate a new "underlying" collection exhibiting the same capacity
-	 * charactersitcs and the passed "original".
-	 *
-	 * @param original The original collection.
-	 * @return The newly instantiated collection.
-	 */
-	protected Object instantiateResult(Object original) {
-		// by default just use an unanticipated capacity since we don't
-		// know how to extract the capacity to use from original here...
-		return instantiate( -1 );
-	}
-
-	/**
-	 * Instantiate an empty instance of the "underlying" collection (not a wrapper),
-	 * but with the given anticipated size (i.e. accounting for initial capacity
-	 * and perhaps load factor).
-	 *
-	 * @param anticipatedSize The anticipated size of the instaniated collection
-	 * after we are done populating it.
-	 * @return A newly instantiated collection to be wrapped.
-	 */
-	public abstract Object instantiate(int anticipatedSize);
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object replace(
-			final Object original,
-			final Object target,
-			final SessionImplementor session,
-			final Object owner,
-			final Map copyCache) throws HibernateException {
-		if ( original == null ) {
-			return null;
-		}
-		if ( !Hibernate.isInitialized( original ) ) {
-			return target;
-		}
-
-		// for a null target, or a target which is the same as the original, we
-		// need to put the merged elements in a new collection
-		Object result = target == null || target == original ? instantiateResult( original ) : target;
-		
-		//for arrays, replaceElements() may return a different reference, since
-		//the array length might not match
-		result = replaceElements( original, result, owner, copyCache, session );
-
-		if ( original == target ) {
-			// get the elements back into the target making sure to handle dirty flag
-			boolean wasClean = PersistentCollection.class.isInstance( target ) && !( ( PersistentCollection ) target ).isDirty();
-			//TODO: this is a little inefficient, don't need to do a whole
-			//      deep replaceElements() call
-			replaceElements( result, target, owner, copyCache, session );
-			if ( wasClean ) {
-				( ( PersistentCollection ) target ).clearDirty();
-			}
-			result = target;
-		}
-
-		return result;
-	}
-
-	/**
-	 * Get the Hibernate type of the collection elements
-	 *
-	 * @param factory The session factory.
-	 * @return The type of the collection elements
-	 * @throws MappingException Indicates the underlying persister could not be located.
-	 */
-	public final Type getElementType(SessionFactoryImplementor factory) throws MappingException {
-		return factory.getCollectionPersister( getRole() ).getElementType();
-	}
-
-	public String toString() {
-		return getClass().getName() + '(' + getRole() + ')';
-	}
-
-	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
-			throws MappingException {
-		return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters );
-	}
-
-	/**
-	 * instantiate a collection wrapper (called when loading an object)
-	 *
-	 * @param key The collection owner key
-	 * @param session The session from which the request is originating.
-	 * @param owner The collection owner
-	 * @return The collection
-	 */
-	public Object getCollection(Serializable key, SessionImplementor session, Object owner) {
-
-		CollectionPersister persister = getPersister( session );
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		final EntityMode entityMode = session.getEntityMode();
-
-		if (entityMode==EntityMode.DOM4J && !isEmbeddedInXML) {
-			return UNFETCHED_COLLECTION;
-		}
-		
-		// check if collection is currently being loaded
-		PersistentCollection collection = persistenceContext.getLoadContexts().locateLoadingCollection( persister, key );
-		
-		if ( collection == null ) {
-			
-			// check if it is already completely loaded, but unowned
-			collection = persistenceContext.useUnownedCollection( new CollectionKey(persister, key, entityMode) );
-			
-			if ( collection == null ) {
-				// create a new collection wrapper, to be initialized later
-				collection = instantiate( session, persister, key );
-				collection.setOwner(owner);
-	
-				persistenceContext.addUninitializedCollection( persister, collection, key );
-	
-				// some collections are not lazy:
-				if ( initializeImmediately( entityMode ) ) {
-					session.initializeCollection( collection, false );
-				}
-				else if ( !persister.isLazy() ) {
-					persistenceContext.addNonLazyCollection( collection );
-				}
-	
-				if ( hasHolder( entityMode ) ) {
-					session.getPersistenceContext().addCollectionHolder( collection );
-				}
-				
-			}
-			
-		}
-		
-		collection.setOwner(owner);
-
-		return collection.getValue();
-	}
-
-	public boolean hasHolder(EntityMode entityMode) {
-		return entityMode == EntityMode.DOM4J;
-	}
-
-	protected boolean initializeImmediately(EntityMode entityMode) {
-		return entityMode == EntityMode.DOM4J;
-	}
-
-	public String getLHSPropertyName() {
-		return foreignKeyPropertyName;
-	}
-
-	public boolean isXMLElement() {
-		return true;
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return xml;
-	}
-
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		if ( !isEmbeddedInXML ) {
-			node.detach();
-		}
-		else {
-			replaceNode( node, (Element) value );
-		}
-	}
-	
-	/**
-	 * We always need to dirty check the collection because we sometimes 
-	 * need to incremement version number of owner and also because of 
-	 * how assemble/disassemble is implemented for uks
-	 */
-	public boolean isAlwaysDirtyChecked() {
-		return true; 
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CollectionType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,707 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.dom4j.Node;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.CollectionKey;
+import org.hibernate.engine.EntityEntry;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.persister.collection.QueryableCollection;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.MarkerObject;
+
+/**
+ * A type that handles Hibernate <tt>PersistentCollection</tt>s (including arrays).
+ * 
+ * @author Gavin King
+ */
+public abstract class CollectionType extends AbstractType implements AssociationType {
+
+	private static final Object NOT_NULL_COLLECTION = new MarkerObject( "NOT NULL COLLECTION" );
+	public static final Object UNFETCHED_COLLECTION = new MarkerObject( "UNFETCHED COLLECTION" );
+
+	private final String role;
+	private final String foreignKeyPropertyName;
+	private final boolean isEmbeddedInXML;
+
+	public CollectionType(String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) {
+		this.role = role;
+		this.foreignKeyPropertyName = foreignKeyPropertyName;
+		this.isEmbeddedInXML = isEmbeddedInXML;
+	}
+	
+	public boolean isEmbeddedInXML() {
+		return isEmbeddedInXML;
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public Object indexOf(Object collection, Object element) {
+		throw new UnsupportedOperationException( "generic collections don't have indexes" );
+	}
+
+	public boolean contains(Object collection, Object childObject, SessionImplementor session) {
+		// we do not have to worry about queued additions to uninitialized
+		// collections, since they can only occur for inverse collections!
+		Iterator elems = getElementsIterator( collection, session );
+		while ( elems.hasNext() ) {
+			Object element = elems.next();
+			// worrying about proxies is perhaps a little bit of overkill here...
+			if ( element instanceof HibernateProxy ) {
+				LazyInitializer li = ( (HibernateProxy) element ).getHibernateLazyInitializer();
+				if ( !li.isUninitialized() ) element = li.getImplementation();
+			}
+			if ( element == childObject ) return true;
+		}
+		return false;
+	}
+
+	public boolean isCollectionType() {
+		return true;
+	}
+
+	public final boolean isEqual(Object x, Object y, EntityMode entityMode) {
+		return x == y
+			|| ( x instanceof PersistentCollection && ( (PersistentCollection) x ).isWrapper( y ) )
+			|| ( y instanceof PersistentCollection && ( (PersistentCollection) y ).isWrapper( x ) );
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return 0; // collections cannot be compared
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		throw new UnsupportedOperationException( "cannot perform lookups on collections" );
+	}
+
+	/**
+	 * Instantiate an uninitialized collection wrapper or holder. Callers MUST add the holder to the
+	 * persistence context!
+	 *
+	 * @param session The session from which the request is originating.
+	 * @param persister The underlying collection persister (metadata)
+	 * @param key The owner key.
+	 * @return The instantiated collection.
+	 */
+	public abstract PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key);
+
+	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner) throws SQLException {
+		return nullSafeGet( rs, new String[] { name }, session, owner );
+	}
+
+	public Object nullSafeGet(ResultSet rs, String[] name, SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return resolve( null, session, owner );
+	}
+
+	public final void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable,
+			SessionImplementor session) throws HibernateException, SQLException {
+		//NOOP
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+	}
+
+	public int[] sqlTypes(Mapping session) throws MappingException {
+		return ArrayHelper.EMPTY_INT_ARRAY;
+	}
+
+	public int getColumnSpan(Mapping session) throws MappingException {
+		return 0;
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+		if ( value == null ) {
+			return "null";
+		}
+		else if ( !Hibernate.isInitialized( value ) ) {
+			return "<uninitialized>";
+		}
+		else {
+			return renderLoggableString( value, factory );
+		}
+	}
+
+	protected String renderLoggableString(Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+		if ( Element.class.isInstance( value ) ) {
+			// for DOM4J "collections" only
+			// TODO: it would be better if this was done at the higher level by Printer
+			return ( ( Element ) value ).asXML();
+		}
+		else {
+			List list = new ArrayList();
+			Type elemType = getElementType( factory );
+			Iterator iter = getElementsIterator( value );
+			while ( iter.hasNext() ) {
+				list.add( elemType.toLoggableString( iter.next(), factory ) );
+			}
+			return list.toString();
+		}
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
+			throws HibernateException {
+		return value;
+	}
+
+	public String getName() {
+		return getReturnedClass().getName() + '(' + getRole() + ')';
+	}
+
+	/**
+	 * Get an iterator over the element set of the collection, which may not yet be wrapped
+	 *
+	 * @param collection The collection to be iterated
+	 * @param session The session from which the request is originating.
+	 * @return The iterator.
+	 */
+	public Iterator getElementsIterator(Object collection, SessionImplementor session) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			final SessionFactoryImplementor factory = session.getFactory();
+			final CollectionPersister persister = factory.getCollectionPersister( getRole() );
+			final Type elementType = persister.getElementType();
+			
+			List elements = ( (Element) collection ).elements( persister.getElementNodeName() );
+			ArrayList results = new ArrayList();
+			for ( int i=0; i<elements.size(); i++ ) {
+				Element value = (Element) elements.get(i);
+				results.add( elementType.fromXMLNode( value, factory ) );
+			}
+			return results.iterator();
+		}
+		else {
+			return getElementsIterator(collection);
+		}
+	}
+
+	/**
+	 * Get an iterator over the element set of the collection in POJO mode
+	 *
+	 * @param collection The collection to be iterated
+	 * @return The iterator.
+	 */
+	protected Iterator getElementsIterator(Object collection) {
+		return ( (Collection) collection ).iterator();
+	}
+
+	public boolean isMutable() {
+		return false;
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+		//remember the uk value
+		
+		//This solution would allow us to eliminate the owner arg to disassemble(), but
+		//what if the collection was null, and then later had elements added? seems unsafe
+		//session.getPersistenceContext().getCollectionEntry( (PersistentCollection) value ).getKey();
+		
+		final Serializable key = getKeyOfOwner(owner, session);
+		if (key==null) {
+			return null;
+		}
+		else {
+			return getPersister(session)
+					.getKeyType()
+					.disassemble( key, session, owner );
+		}
+	}
+
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
+			throws HibernateException {
+		//we must use the "remembered" uk value, since it is 
+		//not available from the EntityEntry during assembly
+		if (cached==null) {
+			return null;
+		}
+		else {
+			final Serializable key = (Serializable) getPersister(session)
+					.getKeyType()
+					.assemble( cached, session, owner);
+			return resolveKey( key, session, owner );
+		}
+	}
+
+	/**
+	 * Is the owning entity versioned?
+	 *
+	 * @param session The session from which the request is originating.
+	 * @return True if the collection owner is versioned; false otherwise.
+	 * @throws org.hibernate.MappingException Indicates our persister could not be located.
+	 */
+	private boolean isOwnerVersioned(SessionImplementor session) throws MappingException {
+		return getPersister( session ).getOwnerEntityPersister().isVersioned();
+	}
+
+	/**
+	 * Get our underlying collection persister (using the session to access the
+	 * factory).
+	 *
+	 * @param session The session from which the request is originating.
+	 * @return The underlying collection persister
+	 */
+	private CollectionPersister getPersister(SessionImplementor session) {
+		return session.getFactory().getCollectionPersister( role );
+	}
+
+	public boolean isDirty(Object old, Object current, SessionImplementor session)
+			throws HibernateException {
+
+		// collections don't dirty an unversioned parent entity
+
+		// TODO: I don't really like this implementation; it would be better if
+		// this was handled by searchForDirtyCollections()
+		return isOwnerVersioned( session ) && super.isDirty( old, current, session );
+		// return false;
+
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
+			throws HibernateException {
+		return isDirty(old, current, session);
+	}
+
+	/**
+	 * Wrap the naked collection instance in a wrapper, or instantiate a
+	 * holder. Callers <b>MUST</b> add the holder to the persistence context!
+	 *
+	 * @param session The session from which the request is originating.
+	 * @param collection The bare collection to be wrapped.
+	 * @return The wrapped collection.
+	 */
+	public abstract PersistentCollection wrap(SessionImplementor session, Object collection);
+
+	/**
+	 * Note: return true because this type is castable to <tt>AssociationType</tt>. Not because
+	 * all collections are associations.
+	 */
+	public boolean isAssociationType() {
+		return true;
+	}
+
+	public ForeignKeyDirection getForeignKeyDirection() {
+		return ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;
+	}
+
+	/**
+	 * Get the key value from the owning entity instance, usually the identifier, but might be some
+	 * other unique key, in the case of property-ref
+	 *
+	 * @param owner The collection owner
+	 * @param session The session from which the request is originating.
+	 * @return The collection owner's key
+	 */
+	public Serializable getKeyOfOwner(Object owner, SessionImplementor session) {
+		
+		EntityEntry entityEntry = session.getPersistenceContext().getEntry( owner );
+		if ( entityEntry == null ) return null; // This just handles a particular case of component
+									  // projection, perhaps get rid of it and throw an exception
+		
+		if ( foreignKeyPropertyName == null ) {
+			return entityEntry.getId();
+		}
+		else {
+			// TODO: at the point where we are resolving collection references, we don't
+			// know if the uk value has been resolved (depends if it was earlier or
+			// later in the mapping document) - now, we could try and use e.getStatus()
+			// to decide to semiResolve(), trouble is that initializeEntity() reuses
+			// the same array for resolved and hydrated values
+			Object id;
+			if ( entityEntry.getLoadedState() != null ) {
+				id = entityEntry.getLoadedValue( foreignKeyPropertyName );
+			}
+			else {
+				id = entityEntry.getPersister().getPropertyValue( owner, foreignKeyPropertyName, session.getEntityMode() );
+			}
+
+			// NOTE VERY HACKISH WORKAROUND!!
+			// TODO: Fix this so it will work for non-POJO entity mode
+			Type keyType = getPersister( session ).getKeyType();
+			if ( !keyType.getReturnedClass().isInstance( id ) ) {
+				id = (Serializable) keyType.semiResolve(
+						entityEntry.getLoadedValue( foreignKeyPropertyName ),
+						session,
+						owner 
+					);
+			}
+
+			return (Serializable) id;
+		}
+	}
+
+	/**
+	 * Get the id value from the owning entity key, usually the same as the key, but might be some
+	 * other property, in the case of property-ref
+	 *
+	 * @param key The collection owner key
+	 * @param session The session from which the request is originating.
+	 * @return The collection owner's id, if it can be obtained from the key;
+	 * otherwise, null is returned
+	 */
+	public Serializable getIdOfOwnerOrNull(Serializable key, SessionImplementor session) {
+		Serializable ownerId = null;
+		if ( foreignKeyPropertyName == null ) {
+			ownerId = key;
+		}
+		else {
+			Type keyType = getPersister( session ).getKeyType();
+			EntityPersister ownerPersister = getPersister( session ).getOwnerEntityPersister();
+			// TODO: Fix this so it will work for non-POJO entity mode
+			Class ownerMappedClass = ownerPersister.getMappedClass( session.getEntityMode() );
+			if ( ownerMappedClass.isAssignableFrom( keyType.getReturnedClass() ) &&
+					keyType.getReturnedClass().isInstance( key ) ) {
+				// the key is the owning entity itself, so get the ID from the key
+				ownerId = ownerPersister.getIdentifier( key, session.getEntityMode() );
+			}
+			else {
+				// TODO: check if key contains the owner ID
+			}
+		}
+		return ownerId;
+	}
+
+	public Object hydrate(ResultSet rs, String[] name, SessionImplementor session, Object owner) {
+		// can't just return null here, since that would
+		// cause an owning component to become null
+		return NOT_NULL_COLLECTION;
+	}
+
+	public Object resolve(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+		
+		return resolveKey( getKeyOfOwner( owner, session ), session, owner );
+	}
+	
+	private Object resolveKey(Serializable key, SessionImplementor session, Object owner) {
+		// if (key==null) throw new AssertionFailure("owner identifier unknown when re-assembling
+		// collection reference");
+		return key == null ? null : // TODO: can this case really occur??
+			getCollection( key, session, owner );
+	}
+
+	public Object semiResolve(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+		throw new UnsupportedOperationException(
+			"collection mappings may not form part of a property-ref" );
+	}
+
+	public boolean isArrayType() {
+		return false;
+	}
+
+	public boolean useLHSPrimaryKey() {
+		return foreignKeyPropertyName == null;
+	}
+
+	public String getRHSUniqueKeyPropertyName() {
+		return null;
+	}
+
+	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory)
+			throws MappingException {
+		return (Joinable) factory.getCollectionPersister( role );
+	}
+
+	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return false;
+	}
+
+	public String getAssociatedEntityName(SessionFactoryImplementor factory)
+			throws MappingException {
+		try {
+			
+			QueryableCollection collectionPersister = (QueryableCollection) factory
+					.getCollectionPersister( role );
+			
+			if ( !collectionPersister.getElementType().isEntityType() ) {
+				throw new MappingException( 
+						"collection was not an association: " + 
+						collectionPersister.getRole() 
+					);
+			}
+			
+			return collectionPersister.getElementPersister().getEntityName();
+			
+		}
+		catch (ClassCastException cce) {
+			throw new MappingException( "collection role is not queryable " + role );
+		}
+	}
+
+	/**
+	 * Replace the elements of a collection with the elements of another collection.
+	 *
+	 * @param original The 'source' of the replacement elements (where we copy from)
+	 * @param target The target of the replacement elements (where we copy to)
+	 * @param owner The owner of the collection being merged
+	 * @param copyCache The map of elements already replaced.
+	 * @param session The session from which the merge event originated.
+	 * @return The merged collection.
+	 */
+	public Object replaceElements(
+			Object original,
+			Object target,
+			Object owner,
+			Map copyCache,
+			SessionImplementor session) {
+		// TODO: does not work for EntityMode.DOM4J yet!
+		java.util.Collection result = ( java.util.Collection ) target;
+		result.clear();
+
+		// copy elements into newly empty target collection
+		Type elemType = getElementType( session.getFactory() );
+		Iterator iter = ( (java.util.Collection) original ).iterator();
+		while ( iter.hasNext() ) {
+			result.add( elemType.replace( iter.next(), null, session, owner, copyCache ) );
+		}
+
+		// if the original is a PersistentCollection, and that original
+		// was not flagged as dirty, then reset the target's dirty flag
+		// here after the copy operation.
+		// </p>
+		// One thing to be careful of here is a "bare" original collection
+		// in which case we should never ever ever reset the dirty flag
+		// on the target because we simply do not know...
+		if ( original instanceof PersistentCollection ) {
+			if ( result instanceof PersistentCollection ) {
+				if ( ! ( ( PersistentCollection ) original ).isDirty() ) {
+					( ( PersistentCollection ) result ).clearDirty();
+				}
+			}
+		}
+
+		return result;
+	}
+
+	/**
+	 * Instantiate a new "underlying" collection exhibiting the same capacity
+	 * charactersitcs and the passed "original".
+	 *
+	 * @param original The original collection.
+	 * @return The newly instantiated collection.
+	 */
+	protected Object instantiateResult(Object original) {
+		// by default just use an unanticipated capacity since we don't
+		// know how to extract the capacity to use from original here...
+		return instantiate( -1 );
+	}
+
+	/**
+	 * Instantiate an empty instance of the "underlying" collection (not a wrapper),
+	 * but with the given anticipated size (i.e. accounting for initial capacity
+	 * and perhaps load factor).
+	 *
+	 * @param anticipatedSize The anticipated size of the instaniated collection
+	 * after we are done populating it.
+	 * @return A newly instantiated collection to be wrapped.
+	 */
+	public abstract Object instantiate(int anticipatedSize);
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object replace(
+			final Object original,
+			final Object target,
+			final SessionImplementor session,
+			final Object owner,
+			final Map copyCache) throws HibernateException {
+		if ( original == null ) {
+			return null;
+		}
+		if ( !Hibernate.isInitialized( original ) ) {
+			return target;
+		}
+
+		// for a null target, or a target which is the same as the original, we
+		// need to put the merged elements in a new collection
+		Object result = target == null || target == original ? instantiateResult( original ) : target;
+		
+		//for arrays, replaceElements() may return a different reference, since
+		//the array length might not match
+		result = replaceElements( original, result, owner, copyCache, session );
+
+		if ( original == target ) {
+			// get the elements back into the target making sure to handle dirty flag
+			boolean wasClean = PersistentCollection.class.isInstance( target ) && !( ( PersistentCollection ) target ).isDirty();
+			//TODO: this is a little inefficient, don't need to do a whole
+			//      deep replaceElements() call
+			replaceElements( result, target, owner, copyCache, session );
+			if ( wasClean ) {
+				( ( PersistentCollection ) target ).clearDirty();
+			}
+			result = target;
+		}
+
+		return result;
+	}
+
+	/**
+	 * Get the Hibernate type of the collection elements
+	 *
+	 * @param factory The session factory.
+	 * @return The type of the collection elements
+	 * @throws MappingException Indicates the underlying persister could not be located.
+	 */
+	public final Type getElementType(SessionFactoryImplementor factory) throws MappingException {
+		return factory.getCollectionPersister( getRole() ).getElementType();
+	}
+
+	public String toString() {
+		return getClass().getName() + '(' + getRole() + ')';
+	}
+
+	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
+			throws MappingException {
+		return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters );
+	}
+
+	/**
+	 * instantiate a collection wrapper (called when loading an object)
+	 *
+	 * @param key The collection owner key
+	 * @param session The session from which the request is originating.
+	 * @param owner The collection owner
+	 * @return The collection
+	 */
+	public Object getCollection(Serializable key, SessionImplementor session, Object owner) {
+
+		CollectionPersister persister = getPersister( session );
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		final EntityMode entityMode = session.getEntityMode();
+
+		if (entityMode==EntityMode.DOM4J && !isEmbeddedInXML) {
+			return UNFETCHED_COLLECTION;
+		}
+		
+		// check if collection is currently being loaded
+		PersistentCollection collection = persistenceContext.getLoadContexts().locateLoadingCollection( persister, key );
+		
+		if ( collection == null ) {
+			
+			// check if it is already completely loaded, but unowned
+			collection = persistenceContext.useUnownedCollection( new CollectionKey(persister, key, entityMode) );
+			
+			if ( collection == null ) {
+				// create a new collection wrapper, to be initialized later
+				collection = instantiate( session, persister, key );
+				collection.setOwner(owner);
+	
+				persistenceContext.addUninitializedCollection( persister, collection, key );
+	
+				// some collections are not lazy:
+				if ( initializeImmediately( entityMode ) ) {
+					session.initializeCollection( collection, false );
+				}
+				else if ( !persister.isLazy() ) {
+					persistenceContext.addNonLazyCollection( collection );
+				}
+	
+				if ( hasHolder( entityMode ) ) {
+					session.getPersistenceContext().addCollectionHolder( collection );
+				}
+				
+			}
+			
+		}
+		
+		collection.setOwner(owner);
+
+		return collection.getValue();
+	}
+
+	public boolean hasHolder(EntityMode entityMode) {
+		return entityMode == EntityMode.DOM4J;
+	}
+
+	protected boolean initializeImmediately(EntityMode entityMode) {
+		return entityMode == EntityMode.DOM4J;
+	}
+
+	public String getLHSPropertyName() {
+		return foreignKeyPropertyName;
+	}
+
+	public boolean isXMLElement() {
+		return true;
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return xml;
+	}
+
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		if ( !isEmbeddedInXML ) {
+			node.detach();
+		}
+		else {
+			replaceNode( node, (Element) value );
+		}
+	}
+	
+	/**
+	 * We always need to dirty check the collection because we sometimes 
+	 * need to incremement version number of owner and also because of 
+	 * how assemble/disassemble is implemented for uks
+	 */
+	public boolean isAlwaysDirtyChecked() {
+		return true; 
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ComponentType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,636 +0,0 @@
-//$Id: ComponentType.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.tuple.component.ComponentTuplizer;
-import org.hibernate.tuple.component.ComponentMetamodel;
-import org.hibernate.tuple.StandardProperty;
-import org.hibernate.tuple.EntityModeToTuplizerMapping;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Handles "component" mappings
- *
- * @author Gavin King
- */
-public class ComponentType extends AbstractType implements AbstractComponentType {
-
-	private final String[] propertyNames;
-	private final Type[] propertyTypes;
-	private final boolean[] propertyNullability;
-	protected final int propertySpan;
-	private final CascadeStyle[] cascade;
-	private final FetchMode[] joinedFetch;
-	private final boolean isKey;
-
-	protected final EntityModeToTuplizerMapping tuplizerMapping;
-
-	public ComponentType(ComponentMetamodel metamodel) {
-		// for now, just "re-flatten" the metamodel since this is temporary stuff anyway (HHH-1907)
-		this.isKey = metamodel.isKey();
-		this.propertySpan = metamodel.getPropertySpan();
-		this.propertyNames = new String[ propertySpan ];
-		this.propertyTypes = new Type[ propertySpan ];
-		this.propertyNullability = new boolean[ propertySpan ];
-		this.cascade = new CascadeStyle[ propertySpan ];
-		this.joinedFetch = new FetchMode[ propertySpan ];
-
-		for ( int i = 0; i < propertySpan; i++ ) {
-			StandardProperty prop = metamodel.getProperty( i );
-			this.propertyNames[i] = prop.getName();
-			this.propertyTypes[i] = prop.getType();
-			this.propertyNullability[i] = prop.isNullable();
-			this.cascade[i] = prop.getCascadeStyle();
-			this.joinedFetch[i] = prop.getFetchMode();
-		}
-
-		this.tuplizerMapping = metamodel.getTuplizerMapping();
-	}
-
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		//Not called at runtime so doesn't matter if its slow :)
-		int[] sqlTypes = new int[getColumnSpan( mapping )];
-		int n = 0;
-		for ( int i = 0; i < propertySpan; i++ ) {
-			int[] subtypes = propertyTypes[i].sqlTypes( mapping );
-			for ( int j = 0; j < subtypes.length; j++ ) {
-				sqlTypes[n++] = subtypes[j];
-			}
-		}
-		return sqlTypes;
-	}
-
-	public int getColumnSpan(Mapping mapping) throws MappingException {
-		int span = 0;
-		for ( int i = 0; i < propertySpan; i++ ) {
-			span += propertyTypes[i].getColumnSpan( mapping );
-		}
-		return span;
-	}
-
-	public final boolean isComponentType() {
-		return true;
-	}
-
-	public Class getReturnedClass() {
-		return tuplizerMapping.getTuplizer( EntityMode.POJO ).getMappedClass(); //TODO
-	}
-
-	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
-		if ( x == y ) {
-			return true;
-		}
-		if ( x == null || y == null ) {
-			return false;
-		}
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i], entityMode ) ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode)
-			throws HibernateException {
-		if ( x == y ) {
-			return true;
-		}
-		if ( x == null || y == null ) {
-			return false;
-		}
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode ) ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory)
-			throws HibernateException {
-		if ( x == y ) {
-			return true;
-		}
-		if ( x == null || y == null ) {
-			return false;
-		}
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode, factory ) ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		if ( x == y ) {
-			return 0;
-		}
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			int propertyCompare = propertyTypes[i].compare( xvalues[i], yvalues[i], entityMode );
-			if ( propertyCompare != 0 ) {
-				return propertyCompare;
-			}
-		}
-		return 0;
-	}
-
-	public boolean isMethodOf(Method method) {
-		return false;
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		int result = 17;
-		Object[] values = getPropertyValues( x, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			Object y = values[i];
-			result *= 37;
-			if ( y != null ) {
-				result += propertyTypes[i].getHashCode( y, entityMode );
-			}
-		}
-		return result;
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
-		int result = 17;
-		Object[] values = getPropertyValues( x, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			Object y = values[i];
-			result *= 37;
-			if ( y != null ) {
-				result += propertyTypes[i].getHashCode( y, entityMode, factory );
-			}
-		}
-		return result;
-	}
-
-	public boolean isDirty(Object x, Object y, SessionImplementor session)
-			throws HibernateException {
-		if ( x == y ) {
-			return false;
-		}
-		if ( x == null || y == null ) {
-			return true;
-		}
-		EntityMode entityMode = session.getEntityMode();
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		for ( int i = 0; i < xvalues.length; i++ ) {
-			if ( propertyTypes[i].isDirty( xvalues[i], yvalues[i], session ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public boolean isDirty(Object x, Object y, boolean[] checkable, SessionImplementor session)
-			throws HibernateException {
-		if ( x == y ) {
-			return false;
-		}
-		if ( x == null || y == null ) {
-			return true;
-		}
-		EntityMode entityMode = session.getEntityMode();
-		Object[] xvalues = getPropertyValues( x, entityMode );
-		Object[] yvalues = getPropertyValues( y, entityMode );
-		int loc = 0;
-		for ( int i = 0; i < xvalues.length; i++ ) {
-			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
-			if ( len <= 1 ) {
-				final boolean dirty = ( len == 0 || checkable[loc] ) &&
-				                      propertyTypes[i].isDirty( xvalues[i], yvalues[i], session );
-				if ( dirty ) {
-					return true;
-				}
-			}
-			else {
-				boolean[] subcheckable = new boolean[len];
-				System.arraycopy( checkable, loc, subcheckable, 0, len );
-				final boolean dirty = propertyTypes[i].isDirty( xvalues[i], yvalues[i], subcheckable, session );
-				if ( dirty ) {
-					return true;
-				}
-			}
-			loc += len;
-		}
-		return false;
-	}
-
-	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
-			throws HibernateException {
-
-		if ( current == null ) {
-			return old != null;
-		}
-		if ( old == null ) {
-			return current != null;
-		}
-		Object[] currentValues = getPropertyValues( current, session );
-		Object[] oldValues = ( Object[] ) old;
-		int loc = 0;
-		for ( int i = 0; i < currentValues.length; i++ ) {
-			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
-			boolean[] subcheckable = new boolean[len];
-			System.arraycopy( checkable, loc, subcheckable, 0, len );
-			if ( propertyTypes[i].isModified( oldValues[i], currentValues[i], subcheckable, session ) ) {
-				return true;
-			}
-			loc += len;
-		}
-		return false;
-
-	}
-
-	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-		return resolve( hydrate( rs, names, session, owner ), session, owner );
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value, int begin, SessionImplementor session)
-			throws HibernateException, SQLException {
-
-		Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
-
-		for ( int i = 0; i < propertySpan; i++ ) {
-			propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
-			begin += propertyTypes[i].getColumnSpan( session.getFactory() );
-		}
-	}
-
-	public void nullSafeSet(
-			PreparedStatement st,
-			Object value,
-			int begin,
-			boolean[] settable,
-			SessionImplementor session)
-			throws HibernateException, SQLException {
-
-		Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
-
-		int loc = 0;
-		for ( int i = 0; i < propertySpan; i++ ) {
-			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
-			if ( len == 0 ) {
-				//noop
-			}
-			else if ( len == 1 ) {
-				if ( settable[loc] ) {
-					propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
-					begin++;
-				}
-			}
-			else {
-				boolean[] subsettable = new boolean[len];
-				System.arraycopy( settable, loc, subsettable, 0, len );
-				propertyTypes[i].nullSafeSet( st, subvalues[i], begin, subsettable, session );
-				begin += ArrayHelper.countTrue( subsettable );
-			}
-			loc += len;
-		}
-	}
-
-	private Object[] nullSafeGetValues(Object value, EntityMode entityMode) throws HibernateException {
-		if ( value == null ) {
-			return new Object[propertySpan];
-		}
-		else {
-			return getPropertyValues( value, entityMode );
-		}
-	}
-
-	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
-			throws HibernateException, SQLException {
-
-		return nullSafeGet( rs, new String[] {name}, session, owner );
-	}
-
-	public Object getPropertyValue(Object component, int i, SessionImplementor session)
-			throws HibernateException {
-		return getPropertyValue( component, i, session.getEntityMode() );
-	}
-
-	public Object getPropertyValue(Object component, int i, EntityMode entityMode)
-			throws HibernateException {
-		return tuplizerMapping.getTuplizer( entityMode ).getPropertyValue( component, i );
-	}
-
-	public Object[] getPropertyValues(Object component, SessionImplementor session)
-			throws HibernateException {
-		return getPropertyValues( component, session.getEntityMode() );
-	}
-
-	public Object[] getPropertyValues(Object component, EntityMode entityMode)
-			throws HibernateException {
-		return tuplizerMapping.getTuplizer( entityMode ).getPropertyValues( component );
-	}
-
-	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
-			throws HibernateException {
-		tuplizerMapping.getTuplizer( entityMode ).setPropertyValues( component, values );
-	}
-
-	public Type[] getSubtypes() {
-		return propertyTypes;
-	}
-
-	public String getName() {
-		return "component" + ArrayHelper.toString( propertyNames );
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-			throws HibernateException {
-		if ( value == null ) {
-			return "null";
-		}
-		Map result = new HashMap();
-		EntityMode entityMode = tuplizerMapping.guessEntityMode( value );
-		if ( entityMode == null ) {
-			throw new ClassCastException( value.getClass().getName() );
-		}
-		Object[] values = getPropertyValues( value, entityMode );
-		for ( int i = 0; i < propertyTypes.length; i++ ) {
-			result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) );
-		}
-		return StringHelper.unqualify( getName() ) + result.toString();
-	}
-
-	public String[] getPropertyNames() {
-		return propertyNames;
-	}
-
-	public Object deepCopy(Object component, EntityMode entityMode, SessionFactoryImplementor factory)
-			throws HibernateException {
-		if ( component == null ) {
-			return null;
-		}
-
-		Object[] values = getPropertyValues( component, entityMode );
-		for ( int i = 0; i < propertySpan; i++ ) {
-			values[i] = propertyTypes[i].deepCopy( values[i], entityMode, factory );
-		}
-
-		Object result = instantiate( entityMode );
-		setPropertyValues( result, values, entityMode );
-
-		//not absolutely necessary, but helps for some
-		//equals()/hashCode() implementations
-		ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( entityMode );
-		if ( ct.hasParentProperty() ) {
-			ct.setParent( result, ct.getParent( component ), factory );
-		}
-
-		return result;
-	}
-
-	public Object replace(
-			Object original,
-			Object target,
-			SessionImplementor session,
-			Object owner,
-			Map copyCache)
-			throws HibernateException {
-
-		if ( original == null ) {
-			return null;
-		}
-		//if ( original == target ) return target;
-
-		final Object result = target == null
-				? instantiate( owner, session )
-				: target;
-
-		final EntityMode entityMode = session.getEntityMode();
-		Object[] values = TypeFactory.replace(
-				getPropertyValues( original, entityMode ),
-				getPropertyValues( result, entityMode ),
-				propertyTypes,
-				session,
-				owner,
-				copyCache
-		);
-
-		setPropertyValues( result, values, entityMode );
-		return result;
-	}
-
-	public Object replace(
-			Object original,
-			Object target,
-			SessionImplementor session,
-			Object owner,
-			Map copyCache,
-			ForeignKeyDirection foreignKeyDirection)
-			throws HibernateException {
-
-		if ( original == null ) {
-			return null;
-		}
-		//if ( original == target ) return target;
-
-		final Object result = target == null ?
-				instantiate( owner, session ) :
-				target;
-
-		final EntityMode entityMode = session.getEntityMode();
-		Object[] values = TypeFactory.replace(
-				getPropertyValues( original, entityMode ),
-				getPropertyValues( result, entityMode ),
-				propertyTypes,
-				session,
-				owner,
-				copyCache,
-				foreignKeyDirection
-		);
-
-		setPropertyValues( result, values, entityMode );
-		return result;
-	}
-
-	/**
-	 * This method does not populate the component parent
-	 */
-	public Object instantiate(EntityMode entityMode) throws HibernateException {
-		return tuplizerMapping.getTuplizer( entityMode ).instantiate();
-	}
-
-	public Object instantiate(Object parent, SessionImplementor session)
-			throws HibernateException {
-
-		Object result = instantiate( session.getEntityMode() );
-
-		ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( session.getEntityMode() );
-		if ( ct.hasParentProperty() && parent != null ) {
-			ct.setParent(
-					result,
-					session.getPersistenceContext().proxyFor( parent ),
-					session.getFactory()
-			);
-		}
-
-		return result;
-	}
-
-	public CascadeStyle getCascadeStyle(int i) {
-		return cascade[i];
-	}
-
-	public boolean isMutable() {
-		return true;
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-
-		if ( value == null ) {
-			return null;
-		}
-		else {
-			Object[] values = getPropertyValues( value, session.getEntityMode() );
-			for ( int i = 0; i < propertyTypes.length; i++ ) {
-				values[i] = propertyTypes[i].disassemble( values[i], session, owner );
-			}
-			return values;
-		}
-	}
-
-	public Object assemble(Serializable object, SessionImplementor session, Object owner)
-			throws HibernateException {
-
-		if ( object == null ) {
-			return null;
-		}
-		else {
-			Object[] values = ( Object[] ) object;
-			Object[] assembled = new Object[values.length];
-			for ( int i = 0; i < propertyTypes.length; i++ ) {
-				assembled[i] = propertyTypes[i].assemble( ( Serializable ) values[i], session, owner );
-			}
-			Object result = instantiate( owner, session );
-			setPropertyValues( result, assembled, session.getEntityMode() );
-			return result;
-		}
-	}
-
-	public FetchMode getFetchMode(int i) {
-		return joinedFetch[i];
-	}
-
-	public Object hydrate(
-			final ResultSet rs,
-			final String[] names,
-			final SessionImplementor session,
-			final Object owner)
-			throws HibernateException, SQLException {
-
-		int begin = 0;
-		boolean notNull = false;
-		Object[] values = new Object[propertySpan];
-		for ( int i = 0; i < propertySpan; i++ ) {
-			int length = propertyTypes[i].getColumnSpan( session.getFactory() );
-			String[] range = ArrayHelper.slice( names, begin, length ); //cache this
-			Object val = propertyTypes[i].hydrate( rs, range, session, owner );
-			if ( val == null ) {
-				if ( isKey ) {
-					return null; //different nullability rules for pk/fk
-				}
-			}
-			else {
-				notNull = true;
-			}
-			values[i] = val;
-			begin += length;
-		}
-
-		return notNull ? values : null;
-	}
-
-	public Object resolve(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-
-		if ( value != null ) {
-			Object result = instantiate( owner, session );
-			Object[] values = ( Object[] ) value;
-			Object[] resolvedValues = new Object[values.length]; //only really need new array during semiresolve!
-			for ( int i = 0; i < values.length; i++ ) {
-				resolvedValues[i] = propertyTypes[i].resolve( values[i], session, owner );
-			}
-			setPropertyValues( result, resolvedValues, session.getEntityMode() );
-			return result;
-		}
-		else {
-			return null;
-		}
-	}
-
-	public Object semiResolve(Object value, SessionImplementor session, Object owner)
-			throws HibernateException {
-		//note that this implementation is kinda broken
-		//for components with many-to-one associations
-		return resolve( value, session, owner );
-	}
-
-	public boolean[] getPropertyNullability() {
-		return propertyNullability;
-	}
-
-	public boolean isXMLElement() {
-		return true;
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return xml;
-	}
-
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
-		replaceNode( node, ( Element ) value );
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		boolean[] result = new boolean[ getColumnSpan( mapping ) ];
-		if ( value == null ) {
-			return result;
-		}
-		Object[] values = getPropertyValues( value, EntityMode.POJO ); //TODO!!!!!!!
-		int loc = 0;
-		for ( int i = 0; i < propertyTypes.length; i++ ) {
-			boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
-			System.arraycopy( propertyNullness, 0, result, loc, propertyNullness.length );
-			loc += propertyNullness.length;
-		}
-		return result;
-	}
-
-	public boolean isEmbedded() {
-		return false;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ComponentType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,659 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.tuple.component.ComponentTuplizer;
+import org.hibernate.tuple.component.ComponentMetamodel;
+import org.hibernate.tuple.StandardProperty;
+import org.hibernate.tuple.EntityModeToTuplizerMapping;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Handles "component" mappings
+ *
+ * @author Gavin King
+ */
+public class ComponentType extends AbstractType implements AbstractComponentType {
+
+	private final String[] propertyNames;
+	private final Type[] propertyTypes;
+	private final boolean[] propertyNullability;
+	protected final int propertySpan;
+	private final CascadeStyle[] cascade;
+	private final FetchMode[] joinedFetch;
+	private final boolean isKey;
+
+	protected final EntityModeToTuplizerMapping tuplizerMapping;
+
+	public ComponentType(ComponentMetamodel metamodel) {
+		// for now, just "re-flatten" the metamodel since this is temporary stuff anyway (HHH-1907)
+		this.isKey = metamodel.isKey();
+		this.propertySpan = metamodel.getPropertySpan();
+		this.propertyNames = new String[ propertySpan ];
+		this.propertyTypes = new Type[ propertySpan ];
+		this.propertyNullability = new boolean[ propertySpan ];
+		this.cascade = new CascadeStyle[ propertySpan ];
+		this.joinedFetch = new FetchMode[ propertySpan ];
+
+		for ( int i = 0; i < propertySpan; i++ ) {
+			StandardProperty prop = metamodel.getProperty( i );
+			this.propertyNames[i] = prop.getName();
+			this.propertyTypes[i] = prop.getType();
+			this.propertyNullability[i] = prop.isNullable();
+			this.cascade[i] = prop.getCascadeStyle();
+			this.joinedFetch[i] = prop.getFetchMode();
+		}
+
+		this.tuplizerMapping = metamodel.getTuplizerMapping();
+	}
+
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		//Not called at runtime so doesn't matter if its slow :)
+		int[] sqlTypes = new int[getColumnSpan( mapping )];
+		int n = 0;
+		for ( int i = 0; i < propertySpan; i++ ) {
+			int[] subtypes = propertyTypes[i].sqlTypes( mapping );
+			for ( int j = 0; j < subtypes.length; j++ ) {
+				sqlTypes[n++] = subtypes[j];
+			}
+		}
+		return sqlTypes;
+	}
+
+	public int getColumnSpan(Mapping mapping) throws MappingException {
+		int span = 0;
+		for ( int i = 0; i < propertySpan; i++ ) {
+			span += propertyTypes[i].getColumnSpan( mapping );
+		}
+		return span;
+	}
+
+	public final boolean isComponentType() {
+		return true;
+	}
+
+	public Class getReturnedClass() {
+		return tuplizerMapping.getTuplizer( EntityMode.POJO ).getMappedClass(); //TODO
+	}
+
+	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException {
+		if ( x == y ) {
+			return true;
+		}
+		if ( x == null || y == null ) {
+			return false;
+		}
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			if ( !propertyTypes[i].isSame( xvalues[i], yvalues[i], entityMode ) ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode)
+			throws HibernateException {
+		if ( x == y ) {
+			return true;
+		}
+		if ( x == null || y == null ) {
+			return false;
+		}
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode ) ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory)
+			throws HibernateException {
+		if ( x == y ) {
+			return true;
+		}
+		if ( x == null || y == null ) {
+			return false;
+		}
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			if ( !propertyTypes[i].isEqual( xvalues[i], yvalues[i], entityMode, factory ) ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		if ( x == y ) {
+			return 0;
+		}
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			int propertyCompare = propertyTypes[i].compare( xvalues[i], yvalues[i], entityMode );
+			if ( propertyCompare != 0 ) {
+				return propertyCompare;
+			}
+		}
+		return 0;
+	}
+
+	public boolean isMethodOf(Method method) {
+		return false;
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		int result = 17;
+		Object[] values = getPropertyValues( x, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			Object y = values[i];
+			result *= 37;
+			if ( y != null ) {
+				result += propertyTypes[i].getHashCode( y, entityMode );
+			}
+		}
+		return result;
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
+		int result = 17;
+		Object[] values = getPropertyValues( x, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			Object y = values[i];
+			result *= 37;
+			if ( y != null ) {
+				result += propertyTypes[i].getHashCode( y, entityMode, factory );
+			}
+		}
+		return result;
+	}
+
+	public boolean isDirty(Object x, Object y, SessionImplementor session)
+			throws HibernateException {
+		if ( x == y ) {
+			return false;
+		}
+		if ( x == null || y == null ) {
+			return true;
+		}
+		EntityMode entityMode = session.getEntityMode();
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		for ( int i = 0; i < xvalues.length; i++ ) {
+			if ( propertyTypes[i].isDirty( xvalues[i], yvalues[i], session ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public boolean isDirty(Object x, Object y, boolean[] checkable, SessionImplementor session)
+			throws HibernateException {
+		if ( x == y ) {
+			return false;
+		}
+		if ( x == null || y == null ) {
+			return true;
+		}
+		EntityMode entityMode = session.getEntityMode();
+		Object[] xvalues = getPropertyValues( x, entityMode );
+		Object[] yvalues = getPropertyValues( y, entityMode );
+		int loc = 0;
+		for ( int i = 0; i < xvalues.length; i++ ) {
+			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
+			if ( len <= 1 ) {
+				final boolean dirty = ( len == 0 || checkable[loc] ) &&
+				                      propertyTypes[i].isDirty( xvalues[i], yvalues[i], session );
+				if ( dirty ) {
+					return true;
+				}
+			}
+			else {
+				boolean[] subcheckable = new boolean[len];
+				System.arraycopy( checkable, loc, subcheckable, 0, len );
+				final boolean dirty = propertyTypes[i].isDirty( xvalues[i], yvalues[i], subcheckable, session );
+				if ( dirty ) {
+					return true;
+				}
+			}
+			loc += len;
+		}
+		return false;
+	}
+
+	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session)
+			throws HibernateException {
+
+		if ( current == null ) {
+			return old != null;
+		}
+		if ( old == null ) {
+			return current != null;
+		}
+		Object[] currentValues = getPropertyValues( current, session );
+		Object[] oldValues = ( Object[] ) old;
+		int loc = 0;
+		for ( int i = 0; i < currentValues.length; i++ ) {
+			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
+			boolean[] subcheckable = new boolean[len];
+			System.arraycopy( checkable, loc, subcheckable, 0, len );
+			if ( propertyTypes[i].isModified( oldValues[i], currentValues[i], subcheckable, session ) ) {
+				return true;
+			}
+			loc += len;
+		}
+		return false;
+
+	}
+
+	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+		return resolve( hydrate( rs, names, session, owner ), session, owner );
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int begin, SessionImplementor session)
+			throws HibernateException, SQLException {
+
+		Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
+
+		for ( int i = 0; i < propertySpan; i++ ) {
+			propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
+			begin += propertyTypes[i].getColumnSpan( session.getFactory() );
+		}
+	}
+
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int begin,
+			boolean[] settable,
+			SessionImplementor session)
+			throws HibernateException, SQLException {
+
+		Object[] subvalues = nullSafeGetValues( value, session.getEntityMode() );
+
+		int loc = 0;
+		for ( int i = 0; i < propertySpan; i++ ) {
+			int len = propertyTypes[i].getColumnSpan( session.getFactory() );
+			if ( len == 0 ) {
+				//noop
+			}
+			else if ( len == 1 ) {
+				if ( settable[loc] ) {
+					propertyTypes[i].nullSafeSet( st, subvalues[i], begin, session );
+					begin++;
+				}
+			}
+			else {
+				boolean[] subsettable = new boolean[len];
+				System.arraycopy( settable, loc, subsettable, 0, len );
+				propertyTypes[i].nullSafeSet( st, subvalues[i], begin, subsettable, session );
+				begin += ArrayHelper.countTrue( subsettable );
+			}
+			loc += len;
+		}
+	}
+
+	private Object[] nullSafeGetValues(Object value, EntityMode entityMode) throws HibernateException {
+		if ( value == null ) {
+			return new Object[propertySpan];
+		}
+		else {
+			return getPropertyValues( value, entityMode );
+		}
+	}
+
+	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
+			throws HibernateException, SQLException {
+
+		return nullSafeGet( rs, new String[] {name}, session, owner );
+	}
+
+	public Object getPropertyValue(Object component, int i, SessionImplementor session)
+			throws HibernateException {
+		return getPropertyValue( component, i, session.getEntityMode() );
+	}
+
+	public Object getPropertyValue(Object component, int i, EntityMode entityMode)
+			throws HibernateException {
+		return tuplizerMapping.getTuplizer( entityMode ).getPropertyValue( component, i );
+	}
+
+	public Object[] getPropertyValues(Object component, SessionImplementor session)
+			throws HibernateException {
+		return getPropertyValues( component, session.getEntityMode() );
+	}
+
+	public Object[] getPropertyValues(Object component, EntityMode entityMode)
+			throws HibernateException {
+		return tuplizerMapping.getTuplizer( entityMode ).getPropertyValues( component );
+	}
+
+	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
+			throws HibernateException {
+		tuplizerMapping.getTuplizer( entityMode ).setPropertyValues( component, values );
+	}
+
+	public Type[] getSubtypes() {
+		return propertyTypes;
+	}
+
+	public String getName() {
+		return "component" + ArrayHelper.toString( propertyNames );
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+			throws HibernateException {
+		if ( value == null ) {
+			return "null";
+		}
+		Map result = new HashMap();
+		EntityMode entityMode = tuplizerMapping.guessEntityMode( value );
+		if ( entityMode == null ) {
+			throw new ClassCastException( value.getClass().getName() );
+		}
+		Object[] values = getPropertyValues( value, entityMode );
+		for ( int i = 0; i < propertyTypes.length; i++ ) {
+			result.put( propertyNames[i], propertyTypes[i].toLoggableString( values[i], factory ) );
+		}
+		return StringHelper.unqualify( getName() ) + result.toString();
+	}
+
+	public String[] getPropertyNames() {
+		return propertyNames;
+	}
+
+	public Object deepCopy(Object component, EntityMode entityMode, SessionFactoryImplementor factory)
+			throws HibernateException {
+		if ( component == null ) {
+			return null;
+		}
+
+		Object[] values = getPropertyValues( component, entityMode );
+		for ( int i = 0; i < propertySpan; i++ ) {
+			values[i] = propertyTypes[i].deepCopy( values[i], entityMode, factory );
+		}
+
+		Object result = instantiate( entityMode );
+		setPropertyValues( result, values, entityMode );
+
+		//not absolutely necessary, but helps for some
+		//equals()/hashCode() implementations
+		ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( entityMode );
+		if ( ct.hasParentProperty() ) {
+			ct.setParent( result, ct.getParent( component ), factory );
+		}
+
+		return result;
+	}
+
+	public Object replace(
+			Object original,
+			Object target,
+			SessionImplementor session,
+			Object owner,
+			Map copyCache)
+			throws HibernateException {
+
+		if ( original == null ) {
+			return null;
+		}
+		//if ( original == target ) return target;
+
+		final Object result = target == null
+				? instantiate( owner, session )
+				: target;
+
+		final EntityMode entityMode = session.getEntityMode();
+		Object[] values = TypeFactory.replace(
+				getPropertyValues( original, entityMode ),
+				getPropertyValues( result, entityMode ),
+				propertyTypes,
+				session,
+				owner,
+				copyCache
+		);
+
+		setPropertyValues( result, values, entityMode );
+		return result;
+	}
+
+	public Object replace(
+			Object original,
+			Object target,
+			SessionImplementor session,
+			Object owner,
+			Map copyCache,
+			ForeignKeyDirection foreignKeyDirection)
+			throws HibernateException {
+
+		if ( original == null ) {
+			return null;
+		}
+		//if ( original == target ) return target;
+
+		final Object result = target == null ?
+				instantiate( owner, session ) :
+				target;
+
+		final EntityMode entityMode = session.getEntityMode();
+		Object[] values = TypeFactory.replace(
+				getPropertyValues( original, entityMode ),
+				getPropertyValues( result, entityMode ),
+				propertyTypes,
+				session,
+				owner,
+				copyCache,
+				foreignKeyDirection
+		);
+
+		setPropertyValues( result, values, entityMode );
+		return result;
+	}
+
+	/**
+	 * This method does not populate the component parent
+	 */
+	public Object instantiate(EntityMode entityMode) throws HibernateException {
+		return tuplizerMapping.getTuplizer( entityMode ).instantiate();
+	}
+
+	public Object instantiate(Object parent, SessionImplementor session)
+			throws HibernateException {
+
+		Object result = instantiate( session.getEntityMode() );
+
+		ComponentTuplizer ct = ( ComponentTuplizer ) tuplizerMapping.getTuplizer( session.getEntityMode() );
+		if ( ct.hasParentProperty() && parent != null ) {
+			ct.setParent(
+					result,
+					session.getPersistenceContext().proxyFor( parent ),
+					session.getFactory()
+			);
+		}
+
+		return result;
+	}
+
+	public CascadeStyle getCascadeStyle(int i) {
+		return cascade[i];
+	}
+
+	public boolean isMutable() {
+		return true;
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+
+		if ( value == null ) {
+			return null;
+		}
+		else {
+			Object[] values = getPropertyValues( value, session.getEntityMode() );
+			for ( int i = 0; i < propertyTypes.length; i++ ) {
+				values[i] = propertyTypes[i].disassemble( values[i], session, owner );
+			}
+			return values;
+		}
+	}
+
+	public Object assemble(Serializable object, SessionImplementor session, Object owner)
+			throws HibernateException {
+
+		if ( object == null ) {
+			return null;
+		}
+		else {
+			Object[] values = ( Object[] ) object;
+			Object[] assembled = new Object[values.length];
+			for ( int i = 0; i < propertyTypes.length; i++ ) {
+				assembled[i] = propertyTypes[i].assemble( ( Serializable ) values[i], session, owner );
+			}
+			Object result = instantiate( owner, session );
+			setPropertyValues( result, assembled, session.getEntityMode() );
+			return result;
+		}
+	}
+
+	public FetchMode getFetchMode(int i) {
+		return joinedFetch[i];
+	}
+
+	public Object hydrate(
+			final ResultSet rs,
+			final String[] names,
+			final SessionImplementor session,
+			final Object owner)
+			throws HibernateException, SQLException {
+
+		int begin = 0;
+		boolean notNull = false;
+		Object[] values = new Object[propertySpan];
+		for ( int i = 0; i < propertySpan; i++ ) {
+			int length = propertyTypes[i].getColumnSpan( session.getFactory() );
+			String[] range = ArrayHelper.slice( names, begin, length ); //cache this
+			Object val = propertyTypes[i].hydrate( rs, range, session, owner );
+			if ( val == null ) {
+				if ( isKey ) {
+					return null; //different nullability rules for pk/fk
+				}
+			}
+			else {
+				notNull = true;
+			}
+			values[i] = val;
+			begin += length;
+		}
+
+		return notNull ? values : null;
+	}
+
+	public Object resolve(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+
+		if ( value != null ) {
+			Object result = instantiate( owner, session );
+			Object[] values = ( Object[] ) value;
+			Object[] resolvedValues = new Object[values.length]; //only really need new array during semiresolve!
+			for ( int i = 0; i < values.length; i++ ) {
+				resolvedValues[i] = propertyTypes[i].resolve( values[i], session, owner );
+			}
+			setPropertyValues( result, resolvedValues, session.getEntityMode() );
+			return result;
+		}
+		else {
+			return null;
+		}
+	}
+
+	public Object semiResolve(Object value, SessionImplementor session, Object owner)
+			throws HibernateException {
+		//note that this implementation is kinda broken
+		//for components with many-to-one associations
+		return resolve( value, session, owner );
+	}
+
+	public boolean[] getPropertyNullability() {
+		return propertyNullability;
+	}
+
+	public boolean isXMLElement() {
+		return true;
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return xml;
+	}
+
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
+		replaceNode( node, ( Element ) value );
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		boolean[] result = new boolean[ getColumnSpan( mapping ) ];
+		if ( value == null ) {
+			return result;
+		}
+		Object[] values = getPropertyValues( value, EntityMode.POJO ); //TODO!!!!!!!
+		int loc = 0;
+		for ( int i = 0; i < propertyTypes.length; i++ ) {
+			boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
+			System.arraycopy( propertyNullness, 0, result, loc, propertyNullness.length );
+			loc += propertyNullness.length;
+		}
+		return result;
+	}
+
+	public boolean isEmbedded() {
+		return false;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,274 +0,0 @@
-//$Id: CompositeCustomType.java 7670 2005-07-29 05:36:14Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-import java.util.Properties;
-
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.FetchMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.CascadeStyle;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.usertype.CompositeUserType;
-
-/**
- * Adapts <tt>CompositeUserType</tt> to <tt>Type</tt> interface
- * @author Gavin King
- */
-public class CompositeCustomType extends AbstractType
-	implements AbstractComponentType {
-
-	private final CompositeUserType userType;
-	private final String name;
-
-	public CompositeCustomType(Class userTypeClass, Properties parameters) 
-	throws MappingException {
-		name = userTypeClass.getName();
-
-		if ( !CompositeUserType.class.isAssignableFrom(userTypeClass) ) {
-			throw new MappingException( 
-					"Custom type does not implement CompositeUserType: " + 
-					userTypeClass.getName() 
-				);
-		}
-		
-		try {
-			userType = (CompositeUserType) userTypeClass.newInstance();
-		}
-		catch (InstantiationException ie) {
-			throw new MappingException( 
-					"Cannot instantiate custom type: " + 
-					userTypeClass.getName() 
-				);
-		}
-		catch (IllegalAccessException iae) {
-			throw new MappingException( 
-					"IllegalAccessException trying to instantiate custom type: " + 
-					userTypeClass.getName() 
-				);
-		}
-		TypeFactory.injectParameters(userType, parameters);
-	}
-	
-	public boolean isMethodOf(Method method) {
-		return false;
-	}
-
-	public Type[] getSubtypes() {
-		return userType.getPropertyTypes();
-	}
-
-	public String[] getPropertyNames() {
-		return userType.getPropertyNames();
-	}
-
-	public Object[] getPropertyValues(Object component, SessionImplementor session)
-		throws HibernateException {
-		return getPropertyValues( component, session.getEntityMode() );
-	}
-
-	public Object[] getPropertyValues(Object component, EntityMode entityMode)
-		throws HibernateException {
-
-		int len = getSubtypes().length;
-		Object[] result = new Object[len];
-		for ( int i=0; i<len; i++ ) {
-			result[i] = getPropertyValue(component, i);
-		}
-		return result;
-	}
-
-	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
-		throws HibernateException {
-
-		for (int i=0; i<values.length; i++) {
-			userType.setPropertyValue( component, i, values[i] );
-		}
-	}
-
-	public Object getPropertyValue(Object component, int i, SessionImplementor session)
-		throws HibernateException {
-		return getPropertyValue(component, i);
-	}
-
-	public Object getPropertyValue(Object component, int i)
-		throws HibernateException {
-		return userType.getPropertyValue(component, i);
-	}
-
-	public CascadeStyle getCascadeStyle(int i) {
-		return CascadeStyle.NONE;
-	}
-
-	public FetchMode getFetchMode(int i) {
-		return FetchMode.DEFAULT;
-	}
-
-	public boolean isComponentType() {
-		return true;
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		return userType.deepCopy(value);
-	}
-
-	public Object assemble(
-		Serializable cached,
-		SessionImplementor session,
-		Object owner)
-		throws HibernateException {
-
-		return userType.assemble(cached, session, owner);
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return userType.disassemble(value, session);
-	}
-	
-	public Object replace(
-			Object original, 
-			Object target,
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache)
-	throws HibernateException {
-		return userType.replace(original, target, session, owner);
-	}
-	
-	public boolean isEqual(Object x, Object y, EntityMode entityMode) 
-	throws HibernateException {
-		return userType.equals(x, y);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return userType.hashCode(x);
-	}
-	
-	public int getColumnSpan(Mapping mapping) throws MappingException {
-		Type[] types = userType.getPropertyTypes();
-		int n=0;
-		for (int i=0; i<types.length; i++) {
-			n+=types[i].getColumnSpan(mapping);
-		}
-		return n;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Class getReturnedClass() {
-		return userType.returnedClass();
-	}
-
-	public boolean isMutable() {
-		return userType.isMutable();
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String columnName,
-		SessionImplementor session,
-		Object owner)
-		throws HibernateException, SQLException {
-
-		return userType.nullSafeGet(rs, new String[] {columnName}, session, owner);
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String[] names,
-		SessionImplementor session,
-		Object owner)
-		throws HibernateException, SQLException {
-
-		return userType.nullSafeGet(rs, names, session, owner);
-	}
-
-	public void nullSafeSet(
-		PreparedStatement st,
-		Object value,
-		int index,
-		SessionImplementor session)
-		throws HibernateException, SQLException {
-
-		userType.nullSafeSet(st, value, index, session);
-
-	}
-
-	public void nullSafeSet(
-		PreparedStatement st,
-		Object value,
-		int index,
-		boolean[] settable, 
-		SessionImplementor session)
-		throws HibernateException, SQLException {
-
-		userType.nullSafeSet(st, value, index, session);
-
-	}
-
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		Type[] types = userType.getPropertyTypes();
-		int[] result = new int[ getColumnSpan(mapping) ];
-		int n=0;
-		for (int i=0; i<types.length; i++) {
-			int[] sqlTypes = types[i].sqlTypes(mapping);
-			for ( int k=0; k<sqlTypes.length; k++ ) result[n++] = sqlTypes[k];
-		}
-		return result;
-	}
-	
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-		throws HibernateException {
-
-		return value==null ? "null" : value.toString();
-	}
-
-	public boolean[] getPropertyNullability() {
-		return null;
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return xml;
-	}
-
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		replaceNode( node, (Element) value );
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		boolean[] result = new boolean[ getColumnSpan(mapping) ];
-		if (value==null) return result;
-		Object[] values = getPropertyValues(value, EntityMode.POJO); //TODO!!!!!!!
-		int loc = 0;
-		Type[] propertyTypes = getSubtypes();
-		for ( int i=0; i<propertyTypes.length; i++ ) {
-			boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
-			System.arraycopy(propertyNullness, 0, result, loc, propertyNullness.length);
-			loc += propertyNullness.length;
-		}
-		return result;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return isDirty(old, current, session);
-	}
-	
-	public boolean isEmbedded() {
-		return false;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CompositeCustomType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CompositeCustomType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,297 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.FetchMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.CascadeStyle;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.usertype.CompositeUserType;
+
+/**
+ * Adapts <tt>CompositeUserType</tt> to <tt>Type</tt> interface
+ * @author Gavin King
+ */
+public class CompositeCustomType extends AbstractType
+	implements AbstractComponentType {
+
+	private final CompositeUserType userType;
+	private final String name;
+
+	public CompositeCustomType(Class userTypeClass, Properties parameters) 
+	throws MappingException {
+		name = userTypeClass.getName();
+
+		if ( !CompositeUserType.class.isAssignableFrom(userTypeClass) ) {
+			throw new MappingException( 
+					"Custom type does not implement CompositeUserType: " + 
+					userTypeClass.getName() 
+				);
+		}
+		
+		try {
+			userType = (CompositeUserType) userTypeClass.newInstance();
+		}
+		catch (InstantiationException ie) {
+			throw new MappingException( 
+					"Cannot instantiate custom type: " + 
+					userTypeClass.getName() 
+				);
+		}
+		catch (IllegalAccessException iae) {
+			throw new MappingException( 
+					"IllegalAccessException trying to instantiate custom type: " + 
+					userTypeClass.getName() 
+				);
+		}
+		TypeFactory.injectParameters(userType, parameters);
+	}
+	
+	public boolean isMethodOf(Method method) {
+		return false;
+	}
+
+	public Type[] getSubtypes() {
+		return userType.getPropertyTypes();
+	}
+
+	public String[] getPropertyNames() {
+		return userType.getPropertyNames();
+	}
+
+	public Object[] getPropertyValues(Object component, SessionImplementor session)
+		throws HibernateException {
+		return getPropertyValues( component, session.getEntityMode() );
+	}
+
+	public Object[] getPropertyValues(Object component, EntityMode entityMode)
+		throws HibernateException {
+
+		int len = getSubtypes().length;
+		Object[] result = new Object[len];
+		for ( int i=0; i<len; i++ ) {
+			result[i] = getPropertyValue(component, i);
+		}
+		return result;
+	}
+
+	public void setPropertyValues(Object component, Object[] values, EntityMode entityMode)
+		throws HibernateException {
+
+		for (int i=0; i<values.length; i++) {
+			userType.setPropertyValue( component, i, values[i] );
+		}
+	}
+
+	public Object getPropertyValue(Object component, int i, SessionImplementor session)
+		throws HibernateException {
+		return getPropertyValue(component, i);
+	}
+
+	public Object getPropertyValue(Object component, int i)
+		throws HibernateException {
+		return userType.getPropertyValue(component, i);
+	}
+
+	public CascadeStyle getCascadeStyle(int i) {
+		return CascadeStyle.NONE;
+	}
+
+	public FetchMode getFetchMode(int i) {
+		return FetchMode.DEFAULT;
+	}
+
+	public boolean isComponentType() {
+		return true;
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		return userType.deepCopy(value);
+	}
+
+	public Object assemble(
+		Serializable cached,
+		SessionImplementor session,
+		Object owner)
+		throws HibernateException {
+
+		return userType.assemble(cached, session, owner);
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return userType.disassemble(value, session);
+	}
+	
+	public Object replace(
+			Object original, 
+			Object target,
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache)
+	throws HibernateException {
+		return userType.replace(original, target, session, owner);
+	}
+	
+	public boolean isEqual(Object x, Object y, EntityMode entityMode) 
+	throws HibernateException {
+		return userType.equals(x, y);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return userType.hashCode(x);
+	}
+	
+	public int getColumnSpan(Mapping mapping) throws MappingException {
+		Type[] types = userType.getPropertyTypes();
+		int n=0;
+		for (int i=0; i<types.length; i++) {
+			n+=types[i].getColumnSpan(mapping);
+		}
+		return n;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Class getReturnedClass() {
+		return userType.returnedClass();
+	}
+
+	public boolean isMutable() {
+		return userType.isMutable();
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String columnName,
+		SessionImplementor session,
+		Object owner)
+		throws HibernateException, SQLException {
+
+		return userType.nullSafeGet(rs, new String[] {columnName}, session, owner);
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String[] names,
+		SessionImplementor session,
+		Object owner)
+		throws HibernateException, SQLException {
+
+		return userType.nullSafeGet(rs, names, session, owner);
+	}
+
+	public void nullSafeSet(
+		PreparedStatement st,
+		Object value,
+		int index,
+		SessionImplementor session)
+		throws HibernateException, SQLException {
+
+		userType.nullSafeSet(st, value, index, session);
+
+	}
+
+	public void nullSafeSet(
+		PreparedStatement st,
+		Object value,
+		int index,
+		boolean[] settable, 
+		SessionImplementor session)
+		throws HibernateException, SQLException {
+
+		userType.nullSafeSet(st, value, index, session);
+
+	}
+
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		Type[] types = userType.getPropertyTypes();
+		int[] result = new int[ getColumnSpan(mapping) ];
+		int n=0;
+		for (int i=0; i<types.length; i++) {
+			int[] sqlTypes = types[i].sqlTypes(mapping);
+			for ( int k=0; k<sqlTypes.length; k++ ) result[n++] = sqlTypes[k];
+		}
+		return result;
+	}
+	
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+		throws HibernateException {
+
+		return value==null ? "null" : value.toString();
+	}
+
+	public boolean[] getPropertyNullability() {
+		return null;
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return xml;
+	}
+
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		replaceNode( node, (Element) value );
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		boolean[] result = new boolean[ getColumnSpan(mapping) ];
+		if (value==null) return result;
+		Object[] values = getPropertyValues(value, EntityMode.POJO); //TODO!!!!!!!
+		int loc = 0;
+		Type[] propertyTypes = getSubtypes();
+		for ( int i=0; i<propertyTypes.length; i++ ) {
+			boolean[] propertyNullness = propertyTypes[i].toColumnNullness( values[i], mapping );
+			System.arraycopy(propertyNullness, 0, result, loc, propertyNullness.length);
+			loc += propertyNullness.length;
+		}
+		return result;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return isDirty(old, current, session);
+	}
+	
+	public boolean isEmbedded() {
+		return false;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CurrencyType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,142 +0,0 @@
-//$Id: CurrencyType.java 8173 2005-09-14 19:54:49Z oneovthafew $
-package org.hibernate.type;
-
-import java.lang.reflect.Method;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>currency</tt>: A type that maps an SQL VARCHAR to a
- * <tt>java.util.Currency</tt>
- * @see java.util.Currency
- * @author Gavin King
- */
-public class CurrencyType extends ImmutableType implements LiteralType {
-
-	public static final Class CURRENCY_CLASS;
-	private static final Method CURRENCY_GET_INSTANCE;
-	private static final Method CURRENCY_GET_CODE;
-
-	static {
-		Class clazz;
-		try {
-			clazz = Class.forName("java.util.Currency");
-		}
-		catch (ClassNotFoundException cnfe) {
-			clazz = null;
-		}
-		if (clazz==null) {
-			CURRENCY_CLASS = null;
-			CURRENCY_GET_INSTANCE = null;
-			CURRENCY_GET_CODE = null;
-		}
-		else {
-			CURRENCY_CLASS = clazz;
-			try {
-				CURRENCY_GET_INSTANCE = clazz.getMethod("getInstance", new Class[] { String.class } );
-				CURRENCY_GET_CODE = clazz.getMethod("getCurrencyCode", new Class[0] );
-			}
-			catch (Exception e) {
-				throw new AssertionFailure("Exception in static initializer of CurrencyType", e);
-			}
-		}
-	}
-
-	/**
-	 * @see org.hibernate.type.NullableType#get(ResultSet, String)
-	 */
-	public Object get(ResultSet rs, String name)
-	throws HibernateException, SQLException {
-		String code = (String) Hibernate.STRING.nullSafeGet(rs, name);
-		try {
-			return code==null ? null : 
-					CURRENCY_GET_INSTANCE.invoke(null, new Object[] { code } );
-		}
-		catch (Exception e) {
-			throw new HibernateException("Could not resolve currency code: " + code);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.type.NullableType#set(PreparedStatement, Object, int)
-	 */
-	public void set(PreparedStatement st, Object value, int index)
-	throws HibernateException, SQLException {
-		Object code;
-		try {
-			code = CURRENCY_GET_CODE.invoke(value, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException("Could not get Currency code", e);
-		}
-		Hibernate.STRING.set(st, code, index);
-	}
-
-	/**
-	 * @see org.hibernate.type.NullableType#sqlType()
-	 */
-	public int sqlType() {
-		return Hibernate.STRING.sqlType();
-	}
-
-	/**
-	 */
-	public String toString(Object value) throws HibernateException {
-		try {
-			return (String) CURRENCY_GET_CODE.invoke(value, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException("Could not get Currency code", e);
-		}
-	}
-
-	/**
-	 * @see org.hibernate.type.Type#getReturnedClass()
-	 */
-	public Class getReturnedClass() {
-		return CURRENCY_CLASS;
-	}
-
-	/**
-	 * @see org.hibernate.type.Type#getName()
-	 */
-	public String getName() {
-		return "currency";
-	}
-
-	/**
-	 * @see org.hibernate.type.LiteralType#objectToSQLString(Object, Dialect)
-	 */
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		String code;
-		try {
-			code = (String) CURRENCY_GET_CODE.invoke(value, null);
-		}
-		catch (Exception e) {
-			throw new HibernateException("Could not get Currency code", e);
-		}
-		return ( (LiteralType) Hibernate.STRING ).objectToSQLString(code, dialect);
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		try {
-			return CURRENCY_GET_INSTANCE.invoke( null, new Object[] {xml} );
-		}
-		catch (Exception e) {
-			throw new HibernateException("Could not resolve currency code: " + xml);
-		}
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CurrencyType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CurrencyType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,165 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.Method;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>currency</tt>: A type that maps an SQL VARCHAR to a
+ * <tt>java.util.Currency</tt>
+ * @see java.util.Currency
+ * @author Gavin King
+ */
+public class CurrencyType extends ImmutableType implements LiteralType {
+
+	public static final Class CURRENCY_CLASS;
+	private static final Method CURRENCY_GET_INSTANCE;
+	private static final Method CURRENCY_GET_CODE;
+
+	static {
+		Class clazz;
+		try {
+			clazz = Class.forName("java.util.Currency");
+		}
+		catch (ClassNotFoundException cnfe) {
+			clazz = null;
+		}
+		if (clazz==null) {
+			CURRENCY_CLASS = null;
+			CURRENCY_GET_INSTANCE = null;
+			CURRENCY_GET_CODE = null;
+		}
+		else {
+			CURRENCY_CLASS = clazz;
+			try {
+				CURRENCY_GET_INSTANCE = clazz.getMethod("getInstance", new Class[] { String.class } );
+				CURRENCY_GET_CODE = clazz.getMethod("getCurrencyCode", new Class[0] );
+			}
+			catch (Exception e) {
+				throw new AssertionFailure("Exception in static initializer of CurrencyType", e);
+			}
+		}
+	}
+
+	/**
+	 * @see org.hibernate.type.NullableType#get(ResultSet, String)
+	 */
+	public Object get(ResultSet rs, String name)
+	throws HibernateException, SQLException {
+		String code = (String) Hibernate.STRING.nullSafeGet(rs, name);
+		try {
+			return code==null ? null : 
+					CURRENCY_GET_INSTANCE.invoke(null, new Object[] { code } );
+		}
+		catch (Exception e) {
+			throw new HibernateException("Could not resolve currency code: " + code);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.type.NullableType#set(PreparedStatement, Object, int)
+	 */
+	public void set(PreparedStatement st, Object value, int index)
+	throws HibernateException, SQLException {
+		Object code;
+		try {
+			code = CURRENCY_GET_CODE.invoke(value, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException("Could not get Currency code", e);
+		}
+		Hibernate.STRING.set(st, code, index);
+	}
+
+	/**
+	 * @see org.hibernate.type.NullableType#sqlType()
+	 */
+	public int sqlType() {
+		return Hibernate.STRING.sqlType();
+	}
+
+	/**
+	 */
+	public String toString(Object value) throws HibernateException {
+		try {
+			return (String) CURRENCY_GET_CODE.invoke(value, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException("Could not get Currency code", e);
+		}
+	}
+
+	/**
+	 * @see org.hibernate.type.Type#getReturnedClass()
+	 */
+	public Class getReturnedClass() {
+		return CURRENCY_CLASS;
+	}
+
+	/**
+	 * @see org.hibernate.type.Type#getName()
+	 */
+	public String getName() {
+		return "currency";
+	}
+
+	/**
+	 * @see org.hibernate.type.LiteralType#objectToSQLString(Object, Dialect)
+	 */
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		String code;
+		try {
+			code = (String) CURRENCY_GET_CODE.invoke(value, null);
+		}
+		catch (Exception e) {
+			throw new HibernateException("Could not get Currency code", e);
+		}
+		return ( (LiteralType) Hibernate.STRING ).objectToSQLString(code, dialect);
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		try {
+			return CURRENCY_GET_INSTANCE.invoke( null, new Object[] {xml} );
+		}
+		catch (Exception e) {
+			throw new HibernateException("Could not resolve currency code: " + xml);
+		}
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CustomCollectionType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,94 +0,0 @@
-//$Id: CustomCollectionType.java 11496 2007-05-09 03:54:06Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-import org.hibernate.usertype.UserCollectionType;
-import org.hibernate.usertype.LoggableUserType;
-
-/**
- * A custom type for mapping user-written classes that implement <tt>PersistentCollection</tt>
- * 
- * @see org.hibernate.collection.PersistentCollection
- * @see org.hibernate.usertype.UserCollectionType
- * @author Gavin King
- */
-public class CustomCollectionType extends CollectionType {
-
-	private final UserCollectionType userType;
-	private final boolean customLogging;
-
-	public CustomCollectionType(Class userTypeClass, String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) {
-		super(role, foreignKeyPropertyName, isEmbeddedInXML);
-
-		if ( !UserCollectionType.class.isAssignableFrom( userTypeClass ) ) {
-			throw new MappingException( "Custom type does not implement UserCollectionType: " + userTypeClass.getName() );
-		}
-
-		try {
-			userType = ( UserCollectionType ) userTypeClass.newInstance();
-		}
-		catch ( InstantiationException ie ) {
-			throw new MappingException( "Cannot instantiate custom type: " + userTypeClass.getName() );
-		}
-		catch ( IllegalAccessException iae ) {
-			throw new MappingException( "IllegalAccessException trying to instantiate custom type: " + userTypeClass.getName() );
-		}
-
-		customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass );
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key)
-	throws HibernateException {
-		return userType.instantiate(session, persister);
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		return userType.wrap(session, collection);
-	}
-
-	public Class getReturnedClass() {
-		return userType.instantiate( -1 ).getClass();
-	}
-
-	public Object instantiate(int anticipatedType) {
-		return userType.instantiate( anticipatedType );
-	}
-
-	public Iterator getElementsIterator(Object collection) {
-		return userType.getElementsIterator(collection);
-	}
-	public boolean contains(Object collection, Object entity, SessionImplementor session) {
-		return userType.contains(collection, entity);
-	}
-	public Object indexOf(Object collection, Object entity) {
-		return userType.indexOf(collection, entity);
-	}
-
-	public Object replaceElements(Object original, Object target, Object owner, Map copyCache, SessionImplementor session)
-	throws HibernateException {
-		CollectionPersister cp = session.getFactory().getCollectionPersister( getRole() );
-		return userType.replaceElements(original, target, cp, owner, copyCache, session);
-	}
-
-	protected String renderLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
-		if ( customLogging ) {
-			return ( ( LoggableUserType ) userType ).toLoggableString( value, factory );
-		}
-		else {
-			return super.renderLoggableString( value, factory );
-		}
-	}
-
-	public UserCollectionType getUserType() {
-		return userType;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CustomCollectionType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomCollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,117 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+import org.hibernate.usertype.UserCollectionType;
+import org.hibernate.usertype.LoggableUserType;
+
+/**
+ * A custom type for mapping user-written classes that implement <tt>PersistentCollection</tt>
+ * 
+ * @see org.hibernate.collection.PersistentCollection
+ * @see org.hibernate.usertype.UserCollectionType
+ * @author Gavin King
+ */
+public class CustomCollectionType extends CollectionType {
+
+	private final UserCollectionType userType;
+	private final boolean customLogging;
+
+	public CustomCollectionType(Class userTypeClass, String role, String foreignKeyPropertyName, boolean isEmbeddedInXML) {
+		super(role, foreignKeyPropertyName, isEmbeddedInXML);
+
+		if ( !UserCollectionType.class.isAssignableFrom( userTypeClass ) ) {
+			throw new MappingException( "Custom type does not implement UserCollectionType: " + userTypeClass.getName() );
+		}
+
+		try {
+			userType = ( UserCollectionType ) userTypeClass.newInstance();
+		}
+		catch ( InstantiationException ie ) {
+			throw new MappingException( "Cannot instantiate custom type: " + userTypeClass.getName() );
+		}
+		catch ( IllegalAccessException iae ) {
+			throw new MappingException( "IllegalAccessException trying to instantiate custom type: " + userTypeClass.getName() );
+		}
+
+		customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass );
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key)
+	throws HibernateException {
+		return userType.instantiate(session, persister);
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		return userType.wrap(session, collection);
+	}
+
+	public Class getReturnedClass() {
+		return userType.instantiate( -1 ).getClass();
+	}
+
+	public Object instantiate(int anticipatedType) {
+		return userType.instantiate( anticipatedType );
+	}
+
+	public Iterator getElementsIterator(Object collection) {
+		return userType.getElementsIterator(collection);
+	}
+	public boolean contains(Object collection, Object entity, SessionImplementor session) {
+		return userType.contains(collection, entity);
+	}
+	public Object indexOf(Object collection, Object entity) {
+		return userType.indexOf(collection, entity);
+	}
+
+	public Object replaceElements(Object original, Object target, Object owner, Map copyCache, SessionImplementor session)
+	throws HibernateException {
+		CollectionPersister cp = session.getFactory().getCollectionPersister( getRole() );
+		return userType.replaceElements(original, target, cp, owner, copyCache, session);
+	}
+
+	protected String renderLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
+		if ( customLogging ) {
+			return ( ( LoggableUserType ) userType ).toLoggableString( value, factory );
+		}
+		else {
+			return super.renderLoggableString( value, factory );
+		}
+	}
+
+	public UserCollectionType getUserType() {
+		return userType;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/CustomType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,238 +0,0 @@
-//$Id: CustomType.java 10084 2006-07-05 15:03:52Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Properties;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.usertype.EnhancedUserType;
-import org.hibernate.usertype.UserType;
-import org.hibernate.usertype.UserVersionType;
-import org.hibernate.usertype.LoggableUserType;
-
-/**
- * Adapts {@link UserType} to the generic {@link Type} interface, in order
- * to isolate user code from changes in the internal Type contracts.
- *
- * @see org.hibernate.usertype.UserType
- * @author Gavin King
- */
-public class CustomType extends AbstractType implements IdentifierType, DiscriminatorType, VersionType {
-
-	private final UserType userType;
-	private final String name;
-	private final int[] types;
-	private final boolean customLogging;
-
-	public CustomType(Class userTypeClass, Properties parameters) throws MappingException {
-
-		if ( !UserType.class.isAssignableFrom( userTypeClass ) ) {
-			throw new MappingException(
-					"Custom type does not implement UserType: " +
-					userTypeClass.getName()
-				);
-		}
-
-		name = userTypeClass.getName();
-
-		try {
-			userType = ( UserType ) userTypeClass.newInstance();
-		}
-		catch ( InstantiationException ie ) {
-			throw new MappingException(
-					"Cannot instantiate custom type: " +
-					userTypeClass.getName()
-				);
-		}
-		catch ( IllegalAccessException iae ) {
-			throw new MappingException(
-					"IllegalAccessException trying to instantiate custom type: " +
-					userTypeClass.getName()
-				);
-		}
-
-        TypeFactory.injectParameters( userType, parameters );
-		types = userType.sqlTypes();
-
-		customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass );
-	}
-
-	public int[] sqlTypes(Mapping pi) {
-		return types;
-	}
-
-	public int getColumnSpan(Mapping session) {
-		return types.length;
-	}
-
-	public Class getReturnedClass() {
-		return userType.returnedClass();
-	}
-
-	public boolean isEqual(Object x, Object y) throws HibernateException {
-		return userType.equals(x, y);
-	}
-
-	public boolean isEqual(Object x, Object y, EntityMode entityMode)
-	throws HibernateException {
-		return isEqual(x, y);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return userType.hashCode(x);
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String[] names,
-		SessionImplementor session,
-		Object owner
-	) throws HibernateException, SQLException {
-
-		return userType.nullSafeGet(rs, names, owner);
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String columnName,
-		SessionImplementor session,
-		Object owner
-	) throws HibernateException, SQLException {
-		return nullSafeGet(rs, new String[] { columnName }, session, owner);
-	}
-
-
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return userType.assemble(cached, owner);
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return userType.disassemble(value);
-	}
-
-	public Object replace(
-			Object original,
-			Object target,
-			SessionImplementor session,
-			Object owner,
-			Map copyCache)
-	throws HibernateException {
-		return userType.replace(original, target, owner);
-	}
-
-	public void nullSafeSet(
-		PreparedStatement st,
-		Object value,
-		int index,
-		boolean[] settable,
-		SessionImplementor session
-	) throws HibernateException, SQLException {
-
-		if ( settable[0] ) userType.nullSafeSet(st, value, index);
-	}
-
-	public void nullSafeSet(
-		PreparedStatement st,
-		Object value,
-		int index,
-		SessionImplementor session
-	) throws HibernateException, SQLException {
-
-		userType.nullSafeSet(st, value, index);
-	}
-
-	public String toXMLString(Object value, SessionFactoryImplementor factory) {
-		if (value==null) return null;
-		if (userType instanceof EnhancedUserType) {
-			return ( (EnhancedUserType) userType ).toXMLString(value);
-		}
-		else {
-			return value.toString();
-		}
-	}
-
-	public Object fromXMLString(String xml, Mapping factory) {
-		return ( (EnhancedUserType) userType ).fromXMLString(xml);
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
-	throws HibernateException {
-		return userType.deepCopy(value);
-	}
-
-	public boolean isMutable() {
-		return userType.isMutable();
-	}
-
-	public Object stringToObject(String xml) {
-		return ( (EnhancedUserType) userType ).fromXMLString(xml);
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return ( (EnhancedUserType) userType ).objectToSQLString(value);
-	}
-
-	public Comparator getComparator() {
-		return (Comparator) userType;
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return ( (UserVersionType) userType ).next( current, session );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return ( (UserVersionType) userType ).seed( session );
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return fromXMLString( xml.getText(), factory );
-	}
-
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
-	throws HibernateException {
-		node.setText( toXMLString(value, factory) );
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-	throws HibernateException {
-		if ( value == null ) {
-			return "null";
-		}
-		else if ( customLogging ) {
-			return ( ( LoggableUserType ) userType ).toLoggableString( value, factory );
-		}
-		else {
-			return toXMLString( value, factory );
-		}
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		boolean[] result = new boolean[ getColumnSpan(mapping) ];
-		if (value!=null) Arrays.fill(result, true);
-		return result;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return checkable[0] && isDirty(old, current, session);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/CustomType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/CustomType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,261 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.usertype.EnhancedUserType;
+import org.hibernate.usertype.UserType;
+import org.hibernate.usertype.UserVersionType;
+import org.hibernate.usertype.LoggableUserType;
+
+/**
+ * Adapts {@link UserType} to the generic {@link Type} interface, in order
+ * to isolate user code from changes in the internal Type contracts.
+ *
+ * @see org.hibernate.usertype.UserType
+ * @author Gavin King
+ */
+public class CustomType extends AbstractType implements IdentifierType, DiscriminatorType, VersionType {
+
+	private final UserType userType;
+	private final String name;
+	private final int[] types;
+	private final boolean customLogging;
+
+	public CustomType(Class userTypeClass, Properties parameters) throws MappingException {
+
+		if ( !UserType.class.isAssignableFrom( userTypeClass ) ) {
+			throw new MappingException(
+					"Custom type does not implement UserType: " +
+					userTypeClass.getName()
+				);
+		}
+
+		name = userTypeClass.getName();
+
+		try {
+			userType = ( UserType ) userTypeClass.newInstance();
+		}
+		catch ( InstantiationException ie ) {
+			throw new MappingException(
+					"Cannot instantiate custom type: " +
+					userTypeClass.getName()
+				);
+		}
+		catch ( IllegalAccessException iae ) {
+			throw new MappingException(
+					"IllegalAccessException trying to instantiate custom type: " +
+					userTypeClass.getName()
+				);
+		}
+
+        TypeFactory.injectParameters( userType, parameters );
+		types = userType.sqlTypes();
+
+		customLogging = LoggableUserType.class.isAssignableFrom( userTypeClass );
+	}
+
+	public int[] sqlTypes(Mapping pi) {
+		return types;
+	}
+
+	public int getColumnSpan(Mapping session) {
+		return types.length;
+	}
+
+	public Class getReturnedClass() {
+		return userType.returnedClass();
+	}
+
+	public boolean isEqual(Object x, Object y) throws HibernateException {
+		return userType.equals(x, y);
+	}
+
+	public boolean isEqual(Object x, Object y, EntityMode entityMode)
+	throws HibernateException {
+		return isEqual(x, y);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return userType.hashCode(x);
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String[] names,
+		SessionImplementor session,
+		Object owner
+	) throws HibernateException, SQLException {
+
+		return userType.nullSafeGet(rs, names, owner);
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String columnName,
+		SessionImplementor session,
+		Object owner
+	) throws HibernateException, SQLException {
+		return nullSafeGet(rs, new String[] { columnName }, session, owner);
+	}
+
+
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return userType.assemble(cached, owner);
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return userType.disassemble(value);
+	}
+
+	public Object replace(
+			Object original,
+			Object target,
+			SessionImplementor session,
+			Object owner,
+			Map copyCache)
+	throws HibernateException {
+		return userType.replace(original, target, owner);
+	}
+
+	public void nullSafeSet(
+		PreparedStatement st,
+		Object value,
+		int index,
+		boolean[] settable,
+		SessionImplementor session
+	) throws HibernateException, SQLException {
+
+		if ( settable[0] ) userType.nullSafeSet(st, value, index);
+	}
+
+	public void nullSafeSet(
+		PreparedStatement st,
+		Object value,
+		int index,
+		SessionImplementor session
+	) throws HibernateException, SQLException {
+
+		userType.nullSafeSet(st, value, index);
+	}
+
+	public String toXMLString(Object value, SessionFactoryImplementor factory) {
+		if (value==null) return null;
+		if (userType instanceof EnhancedUserType) {
+			return ( (EnhancedUserType) userType ).toXMLString(value);
+		}
+		else {
+			return value.toString();
+		}
+	}
+
+	public Object fromXMLString(String xml, Mapping factory) {
+		return ( (EnhancedUserType) userType ).fromXMLString(xml);
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory)
+	throws HibernateException {
+		return userType.deepCopy(value);
+	}
+
+	public boolean isMutable() {
+		return userType.isMutable();
+	}
+
+	public Object stringToObject(String xml) {
+		return ( (EnhancedUserType) userType ).fromXMLString(xml);
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return ( (EnhancedUserType) userType ).objectToSQLString(value);
+	}
+
+	public Comparator getComparator() {
+		return (Comparator) userType;
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return ( (UserVersionType) userType ).next( current, session );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return ( (UserVersionType) userType ).seed( session );
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return fromXMLString( xml.getText(), factory );
+	}
+
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
+	throws HibernateException {
+		node.setText( toXMLString(value, factory) );
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+	throws HibernateException {
+		if ( value == null ) {
+			return "null";
+		}
+		else if ( customLogging ) {
+			return ( ( LoggableUserType ) userType ).toLoggableString( value, factory );
+		}
+		else {
+			return toXMLString( value, factory );
+		}
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		boolean[] result = new boolean[ getColumnSpan(mapping) ];
+		if (value!=null) Arrays.fill(result, true);
+		return result;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return checkable[0] && isDirty(old, current, session);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/DateType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: DateType.java 8891 2005-12-21 05:13:29Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.Date;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>date</tt>: A type that maps an SQL DATE to a Java Date.
- * @author Gavin King
- */
-public class DateType extends MutableType implements IdentifierType, LiteralType {
-
-	private static final String DATE_FORMAT = "dd MMMM yyyy";
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return rs.getDate(name);
-	}
-
-	public Class getReturnedClass() {
-		return java.util.Date.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-
-		Date sqlDate;
-		if ( value instanceof Date) {
-			sqlDate = (Date) value;
-		}
-		else {
-			sqlDate = new Date( ( (java.util.Date) value ).getTime() );
-		}
-		st.setDate(index, sqlDate);
-	}
-
-	public int sqlType() {
-		return Types.DATE;
-	}
-
-	public boolean isEqual(Object x, Object y) {
-
-		if (x==y) return true;
-		if (x==null || y==null) return false;
-
-		java.util.Date xdate = (java.util.Date) x;
-		java.util.Date ydate = (java.util.Date) y;
-		
-		if ( xdate.getTime()==ydate.getTime() ) return true;
-		
-		Calendar calendar1 = java.util.Calendar.getInstance();
-		Calendar calendar2 = java.util.Calendar.getInstance();
-		calendar1.setTime( xdate );
-		calendar2.setTime( ydate );
-
-		return Hibernate.CALENDAR_DATE.isEqual(calendar1, calendar2);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		Calendar calendar = java.util.Calendar.getInstance();
-		calendar.setTime( (java.util.Date) x );
-		return Hibernate.CALENDAR_DATE.getHashCode(calendar, entityMode);
-	}
-	
-	public String getName() { return "date"; }
-
-	public String toString(Object val) {
-		return new SimpleDateFormat(DATE_FORMAT).format( (java.util.Date) val );
-	}
-
-	public Object deepCopyNotNull(Object value) {
-		return new Date( ( (java.util.Date) value ).getTime() );
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return DateFormat.getDateInstance().parse(xml);
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return '\'' + new Date( ( (java.util.Date) value ).getTime() ).toString() + '\'';
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		try {
-			return new SimpleDateFormat(DATE_FORMAT).parse(xml);
-		}
-		catch (ParseException pe) {
-			throw new HibernateException("could not parse XML", pe);
-		}
-	}
-	
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/DateType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DateType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.type;
+
+import java.sql.Date;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>date</tt>: A type that maps an SQL DATE to a Java Date.
+ * @author Gavin King
+ */
+public class DateType extends MutableType implements IdentifierType, LiteralType {
+
+	private static final String DATE_FORMAT = "dd MMMM yyyy";
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return rs.getDate(name);
+	}
+
+	public Class getReturnedClass() {
+		return java.util.Date.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+
+		Date sqlDate;
+		if ( value instanceof Date) {
+			sqlDate = (Date) value;
+		}
+		else {
+			sqlDate = new Date( ( (java.util.Date) value ).getTime() );
+		}
+		st.setDate(index, sqlDate);
+	}
+
+	public int sqlType() {
+		return Types.DATE;
+	}
+
+	public boolean isEqual(Object x, Object y) {
+
+		if (x==y) return true;
+		if (x==null || y==null) return false;
+
+		java.util.Date xdate = (java.util.Date) x;
+		java.util.Date ydate = (java.util.Date) y;
+		
+		if ( xdate.getTime()==ydate.getTime() ) return true;
+		
+		Calendar calendar1 = java.util.Calendar.getInstance();
+		Calendar calendar2 = java.util.Calendar.getInstance();
+		calendar1.setTime( xdate );
+		calendar2.setTime( ydate );
+
+		return Hibernate.CALENDAR_DATE.isEqual(calendar1, calendar2);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		Calendar calendar = java.util.Calendar.getInstance();
+		calendar.setTime( (java.util.Date) x );
+		return Hibernate.CALENDAR_DATE.getHashCode(calendar, entityMode);
+	}
+	
+	public String getName() { return "date"; }
+
+	public String toString(Object val) {
+		return new SimpleDateFormat(DATE_FORMAT).format( (java.util.Date) val );
+	}
+
+	public Object deepCopyNotNull(Object value) {
+		return new Date( ( (java.util.Date) value ).getTime() );
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return DateFormat.getDateInstance().parse(xml);
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return '\'' + new Date( ( (java.util.Date) value ).getTime() ).toString() + '\'';
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		try {
+			return new SimpleDateFormat(DATE_FORMAT).parse(xml);
+		}
+		catch (ParseException pe) {
+			throw new HibernateException("could not parse XML", pe);
+		}
+	}
+	
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/DbTimestampType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,130 +0,0 @@
-// $Id: DbTimestampType.java 7830 2005-08-11 00:10:26Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.Timestamp;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.sql.ResultSet;
-import java.sql.CallableStatement;
-
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.exception.JDBCExceptionHelper;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * <tt>dbtimestamp</tt>: An extension of {@link TimestampType} which
- * maps to the database's current timestamp, rather than the jvm's
- * current timestamp.
- * <p/>
- * Note: May/may-not cause issues on dialects which do not properly support
- * a true notion of timestamp (Oracle < 8, for example, where only its DATE
- * datatype is supported).  Depends on the frequency of DML operations...
- *
- * @author Steve Ebersole
- */
-public class DbTimestampType extends TimestampType implements VersionType {
-
-	private static final Logger log = LoggerFactory.getLogger( DbTimestampType.class );
-	
-	public String getName() { return "dbtimestamp"; }
-
-	public Object seed(SessionImplementor session) {
-		if ( session == null ) {
-			log.trace( "incoming session was null; using current jvm time" );
-			return super.seed( session );
-		}
-		else if ( !session.getFactory().getDialect().supportsCurrentTimestampSelection() ) {
-			log.debug( "falling back to vm-based timestamp, as dialect does not support current timestamp selection" );
-			return super.seed( session );
-		}
-		else {
-			return getCurrentTimestamp( session );
-		}
-	}
-
-	private Timestamp getCurrentTimestamp(SessionImplementor session) {
-		Dialect dialect = session.getFactory().getDialect();
-		String timestampSelectString = dialect.getCurrentTimestampSelectString();
-		if ( dialect.isCurrentTimestampSelectStringCallable() ) {
-			return useCallableStatement( timestampSelectString, session );
-		}
-		else {
-			return usePreparedStatement( timestampSelectString, session );
-		}
-	}
-
-	private Timestamp usePreparedStatement(String timestampSelectString, SessionImplementor session) {
-		PreparedStatement ps = null;
-		try {
-			ps = session.getBatcher().prepareStatement( timestampSelectString );
-			ResultSet rs = session.getBatcher().getResultSet( ps );
-			rs.next();
-			Timestamp ts = rs.getTimestamp( 1 );
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-				        "current timestamp retreived from db : " + ts +
-				        " (nanos=" + ts.getNanos() +
-				        ", time=" + ts.getTime() + ")"
-					);
-			}
-			return ts;
-		}
-		catch( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not select current db timestamp",
-			        timestampSelectString
-				);
-		}
-		finally {
-			if ( ps != null ) {
-				try {
-					session.getBatcher().closeStatement( ps );
-				}
-				catch( SQLException sqle ) {
-					log.warn( "unable to clean up prepared statement", sqle );
-				}
-			}
-		}
-	}
-
-	private Timestamp useCallableStatement(String callString, SessionImplementor session) {
-		CallableStatement cs = null;
-		try {
-			cs = session.getBatcher().prepareCallableStatement( callString );
-			cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
-			cs.execute();
-			Timestamp ts = cs.getTimestamp( 1 );
-			if ( log.isTraceEnabled() ) {
-				log.trace(
-				        "current timestamp retreived from db : " + ts +
-				        " (nanos=" + ts.getNanos() +
-				        ", time=" + ts.getTime() + ")"
-					);
-			}
-			return ts;
-		}
-		catch( SQLException sqle ) {
-			throw JDBCExceptionHelper.convert(
-			        session.getFactory().getSQLExceptionConverter(),
-			        sqle,
-			        "could not call current db timestamp function",
-			        callString
-				);
-		}
-		finally {
-			if ( cs != null ) {
-				try {
-					session.getBatcher().closeStatement( cs );
-				}
-				catch( SQLException sqle ) {
-					log.warn( "unable to clean up callable statement", sqle );
-				}
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/DbTimestampType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DbTimestampType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,153 @@
+/*
+ * 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.type;
+
+import java.sql.Timestamp;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.ResultSet;
+import java.sql.CallableStatement;
+
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.exception.JDBCExceptionHelper;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <tt>dbtimestamp</tt>: An extension of {@link TimestampType} which
+ * maps to the database's current timestamp, rather than the jvm's
+ * current timestamp.
+ * <p/>
+ * Note: May/may-not cause issues on dialects which do not properly support
+ * a true notion of timestamp (Oracle < 8, for example, where only its DATE
+ * datatype is supported).  Depends on the frequency of DML operations...
+ *
+ * @author Steve Ebersole
+ */
+public class DbTimestampType extends TimestampType implements VersionType {
+
+	private static final Logger log = LoggerFactory.getLogger( DbTimestampType.class );
+	
+	public String getName() { return "dbtimestamp"; }
+
+	public Object seed(SessionImplementor session) {
+		if ( session == null ) {
+			log.trace( "incoming session was null; using current jvm time" );
+			return super.seed( session );
+		}
+		else if ( !session.getFactory().getDialect().supportsCurrentTimestampSelection() ) {
+			log.debug( "falling back to vm-based timestamp, as dialect does not support current timestamp selection" );
+			return super.seed( session );
+		}
+		else {
+			return getCurrentTimestamp( session );
+		}
+	}
+
+	private Timestamp getCurrentTimestamp(SessionImplementor session) {
+		Dialect dialect = session.getFactory().getDialect();
+		String timestampSelectString = dialect.getCurrentTimestampSelectString();
+		if ( dialect.isCurrentTimestampSelectStringCallable() ) {
+			return useCallableStatement( timestampSelectString, session );
+		}
+		else {
+			return usePreparedStatement( timestampSelectString, session );
+		}
+	}
+
+	private Timestamp usePreparedStatement(String timestampSelectString, SessionImplementor session) {
+		PreparedStatement ps = null;
+		try {
+			ps = session.getBatcher().prepareStatement( timestampSelectString );
+			ResultSet rs = session.getBatcher().getResultSet( ps );
+			rs.next();
+			Timestamp ts = rs.getTimestamp( 1 );
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+				        "current timestamp retreived from db : " + ts +
+				        " (nanos=" + ts.getNanos() +
+				        ", time=" + ts.getTime() + ")"
+					);
+			}
+			return ts;
+		}
+		catch( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not select current db timestamp",
+			        timestampSelectString
+				);
+		}
+		finally {
+			if ( ps != null ) {
+				try {
+					session.getBatcher().closeStatement( ps );
+				}
+				catch( SQLException sqle ) {
+					log.warn( "unable to clean up prepared statement", sqle );
+				}
+			}
+		}
+	}
+
+	private Timestamp useCallableStatement(String callString, SessionImplementor session) {
+		CallableStatement cs = null;
+		try {
+			cs = session.getBatcher().prepareCallableStatement( callString );
+			cs.registerOutParameter( 1, java.sql.Types.TIMESTAMP );
+			cs.execute();
+			Timestamp ts = cs.getTimestamp( 1 );
+			if ( log.isTraceEnabled() ) {
+				log.trace(
+				        "current timestamp retreived from db : " + ts +
+				        " (nanos=" + ts.getNanos() +
+				        ", time=" + ts.getTime() + ")"
+					);
+			}
+			return ts;
+		}
+		catch( SQLException sqle ) {
+			throw JDBCExceptionHelper.convert(
+			        session.getFactory().getSQLExceptionConverter(),
+			        sqle,
+			        "could not call current db timestamp function",
+			        callString
+				);
+		}
+		finally {
+			if ( cs != null ) {
+				try {
+					session.getBatcher().closeStatement( cs );
+				}
+				catch( SQLException sqle ) {
+					log.warn( "unable to clean up callable statement", sqle );
+				}
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/DiscriminatorType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: DiscriminatorType.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.type;
-
-/**
- * A <tt>Type</tt> that may be used for a discriminator column.
- * @author Gavin King
- */
-public interface DiscriminatorType extends IdentifierType, LiteralType {
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/DiscriminatorType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DiscriminatorType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+/**
+ * A <tt>Type</tt> that may be used for a discriminator column.
+ * @author Gavin King
+ */
+public interface DiscriminatorType extends IdentifierType, LiteralType {
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/DoubleType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,57 +0,0 @@
-//$Id: DoubleType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>double</tt>: A type that maps an SQL DOUBLE to a Java Double.
- * @author Gavin King
- */
-public class DoubleType extends PrimitiveType {
-
-	public Serializable getDefaultValue() {
-		return new Double(0.0);
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Double( rs.getDouble(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return double.class;
-	}
-
-	public Class getReturnedClass() {
-		return Double.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-		throws SQLException {
-
-		st.setDouble( index, ( (Double) value ).doubleValue() );
-	}
-
-	public int sqlType() {
-		return Types.DOUBLE;
-	}
-	public String getName() { return "double"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object fromStringValue(String xml) {
-		return new Double(xml);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/DoubleType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/DoubleType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>double</tt>: A type that maps an SQL DOUBLE to a Java Double.
+ * @author Gavin King
+ */
+public class DoubleType extends PrimitiveType {
+
+	public Serializable getDefaultValue() {
+		return new Double(0.0);
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Double( rs.getDouble(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return double.class;
+	}
+
+	public Class getReturnedClass() {
+		return Double.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+		throws SQLException {
+
+		st.setDouble( index, ( (Double) value ).doubleValue() );
+	}
+
+	public int sqlType() {
+		return Types.DOUBLE;
+	}
+	public String getName() { return "double"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object fromStringValue(String xml) {
+		return new Double(xml);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: EmbeddedComponentType.java 10119 2006-07-14 00:09:19Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.lang.reflect.Method;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.tuple.component.ComponentTuplizer;
-import org.hibernate.tuple.component.ComponentMetamodel;
-
-/**
- * @author Gavin King
- */
-public class EmbeddedComponentType extends ComponentType {
-
-	public boolean isEmbedded() {
-		return true;
-	}
-
-	public EmbeddedComponentType(ComponentMetamodel metamodel) {
-		super( metamodel );
-	}
-
-	public boolean isMethodOf(Method method) {
-		return ( ( ComponentTuplizer ) tuplizerMapping.getTuplizer(EntityMode.POJO) ).isMethodOf(method);
-	}
-
-	public Object instantiate(Object parent, SessionImplementor session)
-	throws HibernateException {
-		final boolean useParent = parent!=null &&
-		                          //TODO: Yuck! This is not quite good enough, it's a quick
-		                          //hack around the problem of having a to-one association
-		                          //that refers to an embedded component:
-		                          super.getReturnedClass().isInstance(parent);
-
-		return useParent ? parent : super.instantiate(parent, session);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EmbeddedComponentType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.type;
+
+import java.lang.reflect.Method;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.tuple.component.ComponentTuplizer;
+import org.hibernate.tuple.component.ComponentMetamodel;
+
+/**
+ * @author Gavin King
+ */
+public class EmbeddedComponentType extends ComponentType {
+
+	public boolean isEmbedded() {
+		return true;
+	}
+
+	public EmbeddedComponentType(ComponentMetamodel metamodel) {
+		super( metamodel );
+	}
+
+	public boolean isMethodOf(Method method) {
+		return ( ( ComponentTuplizer ) tuplizerMapping.getTuplizer(EntityMode.POJO) ).isMethodOf(method);
+	}
+
+	public Object instantiate(Object parent, SessionImplementor session)
+	throws HibernateException {
+		final boolean useParent = parent!=null &&
+		                          //TODO: Yuck! This is not quite good enough, it's a quick
+		                          //hack around the problem of having a to-one association
+		                          //that refers to an embedded component:
+		                          super.getReturnedClass().isInstance(parent);
+
+		return useParent ? parent : super.instantiate(parent, session);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/EntityType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,623 +0,0 @@
-//$Id: EntityType.java 14513 2008-04-17 23:05:11Z gbadner $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.hibernate.AssertionFailure;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.EntityUniqueKey;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.PersistenceContext;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.persister.entity.Joinable;
-import org.hibernate.persister.entity.UniqueKeyLoadable;
-import org.hibernate.proxy.HibernateProxy;
-import org.hibernate.proxy.LazyInitializer;
-import org.hibernate.tuple.ElementWrapper;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Base for types which map associations to persistent entities.
- *
- * @author Gavin King
- */
-public abstract class EntityType extends AbstractType implements AssociationType {
-
-	private final String associatedEntityName;
-	protected final String uniqueKeyPropertyName;
-	protected final boolean isEmbeddedInXML;
-	private final boolean eager;
-	private final boolean unwrapProxy;
-
-	private transient Class returnedClass;
-
-	/**
-	 * Constructs the requested entity type mapping.
-	 *
-	 * @param entityName The name of the associated entity.
-	 * @param uniqueKeyPropertyName The property-ref name, or null if we
-	 * reference the PK of the associated entity.
-	 * @param eager Is eager fetching enabled.
-	 * @param isEmbeddedInXML Should values of this mapping be embedded in XML modes?
-	 * @param unwrapProxy Is unwrapping of proxies allowed for this association; unwrapping
-	 * says to return the "implementation target" of lazy prooxies; typically only possible
-	 * with lazy="no-proxy".
-	 */
-	protected EntityType(
-			String entityName,
-			String uniqueKeyPropertyName,
-			boolean eager,
-			boolean isEmbeddedInXML,
-			boolean unwrapProxy) {
-		this.associatedEntityName = entityName;
-		this.uniqueKeyPropertyName = uniqueKeyPropertyName;
-		this.isEmbeddedInXML = isEmbeddedInXML;
-		this.eager = eager;
-		this.unwrapProxy = unwrapProxy;
-	}
-
-	/**
-	 * An entity type is a type of association type
-	 *
-	 * @return True.
-	 */
-	public boolean isAssociationType() {
-		return true;
-	}
-
-	/**
-	 * Explicitly, an entity type is an entity type ;)
-	 *
-	 * @return True.
-	 */
-	public final boolean isEntityType() {
-		return true;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isMutable() {
-		return false;
-	}
-
-	/**
-	 * Generates a string representation of this type.
-	 *
-	 * @return string rep
-	 */
-	public String toString() {
-		return getClass().getName() + '(' + getAssociatedEntityName() + ')';
-	}
-
-	/**
-	 * For entity types, the name correlates to the associated entity name.
-	 */
-	public String getName() {
-		return associatedEntityName;
-	}
-
-	/**
-	 * Does this association foreign key reference the primary key of the other table?
-	 * Otherwise, it references a property-ref.
-	 *
-	 * @return True if this association reference the PK of the associated entity.
-	 */
-	public boolean isReferenceToPrimaryKey() {
-		return uniqueKeyPropertyName==null;
-	}
-
-	public String getRHSUniqueKeyPropertyName() {
-		return uniqueKeyPropertyName;
-	}
-
-	public String getLHSPropertyName() {
-		return null;
-	}
-
-	public String getPropertyName() {
-		return null;
-	}
-
-	/**
-	 * The name of the associated entity.
-	 *
-	 * @return The associated entity name.
-	 */
-	public final String getAssociatedEntityName() {
-		return associatedEntityName;
-	}
-
-	/**
-	 * The name of the associated entity.
-	 *
-	 * @param factory The session factory, for resolution.
-	 * @return The associated entity name.
-	 */
-	public String getAssociatedEntityName(SessionFactoryImplementor factory) {
-		return getAssociatedEntityName();
-	}
-
-	/**
-	 * Retrieves the {@link Joinable} defining the associated entity.
-	 *
-	 * @param factory The session factory.
-	 * @return The associated joinable
-	 * @throws MappingException Generally indicates an invalid entity name.
-	 */
-	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException {
-		return ( Joinable ) factory.getEntityPersister( associatedEntityName );
-	}
-
-	/**
-	 * This returns the wrong class for an entity with a proxy, or for a named
-	 * entity.  Theoretically it should return the proxy class, but it doesn't.
-	 * <p/>
-	 * The problem here is that we do not necessarily have a ref to the associated
-	 * entity persister (nor to the session factory, to look it up) which is really
-	 * needed to "do the right thing" here...
-	 *
-	 * @return The entiyt class.
-	 */
-	public final Class getReturnedClass() {
-		if ( returnedClass == null ) {
-			returnedClass = determineAssociatedEntityClass();
-		}
-		return returnedClass;
-	}
-
-	private Class determineAssociatedEntityClass() {
-		try {
-			return ReflectHelper.classForName( getAssociatedEntityName() );
-		}
-		catch ( ClassNotFoundException cnfe ) {
-			return java.util.Map.class;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException {
-		return nullSafeGet( rs, new String[] {name}, session, owner );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public final Object nullSafeGet(
-			ResultSet rs,
-			String[] names,
-			SessionImplementor session,
-			Object owner) throws HibernateException, SQLException {
-		return resolve( hydrate(rs, names, session, owner), session, owner );
-	}
-
-	/**
-	 * Two entities are considered the same when their instances are the same.
-	 *
-	 * @param x One entity instance
-	 * @param y Another entity instance
-	 * @param entityMode The entity mode.
-	 * @return True if x == y; false otherwise.
-	 */
-	public final boolean isSame(Object x, Object y, EntityMode entityMode) {
-		return x == y;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return 0; //TODO: entities CAN be compared, by PK, fix this! -> only if/when we can extract the id values....
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) {
-		return value; //special case ... this is the leaf of the containment graph, even though not immutable
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object replace(
-			Object original,
-			Object target,
-			SessionImplementor session,
-			Object owner,
-			Map copyCache) throws HibernateException {
-		if ( original == null ) {
-			return null;
-		}
-		Object cached = copyCache.get(original);
-		if ( cached != null ) {
-			return cached;
-		}
-		else {
-			if ( original == target ) {
-				return target;
-			}
-			if ( session.getContextEntityIdentifier( original ) == null  &&
-					ForeignKeys.isTransient( associatedEntityName, original, Boolean.FALSE, session ) ) {
-				final Object copy = session.getFactory().getEntityPersister( associatedEntityName )
-						.instantiate( null, session.getEntityMode() );
-				//TODO: should this be Session.instantiate(Persister, ...)?
-				copyCache.put( original, copy );
-				return copy;
-			}
-			else {
-				Object id = getIdentifier( original, session );
-				if ( id == null ) {
-					throw new AssertionFailure("non-transient entity has a null id");
-				}
-				id = getIdentifierOrUniqueKeyType( session.getFactory() )
-						.replace(id, null, session, owner, copyCache);
-				return resolve( id, session, owner );
-			}
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
-		EntityPersister persister = factory.getEntityPersister(associatedEntityName);
-		if ( !persister.canExtractIdOutOfEntity() ) {
-			return super.getHashCode(x, entityMode);
-		}
-
-		final Serializable id;
-		if (x instanceof HibernateProxy) {
-			id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier();
-		}
-		else {
-			id = persister.getIdentifier(x, entityMode);
-		}
-		return persister.getIdentifierType().getHashCode(id, entityMode, factory);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) {
-		EntityPersister persister = factory.getEntityPersister(associatedEntityName);
-		if ( !persister.canExtractIdOutOfEntity() ) {
-			return super.isEqual(x, y, entityMode);
-		}
-
-		Serializable xid;
-		if (x instanceof HibernateProxy) {
-			xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
-					.getIdentifier();
-		}
-		else {
-			xid = persister.getIdentifier(x, entityMode);
-		}
-
-		Serializable yid;
-		if (y instanceof HibernateProxy) {
-			yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
-					.getIdentifier();
-		}
-		else {
-			yid = persister.getIdentifier(y, entityMode);
-		}
-
-		return persister.getIdentifierType()
-				.isEqual(xid, yid, entityMode, factory);
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isEmbeddedInXML() {
-		return isEmbeddedInXML;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public boolean isXMLElement() {
-		return isEmbeddedInXML;
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		if ( !isEmbeddedInXML ) {
-			return getIdentifierType(factory).fromXMLNode(xml, factory);
-		}
-		else {
-			return xml;
-		}
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
-		if ( !isEmbeddedInXML ) {
-			getIdentifierType(factory).setToXMLNode(node, value, factory);
-		}
-		else {
-			Element elt = (Element) value;
-			replaceNode( node, new ElementWrapper(elt) );
-		}
-	}
-
-	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
-	throws MappingException {
-		if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user?
-			return "";
-		}
-		else {
-			return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters );
-		}
-	}
-
-	/**
-	 * Resolve an identifier or unique key value
-	 */
-	public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException {
-		if ( isNotEmbedded( session ) ) {
-			return value;
-		}
-
-		if ( value == null ) {
-			return null;
-		}
-		else {
-			if ( isNull( owner, session ) ) {
-				return null; //EARLY EXIT!
-			}
-
-			if ( isReferenceToPrimaryKey() ) {
-				return resolveIdentifier( (Serializable) value, session );
-			}
-			else {
-				return loadByUniqueKey( getAssociatedEntityName(), uniqueKeyPropertyName, value, session );
-			}
-		}
-	}
-
-	public Type getSemiResolvedType(SessionFactoryImplementor factory) {
-		return factory.getEntityPersister( associatedEntityName ).getIdentifierType();
-	}
-
-	protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException {
-		if ( isNotEmbedded(session) ) {
-			return value;
-		}
-
-		if ( isReferenceToPrimaryKey() ) {
-			return ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session ); //tolerates nulls
-		}
-		else if ( value == null ) {
-			return null;
-		}
-		else {
-			EntityPersister entityPersister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
-			Object propertyValue = entityPersister.getPropertyValue( value, uniqueKeyPropertyName, session.getEntityMode() );
-			// We now have the value of the property-ref we reference.  However,
-			// we need to dig a little deeper, as that property might also be
-			// an entity type, in which case we need to resolve its identitifier
-			Type type = entityPersister.getPropertyType( uniqueKeyPropertyName );
-			if ( type.isEntityType() ) {
-				propertyValue = ( ( EntityType ) type ).getIdentifier( propertyValue, session );
-			}
-
-			return propertyValue;
-		}
-	}
-
-	protected boolean isNotEmbedded(SessionImplementor session) {
-		return !isEmbeddedInXML && session.getEntityMode()==EntityMode.DOM4J;
-	}
-
-	/**
-	 * Get the identifier value of an instance or proxy.
-	 * <p/>
-	 * Intended only for loggin purposes!!!
-	 *
-	 * @param object The object from which to extract the identifier.
-	 * @param persister The entity persister
-	 * @param entityMode The entity mode
-	 * @return The extracted identifier.
-	 */
-	private static Serializable getIdentifier(Object object, EntityPersister persister, EntityMode entityMode) {
-		if (object instanceof HibernateProxy) {
-			HibernateProxy proxy = (HibernateProxy) object;
-			LazyInitializer li = proxy.getHibernateLazyInitializer();
-			return li.getIdentifier();
-		}
-		else {
-			return persister.getIdentifier( object, entityMode );
-		}
-	}
-
-	/**
-	 * Generate a loggable representation of an instance of the value mapped by this type.
-	 *
-	 * @param value The instance to be logged.
-	 * @param factory The session factory.
-	 * @return The loggable string.
-	 * @throws HibernateException Generally some form of resolution problem.
-	 */
-	public String toLoggableString(Object value, SessionFactoryImplementor factory) {
-		if ( value == null ) {
-			return "null";
-		}
-		
-		EntityPersister persister = factory.getEntityPersister( associatedEntityName );
-		StringBuffer result = new StringBuffer().append( associatedEntityName );
-
-		if ( persister.hasIdentifierProperty() ) {
-			final EntityMode entityMode = persister.guessEntityMode( value );
-			final Serializable id;
-			if ( entityMode == null ) {
-				if ( isEmbeddedInXML ) {
-					throw new ClassCastException( value.getClass().getName() );
-				}
-				id = ( Serializable ) value;
-			}
-			else {
-				id = getIdentifier( value, persister, entityMode );
-			}
-			
-			result.append( '#' )
-				.append( persister.getIdentifierType().toLoggableString( id, factory ) );
-		}
-		
-		return result.toString();
-	}
-
-	public abstract boolean isOneToOne();
-
-	/**
-	 * Convenience method to locate the identifier type of the associated entity.
-	 *
-	 * @param factory The mappings...
-	 * @return The identifier type
-	 */
-	Type getIdentifierType(Mapping factory) {
-		return factory.getIdentifierType( getAssociatedEntityName() );
-	}
-
-	/**
-	 * Convenience method to locate the identifier type of the associated entity.
-	 *
-	 * @param session The originating session
-	 * @return The identifier type
-	 */
-	Type getIdentifierType(SessionImplementor session) {
-		return getIdentifierType( session.getFactory() );
-	}
-
-	/**
-	 * Determine the type of either (1) the identifier if we reference the
-	 * associated entity's PK or (2) the unique key to which we refer (i.e.
-	 * the property-ref).
-	 *
-	 * @param factory The mappings...
-	 * @return The appropriate type.
-	 * @throws MappingException Generally, if unable to resolve the associated entity name
-	 * or unique key property name.
-	 */
-	public final Type getIdentifierOrUniqueKeyType(Mapping factory) throws MappingException {
-		if ( isReferenceToPrimaryKey() ) {
-			return getIdentifierType(factory);
-		}
-		else {
-			Type type = factory.getReferencedPropertyType( getAssociatedEntityName(), uniqueKeyPropertyName );
-			if ( type.isEntityType() ) {
-				type = ( ( EntityType ) type).getIdentifierOrUniqueKeyType( factory );
-			}
-			return type;
-		}
-	}
-
-	/**
-	 * The name of the property on the associated entity to which our FK
-	 * refers
-	 *
-	 * @param factory The mappings...
-	 * @return The appropriate property name.
-	 * @throws MappingException Generally, if unable to resolve the associated entity name
-	 */
-	public final String getIdentifierOrUniqueKeyPropertyName(Mapping factory)
-	throws MappingException {
-		if ( isReferenceToPrimaryKey() ) {
-			return factory.getIdentifierPropertyName( getAssociatedEntityName() );
-		}
-		else {
-			return uniqueKeyPropertyName;
-		}
-	}
-	
-	protected abstract boolean isNullable();
-
-	/**
-	 * Resolve an identifier via a load.
-	 *
-	 * @param id The entity id to resolve
-	 * @param session The orginating session.
-	 * @return The resolved identifier (i.e., loaded entity).
-	 * @throws org.hibernate.HibernateException Indicates problems performing the load.
-	 */
-	protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
-		boolean isProxyUnwrapEnabled = unwrapProxy &&
-				session.getFactory()
-						.getEntityPersister( getAssociatedEntityName() )
-						.isInstrumented( session.getEntityMode() );
-
-		Object proxyOrEntity = session.internalLoad(
-				getAssociatedEntityName(),
-				id,
-				eager,
-				isNullable() && !isProxyUnwrapEnabled
-		);
-
-		if ( proxyOrEntity instanceof HibernateProxy ) {
-			( ( HibernateProxy ) proxyOrEntity ).getHibernateLazyInitializer()
-					.setUnwrap( isProxyUnwrapEnabled );
-		}
-
-		return proxyOrEntity;
-	}
-
-	protected boolean isNull(Object owner, SessionImplementor session) {
-		return false;
-	}
-
-	/**
-	 * Load an instance by a unique key that is not the primary key.
-	 *
-	 * @param entityName The name of the entity to load
-	 * @param uniqueKeyPropertyName The name of the property defining the uniqie key.
-	 * @param key The unique key property value.
-	 * @param session The originating session.
-	 * @return The loaded entity
-	 * @throws HibernateException generally indicates problems performing the load.
-	 */
-	public Object loadByUniqueKey(
-			String entityName, 
-			String uniqueKeyPropertyName, 
-			Object key, 
-			SessionImplementor session) throws HibernateException {
-		final SessionFactoryImplementor factory = session.getFactory();
-		UniqueKeyLoadable persister = ( UniqueKeyLoadable ) factory.getEntityPersister( entityName );
-
-		//TODO: implement caching?! proxies?!
-
-		EntityUniqueKey euk = new EntityUniqueKey(
-				entityName, 
-				uniqueKeyPropertyName, 
-				key, 
-				getIdentifierOrUniqueKeyType( factory ),
-				session.getEntityMode(), 
-				session.getFactory()
-		);
-
-		final PersistenceContext persistenceContext = session.getPersistenceContext();
-		Object result = persistenceContext.getEntity( euk );
-		if ( result == null ) {
-			result = persister.loadByUniqueKey( uniqueKeyPropertyName, key, session );
-		}
-		return result == null ? null : persistenceContext.proxyFor( result );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/EntityType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/EntityType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,646 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.dom4j.Node;
+import org.hibernate.AssertionFailure;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.EntityUniqueKey;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.PersistenceContext;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.persister.entity.Joinable;
+import org.hibernate.persister.entity.UniqueKeyLoadable;
+import org.hibernate.proxy.HibernateProxy;
+import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.tuple.ElementWrapper;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Base for types which map associations to persistent entities.
+ *
+ * @author Gavin King
+ */
+public abstract class EntityType extends AbstractType implements AssociationType {
+
+	private final String associatedEntityName;
+	protected final String uniqueKeyPropertyName;
+	protected final boolean isEmbeddedInXML;
+	private final boolean eager;
+	private final boolean unwrapProxy;
+
+	private transient Class returnedClass;
+
+	/**
+	 * Constructs the requested entity type mapping.
+	 *
+	 * @param entityName The name of the associated entity.
+	 * @param uniqueKeyPropertyName The property-ref name, or null if we
+	 * reference the PK of the associated entity.
+	 * @param eager Is eager fetching enabled.
+	 * @param isEmbeddedInXML Should values of this mapping be embedded in XML modes?
+	 * @param unwrapProxy Is unwrapping of proxies allowed for this association; unwrapping
+	 * says to return the "implementation target" of lazy prooxies; typically only possible
+	 * with lazy="no-proxy".
+	 */
+	protected EntityType(
+			String entityName,
+			String uniqueKeyPropertyName,
+			boolean eager,
+			boolean isEmbeddedInXML,
+			boolean unwrapProxy) {
+		this.associatedEntityName = entityName;
+		this.uniqueKeyPropertyName = uniqueKeyPropertyName;
+		this.isEmbeddedInXML = isEmbeddedInXML;
+		this.eager = eager;
+		this.unwrapProxy = unwrapProxy;
+	}
+
+	/**
+	 * An entity type is a type of association type
+	 *
+	 * @return True.
+	 */
+	public boolean isAssociationType() {
+		return true;
+	}
+
+	/**
+	 * Explicitly, an entity type is an entity type ;)
+	 *
+	 * @return True.
+	 */
+	public final boolean isEntityType() {
+		return true;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isMutable() {
+		return false;
+	}
+
+	/**
+	 * Generates a string representation of this type.
+	 *
+	 * @return string rep
+	 */
+	public String toString() {
+		return getClass().getName() + '(' + getAssociatedEntityName() + ')';
+	}
+
+	/**
+	 * For entity types, the name correlates to the associated entity name.
+	 */
+	public String getName() {
+		return associatedEntityName;
+	}
+
+	/**
+	 * Does this association foreign key reference the primary key of the other table?
+	 * Otherwise, it references a property-ref.
+	 *
+	 * @return True if this association reference the PK of the associated entity.
+	 */
+	public boolean isReferenceToPrimaryKey() {
+		return uniqueKeyPropertyName==null;
+	}
+
+	public String getRHSUniqueKeyPropertyName() {
+		return uniqueKeyPropertyName;
+	}
+
+	public String getLHSPropertyName() {
+		return null;
+	}
+
+	public String getPropertyName() {
+		return null;
+	}
+
+	/**
+	 * The name of the associated entity.
+	 *
+	 * @return The associated entity name.
+	 */
+	public final String getAssociatedEntityName() {
+		return associatedEntityName;
+	}
+
+	/**
+	 * The name of the associated entity.
+	 *
+	 * @param factory The session factory, for resolution.
+	 * @return The associated entity name.
+	 */
+	public String getAssociatedEntityName(SessionFactoryImplementor factory) {
+		return getAssociatedEntityName();
+	}
+
+	/**
+	 * Retrieves the {@link Joinable} defining the associated entity.
+	 *
+	 * @param factory The session factory.
+	 * @return The associated joinable
+	 * @throws MappingException Generally indicates an invalid entity name.
+	 */
+	public Joinable getAssociatedJoinable(SessionFactoryImplementor factory) throws MappingException {
+		return ( Joinable ) factory.getEntityPersister( associatedEntityName );
+	}
+
+	/**
+	 * This returns the wrong class for an entity with a proxy, or for a named
+	 * entity.  Theoretically it should return the proxy class, but it doesn't.
+	 * <p/>
+	 * The problem here is that we do not necessarily have a ref to the associated
+	 * entity persister (nor to the session factory, to look it up) which is really
+	 * needed to "do the right thing" here...
+	 *
+	 * @return The entiyt class.
+	 */
+	public final Class getReturnedClass() {
+		if ( returnedClass == null ) {
+			returnedClass = determineAssociatedEntityClass();
+		}
+		return returnedClass;
+	}
+
+	private Class determineAssociatedEntityClass() {
+		try {
+			return ReflectHelper.classForName( getAssociatedEntityName() );
+		}
+		catch ( ClassNotFoundException cnfe ) {
+			return java.util.Map.class;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException {
+		return nullSafeGet( rs, new String[] {name}, session, owner );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public final Object nullSafeGet(
+			ResultSet rs,
+			String[] names,
+			SessionImplementor session,
+			Object owner) throws HibernateException, SQLException {
+		return resolve( hydrate(rs, names, session, owner), session, owner );
+	}
+
+	/**
+	 * Two entities are considered the same when their instances are the same.
+	 *
+	 * @param x One entity instance
+	 * @param y Another entity instance
+	 * @param entityMode The entity mode.
+	 * @return True if x == y; false otherwise.
+	 */
+	public final boolean isSame(Object x, Object y, EntityMode entityMode) {
+		return x == y;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return 0; //TODO: entities CAN be compared, by PK, fix this! -> only if/when we can extract the id values....
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) {
+		return value; //special case ... this is the leaf of the containment graph, even though not immutable
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object replace(
+			Object original,
+			Object target,
+			SessionImplementor session,
+			Object owner,
+			Map copyCache) throws HibernateException {
+		if ( original == null ) {
+			return null;
+		}
+		Object cached = copyCache.get(original);
+		if ( cached != null ) {
+			return cached;
+		}
+		else {
+			if ( original == target ) {
+				return target;
+			}
+			if ( session.getContextEntityIdentifier( original ) == null  &&
+					ForeignKeys.isTransient( associatedEntityName, original, Boolean.FALSE, session ) ) {
+				final Object copy = session.getFactory().getEntityPersister( associatedEntityName )
+						.instantiate( null, session.getEntityMode() );
+				//TODO: should this be Session.instantiate(Persister, ...)?
+				copyCache.put( original, copy );
+				return copy;
+			}
+			else {
+				Object id = getIdentifier( original, session );
+				if ( id == null ) {
+					throw new AssertionFailure("non-transient entity has a null id");
+				}
+				id = getIdentifierOrUniqueKeyType( session.getFactory() )
+						.replace(id, null, session, owner, copyCache);
+				return resolve( id, session, owner );
+			}
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) {
+		EntityPersister persister = factory.getEntityPersister(associatedEntityName);
+		if ( !persister.canExtractIdOutOfEntity() ) {
+			return super.getHashCode(x, entityMode);
+		}
+
+		final Serializable id;
+		if (x instanceof HibernateProxy) {
+			id = ( (HibernateProxy) x ).getHibernateLazyInitializer().getIdentifier();
+		}
+		else {
+			id = persister.getIdentifier(x, entityMode);
+		}
+		return persister.getIdentifierType().getHashCode(id, entityMode, factory);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) {
+		EntityPersister persister = factory.getEntityPersister(associatedEntityName);
+		if ( !persister.canExtractIdOutOfEntity() ) {
+			return super.isEqual(x, y, entityMode);
+		}
+
+		Serializable xid;
+		if (x instanceof HibernateProxy) {
+			xid = ( (HibernateProxy) x ).getHibernateLazyInitializer()
+					.getIdentifier();
+		}
+		else {
+			xid = persister.getIdentifier(x, entityMode);
+		}
+
+		Serializable yid;
+		if (y instanceof HibernateProxy) {
+			yid = ( (HibernateProxy) y ).getHibernateLazyInitializer()
+					.getIdentifier();
+		}
+		else {
+			yid = persister.getIdentifier(y, entityMode);
+		}
+
+		return persister.getIdentifierType()
+				.isEqual(xid, yid, entityMode, factory);
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isEmbeddedInXML() {
+		return isEmbeddedInXML;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public boolean isXMLElement() {
+		return isEmbeddedInXML;
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		if ( !isEmbeddedInXML ) {
+			return getIdentifierType(factory).fromXMLNode(xml, factory);
+		}
+		else {
+			return xml;
+		}
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
+		if ( !isEmbeddedInXML ) {
+			getIdentifierType(factory).setToXMLNode(node, value, factory);
+		}
+		else {
+			Element elt = (Element) value;
+			replaceNode( node, new ElementWrapper(elt) );
+		}
+	}
+
+	public String getOnCondition(String alias, SessionFactoryImplementor factory, Map enabledFilters)
+	throws MappingException {
+		if ( isReferenceToPrimaryKey() ) { //TODO: this is a bit arbitrary, expose a switch to the user?
+			return "";
+		}
+		else {
+			return getAssociatedJoinable( factory ).filterFragment( alias, enabledFilters );
+		}
+	}
+
+	/**
+	 * Resolve an identifier or unique key value
+	 */
+	public Object resolve(Object value, SessionImplementor session, Object owner) throws HibernateException {
+		if ( isNotEmbedded( session ) ) {
+			return value;
+		}
+
+		if ( value == null ) {
+			return null;
+		}
+		else {
+			if ( isNull( owner, session ) ) {
+				return null; //EARLY EXIT!
+			}
+
+			if ( isReferenceToPrimaryKey() ) {
+				return resolveIdentifier( (Serializable) value, session );
+			}
+			else {
+				return loadByUniqueKey( getAssociatedEntityName(), uniqueKeyPropertyName, value, session );
+			}
+		}
+	}
+
+	public Type getSemiResolvedType(SessionFactoryImplementor factory) {
+		return factory.getEntityPersister( associatedEntityName ).getIdentifierType();
+	}
+
+	protected final Object getIdentifier(Object value, SessionImplementor session) throws HibernateException {
+		if ( isNotEmbedded(session) ) {
+			return value;
+		}
+
+		if ( isReferenceToPrimaryKey() ) {
+			return ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session ); //tolerates nulls
+		}
+		else if ( value == null ) {
+			return null;
+		}
+		else {
+			EntityPersister entityPersister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
+			Object propertyValue = entityPersister.getPropertyValue( value, uniqueKeyPropertyName, session.getEntityMode() );
+			// We now have the value of the property-ref we reference.  However,
+			// we need to dig a little deeper, as that property might also be
+			// an entity type, in which case we need to resolve its identitifier
+			Type type = entityPersister.getPropertyType( uniqueKeyPropertyName );
+			if ( type.isEntityType() ) {
+				propertyValue = ( ( EntityType ) type ).getIdentifier( propertyValue, session );
+			}
+
+			return propertyValue;
+		}
+	}
+
+	protected boolean isNotEmbedded(SessionImplementor session) {
+		return !isEmbeddedInXML && session.getEntityMode()==EntityMode.DOM4J;
+	}
+
+	/**
+	 * Get the identifier value of an instance or proxy.
+	 * <p/>
+	 * Intended only for loggin purposes!!!
+	 *
+	 * @param object The object from which to extract the identifier.
+	 * @param persister The entity persister
+	 * @param entityMode The entity mode
+	 * @return The extracted identifier.
+	 */
+	private static Serializable getIdentifier(Object object, EntityPersister persister, EntityMode entityMode) {
+		if (object instanceof HibernateProxy) {
+			HibernateProxy proxy = (HibernateProxy) object;
+			LazyInitializer li = proxy.getHibernateLazyInitializer();
+			return li.getIdentifier();
+		}
+		else {
+			return persister.getIdentifier( object, entityMode );
+		}
+	}
+
+	/**
+	 * Generate a loggable representation of an instance of the value mapped by this type.
+	 *
+	 * @param value The instance to be logged.
+	 * @param factory The session factory.
+	 * @return The loggable string.
+	 * @throws HibernateException Generally some form of resolution problem.
+	 */
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) {
+		if ( value == null ) {
+			return "null";
+		}
+		
+		EntityPersister persister = factory.getEntityPersister( associatedEntityName );
+		StringBuffer result = new StringBuffer().append( associatedEntityName );
+
+		if ( persister.hasIdentifierProperty() ) {
+			final EntityMode entityMode = persister.guessEntityMode( value );
+			final Serializable id;
+			if ( entityMode == null ) {
+				if ( isEmbeddedInXML ) {
+					throw new ClassCastException( value.getClass().getName() );
+				}
+				id = ( Serializable ) value;
+			}
+			else {
+				id = getIdentifier( value, persister, entityMode );
+			}
+			
+			result.append( '#' )
+				.append( persister.getIdentifierType().toLoggableString( id, factory ) );
+		}
+		
+		return result.toString();
+	}
+
+	public abstract boolean isOneToOne();
+
+	/**
+	 * Convenience method to locate the identifier type of the associated entity.
+	 *
+	 * @param factory The mappings...
+	 * @return The identifier type
+	 */
+	Type getIdentifierType(Mapping factory) {
+		return factory.getIdentifierType( getAssociatedEntityName() );
+	}
+
+	/**
+	 * Convenience method to locate the identifier type of the associated entity.
+	 *
+	 * @param session The originating session
+	 * @return The identifier type
+	 */
+	Type getIdentifierType(SessionImplementor session) {
+		return getIdentifierType( session.getFactory() );
+	}
+
+	/**
+	 * Determine the type of either (1) the identifier if we reference the
+	 * associated entity's PK or (2) the unique key to which we refer (i.e.
+	 * the property-ref).
+	 *
+	 * @param factory The mappings...
+	 * @return The appropriate type.
+	 * @throws MappingException Generally, if unable to resolve the associated entity name
+	 * or unique key property name.
+	 */
+	public final Type getIdentifierOrUniqueKeyType(Mapping factory) throws MappingException {
+		if ( isReferenceToPrimaryKey() ) {
+			return getIdentifierType(factory);
+		}
+		else {
+			Type type = factory.getReferencedPropertyType( getAssociatedEntityName(), uniqueKeyPropertyName );
+			if ( type.isEntityType() ) {
+				type = ( ( EntityType ) type).getIdentifierOrUniqueKeyType( factory );
+			}
+			return type;
+		}
+	}
+
+	/**
+	 * The name of the property on the associated entity to which our FK
+	 * refers
+	 *
+	 * @param factory The mappings...
+	 * @return The appropriate property name.
+	 * @throws MappingException Generally, if unable to resolve the associated entity name
+	 */
+	public final String getIdentifierOrUniqueKeyPropertyName(Mapping factory)
+	throws MappingException {
+		if ( isReferenceToPrimaryKey() ) {
+			return factory.getIdentifierPropertyName( getAssociatedEntityName() );
+		}
+		else {
+			return uniqueKeyPropertyName;
+		}
+	}
+	
+	protected abstract boolean isNullable();
+
+	/**
+	 * Resolve an identifier via a load.
+	 *
+	 * @param id The entity id to resolve
+	 * @param session The orginating session.
+	 * @return The resolved identifier (i.e., loaded entity).
+	 * @throws org.hibernate.HibernateException Indicates problems performing the load.
+	 */
+	protected final Object resolveIdentifier(Serializable id, SessionImplementor session) throws HibernateException {
+		boolean isProxyUnwrapEnabled = unwrapProxy &&
+				session.getFactory()
+						.getEntityPersister( getAssociatedEntityName() )
+						.isInstrumented( session.getEntityMode() );
+
+		Object proxyOrEntity = session.internalLoad(
+				getAssociatedEntityName(),
+				id,
+				eager,
+				isNullable() && !isProxyUnwrapEnabled
+		);
+
+		if ( proxyOrEntity instanceof HibernateProxy ) {
+			( ( HibernateProxy ) proxyOrEntity ).getHibernateLazyInitializer()
+					.setUnwrap( isProxyUnwrapEnabled );
+		}
+
+		return proxyOrEntity;
+	}
+
+	protected boolean isNull(Object owner, SessionImplementor session) {
+		return false;
+	}
+
+	/**
+	 * Load an instance by a unique key that is not the primary key.
+	 *
+	 * @param entityName The name of the entity to load
+	 * @param uniqueKeyPropertyName The name of the property defining the uniqie key.
+	 * @param key The unique key property value.
+	 * @param session The originating session.
+	 * @return The loaded entity
+	 * @throws HibernateException generally indicates problems performing the load.
+	 */
+	public Object loadByUniqueKey(
+			String entityName, 
+			String uniqueKeyPropertyName, 
+			Object key, 
+			SessionImplementor session) throws HibernateException {
+		final SessionFactoryImplementor factory = session.getFactory();
+		UniqueKeyLoadable persister = ( UniqueKeyLoadable ) factory.getEntityPersister( entityName );
+
+		//TODO: implement caching?! proxies?!
+
+		EntityUniqueKey euk = new EntityUniqueKey(
+				entityName, 
+				uniqueKeyPropertyName, 
+				key, 
+				getIdentifierOrUniqueKeyType( factory ),
+				session.getEntityMode(), 
+				session.getFactory()
+		);
+
+		final PersistenceContext persistenceContext = session.getPersistenceContext();
+		Object result = persistenceContext.getEntity( euk );
+		if ( result == null ) {
+			result = persister.loadByUniqueKey( uniqueKeyPropertyName, key, session );
+		}
+		return result == null ? null : persistenceContext.proxyFor( result );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/FloatType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,59 +0,0 @@
-//$Id: FloatType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>float</tt>: A type that maps an SQL FLOAT to a Java Float.
- * @author Gavin King
- */
-public class FloatType extends PrimitiveType {
-
-	public Serializable getDefaultValue() {
-		return new Float(0.0);
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Float( rs.getFloat(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return float.class;
-	}
-
-	public Class getReturnedClass() {
-		return Float.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws SQLException {
-
-		st.setFloat( index, ( (Float) value ).floatValue() );
-	}
-
-	public int sqlType() {
-		return Types.FLOAT;
-	}
-
-	public String getName() { return "float"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object fromStringValue(String xml) {
-		return new Float(xml);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/FloatType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/FloatType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>float</tt>: A type that maps an SQL FLOAT to a Java Float.
+ * @author Gavin King
+ */
+public class FloatType extends PrimitiveType {
+
+	public Serializable getDefaultValue() {
+		return new Float(0.0);
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Float( rs.getFloat(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return float.class;
+	}
+
+	public Class getReturnedClass() {
+		return Float.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws SQLException {
+
+		st.setFloat( index, ( (Float) value ).floatValue() );
+	}
+
+	public int sqlType() {
+		return Types.FLOAT;
+	}
+
+	public String getName() { return "float"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object fromStringValue(String xml) {
+		return new Float(xml);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,52 +0,0 @@
-//$Id: ForeignKeyDirection.java 7019 2005-06-05 05:09:58Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-
-import org.hibernate.engine.Cascade;
-
-/**
- * Represents directionality of the foreign key constraint
- * @author Gavin King
- */
-public abstract class ForeignKeyDirection implements Serializable {
-	protected ForeignKeyDirection() {}
-	/**
-	 * Should we cascade at this cascade point?
-	 * @see org.hibernate.engine.Cascade
-	 */
-	public abstract boolean cascadeNow(int cascadePoint);
-
-	/**
-	 * A foreign key from child to parent
-	 */
-	public static final ForeignKeyDirection FOREIGN_KEY_TO_PARENT = new ForeignKeyDirection() {
-		public boolean cascadeNow(int cascadePoint) {
-			return cascadePoint!=Cascade.BEFORE_INSERT_AFTER_DELETE;
-		}
-
-		public String toString() {
-			return "toParent";
-		}
-		
-		Object readResolve() {
-			return FOREIGN_KEY_TO_PARENT;
-		}
-	};
-	/**
-	 * A foreign key from parent to child
-	 */
-	public static final ForeignKeyDirection FOREIGN_KEY_FROM_PARENT = new ForeignKeyDirection() {
-		public boolean cascadeNow(int cascadePoint) {
-			return cascadePoint!=Cascade.AFTER_INSERT_BEFORE_DELETE;
-		}
-
-		public String toString() {
-			return "fromParent";
-		}
-		
-		Object readResolve() {
-			return FOREIGN_KEY_FROM_PARENT;
-		}
-	};
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ForeignKeyDirection.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,75 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+
+import org.hibernate.engine.Cascade;
+
+/**
+ * Represents directionality of the foreign key constraint
+ * @author Gavin King
+ */
+public abstract class ForeignKeyDirection implements Serializable {
+	protected ForeignKeyDirection() {}
+	/**
+	 * Should we cascade at this cascade point?
+	 * @see org.hibernate.engine.Cascade
+	 */
+	public abstract boolean cascadeNow(int cascadePoint);
+
+	/**
+	 * A foreign key from child to parent
+	 */
+	public static final ForeignKeyDirection FOREIGN_KEY_TO_PARENT = new ForeignKeyDirection() {
+		public boolean cascadeNow(int cascadePoint) {
+			return cascadePoint!=Cascade.BEFORE_INSERT_AFTER_DELETE;
+		}
+
+		public String toString() {
+			return "toParent";
+		}
+		
+		Object readResolve() {
+			return FOREIGN_KEY_TO_PARENT;
+		}
+	};
+	/**
+	 * A foreign key from parent to child
+	 */
+	public static final ForeignKeyDirection FOREIGN_KEY_FROM_PARENT = new ForeignKeyDirection() {
+		public boolean cascadeNow(int cascadePoint) {
+			return cascadePoint!=Cascade.AFTER_INSERT_BEFORE_DELETE;
+		}
+
+		public String toString() {
+			return "fromParent";
+		}
+		
+		Object readResolve() {
+			return FOREIGN_KEY_FROM_PARENT;
+		}
+	};
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/IdentifierBagType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-//$Id: IdentifierBagType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentIdentifierBag;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-public class IdentifierBagType extends CollectionType {
-
-	public IdentifierBagType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-	}
-
-	public PersistentCollection instantiate(
-		SessionImplementor session,
-		CollectionPersister persister, Serializable key)
-		throws HibernateException {
-
-		return new PersistentIdentifierBag(session);
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
-	}
-	
-	public Class getReturnedClass() {
-		return java.util.Collection.class;
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		return new PersistentIdentifierBag( session, (java.util.Collection) collection );
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/IdentifierBagType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierBagType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,68 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentIdentifierBag;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+public class IdentifierBagType extends CollectionType {
+
+	public IdentifierBagType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+	}
+
+	public PersistentCollection instantiate(
+		SessionImplementor session,
+		CollectionPersister persister, Serializable key)
+		throws HibernateException {
+
+		return new PersistentIdentifierBag(session);
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
+	}
+	
+	public Class getReturnedClass() {
+		return java.util.Collection.class;
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		return new PersistentIdentifierBag( session, (java.util.Collection) collection );
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/IdentifierType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,24 +0,0 @@
-//$Id: IdentifierType.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.type;
-
-/**
- * A <tt>Type</tt> that may be used as an identifier.
- * @author Gavin King
- */
-public interface IdentifierType extends Type {
-
-	/**
-	 * Convert the value from the mapping file to a Java object.
-	 * @param xml the value of <tt>discriminator-value</tt> or <tt>unsaved-value</tt> attribute
-	 * @return Object
-	 * @throws Exception
-	 */
-	public Object stringToObject(String xml) throws Exception;
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/IdentifierType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IdentifierType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+/**
+ * A <tt>Type</tt> that may be used as an identifier.
+ * @author Gavin King
+ */
+public interface IdentifierType extends Type {
+
+	/**
+	 * Convert the value from the mapping file to a Java object.
+	 * @param xml the value of <tt>discriminator-value</tt> or <tt>unsaved-value</tt> attribute
+	 * @return Object
+	 * @throws Exception
+	 */
+	public Object stringToObject(String xml) throws Exception;
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ImmutableType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-//$Id: ImmutableType.java 5744 2005-02-16 12:50:19Z oneovthafew $
-package org.hibernate.type;
-
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Superclass of nullable immutable types.
- * @author Gavin King
- */
-public abstract class ImmutableType extends NullableType {
-
-	public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) {
-		return value;
-	}
-
-	public final boolean isMutable() {
-		return false;
-	}
-
-	public Object replace(
-		Object original,
-		Object target,
-		SessionImplementor session,
-		Object owner, 
-		Map copyCache)
-	throws HibernateException {
-		return original;
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ImmutableType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ImmutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Superclass of nullable immutable types.
+ * @author Gavin King
+ */
+public abstract class ImmutableType extends NullableType {
+
+	public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) {
+		return value;
+	}
+
+	public final boolean isMutable() {
+		return false;
+	}
+
+	public Object replace(
+		Object original,
+		Object target,
+		SessionImplementor session,
+		Object owner, 
+		Map copyCache)
+	throws HibernateException {
+		return original;
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/IntegerType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,74 +0,0 @@
-//$Id: IntegerType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Comparator;
-
-import org.hibernate.util.ComparableComparator;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * <tt>integer</tt>: A type that maps an SQL INT to a Java Integer.
- * @author Gavin King
- */
-public class IntegerType extends PrimitiveType implements DiscriminatorType, VersionType {
-
-	private static final Integer ZERO = new Integer(0);
-
-	public Serializable getDefaultValue() {
-		return ZERO;
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Integer( rs.getInt(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return int.class;
-	}
-
-	public Class getReturnedClass() {
-		return Integer.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws SQLException {
-		st.setInt( index, ( (Integer) value ).intValue() );
-	}
-
-	public int sqlType() {
-		return Types.INTEGER;
-	}
-
-	public String getName() { return "integer"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return new Integer(xml);
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return new Integer( ( (Integer) current ).intValue() + 1 );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return ZERO;
-	}
-
-	public Comparator getComparator() {
-		return ComparableComparator.INSTANCE;
-	}
-	
-	public Object fromStringValue(String xml) {
-		return new Integer(xml);
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/IntegerType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/IntegerType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,97 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Comparator;
+
+import org.hibernate.util.ComparableComparator;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * <tt>integer</tt>: A type that maps an SQL INT to a Java Integer.
+ * @author Gavin King
+ */
+public class IntegerType extends PrimitiveType implements DiscriminatorType, VersionType {
+
+	private static final Integer ZERO = new Integer(0);
+
+	public Serializable getDefaultValue() {
+		return ZERO;
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Integer( rs.getInt(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return int.class;
+	}
+
+	public Class getReturnedClass() {
+		return Integer.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws SQLException {
+		st.setInt( index, ( (Integer) value ).intValue() );
+	}
+
+	public int sqlType() {
+		return Types.INTEGER;
+	}
+
+	public String getName() { return "integer"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return new Integer(xml);
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return new Integer( ( (Integer) current ).intValue() + 1 );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return ZERO;
+	}
+
+	public Comparator getComparator() {
+		return ComparableComparator.INSTANCE;
+	}
+	
+	public Object fromStringValue(String xml) {
+		return new Integer(xml);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ListType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,62 +0,0 @@
-//$Id: ListType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentList;
-import org.hibernate.collection.PersistentListElementHolder;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-public class ListType extends CollectionType {
-
-	public ListType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentListElementHolder(session, persister, key);
-		}
-		else {
-			return new PersistentList(session);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return List.class;
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentListElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentList( session, (List) collection );
-		}
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
-	}
-	
-	public Object indexOf(Object collection, Object element) {
-		List list = (List) collection;
-		for ( int i=0; i<list.size(); i++ ) {
-			//TODO: proxies!
-			if ( list.get(i)==element ) return new Integer(i);
-		}
-		return null;
-	}
-	
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ListType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ListType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,85 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentList;
+import org.hibernate.collection.PersistentListElementHolder;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+public class ListType extends CollectionType {
+
+	public ListType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentListElementHolder(session, persister, key);
+		}
+		else {
+			return new PersistentList(session);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return List.class;
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentListElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentList( session, (List) collection );
+		}
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize <= 0 ? new ArrayList() : new ArrayList( anticipatedSize + 1 );
+	}
+	
+	public Object indexOf(Object collection, Object element) {
+		List list = (List) collection;
+		for ( int i=0; i<list.size(); i++ ) {
+			//TODO: proxies!
+			if ( list.get(i)==element ) return new Integer(i);
+		}
+		return null;
+	}
+	
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/LiteralType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: LiteralType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * A type that may appear as an SQL literal
- * @author Gavin King
- */
-public interface LiteralType {
-	/**
-	 * String representation of the value, suitable for embedding in
-	 * an SQL statement.
-	 * @param value
-	 * @param dialect
-	 * @return String the value, as it appears in a SQL query
-	 * @throws Exception
-	 */
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception;
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/LiteralType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LiteralType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.type;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * A type that may appear as an SQL literal
+ * @author Gavin King
+ */
+public interface LiteralType {
+	/**
+	 * String representation of the value, suitable for embedding in
+	 * an SQL statement.
+	 * @param value
+	 * @param dialect
+	 * @return String the value, as it appears in a SQL query
+	 * @throws Exception
+	 */
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception;
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/LocaleType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: LocaleType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Locale;
-import java.util.StringTokenizer;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>locale</tt>: A type that maps an SQL VARCHAR to a Java Locale.
- * @author Gavin King
- */
-public class LocaleType extends ImmutableType implements LiteralType {
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		return fromStringValue( (String) Hibernate.STRING.get(rs, name) );
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		Hibernate.STRING.set(st, value.toString(), index);
-	}
-
-	public Object fromStringValue(String string) {
-		if (string == null) {
-			return null;
-		}
-		else {
-			StringTokenizer tokens = new StringTokenizer(string, "_");
-			String language = tokens.hasMoreTokens() ? tokens.nextToken() : "";
-			String country = tokens.hasMoreTokens() ? tokens.nextToken() : "";
-			// Need to account for allowable '_' within the variant
-			String variant = "";
-			String sep = "";
-			while ( tokens.hasMoreTokens() ) {
-				variant += sep + tokens.nextToken();
-				sep = "_";
-			}
-			return new Locale(language, country, variant);
-		}
-	}
-	
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return x.toString().compareTo( y.toString() );
-	}
-
-	public int sqlType() {
-		return Hibernate.STRING.sqlType();
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return value.toString();
-	}
-
-	public Class getReturnedClass() {
-		return Locale.class;
-	}
-
-	public String getName() {
-		return "locale";
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return ( (LiteralType) Hibernate.STRING ).objectToSQLString( value.toString(), dialect );
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/LocaleType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LocaleType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>locale</tt>: A type that maps an SQL VARCHAR to a Java Locale.
+ * @author Gavin King
+ */
+public class LocaleType extends ImmutableType implements LiteralType {
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		return fromStringValue( (String) Hibernate.STRING.get(rs, name) );
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		Hibernate.STRING.set(st, value.toString(), index);
+	}
+
+	public Object fromStringValue(String string) {
+		if (string == null) {
+			return null;
+		}
+		else {
+			StringTokenizer tokens = new StringTokenizer(string, "_");
+			String language = tokens.hasMoreTokens() ? tokens.nextToken() : "";
+			String country = tokens.hasMoreTokens() ? tokens.nextToken() : "";
+			// Need to account for allowable '_' within the variant
+			String variant = "";
+			String sep = "";
+			while ( tokens.hasMoreTokens() ) {
+				variant += sep + tokens.nextToken();
+				sep = "_";
+			}
+			return new Locale(language, country, variant);
+		}
+	}
+	
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return x.toString().compareTo( y.toString() );
+	}
+
+	public int sqlType() {
+		return Hibernate.STRING.sqlType();
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return value.toString();
+	}
+
+	public Class getReturnedClass() {
+		return Locale.class;
+	}
+
+	public String getName() {
+		return "locale";
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return ( (LiteralType) Hibernate.STRING ).objectToSQLString( value.toString(), dialect );
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/LongType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,76 +0,0 @@
-//$Id: LongType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Comparator;
-
-import org.hibernate.util.ComparableComparator;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * <tt>long</tt>: A type that maps an SQL BIGINT to a Java Long.
- * @author Gavin King
- */
-public class LongType extends PrimitiveType implements DiscriminatorType, VersionType {
-
-	private static final Long ZERO = new Long(0);
-
-	public Serializable getDefaultValue() {
-		return ZERO;
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Long( rs.getLong(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return long.class;
-	}
-
-	public Class getReturnedClass() {
-		return Long.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index)
-	throws SQLException {
-
-		st.setLong( index, ( (Long) value ).longValue() );
-	}
-
-	public int sqlType() {
-		return Types.BIGINT;
-	}
-
-	public String getName() { return "long"; }
-
-	public Object stringToObject(String xml) throws Exception {
-		return new Long(xml);
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return new Long( ( (Long) current ).longValue() + 1 );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return ZERO;
-	}
-
-	public Comparator getComparator() {
-		return ComparableComparator.INSTANCE;
-	}
-	
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object fromStringValue(String xml) {
-		return new Long(xml);
-	}
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/LongType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/LongType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,99 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Comparator;
+
+import org.hibernate.util.ComparableComparator;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * <tt>long</tt>: A type that maps an SQL BIGINT to a Java Long.
+ * @author Gavin King
+ */
+public class LongType extends PrimitiveType implements DiscriminatorType, VersionType {
+
+	private static final Long ZERO = new Long(0);
+
+	public Serializable getDefaultValue() {
+		return ZERO;
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Long( rs.getLong(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return long.class;
+	}
+
+	public Class getReturnedClass() {
+		return Long.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index)
+	throws SQLException {
+
+		st.setLong( index, ( (Long) value ).longValue() );
+	}
+
+	public int sqlType() {
+		return Types.BIGINT;
+	}
+
+	public String getName() { return "long"; }
+
+	public Object stringToObject(String xml) throws Exception {
+		return new Long(xml);
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return new Long( ( (Long) current ).longValue() + 1 );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return ZERO;
+	}
+
+	public Comparator getComparator() {
+		return ComparableComparator.INSTANCE;
+	}
+	
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object fromStringValue(String xml) {
+		return new Long(xml);
+	}
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ManyToOneType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,248 +0,0 @@
-//$Id: ManyToOneType.java 10020 2006-06-15 16:38:03Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Arrays;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-
-/**
- * A many-to-one association to an entity.
- *
- * @author Gavin King
- */
-public class ManyToOneType extends EntityType {
-	
-	private final boolean ignoreNotFound;
-
-	public ManyToOneType(String className) {
-		this( className, false );
-	}
-
-	public ManyToOneType(String className, boolean lazy) {
-		super( className, null, !lazy, true, false );
-		this.ignoreNotFound = false;
-	}
-
-	public ManyToOneType(
-			String entityName,
-			String uniqueKeyPropertyName,
-			boolean lazy,
-			boolean unwrapProxy,
-			boolean isEmbeddedInXML,
-			boolean ignoreNotFound) {
-		super( entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy );
-		this.ignoreNotFound = ignoreNotFound;
-	}
-
-	protected boolean isNullable() {
-		return ignoreNotFound;
-	}
-
-	public boolean isAlwaysDirtyChecked() {
-		// If we have <tt>not-found="ignore"</tt> association mapped to a
-		// formula, we always need to dirty check it, so we can update the
-		// second-level cache
-		return ignoreNotFound;
-	}
-
-	public boolean isOneToOne() {
-		return false;
-	}
-	
-	public int getColumnSpan(Mapping mapping) throws MappingException {
-		// our column span is the number of columns in the PK
-		return getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping );
-	}
-
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return getIdentifierOrUniqueKeyType( mapping ).sqlTypes( mapping );
-	}
-
-	public void nullSafeSet(
-			PreparedStatement st,
-			Object value,
-			int index,
-			boolean[] settable,
-			SessionImplementor session) throws HibernateException, SQLException {
-		getIdentifierOrUniqueKeyType( session.getFactory() )
-				.nullSafeSet( st, getIdentifier( value, session ), index, settable, session );
-	}
-
-	public void nullSafeSet(
-			PreparedStatement st,
-			Object value,
-			int index,
-			SessionImplementor session) throws HibernateException, SQLException {
-		getIdentifierOrUniqueKeyType( session.getFactory() )
-				.nullSafeSet( st, getIdentifier( value, session ), index, session );
-	}
-
-	public ForeignKeyDirection getForeignKeyDirection() {
-		return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
-	}
-
-	public Object hydrate(
-			ResultSet rs,
-			String[] names,
-			SessionImplementor session,
-			Object owner) throws HibernateException, SQLException {
-		// return the (fully resolved) identifier value, but do not resolve
-		// to the actual referenced entity instance
-		// NOTE: the owner of the association is not really the owner of the id!
-		Serializable id = (Serializable) getIdentifierOrUniqueKeyType( session.getFactory() )
-				.nullSafeGet( rs, names, session, null );
-		scheduleBatchLoadIfNeeded( id, session );
-		return id;
-	}
-
-	/**
-	 * Register the entity as batch loadable, if enabled
-	 */
-	private void scheduleBatchLoadIfNeeded(
-			Serializable id,
-			SessionImplementor session) throws MappingException {
-		//cannot batch fetch by unique key (property-ref associations)
-		if ( uniqueKeyPropertyName == null && id != null ) {
-			EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
-			EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() );
-			if ( !session.getPersistenceContext().containsEntity( entityKey ) ) {
-				session.getPersistenceContext()
-						.getBatchFetchQueue()
-						.addBatchLoadableEntityKey( entityKey );
-			}
-		}
-	}
-	
-	public boolean useLHSPrimaryKey() {
-		return false;
-	}
-
-	public boolean isModified(
-			Object old,
-			Object current,
-			boolean[] checkable,
-			SessionImplementor session) throws HibernateException {
-		if ( current == null ) {
-			return old!=null;
-		}
-		if ( old == null ) {
-			// we already know current is not null...
-			return true;
-		}
-		// the ids are fully resolved, so compare them with isDirty(), not isModified()
-		return getIdentifierOrUniqueKeyType( session.getFactory() )
-				.isDirty( old, getIdentifier( current, session ), session );
-	}
-
-	public Serializable disassemble(
-			Object value,
-			SessionImplementor session,
-			Object owner) throws HibernateException {
-
-		if ( isNotEmbedded( session ) ) {
-			return getIdentifierType( session ).disassemble( value, session, owner );
-		}
-		
-		if ( value == null ) {
-			return null;
-		}
-		else {
-			// cache the actual id of the object, not the value of the
-			// property-ref, which might not be initialized
-			Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 
-					getAssociatedEntityName(), 
-					value, 
-					session
-			);
-			if ( id == null ) {
-				throw new AssertionFailure(
-						"cannot cache a reference to an object with a null id: " + 
-						getAssociatedEntityName()
-				);
-			}
-			return getIdentifierType( session ).disassemble( id, session, owner );
-		}
-	}
-
-	public Object assemble(
-			Serializable oid,
-			SessionImplementor session,
-			Object owner) throws HibernateException {
-		
-		//TODO: currently broken for unique-key references (does not detect
-		//      change to unique key property of the associated object)
-		
-		Serializable id = assembleId( oid, session );
-
-		if ( isNotEmbedded( session ) ) {
-			return id;
-		}
-		
-		if ( id == null ) {
-			return null;
-		}
-		else {
-			return resolveIdentifier( id, session );
-		}
-	}
-
-	private Serializable assembleId(Serializable oid, SessionImplementor session) {
-		//the owner of the association is not the owner of the id
-		return ( Serializable ) getIdentifierType( session ).assemble( oid, session, null );
-	}
-
-	public void beforeAssemble(Serializable oid, SessionImplementor session) {
-		scheduleBatchLoadIfNeeded( assembleId( oid, session ), session );
-	}
-	
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		boolean[] result = new boolean[ getColumnSpan( mapping ) ];
-		if ( value != null ) {
-			Arrays.fill( result, true );
-		}
-		return result;
-	}
-	
-	public boolean isDirty(
-			Object old,
-			Object current,
-			SessionImplementor session) throws HibernateException {
-		if ( isSame( old, current, session.getEntityMode() ) ) {
-			return false;
-		}
-		Object oldid = getIdentifier( old, session );
-		Object newid = getIdentifier( current, session );
-		return getIdentifierType( session ).isDirty( oldid, newid, session );
-	}
-
-	public boolean isDirty(
-			Object old,
-			Object current,
-			boolean[] checkable,
-			SessionImplementor session) throws HibernateException {
-		if ( isAlwaysDirtyChecked() ) {
-			return isDirty( old, current, session );
-		}
-		else {
-			if ( isSame( old, current, session.getEntityMode() ) ) {
-				return false;
-			}
-			Object oldid = getIdentifier( old, session );
-			Object newid = getIdentifier( current, session );
-			return getIdentifierType( session ).isDirty( oldid, newid, checkable, session );
-		}
-		
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ManyToOneType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ManyToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,271 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+
+/**
+ * A many-to-one association to an entity.
+ *
+ * @author Gavin King
+ */
+public class ManyToOneType extends EntityType {
+	
+	private final boolean ignoreNotFound;
+
+	public ManyToOneType(String className) {
+		this( className, false );
+	}
+
+	public ManyToOneType(String className, boolean lazy) {
+		super( className, null, !lazy, true, false );
+		this.ignoreNotFound = false;
+	}
+
+	public ManyToOneType(
+			String entityName,
+			String uniqueKeyPropertyName,
+			boolean lazy,
+			boolean unwrapProxy,
+			boolean isEmbeddedInXML,
+			boolean ignoreNotFound) {
+		super( entityName, uniqueKeyPropertyName, !lazy, isEmbeddedInXML, unwrapProxy );
+		this.ignoreNotFound = ignoreNotFound;
+	}
+
+	protected boolean isNullable() {
+		return ignoreNotFound;
+	}
+
+	public boolean isAlwaysDirtyChecked() {
+		// If we have <tt>not-found="ignore"</tt> association mapped to a
+		// formula, we always need to dirty check it, so we can update the
+		// second-level cache
+		return ignoreNotFound;
+	}
+
+	public boolean isOneToOne() {
+		return false;
+	}
+	
+	public int getColumnSpan(Mapping mapping) throws MappingException {
+		// our column span is the number of columns in the PK
+		return getIdentifierOrUniqueKeyType( mapping ).getColumnSpan( mapping );
+	}
+
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return getIdentifierOrUniqueKeyType( mapping ).sqlTypes( mapping );
+	}
+
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			boolean[] settable,
+			SessionImplementor session) throws HibernateException, SQLException {
+		getIdentifierOrUniqueKeyType( session.getFactory() )
+				.nullSafeSet( st, getIdentifier( value, session ), index, settable, session );
+	}
+
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			SessionImplementor session) throws HibernateException, SQLException {
+		getIdentifierOrUniqueKeyType( session.getFactory() )
+				.nullSafeSet( st, getIdentifier( value, session ), index, session );
+	}
+
+	public ForeignKeyDirection getForeignKeyDirection() {
+		return ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT;
+	}
+
+	public Object hydrate(
+			ResultSet rs,
+			String[] names,
+			SessionImplementor session,
+			Object owner) throws HibernateException, SQLException {
+		// return the (fully resolved) identifier value, but do not resolve
+		// to the actual referenced entity instance
+		// NOTE: the owner of the association is not really the owner of the id!
+		Serializable id = (Serializable) getIdentifierOrUniqueKeyType( session.getFactory() )
+				.nullSafeGet( rs, names, session, null );
+		scheduleBatchLoadIfNeeded( id, session );
+		return id;
+	}
+
+	/**
+	 * Register the entity as batch loadable, if enabled
+	 */
+	private void scheduleBatchLoadIfNeeded(
+			Serializable id,
+			SessionImplementor session) throws MappingException {
+		//cannot batch fetch by unique key (property-ref associations)
+		if ( uniqueKeyPropertyName == null && id != null ) {
+			EntityPersister persister = session.getFactory().getEntityPersister( getAssociatedEntityName() );
+			EntityKey entityKey = new EntityKey( id, persister, session.getEntityMode() );
+			if ( !session.getPersistenceContext().containsEntity( entityKey ) ) {
+				session.getPersistenceContext()
+						.getBatchFetchQueue()
+						.addBatchLoadableEntityKey( entityKey );
+			}
+		}
+	}
+	
+	public boolean useLHSPrimaryKey() {
+		return false;
+	}
+
+	public boolean isModified(
+			Object old,
+			Object current,
+			boolean[] checkable,
+			SessionImplementor session) throws HibernateException {
+		if ( current == null ) {
+			return old!=null;
+		}
+		if ( old == null ) {
+			// we already know current is not null...
+			return true;
+		}
+		// the ids are fully resolved, so compare them with isDirty(), not isModified()
+		return getIdentifierOrUniqueKeyType( session.getFactory() )
+				.isDirty( old, getIdentifier( current, session ), session );
+	}
+
+	public Serializable disassemble(
+			Object value,
+			SessionImplementor session,
+			Object owner) throws HibernateException {
+
+		if ( isNotEmbedded( session ) ) {
+			return getIdentifierType( session ).disassemble( value, session, owner );
+		}
+		
+		if ( value == null ) {
+			return null;
+		}
+		else {
+			// cache the actual id of the object, not the value of the
+			// property-ref, which might not be initialized
+			Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( 
+					getAssociatedEntityName(), 
+					value, 
+					session
+			);
+			if ( id == null ) {
+				throw new AssertionFailure(
+						"cannot cache a reference to an object with a null id: " + 
+						getAssociatedEntityName()
+				);
+			}
+			return getIdentifierType( session ).disassemble( id, session, owner );
+		}
+	}
+
+	public Object assemble(
+			Serializable oid,
+			SessionImplementor session,
+			Object owner) throws HibernateException {
+		
+		//TODO: currently broken for unique-key references (does not detect
+		//      change to unique key property of the associated object)
+		
+		Serializable id = assembleId( oid, session );
+
+		if ( isNotEmbedded( session ) ) {
+			return id;
+		}
+		
+		if ( id == null ) {
+			return null;
+		}
+		else {
+			return resolveIdentifier( id, session );
+		}
+	}
+
+	private Serializable assembleId(Serializable oid, SessionImplementor session) {
+		//the owner of the association is not the owner of the id
+		return ( Serializable ) getIdentifierType( session ).assemble( oid, session, null );
+	}
+
+	public void beforeAssemble(Serializable oid, SessionImplementor session) {
+		scheduleBatchLoadIfNeeded( assembleId( oid, session ), session );
+	}
+	
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		boolean[] result = new boolean[ getColumnSpan( mapping ) ];
+		if ( value != null ) {
+			Arrays.fill( result, true );
+		}
+		return result;
+	}
+	
+	public boolean isDirty(
+			Object old,
+			Object current,
+			SessionImplementor session) throws HibernateException {
+		if ( isSame( old, current, session.getEntityMode() ) ) {
+			return false;
+		}
+		Object oldid = getIdentifier( old, session );
+		Object newid = getIdentifier( current, session );
+		return getIdentifierType( session ).isDirty( oldid, newid, session );
+	}
+
+	public boolean isDirty(
+			Object old,
+			Object current,
+			boolean[] checkable,
+			SessionImplementor session) throws HibernateException {
+		if ( isAlwaysDirtyChecked() ) {
+			return isDirty( old, current, session );
+		}
+		else {
+			if ( isSame( old, current, session.getEntityMode() ) ) {
+				return false;
+			}
+			Object oldid = getIdentifier( old, session );
+			Object newid = getIdentifier( current, session );
+			return getIdentifierType( session ).isDirty( oldid, newid, checkable, session );
+		}
+		
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/MapType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,92 +0,0 @@
-//$Id: MapType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentMap;
-import org.hibernate.collection.PersistentMapElementHolder;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-
-public class MapType extends CollectionType {
-
-	public MapType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentMapElementHolder(session, persister, key);
-		}
-		else {
-			return new PersistentMap(session);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return Map.class;
-	}
-
-	public Iterator getElementsIterator(Object collection) {
-		return ( (java.util.Map) collection ).values().iterator();
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentMapElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentMap( session, (java.util.Map) collection );
-		}
-	}
-	
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize <= 0 
-		       ? new HashMap()
-		       : new HashMap( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
-	}
-
-	public Object replaceElements(
-		final Object original,
-		final Object target,
-		final Object owner, 
-		final java.util.Map copyCache, 
-		final SessionImplementor session)
-		throws HibernateException {
-
-		CollectionPersister cp = session.getFactory().getCollectionPersister( getRole() );
-		
-		java.util.Map result = (java.util.Map) target;
-		result.clear();
-		
-		Iterator iter = ( (java.util.Map) original ).entrySet().iterator();
-		while ( iter.hasNext() ) {
-			java.util.Map.Entry me = (java.util.Map.Entry) iter.next();
-			Object key = cp.getIndexType().replace( me.getKey(), null, session, owner, copyCache );
-			Object value = cp.getElementType().replace( me.getValue(), null, session, owner, copyCache );
-			result.put(key, value);
-		}
-		
-		return result;
-		
-	}
-	
-	public Object indexOf(Object collection, Object element) {
-		Iterator iter = ( (Map) collection ).entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			//TODO: proxies!
-			if ( me.getValue()==element ) return me.getKey();
-		}
-		return null;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/MapType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentMap;
+import org.hibernate.collection.PersistentMapElementHolder;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+
+public class MapType extends CollectionType {
+
+	public MapType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentMapElementHolder(session, persister, key);
+		}
+		else {
+			return new PersistentMap(session);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return Map.class;
+	}
+
+	public Iterator getElementsIterator(Object collection) {
+		return ( (java.util.Map) collection ).values().iterator();
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentMapElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentMap( session, (java.util.Map) collection );
+		}
+	}
+	
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize <= 0 
+		       ? new HashMap()
+		       : new HashMap( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
+	}
+
+	public Object replaceElements(
+		final Object original,
+		final Object target,
+		final Object owner, 
+		final java.util.Map copyCache, 
+		final SessionImplementor session)
+		throws HibernateException {
+
+		CollectionPersister cp = session.getFactory().getCollectionPersister( getRole() );
+		
+		java.util.Map result = (java.util.Map) target;
+		result.clear();
+		
+		Iterator iter = ( (java.util.Map) original ).entrySet().iterator();
+		while ( iter.hasNext() ) {
+			java.util.Map.Entry me = (java.util.Map.Entry) iter.next();
+			Object key = cp.getIndexType().replace( me.getKey(), null, session, owner, copyCache );
+			Object value = cp.getElementType().replace( me.getValue(), null, session, owner, copyCache );
+			result.put(key, value);
+		}
+		
+		return result;
+		
+	}
+	
+	public Object indexOf(Object collection, Object element) {
+		Iterator iter = ( (Map) collection ).entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			//TODO: proxies!
+			if ( me.getValue()==element ) return me.getKey();
+		}
+		return null;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/MetaType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,139 +0,0 @@
-//$Id: MetaType.java 7644 2005-07-25 06:53:09Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * @author Gavin King
- */
-public class MetaType extends AbstractType {
-
-	private final Map values;
-	private final Map keys;
-	private final Type baseType;
-
-	public MetaType(Map values, Type baseType) {
-		this.baseType = baseType;
-		this.values = values;
-		keys = new HashMap();
-		Iterator iter = values.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			keys.put( me.getValue(), me.getKey() );
-		}
-	}
-
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return baseType.sqlTypes(mapping);
-	}
-
-	public int getColumnSpan(Mapping mapping) throws MappingException {
-		return baseType.getColumnSpan(mapping);
-	}
-
-	public Class getReturnedClass() {
-		return String.class;
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String[] names,
-		SessionImplementor session,
-		Object owner)
-	throws HibernateException, SQLException {
-		Object key = baseType.nullSafeGet(rs, names, session, owner);
-		return key==null ? null : values.get(key);
-	}
-
-	public Object nullSafeGet(
-		ResultSet rs,
-		String name,
-		SessionImplementor session,
-		Object owner)
-	throws HibernateException, SQLException {
-		Object key = baseType.nullSafeGet(rs, name, session, owner);
-		return key==null ? null : values.get(key);
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
-	throws HibernateException, SQLException {
-		baseType.nullSafeSet(st, value==null ? null : keys.get(value), index, session);
-	}
-	
-	public void nullSafeSet(
-			PreparedStatement st,
-			Object value,
-			int index,
-			boolean[] settable, 
-			SessionImplementor session)
-	throws HibernateException, SQLException {
-		if ( settable[0] ) nullSafeSet(st, value, index, session);
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
-		return toXMLString(value, factory);
-	}
-	
-	public String toXMLString(Object value, SessionFactoryImplementor factory)
-		throws HibernateException {
-		return (String) value; //value is the entity name
-	}
-
-	public Object fromXMLString(String xml, Mapping factory)
-		throws HibernateException {
-		return xml; //xml is the entity name
-	}
-
-	public String getName() {
-		return baseType.getName(); //TODO!
-	}
-
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		return value;
-	}
-
-	public Object replace(
-			Object original, 
-			Object target,
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache
-	) {
-		return original;
-	}
-	
-	public boolean isMutable() {
-		return false;
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return fromXMLString( xml.getText(), factory );
-	}
-
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
-		node.setText( toXMLString(value, factory) );
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		throw new UnsupportedOperationException();
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
-		return checkable[0] && isDirty(old, current, session);
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/MetaType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MetaType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * @author Gavin King
+ */
+public class MetaType extends AbstractType {
+
+	private final Map values;
+	private final Map keys;
+	private final Type baseType;
+
+	public MetaType(Map values, Type baseType) {
+		this.baseType = baseType;
+		this.values = values;
+		keys = new HashMap();
+		Iterator iter = values.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			keys.put( me.getValue(), me.getKey() );
+		}
+	}
+
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return baseType.sqlTypes(mapping);
+	}
+
+	public int getColumnSpan(Mapping mapping) throws MappingException {
+		return baseType.getColumnSpan(mapping);
+	}
+
+	public Class getReturnedClass() {
+		return String.class;
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String[] names,
+		SessionImplementor session,
+		Object owner)
+	throws HibernateException, SQLException {
+		Object key = baseType.nullSafeGet(rs, names, session, owner);
+		return key==null ? null : values.get(key);
+	}
+
+	public Object nullSafeGet(
+		ResultSet rs,
+		String name,
+		SessionImplementor session,
+		Object owner)
+	throws HibernateException, SQLException {
+		Object key = baseType.nullSafeGet(rs, name, session, owner);
+		return key==null ? null : values.get(key);
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
+	throws HibernateException, SQLException {
+		baseType.nullSafeSet(st, value==null ? null : keys.get(value), index, session);
+	}
+	
+	public void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			boolean[] settable, 
+			SessionImplementor session)
+	throws HibernateException, SQLException {
+		if ( settable[0] ) nullSafeSet(st, value, index, session);
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) throws HibernateException {
+		return toXMLString(value, factory);
+	}
+	
+	public String toXMLString(Object value, SessionFactoryImplementor factory)
+		throws HibernateException {
+		return (String) value; //value is the entity name
+	}
+
+	public Object fromXMLString(String xml, Mapping factory)
+		throws HibernateException {
+		return xml; //xml is the entity name
+	}
+
+	public String getName() {
+		return baseType.getName(); //TODO!
+	}
+
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		return value;
+	}
+
+	public Object replace(
+			Object original, 
+			Object target,
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache
+	) {
+		return original;
+	}
+	
+	public boolean isMutable() {
+		return false;
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return fromXMLString( xml.getText(), factory );
+	}
+
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory) throws HibernateException {
+		node.setText( toXMLString(value, factory) );
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) throws HibernateException {
+		return checkable[0] && isDirty(old, current, session);
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/MutableType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,39 +0,0 @@
-//$Id: MutableType.java 6883 2005-05-24 16:22:15Z oneovthafew $
-package org.hibernate.type;
-
-import java.util.Map;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Superclass for mutable nullable types
- * @author Gavin King
- */
-public abstract class MutableType extends NullableType {
-
-	public final boolean isMutable() {
-		return true;
-	}
-
-	protected abstract Object deepCopyNotNull(Object value) throws HibernateException;
-
-	public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException {
-		return (value==null) ? null : deepCopyNotNull(value);
-	}
-
-	public Object replace(
-		Object original,
-		Object target,
-		SessionImplementor session,
-		Object owner, 
-		Map copyCache)
-	throws HibernateException {
-		if ( isEqual( original, target, session.getEntityMode() ) ) return original;
-		return deepCopy( original, session.getEntityMode(), session.getFactory() );
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/MutableType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/MutableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,62 @@
+/*
+ * 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.type;
+
+import java.util.Map;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Superclass for mutable nullable types
+ * @author Gavin King
+ */
+public abstract class MutableType extends NullableType {
+
+	public final boolean isMutable() {
+		return true;
+	}
+
+	protected abstract Object deepCopyNotNull(Object value) throws HibernateException;
+
+	public final Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException {
+		return (value==null) ? null : deepCopyNotNull(value);
+	}
+
+	public Object replace(
+		Object original,
+		Object target,
+		SessionImplementor session,
+		Object owner, 
+		Map copyCache)
+	throws HibernateException {
+		if ( isEqual( original, target, session.getEntityMode() ) ) return original;
+		return deepCopy( original, session.getEntityMode(), session.getFactory() );
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/NullableType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,236 +0,0 @@
-//$Id: NullableType.java 11047 2007-01-16 15:26:09Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.slf4j.LoggerFactory;
-import org.slf4j.Logger;
-import org.dom4j.Node;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.ArrayHelper;
-import org.hibernate.util.EqualsHelper;
-import org.hibernate.util.StringHelper;
-
-/**
- * Superclass of single-column nullable types.
- * 
- * @author Gavin King
- */
-public abstract class NullableType extends AbstractType {
-
-	/**
-	 * This is the old scheme where logging of parameter bindings and value extractions
-	 * was controlled by the trace level enablement on the 'org.hibernate.type' package...
-	 * <p/>
-	 * Originally was cached such because of performance of looking up the logger each time
-	 * in order to check the trace-enablement.  Driving this via a central Log-specific class
-	 * would alleviate that performance hit, and yet still allow more "normal" logging usage/config.
-	 */
-	private static final boolean IS_VALUE_TRACING_ENABLED = LoggerFactory.getLogger( StringHelper.qualifier( Type.class.getName() ) ).isTraceEnabled();
-	private transient Logger log;
-
-	private Logger log() {
-		if ( log == null ) {
-			log = LoggerFactory.getLogger( getClass() );
-		}
-		return log;
-	}
-
-	/**
-	 * Get a column value from a result set, without worrying about the
-	 * possibility of null values.  Called from {@link #nullSafeGet} after
-	 * nullness checks have been performed.
-	 *
-	 * @param rs The result set from which to extract the value.
-	 * @param name The name of the value to extract.
-	 *
-	 * @return The extracted value.
-	 *
-	 * @throws org.hibernate.HibernateException Generally some form of mismatch error.
-	 * @throws java.sql.SQLException Indicates problem making the JDBC call(s).
-	 */
-	public abstract Object get(ResultSet rs, String name) throws HibernateException, SQLException;
-
-	/**
-	 * Set a parameter value without worrying about the possibility of null
-	 * values.  Called from {@link #nullSafeSet} after nullness checks have
-	 * been performed.
-	 *
-	 * @param st The statement into which to bind the parameter value.
-	 * @param value The parameter value to bind.
-	 * @param index The position or index at which to bind the param value.
-	 *
-	 * @throws org.hibernate.HibernateException Generally some form of mismatch error.
-	 * @throws java.sql.SQLException Indicates problem making the JDBC call(s).
-	 */
-	public abstract void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
-
-	/**
-	 * A convenience form of {@link #sqlTypes(org.hibernate.engine.Mapping)}, returning
-	 * just a single type value since these are explicitly dealing with single column
-	 * mappings.
-	 *
-	 * @return The {@link java.sql.Types} mapping value.
-	 */
-	public abstract int sqlType();
-
-	/**
-	 * A null-safe version of {@link #toString(Object)}.  Specifically we are
-	 * worried about null safeness in regards to the incoming value parameter,
-	 * not the return.
-	 *
-	 * @param value The value to convert to a string representation; may be null.
-	 * @return The string representation; may be null.
-	 * @throws HibernateException Thrown by {@link #toString(Object)}, which this calls.
-	 */
-	public String nullSafeToString(Object value) throws HibernateException {
-		return value == null ? null : toString( value );
-	}
-
-	public abstract String toString(Object value) throws HibernateException;
-
-	public abstract Object fromStringValue(String xml) throws HibernateException;
-
-	public final void nullSafeSet(
-			PreparedStatement st,
-			Object value,
-			int index,
-			boolean[] settable,
-			SessionImplementor session)
-	throws HibernateException, SQLException {
-		if ( settable[0] ) nullSafeSet(st, value, index);
-	}
-
-	public final void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
-	throws HibernateException, SQLException {
-		nullSafeSet(st, value, index);
-	}
-
-	public final void nullSafeSet(PreparedStatement st, Object value, int index)
-	throws HibernateException, SQLException {
-		try {
-			if ( value == null ) {
-				if ( IS_VALUE_TRACING_ENABLED ) {
-					log().trace( "binding null to parameter: " + index );
-				}
-
-				st.setNull( index, sqlType() );
-			}
-			else {
-				if ( IS_VALUE_TRACING_ENABLED ) {
-					log().trace( "binding '" + toString( value ) + "' to parameter: " + index );
-				}
-
-				set( st, value, index );
-			}
-		}
-		catch ( RuntimeException re ) {
-			log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + re.getMessage() );
-			throw re;
-		}
-		catch ( SQLException se ) {
-			log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + se.getMessage() );
-			throw se;
-		}
-	}
-
-	public final Object nullSafeGet(
-			ResultSet rs,
-			String[] names,
-			SessionImplementor session,
-			Object owner)
-	throws HibernateException, SQLException {
-		return nullSafeGet(rs, names[0]);
-	}
-
-	public final Object nullSafeGet(ResultSet rs, String[] names)
-	throws HibernateException, SQLException {
-		return nullSafeGet(rs, names[0]);
-	}
-
-	public final Object nullSafeGet(ResultSet rs, String name)
-	throws HibernateException, SQLException {
-		try {
-			Object value = get(rs, name);
-			if ( value == null || rs.wasNull() ) {
-				if ( IS_VALUE_TRACING_ENABLED ) {
-					log().trace( "returning null as column: " + name );
-				}
-				return null;
-			}
-			else {
-				if ( IS_VALUE_TRACING_ENABLED ) {
-					log().trace( "returning '" + toString( value ) + "' as column: " + name );
-				}
-				return value;
-			}
-		}
-		catch ( RuntimeException re ) {
-			log().info( "could not read column value from result set: " + name + "; " + re.getMessage() );
-			throw re;
-		}
-		catch ( SQLException se ) {
-			log().info( "could not read column value from result set: " + name + "; " + se.getMessage() );
-			throw se;
-		}
-	}
-
-	public final Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException {
-		return nullSafeGet(rs, name);
-	}
-
-	public final String toXMLString(Object value, SessionFactoryImplementor pc)
-	throws HibernateException {
-		return toString(value);
-	}
-
-	public final Object fromXMLString(String xml, Mapping factory) throws HibernateException {
-		return xml==null || xml.length()==0 ? null : fromStringValue(xml);
-	}
-
-	public final int getColumnSpan(Mapping session) {
-		return 1;
-	}
-
-	public final int[] sqlTypes(Mapping session) {
-		return new int[] { sqlType() };
-	}
-
-	public final boolean isEqual(Object x, Object y, EntityMode entityMode) {
-		return isEqual(x, y);
-	}
-
-	public boolean isEqual(Object x, Object y) {
-		return EqualsHelper.equals(x, y);
-	}
-
-	public String toLoggableString(Object value, SessionFactoryImplementor factory) {
-		return value == null ? "null" : toString(value);
-	}
-
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
-		return fromXMLString( xml.getText(), factory );
-	}
-
-	public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory)
-	throws HibernateException {
-		xml.setText( toXMLString(value, factory) );
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
-	throws HibernateException {
-		return checkable[0] && isDirty(old, current, session);
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/NullableType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/NullableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,259 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.slf4j.LoggerFactory;
+import org.slf4j.Logger;
+import org.dom4j.Node;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.ArrayHelper;
+import org.hibernate.util.EqualsHelper;
+import org.hibernate.util.StringHelper;
+
+/**
+ * Superclass of single-column nullable types.
+ * 
+ * @author Gavin King
+ */
+public abstract class NullableType extends AbstractType {
+
+	/**
+	 * This is the old scheme where logging of parameter bindings and value extractions
+	 * was controlled by the trace level enablement on the 'org.hibernate.type' package...
+	 * <p/>
+	 * Originally was cached such because of performance of looking up the logger each time
+	 * in order to check the trace-enablement.  Driving this via a central Log-specific class
+	 * would alleviate that performance hit, and yet still allow more "normal" logging usage/config.
+	 */
+	private static final boolean IS_VALUE_TRACING_ENABLED = LoggerFactory.getLogger( StringHelper.qualifier( Type.class.getName() ) ).isTraceEnabled();
+	private transient Logger log;
+
+	private Logger log() {
+		if ( log == null ) {
+			log = LoggerFactory.getLogger( getClass() );
+		}
+		return log;
+	}
+
+	/**
+	 * Get a column value from a result set, without worrying about the
+	 * possibility of null values.  Called from {@link #nullSafeGet} after
+	 * nullness checks have been performed.
+	 *
+	 * @param rs The result set from which to extract the value.
+	 * @param name The name of the value to extract.
+	 *
+	 * @return The extracted value.
+	 *
+	 * @throws org.hibernate.HibernateException Generally some form of mismatch error.
+	 * @throws java.sql.SQLException Indicates problem making the JDBC call(s).
+	 */
+	public abstract Object get(ResultSet rs, String name) throws HibernateException, SQLException;
+
+	/**
+	 * Set a parameter value without worrying about the possibility of null
+	 * values.  Called from {@link #nullSafeSet} after nullness checks have
+	 * been performed.
+	 *
+	 * @param st The statement into which to bind the parameter value.
+	 * @param value The parameter value to bind.
+	 * @param index The position or index at which to bind the param value.
+	 *
+	 * @throws org.hibernate.HibernateException Generally some form of mismatch error.
+	 * @throws java.sql.SQLException Indicates problem making the JDBC call(s).
+	 */
+	public abstract void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
+
+	/**
+	 * A convenience form of {@link #sqlTypes(org.hibernate.engine.Mapping)}, returning
+	 * just a single type value since these are explicitly dealing with single column
+	 * mappings.
+	 *
+	 * @return The {@link java.sql.Types} mapping value.
+	 */
+	public abstract int sqlType();
+
+	/**
+	 * A null-safe version of {@link #toString(Object)}.  Specifically we are
+	 * worried about null safeness in regards to the incoming value parameter,
+	 * not the return.
+	 *
+	 * @param value The value to convert to a string representation; may be null.
+	 * @return The string representation; may be null.
+	 * @throws HibernateException Thrown by {@link #toString(Object)}, which this calls.
+	 */
+	public String nullSafeToString(Object value) throws HibernateException {
+		return value == null ? null : toString( value );
+	}
+
+	public abstract String toString(Object value) throws HibernateException;
+
+	public abstract Object fromStringValue(String xml) throws HibernateException;
+
+	public final void nullSafeSet(
+			PreparedStatement st,
+			Object value,
+			int index,
+			boolean[] settable,
+			SessionImplementor session)
+	throws HibernateException, SQLException {
+		if ( settable[0] ) nullSafeSet(st, value, index);
+	}
+
+	public final void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
+	throws HibernateException, SQLException {
+		nullSafeSet(st, value, index);
+	}
+
+	public final void nullSafeSet(PreparedStatement st, Object value, int index)
+	throws HibernateException, SQLException {
+		try {
+			if ( value == null ) {
+				if ( IS_VALUE_TRACING_ENABLED ) {
+					log().trace( "binding null to parameter: " + index );
+				}
+
+				st.setNull( index, sqlType() );
+			}
+			else {
+				if ( IS_VALUE_TRACING_ENABLED ) {
+					log().trace( "binding '" + toString( value ) + "' to parameter: " + index );
+				}
+
+				set( st, value, index );
+			}
+		}
+		catch ( RuntimeException re ) {
+			log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + re.getMessage() );
+			throw re;
+		}
+		catch ( SQLException se ) {
+			log().info( "could not bind value '" + nullSafeToString( value ) + "' to parameter: " + index + "; " + se.getMessage() );
+			throw se;
+		}
+	}
+
+	public final Object nullSafeGet(
+			ResultSet rs,
+			String[] names,
+			SessionImplementor session,
+			Object owner)
+	throws HibernateException, SQLException {
+		return nullSafeGet(rs, names[0]);
+	}
+
+	public final Object nullSafeGet(ResultSet rs, String[] names)
+	throws HibernateException, SQLException {
+		return nullSafeGet(rs, names[0]);
+	}
+
+	public final Object nullSafeGet(ResultSet rs, String name)
+	throws HibernateException, SQLException {
+		try {
+			Object value = get(rs, name);
+			if ( value == null || rs.wasNull() ) {
+				if ( IS_VALUE_TRACING_ENABLED ) {
+					log().trace( "returning null as column: " + name );
+				}
+				return null;
+			}
+			else {
+				if ( IS_VALUE_TRACING_ENABLED ) {
+					log().trace( "returning '" + toString( value ) + "' as column: " + name );
+				}
+				return value;
+			}
+		}
+		catch ( RuntimeException re ) {
+			log().info( "could not read column value from result set: " + name + "; " + re.getMessage() );
+			throw re;
+		}
+		catch ( SQLException se ) {
+			log().info( "could not read column value from result set: " + name + "; " + se.getMessage() );
+			throw se;
+		}
+	}
+
+	public final Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException {
+		return nullSafeGet(rs, name);
+	}
+
+	public final String toXMLString(Object value, SessionFactoryImplementor pc)
+	throws HibernateException {
+		return toString(value);
+	}
+
+	public final Object fromXMLString(String xml, Mapping factory) throws HibernateException {
+		return xml==null || xml.length()==0 ? null : fromStringValue(xml);
+	}
+
+	public final int getColumnSpan(Mapping session) {
+		return 1;
+	}
+
+	public final int[] sqlTypes(Mapping session) {
+		return new int[] { sqlType() };
+	}
+
+	public final boolean isEqual(Object x, Object y, EntityMode entityMode) {
+		return isEqual(x, y);
+	}
+
+	public boolean isEqual(Object x, Object y) {
+		return EqualsHelper.equals(x, y);
+	}
+
+	public String toLoggableString(Object value, SessionFactoryImplementor factory) {
+		return value == null ? "null" : toString(value);
+	}
+
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException {
+		return fromXMLString( xml.getText(), factory );
+	}
+
+	public void setToXMLNode(Node xml, Object value, SessionFactoryImplementor factory)
+	throws HibernateException {
+		xml.setText( toXMLString(value, factory) );
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		return value==null ? ArrayHelper.FALSE : ArrayHelper.TRUE;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
+	throws HibernateException {
+		return checkable[0] && isDirty(old, current, session);
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/OneToOneType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,155 +0,0 @@
-//$Id: OneToOneType.java 7644 2005-07-25 06:53:09Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.EntityKey;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.entity.EntityPersister;
-import org.hibernate.util.ArrayHelper;
-
-/**
- * A one-to-one association to an entity
- * @author Gavin King
- */
-public class OneToOneType extends EntityType {
-
-	private final ForeignKeyDirection foreignKeyType;
-	private final String propertyName;
-	private final String entityName;
-	
-	public String getPropertyName() {
-		return propertyName;
-	}
-	
-	public boolean isNull(Object owner, SessionImplementor session) {
-		
-		if ( propertyName != null ) {
-			
-			EntityPersister ownerPersister = session.getFactory()
-					.getEntityPersister(entityName); 
-			Serializable id = session.getContextEntityIdentifier(owner);
-
-			EntityKey entityKey = new EntityKey( id, ownerPersister, session.getEntityMode() );
-			
-			return session.getPersistenceContext()
-					.isPropertyNull( entityKey, getPropertyName() );
-			
-		}
-		else {
-			return false;
-		}
-
-	}
-
-	public int getColumnSpan(Mapping session) throws MappingException {
-		return 0;
-	}
-
-	public int[] sqlTypes(Mapping session) throws MappingException {
-		return ArrayHelper.EMPTY_INT_ARRAY;
-	}
-
-	public boolean[] toColumnNullness(Object value, Mapping mapping) {
-		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
-	}
-
-	public OneToOneType(
-			String referencedEntityName, 
-			ForeignKeyDirection foreignKeyType, 
-			String uniqueKeyPropertyName,
-			boolean lazy,
-			boolean unwrapProxy,
-			boolean isEmbeddedInXML,
-			String entityName,
-			String propertyName
-	) {
-		super(
-				referencedEntityName, 
-				uniqueKeyPropertyName, 
-				!lazy, 
-				isEmbeddedInXML, 
-				unwrapProxy
-			);
-		this.foreignKeyType = foreignKeyType;
-		this.propertyName = propertyName;
-		this.entityName = entityName;
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) {
-		//nothing to do
-	}
-
-	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) {
-		//nothing to do
-	}
-
-	public boolean isOneToOne() {
-		return true;
-	}
-
-	public boolean isDirty(Object old, Object current, SessionImplementor session) {
-		return false;
-	}
-
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) {
-		return false;
-	}
-
-	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) {
-		return false;
-	}
-
-	public ForeignKeyDirection getForeignKeyDirection() {
-		return foreignKeyType;
-	}
-
-	public Object hydrate(
-		ResultSet rs,
-		String[] names,
-		SessionImplementor session,
-		Object owner)
-	throws HibernateException, SQLException {
-
-		return session.getContextEntityIdentifier(owner);
-	}
-
-	protected boolean isNullable() {
-		return foreignKeyType==ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;
-	}
-
-	public boolean useLHSPrimaryKey() {
-		return true;
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return null;
-	}
-
-	public Object assemble(Serializable oid, SessionImplementor session, Object owner)
-	throws HibernateException {
-		//this should be a call to resolve(), not resolveIdentifier(), 
-		//'cos it might be a property-ref, and we did not cache the
-		//referenced value
-		return resolve( session.getContextEntityIdentifier(owner), session, owner );
-	}
-	
-	/**
-	 * We don't need to dirty check one-to-one because of how 
-	 * assemble/disassemble is implemented and because a one-to-one 
-	 * association is never dirty
-	 */
-	public boolean isAlwaysDirtyChecked() {
-		//TODO: this is kinda inconsistent with CollectionType
-		return false; 
-	}
-	
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/OneToOneType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OneToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,178 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.EntityKey;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.entity.EntityPersister;
+import org.hibernate.util.ArrayHelper;
+
+/**
+ * A one-to-one association to an entity
+ * @author Gavin King
+ */
+public class OneToOneType extends EntityType {
+
+	private final ForeignKeyDirection foreignKeyType;
+	private final String propertyName;
+	private final String entityName;
+	
+	public String getPropertyName() {
+		return propertyName;
+	}
+	
+	public boolean isNull(Object owner, SessionImplementor session) {
+		
+		if ( propertyName != null ) {
+			
+			EntityPersister ownerPersister = session.getFactory()
+					.getEntityPersister(entityName); 
+			Serializable id = session.getContextEntityIdentifier(owner);
+
+			EntityKey entityKey = new EntityKey( id, ownerPersister, session.getEntityMode() );
+			
+			return session.getPersistenceContext()
+					.isPropertyNull( entityKey, getPropertyName() );
+			
+		}
+		else {
+			return false;
+		}
+
+	}
+
+	public int getColumnSpan(Mapping session) throws MappingException {
+		return 0;
+	}
+
+	public int[] sqlTypes(Mapping session) throws MappingException {
+		return ArrayHelper.EMPTY_INT_ARRAY;
+	}
+
+	public boolean[] toColumnNullness(Object value, Mapping mapping) {
+		return ArrayHelper.EMPTY_BOOLEAN_ARRAY;
+	}
+
+	public OneToOneType(
+			String referencedEntityName, 
+			ForeignKeyDirection foreignKeyType, 
+			String uniqueKeyPropertyName,
+			boolean lazy,
+			boolean unwrapProxy,
+			boolean isEmbeddedInXML,
+			String entityName,
+			String propertyName
+	) {
+		super(
+				referencedEntityName, 
+				uniqueKeyPropertyName, 
+				!lazy, 
+				isEmbeddedInXML, 
+				unwrapProxy
+			);
+		this.foreignKeyType = foreignKeyType;
+		this.propertyName = propertyName;
+		this.entityName = entityName;
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session) {
+		//nothing to do
+	}
+
+	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) {
+		//nothing to do
+	}
+
+	public boolean isOneToOne() {
+		return true;
+	}
+
+	public boolean isDirty(Object old, Object current, SessionImplementor session) {
+		return false;
+	}
+
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) {
+		return false;
+	}
+
+	public boolean isModified(Object old, Object current, boolean[] checkable, SessionImplementor session) {
+		return false;
+	}
+
+	public ForeignKeyDirection getForeignKeyDirection() {
+		return foreignKeyType;
+	}
+
+	public Object hydrate(
+		ResultSet rs,
+		String[] names,
+		SessionImplementor session,
+		Object owner)
+	throws HibernateException, SQLException {
+
+		return session.getContextEntityIdentifier(owner);
+	}
+
+	protected boolean isNullable() {
+		return foreignKeyType==ForeignKeyDirection.FOREIGN_KEY_TO_PARENT;
+	}
+
+	public boolean useLHSPrimaryKey() {
+		return true;
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return null;
+	}
+
+	public Object assemble(Serializable oid, SessionImplementor session, Object owner)
+	throws HibernateException {
+		//this should be a call to resolve(), not resolveIdentifier(), 
+		//'cos it might be a property-ref, and we did not cache the
+		//referenced value
+		return resolve( session.getContextEntityIdentifier(owner), session, owner );
+	}
+	
+	/**
+	 * We don't need to dirty check one-to-one because of how 
+	 * assemble/disassemble is implemented and because a one-to-one 
+	 * association is never dirty
+	 */
+	public boolean isAlwaysDirtyChecked() {
+		//TODO: this is kinda inconsistent with CollectionType
+		return false; 
+	}
+	
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/OrderedMapType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: OrderedMapType.java 10100 2006-07-10 16:31:09Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.util.LinkedHashMap;
-
-/**
- * A specialization of the map type, with (resultset-based) ordering.
- */
-public class OrderedMapType extends MapType {
-
-	/**
-	 * Constructs a map type capable of creating ordered maps of the given
-	 * role.
-	 *
-	 * @param role The collection role name.
-	 * @param propertyRef The property ref name.
-	 * @param isEmbeddedInXML Is this collection to embed itself in xml
-	 */
-	public OrderedMapType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super( role, propertyRef, isEmbeddedInXML );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize > 0
-				? new LinkedHashMap( anticipatedSize )
-				: new LinkedHashMap();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/OrderedMapType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedMapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.util.LinkedHashMap;
+
+/**
+ * A specialization of the map type, with (resultset-based) ordering.
+ */
+public class OrderedMapType extends MapType {
+
+	/**
+	 * Constructs a map type capable of creating ordered maps of the given
+	 * role.
+	 *
+	 * @param role The collection role name.
+	 * @param propertyRef The property ref name.
+	 * @param isEmbeddedInXML Is this collection to embed itself in xml
+	 */
+	public OrderedMapType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super( role, propertyRef, isEmbeddedInXML );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize > 0
+				? new LinkedHashMap( anticipatedSize )
+				: new LinkedHashMap();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/OrderedSetType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: OrderedSetType.java 10100 2006-07-10 16:31:09Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.util.LinkedHashSet;
-
-/**
- * A specialization of the set type, with (resultset-based) ordering.
- */
-public class OrderedSetType extends SetType {
-
-	/**
-	 * Constructs a set type capable of creating ordered sets of the given
-	 * role.
-	 *
-	 * @param role The collection role name.
-	 * @param propertyRef The property ref name.
-	 * @param isEmbeddedInXML Is this collection to embed itself in xml
-	 */
-	public OrderedSetType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super( role, propertyRef, isEmbeddedInXML );
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize > 0
-				? new LinkedHashSet( anticipatedSize )
-				: new LinkedHashSet();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/OrderedSetType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/OrderedSetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.util.LinkedHashSet;
+
+/**
+ * A specialization of the set type, with (resultset-based) ordering.
+ */
+public class OrderedSetType extends SetType {
+
+	/**
+	 * Constructs a set type capable of creating ordered sets of the given
+	 * role.
+	 *
+	 * @param role The collection role name.
+	 * @param propertyRef The property ref name.
+	 * @param isEmbeddedInXML Is this collection to embed itself in xml
+	 */
+	public OrderedSetType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super( role, propertyRef, isEmbeddedInXML );
+	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize > 0
+				? new LinkedHashSet( anticipatedSize )
+				: new LinkedHashSet();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/PrimitiveType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: PrimitiveType.java 4582 2004-09-25 11:22:20Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-
-/**
- * Superclass of primitive / primitive wrapper types.
- * @author Gavin King
- */
-public abstract class PrimitiveType extends ImmutableType implements LiteralType {
-
-	public abstract Class getPrimitiveClass();
-
-	public String toString(Object value) {
-		return value.toString();
-	}
-	
-	public abstract Serializable getDefaultValue();
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/PrimitiveType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/PrimitiveType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+
+/**
+ * Superclass of primitive / primitive wrapper types.
+ * @author Gavin King
+ */
+public abstract class PrimitiveType extends ImmutableType implements LiteralType {
+
+	public abstract Class getPrimitiveClass();
+
+	public String toString(Object value) {
+		return value.toString();
+	}
+	
+	public abstract Serializable getDefaultValue();
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,106 +0,0 @@
-//$Id: SerializableType.java 10818 2006-11-16 05:12:01Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.SerializationHelper;
-
-/**
- * <tt>serializable</tt>: A type that maps an SQL VARBINARY to a
- * serializable Java object.
- * @author Gavin King
- */
-public class SerializableType extends MutableType {
-
-	private final Class serializableClass;
-
-	public SerializableType(Class serializableClass) {
-		this.serializableClass = serializableClass;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		Hibernate.BINARY.set(st, toBytes(value), index);
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-		byte[] bytes = (byte[]) Hibernate.BINARY.get(rs, name);
-		// Some JDBC drivers erroneously return an empty array here for a null DB value :/
-		if ( bytes == null || bytes.length == 0 ) {
-			return null;
-		}
-		else {
-			return fromBytes(bytes);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return serializableClass;
-	}
-
-	public boolean isEqual(Object x, Object y) throws HibernateException {
-		if ( x == y ) {
-			return true;
-		}
-		if ( x == null || y == null ) {
-			return false;
-		}
-		return x.equals( y ) || Hibernate.BINARY.isEqual( toBytes( x ), toBytes( y ) );
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		return Hibernate.BINARY.getHashCode( toBytes(x), entityMode );
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return Hibernate.BINARY.toString( toBytes(value) );
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		return fromBytes( (byte[]) Hibernate.BINARY.fromStringValue(xml) );
-	}
-
-	public String getName() {
-		return (serializableClass==Serializable.class) ? "serializable" : serializableClass.getName();
-	}
-
-	public Object deepCopyNotNull(Object value) throws HibernateException {
-		return fromBytes( toBytes(value) );
-	}
-
-	private static byte[] toBytes(Object object) throws SerializationException {
-		return SerializationHelper.serialize( (Serializable) object );
-	}
-
-	private static Object fromBytes( byte[] bytes ) throws SerializationException {
-		return SerializationHelper.deserialize(bytes);
-	}
-
-	public int sqlType() {
-		return Hibernate.BINARY.sqlType();
-	}
-
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return (cached==null) ? null : fromBytes( (byte[]) cached );
-	}
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-		return (value==null) ? null : toBytes(value);
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SerializableType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializableType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,129 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.SerializationHelper;
+
+/**
+ * <tt>serializable</tt>: A type that maps an SQL VARBINARY to a
+ * serializable Java object.
+ * @author Gavin King
+ */
+public class SerializableType extends MutableType {
+
+	private final Class serializableClass;
+
+	public SerializableType(Class serializableClass) {
+		this.serializableClass = serializableClass;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		Hibernate.BINARY.set(st, toBytes(value), index);
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+		byte[] bytes = (byte[]) Hibernate.BINARY.get(rs, name);
+		// Some JDBC drivers erroneously return an empty array here for a null DB value :/
+		if ( bytes == null || bytes.length == 0 ) {
+			return null;
+		}
+		else {
+			return fromBytes(bytes);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return serializableClass;
+	}
+
+	public boolean isEqual(Object x, Object y) throws HibernateException {
+		if ( x == y ) {
+			return true;
+		}
+		if ( x == null || y == null ) {
+			return false;
+		}
+		return x.equals( y ) || Hibernate.BINARY.isEqual( toBytes( x ), toBytes( y ) );
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		return Hibernate.BINARY.getHashCode( toBytes(x), entityMode );
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return Hibernate.BINARY.toString( toBytes(value) );
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		return fromBytes( (byte[]) Hibernate.BINARY.fromStringValue(xml) );
+	}
+
+	public String getName() {
+		return (serializableClass==Serializable.class) ? "serializable" : serializableClass.getName();
+	}
+
+	public Object deepCopyNotNull(Object value) throws HibernateException {
+		return fromBytes( toBytes(value) );
+	}
+
+	private static byte[] toBytes(Object object) throws SerializationException {
+		return SerializationHelper.serialize( (Serializable) object );
+	}
+
+	private static Object fromBytes( byte[] bytes ) throws SerializationException {
+		return SerializationHelper.deserialize(bytes);
+	}
+
+	public int sqlType() {
+		return Hibernate.BINARY.sqlType();
+	}
+
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return (cached==null) ? null : fromBytes( (byte[]) cached );
+	}
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+		return (value==null) ? null : toBytes(value);
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SerializationException.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: SerializationException.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.type;
-
-import org.hibernate.HibernateException;
-
-/**
- * Thrown when a property cannot be serializaed/deserialized
- * @author Gavin King
- */
-public class SerializationException extends HibernateException {
-
-	public SerializationException(String message, Exception root) {
-		super(message, root);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SerializationException.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SerializationException.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import org.hibernate.HibernateException;
+
+/**
+ * Thrown when a property cannot be serializaed/deserialized
+ * @author Gavin King
+ */
+public class SerializationException extends HibernateException {
+
+	public SerializationException(String message, Exception root) {
+		super(message, root);
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SetType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,49 +0,0 @@
-//$Id: SetType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.HashSet;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentElementHolder;
-import org.hibernate.collection.PersistentSet;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-public class SetType extends CollectionType {
-
-	public SetType(String role, String propertyRef, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder(session, persister, key);
-		}
-		else {
-			return new PersistentSet(session);
-		}
-	}
-
-	public Class getReturnedClass() {
-		return java.util.Set.class;
-	}
-
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentSet( session, (java.util.Set) collection );
-		}
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return anticipatedSize <= 0
-		       ? new HashSet()
-		       : new HashSet( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SetType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.util.HashSet;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentElementHolder;
+import org.hibernate.collection.PersistentSet;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+public class SetType extends CollectionType {
+
+	public SetType(String role, String propertyRef, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder(session, persister, key);
+		}
+		else {
+			return new PersistentSet(session);
+		}
+	}
+
+	public Class getReturnedClass() {
+		return java.util.Set.class;
+	}
+
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentSet( session, (java.util.Set) collection );
+		}
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return anticipatedSize <= 0
+		       ? new HashSet()
+		       : new HashSet( anticipatedSize + (int)( anticipatedSize * .75f ), .75f );
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/ShortType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,78 +0,0 @@
-//$Id: ShortType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Comparator;
-
-import org.hibernate.util.ComparableComparator;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * <tt>short</tt>: A type that maps an SQL SMALLINT to a Java Short.
- * @author Gavin King
- */
-public class ShortType extends PrimitiveType  implements DiscriminatorType, VersionType {
-
-	private static final Short ZERO = new Short( (short) 0 );
-
-	public Serializable getDefaultValue() {
-		return ZERO;
-	}
-	
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return new Short( rs.getShort(name) );
-	}
-
-	public Class getPrimitiveClass() {
-		return short.class;
-	}
-
-	public Class getReturnedClass() {
-		return Short.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		st.setShort( index, ( (Short) value ).shortValue() );
-	}
-
-	public int sqlType() {
-		return Types.SMALLINT;
-	}
-
-	public String getName() { return "short"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return value.toString();
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return new Short(xml);
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return new Short( (short) ( ( (Short) current ).shortValue() + 1 ) );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return ZERO;
-	}
-
-	public Comparator getComparator() {
-		return ComparableComparator.INSTANCE;
-	}
-	
-	public Object fromStringValue(String xml) {
-		return new Short(xml);
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/ShortType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/ShortType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Comparator;
+
+import org.hibernate.util.ComparableComparator;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * <tt>short</tt>: A type that maps an SQL SMALLINT to a Java Short.
+ * @author Gavin King
+ */
+public class ShortType extends PrimitiveType  implements DiscriminatorType, VersionType {
+
+	private static final Short ZERO = new Short( (short) 0 );
+
+	public Serializable getDefaultValue() {
+		return ZERO;
+	}
+	
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return new Short( rs.getShort(name) );
+	}
+
+	public Class getPrimitiveClass() {
+		return short.class;
+	}
+
+	public Class getReturnedClass() {
+		return Short.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		st.setShort( index, ( (Short) value ).shortValue() );
+	}
+
+	public int sqlType() {
+		return Types.SMALLINT;
+	}
+
+	public String getName() { return "short"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return value.toString();
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return new Short(xml);
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return new Short( (short) ( ( (Short) current ).shortValue() + 1 ) );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return ZERO;
+	}
+
+	public Comparator getComparator() {
+		return ComparableComparator.INSTANCE;
+	}
+	
+	public Object fromStringValue(String xml) {
+		return new Short(xml);
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SortedMapType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,61 +0,0 @@
-//$Id: SortedMapType.java 10100 2006-07-10 16:31:09Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.Comparator;
-import java.util.TreeMap;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentElementHolder;
-import org.hibernate.collection.PersistentMapElementHolder;
-import org.hibernate.collection.PersistentSortedMap;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-
-public class SortedMapType extends MapType {
-
-	private final Comparator comparator;
-
-	public SortedMapType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-		this.comparator = comparator;
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentMapElementHolder(session, persister, key);
-		}
-		else {
-			PersistentSortedMap map = new PersistentSortedMap(session);
-			map.setComparator(comparator);
-			return map;
-		}
-	}
-
-	public Class getReturnedClass() {
-		return java.util.SortedMap.class;
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return new TreeMap(comparator);
-	}
-	
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentSortedMap( session, (java.util.SortedMap) collection );
-		}
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SortedMapType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedMapType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,84 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.TreeMap;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentElementHolder;
+import org.hibernate.collection.PersistentMapElementHolder;
+import org.hibernate.collection.PersistentSortedMap;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+
+public class SortedMapType extends MapType {
+
+	private final Comparator comparator;
+
+	public SortedMapType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+		this.comparator = comparator;
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentMapElementHolder(session, persister, key);
+		}
+		else {
+			PersistentSortedMap map = new PersistentSortedMap(session);
+			map.setComparator(comparator);
+			return map;
+		}
+	}
+
+	public Class getReturnedClass() {
+		return java.util.SortedMap.class;
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return new TreeMap(comparator);
+	}
+	
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentSortedMap( session, (java.util.SortedMap) collection );
+		}
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SortedSetType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-//$Id: SortedSetType.java 10100 2006-07-10 16:31:09Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.util.Comparator;
-import java.util.TreeSet;
-
-import org.dom4j.Element;
-import org.hibernate.EntityMode;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.collection.PersistentElementHolder;
-import org.hibernate.collection.PersistentSortedSet;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-public class SortedSetType extends SetType {
-
-	private final Comparator comparator;
-
-	public SortedSetType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) {
-		super(role, propertyRef, isEmbeddedInXML);
-		this.comparator = comparator;
-	}
-
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder(session, persister, key);
-		}
-		else {
-			PersistentSortedSet set = new PersistentSortedSet(session);
-			set.setComparator(comparator);
-			return set;
-		}
-	}
-
-	public Class getReturnedClass() {
-		return java.util.SortedSet.class;
-	}
-
-	public Object instantiate(int anticipatedSize) {
-		return new TreeSet(comparator);
-	}
-	
-	public PersistentCollection wrap(SessionImplementor session, Object collection) {
-		if ( session.getEntityMode()==EntityMode.DOM4J ) {
-			return new PersistentElementHolder( session, (Element) collection );
-		}
-		else {
-			return new PersistentSortedSet( session, (java.util.SortedSet) collection );
-		}
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SortedSetType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SortedSetType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.TreeSet;
+
+import org.dom4j.Element;
+import org.hibernate.EntityMode;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.collection.PersistentElementHolder;
+import org.hibernate.collection.PersistentSortedSet;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+public class SortedSetType extends SetType {
+
+	private final Comparator comparator;
+
+	public SortedSetType(String role, String propertyRef, Comparator comparator, boolean isEmbeddedInXML) {
+		super(role, propertyRef, isEmbeddedInXML);
+		this.comparator = comparator;
+	}
+
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister, Serializable key) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder(session, persister, key);
+		}
+		else {
+			PersistentSortedSet set = new PersistentSortedSet(session);
+			set.setComparator(comparator);
+			return set;
+		}
+	}
+
+	public Class getReturnedClass() {
+		return java.util.SortedSet.class;
+	}
+
+	public Object instantiate(int anticipatedSize) {
+		return new TreeSet(comparator);
+	}
+	
+	public PersistentCollection wrap(SessionImplementor session, Object collection) {
+		if ( session.getEntityMode()==EntityMode.DOM4J ) {
+			return new PersistentElementHolder( session, (Element) collection );
+		}
+		else {
+			return new PersistentSortedSet( session, (java.util.SortedSet) collection );
+		}
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,106 +0,0 @@
-//$Id: SpecialOneToOneType.java 7246 2005-06-20 20:32:36Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.ForeignKeys;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * A one-to-one association that maps to specific formula(s)
- * instead of the primary key column of the owning entity.
- * 
- * @author Gavin King
- */
-public class SpecialOneToOneType extends OneToOneType {
-	
-	public SpecialOneToOneType(
-			String referencedEntityName,
-			ForeignKeyDirection foreignKeyType, 
-			String uniqueKeyPropertyName,
-			boolean lazy,
-			boolean unwrapProxy,
-			String entityName,
-			String propertyName
-	) {
-		super(
-				referencedEntityName, 
-				foreignKeyType, 
-				uniqueKeyPropertyName, 
-				lazy,
-				unwrapProxy,
-				true, 
-				entityName, 
-				propertyName
-			);
-	}
-	
-	public int getColumnSpan(Mapping mapping) throws MappingException {
-		return super.getIdentifierOrUniqueKeyType(mapping).getColumnSpan(mapping);
-	}
-	
-	public int[] sqlTypes(Mapping mapping) throws MappingException {
-		return super.getIdentifierOrUniqueKeyType(mapping).sqlTypes(mapping);
-	}
-
-	public boolean useLHSPrimaryKey() {
-		return false;
-	}
-	
-	public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException {
-		return super.getIdentifierOrUniqueKeyType( session.getFactory() )
-			.nullSafeGet(rs, names, session, owner);
-	}
-	
-	// TODO: copy/paste from ManyToOneType
-
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
-	throws HibernateException {
-
-		if ( isNotEmbedded(session) ) {
-			return getIdentifierType(session).disassemble(value, session, owner);
-		}
-		
-		if (value==null) {
-			return null;
-		}
-		else {
-			// cache the actual id of the object, not the value of the
-			// property-ref, which might not be initialized
-			Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session );
-			if (id==null) {
-				throw new AssertionFailure(
-						"cannot cache a reference to an object with a null id: " + 
-						getAssociatedEntityName() 
-				);
-			}
-			return getIdentifierType(session).disassemble(id, session, owner);
-		}
-	}
-
-	public Object assemble(Serializable oid, SessionImplementor session, Object owner)
-	throws HibernateException {
-		//TODO: currently broken for unique-key references (does not detect
-		//      change to unique key property of the associated object)
-		Serializable id = (Serializable) getIdentifierType(session).assemble(oid, session, null); //the owner of the association is not the owner of the id
-
-		if ( isNotEmbedded(session) ) return id;
-		
-		if (id==null) {
-			return null;
-		}
-		else {
-			return resolveIdentifier(id, session);
-		}
-	}
-	
-
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/SpecialOneToOneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,129 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.ForeignKeys;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * A one-to-one association that maps to specific formula(s)
+ * instead of the primary key column of the owning entity.
+ * 
+ * @author Gavin King
+ */
+public class SpecialOneToOneType extends OneToOneType {
+	
+	public SpecialOneToOneType(
+			String referencedEntityName,
+			ForeignKeyDirection foreignKeyType, 
+			String uniqueKeyPropertyName,
+			boolean lazy,
+			boolean unwrapProxy,
+			String entityName,
+			String propertyName
+	) {
+		super(
+				referencedEntityName, 
+				foreignKeyType, 
+				uniqueKeyPropertyName, 
+				lazy,
+				unwrapProxy,
+				true, 
+				entityName, 
+				propertyName
+			);
+	}
+	
+	public int getColumnSpan(Mapping mapping) throws MappingException {
+		return super.getIdentifierOrUniqueKeyType(mapping).getColumnSpan(mapping);
+	}
+	
+	public int[] sqlTypes(Mapping mapping) throws MappingException {
+		return super.getIdentifierOrUniqueKeyType(mapping).sqlTypes(mapping);
+	}
+
+	public boolean useLHSPrimaryKey() {
+		return false;
+	}
+	
+	public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException {
+		return super.getIdentifierOrUniqueKeyType( session.getFactory() )
+			.nullSafeGet(rs, names, session, owner);
+	}
+	
+	// TODO: copy/paste from ManyToOneType
+
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner)
+	throws HibernateException {
+
+		if ( isNotEmbedded(session) ) {
+			return getIdentifierType(session).disassemble(value, session, owner);
+		}
+		
+		if (value==null) {
+			return null;
+		}
+		else {
+			// cache the actual id of the object, not the value of the
+			// property-ref, which might not be initialized
+			Object id = ForeignKeys.getEntityIdentifierIfNotUnsaved( getAssociatedEntityName(), value, session );
+			if (id==null) {
+				throw new AssertionFailure(
+						"cannot cache a reference to an object with a null id: " + 
+						getAssociatedEntityName() 
+				);
+			}
+			return getIdentifierType(session).disassemble(id, session, owner);
+		}
+	}
+
+	public Object assemble(Serializable oid, SessionImplementor session, Object owner)
+	throws HibernateException {
+		//TODO: currently broken for unique-key references (does not detect
+		//      change to unique key property of the associated object)
+		Serializable id = (Serializable) getIdentifierType(session).assemble(oid, session, null); //the owner of the association is not the owner of the id
+
+		if ( isNotEmbedded(session) ) return id;
+		
+		if (id==null) {
+			return null;
+		}
+		else {
+			return resolveIdentifier(id, session);
+		}
+	}
+	
+
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/StringType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,56 +0,0 @@
-//$Id: StringType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>string</tt>: A type that maps an SQL VARCHAR to a Java String.
- * @author Gavin King
- */
-public class StringType extends ImmutableType implements DiscriminatorType {
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return rs.getString(name);
-	}
-
-	public Class getReturnedClass() {
-		return String.class;
-	}
-
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		st.setString(index, (String) value);
-	}
-
-	public int sqlType() {
-		return Types.VARCHAR;
-	}
-
-	public String getName() { return "string"; }
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return '\'' + (String) value + '\'';
-	}
-
-	public Object stringToObject(String xml) throws Exception {
-		return xml;
-	}
-
-	public String toString(Object value) {
-		return (String) value;
-	}
-
-	public Object fromStringValue(String xml) {
-		return xml;
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/StringType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/StringType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>string</tt>: A type that maps an SQL VARCHAR to a Java String.
+ * @author Gavin King
+ */
+public class StringType extends ImmutableType implements DiscriminatorType {
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return rs.getString(name);
+	}
+
+	public Class getReturnedClass() {
+		return String.class;
+	}
+
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		st.setString(index, (String) value);
+	}
+
+	public int sqlType() {
+		return Types.VARCHAR;
+	}
+
+	public String getName() { return "string"; }
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return '\'' + (String) value + '\'';
+	}
+
+	public Object stringToObject(String xml) throws Exception {
+		return xml;
+	}
+
+	public String toString(Object value) {
+		return (String) value;
+	}
+
+	public Object fromStringValue(String xml) {
+		return xml;
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TextType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,84 +0,0 @@
-//$Id: TextType.java 4582 2004-09-25 11:22:20Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Types;
-
-import org.hibernate.HibernateException;
-
-/**
- * <tt>text</tt>: A type that maps an SQL CLOB to a Java String.
- * @author Gavin King, Bertrand Renuart
- */
-public class TextType extends ImmutableType {
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		String str = (String) value;
-		st.setCharacterStream( index, new StringReader(str), str.length() );
-	}
-
-	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
-
-			// Retrieve the value of the designated column in the current row of this
-			// ResultSet object as a java.io.Reader object
-			Reader charReader = rs.getCharacterStream(name);
-
-			// if the corresponding SQL value is NULL, the reader we got is NULL as well
-			if (charReader==null) return null;
-
-			// Fetch Reader content up to the end - and put characters in a StringBuffer
-			StringBuffer sb = new StringBuffer();
-			try {
-				char[] buffer = new char[2048];
-				while (true) {
-					int amountRead = charReader.read(buffer, 0, buffer.length);
-					if ( amountRead == -1 ) break;
-					sb.append(buffer, 0, amountRead);
-				}
-			}
-			catch (IOException ioe) {
-				throw new HibernateException( "IOException occurred reading text", ioe );
-			}
-			finally {
-				try {
-					charReader.close();
-				}
-				catch (IOException e) {
-					throw new HibernateException( "IOException occurred closing stream", e );
-				}
-			}
-
-			// Return StringBuffer content as a large String
-			return sb.toString();
-	}
-
-	public int sqlType() {
-		return Types.CLOB; //or Types.LONGVARCHAR?
-	}
-
-	public Class getReturnedClass() {
-		return String.class;
-	}
-
-	public String getName() { return "text"; }
-
-	public String toString(Object val) {
-		return (String) val;
-	}
-	public Object fromStringValue(String xml) {
-		return xml;
-	}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TextType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TextType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,107 @@
+/*
+ * 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.type;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.hibernate.HibernateException;
+
+/**
+ * <tt>text</tt>: A type that maps an SQL CLOB to a Java String.
+ * @author Gavin King, Bertrand Renuart
+ */
+public class TextType extends ImmutableType {
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		String str = (String) value;
+		st.setCharacterStream( index, new StringReader(str), str.length() );
+	}
+
+	public Object get(ResultSet rs, String name) throws HibernateException, SQLException {
+
+			// Retrieve the value of the designated column in the current row of this
+			// ResultSet object as a java.io.Reader object
+			Reader charReader = rs.getCharacterStream(name);
+
+			// if the corresponding SQL value is NULL, the reader we got is NULL as well
+			if (charReader==null) return null;
+
+			// Fetch Reader content up to the end - and put characters in a StringBuffer
+			StringBuffer sb = new StringBuffer();
+			try {
+				char[] buffer = new char[2048];
+				while (true) {
+					int amountRead = charReader.read(buffer, 0, buffer.length);
+					if ( amountRead == -1 ) break;
+					sb.append(buffer, 0, amountRead);
+				}
+			}
+			catch (IOException ioe) {
+				throw new HibernateException( "IOException occurred reading text", ioe );
+			}
+			finally {
+				try {
+					charReader.close();
+				}
+				catch (IOException e) {
+					throw new HibernateException( "IOException occurred closing stream", e );
+				}
+			}
+
+			// Return StringBuffer content as a large String
+			return sb.toString();
+	}
+
+	public int sqlType() {
+		return Types.CLOB; //or Types.LONGVARCHAR?
+	}
+
+	public Class getReturnedClass() {
+		return String.class;
+	}
+
+	public String getName() { return "text"; }
+
+	public String toString(Object val) {
+		return (String) val;
+	}
+	public Object fromStringValue(String xml) {
+		return xml;
+	}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TimeType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,107 +0,0 @@
-//$Id: TimeType.java 8891 2005-12-21 05:13:29Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Time;
-import java.sql.Types;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>time</tt>: A type that maps an SQL TIME to a Java
- * java.util.Date or java.sql.Time.
- * @author Gavin King
- */
-public class TimeType extends MutableType implements LiteralType {
-
-	private static final String TIME_FORMAT = "HH:mm:ss";
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return rs.getTime(name);
-	}
-	public Class getReturnedClass() {
-		return java.util.Date.class;
-	}
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-
-		Time time;
-		if (value instanceof Time) {
-			time = (Time) value;
-		}
-		else {
-			time = new Time( ( (java.util.Date) value ).getTime() );
-		}
-		st.setTime(index, time);
-	}
-
-	public int sqlType() {
-		return Types.TIME;
-	}
-	public String getName() { return "time"; }
-
-	public String toString(Object val) {
-		return new SimpleDateFormat(TIME_FORMAT).format( (java.util.Date) val );
-	}
-	public boolean isEqual(Object x, Object y) {
-
-		if (x==y) return true;
-		if (x==null || y==null) return false;
-
-		Date xdate = (Date) x;
-		Date ydate = (Date) y;
-		
-		if ( xdate.getTime()==ydate.getTime() ) return true;
-		
-		Calendar calendar1 = java.util.Calendar.getInstance();
-		Calendar calendar2 = java.util.Calendar.getInstance();
-		calendar1.setTime( xdate );
-		calendar2.setTime( ydate );
-
-		return calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY)
-			&& calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE)
-			&& calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND)
-			&& calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND);
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		Calendar calendar = java.util.Calendar.getInstance();
-		calendar.setTime( (java.util.Date) x );
-		int hashCode = 1;
-		hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY);
-		hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE);
-		hashCode = 31 * hashCode + calendar.get(Calendar.SECOND);
-		hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND);
-		return hashCode;
-	}
-
-	public Object deepCopyNotNull(Object value) {
-		return  new Time( ( (java.util.Date) value ).getTime() );
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return '\'' + new Time( ( (java.util.Date) value ).getTime() ).toString() + '\'';
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		try {
-			return new SimpleDateFormat(TIME_FORMAT).parse(xml);
-		}
-		catch (ParseException pe) {
-			throw new HibernateException("could not parse XML", pe);
-		}
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TimeType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,130 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Time;
+import java.sql.Types;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>time</tt>: A type that maps an SQL TIME to a Java
+ * java.util.Date or java.sql.Time.
+ * @author Gavin King
+ */
+public class TimeType extends MutableType implements LiteralType {
+
+	private static final String TIME_FORMAT = "HH:mm:ss";
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return rs.getTime(name);
+	}
+	public Class getReturnedClass() {
+		return java.util.Date.class;
+	}
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+
+		Time time;
+		if (value instanceof Time) {
+			time = (Time) value;
+		}
+		else {
+			time = new Time( ( (java.util.Date) value ).getTime() );
+		}
+		st.setTime(index, time);
+	}
+
+	public int sqlType() {
+		return Types.TIME;
+	}
+	public String getName() { return "time"; }
+
+	public String toString(Object val) {
+		return new SimpleDateFormat(TIME_FORMAT).format( (java.util.Date) val );
+	}
+	public boolean isEqual(Object x, Object y) {
+
+		if (x==y) return true;
+		if (x==null || y==null) return false;
+
+		Date xdate = (Date) x;
+		Date ydate = (Date) y;
+		
+		if ( xdate.getTime()==ydate.getTime() ) return true;
+		
+		Calendar calendar1 = java.util.Calendar.getInstance();
+		Calendar calendar2 = java.util.Calendar.getInstance();
+		calendar1.setTime( xdate );
+		calendar2.setTime( ydate );
+
+		return calendar1.get(Calendar.HOUR_OF_DAY) == calendar2.get(Calendar.HOUR_OF_DAY)
+			&& calendar1.get(Calendar.MINUTE) == calendar2.get(Calendar.MINUTE)
+			&& calendar1.get(Calendar.SECOND) == calendar2.get(Calendar.SECOND)
+			&& calendar1.get(Calendar.MILLISECOND) == calendar2.get(Calendar.MILLISECOND);
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		Calendar calendar = java.util.Calendar.getInstance();
+		calendar.setTime( (java.util.Date) x );
+		int hashCode = 1;
+		hashCode = 31 * hashCode + calendar.get(Calendar.HOUR_OF_DAY);
+		hashCode = 31 * hashCode + calendar.get(Calendar.MINUTE);
+		hashCode = 31 * hashCode + calendar.get(Calendar.SECOND);
+		hashCode = 31 * hashCode + calendar.get(Calendar.MILLISECOND);
+		return hashCode;
+	}
+
+	public Object deepCopyNotNull(Object value) {
+		return  new Time( ( (java.util.Date) value ).getTime() );
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return '\'' + new Time( ( (java.util.Date) value ).getTime() ).toString() + '\'';
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		try {
+			return new SimpleDateFormat(TIME_FORMAT).parse(xml);
+		}
+		catch (ParseException pe) {
+			throw new HibernateException("could not parse XML", pe);
+		}
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TimeZoneType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,69 +0,0 @@
-//$Id: TimeZoneType.java 7825 2005-08-10 20:23:55Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.TimeZone;
-
-import org.hibernate.EntityMode;
-import org.hibernate.Hibernate;
-import org.hibernate.HibernateException;
-import org.hibernate.dialect.Dialect;
-
-/**
- * <tt>timezone</tt>: A type that maps an SQL VARCHAR to a
- * <tt>java.util.TimeZone</tt>
- * @see java.util.TimeZone
- * @author Gavin King
- */
-public class TimeZoneType extends ImmutableType implements LiteralType {
-
-	public Object get(ResultSet rs, String name)
-	throws HibernateException, SQLException {
-		String id = (String) Hibernate.STRING.nullSafeGet(rs, name);
-		return (id==null) ? null : TimeZone.getTimeZone(id);
-	}
-
-
-	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
-		Hibernate.STRING.set(st, ( (TimeZone) value ).getID(), index);
-	}
-
-	public int sqlType() {
-		return Hibernate.STRING.sqlType();
-	}
-
-	public String toString(Object value) throws HibernateException {
-		return ( (TimeZone) value ).getID();
-	}
-
-	public int compare(Object x, Object y, EntityMode entityMode) {
-		return ( (TimeZone) x ).getID().compareTo( ( (TimeZone) y ).getID() );
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		return TimeZone.getTimeZone(xml);
-	}
-
-	public Class getReturnedClass() {
-		return TimeZone.class;
-	}
-
-	public String getName() {
-		return "timezone";
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return ( (LiteralType) Hibernate.STRING ).objectToSQLString(
-			( (TimeZone) value ).getID(), dialect
-		);
-	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TimeZoneType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimeZoneType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,92 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.TimeZone;
+
+import org.hibernate.EntityMode;
+import org.hibernate.Hibernate;
+import org.hibernate.HibernateException;
+import org.hibernate.dialect.Dialect;
+
+/**
+ * <tt>timezone</tt>: A type that maps an SQL VARCHAR to a
+ * <tt>java.util.TimeZone</tt>
+ * @see java.util.TimeZone
+ * @author Gavin King
+ */
+public class TimeZoneType extends ImmutableType implements LiteralType {
+
+	public Object get(ResultSet rs, String name)
+	throws HibernateException, SQLException {
+		String id = (String) Hibernate.STRING.nullSafeGet(rs, name);
+		return (id==null) ? null : TimeZone.getTimeZone(id);
+	}
+
+
+	public void set(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
+		Hibernate.STRING.set(st, ( (TimeZone) value ).getID(), index);
+	}
+
+	public int sqlType() {
+		return Hibernate.STRING.sqlType();
+	}
+
+	public String toString(Object value) throws HibernateException {
+		return ( (TimeZone) value ).getID();
+	}
+
+	public int compare(Object x, Object y, EntityMode entityMode) {
+		return ( (TimeZone) x ).getID().compareTo( ( (TimeZone) y ).getID() );
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		return TimeZone.getTimeZone(xml);
+	}
+
+	public Class getReturnedClass() {
+		return TimeZone.class;
+	}
+
+	public String getName() {
+		return "timezone";
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return ( (LiteralType) Hibernate.STRING ).objectToSQLString(
+			( (TimeZone) value ).getID(), dialect
+		);
+	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TimestampType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,135 +0,0 @@
-//$Id: TimestampType.java 8891 2005-12-21 05:13:29Z oneovthafew $
-package org.hibernate.type;
-
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Timestamp;
-import java.sql.Types;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Comparator;
-
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.util.ComparableComparator;
-
-/**
- * <tt>timestamp</tt>: A type that maps an SQL TIMESTAMP to a Java
- * java.util.Date or java.sql.Timestamp.
- * @author Gavin King
- */
-public class TimestampType extends MutableType implements VersionType, LiteralType {
-
-	private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
-
-	public Object get(ResultSet rs, String name) throws SQLException {
-		return rs.getTimestamp(name);
-	}
-	
-	public Class getReturnedClass() {
-		return java.util.Date.class;
-	}
-	
-	public void set(PreparedStatement st, Object value, int index) throws SQLException {
-		Timestamp ts;
-		if (value instanceof Timestamp) {
-			ts = (Timestamp) value;
-		}
-		else {
-			ts = new Timestamp( ( (java.util.Date) value ).getTime() );
-		}
-		st.setTimestamp(index, ts);
-	}
-
-	public int sqlType() {
-		return Types.TIMESTAMP;
-	}
-	
-	public String getName() { return "timestamp"; }
-
-	public String toString(Object val) {
-		return new SimpleDateFormat(TIMESTAMP_FORMAT).format( (java.util.Date) val );
-	}
-
-	public Object deepCopyNotNull(Object value) {
-		if ( value instanceof Timestamp ) {
-			Timestamp orig = (Timestamp) value;
-			Timestamp ts = new Timestamp( orig.getTime() );
-			ts.setNanos( orig.getNanos() );
-			return ts;
-		}
-		else {
-			java.util.Date orig = (java.util.Date) value;
-			return new java.util.Date( orig.getTime() );
-		}
-	}
-
-	public boolean isEqual(Object x, Object y) {
-
-		if (x==y) return true;
-		if (x==null || y==null) return false;
-
-		long xTime = ( (java.util.Date) x ).getTime();
-		long yTime = ( (java.util.Date) y ).getTime();
-		boolean xts = x instanceof Timestamp;
-		boolean yts = y instanceof Timestamp;
-		int xNanos = xts ? ( (Timestamp) x ).getNanos() : 0;
-		int yNanos = yts ? ( (Timestamp) y ).getNanos() : 0;
-		if ( !Environment.jvmHasJDK14Timestamp() ) {
-			xTime += xNanos / 1000000;
-			yTime += yNanos / 1000000;
-		}
-		if ( xTime!=yTime ) return false;
-		if (xts && yts) {
-			// both are Timestamps
-			int xn = xNanos % 1000000;
-			int yn = yNanos % 1000000;
-			return xn==yn;
-		}
-		else {
-			// at least one is a plain old Date
-			return true;
-		}
-
-	}
-
-	public int getHashCode(Object x, EntityMode entityMode) {
-		java.util.Date ts = (java.util.Date) x;
-		return new Long( ts.getTime() / 1000 ).hashCode();
-	}
-
-	public Object next(Object current, SessionImplementor session) {
-		return seed( session );
-	}
-
-	public Object seed(SessionImplementor session) {
-		return new Timestamp( System.currentTimeMillis() );
-	}
-
-	public Comparator getComparator() {
-		return ComparableComparator.INSTANCE;
-	}
-
-	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
-		return '\'' + new Timestamp( ( (java.util.Date) value ).getTime() ).toString() + '\'';
-	}
-
-	public Object fromStringValue(String xml) throws HibernateException {
-		try {
-			return new Timestamp( new SimpleDateFormat(TIMESTAMP_FORMAT).parse(xml).getTime() );
-		}
-		catch (ParseException pe) {
-			throw new HibernateException("could not parse XML", pe);
-		}
-	}
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TimestampType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TimestampType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,158 @@
+/*
+ * 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.type;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Comparator;
+
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.util.ComparableComparator;
+
+/**
+ * <tt>timestamp</tt>: A type that maps an SQL TIMESTAMP to a Java
+ * java.util.Date or java.sql.Timestamp.
+ * @author Gavin King
+ */
+public class TimestampType extends MutableType implements VersionType, LiteralType {
+
+	private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+	public Object get(ResultSet rs, String name) throws SQLException {
+		return rs.getTimestamp(name);
+	}
+	
+	public Class getReturnedClass() {
+		return java.util.Date.class;
+	}
+	
+	public void set(PreparedStatement st, Object value, int index) throws SQLException {
+		Timestamp ts;
+		if (value instanceof Timestamp) {
+			ts = (Timestamp) value;
+		}
+		else {
+			ts = new Timestamp( ( (java.util.Date) value ).getTime() );
+		}
+		st.setTimestamp(index, ts);
+	}
+
+	public int sqlType() {
+		return Types.TIMESTAMP;
+	}
+	
+	public String getName() { return "timestamp"; }
+
+	public String toString(Object val) {
+		return new SimpleDateFormat(TIMESTAMP_FORMAT).format( (java.util.Date) val );
+	}
+
+	public Object deepCopyNotNull(Object value) {
+		if ( value instanceof Timestamp ) {
+			Timestamp orig = (Timestamp) value;
+			Timestamp ts = new Timestamp( orig.getTime() );
+			ts.setNanos( orig.getNanos() );
+			return ts;
+		}
+		else {
+			java.util.Date orig = (java.util.Date) value;
+			return new java.util.Date( orig.getTime() );
+		}
+	}
+
+	public boolean isEqual(Object x, Object y) {
+
+		if (x==y) return true;
+		if (x==null || y==null) return false;
+
+		long xTime = ( (java.util.Date) x ).getTime();
+		long yTime = ( (java.util.Date) y ).getTime();
+		boolean xts = x instanceof Timestamp;
+		boolean yts = y instanceof Timestamp;
+		int xNanos = xts ? ( (Timestamp) x ).getNanos() : 0;
+		int yNanos = yts ? ( (Timestamp) y ).getNanos() : 0;
+		if ( !Environment.jvmHasJDK14Timestamp() ) {
+			xTime += xNanos / 1000000;
+			yTime += yNanos / 1000000;
+		}
+		if ( xTime!=yTime ) return false;
+		if (xts && yts) {
+			// both are Timestamps
+			int xn = xNanos % 1000000;
+			int yn = yNanos % 1000000;
+			return xn==yn;
+		}
+		else {
+			// at least one is a plain old Date
+			return true;
+		}
+
+	}
+
+	public int getHashCode(Object x, EntityMode entityMode) {
+		java.util.Date ts = (java.util.Date) x;
+		return new Long( ts.getTime() / 1000 ).hashCode();
+	}
+
+	public Object next(Object current, SessionImplementor session) {
+		return seed( session );
+	}
+
+	public Object seed(SessionImplementor session) {
+		return new Timestamp( System.currentTimeMillis() );
+	}
+
+	public Comparator getComparator() {
+		return ComparableComparator.INSTANCE;
+	}
+
+	public String objectToSQLString(Object value, Dialect dialect) throws Exception {
+		return '\'' + new Timestamp( ( (java.util.Date) value ).getTime() ).toString() + '\'';
+	}
+
+	public Object fromStringValue(String xml) throws HibernateException {
+		try {
+			return new Timestamp( new SimpleDateFormat(TIMESTAMP_FORMAT).parse(xml).getTime() );
+		}
+		catch (ParseException pe) {
+			throw new HibernateException("could not parse XML", pe);
+		}
+	}
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TrueFalseType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: TrueFalseType.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.type;
-
-/**
- * <tt>true_false</tt>: A type that maps an SQL CHAR(1) to a Java Boolean.
- * @author Gavin King
- */
-public class TrueFalseType extends CharBooleanType {
-
-	protected final String getTrueString() {
-		return "T";
-	}
-	protected final String getFalseString() {
-		return "F";
-	}
-	public String getName() { return "true_false"; }
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TrueFalseType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TrueFalseType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+/**
+ * <tt>true_false</tt>: A type that maps an SQL CHAR(1) to a Java Boolean.
+ * @author Gavin King
+ */
+public class TrueFalseType extends CharBooleanType {
+
+	protected final String getTrueString() {
+		return "T";
+	}
+	protected final String getFalseString() {
+		return "F";
+	}
+	public String getName() { return "true_false"; }
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/Type.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,427 +0,0 @@
-//$Id: Type.java 7793 2005-08-10 05:06:40Z oneovthafew $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.Map;
-
-import org.dom4j.Node;
-import org.hibernate.EntityMode;
-import org.hibernate.HibernateException;
-import org.hibernate.MappingException;
-import org.hibernate.engine.Mapping;
-import org.hibernate.engine.SessionFactoryImplementor;
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * Defines a mapping from a Java type to an JDBC datatype. This interface is intended to
- * be implemented by applications that need custom types.<br>
- * <br>
- * Implementors should usually be immutable and <b>must</b> certainly be threadsafe.
- *
- * @author Gavin King
- */
-public interface Type extends Serializable {
-
-	/**
-	 * Return true if the implementation is castable to
-	 * <tt>AssociationType</tt>. This does not necessarily imply that
-	 * the type actually represents an association.
-	 * @see AssociationType
-	 * @return boolean
-	 */
-	public boolean isAssociationType();
-	/**
-	 * Is this type a collection type.
-	 */
-	public boolean isCollectionType();
-
-	/**
-	 * Is this type a component type. If so, the implementation
-	 * must be castable to <tt>AbstractComponentType</tt>. A component
-	 * type may own collections or associations and hence must provide
-	 * certain extra functionality.
-	 * @see AbstractComponentType
-	 * @return boolean
-	 */
-	public boolean isComponentType();
-
-	/**
-	 * Is this type an entity type?
-	 * @return boolean
-	 */
-	public boolean isEntityType();
-
-	/**
-	 * Is this an "any" type.
-	 *
-	 * i.e. a reference to a persistent entity
-	 * that is not modelled as a (foreign key) association.
-	 */
-	public boolean isAnyType();
-	
-	public boolean isXMLElement();
-
-	/**
-	 * Return the SQL type codes for the columns mapped by this type. The codes
-	 * are defined on <tt>java.sql.Types</tt>.
-	 * @see java.sql.Types
-	 * @return the typecodes
-	 * @throws MappingException
-	 */
-	public int[] sqlTypes(Mapping mapping) throws MappingException;
-
-	/**
-	 * How many columns are used to persist this type.
-	 */
-	public int getColumnSpan(Mapping mapping) throws MappingException;
-
-	/**
-	 * The class returned by <tt>nullSafeGet()</tt> methods. This is used to 
-	 * establish the class of an array of this type.
-	 *
-	 * @return Class
-	 */
-	public Class getReturnedClass();
-
-	/**
-	 * Compare two instances of the class mapped by this type for persistence
-	 * "equality" - equality of persistent state - taking a shortcut for
-	 * entity references.
-	 * @param x
-	 * @param y
-	 * @param entityMode
-	 *
-	 * @return boolean
-	 * @throws HibernateException
-	 */
-	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Compare two instances of the class mapped by this type for persistence
-	 * "equality" - equality of persistent state.
-	 * @param x
-	 * @param y
-	 * @param entityMode 
-	 *
-	 * @return boolean
-	 * @throws HibernateException
-	 */
-	public boolean isEqual(Object x, Object y, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Compare two instances of the class mapped by this type for persistence
-	 * "equality" - equality of persistent state.
-	 * @param x
-	 * @param y
-	 * @param entityMode 
-	 *
-	 * @return boolean
-	 * @throws HibernateException
-	 */
-	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException;
-
-	/**
-	 * Get a hashcode, consistent with persistence "equality"
-	 * @param x
-	 * @param entityMode 
-	 */
-	public int getHashCode(Object x, EntityMode entityMode) throws HibernateException;
-
-	/**
-	 * Get a hashcode, consistent with persistence "equality"
-	 * @param x
-	 * @param entityMode 
-	 * @param factory
-	 */
-	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException;
-	
-	/**
-	 * compare two instances of the type
-	 * @param entityMode 
-	 */
-	public int compare(Object x, Object y, EntityMode entityMode);
-
-	/**
-	 * Should the parent be considered dirty, given both the old and current field or 
-	 * element value?
-	 * 
-	 * @param old the old value
-	 * @param current the current value
-	 * @param session
-	 * @return true if the field is dirty
-	 */
-	public boolean isDirty(Object old, Object current, SessionImplementor session)
-	throws HibernateException;
-	/**
-	 * Should the parent be considered dirty, given both the old and current field or 
-	 * element value?
-	 * 
-	 * @param old the old value
-	 * @param current the current value
-	 * @param checkable which columns are actually updatable
-	 * @param session
-	 * @return true if the field is dirty
-	 */
-	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Has the parent object been modified, compared to the current database state?
-	 * @param oldHydratedState the database state, in a "hydrated" form, with identifiers unresolved
-	 * @param currentState the current state of the object
-	 * @param checkable which columns are actually updatable
-	 * @param session
-	 * @return true if the field has been modified
-	 */
-	public boolean isModified(Object oldHydratedState, Object currentState, boolean[] checkable, SessionImplementor session)
-	throws HibernateException;
-
-	/**
-	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
-	 * should handle possibility of null values.
-	 *
-	 * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object) alternative, 2-phase property initialization
-	 * @param rs
-	 * @param names the column names
-	 * @param session
-	 * @param owner the parent entity
-	 * @return Object
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException;
-
-	/**
-	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementations
-	 * should handle possibility of null values. This method might be called if the
-	 * type is known to be a single-column type.
-	 *
-	 * @param rs
-	 * @param name the column name
-	 * @param session
-	 * @param owner the parent entity
-	 * @return Object
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException;
-
-	/**
-	 * Write an instance of the mapped class to a prepared statement, ignoring some columns. 
-	 * Implementors should handle possibility of null values. A multi-column type should be 
-	 * written to parameters starting from <tt>index</tt>.
-	 * @param st
-	 * @param value the object to write
-	 * @param index statement parameter index
-	 * @param settable an array indicating which columns to ignore
-	 * @param session
-	 *
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session)
-	throws HibernateException, SQLException;
-
-	/**
-	 * Write an instance of the mapped class to a prepared statement. Implementors
-	 * should handle possibility of null values. A multi-column type should be written
-	 * to parameters starting from <tt>index</tt>.
-	 * @param st
-	 * @param value the object to write
-	 * @param index statement parameter index
-	 * @param session
-	 *
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
-	throws HibernateException, SQLException;
-
-	/**
-	 * A representation of the value to be embedded in an XML element.
-	 *
-	 * @param value
-	 * @param factory
-	 * @return String
-	 * @throws HibernateException
-	 */
-	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
-	throws HibernateException;
-
-	/**
-	 * A representation of the value to be embedded in a log file.
-	 *
-	 * @param value
-	 * @param factory
-	 * @return String
-	 * @throws HibernateException
-	 */
-	public String toLoggableString(Object value, SessionFactoryImplementor factory)
-	throws HibernateException;
-
-	/**
-	 * Parse the XML representation of an instance.
-	 * @param xml
-	 * @param factory
-	 *
-	 * @return an instance of the type
-	 * @throws HibernateException
-	 */
-	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException;
-
-	/**
-	 * Returns the abbreviated name of the type.
-	 *
-	 * @return String the Hibernate type name
-	 */
-	public String getName();
-
-	/**
-	 * Return a deep copy of the persistent state, stopping at entities and at
-	 * collections.
-	 * @param value generally a collection element or entity field
-	 * @param entityMode 
-	 * @param factory
-	 * @return Object a copy
-	 */
-	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
-	throws HibernateException;
-
-	/**
-	 * Are objects of this type mutable. (With respect to the referencing object ...
-	 * entities and collections are considered immutable because they manage their
-	 * own internal state.)
-	 *
-	 * @return boolean
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Return a cacheable "disassembled" representation of the object.
-	 * @param value the value to cache
-	 * @param session the session
-	 * @param owner optional parent entity object (needed for collections)
-	 * @return the disassembled, deep cloned state
-	 */
-	public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException;
-
-	/**
-	 * Reconstruct the object from its cached "disassembled" state.
-	 * @param cached the disassembled state from the cache
-	 * @param session the session
-	 * @param owner the parent entity object
-	 * @return the the object
-	 */
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
-	throws HibernateException;
-	
-	/**
-	 * Called before assembling a query result set from the query cache, to allow batch fetching
-	 * of entities missing from the second-level cache.
-	 */
-	public void beforeAssemble(Serializable cached, SessionImplementor session);
-
-	/**
-	 * Retrieve an instance of the mapped class, or the identifier of an entity or collection, 
-	 * from a JDBC resultset. This is useful for 2-phase property initialization - the second 
-	 * phase is a call to <tt>resolveIdentifier()</tt>.
-	 * 
-	 * @see Type#resolve(Object, SessionImplementor, Object)
-	 * @param rs
-	 * @param names the column names
-	 * @param session the session
-	 * @param owner the parent entity
-	 * @return Object an identifier or actual value
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner)
-	throws HibernateException, SQLException;
-
-	/**
-	 * Map identifiers to entities or collections. This is the second phase of 2-phase property 
-	 * initialization.
-	 * 
-	 * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object)
-	 * @param value an identifier or value returned by <tt>hydrate()</tt>
-	 * @param owner the parent entity
-	 * @param session the session
-	 * @return the given value, or the value associated with the identifier
-	 * @throws HibernateException
-	 */
-	public Object resolve(Object value, SessionImplementor session, Object owner)
-	throws HibernateException;
-	
-	/**
-	 * Given a hydrated, but unresolved value, return a value that may be used to
-	 * reconstruct property-ref associations.
-	 */
-	public Object semiResolve(Object value, SessionImplementor session, Object owner)
-	throws HibernateException;
-	
-	/**
-	 * Get the type of a semi-resolved value.
-	 */
-	public Type getSemiResolvedType(SessionFactoryImplementor factory);
-
-	/**
-	 * During merge, replace the existing (target) value in the entity we are merging to
-	 * with a new (original) value from the detached entity we are merging. For immutable
-	 * objects, or null values, it is safe to simply return the first parameter. For
-	 * mutable objects, it is safe to return a copy of the first parameter. For objects
-	 * with component values, it might make sense to recursively replace component values.
-	 *
-	 * @param original the value from the detached entity being merged
-	 * @param target the value in the managed entity
-	 * @return the value to be merged
-	 */
-	public Object replace(
-			Object original, 
-			Object target, 
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache)
-	throws HibernateException;
-	
-	/**
-	 * During merge, replace the existing (target) value in the entity we are merging to
-	 * with a new (original) value from the detached entity we are merging. For immutable
-	 * objects, or null values, it is safe to simply return the first parameter. For
-	 * mutable objects, it is safe to return a copy of the first parameter. For objects
-	 * with component values, it might make sense to recursively replace component values.
-	 *
-	 * @param original the value from the detached entity being merged
-	 * @param target the value in the managed entity
-	 * @return the value to be merged
-	 */
-	public Object replace(
-			Object original, 
-			Object target, 
-			SessionImplementor session, 
-			Object owner, 
-			Map copyCache, 
-			ForeignKeyDirection foreignKeyDirection)
-	throws HibernateException;
-	
-	/**
-	 * Given an instance of the type, return an array of boolean, indicating
-	 * which mapped columns would be null.
-	 * 
-	 * @param value an instance of the type
-	 */
-	public boolean[] toColumnNullness(Object value, Mapping mapping);
-	
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/Type.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/Type.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,450 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+
+import org.dom4j.Node;
+import org.hibernate.EntityMode;
+import org.hibernate.HibernateException;
+import org.hibernate.MappingException;
+import org.hibernate.engine.Mapping;
+import org.hibernate.engine.SessionFactoryImplementor;
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * Defines a mapping from a Java type to an JDBC datatype. This interface is intended to
+ * be implemented by applications that need custom types.<br>
+ * <br>
+ * Implementors should usually be immutable and <b>must</b> certainly be threadsafe.
+ *
+ * @author Gavin King
+ */
+public interface Type extends Serializable {
+
+	/**
+	 * Return true if the implementation is castable to
+	 * <tt>AssociationType</tt>. This does not necessarily imply that
+	 * the type actually represents an association.
+	 * @see AssociationType
+	 * @return boolean
+	 */
+	public boolean isAssociationType();
+	/**
+	 * Is this type a collection type.
+	 */
+	public boolean isCollectionType();
+
+	/**
+	 * Is this type a component type. If so, the implementation
+	 * must be castable to <tt>AbstractComponentType</tt>. A component
+	 * type may own collections or associations and hence must provide
+	 * certain extra functionality.
+	 * @see AbstractComponentType
+	 * @return boolean
+	 */
+	public boolean isComponentType();
+
+	/**
+	 * Is this type an entity type?
+	 * @return boolean
+	 */
+	public boolean isEntityType();
+
+	/**
+	 * Is this an "any" type.
+	 *
+	 * i.e. a reference to a persistent entity
+	 * that is not modelled as a (foreign key) association.
+	 */
+	public boolean isAnyType();
+	
+	public boolean isXMLElement();
+
+	/**
+	 * Return the SQL type codes for the columns mapped by this type. The codes
+	 * are defined on <tt>java.sql.Types</tt>.
+	 * @see java.sql.Types
+	 * @return the typecodes
+	 * @throws MappingException
+	 */
+	public int[] sqlTypes(Mapping mapping) throws MappingException;
+
+	/**
+	 * How many columns are used to persist this type.
+	 */
+	public int getColumnSpan(Mapping mapping) throws MappingException;
+
+	/**
+	 * The class returned by <tt>nullSafeGet()</tt> methods. This is used to 
+	 * establish the class of an array of this type.
+	 *
+	 * @return Class
+	 */
+	public Class getReturnedClass();
+
+	/**
+	 * Compare two instances of the class mapped by this type for persistence
+	 * "equality" - equality of persistent state - taking a shortcut for
+	 * entity references.
+	 * @param x
+	 * @param y
+	 * @param entityMode
+	 *
+	 * @return boolean
+	 * @throws HibernateException
+	 */
+	public boolean isSame(Object x, Object y, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Compare two instances of the class mapped by this type for persistence
+	 * "equality" - equality of persistent state.
+	 * @param x
+	 * @param y
+	 * @param entityMode 
+	 *
+	 * @return boolean
+	 * @throws HibernateException
+	 */
+	public boolean isEqual(Object x, Object y, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Compare two instances of the class mapped by this type for persistence
+	 * "equality" - equality of persistent state.
+	 * @param x
+	 * @param y
+	 * @param entityMode 
+	 *
+	 * @return boolean
+	 * @throws HibernateException
+	 */
+	public boolean isEqual(Object x, Object y, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException;
+
+	/**
+	 * Get a hashcode, consistent with persistence "equality"
+	 * @param x
+	 * @param entityMode 
+	 */
+	public int getHashCode(Object x, EntityMode entityMode) throws HibernateException;
+
+	/**
+	 * Get a hashcode, consistent with persistence "equality"
+	 * @param x
+	 * @param entityMode 
+	 * @param factory
+	 */
+	public int getHashCode(Object x, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException;
+	
+	/**
+	 * compare two instances of the type
+	 * @param entityMode 
+	 */
+	public int compare(Object x, Object y, EntityMode entityMode);
+
+	/**
+	 * Should the parent be considered dirty, given both the old and current field or 
+	 * element value?
+	 * 
+	 * @param old the old value
+	 * @param current the current value
+	 * @param session
+	 * @return true if the field is dirty
+	 */
+	public boolean isDirty(Object old, Object current, SessionImplementor session)
+	throws HibernateException;
+	/**
+	 * Should the parent be considered dirty, given both the old and current field or 
+	 * element value?
+	 * 
+	 * @param old the old value
+	 * @param current the current value
+	 * @param checkable which columns are actually updatable
+	 * @param session
+	 * @return true if the field is dirty
+	 */
+	public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Has the parent object been modified, compared to the current database state?
+	 * @param oldHydratedState the database state, in a "hydrated" form, with identifiers unresolved
+	 * @param currentState the current state of the object
+	 * @param checkable which columns are actually updatable
+	 * @param session
+	 * @return true if the field has been modified
+	 */
+	public boolean isModified(Object oldHydratedState, Object currentState, boolean[] checkable, SessionImplementor session)
+	throws HibernateException;
+
+	/**
+	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
+	 * should handle possibility of null values.
+	 *
+	 * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object) alternative, 2-phase property initialization
+	 * @param rs
+	 * @param names the column names
+	 * @param session
+	 * @param owner the parent entity
+	 * @return Object
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException;
+
+	/**
+	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementations
+	 * should handle possibility of null values. This method might be called if the
+	 * type is known to be a single-column type.
+	 *
+	 * @param rs
+	 * @param name the column name
+	 * @param session
+	 * @param owner the parent entity
+	 * @return Object
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public Object nullSafeGet(ResultSet rs, String name, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException;
+
+	/**
+	 * Write an instance of the mapped class to a prepared statement, ignoring some columns. 
+	 * Implementors should handle possibility of null values. A multi-column type should be 
+	 * written to parameters starting from <tt>index</tt>.
+	 * @param st
+	 * @param value the object to write
+	 * @param index statement parameter index
+	 * @param settable an array indicating which columns to ignore
+	 * @param session
+	 *
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public void nullSafeSet(PreparedStatement st, Object value, int index, boolean[] settable, SessionImplementor session)
+	throws HibernateException, SQLException;
+
+	/**
+	 * Write an instance of the mapped class to a prepared statement. Implementors
+	 * should handle possibility of null values. A multi-column type should be written
+	 * to parameters starting from <tt>index</tt>.
+	 * @param st
+	 * @param value the object to write
+	 * @param index statement parameter index
+	 * @param session
+	 *
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
+	throws HibernateException, SQLException;
+
+	/**
+	 * A representation of the value to be embedded in an XML element.
+	 *
+	 * @param value
+	 * @param factory
+	 * @return String
+	 * @throws HibernateException
+	 */
+	public void setToXMLNode(Node node, Object value, SessionFactoryImplementor factory)
+	throws HibernateException;
+
+	/**
+	 * A representation of the value to be embedded in a log file.
+	 *
+	 * @param value
+	 * @param factory
+	 * @return String
+	 * @throws HibernateException
+	 */
+	public String toLoggableString(Object value, SessionFactoryImplementor factory)
+	throws HibernateException;
+
+	/**
+	 * Parse the XML representation of an instance.
+	 * @param xml
+	 * @param factory
+	 *
+	 * @return an instance of the type
+	 * @throws HibernateException
+	 */
+	public Object fromXMLNode(Node xml, Mapping factory) throws HibernateException;
+
+	/**
+	 * Returns the abbreviated name of the type.
+	 *
+	 * @return String the Hibernate type name
+	 */
+	public String getName();
+
+	/**
+	 * Return a deep copy of the persistent state, stopping at entities and at
+	 * collections.
+	 * @param value generally a collection element or entity field
+	 * @param entityMode 
+	 * @param factory
+	 * @return Object a copy
+	 */
+	public Object deepCopy(Object value, EntityMode entityMode, SessionFactoryImplementor factory) 
+	throws HibernateException;
+
+	/**
+	 * Are objects of this type mutable. (With respect to the referencing object ...
+	 * entities and collections are considered immutable because they manage their
+	 * own internal state.)
+	 *
+	 * @return boolean
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Return a cacheable "disassembled" representation of the object.
+	 * @param value the value to cache
+	 * @param session the session
+	 * @param owner optional parent entity object (needed for collections)
+	 * @return the disassembled, deep cloned state
+	 */
+	public Serializable disassemble(Object value, SessionImplementor session, Object owner) throws HibernateException;
+
+	/**
+	 * Reconstruct the object from its cached "disassembled" state.
+	 * @param cached the disassembled state from the cache
+	 * @param session the session
+	 * @param owner the parent entity object
+	 * @return the the object
+	 */
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner)
+	throws HibernateException;
+	
+	/**
+	 * Called before assembling a query result set from the query cache, to allow batch fetching
+	 * of entities missing from the second-level cache.
+	 */
+	public void beforeAssemble(Serializable cached, SessionImplementor session);
+
+	/**
+	 * Retrieve an instance of the mapped class, or the identifier of an entity or collection, 
+	 * from a JDBC resultset. This is useful for 2-phase property initialization - the second 
+	 * phase is a call to <tt>resolveIdentifier()</tt>.
+	 * 
+	 * @see Type#resolve(Object, SessionImplementor, Object)
+	 * @param rs
+	 * @param names the column names
+	 * @param session the session
+	 * @param owner the parent entity
+	 * @return Object an identifier or actual value
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public Object hydrate(ResultSet rs, String[] names, SessionImplementor session, Object owner)
+	throws HibernateException, SQLException;
+
+	/**
+	 * Map identifiers to entities or collections. This is the second phase of 2-phase property 
+	 * initialization.
+	 * 
+	 * @see Type#hydrate(ResultSet, String[], SessionImplementor, Object)
+	 * @param value an identifier or value returned by <tt>hydrate()</tt>
+	 * @param owner the parent entity
+	 * @param session the session
+	 * @return the given value, or the value associated with the identifier
+	 * @throws HibernateException
+	 */
+	public Object resolve(Object value, SessionImplementor session, Object owner)
+	throws HibernateException;
+	
+	/**
+	 * Given a hydrated, but unresolved value, return a value that may be used to
+	 * reconstruct property-ref associations.
+	 */
+	public Object semiResolve(Object value, SessionImplementor session, Object owner)
+	throws HibernateException;
+	
+	/**
+	 * Get the type of a semi-resolved value.
+	 */
+	public Type getSemiResolvedType(SessionFactoryImplementor factory);
+
+	/**
+	 * During merge, replace the existing (target) value in the entity we are merging to
+	 * with a new (original) value from the detached entity we are merging. For immutable
+	 * objects, or null values, it is safe to simply return the first parameter. For
+	 * mutable objects, it is safe to return a copy of the first parameter. For objects
+	 * with component values, it might make sense to recursively replace component values.
+	 *
+	 * @param original the value from the detached entity being merged
+	 * @param target the value in the managed entity
+	 * @return the value to be merged
+	 */
+	public Object replace(
+			Object original, 
+			Object target, 
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache)
+	throws HibernateException;
+	
+	/**
+	 * During merge, replace the existing (target) value in the entity we are merging to
+	 * with a new (original) value from the detached entity we are merging. For immutable
+	 * objects, or null values, it is safe to simply return the first parameter. For
+	 * mutable objects, it is safe to return a copy of the first parameter. For objects
+	 * with component values, it might make sense to recursively replace component values.
+	 *
+	 * @param original the value from the detached entity being merged
+	 * @param target the value in the managed entity
+	 * @return the value to be merged
+	 */
+	public Object replace(
+			Object original, 
+			Object target, 
+			SessionImplementor session, 
+			Object owner, 
+			Map copyCache, 
+			ForeignKeyDirection foreignKeyDirection)
+	throws HibernateException;
+	
+	/**
+	 * Given an instance of the type, return an array of boolean, indicating
+	 * which mapped columns would be null.
+	 * 
+	 * @param value an instance of the type
+	 */
+	public boolean[] toColumnNullness(Object value, Mapping mapping);
+	
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,665 +0,0 @@
-// $Id: TypeFactory.java 11496 2007-05-09 03:54:06Z steve.ebersole at jboss.com $
-package org.hibernate.type;
-
-import java.io.Serializable;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.sql.Blob;
-import java.sql.Clob;
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.GregorianCalendar;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TimeZone;
-
-import org.hibernate.Hibernate;
-import org.hibernate.MappingException;
-import org.hibernate.classic.Lifecycle;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.intercept.LazyPropertyInitializer;
-import org.hibernate.property.BackrefPropertyAccessor;
-import org.hibernate.tuple.StandardProperty;
-import org.hibernate.usertype.CompositeUserType;
-import org.hibernate.usertype.UserType;
-import org.hibernate.usertype.ParameterizedType;
-import org.hibernate.util.ReflectHelper;
-
-/**
- * Used internally to obtain instances of <tt>Type</tt>. Applications should use static methods
- * and constants on <tt>org.hibernate.Hibernate</tt>.
- *
- * @see org.hibernate.Hibernate
- * @author Gavin King
- */
-public final class TypeFactory {
-
-	private static final Map BASIC_TYPES;
-
-	static {
-		HashMap basics = new HashMap();
-		basics.put( boolean.class.getName(), Hibernate.BOOLEAN );
-		basics.put( long.class.getName(), Hibernate.LONG );
-		basics.put( short.class.getName(), Hibernate.SHORT );
-		basics.put( int.class.getName(), Hibernate.INTEGER );
-		basics.put( byte.class.getName(), Hibernate.BYTE );
-		basics.put( float.class.getName(), Hibernate.FLOAT );
-		basics.put( double.class.getName(), Hibernate.DOUBLE );
-		basics.put( char.class.getName(), Hibernate.CHARACTER );
-		basics.put( Hibernate.CHARACTER.getName(), Hibernate.CHARACTER );
-		basics.put( Hibernate.INTEGER.getName(), Hibernate.INTEGER );
-		basics.put( Hibernate.STRING.getName(), Hibernate.STRING );
-		basics.put( Hibernate.DATE.getName(), Hibernate.DATE );
-		basics.put( Hibernate.TIME.getName(), Hibernate.TIME );
-		basics.put( Hibernate.TIMESTAMP.getName(), Hibernate.TIMESTAMP );
-		basics.put( "dbtimestamp", new DbTimestampType() );
-		basics.put( Hibernate.LOCALE.getName(), Hibernate.LOCALE );
-		basics.put( Hibernate.CALENDAR.getName(), Hibernate.CALENDAR );
-		basics.put( Hibernate.CALENDAR_DATE.getName(), Hibernate.CALENDAR_DATE );
-		basics.put( Hibernate.CURRENCY.getName(), Hibernate.CURRENCY );
-		basics.put( Hibernate.TIMEZONE.getName(), Hibernate.TIMEZONE );
-		basics.put( Hibernate.CLASS.getName(), Hibernate.CLASS );
-		basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE );
-		basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO );
-		basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY );
-		basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT );
-		basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB );
-		basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB );
-		basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL );
-		basics.put( Hibernate.BIG_INTEGER.getName(), Hibernate.BIG_INTEGER );
-		basics.put( Hibernate.SERIALIZABLE.getName(), Hibernate.SERIALIZABLE );
-		basics.put( Hibernate.OBJECT.getName(), Hibernate.OBJECT );
-		basics.put( Boolean.class.getName(), Hibernate.BOOLEAN );
-		basics.put( Long.class.getName(), Hibernate.LONG );
-		basics.put( Short.class.getName(), Hibernate.SHORT );
-		basics.put( Integer.class.getName(), Hibernate.INTEGER );
-		basics.put( Byte.class.getName(), Hibernate.BYTE );
-		basics.put( Float.class.getName(), Hibernate.FLOAT );
-		basics.put( Double.class.getName(), Hibernate.DOUBLE );
-		basics.put( Character.class.getName(), Hibernate.CHARACTER );
-		basics.put( String.class.getName(), Hibernate.STRING );
-		basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP );
-		basics.put( Time.class.getName(), Hibernate.TIME );
-		basics.put( Timestamp.class.getName(), Hibernate.TIMESTAMP );
-		basics.put( java.sql.Date.class.getName(), Hibernate.DATE );
-		basics.put( BigDecimal.class.getName(), Hibernate.BIG_DECIMAL );
-		basics.put( BigInteger.class.getName(), Hibernate.BIG_INTEGER );
-		basics.put( Locale.class.getName(), Hibernate.LOCALE );
-		basics.put( Calendar.class.getName(), Hibernate.CALENDAR );
-		basics.put( GregorianCalendar.class.getName(), Hibernate.CALENDAR );
-		if ( CurrencyType.CURRENCY_CLASS != null ) {
-			basics.put( CurrencyType.CURRENCY_CLASS.getName(), Hibernate.CURRENCY );
-		}
-		basics.put( TimeZone.class.getName(), Hibernate.TIMEZONE );
-		basics.put( Object.class.getName(), Hibernate.OBJECT );
-		basics.put( Class.class.getName(), Hibernate.CLASS );
-		basics.put( byte[].class.getName(), Hibernate.BINARY );
-		basics.put( "byte[]", Hibernate.BINARY );
-		basics.put( Byte[].class.getName(), Hibernate.WRAPPER_BINARY );
-		basics.put( "Byte[]", Hibernate.WRAPPER_BINARY );
-		basics.put( char[].class.getName(), Hibernate.CHAR_ARRAY );
-		basics.put( "char[]", Hibernate.CHAR_ARRAY );
-		basics.put( Character[].class.getName(), Hibernate.CHARACTER_ARRAY );
-		basics.put( "Character[]", Hibernate.CHARACTER_ARRAY );
-		basics.put( Blob.class.getName(), Hibernate.BLOB );
-		basics.put( Clob.class.getName(), Hibernate.CLOB );
-		basics.put( Serializable.class.getName(), Hibernate.SERIALIZABLE );
-
-		Type type = new AdaptedImmutableType(Hibernate.DATE);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.TIME);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.TIMESTAMP);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType( new DbTimestampType() );
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.CALENDAR);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.CALENDAR_DATE);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.SERIALIZABLE);
-		basics.put( type.getName(), type );
-		type = new AdaptedImmutableType(Hibernate.BINARY);
-		basics.put( type.getName(), type );
-
-		BASIC_TYPES = Collections.unmodifiableMap( basics );
-	}
-
-	private TypeFactory() {
-		throw new UnsupportedOperationException();
-	}
-
-	/**
-	 * A one-to-one association type for the given class
-	 */
-	public static EntityType oneToOne(
-			String persistentClass,
-			ForeignKeyDirection foreignKeyType,
-			String uniqueKeyPropertyName,
-			boolean lazy,
-			boolean unwrapProxy,
-			boolean isEmbeddedInXML,
-			String entityName,
-			String propertyName
-	) {
-		return new OneToOneType(
-				persistentClass,
-				foreignKeyType,
-				uniqueKeyPropertyName,
-				lazy,
-				unwrapProxy,
-				isEmbeddedInXML,
-				entityName,
-				propertyName
-			);
-	}
-
-	/**
-	 * A many-to-one association type for the given class
-	 */
-	public static EntityType manyToOne(String persistentClass) {
-		return new ManyToOneType( persistentClass );
-	}
-
-	/**
-	 * A many-to-one association type for the given class
-	 */
-	public static EntityType manyToOne(String persistentClass, boolean lazy) {
-		return new ManyToOneType( persistentClass, lazy );
-	}
-
-	/**
-	 * A many-to-one association type for the given class
-	 */
-	public static EntityType manyToOne(
-			String persistentClass,
-			String uniqueKeyPropertyName,
-			boolean lazy,
-			boolean unwrapProxy,
-			boolean isEmbeddedInXML,
-			boolean ignoreNotFound
-	) {
-		return new ManyToOneType(
-				persistentClass,
-				uniqueKeyPropertyName,
-				lazy,
-				unwrapProxy,
-				isEmbeddedInXML,
-				ignoreNotFound
-			);
-	}
-
-	/**
-	 * Given the name of a Hibernate basic type, return an instance of
-	 * <tt>org.hibernate.type.Type</tt>.
-	 */
-	public static Type basic(String name) {
-		return (Type) BASIC_TYPES.get( name );
-	}
-
-	/**
-	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
-	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
-	 */
-	public static Type heuristicType(String typeName) throws MappingException {
-		return heuristicType( typeName, null );
-	}
-
-	/**
-	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
-	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
-	 */
-	public static Type heuristicType(String typeName, Properties parameters)
-			throws MappingException {
-		Type type = TypeFactory.basic( typeName );
-		if ( type == null ) {
-			Class typeClass;
-			try {
-				typeClass = ReflectHelper.classForName( typeName );
-			}
-			catch (ClassNotFoundException cnfe) {
-				typeClass = null;
-			}
-			if ( typeClass != null ) {
-				if ( Type.class.isAssignableFrom( typeClass ) ) {
-					try {
-						type = (Type) typeClass.newInstance();
-					}
-					catch (Exception e) {
-						throw new MappingException(
-								"Could not instantiate Type: " + typeClass.getName(),
-								e
-							);
-					}
-					injectParameters(type, parameters);
-				}
-				else if ( CompositeUserType.class.isAssignableFrom( typeClass ) ) {
-					type = new CompositeCustomType( typeClass, parameters );
-				}
-				else if ( UserType.class.isAssignableFrom( typeClass ) ) {
-					type = new CustomType( typeClass, parameters );
-				}
-				else if ( Lifecycle.class.isAssignableFrom( typeClass ) ) {
-					type = Hibernate.entity( typeClass );
-				}
-				else if ( Serializable.class.isAssignableFrom( typeClass ) ) {
-					type = Hibernate.serializable( typeClass );
-				}
-			}
-		}
-		return type;
-
-	}
-
-	/**
-	 * The legacy contract.
-	 *
-	 * @deprecated Use {@link #customCollection(String, java.util.Properties, String, String, boolean)} instead
-	 */
-	public static CollectionType customCollection(
-			String typeName,
-			String role,
-			String propertyRef,
-			boolean embedded) {
-		return customCollection( typeName, null, role, propertyRef, embedded );
-	}
-
-	public static CollectionType customCollection(
-			String typeName,
-			Properties typeParameters,
-			String role,
-			String propertyRef,
-			boolean embedded) {
-		Class typeClass;
-		try {
-			typeClass = ReflectHelper.classForName( typeName );
-		}
-		catch ( ClassNotFoundException cnfe ) {
-			throw new MappingException( "user collection type class not found: " + typeName, cnfe );
-		}
-		CustomCollectionType result = new CustomCollectionType( typeClass, role, propertyRef, embedded );
-		if ( typeParameters != null ) {
-			TypeFactory.injectParameters( result.getUserType(), typeParameters );
-		}
-		return result;
-	}
-
-	// Collection Types:
-
-	public static CollectionType array(String role, String propertyRef, boolean embedded,
-			Class elementClass) {
-		return new ArrayType( role, propertyRef, elementClass, embedded );
-	}
-
-	public static CollectionType list(String role, String propertyRef, boolean embedded) {
-		return new ListType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType bag(String role, String propertyRef, boolean embedded) {
-		return new BagType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType idbag(String role, String propertyRef, boolean embedded) {
-		return new IdentifierBagType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType map(String role, String propertyRef, boolean embedded) {
-		return new MapType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType orderedMap(String role, String propertyRef, boolean embedded) {
-		return new OrderedMapType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType set(String role, String propertyRef, boolean embedded) {
-		return new SetType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType orderedSet(String role, String propertyRef, boolean embedded) {
-		return new OrderedSetType( role, propertyRef, embedded );
-	}
-
-	public static CollectionType sortedMap(String role, String propertyRef, boolean embedded,
-			Comparator comparator) {
-		return new SortedMapType( role, propertyRef, comparator, embedded );
-	}
-
-	public static CollectionType sortedSet(String role, String propertyRef, boolean embedded,
-			Comparator comparator) {
-		return new SortedSetType( role, propertyRef, comparator, embedded );
-	}
-
-	public static void injectParameters(Object type, Properties parameters) {
-		if (type instanceof ParameterizedType) {
-			( (ParameterizedType) type ).setParameterValues(parameters);
-		}
-		else if ( parameters!=null && !parameters.isEmpty() ) {
-			throw new MappingException(
-					"type is not parameterized: " +
-					type.getClass().getName()
-				);
-		}
-	}
-
-
-	// convenience methods relating to operations across arrays of types...
-
-	/**
-	 * Deep copy a series of values from one array to another...
-	 *
-	 * @param values The values to copy (the source)
-	 * @param types The value types
-	 * @param copy an array indicating which values to include in the copy
-	 * @param target The array into which to copy the values
-	 * @param session The orginating session
-	 */
-	public static void deepCopy(
-			final Object[] values,
-			final Type[] types,
-			final boolean[] copy,
-			final Object[] target,
-			final SessionImplementor session) {
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( copy[i] ) {
-				if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
-					|| values[i] == BackrefPropertyAccessor.UNKNOWN ) {
-					target[i] = values[i];
-				}
-				else {
-					target[i] = types[i].deepCopy( values[i], session.getEntityMode(), session
-						.getFactory() );
-				}
-			}
-		}
-	}
-
-	/**
-	 * Apply the {@link Type#beforeAssemble} operation across a series of values.
-	 *
-	 * @param row The values
-	 * @param types The value types
-	 * @param session The orginating session
-	 */
-	public static void beforeAssemble(
-			final Serializable[] row,
-			final Type[] types,
-			final SessionImplementor session) {
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( row[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
-				&& row[i] != BackrefPropertyAccessor.UNKNOWN ) {
-				types[i].beforeAssemble( row[i], session );
-			}
-		}
-	}
-
-	/**
-	 * Apply the {@link Type#assemble} operation across a series of values.
-	 *
-	 * @param row The values
-	 * @param types The value types
-	 * @param session The orginating session
-	 * @param owner The entity "owning" the values
-	 * @return The assembled state
-	 */
-	public static Object[] assemble(
-			final Serializable[] row,
-			final Type[] types,
-			final SessionImplementor session,
-			final Object owner) {
-		Object[] assembled = new Object[row.length];
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
-				assembled[i] = row[i];
-			}
-			else {
-				assembled[i] = types[i].assemble( row[i], session, owner );
-			}
-		}
-		return assembled;
-	}
-
-	/**
-	 * Apply the {@link Type#disassemble} operation across a series of values.
-	 *
-	 * @param row The values
-	 * @param types The value types
-	 * @param nonCacheable An array indicating which values to include in the disassemled state
-	 * @param session The orginating session
-	 * @param owner The entity "owning" the values
-	 * @return The disassembled state
-	 */
-	public static Serializable[] disassemble(
-			final Object[] row,
-			final Type[] types,
-			final boolean[] nonCacheable,
-			final SessionImplementor session,
-			final Object owner) {
-		Serializable[] disassembled = new Serializable[row.length];
-		for ( int i = 0; i < row.length; i++ ) {
-			if ( nonCacheable!=null && nonCacheable[i] ) {
-				disassembled[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
-			}
-			else if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
-				disassembled[i] = (Serializable) row[i];
-			}
-			else {
-				disassembled[i] = types[i].disassemble( row[i], session, owner );
-			}
-		}
-		return disassembled;
-	}
-
-	/**
-	 * Apply the {@link Type#replace} operation across a series of values.
-	 *
-	 * @param original The source of the state
-	 * @param target The target into which to replace the source values.
-	 * @param types The value types
-	 * @param session The orginating session
-	 * @param owner The entity "owning" the values
-	 * @param copyCache A map representing a cache of already replaced state
-	 * @return The replaced state
-	 */
-	public static Object[] replace(
-			final Object[] original,
-			final Object[] target,
-			final Type[] types,
-			final SessionImplementor session,
-			final Object owner,
-			final Map copyCache) {
-		Object[] copied = new Object[original.length];
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
-				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
-				copied[i] = target[i];
-			}
-			else {
-				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache );
-			}
-		}
-		return copied;
-	}
-
-	/**
-	 * Apply the {@link Type#replace} operation across a series of values.
-	 *
-	 * @param original The source of the state
-	 * @param target The target into which to replace the source values.
-	 * @param types The value types
-	 * @param session The orginating session
-	 * @param owner The entity "owning" the values
-	 * @param copyCache A map representing a cache of already replaced state
-	 * @param foreignKeyDirection FK directionality to be applied to the replacement
-	 * @return The replaced state
-	 */
-	public static Object[] replace(
-			final Object[] original,
-			final Object[] target,
-			final Type[] types,
-			final SessionImplementor session,
-			final Object owner,
-			final Map copyCache,
-			final ForeignKeyDirection foreignKeyDirection) {
-		Object[] copied = new Object[original.length];
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
-				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
-				copied[i] = target[i];
-			}
-			else {
-				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
-			}
-		}
-		return copied;
-	}
-
-	/**
-	 * Apply the {@link Type#replace} operation across a series of values, as
-	 * long as the corresponding {@link Type} is an association.
-	 * <p/>
-	 * If the corresponding type is a component type, then apply {@link #replaceAssociations}
-	 * accross the component subtypes but do not replace the component value itself.
-	 *
-	 * @param original The source of the state
-	 * @param target The target into which to replace the source values.
-	 * @param types The value types
-	 * @param session The orginating session
-	 * @param owner The entity "owning" the values
-	 * @param copyCache A map representing a cache of already replaced state
-	 * @param foreignKeyDirection FK directionality to be applied to the replacement
-	 * @return The replaced state
-	 */
-	public static Object[] replaceAssociations(
-			final Object[] original,
-			final Object[] target,
-			final Type[] types,
-			final SessionImplementor session,
-			final Object owner,
-			final Map copyCache,
-			final ForeignKeyDirection foreignKeyDirection) {
-		Object[] copied = new Object[original.length];
-		for ( int i = 0; i < types.length; i++ ) {
-			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
-					|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
-				copied[i] = target[i];
-			}
-			else if ( types[i].isComponentType() ) {
-				// need to extract the component values and check for subtype replacements...
-				AbstractComponentType componentType = ( AbstractComponentType ) types[i];
-				Type[] subtypes = componentType.getSubtypes();
-				Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session );
-				Object[] targetComponentValues = target[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( target[i], session );
-				replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection );
-				copied[i] = target[i];
-			}
-			else if ( !types[i].isAssociationType() ) {
-				copied[i] = target[i];
-			}
-			else {
-				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
-			}
-		}
-		return copied;
-	}
-
-	/**
-	 * Determine if any of the given field values are dirty, returning an array containing
-	 * indices of the dirty fields.
-	 * <p/>
-	 * If it is determined that no fields are dirty, null is returned.
-	 *
-	 * @param properties The property definitions
-	 * @param currentState The current state of the entity
-	 * @param previousState The baseline state of the entity
-	 * @param includeColumns Columns to be included in the dirty checking, per property
-	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
-	 * @param session The session from which the dirty check request originated.
-	 * @return Array containing indices of the dirty properties, or null if no properties considered dirty.
-	 */
-	public static int[] findDirty(
-			final StandardProperty[] properties,
-			final Object[] currentState,
-			final Object[] previousState,
-			final boolean[][] includeColumns,
-			final boolean anyUninitializedProperties,
-			final SessionImplementor session) {
-		int[] results = null;
-		int count = 0;
-		int span = properties.length;
-
-		for ( int i = 0; i < span; i++ ) {
-			final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
-					&& properties[i].isDirtyCheckable( anyUninitializedProperties )
-					&& properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session );
-			if ( dirty ) {
-				if ( results == null ) {
-					results = new int[span];
-				}
-				results[count++] = i;
-			}
-		}
-
-		if ( count == 0 ) {
-			return null;
-		}
-		else {
-			int[] trimmed = new int[count];
-			System.arraycopy( results, 0, trimmed, 0, count );
-			return trimmed;
-		}
-	}
-
-	/**
-	 * Determine if any of the given field values are modified, returning an array containing
-	 * indices of the modified fields.
-	 * <p/>
-	 * If it is determined that no fields are dirty, null is returned.
-	 *
-	 * @param properties The property definitions
-	 * @param currentState The current state of the entity
-	 * @param previousState The baseline state of the entity
-	 * @param includeColumns Columns to be included in the mod checking, per property
-	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
-	 * @param session The session from which the dirty check request originated.
-	 * @return Array containing indices of the modified properties, or null if no properties considered modified.
-	 */
-	public static int[] findModified(
-			final StandardProperty[] properties, 
-			final Object[] currentState,
-			final Object[] previousState,
-			final boolean[][] includeColumns,
-			final boolean anyUninitializedProperties,
-			final SessionImplementor session) {
-		int[] results = null;
-		int count = 0;
-		int span = properties.length;
-
-		for ( int i = 0; i < span; i++ ) {
-			final boolean modified = currentState[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY
-					&& properties[i].isDirtyCheckable(anyUninitializedProperties)
-					&& properties[i].getType().isModified( previousState[i], currentState[i], includeColumns[i], session );
-
-			if ( modified ) {
-				if ( results == null ) {
-					results = new int[span];
-				}
-				results[count++] = i;
-			}
-		}
-
-		if ( count == 0 ) {
-			return null;
-		}
-		else {
-			int[] trimmed = new int[count];
-			System.arraycopy( results, 0, trimmed, 0, count );
-			return trimmed;
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/TypeFactory.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/TypeFactory.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,688 @@
+/*
+ * 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.type;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TimeZone;
+
+import org.hibernate.Hibernate;
+import org.hibernate.MappingException;
+import org.hibernate.classic.Lifecycle;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.intercept.LazyPropertyInitializer;
+import org.hibernate.property.BackrefPropertyAccessor;
+import org.hibernate.tuple.StandardProperty;
+import org.hibernate.usertype.CompositeUserType;
+import org.hibernate.usertype.UserType;
+import org.hibernate.usertype.ParameterizedType;
+import org.hibernate.util.ReflectHelper;
+
+/**
+ * Used internally to obtain instances of <tt>Type</tt>. Applications should use static methods
+ * and constants on <tt>org.hibernate.Hibernate</tt>.
+ *
+ * @see org.hibernate.Hibernate
+ * @author Gavin King
+ */
+public final class TypeFactory {
+
+	private static final Map BASIC_TYPES;
+
+	static {
+		HashMap basics = new HashMap();
+		basics.put( boolean.class.getName(), Hibernate.BOOLEAN );
+		basics.put( long.class.getName(), Hibernate.LONG );
+		basics.put( short.class.getName(), Hibernate.SHORT );
+		basics.put( int.class.getName(), Hibernate.INTEGER );
+		basics.put( byte.class.getName(), Hibernate.BYTE );
+		basics.put( float.class.getName(), Hibernate.FLOAT );
+		basics.put( double.class.getName(), Hibernate.DOUBLE );
+		basics.put( char.class.getName(), Hibernate.CHARACTER );
+		basics.put( Hibernate.CHARACTER.getName(), Hibernate.CHARACTER );
+		basics.put( Hibernate.INTEGER.getName(), Hibernate.INTEGER );
+		basics.put( Hibernate.STRING.getName(), Hibernate.STRING );
+		basics.put( Hibernate.DATE.getName(), Hibernate.DATE );
+		basics.put( Hibernate.TIME.getName(), Hibernate.TIME );
+		basics.put( Hibernate.TIMESTAMP.getName(), Hibernate.TIMESTAMP );
+		basics.put( "dbtimestamp", new DbTimestampType() );
+		basics.put( Hibernate.LOCALE.getName(), Hibernate.LOCALE );
+		basics.put( Hibernate.CALENDAR.getName(), Hibernate.CALENDAR );
+		basics.put( Hibernate.CALENDAR_DATE.getName(), Hibernate.CALENDAR_DATE );
+		basics.put( Hibernate.CURRENCY.getName(), Hibernate.CURRENCY );
+		basics.put( Hibernate.TIMEZONE.getName(), Hibernate.TIMEZONE );
+		basics.put( Hibernate.CLASS.getName(), Hibernate.CLASS );
+		basics.put( Hibernate.TRUE_FALSE.getName(), Hibernate.TRUE_FALSE );
+		basics.put( Hibernate.YES_NO.getName(), Hibernate.YES_NO );
+		basics.put( Hibernate.BINARY.getName(), Hibernate.BINARY );
+		basics.put( Hibernate.TEXT.getName(), Hibernate.TEXT );
+		basics.put( Hibernate.BLOB.getName(), Hibernate.BLOB );
+		basics.put( Hibernate.CLOB.getName(), Hibernate.CLOB );
+		basics.put( Hibernate.BIG_DECIMAL.getName(), Hibernate.BIG_DECIMAL );
+		basics.put( Hibernate.BIG_INTEGER.getName(), Hibernate.BIG_INTEGER );
+		basics.put( Hibernate.SERIALIZABLE.getName(), Hibernate.SERIALIZABLE );
+		basics.put( Hibernate.OBJECT.getName(), Hibernate.OBJECT );
+		basics.put( Boolean.class.getName(), Hibernate.BOOLEAN );
+		basics.put( Long.class.getName(), Hibernate.LONG );
+		basics.put( Short.class.getName(), Hibernate.SHORT );
+		basics.put( Integer.class.getName(), Hibernate.INTEGER );
+		basics.put( Byte.class.getName(), Hibernate.BYTE );
+		basics.put( Float.class.getName(), Hibernate.FLOAT );
+		basics.put( Double.class.getName(), Hibernate.DOUBLE );
+		basics.put( Character.class.getName(), Hibernate.CHARACTER );
+		basics.put( String.class.getName(), Hibernate.STRING );
+		basics.put( java.util.Date.class.getName(), Hibernate.TIMESTAMP );
+		basics.put( Time.class.getName(), Hibernate.TIME );
+		basics.put( Timestamp.class.getName(), Hibernate.TIMESTAMP );
+		basics.put( java.sql.Date.class.getName(), Hibernate.DATE );
+		basics.put( BigDecimal.class.getName(), Hibernate.BIG_DECIMAL );
+		basics.put( BigInteger.class.getName(), Hibernate.BIG_INTEGER );
+		basics.put( Locale.class.getName(), Hibernate.LOCALE );
+		basics.put( Calendar.class.getName(), Hibernate.CALENDAR );
+		basics.put( GregorianCalendar.class.getName(), Hibernate.CALENDAR );
+		if ( CurrencyType.CURRENCY_CLASS != null ) {
+			basics.put( CurrencyType.CURRENCY_CLASS.getName(), Hibernate.CURRENCY );
+		}
+		basics.put( TimeZone.class.getName(), Hibernate.TIMEZONE );
+		basics.put( Object.class.getName(), Hibernate.OBJECT );
+		basics.put( Class.class.getName(), Hibernate.CLASS );
+		basics.put( byte[].class.getName(), Hibernate.BINARY );
+		basics.put( "byte[]", Hibernate.BINARY );
+		basics.put( Byte[].class.getName(), Hibernate.WRAPPER_BINARY );
+		basics.put( "Byte[]", Hibernate.WRAPPER_BINARY );
+		basics.put( char[].class.getName(), Hibernate.CHAR_ARRAY );
+		basics.put( "char[]", Hibernate.CHAR_ARRAY );
+		basics.put( Character[].class.getName(), Hibernate.CHARACTER_ARRAY );
+		basics.put( "Character[]", Hibernate.CHARACTER_ARRAY );
+		basics.put( Blob.class.getName(), Hibernate.BLOB );
+		basics.put( Clob.class.getName(), Hibernate.CLOB );
+		basics.put( Serializable.class.getName(), Hibernate.SERIALIZABLE );
+
+		Type type = new AdaptedImmutableType(Hibernate.DATE);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.TIME);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.TIMESTAMP);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType( new DbTimestampType() );
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.CALENDAR);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.CALENDAR_DATE);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.SERIALIZABLE);
+		basics.put( type.getName(), type );
+		type = new AdaptedImmutableType(Hibernate.BINARY);
+		basics.put( type.getName(), type );
+
+		BASIC_TYPES = Collections.unmodifiableMap( basics );
+	}
+
+	private TypeFactory() {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * A one-to-one association type for the given class
+	 */
+	public static EntityType oneToOne(
+			String persistentClass,
+			ForeignKeyDirection foreignKeyType,
+			String uniqueKeyPropertyName,
+			boolean lazy,
+			boolean unwrapProxy,
+			boolean isEmbeddedInXML,
+			String entityName,
+			String propertyName
+	) {
+		return new OneToOneType(
+				persistentClass,
+				foreignKeyType,
+				uniqueKeyPropertyName,
+				lazy,
+				unwrapProxy,
+				isEmbeddedInXML,
+				entityName,
+				propertyName
+			);
+	}
+
+	/**
+	 * A many-to-one association type for the given class
+	 */
+	public static EntityType manyToOne(String persistentClass) {
+		return new ManyToOneType( persistentClass );
+	}
+
+	/**
+	 * A many-to-one association type for the given class
+	 */
+	public static EntityType manyToOne(String persistentClass, boolean lazy) {
+		return new ManyToOneType( persistentClass, lazy );
+	}
+
+	/**
+	 * A many-to-one association type for the given class
+	 */
+	public static EntityType manyToOne(
+			String persistentClass,
+			String uniqueKeyPropertyName,
+			boolean lazy,
+			boolean unwrapProxy,
+			boolean isEmbeddedInXML,
+			boolean ignoreNotFound
+	) {
+		return new ManyToOneType(
+				persistentClass,
+				uniqueKeyPropertyName,
+				lazy,
+				unwrapProxy,
+				isEmbeddedInXML,
+				ignoreNotFound
+			);
+	}
+
+	/**
+	 * Given the name of a Hibernate basic type, return an instance of
+	 * <tt>org.hibernate.type.Type</tt>.
+	 */
+	public static Type basic(String name) {
+		return (Type) BASIC_TYPES.get( name );
+	}
+
+	/**
+	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
+	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
+	 */
+	public static Type heuristicType(String typeName) throws MappingException {
+		return heuristicType( typeName, null );
+	}
+
+	/**
+	 * Uses heuristics to deduce a Hibernate type given a string naming the type or Java class.
+	 * Return an instance of <tt>org.hibernate.type.Type</tt>.
+	 */
+	public static Type heuristicType(String typeName, Properties parameters)
+			throws MappingException {
+		Type type = TypeFactory.basic( typeName );
+		if ( type == null ) {
+			Class typeClass;
+			try {
+				typeClass = ReflectHelper.classForName( typeName );
+			}
+			catch (ClassNotFoundException cnfe) {
+				typeClass = null;
+			}
+			if ( typeClass != null ) {
+				if ( Type.class.isAssignableFrom( typeClass ) ) {
+					try {
+						type = (Type) typeClass.newInstance();
+					}
+					catch (Exception e) {
+						throw new MappingException(
+								"Could not instantiate Type: " + typeClass.getName(),
+								e
+							);
+					}
+					injectParameters(type, parameters);
+				}
+				else if ( CompositeUserType.class.isAssignableFrom( typeClass ) ) {
+					type = new CompositeCustomType( typeClass, parameters );
+				}
+				else if ( UserType.class.isAssignableFrom( typeClass ) ) {
+					type = new CustomType( typeClass, parameters );
+				}
+				else if ( Lifecycle.class.isAssignableFrom( typeClass ) ) {
+					type = Hibernate.entity( typeClass );
+				}
+				else if ( Serializable.class.isAssignableFrom( typeClass ) ) {
+					type = Hibernate.serializable( typeClass );
+				}
+			}
+		}
+		return type;
+
+	}
+
+	/**
+	 * The legacy contract.
+	 *
+	 * @deprecated Use {@link #customCollection(String, java.util.Properties, String, String, boolean)} instead
+	 */
+	public static CollectionType customCollection(
+			String typeName,
+			String role,
+			String propertyRef,
+			boolean embedded) {
+		return customCollection( typeName, null, role, propertyRef, embedded );
+	}
+
+	public static CollectionType customCollection(
+			String typeName,
+			Properties typeParameters,
+			String role,
+			String propertyRef,
+			boolean embedded) {
+		Class typeClass;
+		try {
+			typeClass = ReflectHelper.classForName( typeName );
+		}
+		catch ( ClassNotFoundException cnfe ) {
+			throw new MappingException( "user collection type class not found: " + typeName, cnfe );
+		}
+		CustomCollectionType result = new CustomCollectionType( typeClass, role, propertyRef, embedded );
+		if ( typeParameters != null ) {
+			TypeFactory.injectParameters( result.getUserType(), typeParameters );
+		}
+		return result;
+	}
+
+	// Collection Types:
+
+	public static CollectionType array(String role, String propertyRef, boolean embedded,
+			Class elementClass) {
+		return new ArrayType( role, propertyRef, elementClass, embedded );
+	}
+
+	public static CollectionType list(String role, String propertyRef, boolean embedded) {
+		return new ListType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType bag(String role, String propertyRef, boolean embedded) {
+		return new BagType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType idbag(String role, String propertyRef, boolean embedded) {
+		return new IdentifierBagType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType map(String role, String propertyRef, boolean embedded) {
+		return new MapType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType orderedMap(String role, String propertyRef, boolean embedded) {
+		return new OrderedMapType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType set(String role, String propertyRef, boolean embedded) {
+		return new SetType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType orderedSet(String role, String propertyRef, boolean embedded) {
+		return new OrderedSetType( role, propertyRef, embedded );
+	}
+
+	public static CollectionType sortedMap(String role, String propertyRef, boolean embedded,
+			Comparator comparator) {
+		return new SortedMapType( role, propertyRef, comparator, embedded );
+	}
+
+	public static CollectionType sortedSet(String role, String propertyRef, boolean embedded,
+			Comparator comparator) {
+		return new SortedSetType( role, propertyRef, comparator, embedded );
+	}
+
+	public static void injectParameters(Object type, Properties parameters) {
+		if (type instanceof ParameterizedType) {
+			( (ParameterizedType) type ).setParameterValues(parameters);
+		}
+		else if ( parameters!=null && !parameters.isEmpty() ) {
+			throw new MappingException(
+					"type is not parameterized: " +
+					type.getClass().getName()
+				);
+		}
+	}
+
+
+	// convenience methods relating to operations across arrays of types...
+
+	/**
+	 * Deep copy a series of values from one array to another...
+	 *
+	 * @param values The values to copy (the source)
+	 * @param types The value types
+	 * @param copy an array indicating which values to include in the copy
+	 * @param target The array into which to copy the values
+	 * @param session The orginating session
+	 */
+	public static void deepCopy(
+			final Object[] values,
+			final Type[] types,
+			final boolean[] copy,
+			final Object[] target,
+			final SessionImplementor session) {
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( copy[i] ) {
+				if ( values[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+					|| values[i] == BackrefPropertyAccessor.UNKNOWN ) {
+					target[i] = values[i];
+				}
+				else {
+					target[i] = types[i].deepCopy( values[i], session.getEntityMode(), session
+						.getFactory() );
+				}
+			}
+		}
+	}
+
+	/**
+	 * Apply the {@link Type#beforeAssemble} operation across a series of values.
+	 *
+	 * @param row The values
+	 * @param types The value types
+	 * @param session The orginating session
+	 */
+	public static void beforeAssemble(
+			final Serializable[] row,
+			final Type[] types,
+			final SessionImplementor session) {
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( row[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
+				&& row[i] != BackrefPropertyAccessor.UNKNOWN ) {
+				types[i].beforeAssemble( row[i], session );
+			}
+		}
+	}
+
+	/**
+	 * Apply the {@link Type#assemble} operation across a series of values.
+	 *
+	 * @param row The values
+	 * @param types The value types
+	 * @param session The orginating session
+	 * @param owner The entity "owning" the values
+	 * @return The assembled state
+	 */
+	public static Object[] assemble(
+			final Serializable[] row,
+			final Type[] types,
+			final SessionImplementor session,
+			final Object owner) {
+		Object[] assembled = new Object[row.length];
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
+				assembled[i] = row[i];
+			}
+			else {
+				assembled[i] = types[i].assemble( row[i], session, owner );
+			}
+		}
+		return assembled;
+	}
+
+	/**
+	 * Apply the {@link Type#disassemble} operation across a series of values.
+	 *
+	 * @param row The values
+	 * @param types The value types
+	 * @param nonCacheable An array indicating which values to include in the disassemled state
+	 * @param session The orginating session
+	 * @param owner The entity "owning" the values
+	 * @return The disassembled state
+	 */
+	public static Serializable[] disassemble(
+			final Object[] row,
+			final Type[] types,
+			final boolean[] nonCacheable,
+			final SessionImplementor session,
+			final Object owner) {
+		Serializable[] disassembled = new Serializable[row.length];
+		for ( int i = 0; i < row.length; i++ ) {
+			if ( nonCacheable!=null && nonCacheable[i] ) {
+				disassembled[i] = LazyPropertyInitializer.UNFETCHED_PROPERTY;
+			}
+			else if ( row[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY || row[i] == BackrefPropertyAccessor.UNKNOWN ) {
+				disassembled[i] = (Serializable) row[i];
+			}
+			else {
+				disassembled[i] = types[i].disassemble( row[i], session, owner );
+			}
+		}
+		return disassembled;
+	}
+
+	/**
+	 * Apply the {@link Type#replace} operation across a series of values.
+	 *
+	 * @param original The source of the state
+	 * @param target The target into which to replace the source values.
+	 * @param types The value types
+	 * @param session The orginating session
+	 * @param owner The entity "owning" the values
+	 * @param copyCache A map representing a cache of already replaced state
+	 * @return The replaced state
+	 */
+	public static Object[] replace(
+			final Object[] original,
+			final Object[] target,
+			final Type[] types,
+			final SessionImplementor session,
+			final Object owner,
+			final Map copyCache) {
+		Object[] copied = new Object[original.length];
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
+				copied[i] = target[i];
+			}
+			else {
+				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache );
+			}
+		}
+		return copied;
+	}
+
+	/**
+	 * Apply the {@link Type#replace} operation across a series of values.
+	 *
+	 * @param original The source of the state
+	 * @param target The target into which to replace the source values.
+	 * @param types The value types
+	 * @param session The orginating session
+	 * @param owner The entity "owning" the values
+	 * @param copyCache A map representing a cache of already replaced state
+	 * @param foreignKeyDirection FK directionality to be applied to the replacement
+	 * @return The replaced state
+	 */
+	public static Object[] replace(
+			final Object[] original,
+			final Object[] target,
+			final Type[] types,
+			final SessionImplementor session,
+			final Object owner,
+			final Map copyCache,
+			final ForeignKeyDirection foreignKeyDirection) {
+		Object[] copied = new Object[original.length];
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+				|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
+				copied[i] = target[i];
+			}
+			else {
+				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
+			}
+		}
+		return copied;
+	}
+
+	/**
+	 * Apply the {@link Type#replace} operation across a series of values, as
+	 * long as the corresponding {@link Type} is an association.
+	 * <p/>
+	 * If the corresponding type is a component type, then apply {@link #replaceAssociations}
+	 * accross the component subtypes but do not replace the component value itself.
+	 *
+	 * @param original The source of the state
+	 * @param target The target into which to replace the source values.
+	 * @param types The value types
+	 * @param session The orginating session
+	 * @param owner The entity "owning" the values
+	 * @param copyCache A map representing a cache of already replaced state
+	 * @param foreignKeyDirection FK directionality to be applied to the replacement
+	 * @return The replaced state
+	 */
+	public static Object[] replaceAssociations(
+			final Object[] original,
+			final Object[] target,
+			final Type[] types,
+			final SessionImplementor session,
+			final Object owner,
+			final Map copyCache,
+			final ForeignKeyDirection foreignKeyDirection) {
+		Object[] copied = new Object[original.length];
+		for ( int i = 0; i < types.length; i++ ) {
+			if ( original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
+					|| original[i] == BackrefPropertyAccessor.UNKNOWN ) {
+				copied[i] = target[i];
+			}
+			else if ( types[i].isComponentType() ) {
+				// need to extract the component values and check for subtype replacements...
+				AbstractComponentType componentType = ( AbstractComponentType ) types[i];
+				Type[] subtypes = componentType.getSubtypes();
+				Object[] origComponentValues = original[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( original[i], session );
+				Object[] targetComponentValues = target[i] == null ? new Object[subtypes.length] : componentType.getPropertyValues( target[i], session );
+				replaceAssociations( origComponentValues, targetComponentValues, subtypes, session, null, copyCache, foreignKeyDirection );
+				copied[i] = target[i];
+			}
+			else if ( !types[i].isAssociationType() ) {
+				copied[i] = target[i];
+			}
+			else {
+				copied[i] = types[i].replace( original[i], target[i], session, owner, copyCache, foreignKeyDirection );
+			}
+		}
+		return copied;
+	}
+
+	/**
+	 * Determine if any of the given field values are dirty, returning an array containing
+	 * indices of the dirty fields.
+	 * <p/>
+	 * If it is determined that no fields are dirty, null is returned.
+	 *
+	 * @param properties The property definitions
+	 * @param currentState The current state of the entity
+	 * @param previousState The baseline state of the entity
+	 * @param includeColumns Columns to be included in the dirty checking, per property
+	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
+	 * @param session The session from which the dirty check request originated.
+	 * @return Array containing indices of the dirty properties, or null if no properties considered dirty.
+	 */
+	public static int[] findDirty(
+			final StandardProperty[] properties,
+			final Object[] currentState,
+			final Object[] previousState,
+			final boolean[][] includeColumns,
+			final boolean anyUninitializedProperties,
+			final SessionImplementor session) {
+		int[] results = null;
+		int count = 0;
+		int span = properties.length;
+
+		for ( int i = 0; i < span; i++ ) {
+			final boolean dirty = currentState[i] != LazyPropertyInitializer.UNFETCHED_PROPERTY
+					&& properties[i].isDirtyCheckable( anyUninitializedProperties )
+					&& properties[i].getType().isDirty( previousState[i], currentState[i], includeColumns[i], session );
+			if ( dirty ) {
+				if ( results == null ) {
+					results = new int[span];
+				}
+				results[count++] = i;
+			}
+		}
+
+		if ( count == 0 ) {
+			return null;
+		}
+		else {
+			int[] trimmed = new int[count];
+			System.arraycopy( results, 0, trimmed, 0, count );
+			return trimmed;
+		}
+	}
+
+	/**
+	 * Determine if any of the given field values are modified, returning an array containing
+	 * indices of the modified fields.
+	 * <p/>
+	 * If it is determined that no fields are dirty, null is returned.
+	 *
+	 * @param properties The property definitions
+	 * @param currentState The current state of the entity
+	 * @param previousState The baseline state of the entity
+	 * @param includeColumns Columns to be included in the mod checking, per property
+	 * @param anyUninitializedProperties Does the entity currently hold any uninitialized property values?
+	 * @param session The session from which the dirty check request originated.
+	 * @return Array containing indices of the modified properties, or null if no properties considered modified.
+	 */
+	public static int[] findModified(
+			final StandardProperty[] properties, 
+			final Object[] currentState,
+			final Object[] previousState,
+			final boolean[][] includeColumns,
+			final boolean anyUninitializedProperties,
+			final SessionImplementor session) {
+		int[] results = null;
+		int count = 0;
+		int span = properties.length;
+
+		for ( int i = 0; i < span; i++ ) {
+			final boolean modified = currentState[i]!=LazyPropertyInitializer.UNFETCHED_PROPERTY
+					&& properties[i].isDirtyCheckable(anyUninitializedProperties)
+					&& properties[i].getType().isModified( previousState[i], currentState[i], includeColumns[i], session );
+
+			if ( modified ) {
+				if ( results == null ) {
+					results = new int[span];
+				}
+				results[count++] = i;
+			}
+		}
+
+		if ( count == 0 ) {
+			return null;
+		}
+		else {
+			int[] trimmed = new int[count];
+			System.arraycopy( results, 0, trimmed, 0, count );
+			return trimmed;
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/VersionType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,51 +0,0 @@
-//$Id: VersionType.java 7736 2005-08-03 20:03:34Z steveebersole $
-package org.hibernate.type;
-
-import java.util.Comparator;
-
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * A <tt>Type</tt> that may be used to version data.
- * @author Gavin King
- */
-public interface VersionType extends Type {
-	/**
-	 * Generate an initial version.
-	 *
-	 * @param session The session from which this request originates.
-	 * @return an instance of the type
-	 */
-	public Object seed(SessionImplementor session);
-
-	/**
-	 * Increment the version.
-	 *
-	 * @param session The session from which this request originates.
-	 * @param current the current version
-	 * @return an instance of the type
-	 */
-	public Object next(Object current, SessionImplementor session);
-
-	/**
-	 * Get a comparator for version values.
-	 *
-	 * @return The comparator to use to compare different version values.
-	 */
-	public Comparator getComparator();
-
-	/**
-	 * Are the two version values considered equal?
-	 *
-	 * @param x One value to check.
-	 * @param y The other value to check.
-	 * @return true if the values are equal, false otherwise.
-	 */
-	public boolean isEqual(Object x, Object y);
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/VersionType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/VersionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,74 @@
+/*
+ * 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.type;
+
+import java.util.Comparator;
+
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * A <tt>Type</tt> that may be used to version data.
+ * @author Gavin King
+ */
+public interface VersionType extends Type {
+	/**
+	 * Generate an initial version.
+	 *
+	 * @param session The session from which this request originates.
+	 * @return an instance of the type
+	 */
+	public Object seed(SessionImplementor session);
+
+	/**
+	 * Increment the version.
+	 *
+	 * @param session The session from which this request originates.
+	 * @param current the current version
+	 * @return an instance of the type
+	 */
+	public Object next(Object current, SessionImplementor session);
+
+	/**
+	 * Get a comparator for version values.
+	 *
+	 * @return The comparator to use to compare different version values.
+	 */
+	public Comparator getComparator();
+
+	/**
+	 * Are the two version values considered equal?
+	 *
+	 * @param x One value to check.
+	 * @param y The other value to check.
+	 * @return true if the values are equal, false otherwise.
+	 */
+	public boolean isEqual(Object x, Object y);
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/WrapperBinaryType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,41 +0,0 @@
-//$Id: $
-package org.hibernate.type;
-
-import org.hibernate.HibernateException;
-
-/**
- * @author Emmanuel Bernard
- */
-public class WrapperBinaryType extends AbstractBynaryType {
-	protected Object toExternalFormat(byte[] bytes) {
-		if (bytes == null) return null;
-		int length = bytes.length;
-		Byte[] result = new Byte[length];
-		for ( int index = 0; index < length ; index++ ) {
-			result[index] = new Byte( bytes[index] );
-		}
-		return result;
-	}
-
-	protected byte[] toInternalFormat(Object val) {
-		if (val == null) return null;
-		Byte[] bytes = (Byte[]) val;
-		int length = bytes.length;
-		byte[] result = new byte[length];
-		for ( int i = 0; i < length ; i++ ) {
-			if (bytes[i] == null)
-				throw new HibernateException("Unable to store an Byte[] when one of its element is null");
-			result[i] = bytes[i].byteValue();
-		}
-		return result;
-	}
-
-	public Class getReturnedClass() {
-		return Byte[].class;
-	}
-
-	public String getName() {
-		//TODO find a decent name before documenting
-		return "wrapper-binary";
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/WrapperBinaryType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/WrapperBinaryType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.type;
+
+import org.hibernate.HibernateException;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class WrapperBinaryType extends AbstractBynaryType {
+	protected Object toExternalFormat(byte[] bytes) {
+		if (bytes == null) return null;
+		int length = bytes.length;
+		Byte[] result = new Byte[length];
+		for ( int index = 0; index < length ; index++ ) {
+			result[index] = new Byte( bytes[index] );
+		}
+		return result;
+	}
+
+	protected byte[] toInternalFormat(Object val) {
+		if (val == null) return null;
+		Byte[] bytes = (Byte[]) val;
+		int length = bytes.length;
+		byte[] result = new byte[length];
+		for ( int i = 0; i < length ; i++ ) {
+			if (bytes[i] == null)
+				throw new HibernateException("Unable to store an Byte[] when one of its element is null");
+			result[i] = bytes[i].byteValue();
+		}
+		return result;
+	}
+
+	public Class getReturnedClass() {
+		return Byte[].class;
+	}
+
+	public String getName() {
+		//TODO find a decent name before documenting
+		return "wrapper-binary";
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/YesNoType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,25 +0,0 @@
-//$Id: YesNoType.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.type;
-
-/**
- * <tt>yes_no</tt>: A type that maps an SQL CHAR(1) to a Java Boolean.
- * @author Gavin King
- */
-public class YesNoType extends CharBooleanType {
-
-	protected final String getTrueString() {
-		return "Y";
-	}
-	protected final String getFalseString() {
-		return "N";
-	}
-	public String getName() { return "yes_no"; }
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/YesNoType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/YesNoType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,48 @@
+/*
+ * 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.type;
+
+/**
+ * <tt>yes_no</tt>: A type that maps an SQL CHAR(1) to a Java Boolean.
+ * @author Gavin King
+ */
+public class YesNoType extends CharBooleanType {
+
+	protected final String getTrueString() {
+		return "Y";
+	}
+	protected final String getFalseString() {
+		return "N";
+	}
+	public String getName() { return "yes_no"; }
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/type/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,9 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	A Hibernate <tt>Type</tt> is a strategy for mapping a 
-	Java property type to a JDBC type or types.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/type/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/type/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,34 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	A Hibernate <tt>Type</tt> is a strategy for mapping a 
+	Java property type to a JDBC type or types.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/CompositeUserType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,184 +0,0 @@
-//$Id: CompositeUserType.java 6471 2005-04-19 20:36:59Z oneovthafew $
-package org.hibernate.usertype;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.type.Type;
-
-/**
- * A <tt>UserType</tt> that may be dereferenced in a query.
- * This interface allows a custom type to define "properties".
- * These need not necessarily correspond to physical JavaBeans
- * style properties.<br>
- * <br>
- * A <tt>CompositeUserType</tt> may be used in almost every way
- * that a component may be used. It may even contain many-to-one
- * associations.<br>
- * <br>
- * Implementors must be immutable and must declare a public
- * default constructor.<br>
- * <br>
- * Unlike <tt>UserType</tt>, cacheability does not depend upon
- * serializability. Instead, <tt>assemble()</tt> and
- * <tt>disassemble</tt> provide conversion to/from a cacheable
- * representation.
- *
- * @see UserType for more simple cases
- * @see org.hibernate.type.Type
- * @author Gavin King
- */
-public interface CompositeUserType {
-
-	/**
-	 * Get the "property names" that may be used in a
-	 * query.
-	 *
-	 * @return an array of "property names"
-	 */
-	public String[] getPropertyNames();
-
-	/**
-	 * Get the corresponding "property types".
-	 *
-	 * @return an array of Hibernate types
-	 */
-	public Type[] getPropertyTypes();
-
-	/**
-	 * Get the value of a property.
-	 *
-	 * @param component an instance of class mapped by this "type"
-	 * @param property
-	 * @return the property value
-	 * @throws HibernateException
-	 */
-	public Object getPropertyValue(Object component, int property) throws HibernateException;
-
-	/**
-	 * Set the value of a property.
-	 *
-	 * @param component an instance of class mapped by this "type"
-	 * @param property
-	 * @param value the value to set
-	 * @throws HibernateException
-	 */
-	public void setPropertyValue(Object component, int property, Object value) throws HibernateException;
-
-	/**
-	 * The class returned by <tt>nullSafeGet()</tt>.
-	 *
-	 * @return Class
-	 */
-	public Class returnedClass();
-
-	/**
-	 * Compare two instances of the class mapped by this type for persistence "equality".
-	 * Equality of the persistent state.
-	 *
-	 * @param x
-	 * @param y
-	 * @return boolean
-	 * @throws HibernateException
-	 */
-	public boolean equals(Object x, Object y) throws HibernateException;
-	
-	/**
-	 * Get a hashcode for the instance, consistent with persistence "equality"
-	 */
-	public int hashCode(Object x) throws HibernateException;
-
-	/**
-	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
-	 * should handle possibility of null values.
-	 *
-	 * @param rs a JDBC result set
-	 * @param names the column names
-	 * @param session
-	 * @param owner the containing entity
-	 * @return Object
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) 
-	throws HibernateException, SQLException;
-
-	/**
-	 * Write an instance of the mapped class to a prepared statement. Implementors
-	 * should handle possibility of null values. A multi-column type should be written
-	 * to parameters starting from <tt>index</tt>.
-	 *
-	 * @param st a JDBC prepared statement
-	 * @param value the object to write
-	 * @param index statement parameter index
-	 * @param session
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) 
-	throws HibernateException, SQLException;
-
-	/**
-	 * Return a deep copy of the persistent state, stopping at entities and at collections.
-	 *
-	 * @param value generally a collection element or entity field
-	 * @return Object a copy
-	 * @throws HibernateException
-	 */
-	public Object deepCopy(Object value) throws HibernateException;
-
-	/**
-	 * Check if objects of this type mutable.
-	 *
-	 * @return boolean
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Transform the object into its cacheable representation. At the very least this
-	 * method should perform a deep copy. That may not be enough for some implementations,
-	 * however; for example, associations must be cached as identifier values. (optional
-	 * operation)
-	 *
-	 * @param value the object to be cached
-	 * @param session
-	 * @return a cachable representation of the object
-	 * @throws HibernateException
-	 */
-	public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException;
-
-	/**
-	 * Reconstruct an object from the cacheable representation. At the very least this
-	 * method should perform a deep copy. (optional operation)
-	 *
-	 * @param cached the object to be cached
-	 * @param session
-	 * @param owner the owner of the cached object
-	 * @return a reconstructed object from the cachable representation
-	 * @throws HibernateException
-	 */
-	public Object assemble(Serializable cached, SessionImplementor session, Object owner) 
-	throws HibernateException;
-
-	/**
-	 * During merge, replace the existing (target) value in the entity we are merging to
-	 * with a new (original) value from the detached entity we are merging. For immutable
-	 * objects, or null values, it is safe to simply return the first parameter. For
-	 * mutable objects, it is safe to return a copy of the first parameter. However, since
-	 * composite user types often define component values, it might make sense to recursively 
-	 * replace component values in the target object.
-	 * 
-	 * @param original
-	 * @param target
-	 * @param session
-	 * @param owner
-	 * @return
-	 * @throws HibernateException
-	 */
-	public Object replace(Object original, Object target, SessionImplementor session, Object owner) 
-	throws HibernateException;
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/CompositeUserType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/CompositeUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,207 @@
+/*
+ * 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.usertype;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.type.Type;
+
+/**
+ * A <tt>UserType</tt> that may be dereferenced in a query.
+ * This interface allows a custom type to define "properties".
+ * These need not necessarily correspond to physical JavaBeans
+ * style properties.<br>
+ * <br>
+ * A <tt>CompositeUserType</tt> may be used in almost every way
+ * that a component may be used. It may even contain many-to-one
+ * associations.<br>
+ * <br>
+ * Implementors must be immutable and must declare a public
+ * default constructor.<br>
+ * <br>
+ * Unlike <tt>UserType</tt>, cacheability does not depend upon
+ * serializability. Instead, <tt>assemble()</tt> and
+ * <tt>disassemble</tt> provide conversion to/from a cacheable
+ * representation.
+ *
+ * @see UserType for more simple cases
+ * @see org.hibernate.type.Type
+ * @author Gavin King
+ */
+public interface CompositeUserType {
+
+	/**
+	 * Get the "property names" that may be used in a
+	 * query.
+	 *
+	 * @return an array of "property names"
+	 */
+	public String[] getPropertyNames();
+
+	/**
+	 * Get the corresponding "property types".
+	 *
+	 * @return an array of Hibernate types
+	 */
+	public Type[] getPropertyTypes();
+
+	/**
+	 * Get the value of a property.
+	 *
+	 * @param component an instance of class mapped by this "type"
+	 * @param property
+	 * @return the property value
+	 * @throws HibernateException
+	 */
+	public Object getPropertyValue(Object component, int property) throws HibernateException;
+
+	/**
+	 * Set the value of a property.
+	 *
+	 * @param component an instance of class mapped by this "type"
+	 * @param property
+	 * @param value the value to set
+	 * @throws HibernateException
+	 */
+	public void setPropertyValue(Object component, int property, Object value) throws HibernateException;
+
+	/**
+	 * The class returned by <tt>nullSafeGet()</tt>.
+	 *
+	 * @return Class
+	 */
+	public Class returnedClass();
+
+	/**
+	 * Compare two instances of the class mapped by this type for persistence "equality".
+	 * Equality of the persistent state.
+	 *
+	 * @param x
+	 * @param y
+	 * @return boolean
+	 * @throws HibernateException
+	 */
+	public boolean equals(Object x, Object y) throws HibernateException;
+	
+	/**
+	 * Get a hashcode for the instance, consistent with persistence "equality"
+	 */
+	public int hashCode(Object x) throws HibernateException;
+
+	/**
+	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
+	 * should handle possibility of null values.
+	 *
+	 * @param rs a JDBC result set
+	 * @param names the column names
+	 * @param session
+	 * @param owner the containing entity
+	 * @return Object
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) 
+	throws HibernateException, SQLException;
+
+	/**
+	 * Write an instance of the mapped class to a prepared statement. Implementors
+	 * should handle possibility of null values. A multi-column type should be written
+	 * to parameters starting from <tt>index</tt>.
+	 *
+	 * @param st a JDBC prepared statement
+	 * @param value the object to write
+	 * @param index statement parameter index
+	 * @param session
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) 
+	throws HibernateException, SQLException;
+
+	/**
+	 * Return a deep copy of the persistent state, stopping at entities and at collections.
+	 *
+	 * @param value generally a collection element or entity field
+	 * @return Object a copy
+	 * @throws HibernateException
+	 */
+	public Object deepCopy(Object value) throws HibernateException;
+
+	/**
+	 * Check if objects of this type mutable.
+	 *
+	 * @return boolean
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Transform the object into its cacheable representation. At the very least this
+	 * method should perform a deep copy. That may not be enough for some implementations,
+	 * however; for example, associations must be cached as identifier values. (optional
+	 * operation)
+	 *
+	 * @param value the object to be cached
+	 * @param session
+	 * @return a cachable representation of the object
+	 * @throws HibernateException
+	 */
+	public Serializable disassemble(Object value, SessionImplementor session) throws HibernateException;
+
+	/**
+	 * Reconstruct an object from the cacheable representation. At the very least this
+	 * method should perform a deep copy. (optional operation)
+	 *
+	 * @param cached the object to be cached
+	 * @param session
+	 * @param owner the owner of the cached object
+	 * @return a reconstructed object from the cachable representation
+	 * @throws HibernateException
+	 */
+	public Object assemble(Serializable cached, SessionImplementor session, Object owner) 
+	throws HibernateException;
+
+	/**
+	 * During merge, replace the existing (target) value in the entity we are merging to
+	 * with a new (original) value from the detached entity we are merging. For immutable
+	 * objects, or null values, it is safe to simply return the first parameter. For
+	 * mutable objects, it is safe to return a copy of the first parameter. However, since
+	 * composite user types often define component values, it might make sense to recursively 
+	 * replace component values in the target object.
+	 * 
+	 * @param original
+	 * @param target
+	 * @param session
+	 * @param owner
+	 * @return
+	 * @throws HibernateException
+	 */
+	public Object replace(Object original, Object target, SessionImplementor session, Object owner) 
+	throws HibernateException;
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: EnhancedUserType.java 5956 2005-02-28 06:07:06Z oneovthafew $
-package org.hibernate.usertype;
-
-/**
- * A custom type that may function as an identifier or
- * discriminator type, or may be marshalled to and from
- * an XML document
- * 
- * @author Gavin King
- */
-public interface EnhancedUserType extends UserType {
-	/**
-	 * Return an SQL literal representation of the value
-	 */
-	public String objectToSQLString(Object value);
-	
-	/**
-	 * Return a string representation of this value, as it
-	 * should appear in an XML document
-	 */
-	public String toXMLString(Object value);
-	/**
-	 * Parse a string representation of this value, as it
-	 * appears in an XML document
-	 */
-	public Object fromXMLString(String xmlValue);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/EnhancedUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.usertype;
+
+/**
+ * A custom type that may function as an identifier or
+ * discriminator type, or may be marshalled to and from
+ * an XML document
+ * 
+ * @author Gavin King
+ */
+public interface EnhancedUserType extends UserType {
+	/**
+	 * Return an SQL literal representation of the value
+	 */
+	public String objectToSQLString(Object value);
+	
+	/**
+	 * Return a string representation of this value, as it
+	 * should appear in an XML document
+	 */
+	public String toXMLString(Object value);
+	/**
+	 * Parse a string representation of this value, as it
+	 * appears in an XML document
+	 */
+	public Object fromXMLString(String xmlValue);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/LoggableUserType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,20 +0,0 @@
-package org.hibernate.usertype;
-
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * Marker interface for user types which want to perform custom
- * logging of their corresponding values
- *
- * @author Steve Ebersole
- */
-public interface LoggableUserType {
-	/**
-	 * Generate a loggable string representation of the collection (value).
-	 *
-	 * @param value The collection to be logged; guarenteed to be non-null and initialized.
-	 * @param factory The factory.
-	 * @return The loggable string representation.
-	 */
-	public String toLoggableString(Object value, SessionFactoryImplementor factory);
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/LoggableUserType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/LoggableUserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.usertype;
+
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * Marker interface for user types which want to perform custom
+ * logging of their corresponding values
+ *
+ * @author Steve Ebersole
+ */
+public interface LoggableUserType {
+	/**
+	 * Generate a loggable string representation of the collection (value).
+	 *
+	 * @param value The collection to be logged; guarenteed to be non-null and initialized.
+	 * @param factory The factory.
+	 * @return The loggable string representation.
+	 */
+	public String toLoggableString(Object value, SessionFactoryImplementor factory);
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/ParameterizedType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,21 +0,0 @@
-//$Id: ParameterizedType.java 4499 2004-09-05 04:32:54Z oneovthafew $
-package org.hibernate.usertype;
-
-import java.util.Properties;
-
-/**
- * Support for parameterizable types. A UserType or CustomUserType may be
- * made parameterizable by implementing this interface. Parameters for a
- * type may be set by using a nested type element for the property element
- * in the mapping file, or by defining a typedef.
- *
- * @author Michael Gloegl
- */
-public interface ParameterizedType {
-
-	/**
-	 * Gets called by Hibernate to pass the configured type parameters to
-	 * the implementation.
-	 */
-	public void setParameterValues(Properties parameters);
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/ParameterizedType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/ParameterizedType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,44 @@
+/*
+ * 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.usertype;
+
+import java.util.Properties;
+
+/**
+ * Support for parameterizable types. A UserType or CustomUserType may be
+ * made parameterizable by implementing this interface. Parameters for a
+ * type may be set by using a nested type element for the property element
+ * in the mapping file, or by defining a typedef.
+ *
+ * @author Michael Gloegl
+ */
+public interface ParameterizedType {
+
+	/**
+	 * Gets called by Hibernate to pass the configured type parameters to
+	 * the implementation.
+	 */
+	public void setParameterValues(Properties parameters);
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/UserCollectionType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,70 +0,0 @@
-//$Id: UserCollectionType.java 10086 2006-07-05 18:17:27Z steve.ebersole at jboss.com $
-package org.hibernate.usertype;
-
-import java.util.Iterator;
-import java.util.Map;
-
-import org.hibernate.HibernateException;
-import org.hibernate.collection.PersistentCollection;
-import org.hibernate.engine.SessionImplementor;
-import org.hibernate.persister.collection.CollectionPersister;
-
-/**
- * A custom type for mapping user-written classes that implement <tt>PersistentCollection</tt>
- * 
- * @see org.hibernate.collection.PersistentCollection
- * @author Gavin King
- */
-public interface UserCollectionType {
-	
-	/**
-	 * Instantiate an uninitialized instance of the collection wrapper
-	 */
-	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) 
-	throws HibernateException;
-	
-	/**
-	 * Wrap an instance of a collection
-	 */
-	public PersistentCollection wrap(SessionImplementor session, Object collection);
-	
-	/**
-	 * Return an iterator over the elements of this collection - the passed collection
-	 * instance may or may not be a wrapper
-	 */
-	public Iterator getElementsIterator(Object collection);
-
-	/**
-	 * Optional operation. Does the collection contain the entity instance?
-	 */
-	public boolean contains(Object collection, Object entity);
-	/**
-	 * Optional operation. Return the index of the entity in the collection.
-	 */
-	public Object indexOf(Object collection, Object entity);
-	
-	/**
-	 * Replace the elements of a collection with the elements of another collection
-	 */
-	public Object replaceElements(
-			Object original, 
-			Object target, 
-			CollectionPersister persister, 
-			Object owner, 
-			Map copyCache, 
-			SessionImplementor session)
-			throws HibernateException;
-
-	/**
-	 * Instantiate an empty instance of the "underlying" collection (not a wrapper),
-	 * but with the given anticipated size (i.e. accounting for initial size
-	 * and perhaps load factor).
-	 *
-	 * @param anticipatedSize The anticipated size of the instaniated collection
-	 * after we are done populating it.  Note, may be negative to indicate that
-	 * we not yet know anything about the anticipated size (i.e., when initializing
-	 * from a result set row by row).
-	 */
-	public Object instantiate(int anticipatedSize);
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/UserCollectionType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserCollectionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,93 @@
+/*
+ * 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.usertype;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import org.hibernate.HibernateException;
+import org.hibernate.collection.PersistentCollection;
+import org.hibernate.engine.SessionImplementor;
+import org.hibernate.persister.collection.CollectionPersister;
+
+/**
+ * A custom type for mapping user-written classes that implement <tt>PersistentCollection</tt>
+ * 
+ * @see org.hibernate.collection.PersistentCollection
+ * @author Gavin King
+ */
+public interface UserCollectionType {
+	
+	/**
+	 * Instantiate an uninitialized instance of the collection wrapper
+	 */
+	public PersistentCollection instantiate(SessionImplementor session, CollectionPersister persister) 
+	throws HibernateException;
+	
+	/**
+	 * Wrap an instance of a collection
+	 */
+	public PersistentCollection wrap(SessionImplementor session, Object collection);
+	
+	/**
+	 * Return an iterator over the elements of this collection - the passed collection
+	 * instance may or may not be a wrapper
+	 */
+	public Iterator getElementsIterator(Object collection);
+
+	/**
+	 * Optional operation. Does the collection contain the entity instance?
+	 */
+	public boolean contains(Object collection, Object entity);
+	/**
+	 * Optional operation. Return the index of the entity in the collection.
+	 */
+	public Object indexOf(Object collection, Object entity);
+	
+	/**
+	 * Replace the elements of a collection with the elements of another collection
+	 */
+	public Object replaceElements(
+			Object original, 
+			Object target, 
+			CollectionPersister persister, 
+			Object owner, 
+			Map copyCache, 
+			SessionImplementor session)
+			throws HibernateException;
+
+	/**
+	 * Instantiate an empty instance of the "underlying" collection (not a wrapper),
+	 * but with the given anticipated size (i.e. accounting for initial size
+	 * and perhaps load factor).
+	 *
+	 * @param anticipatedSize The anticipated size of the instaniated collection
+	 * after we are done populating it.  Note, may be negative to indicate that
+	 * we not yet know anything about the anticipated size (i.e., when initializing
+	 * from a result set row by row).
+	 */
+	public Object instantiate(int anticipatedSize);
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/UserType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,160 +0,0 @@
-//$Id: UserType.java 6133 2005-03-21 16:53:58Z turin42 $
-package org.hibernate.usertype;
-
-import java.io.Serializable;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-import org.hibernate.HibernateException;
-
-/**
- * This interface should be implemented by user-defined "types".
- * A "type" class is <em>not</em> the actual property type - it
- * is a class that knows how to serialize instances of another
- * class to and from JDBC.<br>
- * <br>
- * This interface
- * <ul>
- * <li>abstracts user code from future changes to the <tt>Type</tt>
- * interface,</li>
- * <li>simplifies the implementation of custom types and</li>
- * <li>hides certain "internal" interfaces from user code.</li>
- * </ul>
- * <br>
- * Implementors must be immutable and must declare a public
- * default constructor.<br>
- * <br>
- * The actual class mapped by a <tt>UserType</tt> may be just
- * about anything.<br>
- * <br>
- * <tt>CompositeUserType</tt> provides an extended version of
- * this interface that is useful for more complex cases.<br>
- * <br>
- * Alternatively, custom types could implement <tt>Type</tt>
- * directly or extend one of the abstract classes in
- * <tt>org.hibernate.type</tt>. This approach risks future
- * incompatible changes to classes or interfaces in that
- * package.
- *
- * @see CompositeUserType for more complex cases
- * @see org.hibernate.type.Type
- * @author Gavin King
- */
-public interface UserType {
-
-	/**
-	 * Return the SQL type codes for the columns mapped by this type. The
-	 * codes are defined on <tt>java.sql.Types</tt>.
-	 * @see java.sql.Types
-	 * @return int[] the typecodes
-	 */
-	public int[] sqlTypes();
-
-	/**
-	 * The class returned by <tt>nullSafeGet()</tt>.
-	 *
-	 * @return Class
-	 */
-	public Class returnedClass();
-
-	/**
-	 * Compare two instances of the class mapped by this type for persistence "equality".
-	 * Equality of the persistent state.
-	 *
-	 * @param x
-	 * @param y
-	 * @return boolean
-	 */
-	public boolean equals(Object x, Object y) throws HibernateException;
-
-	/**
-	 * Get a hashcode for the instance, consistent with persistence "equality"
-	 */
-	public int hashCode(Object x) throws HibernateException;
-
-	/**
-	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
-	 * should handle possibility of null values.
-	 *
-	 * @param rs a JDBC result set
-	 * @param names the column names
-	 * @param owner the containing entity
-	 * @return Object
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException;
-
-	/**
-	 * Write an instance of the mapped class to a prepared statement. Implementors
-	 * should handle possibility of null values. A multi-column type should be written
-	 * to parameters starting from <tt>index</tt>.
-	 *
-	 * @param st a JDBC prepared statement
-	 * @param value the object to write
-	 * @param index statement parameter index
-	 * @throws HibernateException
-	 * @throws SQLException
-	 */
-	public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
-
-	/**
-	 * Return a deep copy of the persistent state, stopping at entities and at
-	 * collections. It is not necessary to copy immutable objects, or null
-	 * values, in which case it is safe to simply return the argument.
-	 *
-	 * @param value the object to be cloned, which may be null
-	 * @return Object a copy
-	 */
-	public Object deepCopy(Object value) throws HibernateException;
-
-	/**
-	 * Are objects of this type mutable?
-	 *
-	 * @return boolean
-	 */
-	public boolean isMutable();
-
-	/**
-	 * Transform the object into its cacheable representation. At the very least this
-	 * method should perform a deep copy if the type is mutable. That may not be enough
-	 * for some implementations, however; for example, associations must be cached as
-	 * identifier values. (optional operation)
-	 *
-	 * @param value the object to be cached
-	 * @return a cachable representation of the object
-	 * @throws HibernateException
-	 */
-	public Serializable disassemble(Object value) throws HibernateException;
-
-	/**
-	 * Reconstruct an object from the cacheable representation. At the very least this
-	 * method should perform a deep copy if the type is mutable. (optional operation)
-	 *
-	 * @param cached the object to be cached
-	 * @param owner the owner of the cached object
-	 * @return a reconstructed object from the cachable representation
-	 * @throws HibernateException
-	 */
-	public Object assemble(Serializable cached, Object owner) throws HibernateException;
-
-	/**
-	 * During merge, replace the existing (target) value in the entity we are merging to
-	 * with a new (original) value from the detached entity we are merging. For immutable
-	 * objects, or null values, it is safe to simply return the first parameter. For
-	 * mutable objects, it is safe to return a copy of the first parameter. For objects
-	 * with component values, it might make sense to recursively replace component values.
-	 *
-	 * @param original the value from the detached entity being merged
-	 * @param target the value in the managed entity
-	 * @return the value to be merged
-	 */
-	public Object replace(Object original, Object target, Object owner) throws HibernateException;
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/UserType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,183 @@
+/*
+ * 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.usertype;
+
+import java.io.Serializable;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.hibernate.HibernateException;
+
+/**
+ * This interface should be implemented by user-defined "types".
+ * A "type" class is <em>not</em> the actual property type - it
+ * is a class that knows how to serialize instances of another
+ * class to and from JDBC.<br>
+ * <br>
+ * This interface
+ * <ul>
+ * <li>abstracts user code from future changes to the <tt>Type</tt>
+ * interface,</li>
+ * <li>simplifies the implementation of custom types and</li>
+ * <li>hides certain "internal" interfaces from user code.</li>
+ * </ul>
+ * <br>
+ * Implementors must be immutable and must declare a public
+ * default constructor.<br>
+ * <br>
+ * The actual class mapped by a <tt>UserType</tt> may be just
+ * about anything.<br>
+ * <br>
+ * <tt>CompositeUserType</tt> provides an extended version of
+ * this interface that is useful for more complex cases.<br>
+ * <br>
+ * Alternatively, custom types could implement <tt>Type</tt>
+ * directly or extend one of the abstract classes in
+ * <tt>org.hibernate.type</tt>. This approach risks future
+ * incompatible changes to classes or interfaces in that
+ * package.
+ *
+ * @see CompositeUserType for more complex cases
+ * @see org.hibernate.type.Type
+ * @author Gavin King
+ */
+public interface UserType {
+
+	/**
+	 * Return the SQL type codes for the columns mapped by this type. The
+	 * codes are defined on <tt>java.sql.Types</tt>.
+	 * @see java.sql.Types
+	 * @return int[] the typecodes
+	 */
+	public int[] sqlTypes();
+
+	/**
+	 * The class returned by <tt>nullSafeGet()</tt>.
+	 *
+	 * @return Class
+	 */
+	public Class returnedClass();
+
+	/**
+	 * Compare two instances of the class mapped by this type for persistence "equality".
+	 * Equality of the persistent state.
+	 *
+	 * @param x
+	 * @param y
+	 * @return boolean
+	 */
+	public boolean equals(Object x, Object y) throws HibernateException;
+
+	/**
+	 * Get a hashcode for the instance, consistent with persistence "equality"
+	 */
+	public int hashCode(Object x) throws HibernateException;
+
+	/**
+	 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors
+	 * should handle possibility of null values.
+	 *
+	 * @param rs a JDBC result set
+	 * @param names the column names
+	 * @param owner the containing entity
+	 * @return Object
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException;
+
+	/**
+	 * Write an instance of the mapped class to a prepared statement. Implementors
+	 * should handle possibility of null values. A multi-column type should be written
+	 * to parameters starting from <tt>index</tt>.
+	 *
+	 * @param st a JDBC prepared statement
+	 * @param value the object to write
+	 * @param index statement parameter index
+	 * @throws HibernateException
+	 * @throws SQLException
+	 */
+	public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
+
+	/**
+	 * Return a deep copy of the persistent state, stopping at entities and at
+	 * collections. It is not necessary to copy immutable objects, or null
+	 * values, in which case it is safe to simply return the argument.
+	 *
+	 * @param value the object to be cloned, which may be null
+	 * @return Object a copy
+	 */
+	public Object deepCopy(Object value) throws HibernateException;
+
+	/**
+	 * Are objects of this type mutable?
+	 *
+	 * @return boolean
+	 */
+	public boolean isMutable();
+
+	/**
+	 * Transform the object into its cacheable representation. At the very least this
+	 * method should perform a deep copy if the type is mutable. That may not be enough
+	 * for some implementations, however; for example, associations must be cached as
+	 * identifier values. (optional operation)
+	 *
+	 * @param value the object to be cached
+	 * @return a cachable representation of the object
+	 * @throws HibernateException
+	 */
+	public Serializable disassemble(Object value) throws HibernateException;
+
+	/**
+	 * Reconstruct an object from the cacheable representation. At the very least this
+	 * method should perform a deep copy if the type is mutable. (optional operation)
+	 *
+	 * @param cached the object to be cached
+	 * @param owner the owner of the cached object
+	 * @return a reconstructed object from the cachable representation
+	 * @throws HibernateException
+	 */
+	public Object assemble(Serializable cached, Object owner) throws HibernateException;
+
+	/**
+	 * During merge, replace the existing (target) value in the entity we are merging to
+	 * with a new (original) value from the detached entity we are merging. For immutable
+	 * objects, or null values, it is safe to simply return the first parameter. For
+	 * mutable objects, it is safe to return a copy of the first parameter. For objects
+	 * with component values, it might make sense to recursively replace component values.
+	 *
+	 * @param original the value from the detached entity being merged
+	 * @param target the value in the managed entity
+	 * @return the value to be merged
+	 */
+	public Object replace(Object original, Object target, Object owner) throws HibernateException;
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/UserVersionType.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,32 +0,0 @@
-//$Id: UserVersionType.java 7736 2005-08-03 20:03:34Z steveebersole $
-package org.hibernate.usertype;
-
-import java.util.Comparator;
-
-import org.hibernate.engine.SessionImplementor;
-
-/**
- * A user type that may be used for a version property
- * 
- * @author Gavin King
- */
-public interface UserVersionType extends UserType, Comparator {
-	/**
-	 * Generate an initial version.
-	 *
-	 * @param session The session from which this request originates.  May be
-	 * null; currently this only happens during startup when trying to determine
-	 * the "unsaved value" of entities.
-	 * @return an instance of the type
-	 */
-	public Object seed(SessionImplementor session);
-	/**
-	 * Increment the version.
-	 *
-	 * @param session The session from which this request originates.
-	 * @param current the current version
-	 * @return an instance of the type
-	 */
-	public Object next(Object current, SessionImplementor session);
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/UserVersionType.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/UserVersionType.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.usertype;
+
+import java.util.Comparator;
+
+import org.hibernate.engine.SessionImplementor;
+
+/**
+ * A user type that may be used for a version property
+ * 
+ * @author Gavin King
+ */
+public interface UserVersionType extends UserType, Comparator {
+	/**
+	 * Generate an initial version.
+	 *
+	 * @param session The session from which this request originates.  May be
+	 * null; currently this only happens during startup when trying to determine
+	 * the "unsaved value" of entities.
+	 * @return an instance of the type
+	 */
+	public Object seed(SessionImplementor session);
+	/**
+	 * Increment the version.
+	 *
+	 * @param session The session from which this request originates.
+	 * @param current the current version
+	 * @return an instance of the type
+	 */
+	public Object next(Object current, SessionImplementor session);
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/usertype/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Interfaces for user-defined custom types.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/usertype/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/usertype/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Interfaces for user-defined custom types.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ArrayHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,345 +0,0 @@
-//$Id: ArrayHelper.java 7546 2005-07-19 18:17:15Z oneovthafew $
-package org.hibernate.util;
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-
-import org.hibernate.LockMode;
-import org.hibernate.type.Type;
-
-public final class ArrayHelper {
-	
-	/*public static boolean contains(Object[] array, Object object) {
-		for ( int i=0; i<array.length; i++ ) {
-			if ( array[i].equals(object) ) return true;
-		}
-		return false;
-	}*/
-	
-	public static int indexOf(Object[] array, Object object) {
-		for ( int i=0; i<array.length; i++ ) {
-			if ( array[i].equals(object) ) return i;
-		}
-		return -1;
-	}
-	
-	/*public static Object[] clone(Class elementClass, Object[] array) {
-		Object[] result = (Object[]) Array.newInstance( elementClass, array.length );
-		System.arraycopy(array, 0, result, 0, array.length);
-		return result;
-	}*/
-
-	public static String[] toStringArray(Object[] objects) {
-		int length=objects.length;
-		String[] result = new String[length];
-		for (int i=0; i<length; i++) {
-			result[i] = objects[i].toString();
-		}
-		return result;
-	}
-
-	public static String[] fillArray(String value, int length) {
-		String[] result = new String[length];
-		Arrays.fill(result, value);
-		return result;
-	}
-
-	public static int[] fillArray(int value, int length) {
-		int[] result = new int[length];
-		Arrays.fill(result, value);
-		return result;
-	}
-
-	public static LockMode[] fillArray(LockMode lockMode, int length) {
-		LockMode[] array = new LockMode[length];
-		Arrays.fill(array, lockMode);
-		return array;
-	}
-
-	public static String[] toStringArray(Collection coll) {
-		return (String[]) coll.toArray(EMPTY_STRING_ARRAY);
-	}
-	
-	public static String[][] to2DStringArray(Collection coll) {
-		return (String[][]) coll.toArray( new String[ coll.size() ][] );
-	}
-	
-	public static int[][] to2DIntArray(Collection coll) {
-		return (int[][]) coll.toArray( new int[ coll.size() ][] );
-	}
-	
-	public static Type[] toTypeArray(Collection coll) {
-		return (Type[]) coll.toArray(EMPTY_TYPE_ARRAY);
-	}
-
-	public static int[] toIntArray(Collection coll) {
-		Iterator iter = coll.iterator();
-		int[] arr = new int[ coll.size() ];
-		int i=0;
-		while( iter.hasNext() ) {
-			arr[i++] = ( (Integer) iter.next() ).intValue();
-		}
-		return arr;
-	}
-
-	public static boolean[] toBooleanArray(Collection coll) {
-		Iterator iter = coll.iterator();
-		boolean[] arr = new boolean[ coll.size() ];
-		int i=0;
-		while( iter.hasNext() ) {
-			arr[i++] = ( (Boolean) iter.next() ).booleanValue();
-		}
-		return arr;
-	}
-
-	public static Object[] typecast(Object[] array, Object[] to) {
-		return java.util.Arrays.asList(array).toArray(to);
-	}
-
-	//Arrays.asList doesn't do primitive arrays
-	public static List toList(Object array) {
-		if ( array instanceof Object[] ) return Arrays.asList( (Object[]) array ); //faster?
-		int size = Array.getLength(array);
-		ArrayList list = new ArrayList(size);
-		for (int i=0; i<size; i++) {
-			list.add( Array.get(array, i) );
-		}
-		return list;
-	}
-
-	public static String[] slice(String[] strings, int begin, int length) {
-		String[] result = new String[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = strings[begin+i];
-		}
-		return result;
-	}
-
-	public static Object[] slice(Object[] objects, int begin, int length) {
-		Object[] result = new Object[length];
-		for ( int i=0; i<length; i++ ) {
-			result[i] = objects[begin+i];
-		}
-		return result;
-	}
-
-	public static List toList(Iterator iter) {
-		List list = new ArrayList();
-		while ( iter.hasNext() ) {
-			list.add( iter.next() );
-		}
-		return list;
-	}
-
-	public static String[] join(String[] x, String[] y) {
-		String[] result = new String[ x.length + y.length ];
-		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
-		for ( int i=0; i<y.length; i++ ) result[i+x.length] = y[i];
-		return result;
-	}
-
-	public static String[] join(String[] x, String[] y, boolean[] use) {
-		String[] result = new String[ x.length + countTrue(use) ];
-		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
-		int k = x.length;
-		for ( int i=0; i<y.length; i++ ) {
-			if ( use[i] ) result[k++] = y[i];
-		}
-		return result;
-	}
-
-	public static int[] join(int[] x, int[] y) {
-		int[] result = new int[ x.length + y.length ];
-		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
-		for ( int i=0; i<y.length; i++ ) result[i+x.length] = y[i];
-		return result;
-	}
-
-	public static final boolean[] TRUE = { true };
-	public static final boolean[] FALSE = { false };
-
-	private ArrayHelper() {}
-
-	public static String toString( Object[] array ) {
-		StringBuffer sb = new StringBuffer();
-		sb.append("[");
-		for (int i = 0; i < array.length; i++) {
-			sb.append( array[i] );
-			if( i<array.length-1 ) sb.append(",");
-		}
-		sb.append("]");
-		return sb.toString();
-	}
-
-	public static boolean isAllNegative(int[] array) {
-		for ( int i=0; i<array.length; i++ ) {
-			if ( array[i] >=0 ) return false;
-		}
-		return true;
-	}
-
-	public static boolean isAllTrue(boolean[] array) {
-		for ( int i=0; i<array.length; i++ ) {
-			if ( !array[i] ) return false;
-		}
-		return true;
-	}
-
-	public static int countTrue(boolean[] array) {
-		int result=0;
-		for ( int i=0; i<array.length; i++ ) {
-			if ( array[i] ) result++;
-		}
-		return result;
-	}
-
-	/*public static int countFalse(boolean[] array) {
-		int result=0;
-		for ( int i=0; i<array.length; i++ ) {
-			if ( !array[i] ) result++;
-		}
-		return result;
-	}*/
-
-	public static boolean isAllFalse(boolean[] array) {
-		for ( int i=0; i<array.length; i++ ) {
-			if ( array[i] ) return false;
-		}
-		return true;
-	}
-
-	public static void addAll(Collection collection, Object[] array) {
-		for ( int i=0; i<array.length; i++ ) {
-			collection.add( array[i] );
-		}
-	}
-
-	public static final String[] EMPTY_STRING_ARRAY = {};
-	public static final int[] EMPTY_INT_ARRAY = {};
-	public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};
-	public static final Class[] EMPTY_CLASS_ARRAY = {};
-	public static final Object[] EMPTY_OBJECT_ARRAY = {};
-	public static final Type[] EMPTY_TYPE_ARRAY = {};
-	
-	public static int[] getBatchSizes(int maxBatchSize) {
-		int batchSize = maxBatchSize;
-		int n=1;
-		while ( batchSize>1 ) {
-			batchSize = getNextBatchSize(batchSize);
-			n++;
-		}
-		int[] result = new int[n];
-		batchSize = maxBatchSize;
-		for ( int i=0; i<n; i++ ) {
-			result[i] = batchSize;
-			batchSize = getNextBatchSize(batchSize);
-		}
-		return result;
-	}
-	
-	private static int getNextBatchSize(int batchSize) {
-		if (batchSize<=10) {
-			return batchSize-1; //allow 9,8,7,6,5,4,3,2,1
-		}
-		else if (batchSize/2 < 10) {
-			return 10;
-		}
-		else {
-			return batchSize / 2;
-		}
-	}
-
-	private static int SEED = 23;
-	private static int PRIME_NUMER = 37;
-
-	/**
-	 * calculate the array hash (only the first level)
-	 */
-	public static int hash(Object[] array) {
-		int length = array.length;
-		int seed = SEED;
-		for (int index = 0 ; index < length ; index++) {
-			seed = hash( seed, array[index] == null ? 0 : array[index].hashCode() );
-		}
-		return seed;
-	}
-
-	/**
-	 * calculate the array hash (only the first level)
-	 */
-	public static int hash(char[] array) {
-		int length = array.length;
-		int seed = SEED;
-		for (int index = 0 ; index < length ; index++) {
-			seed = hash( seed, (int) array[index] ) ;
-		}
-		return seed;
-	}
-
-	/**
-	 * calculate the array hash (only the first level)
-	 */
-	public static int hash(byte[] bytes) {
-		int length = bytes.length;
-		int seed = SEED;
-		for (int index = 0 ; index < length ; index++) {
-			seed = hash( seed, (int) bytes[index] ) ;
-		}
-		return seed;
-	}
-
-	private static int hash(int seed, int i) {
-		return PRIME_NUMER * seed + i;
-	}
-
-	/**
-	 * Compare 2 arrays only at the first level
-	 */
-	public static boolean isEquals(Object[] o1, Object[] o2) {
-		if (o1 == o2) return true;
-		if (o1 == null || o2 == null) return false;
-		int length = o1.length;
-		if (length != o2.length) return false;
-		for (int index = 0 ; index < length ; index++) {
-			if ( ! o1[index].equals( o2[index] ) ) return false;
-		}
-        return true;
-	}
-
-	/**
-	 * Compare 2 arrays only at the first level
-	 */
-	public static boolean isEquals(char[] o1, char[] o2) {
-		if (o1 == o2) return true;
-		if (o1 == null || o2 == null) return false;
-		int length = o1.length;
-		if (length != o2.length) return false;
-		for (int index = 0 ; index < length ; index++) {
-			if ( ! ( o1[index] == o2[index] ) ) return false;
-		}
-        return true;
-	}
-
-	/**
-	 * Compare 2 arrays only at the first level
-	 */
-	public static boolean isEquals(byte[] b1, byte[] b2) {
-		if (b1 == b2) return true;
-		if (b1 == null || b2 == null) return false;
-		int length = b1.length;
-		if (length != b2.length) return false;
-		for (int index = 0 ; index < length ; index++) {
-			if ( ! ( b1[index] == b2[index] ) ) return false;
-		}
-        return true;
-	}
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/ArrayHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ArrayHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,369 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.hibernate.LockMode;
+import org.hibernate.type.Type;
+
+public final class ArrayHelper {
+	
+	/*public static boolean contains(Object[] array, Object object) {
+		for ( int i=0; i<array.length; i++ ) {
+			if ( array[i].equals(object) ) return true;
+		}
+		return false;
+	}*/
+	
+	public static int indexOf(Object[] array, Object object) {
+		for ( int i=0; i<array.length; i++ ) {
+			if ( array[i].equals(object) ) return i;
+		}
+		return -1;
+	}
+	
+	/*public static Object[] clone(Class elementClass, Object[] array) {
+		Object[] result = (Object[]) Array.newInstance( elementClass, array.length );
+		System.arraycopy(array, 0, result, 0, array.length);
+		return result;
+	}*/
+
+	public static String[] toStringArray(Object[] objects) {
+		int length=objects.length;
+		String[] result = new String[length];
+		for (int i=0; i<length; i++) {
+			result[i] = objects[i].toString();
+		}
+		return result;
+	}
+
+	public static String[] fillArray(String value, int length) {
+		String[] result = new String[length];
+		Arrays.fill(result, value);
+		return result;
+	}
+
+	public static int[] fillArray(int value, int length) {
+		int[] result = new int[length];
+		Arrays.fill(result, value);
+		return result;
+	}
+
+	public static LockMode[] fillArray(LockMode lockMode, int length) {
+		LockMode[] array = new LockMode[length];
+		Arrays.fill(array, lockMode);
+		return array;
+	}
+
+	public static String[] toStringArray(Collection coll) {
+		return (String[]) coll.toArray(EMPTY_STRING_ARRAY);
+	}
+	
+	public static String[][] to2DStringArray(Collection coll) {
+		return (String[][]) coll.toArray( new String[ coll.size() ][] );
+	}
+	
+	public static int[][] to2DIntArray(Collection coll) {
+		return (int[][]) coll.toArray( new int[ coll.size() ][] );
+	}
+	
+	public static Type[] toTypeArray(Collection coll) {
+		return (Type[]) coll.toArray(EMPTY_TYPE_ARRAY);
+	}
+
+	public static int[] toIntArray(Collection coll) {
+		Iterator iter = coll.iterator();
+		int[] arr = new int[ coll.size() ];
+		int i=0;
+		while( iter.hasNext() ) {
+			arr[i++] = ( (Integer) iter.next() ).intValue();
+		}
+		return arr;
+	}
+
+	public static boolean[] toBooleanArray(Collection coll) {
+		Iterator iter = coll.iterator();
+		boolean[] arr = new boolean[ coll.size() ];
+		int i=0;
+		while( iter.hasNext() ) {
+			arr[i++] = ( (Boolean) iter.next() ).booleanValue();
+		}
+		return arr;
+	}
+
+	public static Object[] typecast(Object[] array, Object[] to) {
+		return java.util.Arrays.asList(array).toArray(to);
+	}
+
+	//Arrays.asList doesn't do primitive arrays
+	public static List toList(Object array) {
+		if ( array instanceof Object[] ) return Arrays.asList( (Object[]) array ); //faster?
+		int size = Array.getLength(array);
+		ArrayList list = new ArrayList(size);
+		for (int i=0; i<size; i++) {
+			list.add( Array.get(array, i) );
+		}
+		return list;
+	}
+
+	public static String[] slice(String[] strings, int begin, int length) {
+		String[] result = new String[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = strings[begin+i];
+		}
+		return result;
+	}
+
+	public static Object[] slice(Object[] objects, int begin, int length) {
+		Object[] result = new Object[length];
+		for ( int i=0; i<length; i++ ) {
+			result[i] = objects[begin+i];
+		}
+		return result;
+	}
+
+	public static List toList(Iterator iter) {
+		List list = new ArrayList();
+		while ( iter.hasNext() ) {
+			list.add( iter.next() );
+		}
+		return list;
+	}
+
+	public static String[] join(String[] x, String[] y) {
+		String[] result = new String[ x.length + y.length ];
+		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
+		for ( int i=0; i<y.length; i++ ) result[i+x.length] = y[i];
+		return result;
+	}
+
+	public static String[] join(String[] x, String[] y, boolean[] use) {
+		String[] result = new String[ x.length + countTrue(use) ];
+		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
+		int k = x.length;
+		for ( int i=0; i<y.length; i++ ) {
+			if ( use[i] ) result[k++] = y[i];
+		}
+		return result;
+	}
+
+	public static int[] join(int[] x, int[] y) {
+		int[] result = new int[ x.length + y.length ];
+		for ( int i=0; i<x.length; i++ ) result[i] = x[i];
+		for ( int i=0; i<y.length; i++ ) result[i+x.length] = y[i];
+		return result;
+	}
+
+	public static final boolean[] TRUE = { true };
+	public static final boolean[] FALSE = { false };
+
+	private ArrayHelper() {}
+
+	public static String toString( Object[] array ) {
+		StringBuffer sb = new StringBuffer();
+		sb.append("[");
+		for (int i = 0; i < array.length; i++) {
+			sb.append( array[i] );
+			if( i<array.length-1 ) sb.append(",");
+		}
+		sb.append("]");
+		return sb.toString();
+	}
+
+	public static boolean isAllNegative(int[] array) {
+		for ( int i=0; i<array.length; i++ ) {
+			if ( array[i] >=0 ) return false;
+		}
+		return true;
+	}
+
+	public static boolean isAllTrue(boolean[] array) {
+		for ( int i=0; i<array.length; i++ ) {
+			if ( !array[i] ) return false;
+		}
+		return true;
+	}
+
+	public static int countTrue(boolean[] array) {
+		int result=0;
+		for ( int i=0; i<array.length; i++ ) {
+			if ( array[i] ) result++;
+		}
+		return result;
+	}
+
+	/*public static int countFalse(boolean[] array) {
+		int result=0;
+		for ( int i=0; i<array.length; i++ ) {
+			if ( !array[i] ) result++;
+		}
+		return result;
+	}*/
+
+	public static boolean isAllFalse(boolean[] array) {
+		for ( int i=0; i<array.length; i++ ) {
+			if ( array[i] ) return false;
+		}
+		return true;
+	}
+
+	public static void addAll(Collection collection, Object[] array) {
+		for ( int i=0; i<array.length; i++ ) {
+			collection.add( array[i] );
+		}
+	}
+
+	public static final String[] EMPTY_STRING_ARRAY = {};
+	public static final int[] EMPTY_INT_ARRAY = {};
+	public static final boolean[] EMPTY_BOOLEAN_ARRAY = {};
+	public static final Class[] EMPTY_CLASS_ARRAY = {};
+	public static final Object[] EMPTY_OBJECT_ARRAY = {};
+	public static final Type[] EMPTY_TYPE_ARRAY = {};
+	
+	public static int[] getBatchSizes(int maxBatchSize) {
+		int batchSize = maxBatchSize;
+		int n=1;
+		while ( batchSize>1 ) {
+			batchSize = getNextBatchSize(batchSize);
+			n++;
+		}
+		int[] result = new int[n];
+		batchSize = maxBatchSize;
+		for ( int i=0; i<n; i++ ) {
+			result[i] = batchSize;
+			batchSize = getNextBatchSize(batchSize);
+		}
+		return result;
+	}
+	
+	private static int getNextBatchSize(int batchSize) {
+		if (batchSize<=10) {
+			return batchSize-1; //allow 9,8,7,6,5,4,3,2,1
+		}
+		else if (batchSize/2 < 10) {
+			return 10;
+		}
+		else {
+			return batchSize / 2;
+		}
+	}
+
+	private static int SEED = 23;
+	private static int PRIME_NUMER = 37;
+
+	/**
+	 * calculate the array hash (only the first level)
+	 */
+	public static int hash(Object[] array) {
+		int length = array.length;
+		int seed = SEED;
+		for (int index = 0 ; index < length ; index++) {
+			seed = hash( seed, array[index] == null ? 0 : array[index].hashCode() );
+		}
+		return seed;
+	}
+
+	/**
+	 * calculate the array hash (only the first level)
+	 */
+	public static int hash(char[] array) {
+		int length = array.length;
+		int seed = SEED;
+		for (int index = 0 ; index < length ; index++) {
+			seed = hash( seed, (int) array[index] ) ;
+		}
+		return seed;
+	}
+
+	/**
+	 * calculate the array hash (only the first level)
+	 */
+	public static int hash(byte[] bytes) {
+		int length = bytes.length;
+		int seed = SEED;
+		for (int index = 0 ; index < length ; index++) {
+			seed = hash( seed, (int) bytes[index] ) ;
+		}
+		return seed;
+	}
+
+	private static int hash(int seed, int i) {
+		return PRIME_NUMER * seed + i;
+	}
+
+	/**
+	 * Compare 2 arrays only at the first level
+	 */
+	public static boolean isEquals(Object[] o1, Object[] o2) {
+		if (o1 == o2) return true;
+		if (o1 == null || o2 == null) return false;
+		int length = o1.length;
+		if (length != o2.length) return false;
+		for (int index = 0 ; index < length ; index++) {
+			if ( ! o1[index].equals( o2[index] ) ) return false;
+		}
+        return true;
+	}
+
+	/**
+	 * Compare 2 arrays only at the first level
+	 */
+	public static boolean isEquals(char[] o1, char[] o2) {
+		if (o1 == o2) return true;
+		if (o1 == null || o2 == null) return false;
+		int length = o1.length;
+		if (length != o2.length) return false;
+		for (int index = 0 ; index < length ; index++) {
+			if ( ! ( o1[index] == o2[index] ) ) return false;
+		}
+        return true;
+	}
+
+	/**
+	 * Compare 2 arrays only at the first level
+	 */
+	public static boolean isEquals(byte[] b1, byte[] b2) {
+		if (b1 == b2) return true;
+		if (b1 == null || b2 == null) return false;
+		int length = b1.length;
+		if (length != b2.length) return false;
+		for (int index = 0 ; index < length ; index++) {
+			if ( ! ( b1[index] == b2[index] ) ) return false;
+		}
+        return true;
+	}
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/BytesHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: BytesHelper.java 4597 2004-09-26 03:17:21Z oneovthafew $
-package org.hibernate.util;
-
-public final class BytesHelper {
-
-	private BytesHelper() {}
-
-	public static int toInt( byte[] bytes ) {
-		int result = 0;
-		for (int i=0; i<4; i++) {
-			result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
-		}
-		return result;
-	}
-	
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/BytesHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/BytesHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+public final class BytesHelper {
+
+	private BytesHelper() {}
+
+	public static int toInt( byte[] bytes ) {
+		int result = 0;
+		for (int i=0; i<4; i++) {
+			result = ( result << 8 ) - Byte.MIN_VALUE + (int) bytes[i];
+		}
+		return result;
+	}
+	
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/CalendarComparator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: CalendarComparator.java 4496 2004-09-04 13:01:55Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.Calendar;
-import java.util.Comparator;
-
-/**
- * @author Gavin King
- */
-public class CalendarComparator implements Comparator {
-
-	public int compare(Object x, Object y) {
-		Calendar xcal = (Calendar) x;
-		Calendar ycal = (Calendar) y;
-		if ( xcal.before(ycal) ) return -1;
-		if ( xcal.after(ycal) ) return 1;
-		return 0;
-	}
-	
-	public static final Comparator INSTANCE = new CalendarComparator();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/CalendarComparator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CalendarComparator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.util.Calendar;
+import java.util.Comparator;
+
+/**
+ * @author Gavin King
+ */
+public class CalendarComparator implements Comparator {
+
+	public int compare(Object x, Object y) {
+		Calendar xcal = (Calendar) x;
+		Calendar ycal = (Calendar) y;
+		if ( xcal.before(ycal) ) return -1;
+		if ( xcal.after(ycal) ) return 1;
+		return 0;
+	}
+	
+	public static final Comparator INSTANCE = new CalendarComparator();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/Cloneable.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,139 +0,0 @@
-//$Id: Cloneable.java 8670 2005-11-25 17:36:29Z epbernard $
-package org.hibernate.util;
-
-import java.beans.BeanInfo;
-import java.beans.IntrospectionException;
-import java.beans.Introspector;
-import java.beans.PropertyDescriptor;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.hibernate.HibernateException;
-
-/**
- * An object that is shallow-coneable
- * 
- * @author Steve Ebersole
- */
-public class Cloneable {
-	
-	private static final Object[] READER_METHOD_ARGS = new Object[0];
-
-	/**
-	 * Essentially performs a shallow copy of this SessionEventListenerConfig
-	 * instance; meaning the SessionEventListenerConfig itself is cloned, but
-	 * the individual listeners are <b>not</b> cloned.
-	 *
-	 * @return The SessionEventListenerConfig shallow copy.
-	 */
-	public Object shallowCopy() {
-		return AccessController.doPrivileged(
-		        new PrivilegedAction() {
-			        public Object run() {
-				        return copyListeners();
-			        }
-		        }
-			);
-	}
-
-	/**
-	 * Checks to ensure the SessionEventListenerConfig is fully
-	 * configured (basically, that none of the listeners is null).
-	 *
-	 * @throws HibernateException If the SessionEventListenerConfig
-	 * is not fully configured.
-	 */
-	public void validate() throws HibernateException {
-		AccessController.doPrivileged(
-		        new PrivilegedAction() {
-			        public Object run() {
-				        checkListeners();
-				        return null;
-			        }
-		        }
-			);
-
-	}
-
-	private Object copyListeners() {
-		Object copy = null;
-		BeanInfo beanInfo = null;
-		try {
-			beanInfo = Introspector.getBeanInfo( getClass(), Object.class );
-			internalCheckListeners( beanInfo );
-			copy = getClass().newInstance();
-			PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
-			for ( int i = 0, max = pds.length; i < max; i++ ) {
-				try {
-					pds[i].getWriteMethod().invoke(
-							copy,
-							new Object[] {
-								pds[i].getReadMethod().invoke( this, READER_METHOD_ARGS )
-							}
-						);
-				}
-				catch( Throwable t ) {
-					throw new HibernateException( "Unable copy copy listener [" + pds[i].getName() + "]" );
-				}
-			}
-		}
-		catch( Exception t ) {
-			throw new HibernateException( "Unable to copy listeners", t );
-		}
-		finally {
-			if ( beanInfo != null ) {
-				// release the jdk internal caches everytime to ensure this
-				// plays nicely with destroyable class-loaders
-				Introspector.flushFromCaches( getClass() );
-			}
-		}
-		
-		return copy;
-	}
-
-	private void checkListeners() {
-		BeanInfo beanInfo = null;
-		try {
-			beanInfo = Introspector.getBeanInfo( getClass(), Object.class );
-			internalCheckListeners( beanInfo );
-		}
-		catch( IntrospectionException t ) {
-			throw new HibernateException( "Unable to validate listener config", t );
-		}
-		finally {
-			if ( beanInfo != null ) {
-				// release the jdk internal caches everytime to ensure this
-				// plays nicely with destroyable class-loaders
-				Introspector.flushFromCaches( getClass() );
-			}
-		}
-	}
-
-	private void internalCheckListeners(BeanInfo beanInfo) {
-		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
-		try {
-			for ( int i = 0, max = pds.length; i < max; i++ ) {
-				final Object listener = pds[i].getReadMethod().invoke( this, READER_METHOD_ARGS );
-				if ( listener == null ) {
-					throw new HibernateException( "Listener [" + pds[i].getName() + "] was null" );
-				}
-				if ( listener.getClass().isArray() ) {
-					Object[] listenerArray = (Object[]) listener;
-					int length = listenerArray.length;
-					for ( int index = 0 ; index < length ; index++ ) {
-						if ( listenerArray[index] == null ) {
-							throw new HibernateException( "Listener in [" + pds[i].getName() + "] was null" );
-						}
-					}
-				}
-			}
-		}
-		catch( HibernateException e ) {
-			throw e;
-		}
-		catch( Throwable t ) {
-			throw new HibernateException( "Unable to validate listener config" );
-		}
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/Cloneable.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/Cloneable.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.hibernate.HibernateException;
+
+/**
+ * An object that is shallow-coneable
+ * 
+ * @author Steve Ebersole
+ */
+public class Cloneable {
+	
+	private static final Object[] READER_METHOD_ARGS = new Object[0];
+
+	/**
+	 * Essentially performs a shallow copy of this SessionEventListenerConfig
+	 * instance; meaning the SessionEventListenerConfig itself is cloned, but
+	 * the individual listeners are <b>not</b> cloned.
+	 *
+	 * @return The SessionEventListenerConfig shallow copy.
+	 */
+	public Object shallowCopy() {
+		return AccessController.doPrivileged(
+		        new PrivilegedAction() {
+			        public Object run() {
+				        return copyListeners();
+			        }
+		        }
+			);
+	}
+
+	/**
+	 * Checks to ensure the SessionEventListenerConfig is fully
+	 * configured (basically, that none of the listeners is null).
+	 *
+	 * @throws HibernateException If the SessionEventListenerConfig
+	 * is not fully configured.
+	 */
+	public void validate() throws HibernateException {
+		AccessController.doPrivileged(
+		        new PrivilegedAction() {
+			        public Object run() {
+				        checkListeners();
+				        return null;
+			        }
+		        }
+			);
+
+	}
+
+	private Object copyListeners() {
+		Object copy = null;
+		BeanInfo beanInfo = null;
+		try {
+			beanInfo = Introspector.getBeanInfo( getClass(), Object.class );
+			internalCheckListeners( beanInfo );
+			copy = getClass().newInstance();
+			PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
+			for ( int i = 0, max = pds.length; i < max; i++ ) {
+				try {
+					pds[i].getWriteMethod().invoke(
+							copy,
+							new Object[] {
+								pds[i].getReadMethod().invoke( this, READER_METHOD_ARGS )
+							}
+						);
+				}
+				catch( Throwable t ) {
+					throw new HibernateException( "Unable copy copy listener [" + pds[i].getName() + "]" );
+				}
+			}
+		}
+		catch( Exception t ) {
+			throw new HibernateException( "Unable to copy listeners", t );
+		}
+		finally {
+			if ( beanInfo != null ) {
+				// release the jdk internal caches everytime to ensure this
+				// plays nicely with destroyable class-loaders
+				Introspector.flushFromCaches( getClass() );
+			}
+		}
+		
+		return copy;
+	}
+
+	private void checkListeners() {
+		BeanInfo beanInfo = null;
+		try {
+			beanInfo = Introspector.getBeanInfo( getClass(), Object.class );
+			internalCheckListeners( beanInfo );
+		}
+		catch( IntrospectionException t ) {
+			throw new HibernateException( "Unable to validate listener config", t );
+		}
+		finally {
+			if ( beanInfo != null ) {
+				// release the jdk internal caches everytime to ensure this
+				// plays nicely with destroyable class-loaders
+				Introspector.flushFromCaches( getClass() );
+			}
+		}
+	}
+
+	private void internalCheckListeners(BeanInfo beanInfo) {
+		PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
+		try {
+			for ( int i = 0, max = pds.length; i < max; i++ ) {
+				final Object listener = pds[i].getReadMethod().invoke( this, READER_METHOD_ARGS );
+				if ( listener == null ) {
+					throw new HibernateException( "Listener [" + pds[i].getName() + "] was null" );
+				}
+				if ( listener.getClass().isArray() ) {
+					Object[] listenerArray = (Object[]) listener;
+					int length = listenerArray.length;
+					for ( int index = 0 ; index < length ; index++ ) {
+						if ( listenerArray[index] == null ) {
+							throw new HibernateException( "Listener in [" + pds[i].getName() + "] was null" );
+						}
+					}
+				}
+			}
+		}
+		catch( HibernateException e ) {
+			throw e;
+		}
+		catch( Throwable t ) {
+			throw new HibernateException( "Unable to validate listener config" );
+		}
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/CollectionHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,22 +0,0 @@
-//$Id: CollectionHelper.java 7516 2005-07-16 22:20:48Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Gavin King
- */
-public final class CollectionHelper {
-
-	public static final List EMPTY_LIST = Collections.unmodifiableList( new ArrayList(0) );
-	public static final Collection EMPTY_COLLECTION = Collections.unmodifiableCollection( new ArrayList(0) );
-	public static final Map EMPTY_MAP = Collections.unmodifiableMap( new HashMap(0) );
-	
-	private CollectionHelper() {}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/CollectionHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/CollectionHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Gavin King
+ */
+public final class CollectionHelper {
+
+	public static final List EMPTY_LIST = Collections.unmodifiableList( new ArrayList(0) );
+	public static final Collection EMPTY_COLLECTION = Collections.unmodifiableCollection( new ArrayList(0) );
+	public static final Map EMPTY_MAP = Collections.unmodifiableMap( new HashMap(0) );
+	
+	private CollectionHelper() {}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ComparableComparator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,18 +0,0 @@
-//$Id: ComparableComparator.java 4496 2004-09-04 13:01:55Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.Comparator;
-
-/**
- * Delegates to Comparable
- * @author Gavin King
- */
-public class ComparableComparator implements Comparator {
-
-	public int compare(Object x, Object y) {
-		return ( (Comparable) x ).compareTo(y);
-	}
-	
-	public static final Comparator INSTANCE = new ComparableComparator();
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/ComparableComparator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ComparableComparator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.util.Comparator;
+
+/**
+ * Delegates to Comparable
+ * @author Gavin King
+ */
+public class ComparableComparator implements Comparator {
+
+	public int compare(Object x, Object y) {
+		return ( (Comparable) x ).compareTo(y);
+	}
+	
+	public static final Comparator INSTANCE = new ComparableComparator();
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ConfigHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,181 +0,0 @@
-// $Id: ConfigHelper.java 9972 2006-05-31 16:59:05Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Properties;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.hibernate.HibernateException;
-import org.hibernate.cfg.Environment;
-
-/**
- * A simple class to centralize logic needed to locate config files on the system.
- *
- * @author Steve
- */
-public final class ConfigHelper {
-	private static final Logger log = LoggerFactory.getLogger(ConfigHelper.class);
-
-	/** Try to locate a local URL representing the incoming path.  The first attempt
-	 * assumes that the incoming path is an actual URL string (file://, etc).  If this
-	 * does not work, then the next attempts try to locate this UURL as a java system
-	 * resource.
-	 *
-	 * @param path The path representing the config location.
-	 * @return An appropriate URL or null.
-	 */
-	public static final URL locateConfig(final String path) {
-		try {
-			return new URL(path);
-		}
-		catch(MalformedURLException e) {
-			return findAsResource(path);
-		}
-	}
-
-	/** 
-	 * Try to locate a local URL representing the incoming path.  
-	 * This method <b>only</b> attempts to locate this URL as a 
-	 * java system resource.
-	 *
-	 * @param path The path representing the config location.
-	 * @return An appropriate URL or null.
-	 */
-	public static final URL findAsResource(final String path) {
-		URL url = null;
-
-		// First, try to locate this resource through the current
-		// context classloader.
-		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-		if (contextClassLoader!=null) {
-			url = contextClassLoader.getResource(path);
-		}
-		if (url != null)
-			return url;
-
-		// Next, try to locate this resource through this class's classloader
-		url = ConfigHelper.class.getClassLoader().getResource(path);
-		if (url != null)
-			return url;
-
-		// Next, try to locate this resource through the system classloader
-		url = ClassLoader.getSystemClassLoader().getResource(path);
-
-		// Anywhere else we should look?
-		return url;
-	}
-
-	/** Open an InputStream to the URL represented by the incoming path.  First makes a call
-	 * to {@link #locateConfig(java.lang.String)} in order to find an appropriate URL.
-	 * {@link java.net.URL#openStream()} is then called to obtain the stream.
-	 *
-	 * @param path The path representing the config location.
-	 * @return An input stream to the requested config resource.
-	 * @throws HibernateException Unable to open stream to that resource.
-	 */
-	public static final InputStream getConfigStream(final String path) throws HibernateException {
-		final URL url = ConfigHelper.locateConfig(path);
-
-		if (url == null) {
-			String msg = "Unable to locate config file: " + path;
-			log.error( msg );
-			throw new HibernateException(msg);
-		}
-
-		try {
-			return url.openStream();
-        }
-		catch(IOException e) {
-	        throw new HibernateException("Unable to open config file: " + path, e);
-        }
-	}
-
-	/** Open an Reader to the URL represented by the incoming path.  First makes a call
-	 * to {@link #locateConfig(java.lang.String)} in order to find an appropriate URL.
-	 * {@link java.net.URL#openStream()} is then called to obtain a stream, which is then
-	 * wrapped in a Reader.
-	 *
-	 * @param path The path representing the config location.
-	 * @return An input stream to the requested config resource.
-	 * @throws HibernateException Unable to open reader to that resource.
-	 */
-	public static final Reader getConfigStreamReader(final String path) throws HibernateException {
-		return new InputStreamReader( getConfigStream(path) );
-	}
-
-	/** Loads a properties instance based on the data at the incoming config location.
-	 *
-	 * @param path The path representing the config location.
-	 * @return The loaded properties instance.
-	 * @throws HibernateException Unable to load properties from that resource.
-	 */
-	public static final Properties getConfigProperties(String path) throws HibernateException {
-		try {
-			Properties properties = new Properties();
-			properties.load( getConfigStream(path) );
-			return properties;
-		}
-		catch(IOException e) {
-			throw new HibernateException("Unable to load properties from specified config file: " + path, e);
-		}
-	}
-	
-	private ConfigHelper() {}
-
-	public static InputStream getResourceAsStream(String resource) {
-		String stripped = resource.startsWith("/") ?
-				resource.substring(1) : resource;
-
-		InputStream stream = null;
-		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-		if (classLoader!=null) {
-			stream = classLoader.getResourceAsStream( stripped );
-		}
-		if ( stream == null ) {
-			stream = Environment.class.getResourceAsStream( resource );
-		}
-		if ( stream == null ) {
-			stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
-		}
-		if ( stream == null ) {
-			throw new HibernateException( resource + " not found" );
-		}
-		return stream;
-	}
-
-
-	public static InputStream getUserResourceAsStream(String resource) {
-		boolean hasLeadingSlash = resource.startsWith( "/" );
-		String stripped = hasLeadingSlash ? resource.substring(1) : resource;
-
-		InputStream stream = null;
-
-		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
-		if ( classLoader != null ) {
-			stream = classLoader.getResourceAsStream( resource );
-			if ( stream == null && hasLeadingSlash ) {
-				stream = classLoader.getResourceAsStream( stripped );
-			}
-		}
-
-		if ( stream == null ) {
-			stream = Environment.class.getClassLoader().getResourceAsStream( resource );
-		}
-		if ( stream == null && hasLeadingSlash ) {
-			stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
-		}
-
-		if ( stream == null ) {
-			throw new HibernateException( resource + " not found" );
-		}
-
-		return stream;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/ConfigHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ConfigHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,204 @@
+/*
+ * 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.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.cfg.Environment;
+
+/**
+ * A simple class to centralize logic needed to locate config files on the system.
+ *
+ * @author Steve
+ */
+public final class ConfigHelper {
+	private static final Logger log = LoggerFactory.getLogger(ConfigHelper.class);
+
+	/** Try to locate a local URL representing the incoming path.  The first attempt
+	 * assumes that the incoming path is an actual URL string (file://, etc).  If this
+	 * does not work, then the next attempts try to locate this UURL as a java system
+	 * resource.
+	 *
+	 * @param path The path representing the config location.
+	 * @return An appropriate URL or null.
+	 */
+	public static final URL locateConfig(final String path) {
+		try {
+			return new URL(path);
+		}
+		catch(MalformedURLException e) {
+			return findAsResource(path);
+		}
+	}
+
+	/** 
+	 * Try to locate a local URL representing the incoming path.  
+	 * This method <b>only</b> attempts to locate this URL as a 
+	 * java system resource.
+	 *
+	 * @param path The path representing the config location.
+	 * @return An appropriate URL or null.
+	 */
+	public static final URL findAsResource(final String path) {
+		URL url = null;
+
+		// First, try to locate this resource through the current
+		// context classloader.
+		ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+		if (contextClassLoader!=null) {
+			url = contextClassLoader.getResource(path);
+		}
+		if (url != null)
+			return url;
+
+		// Next, try to locate this resource through this class's classloader
+		url = ConfigHelper.class.getClassLoader().getResource(path);
+		if (url != null)
+			return url;
+
+		// Next, try to locate this resource through the system classloader
+		url = ClassLoader.getSystemClassLoader().getResource(path);
+
+		// Anywhere else we should look?
+		return url;
+	}
+
+	/** Open an InputStream to the URL represented by the incoming path.  First makes a call
+	 * to {@link #locateConfig(java.lang.String)} in order to find an appropriate URL.
+	 * {@link java.net.URL#openStream()} is then called to obtain the stream.
+	 *
+	 * @param path The path representing the config location.
+	 * @return An input stream to the requested config resource.
+	 * @throws HibernateException Unable to open stream to that resource.
+	 */
+	public static final InputStream getConfigStream(final String path) throws HibernateException {
+		final URL url = ConfigHelper.locateConfig(path);
+
+		if (url == null) {
+			String msg = "Unable to locate config file: " + path;
+			log.error( msg );
+			throw new HibernateException(msg);
+		}
+
+		try {
+			return url.openStream();
+        }
+		catch(IOException e) {
+	        throw new HibernateException("Unable to open config file: " + path, e);
+        }
+	}
+
+	/** Open an Reader to the URL represented by the incoming path.  First makes a call
+	 * to {@link #locateConfig(java.lang.String)} in order to find an appropriate URL.
+	 * {@link java.net.URL#openStream()} is then called to obtain a stream, which is then
+	 * wrapped in a Reader.
+	 *
+	 * @param path The path representing the config location.
+	 * @return An input stream to the requested config resource.
+	 * @throws HibernateException Unable to open reader to that resource.
+	 */
+	public static final Reader getConfigStreamReader(final String path) throws HibernateException {
+		return new InputStreamReader( getConfigStream(path) );
+	}
+
+	/** Loads a properties instance based on the data at the incoming config location.
+	 *
+	 * @param path The path representing the config location.
+	 * @return The loaded properties instance.
+	 * @throws HibernateException Unable to load properties from that resource.
+	 */
+	public static final Properties getConfigProperties(String path) throws HibernateException {
+		try {
+			Properties properties = new Properties();
+			properties.load( getConfigStream(path) );
+			return properties;
+		}
+		catch(IOException e) {
+			throw new HibernateException("Unable to load properties from specified config file: " + path, e);
+		}
+	}
+	
+	private ConfigHelper() {}
+
+	public static InputStream getResourceAsStream(String resource) {
+		String stripped = resource.startsWith("/") ?
+				resource.substring(1) : resource;
+
+		InputStream stream = null;
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+		if (classLoader!=null) {
+			stream = classLoader.getResourceAsStream( stripped );
+		}
+		if ( stream == null ) {
+			stream = Environment.class.getResourceAsStream( resource );
+		}
+		if ( stream == null ) {
+			stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
+		}
+		if ( stream == null ) {
+			throw new HibernateException( resource + " not found" );
+		}
+		return stream;
+	}
+
+
+	public static InputStream getUserResourceAsStream(String resource) {
+		boolean hasLeadingSlash = resource.startsWith( "/" );
+		String stripped = hasLeadingSlash ? resource.substring(1) : resource;
+
+		InputStream stream = null;
+
+		ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+		if ( classLoader != null ) {
+			stream = classLoader.getResourceAsStream( resource );
+			if ( stream == null && hasLeadingSlash ) {
+				stream = classLoader.getResourceAsStream( stripped );
+			}
+		}
+
+		if ( stream == null ) {
+			stream = Environment.class.getClassLoader().getResourceAsStream( resource );
+		}
+		if ( stream == null && hasLeadingSlash ) {
+			stream = Environment.class.getClassLoader().getResourceAsStream( stripped );
+		}
+
+		if ( stream == null ) {
+			throw new HibernateException( resource + " not found" );
+		}
+
+		return stream;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/DTDEntityResolver.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,89 +0,0 @@
-//$Id: DTDEntityResolver.java 10033 2006-06-21 06:23:30Z christian.bauer at jboss.com $
-//Contributed by Markus Meissner
-package org.hibernate.util;
-
-import java.io.InputStream;
-import java.io.Serializable;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-
-/**
- * An {@link EntityResolver} implementation which attempts to resolve
- * various systemId URLs to local classpath lookups<ol>
- * <li>Any systemId URL beginning with <tt>http://hibernate.sourceforge.net/</tt> is
- * searched for as a classpath resource in the classloader which loaded the
- * Hibernate classes.</li>
- * <li>Any systemId URL using <tt>classpath</tt> as the scheme (i.e. starting
- * with <tt>classpath://</tt> is searched for as a classpath resource using first
- * the current thread context classloader and then the classloader which loaded
- * the Hibernate classes.
- * </ol>
- * <p/>
- * Any entity references which cannot be resolved in relation to the above
- * rules result in returning null, which should force the SAX reader to
- * handle the entity reference in its default manner.
- */
-public class DTDEntityResolver implements EntityResolver, Serializable {
-
-	private static final Logger log = LoggerFactory.getLogger( DTDEntityResolver.class );
-
-	private static final String HIBERNATE_NAMESPACE = "http://hibernate.sourceforge.net/";
-	private static final String USER_NAMESPACE = "classpath://";
-
-	public InputSource resolveEntity(String publicId, String systemId) {
-		if ( systemId != null ) {
-			log.debug( "trying to resolve system-id [" + systemId + "]" );
-			if ( systemId.startsWith( HIBERNATE_NAMESPACE ) ) {
-				log.debug( "recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/" );
-				String path = "org/hibernate/" + systemId.substring( HIBERNATE_NAMESPACE.length() );
-				InputStream dtdStream = resolveInHibernateNamespace( path );
-				if ( dtdStream == null ) {
-					log.debug( "unable to locate [" + systemId + "] on classpath" );
-					if ( systemId.substring( HIBERNATE_NAMESPACE.length() ).indexOf( "2.0" ) > -1 ) {
-						log.error( "Don't use old DTDs, read the Hibernate 3.x Migration Guide!" );
-					}
-				}
-				else {
-					log.debug( "located [" + systemId + "] in classpath" );
-					InputSource source = new InputSource( dtdStream );
-					source.setPublicId( publicId );
-					source.setSystemId( systemId );
-					return source;
-				}
-			}
-			else if ( systemId.startsWith( USER_NAMESPACE ) ) {
-				log.debug( "recognized local namespace; attempting to resolve on classpath" );
-				String path = systemId.substring( USER_NAMESPACE.length() );
-				InputStream stream = resolveInLocalNamespace( path );
-				if ( stream == null ) {
-					log.debug( "unable to locate [" + systemId + "] on classpath" );
-				}
-				else {
-					log.debug( "located [" + systemId + "] in classpath" );
-					InputSource source = new InputSource( stream );
-					source.setPublicId( publicId );
-					source.setSystemId( systemId );
-					return source;
-				}
-			}
-		}
-		// use default behavior
-		return null;
-	}
-
-	protected InputStream resolveInHibernateNamespace(String path) {
-		return this.getClass().getClassLoader().getResourceAsStream( path );
-	}
-
-	protected InputStream resolveInLocalNamespace(String path) {
-		try {
-			return ConfigHelper.getUserResourceAsStream( path );
-		}
-		catch( Throwable t ) {
-			return null;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/DTDEntityResolver.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/DTDEntityResolver.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,115 @@
+/*
+ * 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.util;
+
+import java.io.InputStream;
+import java.io.Serializable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+
+/**
+ * An {@link EntityResolver} implementation which attempts to resolve
+ * various systemId URLs to local classpath lookups<ol>
+ * <li>Any systemId URL beginning with <tt>http://hibernate.sourceforge.net/</tt> is
+ * searched for as a classpath resource in the classloader which loaded the
+ * Hibernate classes.</li>
+ * <li>Any systemId URL using <tt>classpath</tt> as the scheme (i.e. starting
+ * with <tt>classpath://</tt> is searched for as a classpath resource using first
+ * the current thread context classloader and then the classloader which loaded
+ * the Hibernate classes.
+ * </ol>
+ * <p/>
+ * Any entity references which cannot be resolved in relation to the above
+ * rules result in returning null, which should force the SAX reader to
+ * handle the entity reference in its default manner.
+ *
+ * @author Markus Meissner
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public class DTDEntityResolver implements EntityResolver, Serializable {
+
+	private static final Logger log = LoggerFactory.getLogger( DTDEntityResolver.class );
+
+	private static final String HIBERNATE_NAMESPACE = "http://hibernate.sourceforge.net/";
+	private static final String USER_NAMESPACE = "classpath://";
+
+	public InputSource resolveEntity(String publicId, String systemId) {
+		if ( systemId != null ) {
+			log.debug( "trying to resolve system-id [" + systemId + "]" );
+			if ( systemId.startsWith( HIBERNATE_NAMESPACE ) ) {
+				log.debug( "recognized hibernate namespace; attempting to resolve on classpath under org/hibernate/" );
+				String path = "org/hibernate/" + systemId.substring( HIBERNATE_NAMESPACE.length() );
+				InputStream dtdStream = resolveInHibernateNamespace( path );
+				if ( dtdStream == null ) {
+					log.debug( "unable to locate [" + systemId + "] on classpath" );
+					if ( systemId.substring( HIBERNATE_NAMESPACE.length() ).indexOf( "2.0" ) > -1 ) {
+						log.error( "Don't use old DTDs, read the Hibernate 3.x Migration Guide!" );
+					}
+				}
+				else {
+					log.debug( "located [" + systemId + "] in classpath" );
+					InputSource source = new InputSource( dtdStream );
+					source.setPublicId( publicId );
+					source.setSystemId( systemId );
+					return source;
+				}
+			}
+			else if ( systemId.startsWith( USER_NAMESPACE ) ) {
+				log.debug( "recognized local namespace; attempting to resolve on classpath" );
+				String path = systemId.substring( USER_NAMESPACE.length() );
+				InputStream stream = resolveInLocalNamespace( path );
+				if ( stream == null ) {
+					log.debug( "unable to locate [" + systemId + "] on classpath" );
+				}
+				else {
+					log.debug( "located [" + systemId + "] in classpath" );
+					InputSource source = new InputSource( stream );
+					source.setPublicId( publicId );
+					source.setSystemId( systemId );
+					return source;
+				}
+			}
+		}
+		// use default behavior
+		return null;
+	}
+
+	protected InputStream resolveInHibernateNamespace(String path) {
+		return this.getClass().getClassLoader().getResourceAsStream( path );
+	}
+
+	protected InputStream resolveInLocalNamespace(String path) {
+		try {
+			return ConfigHelper.getUserResourceAsStream( path );
+		}
+		catch( Throwable t ) {
+			return null;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/EmptyIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-//$Id: EmptyIterator.java 3890 2004-06-03 16:31:32Z steveebersole $
-package org.hibernate.util;
-
-import java.util.Iterator;
-
-/**
- * @author Gavin King
- */
-public final class EmptyIterator implements Iterator {
-
-	public static final Iterator INSTANCE = new EmptyIterator();
-
-	public boolean hasNext() {
-		return false;
-	}
-
-	public Object next() {
-		throw new UnsupportedOperationException();
-	}
-
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	private EmptyIterator() {}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/EmptyIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EmptyIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,50 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+
+/**
+ * @author Gavin King
+ */
+public final class EmptyIterator implements Iterator {
+
+	public static final Iterator INSTANCE = new EmptyIterator();
+
+	public boolean hasNext() {
+		return false;
+	}
+
+	public Object next() {
+		throw new UnsupportedOperationException();
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	private EmptyIterator() {}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/EqualsHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,15 +0,0 @@
-//$Id: EqualsHelper.java 4582 2004-09-25 11:22:20Z oneovthafew $
-package org.hibernate.util;
-
-/**
- * @author Gavin King
- */
-public final class EqualsHelper {
-
-	public static boolean equals(Object x, Object y) {
-		return x==y || ( x!=null && y!=null && x.equals(y) );
-	}
-	
-	private EqualsHelper() {}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/EqualsHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/EqualsHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+/**
+ * @author Gavin King
+ */
+public final class EqualsHelper {
+
+	public static boolean equals(Object x, Object y) {
+		return x==y || ( x!=null && y!=null && x.equals(y) );
+	}
+	
+	private EqualsHelper() {}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,374 +0,0 @@
-// $Id: ExternalSessionFactoryConfig.java 10860 2006-11-22 00:02:55Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
-
-import java.util.Properties;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.HashMap;
-import java.util.HashSet;
-
-/**
- * Defines support for various externally configurable SessionFactory(s), for
- * example, {@link org.hibernate.jmx.HibernateService JMX} or the JCA
- * adapter.
- *
- * @author Steve Ebersole
- */
-public abstract class ExternalSessionFactoryConfig {
-
-	private String mapResources;
-	private String dialect;
-	private String defaultSchema;
-	private String defaultCatalog;
-	private String maximumFetchDepth;
-	private String jdbcFetchSize;
-	private String jdbcBatchSize;
-	private String batchVersionedDataEnabled;
-	private String jdbcScrollableResultSetEnabled;
-	private String getGeneratedKeysEnabled;
-	private String streamsForBinaryEnabled;
-	private String reflectionOptimizationEnabled;
-	private String querySubstitutions;
-	private String showSqlEnabled;
-	private String commentsEnabled;
-	private String cacheProviderClass;
-	private String cacheProviderConfig;
-	private String cacheRegionPrefix;
-	private String secondLevelCacheEnabled;
-	private String minimalPutsEnabled;
-	private String queryCacheEnabled;
-
-	private Map additionalProperties;
-	private Set excludedPropertyNames = new HashSet();
-	private Map customListeners;
-
-
-	protected Set getExcludedPropertyNames() {
-		return excludedPropertyNames;
-	}
-
-	public final String getMapResources() {
-		return mapResources;
-	}
-
-	public final void setMapResources(String mapResources) {
-		this.mapResources = mapResources;
-	}
-
-	public void addMapResource(String mapResource) {
-		if ( mapResources==null || mapResources.length()==0 ) {
-			mapResources = mapResource.trim();
-		}
-		else {
-			mapResources += ", " + mapResource.trim();
-		}
-	}
-
-	public final String getDialect() {
-		return dialect;
-	}
-
-	public final void setDialect(String dialect) {
-		this.dialect = dialect;
-	}
-
-	public final String getDefaultSchema() {
-		return defaultSchema;
-	}
-
-	public final void setDefaultSchema(String defaultSchema) {
-		this.defaultSchema = defaultSchema;
-	}
-
-	public final String getDefaultCatalog() {
-		return defaultCatalog;
-	}
-
-	public final void setDefaultCatalog(String defaultCatalog) {
-		this.defaultCatalog = defaultCatalog;
-	}
-
-	public final String getMaximumFetchDepth() {
-		return maximumFetchDepth;
-	}
-
-	public final void setMaximumFetchDepth(String maximumFetchDepth) {
-		verifyInt( maximumFetchDepth );
-		this.maximumFetchDepth = maximumFetchDepth;
-	}
-
-	public final String getJdbcFetchSize() {
-		return jdbcFetchSize;
-	}
-
-	public final void setJdbcFetchSize(String jdbcFetchSize) {
-		verifyInt( jdbcFetchSize );
-		this.jdbcFetchSize = jdbcFetchSize;
-	}
-
-	public final String getJdbcBatchSize() {
-		return jdbcBatchSize;
-	}
-
-	public final void setJdbcBatchSize(String jdbcBatchSize) {
-		verifyInt( jdbcBatchSize );
-		this.jdbcBatchSize = jdbcBatchSize;
-	}
-
-	public final String getBatchVersionedDataEnabled() {
-		return batchVersionedDataEnabled;
-	}
-
-	public final void setBatchVersionedDataEnabled(String batchVersionedDataEnabled) {
-		this.batchVersionedDataEnabled = batchVersionedDataEnabled;
-	}
-
-	public final String getJdbcScrollableResultSetEnabled() {
-		return jdbcScrollableResultSetEnabled;
-	}
-
-	public final void setJdbcScrollableResultSetEnabled(String jdbcScrollableResultSetEnabled) {
-		this.jdbcScrollableResultSetEnabled = jdbcScrollableResultSetEnabled;
-	}
-
-	public final String getGetGeneratedKeysEnabled() {
-		return getGeneratedKeysEnabled;
-	}
-
-	public final void setGetGeneratedKeysEnabled(String getGeneratedKeysEnabled) {
-		this.getGeneratedKeysEnabled = getGeneratedKeysEnabled;
-	}
-
-	public final String getStreamsForBinaryEnabled() {
-		return streamsForBinaryEnabled;
-	}
-
-	public final void setStreamsForBinaryEnabled(String streamsForBinaryEnabled) {
-		this.streamsForBinaryEnabled = streamsForBinaryEnabled;
-	}
-
-	public final String getReflectionOptimizationEnabled() {
-		return reflectionOptimizationEnabled;
-	}
-
-	public final void setReflectionOptimizationEnabled(String reflectionOptimizationEnabled) {
-		this.reflectionOptimizationEnabled = reflectionOptimizationEnabled;
-	}
-
-	public final String getQuerySubstitutions() {
-		return querySubstitutions;
-	}
-
-	public final void setQuerySubstitutions(String querySubstitutions) {
-		this.querySubstitutions = querySubstitutions;
-	}
-
-	public final String getShowSqlEnabled() {
-		return showSqlEnabled;
-	}
-
-	public final void setShowSqlEnabled(String showSqlEnabled) {
-		this.showSqlEnabled = showSqlEnabled;
-	}
-
-	public final String getCommentsEnabled() {
-		return commentsEnabled;
-	}
-
-	public final void setCommentsEnabled(String commentsEnabled) {
-		this.commentsEnabled = commentsEnabled;
-	}
-
-	public final String getSecondLevelCacheEnabled() {
-		return secondLevelCacheEnabled;
-	}
-
-	public final void setSecondLevelCacheEnabled(String secondLevelCacheEnabled) {
-		this.secondLevelCacheEnabled = secondLevelCacheEnabled;
-	}
-
-	public final String getCacheProviderClass() {
-		return cacheProviderClass;
-	}
-
-	public final void setCacheProviderClass(String cacheProviderClass) {
-		this.cacheProviderClass = cacheProviderClass;
-	}
-
-	public String getCacheProviderConfig() {
-		return cacheProviderConfig;
-	}
-
-	public void setCacheProviderConfig(String cacheProviderConfig) {
-		this.cacheProviderConfig = cacheProviderConfig;
-	}
-
-	public final String getCacheRegionPrefix() {
-		return cacheRegionPrefix;
-	}
-
-	public final void setCacheRegionPrefix(String cacheRegionPrefix) {
-		this.cacheRegionPrefix = cacheRegionPrefix;
-	}
-
-	public final String getMinimalPutsEnabled() {
-		return minimalPutsEnabled;
-	}
-
-	public final void setMinimalPutsEnabled(String minimalPutsEnabled) {
-		this.minimalPutsEnabled = minimalPutsEnabled;
-	}
-
-	public final String getQueryCacheEnabled() {
-		return queryCacheEnabled;
-	}
-
-	public final void setQueryCacheEnabled(String queryCacheEnabled) {
-		this.queryCacheEnabled = queryCacheEnabled;
-	}
-
-	public final Map getCustomListeners() {
-		return customListeners;
-	}
-
-	public void setCustomListeners(Map customListeners) {
-		this.customListeners = customListeners;
-	}
-
-	public void setCustomListenersAsString(String customListenersString) {
-		// Note : expected in the syntax:
-		//      type=listenerClass
-		//          ({sep}type=listenerClass)*
-		// where {sep} is any whitespace or comma
-		if ( StringHelper.isNotEmpty( customListenersString) ) {
-			String[] listenerEntries = PropertiesHelper.toStringArray( customListenersString, " ,\n\t\r\f" );
-			for ( int i = 0; i < listenerEntries.length; i++ ) {
-				final int keyValueSepPosition = listenerEntries[i].indexOf( '=' );
-				final String type = listenerEntries[i].substring( 0, keyValueSepPosition );
-				final String listenerClass = listenerEntries[i].substring( keyValueSepPosition + 1 );
-				setCustomListener( type, listenerClass );
-			}
-		}
-	}
-
-	public void setCustomListener(String type, String listenerClass) {
-		if ( customListeners == null ) {
-			customListeners = new HashMap();
-		}
-		customListeners.put( type, listenerClass );
-	}
-
-	public final void addAdditionalProperty(String name, String value) {
-		if ( !getExcludedPropertyNames().contains( name ) ) {
-			if ( additionalProperties == null ) {
-				additionalProperties = new HashMap();
-			}
-			additionalProperties.put( name, value );
-		}
-	}
-
-	protected final Configuration buildConfiguration() {
-
-		Configuration cfg = new Configuration().setProperties( buildProperties() );
-
-
-		String[] mappingFiles = PropertiesHelper.toStringArray( mapResources, " ,\n\t\r\f" );
-		for ( int i = 0; i < mappingFiles.length; i++ ) {
-			cfg.addResource( mappingFiles[i] );
-		}
-
-		if ( customListeners != null && !customListeners.isEmpty() ) {
-			Iterator entries = customListeners.entrySet().iterator();
-			while ( entries.hasNext() ) {
-				final Map.Entry entry = ( Map.Entry ) entries.next();
-				final String type = ( String ) entry.getKey();
-				final Object value = entry.getValue();
-				if ( value != null ) {
-					if ( String.class.isAssignableFrom( value.getClass() ) ) {
-						// Its the listener class name
-						cfg.setListener( type, ( ( String ) value ) );
-					}
-					else {
-						// Its the listener instance (or better be)
-						cfg.setListener( type, value );
-					}
-				}
-			}
-		}
-
-		return cfg;
-	}
-
-	protected final Properties buildProperties() {
-		Properties props = new Properties();
-		setUnlessNull( props, Environment.DIALECT, dialect );
-		setUnlessNull( props, Environment.DEFAULT_SCHEMA, defaultSchema );
-		setUnlessNull( props, Environment.DEFAULT_CATALOG, defaultCatalog );
-		setUnlessNull( props, Environment.MAX_FETCH_DEPTH, maximumFetchDepth );
-		setUnlessNull( props, Environment.STATEMENT_FETCH_SIZE, jdbcFetchSize );
-		setUnlessNull( props, Environment.STATEMENT_BATCH_SIZE, jdbcBatchSize );
-		setUnlessNull( props, Environment.BATCH_VERSIONED_DATA, batchVersionedDataEnabled );
-		setUnlessNull( props, Environment.USE_SCROLLABLE_RESULTSET, jdbcScrollableResultSetEnabled );
-		setUnlessNull( props, Environment.USE_GET_GENERATED_KEYS, getGeneratedKeysEnabled );
-		setUnlessNull( props, Environment.USE_STREAMS_FOR_BINARY, streamsForBinaryEnabled );
-		setUnlessNull( props, Environment.USE_REFLECTION_OPTIMIZER, reflectionOptimizationEnabled );
-		setUnlessNull( props, Environment.QUERY_SUBSTITUTIONS, querySubstitutions );
-		setUnlessNull( props, Environment.SHOW_SQL, showSqlEnabled );
-		setUnlessNull( props, Environment.USE_SQL_COMMENTS, commentsEnabled );
-		setUnlessNull( props, Environment.CACHE_PROVIDER, cacheProviderClass );
-		setUnlessNull( props, Environment.CACHE_PROVIDER_CONFIG, cacheProviderConfig );
-		setUnlessNull( props, Environment.CACHE_REGION_PREFIX, cacheRegionPrefix );
-		setUnlessNull( props, Environment.USE_MINIMAL_PUTS, minimalPutsEnabled );
-		setUnlessNull( props, Environment.USE_SECOND_LEVEL_CACHE, secondLevelCacheEnabled );
-		setUnlessNull( props, Environment.USE_QUERY_CACHE, queryCacheEnabled );
-
-		Map extraProperties = getExtraProperties();
-		if ( extraProperties != null ) {
-			addAll( props, extraProperties );
-		}
-
-		if ( additionalProperties != null ) {
-			addAll( props, additionalProperties );
-		}
-
-		return props;
-	}
-
-	protected void addAll( Properties target, Map source ) {
-		Iterator itr = source.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final String propertyName = ( String ) entry.getKey();
-			final String propertyValue = ( String ) entry.getValue();
-			if ( propertyName != null && propertyValue != null ) {
-				// Make sure we don't override previous set values
-				if ( !target.keySet().contains( propertyName ) ) {
-					if ( !getExcludedPropertyNames().contains( propertyName) ) {
-						target.put( propertyName, propertyValue );
-					}
-				}
-			}
-		}
-	}
-
-	protected Map getExtraProperties() {
-		return null;
-	}
-
-	private void setUnlessNull(Properties props, String key, String value) {
-		if ( value != null ) {
-			props.setProperty( key, value );
-		}
-	}
-
-	private void verifyInt(String value)
-	{
-		if ( value != null ) {
-			Integer.parseInt( value );
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ExternalSessionFactoryConfig.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,397 @@
+/*
+ * 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.util;
+
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+
+import java.util.Properties;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.HashSet;
+
+/**
+ * Defines support for various externally configurable SessionFactory(s), for
+ * example, {@link org.hibernate.jmx.HibernateService JMX} or the JCA
+ * adapter.
+ *
+ * @author Steve Ebersole
+ */
+public abstract class ExternalSessionFactoryConfig {
+
+	private String mapResources;
+	private String dialect;
+	private String defaultSchema;
+	private String defaultCatalog;
+	private String maximumFetchDepth;
+	private String jdbcFetchSize;
+	private String jdbcBatchSize;
+	private String batchVersionedDataEnabled;
+	private String jdbcScrollableResultSetEnabled;
+	private String getGeneratedKeysEnabled;
+	private String streamsForBinaryEnabled;
+	private String reflectionOptimizationEnabled;
+	private String querySubstitutions;
+	private String showSqlEnabled;
+	private String commentsEnabled;
+	private String cacheProviderClass;
+	private String cacheProviderConfig;
+	private String cacheRegionPrefix;
+	private String secondLevelCacheEnabled;
+	private String minimalPutsEnabled;
+	private String queryCacheEnabled;
+
+	private Map additionalProperties;
+	private Set excludedPropertyNames = new HashSet();
+	private Map customListeners;
+
+
+	protected Set getExcludedPropertyNames() {
+		return excludedPropertyNames;
+	}
+
+	public final String getMapResources() {
+		return mapResources;
+	}
+
+	public final void setMapResources(String mapResources) {
+		this.mapResources = mapResources;
+	}
+
+	public void addMapResource(String mapResource) {
+		if ( mapResources==null || mapResources.length()==0 ) {
+			mapResources = mapResource.trim();
+		}
+		else {
+			mapResources += ", " + mapResource.trim();
+		}
+	}
+
+	public final String getDialect() {
+		return dialect;
+	}
+
+	public final void setDialect(String dialect) {
+		this.dialect = dialect;
+	}
+
+	public final String getDefaultSchema() {
+		return defaultSchema;
+	}
+
+	public final void setDefaultSchema(String defaultSchema) {
+		this.defaultSchema = defaultSchema;
+	}
+
+	public final String getDefaultCatalog() {
+		return defaultCatalog;
+	}
+
+	public final void setDefaultCatalog(String defaultCatalog) {
+		this.defaultCatalog = defaultCatalog;
+	}
+
+	public final String getMaximumFetchDepth() {
+		return maximumFetchDepth;
+	}
+
+	public final void setMaximumFetchDepth(String maximumFetchDepth) {
+		verifyInt( maximumFetchDepth );
+		this.maximumFetchDepth = maximumFetchDepth;
+	}
+
+	public final String getJdbcFetchSize() {
+		return jdbcFetchSize;
+	}
+
+	public final void setJdbcFetchSize(String jdbcFetchSize) {
+		verifyInt( jdbcFetchSize );
+		this.jdbcFetchSize = jdbcFetchSize;
+	}
+
+	public final String getJdbcBatchSize() {
+		return jdbcBatchSize;
+	}
+
+	public final void setJdbcBatchSize(String jdbcBatchSize) {
+		verifyInt( jdbcBatchSize );
+		this.jdbcBatchSize = jdbcBatchSize;
+	}
+
+	public final String getBatchVersionedDataEnabled() {
+		return batchVersionedDataEnabled;
+	}
+
+	public final void setBatchVersionedDataEnabled(String batchVersionedDataEnabled) {
+		this.batchVersionedDataEnabled = batchVersionedDataEnabled;
+	}
+
+	public final String getJdbcScrollableResultSetEnabled() {
+		return jdbcScrollableResultSetEnabled;
+	}
+
+	public final void setJdbcScrollableResultSetEnabled(String jdbcScrollableResultSetEnabled) {
+		this.jdbcScrollableResultSetEnabled = jdbcScrollableResultSetEnabled;
+	}
+
+	public final String getGetGeneratedKeysEnabled() {
+		return getGeneratedKeysEnabled;
+	}
+
+	public final void setGetGeneratedKeysEnabled(String getGeneratedKeysEnabled) {
+		this.getGeneratedKeysEnabled = getGeneratedKeysEnabled;
+	}
+
+	public final String getStreamsForBinaryEnabled() {
+		return streamsForBinaryEnabled;
+	}
+
+	public final void setStreamsForBinaryEnabled(String streamsForBinaryEnabled) {
+		this.streamsForBinaryEnabled = streamsForBinaryEnabled;
+	}
+
+	public final String getReflectionOptimizationEnabled() {
+		return reflectionOptimizationEnabled;
+	}
+
+	public final void setReflectionOptimizationEnabled(String reflectionOptimizationEnabled) {
+		this.reflectionOptimizationEnabled = reflectionOptimizationEnabled;
+	}
+
+	public final String getQuerySubstitutions() {
+		return querySubstitutions;
+	}
+
+	public final void setQuerySubstitutions(String querySubstitutions) {
+		this.querySubstitutions = querySubstitutions;
+	}
+
+	public final String getShowSqlEnabled() {
+		return showSqlEnabled;
+	}
+
+	public final void setShowSqlEnabled(String showSqlEnabled) {
+		this.showSqlEnabled = showSqlEnabled;
+	}
+
+	public final String getCommentsEnabled() {
+		return commentsEnabled;
+	}
+
+	public final void setCommentsEnabled(String commentsEnabled) {
+		this.commentsEnabled = commentsEnabled;
+	}
+
+	public final String getSecondLevelCacheEnabled() {
+		return secondLevelCacheEnabled;
+	}
+
+	public final void setSecondLevelCacheEnabled(String secondLevelCacheEnabled) {
+		this.secondLevelCacheEnabled = secondLevelCacheEnabled;
+	}
+
+	public final String getCacheProviderClass() {
+		return cacheProviderClass;
+	}
+
+	public final void setCacheProviderClass(String cacheProviderClass) {
+		this.cacheProviderClass = cacheProviderClass;
+	}
+
+	public String getCacheProviderConfig() {
+		return cacheProviderConfig;
+	}
+
+	public void setCacheProviderConfig(String cacheProviderConfig) {
+		this.cacheProviderConfig = cacheProviderConfig;
+	}
+
+	public final String getCacheRegionPrefix() {
+		return cacheRegionPrefix;
+	}
+
+	public final void setCacheRegionPrefix(String cacheRegionPrefix) {
+		this.cacheRegionPrefix = cacheRegionPrefix;
+	}
+
+	public final String getMinimalPutsEnabled() {
+		return minimalPutsEnabled;
+	}
+
+	public final void setMinimalPutsEnabled(String minimalPutsEnabled) {
+		this.minimalPutsEnabled = minimalPutsEnabled;
+	}
+
+	public final String getQueryCacheEnabled() {
+		return queryCacheEnabled;
+	}
+
+	public final void setQueryCacheEnabled(String queryCacheEnabled) {
+		this.queryCacheEnabled = queryCacheEnabled;
+	}
+
+	public final Map getCustomListeners() {
+		return customListeners;
+	}
+
+	public void setCustomListeners(Map customListeners) {
+		this.customListeners = customListeners;
+	}
+
+	public void setCustomListenersAsString(String customListenersString) {
+		// Note : expected in the syntax:
+		//      type=listenerClass
+		//          ({sep}type=listenerClass)*
+		// where {sep} is any whitespace or comma
+		if ( StringHelper.isNotEmpty( customListenersString) ) {
+			String[] listenerEntries = PropertiesHelper.toStringArray( customListenersString, " ,\n\t\r\f" );
+			for ( int i = 0; i < listenerEntries.length; i++ ) {
+				final int keyValueSepPosition = listenerEntries[i].indexOf( '=' );
+				final String type = listenerEntries[i].substring( 0, keyValueSepPosition );
+				final String listenerClass = listenerEntries[i].substring( keyValueSepPosition + 1 );
+				setCustomListener( type, listenerClass );
+			}
+		}
+	}
+
+	public void setCustomListener(String type, String listenerClass) {
+		if ( customListeners == null ) {
+			customListeners = new HashMap();
+		}
+		customListeners.put( type, listenerClass );
+	}
+
+	public final void addAdditionalProperty(String name, String value) {
+		if ( !getExcludedPropertyNames().contains( name ) ) {
+			if ( additionalProperties == null ) {
+				additionalProperties = new HashMap();
+			}
+			additionalProperties.put( name, value );
+		}
+	}
+
+	protected final Configuration buildConfiguration() {
+
+		Configuration cfg = new Configuration().setProperties( buildProperties() );
+
+
+		String[] mappingFiles = PropertiesHelper.toStringArray( mapResources, " ,\n\t\r\f" );
+		for ( int i = 0; i < mappingFiles.length; i++ ) {
+			cfg.addResource( mappingFiles[i] );
+		}
+
+		if ( customListeners != null && !customListeners.isEmpty() ) {
+			Iterator entries = customListeners.entrySet().iterator();
+			while ( entries.hasNext() ) {
+				final Map.Entry entry = ( Map.Entry ) entries.next();
+				final String type = ( String ) entry.getKey();
+				final Object value = entry.getValue();
+				if ( value != null ) {
+					if ( String.class.isAssignableFrom( value.getClass() ) ) {
+						// Its the listener class name
+						cfg.setListener( type, ( ( String ) value ) );
+					}
+					else {
+						// Its the listener instance (or better be)
+						cfg.setListener( type, value );
+					}
+				}
+			}
+		}
+
+		return cfg;
+	}
+
+	protected final Properties buildProperties() {
+		Properties props = new Properties();
+		setUnlessNull( props, Environment.DIALECT, dialect );
+		setUnlessNull( props, Environment.DEFAULT_SCHEMA, defaultSchema );
+		setUnlessNull( props, Environment.DEFAULT_CATALOG, defaultCatalog );
+		setUnlessNull( props, Environment.MAX_FETCH_DEPTH, maximumFetchDepth );
+		setUnlessNull( props, Environment.STATEMENT_FETCH_SIZE, jdbcFetchSize );
+		setUnlessNull( props, Environment.STATEMENT_BATCH_SIZE, jdbcBatchSize );
+		setUnlessNull( props, Environment.BATCH_VERSIONED_DATA, batchVersionedDataEnabled );
+		setUnlessNull( props, Environment.USE_SCROLLABLE_RESULTSET, jdbcScrollableResultSetEnabled );
+		setUnlessNull( props, Environment.USE_GET_GENERATED_KEYS, getGeneratedKeysEnabled );
+		setUnlessNull( props, Environment.USE_STREAMS_FOR_BINARY, streamsForBinaryEnabled );
+		setUnlessNull( props, Environment.USE_REFLECTION_OPTIMIZER, reflectionOptimizationEnabled );
+		setUnlessNull( props, Environment.QUERY_SUBSTITUTIONS, querySubstitutions );
+		setUnlessNull( props, Environment.SHOW_SQL, showSqlEnabled );
+		setUnlessNull( props, Environment.USE_SQL_COMMENTS, commentsEnabled );
+		setUnlessNull( props, Environment.CACHE_PROVIDER, cacheProviderClass );
+		setUnlessNull( props, Environment.CACHE_PROVIDER_CONFIG, cacheProviderConfig );
+		setUnlessNull( props, Environment.CACHE_REGION_PREFIX, cacheRegionPrefix );
+		setUnlessNull( props, Environment.USE_MINIMAL_PUTS, minimalPutsEnabled );
+		setUnlessNull( props, Environment.USE_SECOND_LEVEL_CACHE, secondLevelCacheEnabled );
+		setUnlessNull( props, Environment.USE_QUERY_CACHE, queryCacheEnabled );
+
+		Map extraProperties = getExtraProperties();
+		if ( extraProperties != null ) {
+			addAll( props, extraProperties );
+		}
+
+		if ( additionalProperties != null ) {
+			addAll( props, additionalProperties );
+		}
+
+		return props;
+	}
+
+	protected void addAll( Properties target, Map source ) {
+		Iterator itr = source.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final String propertyName = ( String ) entry.getKey();
+			final String propertyValue = ( String ) entry.getValue();
+			if ( propertyName != null && propertyValue != null ) {
+				// Make sure we don't override previous set values
+				if ( !target.keySet().contains( propertyName ) ) {
+					if ( !getExcludedPropertyNames().contains( propertyName) ) {
+						target.put( propertyName, propertyValue );
+					}
+				}
+			}
+		}
+	}
+
+	protected Map getExtraProperties() {
+		return null;
+	}
+
+	private void setUnlessNull(Properties props, String key, String value) {
+		if ( value != null ) {
+			props.setProperty( key, value );
+		}
+	}
+
+	private void verifyInt(String value)
+	{
+		if ( value != null ) {
+			Integer.parseInt( value );
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/FastHashMap.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,368 +0,0 @@
-//$Id: FastHashMap.java 3890 2004-06-03 16:31:32Z steveebersole $
-/*
- * ====================================================================
- *
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowlegement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowlegement may appear in the software itself,
- *    if and wherever such third-party acknowlegements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Group.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- *
- */
-
-// This class was taken from Apache commons-collections -
-// I made it final + removed the "slow" mode...
-
-package org.hibernate.util;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * <p>A customized implementation of <code>java.util.HashMap</code> designed
- * to operate in a multithreaded environment where the large majority of
- * method calls are read-only, instead of structural changes.
- * Read calls are non-synchronized and write calls perform the
- * following steps:</p>
- * <ul>
- * <li>Clone the existing collection
- * <li>Perform the modification on the clone
- * <li>Replace the existing collection with the (modified) clone
- * </ul>
- * <p><strong>NOTE</strong>: If you are creating and accessing a
- * <code>HashMap</code> only within a single thread, you should use
- * <code>java.util.HashMap</code> directly (with no synchronization), for
- * maximum performance.</p>
- *
- */
-
-public final class FastHashMap implements Map, Serializable {
-
-	// ----------------------------------------------------------- Constructors
-
-	/**
-	 * Construct a an empty map.
-	 */
-	public FastHashMap() {
-
-		super();
-		this.map = new HashMap();
-
-	}
-
-	/**
-	 * Construct an empty map with the specified capacity.
-	 *
-	 * @param capacity The initial capacity of the empty map
-	 */
-	public FastHashMap(int capacity) {
-
-		super();
-		this.map = new HashMap(capacity);
-
-	}
-
-	/**
-	 * Construct an empty map with the specified capacity and load factor.
-	 *
-	 * @param capacity The initial capacity of the empty map
-	 * @param factor The load factor of the new map
-	 */
-	public FastHashMap(int capacity, float factor) {
-
-		super();
-		this.map = new HashMap(capacity, factor);
-
-	}
-
-	/**
-	 * Construct a new map with the same mappings as the specified map.
-	 *
-	 * @param map The map whose mappings are to be copied
-	 */
-	public FastHashMap(Map map) {
-
-		super();
-		this.map = new HashMap(map);
-
-	}
-
-	// ----------------------------------------------------- Instance Variables
-
-	/**
-	 * The underlying map we are managing.
-	 */
-	private HashMap map = null;
-
-	// --------------------------------------------------------- Public Methods
-
-	/**
-	 * Remove all mappings from this map.
-	 */
-	public void clear() {
-
-		synchronized (this) {
-			HashMap temp = (HashMap) map.clone();
-			temp.clear();
-			map = temp;
-		}
-
-	}
-
-	/**
-	 * Return a shallow copy of this <code>FastHashMap</code> instance.
-	 * The keys and values themselves are not copied.
-	 */
-	public Object clone() {
-
-		return new FastHashMap(map);
-
-	}
-
-	/**
-	 * Return <code>true</code> if this map contains a mapping for the
-	 * specified key.
-	 *
-	 * @param key Key to be searched for
-	 */
-	public boolean containsKey(Object key) {
-
-		return map.containsKey(key);
-
-	}
-
-	/**
-	 * Return <code>true</code> if this map contains one or more keys mapping
-	 * to the specified value.
-	 *
-	 * @param value Value to be searched for
-	 */
-	public boolean containsValue(Object value) {
-
-		return map.containsValue(value);
-
-	}
-
-	/**
-	 * Return a collection view of the mappings contained in this map.  Each
-	 * element in the returned collection is a <code>Map.Entry</code>.
-	 */
-	public Set entrySet() {
-
-		return map.entrySet();
-
-	}
-
-	/**
-	 * Compare the specified object with this list for equality.  This
-	 * implementation uses exactly the code that is used to define the
-	 * list equals function in the documentation for the
-	 * <code>Map.equals</code> method.
-	 *
-	 * @param o Object to be compared to this list
-	 */
-	public boolean equals(Object o) {
-
-		// Simple tests that require no synchronization
-		if (o == this)
-			return true;
-		else if ( !(o instanceof Map) )
-			return false;
-		Map mo = (Map) o;
-
-		// Compare the two maps for equality
-
-		if ( mo.size() != map.size() )
-			return false;
-		java.util.Iterator i = map.entrySet().iterator();
-		while ( i.hasNext() ) {
-			Map.Entry e = (Map.Entry) i.next();
-			Object key = e.getKey();
-			Object value = e.getValue();
-			if (value == null) {
-				if ( !( mo.get(key) == null && mo.containsKey(key) ) )
-					return false;
-			}
-			else {
-				if ( !value.equals( mo.get(key) ) )
-					return false;
-			}
-		}
-		return true;
-
-	}
-
-	/**
-	 * Return the value to which this map maps the specified key.  Returns
-	 * <code>null</code> if the map contains no mapping for this key, or if
-	 * there is a mapping with a value of <code>null</code>.  Use the
-	 * <code>containsKey()</code> method to disambiguate these cases.
-	 *
-	 * @param key Key whose value is to be returned
-	 */
-	public Object get(Object key) {
-
-		return map.get(key);
-
-	}
-
-	/**
-	 * Return the hash code value for this map.  This implementation uses
-	 * exactly the code that is used to define the list hash function in the
-	 * documentation for the <code>Map.hashCode</code> method.
-	 */
-	public int hashCode() {
-
-		int h = 0;
-		java.util.Iterator i = map.entrySet().iterator();
-		while ( i.hasNext() )
-			h += i.next().hashCode();
-		return h;
-
-	}
-
-	/**
-	 * Return <code>true</code> if this map contains no mappings.
-	 */
-	public boolean isEmpty() {
-
-		return map.isEmpty();
-
-	}
-
-	/**
-	 * Return a set view of the keys contained in this map.
-	 */
-	public Set keySet() {
-
-		return map.keySet();
-
-	}
-
-	/**
-	 * Associate the specified value with the specified key in this map.
-	 * If the map previously contained a mapping for this key, the old
-	 * value is replaced and returned.
-	 *
-	 * @param key The key with which the value is to be associated
-	 * @param value The value to be associated with this key
-	 */
-	public Object put(Object key, Object value) {
-
-		synchronized (this) {
-			HashMap temp = (HashMap) map.clone();
-			Object result = temp.put(key, value);
-			map = temp;
-			return (result);
-		}
-
-	}
-
-	/**
-	 * Copy all of the mappings from the specified map to this one, replacing
-	 * any mappings with the same keys.
-	 *
-	 * @param in Map whose mappings are to be copied
-	 */
-	public void putAll(Map in) {
-
-		synchronized (this) {
-			HashMap temp = (HashMap) map.clone();
-			temp.putAll(in);
-			map = temp;
-		}
-
-	}
-
-	/**
-	 * Remove any mapping for this key, and return any previously
-	 * mapped value.
-	 *
-	 * @param key Key whose mapping is to be removed
-	 */
-	public Object remove(Object key) {
-
-		synchronized (this) {
-			HashMap temp = (HashMap) map.clone();
-			Object result = temp.remove(key);
-			map = temp;
-			return (result);
-		}
-
-	}
-
-	/**
-	 * Return the number of key-value mappings in this map.
-	 */
-	public int size() {
-
-		return map.size();
-
-	}
-
-	/**
-	 * Return a collection view of the values contained in this map.
-	 */
-	public Collection values() {
-
-		return map.values();
-
-	}
-
-	public String toString() { return map.toString(); }
-
-}
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/FastHashMap.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FastHashMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,335 @@
+/*
+ * 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
+ *
+ */
+
+// This class was taken from Apache commons-collections -
+// I made it final + removed the "slow" mode...
+
+package org.hibernate.util;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * <p>A customized implementation of <code>java.util.HashMap</code> designed
+ * to operate in a multithreaded environment where the large majority of
+ * method calls are read-only, instead of structural changes.
+ * Read calls are non-synchronized and write calls perform the
+ * following steps:</p>
+ * <ul>
+ * <li>Clone the existing collection
+ * <li>Perform the modification on the clone
+ * <li>Replace the existing collection with the (modified) clone
+ * </ul>
+ * <p><strong>NOTE</strong>: If you are creating and accessing a
+ * <code>HashMap</code> only within a single thread, you should use
+ * <code>java.util.HashMap</code> directly (with no synchronization), for
+ * maximum performance.</p>
+ *
+ */
+
+public final class FastHashMap implements Map, Serializable {
+
+	// ----------------------------------------------------------- Constructors
+
+	/**
+	 * Construct a an empty map.
+	 */
+	public FastHashMap() {
+
+		super();
+		this.map = new HashMap();
+
+	}
+
+	/**
+	 * Construct an empty map with the specified capacity.
+	 *
+	 * @param capacity The initial capacity of the empty map
+	 */
+	public FastHashMap(int capacity) {
+
+		super();
+		this.map = new HashMap(capacity);
+
+	}
+
+	/**
+	 * Construct an empty map with the specified capacity and load factor.
+	 *
+	 * @param capacity The initial capacity of the empty map
+	 * @param factor The load factor of the new map
+	 */
+	public FastHashMap(int capacity, float factor) {
+
+		super();
+		this.map = new HashMap(capacity, factor);
+
+	}
+
+	/**
+	 * Construct a new map with the same mappings as the specified map.
+	 *
+	 * @param map The map whose mappings are to be copied
+	 */
+	public FastHashMap(Map map) {
+
+		super();
+		this.map = new HashMap(map);
+
+	}
+
+	// ----------------------------------------------------- Instance Variables
+
+	/**
+	 * The underlying map we are managing.
+	 */
+	private HashMap map = null;
+
+	// --------------------------------------------------------- Public Methods
+
+	/**
+	 * Remove all mappings from this map.
+	 */
+	public void clear() {
+
+		synchronized (this) {
+			HashMap temp = (HashMap) map.clone();
+			temp.clear();
+			map = temp;
+		}
+
+	}
+
+	/**
+	 * Return a shallow copy of this <code>FastHashMap</code> instance.
+	 * The keys and values themselves are not copied.
+	 */
+	public Object clone() {
+
+		return new FastHashMap(map);
+
+	}
+
+	/**
+	 * Return <code>true</code> if this map contains a mapping for the
+	 * specified key.
+	 *
+	 * @param key Key to be searched for
+	 */
+	public boolean containsKey(Object key) {
+
+		return map.containsKey(key);
+
+	}
+
+	/**
+	 * Return <code>true</code> if this map contains one or more keys mapping
+	 * to the specified value.
+	 *
+	 * @param value Value to be searched for
+	 */
+	public boolean containsValue(Object value) {
+
+		return map.containsValue(value);
+
+	}
+
+	/**
+	 * Return a collection view of the mappings contained in this map.  Each
+	 * element in the returned collection is a <code>Map.Entry</code>.
+	 */
+	public Set entrySet() {
+
+		return map.entrySet();
+
+	}
+
+	/**
+	 * Compare the specified object with this list for equality.  This
+	 * implementation uses exactly the code that is used to define the
+	 * list equals function in the documentation for the
+	 * <code>Map.equals</code> method.
+	 *
+	 * @param o Object to be compared to this list
+	 */
+	public boolean equals(Object o) {
+
+		// Simple tests that require no synchronization
+		if (o == this)
+			return true;
+		else if ( !(o instanceof Map) )
+			return false;
+		Map mo = (Map) o;
+
+		// Compare the two maps for equality
+
+		if ( mo.size() != map.size() )
+			return false;
+		java.util.Iterator i = map.entrySet().iterator();
+		while ( i.hasNext() ) {
+			Map.Entry e = (Map.Entry) i.next();
+			Object key = e.getKey();
+			Object value = e.getValue();
+			if (value == null) {
+				if ( !( mo.get(key) == null && mo.containsKey(key) ) )
+					return false;
+			}
+			else {
+				if ( !value.equals( mo.get(key) ) )
+					return false;
+			}
+		}
+		return true;
+
+	}
+
+	/**
+	 * Return the value to which this map maps the specified key.  Returns
+	 * <code>null</code> if the map contains no mapping for this key, or if
+	 * there is a mapping with a value of <code>null</code>.  Use the
+	 * <code>containsKey()</code> method to disambiguate these cases.
+	 *
+	 * @param key Key whose value is to be returned
+	 */
+	public Object get(Object key) {
+
+		return map.get(key);
+
+	}
+
+	/**
+	 * Return the hash code value for this map.  This implementation uses
+	 * exactly the code that is used to define the list hash function in the
+	 * documentation for the <code>Map.hashCode</code> method.
+	 */
+	public int hashCode() {
+
+		int h = 0;
+		java.util.Iterator i = map.entrySet().iterator();
+		while ( i.hasNext() )
+			h += i.next().hashCode();
+		return h;
+
+	}
+
+	/**
+	 * Return <code>true</code> if this map contains no mappings.
+	 */
+	public boolean isEmpty() {
+
+		return map.isEmpty();
+
+	}
+
+	/**
+	 * Return a set view of the keys contained in this map.
+	 */
+	public Set keySet() {
+
+		return map.keySet();
+
+	}
+
+	/**
+	 * Associate the specified value with the specified key in this map.
+	 * If the map previously contained a mapping for this key, the old
+	 * value is replaced and returned.
+	 *
+	 * @param key The key with which the value is to be associated
+	 * @param value The value to be associated with this key
+	 */
+	public Object put(Object key, Object value) {
+
+		synchronized (this) {
+			HashMap temp = (HashMap) map.clone();
+			Object result = temp.put(key, value);
+			map = temp;
+			return (result);
+		}
+
+	}
+
+	/**
+	 * Copy all of the mappings from the specified map to this one, replacing
+	 * any mappings with the same keys.
+	 *
+	 * @param in Map whose mappings are to be copied
+	 */
+	public void putAll(Map in) {
+
+		synchronized (this) {
+			HashMap temp = (HashMap) map.clone();
+			temp.putAll(in);
+			map = temp;
+		}
+
+	}
+
+	/**
+	 * Remove any mapping for this key, and return any previously
+	 * mapped value.
+	 *
+	 * @param key Key whose mapping is to be removed
+	 */
+	public Object remove(Object key) {
+
+		synchronized (this) {
+			HashMap temp = (HashMap) map.clone();
+			Object result = temp.remove(key);
+			map = temp;
+			return (result);
+		}
+
+	}
+
+	/**
+	 * Return the number of key-value mappings in this map.
+	 */
+	public int size() {
+
+		return map.size();
+
+	}
+
+	/**
+	 * Return a collection view of the values contained in this map.
+	 */
+	public Collection values() {
+
+		return map.values();
+
+	}
+
+	public String toString() { return map.toString(); }
+
+}
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/FilterHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,81 +0,0 @@
-// $Id: FilterHelper.java 9908 2006-05-08 20:59:20Z max.andersen at jboss.com $
-package org.hibernate.util;
-
-import org.hibernate.sql.Template;
-import org.hibernate.impl.FilterImpl;
-import org.hibernate.dialect.Dialect;
-import org.hibernate.dialect.function.SQLFunctionRegistry;
-
-import java.util.Map;
-import java.util.Iterator;
-
-/**
- * Implementation of FilterHelper.
- *
- * @author Steve Ebersole
- */
-public class FilterHelper {
-
-	private final String[] filterNames;
-	private final String[] filterConditions;
-
-	/**
-	 * The map of defined filters.  This is expected to be in format
-	 * where the filter names are the map keys, and the defined
-	 * conditions are the values.
-	 *
-	 * @param filters The map of defined filters.
-	 * @param dialect The sql dialect
-	 * @param functionRegistry The SQL function registry
-	 */
-	public FilterHelper(Map filters, Dialect dialect, SQLFunctionRegistry functionRegistry) {
-		int filterCount = filters.size();
-		filterNames = new String[filterCount];
-		filterConditions = new String[filterCount];
-		Iterator iter = filters.entrySet().iterator();
-		filterCount = 0;
-		while ( iter.hasNext() ) {
-			final Map.Entry entry = (Map.Entry) iter.next();
-			filterNames[filterCount] = (String) entry.getKey();
-			filterConditions[filterCount] = Template.renderWhereStringTemplate(
-					(String) entry.getValue(),
-					FilterImpl.MARKER,
-					dialect,
-					functionRegistry
-				);
-			filterConditions[filterCount] = StringHelper.replace( filterConditions[filterCount],
-					":",
-					":" + filterNames[filterCount] + "." );
-			filterCount++;
-		}
-	}
-
-	public boolean isAffectedBy(Map enabledFilters) {
-		for ( int i = 0, max = filterNames.length; i < max; i++ ) {
-			if ( enabledFilters.containsKey( filterNames[i] ) ) {
-				return true;
-			}
-		}
-		return false;
-	}
-
-	public String render(String alias, Map enabledFilters) {
-		StringBuffer buffer = new StringBuffer();
-		render( buffer, alias, enabledFilters );
-		return buffer.toString();
-	}
-
-	public void render(StringBuffer buffer, String alias, Map enabledFilters) {
-		if ( filterNames != null && filterNames.length > 0 ) {
-			for ( int i = 0, max = filterNames.length; i < max; i++ ) {
-				if ( enabledFilters.containsKey( filterNames[i] ) ) {
-					final String condition = filterConditions[i];
-					if ( StringHelper.isNotEmpty( condition ) ) {
-						buffer.append( " and " )
-								.append( StringHelper.replace( condition, FilterImpl.MARKER, alias ) );
-					}
-				}
-			}
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/FilterHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/FilterHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import org.hibernate.sql.Template;
+import org.hibernate.impl.FilterImpl;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.dialect.function.SQLFunctionRegistry;
+
+import java.util.Map;
+import java.util.Iterator;
+
+/**
+ * Implementation of FilterHelper.
+ *
+ * @author Steve Ebersole
+ */
+public class FilterHelper {
+
+	private final String[] filterNames;
+	private final String[] filterConditions;
+
+	/**
+	 * The map of defined filters.  This is expected to be in format
+	 * where the filter names are the map keys, and the defined
+	 * conditions are the values.
+	 *
+	 * @param filters The map of defined filters.
+	 * @param dialect The sql dialect
+	 * @param functionRegistry The SQL function registry
+	 */
+	public FilterHelper(Map filters, Dialect dialect, SQLFunctionRegistry functionRegistry) {
+		int filterCount = filters.size();
+		filterNames = new String[filterCount];
+		filterConditions = new String[filterCount];
+		Iterator iter = filters.entrySet().iterator();
+		filterCount = 0;
+		while ( iter.hasNext() ) {
+			final Map.Entry entry = (Map.Entry) iter.next();
+			filterNames[filterCount] = (String) entry.getKey();
+			filterConditions[filterCount] = Template.renderWhereStringTemplate(
+					(String) entry.getValue(),
+					FilterImpl.MARKER,
+					dialect,
+					functionRegistry
+				);
+			filterConditions[filterCount] = StringHelper.replace( filterConditions[filterCount],
+					":",
+					":" + filterNames[filterCount] + "." );
+			filterCount++;
+		}
+	}
+
+	public boolean isAffectedBy(Map enabledFilters) {
+		for ( int i = 0, max = filterNames.length; i < max; i++ ) {
+			if ( enabledFilters.containsKey( filterNames[i] ) ) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	public String render(String alias, Map enabledFilters) {
+		StringBuffer buffer = new StringBuffer();
+		render( buffer, alias, enabledFilters );
+		return buffer.toString();
+	}
+
+	public void render(StringBuffer buffer, String alias, Map enabledFilters) {
+		if ( filterNames != null && filterNames.length > 0 ) {
+			for ( int i = 0, max = filterNames.length; i < max; i++ ) {
+				if ( enabledFilters.containsKey( filterNames[i] ) ) {
+					final String condition = filterConditions[i];
+					if ( StringHelper.isNotEmpty( condition ) ) {
+						buffer.append( " and " )
+								.append( StringHelper.replace( condition, FilterImpl.MARKER, alias ) );
+					}
+				}
+			}
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/IdentityMap.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,272 +0,0 @@
-//$Id: IdentityMap.java 9194 2006-02-01 19:59:07Z steveebersole $
-package org.hibernate.util;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * A <tt>Map</tt> where keys are compared by object identity,
- * rather than <tt>equals()</tt>.
- */
-
-public final class IdentityMap implements Map {
-
-	private final Map map;
-	private transient Map.Entry[] entryArray = new Map.Entry[0];
-	private transient boolean dirty = false;
-
-	/**
-	 * Return a new instance of this class, with an undefined
-	 * iteration order.
-	 *
-	 * @param size The size of the map
-	 * @return Map
-	 */
-	public static Map instantiate(int size) {
-		return new IdentityMap( new HashMap( size ) );
-	}
-
-	/**
-	 * Return a new instance of this class, with iteration
-	 * order defined as the order in which entries were added
-	 *
-	 * @param size The size of the map to create
-	 * @return
-	 */
-	public static Map instantiateSequenced(int size) {
-		return new IdentityMap( new LinkedHashMap( size ) );
-	}
-
-	/**
-	 * Private ctor used in serialization.
-	 *
-	 * @param underlyingMap The delegate map.
-	 */
-	private IdentityMap(Map underlyingMap) {
-		map = underlyingMap;
-		dirty = true;
-	}
-
-	/**
-	 * Return the map entries (as instances of <tt>Map.Entry</tt> in a collection that
-	 * is safe from concurrent modification). ie. we may safely add new instances to
-	 * the underlying <tt>Map</tt> during iteration of the <tt>entries()</tt>.
-	 *
-	 * @param map
-	 * @return Collection
-	 */
-	public static Map.Entry[] concurrentEntries(Map map) {
-		return ( (IdentityMap) map ).entryArray();
-	}
-
-	public static List entries(Map map) {
-		return ( (IdentityMap) map ).entryList();
-	}
-
-	public static Iterator keyIterator(Map map) {
-		return ( (IdentityMap) map ).keyIterator();
-	}
-
-	public Iterator keyIterator() {
-		return new KeyIterator( map.keySet().iterator() );
-	}
-
-	public static final class IdentityMapEntry implements java.util.Map.Entry {
-		IdentityMapEntry(Object key, Object value) {
-			this.key=key;
-			this.value=value;
-		}
-		private Object key;
-		private Object value;
-		public Object getKey() {
-			return key;
-		}
-
-		public Object getValue() {
-			return value;
-		}
-
-		public Object setValue(Object value) {
-			Object result = this.value;
-			this.value = value;
-			return result;
-		}
-	}
-
-	public static final class IdentityKey implements Serializable {
-		private Object key;
-
-		IdentityKey(Object key) {
-			this.key=key;
-		}
-		public boolean equals(Object other) {
-			return key == ( (IdentityKey) other ).key;
-		}
-		public int hashCode() {
-			return System.identityHashCode(key);
-		}
-		public String toString() {
-			return key.toString();
-		}
-		public Object getRealKey() {
-			return key;
-		}
-	}
-
-	public int size() {
-		return map.size();
-	}
-
-	public boolean isEmpty() {
-		return map.isEmpty();
-	}
-
-	public boolean containsKey(Object key) {
-		IdentityKey k = new IdentityKey(key);
-		return map.containsKey(k);
-	}
-
-	public boolean containsValue(Object val) {
-		return map.containsValue(val);
-	}
-
-	public Object get(Object key) {
-		IdentityKey k = new IdentityKey(key);
-		return map.get(k);
-	}
-
-	public Object put(Object key, Object value) {
-		dirty = true;
-		return map.put( new IdentityKey(key), value );
-	}
-
-	public Object remove(Object key) {
-		dirty = true;
-		IdentityKey k = new IdentityKey(key);
-		return map.remove(k);
-	}
-
-	public void putAll(Map otherMap) {
-		Iterator iter = otherMap.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			put( me.getKey(), me.getValue() );
-		}
-	}
-
-	public void clear() {
-		dirty = true;
-		entryArray = null;
-		map.clear();
-	}
-
-	public Set keySet() {
-		// would need an IdentitySet for this!
-		throw new UnsupportedOperationException();
-	}
-
-	public Collection values() {
-		return map.values();
-	}
-
-	public Set entrySet() {
-		Set set = new HashSet( map.size() );
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			set.add( new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() ) );
-		}
-		return set;
-	}
-
-	public List entryList() {
-		ArrayList list = new ArrayList( map.size() );
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			list.add( new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() ) );
-		}
-		return list;
-	}
-
-	public Map.Entry[] entryArray() {
-		if (dirty) {
-			entryArray = new Map.Entry[ map.size() ];
-			Iterator iter = map.entrySet().iterator();
-			int i=0;
-			while ( iter.hasNext() ) {
-				Map.Entry me = (Map.Entry) iter.next();
-				entryArray[i++] = new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() );
-			}
-			dirty = false;
-		}
-		return entryArray;
-	}
-
-	/**
-	 * Workaround for a JDK 1.4.1 bug where <tt>IdentityHashMap</tt>s are not
-	 * correctly deserialized.
-	 *
-	 * @param map
-	 * @return Object
-	 */
-	public static Object serialize(Map map) {
-		return ( (IdentityMap) map ).map;
-	}
-
-	/**
-	 * Workaround for a JDK 1.4.1 bug where <tt>IdentityHashMap</tt>s are not
-	 * correctly deserialized.
-	 *
-	 * @param o
-	 * @return Map
-	 */
-	public static Map deserialize(Object o) {
-		return new IdentityMap( (Map) o );
-	}
-	
-	public String toString() {
-		return map.toString();
-	}
-
-	public static Map invert(Map map) {
-		Map result = instantiate( map.size() );
-		Iterator iter = map.entrySet().iterator();
-		while ( iter.hasNext() ) {
-			Map.Entry me = (Map.Entry) iter.next();
-			result.put( me.getValue(), me.getKey() );
-		}
-		return result;
-	}
-
-	static final class KeyIterator implements Iterator {
-
-		private KeyIterator(Iterator iter) {
-			identityKeyIterator = iter;
-		}
-
-		private final Iterator identityKeyIterator;
-
-		public boolean hasNext() {
-			return identityKeyIterator.hasNext();
-		}
-
-		public Object next() {
-			return ( (IdentityKey) identityKeyIterator.next() ).key;
-		}
-
-		public void remove() {
-			throw new UnsupportedOperationException();
-		}
-
-	}
-
-}
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/IdentityMap.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentityMap.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,294 @@
+/*
+ * 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.util;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A <tt>Map</tt> where keys are compared by object identity,
+ * rather than <tt>equals()</tt>.
+ */
+public final class IdentityMap implements Map {
+
+	private final Map map;
+	private transient Map.Entry[] entryArray = new Map.Entry[0];
+	private transient boolean dirty = false;
+
+	/**
+	 * Return a new instance of this class, with an undefined
+	 * iteration order.
+	 *
+	 * @param size The size of the map
+	 * @return Map
+	 */
+	public static Map instantiate(int size) {
+		return new IdentityMap( new HashMap( size ) );
+	}
+
+	/**
+	 * Return a new instance of this class, with iteration
+	 * order defined as the order in which entries were added
+	 *
+	 * @param size The size of the map to create
+	 * @return
+	 */
+	public static Map instantiateSequenced(int size) {
+		return new IdentityMap( new LinkedHashMap( size ) );
+	}
+
+	/**
+	 * Private ctor used in serialization.
+	 *
+	 * @param underlyingMap The delegate map.
+	 */
+	private IdentityMap(Map underlyingMap) {
+		map = underlyingMap;
+		dirty = true;
+	}
+
+	/**
+	 * Return the map entries (as instances of <tt>Map.Entry</tt> in a collection that
+	 * is safe from concurrent modification). ie. we may safely add new instances to
+	 * the underlying <tt>Map</tt> during iteration of the <tt>entries()</tt>.
+	 *
+	 * @param map
+	 * @return Collection
+	 */
+	public static Map.Entry[] concurrentEntries(Map map) {
+		return ( (IdentityMap) map ).entryArray();
+	}
+
+	public static List entries(Map map) {
+		return ( (IdentityMap) map ).entryList();
+	}
+
+	public static Iterator keyIterator(Map map) {
+		return ( (IdentityMap) map ).keyIterator();
+	}
+
+	public Iterator keyIterator() {
+		return new KeyIterator( map.keySet().iterator() );
+	}
+
+	public static final class IdentityMapEntry implements java.util.Map.Entry {
+		IdentityMapEntry(Object key, Object value) {
+			this.key=key;
+			this.value=value;
+		}
+		private Object key;
+		private Object value;
+		public Object getKey() {
+			return key;
+		}
+
+		public Object getValue() {
+			return value;
+		}
+
+		public Object setValue(Object value) {
+			Object result = this.value;
+			this.value = value;
+			return result;
+		}
+	}
+
+	public static final class IdentityKey implements Serializable {
+		private Object key;
+
+		IdentityKey(Object key) {
+			this.key=key;
+		}
+		public boolean equals(Object other) {
+			return key == ( (IdentityKey) other ).key;
+		}
+		public int hashCode() {
+			return System.identityHashCode(key);
+		}
+		public String toString() {
+			return key.toString();
+		}
+		public Object getRealKey() {
+			return key;
+		}
+	}
+
+	public int size() {
+		return map.size();
+	}
+
+	public boolean isEmpty() {
+		return map.isEmpty();
+	}
+
+	public boolean containsKey(Object key) {
+		IdentityKey k = new IdentityKey(key);
+		return map.containsKey(k);
+	}
+
+	public boolean containsValue(Object val) {
+		return map.containsValue(val);
+	}
+
+	public Object get(Object key) {
+		IdentityKey k = new IdentityKey(key);
+		return map.get(k);
+	}
+
+	public Object put(Object key, Object value) {
+		dirty = true;
+		return map.put( new IdentityKey(key), value );
+	}
+
+	public Object remove(Object key) {
+		dirty = true;
+		IdentityKey k = new IdentityKey(key);
+		return map.remove(k);
+	}
+
+	public void putAll(Map otherMap) {
+		Iterator iter = otherMap.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			put( me.getKey(), me.getValue() );
+		}
+	}
+
+	public void clear() {
+		dirty = true;
+		entryArray = null;
+		map.clear();
+	}
+
+	public Set keySet() {
+		// would need an IdentitySet for this!
+		throw new UnsupportedOperationException();
+	}
+
+	public Collection values() {
+		return map.values();
+	}
+
+	public Set entrySet() {
+		Set set = new HashSet( map.size() );
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			set.add( new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() ) );
+		}
+		return set;
+	}
+
+	public List entryList() {
+		ArrayList list = new ArrayList( map.size() );
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			list.add( new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() ) );
+		}
+		return list;
+	}
+
+	public Map.Entry[] entryArray() {
+		if (dirty) {
+			entryArray = new Map.Entry[ map.size() ];
+			Iterator iter = map.entrySet().iterator();
+			int i=0;
+			while ( iter.hasNext() ) {
+				Map.Entry me = (Map.Entry) iter.next();
+				entryArray[i++] = new IdentityMapEntry( ( (IdentityKey) me.getKey() ).key, me.getValue() );
+			}
+			dirty = false;
+		}
+		return entryArray;
+	}
+
+	/**
+	 * Workaround for a JDK 1.4.1 bug where <tt>IdentityHashMap</tt>s are not
+	 * correctly deserialized.
+	 *
+	 * @param map
+	 * @return Object
+	 */
+	public static Object serialize(Map map) {
+		return ( (IdentityMap) map ).map;
+	}
+
+	/**
+	 * Workaround for a JDK 1.4.1 bug where <tt>IdentityHashMap</tt>s are not
+	 * correctly deserialized.
+	 *
+	 * @param o
+	 * @return Map
+	 */
+	public static Map deserialize(Object o) {
+		return new IdentityMap( (Map) o );
+	}
+	
+	public String toString() {
+		return map.toString();
+	}
+
+	public static Map invert(Map map) {
+		Map result = instantiate( map.size() );
+		Iterator iter = map.entrySet().iterator();
+		while ( iter.hasNext() ) {
+			Map.Entry me = (Map.Entry) iter.next();
+			result.put( me.getValue(), me.getKey() );
+		}
+		return result;
+	}
+
+	static final class KeyIterator implements Iterator {
+
+		private KeyIterator(Iterator iter) {
+			identityKeyIterator = iter;
+		}
+
+		private final Iterator identityKeyIterator;
+
+		public boolean hasNext() {
+			return identityKeyIterator.hasNext();
+		}
+
+		public Object next() {
+			return ( (IdentityKey) identityKeyIterator.next() ).key;
+		}
+
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+
+	}
+
+}
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/IdentitySet.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,108 +0,0 @@
-//$Id: IdentitySet.java 8807 2005-12-09 15:27:05Z epbernard $
-package org.hibernate.util;
-
-import java.util.Collection;
-import java.util.IdentityHashMap;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * Set implementation that use == instead of equals() as its comparison
- * mechanism.  This is achieved by internally using an IdentityHashMap.
- *
- * @author Emmanuel Bernard
- */
-public class IdentitySet implements Set {
-	private static final Object DUMP_VALUE = new Object();
-
-	private final IdentityHashMap map;
-
-	/**
-	 * Create an IdentitySet with default sizing.
-	 */
-	public IdentitySet() {
-		this.map = new IdentityHashMap();
-	}
-
-	/**
-	 * Create an IdentitySet with the given sizing.
-	 *
-	 * @param sizing The sizing of the set to create.
-	 */
-	public IdentitySet(int sizing) {
-		this.map = new IdentityHashMap( sizing );
-	}
-
-	public int size() {
-		return map.size();
-	}
-
-	public boolean isEmpty() {
-		return map.isEmpty();
-	}
-
-	public boolean contains(Object o) {
-		return map.get( o ) == DUMP_VALUE;
-	}
-
-	public Iterator iterator() {
-		return map.entrySet().iterator();
-	}
-
-	public Object[] toArray() {
-		return map.entrySet().toArray();
-	}
-
-	public Object[] toArray(Object[] a) {
-		return map.entrySet().toArray( a );
-	}
-
-	public boolean add(Object o) {
-		return map.put( o, DUMP_VALUE ) == null;
-	}
-
-	public boolean remove(Object o) {
-		return map.remove( o ) == DUMP_VALUE;
-	}
-
-	public boolean containsAll(Collection c) {
-		Iterator it = c.iterator();
-		while ( it.hasNext() ) {
-			if ( !map.containsKey( it.next() ) ) {
-				return false;
-			}
-		}
-		return true;
-	}
-
-	public boolean addAll(Collection c) {
-		Iterator it = c.iterator();
-		boolean changed = false;
-		while ( it.hasNext() ) {
-			if ( this.add( it.next() ) ) {
-				changed = true;
-			}
-		}
-		return changed;
-	}
-
-	public boolean retainAll(Collection c) {
-		//doable if needed
-		throw new UnsupportedOperationException();
-	}
-
-	public boolean removeAll(Collection c) {
-		Iterator it = c.iterator();
-		boolean changed = false;
-		while ( it.hasNext() ) {
-			if ( this.remove( it.next() ) ) {
-				changed = true;
-			}
-		}
-		return changed;
-	}
-
-	public void clear() {
-		map.clear();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/IdentitySet.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/IdentitySet.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,131 @@
+/*
+ * 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.util;
+
+import java.util.Collection;
+import java.util.IdentityHashMap;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * Set implementation that use == instead of equals() as its comparison
+ * mechanism.  This is achieved by internally using an IdentityHashMap.
+ *
+ * @author Emmanuel Bernard
+ */
+public class IdentitySet implements Set {
+	private static final Object DUMP_VALUE = new Object();
+
+	private final IdentityHashMap map;
+
+	/**
+	 * Create an IdentitySet with default sizing.
+	 */
+	public IdentitySet() {
+		this.map = new IdentityHashMap();
+	}
+
+	/**
+	 * Create an IdentitySet with the given sizing.
+	 *
+	 * @param sizing The sizing of the set to create.
+	 */
+	public IdentitySet(int sizing) {
+		this.map = new IdentityHashMap( sizing );
+	}
+
+	public int size() {
+		return map.size();
+	}
+
+	public boolean isEmpty() {
+		return map.isEmpty();
+	}
+
+	public boolean contains(Object o) {
+		return map.get( o ) == DUMP_VALUE;
+	}
+
+	public Iterator iterator() {
+		return map.entrySet().iterator();
+	}
+
+	public Object[] toArray() {
+		return map.entrySet().toArray();
+	}
+
+	public Object[] toArray(Object[] a) {
+		return map.entrySet().toArray( a );
+	}
+
+	public boolean add(Object o) {
+		return map.put( o, DUMP_VALUE ) == null;
+	}
+
+	public boolean remove(Object o) {
+		return map.remove( o ) == DUMP_VALUE;
+	}
+
+	public boolean containsAll(Collection c) {
+		Iterator it = c.iterator();
+		while ( it.hasNext() ) {
+			if ( !map.containsKey( it.next() ) ) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+	public boolean addAll(Collection c) {
+		Iterator it = c.iterator();
+		boolean changed = false;
+		while ( it.hasNext() ) {
+			if ( this.add( it.next() ) ) {
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
+	public boolean retainAll(Collection c) {
+		//doable if needed
+		throw new UnsupportedOperationException();
+	}
+
+	public boolean removeAll(Collection c) {
+		Iterator it = c.iterator();
+		boolean changed = false;
+		while ( it.hasNext() ) {
+			if ( this.remove( it.next() ) ) {
+				changed = true;
+			}
+		}
+		return changed;
+	}
+
+	public void clear() {
+		map.clear();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,103 +0,0 @@
-//$Id: JDBCExceptionReporter.java 10670 2006-10-31 21:30:15Z epbernard $
-package org.hibernate.util;
-
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.sql.SQLWarning;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public final class JDBCExceptionReporter {
-
-	public static final Logger log = LoggerFactory.getLogger(JDBCExceptionReporter.class);
-	public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
-	public static final String DEFAULT_WARNING_MSG = "SQL Warning";
-
-	private JDBCExceptionReporter() {}
-	
-	public static void logAndClearWarnings(Connection connection) {
-		if ( log.isWarnEnabled() ) {
-			try {
-				logWarnings( connection.getWarnings() );
-			}
-			catch (SQLException sqle) {
-				//workaround for WebLogic
-				log.debug("could not log warnings", sqle);
-			}
-		}
-		try {
-			//Sybase fail if we don't do that, sigh...
-			connection.clearWarnings();
-		}
-		catch (SQLException sqle) {
-			log.debug("could not clear warnings", sqle);
-		}
-	}
-
-	public static void logWarnings(SQLWarning warning) {
-		logWarnings(warning, null);
-	}
-
-	public static void logWarnings(SQLWarning warning, String message) {
-		if ( log.isWarnEnabled() ) {
-			if ( log.isDebugEnabled() && warning != null ) {
-				message = StringHelper.isNotEmpty(message) ? message : DEFAULT_WARNING_MSG;
-				log.debug( message, warning );
-			}
-			while (warning != null) {
-				StringBuffer buf = new StringBuffer(30)
-				        .append( "SQL Warning: ")
-						.append( warning.getErrorCode() )
-						.append( ", SQLState: ")
-						.append( warning.getSQLState() );
-				log.warn( buf.toString() );
-				log.warn( warning.getMessage() );
-				warning = warning.getNextWarning();
-			}
-		}
-	}
-
-	public static void logExceptions(SQLException ex) {
-		logExceptions(ex, null);
-	}
-
-	public static void logExceptions(SQLException ex, String message) {
-		if ( log.isErrorEnabled() ) {
-			if ( log.isDebugEnabled() ) {
-				message = StringHelper.isNotEmpty(message) ? message : DEFAULT_EXCEPTION_MSG;
-				log.debug( message, ex );
-			}
-			while (ex != null) {
-				StringBuffer buf = new StringBuffer(30)
-						.append( "SQL Error: " )
-				        .append( ex.getErrorCode() )
-				        .append( ", SQLState: " )
-				        .append( ex.getSQLState() );
-				log.warn( buf.toString() );
-				log.error( ex.getMessage() );
-				ex = ex.getNextException();
-			}
-		}
-	}
-
-//	public static JDBCException newJDBCException(String string, SQLException root, String sql) {
-//		string = string + " [" + sql + ']';
-//		log.error(string, root);
-//		logExceptions(root);
-//		return new JDBCException(string, root, sql);
-//	}
-//
-//	public static JDBCException newJDBCException(String string, SQLException root) {
-//		log.error(string, root);
-//		logExceptions(root);
-//		return new JDBCException(string, root);
-//	}
-
-}
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JDBCExceptionReporter.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,126 @@
+/*
+ * 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.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class JDBCExceptionReporter {
+
+	public static final Logger log = LoggerFactory.getLogger(JDBCExceptionReporter.class);
+	public static final String DEFAULT_EXCEPTION_MSG = "SQL Exception";
+	public static final String DEFAULT_WARNING_MSG = "SQL Warning";
+
+	private JDBCExceptionReporter() {}
+	
+	public static void logAndClearWarnings(Connection connection) {
+		if ( log.isWarnEnabled() ) {
+			try {
+				logWarnings( connection.getWarnings() );
+			}
+			catch (SQLException sqle) {
+				//workaround for WebLogic
+				log.debug("could not log warnings", sqle);
+			}
+		}
+		try {
+			//Sybase fail if we don't do that, sigh...
+			connection.clearWarnings();
+		}
+		catch (SQLException sqle) {
+			log.debug("could not clear warnings", sqle);
+		}
+	}
+
+	public static void logWarnings(SQLWarning warning) {
+		logWarnings(warning, null);
+	}
+
+	public static void logWarnings(SQLWarning warning, String message) {
+		if ( log.isWarnEnabled() ) {
+			if ( log.isDebugEnabled() && warning != null ) {
+				message = StringHelper.isNotEmpty(message) ? message : DEFAULT_WARNING_MSG;
+				log.debug( message, warning );
+			}
+			while (warning != null) {
+				StringBuffer buf = new StringBuffer(30)
+				        .append( "SQL Warning: ")
+						.append( warning.getErrorCode() )
+						.append( ", SQLState: ")
+						.append( warning.getSQLState() );
+				log.warn( buf.toString() );
+				log.warn( warning.getMessage() );
+				warning = warning.getNextWarning();
+			}
+		}
+	}
+
+	public static void logExceptions(SQLException ex) {
+		logExceptions(ex, null);
+	}
+
+	public static void logExceptions(SQLException ex, String message) {
+		if ( log.isErrorEnabled() ) {
+			if ( log.isDebugEnabled() ) {
+				message = StringHelper.isNotEmpty(message) ? message : DEFAULT_EXCEPTION_MSG;
+				log.debug( message, ex );
+			}
+			while (ex != null) {
+				StringBuffer buf = new StringBuffer(30)
+						.append( "SQL Error: " )
+				        .append( ex.getErrorCode() )
+				        .append( ", SQLState: " )
+				        .append( ex.getSQLState() );
+				log.warn( buf.toString() );
+				log.error( ex.getMessage() );
+				ex = ex.getNextException();
+			}
+		}
+	}
+
+//	public static JDBCException newJDBCException(String string, SQLException root, String sql) {
+//		string = string + " [" + sql + ']';
+//		log.error(string, root);
+//		logExceptions(root);
+//		return new JDBCException(string, root, sql);
+//	}
+//
+//	public static JDBCException newJDBCException(String string, SQLException root) {
+//		log.error(string, root);
+//		logExceptions(root);
+//		return new JDBCException(string, root);
+//	}
+
+}
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/JTAHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,54 +0,0 @@
-//$Id: JTAHelper.java 10068 2006-06-28 17:07:06Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import javax.transaction.Status;
-import javax.transaction.SystemException;
-import javax.transaction.TransactionManager;
-
-import org.hibernate.TransactionException;
-import org.hibernate.engine.SessionFactoryImplementor;
-
-/**
- * @author Gavin King
- */
-public final class JTAHelper {
-
-	private JTAHelper() {}
-
-	public static boolean isRollback(int status) {
-		return status==Status.STATUS_MARKED_ROLLBACK ||
-		       status==Status.STATUS_ROLLING_BACK ||
-		       status==Status.STATUS_ROLLEDBACK;
-	}
-
-	public static boolean isInProgress(int status) {
-		return status==Status.STATUS_ACTIVE ||
-		       status==Status.STATUS_MARKED_ROLLBACK;
-	}
-
-	/**
-	 * Return true if a JTA transaction is in progress
-	 * and false in *every* other cases (including in a JDBC transaction).
-	 */
-	public static boolean isTransactionInProgress(SessionFactoryImplementor factory) {
-		TransactionManager tm = factory.getTransactionManager();
-		try {
-			return tm != null && isTransactionInProgress( tm.getTransaction() );
-		}
-		catch (SystemException se) {
-			throw new TransactionException( "could not obtain JTA Transaction", se );
-		}
-	}
-
-	public static boolean isTransactionInProgress(javax.transaction.Transaction tx) throws SystemException {
-		return tx != null && JTAHelper.isInProgress( tx.getStatus() );
-	}
-
-	public static boolean isMarkedForRollback(int status) {
-		return status == Status.STATUS_MARKED_ROLLBACK;
-	}
-
-	public static boolean isMarkedForRollback(javax.transaction.Transaction tx) throws SystemException {
-		return isMarkedForRollback( tx.getStatus() );
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/JTAHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JTAHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import javax.transaction.Status;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
+
+import org.hibernate.TransactionException;
+import org.hibernate.engine.SessionFactoryImplementor;
+
+/**
+ * @author Gavin King
+ */
+public final class JTAHelper {
+
+	private JTAHelper() {}
+
+	public static boolean isRollback(int status) {
+		return status==Status.STATUS_MARKED_ROLLBACK ||
+		       status==Status.STATUS_ROLLING_BACK ||
+		       status==Status.STATUS_ROLLEDBACK;
+	}
+
+	public static boolean isInProgress(int status) {
+		return status==Status.STATUS_ACTIVE ||
+		       status==Status.STATUS_MARKED_ROLLBACK;
+	}
+
+	/**
+	 * Return true if a JTA transaction is in progress
+	 * and false in *every* other cases (including in a JDBC transaction).
+	 */
+	public static boolean isTransactionInProgress(SessionFactoryImplementor factory) {
+		TransactionManager tm = factory.getTransactionManager();
+		try {
+			return tm != null && isTransactionInProgress( tm.getTransaction() );
+		}
+		catch (SystemException se) {
+			throw new TransactionException( "could not obtain JTA Transaction", se );
+		}
+	}
+
+	public static boolean isTransactionInProgress(javax.transaction.Transaction tx) throws SystemException {
+		return tx != null && JTAHelper.isInProgress( tx.getStatus() );
+	}
+
+	public static boolean isMarkedForRollback(int status) {
+		return status == Status.STATUS_MARKED_ROLLBACK;
+	}
+
+	public static boolean isMarkedForRollback(javax.transaction.Transaction tx) throws SystemException {
+		return isMarkedForRollback( tx.getStatus() );
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/JoinedIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,84 +0,0 @@
-//$Id: JoinedIterator.java 3973 2004-06-28 23:58:08Z epbernard $
-package org.hibernate.util;
-
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * An JoinedIterator is an Iterator that wraps a number of Iterators.
- *
- * This class makes multiple iterators look like one to the caller.
- * When any method from the Iterator interface is called, the JoinedIterator
- * will delegate to a single underlying Iterator. The JoinedIterator will
- * invoke the Iterators in sequence until all Iterators are exhausted.
- *
- */
-public class JoinedIterator implements Iterator {
-
-	private static final Iterator[] ITERATORS = {};
-
-	// wrapped iterators
-	private Iterator[] iterators;
-
-	// index of current iterator in the wrapped iterators array
-	private int currentIteratorIndex;
-
-	// the current iterator
-	private Iterator currentIterator;
-
-	// the last used iterator
-	private Iterator lastUsedIterator;
-
-	public JoinedIterator(List iterators) {
-		this( (Iterator[]) iterators.toArray(ITERATORS) );
-	}
-
-	public JoinedIterator(Iterator[] iterators) {
-		if( iterators==null )
-			throw new NullPointerException("Unexpected NULL iterators argument");
-		this.iterators = iterators;
-	}
-
-	public JoinedIterator(Iterator first, Iterator second) {
-		this( new Iterator[] { first, second } );
-	}
-
-	public boolean hasNext() {
-		updateCurrentIterator();
-		return currentIterator.hasNext();
-	}
-
-	public Object next() {
-		updateCurrentIterator();
-		return currentIterator.next();
-	}
-
-	public void remove() {
-		updateCurrentIterator();
-		lastUsedIterator.remove();
-	}
-
-
-	// call this before any Iterator method to make sure that the current Iterator
-	// is not exhausted
-	protected void updateCurrentIterator() {
-
-		if (currentIterator == null) {
-			if( iterators.length==0  ) {
-				currentIterator = EmptyIterator.INSTANCE;
-			}
-			else {
-				currentIterator = iterators[0];
-			}
-			// set last used iterator here, in case the user calls remove
-			// before calling hasNext() or next() (although they shouldn't)
-			lastUsedIterator = currentIterator;
-		}
-
-		while (! currentIterator.hasNext() && currentIteratorIndex < iterators.length - 1) {
-			currentIteratorIndex++;
-			currentIterator = iterators[currentIteratorIndex];
-		}
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/JoinedIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/JoinedIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,107 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * An JoinedIterator is an Iterator that wraps a number of Iterators.
+ *
+ * This class makes multiple iterators look like one to the caller.
+ * When any method from the Iterator interface is called, the JoinedIterator
+ * will delegate to a single underlying Iterator. The JoinedIterator will
+ * invoke the Iterators in sequence until all Iterators are exhausted.
+ *
+ */
+public class JoinedIterator implements Iterator {
+
+	private static final Iterator[] ITERATORS = {};
+
+	// wrapped iterators
+	private Iterator[] iterators;
+
+	// index of current iterator in the wrapped iterators array
+	private int currentIteratorIndex;
+
+	// the current iterator
+	private Iterator currentIterator;
+
+	// the last used iterator
+	private Iterator lastUsedIterator;
+
+	public JoinedIterator(List iterators) {
+		this( (Iterator[]) iterators.toArray(ITERATORS) );
+	}
+
+	public JoinedIterator(Iterator[] iterators) {
+		if( iterators==null )
+			throw new NullPointerException("Unexpected NULL iterators argument");
+		this.iterators = iterators;
+	}
+
+	public JoinedIterator(Iterator first, Iterator second) {
+		this( new Iterator[] { first, second } );
+	}
+
+	public boolean hasNext() {
+		updateCurrentIterator();
+		return currentIterator.hasNext();
+	}
+
+	public Object next() {
+		updateCurrentIterator();
+		return currentIterator.next();
+	}
+
+	public void remove() {
+		updateCurrentIterator();
+		lastUsedIterator.remove();
+	}
+
+
+	// call this before any Iterator method to make sure that the current Iterator
+	// is not exhausted
+	protected void updateCurrentIterator() {
+
+		if (currentIterator == null) {
+			if( iterators.length==0  ) {
+				currentIterator = EmptyIterator.INSTANCE;
+			}
+			else {
+				currentIterator = iterators[0];
+			}
+			// set last used iterator here, in case the user calls remove
+			// before calling hasNext() or next() (although they shouldn't)
+			lastUsedIterator = currentIterator;
+		}
+
+		while (! currentIterator.hasNext() && currentIteratorIndex < iterators.length - 1) {
+			currentIteratorIndex++;
+			currentIterator = iterators[currentIteratorIndex];
+		}
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/LazyIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,35 +0,0 @@
-//$Id: LazyIterator.java 7699 2005-07-30 04:56:09Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.Iterator;
-import java.util.Map;
-
-public final class LazyIterator implements Iterator {
-	
-	private final Map map;
-	private Iterator iterator;
-	
-	private Iterator getIterator() {
-		if (iterator==null) {
-			iterator = map.values().iterator();
-		}
-		return iterator;
-	}
-
-	public LazyIterator(Map map) {
-		this.map = map;
-	}
-	
-	public boolean hasNext() {
-		return getIterator().hasNext();
-	}
-
-	public Object next() {
-		return getIterator().next();
-	}
-
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/LazyIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/LazyIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.util.Iterator;
+import java.util.Map;
+
+public final class LazyIterator implements Iterator {
+	
+	private final Map map;
+	private Iterator iterator;
+	
+	private Iterator getIterator() {
+		if (iterator==null) {
+			iterator = map.values().iterator();
+		}
+		return iterator;
+	}
+
+	public LazyIterator(Map map) {
+		this.map = map;
+	}
+	
+	public boolean hasNext() {
+		return getIterator().hasNext();
+	}
+
+	public Object next() {
+		return getIterator().next();
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,16 +0,0 @@
-//$Id: MarkerObject.java 4649 2004-10-07 00:14:29Z oneovthafew $
-package org.hibernate.util;
-
-/**
- * @author Gavin King
- */
-public class MarkerObject {
-	private String name;
-	
-	public MarkerObject(String name) {
-		this.name=name;
-	}
-	public String toString() {
-		return name;
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/MarkerObject.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/MarkerObject.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+/**
+ * @author Gavin King
+ */
+public class MarkerObject {
+	private String name;
+	
+	public MarkerObject(String name) {
+		this.name=name;
+	}
+	public String toString() {
+		return name;
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/NamingHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,121 +0,0 @@
-//$Id: NamingHelper.java 8149 2005-09-11 21:10:52Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Properties;
-
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.naming.Name;
-import javax.naming.NameNotFoundException;
-import javax.naming.NamingException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.hibernate.cfg.Environment;
-
-public final class NamingHelper {
-
-	private static final Logger log = LoggerFactory.getLogger(NamingHelper.class);
-
-	public static InitialContext getInitialContext(Properties props) throws NamingException {
-
-		Hashtable hash = getJndiProperties(props);
-		log.info("JNDI InitialContext properties:" + hash);
-		try {
-			return hash.size()==0 ?
-					new InitialContext() :
-					new InitialContext(hash);
-		}
-		catch (NamingException e) {
-			log.error("Could not obtain initial context", e);
-			throw e;
-		}
-	}
-
-	/**
-	 * Bind val to name in ctx, and make sure that all intermediate contexts exist.
-	 *
-	 * @param ctx the root context
-	 * @param name the name as a string
-	 * @param val the object to be bound
-	 * @throws NamingException
-	 */
-	public static void bind(Context ctx, String name, Object val) throws NamingException {
-		try {
-			log.trace("binding: " + name);
-			ctx.rebind(name, val);
-		}
-		catch (Exception e) {
-			Name n = ctx.getNameParser("").parse(name);
-			while ( n.size() > 1 ) {
-				String ctxName = n.get(0);
-
-				Context subctx=null;
-				try {
-					log.trace("lookup: " + ctxName);
-					subctx = (Context) ctx.lookup(ctxName);
-				}
-				catch (NameNotFoundException nfe) {}
-
-				if (subctx!=null) {
-					log.debug("Found subcontext: " + ctxName);
-					ctx = subctx;
-				}
-				else {
-					log.info("Creating subcontext: " + ctxName);
-					ctx = ctx.createSubcontext(ctxName);
-				}
-				n = n.getSuffix(1);
-			}
-			log.trace("binding: " + n);
-			ctx.rebind(n, val);
-		}
-		log.debug("Bound name: " + name);
-	}
-
-	/**
-	 * Transform JNDI properties passed in the form <tt>hibernate.jndi.*</tt> to the
-	 * format accepted by <tt>InitialContext</tt> by triming the leading "<tt>hibernate.jndi</tt>".
-	 */
-	public static Properties getJndiProperties(Properties properties) {
-
-		HashSet specialProps = new HashSet();
-		specialProps.add(Environment.JNDI_CLASS);
-		specialProps.add(Environment.JNDI_URL);
-
-		Iterator iter = properties.keySet().iterator();
-		Properties result = new Properties();
-		while ( iter.hasNext() ) {
-			String prop = (String) iter.next();
-			if ( prop.indexOf(Environment.JNDI_PREFIX) > -1 && !specialProps.contains(prop) ) {
-				result.setProperty(
-						prop.substring( Environment.JNDI_PREFIX.length()+1 ),
-						properties.getProperty(prop)
-					);
-			}
-		}
-
-		String jndiClass = properties.getProperty(Environment.JNDI_CLASS);
-		String jndiURL = properties.getProperty(Environment.JNDI_URL);
-		// we want to be able to just use the defaults,
-		// if JNDI environment properties are not supplied
-		// so don't put null in anywhere
-		if (jndiClass != null) result.put(Context.INITIAL_CONTEXT_FACTORY, jndiClass);
-		if (jndiURL != null) result.put(Context.PROVIDER_URL, jndiURL);
-
-		return result;
-	}
-
-	private NamingHelper() {}
-
-}
-
-
-
-
-
-
-

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/NamingHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/NamingHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,144 @@
+/*
+ * 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.util;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Properties;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.Name;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.hibernate.cfg.Environment;
+
+public final class NamingHelper {
+
+	private static final Logger log = LoggerFactory.getLogger(NamingHelper.class);
+
+	public static InitialContext getInitialContext(Properties props) throws NamingException {
+
+		Hashtable hash = getJndiProperties(props);
+		log.info("JNDI InitialContext properties:" + hash);
+		try {
+			return hash.size()==0 ?
+					new InitialContext() :
+					new InitialContext(hash);
+		}
+		catch (NamingException e) {
+			log.error("Could not obtain initial context", e);
+			throw e;
+		}
+	}
+
+	/**
+	 * Bind val to name in ctx, and make sure that all intermediate contexts exist.
+	 *
+	 * @param ctx the root context
+	 * @param name the name as a string
+	 * @param val the object to be bound
+	 * @throws NamingException
+	 */
+	public static void bind(Context ctx, String name, Object val) throws NamingException {
+		try {
+			log.trace("binding: " + name);
+			ctx.rebind(name, val);
+		}
+		catch (Exception e) {
+			Name n = ctx.getNameParser("").parse(name);
+			while ( n.size() > 1 ) {
+				String ctxName = n.get(0);
+
+				Context subctx=null;
+				try {
+					log.trace("lookup: " + ctxName);
+					subctx = (Context) ctx.lookup(ctxName);
+				}
+				catch (NameNotFoundException nfe) {}
+
+				if (subctx!=null) {
+					log.debug("Found subcontext: " + ctxName);
+					ctx = subctx;
+				}
+				else {
+					log.info("Creating subcontext: " + ctxName);
+					ctx = ctx.createSubcontext(ctxName);
+				}
+				n = n.getSuffix(1);
+			}
+			log.trace("binding: " + n);
+			ctx.rebind(n, val);
+		}
+		log.debug("Bound name: " + name);
+	}
+
+	/**
+	 * Transform JNDI properties passed in the form <tt>hibernate.jndi.*</tt> to the
+	 * format accepted by <tt>InitialContext</tt> by triming the leading "<tt>hibernate.jndi</tt>".
+	 */
+	public static Properties getJndiProperties(Properties properties) {
+
+		HashSet specialProps = new HashSet();
+		specialProps.add(Environment.JNDI_CLASS);
+		specialProps.add(Environment.JNDI_URL);
+
+		Iterator iter = properties.keySet().iterator();
+		Properties result = new Properties();
+		while ( iter.hasNext() ) {
+			String prop = (String) iter.next();
+			if ( prop.indexOf(Environment.JNDI_PREFIX) > -1 && !specialProps.contains(prop) ) {
+				result.setProperty(
+						prop.substring( Environment.JNDI_PREFIX.length()+1 ),
+						properties.getProperty(prop)
+					);
+			}
+		}
+
+		String jndiClass = properties.getProperty(Environment.JNDI_CLASS);
+		String jndiURL = properties.getProperty(Environment.JNDI_URL);
+		// we want to be able to just use the defaults,
+		// if JNDI environment properties are not supplied
+		// so don't put null in anywhere
+		if (jndiClass != null) result.put(Context.INITIAL_CONTEXT_FACTORY, jndiClass);
+		if (jndiURL != null) result.put(Context.PROVIDER_URL, jndiURL);
+
+		return result;
+	}
+
+	private NamingHelper() {}
+
+}
+
+
+
+
+
+
+

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/PropertiesHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,277 +0,0 @@
-//$Id: PropertiesHelper.java 9712 2006-03-29 13:56:59Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import java.util.Iterator;
-
-/**
- * Collection of helper methods for dealing with {@link java.util.Properties}
- * objects.
- *
- * @author Gavin King
- * @author Steve Ebersole
- */
-public final class PropertiesHelper {
-
-	private static final String PLACEHOLDER_START = "${";
-
-	/**
-	 * Disallow instantiation
-	 */
-	private PropertiesHelper() {
-	}
-
-	/**
-	 * Get a property value as a string.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param properties The properties object
-	 * @param defaultValue The default property value to use.
-	 * @return The property value; may be null.
-	 */
-	public static String getString(String propertyName, Properties properties, String defaultValue) {
-		String value = extractPropertyValue( propertyName, properties );
-		return value == null ? defaultValue : value;
-	}
-
-	/**
-	 * Extract a property value by name from the given properties object.
-	 * <p/>
-	 * Both <tt>null</tt> and <tt>empty string</tt> are viewed as the same, and return null.
-	 *
-	 * @param propertyName The name of the property for which to extract value
-	 * @param properties The properties object
-	 * @return The property value; may be null.
-	 */
-	public static String extractPropertyValue(String propertyName, Properties properties) {
-		String value = properties.getProperty( propertyName );
-		if ( value == null ) {
-			return null;
-		}
-		value = value.trim();
-		if ( StringHelper.isEmpty( value ) ) {
-			return null;
-		}
-		return value;
-	}
-
-	/**
-	 * Get a property value as a boolean.  Shorthand for calling
-	 * {@link #getBoolean(String, java.util.Properties, boolean)} with <tt>false</tt>
-	 * as the default value.
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param properties The properties object
-	 * @return The property value.
-	 */
-	public static boolean getBoolean(String propertyName, Properties properties) {
-		return getBoolean( propertyName, properties, false );
-	}
-
-	/**
-	 * Get a property value as a boolean.
-	 * <p/>
-	 * First, the string value is extracted, and then {@link Boolean#valueOf(String)} is
-	 * used to determine the correct boolean value.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param properties The properties object
-	 * @param defaultValue The default property value to use.
-	 * @return The property value.
-	 */
-	public static boolean getBoolean(String propertyName, Properties properties, boolean defaultValue) {
-		String value = extractPropertyValue( propertyName, properties );
-		return value == null ? defaultValue : Boolean.valueOf( value ).booleanValue();
-	}
-
-	/**
-	 * Get a property value as an int.
-	 * <p/>
-	 * First, the string value is extracted, and then {@link Integer#parseInt(String)} is
-	 * used to determine the correct int value for any non-null property values.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param properties The properties object
-	 * @param defaultValue The default property value to use.
-	 * @return The property value.
-	 */
-	public static int getInt(String propertyName, Properties properties, int defaultValue) {
-		String value = extractPropertyValue( propertyName, properties );
-		return value == null ? defaultValue : Integer.parseInt( value );
-	}
-
-	/**
-	 * Get a property value as an Integer.
-	 * <p/>
-	 * First, the string value is extracted, and then {@link Integer#valueOf(String)} is
-	 * used to determine the correct boolean value for any non-null property values.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param properties The properties object
-	 * @return The property value; may be null.
-	 */
-	public static Integer getInteger(String propertyName, Properties properties) {
-		String value = extractPropertyValue( propertyName, properties );
-		return value == null ? null : Integer.valueOf( value );
-	}
-
-	/**
-	 * Constructs a map from a property value.
-	 * <p/>
-	 * The exact behavior here is largely dependant upon what is passed in as
-	 * the delimiter.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param delim The string defining tokens used as both entry and key/value delimiters.
-	 * @param properties The properties object
-	 * @return The resulting map; never null, though perhaps empty.
-	 */
-	public static Map toMap(String propertyName, String delim, Properties properties) {
-		Map map = new HashMap();
-		String value = extractPropertyValue( propertyName, properties );
-		if ( value != null ) {
-			StringTokenizer tokens = new StringTokenizer( value, delim );
-			while ( tokens.hasMoreTokens() ) {
-				map.put( tokens.nextToken(), tokens.hasMoreElements() ? tokens.nextToken() : "" );
-			}
-		}
-		return map;
-	}
-
-	/**
-	 * Get a property value as a string array.
-	 *
-	 * @see #extractPropertyValue(String, java.util.Properties)
-	 * @see #toStringArray(String, String)
-	 *
-	 * @param propertyName The name of the property for which to retrieve value
-	 * @param delim The delimiter used to separate individual array elements.
-	 * @param properties The properties object
-	 * @return The array; never null, though may be empty.
-	 */
-	public static String[] toStringArray(String propertyName, String delim, Properties properties) {
-		return toStringArray( extractPropertyValue( propertyName, properties ), delim );
-	}
-
-	/**
-	 * Convert a string to an array of strings.  The assumption is that
-	 * the individual array elements are delimited in the source stringForm
-	 * param by the delim param.
-	 *
-	 * @param stringForm The string form of the string array.
-	 * @param delim The delimiter used to separate individual array elements.
-	 * @return The array; never null, though may be empty.
-	 */
-	public static String[] toStringArray(String stringForm, String delim) {
-		// todo : move to StringHelper?
-		if ( stringForm != null ) {
-			return StringHelper.split( delim, stringForm );
-		}
-		else {
-			return ArrayHelper.EMPTY_STRING_ARRAY;
-		}
-	}
-
-	/**
-	 * replace a property by a starred version
-	 *
-	 * @param props properties to check
-	 * @param key proeprty to mask
-	 * @return cloned and masked properties
-	 */
-	public static Properties maskOut(Properties props, String key) {
-		Properties clone = ( Properties ) props.clone();
-		if ( clone.get( key ) != null ) {
-			clone.setProperty( key, "****" );
-		}
-		return clone;
-	}
-
-	/**
-	 * Handles interpolation processing for all entries in a properties object.
-	 *
-	 * @param properties The properties object.
-	 */
-	public static void resolvePlaceHolders(Properties properties) {
-		Iterator itr = properties.entrySet().iterator();
-		while ( itr.hasNext() ) {
-			final Map.Entry entry = ( Map.Entry ) itr.next();
-			final Object value = entry.getValue();
-			if ( value != null && String.class.isInstance( value ) ) {
-				final String resolved = resolvePlaceHolder( ( String ) value );
-				if ( !value.equals( resolved ) ) {
-					if ( resolved == null ) {
-						itr.remove();
-					}
-					else {
-						entry.setValue( resolved );
-					}
-				}
-			}
-		}
-	}
-
-	/**
-	 * Handles interpolation processing for a single property.
-	 *
-	 * @param property The property value to be processed for interpolation.
-	 * @return The (possibly) interpolated property value.
-	 */
-	public static String resolvePlaceHolder(String property) {
-		if ( property.indexOf( PLACEHOLDER_START ) < 0 ) {
-			return property;
-		}
-		StringBuffer buff = new StringBuffer();
-		char[] chars = property.toCharArray();
-		for ( int pos = 0; pos < chars.length; pos++ ) {
-			if ( chars[pos] == '$' ) {
-				// peek ahead
-				if ( chars[pos+1] == '{' ) {
-					// we have a placeholder, spin forward till we find the end
-					String systemPropertyName = "";
-					int x = pos + 2;
-					for (  ; x < chars.length && chars[x] != '}'; x++ ) {
-						systemPropertyName += chars[x];
-						// if we reach the end of the string w/o finding the
-						// matching end, that is an exception
-						if ( x == chars.length - 1 ) {
-							throw new IllegalArgumentException( "unmatched placeholder start [" + property + "]" );
-						}
-					}
-					String systemProperty = extractFromSystem( systemPropertyName );
-					buff.append( systemProperty == null ? "" : systemProperty );
-					pos = x + 1;
-					// make sure spinning forward did not put us past the end of the buffer...
-					if ( pos >= chars.length ) {
-						break;
-					}
-				}
-			}
-			buff.append( chars[pos] );
-		}
-		String rtn = buff.toString();
-		return StringHelper.isEmpty( rtn ) ? null : rtn;
-	}
-
-	private static String extractFromSystem(String systemPropertyName) {
-		try {
-			return System.getProperty( systemPropertyName );
-		}
-		catch( Throwable t ) {
-			return null;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/PropertiesHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/PropertiesHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,300 @@
+/*
+ * 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.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.Iterator;
+
+/**
+ * Collection of helper methods for dealing with {@link java.util.Properties}
+ * objects.
+ *
+ * @author Gavin King
+ * @author Steve Ebersole
+ */
+public final class PropertiesHelper {
+
+	private static final String PLACEHOLDER_START = "${";
+
+	/**
+	 * Disallow instantiation
+	 */
+	private PropertiesHelper() {
+	}
+
+	/**
+	 * Get a property value as a string.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param properties The properties object
+	 * @param defaultValue The default property value to use.
+	 * @return The property value; may be null.
+	 */
+	public static String getString(String propertyName, Properties properties, String defaultValue) {
+		String value = extractPropertyValue( propertyName, properties );
+		return value == null ? defaultValue : value;
+	}
+
+	/**
+	 * Extract a property value by name from the given properties object.
+	 * <p/>
+	 * Both <tt>null</tt> and <tt>empty string</tt> are viewed as the same, and return null.
+	 *
+	 * @param propertyName The name of the property for which to extract value
+	 * @param properties The properties object
+	 * @return The property value; may be null.
+	 */
+	public static String extractPropertyValue(String propertyName, Properties properties) {
+		String value = properties.getProperty( propertyName );
+		if ( value == null ) {
+			return null;
+		}
+		value = value.trim();
+		if ( StringHelper.isEmpty( value ) ) {
+			return null;
+		}
+		return value;
+	}
+
+	/**
+	 * Get a property value as a boolean.  Shorthand for calling
+	 * {@link #getBoolean(String, java.util.Properties, boolean)} with <tt>false</tt>
+	 * as the default value.
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param properties The properties object
+	 * @return The property value.
+	 */
+	public static boolean getBoolean(String propertyName, Properties properties) {
+		return getBoolean( propertyName, properties, false );
+	}
+
+	/**
+	 * Get a property value as a boolean.
+	 * <p/>
+	 * First, the string value is extracted, and then {@link Boolean#valueOf(String)} is
+	 * used to determine the correct boolean value.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param properties The properties object
+	 * @param defaultValue The default property value to use.
+	 * @return The property value.
+	 */
+	public static boolean getBoolean(String propertyName, Properties properties, boolean defaultValue) {
+		String value = extractPropertyValue( propertyName, properties );
+		return value == null ? defaultValue : Boolean.valueOf( value ).booleanValue();
+	}
+
+	/**
+	 * Get a property value as an int.
+	 * <p/>
+	 * First, the string value is extracted, and then {@link Integer#parseInt(String)} is
+	 * used to determine the correct int value for any non-null property values.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param properties The properties object
+	 * @param defaultValue The default property value to use.
+	 * @return The property value.
+	 */
+	public static int getInt(String propertyName, Properties properties, int defaultValue) {
+		String value = extractPropertyValue( propertyName, properties );
+		return value == null ? defaultValue : Integer.parseInt( value );
+	}
+
+	/**
+	 * Get a property value as an Integer.
+	 * <p/>
+	 * First, the string value is extracted, and then {@link Integer#valueOf(String)} is
+	 * used to determine the correct boolean value for any non-null property values.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param properties The properties object
+	 * @return The property value; may be null.
+	 */
+	public static Integer getInteger(String propertyName, Properties properties) {
+		String value = extractPropertyValue( propertyName, properties );
+		return value == null ? null : Integer.valueOf( value );
+	}
+
+	/**
+	 * Constructs a map from a property value.
+	 * <p/>
+	 * The exact behavior here is largely dependant upon what is passed in as
+	 * the delimiter.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param delim The string defining tokens used as both entry and key/value delimiters.
+	 * @param properties The properties object
+	 * @return The resulting map; never null, though perhaps empty.
+	 */
+	public static Map toMap(String propertyName, String delim, Properties properties) {
+		Map map = new HashMap();
+		String value = extractPropertyValue( propertyName, properties );
+		if ( value != null ) {
+			StringTokenizer tokens = new StringTokenizer( value, delim );
+			while ( tokens.hasMoreTokens() ) {
+				map.put( tokens.nextToken(), tokens.hasMoreElements() ? tokens.nextToken() : "" );
+			}
+		}
+		return map;
+	}
+
+	/**
+	 * Get a property value as a string array.
+	 *
+	 * @see #extractPropertyValue(String, java.util.Properties)
+	 * @see #toStringArray(String, String)
+	 *
+	 * @param propertyName The name of the property for which to retrieve value
+	 * @param delim The delimiter used to separate individual array elements.
+	 * @param properties The properties object
+	 * @return The array; never null, though may be empty.
+	 */
+	public static String[] toStringArray(String propertyName, String delim, Properties properties) {
+		return toStringArray( extractPropertyValue( propertyName, properties ), delim );
+	}
+
+	/**
+	 * Convert a string to an array of strings.  The assumption is that
+	 * the individual array elements are delimited in the source stringForm
+	 * param by the delim param.
+	 *
+	 * @param stringForm The string form of the string array.
+	 * @param delim The delimiter used to separate individual array elements.
+	 * @return The array; never null, though may be empty.
+	 */
+	public static String[] toStringArray(String stringForm, String delim) {
+		// todo : move to StringHelper?
+		if ( stringForm != null ) {
+			return StringHelper.split( delim, stringForm );
+		}
+		else {
+			return ArrayHelper.EMPTY_STRING_ARRAY;
+		}
+	}
+
+	/**
+	 * replace a property by a starred version
+	 *
+	 * @param props properties to check
+	 * @param key proeprty to mask
+	 * @return cloned and masked properties
+	 */
+	public static Properties maskOut(Properties props, String key) {
+		Properties clone = ( Properties ) props.clone();
+		if ( clone.get( key ) != null ) {
+			clone.setProperty( key, "****" );
+		}
+		return clone;
+	}
+
+	/**
+	 * Handles interpolation processing for all entries in a properties object.
+	 *
+	 * @param properties The properties object.
+	 */
+	public static void resolvePlaceHolders(Properties properties) {
+		Iterator itr = properties.entrySet().iterator();
+		while ( itr.hasNext() ) {
+			final Map.Entry entry = ( Map.Entry ) itr.next();
+			final Object value = entry.getValue();
+			if ( value != null && String.class.isInstance( value ) ) {
+				final String resolved = resolvePlaceHolder( ( String ) value );
+				if ( !value.equals( resolved ) ) {
+					if ( resolved == null ) {
+						itr.remove();
+					}
+					else {
+						entry.setValue( resolved );
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Handles interpolation processing for a single property.
+	 *
+	 * @param property The property value to be processed for interpolation.
+	 * @return The (possibly) interpolated property value.
+	 */
+	public static String resolvePlaceHolder(String property) {
+		if ( property.indexOf( PLACEHOLDER_START ) < 0 ) {
+			return property;
+		}
+		StringBuffer buff = new StringBuffer();
+		char[] chars = property.toCharArray();
+		for ( int pos = 0; pos < chars.length; pos++ ) {
+			if ( chars[pos] == '$' ) {
+				// peek ahead
+				if ( chars[pos+1] == '{' ) {
+					// we have a placeholder, spin forward till we find the end
+					String systemPropertyName = "";
+					int x = pos + 2;
+					for (  ; x < chars.length && chars[x] != '}'; x++ ) {
+						systemPropertyName += chars[x];
+						// if we reach the end of the string w/o finding the
+						// matching end, that is an exception
+						if ( x == chars.length - 1 ) {
+							throw new IllegalArgumentException( "unmatched placeholder start [" + property + "]" );
+						}
+					}
+					String systemProperty = extractFromSystem( systemPropertyName );
+					buff.append( systemProperty == null ? "" : systemProperty );
+					pos = x + 1;
+					// make sure spinning forward did not put us past the end of the buffer...
+					if ( pos >= chars.length ) {
+						break;
+					}
+				}
+			}
+			buff.append( chars[pos] );
+		}
+		String rtn = buff.toString();
+		return StringHelper.isEmpty( rtn ) ? null : rtn;
+	}
+
+	private static String extractFromSystem(String systemPropertyName) {
+		try {
+			return System.getProperty( systemPropertyName );
+		}
+		catch( Throwable t ) {
+			return null;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,201 +0,0 @@
-//$Id: ReflectHelper.java 10109 2006-07-12 15:39:59Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-
-import org.hibernate.AssertionFailure;
-import org.hibernate.MappingException;
-import org.hibernate.PropertyNotFoundException;
-import org.hibernate.property.BasicPropertyAccessor;
-import org.hibernate.property.DirectPropertyAccessor;
-import org.hibernate.property.Getter;
-import org.hibernate.property.PropertyAccessor;
-import org.hibernate.type.PrimitiveType;
-import org.hibernate.type.Type;
-
-
-public final class ReflectHelper {
-
-	//TODO: this dependency is kinda Bad
-	private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
-	private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
-
-	private static final Class[] NO_CLASSES = new Class[0];
-	private static final Class[] OBJECT = new Class[] { Object.class };
-	private static final Method OBJECT_EQUALS;
-	private static final Class[] NO_PARAM = new Class[] { };
-
-	private static final Method OBJECT_HASHCODE;
-	static {
-		Method eq;
-		Method hash;
-		try {
-			eq = Object.class.getMethod("equals", OBJECT);
-			hash = Object.class.getMethod("hashCode", NO_PARAM);
-		}
-		catch (Exception e) {
-			throw new AssertionFailure("Could not find Object.equals() or Object.hashCode()", e);
-		}
-		OBJECT_EQUALS = eq;
-		OBJECT_HASHCODE = hash;
-	}
-
-	public static boolean overridesEquals(Class clazz) {
-		Method equals;
-		try {
-			equals = clazz.getMethod("equals", OBJECT);
-		}
-		catch (NoSuchMethodException nsme) {
-			return false; //its an interface so we can't really tell anything...
-		}
-		return !OBJECT_EQUALS.equals(equals);
-	}
-
-	public static boolean overridesHashCode(Class clazz) {
-		Method hashCode;
-		try {
-			hashCode = clazz.getMethod("hashCode", NO_PARAM);
-		}
-		catch (NoSuchMethodException nsme) {
-			return false; //its an interface so we can't really tell anything...
-		}
-		return !OBJECT_HASHCODE.equals(hashCode);
-	}
-
-	public static Class reflectedPropertyClass(String className, String name) throws MappingException {
-		try {
-			Class clazz = ReflectHelper.classForName(className);
-			return getter(clazz, name).getReturnType();
-		}
-		catch (ClassNotFoundException cnfe) {
-			throw new MappingException("class " + className + " not found while looking for property: " + name, cnfe);
-		}
-	}
-
-	private static Getter getter(Class clazz, String name) throws MappingException {
-		try {
-			return BASIC_PROPERTY_ACCESSOR.getGetter(clazz, name);
-		}
-		catch (PropertyNotFoundException pnfe) {
-			return DIRECT_PROPERTY_ACCESSOR.getGetter(clazz, name);
-		}
-	}
-
-	public static Getter getGetter(Class theClass, String name) throws MappingException {
-		return BASIC_PROPERTY_ACCESSOR.getGetter(theClass, name);
-	}
-
-	public static Class classForName(String name) throws ClassNotFoundException {
-		try {
-			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-			if ( contextClassLoader != null ) {
-				return contextClassLoader.loadClass(name);
-			}
-		}
-		catch ( Throwable t ) {
-		}
-		return Class.forName( name );
-	}
-
-	public static Class classForName(String name, Class caller) throws ClassNotFoundException {
-		try {
-			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
-			if ( contextClassLoader != null ) {
-				return contextClassLoader.loadClass( name );
-			}
-		}
-		catch ( Throwable e ) {
-		}
-		return Class.forName( name, true, caller.getClassLoader() );
-	}
-
-	public static boolean isPublic(Class clazz, Member member) {
-		return Modifier.isPublic( member.getModifiers() ) && Modifier.isPublic( clazz.getModifiers() );
-	}
-
-	public static Object getConstantValue(String name) {
-		Class clazz;
-		try {
-			clazz = classForName( StringHelper.qualifier( name ) );
-		}
-		catch ( Throwable t ) {
-			return null;
-		}
-		try {
-			return clazz.getField( StringHelper.unqualify( name ) ).get(null);
-		}
-		catch ( Throwable t ) {
-			return null;
-		}
-	}
-
-	public static Constructor getDefaultConstructor(Class clazz) throws PropertyNotFoundException {
-
-		if ( isAbstractClass(clazz) ) return null;
-
-		try {
-			Constructor constructor = clazz.getDeclaredConstructor(NO_CLASSES);
-			if ( !isPublic(clazz, constructor) ) {
-				constructor.setAccessible(true);
-			}
-			return constructor;
-		}
-		catch (NoSuchMethodException nme) {
-			throw new PropertyNotFoundException(
-				"Object class " + clazz.getName() +
-				" must declare a default (no-argument) constructor"
-			);
-		}
-
-	}
-
-	public static boolean isAbstractClass(Class clazz) {
-		int modifier = clazz.getModifiers();
-		return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
-	}
-	
-	public static boolean isFinalClass(Class clazz) {
-		return Modifier.isFinal( clazz.getModifiers() );
-	}
-
-	public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
-		final Constructor[] candidates = clazz.getConstructors();
-		for ( int i=0; i<candidates.length; i++ ) {
-			final Constructor constructor = candidates[i];
-			final Class[] params = constructor.getParameterTypes();
-			if ( params.length==types.length ) {
-				boolean found = true;
-				for ( int j=0; j<params.length; j++ ) {
-					final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
-						types[j] instanceof PrimitiveType &&
-						params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
-					);
-					if (!ok) {
-						found = false;
-						break;
-					}
-				}
-				if (found) {
-					if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
-					return constructor;
-				}
-			}
-		}
-		throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
-	}
-	
-	public static Method getMethod(Class clazz, Method method) {
-		try {
-			return clazz.getMethod( method.getName(), method.getParameterTypes() );
-		}
-		catch (Exception e) {
-			return null;
-		}
-	}
-
-	private ReflectHelper() {}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/ReflectHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/ReflectHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,224 @@
+/*
+ * 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.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import org.hibernate.AssertionFailure;
+import org.hibernate.MappingException;
+import org.hibernate.PropertyNotFoundException;
+import org.hibernate.property.BasicPropertyAccessor;
+import org.hibernate.property.DirectPropertyAccessor;
+import org.hibernate.property.Getter;
+import org.hibernate.property.PropertyAccessor;
+import org.hibernate.type.PrimitiveType;
+import org.hibernate.type.Type;
+
+
+public final class ReflectHelper {
+
+	//TODO: this dependency is kinda Bad
+	private static final PropertyAccessor BASIC_PROPERTY_ACCESSOR = new BasicPropertyAccessor();
+	private static final PropertyAccessor DIRECT_PROPERTY_ACCESSOR = new DirectPropertyAccessor();
+
+	private static final Class[] NO_CLASSES = new Class[0];
+	private static final Class[] OBJECT = new Class[] { Object.class };
+	private static final Method OBJECT_EQUALS;
+	private static final Class[] NO_PARAM = new Class[] { };
+
+	private static final Method OBJECT_HASHCODE;
+	static {
+		Method eq;
+		Method hash;
+		try {
+			eq = Object.class.getMethod("equals", OBJECT);
+			hash = Object.class.getMethod("hashCode", NO_PARAM);
+		}
+		catch (Exception e) {
+			throw new AssertionFailure("Could not find Object.equals() or Object.hashCode()", e);
+		}
+		OBJECT_EQUALS = eq;
+		OBJECT_HASHCODE = hash;
+	}
+
+	public static boolean overridesEquals(Class clazz) {
+		Method equals;
+		try {
+			equals = clazz.getMethod("equals", OBJECT);
+		}
+		catch (NoSuchMethodException nsme) {
+			return false; //its an interface so we can't really tell anything...
+		}
+		return !OBJECT_EQUALS.equals(equals);
+	}
+
+	public static boolean overridesHashCode(Class clazz) {
+		Method hashCode;
+		try {
+			hashCode = clazz.getMethod("hashCode", NO_PARAM);
+		}
+		catch (NoSuchMethodException nsme) {
+			return false; //its an interface so we can't really tell anything...
+		}
+		return !OBJECT_HASHCODE.equals(hashCode);
+	}
+
+	public static Class reflectedPropertyClass(String className, String name) throws MappingException {
+		try {
+			Class clazz = ReflectHelper.classForName(className);
+			return getter(clazz, name).getReturnType();
+		}
+		catch (ClassNotFoundException cnfe) {
+			throw new MappingException("class " + className + " not found while looking for property: " + name, cnfe);
+		}
+	}
+
+	private static Getter getter(Class clazz, String name) throws MappingException {
+		try {
+			return BASIC_PROPERTY_ACCESSOR.getGetter(clazz, name);
+		}
+		catch (PropertyNotFoundException pnfe) {
+			return DIRECT_PROPERTY_ACCESSOR.getGetter(clazz, name);
+		}
+	}
+
+	public static Getter getGetter(Class theClass, String name) throws MappingException {
+		return BASIC_PROPERTY_ACCESSOR.getGetter(theClass, name);
+	}
+
+	public static Class classForName(String name) throws ClassNotFoundException {
+		try {
+			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+			if ( contextClassLoader != null ) {
+				return contextClassLoader.loadClass(name);
+			}
+		}
+		catch ( Throwable t ) {
+		}
+		return Class.forName( name );
+	}
+
+	public static Class classForName(String name, Class caller) throws ClassNotFoundException {
+		try {
+			ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+			if ( contextClassLoader != null ) {
+				return contextClassLoader.loadClass( name );
+			}
+		}
+		catch ( Throwable e ) {
+		}
+		return Class.forName( name, true, caller.getClassLoader() );
+	}
+
+	public static boolean isPublic(Class clazz, Member member) {
+		return Modifier.isPublic( member.getModifiers() ) && Modifier.isPublic( clazz.getModifiers() );
+	}
+
+	public static Object getConstantValue(String name) {
+		Class clazz;
+		try {
+			clazz = classForName( StringHelper.qualifier( name ) );
+		}
+		catch ( Throwable t ) {
+			return null;
+		}
+		try {
+			return clazz.getField( StringHelper.unqualify( name ) ).get(null);
+		}
+		catch ( Throwable t ) {
+			return null;
+		}
+	}
+
+	public static Constructor getDefaultConstructor(Class clazz) throws PropertyNotFoundException {
+
+		if ( isAbstractClass(clazz) ) return null;
+
+		try {
+			Constructor constructor = clazz.getDeclaredConstructor(NO_CLASSES);
+			if ( !isPublic(clazz, constructor) ) {
+				constructor.setAccessible(true);
+			}
+			return constructor;
+		}
+		catch (NoSuchMethodException nme) {
+			throw new PropertyNotFoundException(
+				"Object class " + clazz.getName() +
+				" must declare a default (no-argument) constructor"
+			);
+		}
+
+	}
+
+	public static boolean isAbstractClass(Class clazz) {
+		int modifier = clazz.getModifiers();
+		return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
+	}
+	
+	public static boolean isFinalClass(Class clazz) {
+		return Modifier.isFinal( clazz.getModifiers() );
+	}
+
+	public static Constructor getConstructor(Class clazz, Type[] types) throws PropertyNotFoundException {
+		final Constructor[] candidates = clazz.getConstructors();
+		for ( int i=0; i<candidates.length; i++ ) {
+			final Constructor constructor = candidates[i];
+			final Class[] params = constructor.getParameterTypes();
+			if ( params.length==types.length ) {
+				boolean found = true;
+				for ( int j=0; j<params.length; j++ ) {
+					final boolean ok = params[j].isAssignableFrom( types[j].getReturnedClass() ) || (
+						types[j] instanceof PrimitiveType &&
+						params[j] == ( (PrimitiveType) types[j] ).getPrimitiveClass()
+					);
+					if (!ok) {
+						found = false;
+						break;
+					}
+				}
+				if (found) {
+					if ( !isPublic(clazz, constructor) ) constructor.setAccessible(true);
+					return constructor;
+				}
+			}
+		}
+		throw new PropertyNotFoundException( "no appropriate constructor in class: " + clazz.getName() );
+	}
+	
+	public static Method getMethod(Class clazz, Method method) {
+		try {
+			return clazz.getMethod( method.getName(), method.getParameterTypes() );
+		}
+		catch (Exception e) {
+			return null;
+		}
+	}
+
+	private ReflectHelper() {}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,274 +0,0 @@
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2002-2003 The Apache Software Foundation.  All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. The end-user documentation included with the redistribution, if
- *    any, must include the following acknowledgement:
- *       "This product includes software developed by the
- *        Apache Software Foundation (http://www.apache.org/)."
- *    Alternately, this acknowledgement may appear in the software itself,
- *    if and wherever such third-party acknowledgements normally appear.
- *
- * 4. The names "The Jakarta Project", "Commons", and "Apache Software
- *    Foundation" must not be used to endorse or promote products derived
- *    from this software without prior written permission. For written
- *    permission, please contact apache at apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- *    nor may "Apache" appear in their names without prior written
- *    permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation.  For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-package org.hibernate.util;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.io.ObjectStreamClass;
-import java.io.ObjectInputStream;
-
-import org.hibernate.type.SerializationException;
-import org.hibernate.Hibernate;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * <p>Assists with the serialization process and performs additional functionality based
- * on serialization.</p>
- * <p>
- * <ul>
- * <li>Deep clone using serialization
- * <li>Serialize managing finally and IOException
- * <li>Deserialize managing finally and IOException
- * </ul>
- *
- * <p>This class throws exceptions for invalid <code>null</code> inputs.
- * Each method documents its behaviour in more detail.</p>
- *
- * @author <a href="mailto:nissim at nksystems.com">Nissim Karpenstein</a>
- * @author <a href="mailto:janekdb at yahoo.co.uk">Janek Bogucki</a>
- * @author <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
- * @author Stephen Colebourne
- * @author Jeff Varszegi
- * @author Gary Gregory
- * @since 1.0
- * @version $Id: SerializationHelper.java 9180 2006-01-30 23:51:27Z steveebersole $
- */
-public final class SerializationHelper {
-
-	private static final Logger log = LoggerFactory.getLogger(SerializationHelper.class);
-
-    private SerializationHelper() {}
-
-    // Clone
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Deep clone an <code>Object</code> using serialization.</p>
-     *
-     * <p>This is many times slower than writing clone methods by hand
-     * on all objects in your object graph. However, for complex object
-     * graphs, or for those that don't support deep cloning this can
-     * be a simple alternative implementation. Of course all the objects
-     * must be <code>Serializable</code>.</p>
-     *
-     * @param object  the <code>Serializable</code> object to clone
-     * @return the cloned object
-     * @throws SerializationException (runtime) if the serialization fails
-     */
-    public static Object clone(Serializable object) throws SerializationException {
-	    log.trace("Starting clone through serialization");
-        return deserialize( serialize(object) );
-    }
-
-    // Serialize
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Serializes an <code>Object</code> to the specified stream.</p>
-     *
-     * <p>The stream will be closed once the object is written.
-     * This avoids the need for a finally clause, and maybe also exception
-     * handling, in the application code.</p>
-     *
-     * <p>The stream passed in is not buffered internally within this method.
-     * This is the responsibility of your application if desired.</p>
-     *
-     * @param obj  the object to serialize to bytes, may be null
-     * @param outputStream  the stream to write to, must not be null
-     * @throws IllegalArgumentException if <code>outputStream</code> is <code>null</code>
-     * @throws SerializationException (runtime) if the serialization fails
-     */
-    public static void serialize(Serializable obj, OutputStream outputStream) throws SerializationException {
-        if (outputStream == null) {
-            throw new IllegalArgumentException("The OutputStream must not be null");
-        }
-
-	    if ( log.isTraceEnabled() ) {
-		    if ( Hibernate.isInitialized( obj ) ) {
-	            log.trace( "Starting serialization of object [" + obj + "]" );
-		    }
-		    else {
-			    log.trace( "Starting serialization of [uninitialized proxy]" );
-		    }
-	    }
-
-        ObjectOutputStream out = null;
-        try {
-            // stream closed in the finally
-            out = new ObjectOutputStream(outputStream);
-            out.writeObject(obj);
-
-        }
-        catch (IOException ex) {
-            throw new SerializationException("could not serialize", ex);
-        }
-        finally {
-            try {
-                if (out != null) out.close();
-            }
-            catch (IOException ignored) {}
-        }
-    }
-
-    /**
-     * <p>Serializes an <code>Object</code> to a byte array for
-     * storage/serialization.</p>
-     *
-     * @param obj  the object to serialize to bytes
-     * @return a byte[] with the converted Serializable
-     * @throws SerializationException (runtime) if the serialization fails
-     */
-    public static byte[] serialize(Serializable obj) throws SerializationException {
-        ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
-        serialize(obj, baos);
-        return baos.toByteArray();
-    }
-
-    // Deserialize
-    //-----------------------------------------------------------------------
-    /**
-     * <p>Deserializes an <code>Object</code> from the specified stream.</p>
-     *
-     * <p>The stream will be closed once the object is written. This
-     * avoids the need for a finally clause, and maybe also exception
-     * handling, in the application code.</p>
-     *
-     * <p>The stream passed in is not buffered internally within this method.
-     * This is the responsibility of your application if desired.</p>
-     *
-     * @param inputStream  the serialized object input stream, must not be null
-     * @return the deserialized object
-     * @throws IllegalArgumentException if <code>inputStream</code> is <code>null</code>
-     * @throws SerializationException (runtime) if the serialization fails
-     */
-    public static Object deserialize(InputStream inputStream) throws SerializationException {
-        if (inputStream == null) {
-            throw new IllegalArgumentException("The InputStream must not be null");
-        }
-
-		log.trace("Starting deserialization of object");
-
-        CustomObjectInputStream in = null;
-        try {
-            // stream closed in the finally
-            in = new CustomObjectInputStream(inputStream);
-            return in.readObject();
-
-        }
-        catch (ClassNotFoundException ex) {
-            throw new SerializationException("could not deserialize", ex);
-        }
-        catch (IOException ex) {
-            throw new SerializationException("could not deserialize", ex);
-        }
-        finally {
-            try {
-                if (in != null) in.close();
-            }
-            catch (IOException ex) {}
-        }
-    }
-
-    /**
-     * <p>Deserializes a single <code>Object</code> from an array of bytes.</p>
-     *
-     * @param objectData  the serialized object, must not be null
-     * @return the deserialized object
-     * @throws IllegalArgumentException if <code>objectData</code> is <code>null</code>
-     * @throws SerializationException (runtime) if the serialization fails
-     */
-    public static Object deserialize(byte[] objectData) throws SerializationException {
-        if (objectData == null) {
-            throw new IllegalArgumentException("The byte[] must not be null");
-        }
-        ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
-        return deserialize(bais);
-    }
-
-
-	/**
-	 * Custom ObjectInputStream implementation to more appropriately handle classloading
-	 * within app servers (mainly jboss - hence this class inspired by jboss's class of
-	 * the same purpose).
-	 */
-	private static final class CustomObjectInputStream extends ObjectInputStream {
-
-		public CustomObjectInputStream(InputStream in) throws IOException {
-			super(in);
-		}
-
-		protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException {
-			String className = v.getName();
-			Class resolvedClass = null;
-
-			log.trace("Attempting to locate class [" + className + "]");
-
-			ClassLoader loader = Thread.currentThread().getContextClassLoader();
-			try {
-				resolvedClass = loader.loadClass(className);
-				log.trace("Class resolved through context class loader");
-			}
-			catch(ClassNotFoundException e) {
-				log.trace("Asking super to resolve");
-				resolvedClass = super.resolveClass(v);
-			}
-
-			return resolvedClass;
-		}
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/SerializationHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SerializationHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,245 @@
+/*
+ * 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.util;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.io.Serializable;
+import java.io.ObjectStreamClass;
+import java.io.ObjectInputStream;
+
+import org.hibernate.type.SerializationException;
+import org.hibernate.Hibernate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>Assists with the serialization process and performs additional functionality based
+ * on serialization.</p>
+ * <p>
+ * <ul>
+ * <li>Deep clone using serialization
+ * <li>Serialize managing finally and IOException
+ * <li>Deserialize managing finally and IOException
+ * </ul>
+ *
+ * <p>This class throws exceptions for invalid <code>null</code> inputs.
+ * Each method documents its behaviour in more detail.</p>
+ *
+ * @author <a href="mailto:nissim at nksystems.com">Nissim Karpenstein</a>
+ * @author <a href="mailto:janekdb at yahoo.co.uk">Janek Bogucki</a>
+ * @author <a href="mailto:dlr at finemaltcoding.com">Daniel Rall</a>
+ * @author Stephen Colebourne
+ * @author Jeff Varszegi
+ * @author Gary Gregory
+ * @since 1.0
+ * @version $Id: SerializationHelper.java 9180 2006-01-30 23:51:27Z steveebersole $
+ */
+public final class SerializationHelper {
+
+	private static final Logger log = LoggerFactory.getLogger(SerializationHelper.class);
+
+    private SerializationHelper() {}
+
+    // Clone
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Deep clone an <code>Object</code> using serialization.</p>
+     *
+     * <p>This is many times slower than writing clone methods by hand
+     * on all objects in your object graph. However, for complex object
+     * graphs, or for those that don't support deep cloning this can
+     * be a simple alternative implementation. Of course all the objects
+     * must be <code>Serializable</code>.</p>
+     *
+     * @param object  the <code>Serializable</code> object to clone
+     * @return the cloned object
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static Object clone(Serializable object) throws SerializationException {
+	    log.trace("Starting clone through serialization");
+        return deserialize( serialize(object) );
+    }
+
+    // Serialize
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Serializes an <code>Object</code> to the specified stream.</p>
+     *
+     * <p>The stream will be closed once the object is written.
+     * This avoids the need for a finally clause, and maybe also exception
+     * handling, in the application code.</p>
+     *
+     * <p>The stream passed in is not buffered internally within this method.
+     * This is the responsibility of your application if desired.</p>
+     *
+     * @param obj  the object to serialize to bytes, may be null
+     * @param outputStream  the stream to write to, must not be null
+     * @throws IllegalArgumentException if <code>outputStream</code> is <code>null</code>
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static void serialize(Serializable obj, OutputStream outputStream) throws SerializationException {
+        if (outputStream == null) {
+            throw new IllegalArgumentException("The OutputStream must not be null");
+        }
+
+	    if ( log.isTraceEnabled() ) {
+		    if ( Hibernate.isInitialized( obj ) ) {
+	            log.trace( "Starting serialization of object [" + obj + "]" );
+		    }
+		    else {
+			    log.trace( "Starting serialization of [uninitialized proxy]" );
+		    }
+	    }
+
+        ObjectOutputStream out = null;
+        try {
+            // stream closed in the finally
+            out = new ObjectOutputStream(outputStream);
+            out.writeObject(obj);
+
+        }
+        catch (IOException ex) {
+            throw new SerializationException("could not serialize", ex);
+        }
+        finally {
+            try {
+                if (out != null) out.close();
+            }
+            catch (IOException ignored) {}
+        }
+    }
+
+    /**
+     * <p>Serializes an <code>Object</code> to a byte array for
+     * storage/serialization.</p>
+     *
+     * @param obj  the object to serialize to bytes
+     * @return a byte[] with the converted Serializable
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static byte[] serialize(Serializable obj) throws SerializationException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
+        serialize(obj, baos);
+        return baos.toByteArray();
+    }
+
+    // Deserialize
+    //-----------------------------------------------------------------------
+    /**
+     * <p>Deserializes an <code>Object</code> from the specified stream.</p>
+     *
+     * <p>The stream will be closed once the object is written. This
+     * avoids the need for a finally clause, and maybe also exception
+     * handling, in the application code.</p>
+     *
+     * <p>The stream passed in is not buffered internally within this method.
+     * This is the responsibility of your application if desired.</p>
+     *
+     * @param inputStream  the serialized object input stream, must not be null
+     * @return the deserialized object
+     * @throws IllegalArgumentException if <code>inputStream</code> is <code>null</code>
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static Object deserialize(InputStream inputStream) throws SerializationException {
+        if (inputStream == null) {
+            throw new IllegalArgumentException("The InputStream must not be null");
+        }
+
+		log.trace("Starting deserialization of object");
+
+        CustomObjectInputStream in = null;
+        try {
+            // stream closed in the finally
+            in = new CustomObjectInputStream(inputStream);
+            return in.readObject();
+
+        }
+        catch (ClassNotFoundException ex) {
+            throw new SerializationException("could not deserialize", ex);
+        }
+        catch (IOException ex) {
+            throw new SerializationException("could not deserialize", ex);
+        }
+        finally {
+            try {
+                if (in != null) in.close();
+            }
+            catch (IOException ex) {}
+        }
+    }
+
+    /**
+     * <p>Deserializes a single <code>Object</code> from an array of bytes.</p>
+     *
+     * @param objectData  the serialized object, must not be null
+     * @return the deserialized object
+     * @throws IllegalArgumentException if <code>objectData</code> is <code>null</code>
+     * @throws SerializationException (runtime) if the serialization fails
+     */
+    public static Object deserialize(byte[] objectData) throws SerializationException {
+        if (objectData == null) {
+            throw new IllegalArgumentException("The byte[] must not be null");
+        }
+        ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
+        return deserialize(bais);
+    }
+
+
+	/**
+	 * Custom ObjectInputStream implementation to more appropriately handle classloading
+	 * within app servers (mainly jboss - hence this class inspired by jboss's class of
+	 * the same purpose).
+	 */
+	private static final class CustomObjectInputStream extends ObjectInputStream {
+
+		public CustomObjectInputStream(InputStream in) throws IOException {
+			super(in);
+		}
+
+		protected Class resolveClass(ObjectStreamClass v) throws IOException, ClassNotFoundException {
+			String className = v.getName();
+			Class resolvedClass = null;
+
+			log.trace("Attempting to locate class [" + className + "]");
+
+			ClassLoader loader = Thread.currentThread().getContextClassLoader();
+			try {
+				resolvedClass = loader.loadClass(className);
+				log.trace("Class resolved through context class loader");
+			}
+			catch(ClassNotFoundException e) {
+				log.trace("Asking super to resolve");
+				resolvedClass = super.resolveClass(v);
+			}
+
+			return resolvedClass;
+		}
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/SimpleMRUCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,58 +0,0 @@
-package org.hibernate.util;
-
-import org.apache.commons.collections.map.LRUMap;
-
-import java.io.Serializable;
-import java.io.IOException;
-
-/**
- * Cache following a "Most Recently Used" (MRU) algorithm for maintaining a
- * bounded in-memory size; the "Least Recently Used" (LRU) entry is the first
- * available for removal from the cache.
- * <p/>
- * This implementation uses a bounded MRU Map to limit the in-memory size of
- * the cache.  Thus the size of this cache never grows beyond the stated size.
- *
- * @author Steve Ebersole
- */
-public class SimpleMRUCache implements Serializable {
-
-	public static final int DEFAULT_STRONG_REF_COUNT = 128;
-
-	private final int strongReferenceCount;
-	private transient LRUMap cache;
-
-	public SimpleMRUCache() {
-		this( DEFAULT_STRONG_REF_COUNT );
-	}
-
-	public SimpleMRUCache(int strongReferenceCount) {
-		this.strongReferenceCount = strongReferenceCount;
-		init();
-	}
-
-	public synchronized Object get(Object key) {
-		return cache.get( key );
-	}
-
-	public synchronized Object put(Object key, Object value) {
-		return cache.put( key, value );
-	}
-
-	public synchronized int size() {
-		return cache.size();
-	}
-
-	private void init() {
-		cache = new LRUMap( strongReferenceCount );
-	}
-
-	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
-		in.defaultReadObject();
-		init();
-	}
-
-	public synchronized void clear() {
-		cache.clear();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/SimpleMRUCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SimpleMRUCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import org.apache.commons.collections.map.LRUMap;
+
+import java.io.Serializable;
+import java.io.IOException;
+
+/**
+ * Cache following a "Most Recently Used" (MRU) algorithm for maintaining a
+ * bounded in-memory size; the "Least Recently Used" (LRU) entry is the first
+ * available for removal from the cache.
+ * <p/>
+ * This implementation uses a bounded MRU Map to limit the in-memory size of
+ * the cache.  Thus the size of this cache never grows beyond the stated size.
+ *
+ * @author Steve Ebersole
+ */
+public class SimpleMRUCache implements Serializable {
+
+	public static final int DEFAULT_STRONG_REF_COUNT = 128;
+
+	private final int strongReferenceCount;
+	private transient LRUMap cache;
+
+	public SimpleMRUCache() {
+		this( DEFAULT_STRONG_REF_COUNT );
+	}
+
+	public SimpleMRUCache(int strongReferenceCount) {
+		this.strongReferenceCount = strongReferenceCount;
+		init();
+	}
+
+	public synchronized Object get(Object key) {
+		return cache.get( key );
+	}
+
+	public synchronized Object put(Object key, Object value) {
+		return cache.put( key, value );
+	}
+
+	public synchronized int size() {
+		return cache.size();
+	}
+
+	private void init() {
+		cache = new LRUMap( strongReferenceCount );
+	}
+
+	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		in.defaultReadObject();
+		init();
+	}
+
+	public synchronized void clear() {
+		cache.clear();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/SingletonIterator.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,36 +0,0 @@
-//$Id: SingletonIterator.java 6514 2005-04-26 06:37:54Z oneovthafew $
-package org.hibernate.util;
-
-import java.util.Iterator;
-
-/**
- * @author Gavin King
- */
-public final class SingletonIterator implements Iterator {
-
-	private Object value;
-	private boolean hasNext = true;
-
-	public boolean hasNext() {
-		return hasNext;
-	}
-
-	public Object next() {
-		if (hasNext) {
-			hasNext = false;
-			return value;
-		}
-		else {
-			throw new IllegalStateException();
-		}
-	}
-
-	public void remove() {
-		throw new UnsupportedOperationException();
-	}
-
-	public SingletonIterator(Object value) {
-		this.value = value;
-	}
-
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/SingletonIterator.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SingletonIterator.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -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.util;
+
+import java.util.Iterator;
+
+/**
+ * @author Gavin King
+ */
+public final class SingletonIterator implements Iterator {
+
+	private Object value;
+	private boolean hasNext = true;
+
+	public boolean hasNext() {
+		return hasNext;
+	}
+
+	public Object next() {
+		if (hasNext) {
+			hasNext = false;
+			return value;
+		}
+		else {
+			throw new IllegalStateException();
+		}
+	}
+
+	public void remove() {
+		throw new UnsupportedOperationException();
+	}
+
+	public SingletonIterator(Object value) {
+		this.value = value;
+	}
+
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,83 +0,0 @@
-package org.hibernate.util;
-
-import org.apache.commons.collections.map.ReferenceMap;
-import org.apache.commons.collections.map.LRUMap;
-
-import java.io.Serializable;
-import java.io.IOException;
-
-/**
- * Cache following a "Most Recently Used" (MRY) algorithm for maintaining a
- * bounded in-memory size; the "Least Recently Used" (LRU) entry is the first
- * available for removal from the cache.
- * <p/>
- * This implementation uses a "soft limit" to the in-memory size of the cache,
- * meaning that all cache entries are kept within a completely
- * {@link java.lang.ref.SoftReference}-based map with the most recently utilized
- * entries additionally kept in a hard-reference manner to prevent those cache
- * entries soft references from becoming enqueued by the garbage collector.
- * Thus the actual size of this cache impl can actually grow beyond the stated
- * max size bound as long as GC is not actively seeking soft references for
- * enqueuement.
- *
- * @author Steve Ebersole
- */
-public class SoftLimitMRUCache implements Serializable {
-
-	public static final int DEFAULT_STRONG_REF_COUNT = 128;
-
-	private final int strongReferenceCount;
-
-	// actual cache of the entries.  soft references are used for both the keys and the
-	// values here since the values pertaining to the MRU entries are kept in a
-	// seperate hard reference cache (to avoid their enqueuement/garbage-collection).
-	private transient ReferenceMap softReferenceCache = new ReferenceMap( ReferenceMap.SOFT, ReferenceMap.SOFT );
-	// the MRU cache used to keep hard references to the most recently used query plans;
-	// note : LRU here is a bit of a misnomer, it indicates that LRU entries are removed, the
-	// actual kept entries are the MRU entries
-	private transient LRUMap strongReferenceCache;
-
-	public SoftLimitMRUCache() {
-		this( DEFAULT_STRONG_REF_COUNT );
-	}
-
-	public SoftLimitMRUCache(int strongRefCount) {
-		this.strongReferenceCount = strongRefCount;
-		init();
-	}
-
-	public synchronized Object get(Object key) {
-		Object result = softReferenceCache.get( key );
-		if ( result != null ) {
-			strongReferenceCache.put( key, result );
-		}
-		return result;
-	}
-
-	public synchronized Object put(Object key, Object value) {
-		softReferenceCache.put( key, value );
-		return strongReferenceCache.put( key, value );
-	}
-
-	public synchronized int size() {
-		return strongReferenceCache.size();
-	}
-
-	public synchronized int softSize() {
-		return softReferenceCache.size();
-	}
-
-	private void init() {
-		strongReferenceCache = new LRUMap( strongReferenceCount );
-	}
-
-	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
-		in.defaultReadObject();
-		init();
-	}
-
-	public synchronized void clear() {
-		strongReferenceCache.clear();
-		softReferenceCache.clear();
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/SoftLimitMRUCache.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,107 @@
+/*
+ * 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.util;
+
+import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.commons.collections.map.LRUMap;
+
+import java.io.Serializable;
+import java.io.IOException;
+
+/**
+ * Cache following a "Most Recently Used" (MRY) algorithm for maintaining a
+ * bounded in-memory size; the "Least Recently Used" (LRU) entry is the first
+ * available for removal from the cache.
+ * <p/>
+ * This implementation uses a "soft limit" to the in-memory size of the cache,
+ * meaning that all cache entries are kept within a completely
+ * {@link java.lang.ref.SoftReference}-based map with the most recently utilized
+ * entries additionally kept in a hard-reference manner to prevent those cache
+ * entries soft references from becoming enqueued by the garbage collector.
+ * Thus the actual size of this cache impl can actually grow beyond the stated
+ * max size bound as long as GC is not actively seeking soft references for
+ * enqueuement.
+ *
+ * @author Steve Ebersole
+ */
+public class SoftLimitMRUCache implements Serializable {
+
+	public static final int DEFAULT_STRONG_REF_COUNT = 128;
+
+	private final int strongReferenceCount;
+
+	// actual cache of the entries.  soft references are used for both the keys and the
+	// values here since the values pertaining to the MRU entries are kept in a
+	// seperate hard reference cache (to avoid their enqueuement/garbage-collection).
+	private transient ReferenceMap softReferenceCache = new ReferenceMap( ReferenceMap.SOFT, ReferenceMap.SOFT );
+	// the MRU cache used to keep hard references to the most recently used query plans;
+	// note : LRU here is a bit of a misnomer, it indicates that LRU entries are removed, the
+	// actual kept entries are the MRU entries
+	private transient LRUMap strongReferenceCache;
+
+	public SoftLimitMRUCache() {
+		this( DEFAULT_STRONG_REF_COUNT );
+	}
+
+	public SoftLimitMRUCache(int strongRefCount) {
+		this.strongReferenceCount = strongRefCount;
+		init();
+	}
+
+	public synchronized Object get(Object key) {
+		Object result = softReferenceCache.get( key );
+		if ( result != null ) {
+			strongReferenceCache.put( key, result );
+		}
+		return result;
+	}
+
+	public synchronized Object put(Object key, Object value) {
+		softReferenceCache.put( key, value );
+		return strongReferenceCache.put( key, value );
+	}
+
+	public synchronized int size() {
+		return strongReferenceCache.size();
+	}
+
+	public synchronized int softSize() {
+		return softReferenceCache.size();
+	}
+
+	private void init() {
+		strongReferenceCache = new LRUMap( strongReferenceCount );
+	}
+
+	private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
+		in.defaultReadObject();
+		init();
+	}
+
+	public synchronized void clear() {
+		strongReferenceCache.clear();
+		softReferenceCache.clear();
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,393 +0,0 @@
-//$Id: StringHelper.java 10315 2006-08-23 13:22:54Z steve.ebersole at jboss.com $
-package org.hibernate.util;
-
-import java.util.Iterator;
-import java.util.StringTokenizer;
-import java.util.ArrayList;
-
-public final class StringHelper {
-
-	private static final int ALIAS_TRUNCATE_LENGTH = 10;
-	public static final String WHITESPACE = " \n\r\f\t";
-
-	private StringHelper() { /* static methods only - hide constructor */
-	}
-	
-	/*public static boolean containsDigits(String string) {
-		for ( int i=0; i<string.length(); i++ ) {
-			if ( Character.isDigit( string.charAt(i) ) ) return true;
-		}
-		return false;
-	}*/
-
-	public static int lastIndexOfLetter(String string) {
-		for ( int i=0; i<string.length(); i++ ) {
-			char character = string.charAt(i);
-			if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
-		}
-		return string.length()-1;
-	}
-
-	public static String join(String seperator, String[] strings) {
-		int length = strings.length;
-		if ( length == 0 ) return "";
-		StringBuffer buf = new StringBuffer( length * strings[0].length() )
-				.append( strings[0] );
-		for ( int i = 1; i < length; i++ ) {
-			buf.append( seperator ).append( strings[i] );
-		}
-		return buf.toString();
-	}
-
-	public static String join(String seperator, Iterator objects) {
-		StringBuffer buf = new StringBuffer();
-		if ( objects.hasNext() ) buf.append( objects.next() );
-		while ( objects.hasNext() ) {
-			buf.append( seperator ).append( objects.next() );
-		}
-		return buf.toString();
-	}
-
-	public static String[] add(String[] x, String sep, String[] y) {
-		String[] result = new String[x.length];
-		for ( int i = 0; i < x.length; i++ ) {
-			result[i] = x[i] + sep + y[i];
-		}
-		return result;
-	}
-
-	public static String repeat(String string, int times) {
-		StringBuffer buf = new StringBuffer( string.length() * times );
-		for ( int i = 0; i < times; i++ ) buf.append( string );
-		return buf.toString();
-	}
-
-
-	public static String replace(String template, String placeholder, String replacement) {
-		return replace( template, placeholder, replacement, false );
-	}
-
-	public static String[] replace(String templates[], String placeholder, String replacement) {
-		String[] result = new String[templates.length];
-		for ( int i =0; i<templates.length; i++ ) {
-			result[i] = replace( templates[i], placeholder, replacement );;
-		}
-		return result;
-	}
-
-	public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
-		int loc = template == null ? -1 : template.indexOf( placeholder );
-		if ( loc < 0 ) {
-			return template;
-		}
-		else {
-			final boolean actuallyReplace = !wholeWords ||
-					loc + placeholder.length() == template.length() ||
-					!Character.isJavaIdentifierPart( template.charAt( loc + placeholder.length() ) );
-			String actualReplacement = actuallyReplace ? replacement : placeholder;
-			return new StringBuffer( template.substring( 0, loc ) )
-					.append( actualReplacement )
-					.append( replace( template.substring( loc + placeholder.length() ),
-							placeholder,
-							replacement,
-							wholeWords ) ).toString();
-		}
-	}
-
-
-	public static String replaceOnce(String template, String placeholder, String replacement) {
-        int loc = template == null ? -1 : template.indexOf( placeholder );
-		if ( loc < 0 ) {
-			return template;
-		}
-		else {
-			return new StringBuffer( template.substring( 0, loc ) )
-					.append( replacement )
-					.append( template.substring( loc + placeholder.length() ) )
-					.toString();
-		}
-	}
-
-
-	public static String[] split(String seperators, String list) {
-		return split( seperators, list, false );
-	}
-
-	public static String[] split(String seperators, String list, boolean include) {
-		StringTokenizer tokens = new StringTokenizer( list, seperators, include );
-		String[] result = new String[ tokens.countTokens() ];
-		int i = 0;
-		while ( tokens.hasMoreTokens() ) {
-			result[i++] = tokens.nextToken();
-		}
-		return result;
-	}
-
-	public static String unqualify(String qualifiedName) {
-		int loc = qualifiedName.lastIndexOf(".");
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1 );
-	}
-
-	public static String qualifier(String qualifiedName) {
-		int loc = qualifiedName.lastIndexOf(".");
-		return ( loc < 0 ) ? "" : qualifiedName.substring( 0, loc );
-	}
-
-	public static String[] suffix(String[] columns, String suffix) {
-		if ( suffix == null ) return columns;
-		String[] qualified = new String[columns.length];
-		for ( int i = 0; i < columns.length; i++ ) {
-			qualified[i] = suffix( columns[i], suffix );
-		}
-		return qualified;
-	}
-
-	private static String suffix(String name, String suffix) {
-		return ( suffix == null ) ? name : name + suffix;
-	}
-
-	public static String root(String qualifiedName) {
-		int loc = qualifiedName.indexOf( "." );
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( 0, loc );
-	}
-
-	public static String unroot(String qualifiedName) {
-		int loc = qualifiedName.indexOf( "." );
-		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( loc+1, qualifiedName.length() );
-	}
-
-	public static boolean booleanValue(String tfString) {
-		String trimmed = tfString.trim().toLowerCase();
-		return trimmed.equals( "true" ) || trimmed.equals( "t" );
-	}
-
-	public static String toString(Object[] array) {
-		int len = array.length;
-		if ( len == 0 ) return "";
-		StringBuffer buf = new StringBuffer( len * 12 );
-		for ( int i = 0; i < len - 1; i++ ) {
-			buf.append( array[i] ).append(", ");
-		}
-		return buf.append( array[len - 1] ).toString();
-	}
-
-	public static String[] multiply(String string, Iterator placeholders, Iterator replacements) {
-		String[] result = new String[]{string};
-		while ( placeholders.hasNext() ) {
-			result = multiply( result, ( String ) placeholders.next(), ( String[] ) replacements.next() );
-		}
-		return result;
-	}
-
-	private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
-		String[] results = new String[replacements.length * strings.length];
-		int n = 0;
-		for ( int i = 0; i < replacements.length; i++ ) {
-			for ( int j = 0; j < strings.length; j++ ) {
-				results[n++] = replaceOnce( strings[j], placeholder, replacements[i] );
-			}
-		}
-		return results;
-	}
-
-	public static int countUnquoted(String string, char character) {
-		if ( '\'' == character ) {
-			throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
-		}
-		if (string == null)
-			return 0;
-		// Impl note: takes advantage of the fact that an escpaed single quote
-		// embedded within a quote-block can really be handled as two seperate
-		// quote-blocks for the purposes of this method...
-		int count = 0;
-		int stringLength = string.length();
-		boolean inQuote = false;
-		for ( int indx = 0; indx < stringLength; indx++ ) {
-			char c = string.charAt( indx );
-			if ( inQuote ) {
-				if ( '\'' == c ) {
-					inQuote = false;
-				}
-			}
-			else if ( '\'' == c ) {
-				inQuote = true;
-			}
-			else if ( c == character ) {
-				count++;
-			}
-		}
-		return count;
-	}
-
-	public static int[] locateUnquoted(String string, char character) {
-		if ( '\'' == character ) {
-			throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
-		}
-		if (string == null) {
-			return new int[0];
-		}
-
-		ArrayList locations = new ArrayList( 20 );
-
-		// Impl note: takes advantage of the fact that an escpaed single quote
-		// embedded within a quote-block can really be handled as two seperate
-		// quote-blocks for the purposes of this method...
-		int stringLength = string.length();
-		boolean inQuote = false;
-		for ( int indx = 0; indx < stringLength; indx++ ) {
-			char c = string.charAt( indx );
-			if ( inQuote ) {
-				if ( '\'' == c ) {
-					inQuote = false;
-				}
-			}
-			else if ( '\'' == c ) {
-				inQuote = true;
-			}
-			else if ( c == character ) {
-				locations.add( new Integer( indx ) );
-			}
-		}
-		return ArrayHelper.toIntArray( locations );
-	}
-
-	public static boolean isNotEmpty(String string) {
-		return string != null && string.length() > 0;
-	}
-
-	public static boolean isEmpty(String string) {
-		return string == null || string.length() == 0;
-	}
-
-	public static String qualify(String prefix, String name) {
-		if ( name == null || prefix == null ) {
-			throw new NullPointerException();
-		}
-		return new StringBuffer( prefix.length() + name.length() + 1 )
-				.append(prefix)
-				.append('.')
-				.append(name)
-				.toString();
-	}
-
-	public static String[] qualify(String prefix, String[] names) {
-		if ( prefix == null ) return names;
-		int len = names.length;
-		String[] qualified = new String[len];
-		for ( int i = 0; i < len; i++ ) {
-			qualified[i] = qualify( prefix, names[i] );
-		}
-		return qualified;
-	}
-
-	public static int firstIndexOfChar(String sqlString, String string, int startindex) {
-		int matchAt = -1;
-		for ( int i = 0; i < string.length(); i++ ) {
-			int curMatch = sqlString.indexOf( string.charAt( i ), startindex );
-			if ( curMatch >= 0 ) {
-				if ( matchAt == -1 ) { // first time we find match!
-					matchAt = curMatch;
-				}
-				else {
-					matchAt = Math.min( matchAt, curMatch );
-				}
-			}
-		}
-		return matchAt;
-	}
-
-	public static String truncate(String string, int length) {
-		if ( string.length() <= length ) {
-			return string;
-		}
-		else {
-			return string.substring( 0, length );
-		}
-	}
-
-	public static String generateAlias(String description) {
-		return generateAliasRoot(description) + '_';
-	}
-
-	/**
-	 * Generate a nice alias for the given class name or collection role
-	 * name and unique integer. Subclasses of Loader do <em>not</em> have 
-	 * to use aliases of this form.
-	 * @return an alias of the form <tt>foo1_</tt>
-	 */
-	public static String generateAlias(String description, int unique) {
-		return generateAliasRoot(description) +
-			Integer.toString(unique) +
-			'_';
-	}
-
-	/**
-	 * Generates a root alias by truncating the "root name" defined by
-	 * the incoming decription and removing/modifying any non-valid
-	 * alias characters.
-	 *
-	 * @param description The root name from which to generate a root alias.
-	 * @return The generated root alias.
-	 */
-	private static String generateAliasRoot(String description) {
-		String result = truncate( unqualifyEntityName(description), ALIAS_TRUNCATE_LENGTH )
-				.toLowerCase()
-		        .replace( '/', '_' ) // entityNames may now include slashes for the representations
-				.replace( '$', '_' ); //classname may be an inner class
-		result = cleanAlias( result );
-		if ( Character.isDigit( result.charAt(result.length()-1) ) ) {
-			return result + "x"; //ick!
-		}
-		else {
-			return result;
-		}
-	}
-
-	/**
-	 * Clean the generated alias by removing any non-alpha characters from the
-	 * beginning.
-	 *
-	 * @param alias The generated alias to be cleaned.
-	 * @return The cleaned alias, stripped of any leading non-alpha characters.
-	 */
-	private static String cleanAlias(String alias) {
-		char[] chars = alias.toCharArray();
-		// short cut check...
-		if ( !Character.isLetter( chars[0] ) ) {
-			for ( int i = 1; i < chars.length; i++ ) {
-				// as soon as we encounter our first letter, return the substring
-				// from that position
-				if ( Character.isLetter( chars[i] ) ) {
-					return alias.substring( i );
-				}
-			}
-		}
-		return alias;
-	}
-
-	public static String unqualifyEntityName(String entityName) {
-		String result = unqualify(entityName);
-		int slashPos = result.indexOf( '/' );
-		if ( slashPos > 0 ) {
-			result = result.substring( 0, slashPos - 1 );
-		}
-		return result;
-	}
-	
-	public static String toUpperCase(String str) {
-		return str==null ? null : str.toUpperCase();
-	}
-	
-	public static String toLowerCase(String str) {
-		return str==null ? null : str.toLowerCase();
-	}
-
-	public static String moveAndToBeginning(String filter) {
-		if ( filter.trim().length()>0 ){
-			filter += " and ";
-			if ( filter.startsWith(" and ") ) filter = filter.substring(4);
-		}
-		return filter;
-	}
-	
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/StringHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/StringHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,416 @@
+/*
+ * 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.util;
+
+import java.util.Iterator;
+import java.util.StringTokenizer;
+import java.util.ArrayList;
+
+public final class StringHelper {
+
+	private static final int ALIAS_TRUNCATE_LENGTH = 10;
+	public static final String WHITESPACE = " \n\r\f\t";
+
+	private StringHelper() { /* static methods only - hide constructor */
+	}
+	
+	/*public static boolean containsDigits(String string) {
+		for ( int i=0; i<string.length(); i++ ) {
+			if ( Character.isDigit( string.charAt(i) ) ) return true;
+		}
+		return false;
+	}*/
+
+	public static int lastIndexOfLetter(String string) {
+		for ( int i=0; i<string.length(); i++ ) {
+			char character = string.charAt(i);
+			if ( !Character.isLetter(character) /*&& !('_'==character)*/ ) return i-1;
+		}
+		return string.length()-1;
+	}
+
+	public static String join(String seperator, String[] strings) {
+		int length = strings.length;
+		if ( length == 0 ) return "";
+		StringBuffer buf = new StringBuffer( length * strings[0].length() )
+				.append( strings[0] );
+		for ( int i = 1; i < length; i++ ) {
+			buf.append( seperator ).append( strings[i] );
+		}
+		return buf.toString();
+	}
+
+	public static String join(String seperator, Iterator objects) {
+		StringBuffer buf = new StringBuffer();
+		if ( objects.hasNext() ) buf.append( objects.next() );
+		while ( objects.hasNext() ) {
+			buf.append( seperator ).append( objects.next() );
+		}
+		return buf.toString();
+	}
+
+	public static String[] add(String[] x, String sep, String[] y) {
+		String[] result = new String[x.length];
+		for ( int i = 0; i < x.length; i++ ) {
+			result[i] = x[i] + sep + y[i];
+		}
+		return result;
+	}
+
+	public static String repeat(String string, int times) {
+		StringBuffer buf = new StringBuffer( string.length() * times );
+		for ( int i = 0; i < times; i++ ) buf.append( string );
+		return buf.toString();
+	}
+
+
+	public static String replace(String template, String placeholder, String replacement) {
+		return replace( template, placeholder, replacement, false );
+	}
+
+	public static String[] replace(String templates[], String placeholder, String replacement) {
+		String[] result = new String[templates.length];
+		for ( int i =0; i<templates.length; i++ ) {
+			result[i] = replace( templates[i], placeholder, replacement );;
+		}
+		return result;
+	}
+
+	public static String replace(String template, String placeholder, String replacement, boolean wholeWords) {
+		int loc = template == null ? -1 : template.indexOf( placeholder );
+		if ( loc < 0 ) {
+			return template;
+		}
+		else {
+			final boolean actuallyReplace = !wholeWords ||
+					loc + placeholder.length() == template.length() ||
+					!Character.isJavaIdentifierPart( template.charAt( loc + placeholder.length() ) );
+			String actualReplacement = actuallyReplace ? replacement : placeholder;
+			return new StringBuffer( template.substring( 0, loc ) )
+					.append( actualReplacement )
+					.append( replace( template.substring( loc + placeholder.length() ),
+							placeholder,
+							replacement,
+							wholeWords ) ).toString();
+		}
+	}
+
+
+	public static String replaceOnce(String template, String placeholder, String replacement) {
+        int loc = template == null ? -1 : template.indexOf( placeholder );
+		if ( loc < 0 ) {
+			return template;
+		}
+		else {
+			return new StringBuffer( template.substring( 0, loc ) )
+					.append( replacement )
+					.append( template.substring( loc + placeholder.length() ) )
+					.toString();
+		}
+	}
+
+
+	public static String[] split(String seperators, String list) {
+		return split( seperators, list, false );
+	}
+
+	public static String[] split(String seperators, String list, boolean include) {
+		StringTokenizer tokens = new StringTokenizer( list, seperators, include );
+		String[] result = new String[ tokens.countTokens() ];
+		int i = 0;
+		while ( tokens.hasMoreTokens() ) {
+			result[i++] = tokens.nextToken();
+		}
+		return result;
+	}
+
+	public static String unqualify(String qualifiedName) {
+		int loc = qualifiedName.lastIndexOf(".");
+		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( qualifiedName.lastIndexOf(".") + 1 );
+	}
+
+	public static String qualifier(String qualifiedName) {
+		int loc = qualifiedName.lastIndexOf(".");
+		return ( loc < 0 ) ? "" : qualifiedName.substring( 0, loc );
+	}
+
+	public static String[] suffix(String[] columns, String suffix) {
+		if ( suffix == null ) return columns;
+		String[] qualified = new String[columns.length];
+		for ( int i = 0; i < columns.length; i++ ) {
+			qualified[i] = suffix( columns[i], suffix );
+		}
+		return qualified;
+	}
+
+	private static String suffix(String name, String suffix) {
+		return ( suffix == null ) ? name : name + suffix;
+	}
+
+	public static String root(String qualifiedName) {
+		int loc = qualifiedName.indexOf( "." );
+		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( 0, loc );
+	}
+
+	public static String unroot(String qualifiedName) {
+		int loc = qualifiedName.indexOf( "." );
+		return ( loc < 0 ) ? qualifiedName : qualifiedName.substring( loc+1, qualifiedName.length() );
+	}
+
+	public static boolean booleanValue(String tfString) {
+		String trimmed = tfString.trim().toLowerCase();
+		return trimmed.equals( "true" ) || trimmed.equals( "t" );
+	}
+
+	public static String toString(Object[] array) {
+		int len = array.length;
+		if ( len == 0 ) return "";
+		StringBuffer buf = new StringBuffer( len * 12 );
+		for ( int i = 0; i < len - 1; i++ ) {
+			buf.append( array[i] ).append(", ");
+		}
+		return buf.append( array[len - 1] ).toString();
+	}
+
+	public static String[] multiply(String string, Iterator placeholders, Iterator replacements) {
+		String[] result = new String[]{string};
+		while ( placeholders.hasNext() ) {
+			result = multiply( result, ( String ) placeholders.next(), ( String[] ) replacements.next() );
+		}
+		return result;
+	}
+
+	private static String[] multiply(String[] strings, String placeholder, String[] replacements) {
+		String[] results = new String[replacements.length * strings.length];
+		int n = 0;
+		for ( int i = 0; i < replacements.length; i++ ) {
+			for ( int j = 0; j < strings.length; j++ ) {
+				results[n++] = replaceOnce( strings[j], placeholder, replacements[i] );
+			}
+		}
+		return results;
+	}
+
+	public static int countUnquoted(String string, char character) {
+		if ( '\'' == character ) {
+			throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
+		}
+		if (string == null)
+			return 0;
+		// Impl note: takes advantage of the fact that an escpaed single quote
+		// embedded within a quote-block can really be handled as two seperate
+		// quote-blocks for the purposes of this method...
+		int count = 0;
+		int stringLength = string.length();
+		boolean inQuote = false;
+		for ( int indx = 0; indx < stringLength; indx++ ) {
+			char c = string.charAt( indx );
+			if ( inQuote ) {
+				if ( '\'' == c ) {
+					inQuote = false;
+				}
+			}
+			else if ( '\'' == c ) {
+				inQuote = true;
+			}
+			else if ( c == character ) {
+				count++;
+			}
+		}
+		return count;
+	}
+
+	public static int[] locateUnquoted(String string, char character) {
+		if ( '\'' == character ) {
+			throw new IllegalArgumentException( "Unquoted count of quotes is invalid" );
+		}
+		if (string == null) {
+			return new int[0];
+		}
+
+		ArrayList locations = new ArrayList( 20 );
+
+		// Impl note: takes advantage of the fact that an escpaed single quote
+		// embedded within a quote-block can really be handled as two seperate
+		// quote-blocks for the purposes of this method...
+		int stringLength = string.length();
+		boolean inQuote = false;
+		for ( int indx = 0; indx < stringLength; indx++ ) {
+			char c = string.charAt( indx );
+			if ( inQuote ) {
+				if ( '\'' == c ) {
+					inQuote = false;
+				}
+			}
+			else if ( '\'' == c ) {
+				inQuote = true;
+			}
+			else if ( c == character ) {
+				locations.add( new Integer( indx ) );
+			}
+		}
+		return ArrayHelper.toIntArray( locations );
+	}
+
+	public static boolean isNotEmpty(String string) {
+		return string != null && string.length() > 0;
+	}
+
+	public static boolean isEmpty(String string) {
+		return string == null || string.length() == 0;
+	}
+
+	public static String qualify(String prefix, String name) {
+		if ( name == null || prefix == null ) {
+			throw new NullPointerException();
+		}
+		return new StringBuffer( prefix.length() + name.length() + 1 )
+				.append(prefix)
+				.append('.')
+				.append(name)
+				.toString();
+	}
+
+	public static String[] qualify(String prefix, String[] names) {
+		if ( prefix == null ) return names;
+		int len = names.length;
+		String[] qualified = new String[len];
+		for ( int i = 0; i < len; i++ ) {
+			qualified[i] = qualify( prefix, names[i] );
+		}
+		return qualified;
+	}
+
+	public static int firstIndexOfChar(String sqlString, String string, int startindex) {
+		int matchAt = -1;
+		for ( int i = 0; i < string.length(); i++ ) {
+			int curMatch = sqlString.indexOf( string.charAt( i ), startindex );
+			if ( curMatch >= 0 ) {
+				if ( matchAt == -1 ) { // first time we find match!
+					matchAt = curMatch;
+				}
+				else {
+					matchAt = Math.min( matchAt, curMatch );
+				}
+			}
+		}
+		return matchAt;
+	}
+
+	public static String truncate(String string, int length) {
+		if ( string.length() <= length ) {
+			return string;
+		}
+		else {
+			return string.substring( 0, length );
+		}
+	}
+
+	public static String generateAlias(String description) {
+		return generateAliasRoot(description) + '_';
+	}
+
+	/**
+	 * Generate a nice alias for the given class name or collection role
+	 * name and unique integer. Subclasses of Loader do <em>not</em> have 
+	 * to use aliases of this form.
+	 * @return an alias of the form <tt>foo1_</tt>
+	 */
+	public static String generateAlias(String description, int unique) {
+		return generateAliasRoot(description) +
+			Integer.toString(unique) +
+			'_';
+	}
+
+	/**
+	 * Generates a root alias by truncating the "root name" defined by
+	 * the incoming decription and removing/modifying any non-valid
+	 * alias characters.
+	 *
+	 * @param description The root name from which to generate a root alias.
+	 * @return The generated root alias.
+	 */
+	private static String generateAliasRoot(String description) {
+		String result = truncate( unqualifyEntityName(description), ALIAS_TRUNCATE_LENGTH )
+				.toLowerCase()
+		        .replace( '/', '_' ) // entityNames may now include slashes for the representations
+				.replace( '$', '_' ); //classname may be an inner class
+		result = cleanAlias( result );
+		if ( Character.isDigit( result.charAt(result.length()-1) ) ) {
+			return result + "x"; //ick!
+		}
+		else {
+			return result;
+		}
+	}
+
+	/**
+	 * Clean the generated alias by removing any non-alpha characters from the
+	 * beginning.
+	 *
+	 * @param alias The generated alias to be cleaned.
+	 * @return The cleaned alias, stripped of any leading non-alpha characters.
+	 */
+	private static String cleanAlias(String alias) {
+		char[] chars = alias.toCharArray();
+		// short cut check...
+		if ( !Character.isLetter( chars[0] ) ) {
+			for ( int i = 1; i < chars.length; i++ ) {
+				// as soon as we encounter our first letter, return the substring
+				// from that position
+				if ( Character.isLetter( chars[i] ) ) {
+					return alias.substring( i );
+				}
+			}
+		}
+		return alias;
+	}
+
+	public static String unqualifyEntityName(String entityName) {
+		String result = unqualify(entityName);
+		int slashPos = result.indexOf( '/' );
+		if ( slashPos > 0 ) {
+			result = result.substring( 0, slashPos - 1 );
+		}
+		return result;
+	}
+	
+	public static String toUpperCase(String str) {
+		return str==null ? null : str.toUpperCase();
+	}
+	
+	public static String toLowerCase(String str) {
+		return str==null ? null : str.toLowerCase();
+	}
+
+	public static String moveAndToBeginning(String filter) {
+		if ( filter.trim().length()>0 ){
+			filter += " and ";
+			if ( filter.startsWith(" and ") ) filter = filter.substring(4);
+		}
+		return filter;
+	}
+	
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,91 +0,0 @@
-//$Id: XMLHelper.java 8563 2005-11-10 15:58:59Z steveebersole $
-package org.hibernate.util;
-
-import java.util.List;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.dom4j.io.DOMReader;
-import org.dom4j.io.SAXReader;
-import org.dom4j.io.OutputFormat;
-import org.dom4j.io.XMLWriter;
-import org.dom4j.Element;
-import org.dom4j.DocumentFactory;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.SAXParseException;
-
-/**
- * Small helper class that lazy loads DOM and SAX reader and keep them for fast use afterwards.
- *
- *
- *
- */
-public final class XMLHelper {
-
-	private static final Logger log = LoggerFactory.getLogger(XMLHelper.class);
-	public static final EntityResolver DEFAULT_DTD_RESOLVER = new DTDEntityResolver();
-
-	private DOMReader domReader;
-	private SAXReader saxReader;
-
-	/**
-	 * Create a dom4j SAXReader which will append all validation errors
-	 * to errorList
-	 */
-	public SAXReader createSAXReader(String file, List errorsList, EntityResolver entityResolver) {
-		if (saxReader==null) saxReader = new SAXReader();
-		saxReader.setEntityResolver(entityResolver);
-		saxReader.setErrorHandler( new ErrorLogger(file, errorsList) );
-		saxReader.setMergeAdjacentText(true);
-		saxReader.setValidation(true);
-		return saxReader;
-	}
-
-	/**
-	 * Create a dom4j DOMReader
-	 */
-	public DOMReader createDOMReader() {
-		if (domReader==null) domReader = new DOMReader();
-		return domReader;
-	}
-
-	public static class ErrorLogger implements ErrorHandler {
-		private String file;
-		private List errors;
-		ErrorLogger(String file, List errors) {
-			this.file=file;
-			this.errors = errors;
-		}
-		public void error(SAXParseException error) {
-			log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
-			errors.add(error);
-		}
-		public void fatalError(SAXParseException error) {
-			error(error);
-		}
-		public void warning(SAXParseException warn) {
-			log.warn( "Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage() );
-		}
-	}
-
-	public static Element generateDom4jElement(String elementName) {
-		return DocumentFactory.getInstance().createElement( elementName );
-	}
-
-	public static void dump(Element element) {
-		try {
-			// try to "pretty print" it
-			OutputFormat outformat = OutputFormat.createPrettyPrint();
-			XMLWriter writer = new XMLWriter( System.out, outformat );
-			writer.write( element );
-			writer.flush();
-			System.out.println( "" );
-		}
-		catch( Throwable t ) {
-			// otherwise, just dump it
-			System.out.println( element.asXML() );
-		}
-
-	}
-}

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/XMLHelper.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/XMLHelper.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,111 @@
+/*
+ * 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.util;
+
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.dom4j.io.DOMReader;
+import org.dom4j.io.SAXReader;
+import org.dom4j.io.OutputFormat;
+import org.dom4j.io.XMLWriter;
+import org.dom4j.Element;
+import org.dom4j.DocumentFactory;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Small helper class that lazy loads DOM and SAX reader and keep them for fast use afterwards.
+ */
+public final class XMLHelper {
+
+	private static final Logger log = LoggerFactory.getLogger(XMLHelper.class);
+	public static final EntityResolver DEFAULT_DTD_RESOLVER = new DTDEntityResolver();
+
+	private DOMReader domReader;
+	private SAXReader saxReader;
+
+	/**
+	 * Create a dom4j SAXReader which will append all validation errors
+	 * to errorList
+	 */
+	public SAXReader createSAXReader(String file, List errorsList, EntityResolver entityResolver) {
+		if (saxReader==null) saxReader = new SAXReader();
+		saxReader.setEntityResolver(entityResolver);
+		saxReader.setErrorHandler( new ErrorLogger(file, errorsList) );
+		saxReader.setMergeAdjacentText(true);
+		saxReader.setValidation(true);
+		return saxReader;
+	}
+
+	/**
+	 * Create a dom4j DOMReader
+	 */
+	public DOMReader createDOMReader() {
+		if (domReader==null) domReader = new DOMReader();
+		return domReader;
+	}
+
+	public static class ErrorLogger implements ErrorHandler {
+		private String file;
+		private List errors;
+		ErrorLogger(String file, List errors) {
+			this.file=file;
+			this.errors = errors;
+		}
+		public void error(SAXParseException error) {
+			log.error( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
+			errors.add(error);
+		}
+		public void fatalError(SAXParseException error) {
+			error(error);
+		}
+		public void warning(SAXParseException warn) {
+			log.warn( "Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage() );
+		}
+	}
+
+	public static Element generateDom4jElement(String elementName) {
+		return DocumentFactory.getInstance().createElement( elementName );
+	}
+
+	public static void dump(Element element) {
+		try {
+			// try to "pretty print" it
+			OutputFormat outformat = OutputFormat.createPrettyPrint();
+			XMLWriter writer = new XMLWriter( System.out, outformat );
+			writer.write( element );
+			writer.flush();
+			System.out.println( "" );
+		}
+		catch( Throwable t ) {
+			// otherwise, just dump it
+			System.out.println( element.asXML() );
+		}
+
+	}
+}

Deleted: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/util/package.html	2008-07-29 18:50:51 UTC (rev 14992)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,8 +0,0 @@
-<html>
-<head></head>
-<body>
-<p>
-	Utility classes.
-</p>
-</body>
-</html>

Copied: core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html (from rev 14993, core/trunk/core/src/main/java/org/hibernate/util/package.html)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/core/src/main/java/org/hibernate/util/package.html	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,33 @@
+<!--
+  ~ 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
+  ~
+  -->
+
+<html>
+<head></head>
+<body>
+<p>
+	Utility classes.
+</p>
+</body>
+</html>

Deleted: core/tags/hibernate-3.3.0.CR2/distribution/pom.xml
===================================================================
--- core/trunk/distribution/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/distribution/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,171 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  ~ 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
-  ~
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-distribution</artifactId>
-    <packaging>pom</packaging>
-
-    <name>Hibernate Distribution</name>
-    <description>Builds the complete Hibernate distribution bundles</description>
-
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-assembly-plugin</artifactId>
-                    <version>2.2-beta-2</version>
-                    <configuration>
-                        <descriptors>
-                            <descriptor>src/assembly/hibernate-all.xml</descriptor>
-                            <descriptor>src/assembly/dist.xml</descriptor>
-                        </descriptors>
-                    </configuration>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-    </build>
-
-    <!--
-        The assemblies work off of dependency sets since the stuff to be
-        aggregated is no longer sub-modules after moving assembly itself
-        into this 'distribution' module.
-    -->
-    <dependencies>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-jmx</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-ehcache</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-jbosscache</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-jbosscache2</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-oscache</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-swarmcache</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-c3p0</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${project.groupId}</groupId>
-            <artifactId>hibernate-proxool</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <!-- optional deps for bytecode providers since they are optional on core -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib</artifactId>
-            <version>2.1_3</version>
-            <optional>true</optional>
-        </dependency>
-        <dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm-attrs</artifactId>
-            <version>1.5.3</version>
-            <optional>true</optional>
-        </dependency>
-    </dependencies>
-
-    <profiles>
-        <profile>
-            <!--
-                A profile used implicitly by the release plugin.  Here we use
-                it to implicitly execute assembly building when deploy is executed
-                as part of release ( I think/hope :p )
-            -->
-            <id>release-profile</id>
-            <activation>
-                <property>
-                    <name>performRelease</name>
-                    <value>true</value>
-                </property>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-assembly-plugin</artifactId>
-                        <version>2.2-beta-2</version>
-                        <executions>
-                            <execution>
-                                <phase>deploy</phase>
-                                <goals>
-                                    <goal>single</goal>
-                                </goals>
-                            </execution>
-                        </executions>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/distribution/pom.xml (from rev 15003, core/trunk/distribution/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/distribution/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/distribution/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ 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
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-distribution</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Hibernate Distribution</name>
+    <description>Builds the complete Hibernate distribution bundles</description>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-assembly-plugin</artifactId>
+                    <version>2.2-beta-2</version>
+                    <configuration>
+                        <descriptors>
+                            <descriptor>src/assembly/hibernate-all.xml</descriptor>
+                            <descriptor>src/assembly/dist.xml</descriptor>
+                        </descriptors>
+                    </configuration>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+    </build>
+
+    <!--
+        The assemblies work off of dependency sets since the stuff to be
+        aggregated is no longer sub-modules after moving assembly itself
+        into this 'distribution' module.
+    -->
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-jmx</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-ehcache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-jbosscache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-jbosscache2</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-oscache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-swarmcache</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-c3p0</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>hibernate-proxool</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <!-- optional deps for bytecode providers since they are optional on core -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib</artifactId>
+            <version>2.1_3</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-attrs</artifactId>
+            <version>1.5.3</version>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+
+    <profiles>
+        <profile>
+            <!--
+                A profile used implicitly by the release plugin.  Here we use
+                it to implicitly execute assembly building when deploy is executed
+                as part of release ( I think/hope :p )
+            -->
+            <id>release-profile</id>
+            <activation>
+                <property>
+                    <name>performRelease</name>
+                    <value>true</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <version>2.2-beta-2</version>
+                        <executions>
+                            <execution>
+                                <phase>deploy</phase>
+                                <goals>
+                                    <goal>single</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml
===================================================================
--- core/trunk/documentation/manual/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,100 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-manual</artifactId>
-    <version>3.3.0-SNAPSHOT</version>
-    <packaging>jdocbook</packaging>
-
-    <name>Hibernate Manual</name>
-    <description>The Hibernate reference manual</description>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.jboss.maven.plugins</groupId>
-                <artifactId>maven-jdocbook-plugin</artifactId>
-                <version>2.1.1</version>
-                <extensions>true</extensions>
-                <executions>
-                    <execution>
-                        <!--
-                            here we are attaching the translate goal so that the translations are processed
-                            before compilation so that the transated XML is also transformed during
-                            generation
-                        -->
-                        <phase>process-resources</phase>
-                        <goals>
-                            <goal>translate</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.hibernate</groupId>
-                        <artifactId>hibernate-jdocbook-style</artifactId>
-                        <version>1.0.2</version>
-                        <type>jdocbook-style</type>
-                    </dependency>
-                </dependencies>
-                <configuration>
-                    <sourceDocumentName>Hibernate_Reference.xml</sourceDocumentName>
-                    <masterTranslation>en-US</masterTranslation>
-                    <translations>
-<!--
-                        <translation>es-ES</translation>
--->
-                        <translation>fr-FR</translation>
-                        <translation>ja-JP</translation>
-                        <translation>ko-KR</translation>
-                        <translation>pt-BR</translation>
-                        <translation>zh-CN</translation>
-                    </translations>
-                    <imageResource>
-                        <directory>${basedir}/src/main/docbook/en-US</directory>
-                        <excludes>
-                            <exclude>*.xml</exclude>
-                            <exclude>**/*.xml</exclude>
-                            <exclude>*.zargo</exclude>
-                            <exclude>**/*.zargo</exclude>
-                        </excludes>
-                    </imageResource>
-                    <formats>
-                        <format>
-                            <formatName>pdf</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
-                            <finalName>hibernate_reference.pdf</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                        <format>
-                            <formatName>html_single</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl</stylesheetResource>
-                            <finalName>index.html</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                        <format>
-                            <formatName>html</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl</stylesheetResource>
-                            <finalName>index.html</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                    </formats>
-                    <options>
-                        <xincludeSupported>true</xincludeSupported>
-                        <localeSeparator>-</localeSeparator>
-                        <useRelativeImageUris>false</useRelativeImageUris>
-                    </options>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml (from rev 15003, core/trunk/documentation/manual/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,102 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-manual</artifactId>
+    <version>3.3.0.CR2</version>
+    <packaging>jdocbook</packaging>
+
+    <name>Hibernate Manual</name>
+    <description>The Hibernate reference manual</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jboss.maven.plugins</groupId>
+                <artifactId>maven-jdocbook-plugin</artifactId>
+                <version>2.1.2</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <!--
+                            here we are attaching the translate goal so that the translations are processed
+                            before compilation so that the transated XML is also transformed during
+                            generation
+                        -->
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>translate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.hibernate</groupId>
+                        <artifactId>hibernate-jdocbook-style</artifactId>
+                        <version>1.0.2</version>
+                        <type>jdocbook-style</type>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <sourceDocumentName>Hibernate_Reference.xml</sourceDocumentName>
+                    <masterTranslation>en-US</masterTranslation>
+                    <translations>
+<!--
+                        <translation>es-ES</translation>
+-->
+                        <translation>fr-FR</translation>
+                        <translation>ja-JP</translation>
+                        <translation>ko-KR</translation>
+<!--
+                        <translation>pt-BR</translation>
+-->
+                        <translation>zh-CN</translation>
+                    </translations>
+                    <imageResource>
+                        <directory>${basedir}/src/main/docbook/en-US</directory>
+                        <excludes>
+                            <exclude>*.xml</exclude>
+                            <exclude>**/*.xml</exclude>
+                            <exclude>*.zargo</exclude>
+                            <exclude>**/*.zargo</exclude>
+                        </excludes>
+                    </imageResource>
+                    <formats>
+                        <format>
+                            <formatName>pdf</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
+                            <finalName>hibernate_reference.pdf</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                        <format>
+                            <formatName>html_single</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl</stylesheetResource>
+                            <finalName>index.html</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                        <format>
+                            <formatName>html</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl</stylesheetResource>
+                            <finalName>index.html</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                    </formats>
+                    <options>
+                        <xincludeSupported>true</xincludeSupported>
+                        <localeSeparator>-</localeSeparator>
+                        <useRelativeImageUris>false</useRelativeImageUris>
+                    </options>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,95 +0,0 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!--
-  ~ 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 book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-        <!ENTITY versionNumber "3.3.0.CR1">
-        <!ENTITY copyrightYear "2004">
-        <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
-]>
-
-<book>
-
-    <bookinfo>
-        <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
-        <subtitle>Hibernate Reference Documentation</subtitle>
-        <releaseinfo>&versionNumber;</releaseinfo>
-        <productnumber>&versionNumber;</productnumber>
-        <issuenum>1</issuenum>
-        <mediaobject>
-            <imageobject role="fo">
-                <imagedata fileref="images/hibernate_logo_a.png" align="center" />
-            </imageobject>
-            <imageobject role="html">
-                <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
-            </imageobject>
-        </mediaobject>
-        <copyright>
-            <year>&copyrightYear;</year>
-            <holder>&copyrightHolder;</holder>
-        </copyright>
-        <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-	<!-- include translators... -->
-    </bookinfo>
-
-    <toc/>
-
-    <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-    <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-    <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-
-</book>
-

Copied: core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml (from rev 15001, core/trunk/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/Hibernate_Reference.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,95 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+  ~ 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 book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+        <!ENTITY versionNumber "3.3.0.CR2">
+        <!ENTITY copyrightYear "2004">
+        <!ENTITY copyrightHolder "Red Hat Middleware, LLC.">
+]>
+
+<book>
+
+    <bookinfo>
+        <title>HIBERNATE - Relational Persistence for Idiomatic Java</title>
+        <subtitle>Hibernate Reference Documentation</subtitle>
+        <releaseinfo>&versionNumber;</releaseinfo>
+        <productnumber>&versionNumber;</productnumber>
+        <issuenum>1</issuenum>
+        <mediaobject>
+            <imageobject role="fo">
+                <imagedata fileref="images/hibernate_logo_a.png" align="center" />
+            </imageobject>
+            <imageobject role="html">
+                <imagedata fileref="images/hibernate_logo_a.png" depth="3cm" />
+            </imageobject>
+        </mediaobject>
+        <copyright>
+            <year>&copyrightYear;</year>
+            <holder>&copyrightHolder;</holder>
+        </copyright>
+        <xi:include href="legal_notice.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+	<!-- include translators... -->
+    </bookinfo>
+
+    <toc/>
+
+    <xi:include href="content/preface.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/tutorial.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/architecture.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/configuration.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/persistent_classes.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/basic_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/collection_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/association_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/component_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/inheritance_mapping.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/session_api.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/transactions.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/events.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/batch.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/query_hql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/query_criteria.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/query_sql.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/filters.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/xml.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/performance.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/toolset_guide.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/example_parentchild.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/example_weblog.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+    <xi:include href="content/example_mappings.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+    <xi:include href="content/best_practices.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+
+</book>
+

Deleted: core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml
===================================================================
--- core/trunk/documentation/manual/src/main/docbook/en-US/content/tutorial.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,1583 +0,0 @@
-<?xml version='1.0' encoding="UTF-8"?>
-<!--
-  ~ 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 chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-        <!ENTITY mdash "-">
-]>
-
-<chapter id="tutorial">
-    <title>Introduction to Hibernate</title>
-    
-    <sect1 id="tutorial-intro" revision="1">
-        <title>Preface</title>
-        
-        <para>
-            This chapter is an introductory tutorial for new users of Hibernate. We start
-            with a simple command line application using an in-memory database and develop
-            it in easy to understand steps.
-        </para>
-
-        <para>
-            This tutorial is intended for new users of Hibernate but requires Java and
-            SQL knowledge. It is based on a tutorial by Michael Gloegl, the third-party
-            libraries we name are for JDK 1.4 and 5.0. You might need others for JDK 1.3.
-        </para>
-
-        <para>
-            The source code for the tutorial is included in the distribution in the
-            <literal>doc/reference/tutorial/</literal> directory.
-        </para>
-
-    </sect1>
-    
-    <sect1 id="tutorial-firstapp" revision="2">
-        <title>Part 1 - The first Hibernate Application</title>
-
-        <para>
-            First, we'll create a simple console-based Hibernate application. We use an
-            Java database (HSQL DB), so we do not have to install any database server.
-        </para>
-
-        <para>
-            Let's assume we need a small database application that can store events we want to
-            attend, and information about the hosts of these events.
-        </para>
-            
-        <para>
-            The first thing we do, is set up our development directory and put all the
-            Java libraries we need into it. Download the Hibernate distribution from the
-            Hibernate website. Extract the package and place all required libraries
-            found in <literal>/lib</literal> into into the <literal>/lib</literal> directory
-            of your new development working directory. It should look like this:
-        </para>
-            
-        <programlisting><![CDATA[.
-+lib
-  antlr.jar
-  cglib.jar
-  asm.jar
-  asm-attrs.jars
-  commons-collections.jar
-  commons-logging.jar
-  hibernate3.jar
-  jta.jar
-  dom4j.jar
-  log4j.jar ]]></programlisting>
-
-        <para>
-            This is the minimum set of required libraries (note that we also copied
-            hibernate3.jar, the main archive) for Hibernate <emphasis>at the time of writing</emphasis>.
-            The Hibernate release you are using might require more or less libraries. See the
-            <literal>README.txt</literal> file in the <literal>lib/</literal> directory of the
-            Hibernate distribution for more information about required and optional third-party
-            libraries. (Actually, Log4j is not required but preferred by many developers.)
-        </para>
-
-        <para>
-            Next we create a class that represents the event we want to store in database.
-        </para>
-      
-        <sect2 id="tutorial-firstapp-firstclass" revision="1">
-            <title>The first class</title>
-            
-            <para>
-                Our first persistent class is a simple JavaBean class with some properties:
-            </para>
-
-            <programlisting><![CDATA[package events;
-
-import java.util.Date;
-
-public class Event {
-    private Long id;
-
-    private String title;
-    private Date date;
-
-    public Event() {}
-
-    public Long getId() {
-        return id;
-    }
-
-    private void setId(Long id) {
-        this.id = id;
-    }
-
-    public Date getDate() {
-        return date;
-    }
-
-    public void setDate(Date date) {
-        this.date = date;
-    }
-
-    public String getTitle() {
-        return title;
-    }
-
-    public void setTitle(String title) {
-        this.title = title;
-    }
-}]]></programlisting>
-
-            <para>
-                You can see that this class uses standard JavaBean naming conventions for property
-                getter and setter methods, as well as private visibility for the fields. This is
-                a recommended design - but not required. Hibernate can also access fields directly,
-                the benefit of accessor methods is robustness for refactoring. The no-argument
-                constructor is required to instantiate an object of this class through reflection.
-            </para>
-
-            <para>
-                The <literal>id</literal> property holds a unique identifier value for a particular event.
-                All persistent entity classes (there are less important dependent classes as well) will need
-                such an identifier property if we want to use the full feature set of Hibernate. In fact,
-                most applications (esp. web applications) need to distinguish objects by identifier, so you
-                should consider this a feature rather than a limitation. However, we usually don't manipulate
-                the identity of an object, hence the setter method should be private. Only Hibernate will assign
-                identifiers when an object is saved. You can see that Hibernate can access public, private,
-                and protected accessor methods, as well as (public, private, protected) fields directly. The
-                choice is up to you and you can match it to fit your application design.
-            </para>
-
-            <para>
-                The no-argument constructor is a requirement for all persistent classes; Hibernate
-                has to create objects for you, using Java Reflection. The constructor can be
-                private, however, package visibility is required for runtime proxy generation and
-                efficient data retrieval without bytecode instrumentation.
-            </para>
-
-            <para>
-                Place this Java source file in a directory called <literal>src</literal> in the
-                development folder, and in its correct package. The directory should now look like this:
-            </para>
-
-            <programlisting><![CDATA[.
-+lib
-  <Hibernate and third-party libraries>
-+src
-  +events
-    Event.java]]></programlisting>
-
-            <para>
-                In the next step, we tell Hibernate about this persistent class.
-            </para>
-                
-        </sect2>
-
-        <sect2 id="tutorial-firstapp-mapping" revision="1">
-            <title>The mapping file</title>
-
-            <para>
-                Hibernate needs to know how to load and store objects of the persistent class.
-                This is where the Hibernate mapping file comes into play. The mapping file
-                tells Hibernate what table in the database it has to access, and what columns
-                in that table it should use.
-            </para>
-
-            <para>
-                The basic structure of a mapping file looks like this:
-            </para>
-
-            <programlisting><![CDATA[<?xml version="1.0"?>
-<!DOCTYPE hibernate-mapping PUBLIC
-        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-
-<hibernate-mapping>
-[...]
-</hibernate-mapping>]]></programlisting>
-
-            <para>
-                Note that the Hibernate DTD is very sophisticated. You can use it for
-                auto-completion of XML mapping elements and attributes in your editor or
-                IDE. You also should open up the DTD file in your text editor - it's the
-                easiest way to get an overview of all elements and attributes and to see
-                the defaults, as well as some comments. Note that Hibernate will not
-                load the DTD file from the web, but first look it up from the classpath
-                of the application. The DTD file is included in <literal>hibernate3.jar</literal>
-                as well as in the <literal>src/</literal> directory of the Hibernate distribution.
-            </para>
-
-            <para>
-                We will omit the DTD declaration in future examples to shorten the code. It is
-                of course not optional.
-            </para>
-
-            <para>
-                Between the two <literal>hibernate-mapping</literal> tags, include a
-                <literal>class</literal> element. All persistent entity classes (again, there
-                might be dependent classes later on, which are not first-class entities) need
-                such a mapping, to a table in the SQL database:
-            </para>
-
-            <programlisting><![CDATA[<hibernate-mapping>
-
-    <class name="events.Event" table="EVENTS">
-
-    </class>
-
-</hibernate-mapping>]]></programlisting>
-
-            <para>
-                So far we told Hibernate how to persist and load object of class <literal>Event</literal>
-                to the table <literal>EVENTS</literal>, each instance represented by a row in that table.
-                Now we continue with a mapping of the unique identifier property to the tables primary key.
-                In addition, as we don't want to care about handling this identifier, we configure Hibernate's
-                identifier generation strategy for a surrogate primary key column:
-            </para>
-
-            <programlisting><![CDATA[<hibernate-mapping>
-
-    <class name="events.Event" table="EVENTS">
-        <id name="id" column="EVENT_ID">
-            <generator class="native"/>
-        </id>
-    </class>
-
-</hibernate-mapping>]]></programlisting>
-
-            <para>
-                The <literal>id</literal> element is the declaration of the identifier property,
-                <literal>name="id"</literal> declares the name of the Java property -
-                Hibernate will use the getter and setter methods to access the property.
-                The column attribute tells Hibernate which column of the
-                <literal>EVENTS</literal> table we use for this primary key. The nested
-                <literal>generator</literal> element specifies the identifier generation strategy,
-                in this case we used <literal>native</literal>, which picks the best strategy depending
-                on the configured database (dialect). Hibernate supports database generated, globally
-                unique, as well as application assigned identifiers (or any strategy you have written
-                an extension for).
-            </para>
-
-            <para>
-                Finally we include declarations for the persistent properties of the class in
-                the mapping file. By default, no properties of the class are considered
-                persistent:
-            </para>
-            
-            <programlisting><![CDATA[
-<hibernate-mapping>
-
-    <class name="events.Event" table="EVENTS">
-        <id name="id" column="EVENT_ID">
-            <generator class="native"/>
-        </id>
-        <property name="date" type="timestamp" column="EVENT_DATE"/>
-        <property name="title"/>
-    </class>
-
-</hibernate-mapping>]]></programlisting>
-            
-            <para>
-                Just as with the <literal>id</literal> element, the <literal>name</literal>
-                attribute of the <literal>property</literal> element tells Hibernate which getter
-                and setter methods to use. So, in this case, Hibernate will look for
-                <literal>getDate()/setDate()</literal>, as well as <literal>getTitle()/setTitle()</literal>.
-            </para>
-
-            <para>
-                Why does the <literal>date</literal> property mapping include the
-                <literal>column</literal> attribute, but the <literal>title</literal>
-                doesn't? Without the <literal>column</literal> attribute Hibernate
-                by default uses the property name as the column name. This works fine for
-                <literal>title</literal>. However, <literal>date</literal> is a reserved
-                keyword in most database, so we better map it to a different name.
-            </para>
-
-            <para>
-                The next interesting thing is that the <literal>title</literal> mapping also lacks
-                a <literal>type</literal> attribute. The types we declare and use in the mapping
-                files are not, as you might expect, Java data types. They are also not SQL
-                database types. These types are so called <emphasis>Hibernate mapping types</emphasis>,
-                converters which can translate from Java to SQL data types and vice versa. Again,
-                Hibernate will try to determine the correct conversion and mapping type itself if
-                the <literal>type</literal> attribute is not present in the mapping. In some cases this
-                automatic detection (using Reflection on the Java class) might not have the default you
-                expect or need. This is the case with the <literal>date</literal> property. Hibernate can't
-                know if the property (which is of <literal>java.util.Date</literal>) should map to a
-                SQL <literal>date</literal>, <literal>timestamp</literal>, or <literal>time</literal> column.
-                We preserve full date and time information by mapping the property with a
-                <literal>timestamp</literal> converter.
-            </para>
-
-            <para>
-                This mapping file should be saved as <literal>Event.hbm.xml</literal>, right in
-                the directory next to the <literal>Event</literal> Java class source file.
-                The naming of mapping files can be arbitrary, however the <literal>hbm.xml</literal>
-                suffix  is a convention in the Hibernate developer community. The directory structure
-                should now look like this:
-            </para>
-
-            <programlisting><![CDATA[.
-+lib
-  <Hibernate and third-party libraries>
-+src
-  +events
-    Event.java
-    Event.hbm.xml]]></programlisting>
-
-             <para>
-                 We continue with the main configuration of Hibernate.
-             </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-firstapp-configuration" revision="2">
-            <title>Hibernate configuration</title>
-
-            <para>
-                We now have a persistent class and its mapping file in place. It is time to configure
-                Hibernate. Before we do this, we will need a database. HSQL DB, a java-based SQL DBMS,
-                can be downloaded from the HSQL DB website(http://hsqldb.org/). Actually, you only need the <literal>hsqldb.jar</literal>
-                from this download. Place this file in the <literal>lib/</literal> directory of the
-                development folder.
-            </para>
-
-            <para>
-                Create a directory called <literal>data</literal> in the root of the development directory -
-                this is where HSQL DB will store its data files. Now start the database by running
-                <literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal> in this data directory.
-                You can see it start up and bind to a TCP/IP socket, this is where our application
-                will connect later. If you want to start with a fresh database during this tutorial,
-                shutdown HSQL DB (press <literal>CTRL + C</literal> in the window), delete all files in the
-                <literal>data/</literal> directory, and start HSQL DB again.
-            </para>
-
-            <para>
-                Hibernate is the layer in your application which connects to this database, so it needs
-                connection information. The connections are made through a JDBC connection pool, which we
-                also have to configure. The Hibernate distribution contains several open source JDBC connection
-                pooling tools, but will use the Hibernate built-in connection pool for this tutorial. Note that
-                you have to copy the required library into your classpath and use different
-                connection pooling settings if you want to use a production-quality third party
-                JDBC pooling software.
-            </para>
-
-            <para>
-                For Hibernate's configuration, we can use a simple <literal>hibernate.properties</literal> file, a
-                slightly more sophisticated <literal>hibernate.cfg.xml</literal> file, or even complete
-                programmatic setup. Most users prefer the XML configuration file:
-            </para>
-
-            <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
-<!DOCTYPE hibernate-configuration PUBLIC
-        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
-        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
-
-<hibernate-configuration>
-
-    <session-factory>
-
-        <!-- Database connection settings -->
-        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
-        <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
-        <property name="connection.username">sa</property>
-        <property name="connection.password"></property>
-
-        <!-- JDBC connection pool (use the built-in) -->
-        <property name="connection.pool_size">1</property>
-
-        <!-- SQL dialect -->
-        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
-
-        <!-- Enable Hibernate's automatic session context management -->
-        <property name="current_session_context_class">thread</property>
-
-        <!-- Disable the second-level cache  -->
-        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
-
-        <!-- Echo all executed SQL to stdout -->
-        <property name="show_sql">true</property>
-
-        <!-- Drop and re-create the database schema on startup -->
-        <property name="hbm2ddl.auto">create</property>
-
-        <mapping resource="events/Event.hbm.xml"/>
-
-    </session-factory>
-
-</hibernate-configuration>]]></programlisting>
-
-            <para>
-                Note that this XML configuration uses a different DTD. We configure
-                Hibernate's <literal>SessionFactory</literal> - a global factory responsible
-                for a particular database. If you have several databases, use several
-                <literal>&lt;session-factory&gt;</literal> configurations, usually in
-                several configuration files (for easier startup).
-            </para>
-
-            <para>
-                The first four <literal>property</literal> elements contain the necessary
-                configuration for the JDBC connection. The dialect <literal>property</literal>
-                element specifies the particular SQL variant Hibernate generates.
-                Hibernate's automatic session management for persistence contexts will
-                come in handy as you will soon see.
-                The <literal>hbm2ddl.auto</literal> option turns on automatic generation of
-                database schemas - directly into the database. This can of course also be turned
-                off (by removing the config option) or redirected to a file with the help of
-                the <literal>SchemaExport</literal> Ant task. Finally, we add the mapping file(s)
-                for persistent classes to the configuration.
-            </para>
-
-            <para>
-                Copy this file into the source directory, so it will end up in the
-                root of the classpath. Hibernate automatically looks for a file called
-                <literal>hibernate.cfg.xml</literal> in the root of the classpath, on startup.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-firstapp-ant" revision="1">
-            <title>Building with Ant</title>
-
-            <para>
-                We'll now build the tutorial with Ant. You will need to have Ant installed - get
-                it from the <ulink url="http://ant.apache.org/bindownload.cgi">Ant download page</ulink>.
-                How to install Ant will not be covered here. Please refer to the
-                <ulink url="http://ant.apache.org/manual/index.html">Ant manual</ulink>. After you
-                have installed Ant, we can start to create the buildfile. It will be called
-                <literal>build.xml</literal> and placed directly in the development directory.
-            </para>
-
-            <para>
-                A basic build file looks like this:
-            </para>
-
-            <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
-
-    <property name="sourcedir" value="${basedir}/src"/>
-    <property name="targetdir" value="${basedir}/bin"/>
-    <property name="librarydir" value="${basedir}/lib"/>
-
-    <path id="libraries">
-        <fileset dir="${librarydir}">
-            <include name="*.jar"/>
-        </fileset>
-    </path>
-
-    <target name="clean">
-        <delete dir="${targetdir}"/>
-        <mkdir dir="${targetdir}"/>
-    </target>
-
-    <target name="compile" depends="clean, copy-resources">
-      <javac srcdir="${sourcedir}"
-             destdir="${targetdir}"
-             classpathref="libraries"/>
-    </target>
-
-    <target name="copy-resources">
-        <copy todir="${targetdir}">
-            <fileset dir="${sourcedir}">
-                <exclude name="**/*.java"/>
-            </fileset>
-        </copy>
-    </target>
-
-</project>]]></programlisting>
-
-            <para>
-                This will tell Ant to add all files in the lib directory ending with <literal>.jar</literal>
-                to the classpath used for compilation. It will also copy all non-Java source files to the
-                target directory, e.g. configuration and Hibernate mapping files. If you now run Ant, you
-                should get this output:
-            </para>
-
-            <programlisting><![CDATA[C:\hibernateTutorial\>ant
-Buildfile: build.xml
-
-copy-resources:
-     [copy] Copying 2 files to C:\hibernateTutorial\bin
-
-compile:
-    [javac] Compiling 1 source file to C:\hibernateTutorial\bin
-
-BUILD SUCCESSFUL
-Total time: 1 second ]]></programlisting>
-
-        </sect2>
-
-        <sect2 id="tutorial-firstapp-helpers" revision="3">
-            <title>Startup and helpers</title>
-
-            <para>
-                It's time to load and store some <literal>Event</literal> objects, but first
-                we have to complete the setup with some infrastructure code. We have to startup
-                Hibernate. This startup includes building a global <literal>SessionFactory</literal>
-                object and to store it somewhere for easy access in application code.
-                A <literal>SessionFactory</literal> can open up new <literal>Session</literal>'s.
-                A <literal>Session</literal> represents a single-threaded unit of work, the
-                <literal>SessionFactory</literal> is a thread-safe global object, instantiated once.
-            </para>
-
-            <para>
-                We'll create a <literal>HibernateUtil</literal> helper class which takes care
-                of startup and makes accessing a <literal>SessionFactory</literal> convenient.
-                Let's have a look at the implementation:
-            </para>
-
-            <programlisting><![CDATA[package util;
-
-import org.hibernate.*;
-import org.hibernate.cfg.*;
-
-public class HibernateUtil {
-
-    private static final SessionFactory sessionFactory;
-
-    static {
-        try {
-            // Create the SessionFactory from hibernate.cfg.xml
-            sessionFactory = new Configuration().configure().buildSessionFactory();
-        } catch (Throwable ex) {
-            // Make sure you log the exception, as it might be swallowed
-            System.err.println("Initial SessionFactory creation failed." + ex);
-            throw new ExceptionInInitializerError(ex);
-        }
-    }
-
-    public static SessionFactory getSessionFactory() {
-        return sessionFactory;
-    }
-
-}]]></programlisting>
-
-            <para>
-                This class does not only produce the global <literal>SessionFactory</literal> in
-                its static initializer (called once by the JVM when the class is loaded), but also
-                hides the fact that it uses a static singleton. It might as well lookup the
-                <literal>SessionFactory</literal> from JNDI in an application server.
-            </para>
-
-            <para>
-                If you give the <literal>SessionFactory</literal> a name in your configuration
-                file, Hibernate will in fact try to bind it to JNDI after it has been built.
-                To avoid this code completely you could also use JMX deployment and let the
-                JMX-capable container instantiate and bind a <literal>HibernateService</literal>
-                to JNDI. These advanced options are discussed in the Hibernate reference
-                documentation.
-            </para>
-
-            <para>
-                Place <literal>HibernateUtil.java</literal> in the development source directory, in
-                a package next to <literal>events</literal>:
-            </para>
-
-            <programlisting><![CDATA[.
-+lib
-  <Hibernate and third-party libraries>
-+src
-  +events
-    Event.java
-    Event.hbm.xml
-  +util
-    HibernateUtil.java
-  hibernate.cfg.xml
-+data
-build.xml]]></programlisting>
-
-            <para>
-                This should again compile without problems. We finally need to configure a logging
-                system - Hibernate uses commons logging and leaves you the choice between Log4j and
-                JDK 1.4 logging. Most developers prefer Log4j: copy <literal>log4j.properties</literal>
-                from the Hibernate distribution (it's in the <literal>etc/</literal> directory) to
-                your <literal>src</literal> directory, next to <literal>hibernate.cfg.xml</literal>.
-                Have a look at the example configuration and change the settings if you like to have
-                more verbose output. By default, only Hibernate startup message are shown on stdout.
-            </para>
-
-            <para>
-                The tutorial infrastructure is complete - and we are ready to do some real work with
-                Hibernate.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-firstapp-workingpersistence" revision="5">
-            <title>Loading and storing objects</title>
-
-            <para>
-                Finally, we can use Hibernate to load and store objects. We write an
-                <literal>EventManager</literal> class with a <literal>main()</literal> method:
-            </para>
-
-            <programlisting><![CDATA[package events;
-import org.hibernate.Session;
-
-import java.util.Date;
-
-import util.HibernateUtil;
-
-public class EventManager {
-
-    public static void main(String[] args) {
-        EventManager mgr = new EventManager();
-
-        if (args[0].equals("store")) {
-            mgr.createAndStoreEvent("My Event", new Date());
-        }
-
-        HibernateUtil.getSessionFactory().close();
-    }
-
-    private void createAndStoreEvent(String title, Date theDate) {
-
-        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
-
-        session.beginTransaction();
-
-        Event theEvent = new Event();
-        theEvent.setTitle(title);
-        theEvent.setDate(theDate);
-
-        session.save(theEvent);
-
-        session.getTransaction().commit();
-    }
-
-}]]></programlisting>
-
-            <para>
-                We create a new <literal>Event</literal> object, and hand it over to Hibernate.
-                Hibernate now takes care of the SQL and executes <literal>INSERT</literal>s
-                on the database. Let's have a look at the <literal>Session</literal> and
-                <literal>Transaction</literal>-handling code before we run this.
-            </para>
-
-            <para>
-                A <literal>Session</literal> is a single unit of work. For now we'll keep things
-                simple and assume a one-to-one granularity between a Hibernate <literal>Session</literal>
-                and a database transaction. To shield our code from the actual underlying transaction
-                system (in this case plain JDBC, but it could also run with JTA) we use the
-                <literal>Transaction</literal> API that is available on the Hibernate <literal>Session</literal>.
-            </para>
-
-            <para>
-                What does <literal>sessionFactory.getCurrentSession()</literal> do? First, you can call it
-                as many times and anywhere you like, once you get hold of your <literal>SessionFactory</literal>
-                (easy thanks to <literal>HibernateUtil</literal>). The <literal>getCurrentSession()</literal>
-                method always returns the "current" unit of work. Remember that we switched the configuration
-                option for this mechanism to "thread" in <literal>hibernate.cfg.xml</literal>? Hence,
-                the current unit of work is bound to the current Java thread that executes our application.
-                However, this is not the full picture, you also have to consider scope, when a unit of work
-                begins and when it ends.
-            </para>
-
-            <para>
-                A <literal>Session</literal> begins when it is first needed, when the first call to
-                <literal>getCurrentSession()</literal> is made. It is then bound by Hibernate to the current
-                thread. When the transaction ends, either through commit or rollback, Hibernate automatically
-                unbinds the <literal>Session</literal> from the thread and closes it for you. If you call
-                <literal>getCurrentSession()</literal> again, you get a new <literal>Session</literal> and can
-                start a new unit of work. This <emphasis>thread-bound</emphasis> programming model is the most
-                popular way of using Hibernate, as it allows flexible layering of your code (transaction
-                demarcation code can be separated from data access code, we'll do this later in this tutorial).
-            </para>
-
-            <para>
-                Related to the unit of work scope, should the Hibernate <literal>Session</literal> be used to
-                execute one or several database operations? The above example uses one <literal>Session</literal>
-                for one operation. This is pure coincidence, the example is just not complex enough to show any
-                other approach. The scope of a Hibernate <literal>Session</literal> is flexible but you should
-                never design your application to use a new Hibernate <literal>Session</literal> for
-                <emphasis>every</emphasis> database operation. So even if you see it a few more times in
-                the following (very trivial) examples, consider <emphasis>session-per-operation</emphasis>
-                an anti-pattern. A real (web) application is shown later in this tutorial.
-            </para>
-
-            <para>
-                Have a look at <xref linkend="transactions"/> for more information
-                about transaction handling and demarcation. We also skipped any error handling and
-                rollback in the previous example.
-            </para>
-
-            <para>
-                To run this first routine we have to add a callable target to the Ant build file:
-            </para>
-
-            <programlisting><![CDATA[<target name="run" depends="compile">
-    <java fork="true" classname="events.EventManager" classpathref="libraries">
-        <classpath path="${targetdir}"/>
-        <arg value="${action}"/>
-    </java>
-</target>]]></programlisting>
-
-            <para>
-                The value of the <literal>action</literal> argument is set on the command line when
-                calling the target:
-            </para>
-
-            <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
-
-            <para>
-                You should see, after compilation, Hibernate starting up and, depending on your
-                configuration, lots of log output. At the end you will find the following line:
-            </para>
-
-            <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
-
-            <para>
-                This is the <literal>INSERT</literal> executed by Hibernate, the question marks
-                represent JDBC bind parameters. To see the values bound as arguments, or to reduce
-                the verbosity of the log, check your <literal>log4j.properties</literal>.
-            </para>
-
-            <para>
-                Now we'd like to list stored events as well, so we add an option to the main method:
-            </para>
-
-            <programlisting><![CDATA[if (args[0].equals("store")) {
-    mgr.createAndStoreEvent("My Event", new Date());
-}
-else if (args[0].equals("list")) {
-    List events = mgr.listEvents();
-    for (int i = 0; i < events.size(); i++) {
-        Event theEvent = (Event) events.get(i);
-        System.out.println("Event: " + theEvent.getTitle() +
-                           " Time: " + theEvent.getDate());
-    }
-}]]></programlisting>
-
-            <para>
-                We also add a new <literal>listEvents() method</literal>:
-            </para>
-
-            <programlisting><![CDATA[private List listEvents() {
-
-    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
-
-    session.beginTransaction();
-
-    List result = session.createQuery("from Event").list();
-
-    session.getTransaction().commit();
-
-    return result;
-}]]></programlisting>
-
-            <para>
-                What we do here is use an HQL (Hibernate Query Language) query to load all existing
-                <literal>Event</literal> objects from the database. Hibernate will generate the
-                appropriate SQL, send it to the database and populate <literal>Event</literal> objects
-                with the data. You can create more complex queries with HQL, of course.
-            </para>
-
-            <para>
-                Now, to execute and test all of this, follow these steps:
-            </para>
-
-            <itemizedlist>
-                <listitem>
-                    <para>
-                        Run <literal>ant run -Daction=store</literal> to store something into the database
-                        and, of course, to generate the database schema before through hbm2ddl.
-                    </para>
-                </listitem>
-                <listitem>
-                    <para>
-                        Now disable hbm2ddl by commenting out the property in your <literal>hibernate.cfg.xml</literal>
-                        file. Usually you only leave it turned on in continuous unit testing, but another
-                        run of hbm2ddl would <emphasis>drop</emphasis> everything you have stored - the
-                        <literal>create</literal> configuration setting actually translates into "drop all
-                        tables from the schema, then re-create all tables, when the SessionFactory is build".
-                    </para>
-                </listitem>
-            </itemizedlist>
-
-            <para>
-                If you now call Ant with <literal>-Daction=list</literal>, you should see the events
-                you have stored so far. You can of course also call the <literal>store</literal> action a few
-                times more.
-            </para>
-
-            <para>
-                Note: Most new Hibernate users fail at this point and we see questions about
-                <emphasis>Table not found</emphasis> error messages regularly. However, if you follow the
-                steps outlined above you will not have this problem, as hbm2ddl creates the database
-                schema on the first run, and subsequent application restarts will use this schema. If
-                you change the mapping and/or database schema, you have to re-enable hbm2ddl once again.
-            </para>
-
-        </sect2>
-
-    </sect1>
-
-    <sect1 id="tutorial-associations">
-        <title>Part 2 - Mapping associations</title>
-
-        <para>
-            We mapped a persistent entity class to a table. Let's build on this and add some class associations.
-            First we'll add people to our application, and store a list of events they participate in.
-        </para>
-
-        <sect2 id="tutorial-associations-mappinguser" revision="1">
-            <title>Mapping the Person class</title>
-
-            <para>
-                The first cut of the <literal>Person</literal> class is simple:
-            </para>
-
-            <programlisting><![CDATA[package events;
-
-public class Person {
-
-    private Long id;
-    private int age;
-    private String firstname;
-    private String lastname;
-
-    public Person() {}
-
-    // Accessor methods for all properties, private setter for 'id'
-
-}]]></programlisting>
-
-            <para>
-                Create a new mapping file called <literal>Person.hbm.xml</literal> (don't forget the
-                DTD reference at the top):
-            </para>
-
-            <programlisting><![CDATA[<hibernate-mapping>
-
-    <class name="events.Person" table="PERSON">
-        <id name="id" column="PERSON_ID">
-            <generator class="native"/>
-        </id>
-        <property name="age"/>
-        <property name="firstname"/>
-        <property name="lastname"/>
-    </class>
-
-</hibernate-mapping>]]></programlisting>
-
-            <para>
-                Finally, add the new mapping to Hibernate's configuration:
-            </para>
-
-            <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
-<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
-
-            <para>
-                We'll now create an association between these two entities. Obviously, persons
-                can participate in events, and events have participants. The design questions
-                we have to deal with are: directionality, multiplicity, and collection
-                behavior.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-associations-unidirset" revision="3">
-            <title>A unidirectional Set-based association</title>
-
-            <para>
-                We'll add a collection of events to the <literal>Person</literal> class. That way we can
-                easily navigate to the events for a particular person, without executing an explicit query -
-                by calling <literal>aPerson.getEvents()</literal>. We use a Java collection, a <literal>Set</literal>,
-                because the collection will not contain duplicate elements and the ordering is not relevant for us.
-            </para>
-
-            <para>
-                We need a unidirectional, many-valued associations, implemented with a <literal>Set</literal>.
-                Let's write the code for this in the Java classes and then map it:
-            </para>
-
-            <programlisting><![CDATA[public class Person {
-
-    private Set events = new HashSet();
-
-    public Set getEvents() {
-        return events;
-    }
-
-    public void setEvents(Set events) {
-        this.events = events;
-    }
-}]]></programlisting>
-
-            <para>
-                Before we map this association, think about the other side. Clearly, we could just keep this
-                unidirectional. Or, we could create another collection on the <literal>Event</literal>, if we
-                want to be able to navigate it bi-directional, i.e. <literal>anEvent.getParticipants()</literal>.
-                This is not necessary, from a functional perspective. You could always execute an explicit query
-                to retrieve the participants for a particular event. This is a design choice left to you, but what
-                is clear from this discussion is the multiplicity of the association: "many" valued on both sides,
-                we call this a <emphasis>many-to-many</emphasis> association. Hence, we use Hibernate's
-                many-to-many mapping:
-            </para>
-
-            <programlisting><![CDATA[<class name="events.Person" table="PERSON">
-    <id name="id" column="PERSON_ID">
-        <generator class="native"/>
-    </id>
-    <property name="age"/>
-    <property name="firstname"/>
-    <property name="lastname"/>
-
-    <set name="events" table="PERSON_EVENT">
-        <key column="PERSON_ID"/>
-        <many-to-many column="EVENT_ID" class="events.Event"/>
-    </set>
-
-</class>]]></programlisting>
-
-            <para>
-                Hibernate supports all kinds of collection mappings, a <literal>&lt;set&gt;</literal> being most
-                common. For a many-to-many association (or <emphasis>n:m</emphasis> entity relationship), an
-                association table is needed. Each row in this table represents a link between a person and an event.
-                The table name is configured with the <literal>table</literal> attribute of the <literal>set</literal>
-                element. The identifier column name in the association, for the person's side, is defined with the
-                <literal>&lt;key&gt;</literal> element, the column name for the event's side with the
-                <literal>column</literal> attribute of the <literal>&lt;many-to-many&gt;</literal>. You also
-                have to tell Hibernate the class of the objects in your collection (correct: the class on the
-                other side of the collection of references).
-            </para>
-
-            <para>
-                The database schema for this mapping is therefore:
-            </para>
-
-            <programlisting><![CDATA[
-    _____________        __________________
-   |             |      |                  |       _____________
-   |   EVENTS    |      |   PERSON_EVENT   |      |             |
-   |_____________|      |__________________|      |    PERSON   |
-   |             |      |                  |      |_____________|
-   | *EVENT_ID   | <--> | *EVENT_ID        |      |             |
-   |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  |
-   |  TITLE      |      |__________________|      |  AGE        |
-   |_____________|                                |  FIRSTNAME  |
-                                                  |  LASTNAME   |
-                                                  |_____________|
- ]]></programlisting>
-
-        </sect2>
-
-        <sect2 id="tutorial-associations-working" revision="2">
-            <title>Working the association</title>
-
-            <para>
-                Let's bring some people and events together in a new method in <literal>EventManager</literal>:
-            </para>
-
-            <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
-
-    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
-    session.beginTransaction();
-
-    Person aPerson = (Person) session.load(Person.class, personId);
-    Event anEvent = (Event) session.load(Event.class, eventId);
-
-    aPerson.getEvents().add(anEvent);
-
-    session.getTransaction().commit();
-}]]></programlisting>
-
-            <para>
-                After loading a <literal>Person</literal> and an <literal>Event</literal>, simply
-                modify the collection using the normal collection methods. As you can see, there is no explicit call
-                to <literal>update()</literal> or <literal>save()</literal>, Hibernate automatically
-                detects that the collection has been modified and needs to be updated. This is called <emphasis>automatic
-                dirty checking</emphasis>, and you can also try it by modifying the name or the date property of
-                any of your objects. As long as they are in <emphasis>persistent</emphasis> state, that is, bound
-                to a particular Hibernate <literal>Session</literal> (i.e. they have been just loaded or saved in
-                a unit of work), Hibernate monitors any changes and executes SQL in a write-behind fashion. The
-                process of synchronizing the memory state with the database, usually only at the end of a unit of
-                work, is called <emphasis>flushing</emphasis>. In our code, the unit of work ends with a commit
-                (or rollback) of the database transaction - as defined by the <literal>thread</literal> configuration
-                option for the <literal>CurrentSessionContext</literal> class.
-            </para>
-
-            <para>
-                You might of course load person and event in different units of work. Or you modify an object
-                outside of a <literal>Session</literal>, when it is not in persistent state (if it was persistent
-                before, we call this state <emphasis>detached</emphasis>). You can even modify a collection when
-                it is detached:
-            </para>
-
-            <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
-
-    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
-    session.beginTransaction();
-
-    Person aPerson = (Person) session
-            .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
-            .setParameter("pid", personId)
-            .uniqueResult(); // Eager fetch the collection so we can use it detached
-
-    Event anEvent = (Event) session.load(Event.class, eventId);
-
-    session.getTransaction().commit();
-
-    // End of first unit of work
-
-    aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
-
-    // Begin second unit of work
-
-    Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
-    session2.beginTransaction();
-
-    session2.update(aPerson); // Reattachment of aPerson
-
-    session2.getTransaction().commit();
-}]]></programlisting>
-
-            <para>
-                The call to <literal>update</literal> makes a detached object persistent again, you could
-                say it binds it to a new unit of work, so any modifications you made to it while detached
-                can be saved to the database. This includes any modifications (additions/deletions) you
-                made to a collection of that entity object.
-            </para>
-
-            <para>
-                Well, this is not much use in our current situation, but it's an important concept you can
-                design into your own application. For now, complete this exercise by adding a new action
-                to the <literal>EventManager</literal>'s main method and call it from the command line. If
-                you need the identifiers of a person and an event - the <literal>save()</literal> method
-                returns it (you might have to modify some of the previous methods to return that identifier):
-            </para>
-
-            <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
-    Long eventId = mgr.createAndStoreEvent("My Event", new Date());
-    Long personId = mgr.createAndStorePerson("Foo", "Bar");
-    mgr.addPersonToEvent(personId, eventId);
-    System.out.println("Added person " + personId + " to event " + eventId);
-}]]></programlisting>
-
-            <para>
-                This was an example of an association between two equally important classes, two entities.
-                As mentioned earlier, there are other classes and types in a typical model, usually "less
-                important". Some you have already seen, like an <literal>int</literal> or a <literal>String</literal>.
-                We call these classes <emphasis>value types</emphasis>, and their instances <emphasis>depend</emphasis>
-                on a particular entity. Instances of these types don't have their own identity, nor are they
-                shared between entities (two persons don't reference the same <literal>firstname</literal>
-                object, even if they have the same first name). Of course, value types can not only be found in
-                the JDK (in fact, in a Hibernate application all JDK classes are considered value types), but
-                you can also write dependent classes yourself, <literal>Address</literal> or <literal>MonetaryAmount</literal>,
-                for example.
-            </para>
-
-            <para>
-                You can also design a collection of value types. This is conceptually very different from a
-                collection of references to other entities, but looks almost the same in Java.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-associations-valuecollections">
-            <title>Collection of values</title>
-
-            <para>
-                We add a collection of value typed objects to the <literal>Person</literal> entity. We want to
-                store email addresses, so the type we use is <literal>String</literal>, and the collection is
-                again a <literal>Set</literal>:
-            </para>
-            <programlisting><![CDATA[private Set emailAddresses = new HashSet();
-
-public Set getEmailAddresses() {
-    return emailAddresses;
-}
-
-public void setEmailAddresses(Set emailAddresses) {
-    this.emailAddresses = emailAddresses;
-}]]></programlisting>
-
-            <para>
-                The mapping of this <literal>Set</literal>:
-            </para>
-
-            <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
-    <key column="PERSON_ID"/>
-    <element type="string" column="EMAIL_ADDR"/>
-</set>]]></programlisting>
-
-            <para>
-                The difference compared with the earlier mapping is the <literal>element</literal> part, which tells Hibernate that the collection
-                does not contain references to another entity, but a collection of elements of type
-                <literal>String</literal> (the lowercase name tells you it's a Hibernate mapping type/converter).
-                Once again, the <literal>table</literal> attribute of the <literal>set</literal> element determines
-                the table name for the collection. The <literal>key</literal> element defines the foreign-key column
-                name in the collection table. The <literal>column</literal> attribute in the <literal>element</literal>
-                element defines the column name where the <literal>String</literal> values will actually be stored.
-            </para>
-
-            <para>
-                Have a look at the updated schema:
-            </para>
-
-            <programlisting><![CDATA[
-  _____________        __________________
- |             |      |                  |       _____________
- |   EVENTS    |      |   PERSON_EVENT   |      |             |       ___________________
- |_____________|      |__________________|      |    PERSON   |      |                   |
- |             |      |                  |      |_____________|      | PERSON_EMAIL_ADDR |
- | *EVENT_ID   | <--> | *EVENT_ID        |      |             |      |___________________|
- |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  | <--> |  *PERSON_ID       |
- |  TITLE      |      |__________________|      |  AGE        |      |  *EMAIL_ADDR      |
- |_____________|                                |  FIRSTNAME  |      |___________________|
-                                                |  LASTNAME   |
-                                                |_____________|
- ]]></programlisting>
-
-            <para>
-                You can see that the primary key of the collection table is in fact a composite key,
-                using both columns. This also implies that there can't be duplicate email addresses
-                per person, which is exactly the semantics we need for a set in Java.
-            </para>
-
-            <para>
-                You can now try and add elements to this collection, just like we did before by
-                linking persons and events. It's the same code in Java:
-            </para>
-
-            <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
-
-    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
-    session.beginTransaction();
-
-    Person aPerson = (Person) session.load(Person.class, personId);
-
-    // The getEmailAddresses() might trigger a lazy load of the collection
-    aPerson.getEmailAddresses().add(emailAddress);
-
-    session.getTransaction().commit();
-}]]></programlisting>
-
-            <para>
-                This time we didn't use a <emphasis>fetch</emphasis> query to initialize the collection.
-                Hence, the call to its getter method will trigger an additional select to initialize
-                it, so we can add an element to it. Monitor the SQL log and try to optimize this with
-                an eager fetch.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-associations-bidirectional" revision="1">
-            <title>Bi-directional associations</title>
-
-            <para>
-                Next we are going to map a bi-directional association - making the association between
-                person and event work from both sides in Java. Of course, the database schema doesn't
-                change, we still have many-to-many multiplicity. A relational database is more flexible
-                than a network programming language, so it doesn't need anything like a navigation
-                direction - data can be viewed and retrieved in any possible way.
-            </para>
-
-            <para>
-                First, add a collection of participants to the <literal>Event</literal> Event class:
-            </para>
-
-            <programlisting><![CDATA[private Set participants = new HashSet();
-
-public Set getParticipants() {
-    return participants;
-}
-
-public void setParticipants(Set participants) {
-    this.participants = participants;
-}]]></programlisting>
-
-            <para>
-                Now map this side of the association too, in <literal>Event.hbm.xml</literal>.
-            </para>
-
-            <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
-    <key column="EVENT_ID"/>
-    <many-to-many column="PERSON_ID" class="events.Person"/>
-</set>]]></programlisting>
-
-            <para>
-                As you see, these are normal <literal>set</literal> mappings in both mapping documents.
-                Notice that the column names in <literal>key</literal> and <literal>many-to-many</literal> are
-                swapped in both mapping documents. The most important addition here is the
-                <literal>inverse="true"</literal> attribute in the <literal>set</literal> element of the
-                <literal>Event</literal>'s collection mapping.
-            </para>
-
-            <para>
-                What this means is that Hibernate should take the other side - the <literal>Person</literal> class -
-                when it needs to find out information about the link between the two. This will be a lot easier to
-                understand once you see how the bi-directional link between our two entities is created .
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-associations-usingbidir">
-            <title>Working bi-directional links</title>
-
-            <para>
-                First, keep in mind that Hibernate does not affect normal Java semantics. How did we create a
-                link between a <literal>Person</literal> and an <literal>Event</literal> in the unidirectional
-                example? We added an instance of <literal>Event</literal> to the collection of event references,
-                of an instance of <literal>Person</literal>. So, obviously, if we want to make this link working
-                bi-directional, we have to do the same on the other side - adding a <literal>Person</literal>
-                reference to the collection in an <literal>Event</literal>. This "setting the link on both sides"
-                is absolutely necessary and you should never forget doing it.
-            </para>
-
-            <para>
-                Many developers program defensively and create link management methods to
-                correctly set both sides, e.g. in <literal>Person</literal>:
-            </para>
-
-            <programlisting><![CDATA[protected Set getEvents() {
-    return events;
-}
-
-protected void setEvents(Set events) {
-    this.events = events;
-}
-
-public void addToEvent(Event event) {
-    this.getEvents().add(event);
-    event.getParticipants().add(this);
-}
-
-public void removeFromEvent(Event event) {
-    this.getEvents().remove(event);
-    event.getParticipants().remove(this);
-}]]></programlisting>
-
-            <para>
-                Notice that the get and set methods for the collection are now protected - this allows classes in the
-                same package and subclasses to still access the methods, but prevents everybody else from messing
-                with the collections directly (well, almost). You should probably do the same with the collection
-                on the other side.
-            </para>
-
-            <para>
-                What about the <literal>inverse</literal> mapping attribute? For you, and for Java, a bi-directional
-                link is simply a matter of setting the references on both sides correctly. Hibernate however doesn't
-                have enough information to correctly arrange SQL <literal>INSERT</literal> and <literal>UPDATE</literal>
-                statements (to avoid constraint violations), and needs some help to handle bi-directional associations
-                properly. Making one side of the association <literal>inverse</literal> tells Hibernate to basically
-                ignore it, to consider it a <emphasis>mirror</emphasis> of the other side. That's all that is necessary
-                for Hibernate to work out all of the issues when transformation a directional navigation model to
-                a SQL database schema. The rules you have to remember are straightforward: All bi-directional associations
-                need one side as <literal>inverse</literal>. In a one-to-many association it has to be the many-side,
-                in many-to-many association you can pick either side, there is no difference.
-            </para>
-
-        </sect2>
-
-    </sect1>
-
-    <sect1 id="tutorial-webapp">
-        <title>Part 3 - The EventManager web application</title>
-
-        <para>
-            Let's turn the following discussion into a small web application...
-        </para>
-
-        <para>
-            A Hibernate web application uses <literal>Session</literal> and <literal>Transaction</literal>
-            almost like a standalone application. However, some common patterns are useful. We now write
-            an <literal>EventManagerServlet</literal>. This servlet can list all events stored in the
-            database, and it provides an HTML form to enter new events.
-        </para>
-
-        <sect2 id="tutorial-webapp-servlet" revision="2">
-            <title>Writing the basic servlet</title>
-
-            <para>
-                Create a new class in your source directory, in the <literal>events</literal>
-                package:
-            </para>
-
-            <programlisting><![CDATA[package events;
-
-// Imports
-
-public class EventManagerServlet extends HttpServlet {
-
-    // Servlet code
-}]]></programlisting>
-
-            <para>
-                The servlet handles HTTP <literal>GET</literal> requests only, hence, the method
-                we implement is <literal>doGet()</literal>:
-            </para>
-
-            <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
-                     HttpServletResponse response)
-        throws ServletException, IOException {
-
-    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
-
-    try {
-        // Begin unit of work
-        HibernateUtil.getSessionFactory()
-                .getCurrentSession().beginTransaction();
-
-        // Process request and render page...
-
-        // End unit of work
-        HibernateUtil.getSessionFactory()
-                .getCurrentSession().getTransaction().commit();
-
-    } catch (Exception ex) {
-        HibernateUtil.getSessionFactory()
-                .getCurrentSession().getTransaction().rollback();
-        throw new ServletException(ex);
-    }
-
-}]]></programlisting>
-
-            <para>
-                The pattern we are applying here is called <emphasis>session-per-request</emphasis>.
-                When a request hits the servlet, a new Hibernate <literal>Session</literal> is
-                opened through the first call to <literal>getCurrentSession()</literal> on the
-                <literal>SessionFactory</literal>. Then a database transaction is started&mdash;all
-                data access as to occur inside a transaction, no matter if data is read or written
-                (we don't use the auto-commit mode in applications).
-            </para>
-
-            <para>
-                Do <emphasis>not</emphasis> use a new Hibernate <literal>Session</literal> for
-                every database operation. Use one Hibernate <literal>Session</literal> that is
-                scoped to the whole request. Use <literal>getCurrentSession()</literal>, so that
-                it is automatically bound to the current Java thread.
-            </para>
-
-            <para>
-                Next, the possible actions of the request are processed and the response HTML
-                is rendered. We'll get to that part soon.
-            </para>
-
-            <para>
-                Finally, the unit of work ends when processing and rendering is complete. If any
-                problem occurred during processing or rendering, an exception will be thrown
-                and the database transaction rolled back. This completes the
-                <literal>session-per-request</literal> pattern. Instead of the transaction
-                demarcation code in every servlet you could also write a servlet filter.
-                See the Hibernate website and Wiki for more information about this pattern,
-                called <emphasis>Open Session in View</emphasis>&mdash;you'll need it as soon
-                as you consider rendering your view in JSP, not in a servlet.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-webapp-processing" revision="1">
-            <title>Processing and rendering</title>
-
-            <para>
-                Let's implement the processing of the request and rendering of the page.
-            </para>
-
-<programlisting><![CDATA[// Write HTML header
-PrintWriter out = response.getWriter();
-out.println("<html><head><title>Event Manager</title></head><body>");
-
-// Handle actions
-if ( "store".equals(request.getParameter("action")) ) {
-
-    String eventTitle = request.getParameter("eventTitle");
-    String eventDate = request.getParameter("eventDate");
-
-    if ( "".equals(eventTitle) || "".equals(eventDate) ) {
-        out.println("<b><i>Please enter event title and date.</i></b>");
-    } else {
-        createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
-        out.println("<b><i>Added event.</i></b>");
-    }
-}
-
-// Print page
-printEventForm(out);
-listEvents(out, dateFormatter);
-
-// Write HTML footer
-out.println("</body></html>");
-out.flush();
-out.close();]]></programlisting>
-
-            <para>
-                Granted, this coding style with a mix of Java and HTML would not scale
-                in a more complex application&mdash;keep in mind that we are only illustrating
-                basic Hibernate concepts in this tutorial. The code prints an HTML
-                header and a footer. Inside this page, an HTML form for event entry and
-                a list of all events in the database are printed. The first method is
-                trivial and only outputs HTML:
-            </para>
-
-            <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
-    out.println("<h2>Add new event:</h2>");
-    out.println("<form>");
-    out.println("Title: <input name='eventTitle' length='50'/><br/>");
-    out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
-    out.println("<input type='submit' name='action' value='store'/>");
-    out.println("</form>");
-}]]></programlisting>
-
-            <para>
-                The <literal>listEvents()</literal> method uses the Hibernate
-                <literal>Session</literal> bound to the current thread to execute
-                a query:
-            </para>
-
-            <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
-
-    List result = HibernateUtil.getSessionFactory()
-                    .getCurrentSession().createCriteria(Event.class).list();
-    if (result.size() > 0) {
-        out.println("<h2>Events in database:</h2>");
-        out.println("<table border='1'>");
-        out.println("<tr>");
-        out.println("<th>Event title</th>");
-        out.println("<th>Event date</th>");
-        out.println("</tr>");
-        for (Iterator it = result.iterator(); it.hasNext();) {
-            Event event = (Event) it.next();
-            out.println("<tr>");
-            out.println("<td>" + event.getTitle() + "</td>");
-            out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
-            out.println("</tr>");
-        }
-        out.println("</table>");
-    }
-}]]></programlisting>
-
-            <para>
-                Finally, the <literal>store</literal> action is dispatched to the
-                <literal>createAndStoreEvent()</literal> method, which also uses
-                the <literal>Session</literal> of the current thread:
-            </para>
-
-            <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
-    Event theEvent = new Event();
-    theEvent.setTitle(title);
-    theEvent.setDate(theDate);
-
-    HibernateUtil.getSessionFactory()
-                    .getCurrentSession().save(theEvent);
-}]]></programlisting>
-
-            <para>
-                That's it, the servlet is complete. A request to the servlet will be processed
-                in a single <literal>Session</literal> and <literal>Transaction</literal>. As
-                earlier in the standalone application, Hibernate can automatically bind these
-                objects to the current thread of execution. This gives you the freedom to layer
-                your code and access the <literal>SessionFactory</literal> in any way you like.
-                Usually you'd use a more sophisticated design and move the data access code
-                into data access objects (the DAO pattern). See the Hibernate Wiki for more
-                examples.
-            </para>
-
-        </sect2>
-
-        <sect2 id="tutorial-webapp-deploy">
-            <title>Deploying and testing</title>
-
-            <para>
-                To deploy this application you have to create a web archive, a WAR. Add the
-                following Ant target to your <literal>build.xml</literal>:
-            </para>
-
-<programlisting><![CDATA[<target name="war" depends="compile">
-    <war destfile="hibernate-tutorial.war" webxml="web.xml">
-        <lib dir="${librarydir}">
-          <exclude name="jsdk*.jar"/>
-        </lib>
-
-        <classes dir="${targetdir}"/>
-    </war>
-</target>]]></programlisting>
-
-            <para>
-                This target creates a file called <literal>hibernate-tutorial.war</literal>
-                in your project directory. It packages all libraries and the <literal>web.xml</literal>
-                descriptor, which is expected in the base directory of your project:
-            </para>
-
-            <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<web-app version="2.4"
-    xmlns="http://java.sun.com/xml/ns/j2ee"
-    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
-
-    <servlet>
-        <servlet-name>Event Manager</servlet-name>
-        <servlet-class>events.EventManagerServlet</servlet-class>
-    </servlet>
-
-    <servlet-mapping>
-        <servlet-name>Event Manager</servlet-name>
-        <url-pattern>/eventmanager</url-pattern>
-    </servlet-mapping>
-</web-app>]]></programlisting>
-
-            <para>
-                Before you compile and deploy the web application, note that an additional library
-                is required: <literal>jsdk.jar</literal>. This is the Java servlet development kit,
-                if you don't have this library already, get it from the Sun website and copy it to
-                your library directory. However, it will be only used for compilation and excluded
-                from the WAR package.
-            </para>
-
-            <para>
-                To build and deploy call <literal>ant war</literal> in your project directory
-                and copy the <literal>hibernate-tutorial.war</literal> file into your Tomcat
-                <literal>webapp</literal> directory. If you don't have Tomcat installed, download
-                it and follow the installation instructions. You don't have to change any Tomcat
-                configuration to deploy this application though.
-            </para>
-
-            <para>
-                Once deployed and Tomcat is running, access the application at
-                <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>. Make
-                sure you watch the Tomcat log to see Hibernate initialize when the first
-                request hits your servlet (the static initializer in <literal>HibernateUtil</literal>
-                is called) and to get the detailed output if any exceptions occurs.
-            </para>
-
-        </sect2>
-
-    </sect1>
-
-    <sect1 id="tutorial-summary" revision="1">
-        <title>Summary</title>
-
-        <para>
-            This tutorial covered the basics of writing a simple standalone Hibernate application
-            and a small web application.
-        </para>
-
-        <para>
-            If you already feel confident with Hibernate, continue browsing through the reference
-            documentation table of contents for topics you find interesting - most asked are
-            transactional processing (<xref linkend="transactions"/>), fetch
-            performance (<xref linkend="performance"/>), or the usage of the API (<xref linkend="objectstate"/>)
-            and the query features (<xref linkend="objectstate-querying"/>).
-        </para>
-
-        <para>
-            Don't forget to check the Hibernate website for more (specialized) tutorials.
-        </para>
-
-    </sect1>
-
-</chapter>

Copied: core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml (from rev 14994, core/trunk/documentation/manual/src/main/docbook/en-US/content/tutorial.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/documentation/manual/src/main/docbook/en-US/content/tutorial.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,1617 @@
+<?xml version='1.0' encoding="UTF-8"?>
+<!--
+  ~ 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 chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+        <!ENTITY mdash "-">
+]>
+
+        <!-- todo : need searate sections, one for each tutorial -->
+
+<chapter id="tutorial">
+    <title>Introduction to Hibernate</title>
+    
+    <sect1 id="tutorial-intro">
+        <title>Preface</title>
+
+        <para>
+            This chapter is an introduction to Hibernate by way of a tutorial,
+            intended for new users of Hibernate.  We start with a simple
+            application using an in-memory database.  We build the
+            application in small, easy to understand steps.  The tutorial is
+            based on another, earlier one developed by Michael Gloegl.  All
+            code is contained in the <filename>tutorials/web</filename> directory
+            of the project source.
+        </para>
+
+    </sect1>
+
+    <important>
+        <para>
+            This tutorial expects the user have knowledge of both Java and
+            SQL.  If you are new or uncomfortable with either, it is advised
+            that you start with a good introduction to that technology prior
+            to attempting to learn Hibernate.  It will save time and effort
+            in the long run.
+        </para>
+    </important>
+
+    <note>
+        <para>
+            There is another tutorial/example application in the
+            <filename>/tutorials/eg</filename> directory of the project source.
+            That example is console based and as such would not have the
+            dependency on a servlet container to execute.  The basic setup is
+            the same as the instructions below.
+        </para>
+    </note>
+
+    <sect1 id="tutorial-firstapp">
+        <title>Part 1 - The first Hibernate Application</title>
+
+        <para>
+            Let's assume we need a small database application that can store
+            events we want to attend, and information about the host(s) of
+            these events.  We will use an in-memory, Java database named HSQLDB
+            to avoid describing installation/setup of any particular database
+            servers.  Feel free to tweak this tutorial to use whatever database
+            you feel comfortable using.
+        </para>
+            
+        <para>
+            The first thing we need to do is set up our development environment,
+            and specifically to setup all the required dependencies to Hibernate
+            as well as other libraries.  Hibernate is built using Maven which 
+            amongst other features provides <literal>dependecy management</literal>;
+            moreover it provides <emphasis>transitive</emphasis>
+            <literal>dependecy management</literal> which simply means that to use
+            Hibernate we can simply define our dependency on Hibernate, Hibernate
+            itself defines the dependencies it needs which then become transitive
+            dependencies of our project.
+        </para>
+
+        <programlisting><![CDATA[.
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    ...
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+        </dependency>
+
+        <!-- Because this is a web app, we also have a dependency on the servlet api. -->
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>]]></programlisting>
+
+        <note>
+            <para>
+                Essentially we are describing here the
+                <filename>/tutorials/web/pom.xml</filename> file.  See the
+                <ulink url="http://maven.org">Maven</ulink> site for more information.
+            </para>
+        </note>
+
+        <tip>
+            <para>
+                While not strictly necessary, most IDEs have integration with Maven
+                to read these POM files and automatically set up a project for you
+                which can save lots of time and effort.
+            </para>
+        </tip>
+
+        <para>
+            Next we create a class that represents the event we want to store in database.
+        </para>
+      
+        <sect2 id="tutorial-firstapp-firstclass">
+            <title>The first class</title>
+            
+            <para>
+                Our first persistent class is a simple JavaBean class with some properties:
+            </para>
+
+            <programlisting><![CDATA[package org.hibernate.tutorial.domain;
+
+import java.util.Date;
+
+public class Event {
+    private Long id;
+
+    private String title;
+    private Date date;
+
+    public Event() {}
+
+    public Long getId() {
+        return id;
+    }
+
+    private void setId(Long id) {
+        this.id = id;
+    }
+
+    public Date getDate() {
+        return date;
+    }
+
+    public void setDate(Date date) {
+        this.date = date;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+}]]></programlisting>
+
+            <para>
+                You can see that this class uses standard JavaBean naming conventions for property
+                getter and setter methods, as well as private visibility for the fields. This is
+                a recommended design - but not required. Hibernate can also access fields directly,
+                the benefit of accessor methods is robustness for refactoring. The no-argument
+                constructor is required to instantiate an object of this class through reflection.
+            </para>
+
+            <para>
+                The <literal>id</literal> property holds a unique identifier value for a particular event.
+                All persistent entity classes (there are less important dependent classes as well) will need
+                such an identifier property if we want to use the full feature set of Hibernate. In fact,
+                most applications (esp. web applications) need to distinguish objects by identifier, so you
+                should consider this a feature rather than a limitation. However, we usually don't manipulate
+                the identity of an object, hence the setter method should be private. Only Hibernate will assign
+                identifiers when an object is saved. You can see that Hibernate can access public, private,
+                and protected accessor methods, as well as (public, private, protected) fields directly. The
+                choice is up to you and you can match it to fit your application design.
+            </para>
+
+            <para>
+                The no-argument constructor is a requirement for all persistent classes; Hibernate
+                has to create objects for you, using Java Reflection. The constructor can be
+                private, however, package visibility is required for runtime proxy generation and
+                efficient data retrieval without bytecode instrumentation.
+            </para>
+
+            <para>
+                Place this Java source file in a directory called <literal>src</literal> in the
+                development folder, and in its correct package. The directory should now look like this:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  +events
+    Event.java]]></programlisting>
+
+            <para>
+                In the next step, we tell Hibernate about this persistent class.
+            </para>
+                
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-mapping">
+            <title>The mapping file</title>
+
+            <para>
+                Hibernate needs to know how to load and store objects of the persistent class.
+                This is where the Hibernate mapping file comes into play. The mapping file
+                tells Hibernate what table in the database it has to access, and what columns
+                in that table it should use.
+            </para>
+
+            <para>
+                The basic structure of a mapping file looks like this:
+            </para>
+
+            <programlisting><![CDATA[<?xml version="1.0"?>
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<hibernate-mapping>
+[...]
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Note that the Hibernate DTD is very sophisticated. You can use it for
+                auto-completion of XML mapping elements and attributes in your editor or
+                IDE. You also should open up the DTD file in your text editor - it's the
+                easiest way to get an overview of all elements and attributes and to see
+                the defaults, as well as some comments. Note that Hibernate will not
+                load the DTD file from the web, but first look it up from the classpath
+                of the application. The DTD file is included in <literal>hibernate3.jar</literal>
+                as well as in the <literal>src/</literal> directory of the Hibernate distribution.
+            </para>
+
+            <para>
+                We will omit the DTD declaration in future examples to shorten the code. It is
+                of course not optional.
+            </para>
+
+            <para>
+                Between the two <literal>hibernate-mapping</literal> tags, include a
+                <literal>class</literal> element. All persistent entity classes (again, there
+                might be dependent classes later on, which are not first-class entities) need
+                such a mapping, to a table in the SQL database:
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="events.Event" table="EVENTS">
+
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                So far we told Hibernate how to persist and load object of class <literal>Event</literal>
+                to the table <literal>EVENTS</literal>, each instance represented by a row in that table.
+                Now we continue with a mapping of the unique identifier property to the tables primary key.
+                In addition, as we don't want to care about handling this identifier, we configure Hibernate's
+                identifier generation strategy for a surrogate primary key column:
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="events.Event" table="EVENTS">
+        <id name="id" column="EVENT_ID">
+            <generator class="native"/>
+        </id>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                The <literal>id</literal> element is the declaration of the identifier property,
+                <literal>name="id"</literal> declares the name of the Java property -
+                Hibernate will use the getter and setter methods to access the property.
+                The column attribute tells Hibernate which column of the
+                <literal>EVENTS</literal> table we use for this primary key. The nested
+                <literal>generator</literal> element specifies the identifier generation strategy,
+                in this case we used <literal>native</literal>, which picks the best strategy depending
+                on the configured database (dialect). Hibernate supports database generated, globally
+                unique, as well as application assigned identifiers (or any strategy you have written
+                an extension for).
+            </para>
+
+            <para>
+                Finally we include declarations for the persistent properties of the class in
+                the mapping file. By default, no properties of the class are considered
+                persistent:
+            </para>
+            
+            <programlisting><![CDATA[
+<hibernate-mapping>
+
+    <class name="events.Event" table="EVENTS">
+        <id name="id" column="EVENT_ID">
+            <generator class="native"/>
+        </id>
+        <property name="date" type="timestamp" column="EVENT_DATE"/>
+        <property name="title"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+            
+            <para>
+                Just as with the <literal>id</literal> element, the <literal>name</literal>
+                attribute of the <literal>property</literal> element tells Hibernate which getter
+                and setter methods to use. So, in this case, Hibernate will look for
+                <literal>getDate()/setDate()</literal>, as well as <literal>getTitle()/setTitle()</literal>.
+            </para>
+
+            <para>
+                Why does the <literal>date</literal> property mapping include the
+                <literal>column</literal> attribute, but the <literal>title</literal>
+                doesn't? Without the <literal>column</literal> attribute Hibernate
+                by default uses the property name as the column name. This works fine for
+                <literal>title</literal>. However, <literal>date</literal> is a reserved
+                keyword in most database, so we better map it to a different name.
+            </para>
+
+            <para>
+                The next interesting thing is that the <literal>title</literal> mapping also lacks
+                a <literal>type</literal> attribute. The types we declare and use in the mapping
+                files are not, as you might expect, Java data types. They are also not SQL
+                database types. These types are so called <emphasis>Hibernate mapping types</emphasis>,
+                converters which can translate from Java to SQL data types and vice versa. Again,
+                Hibernate will try to determine the correct conversion and mapping type itself if
+                the <literal>type</literal> attribute is not present in the mapping. In some cases this
+                automatic detection (using Reflection on the Java class) might not have the default you
+                expect or need. This is the case with the <literal>date</literal> property. Hibernate can't
+                know if the property (which is of <literal>java.util.Date</literal>) should map to a
+                SQL <literal>date</literal>, <literal>timestamp</literal>, or <literal>time</literal> column.
+                We preserve full date and time information by mapping the property with a
+                <literal>timestamp</literal> converter.
+            </para>
+
+            <para>
+                This mapping file should be saved as <literal>Event.hbm.xml</literal>, right in
+                the directory next to the <literal>Event</literal> Java class source file.
+                The naming of mapping files can be arbitrary, however the <literal>hbm.xml</literal>
+                suffix  is a convention in the Hibernate developer community. The directory structure
+                should now look like this:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  +events
+    Event.java
+    Event.hbm.xml]]></programlisting>
+
+             <para>
+                 We continue with the main configuration of Hibernate.
+             </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-configuration" revision="2">
+            <title>Hibernate configuration</title>
+
+            <para>
+                We now have a persistent class and its mapping file in place. It is time to configure
+                Hibernate. Before we do this, we will need a database. HSQL DB, a java-based SQL DBMS,
+                can be downloaded from the HSQL DB website(http://hsqldb.org/). Actually, you only need the <literal>hsqldb.jar</literal>
+                from this download. Place this file in the <literal>lib/</literal> directory of the
+                development folder.
+            </para>
+
+            <para>
+                Create a directory called <literal>data</literal> in the root of the development directory -
+                this is where HSQL DB will store its data files. Now start the database by running
+                <literal>java -classpath ../lib/hsqldb.jar org.hsqldb.Server</literal> in this data directory.
+                You can see it start up and bind to a TCP/IP socket, this is where our application
+                will connect later. If you want to start with a fresh database during this tutorial,
+                shutdown HSQL DB (press <literal>CTRL + C</literal> in the window), delete all files in the
+                <literal>data/</literal> directory, and start HSQL DB again.
+            </para>
+
+            <para>
+                Hibernate is the layer in your application which connects to this database, so it needs
+                connection information. The connections are made through a JDBC connection pool, which we
+                also have to configure. The Hibernate distribution contains several open source JDBC connection
+                pooling tools, but will use the Hibernate built-in connection pool for this tutorial. Note that
+                you have to copy the required library into your classpath and use different
+                connection pooling settings if you want to use a production-quality third party
+                JDBC pooling software.
+            </para>
+
+            <para>
+                For Hibernate's configuration, we can use a simple <literal>hibernate.properties</literal> file, a
+                slightly more sophisticated <literal>hibernate.cfg.xml</literal> file, or even complete
+                programmatic setup. Most users prefer the XML configuration file:
+            </para>
+
+            <programlisting><![CDATA[<?xml version='1.0' encoding='utf-8'?>
+<!DOCTYPE hibernate-configuration PUBLIC
+        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
+
+<hibernate-configuration>
+
+    <session-factory>
+
+        <!-- Database connection settings -->
+        <property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
+        <property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
+        <property name="connection.username">sa</property>
+        <property name="connection.password"></property>
+
+        <!-- JDBC connection pool (use the built-in) -->
+        <property name="connection.pool_size">1</property>
+
+        <!-- SQL dialect -->
+        <property name="dialect">org.hibernate.dialect.HSQLDialect</property>
+
+        <!-- Enable Hibernate's automatic session context management -->
+        <property name="current_session_context_class">thread</property>
+
+        <!-- Disable the second-level cache  -->
+        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
+
+        <!-- Echo all executed SQL to stdout -->
+        <property name="show_sql">true</property>
+
+        <!-- Drop and re-create the database schema on startup -->
+        <property name="hbm2ddl.auto">create</property>
+
+        <mapping resource="events/Event.hbm.xml"/>
+
+    </session-factory>
+
+</hibernate-configuration>]]></programlisting>
+
+            <para>
+                Note that this XML configuration uses a different DTD. We configure
+                Hibernate's <literal>SessionFactory</literal> - a global factory responsible
+                for a particular database. If you have several databases, use several
+                <literal>&lt;session-factory&gt;</literal> configurations, usually in
+                several configuration files (for easier startup).
+            </para>
+
+            <para>
+                The first four <literal>property</literal> elements contain the necessary
+                configuration for the JDBC connection. The dialect <literal>property</literal>
+                element specifies the particular SQL variant Hibernate generates.
+                Hibernate's automatic session management for persistence contexts will
+                come in handy as you will soon see.
+                The <literal>hbm2ddl.auto</literal> option turns on automatic generation of
+                database schemas - directly into the database. This can of course also be turned
+                off (by removing the config option) or redirected to a file with the help of
+                the <literal>SchemaExport</literal> Ant task. Finally, we add the mapping file(s)
+                for persistent classes to the configuration.
+            </para>
+
+            <para>
+                Copy this file into the source directory, so it will end up in the
+                root of the classpath. Hibernate automatically looks for a file called
+                <literal>hibernate.cfg.xml</literal> in the root of the classpath, on startup.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-ant" revision="1">
+            <title>Building with Ant</title>
+
+            <para>
+                We'll now build the tutorial with Ant. You will need to have Ant installed - get
+                it from the <ulink url="http://ant.apache.org/bindownload.cgi">Ant download page</ulink>.
+                How to install Ant will not be covered here. Please refer to the
+                <ulink url="http://ant.apache.org/manual/index.html">Ant manual</ulink>. After you
+                have installed Ant, we can start to create the buildfile. It will be called
+                <literal>build.xml</literal> and placed directly in the development directory.
+            </para>
+
+            <para>
+                A basic build file looks like this:
+            </para>
+
+            <programlisting><![CDATA[<project name="hibernate-tutorial" default="compile">
+
+    <property name="sourcedir" value="${basedir}/src"/>
+    <property name="targetdir" value="${basedir}/bin"/>
+    <property name="librarydir" value="${basedir}/lib"/>
+
+    <path id="libraries">
+        <fileset dir="${librarydir}">
+            <include name="*.jar"/>
+        </fileset>
+    </path>
+
+    <target name="clean">
+        <delete dir="${targetdir}"/>
+        <mkdir dir="${targetdir}"/>
+    </target>
+
+    <target name="compile" depends="clean, copy-resources">
+      <javac srcdir="${sourcedir}"
+             destdir="${targetdir}"
+             classpathref="libraries"/>
+    </target>
+
+    <target name="copy-resources">
+        <copy todir="${targetdir}">
+            <fileset dir="${sourcedir}">
+                <exclude name="**/*.java"/>
+            </fileset>
+        </copy>
+    </target>
+
+</project>]]></programlisting>
+
+            <para>
+                This will tell Ant to add all files in the lib directory ending with <literal>.jar</literal>
+                to the classpath used for compilation. It will also copy all non-Java source files to the
+                target directory, e.g. configuration and Hibernate mapping files. If you now run Ant, you
+                should get this output:
+            </para>
+
+            <programlisting><![CDATA[C:\hibernateTutorial\>ant
+Buildfile: build.xml
+
+copy-resources:
+     [copy] Copying 2 files to C:\hibernateTutorial\bin
+
+compile:
+    [javac] Compiling 1 source file to C:\hibernateTutorial\bin
+
+BUILD SUCCESSFUL
+Total time: 1 second ]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-helpers" revision="3">
+            <title>Startup and helpers</title>
+
+            <para>
+                It's time to load and store some <literal>Event</literal> objects, but first
+                we have to complete the setup with some infrastructure code. We have to startup
+                Hibernate. This startup includes building a global <literal>SessionFactory</literal>
+                object and to store it somewhere for easy access in application code.
+                A <literal>SessionFactory</literal> can open up new <literal>Session</literal>'s.
+                A <literal>Session</literal> represents a single-threaded unit of work, the
+                <literal>SessionFactory</literal> is a thread-safe global object, instantiated once.
+            </para>
+
+            <para>
+                We'll create a <literal>HibernateUtil</literal> helper class which takes care
+                of startup and makes accessing a <literal>SessionFactory</literal> convenient.
+                Let's have a look at the implementation:
+            </para>
+
+            <programlisting><![CDATA[package util;
+
+import org.hibernate.*;
+import org.hibernate.cfg.*;
+
+public class HibernateUtil {
+
+    private static final SessionFactory sessionFactory;
+
+    static {
+        try {
+            // Create the SessionFactory from hibernate.cfg.xml
+            sessionFactory = new Configuration().configure().buildSessionFactory();
+        } catch (Throwable ex) {
+            // Make sure you log the exception, as it might be swallowed
+            System.err.println("Initial SessionFactory creation failed." + ex);
+            throw new ExceptionInInitializerError(ex);
+        }
+    }
+
+    public static SessionFactory getSessionFactory() {
+        return sessionFactory;
+    }
+
+}]]></programlisting>
+
+            <para>
+                This class does not only produce the global <literal>SessionFactory</literal> in
+                its static initializer (called once by the JVM when the class is loaded), but also
+                hides the fact that it uses a static singleton. It might as well lookup the
+                <literal>SessionFactory</literal> from JNDI in an application server.
+            </para>
+
+            <para>
+                If you give the <literal>SessionFactory</literal> a name in your configuration
+                file, Hibernate will in fact try to bind it to JNDI after it has been built.
+                To avoid this code completely you could also use JMX deployment and let the
+                JMX-capable container instantiate and bind a <literal>HibernateService</literal>
+                to JNDI. These advanced options are discussed in the Hibernate reference
+                documentation.
+            </para>
+
+            <para>
+                Place <literal>HibernateUtil.java</literal> in the development source directory, in
+                a package next to <literal>events</literal>:
+            </para>
+
+            <programlisting><![CDATA[.
++lib
+  <Hibernate and third-party libraries>
++src
+  +events
+    Event.java
+    Event.hbm.xml
+  +util
+    HibernateUtil.java
+  hibernate.cfg.xml
++data
+build.xml]]></programlisting>
+
+            <para>
+                This should again compile without problems. We finally need to configure a logging
+                system - Hibernate uses commons logging and leaves you the choice between Log4j and
+                JDK 1.4 logging. Most developers prefer Log4j: copy <literal>log4j.properties</literal>
+                from the Hibernate distribution (it's in the <literal>etc/</literal> directory) to
+                your <literal>src</literal> directory, next to <literal>hibernate.cfg.xml</literal>.
+                Have a look at the example configuration and change the settings if you like to have
+                more verbose output. By default, only Hibernate startup message are shown on stdout.
+            </para>
+
+            <para>
+                The tutorial infrastructure is complete - and we are ready to do some real work with
+                Hibernate.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-firstapp-workingpersistence" revision="5">
+            <title>Loading and storing objects</title>
+
+            <para>
+                Finally, we can use Hibernate to load and store objects. We write an
+                <literal>EventManager</literal> class with a <literal>main()</literal> method:
+            </para>
+
+            <programlisting><![CDATA[package events;
+import org.hibernate.Session;
+
+import java.util.Date;
+
+import util.HibernateUtil;
+
+public class EventManager {
+
+    public static void main(String[] args) {
+        EventManager mgr = new EventManager();
+
+        if (args[0].equals("store")) {
+            mgr.createAndStoreEvent("My Event", new Date());
+        }
+
+        HibernateUtil.getSessionFactory().close();
+    }
+
+    private void createAndStoreEvent(String title, Date theDate) {
+
+        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+        session.beginTransaction();
+
+        Event theEvent = new Event();
+        theEvent.setTitle(title);
+        theEvent.setDate(theDate);
+
+        session.save(theEvent);
+
+        session.getTransaction().commit();
+    }
+
+}]]></programlisting>
+
+            <para>
+                We create a new <literal>Event</literal> object, and hand it over to Hibernate.
+                Hibernate now takes care of the SQL and executes <literal>INSERT</literal>s
+                on the database. Let's have a look at the <literal>Session</literal> and
+                <literal>Transaction</literal>-handling code before we run this.
+            </para>
+
+            <para>
+                A <literal>Session</literal> is a single unit of work. For now we'll keep things
+                simple and assume a one-to-one granularity between a Hibernate <literal>Session</literal>
+                and a database transaction. To shield our code from the actual underlying transaction
+                system (in this case plain JDBC, but it could also run with JTA) we use the
+                <literal>Transaction</literal> API that is available on the Hibernate <literal>Session</literal>.
+            </para>
+
+            <para>
+                What does <literal>sessionFactory.getCurrentSession()</literal> do? First, you can call it
+                as many times and anywhere you like, once you get hold of your <literal>SessionFactory</literal>
+                (easy thanks to <literal>HibernateUtil</literal>). The <literal>getCurrentSession()</literal>
+                method always returns the "current" unit of work. Remember that we switched the configuration
+                option for this mechanism to "thread" in <literal>hibernate.cfg.xml</literal>? Hence,
+                the current unit of work is bound to the current Java thread that executes our application.
+                However, this is not the full picture, you also have to consider scope, when a unit of work
+                begins and when it ends.
+            </para>
+
+            <para>
+                A <literal>Session</literal> begins when it is first needed, when the first call to
+                <literal>getCurrentSession()</literal> is made. It is then bound by Hibernate to the current
+                thread. When the transaction ends, either through commit or rollback, Hibernate automatically
+                unbinds the <literal>Session</literal> from the thread and closes it for you. If you call
+                <literal>getCurrentSession()</literal> again, you get a new <literal>Session</literal> and can
+                start a new unit of work. This <emphasis>thread-bound</emphasis> programming model is the most
+                popular way of using Hibernate, as it allows flexible layering of your code (transaction
+                demarcation code can be separated from data access code, we'll do this later in this tutorial).
+            </para>
+
+            <para>
+                Related to the unit of work scope, should the Hibernate <literal>Session</literal> be used to
+                execute one or several database operations? The above example uses one <literal>Session</literal>
+                for one operation. This is pure coincidence, the example is just not complex enough to show any
+                other approach. The scope of a Hibernate <literal>Session</literal> is flexible but you should
+                never design your application to use a new Hibernate <literal>Session</literal> for
+                <emphasis>every</emphasis> database operation. So even if you see it a few more times in
+                the following (very trivial) examples, consider <emphasis>session-per-operation</emphasis>
+                an anti-pattern. A real (web) application is shown later in this tutorial.
+            </para>
+
+            <para>
+                Have a look at <xref linkend="transactions"/> for more information
+                about transaction handling and demarcation. We also skipped any error handling and
+                rollback in the previous example.
+            </para>
+
+            <para>
+                To run this first routine we have to add a callable target to the Ant build file:
+            </para>
+
+            <programlisting><![CDATA[<target name="run" depends="compile">
+    <java fork="true" classname="events.EventManager" classpathref="libraries">
+        <classpath path="${targetdir}"/>
+        <arg value="${action}"/>
+    </java>
+</target>]]></programlisting>
+
+            <para>
+                The value of the <literal>action</literal> argument is set on the command line when
+                calling the target:
+            </para>
+
+            <programlisting><![CDATA[C:\hibernateTutorial\>ant run -Daction=store]]></programlisting>
+
+            <para>
+                You should see, after compilation, Hibernate starting up and, depending on your
+                configuration, lots of log output. At the end you will find the following line:
+            </para>
+
+            <programlisting><![CDATA[[java] Hibernate: insert into EVENTS (EVENT_DATE, title, EVENT_ID) values (?, ?, ?)]]></programlisting>
+
+            <para>
+                This is the <literal>INSERT</literal> executed by Hibernate, the question marks
+                represent JDBC bind parameters. To see the values bound as arguments, or to reduce
+                the verbosity of the log, check your <literal>log4j.properties</literal>.
+            </para>
+
+            <para>
+                Now we'd like to list stored events as well, so we add an option to the main method:
+            </para>
+
+            <programlisting><![CDATA[if (args[0].equals("store")) {
+    mgr.createAndStoreEvent("My Event", new Date());
+}
+else if (args[0].equals("list")) {
+    List events = mgr.listEvents();
+    for (int i = 0; i < events.size(); i++) {
+        Event theEvent = (Event) events.get(i);
+        System.out.println("Event: " + theEvent.getTitle() +
+                           " Time: " + theEvent.getDate());
+    }
+}]]></programlisting>
+
+            <para>
+                We also add a new <literal>listEvents() method</literal>:
+            </para>
+
+            <programlisting><![CDATA[private List listEvents() {
+
+    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+
+    session.beginTransaction();
+
+    List result = session.createQuery("from Event").list();
+
+    session.getTransaction().commit();
+
+    return result;
+}]]></programlisting>
+
+            <para>
+                What we do here is use an HQL (Hibernate Query Language) query to load all existing
+                <literal>Event</literal> objects from the database. Hibernate will generate the
+                appropriate SQL, send it to the database and populate <literal>Event</literal> objects
+                with the data. You can create more complex queries with HQL, of course.
+            </para>
+
+            <para>
+                Now, to execute and test all of this, follow these steps:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Run <literal>ant run -Daction=store</literal> to store something into the database
+                        and, of course, to generate the database schema before through hbm2ddl.
+                    </para>
+                </listitem>
+                <listitem>
+                    <para>
+                        Now disable hbm2ddl by commenting out the property in your <literal>hibernate.cfg.xml</literal>
+                        file. Usually you only leave it turned on in continuous unit testing, but another
+                        run of hbm2ddl would <emphasis>drop</emphasis> everything you have stored - the
+                        <literal>create</literal> configuration setting actually translates into "drop all
+                        tables from the schema, then re-create all tables, when the SessionFactory is build".
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                If you now call Ant with <literal>-Daction=list</literal>, you should see the events
+                you have stored so far. You can of course also call the <literal>store</literal> action a few
+                times more.
+            </para>
+
+            <para>
+                Note: Most new Hibernate users fail at this point and we see questions about
+                <emphasis>Table not found</emphasis> error messages regularly. However, if you follow the
+                steps outlined above you will not have this problem, as hbm2ddl creates the database
+                schema on the first run, and subsequent application restarts will use this schema. If
+                you change the mapping and/or database schema, you have to re-enable hbm2ddl once again.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="tutorial-associations">
+        <title>Part 2 - Mapping associations</title>
+
+        <para>
+            We mapped a persistent entity class to a table. Let's build on this and add some class associations.
+            First we'll add people to our application, and store a list of events they participate in.
+        </para>
+
+        <sect2 id="tutorial-associations-mappinguser" revision="1">
+            <title>Mapping the Person class</title>
+
+            <para>
+                The first cut of the <literal>Person</literal> class is simple:
+            </para>
+
+            <programlisting><![CDATA[package events;
+
+public class Person {
+
+    private Long id;
+    private int age;
+    private String firstname;
+    private String lastname;
+
+    public Person() {}
+
+    // Accessor methods for all properties, private setter for 'id'
+
+}]]></programlisting>
+
+            <para>
+                Create a new mapping file called <literal>Person.hbm.xml</literal> (don't forget the
+                DTD reference at the top):
+            </para>
+
+            <programlisting><![CDATA[<hibernate-mapping>
+
+    <class name="events.Person" table="PERSON">
+        <id name="id" column="PERSON_ID">
+            <generator class="native"/>
+        </id>
+        <property name="age"/>
+        <property name="firstname"/>
+        <property name="lastname"/>
+    </class>
+
+</hibernate-mapping>]]></programlisting>
+
+            <para>
+                Finally, add the new mapping to Hibernate's configuration:
+            </para>
+
+            <programlisting><![CDATA[<mapping resource="events/Event.hbm.xml"/>
+<mapping resource="events/Person.hbm.xml"/>]]></programlisting>
+
+            <para>
+                We'll now create an association between these two entities. Obviously, persons
+                can participate in events, and events have participants. The design questions
+                we have to deal with are: directionality, multiplicity, and collection
+                behavior.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-unidirset" revision="3">
+            <title>A unidirectional Set-based association</title>
+
+            <para>
+                We'll add a collection of events to the <literal>Person</literal> class. That way we can
+                easily navigate to the events for a particular person, without executing an explicit query -
+                by calling <literal>aPerson.getEvents()</literal>. We use a Java collection, a <literal>Set</literal>,
+                because the collection will not contain duplicate elements and the ordering is not relevant for us.
+            </para>
+
+            <para>
+                We need a unidirectional, many-valued associations, implemented with a <literal>Set</literal>.
+                Let's write the code for this in the Java classes and then map it:
+            </para>
+
+            <programlisting><![CDATA[public class Person {
+
+    private Set events = new HashSet();
+
+    public Set getEvents() {
+        return events;
+    }
+
+    public void setEvents(Set events) {
+        this.events = events;
+    }
+}]]></programlisting>
+
+            <para>
+                Before we map this association, think about the other side. Clearly, we could just keep this
+                unidirectional. Or, we could create another collection on the <literal>Event</literal>, if we
+                want to be able to navigate it bi-directional, i.e. <literal>anEvent.getParticipants()</literal>.
+                This is not necessary, from a functional perspective. You could always execute an explicit query
+                to retrieve the participants for a particular event. This is a design choice left to you, but what
+                is clear from this discussion is the multiplicity of the association: "many" valued on both sides,
+                we call this a <emphasis>many-to-many</emphasis> association. Hence, we use Hibernate's
+                many-to-many mapping:
+            </para>
+
+            <programlisting><![CDATA[<class name="events.Person" table="PERSON">
+    <id name="id" column="PERSON_ID">
+        <generator class="native"/>
+    </id>
+    <property name="age"/>
+    <property name="firstname"/>
+    <property name="lastname"/>
+
+    <set name="events" table="PERSON_EVENT">
+        <key column="PERSON_ID"/>
+        <many-to-many column="EVENT_ID" class="events.Event"/>
+    </set>
+
+</class>]]></programlisting>
+
+            <para>
+                Hibernate supports all kinds of collection mappings, a <literal>&lt;set&gt;</literal> being most
+                common. For a many-to-many association (or <emphasis>n:m</emphasis> entity relationship), an
+                association table is needed. Each row in this table represents a link between a person and an event.
+                The table name is configured with the <literal>table</literal> attribute of the <literal>set</literal>
+                element. The identifier column name in the association, for the person's side, is defined with the
+                <literal>&lt;key&gt;</literal> element, the column name for the event's side with the
+                <literal>column</literal> attribute of the <literal>&lt;many-to-many&gt;</literal>. You also
+                have to tell Hibernate the class of the objects in your collection (correct: the class on the
+                other side of the collection of references).
+            </para>
+
+            <para>
+                The database schema for this mapping is therefore:
+            </para>
+
+            <programlisting><![CDATA[
+    _____________        __________________
+   |             |      |                  |       _____________
+   |   EVENTS    |      |   PERSON_EVENT   |      |             |
+   |_____________|      |__________________|      |    PERSON   |
+   |             |      |                  |      |_____________|
+   | *EVENT_ID   | <--> | *EVENT_ID        |      |             |
+   |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  |
+   |  TITLE      |      |__________________|      |  AGE        |
+   |_____________|                                |  FIRSTNAME  |
+                                                  |  LASTNAME   |
+                                                  |_____________|
+ ]]></programlisting>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-working" revision="2">
+            <title>Working the association</title>
+
+            <para>
+                Let's bring some people and events together in a new method in <literal>EventManager</literal>:
+            </para>
+
+            <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+    session.beginTransaction();
+
+    Person aPerson = (Person) session.load(Person.class, personId);
+    Event anEvent = (Event) session.load(Event.class, eventId);
+
+    aPerson.getEvents().add(anEvent);
+
+    session.getTransaction().commit();
+}]]></programlisting>
+
+            <para>
+                After loading a <literal>Person</literal> and an <literal>Event</literal>, simply
+                modify the collection using the normal collection methods. As you can see, there is no explicit call
+                to <literal>update()</literal> or <literal>save()</literal>, Hibernate automatically
+                detects that the collection has been modified and needs to be updated. This is called <emphasis>automatic
+                dirty checking</emphasis>, and you can also try it by modifying the name or the date property of
+                any of your objects. As long as they are in <emphasis>persistent</emphasis> state, that is, bound
+                to a particular Hibernate <literal>Session</literal> (i.e. they have been just loaded or saved in
+                a unit of work), Hibernate monitors any changes and executes SQL in a write-behind fashion. The
+                process of synchronizing the memory state with the database, usually only at the end of a unit of
+                work, is called <emphasis>flushing</emphasis>. In our code, the unit of work ends with a commit
+                (or rollback) of the database transaction - as defined by the <literal>thread</literal> configuration
+                option for the <literal>CurrentSessionContext</literal> class.
+            </para>
+
+            <para>
+                You might of course load person and event in different units of work. Or you modify an object
+                outside of a <literal>Session</literal>, when it is not in persistent state (if it was persistent
+                before, we call this state <emphasis>detached</emphasis>). You can even modify a collection when
+                it is detached:
+            </para>
+
+            <programlisting><![CDATA[private void addPersonToEvent(Long personId, Long eventId) {
+
+    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+    session.beginTransaction();
+
+    Person aPerson = (Person) session
+            .createQuery("select p from Person p left join fetch p.events where p.id = :pid")
+            .setParameter("pid", personId)
+            .uniqueResult(); // Eager fetch the collection so we can use it detached
+
+    Event anEvent = (Event) session.load(Event.class, eventId);
+
+    session.getTransaction().commit();
+
+    // End of first unit of work
+
+    aPerson.getEvents().add(anEvent); // aPerson (and its collection) is detached
+
+    // Begin second unit of work
+
+    Session session2 = HibernateUtil.getSessionFactory().getCurrentSession();
+    session2.beginTransaction();
+
+    session2.update(aPerson); // Reattachment of aPerson
+
+    session2.getTransaction().commit();
+}]]></programlisting>
+
+            <para>
+                The call to <literal>update</literal> makes a detached object persistent again, you could
+                say it binds it to a new unit of work, so any modifications you made to it while detached
+                can be saved to the database. This includes any modifications (additions/deletions) you
+                made to a collection of that entity object.
+            </para>
+
+            <para>
+                Well, this is not much use in our current situation, but it's an important concept you can
+                design into your own application. For now, complete this exercise by adding a new action
+                to the <literal>EventManager</literal>'s main method and call it from the command line. If
+                you need the identifiers of a person and an event - the <literal>save()</literal> method
+                returns it (you might have to modify some of the previous methods to return that identifier):
+            </para>
+
+            <programlisting><![CDATA[else if (args[0].equals("addpersontoevent")) {
+    Long eventId = mgr.createAndStoreEvent("My Event", new Date());
+    Long personId = mgr.createAndStorePerson("Foo", "Bar");
+    mgr.addPersonToEvent(personId, eventId);
+    System.out.println("Added person " + personId + " to event " + eventId);
+}]]></programlisting>
+
+            <para>
+                This was an example of an association between two equally important classes, two entities.
+                As mentioned earlier, there are other classes and types in a typical model, usually "less
+                important". Some you have already seen, like an <literal>int</literal> or a <literal>String</literal>.
+                We call these classes <emphasis>value types</emphasis>, and their instances <emphasis>depend</emphasis>
+                on a particular entity. Instances of these types don't have their own identity, nor are they
+                shared between entities (two persons don't reference the same <literal>firstname</literal>
+                object, even if they have the same first name). Of course, value types can not only be found in
+                the JDK (in fact, in a Hibernate application all JDK classes are considered value types), but
+                you can also write dependent classes yourself, <literal>Address</literal> or <literal>MonetaryAmount</literal>,
+                for example.
+            </para>
+
+            <para>
+                You can also design a collection of value types. This is conceptually very different from a
+                collection of references to other entities, but looks almost the same in Java.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-valuecollections">
+            <title>Collection of values</title>
+
+            <para>
+                We add a collection of value typed objects to the <literal>Person</literal> entity. We want to
+                store email addresses, so the type we use is <literal>String</literal>, and the collection is
+                again a <literal>Set</literal>:
+            </para>
+            <programlisting><![CDATA[private Set emailAddresses = new HashSet();
+
+public Set getEmailAddresses() {
+    return emailAddresses;
+}
+
+public void setEmailAddresses(Set emailAddresses) {
+    this.emailAddresses = emailAddresses;
+}]]></programlisting>
+
+            <para>
+                The mapping of this <literal>Set</literal>:
+            </para>
+
+            <programlisting><![CDATA[<set name="emailAddresses" table="PERSON_EMAIL_ADDR">
+    <key column="PERSON_ID"/>
+    <element type="string" column="EMAIL_ADDR"/>
+</set>]]></programlisting>
+
+            <para>
+                The difference compared with the earlier mapping is the <literal>element</literal> part, which tells Hibernate that the collection
+                does not contain references to another entity, but a collection of elements of type
+                <literal>String</literal> (the lowercase name tells you it's a Hibernate mapping type/converter).
+                Once again, the <literal>table</literal> attribute of the <literal>set</literal> element determines
+                the table name for the collection. The <literal>key</literal> element defines the foreign-key column
+                name in the collection table. The <literal>column</literal> attribute in the <literal>element</literal>
+                element defines the column name where the <literal>String</literal> values will actually be stored.
+            </para>
+
+            <para>
+                Have a look at the updated schema:
+            </para>
+
+            <programlisting><![CDATA[
+  _____________        __________________
+ |             |      |                  |       _____________
+ |   EVENTS    |      |   PERSON_EVENT   |      |             |       ___________________
+ |_____________|      |__________________|      |    PERSON   |      |                   |
+ |             |      |                  |      |_____________|      | PERSON_EMAIL_ADDR |
+ | *EVENT_ID   | <--> | *EVENT_ID        |      |             |      |___________________|
+ |  EVENT_DATE |      | *PERSON_ID       | <--> | *PERSON_ID  | <--> |  *PERSON_ID       |
+ |  TITLE      |      |__________________|      |  AGE        |      |  *EMAIL_ADDR      |
+ |_____________|                                |  FIRSTNAME  |      |___________________|
+                                                |  LASTNAME   |
+                                                |_____________|
+ ]]></programlisting>
+
+            <para>
+                You can see that the primary key of the collection table is in fact a composite key,
+                using both columns. This also implies that there can't be duplicate email addresses
+                per person, which is exactly the semantics we need for a set in Java.
+            </para>
+
+            <para>
+                You can now try and add elements to this collection, just like we did before by
+                linking persons and events. It's the same code in Java:
+            </para>
+
+            <programlisting><![CDATA[private void addEmailToPerson(Long personId, String emailAddress) {
+
+    Session session = HibernateUtil.getSessionFactory().getCurrentSession();
+    session.beginTransaction();
+
+    Person aPerson = (Person) session.load(Person.class, personId);
+
+    // The getEmailAddresses() might trigger a lazy load of the collection
+    aPerson.getEmailAddresses().add(emailAddress);
+
+    session.getTransaction().commit();
+}]]></programlisting>
+
+            <para>
+                This time we didn't use a <emphasis>fetch</emphasis> query to initialize the collection.
+                Hence, the call to its getter method will trigger an additional select to initialize
+                it, so we can add an element to it. Monitor the SQL log and try to optimize this with
+                an eager fetch.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-bidirectional" revision="1">
+            <title>Bi-directional associations</title>
+
+            <para>
+                Next we are going to map a bi-directional association - making the association between
+                person and event work from both sides in Java. Of course, the database schema doesn't
+                change, we still have many-to-many multiplicity. A relational database is more flexible
+                than a network programming language, so it doesn't need anything like a navigation
+                direction - data can be viewed and retrieved in any possible way.
+            </para>
+
+            <para>
+                First, add a collection of participants to the <literal>Event</literal> Event class:
+            </para>
+
+            <programlisting><![CDATA[private Set participants = new HashSet();
+
+public Set getParticipants() {
+    return participants;
+}
+
+public void setParticipants(Set participants) {
+    this.participants = participants;
+}]]></programlisting>
+
+            <para>
+                Now map this side of the association too, in <literal>Event.hbm.xml</literal>.
+            </para>
+
+            <programlisting><![CDATA[<set name="participants" table="PERSON_EVENT" inverse="true">
+    <key column="EVENT_ID"/>
+    <many-to-many column="PERSON_ID" class="events.Person"/>
+</set>]]></programlisting>
+
+            <para>
+                As you see, these are normal <literal>set</literal> mappings in both mapping documents.
+                Notice that the column names in <literal>key</literal> and <literal>many-to-many</literal> are
+                swapped in both mapping documents. The most important addition here is the
+                <literal>inverse="true"</literal> attribute in the <literal>set</literal> element of the
+                <literal>Event</literal>'s collection mapping.
+            </para>
+
+            <para>
+                What this means is that Hibernate should take the other side - the <literal>Person</literal> class -
+                when it needs to find out information about the link between the two. This will be a lot easier to
+                understand once you see how the bi-directional link between our two entities is created .
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-associations-usingbidir">
+            <title>Working bi-directional links</title>
+
+            <para>
+                First, keep in mind that Hibernate does not affect normal Java semantics. How did we create a
+                link between a <literal>Person</literal> and an <literal>Event</literal> in the unidirectional
+                example? We added an instance of <literal>Event</literal> to the collection of event references,
+                of an instance of <literal>Person</literal>. So, obviously, if we want to make this link working
+                bi-directional, we have to do the same on the other side - adding a <literal>Person</literal>
+                reference to the collection in an <literal>Event</literal>. This "setting the link on both sides"
+                is absolutely necessary and you should never forget doing it.
+            </para>
+
+            <para>
+                Many developers program defensively and create link management methods to
+                correctly set both sides, e.g. in <literal>Person</literal>:
+            </para>
+
+            <programlisting><![CDATA[protected Set getEvents() {
+    return events;
+}
+
+protected void setEvents(Set events) {
+    this.events = events;
+}
+
+public void addToEvent(Event event) {
+    this.getEvents().add(event);
+    event.getParticipants().add(this);
+}
+
+public void removeFromEvent(Event event) {
+    this.getEvents().remove(event);
+    event.getParticipants().remove(this);
+}]]></programlisting>
+
+            <para>
+                Notice that the get and set methods for the collection are now protected - this allows classes in the
+                same package and subclasses to still access the methods, but prevents everybody else from messing
+                with the collections directly (well, almost). You should probably do the same with the collection
+                on the other side.
+            </para>
+
+            <para>
+                What about the <literal>inverse</literal> mapping attribute? For you, and for Java, a bi-directional
+                link is simply a matter of setting the references on both sides correctly. Hibernate however doesn't
+                have enough information to correctly arrange SQL <literal>INSERT</literal> and <literal>UPDATE</literal>
+                statements (to avoid constraint violations), and needs some help to handle bi-directional associations
+                properly. Making one side of the association <literal>inverse</literal> tells Hibernate to basically
+                ignore it, to consider it a <emphasis>mirror</emphasis> of the other side. That's all that is necessary
+                for Hibernate to work out all of the issues when transformation a directional navigation model to
+                a SQL database schema. The rules you have to remember are straightforward: All bi-directional associations
+                need one side as <literal>inverse</literal>. In a one-to-many association it has to be the many-side,
+                in many-to-many association you can pick either side, there is no difference.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="tutorial-webapp">
+        <title>Part 3 - The EventManager web application</title>
+
+        <para>
+            Let's turn the following discussion into a small web application...
+        </para>
+
+        <para>
+            A Hibernate web application uses <literal>Session</literal> and <literal>Transaction</literal>
+            almost like a standalone application. However, some common patterns are useful. We now write
+            an <literal>EventManagerServlet</literal>. This servlet can list all events stored in the
+            database, and it provides an HTML form to enter new events.
+        </para>
+
+        <sect2 id="tutorial-webapp-servlet" revision="2">
+            <title>Writing the basic servlet</title>
+
+            <para>
+                Create a new class in your source directory, in the <literal>events</literal>
+                package:
+            </para>
+
+            <programlisting><![CDATA[package events;
+
+// Imports
+
+public class EventManagerServlet extends HttpServlet {
+
+    // Servlet code
+}]]></programlisting>
+
+            <para>
+                The servlet handles HTTP <literal>GET</literal> requests only, hence, the method
+                we implement is <literal>doGet()</literal>:
+            </para>
+
+            <programlisting><![CDATA[protected void doGet(HttpServletRequest request,
+                     HttpServletResponse response)
+        throws ServletException, IOException {
+
+    SimpleDateFormat dateFormatter = new SimpleDateFormat("dd.MM.yyyy");
+
+    try {
+        // Begin unit of work
+        HibernateUtil.getSessionFactory()
+                .getCurrentSession().beginTransaction();
+
+        // Process request and render page...
+
+        // End unit of work
+        HibernateUtil.getSessionFactory()
+                .getCurrentSession().getTransaction().commit();
+
+    } catch (Exception ex) {
+        HibernateUtil.getSessionFactory()
+                .getCurrentSession().getTransaction().rollback();
+        throw new ServletException(ex);
+    }
+
+}]]></programlisting>
+
+            <para>
+                The pattern we are applying here is called <emphasis>session-per-request</emphasis>.
+                When a request hits the servlet, a new Hibernate <literal>Session</literal> is
+                opened through the first call to <literal>getCurrentSession()</literal> on the
+                <literal>SessionFactory</literal>. Then a database transaction is started&mdash;all
+                data access as to occur inside a transaction, no matter if data is read or written
+                (we don't use the auto-commit mode in applications).
+            </para>
+
+            <para>
+                Do <emphasis>not</emphasis> use a new Hibernate <literal>Session</literal> for
+                every database operation. Use one Hibernate <literal>Session</literal> that is
+                scoped to the whole request. Use <literal>getCurrentSession()</literal>, so that
+                it is automatically bound to the current Java thread.
+            </para>
+
+            <para>
+                Next, the possible actions of the request are processed and the response HTML
+                is rendered. We'll get to that part soon.
+            </para>
+
+            <para>
+                Finally, the unit of work ends when processing and rendering is complete. If any
+                problem occurred during processing or rendering, an exception will be thrown
+                and the database transaction rolled back. This completes the
+                <literal>session-per-request</literal> pattern. Instead of the transaction
+                demarcation code in every servlet you could also write a servlet filter.
+                See the Hibernate website and Wiki for more information about this pattern,
+                called <emphasis>Open Session in View</emphasis>&mdash;you'll need it as soon
+                as you consider rendering your view in JSP, not in a servlet.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-webapp-processing" revision="1">
+            <title>Processing and rendering</title>
+
+            <para>
+                Let's implement the processing of the request and rendering of the page.
+            </para>
+
+<programlisting><![CDATA[// Write HTML header
+PrintWriter out = response.getWriter();
+out.println("<html><head><title>Event Manager</title></head><body>");
+
+// Handle actions
+if ( "store".equals(request.getParameter("action")) ) {
+
+    String eventTitle = request.getParameter("eventTitle");
+    String eventDate = request.getParameter("eventDate");
+
+    if ( "".equals(eventTitle) || "".equals(eventDate) ) {
+        out.println("<b><i>Please enter event title and date.</i></b>");
+    } else {
+        createAndStoreEvent(eventTitle, dateFormatter.parse(eventDate));
+        out.println("<b><i>Added event.</i></b>");
+    }
+}
+
+// Print page
+printEventForm(out);
+listEvents(out, dateFormatter);
+
+// Write HTML footer
+out.println("</body></html>");
+out.flush();
+out.close();]]></programlisting>
+
+            <para>
+                Granted, this coding style with a mix of Java and HTML would not scale
+                in a more complex application&mdash;keep in mind that we are only illustrating
+                basic Hibernate concepts in this tutorial. The code prints an HTML
+                header and a footer. Inside this page, an HTML form for event entry and
+                a list of all events in the database are printed. The first method is
+                trivial and only outputs HTML:
+            </para>
+
+            <programlisting><![CDATA[private void printEventForm(PrintWriter out) {
+    out.println("<h2>Add new event:</h2>");
+    out.println("<form>");
+    out.println("Title: <input name='eventTitle' length='50'/><br/>");
+    out.println("Date (e.g. 24.12.2009): <input name='eventDate' length='10'/><br/>");
+    out.println("<input type='submit' name='action' value='store'/>");
+    out.println("</form>");
+}]]></programlisting>
+
+            <para>
+                The <literal>listEvents()</literal> method uses the Hibernate
+                <literal>Session</literal> bound to the current thread to execute
+                a query:
+            </para>
+
+            <programlisting><![CDATA[private void listEvents(PrintWriter out, SimpleDateFormat dateFormatter) {
+
+    List result = HibernateUtil.getSessionFactory()
+                    .getCurrentSession().createCriteria(Event.class).list();
+    if (result.size() > 0) {
+        out.println("<h2>Events in database:</h2>");
+        out.println("<table border='1'>");
+        out.println("<tr>");
+        out.println("<th>Event title</th>");
+        out.println("<th>Event date</th>");
+        out.println("</tr>");
+        for (Iterator it = result.iterator(); it.hasNext();) {
+            Event event = (Event) it.next();
+            out.println("<tr>");
+            out.println("<td>" + event.getTitle() + "</td>");
+            out.println("<td>" + dateFormatter.format(event.getDate()) + "</td>");
+            out.println("</tr>");
+        }
+        out.println("</table>");
+    }
+}]]></programlisting>
+
+            <para>
+                Finally, the <literal>store</literal> action is dispatched to the
+                <literal>createAndStoreEvent()</literal> method, which also uses
+                the <literal>Session</literal> of the current thread:
+            </para>
+
+            <programlisting><![CDATA[protected void createAndStoreEvent(String title, Date theDate) {
+    Event theEvent = new Event();
+    theEvent.setTitle(title);
+    theEvent.setDate(theDate);
+
+    HibernateUtil.getSessionFactory()
+                    .getCurrentSession().save(theEvent);
+}]]></programlisting>
+
+            <para>
+                That's it, the servlet is complete. A request to the servlet will be processed
+                in a single <literal>Session</literal> and <literal>Transaction</literal>. As
+                earlier in the standalone application, Hibernate can automatically bind these
+                objects to the current thread of execution. This gives you the freedom to layer
+                your code and access the <literal>SessionFactory</literal> in any way you like.
+                Usually you'd use a more sophisticated design and move the data access code
+                into data access objects (the DAO pattern). See the Hibernate Wiki for more
+                examples.
+            </para>
+
+        </sect2>
+
+        <sect2 id="tutorial-webapp-deploy">
+            <title>Deploying and testing</title>
+
+            <para>
+                To deploy this application you have to create a web archive, a WAR. Add the
+                following Ant target to your <literal>build.xml</literal>:
+            </para>
+
+<programlisting><![CDATA[<target name="war" depends="compile">
+    <war destfile="hibernate-tutorial.war" webxml="web.xml">
+        <lib dir="${librarydir}">
+          <exclude name="jsdk*.jar"/>
+        </lib>
+
+        <classes dir="${targetdir}"/>
+    </war>
+</target>]]></programlisting>
+
+            <para>
+                This target creates a file called <literal>hibernate-tutorial.war</literal>
+                in your project directory. It packages all libraries and the <literal>web.xml</literal>
+                descriptor, which is expected in the base directory of your project:
+            </para>
+
+            <programlisting><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
+<web-app version="2.4"
+    xmlns="http://java.sun.com/xml/ns/j2ee"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+    <servlet>
+        <servlet-name>Event Manager</servlet-name>
+        <servlet-class>events.EventManagerServlet</servlet-class>
+    </servlet>
+
+    <servlet-mapping>
+        <servlet-name>Event Manager</servlet-name>
+        <url-pattern>/eventmanager</url-pattern>
+    </servlet-mapping>
+</web-app>]]></programlisting>
+
+            <para>
+                Before you compile and deploy the web application, note that an additional library
+                is required: <literal>jsdk.jar</literal>. This is the Java servlet development kit,
+                if you don't have this library already, get it from the Sun website and copy it to
+                your library directory. However, it will be only used for compilation and excluded
+                from the WAR package.
+            </para>
+
+            <para>
+                To build and deploy call <literal>ant war</literal> in your project directory
+                and copy the <literal>hibernate-tutorial.war</literal> file into your Tomcat
+                <literal>webapp</literal> directory. If you don't have Tomcat installed, download
+                it and follow the installation instructions. You don't have to change any Tomcat
+                configuration to deploy this application though.
+            </para>
+
+            <para>
+                Once deployed and Tomcat is running, access the application at
+                <literal>http://localhost:8080/hibernate-tutorial/eventmanager</literal>. Make
+                sure you watch the Tomcat log to see Hibernate initialize when the first
+                request hits your servlet (the static initializer in <literal>HibernateUtil</literal>
+                is called) and to get the detailed output if any exceptions occurs.
+            </para>
+
+        </sect2>
+
+    </sect1>
+
+    <sect1 id="tutorial-summary" revision="1">
+        <title>Summary</title>
+
+        <para>
+            This tutorial covered the basics of writing a simple standalone Hibernate application
+            and a small web application.
+        </para>
+
+        <para>
+            If you already feel confident with Hibernate, continue browsing through the reference
+            documentation table of contents for topics you find interesting - most asked are
+            transactional processing (<xref linkend="transactions"/>), fetch
+            performance (<xref linkend="performance"/>), or the usage of the API (<xref linkend="objectstate"/>)
+            and the query features (<xref linkend="objectstate-querying"/>).
+        </para>
+
+        <para>
+            Don't forget to check the Hibernate website for more (specialized) tutorials.
+        </para>
+
+    </sect1>
+
+</chapter>

Deleted: core/tags/hibernate-3.3.0.CR2/documentation/pom.xml
===================================================================
--- core/trunk/documentation/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/documentation/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-documentation</artifactId>
-    <packaging>pom</packaging>
-
-    <name>Hibernate Core - Documentation</name>
-    <description>Grouping of Hibernate Core Project documentation modules</description>
-
-    <modules>
-        <module>releasenotes</module>
-        <module>manual</module>
-<!--
-        <module>jbosscache2</module>
--->
-    </modules>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/documentation/pom.xml (from rev 15003, core/trunk/documentation/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/documentation/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/documentation/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-documentation</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Hibernate Core - Documentation</name>
+    <description>Grouping of Hibernate Core Project documentation modules</description>
+
+    <modules>
+        <module>releasenotes</module>
+        <module>manual</module>
+<!--
+        <module>jbosscache2</module>
+-->
+    </modules>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml
===================================================================
--- core/trunk/documentation/releasenotes/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,116 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  ~ 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
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" 
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-releasenotes</artifactId>
-    <version>3.3.0-SNAPSHOT</version>
-    <packaging>jdocbook</packaging>
-
-    <name>Hibernate Release Notes</name>
-    <description>The Hibernate release notes DocBook source module</description>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.jboss.maven.plugins</groupId>
-                <artifactId>maven-jdocbook-plugin</artifactId>
-                <version>2.1.0</version>
-                <extensions>true</extensions>
-                <executions>
-                    <execution>
-                        <!--
-                            here we are attaching the translate goal so that the translations are processed
-                            before compilation so that the transated XML is also transformed during
-                            generation
-                        -->
-                        <phase>process-resources</phase>
-                        <goals>
-                            <goal>translate</goal>
-                        </goals>
-                    </execution>
-                </executions>
-                <dependencies>
-                    <dependency>
-                        <groupId>org.hibernate</groupId>
-                        <artifactId>hibernate-jdocbook-style</artifactId>
-                        <version>1.0.2</version>
-                        <type>jdocbook-style</type>
-                    </dependency>
-                </dependencies>
-                <configuration>
-                    <sourceDocumentName>en-US/Release_Notes.xml</sourceDocumentName>
-                    <masterTranslation>en-US</masterTranslation>
-                    <imageResource>
-                        <directory>${basedir}/src/main/docbook/en-US</directory>
-                        <includes>
-                            <include>**/*.svg</include>
-                            <include>**/*.png</include>
-                        </includes>
-                    </imageResource>
-                    <formats>
-                        <format>
-                            <formatName>pdf</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
-                            <finalName>Release_Notes.pdf</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                        <format>
-                            <formatName>html_single</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl</stylesheetResource>
-                            <finalName>index.html</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                        <format>
-                            <formatName>html</formatName>
-                            <stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl</stylesheetResource>
-                            <finalName>index.html</finalName>
-                            <profilingTypeName>two_pass</profilingTypeName>
-                        </format>
-                    </formats>
-                    <options>
-                        <xincludeSupported>true</xincludeSupported>
-                        <localeSeparator>-</localeSeparator>
-                        <useRelativeImageUris>true</useRelativeImageUris>
-                    </options>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-</project>

Copied: core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml (from rev 15003, core/trunk/documentation/releasenotes/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/documentation/releasenotes/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,88 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-releasenotes</artifactId>
+    <version>3.3.0.CR2</version>
+    <packaging>jdocbook</packaging>
+
+    <name>Hibernate Release Notes</name>
+    <description>The Hibernate release notes DocBook source module</description>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.jboss.maven.plugins</groupId>
+                <artifactId>maven-jdocbook-plugin</artifactId>
+                <version>2.1.0</version>
+                <extensions>true</extensions>
+                <executions>
+                    <execution>
+                        <!--
+                            here we are attaching the translate goal so that the translations are processed
+                            before compilation so that the transated XML is also transformed during
+                            generation
+                        -->
+                        <phase>process-resources</phase>
+                        <goals>
+                            <goal>translate</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.hibernate</groupId>
+                        <artifactId>hibernate-jdocbook-style</artifactId>
+                        <version>1.0.2</version>
+                        <type>jdocbook-style</type>
+                    </dependency>
+                </dependencies>
+                <configuration>
+                    <sourceDocumentName>en-US/Release_Notes.xml</sourceDocumentName>
+                    <masterTranslation>en-US</masterTranslation>
+                    <imageResource>
+                        <directory>${basedir}/src/main/docbook/en-US</directory>
+                        <includes>
+                            <include>**/*.svg</include>
+                            <include>**/*.png</include>
+                        </includes>
+                    </imageResource>
+                    <formats>
+                        <format>
+                            <formatName>pdf</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/pdf/main-pdf.xsl</stylesheetResource>
+                            <finalName>Release_Notes.pdf</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                        <format>
+                            <formatName>html_single</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-single.xsl</stylesheetResource>
+                            <finalName>index.html</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                        <format>
+                            <formatName>html</formatName>
+                            <stylesheetResource>classpath:/xslt/hibernate/html/main-chunk.xsl</stylesheetResource>
+                            <finalName>index.html</finalName>
+                            <profilingTypeName>two_pass</profilingTypeName>
+                        </format>
+                    </formats>
+                    <options>
+                        <xincludeSupported>true</xincludeSupported>
+                        <localeSeparator>-</localeSeparator>
+                        <useRelativeImageUris>true</useRelativeImageUris>
+                    </options>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/jmx/pom.xml
===================================================================
--- core/trunk/jmx/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/jmx/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,37 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-jmx</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate JMX Module</name>
-    <description>Defines Hibernate JMX capabilities</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <!-- logging setup for the test suite -->
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-        </dependency>
-    </dependencies>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/jmx/pom.xml (from rev 15003, core/trunk/jmx/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/jmx/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/jmx/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,37 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-jmx</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate JMX Module</name>
+    <description>Defines Hibernate JMX capabilities</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <!-- logging setup for the test suite -->
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/parent/pom.xml
===================================================================
--- core/trunk/parent/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/parent/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,333 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  ~ 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
-  ~
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-parent</artifactId>
-    <packaging>pom</packaging>
-    <version>3.3.0-SNAPSHOT</version>
-
-    <name>Hibernate Core Parent POM</name>
-    <description>The base POM for all Hibernate Core modules.</description>
-    <url>http://hibernate.org</url>
-
-    <organization>
-        <name>Hibernate.org</name>
-        <url>http://hibernate.org</url>
-    </organization>
-
-    <licenses>
-        <license>
-            <name>GNU Lesser General Public License</name>
-            <url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
-            <comments>See discussion at http://hibernate.org/356.html for more details.</comments>
-            <distribution>repo</distribution>
-        </license>
-    </licenses>
-
-    <scm>
-        <connection>scm:svn:https://svn.jboss.org/repos/hibernate/core/trunk</connection>
-        <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/core/trunk</developerConnection>
-        <url>https://svn.jboss.org/repos/hibernate/core/trunk</url>
-    </scm>
-
-    <ciManagement>
-        <system>hudson</system>
-        <url>http://hudson.jboss.org/hudson/job/hibernate-testsuite/</url>
-        <notifiers>
-            <notifier>
-                <type>mail</type>
-                <address>hibernate-dev at lists.jboss.org</address>
-            </notifier>
-        </notifiers>
-    </ciManagement>
-
-    <issueManagement>
-        <system>jira</system>
-        <url>http://opensource.atlassian.com/projects/hibernate/browse/HHH</url>
-    </issueManagement>
-
-    <mailingLists>
-        <mailingList>
-            <name>Hibernate Announcements</name>
-            <post>hibernate-announce at lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Commit Notificatons</name>
-            <post>hibernate-commits at lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Developers</name>
-            <post>hibernate-dev at lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
-            <otherArchives>
-                <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
-            </otherArchives>
-        </mailingList>
-        <mailingList>
-            <name>Hibernate Issue Notifications</name>
-            <post>hibernate-issues at lists.jboss.org</post>
-            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
-            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
-            <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
-        </mailingList>
-    </mailingLists>
-
-    <build>
-        <plugins>
-            <plugin>
-                <!-- require at least JDK 1.5 to run the build -->
-                <!-- ... -->
-                <!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
-                <!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-enforcer-plugin</artifactId>
-                <executions>
-                    <execution>
-                        <id>enforce-java</id>
-                        <goals>
-                            <goal>enforce</goal>
-                        </goals>
-                        <configuration>
-                            <rules>
-                                <requireJavaVersion>
-                                    <version>[1.5,)</version>
-                                </requireJavaVersion>
-                                <requireMavenVersion>
-                                    <version>(2.0.7,)</version>
-                                </requireMavenVersion>
-                            </rules>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
-            <!-- by default, compile to JDK 1.4 compatibility (individual modules and/or user can override) -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.4</source>
-                    <target>1.4</target>
-                </configuration>
-            </plugin>
-            <!-- add specification/implementation details to the manifests -->
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifest>
-                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                        </manifest>
-                        <manifestEntries>
-                            <Implementation-URL>${pom.url}</Implementation-URL>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
-                </configuration>
-            </plugin>
-        </plugins>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-javadoc-plugin</artifactId>
-                    <version>2.4</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <version>2.4.3</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-jar-plugin</artifactId>
-                    <version>2.1</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-enforcer-plugin</artifactId>
-                    <version>1.0-alpha-3</version>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-compiler-plugin</artifactId>
-                    <version>2.0.2</version>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-        <extensions>
-            <extension>
-                <groupId>org.apache.maven.wagon</groupId>
-                <artifactId>wagon-webdav</artifactId>
-                <version>1.0-beta-2</version>
-            </extension>
-        </extensions>
-    </build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-report-plugin</artifactId>
-                <version>2.4.3</version>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <configuration>
-                    <links>
-                        <link>http://java.sun.com/j2se/1.4.2/docs/api/</link>
-                        <link>http://java.sun.com/j2ee/1.4/docs/api/</link>
-                    </links>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jxr-plugin</artifactId>
-                <version>2.1</version>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-pmd-plugin</artifactId>
-                <version>2.2</version>
-                <configuration>
-                    <linkXref>true</linkXref>
-                    <minimumTokens>100</minimumTokens>
-                    <targetJdk>1.4</targetJdk>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>taglist-maven-plugin</artifactId>
-                <version>2.1</version>
-                <configuration>
-                    <tags>
-                        <tag>@FIXME</tag>
-                        <tag>@fixme</tag>
-                        <tag>FIXME</tag>
-                        <tag>fixme</tag>
-                        <tag>@TODO</tag>
-                        <tag>@todo</tag>
-                        <tag>TODO</tag>
-                        <tag>todo</tag>
-                    </tags>
-                </configuration>
-            </plugin>
-            <plugin>
-                <!-- Note: aggregate-able, may cause problems if we aggregate jxr and not this because of the xref links -->
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>javancss-maven-plugin</artifactId>
-                <version>2.0-beta-2</version>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>findbugs-maven-plugin</artifactId>
-                <version>1.1.1</version>
-                <configuration>
-                    <onlyAnalyze>org.hibernate.*</onlyAnalyze>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <scope>test</scope>
-        </dependency>
-    </dependencies>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.slf4j</groupId>
-                <artifactId>slf4j-api</artifactId>
-                <version>1.4.2</version>
-            </dependency>
-            <dependency>
-                <groupId>antlr</groupId>
-                <artifactId>antlr</artifactId>
-                <version>2.7.6</version>
-            </dependency>
-            <dependency>
-                <groupId>commons-collections</groupId>
-                <artifactId>commons-collections</artifactId>
-                <version>3.1</version>
-            </dependency>
-            <dependency>
-                <groupId>junit</groupId>
-                <artifactId>junit</artifactId>
-                <version>3.8.1</version>
-            </dependency>
-            <dependency>
-                <groupId>dom4j</groupId>
-                <artifactId>dom4j</artifactId>
-                <version>1.6.1</version>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <distributionManagement>
-        <repository>
-            <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
-            <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
-            <!-- todo : replace this with direct svn access once the svnkit providers are available -->
-            <id>repository.jboss.org</id>
-            <url>file://${maven.repository.root}</url>
-        </repository>
-        <snapshotRepository>
-            <id>snapshots.jboss.org</id>
-            <name>JBoss Snapshot Repository</name>
-            <url>dav:https://snapshots.jboss.org/maven2</url>
-        </snapshotRepository>
-    </distributionManagement>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/parent/pom.xml (from rev 15003, core/trunk/parent/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/parent/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/parent/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ 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
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-parent</artifactId>
+    <packaging>pom</packaging>
+    <version>3.3.0.CR2</version>
+
+    <name>Hibernate Core Parent POM</name>
+    <description>The base POM for all Hibernate Core modules.</description>
+    <url>http://hibernate.org</url>
+
+    <organization>
+        <name>Hibernate.org</name>
+        <url>http://hibernate.org</url>
+    </organization>
+
+    <licenses>
+        <license>
+            <name>GNU Lesser General Public License</name>
+            <url>http://www.gnu.org/licenses/lgpl-2.1.html</url>
+            <comments>See discussion at http://hibernate.org/356.html for more details.</comments>
+            <distribution>repo</distribution>
+        </license>
+    </licenses>
+
+    <scm>
+        <connection>scm:svn:https://svn.jboss.org/repos/hibernate/core/tags/hibernate-3.3.0.CR2</connection>
+        <developerConnection>scm:svn:https://svn.jboss.org/repos/hibernate/core/tags/hibernate-3.3.0.CR2</developerConnection>
+        <url>https://svn.jboss.org/repos/hibernate/core/tags/hibernate-3.3.0.CR2</url>
+    </scm>
+
+    <ciManagement>
+        <system>hudson</system>
+        <url>http://hudson.jboss.org/hudson/job/hibernate-testsuite/</url>
+        <notifiers>
+            <notifier>
+                <type>mail</type>
+                <address>hibernate-dev at lists.jboss.org</address>
+            </notifier>
+        </notifiers>
+    </ciManagement>
+
+    <issueManagement>
+        <system>jira</system>
+        <url>http://opensource.atlassian.com/projects/hibernate/browse/HHH</url>
+    </issueManagement>
+
+    <mailingLists>
+        <mailingList>
+            <name>Hibernate Announcements</name>
+            <post>hibernate-announce at lists.jboss.org</post>
+            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</subscribe>
+            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-announce</unsubscribe>
+            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+        </mailingList>
+        <mailingList>
+            <name>Hibernate Commit Notificatons</name>
+            <post>hibernate-commits at lists.jboss.org</post>
+            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</subscribe>
+            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-commits</unsubscribe>
+            <archive>http://lists.jboss.org/pipermail/hibernate-commits/</archive>
+        </mailingList>
+        <mailingList>
+            <name>Hibernate Developers</name>
+            <post>hibernate-dev at lists.jboss.org</post>
+            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</subscribe>
+            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-dev</unsubscribe>
+            <archive>http://lists.jboss.org/pipermail/hibernate-dev/</archive>
+            <otherArchives>
+                <otherArchive>http://www.mail-archive.com/hibernate-dev%40lists.jboss.org/index.html</otherArchive>
+            </otherArchives>
+        </mailingList>
+        <mailingList>
+            <name>Hibernate Issue Notifications</name>
+            <post>hibernate-issues at lists.jboss.org</post>
+            <subscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</subscribe>
+            <unsubscribe>https://lists.jboss.org/mailman/listinfo/hibernate-issues</unsubscribe>
+            <archive>http://lists.jboss.org/pipermail/hibernate-issues/</archive>
+        </mailingList>
+    </mailingLists>
+
+    <build>
+        <plugins>
+            <plugin>
+                <!-- require at least JDK 1.5 to run the build -->
+                <!-- ... -->
+                <!-- we need at least Maven 2.0.8 because of a bug fix affecting our antlr usage -->
+                <!-- 2.0.8 not released at this time, so I instead say anything greater that 2.0.7 -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>enforce-java</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <version>[1.5,)</version>
+                                </requireJavaVersion>
+                                <requireMavenVersion>
+                                    <version>(2.0.7,)</version>
+                                </requireMavenVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <!-- by default, compile to JDK 1.4 compatibility (individual modules and/or user can override) -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.4</source>
+                    <target>1.4</target>
+                </configuration>
+            </plugin>
+            <!-- add specification/implementation details to the manifests -->
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                        </manifest>
+                        <manifestEntries>
+                            <Implementation-URL>${pom.url}</Implementation-URL>
+                        </manifestEntries>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <redirectTestOutputToFile>true</redirectTestOutputToFile>
+                </configuration>
+            </plugin>
+        </plugins>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-javadoc-plugin</artifactId>
+                    <version>2.4</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-surefire-plugin</artifactId>
+                    <version>2.4.3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <version>2.1</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-enforcer-plugin</artifactId>
+                    <version>1.0-alpha-3</version>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.maven.plugins</groupId>
+                    <artifactId>maven-compiler-plugin</artifactId>
+                    <version>2.0.2</version>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <extensions>
+            <extension>
+                <groupId>org.apache.maven.wagon</groupId>
+                <artifactId>wagon-webdav</artifactId>
+                <version>1.0-beta-2</version>
+            </extension>
+        </extensions>
+    </build>
+
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-report-plugin</artifactId>
+                <version>2.4.3</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <links>
+                        <link>http://java.sun.com/j2se/1.4.2/docs/api/</link>
+                        <link>http://java.sun.com/j2ee/1.4/docs/api/</link>
+                    </links>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jxr-plugin</artifactId>
+                <version>2.1</version>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-pmd-plugin</artifactId>
+                <version>2.2</version>
+                <configuration>
+                    <linkXref>true</linkXref>
+                    <minimumTokens>100</minimumTokens>
+                    <targetJdk>1.4</targetJdk>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>taglist-maven-plugin</artifactId>
+                <version>2.1</version>
+                <configuration>
+                    <tags>
+                        <tag>@FIXME</tag>
+                        <tag>@fixme</tag>
+                        <tag>FIXME</tag>
+                        <tag>fixme</tag>
+                        <tag>@TODO</tag>
+                        <tag>@todo</tag>
+                        <tag>TODO</tag>
+                        <tag>todo</tag>
+                    </tags>
+                </configuration>
+            </plugin>
+            <plugin>
+                <!-- Note: aggregate-able, may cause problems if we aggregate jxr and not this because of the xref links -->
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>javancss-maven-plugin</artifactId>
+                <version>2.0-beta-2</version>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>findbugs-maven-plugin</artifactId>
+                <version>1.1.1</version>
+                <configuration>
+                    <onlyAnalyze>org.hibernate.*</onlyAnalyze>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>slf4j-api</artifactId>
+                <version>1.4.2</version>
+            </dependency>
+            <dependency>
+                <groupId>antlr</groupId>
+                <artifactId>antlr</artifactId>
+                <version>2.7.6</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-collections</groupId>
+                <artifactId>commons-collections</artifactId>
+                <version>3.1</version>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>3.8.1</version>
+            </dependency>
+            <dependency>
+                <groupId>dom4j</groupId>
+                <artifactId>dom4j</artifactId>
+                <version>1.6.1</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <distributionManagement>
+        <repository>
+            <!-- Copy the dist to the local checkout of the JBoss maven2 repo ${maven.repository.root} -->
+            <!-- It is anticipated that ${maven.repository.root} be set in user's settings.xml -->
+            <!-- todo : replace this with direct svn access once the svnkit providers are available -->
+            <id>repository.jboss.org</id>
+            <url>file://${maven.repository.root}</url>
+        </repository>
+        <snapshotRepository>
+            <id>snapshots.jboss.org</id>
+            <name>JBoss Snapshot Repository</name>
+            <url>dav:https://snapshots.jboss.org/maven2</url>
+        </snapshotRepository>
+    </distributionManagement>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/pom.xml
===================================================================
--- core/trunk/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,96 +0,0 @@
-<?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
-  ~
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate</artifactId>
-    <packaging>pom</packaging>
-
-    <name>Hibernate Core Aggregator</name>
-    <description>Aggregator of the Hibernate Core modules.</description>
-
-    <modules>
-        <module>parent</module>
-        <module>core</module>
-        <module>cache-ehcache</module>
-        <module>cache-jbosscache</module>
-        <module>cache-jbosscache2</module>
-        <module>cache-oscache</module>
-        <module>cache-swarmcache</module>
-        <module>connection-c3p0</module>
-        <module>connection-proxool</module>
-        <module>jmx</module>
-        <module>testing</module>
-        <module>testsuite</module>
-        <module>tutorials</module>
-<!--
-    Need to scope bytecode providers first...
-        <module>bytecode-cglib</module>
-        <module>bytecode-javassist</module>
--->
-    </modules>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-release-plugin</artifactId>
-                <version>2.0-beta-7</version>
-                <configuration>
-                    <autoVersionSubmodules>true</autoVersionSubmodules>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>docs</id>
-            <activation>
-                <property>
-                    <name>disableDistribution</name>
-                    <value>!true</value>
-                </property>
-            </activation>
-            <modules>
-                <module>documentation</module>
-                <module>distribution</module>
-            </modules>
-        </profile>
-    </profiles>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/pom.xml (from rev 15003, core/trunk/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,96 @@
+<?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
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Hibernate Core Aggregator</name>
+    <description>Aggregator of the Hibernate Core modules.</description>
+
+    <modules>
+        <module>parent</module>
+        <module>core</module>
+        <module>cache-ehcache</module>
+        <module>cache-jbosscache</module>
+        <module>cache-jbosscache2</module>
+        <module>cache-oscache</module>
+        <module>cache-swarmcache</module>
+        <module>connection-c3p0</module>
+        <module>connection-proxool</module>
+        <module>jmx</module>
+        <module>testing</module>
+        <module>testsuite</module>
+        <module>tutorials</module>
+<!--
+    Need to scope bytecode providers first...
+        <module>bytecode-cglib</module>
+        <module>bytecode-javassist</module>
+-->
+    </modules>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <version>2.0-beta-7</version>
+                <configuration>
+                    <autoVersionSubmodules>true</autoVersionSubmodules>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>docs</id>
+            <activation>
+                <property>
+                    <name>disableDistribution</name>
+                    <value>!true</value>
+                </property>
+            </activation>
+            <modules>
+                <module>documentation</module>
+                <module>distribution</module>
+            </modules>
+        </profile>
+    </profiles>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/testing/pom.xml
===================================================================
--- core/trunk/testing/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/testing/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,45 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-testing</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Testing</name>
-    <description>Hibernate JUnit test utilities</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <!-- here we need to pull JUnit deps into compile scope, as opposed to the normal test scope -->
-            <version>3.8.1</version>
-            <scope>compile</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <resources>
-            <resource>
-                <filtering>false</filtering>
-                <directory>src/main/java</directory>
-                <includes>
-                    <include>**/*.hbm.xml</include>
-                </includes>
-            </resource>
-        </resources>
-    </build>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/testing/pom.xml (from rev 15003, core/trunk/testing/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/testing/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/testing/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,45 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-testing</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Testing</name>
+    <description>Hibernate JUnit test utilities</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <!-- here we need to pull JUnit deps into compile scope, as opposed to the normal test scope -->
+            <version>3.8.1</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <filtering>false</filtering>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**/*.hbm.xml</include>
+                </includes>
+            </resource>
+        </resources>
+    </build>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml
===================================================================
--- core/trunk/testsuite/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,353 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-    
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-testsuite</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Testsuite</name>
-    <description>The testsuite of Hibernate functionality</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-testing</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <!-- these are optional on core... :( -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-        </dependency>
-        <dependency>
-            <groupId>org.hibernate</groupId>
-            <artifactId>hibernate-cglib-repack</artifactId>
-            <version>2.1_3</version>
-        </dependency>
-        <!-- optional dom4j dependency; needed here for dom4j (de)serialization -->
-        <dependency>
-            <groupId>jaxen</groupId>
-            <artifactId>jaxen</artifactId>
-            <version>1.1</version>
-        </dependency>
-        <!-- logging setup for the test suite -->
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl104-over-slf4j</artifactId>
-            <version>1.4.2</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <testResources>
-            <testResource>
-                <filtering>false</filtering>
-                <directory>src/test/java</directory>
-                <includes>
-                    <include>**/*.xml</include>
-                </includes>
-            </testResource>
-            <testResource>
-                <filtering>true</filtering>
-                <directory>src/test/resources</directory>
-            </testResource>
-        </testResources>
-
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-              </plugin>
-            <plugin>
-                <groupId>org.jboss.maven.plugins</groupId>
-                <artifactId>maven-test-ext-plugin</artifactId>
-                <version>1.1.0</version>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>extend</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <configuration>
-                    <systemProperties>
-                        <property>
-                            <name>hibernate.test.validatefailureexpected</name>
-                            <value>true</value>
-                        </property>
-                    </systemProperties>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <!-- HSQLDB is the default (eventually move to H2) -->
-        <profile>
-            <id>hsqldb</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>hsqldb</groupId>
-                    <artifactId>hsqldb</artifactId>
-                    <version>1.8.0.2</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.HSQLDialect</db.dialect>
-                <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
-                <jdbc.url>jdbc:hsqldb:target/test/db/hsqldb/hibernate</jdbc.url>
-                <jdbc.user>sa</jdbc.user>
-                <jdbc.pass />
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The H2 test envionment -->
-        <profile>
-            <id>h2</id>
-            <dependencies>
-                <dependency>
-                    <groupId>org.h2database</groupId>
-                    <artifactId>h2database</artifactId>
-                    <version>1.0.20061217</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.H2Dialect</db.dialect>
-                <jdbc.driver>org.h2.Driver</jdbc.driver>
-                <jdbc.url>jdbc:h2:mem:target/test/db/h2/hibernate</jdbc.url>
-                <jdbc.user>sa</jdbc.user>
-                <jdbc.pass />
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!--
-            ###################################################################
-            Profiles naming db instances in the Red Hat QA/QE lab
-
-            First, those with OSS drivers
-            ###################################################################
-        -->
-
-        <!-- The MySQL5 test envionment -->
-        <profile>
-            <id>mysql5</id>
-            <dependencies>
-                <dependency>
-                    <groupId>mysql</groupId>
-                    <artifactId>mysql-connector-java</artifactId>
-                    <version>5.0.5</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</db.dialect>
-                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
-                <jdbc.url>jdbc:mysql://dev02.qa.atl.jboss.com/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The PostgreSQL test envionment -->
-        <profile>
-            <id>pgsql8</id>
-            <dependencies>
-                <dependency>
-                    <groupId>postgresql</groupId>
-                    <artifactId>postgresql</artifactId>
-                    <version>8.2-504</version>
-                    <classifier>jdbc3</classifier>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.PostgreSQLDialect</db.dialect>
-                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
-                <jdbc.url>jdbc:postgresql://dev01.qa.atl.jboss.com:5432:cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!--
-            ###################################################################
-            Then, those with commercial drivers
-            ###################################################################
-        -->
-
-        <!-- The Oracle9i test envionment -->
-        <profile>
-            <id>oracle9i</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.oracle</groupId>
-                    <artifactId>ojdbc14</artifactId>
-                    <!-- use the 10g drivers which are surprisingly largely bug free -->
-                    <version>10.0.2.0</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.Oracle9iDialect</db.dialect>
-                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
-                <jdbc.url>jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The Oracle10g test envionment -->
-        <profile>
-            <id>oracle10g</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.oracle</groupId>
-                    <artifactId>ojdbc14</artifactId>
-                    <!-- use the 10g drivers which are surprisingly largely bug free -->
-                    <version>10.0.2.0</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.Oracle10gDialect</db.dialect>
-                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
-                <jdbc.url>jdbc:oracle:thin:@dev01.qa.atl.jboss.com:1521:qadb01</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The DB2 8.x test envionment (using 9x drivers)-->
-        <profile>
-            <id>db2-8</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.ibm</groupId>
-                    <artifactId>db2jcc</artifactId>
-                    <version>3.1.57</version>
-                </dependency>
-                <dependency>
-                    <groupId>com.ibm</groupId>
-                    <artifactId>db2jcc_license_cu</artifactId>
-                    <version>3.1.57</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.DB2Dialect</db.dialect>
-                <jdbc.driver>com.ibm.db2.jcc.DB2Driver</jdbc.driver>
-                <jdbc.url>jdbc:db2://dev32.qa.atl.jboss.com:50000/jbossqa</jdbc.url>
-                <jdbc.user>hiber</jdbc.user>
-                <jdbc.pass>hiber</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The Sybase 12 test envionment -->
-        <profile>
-            <id>sybase12</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sybase</groupId>
-                    <artifactId>jconnect</artifactId>
-                    <version>6.0.5</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SybaseDialect</db.dialect>
-                <jdbc.driver>com.sybase.jdbc3.jdbc.SybDriver</jdbc.driver>
-                <jdbc.url>jdbc:sybase:Tds:dev01.qa.atl.jboss.com:4100/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The SQLServer2005 (jTDS) test envionment -->
-        <profile>
-            <id>sqlserver-jtds</id>
-            <dependencies>
-                <dependency>
-                    <groupId>net.sourceforge.jtds</groupId>
-                    <artifactId>jtds</artifactId>
-                    <version>1.2</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
-                <jdbc.driver>net.sourceforge.jtds.jdbc.Driver</jdbc.driver>
-                <jdbc.url>jdbc:jtds:sqlserver://dev30.qa.atl.jboss.com:3918/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The SQLServer2005 (MS JDBC) test envionment -->
-        <profile>
-            <id>sqlserver-msjdbc</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.microsoft.sqlserver</groupId>
-                    <artifactId>msjdbc</artifactId>
-                    <version>1.1</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
-                <jdbc.driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc.driver>
-                <jdbc.url>jdbc:sqlserver://dev30.qa.atl.jboss.com:3918</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation>4096</jdbc.isolation>
-            </properties>
-        </profile>
-
-    </profiles>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml (from rev 15003, core/trunk/testsuite/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/testsuite/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,353 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+    
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-testsuite</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Testsuite</name>
+    <description>The testsuite of Hibernate functionality</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-testing</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <!-- these are optional on core... :( -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate</groupId>
+            <artifactId>hibernate-cglib-repack</artifactId>
+            <version>2.1_3</version>
+        </dependency>
+        <!-- optional dom4j dependency; needed here for dom4j (de)serialization -->
+        <dependency>
+            <groupId>jaxen</groupId>
+            <artifactId>jaxen</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <!-- logging setup for the test suite -->
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>99.0-does-not-exist</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>99.0-does-not-exist</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <testResources>
+            <testResource>
+                <filtering>false</filtering>
+                <directory>src/test/java</directory>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </testResource>
+            <testResource>
+                <filtering>true</filtering>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+              </plugin>
+            <plugin>
+                <groupId>org.jboss.maven.plugins</groupId>
+                <artifactId>maven-test-ext-plugin</artifactId>
+                <version>1.1.0</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>extend</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <configuration>
+                    <systemProperties>
+                        <property>
+                            <name>hibernate.test.validatefailureexpected</name>
+                            <value>true</value>
+                        </property>
+                    </systemProperties>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <!-- HSQLDB is the default (eventually move to H2) -->
+        <profile>
+            <id>hsqldb</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>hsqldb</groupId>
+                    <artifactId>hsqldb</artifactId>
+                    <version>1.8.0.2</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.HSQLDialect</db.dialect>
+                <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
+                <jdbc.url>jdbc:hsqldb:target/test/db/hsqldb/hibernate</jdbc.url>
+                <jdbc.user>sa</jdbc.user>
+                <jdbc.pass />
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The H2 test envionment -->
+        <profile>
+            <id>h2</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.h2database</groupId>
+                    <artifactId>h2database</artifactId>
+                    <version>1.0.20061217</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.H2Dialect</db.dialect>
+                <jdbc.driver>org.h2.Driver</jdbc.driver>
+                <jdbc.url>jdbc:h2:mem:target/test/db/h2/hibernate</jdbc.url>
+                <jdbc.user>sa</jdbc.user>
+                <jdbc.pass />
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!--
+            ###################################################################
+            Profiles naming db instances in the Red Hat QA/QE lab
+
+            First, those with OSS drivers
+            ###################################################################
+        -->
+
+        <!-- The MySQL5 test envionment -->
+        <profile>
+            <id>mysql5</id>
+            <dependencies>
+                <dependency>
+                    <groupId>mysql</groupId>
+                    <artifactId>mysql-connector-java</artifactId>
+                    <version>5.0.5</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</db.dialect>
+                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
+                <jdbc.url>jdbc:mysql://dev02.qa.atl.jboss.com/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The PostgreSQL test envionment -->
+        <profile>
+            <id>pgsql8</id>
+            <dependencies>
+                <dependency>
+                    <groupId>postgresql</groupId>
+                    <artifactId>postgresql</artifactId>
+                    <version>8.2-504</version>
+                    <classifier>jdbc3</classifier>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.PostgreSQLDialect</db.dialect>
+                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
+                <jdbc.url>jdbc:postgresql://dev01.qa.atl.jboss.com:5432:cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!--
+            ###################################################################
+            Then, those with commercial drivers
+            ###################################################################
+        -->
+
+        <!-- The Oracle9i test envionment -->
+        <profile>
+            <id>oracle9i</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.oracle</groupId>
+                    <artifactId>ojdbc14</artifactId>
+                    <!-- use the 10g drivers which are surprisingly largely bug free -->
+                    <version>10.0.2.0</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.Oracle9iDialect</db.dialect>
+                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
+                <jdbc.url>jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The Oracle10g test envionment -->
+        <profile>
+            <id>oracle10g</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.oracle</groupId>
+                    <artifactId>ojdbc14</artifactId>
+                    <!-- use the 10g drivers which are surprisingly largely bug free -->
+                    <version>10.0.2.0</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.Oracle10gDialect</db.dialect>
+                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
+                <jdbc.url>jdbc:oracle:thin:@dev01.qa.atl.jboss.com:1521:qadb01</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The DB2 8.x test envionment (using 9x drivers)-->
+        <profile>
+            <id>db2-8</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.ibm</groupId>
+                    <artifactId>db2jcc</artifactId>
+                    <version>3.1.57</version>
+                </dependency>
+                <dependency>
+                    <groupId>com.ibm</groupId>
+                    <artifactId>db2jcc_license_cu</artifactId>
+                    <version>3.1.57</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.DB2Dialect</db.dialect>
+                <jdbc.driver>com.ibm.db2.jcc.DB2Driver</jdbc.driver>
+                <jdbc.url>jdbc:db2://dev32.qa.atl.jboss.com:50000/jbossqa</jdbc.url>
+                <jdbc.user>hiber</jdbc.user>
+                <jdbc.pass>hiber</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The Sybase 12 test envionment -->
+        <profile>
+            <id>sybase12</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.sybase</groupId>
+                    <artifactId>jconnect</artifactId>
+                    <version>6.0.5</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SybaseDialect</db.dialect>
+                <jdbc.driver>com.sybase.jdbc3.jdbc.SybDriver</jdbc.driver>
+                <jdbc.url>jdbc:sybase:Tds:dev01.qa.atl.jboss.com:4100/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The SQLServer2005 (jTDS) test envionment -->
+        <profile>
+            <id>sqlserver-jtds</id>
+            <dependencies>
+                <dependency>
+                    <groupId>net.sourceforge.jtds</groupId>
+                    <artifactId>jtds</artifactId>
+                    <version>1.2</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
+                <jdbc.driver>net.sourceforge.jtds.jdbc.Driver</jdbc.driver>
+                <jdbc.url>jdbc:jtds:sqlserver://dev30.qa.atl.jboss.com:3918/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The SQLServer2005 (MS JDBC) test envionment -->
+        <profile>
+            <id>sqlserver-msjdbc</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.microsoft.sqlserver</groupId>
+                    <artifactId>msjdbc</artifactId>
+                    <version>1.1</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
+                <jdbc.driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc.driver>
+                <jdbc.url>jdbc:sqlserver://dev30.qa.atl.jboss.com:3918</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation>4096</jdbc.isolation>
+            </properties>
+        </profile>
+
+    </profiles>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java
===================================================================
--- core/trunk/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,766 +0,0 @@
-//$Id: MergeTest.java 11037 2007-01-09 16:04:16Z steve.ebersole at jboss.com $
-package org.hibernate.test.ops;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import junit.framework.Test;
-
-import org.hibernate.Hibernate;
-import org.hibernate.NonUniqueObjectException;
-import org.hibernate.Session;
-import org.hibernate.StaleObjectStateException;
-import org.hibernate.Transaction;
-import org.hibernate.criterion.Projections;
-import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
-
-/**
- * @author Gavin King
- */
-public class MergeTest extends AbstractOperationTestCase {
-
-	public MergeTest(String str) {
-		super( str );
-	}
-
-	public static Test suite() {
-		return new FunctionalTestClassTestSuite( MergeTest.class );
-	}
-
-	public void testMergeStaleVersionFails() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		VersionedEntity entity = new VersionedEntity( "entity", "entity" );
-		s.persist( entity );
-		s.getTransaction().commit();
-		s.close();
-
-		// make the detached 'entity' reference stale...
-		s = openSession();
-        s.beginTransaction();
-		VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() );
-		entity2.setName( "entity-name" );
-		s.getTransaction().commit();
-		s.close();
-
-		// now try to reattch it
-		s = openSession();
-		s.beginTransaction();
-		try {
-			s.merge( entity );
-			s.getTransaction().commit();
-			fail( "was expecting staleness error" );
-		}
-		catch ( StaleObjectStateException expected ) {
-			// expected outcome...
-		}
-		finally {
-			s.getTransaction().rollback();
-			s.close();
-		}
-	}
-
-	public void testMergeBidiPrimayKeyOneToOne() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		Person p = new Person( "steve" );
-		new PersonalDetails( "I have big feet", p );
-		s.persist( p );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		p.getDetails().setSomePersonalDetail( p.getDetails().getSomePersonalDetail() + " and big hands too" );
-		s = openSession();
-        s.beginTransaction();
-		p = ( Person ) s.merge( p );
-		s.getTransaction().commit();
-		s.close();
-
-		assertInsertCount( 0 );
-		assertUpdateCount( 1 );
-		assertDeleteCount( 0 );
-
-		s = openSession();
-        s.beginTransaction();
-		s.delete( p );
-		s.getTransaction().commit();
-		s.close();
-	}
-
-	public void testMergeBidiForeignKeyOneToOne() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		Person p = new Person( "steve" );
-		Address a = new Address( "123 Main", "Austin", "US", p );
-		s.persist( a );
-		s.persist( p );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		p.getAddress().setStreetAddress( "321 Main" );
-		s = openSession();
-        s.beginTransaction();
-		p = ( Person ) s.merge( p );
-		s.getTransaction().commit();
-		s.close();
-
-		assertInsertCount( 0 );
-		assertUpdateCount( 0 ); // no cascade
-		assertDeleteCount( 0 );
-
-		s = openSession();
-        s.beginTransaction();
-		s.delete( a );
-		s.delete( p );
-		s.getTransaction().commit();
-		s.close();
-	}
-
-    public void testNoExtraUpdatesOnMerge() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		Node node = new Node( "test" );
-		s.persist( node );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		// node is now detached, but we have made no changes.  so attempt to merge it
-		// into this new session; this should cause no updates...
-		s = openSession();
-		s.beginTransaction();
-		node = ( Node ) s.merge( node );
-		s.getTransaction().commit();
-		s.close();
-
-		assertUpdateCount( 0 );
-		assertInsertCount( 0 );
-
-		///////////////////////////////////////////////////////////////////////
-		// as a control measure, now update the node while it is detached and
-		// make sure we get an update as a result...
-		node.setDescription( "new description" );
-		s = openSession();
-		s.beginTransaction();
-		node = ( Node ) s.merge( node );
-		s.getTransaction().commit();
-		s.close();
-		assertUpdateCount( 1 );
-		assertInsertCount( 0 );
-		///////////////////////////////////////////////////////////////////////
-
-		cleanup();
-    }
-
-	public void testNoExtraUpdatesOnMergeWithCollection() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		Node parent = new Node( "parent" );
-		Node child = new Node( "child" );
-		parent.getChildren().add( child );
-		child.setParent( parent );
-		s.persist( parent );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		// parent is now detached, but we have made no changes.  so attempt to merge it
-		// into this new session; this should cause no updates...
-		s = openSession();
-		s.beginTransaction();
-		parent = ( Node ) s.merge( parent );
-		s.getTransaction().commit();
-		s.close();
-
-		assertUpdateCount( 0 );
-		assertInsertCount( 0 );
-
-		///////////////////////////////////////////////////////////////////////
-		// as a control measure, now update the node while it is detached and
-		// make sure we get an update as a result...
-		( ( Node ) parent.getChildren().iterator().next() ).setDescription( "child's new description" );
-		parent.getChildren().add( new Node( "second child" ) );
-		s = openSession();
-		s.beginTransaction();
-		parent = ( Node ) s.merge( parent );
-		s.getTransaction().commit();
-		s.close();
-		assertUpdateCount( 1 );
-		assertInsertCount( 1 );
-		///////////////////////////////////////////////////////////////////////
-
-		cleanup();
-	}
-
-    public void testNoExtraUpdatesOnMergeVersioned() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		VersionedEntity entity = new VersionedEntity( "entity", "entity" );
-		s.persist( entity );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		// entity is now detached, but we have made no changes.  so attempt to merge it
-		// into this new session; this should cause no updates...
-		s = openSession();
-		s.beginTransaction();
-		VersionedEntity mergedEntity = ( VersionedEntity ) s.merge( entity );
-		s.getTransaction().commit();
-		s.close();
-
-		assertUpdateCount( 0 );
-		assertInsertCount( 0 );
-        assertEquals( "unexpected version increment", entity.getVersion(), mergedEntity.getVersion() );
-
-
-		///////////////////////////////////////////////////////////////////////
-		// as a control measure, now update the node while it is detached and
-		// make sure we get an update as a result...
-		entity.setName( "new name" );
-		s = openSession();
-		s.beginTransaction();
-		entity = ( VersionedEntity ) s.merge( entity );
-		s.getTransaction().commit();
-		s.close();
-		assertUpdateCount( 1 );
-		assertInsertCount( 0 );
-		///////////////////////////////////////////////////////////////////////
-
-		cleanup();
-    }
-
-    public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception {
-		Session s = openSession();
-        s.beginTransaction();
-		VersionedEntity parent = new VersionedEntity( "parent", "parent" );
-		VersionedEntity child = new VersionedEntity( "child", "child" );
-		parent.getChildren().add( child );
-		child.setParent( parent );
-		s.persist( parent );
-		s.getTransaction().commit();
-		s.close();
-
-		clearCounts();
-
-		// parent is now detached, but we have made no changes.  so attempt to merge it
-		// into this new session; this should cause no updates...
-		s = openSession();
-		s.beginTransaction();
-		VersionedEntity mergedParent = ( VersionedEntity ) s.merge( parent );
-		s.getTransaction().commit();
-		s.close();
-
-		assertUpdateCount( 0 );
-		assertInsertCount( 0 );
-		assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
-		VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
-		assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
-
-		///////////////////////////////////////////////////////////////////////
-		// as a control measure, now update the node while it is detached and
-		// make sure we get an update as a result...
-		mergedParent.setName( "new name" );
-		mergedParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
-		s = openSession();
-		s.beginTransaction();
-		parent = ( VersionedEntity ) s.merge( mergedParent );
-		s.getTransaction().commit();
-		s.close();
-		assertUpdateCount( 1 );
-		assertInsertCount( 1 );
-		///////////////////////////////////////////////////////////////////////
-
-		cleanup();
-    }
-
-	public void testPersistThenMergeInSameTxnWithVersion() {
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		VersionedEntity entity = new VersionedEntity( "test", "test" );
-		s.persist( entity );
-		s.merge( new VersionedEntity( "test", "test-2" ) );
-
-		try {
-			// control operation...
-			s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
-			fail( "saveOrUpdate() should fail here" );
-		}
-		catch( NonUniqueObjectException expected ) {
-			// expected behavior
-		}
-
-		tx.commit();
-		s.close();
-
-		cleanup();
-	}
-
-	public void testPersistThenMergeInSameTxnWithTimestamp() {
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		TimestampedEntity entity = new TimestampedEntity( "test", "test" );
-		s.persist( entity );
-		s.merge( new TimestampedEntity( "test", "test-2" ) );
-
-		try {
-			// control operation...
-			s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
-			fail( "saveOrUpdate() should fail here" );
-		}
-		catch( NonUniqueObjectException expected ) {
-			// expected behavior
-		}
-
-		tx.commit();
-		s.close();
-
-		cleanup();
-	}
-
-	public void testMergeDeepTree() {
-
-		clearCounts();
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		Node root = new Node("root");
-		Node child = new Node("child");
-		Node grandchild = new Node("grandchild");
-		root.addChild(child);
-		child.addChild(grandchild);
-		s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(3);
-		assertUpdateCount(0);
-		clearCounts();
-
-		grandchild.setDescription("the grand child");
-		Node grandchild2 = new Node("grandchild2");
-		child.addChild( grandchild2 );
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(1);
-		assertUpdateCount(1);
-		clearCounts();
-
-		Node child2 = new Node("child2");
-		Node grandchild3 = new Node("grandchild3");
-		child2.addChild( grandchild3 );
-		root.addChild(child2);
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(2);
-		assertUpdateCount(0);
-		clearCounts();
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.delete(grandchild);
-		s.delete(grandchild2);
-		s.delete(grandchild3);
-		s.delete(child);
-		s.delete(child2);
-		s.delete(root);
-		tx.commit();
-		s.close();
-
-	}
-
-	public void testMergeDeepTreeWithGeneratedId() {
-
-		clearCounts();
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		NumberedNode root = new NumberedNode("root");
-		NumberedNode child = new NumberedNode("child");
-		NumberedNode grandchild = new NumberedNode("grandchild");
-		root.addChild(child);
-		child.addChild(grandchild);
-		root = (NumberedNode) s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(3);
-		assertUpdateCount(0);
-		clearCounts();
-
-		child = (NumberedNode) root.getChildren().iterator().next();
-		grandchild = (NumberedNode) child.getChildren().iterator().next();
-		grandchild.setDescription("the grand child");
-		NumberedNode grandchild2 = new NumberedNode("grandchild2");
-		child.addChild( grandchild2 );
-
-		s = openSession();
-		tx = s.beginTransaction();
-		root = (NumberedNode) s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(1);
-		assertUpdateCount(1);
-		clearCounts();
-
-		getSessions().evict(NumberedNode.class);
-
-		NumberedNode child2 = new NumberedNode("child2");
-		NumberedNode grandchild3 = new NumberedNode("grandchild3");
-		child2.addChild( grandchild3 );
-		root.addChild(child2);
-
-		s = openSession();
-		tx = s.beginTransaction();
-		root = (NumberedNode) s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(2);
-		assertUpdateCount(0);
-		clearCounts();
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.createQuery("delete from NumberedNode where name like 'grand%'").executeUpdate();
-		s.createQuery("delete from NumberedNode where name like 'child%'").executeUpdate();
-		s.createQuery("delete from NumberedNode").executeUpdate();
-		tx.commit();
-		s.close();
-
-	}
-
-	public void testMergeTree() {
-
-		clearCounts();
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		Node root = new Node("root");
-		Node child = new Node("child");
-		root.addChild(child);
-		s.persist(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(2);
-		clearCounts();
-
-		root.setDescription("The root node");
-		child.setDescription("The child node");
-
-		Node secondChild = new Node("second child");
-
-		root.addChild(secondChild);
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(1);
-		assertUpdateCount(2);
-
-		cleanup();
-	}
-
-	public void testMergeTreeWithGeneratedId() {
-
-		clearCounts();
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		NumberedNode root = new NumberedNode("root");
-		NumberedNode child = new NumberedNode("child");
-		root.addChild(child);
-		s.persist(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(2);
-		clearCounts();
-
-		root.setDescription("The root node");
-		child.setDescription("The child node");
-
-		NumberedNode secondChild = new NumberedNode("second child");
-
-		root.addChild(secondChild);
-
-		s = openSession();
-		tx = s.beginTransaction();
-		s.merge(root);
-		tx.commit();
-		s.close();
-
-		assertInsertCount(1);
-		assertUpdateCount(2);
-
-		cleanup();
-	}
-
-	public void testMergeManaged() {
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		NumberedNode root = new NumberedNode("root");
-		s.persist(root);
-		tx.commit();
-
-		clearCounts();
-
-		tx = s.beginTransaction();
-		NumberedNode child = new NumberedNode("child");
-		root.addChild(child);
-		assertSame( root, s.merge(root) );
-		Object mergedChild = root.getChildren().iterator().next();
-		assertNotSame( mergedChild, child );
-		assertTrue( s.contains(mergedChild) );
-		assertFalse( s.contains(child) );
-		assertEquals( root.getChildren().size(), 1 );
-		assertTrue( root.getChildren().contains(mergedChild) );
-		//assertNotSame( mergedChild, s.merge(child) ); //yucky :(
-		tx.commit();
-
-		assertInsertCount(1);
-		assertUpdateCount(0);
-
-		assertEquals( root.getChildren().size(), 1 );
-		assertTrue( root.getChildren().contains(mergedChild) );
-
-		tx = s.beginTransaction();
-		assertEquals(
-			s.createCriteria(NumberedNode.class)
-				.setProjection( Projections.rowCount() )
-				.uniqueResult(),
-			new Integer(2)
-		);
-
-		s.close();
-
-		cleanup();
-	}
-
-	public void testMergeManagedUninitializedCollection() {
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		NumberedNode root = new NumberedNode( "root" );
-		root.addChild( new NumberedNode( "child" ) );
-		s.persist(root);
-		tx.commit();
-		s.close();
-
-		clearCounts();
-
-		NumberedNode newRoot = new NumberedNode( "root" );
-		newRoot.setId( root.getId() );
-
-		s = openSession();
-		tx = s.beginTransaction();
-		root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
-		Set managedChildren = root.getChildren();
-		assertFalse( Hibernate.isInitialized( managedChildren ) );
-		newRoot.setChildren( managedChildren );
-		assertSame( root, s.merge( newRoot ) );
-		assertSame( managedChildren, root.getChildren() );
-		assertFalse( Hibernate.isInitialized( managedChildren ) );
-		tx.commit();
-
-		assertInsertCount(0);
-		assertUpdateCount(0);
-		assertDeleteCount(0);
-
-		tx = s.beginTransaction();
-		assertEquals(
-			s.createCriteria(NumberedNode.class)
-				.setProjection( Projections.rowCount() )
-				.uniqueResult(),
-			new Integer(2)
-		);
-		tx.commit();
-
-		s.close();
-
-		cleanup();
-	}
-
-	public void testMergeManagedInitializedCollection() {
-
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		NumberedNode root = new NumberedNode( "root" );
-		root.addChild( new NumberedNode( "child" ) );
-		s.persist(root);
-		tx.commit();
-		s.close();
-
-		clearCounts();
-
-		NumberedNode newRoot = new NumberedNode( "root" );
-		newRoot.setId( root.getId() );
-
-		s = openSession();
-		tx = s.beginTransaction();
-		root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
-		Set managedChildren = root.getChildren();
-		Hibernate.initialize( managedChildren );
-		assertTrue( Hibernate.isInitialized( managedChildren ) );
-		newRoot.setChildren( managedChildren );
-		assertSame( root, s.merge( newRoot ) );
-		assertSame( managedChildren, root.getChildren() );
-		assertTrue( Hibernate.isInitialized( managedChildren ) );
-		tx.commit();
-
-		assertInsertCount(0);
-		assertUpdateCount(0);
-		assertDeleteCount(0);
-
-		tx = s.beginTransaction();
-		assertEquals(
-			s.createCriteria(NumberedNode.class)
-				.setProjection( Projections.rowCount() )
-				.uniqueResult(),
-			new Integer(2)
-		);
-		tx.commit();
-
-		s.close();
-
-		cleanup();
-	}
-
-	public void testRecursiveMergeTransient() {
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		Employer jboss = new Employer();
-		Employee gavin = new Employee();
-		jboss.setEmployees( new ArrayList() );
-		jboss.getEmployees().add(gavin);
-		s.merge(jboss);
-		s.flush();
-		jboss = (Employer) s.createQuery("from Employer e join fetch e.employees").uniqueResult();
-		assertTrue( Hibernate.isInitialized( jboss.getEmployees() )  );
-		assertEquals( 1, jboss.getEmployees().size() );
-		s.clear();
-		s.merge( jboss.getEmployees().iterator().next() );
-		tx.commit();
-		s.close();
-
-		cleanup();
-	}
-
-	public void testDeleteAndMerge() throws Exception {
-		Session s = openSession();
-		s.getTransaction().begin();
-		Employer jboss = new Employer();
-		s.persist( jboss );
-		s.getTransaction().commit();
-		s.clear();
-
-		s.getTransaction().begin();
-		Employer otherJboss;
-		otherJboss = (Employer) s.get( Employer.class, jboss.getId() );
-		s.delete( otherJboss );
-		s.getTransaction().commit();
-		s.clear();
-		jboss.setVers( new Integer(1) );
-		s.getTransaction().begin();
-		s.merge( jboss );
-		s.getTransaction().commit();
-		s.close();
-
-		cleanup();
-	}
-
-	public void testMergeManyToManyWithCollectionDeference() throws Exception {
-		// setup base data...
-		Session s = openSession();
-		Transaction tx = s.beginTransaction();
-		Competition competition = new Competition();
-		competition.getCompetitors().add( new Competitor( "Name" ) );
-		competition.getCompetitors().add( new Competitor() );
-		competition.getCompetitors().add( new Competitor() );
-		s.persist( competition );
-		tx.commit();
-		s.close();
-
-		// the competition graph is now detached:
-		//   1) create a new List reference to represent the competitors
-		s = openSession();
-		tx = s.beginTransaction();
-		List newComp = new ArrayList();
-		Competitor originalCompetitor = ( Competitor ) competition.getCompetitors().get( 0 );
-		originalCompetitor.setName( "Name2" );
-		newComp.add( originalCompetitor );
-		newComp.add( new Competitor() );
-		//   2) set that new List reference unto the Competition reference
-		competition.setCompetitors( newComp );
-		//   3) attempt the merge
-		Competition competition2 = ( Competition ) s.merge( competition );
-		tx.commit();
-		s.close();
-
-		assertFalse( competition == competition2 );
-		assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
-		assertEquals( 2, competition2.getCompetitors().size() );
-
-		s = openSession();
-		tx = s.beginTransaction();
-		competition = ( Competition ) s.get( Competition.class, competition.getId() );
-		assertEquals( 2, competition.getCompetitors().size() );
-		s.delete( competition );
-		tx.commit();
-		s.close();
-
-		cleanup();
-	}
-
-	private void cleanup() {
-		Session s = openSession();
-		s.beginTransaction();
-		s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
-		s.createQuery( "delete from NumberedNode" ).executeUpdate();
-
-		s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
-		s.createQuery( "delete from Node" ).executeUpdate();
-
-		s.createQuery( "delete from VersionedEntity where parent is not null" ).executeUpdate();
-		s.createQuery( "delete from VersionedEntity" ).executeUpdate();
-		s.createQuery( "delete from TimestampedEntity" ).executeUpdate();
-
-		s.createQuery( "delete from Competitor" ).executeUpdate();
-		s.createQuery( "delete from Competition" ).executeUpdate();
-
-		Iterator itr = s.createQuery( "from Employer" ).list().iterator();
-		while ( itr.hasNext() ) {
-			final Employer employer = ( Employer ) itr.next();
-			s.delete( employer );
-		}
-
-		s.getTransaction().commit();
-		s.close();
-	}
-}
-

Copied: core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java (from rev 14839, core/trunk/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/testsuite/src/test/java/org/hibernate/test/ops/MergeTest.java	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,815 @@
+//$Id: MergeTest.java 11037 2007-01-09 16:04:16Z steve.ebersole at jboss.com $
+package org.hibernate.test.ops;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.hibernate.Hibernate;
+import org.hibernate.NonUniqueObjectException;
+import org.hibernate.Session;
+import org.hibernate.StaleObjectStateException;
+import org.hibernate.Transaction;
+import org.hibernate.criterion.Projections;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * @author Gavin King
+ */
+public class MergeTest extends AbstractOperationTestCase {
+
+	public MergeTest(String str) {
+		super( str );
+	}
+
+	public static Test suite() {
+		return new FunctionalTestClassTestSuite( MergeTest.class );
+	}
+
+	public void testMergeStaleVersionFails() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		VersionedEntity entity = new VersionedEntity( "entity", "entity" );
+		s.persist( entity );
+		s.getTransaction().commit();
+		s.close();
+
+		// make the detached 'entity' reference stale...
+		s = openSession();
+        s.beginTransaction();
+		VersionedEntity entity2 = ( VersionedEntity ) s.get( VersionedEntity.class, entity.getId() );
+		entity2.setName( "entity-name" );
+		s.getTransaction().commit();
+		s.close();
+
+		// now try to reattch it
+		s = openSession();
+		s.beginTransaction();
+		try {
+			s.merge( entity );
+			s.getTransaction().commit();
+			fail( "was expecting staleness error" );
+		}
+		catch ( StaleObjectStateException expected ) {
+			// expected outcome...
+		}
+		finally {
+			s.getTransaction().rollback();
+			s.close();
+		}
+	}
+
+	public void testMergeBidiPrimayKeyOneToOne() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		Person p = new Person( "steve" );
+		new PersonalDetails( "I have big feet", p );
+		s.persist( p );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		p.getDetails().setSomePersonalDetail( p.getDetails().getSomePersonalDetail() + " and big hands too" );
+		s = openSession();
+        s.beginTransaction();
+		p = ( Person ) s.merge( p );
+		s.getTransaction().commit();
+		s.close();
+
+		assertInsertCount( 0 );
+		assertUpdateCount( 1 );
+		assertDeleteCount( 0 );
+
+		s = openSession();
+        s.beginTransaction();
+		s.delete( p );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testMergeBidiForeignKeyOneToOne() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		Person p = new Person( "steve" );
+		Address a = new Address( "123 Main", "Austin", "US", p );
+		s.persist( a );
+		s.persist( p );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		p.getAddress().setStreetAddress( "321 Main" );
+		s = openSession();
+        s.beginTransaction();
+		p = ( Person ) s.merge( p );
+		s.getTransaction().commit();
+		s.close();
+
+		assertInsertCount( 0 );
+		assertUpdateCount( 0 ); // no cascade
+		assertDeleteCount( 0 );
+
+		s = openSession();
+        s.beginTransaction();
+		s.delete( a );
+		s.delete( p );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+    public void testNoExtraUpdatesOnMerge() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		Node node = new Node( "test" );
+		s.persist( node );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		// node is now detached, but we have made no changes.  so attempt to merge it
+		// into this new session; this should cause no updates...
+		s = openSession();
+		s.beginTransaction();
+		node = ( Node ) s.merge( node );
+		s.getTransaction().commit();
+		s.close();
+
+		assertUpdateCount( 0 );
+		assertInsertCount( 0 );
+
+		///////////////////////////////////////////////////////////////////////
+		// as a control measure, now update the node while it is detached and
+		// make sure we get an update as a result...
+		node.setDescription( "new description" );
+		s = openSession();
+		s.beginTransaction();
+		node = ( Node ) s.merge( node );
+		s.getTransaction().commit();
+		s.close();
+		assertUpdateCount( 1 );
+		assertInsertCount( 0 );
+		///////////////////////////////////////////////////////////////////////
+
+		cleanup();
+    }
+
+	public void testNoExtraUpdatesOnMergeWithCollection() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		Node parent = new Node( "parent" );
+		Node child = new Node( "child" );
+		parent.getChildren().add( child );
+		child.setParent( parent );
+		s.persist( parent );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		// parent is now detached, but we have made no changes.  so attempt to merge it
+		// into this new session; this should cause no updates...
+		s = openSession();
+		s.beginTransaction();
+		parent = ( Node ) s.merge( parent );
+		s.getTransaction().commit();
+		s.close();
+
+		assertUpdateCount( 0 );
+		assertInsertCount( 0 );
+
+		///////////////////////////////////////////////////////////////////////
+		// as a control measure, now update the node while it is detached and
+		// make sure we get an update as a result...
+		( ( Node ) parent.getChildren().iterator().next() ).setDescription( "child's new description" );
+		parent.getChildren().add( new Node( "second child" ) );
+		s = openSession();
+		s.beginTransaction();
+		parent = ( Node ) s.merge( parent );
+		s.getTransaction().commit();
+		s.close();
+		assertUpdateCount( 1 );
+		assertInsertCount( 1 );
+		///////////////////////////////////////////////////////////////////////
+
+		cleanup();
+	}
+
+    public void testNoExtraUpdatesOnMergeVersioned() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		VersionedEntity entity = new VersionedEntity( "entity", "entity" );
+		s.persist( entity );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		// entity is now detached, but we have made no changes.  so attempt to merge it
+		// into this new session; this should cause no updates...
+		s = openSession();
+		s.beginTransaction();
+		VersionedEntity mergedEntity = ( VersionedEntity ) s.merge( entity );
+		s.getTransaction().commit();
+		s.close();
+
+		assertUpdateCount( 0 );
+		assertInsertCount( 0 );
+        assertEquals( "unexpected version increment", entity.getVersion(), mergedEntity.getVersion() );
+
+
+		///////////////////////////////////////////////////////////////////////
+		// as a control measure, now update the node while it is detached and
+		// make sure we get an update as a result...
+		entity.setName( "new name" );
+		s = openSession();
+		s.beginTransaction();
+		entity = ( VersionedEntity ) s.merge( entity );
+		s.getTransaction().commit();
+		s.close();
+		assertUpdateCount( 1 );
+		assertInsertCount( 0 );
+		///////////////////////////////////////////////////////////////////////
+
+		cleanup();
+    }
+
+    public void testNoExtraUpdatesOnMergeVersionedWithCollection() throws Exception {
+		Session s = openSession();
+        s.beginTransaction();
+		VersionedEntity parent = new VersionedEntity( "parent", "parent" );
+		VersionedEntity child = new VersionedEntity( "child", "child" );
+		parent.getChildren().add( child );
+		child.setParent( parent );
+		s.persist( parent );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		// parent is now detached, but we have made no changes.  so attempt to merge it
+		// into this new session; this should cause no updates...
+		s = openSession();
+		s.beginTransaction();
+		VersionedEntity mergedParent = ( VersionedEntity ) s.merge( parent );
+		s.getTransaction().commit();
+		s.close();
+
+		assertUpdateCount( 0 );
+		assertInsertCount( 0 );
+		assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
+		VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
+		assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
+
+		///////////////////////////////////////////////////////////////////////
+		// as a control measure, now update the node while it is detached and
+		// make sure we get an update as a result...
+		mergedParent.setName( "new name" );
+		mergedParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
+		s = openSession();
+		s.beginTransaction();
+		parent = ( VersionedEntity ) s.merge( mergedParent );
+		s.getTransaction().commit();
+		s.close();
+		assertUpdateCount( 1 );
+		assertInsertCount( 1 );
+		///////////////////////////////////////////////////////////////////////
+
+		cleanup();
+    }
+
+	public void testNoExtraUpdatesOnPersistentMergeVersionedWithCollection() throws Exception {
+		Session s = openSession();
+		s.beginTransaction();
+		VersionedEntity parent = new VersionedEntity( "parent", "parent" );
+		VersionedEntity child = new VersionedEntity( "child", "child" );
+		parent.getChildren().add( child );
+		child.setParent( parent );
+		s.persist( parent );
+		s.getTransaction().commit();
+		s.close();
+
+		clearCounts();
+
+		// parent is now detached, but we have made no changes. so attempt to merge it
+		// into this new session; this should cause no updates...
+		s = openSession();
+		s.beginTransaction();
+		// load parent so that merge will follow entityIsPersistent path
+		VersionedEntity persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
+		// load children
+		VersionedEntity persistentChild = ( VersionedEntity ) persistentParent.getChildren().iterator().next();
+		VersionedEntity mergedParent = ( VersionedEntity ) s.merge( persistentParent ); // <-- This merge leads to failure
+		s.getTransaction().commit();
+		s.close();
+
+		assertUpdateCount( 0 );
+		assertInsertCount( 0 );
+		assertEquals( "unexpected parent version increment", parent.getVersion(), mergedParent.getVersion() );
+		VersionedEntity mergedChild = ( VersionedEntity ) mergedParent.getChildren().iterator().next();
+		assertEquals( "unexpected child version increment", child.getVersion(), mergedChild.getVersion() );
+
+		///////////////////////////////////////////////////////////////////////
+		// as a control measure, now update the node once it is loaded and
+		// make sure we get an update as a result...
+		s = openSession();
+		s.beginTransaction();
+		persistentParent = ( VersionedEntity ) s.get( VersionedEntity.class, parent.getId() );
+		persistentParent.setName( "new name" );
+		persistentParent.getChildren().add( new VersionedEntity( "child2", "new child" ) );
+		persistentParent = ( VersionedEntity ) s.merge( persistentParent );
+		s.getTransaction().commit();
+		s.close();
+		assertUpdateCount( 1 );
+		assertInsertCount( 1 );
+		///////////////////////////////////////////////////////////////////////
+
+		// cleanup();
+	}
+
+	public void testPersistThenMergeInSameTxnWithVersion() {
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		VersionedEntity entity = new VersionedEntity( "test", "test" );
+		s.persist( entity );
+		s.merge( new VersionedEntity( "test", "test-2" ) );
+
+		try {
+			// control operation...
+			s.saveOrUpdate( new VersionedEntity( "test", "test-3" ) );
+			fail( "saveOrUpdate() should fail here" );
+		}
+		catch( NonUniqueObjectException expected ) {
+			// expected behavior
+		}
+
+		tx.commit();
+		s.close();
+
+		cleanup();
+	}
+
+	public void testPersistThenMergeInSameTxnWithTimestamp() {
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		TimestampedEntity entity = new TimestampedEntity( "test", "test" );
+		s.persist( entity );
+		s.merge( new TimestampedEntity( "test", "test-2" ) );
+
+		try {
+			// control operation...
+			s.saveOrUpdate( new TimestampedEntity( "test", "test-3" ) );
+			fail( "saveOrUpdate() should fail here" );
+		}
+		catch( NonUniqueObjectException expected ) {
+			// expected behavior
+		}
+
+		tx.commit();
+		s.close();
+
+		cleanup();
+	}
+
+	public void testMergeDeepTree() {
+
+		clearCounts();
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		Node root = new Node("root");
+		Node child = new Node("child");
+		Node grandchild = new Node("grandchild");
+		root.addChild(child);
+		child.addChild(grandchild);
+		s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(3);
+		assertUpdateCount(0);
+		clearCounts();
+
+		grandchild.setDescription("the grand child");
+		Node grandchild2 = new Node("grandchild2");
+		child.addChild( grandchild2 );
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(1);
+		assertUpdateCount(1);
+		clearCounts();
+
+		Node child2 = new Node("child2");
+		Node grandchild3 = new Node("grandchild3");
+		child2.addChild( grandchild3 );
+		root.addChild(child2);
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(2);
+		assertUpdateCount(0);
+		clearCounts();
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.delete(grandchild);
+		s.delete(grandchild2);
+		s.delete(grandchild3);
+		s.delete(child);
+		s.delete(child2);
+		s.delete(root);
+		tx.commit();
+		s.close();
+
+	}
+
+	public void testMergeDeepTreeWithGeneratedId() {
+
+		clearCounts();
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		NumberedNode root = new NumberedNode("root");
+		NumberedNode child = new NumberedNode("child");
+		NumberedNode grandchild = new NumberedNode("grandchild");
+		root.addChild(child);
+		child.addChild(grandchild);
+		root = (NumberedNode) s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(3);
+		assertUpdateCount(0);
+		clearCounts();
+
+		child = (NumberedNode) root.getChildren().iterator().next();
+		grandchild = (NumberedNode) child.getChildren().iterator().next();
+		grandchild.setDescription("the grand child");
+		NumberedNode grandchild2 = new NumberedNode("grandchild2");
+		child.addChild( grandchild2 );
+
+		s = openSession();
+		tx = s.beginTransaction();
+		root = (NumberedNode) s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(1);
+		assertUpdateCount(1);
+		clearCounts();
+
+		getSessions().evict(NumberedNode.class);
+
+		NumberedNode child2 = new NumberedNode("child2");
+		NumberedNode grandchild3 = new NumberedNode("grandchild3");
+		child2.addChild( grandchild3 );
+		root.addChild(child2);
+
+		s = openSession();
+		tx = s.beginTransaction();
+		root = (NumberedNode) s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(2);
+		assertUpdateCount(0);
+		clearCounts();
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.createQuery("delete from NumberedNode where name like 'grand%'").executeUpdate();
+		s.createQuery("delete from NumberedNode where name like 'child%'").executeUpdate();
+		s.createQuery("delete from NumberedNode").executeUpdate();
+		tx.commit();
+		s.close();
+
+	}
+
+	public void testMergeTree() {
+
+		clearCounts();
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		Node root = new Node("root");
+		Node child = new Node("child");
+		root.addChild(child);
+		s.persist(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(2);
+		clearCounts();
+
+		root.setDescription("The root node");
+		child.setDescription("The child node");
+
+		Node secondChild = new Node("second child");
+
+		root.addChild(secondChild);
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(1);
+		assertUpdateCount(2);
+
+		cleanup();
+	}
+
+	public void testMergeTreeWithGeneratedId() {
+
+		clearCounts();
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		NumberedNode root = new NumberedNode("root");
+		NumberedNode child = new NumberedNode("child");
+		root.addChild(child);
+		s.persist(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(2);
+		clearCounts();
+
+		root.setDescription("The root node");
+		child.setDescription("The child node");
+
+		NumberedNode secondChild = new NumberedNode("second child");
+
+		root.addChild(secondChild);
+
+		s = openSession();
+		tx = s.beginTransaction();
+		s.merge(root);
+		tx.commit();
+		s.close();
+
+		assertInsertCount(1);
+		assertUpdateCount(2);
+
+		cleanup();
+	}
+
+	public void testMergeManaged() {
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		NumberedNode root = new NumberedNode("root");
+		s.persist(root);
+		tx.commit();
+
+		clearCounts();
+
+		tx = s.beginTransaction();
+		NumberedNode child = new NumberedNode("child");
+		root.addChild(child);
+		assertSame( root, s.merge(root) );
+		Object mergedChild = root.getChildren().iterator().next();
+		assertNotSame( mergedChild, child );
+		assertTrue( s.contains(mergedChild) );
+		assertFalse( s.contains(child) );
+		assertEquals( root.getChildren().size(), 1 );
+		assertTrue( root.getChildren().contains(mergedChild) );
+		//assertNotSame( mergedChild, s.merge(child) ); //yucky :(
+		tx.commit();
+
+		assertInsertCount(1);
+		assertUpdateCount(0);
+
+		assertEquals( root.getChildren().size(), 1 );
+		assertTrue( root.getChildren().contains(mergedChild) );
+
+		tx = s.beginTransaction();
+		assertEquals(
+			s.createCriteria(NumberedNode.class)
+				.setProjection( Projections.rowCount() )
+				.uniqueResult(),
+			new Integer(2)
+		);
+
+		s.close();
+
+		cleanup();
+	}
+
+	public void testMergeManagedUninitializedCollection() {
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		NumberedNode root = new NumberedNode( "root" );
+		root.addChild( new NumberedNode( "child" ) );
+		s.persist(root);
+		tx.commit();
+		s.close();
+
+		clearCounts();
+
+		NumberedNode newRoot = new NumberedNode( "root" );
+		newRoot.setId( root.getId() );
+
+		s = openSession();
+		tx = s.beginTransaction();
+		root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
+		Set managedChildren = root.getChildren();
+		assertFalse( Hibernate.isInitialized( managedChildren ) );
+		newRoot.setChildren( managedChildren );
+		assertSame( root, s.merge( newRoot ) );
+		assertSame( managedChildren, root.getChildren() );
+		assertFalse( Hibernate.isInitialized( managedChildren ) );
+		tx.commit();
+
+		assertInsertCount(0);
+		assertUpdateCount(0);
+		assertDeleteCount(0);
+
+		tx = s.beginTransaction();
+		assertEquals(
+			s.createCriteria(NumberedNode.class)
+				.setProjection( Projections.rowCount() )
+				.uniqueResult(),
+			new Integer(2)
+		);
+		tx.commit();
+
+		s.close();
+
+		cleanup();
+	}
+
+	public void testMergeManagedInitializedCollection() {
+
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		NumberedNode root = new NumberedNode( "root" );
+		root.addChild( new NumberedNode( "child" ) );
+		s.persist(root);
+		tx.commit();
+		s.close();
+
+		clearCounts();
+
+		NumberedNode newRoot = new NumberedNode( "root" );
+		newRoot.setId( root.getId() );
+
+		s = openSession();
+		tx = s.beginTransaction();
+		root = ( NumberedNode ) s.get( NumberedNode.class, root.getId() );
+		Set managedChildren = root.getChildren();
+		Hibernate.initialize( managedChildren );
+		assertTrue( Hibernate.isInitialized( managedChildren ) );
+		newRoot.setChildren( managedChildren );
+		assertSame( root, s.merge( newRoot ) );
+		assertSame( managedChildren, root.getChildren() );
+		assertTrue( Hibernate.isInitialized( managedChildren ) );
+		tx.commit();
+
+		assertInsertCount(0);
+		assertUpdateCount(0);
+		assertDeleteCount(0);
+
+		tx = s.beginTransaction();
+		assertEquals(
+			s.createCriteria(NumberedNode.class)
+				.setProjection( Projections.rowCount() )
+				.uniqueResult(),
+			new Integer(2)
+		);
+		tx.commit();
+
+		s.close();
+
+		cleanup();
+	}
+
+	public void testRecursiveMergeTransient() {
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		Employer jboss = new Employer();
+		Employee gavin = new Employee();
+		jboss.setEmployees( new ArrayList() );
+		jboss.getEmployees().add(gavin);
+		s.merge(jboss);
+		s.flush();
+		jboss = (Employer) s.createQuery("from Employer e join fetch e.employees").uniqueResult();
+		assertTrue( Hibernate.isInitialized( jboss.getEmployees() )  );
+		assertEquals( 1, jboss.getEmployees().size() );
+		s.clear();
+		s.merge( jboss.getEmployees().iterator().next() );
+		tx.commit();
+		s.close();
+
+		cleanup();
+	}
+
+	public void testDeleteAndMerge() throws Exception {
+		Session s = openSession();
+		s.getTransaction().begin();
+		Employer jboss = new Employer();
+		s.persist( jboss );
+		s.getTransaction().commit();
+		s.clear();
+
+		s.getTransaction().begin();
+		Employer otherJboss;
+		otherJboss = (Employer) s.get( Employer.class, jboss.getId() );
+		s.delete( otherJboss );
+		s.getTransaction().commit();
+		s.clear();
+		jboss.setVers( new Integer(1) );
+		s.getTransaction().begin();
+		s.merge( jboss );
+		s.getTransaction().commit();
+		s.close();
+
+		cleanup();
+	}
+
+	public void testMergeManyToManyWithCollectionDeference() throws Exception {
+		// setup base data...
+		Session s = openSession();
+		Transaction tx = s.beginTransaction();
+		Competition competition = new Competition();
+		competition.getCompetitors().add( new Competitor( "Name" ) );
+		competition.getCompetitors().add( new Competitor() );
+		competition.getCompetitors().add( new Competitor() );
+		s.persist( competition );
+		tx.commit();
+		s.close();
+
+		// the competition graph is now detached:
+		//   1) create a new List reference to represent the competitors
+		s = openSession();
+		tx = s.beginTransaction();
+		List newComp = new ArrayList();
+		Competitor originalCompetitor = ( Competitor ) competition.getCompetitors().get( 0 );
+		originalCompetitor.setName( "Name2" );
+		newComp.add( originalCompetitor );
+		newComp.add( new Competitor() );
+		//   2) set that new List reference unto the Competition reference
+		competition.setCompetitors( newComp );
+		//   3) attempt the merge
+		Competition competition2 = ( Competition ) s.merge( competition );
+		tx.commit();
+		s.close();
+
+		assertFalse( competition == competition2 );
+		assertFalse( competition.getCompetitors() == competition2.getCompetitors() );
+		assertEquals( 2, competition2.getCompetitors().size() );
+
+		s = openSession();
+		tx = s.beginTransaction();
+		competition = ( Competition ) s.get( Competition.class, competition.getId() );
+		assertEquals( 2, competition.getCompetitors().size() );
+		s.delete( competition );
+		tx.commit();
+		s.close();
+
+		cleanup();
+	}
+
+	private void cleanup() {
+		Session s = openSession();
+		s.beginTransaction();
+		s.createQuery( "delete from NumberedNode where parent is not null" ).executeUpdate();
+		s.createQuery( "delete from NumberedNode" ).executeUpdate();
+
+		s.createQuery( "delete from Node where parent is not null" ).executeUpdate();
+		s.createQuery( "delete from Node" ).executeUpdate();
+
+		s.createQuery( "delete from VersionedEntity where parent is not null" ).executeUpdate();
+		s.createQuery( "delete from VersionedEntity" ).executeUpdate();
+		s.createQuery( "delete from TimestampedEntity" ).executeUpdate();
+
+		s.createQuery( "delete from Competitor" ).executeUpdate();
+		s.createQuery( "delete from Competition" ).executeUpdate();
+
+		Iterator itr = s.createQuery( "from Employer" ).list().iterator();
+		while ( itr.hasNext() ) {
+			final Employer employer = ( Employer ) itr.next();
+			s.delete( employer );
+		}
+
+		s.getTransaction().commit();
+		s.close();
+	}
+}
+

Deleted: core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml
===================================================================
--- core/trunk/tutorials/eg/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,46 +0,0 @@
-<?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
-  ~
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-tutorials</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-tutorial-eg</artifactId>
-    <packaging>jar</packaging>
-
-    <name>Hibernate Example</name>
-    <description>A simple example of Hibernate functionality</description>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml (from rev 15003, core/trunk/tutorials/eg/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/eg/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,46 @@
+<?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
+  ~
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-tutorials</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-tutorial-eg</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Hibernate Example</name>
+    <description>A simple example of Hibernate functionality</description>
+
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml
===================================================================
--- core/trunk/tutorials/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,371 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!--
-  ~ 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
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-parent</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../parent/pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-tutorials</artifactId>
-    <packaging>pom</packaging>
-
-    <name>Hibernate Tutorials</name>
-    <description>Series of tutorials demonstrating Hibernate functionality</description>
-
-    <modules>
-        <module>eg</module>
-        <module>web</module>
-    </modules>
-
-    <dependencies>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-core</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <dependency>
-            <groupId>${groupId}</groupId>
-            <artifactId>hibernate-testing</artifactId>
-            <version>${version}</version>
-        </dependency>
-        <!-- these are optional on core... :( -->
-        <dependency>
-            <groupId>javassist</groupId>
-            <artifactId>javassist</artifactId>
-            <version>3.4.GA</version>
-        </dependency>
-        <dependency>
-            <groupId>cglib</groupId>
-            <artifactId>cglib</artifactId>
-            <version>2.1_3</version>
-        </dependency>
-        <dependency>
-            <groupId>asm</groupId>
-            <artifactId>asm-attrs</artifactId>
-            <version>1.5.3</version>
-        </dependency>
-        <!-- optional dom4j dependency; needed here for dom4j (de)serialization -->
-        <dependency>
-            <groupId>jaxen</groupId>
-            <artifactId>jaxen</artifactId>
-            <version>1.1</version>
-        </dependency>
-        <!-- the tutorials use HSQLDB -->
-         <dependency>
-             <groupId>hsqldb</groupId>
-             <artifactId>hsqldb</artifactId>
-             <version>1.8.0.2</version>
-        </dependency>
-        <!-- logging setup -->
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>99.0-does-not-exist</version>
-        </dependency>
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging-api</artifactId>
-            <version>99.0-does-not-exist</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>jcl104-over-slf4j</artifactId>
-            <version>1.4.2</version>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-log4j12</artifactId>
-            <version>1.4.2</version>
-        </dependency>
-        <dependency>
-            <groupId>log4j</groupId>
-            <artifactId>log4j</artifactId>
-            <version>1.2.14</version>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <testResources>
-            <testResource>
-                <filtering>false</filtering>
-                <directory>src/test/java</directory>
-                <includes>
-                    <include>**/*.xml</include>
-                </includes>
-            </testResource>
-            <testResource>
-                <filtering>true</filtering>
-                <directory>src/test/resources</directory>
-            </testResource>
-        </testResources>
-
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <configuration>
-                    <source>1.5</source>
-                    <target>1.5</target>
-                </configuration>
-              </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <!-- HSQLDB is the default (eventually move to H2) -->
-        <profile>
-            <id>hsqldb</id>
-            <activation>
-                <activeByDefault>true</activeByDefault>
-            </activation>
-            <dependencies>
-                <dependency>
-                    <groupId>hsqldb</groupId>
-                    <artifactId>hsqldb</artifactId>
-                    <version>1.8.0.2</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.HSQLDialect</db.dialect>
-                <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
-                <jdbc.url>jdbc:hsqldb:target/test/db/hsqldb/hibernate</jdbc.url>
-                <jdbc.user>sa</jdbc.user>
-                <jdbc.pass />
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The H2 test envionment -->
-        <profile>
-            <id>h2</id>
-            <dependencies>
-                <dependency>
-                    <groupId>org.h2database</groupId>
-                    <artifactId>h2database</artifactId>
-                    <version>1.0.20061217</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.H2Dialect</db.dialect>
-                <jdbc.driver>org.h2.Driver</jdbc.driver>
-                <jdbc.url>jdbc:h2:mem:target/test/db/h2/hibernate</jdbc.url>
-                <jdbc.user>sa</jdbc.user>
-                <jdbc.pass />
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!--
-            ###################################################################
-            Profiles naming db instances in the Red Hat QA/QE lab
-
-            First, those with OSS drivers
-            ###################################################################
-        -->
-
-        <!-- The MySQL5 test envionment -->
-        <profile>
-            <id>mysql5</id>
-            <dependencies>
-                <dependency>
-                    <groupId>mysql</groupId>
-                    <artifactId>mysql-connector-java</artifactId>
-                    <version>5.0.5</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</db.dialect>
-                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
-                <jdbc.url>jdbc:mysql://dev02.qa.atl.jboss.com/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The PostgreSQL test envionment -->
-        <profile>
-            <id>pgsql8</id>
-            <dependencies>
-                <dependency>
-                    <groupId>postgresql</groupId>
-                    <artifactId>postgresql</artifactId>
-                    <version>8.2-504</version>
-                    <classifier>jdbc3</classifier>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.PostgreSQLDialect</db.dialect>
-                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
-                <jdbc.url>jdbc:postgresql://dev01.qa.atl.jboss.com:5432:cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!--
-            ###################################################################
-            Then, those with commercial drivers
-            ###################################################################
-        -->
-
-        <!-- The Oracle9i test envionment -->
-        <profile>
-            <id>oracle9i</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.oracle</groupId>
-                    <artifactId>ojdbc14</artifactId>
-                    <!-- use the 10g drivers which are surprisingly largely bug free -->
-                    <version>10.0.2.0</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.Oracle9iDialect</db.dialect>
-                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
-                <jdbc.url>jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The Oracle10g test envionment -->
-        <profile>
-            <id>oracle10g</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.oracle</groupId>
-                    <artifactId>ojdbc14</artifactId>
-                    <!-- use the 10g drivers which are surprisingly largely bug free -->
-                    <version>10.0.2.0</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.Oracle10gDialect</db.dialect>
-                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
-                <jdbc.url>jdbc:oracle:thin:@dev01.qa.atl.jboss.com:1521:qadb01</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The DB2 8.x test envionment (using 9x drivers)-->
-        <profile>
-            <id>db2-8</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.ibm</groupId>
-                    <artifactId>db2jcc</artifactId>
-                    <version>3.1.57</version>
-                </dependency>
-                <dependency>
-                    <groupId>com.ibm</groupId>
-                    <artifactId>db2jcc_license_cu</artifactId>
-                    <version>3.1.57</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.DB2Dialect</db.dialect>
-                <jdbc.driver>com.ibm.db2.jcc.DB2Driver</jdbc.driver>
-                <jdbc.url>jdbc:db2://dev32.qa.atl.jboss.com:50000/jbossqa</jdbc.url>
-                <jdbc.user>hiber</jdbc.user>
-                <jdbc.pass>hiber</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The Sybase 12 test envionment -->
-        <profile>
-            <id>sybase12</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.sybase</groupId>
-                    <artifactId>jconnect</artifactId>
-                    <version>6.0.5</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SybaseDialect</db.dialect>
-                <jdbc.driver>com.sybase.jdbc3.jdbc.SybDriver</jdbc.driver>
-                <jdbc.url>jdbc:sybase:Tds:dev01.qa.atl.jboss.com:4100/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The SQLServer2005 (jTDS) test envionment -->
-        <profile>
-            <id>sqlserver-jtds</id>
-            <dependencies>
-                <dependency>
-                    <groupId>net.sourceforge.jtds</groupId>
-                    <artifactId>jtds</artifactId>
-                    <version>1.2</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
-                <jdbc.driver>net.sourceforge.jtds.jdbc.Driver</jdbc.driver>
-                <jdbc.url>jdbc:jtds:sqlserver://dev30.qa.atl.jboss.com:3918/cruisecontrol</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation />
-            </properties>
-        </profile>
-
-        <!-- The SQLServer2005 (MS JDBC) test envionment -->
-        <profile>
-            <id>sqlserver-msjdbc</id>
-            <dependencies>
-                <dependency>
-                    <groupId>com.microsoft.sqlserver</groupId>
-                    <artifactId>msjdbc</artifactId>
-                    <version>1.1</version>
-                </dependency>
-            </dependencies>
-            <properties>
-                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
-                <jdbc.driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc.driver>
-                <jdbc.url>jdbc:sqlserver://dev30.qa.atl.jboss.com:3918</jdbc.url>
-                <jdbc.user>cruisecontrol</jdbc.user>
-                <jdbc.pass>cruisecontrol</jdbc.pass>
-                <jdbc.isolation>4096</jdbc.isolation>
-            </properties>
-        </profile>
-
-    </profiles>
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml (from rev 15003, core/trunk/tutorials/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,371 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  ~ 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
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-parent</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../parent/pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-tutorials</artifactId>
+    <packaging>pom</packaging>
+
+    <name>Hibernate Tutorials</name>
+    <description>Series of tutorials demonstrating Hibernate functionality</description>
+
+    <modules>
+        <module>eg</module>
+        <module>web</module>
+    </modules>
+
+    <dependencies>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-core</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>${groupId}</groupId>
+            <artifactId>hibernate-testing</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <!-- these are optional on core... :( -->
+        <dependency>
+            <groupId>javassist</groupId>
+            <artifactId>javassist</artifactId>
+            <version>3.4.GA</version>
+        </dependency>
+        <dependency>
+            <groupId>cglib</groupId>
+            <artifactId>cglib</artifactId>
+            <version>2.1_3</version>
+        </dependency>
+        <dependency>
+            <groupId>asm</groupId>
+            <artifactId>asm-attrs</artifactId>
+            <version>1.5.3</version>
+        </dependency>
+        <!-- optional dom4j dependency; needed here for dom4j (de)serialization -->
+        <dependency>
+            <groupId>jaxen</groupId>
+            <artifactId>jaxen</artifactId>
+            <version>1.1</version>
+        </dependency>
+        <!-- the tutorials use HSQLDB -->
+         <dependency>
+             <groupId>hsqldb</groupId>
+             <artifactId>hsqldb</artifactId>
+             <version>1.8.0.2</version>
+        </dependency>
+        <!-- logging setup -->
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>99.0-does-not-exist</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging-api</artifactId>
+            <version>99.0-does-not-exist</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>jcl104-over-slf4j</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <version>1.4.2</version>
+        </dependency>
+        <dependency>
+            <groupId>log4j</groupId>
+            <artifactId>log4j</artifactId>
+            <version>1.2.14</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <testResources>
+            <testResource>
+                <filtering>false</filtering>
+                <directory>src/test/java</directory>
+                <includes>
+                    <include>**/*.xml</include>
+                </includes>
+            </testResource>
+            <testResource>
+                <filtering>true</filtering>
+                <directory>src/test/resources</directory>
+            </testResource>
+        </testResources>
+
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.5</source>
+                    <target>1.5</target>
+                </configuration>
+              </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <!-- HSQLDB is the default (eventually move to H2) -->
+        <profile>
+            <id>hsqldb</id>
+            <activation>
+                <activeByDefault>true</activeByDefault>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>hsqldb</groupId>
+                    <artifactId>hsqldb</artifactId>
+                    <version>1.8.0.2</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.HSQLDialect</db.dialect>
+                <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
+                <jdbc.url>jdbc:hsqldb:target/test/db/hsqldb/hibernate</jdbc.url>
+                <jdbc.user>sa</jdbc.user>
+                <jdbc.pass />
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The H2 test envionment -->
+        <profile>
+            <id>h2</id>
+            <dependencies>
+                <dependency>
+                    <groupId>org.h2database</groupId>
+                    <artifactId>h2database</artifactId>
+                    <version>1.0.20061217</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.H2Dialect</db.dialect>
+                <jdbc.driver>org.h2.Driver</jdbc.driver>
+                <jdbc.url>jdbc:h2:mem:target/test/db/h2/hibernate</jdbc.url>
+                <jdbc.user>sa</jdbc.user>
+                <jdbc.pass />
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!--
+            ###################################################################
+            Profiles naming db instances in the Red Hat QA/QE lab
+
+            First, those with OSS drivers
+            ###################################################################
+        -->
+
+        <!-- The MySQL5 test envionment -->
+        <profile>
+            <id>mysql5</id>
+            <dependencies>
+                <dependency>
+                    <groupId>mysql</groupId>
+                    <artifactId>mysql-connector-java</artifactId>
+                    <version>5.0.5</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.MySQL5InnoDBDialect</db.dialect>
+                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
+                <jdbc.url>jdbc:mysql://dev02.qa.atl.jboss.com/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The PostgreSQL test envionment -->
+        <profile>
+            <id>pgsql8</id>
+            <dependencies>
+                <dependency>
+                    <groupId>postgresql</groupId>
+                    <artifactId>postgresql</artifactId>
+                    <version>8.2-504</version>
+                    <classifier>jdbc3</classifier>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.PostgreSQLDialect</db.dialect>
+                <jdbc.driver>org.postgresql.Driver</jdbc.driver>
+                <jdbc.url>jdbc:postgresql://dev01.qa.atl.jboss.com:5432:cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!--
+            ###################################################################
+            Then, those with commercial drivers
+            ###################################################################
+        -->
+
+        <!-- The Oracle9i test envionment -->
+        <profile>
+            <id>oracle9i</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.oracle</groupId>
+                    <artifactId>ojdbc14</artifactId>
+                    <!-- use the 10g drivers which are surprisingly largely bug free -->
+                    <version>10.0.2.0</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.Oracle9iDialect</db.dialect>
+                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
+                <jdbc.url>jdbc:oracle:thin:@dev20.qa.atl.jboss.com:1521:qa</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The Oracle10g test envionment -->
+        <profile>
+            <id>oracle10g</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.oracle</groupId>
+                    <artifactId>ojdbc14</artifactId>
+                    <!-- use the 10g drivers which are surprisingly largely bug free -->
+                    <version>10.0.2.0</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.Oracle10gDialect</db.dialect>
+                <jdbc.driver>oracle.jdbc.driver.OracleDriver</jdbc.driver>
+                <jdbc.url>jdbc:oracle:thin:@dev01.qa.atl.jboss.com:1521:qadb01</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The DB2 8.x test envionment (using 9x drivers)-->
+        <profile>
+            <id>db2-8</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.ibm</groupId>
+                    <artifactId>db2jcc</artifactId>
+                    <version>3.1.57</version>
+                </dependency>
+                <dependency>
+                    <groupId>com.ibm</groupId>
+                    <artifactId>db2jcc_license_cu</artifactId>
+                    <version>3.1.57</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.DB2Dialect</db.dialect>
+                <jdbc.driver>com.ibm.db2.jcc.DB2Driver</jdbc.driver>
+                <jdbc.url>jdbc:db2://dev32.qa.atl.jboss.com:50000/jbossqa</jdbc.url>
+                <jdbc.user>hiber</jdbc.user>
+                <jdbc.pass>hiber</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The Sybase 12 test envionment -->
+        <profile>
+            <id>sybase12</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.sybase</groupId>
+                    <artifactId>jconnect</artifactId>
+                    <version>6.0.5</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SybaseDialect</db.dialect>
+                <jdbc.driver>com.sybase.jdbc3.jdbc.SybDriver</jdbc.driver>
+                <jdbc.url>jdbc:sybase:Tds:dev01.qa.atl.jboss.com:4100/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The SQLServer2005 (jTDS) test envionment -->
+        <profile>
+            <id>sqlserver-jtds</id>
+            <dependencies>
+                <dependency>
+                    <groupId>net.sourceforge.jtds</groupId>
+                    <artifactId>jtds</artifactId>
+                    <version>1.2</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
+                <jdbc.driver>net.sourceforge.jtds.jdbc.Driver</jdbc.driver>
+                <jdbc.url>jdbc:jtds:sqlserver://dev30.qa.atl.jboss.com:3918/cruisecontrol</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation />
+            </properties>
+        </profile>
+
+        <!-- The SQLServer2005 (MS JDBC) test envionment -->
+        <profile>
+            <id>sqlserver-msjdbc</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.microsoft.sqlserver</groupId>
+                    <artifactId>msjdbc</artifactId>
+                    <version>1.1</version>
+                </dependency>
+            </dependencies>
+            <properties>
+                <db.dialect>org.hibernate.dialect.SQLServerDialect</db.dialect>
+                <jdbc.driver>com.microsoft.sqlserver.jdbc.SQLServerDriver</jdbc.driver>
+                <jdbc.url>jdbc:sqlserver://dev30.qa.atl.jboss.com:3918</jdbc.url>
+                <jdbc.user>cruisecontrol</jdbc.user>
+                <jdbc.pass>cruisecontrol</jdbc.pass>
+                <jdbc.isolation>4096</jdbc.isolation>
+            </properties>
+        </profile>
+
+    </profiles>
+</project>
\ No newline at end of file

Deleted: core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml
===================================================================
--- core/trunk/tutorials/web/pom.xml	2008-06-05 23:41:49 UTC (rev 14744)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -1,27 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.hibernate</groupId>
-        <artifactId>hibernate-tutorials</artifactId>
-        <version>3.3.0-SNAPSHOT</version>
-        <relativePath>../pom.xml</relativePath>
-    </parent>
-
-    <groupId>org.hibernate</groupId>
-    <artifactId>hibernate-tutorial-web</artifactId>
-    <packaging>war</packaging>
-
-    <name>Hibernate Web Tutorial</name>
-    <description>A webapp-based tutorial project showcasing Hibernate usage</description>
-
-    <dependencies>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
-            <version>2.3</version>
-        </dependency>
-    </dependencies>
-
-</project>
\ No newline at end of file

Copied: core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml (from rev 15003, core/trunk/tutorials/web/pom.xml)
===================================================================
--- core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml	                        (rev 0)
+++ core/tags/hibernate-3.3.0.CR2/tutorials/web/pom.xml	2008-07-31 20:03:48 UTC (rev 15004)
@@ -0,0 +1,27 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.hibernate</groupId>
+        <artifactId>hibernate-tutorials</artifactId>
+        <version>3.3.0.CR2</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <groupId>org.hibernate</groupId>
+    <artifactId>hibernate-tutorial-web</artifactId>
+    <packaging>war</packaging>
+
+    <name>Hibernate Web Tutorial</name>
+    <description>A webapp-based tutorial project showcasing Hibernate usage</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <version>2.3</version>
+        </dependency>
+    </dependencies>
+
+</project>
\ No newline at end of file




More information about the hibernate-commits mailing list